Skip to content

Commit b87d15d

Browse files
V-FEXrtdamyanp
andauthored
[SM6.10][LinAlg][HLK] Small test cleanups (#8295)
Addresses outstanding cleanup requests from the initial LinAlg exec test PR --------- Co-authored-by: Damyan Pepper <damyanp@microsoft.com>
1 parent d013457 commit b87d15d

File tree

3 files changed

+170
-133
lines changed

3 files changed

+170
-133
lines changed

tools/clang/unittests/HLSLExec/HlslExecTestUtils.cpp

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,3 +636,137 @@ UINT getMaxGroupSharedMemoryMS(ID3D12Device *Device) {
636636
D3D12_FEATURE_D3D12_OPTIONS_PREVIEW, &O, sizeof(O)));
637637
return O.MaxGroupSharedMemoryPerGroupMS;
638638
}
639+
640+
std::unique_ptr<st::ShaderOp> createComputeOp(const char *Source,
641+
const char *Target,
642+
const char *RootSig,
643+
const char *Args, UINT DispatchX,
644+
UINT DispatchY, UINT DispatchZ) {
645+
auto Op = std::make_unique<st::ShaderOp>();
646+
LPCSTR CSName = Op->Strings.insert("CS");
647+
Op->Name = CSName;
648+
Op->CS = CSName;
649+
Op->RootSignature = Op->Strings.insert(RootSig);
650+
Op->DispatchX = DispatchX;
651+
Op->DispatchY = DispatchY;
652+
Op->DispatchZ = DispatchZ;
653+
Op->UseWarpDevice = true;
654+
655+
st::ShaderOpShader Shader = {};
656+
Shader.Name = CSName;
657+
Shader.Target = Op->Strings.insert(Target);
658+
Shader.EntryPoint = Op->Strings.insert("main");
659+
Shader.Text = Op->Strings.insert(Source);
660+
Shader.Arguments = Args ? Op->Strings.insert(Args) : nullptr;
661+
Shader.Compiled = FALSE;
662+
Shader.Callback = FALSE;
663+
Op->Shaders.push_back(Shader);
664+
665+
return Op;
666+
}
667+
668+
void addUAVBuffer(st::ShaderOp *Op, const char *Name, UINT64 Width,
669+
bool ReadBack, const char *Init) {
670+
st::ShaderOpResource Res = {};
671+
Res.Name = Op->Strings.insert(Name);
672+
Res.Init = Op->Strings.insert(Init);
673+
Res.ReadBack = ReadBack ? TRUE : FALSE;
674+
675+
Res.HeapProperties.Type = D3D12_HEAP_TYPE_DEFAULT;
676+
Res.HeapFlags = D3D12_HEAP_FLAG_NONE;
677+
Res.Desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
678+
Res.Desc.Width = Width;
679+
Res.Desc.Height = 1;
680+
Res.Desc.DepthOrArraySize = 1;
681+
Res.Desc.MipLevels = 1;
682+
Res.Desc.SampleDesc.Count = 1;
683+
Res.Desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
684+
Res.Desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
685+
Res.InitialResourceState = D3D12_RESOURCE_STATE_COPY_DEST;
686+
Res.TransitionTo = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
687+
688+
Op->Resources.push_back(Res);
689+
}
690+
691+
void addRootUAV(st::ShaderOp *Op, UINT Index, const char *ResName) {
692+
st::ShaderOpRootValue RV = {};
693+
RV.ResName = Op->Strings.insert(ResName);
694+
RV.HeapName = nullptr;
695+
RV.Index = Index;
696+
Op->RootValues.push_back(RV);
697+
}
698+
699+
std::shared_ptr<st::ShaderOpTestResult>
700+
runShaderOp(ID3D12Device *Device, dxc::SpecificDllLoader &DxcSupport,
701+
std::unique_ptr<st::ShaderOp> Op,
702+
st::ShaderOpTest::TInitCallbackFn InitCallback) {
703+
auto OpSet = std::make_shared<st::ShaderOpSet>();
704+
OpSet->ShaderOps.push_back(std::move(Op));
705+
706+
return st::RunShaderOpTestAfterParse(
707+
Device, DxcSupport, nullptr, std::move(InitCallback), std::move(OpSet));
708+
}
709+
710+
void compileShader(dxc::SpecificDllLoader &DxcSupport, const char *Source,
711+
const char *Target, const std::string &Args,
712+
bool VerboseLogging) {
713+
CComPtr<IDxcCompiler3> Compiler;
714+
VERIFY_SUCCEEDED(DxcSupport.CreateInstance(CLSID_DxcCompiler, &Compiler));
715+
716+
CComPtr<IDxcUtils> Utils;
717+
VERIFY_SUCCEEDED(DxcSupport.CreateInstance(CLSID_DxcUtils, &Utils));
718+
719+
CComPtr<IDxcBlobEncoding> SourceBlob;
720+
VERIFY_SUCCEEDED(Utils->CreateBlobFromPinned(
721+
Source, static_cast<UINT32>(strlen(Source)), DXC_CP_UTF8, &SourceBlob));
722+
723+
// Build wide-string argument list: -T <target> -E main <extra args>.
724+
std::vector<std::wstring> WArgStorage;
725+
WArgStorage.push_back(L"-T");
726+
WArgStorage.push_back(std::wstring(Target, Target + strlen(Target)));
727+
WArgStorage.push_back(L"-E");
728+
WArgStorage.push_back(L"main");
729+
730+
// Tokenize the additional arguments string.
731+
std::istringstream SS(Args);
732+
std::string Tok;
733+
while (SS >> Tok)
734+
WArgStorage.push_back(std::wstring(Tok.begin(), Tok.end()));
735+
736+
std::vector<LPCWSTR> WArgPtrs;
737+
std::wstringstream LogFlags;
738+
LogFlags << L"Compiling with flags:";
739+
for (const auto &A : WArgStorage) {
740+
WArgPtrs.push_back(A.c_str());
741+
LogFlags << L" " << A;
742+
}
743+
744+
DxcBuffer Buf = {};
745+
Buf.Ptr = SourceBlob->GetBufferPointer();
746+
Buf.Size = SourceBlob->GetBufferSize();
747+
Buf.Encoding = DXC_CP_UTF8;
748+
749+
if (VerboseLogging) {
750+
hlsl_test::LogCommentFmt(L"Shader Source:");
751+
hlsl_test::LogCommentFmt(L"%c", Source);
752+
}
753+
754+
hlsl_test::LogCommentFmt(LogFlags.str().c_str());
755+
756+
CComPtr<IDxcResult> Result;
757+
VERIFY_SUCCEEDED(Compiler->Compile(&Buf, WArgPtrs.data(),
758+
static_cast<UINT32>(WArgPtrs.size()),
759+
nullptr, IID_PPV_ARGS(&Result)));
760+
761+
HRESULT HR;
762+
VERIFY_SUCCEEDED(Result->GetStatus(&HR));
763+
764+
if (FAILED(HR)) {
765+
CComPtr<IDxcBlobUtf8> Errors;
766+
Result->GetOutput(DXC_OUT_ERRORS, IID_PPV_ARGS(&Errors), nullptr);
767+
if (Errors && Errors->GetStringLength() > 0)
768+
hlsl_test::LogErrorFmt(L"Shader compilation failed:\n%S",
769+
Errors->GetStringPointer());
770+
VERIFY_SUCCEEDED(HR);
771+
}
772+
}

