DxilModuleTest.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // //
  3. // Copyright (C) Microsoft Corporation. All rights reserved. //
  4. // DxilModuleTest.cpp //
  5. // //
  6. // Provides unit tests for DxilModule. //
  7. // //
  8. ///////////////////////////////////////////////////////////////////////////////
  9. #include "dxc/Test/CompilationResult.h"
  10. #include "dxc/Test/HlslTestUtils.h"
  11. #include "dxc/Test/DxcTestUtils.h"
  12. #include "dxc/Support/microcom.h"
  13. #include "dxc/dxcapi.internal.h"
  14. #include "dxc/HLSL/HLOperationLowerExtension.h"
  15. #include "dxc/HlslIntrinsicOp.h"
  16. #include "dxc/DXIL/DxilOperations.h"
  17. #include "dxc/DXIL/DxilInstructions.h"
  18. #include "dxc/DxilContainer/DxilContainer.h"
  19. #include "dxc/DXIL/DxilModule.h"
  20. #include "llvm/Support/Regex.h"
  21. #include "llvm/Support/MSFileSystem.h"
  22. #include "llvm/Support/FileSystem.h"
  23. #include "llvm/Support/MemoryBuffer.h"
  24. #include "llvm/Support/ErrorOr.h"
  25. #include "llvm/Bitcode/ReaderWriter.h"
  26. #include "llvm/IR/LLVMContext.h"
  27. #include "llvm/IR/InstIterator.h"
  28. using namespace hlsl;
  29. using namespace llvm;
  30. ///////////////////////////////////////////////////////////////////////////////
  31. // DxilModule unit tests.
  32. #ifdef _WIN32
  33. class DxilModuleTest {
  34. #else
  35. class DxilModuleTest : public ::testing::Test {
  36. #endif
  37. public:
  38. BEGIN_TEST_CLASS(DxilModuleTest)
  39. TEST_CLASS_PROPERTY(L"Parallel", L"true")
  40. TEST_METHOD_PROPERTY(L"Priority", L"0")
  41. END_TEST_CLASS()
  42. TEST_CLASS_SETUP(InitSupport);
  43. dxc::DxcDllSupport m_dllSupport;
  44. // Basic loading tests.
  45. TEST_METHOD(LoadDxilModule_1_0)
  46. TEST_METHOD(LoadDxilModule_1_1)
  47. TEST_METHOD(LoadDxilModule_1_2)
  48. // Precise query tests.
  49. TEST_METHOD(Precise1)
  50. TEST_METHOD(Precise2)
  51. TEST_METHOD(Precise3)
  52. TEST_METHOD(Precise4)
  53. TEST_METHOD(Precise5)
  54. TEST_METHOD(Precise6)
  55. TEST_METHOD(Precise7)
  56. TEST_METHOD(CSGetNumThreads)
  57. TEST_METHOD(MSGetNumThreads)
  58. TEST_METHOD(ASGetNumThreads)
  59. TEST_METHOD(SetValidatorVersion)
  60. void VerifyValidatorVersionFails(
  61. LPCWSTR shaderModel, const std::vector<LPCWSTR> &arguments,
  62. const std::vector<LPCSTR> &expectedErrors);
  63. void VerifyValidatorVersionMatches(
  64. LPCWSTR shaderModel, const std::vector<LPCWSTR> &arguments,
  65. unsigned expectedMajor = UINT_MAX, unsigned expectedMinor = UINT_MAX);
  66. };
  67. bool DxilModuleTest::InitSupport() {
  68. if (!m_dllSupport.IsEnabled()) {
  69. VERIFY_SUCCEEDED(m_dllSupport.Initialize());
  70. }
  71. return true;
  72. }
  73. ///////////////////////////////////////////////////////////////////////////////
  74. // Compilation and dxil module loading support.
  75. namespace {
  76. class Compiler {
  77. public:
  78. Compiler(dxc::DxcDllSupport &dll)
  79. : m_dllSupport(dll)
  80. , m_msf(CreateMSFileSystem())
  81. , m_pts(m_msf.get())
  82. {
  83. m_ver.Initialize(m_dllSupport);
  84. VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcCompiler, &pCompiler));
  85. }
  86. bool SkipDxil_Test(unsigned major, unsigned minor) {
  87. return m_ver.SkipDxilVersion(major, minor);
  88. }
  89. IDxcOperationResult *Compile(const char *program, LPCWSTR shaderModel = L"ps_6_0") {
  90. return Compile(program, shaderModel, {}, {});
  91. }
  92. IDxcOperationResult *Compile(const char *program, LPCWSTR shaderModel, const std::vector<LPCWSTR> &arguments, const std::vector<DxcDefine> defs ) {
  93. Utf8ToBlob(m_dllSupport, program, &pCodeBlob);
  94. VERIFY_SUCCEEDED(pCompiler->Compile(pCodeBlob, L"hlsl.hlsl", L"main",
  95. shaderModel,
  96. const_cast<LPCWSTR *>(arguments.data()), arguments.size(),
  97. defs.data(), defs.size(),
  98. nullptr, &pCompileResult));
  99. return pCompileResult;
  100. }
  101. std::string Disassemble() {
  102. CComPtr<IDxcBlob> pBlob;
  103. CheckOperationSucceeded(pCompileResult, &pBlob);
  104. return DisassembleProgram(m_dllSupport, pBlob);
  105. }
  106. DxilModule &GetDxilModule() {
  107. // Make sure we compiled successfully.
  108. CComPtr<IDxcBlob> pBlob;
  109. CheckOperationSucceeded(pCompileResult, &pBlob);
  110. // Verify we have a valid dxil container.
  111. const DxilContainerHeader *pContainer =
  112. IsDxilContainerLike(pBlob->GetBufferPointer(), pBlob->GetBufferSize());
  113. VERIFY_IS_NOT_NULL(pContainer);
  114. VERIFY_IS_TRUE(IsValidDxilContainer(pContainer, pBlob->GetBufferSize()));
  115. // Get Dxil part from container.
  116. DxilPartIterator it = std::find_if(begin(pContainer), end(pContainer), DxilPartIsType(DFCC_DXIL));
  117. VERIFY_IS_FALSE(it == end(pContainer));
  118. const DxilProgramHeader *pProgramHeader =
  119. reinterpret_cast<const DxilProgramHeader *>(GetDxilPartData(*it));
  120. VERIFY_IS_TRUE(IsValidDxilProgramHeader(pProgramHeader, (*it)->PartSize));
  121. // Get a pointer to the llvm bitcode.
  122. const char *pIL;
  123. uint32_t pILLength;
  124. GetDxilProgramBitcode(pProgramHeader, &pIL, &pILLength);
  125. // Parse llvm bitcode into a module.
  126. std::unique_ptr<llvm::MemoryBuffer> pBitcodeBuf(
  127. llvm::MemoryBuffer::getMemBuffer(llvm::StringRef(pIL, pILLength), "", false));
  128. llvm::ErrorOr<std::unique_ptr<llvm::Module>>
  129. pModule(llvm::parseBitcodeFile(pBitcodeBuf->getMemBufferRef(), m_llvmContext));
  130. if (std::error_code ec = pModule.getError()) {
  131. VERIFY_FAIL();
  132. }
  133. m_module = std::move(pModule.get());
  134. // Grab the dxil module;
  135. DxilModule *DM = DxilModule::TryGetDxilModule(m_module.get());
  136. VERIFY_IS_NOT_NULL(DM);
  137. return *DM;
  138. }
  139. public:
  140. static ::llvm::sys::fs::MSFileSystem *CreateMSFileSystem() {
  141. ::llvm::sys::fs::MSFileSystem *msfPtr;
  142. VERIFY_SUCCEEDED(CreateMSFileSystemForDisk(&msfPtr));
  143. return msfPtr;
  144. }
  145. dxc::DxcDllSupport &m_dllSupport;
  146. VersionSupportInfo m_ver;
  147. CComPtr<IDxcCompiler> pCompiler;
  148. CComPtr<IDxcBlobEncoding> pCodeBlob;
  149. CComPtr<IDxcOperationResult> pCompileResult;
  150. llvm::LLVMContext m_llvmContext;
  151. std::unique_ptr<llvm::Module> m_module;
  152. std::unique_ptr<::llvm::sys::fs::MSFileSystem> m_msf;
  153. ::llvm::sys::fs::AutoPerThreadSystem m_pts;
  154. };
  155. }
  156. ///////////////////////////////////////////////////////////////////////////////
  157. // Unit Test Implementation
  158. TEST_F(DxilModuleTest, LoadDxilModule_1_0) {
  159. Compiler c(m_dllSupport);
  160. c.Compile(
  161. "float4 main() : SV_Target {\n"
  162. " return 0;\n"
  163. "}\n"
  164. ,
  165. L"ps_6_0"
  166. );
  167. // Basic sanity check on dxil version in dxil module.
  168. DxilModule &DM = c.GetDxilModule();
  169. unsigned vMajor, vMinor;
  170. DM.GetDxilVersion(vMajor, vMinor);
  171. VERIFY_IS_TRUE(vMajor == 1);
  172. VERIFY_IS_TRUE(vMinor == 0);
  173. }
  174. TEST_F(DxilModuleTest, LoadDxilModule_1_1) {
  175. Compiler c(m_dllSupport);
  176. if (c.SkipDxil_Test(1,1)) return;
  177. c.Compile(
  178. "float4 main() : SV_Target {\n"
  179. " return 0;\n"
  180. "}\n"
  181. ,
  182. L"ps_6_1"
  183. );
  184. // Basic sanity check on dxil version in dxil module.
  185. DxilModule &DM = c.GetDxilModule();
  186. unsigned vMajor, vMinor;
  187. DM.GetDxilVersion(vMajor, vMinor);
  188. VERIFY_IS_TRUE(vMajor == 1);
  189. VERIFY_IS_TRUE(vMinor == 1);
  190. }
  191. TEST_F(DxilModuleTest, LoadDxilModule_1_2) {
  192. Compiler c(m_dllSupport);
  193. if (c.SkipDxil_Test(1,2)) return;
  194. c.Compile(
  195. "float4 main() : SV_Target {\n"
  196. " return 0;\n"
  197. "}\n"
  198. ,
  199. L"ps_6_2"
  200. );
  201. // Basic sanity check on dxil version in dxil module.
  202. DxilModule &DM = c.GetDxilModule();
  203. unsigned vMajor, vMinor;
  204. DM.GetDxilVersion(vMajor, vMinor);
  205. VERIFY_IS_TRUE(vMajor == 1);
  206. VERIFY_IS_TRUE(vMinor == 2);
  207. }
  208. TEST_F(DxilModuleTest, Precise1) {
  209. Compiler c(m_dllSupport);
  210. c.Compile(
  211. "precise float main(float x : X, float y : Y) : SV_Target {\n"
  212. " return sqrt(x) + y;\n"
  213. "}\n"
  214. );
  215. // Make sure sqrt and add are marked precise.
  216. DxilModule &DM = c.GetDxilModule();
  217. Function *F = DM.GetEntryFunction();
  218. int numChecks = 0;
  219. for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
  220. Instruction *Inst = &*I;
  221. if (DxilInst_Sqrt(Inst)) {
  222. numChecks++;
  223. VERIFY_IS_TRUE(DM.IsPrecise(Inst));
  224. }
  225. else if (LlvmInst_FAdd(Inst)) {
  226. numChecks++;
  227. VERIFY_IS_TRUE(DM.IsPrecise(Inst));
  228. }
  229. }
  230. VERIFY_ARE_EQUAL(numChecks, 2);
  231. }
  232. TEST_F(DxilModuleTest, Precise2) {
  233. Compiler c(m_dllSupport);
  234. c.Compile(
  235. "float main(float x : X, float y : Y) : SV_Target {\n"
  236. " return sqrt(x) + y;\n"
  237. "}\n"
  238. );
  239. // Make sure sqrt and add are not marked precise.
  240. DxilModule &DM = c.GetDxilModule();
  241. Function *F = DM.GetEntryFunction();
  242. int numChecks = 0;
  243. for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
  244. Instruction *Inst = &*I;
  245. if (DxilInst_Sqrt(Inst)) {
  246. numChecks++;
  247. VERIFY_IS_FALSE(DM.IsPrecise(Inst));
  248. }
  249. else if (LlvmInst_FAdd(Inst)) {
  250. numChecks++;
  251. VERIFY_IS_FALSE(DM.IsPrecise(Inst));
  252. }
  253. }
  254. VERIFY_ARE_EQUAL(numChecks, 2);
  255. }
  256. TEST_F(DxilModuleTest, Precise3) {
  257. // TODO: Enable this test when precise metadata is inserted for Gis.
  258. if (const bool GisIsBroken = true) return;
  259. Compiler c(m_dllSupport);
  260. c.Compile(
  261. "float main(float x : X, float y : Y) : SV_Target {\n"
  262. " return sqrt(x) + y;\n"
  263. "}\n",
  264. L"ps_6_0",
  265. { L"/Gis" }, {}
  266. );
  267. // Make sure sqrt and add are marked precise.
  268. DxilModule &DM = c.GetDxilModule();
  269. Function *F = DM.GetEntryFunction();
  270. int numChecks = 0;
  271. for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
  272. Instruction *Inst = &*I;
  273. if (DxilInst_Sqrt(Inst)) {
  274. numChecks++;
  275. VERIFY_IS_TRUE(DM.IsPrecise(Inst));
  276. }
  277. else if (LlvmInst_FAdd(Inst)) {
  278. numChecks++;
  279. VERIFY_IS_TRUE(DM.IsPrecise(Inst));
  280. }
  281. }
  282. VERIFY_ARE_EQUAL(numChecks, 2);
  283. }
  284. TEST_F(DxilModuleTest, Precise4) {
  285. Compiler c(m_dllSupport);
  286. c.Compile(
  287. "float main(float x : X, float y : Y) : SV_Target {\n"
  288. " precise float sx = 1 / sqrt(x);\n"
  289. " return sx + y;\n"
  290. "}\n"
  291. );
  292. // Make sure sqrt and div are marked precise, and add is not.
  293. DxilModule &DM = c.GetDxilModule();
  294. Function *F = DM.GetEntryFunction();
  295. int numChecks = 0;
  296. for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
  297. Instruction *Inst = &*I;
  298. if (DxilInst_Sqrt(Inst)) {
  299. numChecks++;
  300. VERIFY_IS_TRUE(DM.IsPrecise(Inst));
  301. }
  302. else if (LlvmInst_FDiv(Inst)) {
  303. numChecks++;
  304. VERIFY_IS_TRUE(DM.IsPrecise(Inst));
  305. }
  306. else if (LlvmInst_FAdd(Inst)) {
  307. numChecks++;
  308. VERIFY_IS_FALSE(DM.IsPrecise(Inst));
  309. }
  310. }
  311. VERIFY_ARE_EQUAL(numChecks, 3);
  312. }
  313. TEST_F(DxilModuleTest, Precise5) {
  314. Compiler c(m_dllSupport);
  315. c.Compile(
  316. "float C[10];\n"
  317. "float main(float x : X, float y : Y, int i : I) : SV_Target {\n"
  318. " float A[2];\n"
  319. " A[0] = x;\n"
  320. " A[1] = y;\n"
  321. " return A[i] + C[i];\n"
  322. "}\n"
  323. );
  324. // Make sure load and extract value are not reported as precise.
  325. DxilModule &DM = c.GetDxilModule();
  326. Function *F = DM.GetEntryFunction();
  327. int numChecks = 0;
  328. for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
  329. Instruction *Inst = &*I;
  330. if (LlvmInst_ExtractValue(Inst)) {
  331. numChecks++;
  332. VERIFY_IS_FALSE(DM.IsPrecise(Inst));
  333. }
  334. else if (LlvmInst_Load(Inst)) {
  335. numChecks++;
  336. VERIFY_IS_FALSE(DM.IsPrecise(Inst));
  337. }
  338. else if (LlvmInst_FAdd(Inst)) {
  339. numChecks++;
  340. VERIFY_IS_FALSE(DM.IsPrecise(Inst));
  341. }
  342. }
  343. VERIFY_ARE_EQUAL(numChecks, 3);
  344. }
  345. TEST_F(DxilModuleTest, Precise6) {
  346. Compiler c(m_dllSupport);
  347. c.Compile(
  348. "precise float2 main(float2 x : A, float2 y : B) : SV_Target {\n"
  349. " return sqrt(x * y);\n"
  350. "}\n"
  351. );
  352. // Make sure sqrt and mul are marked precise.
  353. DxilModule &DM = c.GetDxilModule();
  354. Function *F = DM.GetEntryFunction();
  355. int numChecks = 0;
  356. for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
  357. Instruction *Inst = &*I;
  358. if (DxilInst_Sqrt(Inst)) {
  359. numChecks++;
  360. VERIFY_IS_TRUE(DM.IsPrecise(Inst));
  361. }
  362. else if (LlvmInst_FMul(Inst)) {
  363. numChecks++;
  364. VERIFY_IS_TRUE(DM.IsPrecise(Inst));
  365. }
  366. }
  367. VERIFY_ARE_EQUAL(numChecks, 4);
  368. }
  369. TEST_F(DxilModuleTest, Precise7) {
  370. Compiler c(m_dllSupport);
  371. c.Compile(
  372. "float2 main(float2 x : A, float2 y : B) : SV_Target {\n"
  373. " return sqrt(x * y);\n"
  374. "}\n"
  375. );
  376. // Make sure sqrt and mul are not marked precise.
  377. DxilModule &DM = c.GetDxilModule();
  378. Function *F = DM.GetEntryFunction();
  379. int numChecks = 0;
  380. for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
  381. Instruction *Inst = &*I;
  382. if (DxilInst_Sqrt(Inst)) {
  383. numChecks++;
  384. VERIFY_IS_FALSE(DM.IsPrecise(Inst));
  385. }
  386. else if (LlvmInst_FMul(Inst)) {
  387. numChecks++;
  388. VERIFY_IS_FALSE(DM.IsPrecise(Inst));
  389. }
  390. }
  391. VERIFY_ARE_EQUAL(numChecks, 4);
  392. }
  393. TEST_F(DxilModuleTest, CSGetNumThreads) {
  394. Compiler c(m_dllSupport);
  395. c.Compile(
  396. "[numthreads(8, 4, 2)]\n"
  397. "void main() {\n"
  398. "}\n"
  399. ,
  400. L"cs_6_0"
  401. );
  402. DxilModule &DM = c.GetDxilModule();
  403. VERIFY_ARE_EQUAL(8, DM.GetNumThreads(0));
  404. VERIFY_ARE_EQUAL(4, DM.GetNumThreads(1));
  405. VERIFY_ARE_EQUAL(2, DM.GetNumThreads(2));
  406. }
  407. TEST_F(DxilModuleTest, MSGetNumThreads) {
  408. Compiler c(m_dllSupport);
  409. if (c.SkipDxil_Test(1,5)) return;
  410. c.Compile(
  411. "struct MeshPerVertex { float4 pos : SV_Position; };\n"
  412. "[numthreads(8, 4, 2)]\n"
  413. "[outputtopology(\"triangle\")]\n"
  414. "void main(\n"
  415. " out indices uint3 primIndices[1]\n"
  416. ") {\n"
  417. " SetMeshOutputCounts(0, 0);\n"
  418. "}\n"
  419. ,
  420. L"ms_6_5"
  421. );
  422. DxilModule &DM = c.GetDxilModule();
  423. VERIFY_ARE_EQUAL(8, DM.GetNumThreads(0));
  424. VERIFY_ARE_EQUAL(4, DM.GetNumThreads(1));
  425. VERIFY_ARE_EQUAL(2, DM.GetNumThreads(2));
  426. }
  427. TEST_F(DxilModuleTest, ASGetNumThreads) {
  428. Compiler c(m_dllSupport);
  429. if (c.SkipDxil_Test(1,5)) return;
  430. c.Compile(
  431. "struct Payload { uint i; };\n"
  432. "[numthreads(8, 4, 2)]\n"
  433. "void main() {\n"
  434. " Payload pld = {0};\n"
  435. " DispatchMesh(1, 1, 1, pld);\n"
  436. "}\n"
  437. ,
  438. L"as_6_5"
  439. );
  440. DxilModule &DM = c.GetDxilModule();
  441. VERIFY_ARE_EQUAL(8, DM.GetNumThreads(0));
  442. VERIFY_ARE_EQUAL(4, DM.GetNumThreads(1));
  443. VERIFY_ARE_EQUAL(2, DM.GetNumThreads(2));
  444. }
  445. void DxilModuleTest::VerifyValidatorVersionFails(
  446. LPCWSTR shaderModel, const std::vector<LPCWSTR> &arguments,
  447. const std::vector<LPCSTR> &expectedErrors) {
  448. LPCSTR shader =
  449. "[shader(\"pixel\")]"
  450. "float4 main() : SV_Target {\n"
  451. " return 0;\n"
  452. "}\n";
  453. Compiler c(m_dllSupport);
  454. c.Compile(shader, shaderModel, arguments, {});
  455. CheckOperationResultMsgs(c.pCompileResult, expectedErrors, false, false);
  456. }
  457. void DxilModuleTest::VerifyValidatorVersionMatches(
  458. LPCWSTR shaderModel, const std::vector<LPCWSTR> &arguments,
  459. unsigned expectedMajor, unsigned expectedMinor) {
  460. LPCSTR shader =
  461. "[shader(\"pixel\")]"
  462. "float4 main() : SV_Target {\n"
  463. " return 0;\n"
  464. "}\n";
  465. Compiler c(m_dllSupport);
  466. c.Compile(shader, shaderModel, arguments, {});
  467. DxilModule &DM = c.GetDxilModule();
  468. unsigned vMajor, vMinor;
  469. DM.GetValidatorVersion(vMajor, vMinor);
  470. if (expectedMajor == UINT_MAX) {
  471. // Expect current version
  472. VERIFY_ARE_EQUAL(vMajor, c.m_ver.m_ValMajor);
  473. VERIFY_ARE_EQUAL(vMinor, c.m_ver.m_ValMinor);
  474. } else {
  475. VERIFY_ARE_EQUAL(vMajor, expectedMajor);
  476. VERIFY_ARE_EQUAL(vMinor, expectedMinor);
  477. }
  478. }
  479. TEST_F(DxilModuleTest, SetValidatorVersion) {
  480. Compiler c(m_dllSupport);
  481. if (c.SkipDxil_Test(1, 4)) return;
  482. // Current version
  483. VerifyValidatorVersionMatches(L"ps_6_2", {});
  484. VerifyValidatorVersionMatches(L"lib_6_3", {});
  485. // Current version, with validation disabled
  486. VerifyValidatorVersionMatches(L"ps_6_2", {L"-Vd"});
  487. VerifyValidatorVersionMatches(L"lib_6_3", {L"-Vd"});
  488. // Override validator version
  489. VerifyValidatorVersionMatches(L"ps_6_2", {L"-validator-version", L"1.2"}, 1,2);
  490. VerifyValidatorVersionMatches(L"lib_6_3", {L"-validator-version", L"1.3"}, 1,3);
  491. // Override validator version, with validation disabled
  492. VerifyValidatorVersionMatches(L"ps_6_2", {L"-Vd", L"-validator-version", L"1.2"}, 1,2);
  493. VerifyValidatorVersionMatches(L"lib_6_3", {L"-Vd", L"-validator-version", L"1.3"}, 1,3);
  494. // Never can validate (version 0,0):
  495. VerifyValidatorVersionMatches(L"lib_6_1", {L"-Vd"}, 0, 0);
  496. VerifyValidatorVersionMatches(L"lib_6_2", {L"-Vd"}, 0, 0);
  497. VerifyValidatorVersionMatches(L"lib_6_2", {L"-Vd", L"-validator-version", L"0.0"}, 0, 0);
  498. VerifyValidatorVersionMatches(L"lib_6_x", {}, 0, 0);
  499. VerifyValidatorVersionMatches(L"lib_6_x", {L"-validator-version", L"0.0"}, 0, 0);
  500. // Failure cases:
  501. VerifyValidatorVersionFails(L"ps_6_2", {L"-validator-version", L"1.1"}, {
  502. "validator version 1,1 does not support target profile."});
  503. VerifyValidatorVersionFails(L"lib_6_2", {L"-Tlib_6_2"}, {
  504. "Must disable validation for unsupported lib_6_1 or lib_6_2 targets"});
  505. VerifyValidatorVersionFails(L"lib_6_2", {L"-Vd", L"-validator-version", L"1.2"}, {
  506. "-validator-version cannot be used with library profiles lib_6_1 or lib_6_2."});
  507. VerifyValidatorVersionFails(L"lib_6_x", {L"-validator-version", L"1.3"}, {
  508. "Offline library profile cannot be used with non-zero -validator-version."});
  509. }