Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 128 additions & 0 deletions tools/clang/unittests/HLSLExec/HlslExecTestUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -636,3 +636,131 @@ UINT getMaxGroupSharedMemoryMS(ID3D12Device *Device) {
D3D12_FEATURE_D3D12_OPTIONS_PREVIEW, &O, sizeof(O)));
return O.MaxGroupSharedMemoryPerGroupMS;
}

std::unique_ptr<st::ShaderOp> createComputeOp(const char *Source,
const char *Target,
const char *RootSig,
const char *Args, UINT DispatchX,
UINT DispatchY, UINT DispatchZ) {
auto Op = std::make_unique<st::ShaderOp>();
LPCSTR CSName = Op->Strings.insert("CS");
Op->Name = CSName;
Op->CS = CSName;
Op->RootSignature = Op->Strings.insert(RootSig);
Op->DispatchX = DispatchX;
Op->DispatchY = DispatchY;
Op->DispatchZ = DispatchZ;
Op->UseWarpDevice = true;

st::ShaderOpShader Shader = {};
Shader.Name = CSName;
Shader.Target = Op->Strings.insert(Target);
Shader.EntryPoint = Op->Strings.insert("main");
Shader.Text = Op->Strings.insert(Source);
Shader.Arguments = Args ? Op->Strings.insert(Args) : nullptr;
Shader.Compiled = FALSE;
Shader.Callback = FALSE;
Op->Shaders.push_back(Shader);

return Op;
}

void addUAVBuffer(st::ShaderOp *Op, const char *Name, UINT64 Width,
bool ReadBack, const char *Init) {
st::ShaderOpResource Res = {};
Res.Name = Op->Strings.insert(Name);
Res.Init = Op->Strings.insert(Init);
Res.ReadBack = ReadBack ? TRUE : FALSE;

Res.HeapProperties.Type = D3D12_HEAP_TYPE_DEFAULT;
Res.HeapFlags = D3D12_HEAP_FLAG_NONE;
Res.Desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
Res.Desc.Width = Width;
Res.Desc.Height = 1;
Res.Desc.DepthOrArraySize = 1;
Res.Desc.MipLevels = 1;
Res.Desc.SampleDesc.Count = 1;
Res.Desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
Res.Desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
Res.InitialResourceState = D3D12_RESOURCE_STATE_COPY_DEST;
Res.TransitionTo = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;

Op->Resources.push_back(Res);
}

void addRootUAV(st::ShaderOp *Op, UINT Index, const char *ResName) {
st::ShaderOpRootValue RV = {};
RV.ResName = Op->Strings.insert(ResName);
RV.HeapName = nullptr;
RV.Index = Index;
Op->RootValues.push_back(RV);
}

std::shared_ptr<st::ShaderOpTestResult>
runShaderOp(ID3D12Device *Device, dxc::SpecificDllLoader &DxcSupport,
std::unique_ptr<st::ShaderOp> Op,
st::ShaderOpTest::TInitCallbackFn InitCallback) {
auto OpSet = std::make_shared<st::ShaderOpSet>();
OpSet->ShaderOps.push_back(std::move(Op));

return st::RunShaderOpTestAfterParse(
Device, DxcSupport, nullptr, std::move(InitCallback), std::move(OpSet));
}

void compileShader(dxc::SpecificDllLoader &DxcSupport, const char *Source,
const char *Target, const std::string &Args) {
CComPtr<IDxcCompiler3> Compiler;
VERIFY_SUCCEEDED(DxcSupport.CreateInstance(CLSID_DxcCompiler, &Compiler));

CComPtr<IDxcUtils> Utils;
VERIFY_SUCCEEDED(DxcSupport.CreateInstance(CLSID_DxcUtils, &Utils));

CComPtr<IDxcBlobEncoding> SourceBlob;
VERIFY_SUCCEEDED(Utils->CreateBlobFromPinned(
Source, static_cast<UINT32>(strlen(Source)), DXC_CP_UTF8, &SourceBlob));

// Build wide-string argument list: -T <target> -E main <extra args>.
std::vector<std::wstring> WArgStorage;
WArgStorage.push_back(L"-T");
WArgStorage.push_back(std::wstring(Target, Target + strlen(Target)));
WArgStorage.push_back(L"-E");
WArgStorage.push_back(L"main");

// Tokenize the additional arguments string.
std::istringstream SS(Args);
std::string Tok;
while (SS >> Tok)
WArgStorage.push_back(std::wstring(Tok.begin(), Tok.end()));

std::vector<LPCWSTR> WArgPtrs;
std::wstringstream LogFlags;
LogFlags << L"Compiling with flags:";
for (const auto &A : WArgStorage) {
WArgPtrs.push_back(A.c_str());
LogFlags << L" " << A;
}
Comment on lines +737 to +742
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this bit of code was also edited, not just moved


DxcBuffer Buf = {};
Buf.Ptr = SourceBlob->GetBufferPointer();
Buf.Size = SourceBlob->GetBufferSize();
Buf.Encoding = DXC_CP_UTF8;

hlsl_test::LogCommentFmt(LogFlags.str().c_str());

Comment thread
V-FEXrt marked this conversation as resolved.
CComPtr<IDxcResult> Result;
VERIFY_SUCCEEDED(Compiler->Compile(&Buf, WArgPtrs.data(),
static_cast<UINT32>(WArgPtrs.size()),
nullptr, IID_PPV_ARGS(&Result)));

HRESULT HR;
VERIFY_SUCCEEDED(Result->GetStatus(&HR));

if (FAILED(HR)) {
CComPtr<IDxcBlobUtf8> Errors;
Result->GetOutput(DXC_OUT_ERRORS, IID_PPV_ARGS(&Errors), nullptr);
if (Errors && Errors->GetStringLength() > 0)
hlsl_test::LogErrorFmt(L"Shader compilation failed:\n%S",
Errors->GetStringPointer());
VERIFY_SUCCEEDED(HR);
}
}
31 changes: 31 additions & 0 deletions tools/clang/unittests/HLSLExec/HlslExecTestUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@

