Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
5 changes: 1 addition & 4 deletions tools/clang/test/taef_exec/lit.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,9 @@ Execution tests require DXIL.dll to sign shaders, or the experimental shader mod
if config.unsupported == False:
test_dll = os.path.join(bin_dir, 'ExecHLSLTests.dll')

hlsl_data_dir = os.path.join(config.llvm_src_root, 'tools', 'clang', 'unittests', 'HLSLExec')

test_dir = os.path.join(config.llvm_obj_root, config.llvm_build_mode, 'test')
param_hlsl_data_dir = str.format('HlslDataDir={}', hlsl_data_dir)

extra_params = ['/p:', 'ExperimentalShaders=*', '/p:', param_hlsl_data_dir]
extra_params = ['/p:', 'ExperimentalShaders=*']

verbose = bool(getattr(config, 'verbose', False))
if verbose != True:
Expand Down
116 changes: 114 additions & 2 deletions tools/clang/unittests/HLSLExec/HlslExecTestUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <d3d12.h>
#include <dxgi1_4.h>
#include <filesystem>
#include <mutex>
#include <optional>

// D3D12_FEATURE_D3D12_OPTIONS_PREVIEW and its data struct are not yet in
Expand Down Expand Up @@ -425,15 +426,126 @@ static bool createDevice(
return true;
}

// Linker-provided symbol at the base of the module containing this code, which
// is also its HMODULE. Identifies the module without depending on the name of
// the binary these sources are built into.
// See https://devblogs.microsoft.com/oldnewthing/20041025-00/?p=37483.
extern "C" IMAGE_DOS_HEADER __ImageBase;

// Directory of the module containing this code.
static const std::wstring &getContainingModuleDirectory() {
static const std::wstring Dir = [] {
HMODULE Module = reinterpret_cast<HMODULE>(&__ImageBase);

// GetModuleFileNameW truncates rather than failing, so grow until it fits.
std::wstring Path(MAX_PATH, L'\0');
for (;;) {
const DWORD Len =
GetModuleFileNameW(Module, &Path[0], static_cast<DWORD>(Path.size()));
if (Len == 0)
return std::wstring();
if (Len < Path.size()) {
Comment thread
bob80905 marked this conversation as resolved.
Path.resize(Len);
break;
}
Path.resize(Path.size() * 2);
}
return std::filesystem::path(Path).parent_path().wstring();
}();
return Dir;
}

// Every call site loads from the same directory, so log the first resolution
// only. Tests may run in parallel, so this has to be thread-safe.
static void logResolvedDataDirOnce(const wchar_t *Origin,
const std::filesystem::path &Path) {
static std::once_flag Logged;
std::call_once(Logged, [&] {
LogCommentFmt(L"Loading execution test data from %s: %s", Origin,
Path.parent_path().c_str());
});
}

