Skip to content

Commit 836fd7e

Browse files
mardyWinterMute
authored andcommitted
state: do not rebuild TEV stages unless needed
Add a dirty flag to track whether the TEV stages must be rebuilt. The replaces the dirty_lighting, dirty_clip_planes, dirty_stencil and the (de facto unused) dirty_material flags, because all these factors ultimately require the TEV to be rebuilt. This is not super-precide, and we err on the side of rendering safety, but it still brings a huge speed up in the crack-attack game, which uses call lists with several draw commands in each (so the state is guaranteed to be clean between one command and the next).
1 parent d124178 commit 836fd7e

File tree

10 files changed

+68
-32
lines changed

10 files changed

+68
-32
lines changed

src/accum.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ static void draw_screen(GXTexObj *texture, float value)
7272
GX_SetNumChans(1);
7373
GX_SetChanCtrl(GX_COLOR0A0, GX_DISABLE, GX_SRC_VTX, GX_SRC_VTX,
7474
0, GX_DF_NONE, GX_AF_NONE);
75+
glparamstate.dirty.bits.dirty_tev = 1;
7576

7677
GX_SetCullMode(GX_CULL_NONE);
7778
glparamstate.dirty.bits.dirty_cull = 1;

src/clip.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,13 +165,13 @@ void _ogx_clip_setup_tev()
165165
void _ogx_clip_enabled(int plane)
166166
{
167167
glparamstate.clip_plane_mask |= 1 << plane;
168-
glparamstate.dirty.bits.dirty_clip_planes = 1;
168+
glparamstate.dirty.bits.dirty_tev = 1;
169169
}
170170

171171
void _ogx_clip_disabled(int plane)
172172
{
173173
glparamstate.clip_plane_mask &= ~(1 << plane);
174-
glparamstate.dirty.bits.dirty_clip_planes = 1;
174+
glparamstate.dirty.bits.dirty_tev = 1;
175175
}
176176

177177
void glClipPlane(GLenum plane, const GLdouble *equation)
@@ -192,4 +192,6 @@ void glClipPlane(GLenum plane, const GLdouble *equation)
192192
guMtx44Inverse(mv, mv_inverse);
193193
ClipPlane p0 = { equation[0], equation[1], equation[2], equation[3] };
194194
mtx44_multiply(p0, mv_inverse, *p);
195+
196+
glparamstate.dirty.bits.dirty_tev = 1;
195197
}

src/efb.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ void _ogx_efb_restore_texobj(GXTexObj *texobj)
8888
GX_SetNumChans(0);
8989
GX_SetTevOp(GX_TEVSTAGE0, GX_REPLACE);
9090
GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLORNULL);
91+
glparamstate.dirty.bits.dirty_tev = 1;
9192

9293
GX_SetCullMode(GX_CULL_NONE);
9394
glparamstate.dirty.bits.dirty_cull = 1;

