Commit 5868974c authored by Flyinghead's avatar Flyinghead
Browse files

ta: defer index building and strip merging, filter out infinite vertices

parent 4565fe09
......@@ -41,11 +41,19 @@ struct List
}
__forceinline
T* LastPtr(int n=1) const
T* LastPtr(int n = 1) const
{
return daty-n;
}
T* PopLast()
{
daty--;
avail++;
return daty;
}
T* head() const { return daty-used(); }
void InitBytes(int maxbytes,bool* ovrn, const char *name)
......@@ -78,4 +86,7 @@ struct List
Clear();
free(daty);
}
T* begin() const { return head(); }
T* end() const { return LastPtr(0); }
};
......@@ -3,7 +3,7 @@
Parsing of the TA stream and generation of vertex data !
*/
#include <cmath>
#include "ta.h"
#include "ta_ctx.h"
#include "pvr_mem.h"
......@@ -34,9 +34,9 @@ extern int screen_height;
#define TA_V64H
//cache state vars
u32 tileclip_val = 0;
static u32 tileclip_val = 0;
u8 f32_su8_tbl[65536];
static u8 f32_su8_tbl[65536];
#define float_to_satu8(val) f32_su8_tbl[((u32&)val)>>16]
/*
......@@ -67,12 +67,12 @@ static PolyParam* CurrentPP;
static List<PolyParam>* CurrentPPlist;
//TA state vars
DECL_ALIGN(4) u8 FaceBaseColor[4];
DECL_ALIGN(4) u8 FaceOffsColor[4];
DECL_ALIGN(4) u8 FaceBaseColor1[4];
DECL_ALIGN(4) u8 FaceOffsColor1[4];
DECL_ALIGN(4) u32 SFaceBaseColor;
DECL_ALIGN(4) u32 SFaceOffsColor;
DECL_ALIGN(4) static u8 FaceBaseColor[4];
DECL_ALIGN(4) static u8 FaceOffsColor[4];
DECL_ALIGN(4) static u8 FaceBaseColor1[4];
DECL_ALIGN(4) static u8 FaceOffsColor1[4];
DECL_ALIGN(4) static u32 SFaceBaseColor;
DECL_ALIGN(4) static u32 SFaceOffsColor;
//splitter function lookup
extern u32 ta_type_lut[256];
......@@ -728,6 +728,8 @@ public:
__forceinline
static void EndList(u32 ListType)
{
if (CurrentPP != NULL && CurrentPP->count == 0)
CurrentPPlist->PopLast();
CurrentPP = NULL;
CurrentPPlist = NULL;
......@@ -740,36 +742,29 @@ public:
template<class T>
static void glob_param_bdc_(T* pp)
{
if (CurrentPP == NULL
|| CurrentPP->pcw.full != pp->pcw.full
|| CurrentPP->tcw.full != pp->tcw.full
|| CurrentPP->tsp.full != pp->tsp.full
|| CurrentPP->isp.full != pp->isp.full)
PolyParam* d_pp = CurrentPP;
if (d_pp == NULL || d_pp->count != 0)
{
PolyParam* d_pp=CurrentPP;
if (d_pp == NULL || d_pp->count != 0)
{
d_pp=CurrentPPlist->Append();
CurrentPP=d_pp;
}
d_pp->first=vdrc.idx.used();
d_pp->count=0;
d_pp = CurrentPPlist->Append();
CurrentPP = d_pp;
}
d_pp->first = vdrc.verts.used();
d_pp->count = 0;
d_pp->isp=pp->isp;
d_pp->tsp=pp->tsp;
d_pp->tcw=pp->tcw;
d_pp->pcw=pp->pcw;
d_pp->tileclip=tileclip_val;
d_pp->isp = pp->isp;
d_pp->tsp = pp->tsp;
d_pp->tcw = pp->tcw;
d_pp->pcw = pp->pcw;
d_pp->tileclip = tileclip_val;
d_pp->texid = -1;
d_pp->texid = -1;
if (d_pp->pcw.Texture) {
d_pp->texid = renderer->GetTexture(d_pp->tsp,d_pp->tcw);
}
d_pp->tsp1.full = -1;
d_pp->tcw1.full = -1;
d_pp->texid1 = -1;
}
if (d_pp->pcw.Texture)
d_pp->texid = renderer->GetTexture(d_pp->tsp,d_pp->tcw);
d_pp->tsp1.full = -1;
d_pp->tcw1.full = -1;
d_pp->texid1 = -1;
}
#define glob_param_bdc(pp) glob_param_bdc_( (TA_PolyParam0*)pp)
......@@ -864,26 +859,16 @@ public:
__forceinline
static void EndPolyStrip()
{
CurrentPP->count=vdrc.idx.used() - CurrentPP->first;
if (CurrentPPlist==&vdrc.global_param_tr)
{
PolyParam* d_pp =CurrentPPlist->Append();
*d_pp=*CurrentPP;
CurrentPP=d_pp;
d_pp->first=vdrc.idx.used();
d_pp->count=0;
}
else
{
int vbase=vdrc.verts.used();
CurrentPP->count = vdrc.verts.used() - CurrentPP->first;
*vdrc.idx.Append()=vbase-1;
*vdrc.idx.Append()=vbase;
if (CurrentPP->count&1)
*vdrc.idx.Append()=vbase;
}
if (CurrentPP->count > 0)
{
PolyParam* d_pp = CurrentPPlist->Append();
*d_pp = *CurrentPP;
CurrentPP = d_pp;
d_pp->first = vdrc.verts.used();
d_pp->count = 0;
}
}
......@@ -900,7 +885,6 @@ public:
static Vertex* vert_cvt_base_(T* vtx)
{
f32 invW=vtx->xyz[2];
*vdrc.idx.Append()=vdrc.verts.used();
Vertex* cv=vdrc.verts.Append();
cv->x=vtx->xyz[0];
cv->y=vtx->xyz[1];
......@@ -1227,7 +1211,7 @@ public:
CurrentPP=d_pp;
}
d_pp->first=vdrc.idx.used();
d_pp->first = vdrc.verts.used();
d_pp->count=0;
d_pp->isp=spr->isp;
d_pp->tsp=spr->tsp;
......@@ -1269,17 +1253,7 @@ public:
__forceinline
static void AppendSpriteVertexA(TA_Sprite1A* sv)
{
u32* idx = vdrc.idx.Append(6);
u32 vbase=vdrc.verts.used();
idx[0]=vbase+0;
idx[1]=vbase+1;
idx[2]=vbase+2;
idx[3]=vbase+3;
idx[4]=vbase+3;
idx[5]=vbase+4;
CurrentPP->count=vdrc.idx.used()-CurrentPP->first-2;
CurrentPP->count = 4;
Vertex* cv = vdrc.verts.Append(4);
......@@ -1372,24 +1346,12 @@ public:
update_fz(cv[0].z);
/*
if (CurrentPP->count)
{
Vertex* vert=vert_reappend;
vert[-1].x=vert[0].x;
vert[-1].y=vert[0].y;
vert[-1].z=vert[0].z;
CurrentPP->count+=2;
}*/
#if STRIPS_AS_PPARAMS
if (CurrentPPlist==&vdrc.global_param_tr)
{
PolyParam* d_pp =CurrentPPlist->Append();
*d_pp=*CurrentPP;
CurrentPP=d_pp;
d_pp->first=vdrc.idx.used();
d_pp->count=0;
}
PolyParam* d_pp = CurrentPPlist->Append();
*d_pp = *CurrentPP;
CurrentPP = d_pp;
d_pp->first = vdrc.verts.used();
d_pp->count = 0;
#endif
}
......@@ -1406,8 +1368,11 @@ public:
return;
if (list->used() > 0)
{
ModifierVolumeParam *p = &(list->head()[list->used() - 1]);
ModifierVolumeParam *p = list->LastPtr();
p->count = vdrc.modtrig.used() - p->first;
if (p->count == 0)
list->PopLast();
}
}
......@@ -1463,13 +1428,6 @@ public:
//allocate storage for BG poly
vd_rc.global_param_op.Append();
u32* idx = vd_rc.idx.Append(4);
int vbase=vd_rc.verts.used();
idx[0]=vbase+0;
idx[1]=vbase+1;
idx[2]=vbase+2;
idx[3]=vbase+3;
vd_rc.verts.Append(4);
}
};
......@@ -1481,6 +1439,99 @@ FifoSplitter<0> TAFifo0;
int ta_parse_cnt = 0;
//
// Check if a vertex has huge x,y,z values or negative z
//
static bool is_vertex_inf(const Vertex& vtx)
{
return std::isnan(vtx.x) || fabsf(vtx.x) > 3.4e37f
|| std::isnan(vtx.y) || fabsf(vtx.y) > 3.4e37f
|| std::isnan(vtx.z) || vtx.z < 0.f || vtx.z > 3.4e37f;
}
//
// Create the vertex index, eliminating invalid vertices and merging strips when possible.
//
static void make_index(const List<PolyParam> *polys, int first, int end, bool merge, rend_context* ctx)
{
const u32 *indices = ctx->idx.head();
const Vertex *vertices = ctx->verts.head();
PolyParam *last_poly = nullptr;
const PolyParam *end_poly = &polys->head()[end];
for (PolyParam *poly = &polys->head()[first]; poly != end_poly; poly++)
{
int first_index;
bool dupe_next_vtx = false;
if (merge
&& last_poly != nullptr
&& poly->pcw.full == last_poly->pcw.full
&& poly->tcw.full == last_poly->tcw.full
&& poly->tsp.full == last_poly->tsp.full
&& poly->isp.full == last_poly->isp.full
// FIXME tcw1, tsp1, tileclip?
)
{
const u32 last_vtx = indices[last_poly->first + last_poly->count - 1];
*ctx->idx.Append() = last_vtx;
dupe_next_vtx = true;
first_index = last_poly->first;
}
else
{
last_poly = poly;
first_index = ctx->idx.used();
}
int last_good_vtx = -1;
for (int i = 0; i < poly->count; i++)
{
const Vertex& vtx = vertices[poly->first + i];
if (is_vertex_inf(vtx))
{
while (i < poly->count - 1)
{
const Vertex& next_vtx = vertices[poly->first + i + 1];
if (!is_vertex_inf(next_vtx))
{
// repeat last and next vertices to link strips
if (last_good_vtx >= 0)
{
verify(!dupe_next_vtx);
*ctx->idx.Append() = last_good_vtx;
dupe_next_vtx = true;
}
break;
}
i++;
}
}
else
{
last_good_vtx = poly->first + i;
if (dupe_next_vtx)
{
*ctx->idx.Append() = last_good_vtx;
dupe_next_vtx = false;
}
const u32 count = ctx->idx.used() - first_index;
if ((i ^ count) & 1)
*ctx->idx.Append() = last_good_vtx;
*ctx->idx.Append() = last_good_vtx;
}
}
if (last_poly == poly)
{
poly->first = first_index;
poly->count = ctx->idx.used() - first_index;
}
else
{
last_poly->count = ctx->idx.used() - last_poly->first;
poly->count = 0;
}
}
}
static void fix_texture_bleeding(const List<PolyParam> *list)
{
for (const PolyParam *pp = list->head(); pp <= list->LastPtr(); pp++)
......@@ -1529,9 +1580,9 @@ static void fix_texture_bleeding(const List<PolyParam> *list)
*/
bool ta_parse_vdrc(TA_context* ctx)
{
bool rv=false;
bool rv=false;
vd_ctx = ctx;
vd_rc = vd_ctx->rend;
vd_rc = vd_ctx->rend;
ta_parse_cnt++;
......@@ -1539,12 +1590,15 @@ bool ta_parse_vdrc(TA_context* ctx)
{
TAFifo0.vdec_init();
for (int pass = 0; pass <= ctx->tad.render_pass_count; pass++)
{
ctx->MarkRend(pass);
int op_poly_count = 0;
int pt_poly_count = 0;
int tr_poly_count = 0;
vd_rc.proc_start = ctx->rend.proc_start;
vd_rc.proc_end = ctx->rend.proc_end;
for (int pass = 0; pass <= ctx->tad.render_pass_count; pass++)
{
ctx->MarkRend(pass);
vd_rc.proc_start = ctx->rend.proc_start;
vd_rc.proc_end = ctx->rend.proc_end;
Ta_Dma* ta_data=(Ta_Dma*)vd_rc.proc_start;
Ta_Dma* ta_data_end=((Ta_Dma*)vd_rc.proc_end)-1;
......@@ -1556,13 +1610,22 @@ bool ta_parse_vdrc(TA_context* ctx)
RenderPass *render_pass = vd_rc.render_passes.Append();
render_pass->op_count = vd_rc.global_param_op.used();
make_index(&vd_rc.global_param_op, op_poly_count,
render_pass->op_count, true, &vd_rc);
op_poly_count = render_pass->op_count;
render_pass->mvo_count = vd_rc.global_param_mvo.used();
render_pass->pt_count = vd_rc.global_param_pt.used();
make_index(&vd_rc.global_param_pt, pt_poly_count,
render_pass->pt_count, true, &vd_rc);
pt_poly_count = render_pass->pt_count;
render_pass->tr_count = vd_rc.global_param_tr.used();
make_index(&vd_rc.global_param_tr, tr_poly_count,
render_pass->tr_count, false, &vd_rc);
tr_poly_count = render_pass->tr_count;
render_pass->mvo_tr_count = vd_rc.global_param_mvo_tr.used();
render_pass->autosort = UsingAutoSort(pass);
render_pass->z_clear = ClearZBeforePass(pass);
}
}
if (screen_height > 480)
{
......
......@@ -51,11 +51,6 @@ void main()
vtx_offs1 = in_offs1;
vtx_uv1 = in_uv1;
vec4 vpos=in_pos;
if (vpos.z < 0.0 || vpos.z > 3.4e37)
{
gl_Position = vec4(0.0, 0.0, 1.0, 1.0 / vpos.z);
return;
}
vpos.w = extra_depth_scale / vpos.z;
vpos.z = vpos.w;
......
......@@ -85,11 +85,6 @@ void main()
vtx_offs=in_offs;
vtx_uv=in_uv;
highp vec4 vpos = in_pos;
if (vpos.z < 0.0 || vpos.z > 3.4e37)
{
gl_Position = vec4(0.0, 0.0, 1.0, 1.0 / vpos.z);
return;
}
vpos.w = extra_depth_scale / vpos.z;
#if TARGET_GL != GLES2
......
......@@ -24,6 +24,7 @@ struct IndexTrig
f32 z;
};
#if 0
static float min3(float v0, float v1, float v2)
{
return min(min(v0,v1),v2);
......@@ -33,6 +34,7 @@ static float max3(float v0, float v1, float v2)
{
return max(max(v0,v1),v2);
}
#endif
static float minZ(const Vertex *v, const u32 *mod)
{
......@@ -194,10 +196,10 @@ static bool PP_EQ(const PolyParam *pp0, const PolyParam *pp1)
}
static void fill_id(u32 *d, const Vertex *v0, const Vertex *v1, const Vertex *v2, const Vertex *vb)
{
d[0]=v0-vb;
d[1]=v1-vb;
d[2]=v2-vb;
{
d[0] = (u32)(v0 - vb);
d[1] = (u32)(v1 - vb);
d[2] = (u32)(v2 - vb);
}
void GenSorted(int first, int count, vector<SortTrigDrawParam>& pidx_sort, vector<u32>& vidx_sort)
......@@ -216,12 +218,11 @@ void GenSorted(int first, int count, vector<SortTrigDrawParam>& pidx_sort, vecto
const PolyParam *pp = pp_base;
const PolyParam *pp_end = pp + count;
const Vertex *vtx_arr = vtx_base + idx_base[pp->first];
vtx_sort_base=vtx_base;
static u32 vtx_cnt;
int vtx_count=idx_base[pp_end[-1].first+pp_end[-1].count-1]-idx_base[pp->first];
int vtx_count = pvrrc.verts.used() - idx_base[pp->first];
if (vtx_count>vtx_cnt)
vtx_cnt=vtx_count;
......@@ -242,32 +243,29 @@ void GenSorted(int first, int count, vector<SortTrigDrawParam>& pidx_sort, vecto
while(pp!=pp_end)
{
u32 ppid=(pp-pp_base);
u32 ppid = (u32)(pp - pp_base);
if (pp->count>2)
{
const u32 *idx = idx_base + pp->first;
u32 flip = 0;
const Vertex *vtx = vtx_base + idx[0];
const Vertex *vtx_end = vtx_base + idx[pp->count - 1] - 1;
u32 flip=0;
while(vtx!=vtx_end)
for (int i = 0; i < pp->count - 2; i++)
{
const Vertex *v0, *v1, *v2, *v3, *v4, *v5;
const Vertex *v0, *v1;
if (flip)
{
v0=&vtx[1];
v1=&vtx[0];
v2=&vtx[2];
v0 = vtx_base + idx[i + 1];
v1 = vtx_base + idx[i];
}
else
{
v0=&vtx[0];
v1=&vtx[1];
v2=&vtx[2];
v0 = vtx_base + idx[i];
v1 = vtx_base + idx[i + 1];
}
const Vertex *v2 = vtx_base + idx[i + 2];
#if 0
const Vertex *v3, *v4, *v5;
if (settings.pvr.subdivide_transp)
{
u32 tess_x=(max3(v0->x,v1->x,v2->x)-min3(v0->x,v1->x,v2->x))/32;
......@@ -350,8 +348,6 @@ void GenSorted(int first, int count, vector<SortTrigDrawParam>& pidx_sort, vecto
}
flip ^= 1;
vtx++;
}
}
pp++;
......
......@@ -60,11 +60,6 @@ void main()
vtx_offs1 = vec4(in_offs1) / 255.0;
vtx_uv1 = in_uv1;
vec4 vpos = in_pos;
if (vpos.z < 0.0 || vpos.z > 3.4e37)
{
gl_Position = vec4(0.0, 0.0, 1.0, 1.0 / vpos.z);
return;
}
vpos = uniformBuffer.normal_matrix * vpos;
vpos.w = 1.0 / vpos.z;
vpos.z = vpos.w;
......
......@@ -52,11 +52,6 @@ void main()
vtx_offs = vec4(in_offs) / 255.0;
vtx_uv = in_uv;
vec4 vpos = in_pos;
if (vpos.z < 0.0 || vpos.z > 3.4e37)
{
gl_Position = vec4(0.0, 0.0, 1.0, 1.0 / vpos.z);
return;
}
vpos = uniformBuffer.normal_matrix * vpos;
vpos.w = 1.0 / vpos.z;
vpos.z = vpos.w;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment