From 57c9fbd86e202668f371fa776c07770ff9dfceb2 Mon Sep 17 00:00:00 2001 From: Brian Lach <32017152+lachbr@users.noreply.github.com> Date: Wed, 9 Sep 2020 09:59:40 -0400 Subject: [PATCH] glgsg: fix identical states never short-circuiting set_state_and_transform Closes #1012 --- panda/src/display/graphicsStateGuardian.cxx | 1 + panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx | 5 +- .../glstuff/glGraphicsStateGuardian_src.cxx | 49 +++++++++++++------ 3 files changed, 40 insertions(+), 15 deletions(-) diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index f26104449a..b87a6401e6 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -2616,6 +2616,7 @@ reset() { _state_rs = RenderState::make_empty(); _target_rs = nullptr; _state_mask.clear(); + _inv_state_mask = RenderState::SlotMask::all_on(); _internal_transform = _cs_transform; _scene_null = new SceneSetup; _scene_setup = _scene_null; diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index e1efd0374b..aa466201f7 100644 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx @@ -3223,11 +3223,14 @@ set_state_and_transform(const RenderState *target, _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); do_issue_shader(); _state_shader = _target_shader; _state_mask.clear_bit(TextureAttrib::get_class_slot()); + _state_mask.set_bit(shader_slot); } int texture_slot = TextureAttrib::get_class_slot(); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 0c60dcf806..2e5d32b859 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -608,10 +608,10 @@ reset() { GraphicsStateGuardian::reset(); // 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 = - // RenderState::SlotMask::all_on(); + // we do care, about the state. +#ifndef OPENGLES_1 _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(ClipPlaneAttrib::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(DepthWriteAttrib::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(ColorWriteAttrib::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()); +#endif _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(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(FogAttrib::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. query_gl_version(); @@ -11392,17 +11401,27 @@ set_state_and_transform(const RenderState *target, _state_pcollector.add_level(1); 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); _transform_state_pcollector.add_level(1); _internal_transform = 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()) { - // return; - //} + if (target == _state_rs && (_state_mask | _inv_state_mask).is_all_on()) { +#ifndef OPENGLES_1 + 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; #ifndef OPENGLES_1 @@ -11413,10 +11432,12 @@ set_state_and_transform(const RenderState *target, do_issue_shader(); _state_shader = _target_shader; _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. do_issue_shader(); _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.