src/gc_gl.c

Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,7 @@ void glEnable(GLenum cap)
544544
switch (cap) {
545545
case GL_TEXTURE_2D:
546546
glparamstate.texture_enabled |= (1 << glparamstate.active_texture);
547+
glparamstate.dirty.bits.dirty_tev = 1;
547548
break;
548549
case GL_TEXTURE_GEN_S:
549550
case GL_TEXTURE_GEN_T:
@@ -553,9 +554,11 @@ void glEnable(GLenum cap)
553554
OgxTextureUnit *tu = active_tex_unit();
554555
tu->gen_enabled |= (1 << (cap - GL_TEXTURE_GEN_S));
555556
}
557+
glparamstate.dirty.bits.dirty_tev = 1;
556558
break;
557559
case GL_COLOR_MATERIAL:
558560
glparamstate.lighting.color_material_enabled = 1;
561+
glparamstate.dirty.bits.dirty_tev = 1;
559562
break;
560563
case GL_CULL_FACE:
561564
glparamstate.cullenabled = 1;
@@ -590,14 +593,14 @@ void glEnable(GLenum cap)
590593
break;
591594
case GL_LIGHTING:
592595
glparamstate.lighting.enabled = 1;
593-
glparamstate.dirty.bits.dirty_lighting = 1;
596+
glparamstate.dirty.bits.dirty_tev = 1;
594597
break;
595598
case GL_LIGHT0:
596599
case GL_LIGHT1:
597600
case GL_LIGHT2:
598601
case GL_LIGHT3:
599602
glparamstate.lighting.lights[cap - GL_LIGHT0].enabled = 1;
600-
glparamstate.dirty.bits.dirty_lighting = 1;
603+
glparamstate.dirty.bits.dirty_tev = 1;
601604
break;
602605
case GL_POINT_SPRITE:
603606
glparamstate.point_sprites_enabled = 1;
@@ -618,6 +621,7 @@ void glDisable(GLenum cap)
618621
switch (cap) {
619622
case GL_TEXTURE_2D:
620623
glparamstate.texture_enabled &= ~(1 << glparamstate.active_texture);
624+
glparamstate.dirty.bits.dirty_tev = 1;
621625
break;
622626
case GL_TEXTURE_GEN_S:
623627
case GL_TEXTURE_GEN_T:
@@ -627,9 +631,11 @@ void glDisable(GLenum cap)
627631
OgxTextureUnit *tu = active_tex_unit();
628632
tu->gen_enabled &= ~(1 << (cap - GL_TEXTURE_GEN_S));
629633
}
634+
glparamstate.dirty.bits.dirty_tev = 1;
630635
break;
631636
case GL_COLOR_MATERIAL:
632637
glparamstate.lighting.color_material_enabled = 0;
638+
glparamstate.dirty.bits.dirty_tev = 1;
633639
break;
634640
case GL_CULL_FACE:
635641
glparamstate.cullenabled = 0;
@@ -660,14 +666,14 @@ void glDisable(GLenum cap)
660666
break;
661667
case GL_LIGHTING:
662668
glparamstate.lighting.enabled = 0;
663-
glparamstate.dirty.bits.dirty_lighting = 1;
669+
glparamstate.dirty.bits.dirty_tev = 1;
664670
break;
665671
case GL_LIGHT0:
666672
case GL_LIGHT1:
667673
case GL_LIGHT2:
668674
case GL_LIGHT3:
669675
glparamstate.lighting.lights[cap - GL_LIGHT0].enabled = 0;
670-
glparamstate.dirty.bits.dirty_lighting = 1;
676+
glparamstate.dirty.bits.dirty_tev = 1;
671677
break;
672678
case GL_POINT_SPRITE:
673679
glparamstate.point_sprites_enabled = 0;
@@ -756,7 +762,7 @@ void glLightf(GLenum light, GLenum pname, GLfloat param)
756762
default:
757763
break;
758764
}
759-
glparamstate.dirty.bits.dirty_lighting = 1;
765+
glparamstate.dirty.bits.dirty_tev = 1;
760766
}
761767

762768
void glLightfv(GLenum light, GLenum pname, const GLfloat *params)
@@ -794,7 +800,7 @@ void glLightfv(GLenum light, GLenum pname, const GLfloat *params)
794800
floatcpy(glparamstate.lighting.lights[lnum].specular_color, params, 4);
795801
break;
796802
}
797-
glparamstate.dirty.bits.dirty_lighting = 1;
803+
glparamstate.dirty.bits.dirty_tev = 1;
798804
}
799805

800806
void glLightModelfv(GLenum pname, const GLfloat *params)
@@ -804,7 +810,7 @@ void glLightModelfv(GLenum pname, const GLfloat *params)
804810
floatcpy(glparamstate.lighting.globalambient, params, 4);
805811
break;
806812
}
807-
glparamstate.dirty.bits.dirty_material = 1;
813+
glparamstate.dirty.bits.dirty_tev = 1;
808814
};
809815

