--- /dev/null
+/*\r
+ * Copyright © 2021 Intel Corporation\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a\r
+ * copy of this software and associated documentation files (the "Software"),\r
+ * to deal in the Software without restriction, including without limitation\r
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r
+ * and/or sell copies of the Software, and to permit persons to whom the\r
+ * Software is furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice (including the next\r
+ * paragraph) shall be included in all copies or substantial portions of the\r
+ * Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\r
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\r
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\r
+ * DEALINGS IN THE SOFTWARE.\r
+ */\r
+\r
+#include "dxil_validation.h"\r
+\r
+#if DETECT_OS_WINDOWS\r
+\r
+#include <cstdio>\r
+#include <windows.h>\r
+#include <wrl/client.h>\r
+\r
+#include "dxcapi.h"\r
+\r
+using Microsoft::WRL::ComPtr;\r
+\r
+class DxilBlob : public IDxcBlob {\r
+ public:\r
+ DxilBlob(dxil_spirv_object *data) : m_data(data) {}\r
+\r
+ LPVOID STDMETHODCALLTYPE\r
+ GetBufferPointer() override\r
+ {\r
+ return m_data->binary.buffer;\r
+ }\r
+\r
+ SIZE_T STDMETHODCALLTYPE\r
+ GetBufferSize() override\r
+ {\r
+ return m_data->binary.size;\r
+ }\r
+\r
+ HRESULT STDMETHODCALLTYPE\r
+ QueryInterface(REFIID, void **) override\r
+ {\r
+ return E_NOINTERFACE;\r
+ }\r
+\r
+ ULONG STDMETHODCALLTYPE\r
+ AddRef() override\r
+ {\r
+ return 1;\r
+ }\r
+\r
+ ULONG STDMETHODCALLTYPE\r
+ Release() override\r
+ {\r
+ return 0;\r
+ }\r
+\r
+ dxil_spirv_object *m_data;\r
+};\r
+\r
+bool\r
+validate_dxil(dxil_spirv_object *dxil_obj)\r
+{\r
+ HMODULE dxil_dll = LoadLibraryA("dxil.dll");\r
+ if (!dxil_dll) {\r
+ fprintf(stderr, "Unable to load dxil.dll\n");\r
+ return false;\r
+ }\r
+ DxcCreateInstanceProc dxc_create_instance =\r
+ reinterpret_cast<DxcCreateInstanceProc>(\r
+ GetProcAddress(dxil_dll, "DxcCreateInstance"));\r
+\r
+ bool res = false;\r
+ DxilBlob blob(dxil_obj);\r
+ // Creating a block so that ComPtrs free before we call FreeLibrary\r
+ {\r
+ ComPtr<IDxcValidator> validator;\r
+ if (FAILED(dxc_create_instance(CLSID_DxcValidator,\r
+ IID_PPV_ARGS(&validator)))) {\r
+ fprintf(stderr, "Failed to create DxcValidator instance \n");\r
+ FreeLibrary(dxil_dll);\r
+ return false;\r
+ }\r
+\r
+ ComPtr<IDxcOperationResult> result;\r
+ validator->Validate(&blob, DxcValidatorFlags_InPlaceEdit, &result);\r
+ HRESULT status;\r
+ result->GetStatus(&status);\r
+ if (FAILED(status)) {\r
+ ComPtr<IDxcBlobEncoding> error;\r
+ result->GetErrorBuffer(&error);\r
+ BOOL known = false;\r
+ uint32_t cp = 0;\r
+ error->GetEncoding(&known, &cp);\r
+ fprintf(stderr, "DXIL: ");\r
+ if (cp == CP_UTF8 || cp == CP_ACP) {\r
+ fprintf(stderr, "%s\n",\r
+ static_cast<char *>(error->GetBufferPointer()));\r
+ } else {\r
+ fwprintf(stderr, L"%ls\n",\r
+ static_cast<wchar_t *>(error->GetBufferPointer()));\r
+ }\r
+ } else {\r
+ res = true;\r
+ }\r
+ }\r
+\r
+ FreeLibrary(dxil_dll);\r
+ return res;\r
+}\r
+\r
+#else\r
+\r
+bool\r
+validate_dxil(dxil_spirv_object *dxil_obj)\r
+{\r
+ fprintf(stderr, "DXIL validation only available in Windows.\n");\r
+ return false;\r
+}\r
+\r
+#endif\r
--- /dev/null
+/*\r
+ * Copyright © 2021 Intel Corporation\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a\r
+ * copy of this software and associated documentation files (the "Software"),\r
+ * to deal in the Software without restriction, including without limitation\r
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r
+ * and/or sell copies of the Software, and to permit persons to whom the\r
+ * Software is furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice (including the next\r
+ * paragraph) shall be included in all copies or substantial portions of the\r
+ * Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\r
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\r
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\r
+ * DEALINGS IN THE SOFTWARE.\r
+ */\r
+\r
+#ifndef DXIL_VALIDATION_H\r
+#define DXIL_VALIDATION_H\r
+\r
+#include "spirv_to_dxil.h"\r
+#include "util/detect_os.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+bool\r
+validate_dxil(struct dxil_spirv_object *dxil_obj);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* DXIL_VALIDATION_H */\r
*/
#include "nir_to_dxil.h"
+#include "dxil_validation.h"
#include "spirv/nir_spirv.h"
#include "spirv_to_dxil.h"
char *entry_point = "main";
char *output_file = "";
int ch;
-
+ bool validate = false;
+
static struct option long_options[] = {
{"stage", required_argument, 0, 's'},
{"entry", required_argument, 0, 'e'},
{"output", required_argument, 0, 'o'},
+ {"validate", no_argument, 0, 'v'},
{0, 0, 0, 0}};
- while ((ch = getopt_long(argc, argv, "s:e:o:", long_options, NULL)) !=
+
+ while ((ch = getopt_long(argc, argv, "s:e:o:v", long_options, NULL)) !=
-1) {
- switch (ch) {
+ switch(ch)
+ {
case 's':
shader_stage = stage_to_enum(optarg);
if (shader_stage == MESA_SHADER_NONE) {
case 'o':
output_file = optarg;
break;
+ case 'v':
+ validate = true;
+ break;
default:
fprintf(stderr, "Unrecognized option.\n");
return 1;
if (spirv_to_dxil((uint32_t *)file_contents, word_count, NULL, 0,
(dxil_spirv_shader_stage)shader_stage, entry_point,
&conf, &obj)) {
+
+ if (validate && !validate_dxil(&obj)) {
+ fprintf(stderr, "Failed to validate DXIL\n");
+ spirv_to_dxil_free(&obj);
+ free(file_contents);
+ return 1;
+ }
+
FILE *file = fopen(output_file, "wb");
if (!file) {
fprintf(stderr, "Failed to open %s, %s\n", output_file,