GL1 unified draw calls, 7

Changed "buffer" functions (vertex, single/mtex, color) to macros.
Macros eliminate the function call overhead, resulting in faster
execution times. Depending of the hardware, there might be a
performance increase of almost 10%.
This forced the buffer to be exposed as global.
Not worth doing this for 2D elements though.
This commit is contained in:
Jaime Moreira 2024-07-27 23:08:46 -04:00
parent 826f4816f6
commit 94c4bf2df7
7 changed files with 118 additions and 142 deletions

View file

@ -29,33 +29,20 @@
#include "header/local.h"
#define MAX_VERTICES 16384
#define MAX_INDICES (MAX_VERTICES * 4)
#define GLBUFFER_RESET vtx_ptr = idx_ptr = 0; gl_buf.vt = gl_buf.tx = gl_buf.cl = 0;
typedef struct // 832k aprox.
{
buffered_draw_t type;
glbuffer_t gl_buf; // our drawing buffer, used globally
GLfloat
vtx[MAX_VERTICES * 3], // vertexes
tex[MAX_TEXTURE_UNITS][MAX_VERTICES * 2], // texture coords
clr[MAX_VERTICES * 4]; // color components
GLushort
idx[MAX_INDICES], // indices
vtx_ptr, idx_ptr; // pointers for array positions
int texture[MAX_TEXTURE_UNITS];
int flags; // entity flags
float alpha;
} glbuffer_t;
glbuffer_t gl_buf;
GLuint vt, tx, cl; // indices for arrays in gl_buf
static GLushort vtx_ptr, idx_ptr; // pointers for array positions in gl_buf
extern void R_MYgluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);
void
R_ResetGLBuffer(void)
{
GLBUFFER_RESET
}
void
R_ApplyGLBuffer(void)
{
@ -64,7 +51,7 @@ R_ApplyGLBuffer(void)
qboolean texture, mtex, alpha, color, alias, texenv_set;
float fovy, dist;
if (gl_buf.vtx_ptr == 0 || gl_buf.idx_ptr == 0)
if (vtx_ptr == 0 || idx_ptr == 0)
{
return;
}
@ -224,7 +211,7 @@ R_ApplyGLBuffer(void)
}
// All set, we can finally draw
glDrawElements(GL_TRIANGLES, gl_buf.idx_ptr, GL_UNSIGNED_SHORT, gl_buf.idx);
glDrawElements(GL_TRIANGLES, idx_ptr, GL_UNSIGNED_SHORT, gl_buf.idx);
// ... and now, turn back everything as it was
if (color)
@ -277,7 +264,7 @@ R_ApplyGLBuffer(void)
}
}
gl_buf.vtx_ptr = gl_buf.idx_ptr = 0;
GLBUFFER_RESET
}
void
@ -304,46 +291,46 @@ R_Buffer2DQuad(GLfloat ul_vx, GLfloat ul_vy, GLfloat dr_vx, GLfloat dr_vy,
{
static const GLushort idx_max = MAX_INDICES - 7;
static const GLushort vtx_max = MAX_VERTICES - 5;
unsigned int i;
if (gl_buf.idx_ptr > idx_max || gl_buf.vtx_ptr > vtx_max)
if (idx_ptr > idx_max || vtx_ptr > vtx_max)
{
R_ApplyGLBuffer();
}
i = gl_buf.vtx_ptr * 2; // vertex index
// "Quad" = 2-triangle GL_TRIANGLE_FAN
gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr;
gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr+1;
gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr+2;
gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr;
gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr+2;
gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr+3;
gl_buf.idx[idx_ptr] = vtx_ptr;
gl_buf.idx[idx_ptr+1] = vtx_ptr+1;
gl_buf.idx[idx_ptr+2] = vtx_ptr+2;
gl_buf.idx[idx_ptr+3] = vtx_ptr;
gl_buf.idx[idx_ptr+4] = vtx_ptr+2;
gl_buf.idx[idx_ptr+5] = vtx_ptr+3;
idx_ptr += 6;
// up left corner coords
gl_buf.vtx[i] = ul_vx;
gl_buf.vtx[i+1] = ul_vy;
gl_buf.vtx[gl_buf.vt] = ul_vx;
gl_buf.vtx[gl_buf.vt+1] = ul_vy;
// up right
gl_buf.vtx[i+2] = dr_vx;
gl_buf.vtx[i+3] = ul_vy;
gl_buf.vtx[gl_buf.vt+2] = dr_vx;
gl_buf.vtx[gl_buf.vt+3] = ul_vy;
// down right
gl_buf.vtx[i+4] = dr_vx;
gl_buf.vtx[i+5] = dr_vy;
gl_buf.vtx[gl_buf.vt+4] = dr_vx;
gl_buf.vtx[gl_buf.vt+5] = dr_vy;
// and finally, down left
gl_buf.vtx[i+6] = ul_vx;
gl_buf.vtx[i+7] = dr_vy;
gl_buf.vtx[gl_buf.vt+6] = ul_vx;
gl_buf.vtx[gl_buf.vt+7] = dr_vy;
gl_buf.tex[0][i] = ul_tx;
gl_buf.tex[0][i+1] = ul_ty;
gl_buf.tex[0][i+2] = dr_tx;
gl_buf.tex[0][i+3] = ul_ty;
gl_buf.tex[0][i+4] = dr_tx;
gl_buf.tex[0][i+5] = dr_ty;
gl_buf.tex[0][i+6] = ul_tx;
gl_buf.tex[0][i+7] = dr_ty;
gl_buf.tex[0][gl_buf.tx] = ul_tx;
gl_buf.tex[0][gl_buf.tx+1] = ul_ty;
gl_buf.tex[0][gl_buf.tx+2] = dr_tx;
gl_buf.tex[0][gl_buf.tx+3] = ul_ty;
gl_buf.tex[0][gl_buf.tx+4] = dr_tx;
gl_buf.tex[0][gl_buf.tx+5] = dr_ty;
gl_buf.tex[0][gl_buf.tx+6] = ul_tx;
gl_buf.tex[0][gl_buf.tx+7] = dr_ty;
gl_buf.vtx_ptr += 4;
vtx_ptr += 4;
gl_buf.vt += 8;
gl_buf.tx += 8;
}
/*
@ -354,8 +341,8 @@ R_SetBufferIndices(GLenum type, GLuint vertices_num)
{
int i;
if ( gl_buf.vtx_ptr + vertices_num >= MAX_VERTICES ||
gl_buf.idx_ptr + ( (vertices_num - 2) * 3 ) >= MAX_INDICES )
if ( vtx_ptr + vertices_num >= MAX_VERTICES ||
idx_ptr + ( (vertices_num - 2) * 3 ) >= MAX_INDICES )
{
R_ApplyGLBuffer();
}
@ -365,9 +352,10 @@ R_SetBufferIndices(GLenum type, GLuint vertices_num)
case GL_TRIANGLE_FAN:
for (i = 0; i < vertices_num-2; i++)
{
gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr;
gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr+i+1;
gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr+i+2;
gl_buf.idx[idx_ptr] = vtx_ptr;
gl_buf.idx[idx_ptr+1] = vtx_ptr+i+1;
gl_buf.idx[idx_ptr+2] = vtx_ptr+i+2;
idx_ptr += 3;
}
break;
case GL_TRIANGLE_STRIP:
@ -375,16 +363,17 @@ R_SetBufferIndices(GLenum type, GLuint vertices_num)
{
if (i % 2 == 0)
{
gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr+i;
gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr+i+1;
gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr+i+2;
gl_buf.idx[idx_ptr] = vtx_ptr+i;
gl_buf.idx[idx_ptr+1] = vtx_ptr+i+1;
gl_buf.idx[idx_ptr+2] = vtx_ptr+i+2;
}
else // backwards order
{
gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr+i+2;
gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr+i+1;
gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr+i;
gl_buf.idx[idx_ptr] = vtx_ptr+i+2;
gl_buf.idx[idx_ptr+1] = vtx_ptr+i+1;
gl_buf.idx[idx_ptr+2] = vtx_ptr+i;
}
idx_ptr += 3;
}
break;
default:
@ -392,58 +381,6 @@ R_SetBufferIndices(GLenum type, GLuint vertices_num)
return;
}
// These affect the functions that follow in this file
vt = gl_buf.vtx_ptr * 3; // vertex index
tx = gl_buf.vtx_ptr * 2; // texcoord index
cl = gl_buf.vtx_ptr * 4; // color index
// R_BufferVertex() must be called as many times as vertices_num
gl_buf.vtx_ptr += vertices_num;
}
/*
* Adds a single vertex to buffer
*/
void
R_BufferVertex(GLfloat x, GLfloat y, GLfloat z)
{
gl_buf.vtx[vt++] = x;
gl_buf.vtx[vt++] = y;
gl_buf.vtx[vt++] = z;
}
/*
* Adds texture coordinates for color texture (no lightmap coords)
*/
void
R_BufferSingleTex(GLfloat s, GLfloat t)
{
// tx should be set before this is called, by R_SetBufferIndices
gl_buf.tex[0][tx++] = s;
gl_buf.tex[0][tx++] = t;
}
/*
* Adds texture coordinates for color and lightmap
*/
void
R_BufferMultiTex(GLfloat cs, GLfloat ct, GLfloat ls, GLfloat lt)
{
gl_buf.tex[0][tx] = cs;
gl_buf.tex[0][tx+1] = ct;
gl_buf.tex[1][tx] = ls;
gl_buf.tex[1][tx+1] = lt;
tx += 2;
}
/*
* Adds color components of vertex
*/
void
R_BufferColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a)
{
gl_buf.clr[cl++] = r;
gl_buf.clr[cl++] = g;
gl_buf.clr[cl++] = b;
gl_buf.clr[cl++] = a;
// GLBUFFER_VERTEX() must be called as many times as vertices_num
vtx_ptr += vertices_num;
}

