From c7d1c9dcb16302622b1b08d2de9cd7f444aa826d Mon Sep 17 00:00:00 2001 From: Dustin Howett Date: Thu, 1 Sep 2022 13:34:14 -0500 Subject: [PATCH 1/2] atlas: only enable continuous redraw if the shader needs it We do this by detecting whether the shader is using variable 0 in constant buffer 0 (typically "time", but it can go by many names.) Closes #13901 --- src/renderer/atlas/AtlasEngine.cpp | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/renderer/atlas/AtlasEngine.cpp b/src/renderer/atlas/AtlasEngine.cpp index 948cd6b5a33..be66c5749eb 100644 --- a/src/renderer/atlas/AtlasEngine.cpp +++ b/src/renderer/atlas/AtlasEngine.cpp @@ -696,9 +696,30 @@ void AtlasEngine::_createResources() /* ppCode */ blob.addressof(), /* ppErrorMsgs */ error.addressof()); + // Unless we can determine otherwise, assume this shader requires evaluation every frame + _r.requiresContinuousRedraw = true; + if (SUCCEEDED(hr)) { THROW_IF_FAILED(_r.device->CreatePixelShader(blob->GetBufferPointer(), blob->GetBufferSize(), nullptr, _r.customPixelShader.put())); + + // Try to determine whether the shader uses the Time variable + wil::com_ptr reflector; + if (SUCCEEDED(D3DReflect(blob->GetBufferPointer(), blob->GetBufferSize(), IID_PPV_ARGS(reflector.put())))) + { + if (ID3D11ShaderReflectionConstantBuffer* constantBufferReflector = reflector->GetConstantBufferByIndex(0)) // shader buffer + { + if (ID3D11ShaderReflectionVariable* variableReflector = constantBufferReflector->GetVariableByIndex(0)) // time + { + D3D11_SHADER_VARIABLE_DESC variableDescriptor; + if (SUCCEEDED(variableReflector->GetDesc(&variableDescriptor))) + { + // only if time is used + _r.requiresContinuousRedraw = WI_IsFlagSet(variableDescriptor.uFlags, D3D_SVF_USED); + } + } + } + } } else { @@ -710,18 +731,17 @@ void AtlasEngine::_createResources() { LOG_HR(hr); } - if (_api.warningCallback) { _api.warningCallback(D2DERR_SHADER_COMPILE_FAILED); } } - - _r.requiresContinuousRedraw = true; } else if (_api.useRetroTerminalEffect) { THROW_IF_FAILED(_r.device->CreatePixelShader(&custom_shader_ps[0], sizeof(custom_shader_ps), nullptr, _r.customPixelShader.put())); + // We know the built-in retro shader doesn't require continuous redraw. + _r.requiresContinuousRedraw = false; } if (_r.customPixelShader) From 7170c84927a15cd0a00db1e5091de18ef9ef4c77 Mon Sep 17 00:00:00 2001 From: Dustin Howett Date: Thu, 1 Sep 2022 13:58:22 -0500 Subject: [PATCH 2/2] Log it boyo --- src/renderer/atlas/AtlasEngine.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/renderer/atlas/AtlasEngine.cpp b/src/renderer/atlas/AtlasEngine.cpp index be66c5749eb..e33ac4fae22 100644 --- a/src/renderer/atlas/AtlasEngine.cpp +++ b/src/renderer/atlas/AtlasEngine.cpp @@ -705,14 +705,14 @@ void AtlasEngine::_createResources() // Try to determine whether the shader uses the Time variable wil::com_ptr reflector; - if (SUCCEEDED(D3DReflect(blob->GetBufferPointer(), blob->GetBufferSize(), IID_PPV_ARGS(reflector.put())))) + if (SUCCEEDED_LOG(D3DReflect(blob->GetBufferPointer(), blob->GetBufferSize(), IID_PPV_ARGS(reflector.put())))) { if (ID3D11ShaderReflectionConstantBuffer* constantBufferReflector = reflector->GetConstantBufferByIndex(0)) // shader buffer { if (ID3D11ShaderReflectionVariable* variableReflector = constantBufferReflector->GetVariableByIndex(0)) // time { D3D11_SHADER_VARIABLE_DESC variableDescriptor; - if (SUCCEEDED(variableReflector->GetDesc(&variableDescriptor))) + if (SUCCEEDED_LOG(variableReflector->GetDesc(&variableDescriptor))) { // only if time is used _r.requiresContinuousRedraw = WI_IsFlagSet(variableDescriptor.uFlags, D3D_SVF_USED);