From f0d5ab2f8ce56912764d29d1266d118b56e56095 Mon Sep 17 00:00:00 2001 From: Alex Sepkowski <5620315+alsepkow@users.noreply.github.com> Date: Mon, 3 Nov 2025 20:21:04 -0800 Subject: [PATCH 01/12] Basic framework for WaveActive ops. --- .../unittests/HLSLExec/LongVectorOps.def | 2 + .../unittests/HLSLExec/LongVectorTestData.h | 9 +- .../clang/unittests/HLSLExec/LongVectors.cpp | 211 ++++++++++++++++-- .../unittests/HLSLExec/ShaderOpArith.xml | 16 +- 4 files changed, 213 insertions(+), 25 deletions(-) diff --git a/tools/clang/unittests/HLSLExec/LongVectorOps.def b/tools/clang/unittests/HLSLExec/LongVectorOps.def index 002b84a1f2..2b4f4f2dca 100644 --- a/tools/clang/unittests/HLSLExec/LongVectorOps.def +++ b/tools/clang/unittests/HLSLExec/LongVectorOps.def @@ -193,4 +193,6 @@ OP_LOAD_AND_STORE_SB(LoadAndStore_RD_SB_SRV, "RootDescriptor_SRV") #undef OP_LOAD_AND_STORE #undef OP_LOAD_AND_STORE_DEFINES +OP_DEFAULT(Wave, WaveActiveSum, 1, "WaveActiveSum", "") + #undef OP diff --git a/tools/clang/unittests/HLSLExec/LongVectorTestData.h b/tools/clang/unittests/HLSLExec/LongVectorTestData.h index e8099329e8..9c9cd58137 100644 --- a/tools/clang/unittests/HLSLExec/LongVectorTestData.h +++ b/tools/clang/unittests/HLSLExec/LongVectorTestData.h @@ -114,6 +114,10 @@ struct HLSLHalf_t { Val = DirectX::PackedVector::XMConvertFloatToHalf(F); } + HLSLHalf_t(const uint32_t U) { + float F = static_cast(U); + Val = DirectX::PackedVector::XMConvertFloatToHalf(F); + } // PackedVector::HALF is a uint16. Make sure we don't ever accidentally // convert one of these to a HLSLHalf_t by arithmetically converting it to a @@ -345,8 +349,9 @@ INPUT_SET(InputSet::SelectCond, 0, 1); END_INPUT_SETS() BEGIN_INPUT_SETS(HLSLHalf_t) -INPUT_SET(InputSet::Default1, -1.0, -1.0, 1.0, -0.01, 1.0, -0.01, 1.0, -0.01, - 1.0, -0.01); +INPUT_SET(InputSet::Default1, -1.0, 1.0); +// INPUT_SET(InputSet::Default1, -1.0, -1.0, 1.0, -0.01, 1.0, -0.01, 1.0, -0.01, +// 1.0, -0.01); INPUT_SET(InputSet::Default2, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0); INPUT_SET(InputSet::Default3, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, diff --git a/tools/clang/unittests/HLSLExec/LongVectors.cpp b/tools/clang/unittests/HLSLExec/LongVectors.cpp index 95b23ed5b3..0c55592ee7 100644 --- a/tools/clang/unittests/HLSLExec/LongVectors.cpp +++ b/tools/clang/unittests/HLSLExec/LongVectors.cpp @@ -313,10 +313,10 @@ static WEX::Common::String getInputValueSetName(size_t Index) { return ValueSetName; } -std::string getCompilerOptionsString(const Operation &Operation, - const DataType &OpDataType, - const DataType &OutDataType, - size_t VectorSize) { +std::string getCompilerOptionsString( + const Operation &Operation, const DataType &OpDataType, + const DataType &OutDataType, size_t VectorSize, + std::optional AdditionalOptions = std::nullopt) { std::stringstream CompilerOptions; if (OpDataType.Is16Bit || OutDataType.Is16Bit) @@ -337,6 +337,9 @@ std::string getCompilerOptionsString(const Operation &Operation, CompilerOptions << " -DBASIC_OP_TYPE=0x" << std::hex << Operation.Arity; + if (AdditionalOptions) + CompilerOptions << " " << AdditionalOptions.value(); + return CompilerOptions.str(); } @@ -387,7 +390,8 @@ template std::optional> runTest(ID3D12Device *D3DDevice, bool VerboseLogging, const Operation &Operation, const InputSets &Inputs, - size_t ExpectedOutputSize) { + size_t ExpectedOutputSize, + std::optional AdditionalCompilerOptions) { DXASSERT_NOMSG(Inputs.size() == Operation.Arity); if (VerboseLogging) { @@ -403,8 +407,9 @@ runTest(ID3D12Device *D3DDevice, bool VerboseLogging, // We have to construct the string outside of the lambda. Otherwise it's // cleaned up when the lambda finishes executing but before the shader runs. - std::string CompilerOptionsString = getCompilerOptionsString( - Operation, OpDataType, OutDataType, Inputs[0].size()); + std::string CompilerOptionsString = + getCompilerOptionsString(Operation, OpDataType, OutDataType, + Inputs[0].size(), AdditionalCompilerOptions); dxc::SpecificDllLoader DxilDllLoader; CComPtr TestXML; @@ -570,13 +575,15 @@ struct ValidationConfig { }; template -void runAndVerify(ID3D12Device *D3DDevice, bool VerboseLogging, - const Operation &Operation, const InputSets &Inputs, - const std::vector &Expected, - const ValidationConfig &ValidationConfig) { +void runAndVerify( + ID3D12Device *D3DDevice, bool VerboseLogging, const Operation &Operation, + const InputSets &Inputs, const std::vector &Expected, + const ValidationConfig &ValidationConfig, + std::optional AdditionalCompilerOptions = std::nullopt) { - std::optional> Actual = runTest( - D3DDevice, VerboseLogging, Operation, Inputs, Expected.size()); + std::optional> Actual = + runTest(D3DDevice, VerboseLogging, Operation, Inputs, + Expected.size(), AdditionalCompilerOptions); // If the test didn't run, don't verify anything. if (!Actual) @@ -1253,6 +1260,19 @@ FLOAT_SPECIAL_OP(OpType::IsInf, (std::isinf(A))); FLOAT_SPECIAL_OP(OpType::IsNan, (std::isnan(A))); #undef FLOAT_SPECIAL_OP +// +// Wave Ops +// + +#define WAVE_ACTIVE_OP(OP, IMPL) \ + template struct Op : StrictValidation { \ + T operator()(T A, T WaveSize) { return IMPL; } \ + }; + +WAVE_ACTIVE_OP(OpType::WaveActiveSum, (A * WaveSize)); + +#undef WAVE_ACTIVE_OP + // // dispatchTest // @@ -1296,9 +1316,25 @@ template struct ExpectedBuilder { } }; +template struct WaveOpExpectedBuilder { + + static auto buildExpected(Op Op, const InputSets &Inputs, + UINT WaveSize) { + DXASSERT_NOMSG(Inputs.size() == 1); + const T WaveSizeT = static_cast(WaveSize); + + std::vector Expected; + Expected.reserve(Inputs[0].size()); + + for (size_t I = 0; I < Inputs[0].size(); ++I) + Expected.push_back(Op(Inputs[0][I], WaveSizeT)); + + return Expected; + } +}; + template -void dispatchTest(ID3D12Device *D3DDevice, bool VerboseLogging, - size_t OverrideInputSize) { +std::vector getInputSizesToTest(size_t OverrideInputSize) { std::vector InputVectorSizes; const std::array DefaultInputSizes = {3, 5, 16, 17, 35, 100, 256, 1024}; @@ -1319,8 +1355,17 @@ void dispatchTest(ID3D12Device *D3DDevice, bool VerboseLogging, InputVectorSizes.push_back(MaxInputSize); } - constexpr const Operation &Operation = getOperation(OP); + return InputVectorSizes; +} + +template +void dispatchTest(ID3D12Device *D3DDevice, bool VerboseLogging, + size_t OverrideInputSize) { + const std::vector InputVectorSizes = + getInputSizesToTest(OverrideInputSize); + + constexpr const Operation &Operation = getOperation(OP); Op Op; for (size_t VectorSize : InputVectorSizes) { @@ -1334,6 +1379,73 @@ void dispatchTest(ID3D12Device *D3DDevice, bool VerboseLogging, } } +static bool isWarpDevice(ID3D12Device *D3DDevice) { + DXASSERT_NOMSG(D3DDevice != nullptr); + + // Get the adapter LUID from the device + LUID AdapterLuid = D3DDevice->GetAdapterLuid(); + + // Create a DXGI factory to enumerate adapters + CComPtr DXGIFactory; + HRESULT HR = CreateDXGIFactory1(IID_PPV_ARGS(&DXGIFactory)); + if (FAILED(HR)) { + hlsl_test::LogCommentFmt( + L"isWarpDevice: Failed to create DXGI factory, HR=0x%08x", HR); + return false; + } + + // Get the adapter by LUID + CComPtr DXGIAdapter; + HR = DXGIFactory->EnumAdapterByLuid(AdapterLuid, IID_PPV_ARGS(&DXGIAdapter)); + if (FAILED(HR) || !DXGIAdapter) { + hlsl_test::LogCommentFmt( + L"isWarpDevice: Failed to enumerate adapter by LUID, HR=0x%08x", HR); + return false; + } + + DXGI_ADAPTER_DESC1 Desc{}; + HR = DXGIAdapter->GetDesc1(&Desc); + if (FAILED(HR)) { + hlsl_test::LogCommentFmt( + L"isWarpDevice: Failed to get adapter description, HR=0x%08x", HR); + return false; + } + + // Check for WARP adapter (VendorId 0x1414, DeviceId 0x8c) + const bool IsWarp = (Desc.VendorId == 0x1414 && Desc.DeviceId == 0x8c); + hlsl_test::LogCommentFmt( + L"isWarpDevice: VendorId=0x%04x, DeviceId=0x%04x, IsWarp=%d", + Desc.VendorId, Desc.DeviceId, IsWarp); + + return IsWarp; +} + +template +void dispatchWaveOpTest(ID3D12Device *D3DDevice, bool VerboseLogging, + size_t OverrideInputSize, UINT WaveSize) { + + const std::vector InputVectorSizes = + getInputSizesToTest(OverrideInputSize); + + constexpr const Operation &Operation = getOperation(OP); + Op Op; + + std::optional AdditionalCompilerOptions = + "-DWAVE_SIZE=" + std::to_string(WaveSize) + + " -DNUMTHREADS_X=" + std::to_string(WaveSize); + + for (size_t VectorSize : InputVectorSizes) { + std::vector> Inputs = + buildTestInputs(VectorSize, Operation.InputSets, Operation.Arity); + + auto Expected = + WaveOpExpectedBuilder::buildExpected(Op, Inputs, WaveSize); + + runAndVerify(D3DDevice, VerboseLogging, Operation, Inputs, Expected, + Op.ValidationConfig, AdditionalCompilerOptions); + } +} + } // namespace LongVector using namespace LongVector; @@ -1342,6 +1454,9 @@ using namespace LongVector; #define HLK_TEST(Op, DataType) \ TEST_METHOD(Op##_##DataType) { runTest(); } +#define HLK_WAVEOP_TEST(Op, DataType) \ + TEST_METHOD(Op##_##DataType) { runWaveOpTest(); } + class DxilConf_SM69_Vectorized { public: BEGIN_TEST_CLASS(DxilConf_SM69_Vectorized) @@ -1405,6 +1520,8 @@ class DxilConf_SM69_Vectorized { WEX::TestExecution::RuntimeParameters::TryGetValue(L"InputSize", OverrideInputSize); + WEX::TestExecution::RuntimeParameters::TryGetValue(L"WaveLaneCount", + OverrideWaveLaneCount); bool IsRITP = false; WEX::TestExecution::RuntimeParameters::TryGetValue(L"RITP", IsRITP); @@ -1428,15 +1545,54 @@ class DxilConf_SM69_Vectorized { return true; } - template void runTest() { - WEX::TestExecution::SetVerifyOutput verifySettings( - WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures); - + void CheckDevice() { // It's possible a previous test case caused a device removal. If it did we // need to try and create a new device. - if (!D3DDevice || D3DDevice->GetDeviceRemovedReason() != S_OK) + if (!D3DDevice || D3DDevice->GetDeviceRemovedReason() != S_OK) { + hlsl_test::LogCommentFmt( + L"Device was lost: Attempting to create a new D3D12 device."); VERIFY_IS_TRUE( createDevice(&D3DDevice, ExecTestUtils::D3D_SHADER_MODEL_6_9, false)); + } + } + + template void runWaveOpTest() { + WEX::TestExecution::SetVerifyOutput verifySettings( + WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures); + + CheckDevice(); + + UINT MaxWaveSize = 0; + + if (OverrideWaveLaneCount > 0) { + MaxWaveSize = OverrideWaveLaneCount; + hlsl_test::LogCommentFmt( + L"Using overridden WaveLaneCount of %d for this test.", MaxWaveSize); + } else if (isWarpDevice(D3DDevice)) + // Executing with a large wave lane count on WARP leads to very long test + // runtimes for large long vectors. 8 is WARPs default wave size. + MaxWaveSize = 8; + else { + // Get supported wave sizes + D3D12_FEATURE_DATA_D3D12_OPTIONS1 waveOpts; + VERIFY_SUCCEEDED(D3DDevice->CheckFeatureSupport( + (D3D12_FEATURE)D3D12_FEATURE_D3D12_OPTIONS1, &waveOpts, + sizeof(waveOpts))); + + MaxWaveSize = waveOpts.WaveLaneCountMax; + } + + DXASSERT_NOMSG(MaxWaveSize > 0); + + dispatchWaveOpTest(D3DDevice, VerboseLogging, OverrideInputSize, + MaxWaveSize); + } + + template void runTest() { + WEX::TestExecution::SetVerifyOutput verifySettings( + WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures); + + CheckDevice(); dispatchTest(D3DDevice, VerboseLogging, OverrideInputSize); } @@ -2052,9 +2208,22 @@ class DxilConf_SM69_Vectorized { HLK_TEST(LoadAndStore_RD_SB_SRV, double); HLK_TEST(LoadAndStore_RD_SB_UAV, double); + HLK_WAVEOP_TEST(WaveActiveSum, int16_t); + HLK_WAVEOP_TEST(WaveActiveSum, int32_t); + HLK_WAVEOP_TEST(WaveActiveSum, int64_t); + + HLK_WAVEOP_TEST(WaveActiveSum, uint16_t); + HLK_WAVEOP_TEST(WaveActiveSum, uint32_t); + HLK_WAVEOP_TEST(WaveActiveSum, uint64_t); + + HLK_WAVEOP_TEST(WaveActiveSum, HLSLHalf_t); + HLK_WAVEOP_TEST(WaveActiveSum, float); + HLK_WAVEOP_TEST(WaveActiveSum, double); + private: bool Initialized = false; bool VerboseLogging = false; size_t OverrideInputSize = 0; + UINT OverrideWaveLaneCount = 0; CComPtr D3DDevice; }; diff --git a/tools/clang/unittests/HLSLExec/ShaderOpArith.xml b/tools/clang/unittests/HLSLExec/ShaderOpArith.xml index be9ca847b4..99e1b14fa3 100644 --- a/tools/clang/unittests/HLSLExec/ShaderOpArith.xml +++ b/tools/clang/unittests/HLSLExec/ShaderOpArith.xml @@ -4101,7 +4101,20 @@ void MSMain(uint GID : SV_GroupIndex, } #endif - [numthreads(1,1,1)] + #ifdef NUMTHREADS_X + #define NUMTHREADS_ATTR [numthreads(NUMTHREADS_X, 1, 1)] + #else + #define NUMTHREADS_ATTR [numthreads(1, 1, 1)] + #endif + + #ifdef WAVE_SIZE + #define WAVE_SIZE_ATTR [WaveSize(WAVE_SIZE)] + #else + #define WAVE_SIZE_ATTR + #endif + + WAVE_SIZE_ATTR + NUMTHREADS_ATTR void main(uint GI : SV_GroupIndex) { #ifdef FUNC_SHUFFLE_VECTOR @@ -4128,7 +4141,6 @@ void MSMain(uint GID : SV_GroupIndex, #else const uint32_t OutNum = NUM; #endif - #if IS_UNARY_OP vector OutputVector = FUNC(Input1); #elif IS_BINARY_OP From 09149c9c95f3192588185d1b91066eaab2d3b26d Mon Sep 17 00:00:00 2001 From: Alex Sepkowski <5620315+alsepkow@users.noreply.github.com> Date: Wed, 5 Nov 2025 11:19:23 -0800 Subject: [PATCH 02/12] Cleanup. Switch to default validation so we get 1 ULP of tolerance for floating point ops for now. --- tools/clang/unittests/HLSLExec/LongVectorTestData.h | 5 ++--- tools/clang/unittests/HLSLExec/LongVectors.cpp | 2 +- tools/clang/unittests/HLSLExec/ShaderOpArith.xml | 1 + 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/clang/unittests/HLSLExec/LongVectorTestData.h b/tools/clang/unittests/HLSLExec/LongVectorTestData.h index 9c9cd58137..81b9d2cfef 100644 --- a/tools/clang/unittests/HLSLExec/LongVectorTestData.h +++ b/tools/clang/unittests/HLSLExec/LongVectorTestData.h @@ -349,9 +349,8 @@ INPUT_SET(InputSet::SelectCond, 0, 1); END_INPUT_SETS() BEGIN_INPUT_SETS(HLSLHalf_t) -INPUT_SET(InputSet::Default1, -1.0, 1.0); -// INPUT_SET(InputSet::Default1, -1.0, -1.0, 1.0, -0.01, 1.0, -0.01, 1.0, -0.01, -// 1.0, -0.01); +INPUT_SET(InputSet::Default1, -1.0, -1.0, 1.0, -0.01, 1.0, -0.01, 1.0, -0.01, + 1.0, -0.01); INPUT_SET(InputSet::Default2, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0); INPUT_SET(InputSet::Default3, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, diff --git a/tools/clang/unittests/HLSLExec/LongVectors.cpp b/tools/clang/unittests/HLSLExec/LongVectors.cpp index 0c55592ee7..77d91ec9e2 100644 --- a/tools/clang/unittests/HLSLExec/LongVectors.cpp +++ b/tools/clang/unittests/HLSLExec/LongVectors.cpp @@ -1265,7 +1265,7 @@ FLOAT_SPECIAL_OP(OpType::IsNan, (std::isnan(A))); // #define WAVE_ACTIVE_OP(OP, IMPL) \ - template struct Op : StrictValidation { \ + template struct Op : DefaultValidation { \ T operator()(T A, T WaveSize) { return IMPL; } \ }; diff --git a/tools/clang/unittests/HLSLExec/ShaderOpArith.xml b/tools/clang/unittests/HLSLExec/ShaderOpArith.xml index 99e1b14fa3..b48e94bf3d 100644 --- a/tools/clang/unittests/HLSLExec/ShaderOpArith.xml +++ b/tools/clang/unittests/HLSLExec/ShaderOpArith.xml @@ -4141,6 +4141,7 @@ void MSMain(uint GID : SV_GroupIndex, #else const uint32_t OutNum = NUM; #endif + #if IS_UNARY_OP vector OutputVector = FUNC(Input1); #elif IS_BINARY_OP From 2e23f00030854c3ab5895ec6b117bb3b99b18699 Mon Sep 17 00:00:00 2001 From: Alex Sepkowski <5620315+alsepkow@users.noreply.github.com> Date: Wed, 5 Nov 2025 11:40:01 -0800 Subject: [PATCH 03/12] formatting --- tools/clang/unittests/HLSLExec/LongVectors.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/clang/unittests/HLSLExec/LongVectors.cpp b/tools/clang/unittests/HLSLExec/LongVectors.cpp index 77d91ec9e2..2860f8b4d4 100644 --- a/tools/clang/unittests/HLSLExec/LongVectors.cpp +++ b/tools/clang/unittests/HLSLExec/LongVectors.cpp @@ -1522,6 +1522,7 @@ class DxilConf_SM69_Vectorized { WEX::TestExecution::RuntimeParameters::TryGetValue(L"WaveLaneCount", OverrideWaveLaneCount); + bool IsRITP = false; WEX::TestExecution::RuntimeParameters::TryGetValue(L"RITP", IsRITP); @@ -1573,7 +1574,6 @@ class DxilConf_SM69_Vectorized { // runtimes for large long vectors. 8 is WARPs default wave size. MaxWaveSize = 8; else { - // Get supported wave sizes D3D12_FEATURE_DATA_D3D12_OPTIONS1 waveOpts; VERIFY_SUCCEEDED(D3DDevice->CheckFeatureSupport( (D3D12_FEATURE)D3D12_FEATURE_D3D12_OPTIONS1, &waveOpts, @@ -1583,6 +1583,7 @@ class DxilConf_SM69_Vectorized { } DXASSERT_NOMSG(MaxWaveSize > 0); + DXASSERT((MaxWaveSize & (MaxWaveSize - 1)) == 0, "must be a power of 2"); dispatchWaveOpTest(D3DDevice, VerboseLogging, OverrideInputSize, MaxWaveSize); From a027025f73e561c63f2ba26ac750a03a4b1814d9 Mon Sep 17 00:00:00 2001 From: Alex Sepkowski <5620315+alsepkow@users.noreply.github.com> Date: Wed, 5 Nov 2025 20:36:56 -0800 Subject: [PATCH 04/12] check device in test method setup. default to min wave size instead --- .../clang/unittests/HLSLExec/LongVectors.cpp | 70 +++---------------- 1 file changed, 11 insertions(+), 59 deletions(-) diff --git a/tools/clang/unittests/HLSLExec/LongVectors.cpp b/tools/clang/unittests/HLSLExec/LongVectors.cpp index 2860f8b4d4..03dd1f154c 100644 --- a/tools/clang/unittests/HLSLExec/LongVectors.cpp +++ b/tools/clang/unittests/HLSLExec/LongVectors.cpp @@ -1379,47 +1379,6 @@ void dispatchTest(ID3D12Device *D3DDevice, bool VerboseLogging, } } -static bool isWarpDevice(ID3D12Device *D3DDevice) { - DXASSERT_NOMSG(D3DDevice != nullptr); - - // Get the adapter LUID from the device - LUID AdapterLuid = D3DDevice->GetAdapterLuid(); - - // Create a DXGI factory to enumerate adapters - CComPtr DXGIFactory; - HRESULT HR = CreateDXGIFactory1(IID_PPV_ARGS(&DXGIFactory)); - if (FAILED(HR)) { - hlsl_test::LogCommentFmt( - L"isWarpDevice: Failed to create DXGI factory, HR=0x%08x", HR); - return false; - } - - // Get the adapter by LUID - CComPtr DXGIAdapter; - HR = DXGIFactory->EnumAdapterByLuid(AdapterLuid, IID_PPV_ARGS(&DXGIAdapter)); - if (FAILED(HR) || !DXGIAdapter) { - hlsl_test::LogCommentFmt( - L"isWarpDevice: Failed to enumerate adapter by LUID, HR=0x%08x", HR); - return false; - } - - DXGI_ADAPTER_DESC1 Desc{}; - HR = DXGIAdapter->GetDesc1(&Desc); - if (FAILED(HR)) { - hlsl_test::LogCommentFmt( - L"isWarpDevice: Failed to get adapter description, HR=0x%08x", HR); - return false; - } - - // Check for WARP adapter (VendorId 0x1414, DeviceId 0x8c) - const bool IsWarp = (Desc.VendorId == 0x1414 && Desc.DeviceId == 0x8c); - hlsl_test::LogCommentFmt( - L"isWarpDevice: VendorId=0x%04x, DeviceId=0x%04x, IsWarp=%d", - Desc.VendorId, Desc.DeviceId, IsWarp); - - return IsWarp; -} - template void dispatchWaveOpTest(ID3D12Device *D3DDevice, bool VerboseLogging, size_t OverrideInputSize, UINT WaveSize) { @@ -1546,7 +1505,7 @@ class DxilConf_SM69_Vectorized { return true; } - void CheckDevice() { + TEST_METHOD_SETUP(methodSetup) { // It's possible a previous test case caused a device removal. If it did we // need to try and create a new device. if (!D3DDevice || D3DDevice->GetDeviceRemovedReason() != S_OK) { @@ -1555,46 +1514,39 @@ class DxilConf_SM69_Vectorized { VERIFY_IS_TRUE( createDevice(&D3DDevice, ExecTestUtils::D3D_SHADER_MODEL_6_9, false)); } + + return true; } template void runWaveOpTest() { WEX::TestExecution::SetVerifyOutput verifySettings( WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures); - CheckDevice(); - - UINT MaxWaveSize = 0; + UINT WaveSize = 0; if (OverrideWaveLaneCount > 0) { - MaxWaveSize = OverrideWaveLaneCount; + WaveSize = OverrideWaveLaneCount; hlsl_test::LogCommentFmt( - L"Using overridden WaveLaneCount of %d for this test.", MaxWaveSize); - } else if (isWarpDevice(D3DDevice)) - // Executing with a large wave lane count on WARP leads to very long test - // runtimes for large long vectors. 8 is WARPs default wave size. - MaxWaveSize = 8; - else { + L"Using overridden WaveLaneCount of %d for this test.", WaveSize); + } else { D3D12_FEATURE_DATA_D3D12_OPTIONS1 waveOpts; VERIFY_SUCCEEDED(D3DDevice->CheckFeatureSupport( (D3D12_FEATURE)D3D12_FEATURE_D3D12_OPTIONS1, &waveOpts, sizeof(waveOpts))); - MaxWaveSize = waveOpts.WaveLaneCountMax; + WaveSize = waveOpts.WaveLaneCountMin; } - DXASSERT_NOMSG(MaxWaveSize > 0); - DXASSERT((MaxWaveSize & (MaxWaveSize - 1)) == 0, "must be a power of 2"); + DXASSERT_NOMSG(WaveSize > 0); + DXASSERT((WaveSize & (WaveSize - 1)) == 0, "must be a power of 2"); dispatchWaveOpTest(D3DDevice, VerboseLogging, OverrideInputSize, - MaxWaveSize); + WaveSize); } template void runTest() { WEX::TestExecution::SetVerifyOutput verifySettings( WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures); - - CheckDevice(); - dispatchTest(D3DDevice, VerboseLogging, OverrideInputSize); } From 7c06882ec10b98f7832d7a1ec5529e539212705d Mon Sep 17 00:00:00 2001 From: Alex Sepkowski <5620315+alsepkow@users.noreply.github.com> Date: Wed, 5 Nov 2025 21:13:17 -0800 Subject: [PATCH 05/12] Set priority on WAVEOP tests so they dont run in automation for now --- tools/clang/unittests/HLSLExec/LongVectors.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/clang/unittests/HLSLExec/LongVectors.cpp b/tools/clang/unittests/HLSLExec/LongVectors.cpp index 03dd1f154c..9e8a0958d4 100644 --- a/tools/clang/unittests/HLSLExec/LongVectors.cpp +++ b/tools/clang/unittests/HLSLExec/LongVectors.cpp @@ -1414,7 +1414,12 @@ using namespace LongVector; TEST_METHOD(Op##_##DataType) { runTest(); } #define HLK_WAVEOP_TEST(Op, DataType) \ - TEST_METHOD(Op##_##DataType) { runWaveOpTest(); } + TEST_METHOD(Op##_##DataType) { \ + BEGIN_TEST_METHOD_PROPERTIES() \ + TEST_METHOD_PROPERTY(L"Priority", L"2") \ + END_TEST_METHOD_PROPERTIES() \ + runWaveOpTest(); \ + } class DxilConf_SM69_Vectorized { public: From 4d99e8a3119460f686cfcaa874e4cd19da49fc0b Mon Sep 17 00:00:00 2001 From: Alex Sepkowski Date: Thu, 6 Nov 2025 13:36:29 -0800 Subject: [PATCH 06/12] Update tools/clang/unittests/HLSLExec/LongVectors.cpp Co-authored-by: Damyan Pepper --- tools/clang/unittests/HLSLExec/LongVectors.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/clang/unittests/HLSLExec/LongVectors.cpp b/tools/clang/unittests/HLSLExec/LongVectors.cpp index 9e8a0958d4..bb796cb7e1 100644 --- a/tools/clang/unittests/HLSLExec/LongVectors.cpp +++ b/tools/clang/unittests/HLSLExec/LongVectors.cpp @@ -1534,7 +1534,7 @@ class DxilConf_SM69_Vectorized { hlsl_test::LogCommentFmt( L"Using overridden WaveLaneCount of %d for this test.", WaveSize); } else { - D3D12_FEATURE_DATA_D3D12_OPTIONS1 waveOpts; + D3D12_FEATURE_DATA_D3D12_OPTIONS1 WaveOpts; VERIFY_SUCCEEDED(D3DDevice->CheckFeatureSupport( (D3D12_FEATURE)D3D12_FEATURE_D3D12_OPTIONS1, &waveOpts, sizeof(waveOpts))); From b00a6343f5aa52669ca109843ef05a9da3b10778 Mon Sep 17 00:00:00 2001 From: Alex Sepkowski Date: Thu, 6 Nov 2025 13:36:43 -0800 Subject: [PATCH 07/12] Update tools/clang/unittests/HLSLExec/LongVectors.cpp Co-authored-by: Damyan Pepper --- tools/clang/unittests/HLSLExec/LongVectors.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/clang/unittests/HLSLExec/LongVectors.cpp b/tools/clang/unittests/HLSLExec/LongVectors.cpp index bb796cb7e1..94a6468f16 100644 --- a/tools/clang/unittests/HLSLExec/LongVectors.cpp +++ b/tools/clang/unittests/HLSLExec/LongVectors.cpp @@ -1524,7 +1524,7 @@ class DxilConf_SM69_Vectorized { } template void runWaveOpTest() { - WEX::TestExecution::SetVerifyOutput verifySettings( + WEX::TestExecution::SetVerifyOutput VerifySettings( WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures); UINT WaveSize = 0; From 05ade6d577e61e767b1fdf1a8b8cd702ba0f8f28 Mon Sep 17 00:00:00 2001 From: Alex Sepkowski Date: Thu, 6 Nov 2025 13:37:13 -0800 Subject: [PATCH 08/12] Update tools/clang/unittests/HLSLExec/LongVectors.cpp Co-authored-by: Damyan Pepper --- tools/clang/unittests/HLSLExec/LongVectors.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/clang/unittests/HLSLExec/LongVectors.cpp b/tools/clang/unittests/HLSLExec/LongVectors.cpp index 94a6468f16..61747142f0 100644 --- a/tools/clang/unittests/HLSLExec/LongVectors.cpp +++ b/tools/clang/unittests/HLSLExec/LongVectors.cpp @@ -1536,7 +1536,7 @@ class DxilConf_SM69_Vectorized { } else { D3D12_FEATURE_DATA_D3D12_OPTIONS1 WaveOpts; VERIFY_SUCCEEDED(D3DDevice->CheckFeatureSupport( - (D3D12_FEATURE)D3D12_FEATURE_D3D12_OPTIONS1, &waveOpts, + D3D12_FEATURE_D3D12_OPTIONS1, &waveOpts, sizeof(waveOpts))); WaveSize = waveOpts.WaveLaneCountMin; From 4e69eb92635197b2c08e8b506e3504075aa25a0a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 6 Nov 2025 21:43:04 +0000 Subject: [PATCH 09/12] chore: autopublish 2025-11-06T21:43:04Z --- tools/clang/unittests/HLSLExec/LongVectors.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/clang/unittests/HLSLExec/LongVectors.cpp b/tools/clang/unittests/HLSLExec/LongVectors.cpp index 61747142f0..c832500157 100644 --- a/tools/clang/unittests/HLSLExec/LongVectors.cpp +++ b/tools/clang/unittests/HLSLExec/LongVectors.cpp @@ -1536,8 +1536,7 @@ class DxilConf_SM69_Vectorized { } else { D3D12_FEATURE_DATA_D3D12_OPTIONS1 WaveOpts; VERIFY_SUCCEEDED(D3DDevice->CheckFeatureSupport( - D3D12_FEATURE_D3D12_OPTIONS1, &waveOpts, - sizeof(waveOpts))); + D3D12_FEATURE_D3D12_OPTIONS1, &waveOpts, sizeof(waveOpts))); WaveSize = waveOpts.WaveLaneCountMin; } From 6d239809fdd4052ad902c25e6cf1a92561a42984 Mon Sep 17 00:00:00 2001 From: Alex Sepkowski <5620315+alsepkow@users.noreply.github.com> Date: Thu, 6 Nov 2025 13:44:28 -0800 Subject: [PATCH 10/12] Feedback --- tools/clang/unittests/HLSLExec/LongVectors.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tools/clang/unittests/HLSLExec/LongVectors.cpp b/tools/clang/unittests/HLSLExec/LongVectors.cpp index 61747142f0..1a945df67e 100644 --- a/tools/clang/unittests/HLSLExec/LongVectors.cpp +++ b/tools/clang/unittests/HLSLExec/LongVectors.cpp @@ -1389,7 +1389,7 @@ void dispatchWaveOpTest(ID3D12Device *D3DDevice, bool VerboseLogging, constexpr const Operation &Operation = getOperation(OP); Op Op; - std::optional AdditionalCompilerOptions = + const std::string AdditionalCompilerOptions = "-DWAVE_SIZE=" + std::to_string(WaveSize) + " -DNUMTHREADS_X=" + std::to_string(WaveSize); @@ -1536,10 +1536,9 @@ class DxilConf_SM69_Vectorized { } else { D3D12_FEATURE_DATA_D3D12_OPTIONS1 WaveOpts; VERIFY_SUCCEEDED(D3DDevice->CheckFeatureSupport( - D3D12_FEATURE_D3D12_OPTIONS1, &waveOpts, - sizeof(waveOpts))); + D3D12_FEATURE_D3D12_OPTIONS1, &WaveOpts, sizeof(WaveOpts))); - WaveSize = waveOpts.WaveLaneCountMin; + WaveSize = WaveOpts.WaveLaneCountMin; } DXASSERT_NOMSG(WaveSize > 0); From 76cfc91679d49b3347185f875c545545a969b7e7 Mon Sep 17 00:00:00 2001 From: Alex Sepkowski <5620315+alsepkow@users.noreply.github.com> Date: Thu, 6 Nov 2025 16:12:23 -0800 Subject: [PATCH 11/12] Missed merge --- tools/clang/unittests/HLSLExec/LongVectors.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tools/clang/unittests/HLSLExec/LongVectors.cpp b/tools/clang/unittests/HLSLExec/LongVectors.cpp index 9e5ea6ca58..1c1e17c4e3 100644 --- a/tools/clang/unittests/HLSLExec/LongVectors.cpp +++ b/tools/clang/unittests/HLSLExec/LongVectors.cpp @@ -1536,11 +1536,7 @@ class DxilConf_SM69_Vectorized { } else { D3D12_FEATURE_DATA_D3D12_OPTIONS1 WaveOpts; VERIFY_SUCCEEDED(D3DDevice->CheckFeatureSupport( -<<<<<<< HEAD - D3D12_FEATURE_D3D12_OPTIONS1, &WaveOpts, sizeof(WaveOpts))); -======= D3D12_FEATURE_D3D12_OPTIONS1, &waveOpts, sizeof(waveOpts))); ->>>>>>> 4e69eb92635197b2c08e8b506e3504075aa25a0a WaveSize = WaveOpts.WaveLaneCountMin; } From cd4bd581efc36e3b92b48d07303c1fcae4598481 Mon Sep 17 00:00:00 2001 From: Alex Sepkowski <5620315+alsepkow@users.noreply.github.com> Date: Thu, 6 Nov 2025 20:04:52 -0800 Subject: [PATCH 12/12] Doh --- tools/clang/unittests/HLSLExec/LongVectors.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/clang/unittests/HLSLExec/LongVectors.cpp b/tools/clang/unittests/HLSLExec/LongVectors.cpp index 1c1e17c4e3..1a945df67e 100644 --- a/tools/clang/unittests/HLSLExec/LongVectors.cpp +++ b/tools/clang/unittests/HLSLExec/LongVectors.cpp @@ -1536,7 +1536,7 @@ class DxilConf_SM69_Vectorized { } else { D3D12_FEATURE_DATA_D3D12_OPTIONS1 WaveOpts; VERIFY_SUCCEEDED(D3DDevice->CheckFeatureSupport( - D3D12_FEATURE_D3D12_OPTIONS1, &waveOpts, sizeof(waveOpts))); + D3D12_FEATURE_D3D12_OPTIONS1, &WaveOpts, sizeof(WaveOpts))); WaveSize = WaveOpts.WaveLaneCountMin; }