D3D12阴影渲染报错:采样数/质量与渲染目标格式不兼容
D3D12阴影渲染管线创建错误排查与解决
错误日志
D3D12 ERROR: ID3D12Device::CreateGraphicsPipelineState: The specified sample count or quality is not supported with the render target format in slot 1 [ STATE_CREATION ERROR #685: CREATEGRAPHICSPIPELINESTATE_INVALID_SAMPLE_DESC] D3D12 ERROR: ID3D12Device::CreateGraphicsPipelineState: The specified sample count or quality is not supported with the render target format in slot 2 [ STATE_CREATION ERROR #685: CREATEGRAPHICSPIPELINESTATE_INVALID_SAMPLE_DESC] D3D12 ERROR: ID3D12Device::CreateGraphicsPipelineState: The specified sample count or quality is not supported with the render target format in slot 3 [ STATE_CREATION ERROR #685: CREATEGRAPHICSPIPELINESTATE_INVALID_SAMPLE_DESC] D3D12 ERROR: ID3D12Device::CreateGraphicsPipelineState: The specified sample count or quality is not supported with the render target format in slot 4 [ STATE_CREATION ERROR #685: CREATEGRAPHICSPIPELINESTATE_INVALID_SAMPLE_DESC]
问题根源
渲染目标数量与格式数组不匹配:
在Stage::BuildObjects中创建Shader时,统一传入了nRenderTargets=5,但:m_pDepthRenderShader对应的RtvFormats数组仅包含1个格式值,循环赋值时i=1到4会访问数组越界,导致这些位置的格式为内存垃圾值,无效格式无法支持采样数1的配置。m_pShadowShader和m_pShadowMapToViewport传入pdxgiRtvFormats=NULL,会默认将5个渲染目标都设为DXGI_FORMAT_R8G8B8A8_UNORM,但这类Shader实际不需要这么多渲染目标,且格式与后续绑定的资源不匹配。
采样数与格式兼容性:
越界产生的无效渲染目标格式,本身不支持SampleDesc.Count=1的采样配置,触发D3D12格式兼容性检查错误。
解决方案
1. 修正渲染目标数量参数
根据每个Shader的实际需求传递正确的nRenderTargets值:
m_pDepthRenderShader仅需要1个渲染目标,将参数从5改为1;m_pShadowShader仅用于深度渲染(无颜色渲染目标输出),将nRenderTargets设为0;m_pShadowMapToViewport输出到单个视口,将nRenderTargets设为1。
2. 修改后的代码示例
m_ppShaders[0] = pBoxShader; m_pDepthRenderShader = new CDepthRenderShader(pBoxShader, m_pLights); DXGI_FORMAT RtvFormats[1] = { DXGI_FORMAT_R32_FLOAT }; // 修正nRenderTargets为1 m_pDepthRenderShader->CreateShader(pd3dDevice, m_pd3dGraphicsRootSignature, D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE, 1, RtvFormats, DXGI_FORMAT_D32_FLOAT); m_pDepthRenderShader->BuildObjects(pd3dDevice, pd3dCommandList, NULL); m_pShadowShader = new CShadowMapShader(pBoxShader); // 修正nRenderTargets为0(无颜色渲染目标) m_pShadowShader->CreateShader(pd3dDevice, m_pd3dGraphicsRootSignature, D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE, 0, NULL, DXGI_FORMAT_D24_UNORM_S8_UINT); m_pShadowShader->BuildObjects(pd3dDevice, pd3dCommandList, m_pDepthRenderShader->GetDepthTexture()); m_pShadowMapToViewport = new CTextureToViewportShader(); // 修正nRenderTargets为1(单个视口输出) m_pShadowMapToViewport->CreateShader(pd3dDevice, m_pd3dGraphicsRootSignature, D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE, 1, NULL, DXGI_FORMAT_D24_UNORM_S8_UINT); m_pShadowMapToViewport->BuildObjects(pd3dDevice, pd3dCommandList, m_pDepthRenderShader->GetDepthTexture());
3. 额外检查
确保CreateShader函数中,当pdxgiRtvFormats不为NULL时,数组长度与nRenderTargets严格匹配,彻底避免越界访问问题。
内容的提问来源于stack exchange,提问作者yoon-0012
相关产品推荐
相关产品推荐