tools/clang/unittests/HLSLExec/HlslExecTestUtils.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@
33

44
#include <atlcomcli.h>
55
#include <d3d12.h>
6+
#include <memory>
67
#include <optional>
8+
#include <string>
79
#include <windows.h>
810

11+
#include "ShaderOpTest.h"
912
#include "dxc/Support/dxcapi.use.h"
1013

1114
// D3D_SHADER_MODEL_6_10 is not yet in the released Windows SDK.
@@ -74,4 +77,29 @@ UINT getMaxGroupSharedMemoryCS(ID3D12Device *Device);
7477
UINT getMaxGroupSharedMemoryAS(ID3D12Device *Device);
7578
UINT getMaxGroupSharedMemoryMS(ID3D12Device *Device);
7679

80+
/// Create a ShaderOp for a compute shader dispatch.
81+
std::unique_ptr<st::ShaderOp>
82+
createComputeOp(const char *Source, const char *Target, const char *RootSig,
83+
const char *Args = nullptr, UINT DispatchX = 1,
84+
UINT DispatchY = 1, UINT DispatchZ = 1);
85+
86+
/// Add a UAV buffer resource to a ShaderOp.
87+
void addUAVBuffer(st::ShaderOp *Op, const char *Name, UINT64 Width,
88+
bool ReadBack, const char *Init = "zero");
89+
90+
/// Bind a resource to a root UAV parameter by index.
91+
void addRootUAV(st::ShaderOp *Op, UINT Index, const char *ResName);
92+
93+
/// Run a programmatically-built ShaderOp and return the result.
94+
std::shared_ptr<st::ShaderOpTestResult>
95+
runShaderOp(ID3D12Device *Device, dxc::SpecificDllLoader &DxcSupport,
96+
std::unique_ptr<st::ShaderOp> Op,
97+
st::ShaderOpTest::TInitCallbackFn InitCallback = nullptr);
98+
99+
/// Compiles an HLSL shader using the DXC API to verify it is well-formed.
100+
/// Fails the test on compile error.
101+
void compileShader(dxc::SpecificDllLoader &DxcSupport, const char *Source,
102+
const char *Target, const std::string &Args,
103+
bool VerboseLogging = false);
104+
77105
#endif // HLSLEXECTESTUTILS_H