#include <atlcomcli.h>
#include <d3d12.h>
#include <memory>
#include <optional>
#include <string>
#include <windows.h>

#include "ShaderOpTest.h"
#include "dxc/Support/dxcapi.use.h"

// D3D_SHADER_MODEL_6_10 is not yet in the released Windows SDK.
Expand Down Expand Up @@ -74,4 +77,32 @@ UINT getMaxGroupSharedMemoryCS(ID3D12Device *Device);
UINT getMaxGroupSharedMemoryAS(ID3D12Device *Device);
UINT getMaxGroupSharedMemoryMS(ID3D12Device *Device);

/// Create a ShaderOp for a compute shader dispatch.
std::unique_ptr<st::ShaderOp>
createComputeOp(const char *Source, const char *Target, const char *RootSig,
const char *Args = nullptr, UINT DispatchX = 1,
UINT DispatchY = 1, UINT DispatchZ = 1);

/// Add a UAV buffer resource to a ShaderOp.
void addUAVBuffer(st::ShaderOp *Op, const char *Name, UINT64 Width,
bool ReadBack, const char *Init = "zero");

/// Bind a resource to a root UAV parameter by index.
void addRootUAV(st::ShaderOp *Op, UINT Index, const char *ResName);

/// Run a programmatically-built ShaderOp and return the result.
std::shared_ptr<st::ShaderOpTestResult>
runShaderOp(ID3D12Device *Device, dxc::SpecificDllLoader &DxcSupport,
std::unique_ptr<st::ShaderOp> Op,
st::ShaderOpTest::TInitCallbackFn InitCallback = nullptr);

/// Compiles an HLSL shader using the DXC API to verify it is well-formed.
/// Fails the test on compile error.
void compileShader(dxc::SpecificDllLoader &DxcSupport, const char *Source,
const char *Target, const std::string &Args);
/// Compiles an HLSL shader using the DXC API to verify it is well-formed.
/// Fails the test on compile error.
void compileShader(dxc::SpecificDllLoader &DxcSupport, const char *Source,
const char *Target, const std::string &Args);

#endif // HLSLEXECTESTUTILS_H
134 changes: 6 additions & 128 deletions tools/clang/unittests/HLSLExec/LinAlgTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

#include "HlslExecTestUtils.h"

#include <climits>
#include <optional>
#include <sstream>
#include <string>
Expand Down Expand Up @@ -52,134 +53,6 @@ static int elemSize(ComponentType CT) {
}
}

/// Create a ShaderOp for a compute shader dispatch.
static std::unique_ptr<st::ShaderOp>
createComputeOp(const char *Source, const char *Target, const char *RootSig,
const char *Args = nullptr, UINT DispatchX = 1,
UINT DispatchY = 1, UINT DispatchZ = 1) {
auto Op = std::make_unique<st::ShaderOp>();
LPCSTR CSName = Op->Strings.insert("CS");
Op->Name = CSName;
Op->CS = CSName;
Op->RootSignature = Op->Strings.insert(RootSig);
Op->DispatchX = DispatchX;
Op->DispatchY = DispatchY;
Op->DispatchZ = DispatchZ;
Op->UseWarpDevice = true;

st::ShaderOpShader Shader = {};
Shader.Name = CSName;
Shader.Target = Op->Strings.insert(Target);
Shader.EntryPoint = Op->Strings.insert("main");
Shader.Text = Op->Strings.insert(Source);
Shader.Arguments = Args ? Op->Strings.insert(Args) : nullptr;
Shader.Compiled = FALSE;
Shader.Callback = FALSE;
Op->Shaders.push_back(Shader);

return Op;
}

