From 3dc7546dd4907b69a206c20c07166295c659a35e Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Fri, 27 Jun 2025 19:06:25 +0200 Subject: [PATCH] Fix crash when constant buffer is unused by shader but still exists --- Source/Engine/Renderer/AmbientOcclusionPass.cpp | 10 +--------- Source/Engine/Renderer/AntiAliasing/FXAA.cpp | 6 +----- Source/Engine/Renderer/AntiAliasing/SMAA.cpp | 8 +------- Source/Engine/Renderer/AntiAliasing/TAA.cpp | 6 +----- Source/Engine/Renderer/AtmospherePreCompute.cpp | 6 +----- Source/Engine/Renderer/ColorGradingPass.cpp | 8 +------- .../Renderer/ContrastAdaptiveSharpeningPass.cpp | 8 +------- Source/Engine/Renderer/DepthOfFieldPass.cpp | 8 +------- Source/Engine/Renderer/EyeAdaptationPass.cpp | 8 +------- Source/Engine/Renderer/HistogramPass.cpp | 8 +------- Source/Engine/Renderer/LightPass.cpp | 14 ++------------ Source/Engine/Renderer/MotionBlurPass.cpp | 10 +--------- Source/Engine/Renderer/PostProcessingPass.cpp | 14 ++------------ Source/Engine/Renderer/ProbesRenderer.cpp | 6 +----- Source/Engine/Renderer/ReflectionsPass.cpp | 8 +------- Source/Engine/Renderer/RendererPass.h | 1 + .../Engine/Renderer/ScreenSpaceReflectionsPass.cpp | 8 +------- Source/Engine/Renderer/ShadowsPass.cpp | 8 +------- Source/Engine/Renderer/Utils/BitonicSort.cpp | 8 +------- Source/Engine/Renderer/Utils/MultiScaler.cpp | 8 +------- Source/Engine/Renderer/VolumetricFogPass.cpp | 14 ++------------ 21 files changed, 24 insertions(+), 151 deletions(-) diff --git a/Source/Engine/Renderer/AmbientOcclusionPass.cpp b/Source/Engine/Renderer/AmbientOcclusionPass.cpp index 5f181ab97..08a8cefcb 100644 --- a/Source/Engine/Renderer/AmbientOcclusionPass.cpp +++ b/Source/Engine/Renderer/AmbientOcclusionPass.cpp @@ -91,17 +91,9 @@ bool AmbientOcclusionPass::setupResources() { // Check shader if (!_shader->IsLoaded()) - { return true; - } const auto shader = _shader->GetShader(); - - // Validate shader constant buffer size - if (shader->GetCB(0)->GetSize() != sizeof(ASSAOConstants)) - { - REPORT_INVALID_SHADER_PASS_CB_SIZE(shader, 0, ASSAOConstants); - return true; - } + CHECK_INVALID_SHADER_PASS_CB_SIZE(shader, 0, ASSAOConstants); // Create pipeline states GPUPipelineState::Description psDesc = GPUPipelineState::Description::DefaultFullscreenTriangle; diff --git a/Source/Engine/Renderer/AntiAliasing/FXAA.cpp b/Source/Engine/Renderer/AntiAliasing/FXAA.cpp index 41926e2d6..00dfb0cdd 100644 --- a/Source/Engine/Renderer/AntiAliasing/FXAA.cpp +++ b/Source/Engine/Renderer/AntiAliasing/FXAA.cpp @@ -36,11 +36,7 @@ bool FXAA::setupResources() return true; } const auto shader = _shader->GetShader(); - if (shader->GetCB(0)->GetSize() != sizeof(Data)) - { - REPORT_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data); - return true; - } + CHECK_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data); GPUPipelineState::Description psDesc; if (!_psFXAA.IsValid()) diff --git a/Source/Engine/Renderer/AntiAliasing/SMAA.cpp b/Source/Engine/Renderer/AntiAliasing/SMAA.cpp index 25007ad7d..2414118d3 100644 --- a/Source/Engine/Renderer/AntiAliasing/SMAA.cpp +++ b/Source/Engine/Renderer/AntiAliasing/SMAA.cpp @@ -45,13 +45,7 @@ bool SMAA::setupResources() return true; } const auto shader = _shader->GetShader(); - - // Validate shader constant buffer size - if (shader->GetCB(0)->GetSize() != sizeof(Data)) - { - REPORT_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data); - return true; - } + CHECK_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data); // Create pipeline state GPUPipelineState::Description psDesc = GPUPipelineState::Description::DefaultFullscreenTriangle; diff --git a/Source/Engine/Renderer/AntiAliasing/TAA.cpp b/Source/Engine/Renderer/AntiAliasing/TAA.cpp index 8bbb6ba81..b772eb45e 100644 --- a/Source/Engine/Renderer/AntiAliasing/TAA.cpp +++ b/Source/Engine/Renderer/AntiAliasing/TAA.cpp @@ -37,11 +37,7 @@ bool TAA::setupResources() if (!_shader->IsLoaded()) return true; const auto shader = _shader->GetShader(); - if (shader->GetCB(0)->GetSize() != sizeof(Data)) - { - REPORT_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data); - return true; - } + CHECK_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data); if (!_psTAA) _psTAA = GPUDevice::Instance->CreatePipelineState(); GPUPipelineState::Description psDesc; diff --git a/Source/Engine/Renderer/AtmospherePreCompute.cpp b/Source/Engine/Renderer/AtmospherePreCompute.cpp index 595ebcca5..b796e828b 100644 --- a/Source/Engine/Renderer/AtmospherePreCompute.cpp +++ b/Source/Engine/Renderer/AtmospherePreCompute.cpp @@ -166,11 +166,7 @@ bool init() } auto shader = _shader->GetShader(); ASSERT(shader->GetCB(0) != nullptr); - if (shader->GetCB(0)->GetSize() != sizeof(Data)) - { - REPORT_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data); - return true; - } + CHECK_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data); // Create pipeline stages _psTransmittance = GPUDevice::Instance->CreatePipelineState(); diff --git a/Source/Engine/Renderer/ColorGradingPass.cpp b/Source/Engine/Renderer/ColorGradingPass.cpp index 43b49f091..322e7d591 100644 --- a/Source/Engine/Renderer/ColorGradingPass.cpp +++ b/Source/Engine/Renderer/ColorGradingPass.cpp @@ -89,13 +89,7 @@ bool ColorGradingPass::setupResources() if (!_shader || !_shader->IsLoaded()) return true; const auto shader = _shader->GetShader(); - - // Validate shader constant buffer size - if (shader->GetCB(0)->GetSize() != sizeof(Data)) - { - REPORT_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data); - return true; - } + CHECK_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data); // Create pipeline stages GPUPipelineState::Description psDesc = GPUPipelineState::Description::DefaultFullscreenTriangle; diff --git a/Source/Engine/Renderer/ContrastAdaptiveSharpeningPass.cpp b/Source/Engine/Renderer/ContrastAdaptiveSharpeningPass.cpp index 6a6fce521..3231c32f8 100644 --- a/Source/Engine/Renderer/ContrastAdaptiveSharpeningPass.cpp +++ b/Source/Engine/Renderer/ContrastAdaptiveSharpeningPass.cpp @@ -48,13 +48,7 @@ bool ContrastAdaptiveSharpeningPass::setupResources() if (!_shader || !_shader->IsLoaded()) return true; const auto shader = _shader->GetShader(); - - // Validate shader constant buffer size - if (shader->GetCB(0)->GetSize() != sizeof(Data)) - { - REPORT_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data); - return true; - } + CHECK_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data); // Create pipeline stage auto psDesc = GPUPipelineState::Description::DefaultFullscreenTriangle; diff --git a/Source/Engine/Renderer/DepthOfFieldPass.cpp b/Source/Engine/Renderer/DepthOfFieldPass.cpp index 25d9ea94f..2c3dc36f8 100644 --- a/Source/Engine/Renderer/DepthOfFieldPass.cpp +++ b/Source/Engine/Renderer/DepthOfFieldPass.cpp @@ -117,13 +117,7 @@ bool DepthOfFieldPass::setupResources() if (!_shader->IsLoaded()) return true; const auto shader = _shader->GetShader(); - - // Validate shader constant buffer size - if (shader->GetCB(0)->GetSize() != sizeof(Data)) - { - REPORT_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data); - return true; - } + CHECK_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data); // Create pipeline stages GPUPipelineState::Description psDesc = GPUPipelineState::Description::DefaultFullscreenTriangle; diff --git a/Source/Engine/Renderer/EyeAdaptationPass.cpp b/Source/Engine/Renderer/EyeAdaptationPass.cpp index 84e826e36..3cf44af1b 100644 --- a/Source/Engine/Renderer/EyeAdaptationPass.cpp +++ b/Source/Engine/Renderer/EyeAdaptationPass.cpp @@ -258,13 +258,7 @@ bool EyeAdaptationPass::setupResources() if (!_shader->IsLoaded()) return true; const auto shader = _shader->GetShader(); - - // Validate shader constant buffer size - if (shader->GetCB(0)->GetSize() != sizeof(EyeAdaptationData)) - { - REPORT_INVALID_SHADER_PASS_CB_SIZE(shader, 0, EyeAdaptationData); - return true; - } + CHECK_INVALID_SHADER_PASS_CB_SIZE(shader, 0, EyeAdaptationData); // Create pipeline stages GPUPipelineState::Description psDesc = GPUPipelineState::Description::DefaultFullscreenTriangle; diff --git a/Source/Engine/Renderer/HistogramPass.cpp b/Source/Engine/Renderer/HistogramPass.cpp index 96f0cca73..9b6e71a77 100644 --- a/Source/Engine/Renderer/HistogramPass.cpp +++ b/Source/Engine/Renderer/HistogramPass.cpp @@ -113,13 +113,7 @@ bool HistogramPass::setupResources() if (!_shader->IsLoaded()) return true; const auto shader = _shader->GetShader(); - - // Validate shader constant buffer size - if (shader->GetCB(0)->GetSize() != sizeof(HistogramData)) - { - REPORT_INVALID_SHADER_PASS_CB_SIZE(shader, 0, HistogramData); - return true; - } + CHECK_INVALID_SHADER_PASS_CB_SIZE(shader, 0, HistogramData); _csClearHistogram = shader->GetCS("CS_ClearHistogram"); _csGenerateHistogram = shader->GetCS("CS_GenerateHistogram"); diff --git a/Source/Engine/Renderer/LightPass.cpp b/Source/Engine/Renderer/LightPass.cpp index 1371a53ee..ee38ee2ac 100644 --- a/Source/Engine/Renderer/LightPass.cpp +++ b/Source/Engine/Renderer/LightPass.cpp @@ -65,18 +65,8 @@ bool LightPass::setupResources() if (!_sphereModel->CanBeRendered() || !_shader->IsLoaded()) return true; auto shader = _shader->GetShader(); - - // Validate shader constant buffers sizes - if (shader->GetCB(0)->GetSize() != sizeof(PerLight)) - { - REPORT_INVALID_SHADER_PASS_CB_SIZE(shader, 0, PerLight); - return true; - } - if (shader->GetCB(1)->GetSize() != sizeof(PerFrame)) - { - REPORT_INVALID_SHADER_PASS_CB_SIZE(shader, 1, PerFrame); - return true; - } + CHECK_INVALID_SHADER_PASS_CB_SIZE(shader, 0, PerLight); + CHECK_INVALID_SHADER_PASS_CB_SIZE(shader, 1, PerFrame); // Create pipeline stages GPUPipelineState::Description psDesc; diff --git a/Source/Engine/Renderer/MotionBlurPass.cpp b/Source/Engine/Renderer/MotionBlurPass.cpp index d8ce05de1..3077e4cdb 100644 --- a/Source/Engine/Renderer/MotionBlurPass.cpp +++ b/Source/Engine/Renderer/MotionBlurPass.cpp @@ -80,17 +80,9 @@ bool MotionBlurPass::setupResources() { // Check shader if (!_shader->IsLoaded()) - { return true; - } const auto shader = _shader->GetShader(); - - // Validate shader constant buffer size - if (shader->GetCB(0)->GetSize() != sizeof(Data)) - { - REPORT_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data); - return true; - } + CHECK_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data); // Create pipeline state GPUPipelineState::Description psDesc = GPUPipelineState::Description::DefaultFullscreenTriangle; diff --git a/Source/Engine/Renderer/PostProcessingPass.cpp b/Source/Engine/Renderer/PostProcessingPass.cpp index 9192c8ca4..bc7a1b820 100644 --- a/Source/Engine/Renderer/PostProcessingPass.cpp +++ b/Source/Engine/Renderer/PostProcessingPass.cpp @@ -98,18 +98,8 @@ bool PostProcessingPass::setupResources() if (!_shader->IsLoaded()) return true; auto shader = _shader->GetShader(); - - // Validate shader constant buffer size - if (shader->GetCB(0)->GetSize() != sizeof(Data)) - { - REPORT_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data); - return true; - } - if (shader->GetCB(1)->GetSize() != sizeof(GaussianBlurData)) - { - REPORT_INVALID_SHADER_PASS_CB_SIZE(shader, 1, GaussianBlurData); - return true; - } + CHECK_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data); + CHECK_INVALID_SHADER_PASS_CB_SIZE(shader, 1, GaussianBlurData); // Create pipeline stages GPUPipelineState::Description psDesc = GPUPipelineState::Description::DefaultFullscreenTriangle; diff --git a/Source/Engine/Renderer/ProbesRenderer.cpp b/Source/Engine/Renderer/ProbesRenderer.cpp index 70705b8a8..ee72afe72 100644 --- a/Source/Engine/Renderer/ProbesRenderer.cpp +++ b/Source/Engine/Renderer/ProbesRenderer.cpp @@ -231,11 +231,7 @@ bool ProbesRenderer::Init() if (!_shader->IsLoaded()) return false; const auto shader = _shader->GetShader(); - if (shader->GetCB(0)->GetSize() != sizeof(Data)) - { - REPORT_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data); - return true; - } + CHECK_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data); // Create pipeline stages _psFilterFace = GPUDevice::Instance->CreatePipelineState(); diff --git a/Source/Engine/Renderer/ReflectionsPass.cpp b/Source/Engine/Renderer/ReflectionsPass.cpp index 631543010..5aa8404ab 100644 --- a/Source/Engine/Renderer/ReflectionsPass.cpp +++ b/Source/Engine/Renderer/ReflectionsPass.cpp @@ -281,13 +281,7 @@ bool ReflectionsPass::setupResources() if (!_sphereModel->CanBeRendered() || !_preIntegratedGF->IsLoaded() || !_shader->IsLoaded()) return true; const auto shader = _shader->GetShader(); - - // Validate shader constant buffer size - if (shader->GetCB(0)->GetSize() != sizeof(Data)) - { - REPORT_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data); - return true; - } + CHECK_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data); // Create pipeline stages GPUPipelineState::Description psDesc; diff --git a/Source/Engine/Renderer/RendererPass.h b/Source/Engine/Renderer/RendererPass.h index 25d887883..32d3b86b9 100644 --- a/Source/Engine/Renderer/RendererPass.h +++ b/Source/Engine/Renderer/RendererPass.h @@ -113,3 +113,4 @@ class RendererPass : public Singleton, public RendererPassBase }; #define REPORT_INVALID_SHADER_PASS_CB_SIZE(shader, index, dataType) LOG(Fatal, "Shader {0} has incorrect constant buffer {1} size: {2} bytes. Expected: {3} bytes", shader->ToString(), index, shader->GetCB(index)->GetSize(), sizeof(dataType)); +#define CHECK_INVALID_SHADER_PASS_CB_SIZE(shader, index, dataType) if (shader->GetCB(index)->GetSize() != sizeof(dataType) && shader->GetCB(index)->GetSize() != 0) { REPORT_INVALID_SHADER_PASS_CB_SIZE(shader, index, dataType); return true; } diff --git a/Source/Engine/Renderer/ScreenSpaceReflectionsPass.cpp b/Source/Engine/Renderer/ScreenSpaceReflectionsPass.cpp index 55c6d79f2..454540eec 100644 --- a/Source/Engine/Renderer/ScreenSpaceReflectionsPass.cpp +++ b/Source/Engine/Renderer/ScreenSpaceReflectionsPass.cpp @@ -89,13 +89,7 @@ bool ScreenSpaceReflectionsPass::setupResources() if (!_shader->IsLoaded()) return true; const auto shader = _shader->GetShader(); - - // Validate shader constant buffer size - if (shader->GetCB(0)->GetSize() != sizeof(Data)) - { - REPORT_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data); - return true; - } + CHECK_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data); // Create pipeline stages GPUPipelineState::Description psDesc = GPUPipelineState::Description::DefaultFullscreenTriangle; diff --git a/Source/Engine/Renderer/ShadowsPass.cpp b/Source/Engine/Renderer/ShadowsPass.cpp index 3937f8554..5cf90876a 100644 --- a/Source/Engine/Renderer/ShadowsPass.cpp +++ b/Source/Engine/Renderer/ShadowsPass.cpp @@ -507,13 +507,7 @@ bool ShadowsPass::setupResources() if (!_sphereModel->CanBeRendered() || !_shader->IsLoaded()) return true; auto shader = _shader->GetShader(); - - // Validate shader constant buffers sizes - if (shader->GetCB(0)->GetSize() != sizeof(Data)) - { - REPORT_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data); - return true; - } + CHECK_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data); // Create pipeline stages GPUPipelineState::Description psDesc; diff --git a/Source/Engine/Renderer/Utils/BitonicSort.cpp b/Source/Engine/Renderer/Utils/BitonicSort.cpp index 73a310832..babc058e2 100644 --- a/Source/Engine/Renderer/Utils/BitonicSort.cpp +++ b/Source/Engine/Renderer/Utils/BitonicSort.cpp @@ -59,14 +59,8 @@ bool BitonicSort::setupResources() if (!_shader->IsLoaded()) return true; const auto shader = _shader->GetShader(); - - // Validate shader constant buffer size _cb = shader->GetCB(0); - if (_cb->GetSize() != sizeof(Data)) - { - REPORT_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data); - return true; - } + CHECK_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data); // Cache compute shaders _indirectArgsCS = shader->GetCS("CS_IndirectArgs"); diff --git a/Source/Engine/Renderer/Utils/MultiScaler.cpp b/Source/Engine/Renderer/Utils/MultiScaler.cpp index 3f812ea77..ae5633834 100644 --- a/Source/Engine/Renderer/Utils/MultiScaler.cpp +++ b/Source/Engine/Renderer/Utils/MultiScaler.cpp @@ -41,13 +41,7 @@ bool MultiScaler::setupResources() if (!_shader->IsLoaded()) return true; const auto shader = _shader->GetShader(); - - // Validate shader constant buffer size - if (shader->GetCB(0)->GetSize() != sizeof(Data)) - { - REPORT_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data); - return true; - } + CHECK_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data); // Create pipeline states GPUPipelineState::Description psDesc = GPUPipelineState::Description::DefaultFullscreenTriangle; diff --git a/Source/Engine/Renderer/VolumetricFogPass.cpp b/Source/Engine/Renderer/VolumetricFogPass.cpp index c56812c72..b7e57c2bb 100644 --- a/Source/Engine/Renderer/VolumetricFogPass.cpp +++ b/Source/Engine/Renderer/VolumetricFogPass.cpp @@ -53,19 +53,9 @@ bool VolumetricFogPass::setupResources() if (!_shader->IsLoaded()) return true; auto shader = _shader->GetShader(); - - // Validate shader constant buffers sizes - if (shader->GetCB(0)->GetSize() != sizeof(Data)) - { - REPORT_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data); - return true; - } + CHECK_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data); // CB1 is used for per-draw info (ObjectIndex) - if (shader->GetCB(2)->GetSize() != sizeof(PerLight)) - { - REPORT_INVALID_SHADER_PASS_CB_SIZE(shader, 2, PerLight); - return true; - } + CHECK_INVALID_SHADER_PASS_CB_SIZE(shader, 2, PerLight); // Cache compute shaders _csInitialize = shader->GetCS("CS_Initialize");