From a485d10e7d1e18246c0293d7880b1da915fd52c1 Mon Sep 17 00:00:00 2001 From: Alex Sepkowski Date: Tue, 14 Jul 2026 19:05:39 -0700 Subject: [PATCH 1/2] Make PSV/DebugBreak unit tests handle the SM 6.9 cap Capping the highest shader model to 6.9 (PR #8618) lowers the validator version to 1.9, so the compiler emits PSVRuntimeInfo3 (52 bytes) instead of PSVRuntimeInfo4 (56 bytes) and rejects cs_6_10, which broke 14 unit tests. - PixTest DebugBreakInstrumentation_{Basic,Multiple}: skip when Dxil/ Validator < 1.10 (DebugBreak is an experimental SM 6.10 feature). - ValidationTest PSV tests: derive the expected PSVRuntimeInfo size from the validator version (v4 only for >= 1.10, else v3) instead of hard-coding sizeof(PSVRuntimeInfo4), and format the expected size into the WrongPSVVersion mismatch messages. Validated locally against a capped x64 build: the 14 tests pass, and the full ValidationTest + PixTest suites (302) and clang FileCheck lit suite show no failures. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 086148ba-a82b-41c4-8fa0-5eb63e5797e2 --- tools/clang/unittests/HLSL/PixTest.cpp | 4 ++ tools/clang/unittests/HLSL/ValidationTest.cpp | 62 ++++++++++++------- 2 files changed, 42 insertions(+), 24 deletions(-) diff --git a/tools/clang/unittests/HLSL/PixTest.cpp b/tools/clang/unittests/HLSL/PixTest.cpp index 93aad0281f..18c8a1c58b 100644 --- a/tools/clang/unittests/HLSL/PixTest.cpp +++ b/tools/clang/unittests/HLSL/PixTest.cpp @@ -3389,6 +3389,8 @@ void RaygenInternalName() } TEST_F(PixTest, DebugBreakInstrumentation_Basic) { + if (m_ver.SkipDxilVersion(1, 10)) + return; const char *source = R"x( [numthreads(1, 1, 1)] @@ -3426,6 +3428,8 @@ void main() { } TEST_F(PixTest, DebugBreakInstrumentation_Multiple) { + if (m_ver.SkipDxilVersion(1, 10)) + return; const char *source = R"x( RWByteAddressBuffer buf : register(u0); diff --git a/tools/clang/unittests/HLSL/ValidationTest.cpp b/tools/clang/unittests/HLSL/ValidationTest.cpp index 67c22e7b60..5d3a56c9ac 100644 --- a/tools/clang/unittests/HLSL/ValidationTest.cpp +++ b/tools/clang/unittests/HLSL/ValidationTest.cpp @@ -4882,6 +4882,15 @@ TEST_F(ValidationTest, CacheInitWithLowPrec) { TestCheck(L"..\\DXILValidation\\val-dx-type-lowprec.ll"); } +// PSVRuntimeInfo4 adds NumBytesGroupSharedMemory and is only emitted for +// validator version >= 1.10; earlier validators emit PSVRuntimeInfo3. +static uint32_t GetExpectedPSVRuntimeInfoSize(const VersionSupportInfo &ver) { + bool HasV4 = ver.m_ValMajor > 1 || + (ver.m_ValMajor == 1 && ver.m_ValMinor >= 10); + return HasV4 ? static_cast(sizeof(PSVRuntimeInfo4)) + : static_cast(sizeof(PSVRuntimeInfo3)); +} + TEST_F(ValidationTest, PSVStringTableReorder) { if (!m_ver.m_InternalValidator) if (m_ver.SkipDxilVersion(1, 8)) @@ -4916,7 +4925,7 @@ TEST_F(ValidationTest, PSVStringTableReorder) { const uint32_t *PSVPtr = (const uint32_t *)GetDxilPartData(pPSVPart); uint32_t PSVRuntimeInfo_size = *(PSVPtr++); - VERIFY_ARE_EQUAL(sizeof(PSVRuntimeInfo4), PSVRuntimeInfo_size); + VERIFY_ARE_EQUAL(GetExpectedPSVRuntimeInfoSize(m_ver), PSVRuntimeInfo_size); PSVRuntimeInfo4 *PSVInfo = const_cast((const PSVRuntimeInfo4 *)PSVPtr); VERIFY_ARE_EQUAL(2u, PSVInfo->SigInputElements); @@ -5108,7 +5117,7 @@ TEST_F(ValidationTest, PSVSemanticIndexTableReorder) { const uint32_t *PSVPtr = (const uint32_t *)GetDxilPartData(pPSVPart); uint32_t PSVRuntimeInfo_size = *(PSVPtr++); - VERIFY_ARE_EQUAL(sizeof(PSVRuntimeInfo4), PSVRuntimeInfo_size); + VERIFY_ARE_EQUAL(GetExpectedPSVRuntimeInfoSize(m_ver), PSVRuntimeInfo_size); PSVRuntimeInfo4 *PSVInfo = const_cast((const PSVRuntimeInfo4 *)PSVPtr); VERIFY_ARE_EQUAL(PSVInfo->SigInputElements, 3u); @@ -5443,17 +5452,18 @@ struct SimplePSV { llvm::MutableArrayRef PCInputToOutputTable; llvm::MutableArrayRef ViewIDOutputMask[DXIL::kNumOutputStreams]; llvm::MutableArrayRef ViewIDPCOutputMask; - SimplePSV(const DxilPartHeader *pPSVPart); + SimplePSV(const DxilPartHeader *pPSVPart, uint32_t ExpectedRuntimeInfoSize); }; -SimplePSV::SimplePSV(const DxilPartHeader *pPSVPart) { +SimplePSV::SimplePSV(const DxilPartHeader *pPSVPart, + uint32_t ExpectedRuntimeInfoSize) { uint32_t PartSize = pPSVPart->PartSize; uint32_t *PSVPtr = const_cast((const uint32_t *)GetDxilPartData(pPSVPart)); const uint32_t *PSVPtrEnd = PSVPtr + PartSize / 4; uint32_t PSVRuntimeInfoSize = *(PSVPtr++); - VERIFY_ARE_EQUAL(sizeof(PSVRuntimeInfo4), PSVRuntimeInfoSize); + VERIFY_ARE_EQUAL(ExpectedRuntimeInfoSize, PSVRuntimeInfoSize); PSVRuntimeInfo4 *PSVInfo4 = const_cast((const PSVRuntimeInfo4 *)PSVPtr); PSVInfo = PSVInfo4; @@ -5581,7 +5591,7 @@ TEST_F(ValidationTest, PSVContentValidationVS) { VERIFY_ARE_NOT_EQUAL(hlsl::end(pHeader), pPartIter); const DxilPartHeader *pPSVPart = (const DxilPartHeader *)(*pPartIter); - SimplePSV PSV(pPSVPart); + SimplePSV PSV(pPSVPart, GetExpectedPSVRuntimeInfoSize(m_ver)); // Update PSV. PSV.SigInput[0].InterpolationMode = 20; @@ -5737,7 +5747,7 @@ TEST_F(ValidationTest, PSVContentValidationHS) { VERIFY_ARE_NOT_EQUAL(hlsl::end(pHeader), pPartIter); const DxilPartHeader *pPSVPart = (const DxilPartHeader *)(*pPartIter); - SimplePSV PSV(pPSVPart); + SimplePSV PSV(pPSVPart, GetExpectedPSVRuntimeInfoSize(m_ver)); // Update PSV. PSV.SigPatchConstOrPrim[0].InterpolationMode = 20; @@ -5887,7 +5897,7 @@ TEST_F(ValidationTest, PSVContentValidationDS) { VERIFY_ARE_NOT_EQUAL(hlsl::end(pHeader), pPartIter); const DxilPartHeader *pPSVPart = (const DxilPartHeader *)(*pPartIter); - SimplePSV PSV(pPSVPart); + SimplePSV PSV(pPSVPart, GetExpectedPSVRuntimeInfoSize(m_ver)); // Update PSV. PSV.SigPatchConstOrPrim[0].InterpolationMode = 20; @@ -6044,7 +6054,7 @@ TEST_F(ValidationTest, PSVContentValidationGS) { VERIFY_ARE_NOT_EQUAL(hlsl::end(pHeader), pPartIter); const DxilPartHeader *pPSVPart = (const DxilPartHeader *)(*pPartIter); - SimplePSV PSV(pPSVPart); + SimplePSV PSV(pPSVPart, GetExpectedPSVRuntimeInfoSize(m_ver)); // Update PSV. PSV.PSVInfo->MaxVertexCount = 2; @@ -6132,7 +6142,7 @@ TEST_F(ValidationTest, PSVContentValidationPS) { VERIFY_ARE_NOT_EQUAL(hlsl::end(pHeader), pPartIter); const DxilPartHeader *pPSVPart = (const DxilPartHeader *)(*pPartIter); - SimplePSV PSV(pPSVPart); + SimplePSV PSV(pPSVPart, GetExpectedPSVRuntimeInfoSize(m_ver)); // Update PSV. PSV.PSVInfo->PS.DepthOutput = 1; @@ -6217,7 +6227,7 @@ TEST_F(ValidationTest, PSVContentValidationCS) { VERIFY_ARE_NOT_EQUAL(hlsl::end(pHeader), pPartIter); const DxilPartHeader *pPSVPart = (const DxilPartHeader *)(*pPartIter); - SimplePSV PSV(pPSVPart); + SimplePSV PSV(pPSVPart, GetExpectedPSVRuntimeInfoSize(m_ver)); // Update PSV. PSV.PSVInfo->NumThreadsX = 1; @@ -6299,7 +6309,7 @@ TEST_F(ValidationTest, PSVContentValidationMS) { VERIFY_ARE_NOT_EQUAL(hlsl::end(pHeader), pPartIter); const DxilPartHeader *pPSVPart = (const DxilPartHeader *)(*pPartIter); - SimplePSV PSV(pPSVPart); + SimplePSV PSV(pPSVPart, GetExpectedPSVRuntimeInfoSize(m_ver)); // Update PSV. memset(PSV.ViewIDOutputMask[0].data(), 0, PSV.ViewIDOutputMask[0].size() * sizeof(uint32_t)); @@ -6366,7 +6376,7 @@ TEST_F(ValidationTest, PSVContentValidationAS) { VERIFY_ARE_NOT_EQUAL(hlsl::end(pHeader), pPartIter); const DxilPartHeader *pPSVPart = (const DxilPartHeader *)(*pPartIter); - SimplePSV PSV(pPSVPart); + SimplePSV PSV(pPSVPart, GetExpectedPSVRuntimeInfoSize(m_ver)); // Update PSV. PSV.PSVInfo->AS.PayloadSizeInBytes = 0; @@ -6560,7 +6570,7 @@ TEST_F(ValidationTest, WrongPSVSizeOnZeros) { const uint32_t *PSVPtr = (const uint32_t *)GetDxilPartData(pPSVPart); uint32_t PSVRuntimeInfo_size = *(PSVPtr++); - VERIFY_ARE_EQUAL(sizeof(PSVRuntimeInfo4), PSVRuntimeInfo_size); + VERIFY_ARE_EQUAL(GetExpectedPSVRuntimeInfoSize(m_ver), PSVRuntimeInfo_size); PSVRuntimeInfo4 *PSVInfo = const_cast((const PSVRuntimeInfo4 *)PSVPtr); VERIFY_ARE_EQUAL(2u, PSVInfo->SigInputElements); @@ -6791,11 +6801,14 @@ TEST_F(ValidationTest, WrongPSVVersion) { VERIFY_IS_NOT_NULL(p60WithPSV68Result); VERIFY_SUCCEEDED(p60WithPSV68Result->GetStatus(&status)); VERIFY_FAILED(status); - CheckOperationResultMsgs( - p60WithPSV68Result, - {"DXIL container mismatch for 'PSVRuntimeInfoSize' between 'PSV0' " - "part:('56') and DXIL module:('24')"}, - /*maySucceedAnyway*/ false, /*bRegex*/ false); + std::string ExpectedPSVSizeStr = + std::to_string(GetExpectedPSVRuntimeInfoSize(m_ver)); + std::string Msg60WithPSV68 = + "DXIL container mismatch for 'PSVRuntimeInfoSize' between 'PSV0' " + "part:('" + + ExpectedPSVSizeStr + "') and DXIL module:('24')"; + CheckOperationResultMsgs(p60WithPSV68Result, {Msg60WithPSV68.c_str()}, + /*maySucceedAnyway*/ false, /*bRegex*/ false); // Create a new Blob. CComPtr pProgram68WithPSV60; @@ -6809,9 +6822,10 @@ TEST_F(ValidationTest, WrongPSVVersion) { VERIFY_IS_NOT_NULL(p68WithPSV60Result); VERIFY_SUCCEEDED(p68WithPSV60Result->GetStatus(&status)); VERIFY_FAILED(status); - CheckOperationResultMsgs( - p68WithPSV60Result, - {"DXIL container mismatch for 'PSVRuntimeInfoSize' between 'PSV0' " - "part:('24') and DXIL module:('56')"}, - /*maySucceedAnyway*/ false, /*bRegex*/ false); + std::string Msg68WithPSV60 = + "DXIL container mismatch for 'PSVRuntimeInfoSize' between 'PSV0' " + "part:('24') and DXIL module:('" + + ExpectedPSVSizeStr + "')"; + CheckOperationResultMsgs(p68WithPSV60Result, {Msg68WithPSV60.c_str()}, + /*maySucceedAnyway*/ false, /*bRegex*/ false); } From 1ac755da5c9d988e1b873c0adbf57210853a1d4b Mon Sep 17 00:00:00 2001 From: Alex Sepkowski Date: Wed, 15 Jul 2026 13:25:45 -0700 Subject: [PATCH 2/2] Apply clang-format to PSV runtime-info size helper Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 942a5e5f-0252-472b-9529-7218fdab7664 --- tools/clang/unittests/HLSL/ValidationTest.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/clang/unittests/HLSL/ValidationTest.cpp b/tools/clang/unittests/HLSL/ValidationTest.cpp index 5d3a56c9ac..96b07318bf 100644 --- a/tools/clang/unittests/HLSL/ValidationTest.cpp +++ b/tools/clang/unittests/HLSL/ValidationTest.cpp @@ -4885,8 +4885,8 @@ TEST_F(ValidationTest, CacheInitWithLowPrec) { // PSVRuntimeInfo4 adds NumBytesGroupSharedMemory and is only emitted for // validator version >= 1.10; earlier validators emit PSVRuntimeInfo3. static uint32_t GetExpectedPSVRuntimeInfoSize(const VersionSupportInfo &ver) { - bool HasV4 = ver.m_ValMajor > 1 || - (ver.m_ValMajor == 1 && ver.m_ValMinor >= 10); + bool HasV4 = + ver.m_ValMajor > 1 || (ver.m_ValMajor == 1 && ver.m_ValMinor >= 10); return HasV4 ? static_cast(sizeof(PSVRuntimeInfo4)) : static_cast(sizeof(PSVRuntimeInfo3)); }