Optimise state management

This commit is contained in:
Luke Benstead 2023-03-17 20:40:45 +00:00
parent e810d2567d
commit 300f2a611e
3 changed files with 160 additions and 59 deletions

View File

@ -525,6 +525,7 @@ GLboolean _glNearZClippingEnabled();
GLboolean _glGPUStateIsDirty(); GLboolean _glGPUStateIsDirty();
void _glGPUStateMarkClean(); void _glGPUStateMarkClean();
void _glGPUStateMarkDirty();
#define MAX_GLDC_TEXTURE_UNITS 2 #define MAX_GLDC_TEXTURE_UNITS 2
#define MAX_GLDC_LIGHTS 8 #define MAX_GLDC_LIGHTS 8

View File

@ -90,6 +90,10 @@ void _glGPUStateMarkClean() {
GPUState.is_dirty = GL_FALSE; GPUState.is_dirty = GL_FALSE;
} }
void _glGPUStateMarkDirty() {
GPUState.is_dirty = GL_TRUE;
}
GLboolean _glGPUStateIsDirty() { GLboolean _glGPUStateIsDirty() {
return GPUState.is_dirty; return GPUState.is_dirty;
} }
@ -160,10 +164,8 @@ GLboolean _glIsScissorTestEnabled() {
} }
void _glRecalcEnabledLights() { void _glRecalcEnabledLights() {
GLubyte i;
GPUState.enabled_light_count = 0; GPUState.enabled_light_count = 0;
for(int i = 0; i < MAX_GLDC_LIGHTS; ++i) { for(GLubyte i = 0; i < MAX_GLDC_LIGHTS; ++i) {
if(_glLightAt(i)->isEnabled) { if(_glLightAt(i)->isEnabled) {
GPUState.enabled_light_count++; GPUState.enabled_light_count++;
} }
@ -389,41 +391,68 @@ void _glInitContext() {
} }
GLAPI void APIENTRY glEnable(GLenum cap) { GLAPI void APIENTRY glEnable(GLenum cap) {
GLboolean was_dirty = GPUState.is_dirty;
GPUState.is_dirty = GL_TRUE;
switch(cap) { switch(cap) {
case GL_TEXTURE_2D: case GL_TEXTURE_2D:
TEXTURES_ENABLED[_glGetActiveTexture()] = GL_TRUE; if(TEXTURES_ENABLED[_glGetActiveTexture()] != GL_TRUE) {
TEXTURES_ENABLED[_glGetActiveTexture()] = GL_TRUE;
GPUState.is_dirty = GL_TRUE;
}
break; break;
case GL_CULL_FACE: { case GL_CULL_FACE: {
GPUState.cull_face = GL_TRUE; if(GPUState.cull_face != GL_TRUE) {
GPUState.cull_face = GL_TRUE;
GPUState.is_dirty = GL_TRUE;
}
} break; } break;
case GL_DEPTH_TEST: { case GL_DEPTH_TEST: {
GPUState.depth_test_enabled = GL_TRUE; if(GPUState.depth_test_enabled != GL_TRUE) {
GPUState.depth_test_enabled = GL_TRUE;
GPUState.is_dirty = GL_TRUE;
}
} break; } break;
case GL_BLEND: { case GL_BLEND: {
GPUState.blend_enabled = GL_TRUE; if(GPUState.blend_enabled != GL_TRUE) {
GPUState.blend_enabled = GL_TRUE;
GPUState.is_dirty = GL_TRUE;
}
} break; } break;
case GL_SCISSOR_TEST: { case GL_SCISSOR_TEST: {
GPUState.scissor_test_enabled = GL_TRUE; if(GPUState.scissor_test_enabled != GL_TRUE) {
GPUState.scissor_test_enabled = GL_TRUE;
GPUState.is_dirty = GL_TRUE;
}
} break; } break;
case GL_LIGHTING: { case GL_LIGHTING: {
GPUState.lighting_enabled = GL_TRUE; if(GPUState.lighting_enabled != GL_TRUE) {
GPUState.lighting_enabled = GL_TRUE;
GPUState.is_dirty = GL_TRUE;
}
} break; } break;
case GL_FOG: case GL_FOG:
GPUState.fog_enabled = GL_TRUE; if(GPUState.fog_enabled != GL_TRUE) {
GPUState.fog_enabled = GL_TRUE;
GPUState.is_dirty = GL_TRUE;
}
break; break;
case GL_COLOR_MATERIAL: case GL_COLOR_MATERIAL:
GPUState.color_material_enabled = GL_TRUE; if(GPUState.color_material_enabled != GL_TRUE) {
GPUState.color_material_enabled = GL_TRUE;
GPUState.is_dirty = GL_TRUE;
}
break; break;
case GL_SHARED_TEXTURE_PALETTE_EXT: { case GL_SHARED_TEXTURE_PALETTE_EXT: {
GPUState.shared_palette_enabled = GL_TRUE; if(GPUState.shared_palette_enabled != GL_TRUE) {
GPUState.shared_palette_enabled = GL_TRUE;
GPUState.is_dirty = GL_TRUE;
}
} }
break; break;
case GL_ALPHA_TEST: { case GL_ALPHA_TEST: {
GPUState.alpha_test_enabled = GL_TRUE; if(GPUState.alpha_test_enabled != GL_TRUE) {
GPUState.alpha_test_enabled = GL_TRUE;
GPUState.is_dirty = GL_TRUE;
}
} break; } break;
case GL_LIGHT0: case GL_LIGHT0:
case GL_LIGHT1: case GL_LIGHT1:
@ -432,62 +461,102 @@ GLAPI void APIENTRY glEnable(GLenum cap) {
case GL_LIGHT4: case GL_LIGHT4:
case GL_LIGHT5: case GL_LIGHT5:
case GL_LIGHT6: case GL_LIGHT6:
case GL_LIGHT7: case GL_LIGHT7: {
_glLightAt(cap & 0xF)->isEnabled = GL_TRUE; LightSource* ptr = _glLightAt(cap & 0xF);
_glRecalcEnabledLights(); if(ptr->isEnabled != GL_TRUE) {
ptr->isEnabled = GL_TRUE;
_glRecalcEnabledLights();
}
}
break; break;
case GL_NEARZ_CLIPPING_KOS: case GL_NEARZ_CLIPPING_KOS:
GPUState.znear_clipping_enabled = GL_TRUE; if(GPUState.znear_clipping_enabled != GL_TRUE) {
GPUState.znear_clipping_enabled = GL_TRUE;
GPUState.is_dirty = GL_TRUE;
}
break; break;
case GL_POLYGON_OFFSET_POINT: case GL_POLYGON_OFFSET_POINT:
case GL_POLYGON_OFFSET_LINE: case GL_POLYGON_OFFSET_LINE:
case GL_POLYGON_OFFSET_FILL: case GL_POLYGON_OFFSET_FILL:
GPUState.polygon_offset_enabled = GL_TRUE; if(GPUState.polygon_offset_enabled != GL_TRUE) {
GPUState.polygon_offset_enabled = GL_TRUE;
GPUState.is_dirty = GL_TRUE;
}
break; break;
case GL_NORMALIZE: case GL_NORMALIZE:
GPUState.normalize_enabled = GL_TRUE; if(GPUState.normalize_enabled != GL_TRUE) {
GPUState.normalize_enabled = GL_TRUE;
GPUState.is_dirty = GL_TRUE;
}
break; break;
default: default:
GPUState.is_dirty = was_dirty;
break; break;
} }
} }
GLAPI void APIENTRY glDisable(GLenum cap) { GLAPI void APIENTRY glDisable(GLenum cap) {
GLboolean was_dirty = GPUState.is_dirty;
GPUState.is_dirty = GL_TRUE;
switch(cap) { switch(cap) {
case GL_TEXTURE_2D: { case GL_TEXTURE_2D:
TEXTURES_ENABLED[_glGetActiveTexture()] = GL_FALSE; if(TEXTURES_ENABLED[_glGetActiveTexture()] != GL_FALSE) {
} break; TEXTURES_ENABLED[_glGetActiveTexture()] = GL_FALSE;
GPUState.is_dirty = GL_TRUE;
}
break;
case GL_CULL_FACE: { case GL_CULL_FACE: {
GPUState.culling_enabled = GL_FALSE; if(GPUState.cull_face != GL_FALSE) {
GPUState.cull_face = GL_FALSE;
GPUState.is_dirty = GL_TRUE;
}
} break; } break;
case GL_DEPTH_TEST: { case GL_DEPTH_TEST: {
GPUState.depth_test_enabled = GL_FALSE; if(GPUState.depth_test_enabled != GL_FALSE) {
GPUState.depth_test_enabled = GL_FALSE;
GPUState.is_dirty = GL_TRUE;
}
} break;
case GL_BLEND: {
if(GPUState.blend_enabled != GL_FALSE) {
GPUState.blend_enabled = GL_FALSE;
GPUState.is_dirty = GL_TRUE;
}
} break; } break;
case GL_BLEND:
GPUState.blend_enabled = GL_FALSE;
break;
case GL_SCISSOR_TEST: { case GL_SCISSOR_TEST: {
GPUState.scissor_test_enabled = GL_FALSE; if(GPUState.scissor_test_enabled != GL_FALSE) {
GPUState.scissor_test_enabled = GL_FALSE;
GPUState.is_dirty = GL_TRUE;
}
} break; } break;
case GL_LIGHTING: { case GL_LIGHTING: {
GPUState.lighting_enabled = GL_FALSE; if(GPUState.lighting_enabled != GL_FALSE) {
GPUState.lighting_enabled = GL_FALSE;
GPUState.is_dirty = GL_TRUE;
}
} break; } break;
case GL_FOG: case GL_FOG:
GPUState.fog_enabled = GL_FALSE; if(GPUState.fog_enabled != GL_FALSE) {
GPUState.fog_enabled = GL_FALSE;
GPUState.is_dirty = GL_TRUE;
}
break; break;
case GL_COLOR_MATERIAL: case GL_COLOR_MATERIAL:
GPUState.color_material_enabled = GL_FALSE; if(GPUState.color_material_enabled != GL_FALSE) {
GPUState.color_material_enabled = GL_FALSE;
GPUState.is_dirty = GL_TRUE;
}
break; break;
case GL_SHARED_TEXTURE_PALETTE_EXT: { case GL_SHARED_TEXTURE_PALETTE_EXT: {
GPUState.shared_palette_enabled = GL_FALSE; if(GPUState.shared_palette_enabled != GL_FALSE) {
GPUState.shared_palette_enabled = GL_FALSE;
GPUState.is_dirty = GL_TRUE;
}
} }
break; break;
case GL_ALPHA_TEST: { case GL_ALPHA_TEST: {
GPUState.alpha_test_enabled = GL_FALSE; if(GPUState.alpha_test_enabled != GL_FALSE) {
GPUState.alpha_test_enabled = GL_FALSE;
GPUState.is_dirty = GL_TRUE;
}
} break; } break;
case GL_LIGHT0: case GL_LIGHT0:
case GL_LIGHT1: case GL_LIGHT1:
@ -497,21 +566,32 @@ GLAPI void APIENTRY glDisable(GLenum cap) {
case GL_LIGHT5: case GL_LIGHT5:
case GL_LIGHT6: case GL_LIGHT6:
case GL_LIGHT7: case GL_LIGHT7:
_glEnableLight(cap & 0xF, GL_FALSE); if(GPUState.lights[cap & 0xF].isEnabled) {
_glEnableLight(cap & 0xF, GL_FALSE);
GPUState.is_dirty = GL_TRUE;
}
break; break;
case GL_NEARZ_CLIPPING_KOS: case GL_NEARZ_CLIPPING_KOS:
GPUState.znear_clipping_enabled = GL_FALSE; if(GPUState.znear_clipping_enabled != GL_FALSE) {
GPUState.znear_clipping_enabled = GL_FALSE;
GPUState.is_dirty = GL_TRUE;
}
break; break;
case GL_POLYGON_OFFSET_POINT: case GL_POLYGON_OFFSET_POINT:
case GL_POLYGON_OFFSET_LINE: case GL_POLYGON_OFFSET_LINE:
case GL_POLYGON_OFFSET_FILL: case GL_POLYGON_OFFSET_FILL:
GPUState.polygon_offset_enabled = GL_FALSE; if(GPUState.polygon_offset_enabled != GL_FALSE) {
GPUState.polygon_offset_enabled = GL_FALSE;
GPUState.is_dirty = GL_TRUE;
}
break; break;
case GL_NORMALIZE: case GL_NORMALIZE:
GPUState.normalize_enabled = GL_FALSE; if(GPUState.normalize_enabled != GL_FALSE) {
GPUState.normalize_enabled = GL_FALSE;
GPUState.is_dirty = GL_TRUE;
}
break; break;
default: default:
GPUState.is_dirty = was_dirty;
break; break;
} }
} }
@ -558,13 +638,17 @@ GLAPI void APIENTRY glReadBuffer(GLenum mode) {
} }
GLAPI void APIENTRY glDepthMask(GLboolean flag) { GLAPI void APIENTRY glDepthMask(GLboolean flag) {
GPUState.depth_mask_enabled = flag; if(GPUState.depth_mask_enabled != flag) {
GPUState.is_dirty = GL_TRUE; GPUState.depth_mask_enabled = flag;
GPUState.is_dirty = GL_TRUE;
}
} }
GLAPI void APIENTRY glDepthFunc(GLenum func) { GLAPI void APIENTRY glDepthFunc(GLenum func) {
GPUState.depth_func = func; if(GPUState.depth_func != func) {
GPUState.is_dirty = GL_TRUE; GPUState.depth_func = func;
GPUState.is_dirty = GL_TRUE;
}
} }
/* Hints */ /* Hints */
@ -584,26 +668,34 @@ GLAPI void APIENTRY glPolygonMode(GLenum face, GLenum mode) {
/* Culling */ /* Culling */
GLAPI void APIENTRY glFrontFace(GLenum mode) { GLAPI void APIENTRY glFrontFace(GLenum mode) {
GPUState.front_face = mode; if(GPUState.front_face != mode) {
GPUState.is_dirty = GL_TRUE; GPUState.front_face = mode;
GPUState.is_dirty = GL_TRUE;
}
} }
GLAPI void APIENTRY glCullFace(GLenum mode) { GLAPI void APIENTRY glCullFace(GLenum mode) {
GPUState.cull_face = mode; if(GPUState.cull_face != mode) {
GPUState.is_dirty = GL_TRUE; GPUState.cull_face = mode;
GPUState.is_dirty = GL_TRUE;
}
} }
/* Shading - Flat or Goraud */ /* Shading - Flat or Goraud */
GLAPI void APIENTRY glShadeModel(GLenum mode) { GLAPI void APIENTRY glShadeModel(GLenum mode) {
GPUState.shade_model = mode; if(GPUState.shade_model != mode) {
GPUState.is_dirty = GL_TRUE; GPUState.shade_model = mode;
GPUState.is_dirty = GL_TRUE;
}
} }
/* Blending */ /* Blending */
GLAPI void APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor) { GLAPI void APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor) {
GPUState.blend_sfactor = sfactor; if(GPUState.blend_dfactor != dfactor || GPUState.blend_sfactor != sfactor) {
GPUState.blend_dfactor = dfactor; GPUState.blend_sfactor = sfactor;
GPUState.is_dirty = GL_TRUE; GPUState.blend_dfactor = dfactor;
GPUState.is_dirty = GL_TRUE;
}
} }

View File

@ -607,6 +607,8 @@ void APIENTRY glBindTexture(GLenum target, GLuint texture) {
} else { } else {
TEXTURE_UNITS[ACTIVE_TEXTURE] = NULL; TEXTURE_UNITS[ACTIVE_TEXTURE] = NULL;
} }
_glGPUStateMarkDirty();
} }
void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param) { void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param) {
@ -668,6 +670,8 @@ void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param) {
default: default:
break; break;
} }
_glGPUStateMarkDirty();
} }
void APIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param) { void APIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param) {
@ -1626,6 +1630,8 @@ void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param) {
break; break;
} }
} }
_glGPUStateMarkDirty();
} }
void APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param) { void APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param) {
@ -1783,6 +1789,8 @@ GLAPI void APIENTRY glColorTableEXT(GLenum target, GLenum internalFormat, GLsize
} }
_glApplyColorTable(palette); _glApplyColorTable(palette);
_glGPUStateMarkDirty();
} }
GLAPI void APIENTRY glColorSubTableEXT(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data) { GLAPI void APIENTRY glColorSubTableEXT(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data) {