diff options
| author | assiduous <assiduous@diligentgraphics.com> | 2021-02-18 06:16:59 +0000 |
|---|---|---|
| committer | assiduous <assiduous@diligentgraphics.com> | 2021-03-19 00:38:08 +0000 |
| commit | c7091068f37f57dbfbb9cfbf3e8ff190a961ecc7 (patch) | |
| tree | 28efb36f29de18443f2c55ba46c1b74312063e23 | |
| parent | Added PipelineResourceSignatureTest.StructuredBuffers test (diff) | |
| download | DiligentCore-c7091068f37f57dbfbb9cfbf3e8ff190a961ecc7.tar.gz DiligentCore-c7091068f37f57dbfbb9cfbf3e8ff190a961ecc7.zip | |
Imlemented workarounds for tests failing due to D3D12 WARP resource array indexing bug
6 files changed, 194 insertions, 78 deletions
diff --git a/Tests/DiligentCoreAPITest/include/TestingEnvironment.hpp b/Tests/DiligentCoreAPITest/include/TestingEnvironment.hpp index 09eaae20..4e66f44b 100644 --- a/Tests/DiligentCoreAPITest/include/TestingEnvironment.hpp +++ b/Tests/DiligentCoreAPITest/include/TestingEnvironment.hpp @@ -112,6 +112,11 @@ public: static const char* GetCurrentTestStatusString(); static const char* GetTestSkippedString(); + bool NeedWARPResourceArrayIndexingBugWorkaround() const + { + return m_NeedWARPResourceArrayIndexingBugWorkaround; + } + protected: NativeWindow CreateNativeWindow(); @@ -145,6 +150,11 @@ protected: SHADER_COMPILER m_ShaderCompiler = SHADER_COMPILER_DEFAULT; static std::atomic_int m_NumAllowedErrors; + + // As of Windows version 2004 (build 19041), there is a bug in D3D12 WARP rasterizer: + // Shader resource array indexing always references array element 0 when shaders are compiled. + // A workaround is to use SM5.0 and default shader compiler. + bool m_NeedWARPResourceArrayIndexingBugWorkaround = false; }; } // namespace Testing diff --git a/Tests/DiligentCoreAPITest/src/D3D12/TestingEnvironmentD3D12.cpp b/Tests/DiligentCoreAPITest/src/D3D12/TestingEnvironmentD3D12.cpp index 32cf6e95..99aa1367 100644 --- a/Tests/DiligentCoreAPITest/src/D3D12/TestingEnvironmentD3D12.cpp +++ b/Tests/DiligentCoreAPITest/src/D3D12/TestingEnvironmentD3D12.cpp @@ -62,6 +62,15 @@ TestingEnvironmentD3D12::TestingEnvironmentD3D12(const CreateInfo& CI, { CreateTestingSwapChainD3D12(m_pDevice, GetDeviceContext(), SCDesc, &m_pSwapChain); } + + // As of Windows version 2004 (build 19041), there is a bug in D3D12 WARP rasterizer: + // Shader resource array indexing always references array element 0 when shaders are compiled + // with shader model 5.1: + // AllCorrect *= CheckValue(g_Tex2DArr_Static[0].SampleLevel(g_Sampler, UV.xy, 0.0), Tex2DArr_Static_Ref0); // OK + // AllCorrect *= CheckValue(g_Tex2DArr_Static[1].SampleLevel(g_Sampler, UV.xy, 0.0), Tex2DArr_Static_Ref1); // FAIL - g_Tex2DArr_Static[0] is sampled + // The shaders work OK when using shader model 5.0 with old compiler. + // TODO: this should be fixed in the next Windows release - verify. + m_NeedWARPResourceArrayIndexingBugWorkaround = GetAdapterType() == ADAPTER_TYPE_SOFTWARE; } TestingEnvironmentD3D12::~TestingEnvironmentD3D12() diff --git a/Tests/DiligentCoreAPITest/src/DrawCommandTest.cpp b/Tests/DiligentCoreAPITest/src/DrawCommandTest.cpp index b9dc4b68..a62f310d 100644 --- a/Tests/DiligentCoreAPITest/src/DrawCommandTest.cpp +++ b/Tests/DiligentCoreAPITest/src/DrawCommandTest.cpp @@ -2155,6 +2155,15 @@ void DrawCommandTest::TestStructuredOrFormattedBuffers(BUFFER_MODE BuffMode, ShaderCI.SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL; ShaderCI.ShaderCompiler = pEnv->GetDefaultCompiler(ShaderCI.SourceLanguage); ShaderCI.UseCombinedTextureSamplers = true; + if (UseArray && pEnv->NeedWARPResourceArrayIndexingBugWorkaround()) + { + // As of Windows version 2004 (build 19041), there is a bug in D3D12 WARP rasterizer: + // Shader resource array indexing always references array element 0 when shaders are compiled + // with shader model 5.1. + // Use SM5.0 with old compiler as a workaround. + ShaderCI.ShaderCompiler = SHADER_COMPILER_DEFAULT; + ShaderCI.HLSLVersion = ShaderVersion{5, 0}; + } RefCntAutoPtr<IShader> pVS; { diff --git a/Tests/DiligentCoreAPITest/src/PipelineResourceSignatureTest.cpp b/Tests/DiligentCoreAPITest/src/PipelineResourceSignatureTest.cpp index 09c79421..384a787b 100644 --- a/Tests/DiligentCoreAPITest/src/PipelineResourceSignatureTest.cpp +++ b/Tests/DiligentCoreAPITest/src/PipelineResourceSignatureTest.cpp @@ -97,41 +97,41 @@ protected: return pPSO; } - static RefCntAutoPtr<IShader> CreateShaderFromFile(SHADER_TYPE ShaderType, - const char* File, - const char* EntryPoint, - const char* Name, - bool UseCombinedSamplers, - const ShaderMacro* Macros = nullptr, - SHADER_SOURCE_LANGUAGE SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL) + template <typename ModifyCIHandlerType> + static RefCntAutoPtr<IShader> CreateShaderFromFile(SHADER_TYPE ShaderType, + const char* File, + const char* EntryPoint, + const char* Name, + const ShaderMacro* Macros, + ModifyCIHandlerType ModifyCIHandler) { ShaderCreateInfo ShaderCI; ShaderCI.pShaderSourceStreamFactory = pShaderSourceFactory; - ShaderCI.SourceLanguage = SourceLanguage; + ShaderCI.SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL; ShaderCI.FilePath = File; ShaderCI.Macros = Macros; ShaderCI.Desc.Name = Name; ShaderCI.EntryPoint = EntryPoint; ShaderCI.Desc.ShaderType = ShaderType; - ShaderCI.UseCombinedTextureSamplers = UseCombinedSamplers; + ShaderCI.UseCombinedTextureSamplers = false; auto* pDevice = TestingEnvironment::GetInstance()->GetDevice(); if (pDevice->GetDeviceCaps().IsGLDevice()) ShaderCI.UseCombinedTextureSamplers = true; + ModifyCIHandler(ShaderCI); RefCntAutoPtr<IShader> pShader; pDevice->CreateShader(ShaderCI, &pShader); return pShader; } - static RefCntAutoPtr<IShader> CreateShaderFromFile(SHADER_TYPE ShaderType, - const char* File, - const char* EntryPoint, - const char* Name, - const ShaderMacro* Macros = nullptr, - SHADER_SOURCE_LANGUAGE SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL) + static RefCntAutoPtr<IShader> CreateShaderFromFile(SHADER_TYPE ShaderType, + const char* File, + const char* EntryPoint, + const char* Name, + const ShaderMacro* Macros = nullptr) { - return CreateShaderFromFile(ShaderType, File, EntryPoint, Name, false, Macros, SourceLanguage); + return CreateShaderFromFile(ShaderType, File, EntryPoint, Name, Macros, [&](ShaderCreateInfo& ShaderCI) {}); } static RefCntAutoPtr<IShader> CreateShaderFromSource(SHADER_TYPE ShaderType, @@ -251,8 +251,19 @@ TEST_F(PipelineResourceSignatureTest, VariableTypes) for (Uint32 i = 0; i < DynamicTexArraySize; ++i) Macros.AddShaderMacro((std::string{"Tex2DArr_Dyn_Ref"} + std::to_string(i)).c_str(), RefTextures.GetColor(Tex2DArr_DynIdx + i)); - auto pVS = CreateShaderFromFile(SHADER_TYPE_VERTEX, "shaders/ShaderResourceLayout/Textures.hlsl", "VSMain", "PRS variable types test: VS", Macros); - auto pPS = CreateShaderFromFile(SHADER_TYPE_PIXEL, "shaders/ShaderResourceLayout/Textures.hlsl", "PSMain", "PRS variable types test: PS", Macros); + auto ModifyShaderCI = [pEnv](ShaderCreateInfo& ShaderCI) { + if (pEnv->NeedWARPResourceArrayIndexingBugWorkaround()) + { + // As of Windows version 2004 (build 19041), there is a bug in D3D12 WARP rasterizer: + // Shader resource array indexing always references array element 0 when shaders are compiled + // with shader model 5.1. + // Use SM5.0 with old compiler as a workaround. + ShaderCI.ShaderCompiler = SHADER_COMPILER_DEFAULT; + ShaderCI.HLSLVersion = ShaderVersion{5, 0}; + } + }; + auto pVS = CreateShaderFromFile(SHADER_TYPE_VERTEX, "shaders/ShaderResourceLayout/Textures.hlsl", "VSMain", "PRS variable types test: VS", Macros, ModifyShaderCI); + auto pPS = CreateShaderFromFile(SHADER_TYPE_PIXEL, "shaders/ShaderResourceLayout/Textures.hlsl", "PSMain", "PRS variable types test: PS", Macros, ModifyShaderCI); ASSERT_TRUE(pVS && pPS); PipelineResourceSignatureDesc PRSDesc; @@ -727,8 +738,11 @@ TEST_F(PipelineResourceSignatureTest, ImmutableSamplers2) Macros.AddShaderMacro("Tex2D_Ref", RefTextures.GetColor(0)); Macros.AddShaderMacro("Buff_Ref", RefBuffers.GetValue(0)); - auto pVS = CreateShaderFromFile(SHADER_TYPE_VERTEX, "ImmutableSamplers2.hlsl", "VSMain", "PRS static samplers test: VS", true, Macros); - auto pPS = CreateShaderFromFile(SHADER_TYPE_PIXEL, "ImmutableSamplers2.hlsl", "PSMain", "PRS static samplers test: PS", true, Macros); + auto SetUseCombinedSamplers = [](ShaderCreateInfo& ShaderCI) { + ShaderCI.UseCombinedTextureSamplers = true; + }; + auto pVS = CreateShaderFromFile(SHADER_TYPE_VERTEX, "ImmutableSamplers2.hlsl", "VSMain", "PRS static samplers test: VS", Macros, SetUseCombinedSamplers); + auto pPS = CreateShaderFromFile(SHADER_TYPE_PIXEL, "ImmutableSamplers2.hlsl", "PSMain", "PRS static samplers test: PS", Macros, SetUseCombinedSamplers); ASSERT_TRUE(pVS && pPS); PSOCreateInfo.pVS = pVS; @@ -1344,8 +1358,22 @@ void PipelineResourceSignatureTest::TestFormattedOrStructuredBuffer(BUFFER_MODE for (Uint32 i = 0; i < DynamicBuffArraySize; ++i) Macros.AddShaderMacro((std::string{"BuffArr_Dyn_Ref"} + std::to_string(i)).c_str(), RefBuffers.GetValue(BuffArr_DynIdx + i)); - auto pVS = CreateShaderFromFile(SHADER_TYPE_VERTEX, ShaderPath, VSEntry, "PRS FormattedBuffers - VS", Macros, SrcLanguage); - auto pPS = CreateShaderFromFile(SHADER_TYPE_PIXEL, ShaderPath, PSEntry, "PRS FormattedBuffers - PS", Macros, SrcLanguage); + auto ModifyShaderCI = [&](ShaderCreateInfo& ShaderCI) { + ShaderCI.SourceLanguage = SrcLanguage; + + if (pEnv->NeedWARPResourceArrayIndexingBugWorkaround()) + { + // As of Windows version 2004 (build 19041), there is a bug in D3D12 WARP rasterizer: + // Shader resource array indexing always references array element 0 when shaders are compiled + // with shader model 5.1. + // Use SM5.0 with old compiler as a workaround. + ShaderCI.ShaderCompiler = SHADER_COMPILER_DEFAULT; + ShaderCI.HLSLVersion = ShaderVersion{5, 0}; + } + }; + + auto pVS = CreateShaderFromFile(SHADER_TYPE_VERTEX, ShaderPath, VSEntry, "PRS FormattedBuffers - VS", Macros, ModifyShaderCI); + auto pPS = CreateShaderFromFile(SHADER_TYPE_PIXEL, ShaderPath, PSEntry, "PRS FormattedBuffers - PS", Macros, ModifyShaderCI); ASSERT_TRUE(pVS && pPS); PipelineResourceSignatureDesc PRSDesc; diff --git a/Tests/DiligentCoreAPITest/src/ShaderResourceLayoutTest.cpp b/Tests/DiligentCoreAPITest/src/ShaderResourceLayoutTest.cpp index 3d7d5768..86152e5f 100644 --- a/Tests/DiligentCoreAPITest/src/ShaderResourceLayoutTest.cpp +++ b/Tests/DiligentCoreAPITest/src/ShaderResourceLayoutTest.cpp @@ -244,9 +244,10 @@ void ShaderResourceLayoutTest::TestTexturesAndImtblSamplers(bool TestImtblSample { TestingEnvironment::ScopedReset EnvironmentAutoReset; - auto* pEnv = TestingEnvironment::GetInstance(); - auto* pDevice = pEnv->GetDevice(); - auto* pSwapChain = pEnv->GetSwapChain(); + auto* const pEnv = TestingEnvironment::GetInstance(); + auto* const pDevice = pEnv->GetDevice(); + auto* const pSwapChain = pEnv->GetSwapChain(); + const auto& deviceCaps = pDevice->GetDeviceCaps(); float ClearColor[] = {0.25, 0.5, 0.75, 0.125}; RenderDrawCommandReference(pSwapChain, ClearColor); @@ -274,6 +275,9 @@ void ShaderResourceLayoutTest::TestTexturesAndImtblSamplers(bool TestImtblSample static constexpr size_t Tex2DArr_MutIdx[] = {3, 5}; static constexpr size_t Tex2DArr_DynIdx[] = {9, 2}; + const Uint32 VSResArrId = 0; + const Uint32 PSResArrId = deviceCaps.Features.SeparablePrograms ? 1 : 0; + VERIFY_EXPR(deviceCaps.IsGLDevice() || PSResArrId != VSResArrId); // clang-format off std::vector<ShaderResourceDesc> Resources = @@ -285,7 +289,7 @@ void ShaderResourceLayoutTest::TestTexturesAndImtblSamplers(bool TestImtblSample ShaderResourceDesc{"g_Tex2DArr_Mut", SHADER_RESOURCE_TYPE_TEXTURE_SRV, MutableTexArraySize}, ShaderResourceDesc{"g_Tex2DArr_Dyn", SHADER_RESOURCE_TYPE_TEXTURE_SRV, DynamicTexArraySize} }; - if (!pDevice->GetDeviceCaps().IsGLDevice()) + if (!deviceCaps.IsGLDevice()) { if (TestImtblSamplers) { @@ -331,7 +335,7 @@ void ShaderResourceLayoutTest::TestTexturesAndImtblSamplers(bool TestImtblSample return static_cast<const ShaderMacro*>(Macros); }; - auto ModifyShaderCI = [TestImtblSamplers](ShaderCreateInfo& ShaderCI) { + auto ModifyShaderCI = [TestImtblSamplers, pEnv](ShaderCreateInfo& ShaderCI) { if (TestImtblSamplers) { ShaderCI.UseCombinedTextureSamplers = true; @@ -339,19 +343,26 @@ void ShaderResourceLayoutTest::TestTexturesAndImtblSamplers(bool TestImtblSample ShaderCI.ShaderCompiler = SHADER_COMPILER_DEFAULT; ShaderCI.HLSLVersion = ShaderVersion{5, 0}; } + + if (pEnv->NeedWARPResourceArrayIndexingBugWorkaround()) + { + // Due to bug in D3D12 WARP, we have to use SM5.0 with old compiler + ShaderCI.ShaderCompiler = SHADER_COMPILER_DEFAULT; + ShaderCI.HLSLVersion = ShaderVersion{5, 0}; + } }; auto pVS = CreateShader(TestImtblSamplers ? "ShaderResourceLayoutTest.ImtblSamplers - VS" : "ShaderResourceLayoutTest.Textures - VS", TestImtblSamplers ? "ImmutableSamplers.hlsl" : "Textures.hlsl", "VSMain", - SHADER_TYPE_VERTEX, SHADER_SOURCE_LANGUAGE_HLSL, PrepareMacros(0), + SHADER_TYPE_VERTEX, SHADER_SOURCE_LANGUAGE_HLSL, PrepareMacros(VSResArrId), Resources.data(), static_cast<Uint32>(Resources.size()), ModifyShaderCI); auto pPS = CreateShader(TestImtblSamplers ? "ShaderResourceLayoutTest.ImtblSamplers - PS" : "ShaderResourceLayoutTest.Textures - PS", TestImtblSamplers ? "ImmutableSamplers.hlsl" : "Textures.hlsl", "PSMain", - SHADER_TYPE_PIXEL, SHADER_SOURCE_LANGUAGE_HLSL, PrepareMacros(1), + SHADER_TYPE_PIXEL, SHADER_SOURCE_LANGUAGE_HLSL, PrepareMacros(PSResArrId), Resources.data(), static_cast<Uint32>(Resources.size()), ModifyShaderCI); ASSERT_NE(pVS, nullptr); @@ -398,7 +409,7 @@ void ShaderResourceLayoutTest::TestTexturesAndImtblSamplers(bool TestImtblSample ASSERT_NE(pSRB, nullptr); auto BindResources = [&](SHADER_TYPE ShaderType) { - const auto id = ShaderType == SHADER_TYPE_VERTEX ? 0 : 1; + const auto id = ShaderType == SHADER_TYPE_VERTEX ? VSResArrId : PSResArrId; SET_STATIC_VAR(pPSO, ShaderType, "g_Tex2D_Static", Set, RefTextures.GetViewObjects(Tex2D_StaticIdx[id])[0]); SET_STATIC_VAR(pPSO, ShaderType, "g_Tex2DArr_Static", SetArray, RefTextures.GetViewObjects(Tex2DArr_StaticIdx[id]), 0, StaticTexArraySize); @@ -427,13 +438,13 @@ void ShaderResourceLayoutTest::TestTexturesAndImtblSamplers(bool TestImtblSample DrawAttribs DrawAttrs{6, DRAW_FLAG_VERIFY_ALL}; pContext->Draw(DrawAttrs); - SET_SRB_VAR(pSRB, SHADER_TYPE_VERTEX, "g_Tex2D_Dyn", Set, RefTextures.GetViewObjects(Tex2D_DynIdx[0])[0]); - SET_SRB_VAR(pSRB, SHADER_TYPE_VERTEX, "g_Tex2DArr_Dyn", SetArray, RefTextures.GetViewObjects(Tex2DArr_DynIdx[0]), 0, 1); - SET_SRB_VAR(pSRB, SHADER_TYPE_VERTEX, "g_Tex2DArr_Dyn", SetArray, RefTextures.GetViewObjects(Tex2DArr_DynIdx[0] + 1), 1, DynamicTexArraySize - 1); + SET_SRB_VAR(pSRB, SHADER_TYPE_VERTEX, "g_Tex2D_Dyn", Set, RefTextures.GetViewObjects(Tex2D_DynIdx[VSResArrId])[0]); + SET_SRB_VAR(pSRB, SHADER_TYPE_VERTEX, "g_Tex2DArr_Dyn", SetArray, RefTextures.GetViewObjects(Tex2DArr_DynIdx[VSResArrId]), 0, 1); + SET_SRB_VAR(pSRB, SHADER_TYPE_VERTEX, "g_Tex2DArr_Dyn", SetArray, RefTextures.GetViewObjects(Tex2DArr_DynIdx[VSResArrId] + 1), 1, DynamicTexArraySize - 1); - SET_SRB_VAR(pSRB, SHADER_TYPE_PIXEL, "g_Tex2D_Dyn", Set, RefTextures.GetViewObjects(Tex2D_DynIdx[1])[0]); - SET_SRB_VAR(pSRB, SHADER_TYPE_PIXEL, "g_Tex2DArr_Dyn", SetArray, RefTextures.GetViewObjects(Tex2DArr_DynIdx[1]), 0, 1); - SET_SRB_VAR(pSRB, SHADER_TYPE_PIXEL, "g_Tex2DArr_Dyn", SetArray, RefTextures.GetViewObjects(Tex2DArr_DynIdx[1] + 1), 1, DynamicTexArraySize - 1); + SET_SRB_VAR(pSRB, SHADER_TYPE_PIXEL, "g_Tex2D_Dyn", Set, RefTextures.GetViewObjects(Tex2D_DynIdx[PSResArrId])[0]); + SET_SRB_VAR(pSRB, SHADER_TYPE_PIXEL, "g_Tex2DArr_Dyn", SetArray, RefTextures.GetViewObjects(Tex2DArr_DynIdx[PSResArrId]), 0, 1); + SET_SRB_VAR(pSRB, SHADER_TYPE_PIXEL, "g_Tex2DArr_Dyn", SetArray, RefTextures.GetViewObjects(Tex2DArr_DynIdx[PSResArrId] + 1), 1, DynamicTexArraySize - 1); pContext->CommitShaderResources(pSRB, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); @@ -457,9 +468,10 @@ void ShaderResourceLayoutTest::TestStructuredOrFormattedBuffer(bool IsFormatted) { TestingEnvironment::ScopedReset EnvironmentAutoReset; - auto* pEnv = TestingEnvironment::GetInstance(); - auto* pDevice = pEnv->GetDevice(); - auto* pSwapChain = pEnv->GetSwapChain(); + auto* const pEnv = TestingEnvironment::GetInstance(); + auto* const pDevice = pEnv->GetDevice(); + auto* const pSwapChain = pEnv->GetSwapChain(); + const auto& deviceCaps = pDevice->GetDeviceCaps(); float ClearColor[] = {0.625, 0.125, 0.25, 0.875}; RenderDrawCommandReference(pSwapChain, ClearColor); @@ -486,6 +498,10 @@ void ShaderResourceLayoutTest::TestStructuredOrFormattedBuffer(bool IsFormatted) static constexpr size_t BuffArr_MutIdx[] = {3, 4}; static constexpr size_t BuffArr_DynIdx[] = {6, 7}; + const Uint32 VSResArrId = 0; + const Uint32 PSResArrId = deviceCaps.Features.SeparablePrograms ? 1 : 0; + VERIFY_EXPR(deviceCaps.IsGLDevice() || PSResArrId != VSResArrId); + ShaderMacroHelper Macros; auto PrepareMacros = [&](Uint32 s, SHADER_SOURCE_LANGUAGE Lang) { @@ -517,8 +533,6 @@ void ShaderResourceLayoutTest::TestStructuredOrFormattedBuffer(bool IsFormatted) return static_cast<const ShaderMacro*>(Macros); }; - const auto& deviceCaps = pDevice->GetDeviceCaps(); - // Vulkan only allows 16 dynamic storage buffer bindings among all stages, so // use arrays only in fragment shader for structured buffer test. const auto UseArraysInPSOnly = !IsFormatted && (deviceCaps.IsVulkanDevice() || deviceCaps.IsMetalDevice()); @@ -560,10 +574,19 @@ void ShaderResourceLayoutTest::TestStructuredOrFormattedBuffer(bool IsFormatted) GTEST_FAIL() << "Unexpected device type"; } + auto ModifyShaderCI = [pEnv](ShaderCreateInfo& ShaderCI) { + if (pEnv->NeedWARPResourceArrayIndexingBugWorkaround()) + { + // Due to bug in D3D12 WARP, we have to use SM5.0 with old compiler + ShaderCI.ShaderCompiler = SHADER_COMPILER_DEFAULT; + ShaderCI.HLSLVersion = ShaderVersion{5, 0}; + } + }; auto pVS = CreateShader(IsFormatted ? "ShaderResourceLayoutTest.FormattedBuffers - VS" : "ShaderResourceLayoutTest.StructuredBuffers - VS", ShaderFileName, SrcLang == SHADER_SOURCE_LANGUAGE_HLSL ? "VSMain" : "main", - SHADER_TYPE_VERTEX, SrcLang, PrepareMacros(0, SrcLang), - Resources.data(), static_cast<Uint32>(Resources.size())); + SHADER_TYPE_VERTEX, SrcLang, PrepareMacros(VSResArrId, SrcLang), + Resources.data(), static_cast<Uint32>(Resources.size()), + ModifyShaderCI); if (UseArraysInPSOnly) { AddArrayResources(); @@ -571,8 +594,9 @@ void ShaderResourceLayoutTest::TestStructuredOrFormattedBuffer(bool IsFormatted) auto pPS = CreateShader(IsFormatted ? "ShaderResourceLayoutTest.FormattedBuffers - PS" : "ShaderResourceLayoutTest.StructuredBuffers - PS", ShaderFileName, SrcLang == SHADER_SOURCE_LANGUAGE_HLSL ? "PSMain" : "main", - SHADER_TYPE_PIXEL, SrcLang, PrepareMacros(1, SrcLang), - Resources.data(), static_cast<Uint32>(Resources.size())); + SHADER_TYPE_PIXEL, SrcLang, PrepareMacros(PSResArrId, SrcLang), + Resources.data(), static_cast<Uint32>(Resources.size()), + ModifyShaderCI); ASSERT_NE(pVS, nullptr); ASSERT_NE(pPS, nullptr); @@ -602,7 +626,7 @@ void ShaderResourceLayoutTest::TestStructuredOrFormattedBuffer(bool IsFormatted) ASSERT_NE(pSRB, nullptr); auto BindResources = [&](SHADER_TYPE ShaderType) { - const auto id = ShaderType == SHADER_TYPE_VERTEX ? 0 : 1; + const auto id = ShaderType == SHADER_TYPE_VERTEX ? VSResArrId : PSResArrId; SET_STATIC_VAR(pPSO, ShaderType, "g_Buff_Static", Set, RefBuffers.GetViewObjects(Buff_StaticIdx[id])[0]); @@ -647,15 +671,15 @@ void ShaderResourceLayoutTest::TestStructuredOrFormattedBuffer(bool IsFormatted) DrawAttribs DrawAttrs{6, DRAW_FLAG_VERIFY_ALL}; pContext->Draw(DrawAttrs); - SET_SRB_VAR(pSRB, SHADER_TYPE_VERTEX, "g_Buff_Dyn", Set, RefBuffers.GetViewObjects(Buff_DynIdx[0])[0]); + SET_SRB_VAR(pSRB, SHADER_TYPE_VERTEX, "g_Buff_Dyn", Set, RefBuffers.GetViewObjects(Buff_DynIdx[VSResArrId])[0]); if (!UseArraysInPSOnly) { - SET_SRB_VAR(pSRB, SHADER_TYPE_VERTEX, "g_BuffArr_Dyn", SetArray, RefBuffers.GetViewObjects(BuffArr_DynIdx[0] + 0), 0, 1); - SET_SRB_VAR(pSRB, SHADER_TYPE_VERTEX, "g_BuffArr_Dyn", SetArray, RefBuffers.GetViewObjects(BuffArr_DynIdx[0] + 1), 1, 1); + SET_SRB_VAR(pSRB, SHADER_TYPE_VERTEX, "g_BuffArr_Dyn", SetArray, RefBuffers.GetViewObjects(BuffArr_DynIdx[VSResArrId] + 0), 0, 1); + SET_SRB_VAR(pSRB, SHADER_TYPE_VERTEX, "g_BuffArr_Dyn", SetArray, RefBuffers.GetViewObjects(BuffArr_DynIdx[VSResArrId] + 1), 1, 1); } - SET_SRB_VAR(pSRB, SHADER_TYPE_PIXEL, "g_Buff_Dyn", Set, RefBuffers.GetViewObjects(Buff_DynIdx[1])[0]); - SET_SRB_VAR(pSRB, SHADER_TYPE_PIXEL, "g_BuffArr_Dyn", SetArray, RefBuffers.GetViewObjects(BuffArr_DynIdx[1]), 0, DynamicBuffArraySize); + SET_SRB_VAR(pSRB, SHADER_TYPE_PIXEL, "g_Buff_Dyn", Set, RefBuffers.GetViewObjects(Buff_DynIdx[PSResArrId])[0]); + SET_SRB_VAR(pSRB, SHADER_TYPE_PIXEL, "g_BuffArr_Dyn", SetArray, RefBuffers.GetViewObjects(BuffArr_DynIdx[PSResArrId]), 0, DynamicBuffArraySize); pContext->CommitShaderResources(pSRB, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); @@ -688,27 +712,31 @@ void ShaderResourceLayoutTest::TestRWStructuredOrFormattedBuffer(bool IsFormatte { TestingEnvironment::ScopedReset EnvironmentAutoReset; - auto* pEnv = TestingEnvironment::GetInstance(); - auto* pDevice = pEnv->GetDevice(); - auto* pSwapChain = pEnv->GetSwapChain(); + auto* const pEnv = TestingEnvironment::GetInstance(); + auto* const pDevice = pEnv->GetDevice(); + auto* const pSwapChain = pEnv->GetSwapChain(); ComputeShaderReference(pSwapChain); const auto& deviceCaps = pDevice->GetDeviceCaps(); auto deviceType = deviceCaps.DevType; + constexpr Uint32 MaxStaticBuffArraySize = 4; + constexpr Uint32 MaxMutableBuffArraySize = 3; + constexpr Uint32 MaxDynamicBuffArraySize = 2; + // Prepare buffers with reference values ReferenceBuffers RefBuffers{ - 3 + 4 + 3 + 2, + 3 + MaxStaticBuffArraySize + MaxMutableBuffArraySize + MaxDynamicBuffArraySize + 1, // Extra buffer for dynamic variables USAGE_DEFAULT, BIND_UNORDERED_ACCESS, BUFFER_VIEW_UNORDERED_ACCESS, IsFormatted ? BUFFER_MODE_FORMATTED : BUFFER_MODE_STRUCTURED // }; - const Uint32 StaticBuffArraySize = deviceType == RENDER_DEVICE_TYPE_D3D11 || deviceCaps.IsGLDevice() ? 1 : 4; - const Uint32 MutableBuffArraySize = deviceType == RENDER_DEVICE_TYPE_D3D11 || deviceCaps.IsGLDevice() ? 2 : 3; - const Uint32 DynamicBuffArraySize = 2; + const Uint32 StaticBuffArraySize = deviceType == RENDER_DEVICE_TYPE_D3D11 || deviceCaps.IsGLDevice() ? 1 : MaxStaticBuffArraySize; + const Uint32 MutableBuffArraySize = deviceType == RENDER_DEVICE_TYPE_D3D11 || deviceCaps.IsGLDevice() ? 1 : MaxMutableBuffArraySize; + const Uint32 DynamicBuffArraySize = MaxDynamicBuffArraySize; static constexpr size_t Buff_StaticIdx = 0; static constexpr size_t Buff_MutIdx = 1; @@ -770,10 +798,19 @@ void ShaderResourceLayoutTest::TestRWStructuredOrFormattedBuffer(bool IsFormatte for (Uint32 i = 0; i < DynamicBuffArraySize; ++i) Macros.AddShaderMacro((std::string{"BuffArr_Dyn_Ref"} + std::to_string(i)).c_str(), RefBuffers.GetValue(BuffArr_DynIdx + i)); + auto ModifyShaderCI = [pEnv](ShaderCreateInfo& ShaderCI) { + if (pEnv->NeedWARPResourceArrayIndexingBugWorkaround()) + { + // Due to bug in D3D12 WARP, we have to use SM5.0 with old compiler + ShaderCI.ShaderCompiler = SHADER_COMPILER_DEFAULT; + ShaderCI.HLSLVersion = ShaderVersion{5, 0}; + } + }; + auto pCS = CreateShader(IsFormatted ? "ShaderResourceLayoutTest.RWFormattedBuffers - CS" : "ShaderResourceLayoutTest.RWtructuredBuffers - CS", ShaderFileName, "main", SHADER_TYPE_COMPUTE, SrcLang, Macros, - Resources, _countof(Resources)); + Resources, _countof(Resources), ModifyShaderCI); ASSERT_NE(pCS, nullptr); // clang-format off @@ -808,9 +845,11 @@ void ShaderResourceLayoutTest::TestRWStructuredOrFormattedBuffer(bool IsFormatte SET_STATIC_VAR(pPSO, SHADER_TYPE_COMPUTE, "g_RWBuffArr_Static", SetArray, RefBuffers.GetViewObjects(BuffArr_StaticIdx), 0, StaticBuffArraySize); SET_SRB_VAR(pSRB, SHADER_TYPE_COMPUTE, "g_RWBuff_Mut", Set, RefBuffers.GetViewObjects(Buff_MutIdx)[0]); - SET_SRB_VAR(pSRB, SHADER_TYPE_COMPUTE, "g_RWBuff_Dyn", Set, RefBuffers.GetViewObjects(0)[0]); SET_SRB_VAR(pSRB, SHADER_TYPE_COMPUTE, "g_RWBuffArr_Mut", SetArray, RefBuffers.GetViewObjects(BuffArr_MutIdx), 0, MutableBuffArraySize); - SET_SRB_VAR(pSRB, SHADER_TYPE_COMPUTE, "g_RWBuffArr_Dyn", SetArray, RefBuffers.GetViewObjects(0), 0, DynamicBuffArraySize); + + // In Direct3D11 UAVs must not overlap! + SET_SRB_VAR(pSRB, SHADER_TYPE_COMPUTE, "g_RWBuff_Dyn", Set, RefBuffers.GetViewObjects(BuffArr_DynIdx)[0]); + SET_SRB_VAR(pSRB, SHADER_TYPE_COMPUTE, "g_RWBuffArr_Dyn", SetArray, RefBuffers.GetViewObjects(BuffArr_DynIdx + 1), 0, DynamicBuffArraySize); pSRB->InitializeStaticResources(pPSO); @@ -855,12 +894,16 @@ TEST_F(ShaderResourceLayoutTest, RWTextures) const auto& deviceCaps = pDevice->GetDeviceCaps(); auto deviceType = deviceCaps.DevType; - const Uint32 StaticTexArraySize = 2; - const Uint32 MutableTexArraySize = deviceType == RENDER_DEVICE_TYPE_D3D11 || deviceCaps.IsGLDevice() ? 2 : 4; - const Uint32 DynamicTexArraySize = deviceType == RENDER_DEVICE_TYPE_D3D11 || deviceCaps.IsGLDevice() ? 1 : 3; + constexpr Uint32 MaxStaticTexArraySize = 2; + constexpr Uint32 MaxMutableTexArraySize = 4; + constexpr Uint32 MaxDynamicTexArraySize = 3; + + const Uint32 StaticTexArraySize = MaxStaticTexArraySize; + const Uint32 MutableTexArraySize = deviceType == RENDER_DEVICE_TYPE_D3D11 || deviceCaps.IsGLDevice() ? 1 : MaxMutableTexArraySize; + const Uint32 DynamicTexArraySize = deviceType == RENDER_DEVICE_TYPE_D3D11 || deviceCaps.IsGLDevice() ? 1 : MaxDynamicTexArraySize; ReferenceTextures RefTextures{ - 3 + 2 + 4 + 3, + 3 + MaxStaticTexArraySize + MaxMutableTexArraySize + MaxDynamicTexArraySize + 1, // Extra texture for dynamic variables 128, 128, USAGE_DEFAULT, BIND_UNORDERED_ACCESS, @@ -906,10 +949,19 @@ TEST_F(ShaderResourceLayoutTest, RWTextures) {"g_RWTex2DArr_Dyn", SHADER_RESOURCE_TYPE_TEXTURE_UAV, DynamicTexArraySize} }; + auto ModifyShaderCI = [pEnv](ShaderCreateInfo& ShaderCI) { + if (pEnv->NeedWARPResourceArrayIndexingBugWorkaround()) + { + // Due to bug in D3D12 WARP, we have to use SM5.0 with old compiler + ShaderCI.ShaderCompiler = SHADER_COMPILER_DEFAULT; + ShaderCI.HLSLVersion = ShaderVersion{5, 0}; + } + }; + auto pCS = CreateShader("ShaderResourceLayoutTest.RWTextures - CS", "RWTextures.hlsl", "main", SHADER_TYPE_COMPUTE, SHADER_SOURCE_LANGUAGE_HLSL, Macros, - Resources, _countof(Resources)); + Resources, _countof(Resources), ModifyShaderCI); ASSERT_NE(pCS, nullptr); // clang-format off @@ -944,9 +996,11 @@ TEST_F(ShaderResourceLayoutTest, RWTextures) SET_STATIC_VAR(pPSO, SHADER_TYPE_COMPUTE, "g_RWTex2DArr_Static", SetArray, RefTextures.GetViewObjects(Tex2DArr_StaticIdx), 0, StaticTexArraySize); SET_SRB_VAR(pSRB, SHADER_TYPE_COMPUTE, "g_RWTex2D_Mut", Set, RefTextures.GetViewObjects(Tex2D_MutIdx)[0]); - SET_SRB_VAR(pSRB, SHADER_TYPE_COMPUTE, "g_RWTex2D_Dyn", Set, RefTextures.GetViewObjects(0)[0]); SET_SRB_VAR(pSRB, SHADER_TYPE_COMPUTE, "g_RWTex2DArr_Mut", SetArray, RefTextures.GetViewObjects(Tex2DArr_MutIdx), 0, MutableTexArraySize); - SET_SRB_VAR(pSRB, SHADER_TYPE_COMPUTE, "g_RWTex2DArr_Dyn", SetArray, RefTextures.GetViewObjects(0), 0, DynamicTexArraySize); + + // In Direct3D11 UAVs must not overlap! + SET_SRB_VAR(pSRB, SHADER_TYPE_COMPUTE, "g_RWTex2D_Dyn", Set, RefTextures.GetViewObjects(Tex2DArr_DynIdx)[0]); + SET_SRB_VAR(pSRB, SHADER_TYPE_COMPUTE, "g_RWTex2DArr_Dyn", SetArray, RefTextures.GetViewObjects(Tex2DArr_DynIdx + 1), 0, DynamicTexArraySize); pSRB->InitializeStaticResources(pPSO); @@ -976,6 +1030,8 @@ TEST_F(ShaderResourceLayoutTest, ConstantBuffers) auto* pDevice = pEnv->GetDevice(); auto* pSwapChain = pEnv->GetSwapChain(); + const auto& deviceCaps = pDevice->GetDeviceCaps(); + float ClearColor[] = {0.875, 0.75, 0.625, 0.125}; RenderDrawCommandReference(pSwapChain, ClearColor); @@ -995,8 +1051,9 @@ TEST_F(ShaderResourceLayoutTest, ConstantBuffers) static constexpr size_t BuffArr_MutIdx[] = {3, 5}; static constexpr size_t BuffArr_DynIdx[] = {7, 2}; - - const auto& deviceCaps = pDevice->GetDeviceCaps(); + const Uint32 VSResArrId = 0; + const Uint32 PSResArrId = deviceCaps.Features.SeparablePrograms ? 1 : 0; + VERIFY_EXPR(deviceCaps.IsGLDevice() || PSResArrId != VSResArrId); // Vulkan allows 15 dynamic uniform buffer bindings among all stages const Uint32 StaticCBArraySize = 2; @@ -1054,15 +1111,18 @@ TEST_F(ShaderResourceLayoutTest, ConstantBuffers) } // clang-format on + // Even though shader array indexing is generally broken in D3D12 WARP, + // constant buffers seem to be working fine. + auto pVS = CreateShader("ShaderResourceLayoutTest.ConstantBuffers - VS", "ConstantBuffers.hlsl", "VSMain", - SHADER_TYPE_VERTEX, SHADER_SOURCE_LANGUAGE_HLSL, PrepareMacros(0), + SHADER_TYPE_VERTEX, SHADER_SOURCE_LANGUAGE_HLSL, PrepareMacros(VSResArrId), Resources.data(), static_cast<Uint32>(Resources.size())); auto pPS = CreateShader("ShaderResourceLayoutTest.ConstantBuffers - PS", "ConstantBuffers.hlsl", "PSMain", - SHADER_TYPE_PIXEL, SHADER_SOURCE_LANGUAGE_HLSL, PrepareMacros(1), + SHADER_TYPE_PIXEL, SHADER_SOURCE_LANGUAGE_HLSL, PrepareMacros(PSResArrId), Resources.data(), static_cast<Uint32>(Resources.size())); ASSERT_NE(pVS, nullptr); ASSERT_NE(pPS, nullptr); @@ -1095,7 +1155,7 @@ TEST_F(ShaderResourceLayoutTest, ConstantBuffers) ASSERT_NE(pSRB, nullptr); auto BindResources = [&](SHADER_TYPE ShaderType) { - const auto id = ShaderType == SHADER_TYPE_VERTEX ? 0 : 1; + const auto id = ShaderType == SHADER_TYPE_VERTEX ? VSResArrId : PSResArrId; SET_STATIC_VAR(pPSO, ShaderType, "UniformBuff_Stat", Set, RefBuffers.GetBuffObjects(Buff_StaticIdx[id])[0]); @@ -1130,12 +1190,12 @@ TEST_F(ShaderResourceLayoutTest, ConstantBuffers) DrawAttribs DrawAttrs{6, DRAW_FLAG_VERIFY_ALL}; pContext->Draw(DrawAttrs); - SET_SRB_VAR(pSRB, SHADER_TYPE_VERTEX, "UniformBuff_Dyn", Set, RefBuffers.GetBuffObjects(Buff_DynIdx[0])[0]); - SET_SRB_VAR(pSRB, SHADER_TYPE_PIXEL, "UniformBuff_Dyn", Set, RefBuffers.GetBuffObjects(Buff_DynIdx[1])[0]); + SET_SRB_VAR(pSRB, SHADER_TYPE_VERTEX, "UniformBuff_Dyn", Set, RefBuffers.GetBuffObjects(Buff_DynIdx[VSResArrId])[0]); + SET_SRB_VAR(pSRB, SHADER_TYPE_PIXEL, "UniformBuff_Dyn", Set, RefBuffers.GetBuffObjects(Buff_DynIdx[PSResArrId])[0]); if (CBArraysSupported) { - SET_SRB_VAR(pSRB, SHADER_TYPE_VERTEX, "UniformBuffArr_Dyn", SetArray, RefBuffers.GetBuffObjects(BuffArr_DynIdx[0]), 0, DynamicCBArraySize); - SET_SRB_VAR(pSRB, SHADER_TYPE_PIXEL, "UniformBuffArr_Dyn", SetArray, RefBuffers.GetBuffObjects(BuffArr_DynIdx[1]), 0, DynamicCBArraySize); + SET_SRB_VAR(pSRB, SHADER_TYPE_VERTEX, "UniformBuffArr_Dyn", SetArray, RefBuffers.GetBuffObjects(BuffArr_DynIdx[VSResArrId]), 0, DynamicCBArraySize); + SET_SRB_VAR(pSRB, SHADER_TYPE_PIXEL, "UniformBuffArr_Dyn", SetArray, RefBuffers.GetBuffObjects(BuffArr_DynIdx[PSResArrId]), 0, DynamicCBArraySize); } pContext->CommitShaderResources(pSRB, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); diff --git a/Tests/DiligentCoreAPITest/src/TestingSwapChainBase.cpp b/Tests/DiligentCoreAPITest/src/TestingSwapChainBase.cpp index 16b43b55..bd05d1fa 100644 --- a/Tests/DiligentCoreAPITest/src/TestingSwapChainBase.cpp +++ b/Tests/DiligentCoreAPITest/src/TestingSwapChainBase.cpp @@ -110,9 +110,9 @@ void CompareTestImages(const Uint8* pReferencePixels, }; std::string FileName{ValidateName(TestInfo->test_suite_name())}; - auto& FailureCounter = FailureCounters[FileName]; FileName += '.'; FileName += ValidateName(TestInfo->name()); + auto& FailureCounter = FailureCounters[FileName]; FileName += "_FAIL"; if (FailureCounter > 0) FileName += std::to_string(FailureCounter); |
