diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2021-03-08 14:25:57 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-03-09 13:45:34 +0000 |
commit | 2ed9bae3dfbdadea6f60eef6e3a1558918b7a36a (patch) | |
tree | c5ebb42ab4ef9222de194edfac313fbb6210edb8 /src/gui | |
parent | 75e8b80c6e86379e1bab8fde759c79892f164296 (diff) |
rhi: gl: Fix missing uniform data with certain command lists
Following patterns from the other backends is insufficient with OpenGL
because we do not use real uniform buffers. There is currently a
possibility that a shader program will be bound without following it
with setting uniforms. Correct this by having a second level of tracking
of the associated srb object in the pipelines.
Fixes: QTBUG-91630
Change-Id: I74a012daade826dd22c436bde06381c1233bad11
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
(cherry picked from commit 80029e0ca65d4bf4575f7a08d186c781ec6c2f0e)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/rhi/qrhigles2.cpp | 30 | ||||
-rw-r--r-- | src/gui/rhi/qrhigles2_p_p.h | 4 |
2 files changed, 33 insertions, 1 deletions
diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp index 5fdd3b7179..53e47b027c 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -1149,7 +1149,29 @@ void QRhiGles2::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind } } - const bool srbChanged = gfxPsD ? (cbD->currentGraphicsSrb != srb) : (cbD->currentComputeSrb != srb); + bool srbChanged = gfxPsD ? (cbD->currentGraphicsSrb != srb) : (cbD->currentComputeSrb != srb); + + // The Command::BindShaderResources command generated below is what will + // cause uniforms to be set (glUniformNxx). This needs some special + // handling here in this backend without real uniform buffers, because, + // like in other backends, we optimize out the setShaderResources when the + // srb that was set before is attempted to be set again on the command + // buffer, but that is incorrect if the same srb is now used with another + // pipeline. (because that could mean a glUseProgram not followed by + // up-to-date glUniform calls, i.e. with GL we have a strong dependency + // between the pipeline (== program) and the srb, unlike other APIs) This + // is the reason there is a second level of srb(+generation) tracking in + // the pipeline objects. + if (gfxPsD && (gfxPsD->currentSrb != srb || gfxPsD->currentSrbGeneration != srbD->generation)) { + srbChanged = true; + gfxPsD->currentSrb = srb; + gfxPsD->currentSrbGeneration = srbD->generation; + } else if (compPsD && (compPsD->currentSrb != srb || compPsD->currentSrbGeneration != srbD->generation)) { + srbChanged = true; + compPsD->currentSrb = srb; + compPsD->currentSrbGeneration = srbD->generation; + } + if (srbChanged || cbD->currentSrbGeneration != srbD->generation || srbD->hasDynamicOffset) { if (gfxPsD) { cbD->currentGraphicsSrb = srb; @@ -4580,6 +4602,9 @@ bool QGles2GraphicsPipeline::create() memset(uniformState, 0, sizeof(uniformState)); + currentSrb = nullptr; + currentSrbGeneration = 0; + generation += 1; rhiD->registerResource(this); return true; @@ -4653,6 +4678,9 @@ bool QGles2ComputePipeline::create() memset(uniformState, 0, sizeof(uniformState)); + currentSrb = nullptr; + currentSrbGeneration = 0; + generation += 1; rhiD->registerResource(this); return true; diff --git a/src/gui/rhi/qrhigles2_p_p.h b/src/gui/rhi/qrhigles2_p_p.h index a336497b63..49ab684363 100644 --- a/src/gui/rhi/qrhigles2_p_p.h +++ b/src/gui/rhi/qrhigles2_p_p.h @@ -290,6 +290,8 @@ struct QGles2GraphicsPipeline : public QRhiGraphicsPipeline QGles2UniformDescriptionVector uniforms; QGles2SamplerDescriptionVector samplers; QGles2UniformState uniformState[QGles2UniformState::MAX_TRACKED_LOCATION + 1]; + QRhiShaderResourceBindings *currentSrb = nullptr; + uint currentSrbGeneration = 0; uint generation = 0; friend class QRhiGles2; }; @@ -305,6 +307,8 @@ struct QGles2ComputePipeline : public QRhiComputePipeline QGles2UniformDescriptionVector uniforms; QGles2SamplerDescriptionVector samplers; QGles2UniformState uniformState[QGles2UniformState::MAX_TRACKED_LOCATION + 1]; + QRhiShaderResourceBindings *currentSrb = nullptr; + uint currentSrbGeneration = 0; uint generation = 0; friend class QRhiGles2; }; |