DxcTestUtils.h 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // //
  3. // DxcTestUtils.h //
  4. // Copyright (C) Microsoft Corporation. All rights reserved. //
  5. // This file is distributed under the University of Illinois Open Source //
  6. // License. See LICENSE.TXT for details. //
  7. // //
  8. // This file provides utility functions for testing dxc APIs. //
  9. // //
  10. ///////////////////////////////////////////////////////////////////////////////
  11. #pragma once
  12. #include <string>
  13. #include <vector>
  14. #include <map>
  15. #include "dxc/dxcapi.h"
  16. #include "dxc/Support/dxcapi.use.h"
  17. #include "llvm/ADT/ArrayRef.h"
  18. #include "llvm/ADT/StringRef.h"
  19. #include "llvm/ADT/StringMap.h"
  20. namespace hlsl {
  21. namespace options {
  22. class DxcOpts;
  23. class MainArgs;
  24. }
  25. }
  26. /// Use this class to run a FileCheck invocation in memory.
  27. class FileCheckForTest {
  28. public:
  29. FileCheckForTest();
  30. std::string CheckFilename;
  31. /// File to check (defaults to stdin)
  32. std::string InputFilename;
  33. /// Prefix to use from check file (defaults to 'CHECK')
  34. std::vector<std::string> CheckPrefixes;
  35. /// Do not treat all horizontal whitespace as equivalent
  36. bool NoCanonicalizeWhiteSpace;
  37. /// Add an implicit negative check with this pattern to every
  38. /// positive check. This can be used to ensure that no instances of
  39. /// this pattern occur which are not matched by a positive pattern
  40. std::vector<std::string> ImplicitCheckNot;
  41. /// Allow the input file to be empty. This is useful when making
  42. /// checks that some error message does not occur, for example.
  43. bool AllowEmptyInput;
  44. /// VariableTable - This holds all the current filecheck variables.
  45. llvm::StringMap<std::string> VariableTable;
  46. /// String to read in place of standard input.
  47. std::string InputForStdin;
  48. /// Output stream.
  49. std::string test_outs;
  50. /// Output stream.
  51. std::string test_errs;
  52. int Run();
  53. };
  54. // The result of running a single command in a run pipeline
  55. struct FileRunCommandResult {
  56. CComPtr<IDxcOperationResult> OpResult; // The operation result, if any.
  57. std::string StdOut;
  58. std::string StdErr;
  59. int ExitCode = 0;
  60. bool AbortPipeline = false; // True to prevent running subsequent commands
  61. static inline FileRunCommandResult Success() {
  62. FileRunCommandResult result;
  63. result.ExitCode = 0;
  64. return result;
  65. }
  66. static inline FileRunCommandResult Success(std::string StdOut) {
  67. FileRunCommandResult result;
  68. result.ExitCode = 0;
  69. result.StdOut = std::move(StdOut);
  70. return result;
  71. }
  72. static inline FileRunCommandResult Error(int ExitCode, std::string StdErr) {
  73. FileRunCommandResult result;
  74. result.ExitCode = ExitCode;
  75. result.StdErr = std::move(StdErr);
  76. return result;
  77. }
  78. static inline FileRunCommandResult Error(std::string StdErr) {
  79. return Error(1, StdErr);
  80. }
  81. };
  82. typedef std::map<std::string, std::string> PluginToolsPaths;
  83. class FileRunCommandPart {
  84. public:
  85. FileRunCommandPart(const std::string &command, const std::string &arguments, LPCWSTR commandFileName);
  86. FileRunCommandPart(const FileRunCommandPart&) = default;
  87. FileRunCommandPart(FileRunCommandPart&&) = default;
  88. FileRunCommandResult Run(dxc::DxcDllSupport &DllSupport, const FileRunCommandResult *Prior, PluginToolsPaths *pPluginToolsPaths = nullptr, LPCWSTR dumpName = nullptr);
  89. FileRunCommandResult RunHashTests(dxc::DxcDllSupport &DllSupport);
  90. FileRunCommandResult ReadOptsForDxc(hlsl::options::MainArgs &argStrings, hlsl::options::DxcOpts &Opts, unsigned flagsToInclude = 0);
  91. std::string Command; // Command to run, eg %dxc
  92. std::string Arguments; // Arguments to command
  93. LPCWSTR CommandFileName; // File name replacement for %s
  94. private:
  95. FileRunCommandResult RunFileChecker(const FileRunCommandResult *Prior, LPCWSTR dumpName = nullptr);
  96. FileRunCommandResult RunDxc(dxc::DxcDllSupport &DllSupport, const FileRunCommandResult *Prior);
  97. FileRunCommandResult RunDxv(dxc::DxcDllSupport &DllSupport, const FileRunCommandResult *Prior);
  98. FileRunCommandResult RunOpt(dxc::DxcDllSupport &DllSupport, const FileRunCommandResult *Prior);
  99. FileRunCommandResult RunD3DReflect(dxc::DxcDllSupport &DllSupport, const FileRunCommandResult *Prior);
  100. FileRunCommandResult RunDxr(dxc::DxcDllSupport &DllSupport, const FileRunCommandResult *Prior);
  101. FileRunCommandResult RunTee(const FileRunCommandResult *Prior);
  102. FileRunCommandResult RunXFail(const FileRunCommandResult *Prior);
  103. FileRunCommandResult RunDxilVer(dxc::DxcDllSupport& DllSupport, const FileRunCommandResult* Prior);
  104. FileRunCommandResult RunDxcHashTest(dxc::DxcDllSupport &DllSupport);
  105. FileRunCommandResult RunFromPath(const std::string &path, const FileRunCommandResult *Prior);
  106. FileRunCommandResult RunFileCompareText(const FileRunCommandResult *Prior);
  107. #ifdef _WIN32
  108. FileRunCommandResult RunFxc(dxc::DxcDllSupport &DllSupport, const FileRunCommandResult* Prior);
  109. #endif
  110. void SubstituteFilenameVars(std::string &args);
  111. #ifdef _WIN32
  112. bool ReadFileContentToString(HANDLE hFile, std::string &str);
  113. #endif
  114. };
  115. void ParseCommandParts(LPCSTR commands, LPCWSTR fileName, std::vector<FileRunCommandPart> &parts);
  116. void ParseCommandPartsFromFile(LPCWSTR fileName, std::vector<FileRunCommandPart> &parts);
  117. class FileRunTestResult {
  118. public:
  119. std::string ErrorMessage;
  120. int RunResult;
  121. static FileRunTestResult RunHashTestFromFileCommands(LPCWSTR fileName);
  122. static FileRunTestResult RunFromFileCommands(LPCWSTR fileName,
  123. PluginToolsPaths *pPluginToolsPaths = nullptr,
  124. LPCWSTR dumpName = nullptr);
  125. static FileRunTestResult RunFromFileCommands(LPCWSTR fileName,
  126. dxc::DxcDllSupport &dllSupport,
  127. PluginToolsPaths *pPluginToolsPaths = nullptr,
  128. LPCWSTR dumpName = nullptr);
  129. };
  130. void AssembleToContainer(dxc::DxcDllSupport &dllSupport, IDxcBlob *pModule, IDxcBlob **pContainer);
  131. std::string BlobToUtf8(_In_ IDxcBlob *pBlob);
  132. std::wstring BlobToUtf16(_In_ IDxcBlob *pBlob);
  133. void CheckOperationSucceeded(IDxcOperationResult *pResult, IDxcBlob **ppBlob);
  134. bool CheckOperationResultMsgs(IDxcOperationResult *pResult,
  135. llvm::ArrayRef<LPCSTR> pErrorMsgs,
  136. bool maySucceedAnyway, bool bRegex);
  137. bool CheckOperationResultMsgs(IDxcOperationResult *pResult,
  138. const LPCSTR *pErrorMsgs, size_t errorMsgCount,
  139. bool maySucceedAnyway, bool bRegex);
  140. bool CheckMsgs(const LPCSTR pText, size_t TextCount, const LPCSTR *pErrorMsgs,
  141. size_t errorMsgCount, bool bRegex);
  142. bool CheckNotMsgs(const LPCSTR pText, size_t TextCount, const LPCSTR *pErrorMsgs,
  143. size_t errorMsgCount, bool bRegex);
  144. void GetDxilPart(dxc::DxcDllSupport &dllSupport, IDxcBlob *pProgram, IDxcBlob **pDxilPart);
  145. std::string DisassembleProgram(dxc::DxcDllSupport &dllSupport, IDxcBlob *pProgram);
  146. void SplitPassList(LPWSTR pPassesBuffer, std::vector<LPCWSTR> &passes);
  147. void MultiByteStringToBlob(dxc::DxcDllSupport &dllSupport, const std::string &val, UINT32 codePoint, _Outptr_ IDxcBlob **ppBlob);
  148. void MultiByteStringToBlob(dxc::DxcDllSupport &dllSupport, const std::string &val, UINT32 codePoint, _Outptr_ IDxcBlobEncoding **ppBlob);
  149. void Utf8ToBlob(dxc::DxcDllSupport &dllSupport, const std::string &val, _Outptr_ IDxcBlob **ppBlob);
  150. void Utf8ToBlob(dxc::DxcDllSupport &dllSupport, const std::string &val, _Outptr_ IDxcBlobEncoding **ppBlob);
  151. void Utf8ToBlob(dxc::DxcDllSupport &dllSupport, const char *pVal, _Outptr_ IDxcBlobEncoding **ppBlob);
  152. void Utf16ToBlob(dxc::DxcDllSupport &dllSupport, const std::wstring &val, _Outptr_ IDxcBlob **ppBlob);
  153. void Utf16ToBlob(dxc::DxcDllSupport &dllSupport, const std::wstring &val, _Outptr_ IDxcBlobEncoding **ppBlob);
  154. void VerifyCompileOK(dxc::DxcDllSupport &dllSupport, LPCSTR pText,
  155. LPWSTR pTargetProfile, LPCWSTR pArgs,
  156. _Outptr_ IDxcBlob **ppResult);
  157. void VerifyCompileOK(dxc::DxcDllSupport &dllSupport, LPCSTR pText,
  158. LPWSTR pTargetProfile, std::vector<LPCWSTR> &args,
  159. _Outptr_ IDxcBlob **ppResult);
  160. HRESULT GetVersion(dxc::DxcDllSupport& DllSupport, REFCLSID clsid, unsigned &Major, unsigned &Minor);
  161. bool ParseTargetProfile(llvm::StringRef targetProfile, llvm::StringRef &outStage, unsigned &outMajor, unsigned &outMinor);
  162. class VersionSupportInfo {
  163. private:
  164. bool m_CompilerIsDebugBuild;
  165. public:
  166. bool m_InternalValidator;
  167. unsigned m_DxilMajor, m_DxilMinor;
  168. unsigned m_ValMajor, m_ValMinor;
  169. VersionSupportInfo();
  170. // Initialize version info structure. TODO: add device shader model support
  171. void Initialize(dxc::DxcDllSupport &dllSupport);
  172. // Return true if IR sensitive test should be skipped, and log comment
  173. bool SkipIRSensitiveTest();
  174. // Return true if test requiring DXIL of given version should be skipped, and log comment
  175. bool SkipDxilVersion(unsigned major, unsigned minor);
  176. // Return true if out-of-memory test should be skipped, and log comment
  177. bool SkipOutOfMemoryTest();
  178. };