diff --git a/RenderStateNotation/src/RenderStateNotationParserImpl.cpp b/RenderStateNotation/src/RenderStateNotationParserImpl.cpp index 8ddb9b52..0369c696 100644 --- a/RenderStateNotation/src/RenderStateNotationParserImpl.cpp +++ b/RenderStateNotation/src/RenderStateNotationParserImpl.cpp @@ -377,6 +377,7 @@ Bool RenderStateNotationParserImpl::ParseStringInternal(const Char* ShaderCreateInfo DefaultShader{}; PipelineStateNotation DefaultPipeline{}; + GraphicsPipelineDesc DefaultGraphicsPipeline{}; RenderPassDesc DefaultRenderPass{}; PipelineResourceSignatureDesc DefaultResourceSignature{}; @@ -506,7 +507,13 @@ Bool RenderStateNotationParserImpl::ParseStringInternal(const Char* ParseRSN(Default["ResourceSignature"], DefaultResourceSignature, *m_pAllocator); if (Default.contains("Pipeline")) - ParseRSN(Default["Pipeline"], DefaultPipeline, *m_pAllocator, Callbacks); + { + auto const& Pipeline = Default["Pipeline"]; + ParseRSN(Pipeline, DefaultPipeline, *m_pAllocator, Callbacks); + + if (Pipeline.contains("GraphicsPipeline")) + ParseRSN(Pipeline["GraphicsPipeline"], DefaultGraphicsPipeline, *m_pAllocator); + } } for (auto const& Shader : Json["Shaders"]) @@ -533,13 +540,19 @@ Bool RenderStateNotationParserImpl::ParseStringInternal(const Char* LOG_ERROR_AND_THROW("Redefinition of pipeline '", PSONotation.PSODesc.Name, "'."); }; + auto AddGraphicsPipelineState = [&](PIPELINE_TYPE PipelineType, GraphicsPipelineNotation& PSONotation) // + { + PSONotation.Desc = DefaultGraphicsPipeline; + AddPipelineState(PipelineType, PSONotation); + }; + static_assert(PIPELINE_TYPE_LAST == 4, "Please handle the new pipeline type below."); const PIPELINE_TYPE PipelineType = GetPipelineType(Pipeline); switch (PipelineType) { case PIPELINE_TYPE_GRAPHICS: case PIPELINE_TYPE_MESH: - AddPipelineState(PipelineType, *m_pAllocator->Construct()); + AddGraphicsPipelineState(PipelineType, *m_pAllocator->Construct()); break; case PIPELINE_TYPE_COMPUTE: diff --git a/Tests/DiligentToolsTest/assets/RenderStates/RenderStateNotationParser/DefaultGraphicsPipeline.json b/Tests/DiligentToolsTest/assets/RenderStates/RenderStateNotationParser/DefaultGraphicsPipeline.json new file mode 100644 index 00000000..07ff7462 --- /dev/null +++ b/Tests/DiligentToolsTest/assets/RenderStates/RenderStateNotationParser/DefaultGraphicsPipeline.json @@ -0,0 +1,61 @@ +{ + "Defaults": { + "Shader": { + "SourceLanguage": "HLSL", + "Desc": { + "UseCombinedTextureSamplers": true + } + }, + "Pipeline": { + "GraphicsPipeline": { + "PrimitiveTopology": "TRIANGLE_LIST", + "NumViewports": 2, + "SampleMask": 255, + "RasterizerDesc": { + "CullMode": "FRONT" + }, + "DepthStencilDesc": { + "DepthEnable": false + }, + "BlendDesc": { + "AlphaToCoverageEnable": true + } + } + } + }, + "Pipelines": [ + { + "PSODesc": { + "Name": "Graphics-TestPipeline1" + }, + "GraphicsPipeline": { + "RTVFormats": { + "0": "RGBA8_UNORM" + } + }, + "pVS": { + "Desc": { + "Name": "Shader-VS" + } + }, + "pPS": { + "Desc": { + "Name": "Shader-PS" + } + } + }, + { + "PSODesc": { + "Name": "Graphics-TestPipeline2" + }, + "GraphicsPipeline": { + "PrimitiveTopology": "POINT_LIST", + "RTVFormats": { + "0": "RG16_FLOAT" + } + }, + "pVS": "Shader-VS", + "pPS": "Shader-PS" + } + ] +} diff --git a/Tests/DiligentToolsTest/src/RenderStateNotationParser/RenderStateNotationParserTest.cpp b/Tests/DiligentToolsTest/src/RenderStateNotationParser/RenderStateNotationParserTest.cpp index 7c730304..b629086b 100644 --- a/Tests/DiligentToolsTest/src/RenderStateNotationParser/RenderStateNotationParserTest.cpp +++ b/Tests/DiligentToolsTest/src/RenderStateNotationParser/RenderStateNotationParserTest.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 Diligent Graphics LLC + * Copyright 2019-2026 Diligent Graphics LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -545,6 +545,51 @@ TEST(Tools_RenderStateNotationParser, DefaultPipelineStatesTest) EXPECT_EQ(*pRenderPass, RenderPassReference); } +TEST(Tools_RenderStateNotationParser, DefaultGraphicsPipelineTest) +{ + RefCntAutoPtr pParser = LoadFromFile("DefaultGraphicsPipeline.json"); + ASSERT_NE(pParser, nullptr); + + // Test that the first pipeline inherits default GraphicsPipeline settings + { + auto pPipeline = static_cast(pParser->GetPipelineStateByName("Graphics-TestPipeline1")); + ASSERT_NE(pPipeline, nullptr); + + EXPECT_EQ(pPipeline->Desc.PrimitiveTopology, PRIMITIVE_TOPOLOGY_TRIANGLE_LIST); + EXPECT_EQ(pPipeline->Desc.NumViewports, 2u); + EXPECT_EQ(pPipeline->Desc.SampleMask, 255u); + EXPECT_EQ(pPipeline->Desc.RasterizerDesc.CullMode, CULL_MODE_FRONT); + EXPECT_EQ(pPipeline->Desc.DepthStencilDesc.DepthEnable, False); + EXPECT_EQ(pPipeline->Desc.BlendDesc.AlphaToCoverageEnable, True); + + EXPECT_EQ(pPipeline->Desc.RTVFormats[0], TEX_FORMAT_RGBA8_UNORM); + EXPECT_EQ(pPipeline->Desc.NumRenderTargets, 1u); + + EXPECT_STREQ(pPipeline->pVSName, "Shader-VS"); + EXPECT_STREQ(pPipeline->pPSName, "Shader-PS"); + } + + // Test that the second pipeline can override default values + { + auto pPipeline = static_cast(pParser->GetPipelineStateByName("Graphics-TestPipeline2")); + ASSERT_NE(pPipeline, nullptr); + + EXPECT_EQ(pPipeline->Desc.PrimitiveTopology, PRIMITIVE_TOPOLOGY_POINT_LIST); + + EXPECT_EQ(pPipeline->Desc.NumViewports, 2u); + EXPECT_EQ(pPipeline->Desc.SampleMask, 255u); + EXPECT_EQ(pPipeline->Desc.RasterizerDesc.CullMode, CULL_MODE_FRONT); + EXPECT_EQ(pPipeline->Desc.DepthStencilDesc.DepthEnable, False); + EXPECT_EQ(pPipeline->Desc.BlendDesc.AlphaToCoverageEnable, True); + + EXPECT_EQ(pPipeline->Desc.RTVFormats[0], TEX_FORMAT_RG16_FLOAT); + EXPECT_EQ(pPipeline->Desc.NumRenderTargets, 1u); + + EXPECT_STREQ(pPipeline->pVSName, "Shader-VS"); + EXPECT_STREQ(pPipeline->pPSName, "Shader-PS"); + } +} + TEST(Tools_RenderStateNotationParser, RenderStateNotationParserTest) { RefCntAutoPtr pParser = LoadFromFile("RenderStatesLibrary.json");