810816
void glMaterialf(GLenum face, GLenum pname, GLfloat param)
@@ -839,13 +845,14 @@ void glMaterialfv(GLenum face, GLenum pname, const GLfloat *params)
839845
default:
840846
break;
841847
}
842-
glparamstate.dirty.bits.dirty_material = 1;
848+
glparamstate.dirty.bits.dirty_tev = 1;
843849
};
844850

845851
void glColorMaterial(GLenum face, GLenum mode)
846852
{
847853
/* TODO: support the face parameter */
848854
glparamstate.lighting.color_material_mode = mode;
855+
glparamstate.dirty.bits.dirty_tev = 1;
849856
}
850857

851858
void glPixelStoref(GLenum pname, GLfloat param)
@@ -1023,6 +1030,7 @@ void glPopMatrix(void)
10231030
}
10241031
memcpy(glparamstate.projection_matrix, glparamstate.projection_stack[glparamstate.cur_proj_mat], sizeof(Mtx44));
10251032
glparamstate.cur_proj_mat--;
1033+
glparamstate.dirty.bits.dirty_matrices = 1;
10261034
break;
10271035
case 1:
10281036
if (glparamstate.cur_modv_mat < 0) {
@@ -1031,6 +1039,7 @@ void glPopMatrix(void)
10311039
}
10321040
memcpy(glparamstate.modelview_matrix, glparamstate.modelview_stack[glparamstate.cur_modv_mat], sizeof(Mtx));
10331041
glparamstate.cur_modv_mat--;
1042+
glparamstate.dirty.bits.dirty_matrices = 1;
10341043
break;
10351044
case 2:
10361045
{
@@ -1041,10 +1050,11 @@ void glPopMatrix(void)
10411050
}
10421051
tu->matrix_index--;
10431052
}
1053+
glparamstate.dirty.bits.dirty_tev = 1;
1054+
break;
10441055
default:
10451056
break;
10461057
}
1047-
glparamstate.dirty.bits.dirty_matrices = 1;
10481058
}
10491059

10501060
void glPushMatrix(void)
@@ -1089,20 +1099,22 @@ void glLoadMatrixf(const GLfloat *m)
10891099
switch (glparamstate.matrixmode) {
10901100
case 0:
10911101
gl_matrix_to_gx44(m, glparamstate.projection_matrix);
1102+
glparamstate.dirty.bits.dirty_matrices = 1;
10921103
break;
10931104
case 1:
10941105
gl_matrix_to_gx(m, glparamstate.modelview_matrix);
1106+
glparamstate.dirty.bits.dirty_matrices = 1;
10951107
break;
10961108
case 2:
10971109
{
10981110
OgxTextureUnit *tu = active_tex_unit();
10991111
gl_matrix_to_gx(m, tu->matrix[tu->matrix_index]);
11001112
}
1113+
glparamstate.dirty.bits.dirty_tev = 1;
11011114
break;
11021115
default:
11031116
return;
11041117
}
1105-
glparamstate.dirty.bits.dirty_matrices = 1;
11061118
}
11071119

11081120
void glMultMatrixd(const GLdouble *m)
@@ -1126,12 +1138,15 @@ void glMultMatrixf(const GLfloat *m)
11261138
gl_matrix_to_gx44(m, mtx44);
11271139
guMtx44Concat(glparamstate.projection_matrix, mtx44,
11281140
glparamstate.projection_matrix);
1141+
glparamstate.dirty.bits.dirty_matrices = 1;
11291142
break;
11301143
case 1:
11311144
target = &glparamstate.modelview_matrix;
1145+
glparamstate.dirty.bits.dirty_matrices = 1;
11321146
break;
11331147
case 2:
11341148
target = current_tex_matrix();
1149+
glparamstate.dirty.bits.dirty_tev = 1;
11351150
break;
11361151
default:
11371152
break;
@@ -1141,7 +1156,6 @@ void glMultMatrixf(const GLfloat *m)
11411156
gl_matrix_to_gx(m, mtx);
11421157
guMtxConcat(*target, mtx, *target);
11431158
}
1144-
glparamstate.dirty.bits.dirty_matrices = 1;
11451159
}
11461160