View file

@ -46,9 +46,9 @@ R_RenderDlight(dlight_t *light)
vtx [ i ] = light->origin [ i ] - vpn [ i ] * rad;
}
R_BufferVertex( vtx[0], vtx[1], vtx[2] );
R_BufferColor( light->color[0] * 0.2, light->color[1] * 0.2,
light->color[2] * 0.2, 1 );
GLBUFFER_VERTEX( vtx[0], vtx[1], vtx[2] )
GLBUFFER_COLOR( light->color[0] * 0.2, light->color[1] * 0.2,
light->color[2] * 0.2, 1 )
for ( i = 16; i >= 0; i-- )
{
@ -60,8 +60,8 @@ R_RenderDlight(dlight_t *light)
+ vup [ j ] * sin( a ) * rad;
}
R_BufferVertex( vtx[0], vtx[1], vtx[2] );
R_BufferColor( 0, 0, 0, 1 );
GLBUFFER_VERTEX( vtx[0], vtx[1], vtx[2] )
GLBUFFER_COLOR( 0, 0, 0, 1 )
}
}

View file

@ -148,6 +148,8 @@ void LM_FreeLightmapBuffers(void);
void Scrap_Free(void);
void Scrap_Init(void);
extern void R_ResetGLBuffer(void);
void
R_RotateForEntity(entity_t *e)
{
@ -1641,6 +1643,7 @@ RI_Init(void)
Mod_Init();
R_InitParticleTexture();
Draw_InitLocal();
R_ResetGLBuffer();
return true;
}