/// Add a UAV buffer resource to a ShaderOp.
static void addUAVBuffer(st::ShaderOp *Op, const char *Name, UINT64 Width,
bool ReadBack, const char *Init = "zero") {
st::ShaderOpResource Res = {};
Res.Name = Op->Strings.insert(Name);
Res.Init = Op->Strings.insert(Init);
Res.ReadBack = ReadBack ? TRUE : FALSE;

Res.HeapProperties.Type = D3D12_HEAP_TYPE_DEFAULT;
Res.HeapFlags = D3D12_HEAP_FLAG_NONE;
Res.Desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
Res.Desc.Width = Width;
Res.Desc.Height = 1;
Res.Desc.DepthOrArraySize = 1;
Res.Desc.MipLevels = 1;
Res.Desc.SampleDesc.Count = 1;
Res.Desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
Res.Desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
Res.InitialResourceState = D3D12_RESOURCE_STATE_COPY_DEST;
Res.TransitionTo = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;

Op->Resources.push_back(Res);
}

/// Bind a resource to a root UAV parameter by index.
static void addRootUAV(st::ShaderOp *Op, UINT Index, const char *ResName) {
st::ShaderOpRootValue RV = {};
RV.ResName = Op->Strings.insert(ResName);
RV.HeapName = nullptr;
RV.Index = Index;
Op->RootValues.push_back(RV);
}

/// Run a programmatically-built ShaderOp and return the result.
static std::shared_ptr<st::ShaderOpTestResult>
runShaderOp(ID3D12Device *Device, dxc::SpecificDllLoader &DxcSupport,
std::unique_ptr<st::ShaderOp> Op,
st::ShaderOpTest::TInitCallbackFn InitCallback = nullptr) {
auto OpSet = std::make_shared<st::ShaderOpSet>();
OpSet->ShaderOps.push_back(std::move(Op));

return st::RunShaderOpTestAfterParse(
Device, DxcSupport, nullptr, std::move(InitCallback), std::move(OpSet));
}

/// Compiles an HLSL shader using the DXC API to verify it is well-formed.
/// Fails the test on compile error.
static void compileShader(dxc::SpecificDllLoader &DxcSupport,
const char *Source, const char *Target,
const std::string &Args) {
CComPtr<IDxcCompiler3> Compiler;
VERIFY_SUCCEEDED(DxcSupport.CreateInstance(CLSID_DxcCompiler, &Compiler));

CComPtr<IDxcUtils> Utils;
VERIFY_SUCCEEDED(DxcSupport.CreateInstance(CLSID_DxcUtils, &Utils));

CComPtr<IDxcBlobEncoding> SourceBlob;
VERIFY_SUCCEEDED(Utils->CreateBlobFromPinned(
Source, static_cast<UINT32>(strlen(Source)), DXC_CP_UTF8, &SourceBlob));

// Build wide-string argument list: -T <target> -E main <extra args>.
std::vector<std::wstring> WArgStorage;
WArgStorage.push_back(L"-T");
WArgStorage.push_back(std::wstring(Target, Target + strlen(Target)));
WArgStorage.push_back(L"-E");
WArgStorage.push_back(L"main");

// Tokenize the additional arguments string.
std::istringstream SS(Args);
std::string Tok;
while (SS >> Tok)
WArgStorage.push_back(std::wstring(Tok.begin(), Tok.end()));

std::vector<LPCWSTR> WArgPtrs;
for (const auto &A : WArgStorage)
WArgPtrs.push_back(A.c_str());

DxcBuffer Buf = {};
Buf.Ptr = SourceBlob->GetBufferPointer();
Buf.Size = SourceBlob->GetBufferSize();
Buf.Encoding = DXC_CP_UTF8;

CComPtr<IDxcResult> Result;
VERIFY_SUCCEEDED(Compiler->Compile(&Buf, WArgPtrs.data(),
static_cast<UINT32>(WArgPtrs.size()),
nullptr, IID_PPV_ARGS(&Result)));

HRESULT HR;
VERIFY_SUCCEEDED(Result->GetStatus(&HR));

if (FAILED(HR)) {
CComPtr<IDxcBlobUtf8> Errors;
Result->GetOutput(DXC_OUT_ERRORS, IID_PPV_ARGS(&Errors), nullptr);
if (Errors && Errors->GetStringLength() > 0)
hlsl_test::LogErrorFmt(L"Shader compilation failed:\n%S",
Errors->GetStringPointer());
VERIFY_SUCCEEDED(HR);
}
}

struct MatrixParams {
ComponentType CompType;
int M;
Expand Down Expand Up @@ -292,6 +165,9 @@ class DxilConf_SM610_LinAlg {
bool VerboseLogging = false;
bool Initialized = false;
std::optional<D3D12SDKSelector> D3D12SDK;

WEX::TestExecution::SetVerifyOutput VerifyOutput{
WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures};
};

/// Creates the device and setups the test scenario with the following variants
Expand Down Expand Up @@ -523,6 +399,8 @@ static void runSplatStore(ID3D12Device *Device,
ExpectedFloats.assign(NumElements, FillValue);
break;
case ComponentType::I32:
VERIFY_IS_TRUE(FillValue < static_cast<float>(INT_MAX),
"FillValue too large to cast to int32_t");
ExpectedInts.assign(NumElements, static_cast<int32_t>(FillValue));
break;
default:
Expand Down
Loading