tools/clang/unittests/HLSLExec/LinAlgTests.cpp

Lines changed: 8 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#include "HlslExecTestUtils.h"
2626

27+
#include <climits>
2728
#include <optional>
2829
#include <sstream>
2930
#include <string>
@@ -52,134 +53,6 @@ static int elemSize(ComponentType CT) {
5253
}
5354
}
5455

55-
/// Create a ShaderOp for a compute shader dispatch.
56-
static std::unique_ptr<st::ShaderOp>
57-
createComputeOp(const char *Source, const char *Target, const char *RootSig,
58-
const char *Args = nullptr, UINT DispatchX = 1,
59-
UINT DispatchY = 1, UINT DispatchZ = 1) {
60-
auto Op = std::make_unique<st::ShaderOp>();
61-
LPCSTR CSName = Op->Strings.insert("CS");
62-
Op->Name = CSName;
63-
Op->CS = CSName;
64-
Op->RootSignature = Op->Strings.insert(RootSig);
65-
Op->DispatchX = DispatchX;
66-
Op->DispatchY = DispatchY;
67-
Op->DispatchZ = DispatchZ;
68-
Op->UseWarpDevice = true;
69-
70-
st::ShaderOpShader Shader = {};
71-
Shader.Name = CSName;
72-
Shader.Target = Op->Strings.insert(Target);
73-
Shader.EntryPoint = Op->Strings.insert("main");
74-
Shader.Text = Op->Strings.insert(Source);
75-
Shader.Arguments = Args ? Op->Strings.insert(Args) : nullptr;
76-
Shader.Compiled = FALSE;
77-
Shader.Callback = FALSE;
78-
Op->Shaders.push_back(Shader);
79-
80-
return Op;
81-
}
82-
83-
/// Add a UAV buffer resource to a ShaderOp.
84-
static void addUAVBuffer(st::ShaderOp *Op, const char *Name, UINT64 Width,
85-
bool ReadBack, const char *Init = "zero") {
86-
st::ShaderOpResource Res = {};
87-
Res.Name = Op->Strings.insert(Name);
88-
Res.Init = Op->Strings.insert(Init);
89-
Res.ReadBack = ReadBack ? TRUE : FALSE;
90-
91-
Res.HeapProperties.Type = D3D12_HEAP_TYPE_DEFAULT;
92-
Res.HeapFlags = D3D12_HEAP_FLAG_NONE;
93-
Res.Desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
94-
Res.Desc.Width = Width;
95-
Res.Desc.Height = 1;
96-
Res.Desc.DepthOrArraySize = 1;
97-
Res.Desc.MipLevels = 1;
98-
Res.Desc.SampleDesc.Count = 1;
99-
Res.Desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
100-
Res.Desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
101-
Res.InitialResourceState = D3D12_RESOURCE_STATE_COPY_DEST;
102-
Res.TransitionTo = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
103-
104-
Op->Resources.push_back(Res);
105-
}
106-
107-
/// Bind a resource to a root UAV parameter by index.
108-
static void addRootUAV(st::ShaderOp *Op, UINT Index, const char *ResName) {
109-
st::ShaderOpRootValue RV = {};
110-
RV.ResName = Op->Strings.insert(ResName);
111-
RV.HeapName = nullptr;
112-
RV.Index = Index;
113-
Op->RootValues.push_back(RV);
114-
}
115-
116-
/// Run a programmatically-built ShaderOp and return the result.
117-
static std::shared_ptr<st::ShaderOpTestResult>
118-
runShaderOp(ID3D12Device *Device, dxc::SpecificDllLoader &DxcSupport,
119-
std::unique_ptr<st::ShaderOp> Op,
120-
st::ShaderOpTest::TInitCallbackFn InitCallback = nullptr) {
121-
auto OpSet = std::make_shared<st::ShaderOpSet>();
122-
OpSet->ShaderOps.push_back(std::move(Op));
123-
124-
return st::RunShaderOpTestAfterParse(
125-
Device, DxcSupport, nullptr, std::move(InitCallback), std::move(OpSet));
126-
}
127-
128-
/// Compiles an HLSL shader using the DXC API to verify it is well-formed.
129-
/// Fails the test on compile error.
130-
static void compileShader(dxc::SpecificDllLoader &DxcSupport,
131-
const char *Source, const char *Target,
132-
const std::string &Args) {
133-
CComPtr<IDxcCompiler3> Compiler;
134-
VERIFY_SUCCEEDED(DxcSupport.CreateInstance(CLSID_DxcCompiler, &Compiler));
135-
136-
CComPtr<IDxcUtils> Utils;
137-
VERIFY_SUCCEEDED(DxcSupport.CreateInstance(CLSID_DxcUtils, &Utils));
138-
139-
CComPtr<IDxcBlobEncoding> SourceBlob;
140-
VERIFY_SUCCEEDED(Utils->CreateBlobFromPinned(
141-
Source, static_cast<UINT32>(strlen(Source)), DXC_CP_UTF8, &SourceBlob));
142-
143-
// Build wide-string argument list: -T <target> -E main <extra args>.
144-
std::vector<std::wstring> WArgStorage;
145-
WArgStorage.push_back(L"-T");
146-
WArgStorage.push_back(std::wstring(Target, Target + strlen(Target)));
147-
WArgStorage.push_back(L"-E");
148-
WArgStorage.push_back(L"main");
149-
150-
// Tokenize the additional arguments string.
151-
std::istringstream SS(Args);
152-
std::string Tok;
153-
while (SS >> Tok)
154-
WArgStorage.push_back(std::wstring(Tok.begin(), Tok.end()));
155-
156-
std::vector<LPCWSTR> WArgPtrs;
157-
for (const auto &A : WArgStorage)
158-
WArgPtrs.push_back(A.c_str());
159-
160-
DxcBuffer Buf = {};
161-
Buf.Ptr = SourceBlob->GetBufferPointer();
162-
Buf.Size = SourceBlob->GetBufferSize();
163-
Buf.Encoding = DXC_CP_UTF8;
164-
165-
CComPtr<IDxcResult> Result;
166-
VERIFY_SUCCEEDED(Compiler->Compile(&Buf, WArgPtrs.data(),
167-
static_cast<UINT32>(WArgPtrs.size()),
168-
nullptr, IID_PPV_ARGS(&Result)));
169-
170-
HRESULT HR;
171-
VERIFY_SUCCEEDED(Result->GetStatus(&HR));
172-
173-
if (FAILED(HR)) {
174-
CComPtr<IDxcBlobUtf8> Errors;
175-
Result->GetOutput(DXC_OUT_ERRORS, IID_PPV_ARGS(&Errors), nullptr);
176-
if (Errors && Errors->GetStringLength() > 0)
177-
hlsl_test::LogErrorFmt(L"Shader compilation failed:\n%S",
178-
Errors->GetStringPointer());
179-
VERIFY_SUCCEEDED(HR);
180-
}
181-
}
182-
18356
struct MatrixParams {
18457
ComponentType CompType;
18558
int M;
@@ -292,6 +165,9 @@ class DxilConf_SM610_LinAlg {
292165
bool VerboseLogging = false;
293166
bool Initialized = false;
294167
std::optional<D3D12SDKSelector> D3D12SDK;
168+
169+
WEX::TestExecution::SetVerifyOutput VerifyOutput{
170+
WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures};
295171
};
296172

297173
/// Creates the device and setups the test scenario with the following variants
@@ -322,9 +198,6 @@ bool DxilConf_SM610_LinAlg::createDevice() {
322198
}
323199

324200
bool DxilConf_SM610_LinAlg::setupClass() {
325-
WEX::TestExecution::SetVerifyOutput VerifySettings(
326-
WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures);
327-
328201
if (!Initialized) {
329202
Initialized = true;
330203
VERIFY_SUCCEEDED(
@@ -381,7 +254,7 @@ static void runLoadStoreRoundtrip(ID3D12Device *Device,
381254
std::string Args = buildCompilerArgs(Params, ExtraDefs.str().c_str());
382255

383256
// Always verify the shader compiles.
384-
compileShader(DxcSupport, LoadStoreShader, "cs_6_10", Args);
257+
compileShader(DxcSupport, LoadStoreShader, "cs_6_10", Args, Verbose);
385258

386259
#ifndef _HLK_CONF
387260
// Skip GPU execution if no device.
@@ -504,7 +377,7 @@ static void runSplatStore(ID3D12Device *Device,
504377
std::string Args = buildCompilerArgs(Params, ExtraDefs.str().c_str());
505378

506379
// Always verify the shader compiles.
507-
compileShader(DxcSupport, SplatStoreShader, "cs_6_10", Args);
380+
compileShader(DxcSupport, SplatStoreShader, "cs_6_10", Args, Verbose);
508381

509382
#ifndef _HLK_CONF
510383
// Skip GPU execution if no device.
@@ -523,6 +396,8 @@ static void runSplatStore(ID3D12Device *Device,
523396
ExpectedFloats.assign(NumElements, FillValue);
524397
break;
525398
case ComponentType::I32:
399+
VERIFY_IS_TRUE(FillValue < static_cast<float>(INT_MAX),
400+
"FillValue too large to cast to int32_t");
526401
ExpectedInts.assign(NumElements, static_cast<int32_t>(FillValue));
527402
break;
528403
default:

0 commit comments

Comments
 (0)