View file

@ -169,11 +169,11 @@ R_DrawAliasFrameLerp(entity_t *currententity, dmdl_t *paliashdr, float backlerp)
index_xyz = order[2];
order += 3;
R_BufferVertex(s_lerped[index_xyz][0],
s_lerped[index_xyz][1], s_lerped[index_xyz][2]);
GLBUFFER_VERTEX(s_lerped[index_xyz][0],
s_lerped[index_xyz][1], s_lerped[index_xyz][2])
R_BufferColor(shadelight[0], shadelight[1],
shadelight[2], alpha);
GLBUFFER_COLOR(shadelight[0], shadelight[1],
shadelight[2], alpha)
}
while (--count);
}
@ -191,13 +191,13 @@ R_DrawAliasFrameLerp(entity_t *currententity, dmdl_t *paliashdr, float backlerp)
/* normals and vertexes come from the frame list */
l = shadedots[verts[index_xyz].lightnormalindex];
R_BufferVertex(s_lerped[index_xyz][0],
s_lerped[index_xyz][1], s_lerped[index_xyz][2]);
GLBUFFER_VERTEX(s_lerped[index_xyz][0],
s_lerped[index_xyz][1], s_lerped[index_xyz][2])
R_BufferSingleTex(tex[0], tex[1]);
GLBUFFER_SINGLETEX(tex[0], tex[1])
R_BufferColor(l * shadelight[0], l * shadelight[1],
l * shadelight[2], alpha);
GLBUFFER_COLOR(l * shadelight[0], l * shadelight[1],
l * shadelight[2], alpha)
}
while (--count);
}
@ -255,7 +255,7 @@ R_DrawAliasShadow(entity_t *currententity, dmdl_t *paliashdr, int posenum)
point[1] -= shadevector[1] * (point[2] + lheight);
point[2] = height;
R_BufferVertex( point[0], point[1], point[2] );
GLBUFFER_VERTEX( point[0], point[1], point[2] )
order += 3;
}

View file

