Skip to content

Commit 4a6c36a

Browse files
committed
Use VAOs to switch most vertex formats
Faster since all of the required VAOs are prerecorded into each `VBO_t`. The exceptions are the default VAO, which switches its vertex arrays on/off, and md3 VAOs, because they require respecifying vertex attributes when animation frames change.
1 parent 31905f4 commit 4a6c36a

14 files changed

+108
-13
lines changed

src/engine/renderer/GLMemory.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4343
#endif
4444
#include <GL/glew.h>
4545

46-
#include "tr_local.h"
4746
#include "BufferBind.h"
4847
#include "GLUtils.h"
4948
#include "VertexSpecification.h"
@@ -224,14 +223,14 @@ class GLVAO {
224223
vboAttributeLayout_t attrs[ATTR_INDEX_MAX];
225224
uint32_t enabledAttrs;
226225

227-
GLVAO( const GLuint newVBOBindingPoint ) :
226+
GLVAO( const GLuint newVBOBindingPoint = 0 ) :
228227
VBOBindingPoint( newVBOBindingPoint ) {
229228
}
230229

231230
~GLVAO() = default;
232231

233232
void Bind() {
234-
glBindVertexArray( id );
233+
GL_BindVAO( id );
235234
}
236235

237236
void SetAttrs( const vertexAttributeSpec_t* attrBegin, const vertexAttributeSpec_t* attrEnd ) {
@@ -276,6 +275,11 @@ class GLVAO {
276275
glVertexArrayElementBuffer( id, buffer.id );
277276
}
278277

278+
// For compatibility with IBO_t
279+
void SetIndexBuffer( const GLuint bufferID ) {
280+
glVertexArrayElementBuffer( id, bufferID );
281+
}
282+
279283
void GenVAO() {
280284
glGenVertexArrays( 1, &id );
281285
}
@@ -286,7 +290,7 @@ class GLVAO {
286290

287291
private:
288292
GLuint id;
289-
const GLuint VBOBindingPoint;
293+
GLuint VBOBindingPoint;
290294
GLuint stride;
291295
};
292296

src/engine/renderer/GLUtils.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ extern glconfig2_t glConfig2;
3636

3737
void GL_CheckErrors_( const char *filename, int line );
3838

39+
void GL_BindVAO( const GLuint id );
40+
3941
#define GL_CheckErrors() do { if ( !glConfig.smpActive ) GL_CheckErrors_( __FILE__, __LINE__ ); } while ( false )
4042

4143
#endif // GLUTILS_H

src/engine/renderer/GeometryCache.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,5 +92,5 @@ void GeometryCache::AddMapGeometry( const uint32_t verticesNumber, const uint32_
9292

9393
stagingBuffer.FlushAll();
9494

95-
glBindVertexArray( backEnd.currentVAO );
95+
GL_BindVAO( backEnd.defaultVAO );
9696
}

src/engine/renderer/Material.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1887,7 +1887,7 @@ void MaterialSystem::RenderMaterials( const shaderSort_t fromSort, const shaderS
18871887
}
18881888
}
18891889

1890-
glBindVertexArray( backEnd.currentVAO );
1890+
GL_BindVAO( backEnd.defaultVAO );
18911891

18921892
// Draw the skybox here because we skipped R_AddWorldSurfaces()
18931893
const bool environmentFogDraw = ( fromSort <= shaderSort_t::SS_ENVIRONMENT_FOG ) && ( toSort >= shaderSort_t::SS_ENVIRONMENT_FOG );

src/engine/renderer/VBO.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2828
#include "common/Common.h"
2929
#include "GL/glew.h"
3030

31+
#include "GLMemory.h"
3132
#include "VertexSpecification.h"
3233
#include "tr_types.h"
3334

@@ -47,6 +48,9 @@ struct VBO_t
4748
vboLayout_t layout;
4849
uint32_t attribBits; // Which attributes it has. Mostly for detecting errors
4950
GLenum usage;
51+
52+
GLVAO VAO;
53+
bool dynamicVAO = false;
5054
};
5155

5256
struct IBO_t
@@ -67,6 +71,9 @@ VBO_t* R_CreateStaticVBO(
6771

6872
IBO_t* R_CreateStaticIBO( const char* name, glIndex_t* indexes, int numIndexes );
6973

74+
void SetupVAOBuffers( VBO_t* VBO, const IBO_t* IBO, const uint32_t stateBits,
75+
GLVAO* VAO );
76+
7077
void R_BindVBO( VBO_t* vbo );
7178
void R_BindNullVBO();
7279

src/engine/renderer/tr_backend.cpp

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,13 @@ void GL_BindNullProgram()
144144
}
145145
}
146146

147+
void GL_BindVAO( const GLuint id ) {
148+
if ( backEnd.currentVAO != id ) {
149+
glBindVertexArray( id );
150+
backEnd.currentVAO = id;
151+
}
152+
}
153+
147154
void GL_SelectTexture( int unit )
148155
{
149156
if ( glState.currenttmu == unit )
@@ -613,14 +620,27 @@ void GL_VertexAttribsState( uint32_t stateBits )
613620
uint32_t diff;
614621
uint32_t i;
615622

623+
if ( !tess.settingUpVAO && glState.currentVBO && !glState.currentVBO->dynamicVAO ) {
624+
glState.currentVBO->VAO.Bind();
625+
return;
626+
}
627+
616628
if ( glConfig2.vboVertexSkinningAvailable && tess.vboVertexSkinning )
617629
{
618630
stateBits |= ATTR_BONE_FACTORS;
619631
}
620632

621633
GL_VertexAttribPointers( stateBits );
622634

623-
diff = stateBits ^ glState.vertexAttribsState;
635+
if ( !tess.settingUpVAO && backEnd.currentVAO != backEnd.defaultVAO ) {
636+
return;
637+
}
638+
639+
diff = stateBits;
640+
641+
if ( backEnd.currentVAO == backEnd.defaultVAO ) {
642+
diff ^= glState.vertexAttribsState;
643+
}
624644

625645
if ( !diff )
626646
{
@@ -648,7 +668,9 @@ void GL_VertexAttribsState( uint32_t stateBits )
648668
}
649669
}
650670

