Skip to content

Commit 06bfb33

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 1f5cfef commit 06bfb33

14 files changed

+108
-12
lines changed

src/engine/renderer/GLMemory.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -219,14 +219,14 @@ class GLVAO {
219219
vboAttributeLayout_t attrs[ATTR_INDEX_MAX];
220220
uint32_t enabledAttrs;
221221

222-
GLVAO( const GLuint newVBOBindingPoint ) :
222+
GLVAO( const GLuint newVBOBindingPoint = 0 ) :
223223
VBOBindingPoint( newVBOBindingPoint ) {
224224
}
225225

226226
~GLVAO() = default;
227227

228228
void Bind() {
229-
glBindVertexArray( id );
229+
GL_BindVAO( id );
230230
}
231231

232232
void SetAttrs( const vertexAttributeSpec_t* attrBegin, const vertexAttributeSpec_t* attrEnd ) {
@@ -271,6 +271,11 @@ class GLVAO {
271271
glVertexArrayElementBuffer( id, buffer.id );
272272
}
273273

274+
// For compatibility with IBO_t
275+
void SetIndexBuffer( const GLuint bufferID ) {
276+
glVertexArrayElementBuffer( id, bufferID );
277+
}
278+
274279
void GenVAO() {
275280
glGenVertexArrays( 1, &id );
276281
}
@@ -281,7 +286,7 @@ class GLVAO {
281286

282287
private:
283288
GLuint id;
284-
const GLuint VBOBindingPoint;
289+
GLuint VBOBindingPoint;
285290
GLuint stride;
286291
};
287292

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
@@ -1897,7 +1897,7 @@ void MaterialSystem::RenderMaterials( const shaderSort_t fromSort, const shaderS
18971897
}
18981898
}
18991899

1900-
glBindVertexArray( backEnd.currentVAO );
1900+
GL_BindVAO( backEnd.defaultVAO );
19011901

19021902
// Draw the skybox here because we skipped R_AddWorldSurfaces()
19031903
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
@@ -815,6 +815,11 @@ static void FinishSkybox() {
815815
3, 4, 7, 3, 0, 4 }; // Back
816816

817817
surface->ibo = R_CreateStaticIBO( "skybox_IBO", indexes, surface->numTriangles * 3 );
818+
819+
SetupVAOBuffers( surface->vbo, surface->ibo,
820+
ATTR_POSITION,
821+
&surface->vbo->VAO );
822+
818823
skybox->surface = ( surfaceType_t* ) surface;
819824

820825
tr.skybox = skybox;
@@ -2735,6 +2740,11 @@ static void R_CreateWorldVBO() {
27352740
"staticWorld_VBO", std::begin( attrs ), std::end( attrs ), numVerts );
27362741
s_worldData.ibo = R_CreateStaticIBO( "staticWorld_IBO", vboIdxs, numTriangles * 3 );
27372742

2743+
SetupVAOBuffers( s_worldData.vbo, s_worldData.ibo,
2744+
ATTR_POSITION | ATTR_COLOR
2745+
| ATTR_QTANGENT | ATTR_TEXCOORD,
2746+
&s_worldData.vbo->VAO );
2747+
27382748
ri.Hunk_FreeTempMemory( vboIdxs );
27392749
ri.Hunk_FreeTempMemory( vboVerts );
27402750

src/engine/renderer/tr_init.cpp

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

375375
if ( glConfig2.glCoreProfile ) {
376-
glGenVertexArrays( 1, &backEnd.currentVAO );
377-
glBindVertexArray( backEnd.currentVAO );
376+
glGenVertexArrays( 1, &backEnd.defaultVAO );
377+
GL_BindVAO( backEnd.defaultVAO );
378378
}
379379

380380
GL_CheckErrors();
@@ -1485,7 +1485,7 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p
14851485
GLSL_ShutdownGPUShaders();
14861486
if( glConfig2.glCoreProfile ) {
14871487
glBindVertexArray( 0 );
1488-
glDeleteVertexArrays( 1, &backEnd.currentVAO );
1488+
glDeleteVertexArrays( 1, &backEnd.defaultVAO );
14891489
}
14901490

14911491
GLimp_Shutdown();

src/engine/renderer/tr_local.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2190,7 +2190,8 @@ enum class ssaoMode {
21902190
Color::Color32Bit color2D;
21912191
trRefEntity_t entity2D; // currentEntity will point at this when doing 2D rendering
21922192
int currentMainFBO;
2193-
GLuint currentVAO;
2193+
GLuint currentVAO;
2194+
GLuint defaultVAO;
21942195
};
21952196

21962197
struct visTest_t
@@ -3108,6 +3109,8 @@ void GLimp_LogComment_( std::string comment );
31083109
// enabled when an MD3 VBO is used
31093110
bool vboVertexAnimation;
31103111

3112+
bool settingUpVAO = false;
3113+
31113114
// This can be thought of a "flush" function for the vertex buffer.
31123115
// Which function depends on backend mode and also the shader.
31133116
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)