mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2024-11-29 15:51:45 +00:00
MSVC: Don't use YQ2_VLA() in loops
because on MSVC it uses alloca() (or _malloca()) which mustn't be called in loops, as the memory is only freed when returning from the function, not when leaving the scope (or before the next loop iteration). Instead do one "dry-run" iteration to figure out how big the array must be at most, and then allocate it once before the loop with that size.
This commit is contained in:
parent
34a8c3833f
commit
4a02c790e9
3 changed files with 91 additions and 15 deletions
|
@ -154,6 +154,29 @@ R_DrawAliasFrameLerp(entity_t *currententity, dmdl_t *paliashdr, float backlerp)
|
|||
|
||||
R_LerpVerts(currententity, paliashdr->num_xyz, v, ov, verts, lerp, move, frontv, backv);
|
||||
|
||||
#ifdef _MSC_VER // workaround for lack of VLAs (=> our workaround uses alloca() which is bad in loops)
|
||||
int maxCount = 0;
|
||||
const int* tmpOrder = order;
|
||||
while (1)
|
||||
{
|
||||
int c = *tmpOrder++;
|
||||
if (!c)
|
||||
break;
|
||||
if ( c < 0 )
|
||||
c = -c;
|
||||
if ( c > maxCount )
|
||||
maxCount = c;
|
||||
|
||||
do {
|
||||
tmpOrder += 3;
|
||||
} while (--c);
|
||||
}
|
||||
|
||||
YQ2_VLA( GLfloat, vtx, 3 * maxCount );
|
||||
YQ2_VLA( GLfloat, tex, 2 * maxCount );
|
||||
YQ2_VLA( GLfloat, clr, 4 * maxCount );
|
||||
#endif
|
||||
|
||||
while (1)
|
||||
{
|
||||
/* get the vertex count and primitive type */
|
||||
|
@ -176,9 +199,12 @@ R_DrawAliasFrameLerp(entity_t *currententity, dmdl_t *paliashdr, float backlerp)
|
|||
}
|
||||
|
||||
total = count;
|
||||
YQ2_VLA(GLfloat, vtx, 3*total); // FIXME: alloca in loop is bad!
|
||||
|
||||
#ifndef _MSC_VER // we have real VLAs, so it's safe to use one in this loop
|
||||
YQ2_VLA(GLfloat, vtx, 3*total);
|
||||
YQ2_VLA(GLfloat, tex, 2*total);
|
||||
YQ2_VLA(GLfloat, clr, 4*total);
|
||||
#endif
|
||||
unsigned int index_vtx = 0;
|
||||
unsigned int index_tex = 0;
|
||||
unsigned int index_clr = 0;
|
||||
|
@ -240,12 +266,12 @@ R_DrawAliasFrameLerp(entity_t *currententity, dmdl_t *paliashdr, float backlerp)
|
|||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
|
||||
YQ2_VLAFREE(vtx);
|
||||
YQ2_VLAFREE(tex);
|
||||
YQ2_VLAFREE(clr)
|
||||
}
|
||||
|
||||
YQ2_VLAFREE( vtx );
|
||||
YQ2_VLAFREE( tex );
|
||||
YQ2_VLAFREE( clr )
|
||||
|
||||
if (currententity->flags &
|
||||
(RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE |
|
||||
RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM))
|
||||
|
@ -276,6 +302,27 @@ R_DrawAliasShadow(entity_t *currententity, dmdl_t *paliashdr, int posenum)
|
|||
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER // workaround for lack of VLAs (=> our workaround uses alloca() which is bad in loops)
|
||||
int maxCount = 0;
|
||||
const int* tmpOrder = order;
|
||||
while (1)
|
||||
{
|
||||
int c = *tmpOrder++;
|
||||
if (!c)
|
||||
break;
|
||||
if (c < 0)
|
||||
c = -c;
|
||||
if (c > maxCount)
|
||||
maxCount = c;
|
||||
|
||||
do {
|
||||
tmpOrder += 3;
|
||||
} while (--c);
|
||||
}
|
||||
|
||||
YQ2_VLA(GLfloat, vtx, 3 * maxCount);
|
||||
#endif
|
||||
|
||||
while (1)
|
||||
{
|
||||
/* get the vertex count and primitive type */
|
||||
|
@ -299,7 +346,9 @@ R_DrawAliasShadow(entity_t *currententity, dmdl_t *paliashdr, int posenum)
|
|||
|
||||
total = count;
|
||||
|
||||
YQ2_VLA(GLfloat, vtx, 3*total); // FIXME: alloca in loop is bad!
|
||||
#ifndef _MSC_VER // we have real VLAs, so it's safe to use one in this loop
|
||||
YQ2_VLA(GLfloat, vtx, 3*total);
|
||||
#endif
|
||||
unsigned int index_vtx = 0;
|
||||
|
||||
do
|
||||
|
@ -325,8 +374,8 @@ R_DrawAliasShadow(entity_t *currententity, dmdl_t *paliashdr, int posenum)
|
|||
glDrawArrays( type, 0, total );
|
||||
|
||||
glDisableClientState( GL_VERTEX_ARRAY );
|
||||
YQ2_VLAFREE(vtx);
|
||||
}
|
||||
YQ2_VLAFREE(vtx);
|
||||
|
||||
/* stencilbuffer shadows */
|
||||
if (gl_state.stencil && gl1_stencilshadow->value)
|
||||
|
|
|
@ -205,14 +205,28 @@ R_DrawGLPolyChain(glpoly_t *p, float soffset, float toffset)
|
|||
}
|
||||
else
|
||||
{
|
||||
// workaround for lack of VLAs (=> our workaround uses alloca() which is bad in loops)
|
||||
#ifdef _MSC_VER
|
||||
int maxNumVerts = 0;
|
||||
for (glpoly_t* tmp = p; tmp; tmp = tmp->chain)
|
||||
{
|
||||
if ( tmp->numverts > maxNumVerts )
|
||||
maxNumVerts = tmp->numverts;
|
||||
}
|
||||
|
||||
YQ2_VLA( GLfloat, tex, 2 * maxNumVerts );
|
||||
#endif
|
||||
|
||||
for ( ; p != 0; p = p->chain)
|
||||
{
|
||||
float *v;
|
||||
int j;
|
||||
|
||||
v = p->verts[0];
|
||||
#ifndef _MSC_VER // we have real VLAs, so it's safe to use one in this loop
|
||||
YQ2_VLA(GLfloat, tex, 2*p->numverts);
|
||||
#endif
|
||||
|
||||
YQ2_VLA(GLfloat, tex, 2*p->numverts); // FIXME: alloca in loop is bad!
|
||||
unsigned int index_tex = 0;
|
||||
|
||||
for ( j = 0; j < p->numverts; j++, v += VERTEXSIZE )
|
||||
|
@ -232,9 +246,9 @@ R_DrawGLPolyChain(glpoly_t *p, float soffset, float toffset)
|
|||
|
||||
glDisableClientState( GL_VERTEX_ARRAY );
|
||||
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
|
||||
YQ2_VLAFREE(tex);
|
||||
}
|
||||
|
||||
YQ2_VLAFREE( tex );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -297,11 +297,24 @@ R_EmitWaterPolys(msurface_t *fa)
|
|||
scroll = 0;
|
||||
}
|
||||
|
||||
// workaround for lack of VLAs (=> our workaround uses alloca() which is bad in loops)
|
||||
#ifdef _MSC_VER
|
||||
int maxNumVerts = 0;
|
||||
for ( glpoly_t* tmp = fa->polys; tmp; tmp = tmp->next )
|
||||
{
|
||||
if (tmp->numverts > maxNumVerts)
|
||||
maxNumVerts = tmp->numverts;
|
||||
}
|
||||
|
||||
YQ2_VLA( GLfloat, tex, 2 * maxNumVerts );
|
||||
#endif
|
||||
|
||||
for (bp = fa->polys; bp; bp = bp->next)
|
||||
{
|
||||
p = bp;
|
||||
|
||||
YQ2_VLA(GLfloat, tex, 2*p->numverts); // FIXME: alloca in loop is bad!
|
||||
#ifndef _MSC_VER // we have real VLAs, so it's safe to use one in this loop
|
||||
YQ2_VLA(GLfloat, tex, 2*p->numverts);
|
||||
#endif
|
||||
unsigned int index_tex = 0;
|
||||
|
||||
for ( i = 0, v = p->verts [ 0 ]; i < p->numverts; i++, v += VERTEXSIZE )
|
||||
|
@ -328,9 +341,9 @@ R_EmitWaterPolys(msurface_t *fa)
|
|||
|
||||
glDisableClientState( GL_VERTEX_ARRAY );
|
||||
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
|
||||
YQ2_VLAFREE(tex);
|
||||
}
|
||||
|
||||
YQ2_VLAFREE( tex );
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in a new issue