glgsg: fix identical states never short-circuiting set_state_and_transform

Closes #1012
This commit is contained in:
Brian Lach 2020-09-09 09:59:40 -04:00 committed by rdb
parent 71f4802630
commit 57c9fbd86e
3 changed files with 40 additions and 15 deletions

View File

@ -2616,6 +2616,7 @@ reset() {
_state_rs = RenderState::make_empty(); _state_rs = RenderState::make_empty();
_target_rs = nullptr; _target_rs = nullptr;
_state_mask.clear(); _state_mask.clear();
_inv_state_mask = RenderState::SlotMask::all_on();
_internal_transform = _cs_transform; _internal_transform = _cs_transform;
_scene_null = new SceneSetup; _scene_null = new SceneSetup;
_scene_setup = _scene_null; _scene_setup = _scene_null;

View File

@ -3223,11 +3223,14 @@ set_state_and_transform(const RenderState *target,
_state_mask.set_bit(color_blend_slot); _state_mask.set_bit(color_blend_slot);
} }
if (_target_shader != _state_shader) { int shader_slot = ShaderAttrib::get_class_slot();
if (_target_shader != _state_shader ||
!_state_mask.get_bit(shader_slot)) {
// PStatTimer timer(_draw_set_state_shader_pcollector); // PStatTimer timer(_draw_set_state_shader_pcollector);
do_issue_shader(); do_issue_shader();
_state_shader = _target_shader; _state_shader = _target_shader;
_state_mask.clear_bit(TextureAttrib::get_class_slot()); _state_mask.clear_bit(TextureAttrib::get_class_slot());
_state_mask.set_bit(shader_slot);
} }
int texture_slot = TextureAttrib::get_class_slot(); int texture_slot = TextureAttrib::get_class_slot();

View File

