diff --git a/include/dxc/DxilContainer/DxilRuntimeReflection.h b/include/dxc/DxilContainer/DxilRuntimeReflection.h index efdef79ee93..d8523799e9d 100644 --- a/include/dxc/DxilContainer/DxilRuntimeReflection.h +++ b/include/dxc/DxilContainer/DxilRuntimeReflection.h @@ -71,27 +71,28 @@ enum class RuntimeDataPartType : uint32_t { // Keep this ID reserved for compatibility with the mesh-node preview. Reserved_MeshNodesPreviewInfoTable = 12, - ExtendedFunctionPropertiesTable = 13, - LinAlgMatrixOperationShapeTable = 14, - LinAlgMatrixConstructionTable = 15, - LinAlgThreadMatrixVectorMultiplyTable = 16, - LinAlgWaveMatrixMultiplyTable = 17, - LinAlgThreadGroupMatrixMultiplyTable = 18, - LinAlgOuterProductTable = 19, - LinAlgAccumulateStoreTable = 20, + // Preserve the experimental shader-info IDs used by the mesh-node preview. + SignatureElementTable = 13, + VSInfoTable = 14, + PSInfoTable = 15, + HSInfoTable = 16, + DSInfoTable = 17, + GSInfoTable = 18, + CSInfoTable = 19, + MSInfoTable = 20, + ASInfoTable = 21, + + ExtendedFunctionPropertiesTable = 22, + LinAlgMatrixOperationShapeTable = 23, + LinAlgMatrixConstructionTable = 24, + LinAlgThreadMatrixVectorMultiplyTable = 25, + LinAlgWaveMatrixMultiplyTable = 26, + LinAlgThreadGroupMatrixMultiplyTable = 27, + LinAlgOuterProductTable = 28, + LinAlgAccumulateStoreTable = 29, Last_1_10 = LinAlgAccumulateStoreTable, // Insert experimental here. - SignatureElementTable, - VSInfoTable, - PSInfoTable, - HSInfoTable, - DSInfoTable, - GSInfoTable, - CSInfoTable, - MSInfoTable, - ASInfoTable, - LastPlus1, LastExperimental = LastPlus1 - 1, LastRelease = Last_1_10, diff --git a/lib/DxilContainer/DxilContainerAssembler.cpp b/lib/DxilContainer/DxilContainerAssembler.cpp index cb030eea923..db6fdc0044d 100644 --- a/lib/DxilContainer/DxilContainerAssembler.cpp +++ b/lib/DxilContainer/DxilContainerAssembler.cpp @@ -2297,6 +2297,16 @@ class DxilRDATWriter : public DxilPartWriter { RDAT::RuntimeDataPartType maxAllowedType = RDAT::MaxPartTypeForValVer( m_ValMajor, m_ValMinor, mod.GetShaderModel()->IsPreReleaseShaderModel()); + const bool allowExperimentalParts = + DXIL::IsVersionExperimental(m_ValMajor, m_ValMinor) && + (mod.GetShaderModel()->IsPreReleaseShaderModel() || m_ValMajor == 0); + auto isPartAllowed = [maxAllowedType, allowExperimentalParts]( + RDAT::RuntimeDataPartType partType) { + return partType <= maxAllowedType && + (allowExperimentalParts || + partType < RDAT::RuntimeDataPartType::SignatureElementTable || + partType > RDAT::RuntimeDataPartType::ASInfoTable); + }; mod.ComputeShaderCompatInfo(); @@ -2312,7 +2322,7 @@ class DxilRDATWriter : public DxilPartWriter { // Once per table, if not already added. #define RDAT_STRUCT_TABLE(type, table) \ - if (RDAT::RecordTraits::PartType() <= maxAllowedType && \ + if (isPartAllowed(RDAT::RecordTraits::PartType()) && \ !Builder.GetTable()) \ (void)Builder.AddTable(); // Update the record stride for supported derived types. diff --git a/tools/clang/test/CodeGenDXIL/reflection/experimental_rdat.hlsl b/tools/clang/test/CodeGenDXIL/reflection/experimental_rdat.hlsl index 44977d5e7e5..5d8a628821e 100644 --- a/tools/clang/test/CodeGenDXIL/reflection/experimental_rdat.hlsl +++ b/tools/clang/test/CodeGenDXIL/reflection/experimental_rdat.hlsl @@ -19,8 +19,17 @@ // version 0.0 is implied for the offline linking target lib_6_x. // CHECK: DxilRuntimeData +// EXP: SignatureElementTable // EXP: PSInfoTable +// NOEXP-NOT: SignatureElementTable +// NOEXP-NOT: VSInfoTable // NOEXP-NOT: PSInfoTable +// NOEXP-NOT: HSInfoTable +// NOEXP-NOT: DSInfoTable +// NOEXP-NOT: GSInfoTable +// NOEXP-NOT: CSInfoTable +// NOEXP-NOT: MSInfoTable +// NOEXP-NOT: ASInfoTable [shader("pixel")] float4 main() : SV_Target { diff --git a/tools/clang/test/CodeGenDXIL/reflection/experimental_rdat_rel_sm.hlsl b/tools/clang/test/CodeGenDXIL/reflection/experimental_rdat_rel_sm.hlsl index 0d1508a16f5..4086595bae6 100644 --- a/tools/clang/test/CodeGenDXIL/reflection/experimental_rdat_rel_sm.hlsl +++ b/tools/clang/test/CodeGenDXIL/reflection/experimental_rdat_rel_sm.hlsl @@ -20,8 +20,17 @@ // version 0.0 is implied for the offline linking target lib_6_x. // CHECK: DxilRuntimeData +// EXP: SignatureElementTable // EXP: PSInfoTable +// NOEXP-NOT: SignatureElementTable +// NOEXP-NOT: VSInfoTable // NOEXP-NOT: PSInfoTable +// NOEXP-NOT: HSInfoTable +// NOEXP-NOT: DSInfoTable +// NOEXP-NOT: GSInfoTable +// NOEXP-NOT: CSInfoTable +// NOEXP-NOT: MSInfoTable +// NOEXP-NOT: ASInfoTable [shader("pixel")] float4 main() : SV_Target { diff --git a/tools/clang/unittests/HLSL/DxilContainerTest.cpp b/tools/clang/unittests/HLSL/DxilContainerTest.cpp index 448048b6d3f..6addad4e952 100644 --- a/tools/clang/unittests/HLSL/DxilContainerTest.cpp +++ b/tools/clang/unittests/HLSL/DxilContainerTest.cpp @@ -110,6 +110,8 @@ class DxilContainerTest : public ::testing::Test { TEST_METHOD(CompileCSWaveSize_CheckPSV0) TEST_METHOD(CompileCSWaveSizeRange_CheckPSV0) TEST_METHOD(PSVLinAlgRuntimeInfoRoundTripAndPrint) + TEST_METHOD(RDATMeshNodePreviewTables) + TEST_METHOD(RDATMeshNodePreviewAndLinAlgTables) TEST_METHOD(CompileWhenOkThenCheckRDAT) TEST_METHOD(CompileWhenOkThenCheckRDAT2) TEST_METHOD(CompileWhenOkThenCheckRDATSM69) @@ -1623,6 +1625,85 @@ TEST_F(DxilContainerTest, PSVLinAlgRuntimeInfoRoundTripAndPrint) { std::string::npos); } +TEST_F(DxilContainerTest, RDATMeshNodePreviewTables) { + using namespace hlsl::RDAT; + const struct { + uint32_t PartType; + RecordTableIndex TableIndex; + uint32_t RecordStride; + } Cases[] = { + {13, RecordTableIndex::SignatureElementTable, sizeof(SignatureElement)}, + {14, RecordTableIndex::VSInfoTable, sizeof(hlsl::RDAT::VSInfo)}, + {15, RecordTableIndex::PSInfoTable, sizeof(hlsl::RDAT::PSInfo)}, + {16, RecordTableIndex::HSInfoTable, sizeof(hlsl::RDAT::HSInfo)}, + {17, RecordTableIndex::DSInfoTable, sizeof(hlsl::RDAT::DSInfo)}, + {18, RecordTableIndex::GSInfoTable, sizeof(hlsl::RDAT::GSInfo)}, + {19, RecordTableIndex::CSInfoTable, sizeof(hlsl::RDAT::CSInfo)}, + {20, RecordTableIndex::MSInfoTable, sizeof(hlsl::RDAT::MSInfo)}, + {21, RecordTableIndex::ASInfoTable, sizeof(hlsl::RDAT::ASInfo)}, + }; + for (const auto &Case : Cases) { + std::vector Data = { + RDAT_Version_10, + 1, + 3 * sizeof(uint32_t), + Case.PartType, + static_cast(sizeof(RuntimeDataTableHeader)) + + Case.RecordStride, + 1, + Case.RecordStride}; + Data.resize(Data.size() + Case.RecordStride / sizeof(uint32_t), 0); + DxilRuntimeData Reader; + VERIFY_IS_TRUE( + Reader.InitFromRDAT(Data.data(), Data.size() * sizeof(uint32_t))); + VERIFY_ARE_EQUAL(Case.RecordStride, + Reader.GetContext().Table(Case.TableIndex).Stride()); + } +} + +TEST_F(DxilContainerTest, RDATMeshNodePreviewAndLinAlgTables) { + using namespace hlsl::RDAT; + struct { + RuntimeDataHeader Header; + uint32_t Offsets[2]; + RuntimeDataPartHeader MeshPart; + RuntimeDataTableHeader MeshTable; + hlsl::RDAT::MSInfo Mesh; + RuntimeDataPartHeader PropertiesPart; + RuntimeDataTableHeader PropertiesTable; + ExtendedFunctionProperties Properties; + } Data = {}; + Data.Header.Version = RDAT_Version_10; + Data.Header.PartCount = 2; + Data.Offsets[0] = offsetof(decltype(Data), MeshPart); + Data.Offsets[1] = offsetof(decltype(Data), PropertiesPart); + Data.MeshPart.Type = static_cast(20); + Data.MeshPart.Size = sizeof(Data.MeshTable) + sizeof(Data.Mesh); + Data.MeshTable.RecordCount = 1; + Data.MeshTable.RecordStride = sizeof(Data.Mesh); + Data.Mesh.SigOutputElements = RDAT_NULL_REF; + Data.Mesh.SigPrimOutputElements = RDAT_NULL_REF; + Data.Mesh.NumThreads = RDAT_NULL_REF; + Data.Mesh.MaxOutputVertices = 17; + Data.PropertiesPart.Type = static_cast(22); + Data.PropertiesPart.Size = + sizeof(Data.PropertiesTable) + sizeof(Data.Properties); + Data.PropertiesTable.RecordCount = 1; + Data.PropertiesTable.RecordStride = sizeof(Data.Properties); + Data.Properties.PropertyType = + static_cast(FunctionPropertyType::Flags); + Data.Properties.Flags = 0x1234; + + DxilRuntimeData Reader; + VERIFY_IS_TRUE(Reader.InitFromRDAT(&Data, sizeof(Data))); + auto Mesh = Reader.GetMSInfoTable()[0]; + VERIFY_IS_TRUE(Mesh); + VERIFY_ARE_EQUAL(17u, static_cast(Mesh.getMaxOutputVertices())); + auto Properties = Reader.GetExtendedFunctionPropertiesTable()[0]; + VERIFY_IS_TRUE(Properties); + VERIFY_ARE_EQUAL(0x1234u, Properties.getFlags()); +} + TEST_F(DxilContainerTest, CompileWhenOkThenCheckRDAT) { if (m_ver.SkipDxilVersion(1, 3)) return;