@ -69,8 +69,8 @@ R_DrawGLPoly(msurface_t *fa)
for ( i = 0; i < nv; i++, v += VERTEXSIZE )
{
R_BufferVertex(v[0], v[1], v[2]);
R_BufferSingleTex(v[3] + scroll, v[4]);
GLBUFFER_VERTEX( v[0], v[1], v[2] )
GLBUFFER_SINGLETEX( v[3] + scroll, v[4] )
}
}
@ -594,8 +594,8 @@ R_RenderLightmappedPoly(entity_t *currententity, msurface_t *surf)
for (i = 0; i < nv; i++, v += VERTEXSIZE)
{
R_BufferVertex( v[0], v[1], v[2] );
R_BufferMultiTex( v[3] + scroll, v[4], v[5], v[6] );
GLBUFFER_VERTEX( v[0], v[1], v[2] )
GLBUFFER_MULTITEX( v[3] + scroll, v[4], v[5], v[6] )
}
}

View file

@ -310,8 +310,8 @@ R_EmitWaterPolys(msurface_t *fa)
s = os + r_turbsin [ (int) ( ( ot * 0.125 + rdt ) * TURBSCALE ) & 255 ] + scroll;
t = ot + r_turbsin [ (int) ( ( os * 0.125 + rdt ) * TURBSCALE ) & 255 ];
R_BufferVertex( v[0], v[1], v[2] );
R_BufferSingleTex( s * ( 1.0 / 64 ), t * ( 1.0 / 64 ) );
GLBUFFER_VERTEX( v[0], v[1], v[2] )
GLBUFFER_SINGLETEX( s * ( 1.0 / 64 ), t * ( 1.0 / 64 ) )
}
}
}

View file

@ -53,6 +53,10 @@
#define MAX_TEXTURE_UNITS 2
#define GL_LIGHTMAP_FORMAT GL_RGBA
// GL buffer definitions
#define MAX_VERTICES 16384
#define MAX_INDICES (MAX_VERTICES * 4)
/* up / down */
#define PITCH 0
@ -118,10 +122,29 @@ typedef enum
buf_shadow
} buffered_draw_t;
typedef struct // 832k aprox.
{
buffered_draw_t type;
GLfloat
vtx[MAX_VERTICES * 3], // vertexes
tex[MAX_TEXTURE_UNITS][MAX_VERTICES * 2], // texture coords
clr[MAX_VERTICES * 4]; // color components
GLushort idx[MAX_INDICES]; // indices for the draw call
GLuint vt, tx, cl; // indices for GLfloat arrays above
int texture[MAX_TEXTURE_UNITS];
int flags; // entity flags
float alpha;
} glbuffer_t;
#include "model.h"
void R_SetDefaultState(void);
extern glbuffer_t gl_buf;
extern float gldepthmin, gldepthmax;
extern image_t gltextures[MAX_GLTEXTURES];
@ -291,15 +314,28 @@ void R_TextureAlphaMode(char *string);
void R_TextureSolidMode(char *string);
int Scrap_AllocBlock(int w, int h, int *x, int *y);
// GL buffer operations
#define GLBUFFER_VERTEX(X, Y, Z) \
gl_buf.vtx[gl_buf.vt] = X; gl_buf.vtx[gl_buf.vt+1] = Y; \
gl_buf.vtx[gl_buf.vt+2] = Z; gl_buf.vt += 3;
#define GLBUFFER_SINGLETEX(S, T) \
gl_buf.tex[0][gl_buf.tx] = S; gl_buf.tex[0][gl_buf.tx+1] = T; gl_buf.tx += 2;
#define GLBUFFER_MULTITEX(CS, CT, LS, LT) \
gl_buf.tex[0][gl_buf.tx] = CS; gl_buf.tex[0][gl_buf.tx+1] = CT; \
gl_buf.tex[1][gl_buf.tx] = LS; gl_buf.tex[1][gl_buf.tx+1] = LT; gl_buf.tx += 2;
#define GLBUFFER_COLOR(R, G, B, A) \
gl_buf.clr[gl_buf.cl] = R; gl_buf.clr[gl_buf.cl+1] = G; \
gl_buf.clr[gl_buf.cl+2] = B; gl_buf.clr[gl_buf.cl+3] = A; gl_buf.cl += 4;
void R_ApplyGLBuffer(void);
void R_UpdateGLBuffer(buffered_draw_t type, int colortex, int lighttex, int flags, float alpha);
void R_Buffer2DQuad(GLfloat ul_vx, GLfloat ul_vy, GLfloat dr_vx, GLfloat dr_vy,
GLfloat ul_tx, GLfloat ul_ty, GLfloat dr_tx, GLfloat dr_ty);
void R_SetBufferIndices(GLenum type, GLuint vertices_num);
void R_BufferVertex(GLfloat x, GLfloat y, GLfloat z);
void R_BufferSingleTex(GLfloat s, GLfloat t);
void R_BufferMultiTex(GLfloat cs, GLfloat ct, GLfloat ls, GLfloat lt);
void R_BufferColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
#ifdef DEBUG
void glCheckError_(const char *file, const char *function, int line);