Skip to content

Commit 2a9052a

Browse files
authored
Refactor ExecutionTests into a separate dll (microsoft#4905)
ExecutionTests are currently compiled into clang-hlsl-tests.dll together with all of the other DXC unit tests. Later in the code pipeline the ExecutionTests are getting transformed into HLK tests which have different dependency constraints than the clang HLSL tests. Refactoring ExecutionTests into a separate dll allows us to set its dependencies and build settings accordingly and closely matching those of the HLK test dll. This will help HLK authors to implement the tests with those constraints in mind.
1 parent 65795cf commit 2a9052a

16 files changed

+150
-25
lines changed

include/dxc/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ include(HCT)
33
add_hlsl_hctgen(HLSLIntrinsicOp OUTPUT HlslIntrinsicOp.h)
44

55
set(HLSL_TEST_DATA_DIR ${LLVM_SOURCE_DIR}/tools/clang/test/HLSL/)
6+
set(EXEC_TEST_DATA_DIR ${LLVM_SOURCE_DIR}/tools/clang/unittests/HLSLExec/)
67

78
configure_file(
89
${LLVM_MAIN_INCLUDE_DIR}/dxc/Test/TestConfig.h.in

include/dxc/Test/HlslTestUtils.h

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@
2525
#include "dxc/Support/Global.h" // DXASSERT_LOCALVAR
2626
#include "WEXAdapter.h"
2727
#endif
28-
#include "dxc/Support/Unicode.h"
2928
#include "dxc/DXIL/DxilConstants.h" // DenormMode
3029

3130
#ifdef _HLK_CONF
32-
#define DEFAULT_TEST_DIR ""
31+
#define DEFAULT_TEST_DIR L""
32+
#define DEFAULT_EXEC_TEST_DIR DEFAULT_TEST_DIR
3333
#else
3434
#include "dxc/Test/TestConfig.h"
3535
#endif
@@ -210,7 +210,7 @@ inline void LogErrorFmt(_In_z_ _Printf_format_string_ const wchar_t *fmt, ...) {
210210
WEX::Logging::Log::Error(buf.data());
211211
}
212212

213-
inline std::wstring GetPathToHlslDataFile(const wchar_t* relative, LPCWSTR paramName = HLSLDATAFILEPARAM) {
213+
inline std::wstring GetPathToHlslDataFile(const wchar_t* relative, LPCWSTR paramName = HLSLDATAFILEPARAM, LPCWSTR defaultDataDir = DEFAULT_TEST_DIR) {
214214
WEX::TestExecution::SetVerifyOutput verifySettings(WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures);
215215
WEX::Common::String HlslDataDirValue;
216216
if (std::wstring(paramName).compare(HLSLDATAFILEPARAM) != 0) {
@@ -219,7 +219,7 @@ inline std::wstring GetPathToHlslDataFile(const wchar_t* relative, LPCWSTR param
219219
return std::wstring();
220220
} else {
221221
if (FAILED(WEX::TestExecution::RuntimeParameters::TryGetValue(HLSLDATAFILEPARAM, HlslDataDirValue)))
222-
HlslDataDirValue = DEFAULT_TEST_DIR;
222+
HlslDataDirValue = defaultDataDir;
223223
}
224224

225225
wchar_t envPath[MAX_PATH];
@@ -318,6 +318,42 @@ inline HANDLE CreateNewFileForReadWrite(LPCWSTR path) {
318318
return sourceHandle;
319319
}
320320

321+
// Copy of Unicode::IsStarMatchT/IsStarMatchWide is included here to avoid the dependency on
322+
// DXC support libraries.
323+
template<typename TChar>
324+
inline static
325+
bool IsStarMatchT(const TChar *pMask, size_t maskLen, const TChar *pName, size_t nameLen, TChar star) {
326+
if (maskLen == 0 && nameLen == 0) {
327+
return true;
328+
}
329+
if (maskLen == 0 || nameLen == 0) {
330+
return false;
331+
}
332+
333+
if (pMask[maskLen - 1] == star) {
334+
// Prefix match.
335+
if (maskLen == 1) { // For just '*', everything is a match.
336+
return true;
337+
}
338+
--maskLen;
339+
if (maskLen > nameLen) { // Mask is longer than name, can't be a match.
340+
return false;
341+
}
342+
return 0 == memcmp(pMask, pName, sizeof(TChar) * maskLen);
343+
}
344+
else {
345+
// Exact match.
346+
if (nameLen != maskLen) {
347+
return false;
348+
}
349+
return 0 == memcmp(pMask, pName, sizeof(TChar) * nameLen);
350+
}
351+
}
352+
353+
inline bool IsStarMatchWide(const wchar_t *pMask, size_t maskLen, const wchar_t *pName, size_t nameLen) {
354+
return IsStarMatchT<wchar_t>(pMask, maskLen, pName, nameLen, L'*');
355+
}
356+
321357
inline bool GetTestParamBool(LPCWSTR name) {
322358
WEX::Common::String ParamValue;
323359
WEX::Common::String NameValue;
@@ -336,8 +372,9 @@ inline bool GetTestParamBool(LPCWSTR name) {
336372
if (NameValue.IsEmpty()) {
337373
return false;
338374
}
339-
return Unicode::IsStarMatchWide(ParamValue, ParamValue.GetLength(),
340-
NameValue, NameValue.GetLength());
375+
376+
return hlsl_test::IsStarMatchWide(ParamValue, ParamValue.GetLength(),
377+
NameValue, NameValue.GetLength());
341378
}
342379

343380
inline bool GetTestParamUseWARP(bool defaultVal) {

include/dxc/Test/TestConfig.h.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
#define DEFAULT_TEST_DIR L"@HLSL_TEST_DATA_DIR@"
2+
#define DEFAULT_EXEC_TEST_DIR L"@EXEC_TEST_DATA_DIR@"

tools/clang/unittests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ if (HLSL_INCLUDE_TESTS)
4747
add_subdirectory(HLSLTestLib)
4848
if (WIN32) # These tests require MS specific TAEF and DIA SDK
4949
add_subdirectory(HLSLErrors)
50+
add_subdirectory(HLSLExec)
5051
add_subdirectory(HLSLHost)
5152
add_subdirectory(dxc_batch)
5253
add_subdirectory(DxrFallback)

tools/clang/unittests/HLSL/CMakeLists.txt

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
if(WIN32)
44
find_package(TAEF REQUIRED)
55
find_package(DiaSDK REQUIRED) # Used for constants and declarations.
6-
find_package(D3D12 REQUIRED) # Used for ExecutionTest.cpp.
6+
find_package(D3D12 REQUIRED) # Used in DxilContainerTest for DXBC compilation/reflection
77
endif(WIN32)
88

99
set( LLVM_LINK_COMPONENTS
@@ -35,7 +35,6 @@ add_clang_library(ClangHLSLTests SHARED
3535
DxilModuleTest.cpp
3636
DxilResourceTests.cpp
3737
DXIsenseTest.cpp
38-
ExecutionTest.cpp
3938
ExtensionTest.cpp
4039
FunctionTest.cpp
4140
LinkerTest.cpp
@@ -45,17 +44,14 @@ add_clang_library(ClangHLSLTests SHARED
4544
OptionsTest.cpp
4645
PixTest.cpp
4746
RewriterTest.cpp
48-
ShaderOpTest.cpp
4947
SystemValueTest.cpp
5048
ValidationTest.cpp
5149
VerifierTest.cpp
52-
clang-hlsl-tests.rc
5350
)
5451

5552
add_dependencies(ClangUnitTests ClangHLSLTests)
5653
else (WIN32)
5754
set(HLSL_IGNORE_SOURCES
58-
ExecutionTest.cpp
5955
LinkerTest.cpp
6056
MSFileSysTest.cpp
6157
PixTest.cpp
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Copyright (C) Microsoft Corporation. All rights reserved.
2+
# This file is distributed under the University of Illinois Open Source License. See LICENSE.TXT for details.
3+
find_package(TAEF REQUIRED)
4+
find_package(D3D12 REQUIRED) # Used for ExecutionTest.cpp.
5+
6+
add_clang_library(ExecHLSLTests SHARED
7+
ExecutionTest.cpp
8+
ShaderOpTest.cpp
9+
exec-hlsl-tests.rc
10+
)
11+
12+
add_dependencies(ClangUnitTests ExecHLSLTests)
13+
14+
set_target_properties(ExecHLSLTests PROPERTIES FOLDER "Execution tests")
15+
16+
target_link_libraries(ExecHLSLTests PRIVATE
17+
dxcompiler
18+
${TAEF_LIBRARIES}
19+
${D3D12_LIBRARIES}
20+
)
21+
22+
# Add includes for platform helpers and dxc API.
23+
include_directories(${TAEF_INCLUDE_DIRS})
24+
include_directories(${DIASDK_INCLUDE_DIRS})
25+
include_directories(${D3D12_INCLUDE_DIRS})
26+
include_directories(${LLVM_MAIN_INCLUDE_DIR}/dxc/Test)
27+
28+
add_dependencies(ExecHLSLTests dxcompiler)
29+
30+
if (NOT CLANG_INCLUDE_TESTS)
31+
set_target_properties(ExecHLSLTests PROPERTIES OUTPUT_NAME exec-hlsl-tests)
32+
set_output_directory(ExecHLSLTests
33+
${LLVM_RUNTIME_OUTPUT_INTDIR} ${LLVM_LIBRARY_OUTPUT_INTDIR})
34+
endif()
35+
36+
# Add a .user file with settings for te.exe.
37+
file(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" DOS_STYLE_SOURCE_DIR)
38+
file(TO_NATIVE_PATH "${TAEF_BIN_DIR}" DOS_TAEF_BIN_DIR)
39+
configure_file(ExecHLSLTests.vcxproj.user.txt ExecHLSLTests.vcxproj.user)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<PropertyGroup>
4+
<LocalDebuggerCommand>${DOS_TAEF_BIN_DIR}\$(PlatformTarget)\Te.exe</LocalDebuggerCommand>
5+
<LocalDebuggerCommand Condition="'$(PlatformTarget)' == 'x64' And Exists('${DOS_TAEF_BIN_DIR}\amd64\Te.exe')">${DOS_TAEF_BIN_DIR}\amd64\Te.exe</LocalDebuggerCommand>
6+
<LocalDebuggerCommandArguments>$(TargetPath) /inproc /runIgnoredTests /p:"ExperimentalShaders=*" /name:*</LocalDebuggerCommandArguments>
7+
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
8+
</PropertyGroup>
9+
</Project>

tools/clang/unittests/HLSL/ExecutionTest.cpp renamed to tools/clang/unittests/HLSLExec/ExecutionTest.cpp

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ static void SavePixelsToFile(LPCVOID pPixels, DXGI_FORMAT format, UINT32 m_width
164164
CComPtr<IWICBitmap> pBitmap;
165165
CComPtr<IWICBitmapEncoder> pEncoder;
166166
CComPtr<IWICBitmapFrameEncode> pFrameEncode;
167-
CComPtr<hlsl::AbstractMemoryStream> pStream;
167+
CComPtr<IStream> pStream;
168168
CComPtr<IMalloc> pMalloc;
169169

170170
struct PF {
@@ -183,17 +183,17 @@ static void SavePixelsToFile(LPCVOID pPixels, DXGI_FORMAT format, UINT32 m_width
183183
VERIFY_SUCCEEDED(ctx.Init());
184184
VERIFY_SUCCEEDED(CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (LPVOID*)&pFactory));
185185
VERIFY_SUCCEEDED(CoGetMalloc(1, &pMalloc));
186-
VERIFY_SUCCEEDED(hlsl::CreateMemoryStream(pMalloc, &pStream));
187186
VERIFY_ARE_NOT_EQUAL(pFormat, Vals + _countof(Vals));
188187
VERIFY_SUCCEEDED(pFactory->CreateBitmapFromMemory(m_width, m_height, pFormat->PixelFormat, m_width * pFormat->PixelSize, m_width * m_height * pFormat->PixelSize, (BYTE *)pPixels, &pBitmap));
189188
VERIFY_SUCCEEDED(pFactory->CreateEncoder(GUID_ContainerFormatBmp, nullptr, &pEncoder));
189+
VERIFY_SUCCEEDED(SHCreateStreamOnFileEx(pFileName, STGM_WRITE, STGM_CREATE, 0, nullptr, &pStream));
190190
VERIFY_SUCCEEDED(pEncoder->Initialize(pStream, WICBitmapEncoderNoCache));
191191
VERIFY_SUCCEEDED(pEncoder->CreateNewFrame(&pFrameEncode, nullptr));
192192
VERIFY_SUCCEEDED(pFrameEncode->Initialize(nullptr));
193193
VERIFY_SUCCEEDED(pFrameEncode->WriteSource(pBitmap, nullptr));
194194
VERIFY_SUCCEEDED(pFrameEncode->Commit());
195195
VERIFY_SUCCEEDED(pEncoder->Commit());
196-
IFT(hlsl::WriteBinaryFile(pFileName, pStream->GetPtr(), pStream->GetPtrSize()));
196+
VERIFY_SUCCEEDED(pStream->Commit(STGC_DEFAULT));
197197
}
198198

199199
// Checks if the given warp version supports the given operation.
@@ -470,7 +470,6 @@ class ExecutionTest {
470470
END_TEST_METHOD()
471471

472472
dxc::DxcDllSupport m_support;
473-
VersionSupportInfo m_ver;
474473

475474
bool m_D3DInitCompleted = false;
476475
bool m_ExperimentalModeEnabled = false;
@@ -522,6 +521,48 @@ class ExecutionTest {
522521
return true;
523522
}
524523

524+
std::wstring DxcBlobToWide(_In_ IDxcBlob *pBlob) {
525+
if (!pBlob)
526+
return std::wstring();
527+
528+
CComPtr<IDxcBlobWide> pBlobWide;
529+
if (SUCCEEDED(pBlob->QueryInterface(&pBlobWide)))
530+
return std::wstring(pBlobWide->GetStringPointer(), pBlobWide->GetStringLength());
531+
532+
CComPtr<IDxcBlobEncoding> pBlobEncoding;
533+
IFT(pBlob->QueryInterface(&pBlobEncoding));
534+
BOOL known;
535+
UINT32 codePage;
536+
IFT(pBlobEncoding->GetEncoding(&known, &codePage));
537+
if (!known) {
538+
throw std::runtime_error("unknown codepage for blob.");
539+
}
540+
541+
std::wstring result;
542+
if (codePage == DXC_CP_WIDE) {
543+
const wchar_t* text = (const wchar_t *)pBlob->GetBufferPointer();
544+
size_t length = pBlob->GetBufferSize() / 2;
545+
if (length >= 1 && text[length-1] == L'\0')
546+
length -= 1; // Exclude null-terminator
547+
result.resize(length);
548+
memcpy(&result[0], text, length);
549+
return result;
550+
}
551+
if (codePage == CP_UTF8) {
552+
const char* text = (const char *)pBlob->GetBufferPointer();
553+
size_t length = pBlob->GetBufferSize();
554+
if (length >= 1 && text[length-1] == '\0')
555+
length -= 1; // Exclude null-terminator
556+
if (length == 0)
557+
return std::wstring();
558+
int wideLength = ::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, text, (int)length, nullptr, 0);
559+
result.resize(wideLength);
560+
::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, text, (int)length, &result[0], wideLength);
561+
return result;
562+
}
563+
throw std::runtime_error("Unsupported codepage.");
564+
}
565+
525566
// Do not remove the following line - it is used by TranslateExecutionTest.py
526567
// MARKER: ExecutionTest/DxilConf Shared Implementation Start
527568

@@ -645,10 +686,10 @@ class ExecutionTest {
645686
VERIFY_SUCCEEDED(pCompiler->Compile(pTextBlob, L"hlsl.hlsl", pEntryPoint, pTargetProfile, pOptions, numOptions, nullptr, 0, nullptr, &pResult));
646687
VERIFY_SUCCEEDED(pResult->GetStatus(&resultCode));
647688
if (FAILED(resultCode)) {
689+
#ifndef _HLK_CONF
648690
CComPtr<IDxcBlobEncoding> errors;
649691
VERIFY_SUCCEEDED(pResult->GetErrorBuffer(&errors));
650-
#ifndef _HLK_CONF
651-
LogCommentFmt(L"Failed to compile shader: %s", BlobToWide(errors).data());
692+
LogCommentFmt(L"Failed to compile shader: %s", DxcBlobToWide(errors).data());
652693
#endif
653694
}
654695
VERIFY_SUCCEEDED(resultCode);
@@ -1643,7 +1684,7 @@ class ExecutionTest {
16431684
CComPtr<IDxcLibrary> pLibrary;
16441685
CComPtr<IDxcBlobEncoding> pBlob;
16451686
CComPtr<IStream> pStream;
1646-
std::wstring path = GetPathToHlslDataFile(relativePath);
1687+
std::wstring path = GetPathToHlslDataFile(relativePath, HLSLDATAFILEPARAM, DEFAULT_EXEC_TEST_DIR);
16471688
VERIFY_SUCCEEDED(m_support.CreateInstance(CLSID_DxcLibrary, &pLibrary));
16481689
VERIFY_SUCCEEDED(pLibrary->CreateBlobFromFile(path.c_str(), nullptr, &pBlob));
16491690
VERIFY_SUCCEEDED(pLibrary->CreateStreamFromBlobReadOnly(pBlob, &pStream));

0 commit comments

Comments
 (0)