11471161
void glLoadIdentity()
@@ -1151,21 +1165,22 @@ void glLoadIdentity()
11511165
switch (glparamstate.matrixmode) {
11521166
case 0:
11531167
guMtx44Identity(glparamstate.projection_matrix);
1168+
glparamstate.dirty.bits.dirty_matrices = 1;
11541169
break;
11551170
case 1:
11561171
guMtxIdentity(glparamstate.modelview_matrix);
1172+
glparamstate.dirty.bits.dirty_matrices = 1;
11571173
break;
11581174
case 2:
11591175
{
11601176
OgxTextureUnit *tu = active_tex_unit();
11611177
guMtxIdentity(tu->matrix[tu->matrix_index]);
11621178
}
1179+
glparamstate.dirty.bits.dirty_tev = 1;
11631180
break;
11641181
default:
11651182
return;
11661183
}
1167-
1168-
glparamstate.dirty.bits.dirty_matrices = 1;
11691184
}
11701185

11711186
void glScalef(GLfloat x, GLfloat y, GLfloat z)
@@ -1179,12 +1194,15 @@ void glScalef(GLfloat x, GLfloat y, GLfloat z)
11791194
guMtxApplyScale(glparamstate.projection_matrix,
11801195
glparamstate.projection_matrix,
11811196
x, y, z);
1197+
glparamstate.dirty.bits.dirty_matrices = 1;
11821198
break;
11831199
case 1:
11841200
target = &glparamstate.modelview_matrix;
1201+
glparamstate.dirty.bits.dirty_matrices = 1;
11851202
break;
11861203
case 2:
11871204
target = current_tex_matrix();
1205+
glparamstate.dirty.bits.dirty_tev = 1;
11881206
break;
11891207
default:
11901208
break;
@@ -1193,7 +1211,6 @@ void glScalef(GLfloat x, GLfloat y, GLfloat z)
11931211
if (target) {
11941212
guMtxApplyScale(*target, *target, x, y, z);
11951213
}
1196-
glparamstate.dirty.bits.dirty_matrices = 1;
11971214
}
11981215

11991216
void glTranslated(GLdouble x, GLdouble y, GLdouble z)
@@ -1212,12 +1229,15 @@ void glTranslatef(GLfloat x, GLfloat y, GLfloat z)
12121229
guMtxApplyTrans(glparamstate.projection_matrix,
12131230
glparamstate.projection_matrix,
12141231
x, y, z);
1232+
glparamstate.dirty.bits.dirty_matrices = 1;
12151233
break;
12161234
case 1:
12171235
target = &glparamstate.modelview_matrix;
1236+
glparamstate.dirty.bits.dirty_matrices = 1;
12181237
break;
12191238
case 2:
12201239
target = current_tex_matrix();
1240+
glparamstate.dirty.bits.dirty_tev = 1;
12211241
break;
12221242
default:
12231243
break;
@@ -1226,7 +1246,6 @@ void glTranslatef(GLfloat x, GLfloat y, GLfloat z)
12261246
if (target) {
12271247
guMtxApplyTrans(*target, *target, x, y, z);
12281248
}
1229-
glparamstate.dirty.bits.dirty_matrices = 1;
12301249
}
12311250

12321251
void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
@@ -1244,12 +1263,15 @@ void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
12441263
rot[3][0] = rot[3][1] = rot[3][2] = 0.0f;
12451264
rot[3][3] = 1.0f;
12461265
guMtx44Concat(glparamstate.projection_matrix, rot, glparamstate.projection_matrix);
1266+
glparamstate.dirty.bits.dirty_matrices = 1;
12471267
break;
12481268
case 1:
12491269
target = &glparamstate.modelview_matrix;
1270+
glparamstate.dirty.bits.dirty_matrices = 1;
12501271
break;
12511272
case 2:
12521273
target = current_tex_matrix();
1274+
glparamstate.dirty.bits.dirty_tev = 1;
12531275
break;
12541276
default:
12551277
break;
@@ -1258,7 +1280,6 @@ void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
12581280
if (target) {
12591281
guMtxConcat(*target, rot, *target);
12601282
}
1261-
glparamstate.dirty.bits.dirty_matrices = 1;
12621283
}
12631284

