From 51f876af24d24e923a08af00a69e9f5d9ec6bcfe Mon Sep 17 00:00:00 2001 From: azhirnov Date: Tue, 26 Jan 2021 10:15:53 +0300 Subject: allow to combine graphics PRS with mesh pipeline --- .../PipelineResourceSignatureTestHLSL.h | 94 +++++++++ .../src/PipelineResourceSignatureTest.cpp | 218 +++++++++++++++++++++ 2 files changed, 312 insertions(+) (limited to 'Tests') diff --git a/Tests/DiligentCoreAPITest/include/InlineShaders/PipelineResourceSignatureTestHLSL.h b/Tests/DiligentCoreAPITest/include/InlineShaders/PipelineResourceSignatureTestHLSL.h index f7d16192..713a89b2 100644 --- a/Tests/DiligentCoreAPITest/include/InlineShaders/PipelineResourceSignatureTestHLSL.h +++ b/Tests/DiligentCoreAPITest/include/InlineShaders/PipelineResourceSignatureTestHLSL.h @@ -128,6 +128,100 @@ void main(PSInput In, )" }; + +const std::string PRSTest3_VS{ +R"( +struct VSOutput +{ + float4 f4Position : SV_Position; + float2 f2Texcoord : TEXCOORD0; + float3 f3Color : COLOR; +}; + +cbuffer Constants +{ + float4 g_Weight1; + float4 g_Weight2; +}; + +void main(uint uiVertexId : SV_VertexID, + out VSOutput Out) +{ + float4 Positions[3]; + Positions[0] = float4(-0.5, -0.5, 0.0, 1.0) * g_Weight1; + Positions[1] = float4(+0.5, +0.5, 0.0, 1.0) * g_Weight1; + Positions[2] = float4(-0.5, +0.5, 0.0, 1.0) * g_Weight1; + + float3 Color[3]; + Color[0] = float3(0.5, 0.0, 0.0); + Color[1] = float3(0.0, 0.0, 0.5); + Color[2] = float3(0.0, 0.5, 0.0); + + Out.f4Position = Positions[uiVertexId]; + Out.f2Texcoord = Positions[uiVertexId].xy; + Out.f3Color = Color[uiVertexId]; +} +)" +}; + +const std::string PRSTest3_MS{ +R"( +struct MSOutput +{ + float4 f4Position : SV_Position; + float2 f2Texcoord : TEXCOORD0; + float3 f3Color : COLOR; +}; + +static const float3 colors[4] = {float3(1.0,0.0,0.0), float3(0.0,1.0,0.0), float3(0.0,0.0,1.0), float3(1.0,1.0,1.0)}; + +cbuffer Constants +{ + float4 g_Weight1; + float4 g_Weight2; +}; + +[numthreads(4,1,1)] +[outputtopology("triangle")] +void main(uint I : SV_GroupIndex, + out indices uint3 tris[2], + out vertices MSOutput verts[4]) +{ + SetMeshOutputCounts(4, 2); + + if (I == 0) + tris[0] = uint3(0, 1, 2); + + if (I == 3) + tris[1] = uint3(2, 1, 3); + + float2 pos = float2(float(I >> 1), float(I & 1)); + + verts[I].f4Position = float4(pos * 2.0 - 1.0, 0.0, 1.0) * g_Weight1; + verts[I].f2Texcoord = pos * g_Weight2.xy; + verts[I].f3Color = colors[I]; +} +)" +}; + +const std::string PRSTest3_PS{ +R"( +struct PSInput +{ + float4 f4Position : SV_Position; + float2 f2Texcoord : TEXCOORD0; + float3 f3Color : COLOR; +}; + +Texture2D g_Texture; +SamplerState g_Texture_sampler; + +void main(PSInput In, + out float4 Color : SV_Target) +{ +} +)" +}; // clang-format on } // namespace HLSL diff --git a/Tests/DiligentCoreAPITest/src/PipelineResourceSignatureTest.cpp b/Tests/DiligentCoreAPITest/src/PipelineResourceSignatureTest.cpp index 1e09af65..02e705bf 100644 --- a/Tests/DiligentCoreAPITest/src/PipelineResourceSignatureTest.cpp +++ b/Tests/DiligentCoreAPITest/src/PipelineResourceSignatureTest.cpp @@ -789,4 +789,222 @@ TEST_F(PipelineResourceSignatureTest, SRBCompatibility) pContext->Draw(drawAttrs); } + +TEST_F(PipelineResourceSignatureTest, GraphicsAndMeshShader) +{ + auto* pEnv = TestingEnvironment::GetInstance(); + auto* pDevice = pEnv->GetDevice(); + auto* pContext = pEnv->GetDeviceContext(); + if (!pDevice->GetDeviceCaps().Features.MeshShaders) + { + GTEST_SKIP() << "Mesh shader is not supported by this device"; + } + + TestingEnvironment::ScopedReset EnvironmentAutoReset; + + RefCntAutoPtr pSignaturePS; + { + const PipelineResourceDesc Resources[] = { + {SHADER_TYPE_PIXEL, "g_Texture", 1, SHADER_RESOURCE_TYPE_TEXTURE_SRV, SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE}, + {SHADER_TYPE_PIXEL, "g_Texture_sampler", 1, SHADER_RESOURCE_TYPE_SAMPLER, SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE}}; + + SamplerDesc SamLinearWrapDesc{ + FILTER_TYPE_LINEAR, FILTER_TYPE_LINEAR, FILTER_TYPE_LINEAR, + TEXTURE_ADDRESS_WRAP, TEXTURE_ADDRESS_WRAP, TEXTURE_ADDRESS_WRAP}; + ImmutableSamplerDesc ImmutableSamplers[] = {{SHADER_TYPE_PIXEL, "g_Texture", SamLinearWrapDesc}}; + + PipelineResourceSignatureDesc Desc; + Desc.Resources = Resources; + Desc.NumResources = _countof(Resources); + Desc.ImmutableSamplers = ImmutableSamplers; + Desc.NumImmutableSamplers = _countof(ImmutableSamplers); + Desc.UseCombinedTextureSamplers = true; + Desc.CombinedSamplerSuffix = "_sampler"; + Desc.BindingIndex = 0; + + pDevice->CreatePipelineResourceSignature(Desc, &pSignaturePS); + ASSERT_NE(pSignaturePS, nullptr); + } + + RefCntAutoPtr pSignatureVS; + { + const PipelineResourceDesc Resources[] = { + {SHADER_TYPE_VERTEX, "Constants", 1, SHADER_RESOURCE_TYPE_CONSTANT_BUFFER, SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE}}; + + PipelineResourceSignatureDesc Desc; + Desc.Resources = Resources; + Desc.NumResources = _countof(Resources); + Desc.BindingIndex = 1; + + pDevice->CreatePipelineResourceSignature(Desc, &pSignatureVS); + ASSERT_NE(pSignatureVS, nullptr); + } + + RefCntAutoPtr pSignatureMS; + { + const PipelineResourceDesc Resources[] = { + {SHADER_TYPE_MESH, "Constants", 1, SHADER_RESOURCE_TYPE_CONSTANT_BUFFER, SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC}}; + + PipelineResourceSignatureDesc Desc; + Desc.Resources = Resources; + Desc.NumResources = _countof(Resources); + Desc.BindingIndex = 1; + + pDevice->CreatePipelineResourceSignature(Desc, &pSignatureMS); + ASSERT_NE(pSignatureMS, nullptr); + } + + GraphicsPipelineStateCreateInfo PSOCreateInfo; + + auto& PSODesc = PSOCreateInfo.PSODesc; + auto& GraphicsPipeline = PSOCreateInfo.GraphicsPipeline; + + PSODesc.Name = "Graphics PSO"; + + PSODesc.PipelineType = PIPELINE_TYPE_GRAPHICS; + GraphicsPipeline.NumRenderTargets = 1; + GraphicsPipeline.RTVFormats[0] = TEX_FORMAT_RGBA8_UNORM; + GraphicsPipeline.PrimitiveTopology = PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + GraphicsPipeline.RasterizerDesc.CullMode = CULL_MODE_NONE; + GraphicsPipeline.DepthStencilDesc.DepthEnable = False; + + ShaderCreateInfo ShaderCI; + ShaderCI.SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL; + ShaderCI.ShaderCompiler = SHADER_COMPILER_DXC; + ShaderCI.UseCombinedTextureSamplers = true; + + RefCntAutoPtr pVS; + { + ShaderCI.Desc.ShaderType = SHADER_TYPE_VERTEX; + ShaderCI.EntryPoint = "main"; + ShaderCI.Desc.Name = "PRS test - VS"; + ShaderCI.Source = HLSL::PRSTest3_VS.c_str(); + pDevice->CreateShader(ShaderCI, &pVS); + ASSERT_NE(pVS, nullptr); + } + + RefCntAutoPtr pPS; + { + ShaderCI.Desc.ShaderType = SHADER_TYPE_PIXEL; + ShaderCI.EntryPoint = "main"; + ShaderCI.Desc.Name = "PRS test - PS"; + ShaderCI.Source = HLSL::PRSTest3_PS.c_str(); + pDevice->CreateShader(ShaderCI, &pPS); + ASSERT_NE(pPS, nullptr); + } + + PSOCreateInfo.pVS = pVS; + PSOCreateInfo.pPS = pPS; + + IPipelineResourceSignature* GraphicsSignatures[] = {pSignatureVS, pSignaturePS}; + + PSOCreateInfo.ppResourceSignatures = GraphicsSignatures; + PSOCreateInfo.ResourceSignaturesCount = _countof(GraphicsSignatures); + + RefCntAutoPtr pGraphicsPSO; + pDevice->CreateGraphicsPipelineState(PSOCreateInfo, &pGraphicsPSO); + ASSERT_NE(pGraphicsPSO, nullptr); + + ASSERT_EQ(pGraphicsPSO->GetResourceSignatureCount(), 2u); + ASSERT_EQ(pGraphicsPSO->GetResourceSignature(0), pSignaturePS); + ASSERT_EQ(pGraphicsPSO->GetResourceSignature(1), pSignatureVS); + + + RefCntAutoPtr pMS; + { + ShaderCI.Desc.ShaderType = SHADER_TYPE_MESH; + ShaderCI.EntryPoint = "main"; + ShaderCI.Desc.Name = "PRS test - MS"; + ShaderCI.Source = HLSL::PRSTest3_MS.c_str(); + pDevice->CreateShader(ShaderCI, &pMS); + ASSERT_NE(pMS, nullptr); + } + + PSODesc.PipelineType = PIPELINE_TYPE_MESH; + GraphicsPipeline.PrimitiveTopology = PRIMITIVE_TOPOLOGY_UNDEFINED; // unused + + PSOCreateInfo.pVS = nullptr; + PSOCreateInfo.pMS = pMS; + PSOCreateInfo.pPS = pPS; + + IPipelineResourceSignature* MeshSignatures[] = {pSignatureMS, pSignaturePS}; + + PSOCreateInfo.ppResourceSignatures = MeshSignatures; + PSOCreateInfo.ResourceSignaturesCount = _countof(MeshSignatures); + + RefCntAutoPtr pMeshPSO; + pDevice->CreateGraphicsPipelineState(PSOCreateInfo, &pMeshPSO); + ASSERT_NE(pMeshPSO, nullptr); + + ASSERT_EQ(pMeshPSO->GetResourceSignatureCount(), 2u); + ASSERT_EQ(pMeshPSO->GetResourceSignature(0), pSignaturePS); + ASSERT_EQ(pMeshPSO->GetResourceSignature(1), pSignatureMS); + + + RefCntAutoPtr pConstBuf; + { + float ConstData[8] = {}; + BufferDesc BuffDesc; + BuffDesc.uiSizeInBytes = sizeof(ConstData); + BuffDesc.BindFlags = BIND_UNIFORM_BUFFER; + BuffDesc.Usage = USAGE_IMMUTABLE; + BufferData BuffData{ConstData, sizeof(ConstData)}; + pDevice->CreateBuffer(BuffDesc, &BuffData, &pConstBuf); + ASSERT_NE(pConstBuf, nullptr); + } + + RefCntAutoPtr pTexture; + { + TextureDesc TexDesc; + TexDesc.Type = RESOURCE_DIM_TEX_2D; + TexDesc.Width = 256; + TexDesc.Height = 256; + TexDesc.Usage = USAGE_IMMUTABLE; + TexDesc.Format = TEX_FORMAT_RGBA8_UNORM; + TexDesc.BindFlags = BIND_SHADER_RESOURCE; + + std::vector Data(TexDesc.Width * TexDesc.Height * 4, 128); + TextureSubResData TexSubData{Data.data(), TexDesc.Width * 4}; + TextureData TexData{&TexSubData, 1}; + pDevice->CreateTexture(TexDesc, &TexData, &pTexture); + ASSERT_NE(pTexture, nullptr); + } + + RefCntAutoPtr PixelSRB; + pSignaturePS->CreateShaderResourceBinding(&PixelSRB, true); + ASSERT_NE(PixelSRB, nullptr); + + RefCntAutoPtr VertexSRB; + pSignatureVS->CreateShaderResourceBinding(&VertexSRB, true); + ASSERT_NE(VertexSRB, nullptr); + + RefCntAutoPtr MeshSRB; + pSignatureMS->CreateShaderResourceBinding(&MeshSRB, true); + ASSERT_NE(MeshSRB, nullptr); + + PixelSRB->GetVariableByName(SHADER_TYPE_PIXEL, "g_Texture")->Set(pTexture->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE)); + VertexSRB->GetVariableByName(SHADER_TYPE_VERTEX, "Constants")->Set(pConstBuf); + MeshSRB->GetVariableByName(SHADER_TYPE_MESH, "Constants")->Set(pConstBuf); + + ITextureView* ppRTVs[] = {pRTV}; + pContext->SetRenderTargets(1, ppRTVs, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); + + // draw triangles + pContext->CommitShaderResources(PixelSRB, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); + pContext->CommitShaderResources(VertexSRB, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); + + pContext->SetPipelineState(pGraphicsPSO); + + DrawAttribs drawAttrs(3, DRAW_FLAG_VERIFY_ALL); + pContext->Draw(drawAttrs); + + // draw meshes + pContext->CommitShaderResources(MeshSRB, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); + // reuse PixelSRB + + pContext->SetPipelineState(pMeshPSO); + + DrawMeshAttribs drawMeshAttrs(1, DRAW_FLAG_VERIFY_ALL); + pContext->DrawMesh(drawMeshAttrs); +} } // namespace Diligent -- cgit v1.2.3