diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2020-09-18 11:44:59 +0200 |
---|---|---|
committer | Paul Lemire <paul.lemire@kdab.com> | 2020-09-18 14:33:44 +0200 |
commit | 8e4233d6b1ae1517a711e361e9af8739dc8f5579 (patch) | |
tree | 8798c29d8dfb762cc09db664dc04bd680d6d0ebf | |
parent | 76a13b7cf7bdea2344b65f775226a22a17fa78c6 (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.cpp | 8 | ||||
-rw-r--r-- | src/plugins/renderers/rhi/renderer/renderview.cpp | 28 |
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()); |