From b52c1c410cebbd5865186031d4f1b1d91ee84ee3 Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Mon, 28 Jul 2025 17:52:45 -0500 Subject: [PATCH] HAX: make shader cbuffer members movable (descriptor part) --- src/renderer/atlas/BackendD3D.cpp | 59 ++++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 5 deletions(-) diff --git a/src/renderer/atlas/BackendD3D.cpp b/src/renderer/atlas/BackendD3D.cpp index 60ee6aaf1d..9262b77cda 100644 --- a/src/renderer/atlas/BackendD3D.cpp +++ b/src/renderer/atlas/BackendD3D.cpp @@ -5,6 +5,7 @@ #include "BackendD3D.h" #include +#include #include #include @@ -49,6 +50,33 @@ using namespace Microsoft::Console::Render::Atlas; static constexpr D2D1_MATRIX_3X2_F identityTransform{ .m11 = 1, .m22 = 1 }; static constexpr D2D1_COLOR_F whiteColor{ 1, 1, 1, 1 }; +struct CustomShaderMemberDescriptor +{ + const char name[16]; + uint8_t size; +}; + +struct CustomShaderMemberUse +{ + uint8_t used; + UINT off; +}; + +static constexpr CustomShaderMemberDescriptor CustomShaderConstBufferMembers[] = { + { "time", sizeof(f32) }, + { "scale", sizeof(f32) }, + { "resolution", sizeof(f32x2) }, + { "background", sizeof(f32x4) }, +}; + +using shader_member_use_array = std::array>; + +struct CustomShaderUseDescriptor +{ + size_t allocation{ 0 }; + shader_member_use_array uses; +}; + static u64 queryPerfFreq() noexcept { LARGE_INTEGER li; @@ -416,6 +444,8 @@ void BackendD3D::_recreateCustomShader(const RenderingPayload& p) /* ppCode */ blob.addressof(), /* ppErrorMsgs */ error.addressof()); + CustomShaderUseDescriptor csud{}; + if (SUCCEEDED(hr)) { THROW_IF_FAILED(p.device->CreatePixelShader(blob->GetBufferPointer(), blob->GetBufferSize(), nullptr, _customPixelShader.addressof())); @@ -430,13 +460,30 @@ void BackendD3D::_recreateCustomShader(const RenderingPayload& p) // next few lines indicates that the cbuffer is entirely unused (--> _requiresContinuousRedraw=false). if (ID3D11ShaderReflectionConstantBuffer* constantBufferReflector = reflector->GetConstantBufferByIndex(0)) // shader buffer { - if (ID3D11ShaderReflectionVariable* variableReflector = constantBufferReflector->GetVariableByIndex(0)) // time + D3D11_SHADER_BUFFER_DESC desc; + constantBufferReflector->GetDesc(&desc); + for (UINT i = 0; i < desc.Variables; ++i) { - D3D11_SHADER_VARIABLE_DESC variableDescriptor; - if (SUCCEEDED(variableReflector->GetDesc(&variableDescriptor))) + if (ID3D11ShaderReflectionVariable* variableReflector = constantBufferReflector->GetVariableByIndex(i)) { - // only if time is used - _requiresContinuousRedraw = WI_IsFlagSet(variableDescriptor.uFlags, D3D_SVF_USED); + D3D11_SHADER_VARIABLE_DESC variableDescriptor; + if (SUCCEEDED(variableReflector->GetDesc(&variableDescriptor))) + { + auto knownDescriptor = std::find_if(std::begin(CustomShaderConstBufferMembers), std::end(CustomShaderConstBufferMembers), [&](auto&& mem) { + return til::equals_insensitive_ascii(variableDescriptor.Name, mem.name); + }); + + if (knownDescriptor == std::end(CustomShaderConstBufferMembers)) + { + continue; + } + const auto idx = std::distance(std::begin(CustomShaderConstBufferMembers), knownDescriptor); + csud.allocation = std::max(csud.allocation, static_cast(variableDescriptor.StartOffset + variableDescriptor.Size)); + csud.uses[idx].used = 1; + csud.uses[idx].off = variableDescriptor.StartOffset; + // only if time is used + _requiresContinuousRedraw = idx == 0 && WI_IsFlagSet(variableDescriptor.uFlags, D3D_SVF_USED); + } } } } @@ -446,6 +493,8 @@ void BackendD3D::_recreateCustomShader(const RenderingPayload& p) // Unless we can determine otherwise, assume this shader requires evaluation every frame _requiresContinuousRedraw = true; } + + csud.allocation = (csud.allocation + 15) & ~15; } else {