@ -608,10 +608,10 @@ reset() {
GraphicsStateGuardian::reset(); GraphicsStateGuardian::reset();
// Build _inv_state_mask as a mask of 1's where we don't care, and 0's where // Build _inv_state_mask as a mask of 1's where we don't care, and 0's where
// we do care, about the state. _inv_state_mask = // we do care, about the state.
// RenderState::SlotMask::all_on(); #ifndef OPENGLES_1
_inv_state_mask.clear_bit(ShaderAttrib::get_class_slot()); _inv_state_mask.clear_bit(ShaderAttrib::get_class_slot());
_inv_state_mask.clear_bit(AlphaTestAttrib::get_class_slot()); #endif
_inv_state_mask.clear_bit(AntialiasAttrib::get_class_slot()); _inv_state_mask.clear_bit(AntialiasAttrib::get_class_slot());
_inv_state_mask.clear_bit(ClipPlaneAttrib::get_class_slot()); _inv_state_mask.clear_bit(ClipPlaneAttrib::get_class_slot());
_inv_state_mask.clear_bit(ColorAttrib::get_class_slot()); _inv_state_mask.clear_bit(ColorAttrib::get_class_slot());
@ -621,21 +621,30 @@ reset() {
_inv_state_mask.clear_bit(DepthTestAttrib::get_class_slot()); _inv_state_mask.clear_bit(DepthTestAttrib::get_class_slot());
_inv_state_mask.clear_bit(DepthWriteAttrib::get_class_slot()); _inv_state_mask.clear_bit(DepthWriteAttrib::get_class_slot());
_inv_state_mask.clear_bit(RenderModeAttrib::get_class_slot()); _inv_state_mask.clear_bit(RenderModeAttrib::get_class_slot());
_inv_state_mask.clear_bit(RescaleNormalAttrib::get_class_slot());
_inv_state_mask.clear_bit(ShadeModelAttrib::get_class_slot());
_inv_state_mask.clear_bit(TransparencyAttrib::get_class_slot()); _inv_state_mask.clear_bit(TransparencyAttrib::get_class_slot());
_inv_state_mask.clear_bit(ColorWriteAttrib::get_class_slot()); _inv_state_mask.clear_bit(ColorWriteAttrib::get_class_slot());
_inv_state_mask.clear_bit(ColorBlendAttrib::get_class_slot()); _inv_state_mask.clear_bit(ColorBlendAttrib::get_class_slot());
#if !defined(OPENGLES) || defined(OPENGLES_1)
_inv_state_mask.clear_bit(LogicOpAttrib::get_class_slot()); _inv_state_mask.clear_bit(LogicOpAttrib::get_class_slot());
#endif
_inv_state_mask.clear_bit(TextureAttrib::get_class_slot()); _inv_state_mask.clear_bit(TextureAttrib::get_class_slot());
_inv_state_mask.clear_bit(TexGenAttrib::get_class_slot());
_inv_state_mask.clear_bit(TexMatrixAttrib::get_class_slot()); _inv_state_mask.clear_bit(TexMatrixAttrib::get_class_slot());
_inv_state_mask.clear_bit(MaterialAttrib::get_class_slot());
_inv_state_mask.clear_bit(LightAttrib::get_class_slot());
_inv_state_mask.clear_bit(StencilAttrib::get_class_slot()); _inv_state_mask.clear_bit(StencilAttrib::get_class_slot());
_inv_state_mask.clear_bit(FogAttrib::get_class_slot());
_inv_state_mask.clear_bit(ScissorAttrib::get_class_slot()); _inv_state_mask.clear_bit(ScissorAttrib::get_class_slot());
// We only care about this state if we are using the fixed-function pipeline.
#ifdef SUPPORT_FIXED_FUNCTION
if (has_fixed_function_pipeline()) {
_inv_state_mask.clear_bit(AlphaTestAttrib::get_class_slot());
_inv_state_mask.clear_bit(RescaleNormalAttrib::get_class_slot());
_inv_state_mask.clear_bit(ShadeModelAttrib::get_class_slot());
_inv_state_mask.clear_bit(TexGenAttrib::get_class_slot());
_inv_state_mask.clear_bit(MaterialAttrib::get_class_slot());
_inv_state_mask.clear_bit(LightAttrib::get_class_slot());
_inv_state_mask.clear_bit(FogAttrib::get_class_slot());
}
#endif
// Output the vendor and version strings. // Output the vendor and version strings.
query_gl_version(); query_gl_version();
@ -11392,17 +11401,27 @@ set_state_and_transform(const RenderState *target,
_state_pcollector.add_level(1); _state_pcollector.add_level(1);
PStatGPUTimer timer1(this, _draw_set_state_pcollector); PStatGPUTimer timer1(this, _draw_set_state_pcollector);
if (transform != _internal_transform) { bool transform_changed = transform != _internal_transform;
if (transform_changed) {
// PStatGPUTimer timer(this, _draw_set_state_transform_pcollector); // PStatGPUTimer timer(this, _draw_set_state_transform_pcollector);
_transform_state_pcollector.add_level(1); _transform_state_pcollector.add_level(1);
_internal_transform = transform; _internal_transform = transform;
do_issue_transform(); do_issue_transform();
} }
//XXX the _inv_state_mask system does not appear to be used at the moment. if (target == _state_rs && (_state_mask | _inv_state_mask).is_all_on()) {
//if (target == _state_rs && (_state_mask | _inv_state_mask).is_all_on()) { #ifndef OPENGLES_1
// return; if (transform_changed) {
//} // The state has not changed, but the transform has. Set the new
// transform on the shader, if we have one.
if (_current_shader_context != nullptr) {
_current_shader_context->set_state_and_transform(_state_rs, transform,
_scene_setup->get_camera_transform(), _projection_mat);
}
}
#endif
return;
}
_target_rs = target; _target_rs = target;
#ifndef OPENGLES_1 #ifndef OPENGLES_1
@ -11413,10 +11432,12 @@ set_state_and_transform(const RenderState *target,
do_issue_shader(); do_issue_shader();
_state_shader = _target_shader; _state_shader = _target_shader;
_state_mask.clear_bit(TextureAttrib::get_class_slot()); _state_mask.clear_bit(TextureAttrib::get_class_slot());
_state_mask.set_bit(ShaderAttrib::get_class_slot());
} }
else if (!has_fixed_function_pipeline() && _current_shader == nullptr) { // In the case of OpenGL ES 2.x, we need to glUseShader before we draw anything. else if (!has_fixed_function_pipeline() && _current_shader == nullptr) { // In the case of OpenGL ES 2.x, we need to glUseShader before we draw anything.
do_issue_shader(); do_issue_shader();
_state_mask.clear_bit(TextureAttrib::get_class_slot()); _state_mask.clear_bit(TextureAttrib::get_class_slot());
_state_mask.set_bit(ShaderAttrib::get_class_slot());
} }
// Update all of the state that is bound to the shader program. // Update all of the state that is bound to the shader program.