Skip to content

Commit d70a3fa

Browse files
authored
Add a test target to run exec tests with latest warp from nuget (cp to 1.8.2502) (microsoft#7110)
Cherry-pick of microsoft#7101 to release-1.8.2502 Add a test target to run exec tests with latest warp from nuget **Overview:** This PR resolves microsoft#6505. It adds a cmake file with logic to install nuget packages. It was specifically added so the exec tests could install the latest d3d warp nuget, ensuring the latest shader model support we have. Additionally, the nuget install logic has the ability to install the latest prerelese d3d warp nuget. Selection of the prerelease vs release is toggled using an environment variable. This new logic is accessible by using a new test target 'check-clang-taef-exec-warp'. Alternatively, you can use the the hctbuild script and 'hcttest exec-warp' or 'hcttest exec-warp-preview' **How Tested:** 1. Validated locally with a fresh clean clone, build, and test run. Used 'hctbuild' and 'hcttest exec-warp'. I was unable to directly validate the prerelease path as there is no true prerelease d3d warp nuget available at this time. But I did manually confirm the nuget query on another nuget package which does have a prerelease right now and the query works as expected. 2. Validating end-to-end in the ADO pipeline through this PR.
1 parent d6dc036 commit d70a3fa

File tree

6 files changed

+297
-10
lines changed

6 files changed

+297
-10
lines changed

azure-pipelines.yml

+4
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ stages:
3838
call utils\hct\hctstart.cmd %HLSL_SRC_DIR% %HLSL_BLD_DIR%
3939
call utils\hct\hcttest.cmd -$(configuration) noexec
4040
displayName: 'DXIL Tests'
41+
- script: |
42+
call utils\hct\hctstart.cmd %HLSL_SRC_DIR% %HLSL_BLD_DIR%
43+
call utils\hct\hcttest.cmd -$(configuration) exec-warp
44+
displayName: 'DXIL Execution Tests (Nuget WARP)'
4145
4246
- job: Nix
4347
timeoutInMinutes: 90

cmake/modules/Nuget.cmake

+233
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
include_guard(GLOBAL)
2+
3+
if(NOT DEFINED BINARY_DIR)
4+
message(SEND_ERROR "Callers must provide BINARY_DIR")
5+
endif()
6+
7+
if(NOT DEFINED BUILD_TYPE)
8+
message(SEND_ERROR "Callers must provide BUILD_TYPE")
9+
endif()
10+
11+
if(NOT DEFINED ENV{USE_WARP_FROM_NUGET})
12+
message(SEND_ERROR "Callers must set a string value for the environment variable USE_WARP_FROM_NUGET."
13+
"Either 'LATEST_RELEASE' or 'LATEST_PREVIEW'")
14+
endif()
15+
16+
set(USE_WARP_FROM_NUGET $ENV{USE_WARP_FROM_NUGET})
17+
18+
# Downloads nuget.exe to the given path if it doesn't exist yet.
19+
function(EnsureNugetExists target_path)
20+
# Download the latest nuget.exe to the given path.
21+
if(NOT EXISTS ${target_path})
22+
message(STATUS "Installing nuget.exe to ${target_path}...")
23+
file(DOWNLOAD
24+
https://dist.nuget.org/win-x86-commandline/latest/nuget.exe
25+
${target_path}
26+
)
27+
endif()
28+
endfunction()
29+
30+
# Download the latest nuget package for the given ID. Can pass in a custom source, defaults to nuget public feed.
31+
function(GetNuGetPackageLatestVersion)
32+
set(params NAME ID SOURCE OUTPUT_DIR OUTPUT_VARIABLE PREVIEW)
33+
cmake_parse_arguments(PARSE_ARGV 0 ARG "" "${params}" "")
34+
35+
if(NOT ARG_OUTPUT_DIR)
36+
set(ARG_OUTPUT_DIR )
37+
endif()
38+
39+
set(nuget_exe_path "${ARG_OUTPUT_DIR}\\nuget.exe install")
40+
EnsureNugetExists(${nuget_exe_path})
41+
42+
if (${ARG_ID}_LATEST_VERSION)
43+
set(${ARG_OUTPUT_VARIABLE} ${${ARG_ID}_LATEST_VERSION} PARENT_SCOPE)
44+
else()
45+
if(NOT ARG_SOURCE)
46+
set(ARG_SOURCE https://api.nuget.org/v3/index.json)
47+
endif()
48+
49+
if(NOT ARG_PREVIEW)
50+
set(ARG_PREVIEW OFF)
51+
endif()
52+
53+
if(ARG_PREVIEW)
54+
# Note that '-Prerelease' options will only return a prerelease package if that is also the latest.
55+
# If you want a prerelease package with an older version number than the latest release package then you
56+
# need to pass a specific version number.
57+
message("Will add '-Prelease' to nuget list command")
58+
set(prerelease "-Prerelease")
59+
endif()
60+
61+
execute_process(
62+
COMMAND ${nuget_exe_path}
63+
list ${ARG_ID}
64+
-Source ${ARG_SOURCE}
65+
${prerelease}
66+
RESULT_VARIABLE result
67+
OUTPUT_VARIABLE nuget_list_output
68+
OUTPUT_STRIP_TRAILING_WHITESPACE
69+
)
70+
71+
if(NOT ${result} STREQUAL "0")
72+
message(FATAL_ERROR "NuGet failed to find latest version of package ${ARG_ID} with exit code ${result}.")
73+
endif()
74+
75+
# Get last line of running nuget.exe list <ID>.
76+
string(REPLACE "\n" ";" nuget_list_output ${nuget_list_output})
77+
list(POP_BACK nuget_list_output nuget_list_last_line)
78+
if(nuget_list_last_line STREQUAL "No packages found.")
79+
message(FATAL_ERROR "NuGet failed to find latest version of package ${ARG_ID}.")
80+
endif()
81+
82+
# The last line should have the format <ID> <VERSION>
83+
string(REPLACE " " ";" nuget_list_last_line ${nuget_list_last_line})
84+
list(POP_BACK nuget_list_last_line nuget_version)
85+
86+
if(NOT nuget_version)
87+
message(FATAL_ERROR "NuGet failed to find latest version of package ${ARG_ID}.")
88+
endif()
89+
90+
message("Nuget found version:${nuget_version} for ${ARG_ID}")
91+
92+
# Save output variable and cache the result so subsequent calls to the version-unspecified package
93+
# are faster.
94+
set(${ARG_OUTPUT_VARIABLE} ${nuget_version} PARENT_SCOPE)
95+
set(${ARG_ID}_LATEST_VERSION ${nuget_version} CACHE INTERNAL "")
96+
endif()
97+
endfunction()
98+
99+
# Installs a NuGet package under OUTPUT_DIR.
100+
#
101+
# FetchNuGetPackage(
102+
# ID Microsoft.Direct3D.WARP
103+
# VERSION 1.0.13
104+
# SOURCE https://api.nuget.org/v3/index.json
105+
# )
106+
#
107+
# This function sets a variable <name>_SOURCE_DIR (e.g. Microsoft.Direct3D.WARP_SOURCE_DIR in above example) to the
108+
# extract NuGet package contents.
109+
function(FetchNuGetPackage)
110+
set(params NAME ID VERSION SOURCE OUTPUT_DIR RELEASE_TYPE)
111+
cmake_parse_arguments(PARSE_ARGV 0 ARG "" "${params}" "")
112+
113+
# The NAME parameter is optional: if it's not set then the package ID is used as the name. The
114+
# reason for having a separate NAME is to allow a consistent identifier for packages whose ID
115+
# changes with each release (e.g. GDK).
116+
if(NOT ARG_NAME)
117+
set(ARG_NAME ${ARG_ID})
118+
endif()
119+
120+
if(NOT ARG_OUTPUT_DIR)
121+
set(ARG_OUTPUT_DIR ${BINARY_DIR}/temp)
122+
endif()
123+
124+
set(nuget_exe_path ${ARG_OUTPUT_DIR}/nuget.exe)
125+
126+
if(NOT ARG_SOURCE)
127+
set(ARG_SOURCE https://api.nuget.org/v3/index.json)
128+
endif()
129+
130+
if(NOT ARG_RELEASE_TYPE)
131+
set(ARG_RELEASE_TYPE "LATEST_RELEASE")
132+
endif()
133+
134+
set(PREVIEW OFF)
135+
136+
if(${ARG_RELEASE_TYPE} STREQUAL "LATEST_PREVIEW")
137+
set(PREVIEW ON)
138+
endif()
139+
140+
# Default to latest version
141+
if(NOT ARG_VERSION)
142+
GetNuGetPackageLatestVersion(
143+
ID ${ARG_ID}
144+
SOURCE ${ARG_SOURCE}
145+
PREVIEW ${PREVIEW}
146+
OUTPUT_DIR ${ARG_OUTPUT_DIR}
147+
OUTPUT_VARIABLE ARG_VERSION
148+
)
149+
endif()
150+
151+
set(nupkg_path ${ARG_OUTPUT_DIR}/${ARG_ID}.${ARG_VERSION}/${ARG_ID}.${ARG_VERSION}.nupkg)
152+
153+
if(NOT EXISTS ${nupkg_path})
154+
message(STATUS "NuGet: adding package ${ARG_ID}.${ARG_VERSION}")
155+
156+
EnsureNugetExists(${nuget_exe_path})
157+
158+
set(retry_count 0)
159+
set(max_retries 10)
160+
set(retry_delay 10)
161+
set(result 1)
162+
163+
# Run NuGet CLI to download the package.
164+
while(NOT ${result} STREQUAL "0" AND ${retry_count} LESS ${max_retries})
165+
message(STATUS "'${nuget_exe_path}' install '${ARG_ID}' -Version '${ARG_VERSION}' -Source '${ARG_SOURCE}' -OutputDirectory '${ARG_OUTPUT_DIR}' -DependencyVersion Ignore -Verbosity quiet")
166+
execute_process(
167+
COMMAND
168+
${nuget_exe_path}
169+
install ${ARG_ID}
170+
-Version ${ARG_VERSION}
171+
-Source ${ARG_SOURCE}
172+
-OutputDirectory ${ARG_OUTPUT_DIR}
173+
-DependencyVersion Ignore
174+
-Verbosity quiet
175+
RESULT_VARIABLE result
176+
)
177+
if(NOT ${result} STREQUAL "0")
178+
math(EXPR retry_count "${retry_count} + 1")
179+
180+
message(STATUS "Nuget failed: '${result}'. Retrying in ${retry_delay} seconds...")
181+
execute_process(
182+
COMMAND
183+
${CMAKE_COMMAND} -E sleep ${retry_delay}
184+
)
185+
endif()
186+
endwhile()
187+
188+
if(NOT ${result} STREQUAL "0")
189+
message(FATAL_ERROR "NuGet failed: '${result}' Package '${ARG_NAME}' (${ARG_ID}.${ARG_VERSION})")
190+
endif()
191+
endif()
192+
193+
# Set output variable. The NAME parameter is optional: if it's not set then the package ID is used as the
194+
# name. The reason for having a separate NAME is for packages whose IDs change (e.g. GDK) so that callers
195+
# can use a fixed name in dependents. Example, targets can reference gdk_SOURCE_DIR with the snippet below
196+
# instead of having to reference Microsoft.GDK.PC.230300_SOURCE_DIR.
197+
#
198+
# FetchNuGetPackage(
199+
# NAME gdk
200+
# ID Microsoft.GDK.PC.220300
201+
# VERSION 10.0.22621.3049
202+
# )
203+
set(${ARG_NAME}_SOURCE_DIR ${ARG_OUTPUT_DIR}/${ARG_ID}.${ARG_VERSION} PARENT_SCOPE)
204+
endfunction()
205+
206+
# Begin the 'main' logic of this file. Previous code is all defintions.
207+
message("USE_WARP_FROM_NUGET: ${USE_WARP_FROM_NUGET}")
208+
if(${USE_WARP_FROM_NUGET} STREQUAL "LATEST_RELEASE" OR ${USE_WARP_FROM_NUGET} STREQUAL "LATEST_PREVIEW")
209+
210+
message("Fetching warp from nuget")
211+
212+
FetchNuGetPackage(ID Microsoft.Direct3D.WARP OUTPUT_DIR ${BINARY_DIR}/temp RELEASE_TYPE ${USE_WARP_FROM_NUGET})
213+
214+
if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "AMD64")
215+
set(ARCH "x64")
216+
endif()
217+
if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "X86")
218+
set(ARCH "win32")
219+
endif()
220+
if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "ARM64")
221+
set(ARCH "arm64")
222+
endif()
223+
224+
set(WARP_SOURCE_PATH "${Microsoft.Direct3D.WARP_SOURCE_DIR}/build/native/bin/${ARCH}")
225+
set(WARP_DEST_PATH "${BINARY_DIR}/${BUILD_TYPE}/bin/")
226+
message("Copying d3d10warp.dll and d3d10warp.pdb \n"
227+
" from: ${WARP_SOURCE_PATH}\n"
228+
" to: ${WARP_DEST_PATH}")
229+
file(COPY "${WARP_SOURCE_PATH}/d3d10warp.dll"
230+
DESTINATION "${WARP_DEST_PATH}")
231+
file(COPY "${WARP_SOURCE_PATH}/d3d10warp.pdb"
232+
DESTINATION "${WARP_DEST_PATH}")
233+
endif()

