summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2020-09-18 11:44:59 +0200
committerPaul Lemire <paul.lemire@kdab.com>2020-09-18 14:33:44 +0200
commit8e4233d6b1ae1517a711e361e9af8739dc8f5579 (patch)
tree8798c29d8dfb762cc09db664dc04bd680d6d0ebf
parent76a13b7cf7bdea2344b65f775226a22a17fa78c6 (diff)
RenderCommands: try to resolve API shader at command build time
This ensures that if a commands keeps being rebuilt, it will be usage for the current frame, assuming the shader exists. This aligns the RHI renderer with what the GL renderer does. The instanced-arrays-qml is a good way to verify that a command that keeps being rebuilt is rendered correctly. Change-Id: Ie9e574e98efeec6eb836af613d28cbf4cdf2fef5 Reviewed-by: Mike Krus <mike.krus@kdab.com>
-rw-r--r--src/plugins/renderers/opengl/renderer/renderview.cpp8
-rw-r--r--src/plugins/renderers/rhi/renderer/renderview.cpp28
2 files changed, 31 insertions, 5 deletions
diff --git a/src/plugins/renderers/opengl/renderer/renderview.cpp b/src/plugins/renderers/opengl/renderer/renderview.cpp
index 4a385c66b..1b15de2d3 100644
--- a/src/plugins/renderers/opengl/renderer/renderview.cpp
+++ b/src/plugins/renderers/opengl/renderer/renderview.cpp
@@ -927,6 +927,14 @@ EntityRenderCommandData RenderView::buildDrawRenderCommands(const Entity **entit
command.m_changeCost = m_renderer->defaultRenderState()->changeCost(command.m_stateSet.data());
}
command.m_shaderId = pass->shaderProgram();
+
+ // We try to resolve the m_glShader here. If the shader exist,
+ // it won't be null and will allow us to full process the
+ // command over a single frame. Otherwise, the shader will be
+ // loaded at the next submission time and the command will only
+ // be fully valid on the next frame. Additionally, that way, if
+ // a commands keeps being rebuilt, frame after frame, it will
+ // still be visible on screen as long as the shader exists
command.m_glShader = glShaderManager->lookupResource(command.m_shaderId);
// It takes two frames to have a valid command as we can only
diff --git a/src/plugins/renderers/rhi/renderer/renderview.cpp b/src/plugins/renderers/rhi/renderer/renderview.cpp
index c750373da..682a9e28b 100644
--- a/src/plugins/renderers/rhi/renderer/renderview.cpp
+++ b/src/plugins/renderers/rhi/renderer/renderview.cpp
@@ -874,6 +874,16 @@ EntityRenderCommandData RenderView::buildDrawRenderCommands(const Entity **entit
if (!command.m_shaderId)
continue;
+ // We try to resolve the m_rhiShader here. If the shader exist,
+ // it won't be null and will allow us to full process the
+ // command over a single frame. Otherwise, the shader will be
+ // loaded at the next submission time and the command will only
+ // be fully valid on the next frame. Additionally, that way, if
+ // a commands keeps being rebuilt, frame after frame, it will
+ // still be visible on screen as long as the shader exists
+ RHIShaderManager *rhiShaderManager = m_renderer->rhiResourceManagers()->rhiShaderManager();
+ command.m_rhiShader = rhiShaderManager->lookupResource(command.m_shaderId);
+
{ // Scoped to show extent
// Build of list of Attribute Layout information which
@@ -987,7 +997,6 @@ EntityRenderCommandData RenderView::buildComputeRenderCommands(const Entity **en
// layer component
// material/effect/technique/parameters/filters/
EntityRenderCommandData commands;
- RHIShaderManager *rhiShaderManager = m_renderer->rhiResourceManagers()->rhiShaderManager();
commands.reserve(count);
@@ -1023,13 +1032,22 @@ EntityRenderCommandData RenderView::buildComputeRenderCommands(const Entity **en
m_renderer->defaultRenderState()->changeCost(command.m_stateSet.data());
}
command.m_shaderId = pass->shaderProgram();
- command.m_rhiShader = rhiShaderManager->lookupResource(command.m_shaderId);
- // It takes two frames to have a valid command as we can only
- // reference a glShader at frame n if it has been loaded at frame n - 1
- if (!command.m_rhiShader)
+ // At submission time, shaderId is used to retrieve a RHIShader
+ // No point in continuing if shaderId is null
+ if (!command.m_shaderId)
continue;
+ // We try to resolve the m_rhiShader here. If the shader exist,
+ // it won't be null and will allow us to full process the
+ // command over a single frame. Otherwise, the shader will be
+ // loaded at the next submission time and the command will only
+ // be fully valid on the next frame. Additionally, that way, if
+ // a commands keeps being rebuilt, frame after frame, it will
+ // still be visible on screen as long as the shader exists
+ RHIShaderManager *rhiShaderManager = m_renderer->rhiResourceManagers()->rhiShaderManager();
+ command.m_rhiShader = rhiShaderManager->lookupResource(command.m_shaderId);
+
command.m_computeCommand = computeCommandHandle;
command.m_type = RenderCommand::Compute;
command.m_workGroups[0] = std::max(m_workGroups[0], computeJob->x());