// Resolves a data file shipped with the execution tests, in this order:
//
// 1. the HlslDataDir runtime parameter, if supplied. Authoritative: we fail
// rather than fall through, so a typo is reported instead of hidden.
// 2. the directory containing this module, so a binary deployed with its
// data files finds them.
// 3. the source directory recorded by CMake, so a build tree picks up edits
// to the data files without rebuilding.
static std::wstring resolveHlslDataFile(LPCWSTR RelativePath) {
WEX::Common::String ParamValue;
std::wstring OverrideDir;
if (SUCCEEDED(WEX::TestExecution::RuntimeParameters::TryGetValue(
HLSLDATAFILEPARAM, ParamValue)))
OverrideDir = reinterpret_cast<const wchar_t *>(ParamValue.GetBuffer());

// Treat an empty value as absent and fall through to the other locations.
if (!OverrideDir.empty()) {
std::filesystem::path Candidate =
std::filesystem::path(OverrideDir) / RelativePath;
if (!std::filesystem::exists(Candidate))
LOG_ERROR_FMT_THROW(
L"Unable to find %s in the directory given by the %s parameter.\n"
L" Tried: %s\n"
L"%s is authoritative, so no other location was searched. Omit it "
L"to search the test binary's directory and the source directory.",
RelativePath, HLSLDATAFILEPARAM, Candidate.c_str(),
HLSLDATAFILEPARAM);
logResolvedDataDirOnce(
Comment thread
damyanp marked this conversation as resolved.
FormatToWString(L"the %s parameter", HLSLDATAFILEPARAM).c_str(),
Candidate);
return Candidate.wstring();
}

const std::wstring ModuleDir = getContainingModuleDirectory();
std::filesystem::path ModuleCandidate;
if (!ModuleDir.empty()) {
ModuleCandidate = std::filesystem::path(ModuleDir) / RelativePath;
if (std::filesystem::exists(ModuleCandidate)) {
logResolvedDataDirOnce(L"the directory containing the test binary",
ModuleCandidate);
return ModuleCandidate.wstring();
}
}

// Empty in _HLK_CONF builds; probing it would just look in the current
// directory.
const std::wstring SourceDir = DEFAULT_EXEC_TEST_DIR;
std::filesystem::path SourceCandidate;
if (!SourceDir.empty()) {
SourceCandidate = std::filesystem::path(SourceDir) / RelativePath;
if (std::filesystem::exists(SourceCandidate)) {
logResolvedDataDirOnce(L"the build-configured source directory",
SourceCandidate);
return SourceCandidate.wstring();
}
}

LOG_ERROR_FMT_THROW(
L"Unable to find the test data file %s in any known location.\n"
L" Next to the test binary: %s\n"
L" Build-configured source path: %s\n"
L"Deploy %s next to the test binary, or pass "
L"/p:\"%s=<directory containing %s>\" to specify its location.",
RelativePath,
ModuleCandidate.empty() ? L"<could not determine the binary's directory>"
: ModuleCandidate.c_str(),
SourceCandidate.empty() ? L"<not configured for this build>"
Comment thread
bob80905 marked this conversation as resolved.
: SourceCandidate.c_str(),
RelativePath, HLSLDATAFILEPARAM, RelativePath);
return std::wstring();
}

void readHlslDataIntoNewStream(LPCWSTR RelativePath, IStream **Stream,
dxc::SpecificDllLoader &Support) {
VERIFY_SUCCEEDED(
Support.InitializeForDll(dxc::kDxCompilerLib, "DxcCreateInstance"));
CComPtr<IDxcLibrary> Library;
CComPtr<IDxcBlobEncoding> Blob;
CComPtr<IStream> StreamCom;
std::wstring Path = GetPathToHlslDataFile(RelativePath, HLSLDATAFILEPARAM,
DEFAULT_EXEC_TEST_DIR);
std::wstring Path = resolveHlslDataFile(RelativePath);
Comment thread
bob80905 marked this conversation as resolved.
VERIFY_SUCCEEDED(Support.CreateInstance(CLSID_DxcLibrary, &Library));
VERIFY_SUCCEEDED(Library->CreateBlobFromFile(Path.c_str(), nullptr, &Blob));
VERIFY_SUCCEEDED(Library->CreateStreamFromBlobReadOnly(Blob, &StreamCom));
Expand Down
2 changes: 1 addition & 1 deletion utils/hct/hcttest.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,7 @@ if "%TEST_EXEC%"=="1" (
call :copyagility
)

set EXEC_COMMON_ARGS=/p:"HlslDataDir=%HLSL_SRC_DIR%\tools\clang\unittests\HLSLExec" /p:"ExperimentalShaders=*" %TEST_ADAPTER% %USE_AGILITY_SDK%
set EXEC_COMMON_ARGS=/p:"ExperimentalShaders=*" %TEST_ADAPTER% %USE_AGILITY_SDK%
if "%TEST_EXEC%"=="1" (
echo Sniffing for D3D12 configuration ...
call :runte ExecHLSLTests.dll /select:"@Name='ExecutionTest::BasicTriangleTest' AND @Architecture='%TEST_ARCH%'" %EXEC_COMMON_ARGS%
Expand Down
Loading