651-
glState.vertexAttribsState = stateBits;
671+
if ( backEnd.currentVAO == backEnd.defaultVAO ) {
672+
glState.vertexAttribsState = stateBits;
673+
}
652674
}
653675

654676
void GL_VertexAttribPointers( uint32_t attribBits )
@@ -680,7 +702,7 @@ void GL_VertexAttribPointers( uint32_t attribBits )
680702
if ( ( attribBits & bit ) != 0 &&
681703
( !( glState.vertexAttribPointersSet & bit ) ||
682704
tess.vboVertexAnimation ||
683-
glState.currentVBO == tess.vbo ) )
705+
glState.currentVBO == tess.vbo || tess.settingUpVAO || glState.currentVBO->dynamicVAO ) )
684706
{
685707
const vboAttributeLayout_t *layout = &glState.currentVBO->attribs[ i ];
686708

src/engine/renderer/tr_bsp.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -851,6 +851,11 @@ static void FinishSkybox() {
851851
3, 4, 7, 3, 0, 4 }; // Back
852852

853853
surface->ibo = R_CreateStaticIBO( "skybox_IBO", indexes, surface->numTriangles * 3 );
854+
855+
SetupVAOBuffers( surface->vbo, surface->ibo,
856+
ATTR_POSITION,
857+
&surface->vbo->VAO );
858+
854859
skybox->surface = ( surfaceType_t* ) surface;
855860

856861
tr.skybox = skybox;
@@ -2770,6 +2775,11 @@ static void R_CreateWorldVBO() {
27702775
"staticWorld_VBO", std::begin( attrs ), std::end( attrs ), numVerts );
27712776
s_worldData.ibo = R_CreateStaticIBO( "staticWorld_IBO", vboIdxs, numTriangles * 3 );
27722777

2778+
SetupVAOBuffers( s_worldData.vbo, s_worldData.ibo,
2779+
ATTR_POSITION | ATTR_COLOR
2780+
| ATTR_QTANGENT | ATTR_TEXCOORD,
2781+
&s_worldData.vbo->VAO );
2782+
27732783
ri.Hunk_FreeTempMemory( vboIdxs );
27742784
ri.Hunk_FreeTempMemory( vboVerts );
27752785

src/engine/renderer/tr_init.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -374,8 +374,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
374374
}
375375

376376
if ( glConfig2.glCoreProfile ) {
377-
glGenVertexArrays( 1, &backEnd.currentVAO );
378-
glBindVertexArray( backEnd.currentVAO );
377+
glGenVertexArrays( 1, &backEnd.defaultVAO );
378+
GL_BindVAO( backEnd.defaultVAO );
379379
}
380380

381381
GL_CheckErrors();
@@ -1473,7 +1473,7 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p
14731473
GLSL_ShutdownGPUShaders();
14741474
if( glConfig2.glCoreProfile ) {
14751475
glBindVertexArray( 0 );
1476-
glDeleteVertexArrays( 1, &backEnd.currentVAO );
1476+
glDeleteVertexArrays( 1, &backEnd.defaultVAO );
14771477
}
14781478

14791479
GLimp_Shutdown();

src/engine/renderer/tr_local.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2200,7 +2200,8 @@ enum
22002200
Color::Color32Bit color2D;
22012201
trRefEntity_t entity2D; // currentEntity will point at this when doing 2D rendering
22022202
int currentMainFBO;
2203-
GLuint currentVAO;
2203+
GLuint currentVAO;
2204+
GLuint defaultVAO;
22042205
};
22052206

22062207
struct visTest_t
@@ -3125,6 +3126,8 @@ void GLimp_LogComment_( std::string comment );
31253126
// enabled when an MD3 VBO is used
31263127
bool vboVertexAnimation;
31273128

3129+
bool settingUpVAO = false;
3130+
31283131
// This can be thought of a "flush" function for the vertex buffer.
31293132
// Which function depends on backend mode and also the shader.
31303133
void ( *stageIteratorFunc )();

src/engine/renderer/tr_model_iqm.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,11 @@ bool R_LoadIQModel( model_t *mod, const void *buffer, int filesize,
858858
// create IBO
859859
ibo = R_CreateStaticIBO( ( "IQM surface IBO " + name ).c_str(),
860860
( glIndex_t* )IQModel->triangles, IQModel->num_triangles * 3 );
861+
862+
SetupVAOBuffers( vbo, ibo,
863+
ATTR_BONE_FACTORS | ATTR_POSITION | ATTR_QTANGENT | ATTR_TEXCOORD
864+
| ATTR_COLOR,
865+
&vbo->VAO );
861866
} else {
862867
vbo = nullptr;
863868
ibo = nullptr;

0 commit comments

Comments
 (0)