12641285
void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
@@ -1376,6 +1397,7 @@ void glClear(GLbitfield mask)
13761397
glparamstate.dirty.bits.dirty_z = 1;
13771398
glparamstate.dirty.bits.dirty_color_update = 1;
13781399
glparamstate.dirty.bits.dirty_matrices = 1;
1400+
glparamstate.dirty.bits.dirty_tev = 1;
13791401
glparamstate.dirty.bits.dirty_cull = 1;
13801402

13811403
glparamstate.draw_count++;
@@ -2068,6 +2090,8 @@ static void setup_fog()
20682090

20692091
bool _ogx_setup_render_stages()
20702092
{
2093+
if (!glparamstate.dirty.bits.dirty_tev) return true;
2094+
20712095
u8 raster_output, raster_reg_index;
20722096
if (glparamstate.texture_enabled) {
20732097
raster_reg_index = _ogx_gpu_resources->tevreg_first++;
@@ -2231,6 +2255,7 @@ bool _ogx_setup_render_stages()
22312255
* OgxGpuResources::{tevstage,texcoord}_first. */
22322256
GX_SetNumTevStages(_ogx_gpu_resources->tevstage_first);
22332257
GX_SetNumTexGens(_ogx_gpu_resources->texcoord_first);
2258+
glparamstate.dirty.bits.dirty_tev = false;
22342259
return true;
22352260
}
22362261

@@ -2252,8 +2277,7 @@ void _ogx_apply_state()
22522277
}
22532278

22542279
if (glparamstate.dirty.bits.dirty_alphatest ||
2255-
glparamstate.dirty.bits.dirty_stencil ||
2256-
glparamstate.dirty.bits.dirty_clip_planes) {
2280+
glparamstate.dirty.bits.dirty_tev) {
22572281
u8 params[4] = { GX_ALWAYS, 0, GX_ALWAYS, 0 };
22582282
int comparisons = 0;
22592283
if (glparamstate.alphatest_enabled) {
@@ -2280,7 +2304,7 @@ void _ogx_apply_state()
22802304
update_modelview_matrix();
22812305
update_projection_matrix();
22822306
}
2283-
if (glparamstate.dirty.bits.dirty_matrices | glparamstate.dirty.bits.dirty_lighting) {
2307+
if (glparamstate.dirty.bits.dirty_matrices | glparamstate.dirty.bits.dirty_tev) {
22842308
update_normal_matrix();
22852309
}
22862310

@@ -2293,12 +2317,9 @@ void _ogx_apply_state()
22932317
* to 0 because some states might still be dirty: for example, the stencil
22942318
* checks alters the texture coordinate generation. */
22952319
glparamstate.dirty.bits.dirty_cull = 0;
2296-
glparamstate.dirty.bits.dirty_lighting = 0;
22972320
glparamstate.dirty.bits.dirty_matrices = 0;
2298-
glparamstate.dirty.bits.dirty_stencil = 0;
22992321
glparamstate.dirty.bits.dirty_alphatest = 0;
23002322
glparamstate.dirty.bits.dirty_blend = 0;
2301-
glparamstate.dirty.bits.dirty_clip_planes = 0;
23022323
glparamstate.dirty.bits.dirty_color_update = 0;
23032324
glparamstate.dirty.bits.dirty_z = 0;
23042325
}

src/raster.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ static void draw_raster_texture(GXTexObj *texture, int width, int height,
227227
GX_SetNumTexGens(1);
228228
GX_SetNumTevStages(1);
229229
GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
230+
glparamstate.dirty.bits.dirty_tev = 1;
230231

231232
GX_SetCullMode(GX_CULL_NONE);
232233
glparamstate.dirty.bits.dirty_cull = 1;

0 commit comments

Comments
 (0)