pvr: use u32 for vertex indices to avoid overflow
Fixes alpilot glitches
This commit is contained in:
parent
fea5f05b20
commit
5664bfb9b6
|
@ -131,7 +131,7 @@ struct rend_context
|
|||
u32 fog_clamp_max;
|
||||
|
||||
List<Vertex> verts;
|
||||
List<u16> idx;
|
||||
List<u32> idx;
|
||||
List<ModTriangle> modtrig;
|
||||
List<ModifierVolumeParam> global_param_mvo;
|
||||
List<ModifierVolumeParam> global_param_mvo_tr;
|
||||
|
@ -160,6 +160,8 @@ struct rend_context
|
|||
}
|
||||
};
|
||||
|
||||
#define TA_DATA_SIZE (8 * 1024 * 1024)
|
||||
|
||||
//vertex lists
|
||||
struct TA_context
|
||||
{
|
||||
|
@ -199,7 +201,7 @@ struct TA_context
|
|||
|
||||
void Alloc()
|
||||
{
|
||||
tad.Reset((u8*)OS_aligned_malloc(32, 8*1024*1024));
|
||||
tad.Reset((u8*)OS_aligned_malloc(32, TA_DATA_SIZE));
|
||||
|
||||
rend.verts.InitBytes(4 * 1024 * 1024, &rend.Overrun, "verts"); //up to 4 mb of vtx data/frame = ~ 96k vtx/frame
|
||||
rend.idx.Init(120 * 1024, &rend.Overrun, "idx"); //up to 120K indexes ( idx have stripification overhead )
|
||||
|
@ -218,6 +220,7 @@ struct TA_context
|
|||
|
||||
void Reset()
|
||||
{
|
||||
verify(tad.End() - tad.thd_root < TA_DATA_SIZE);
|
||||
tad.Clear();
|
||||
rend_inuse.Lock();
|
||||
rend.Clear();
|
||||
|
@ -227,6 +230,7 @@ struct TA_context
|
|||
|
||||
void Free()
|
||||
{
|
||||
verify(tad.End() - tad.thd_root < TA_DATA_SIZE);
|
||||
OS_aligned_free(tad.thd_root);
|
||||
rend.verts.Free();
|
||||
rend.idx.Free();
|
||||
|
|
|
@ -1304,7 +1304,7 @@ public:
|
|||
__forceinline
|
||||
static void AppendSpriteVertexA(TA_Sprite1A* sv)
|
||||
{
|
||||
u16* idx=vdrc.idx.Append(6);
|
||||
u32* idx = vdrc.idx.Append(6);
|
||||
u32 vbase=vdrc.verts.used();
|
||||
|
||||
idx[0]=vbase+0;
|
||||
|
@ -1496,7 +1496,7 @@ public:
|
|||
|
||||
//allocate storage for BG poly
|
||||
vd_rc.global_param_op.Append();
|
||||
u16* idx=vd_rc.idx.Append(4);
|
||||
u32* idx = vd_rc.idx.Append(4);
|
||||
int vbase=vd_rc.verts.used();
|
||||
|
||||
idx[0]=vbase+0;
|
||||
|
|
|
@ -285,7 +285,7 @@ static void DrawList(const List<PolyParam>& gply, int first, int count, int pass
|
|||
}
|
||||
gl4ShaderUniforms.poly_number = params - gply.head();
|
||||
SetGPState<Type,SortingEnabled>(params, pass);
|
||||
glDrawElements(GL_TRIANGLE_STRIP, params->count, GL_UNSIGNED_SHORT, (GLvoid*)(2*params->first)); glCheck();
|
||||
glDrawElements(GL_TRIANGLE_STRIP, params->count, GL_UNSIGNED_INT, (GLvoid*)(sizeof(u32) * params->first)); glCheck();
|
||||
}
|
||||
|
||||
params++;
|
||||
|
|
|
@ -275,7 +275,7 @@ void DrawList(const List<PolyParam>& gply, int first, int count)
|
|||
if (params->count>2) //this actually happens for some games. No idea why ..
|
||||
{
|
||||
SetGPState<Type,SortingEnabled>(params);
|
||||
glDrawElements(GL_TRIANGLE_STRIP, params->count, GL_UNSIGNED_SHORT, (GLvoid*)(2*params->first)); glCheck();
|
||||
glDrawElements(GL_TRIANGLE_STRIP, params->count, GL_UNSIGNED_INT, (GLvoid*)(sizeof(u32) * params->first)); glCheck();
|
||||
}
|
||||
|
||||
params++;
|
||||
|
@ -296,7 +296,7 @@ void SortPParams(int first, int count)
|
|||
return;
|
||||
|
||||
Vertex* vtx_base=pvrrc.verts.head();
|
||||
u16* idx_base=pvrrc.idx.head();
|
||||
u32* idx_base = pvrrc.idx.head();
|
||||
|
||||
PolyParam* pp = &pvrrc.global_param_tr.head()[first];
|
||||
PolyParam* pp_end = pp + count;
|
||||
|
@ -309,7 +309,7 @@ void SortPParams(int first, int count)
|
|||
}
|
||||
else
|
||||
{
|
||||
u16* idx=idx_base+pp->first;
|
||||
u32* idx = idx_base + pp->first;
|
||||
|
||||
Vertex* vtx=vtx_base+idx[0];
|
||||
Vertex* vtx_end=vtx_base + idx[pp->count-1]+1;
|
||||
|
@ -334,7 +334,7 @@ Vertex* vtx_sort_base;
|
|||
|
||||
struct IndexTrig
|
||||
{
|
||||
u16 id[3];
|
||||
u32 id[3];
|
||||
u16 pid;
|
||||
f32 z;
|
||||
};
|
||||
|
@ -343,8 +343,8 @@ struct IndexTrig
|
|||
struct SortTrigDrawParam
|
||||
{
|
||||
PolyParam* ppid;
|
||||
u16 first;
|
||||
u16 count;
|
||||
u32 first;
|
||||
u32 count;
|
||||
};
|
||||
|
||||
float min3(float v0,float v1,float v2)
|
||||
|
@ -358,7 +358,7 @@ float max3(float v0,float v1,float v2)
|
|||
}
|
||||
|
||||
|
||||
float minZ(Vertex* v,u16* mod)
|
||||
float minZ(Vertex* v, u32* mod)
|
||||
{
|
||||
return min(min(v[mod[0]].z,v[mod[1]].z),v[mod[2]].z);
|
||||
}
|
||||
|
@ -471,7 +471,7 @@ bool PP_EQ(PolyParam* pp0, PolyParam* pp1)
|
|||
|
||||
static vector<SortTrigDrawParam> pidx_sort;
|
||||
|
||||
void fill_id(u16* d, Vertex* v0, Vertex* v1, Vertex* v2, Vertex* vb)
|
||||
void fill_id(u32* d, Vertex* v0, Vertex* v1, Vertex* v2, Vertex* vb)
|
||||
{
|
||||
d[0]=v0-vb;
|
||||
d[1]=v1-vb;
|
||||
|
@ -488,7 +488,7 @@ void GenSorted(int first, int count)
|
|||
return;
|
||||
|
||||
Vertex* vtx_base=pvrrc.verts.head();
|
||||
u16* idx_base=pvrrc.idx.head();
|
||||
u32* idx_base = pvrrc.idx.head();
|
||||
|
||||
PolyParam* pp_base = &pvrrc.global_param_tr.head()[first];
|
||||
PolyParam* pp = pp_base;
|
||||
|
@ -524,7 +524,7 @@ void GenSorted(int first, int count)
|
|||
|
||||
if (pp->count>2)
|
||||
{
|
||||
u16* idx=idx_base+pp->first;
|
||||
u32* idx = idx_base + pp->first;
|
||||
|
||||
Vertex* vtx=vtx_base+idx[0];
|
||||
Vertex* vtx_end=vtx_base + idx[pp->count-1]-1;
|
||||
|
@ -694,7 +694,7 @@ void GenSorted(int first, int count)
|
|||
#endif
|
||||
|
||||
//re-assemble them into drawing commands
|
||||
static vector<u16> vidx_sort;
|
||||
static vector<u32> vidx_sort;
|
||||
|
||||
vidx_sort.resize(aused*3);
|
||||
|
||||
|
@ -703,7 +703,7 @@ void GenSorted(int first, int count)
|
|||
for (u32 i=0; i<aused; i++)
|
||||
{
|
||||
int pid=lst[i].pid;
|
||||
u16* midx=lst[i].id;
|
||||
u32* midx = lst[i].id;
|
||||
|
||||
vidx_sort[i*3 + 0]=midx[0];
|
||||
vidx_sort[i*3 + 1]=midx[1];
|
||||
|
@ -711,7 +711,7 @@ void GenSorted(int first, int count)
|
|||
|
||||
if (idx!=pid /* && !PP_EQ(&pp_base[pid],&pp_base[idx]) */ )
|
||||
{
|
||||
SortTrigDrawParam stdp={pp_base + pid, (u16)(i*3), 0};
|
||||
SortTrigDrawParam stdp = { pp_base + pid, i * 3, 0 };
|
||||
|
||||
if (idx!=-1)
|
||||
{
|
||||
|
@ -736,7 +736,7 @@ void GenSorted(int first, int count)
|
|||
{
|
||||
//Bind and upload sorted index buffer
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gl.vbo.idxs2); glCheck();
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER,vidx_sort.size()*2,&vidx_sort[0],GL_STREAM_DRAW);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, vidx_sort.size() * sizeof(u32), &vidx_sort[0], GL_STREAM_DRAW);
|
||||
|
||||
if (tess_gen) printf("Generated %.2fK Triangles !\n",tess_gen/1000.0);
|
||||
}
|
||||
|
@ -762,7 +762,7 @@ void DrawSorted(bool multipass)
|
|||
if (pidx_sort[p].count>2) //this actually happens for some games. No idea why ..
|
||||
{
|
||||
SetGPState<ListType_Translucent,true>(params);
|
||||
glDrawElements(GL_TRIANGLES, pidx_sort[p].count, GL_UNSIGNED_SHORT, (GLvoid*)(2*pidx_sort[p].first)); glCheck();
|
||||
glDrawElements(GL_TRIANGLES, pidx_sort[p].count, GL_UNSIGNED_INT, (GLvoid*)(sizeof(u32) * pidx_sort[p].first)); glCheck();
|
||||
|
||||
#if 0
|
||||
//Verify restriping -- only valid if no sort
|
||||
|
@ -806,7 +806,7 @@ void DrawSorted(bool multipass)
|
|||
|
||||
SetCull(params->isp.CullMode ^ gcflip);
|
||||
|
||||
glDrawElements(GL_TRIANGLES, pidx_sort[p].count, GL_UNSIGNED_SHORT, (GLvoid*)(2 * pidx_sort[p].first));
|
||||
glDrawElements(GL_TRIANGLES, pidx_sort[p].count, GL_UNSIGNED_INT, (GLvoid*)(sizeof(u32) * pidx_sort[p].first));
|
||||
}
|
||||
}
|
||||
glcache.StencilMask(0xFF);
|
||||
|
|
|
@ -837,7 +837,7 @@ struct softrend : Renderer
|
|||
void RenderParamList(List<PolyParam>* param_list, RECT* area) {
|
||||
|
||||
Vertex* verts = pvrrc.verts.head();
|
||||
u16* idx = pvrrc.idx.head();
|
||||
u32* idx = pvrrc.idx.head();
|
||||
|
||||
PolyParam* params = param_list->head();
|
||||
int param_count = param_list->used();
|
||||
|
@ -846,7 +846,7 @@ struct softrend : Renderer
|
|||
{
|
||||
int vertex_count = params[i].count - 2;
|
||||
|
||||
u16* poly_idx = &idx[params[i].first];
|
||||
u32* poly_idx = &idx[params[i].first];
|
||||
|
||||
for (int v = 0; v < vertex_count; v++) {
|
||||
////<alpha_blend, pp_UseAlpha, pp_Texture, pp_IgnoreTexA, pp_ShadInstr, pp_Offset >
|
||||
|
|
Loading…
Reference in New Issue