tools/clang/test/CMakeLists.txt

+17
Original file line numberDiff line numberDiff line change
@@ -147,12 +147,29 @@ if (WIN32)
147147
)
148148
set(TAEF_EXEC_ADAPTER "" CACHE STRING "adapter for taef exec test")
149149

150+
# Use a custom target so we can depend on it and re-run the cmake logic which downloads warp
151+
# from nuget if requested.
152+
add_custom_target(WarpFromNuget
153+
COMMAND "${CMAKE_COMMAND}"
154+
-DCMAKE_SYSTEM_PROCESSOR=${CMAKE_SYSTEM_PROCESSOR}
155+
-DBUILD_TYPE=${CMAKE_BUILD_TYPE}
156+
-DBINARY_DIR=${CMAKE_BINARY_DIR}
157+
-P "${CMAKE_SOURCE_DIR}/cmake/modules/nuget.cmake")
158+
150159
add_lit_target("check-clang-taef-exec" "Running lit suite hlsl execution test"
151160
${CMAKE_CURRENT_SOURCE_DIR}/taef_exec
152161
PARAMS ${CLANG_TEST_PARAMS}
153162
adapter=${TAEF_EXEC_ADAPTER}
154163
DEPENDS ExecHLSLTests dxexp
155164
ARGS ${CLANG_TEST_EXTRA_ARGS}
156165
)
166+
167+
add_lit_target("check-clang-taef-exec-warp" "Running lit suite hlsl execution test with D3D WARP from nuget"
168+
${CMAKE_CURRENT_SOURCE_DIR}/taef_exec
169+
PARAMS ${CLANG_TEST_PARAMS}
170+
adapter=${TAEF_EXEC_ADAPTER}
171+
DEPENDS ExecHLSLTests dxexp WarpFromNuget
172+
ARGS ${CLANG_TEST_EXTRA_ARGS}
173+
)
157174
endif()
158175
# HLSL Change End

tools/clang/unittests/HLSLExec/ExecutionTest.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -819,6 +819,15 @@ class ExecutionTest {
819819

820820
return false;
821821
}
822+
823+
if (GetModuleHandle("d3d10warp.dll") != NULL) {
824+
CHAR szFullModuleFilePath[MAX_PATH] = "";
825+
GetModuleFileName(GetModuleHandle("d3d10warp.dll"),
826+
szFullModuleFilePath, sizeof(szFullModuleFilePath));
827+
WEX::Logging::Log::Comment(WEX::Common::String().Format(
828+
L"WARP driver loaded from: %S", szFullModuleFilePath));
829+
}
830+
822831
} else {
823832
CComPtr<IDXGIAdapter1> hardwareAdapter;
824833
WEX::Common::String AdapterValue;

utils/hct/hctbuild.cmd

+9-4
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ set WINSDK_MIN_VERSION=10.0.17763.0
4646
set INSTALL_DIR=
4747
set DEFAULT_EXEC_ADAPTER=-DTAEF_EXEC_ADAPTER=
4848
set LIT_ARGS=
49+
set FRESH=
4950

5051
:parse_args
5152
if "%1"=="" (
@@ -208,6 +209,10 @@ if "%1"=="-sanitizer" (
208209
set CMAKE_OPTS=%CMAKE_OPTS% -DLLVM_USE_SANITIZER:STRING=Address
209210
shift /1 & goto :parse_args
210211
)
212+
if "%1"=="-fresh" (
213+
set FRESH="--fresh"
214+
shift /1 & goto :parse_args
215+
)
211216

212217

213218
rem Begin SPIRV change
@@ -468,13 +473,13 @@ cd /d %3
468473
if "%DO_SETUP%"=="1" (
469474
echo Creating solution files for %2, logging to %3\cmake-log.txt
470475
if "%BUILD_GENERATOR%"=="Ninja" (
471-
echo Running "%CMAKE_PATH%" -DCMAKE_BUILD_TYPE:STRING=%1 %CMAKE_OPTS% -G %4 %HLSL_SRC_DIR% > %3\cmake-log.txt
472-
"%CMAKE_PATH%" -DCMAKE_BUILD_TYPE:STRING=%1 %CMAKE_OPTS% -G %4 %HLSL_SRC_DIR% >> %3\cmake-log.txt 2>&1
476+
echo Running "%CMAKE_PATH%" %FRESH% -DCMAKE_BUILD_TYPE:STRING=%1 %CMAKE_OPTS% -G %4 %HLSL_SRC_DIR% > %3\cmake-log.txt
477+
"%CMAKE_PATH%" %FRESH% -DCMAKE_BUILD_TYPE:STRING=%1 %CMAKE_OPTS% -G %4 %HLSL_SRC_DIR% >> %3\cmake-log.txt 2>&1
473478
) else (
474479
rem BUILD_TYPE is mostly ignored in this path as VS generates multiple targets
475480
rem it is still needed to satisfy cmake file expectations
476-
echo Running "%CMAKE_PATH%" -DCMAKE_BUILD_TYPE:STRING=%1 %CMAKE_OPTS% -G %4 %5 %HLSL_SRC_DIR% > %3\cmake-log.txt
477-
"%CMAKE_PATH%" -DCMAKE_BUILD_TYPE:STRING=%1 %CMAKE_OPTS% -G %4 %5 %HLSL_SRC_DIR% >> %3\cmake-log.txt 2>&1
481+
echo Running "%CMAKE_PATH%" %FRESH% -DCMAKE_BUILD_TYPE:STRING=%1 %CMAKE_OPTS% -G %4 %5 %HLSL_SRC_DIR% > %3\cmake-log.txt
482+
"%CMAKE_PATH%" %FRESH% -DCMAKE_BUILD_TYPE:STRING=%1 %CMAKE_OPTS% -G %4 %5 %HLSL_SRC_DIR% >> %3\cmake-log.txt 2>&1
478483
)
479484
if %SHOW_CMAKE_LOG%==1 (
480485
echo ------- Start of %3\cmake-log.txt -------

utils/hct/hcttest.cmd

+25-6
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ set TEST_MANUAL_FILE_CHECK=0
3737
set SINGLE_FILE_CHECK_NAME=0
3838
set CUSTOM_BIN_SET=
3939
set USE_AGILITY_SDK=
40+
set USE_WARP_FROM_NUGET=
41+
set EXEC_TEST_TARGET="check-clang-taef-exec"
4042

4143
rem Begin SPIRV change
4244
set TEST_SPIRV=0
@@ -132,6 +134,22 @@ if "%1"=="-clean" (
132134
set TEST_ALL=0
133135
set TEST_EXEC=1
134136
set TEST_EXEC_REQUIRED=1
137+
) else if "%1"=="exec-warp" (
138+
rem If exec-warp is explicitly supplied, hcttest will fail if machine is not configured
139+
rem to run execution tests, otherwise, execution tests would be skipped.
140+
set TEST_ALL=0
141+
set TEST_EXEC=1
142+
set USE_WARP_FROM_NUGET=LATEST_RELEASE
143+
set TEST_EXEC_REQUIRED=1
144+
set EXEC_TEST_TARGET="check-clang-taef-exec-warp"
145+
) else if "%1"=="exec-warp-preview" (
146+
rem If exec-warp-preview is explicitly supplied, hcttest will fail if machine is not configured
147+
rem to run execution tests, otherwise, execution tests would be skipped.
148+
set TEST_ALL=0
149+
set TEST_EXEC=1
150+
set USE_WARP_FROM_NUGET=LATEST_PREVIEW
151+
set TEST_EXEC_REQUIRED=1
152+
set EXEC_TEST_TARGET="check-clang-taef-exec-warp"
135153
) else if "%1"=="exec-filter" (
136154
set TEST_ALL=0
137155
set TEST_EXEC=1
@@ -333,21 +351,22 @@ if "%TEST_USE_LIT%"=="1" (
333351
if defined EXEC_ADAPTER (
334352
py %HLSL_SRC_DIR%/utils/lit/lit.py -v --no-progress-bar --param build_mode=%BUILD_CONFIG% --param clang_site_config=%HLSL_BLD_DIR%/tools/clang/test/lit.site.cfg --param clang_taef_exec_site_config=%HLSL_BLD_DIR%/tools/clang/test/taef_exec/lit.site.cfg %EXEC_ADAPTER% %HLSL_SRC_DIR%/tools/clang/test/taef_exec
335353
) else (
336-
cmake --build %HLSL_BLD_DIR% --config %BUILD_CONFIG% --target check-clang-taef-exec
354+
cmake --build %HLSL_BLD_DIR% --config %BUILD_CONFIG% --target %EXEC_TEST_TARGET%
337355
)
338356
set RES_EXEC=!ERRORLEVEL!
339357
)
340358
)
341-
set TEST_CLANG=0
342-
set TEST_DXILCONV=0
343-
set TEST_SPIRV=0
344-
set TEST_EXEC=0
345-
set TEST_CMD=0
346359

347360
rem No other tests to run - skip copying and move on to report the results
348361
if not exist "%HCT_EXTRAS%\hcttest-extras.cmd" (
349362
goto :report_results
350363
)
364+
365+
set TEST_CLANG=0
366+
set TEST_DXILCONV=0
367+
set TEST_SPIRV=0
368+
set TEST_EXEC=0
369+
set TEST_CMD=0
351370
)
352371

353372
if not exist %TEST_DIR% (mkdir %TEST_DIR%)

0 commit comments

Comments
 (0)