Mesa (main): d3d12: use dxil_validator

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Apr 7 00:14:47 UTC 2022


Module: Mesa
Branch: main
Commit: 1e570962ef595444d77c7ba28b5a4f5edc504f32
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=1e570962ef595444d77c7ba28b5a4f5edc504f32

Author: Erik Faye-Lund <erik.faye-lund at collabora.com>
Date:   Tue Apr  5 11:11:54 2022 +0200

d3d12: use dxil_validator

Now that we have a shiny, new dxil validator interface, let's start
using it in the D3D12 gallium driver.

Reviewed-by: Boris Brezillon <boris.brezillon at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15751>

---

 src/gallium/drivers/d3d12/d3d12_compiler.cpp | 256 +++------------------------
 src/gallium/drivers/d3d12/d3d12_compiler.h   |   4 -
 src/gallium/drivers/d3d12/d3d12_context.cpp  |  17 +-
 src/gallium/drivers/d3d12/d3d12_context.h    |   9 +-
 src/gallium/drivers/d3d12/d3d12_screen.cpp   |   9 +-
 5 files changed, 49 insertions(+), 246 deletions(-)

diff --git a/src/gallium/drivers/d3d12/d3d12_compiler.cpp b/src/gallium/drivers/d3d12/d3d12_compiler.cpp
index da42eb14954..7f09dd76c3d 100644
--- a/src/gallium/drivers/d3d12/d3d12_compiler.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_compiler.cpp
@@ -46,57 +46,14 @@
 #include <directx/d3d12.h>
 #include <dxguids/dxguids.h>
 
-#include <dxcapi.h>
-#include <wrl/client.h>
-
 extern "C" {
 #include "tgsi/tgsi_parse.h"
 #include "tgsi/tgsi_point_sprite.h"
 }
 
-using Microsoft::WRL::ComPtr;
-
-struct d3d12_validation_tools
-{
-   d3d12_validation_tools();
-
-   bool validate_and_sign(struct blob *dxil);
-
-   void disassemble(struct blob *dxil);
-
-   void load_dxil_dll();
-
-   struct HModule {
-      HModule();
-      ~HModule();
-
-      bool load(LPCSTR file_name);
-      operator util_dl_library *() const;
-   private:
-      util_dl_library *module;
-   };
-
-   HModule dxil_module;
-   HModule dxc_compiler_module;
-   ComPtr<IDxcCompiler> compiler;
-   ComPtr<IDxcValidator> validator;
-   ComPtr<IDxcLibrary> library;
-};
-
-struct d3d12_validation_tools *d3d12_validator_create()
-{
-   d3d12_validation_tools *tools = new d3d12_validation_tools();
-   if (tools->validator)
-      return tools;
-   delete tools;
-   return nullptr;
-}
-
-void d3d12_validator_destroy(struct d3d12_validation_tools *validator)
-{
-   delete validator;
-}
-
+#ifdef _WIN32
+#include "dxil_validator.h"
+#endif
 
 const void *
 d3d12_get_compiler_options(struct pipe_screen *screen,
@@ -227,13 +184,34 @@ compile_nir(struct d3d12_context *ctx, struct d3d12_shader_selector *sel,
          shader->cb_bindings[shader->num_cb_bindings++].binding = i;
       }
    }
-   if (ctx->validation_tools) {
-      ctx->validation_tools->validate_and_sign(&tmp);
+
+#ifdef _WIN32
+   if (ctx->dxil_validator) {
+      if (!(d3d12_debug & D3D12_DEBUG_EXPERIMENTAL)) {
+         char *err;
+         if (!dxil_validate_module(ctx->dxil_validator, tmp.data,
+                                   tmp.size, &err) && err) {
+            debug_printf(
+               "== VALIDATION ERROR =============================================\n"
+               "%s\n"
+               "== END ==========================================================\n",
+               err);
+            ralloc_free(err);
+         }
+      }
 
       if (d3d12_debug & D3D12_DEBUG_DISASS) {
-         ctx->validation_tools->disassemble(&tmp);
+         char *str = dxil_disasm_module(ctx->dxil_validator, tmp.data,
+                                        tmp.size);
+         fprintf(stderr,
+                 "== BEGIN SHADER ============================================\n"
+                 "%s\n"
+                 "== END SHADER ==============================================\n",
+               str);
+         ralloc_free(str);
       }
    }
+#endif
 
    blob_finish_get_buffer(&tmp, &shader->bytecode, &shader->bytecode_length);
 
@@ -1467,183 +1445,3 @@ d3d12_shader_free(struct d3d12_shader_selector *sel)
    ralloc_free(sel->initial);
    ralloc_free(sel);
 }
-
-#ifdef _WIN32
-// Used to get path to self
-extern "C" extern IMAGE_DOS_HEADER __ImageBase;
-#endif
-
-void d3d12_validation_tools::load_dxil_dll()
-{
-   if (!dxil_module.load(UTIL_DL_PREFIX "dxil" UTIL_DL_EXT)) {
-#ifdef _WIN32
-      char selfPath[MAX_PATH] = "";
-      uint32_t pathSize = GetModuleFileNameA((HINSTANCE)&__ImageBase, selfPath, sizeof(selfPath));
-      if (pathSize == 0 || pathSize == sizeof(selfPath)) {
-         debug_printf("D3D12: Unable to get path to self");
-         return;
-      }
-
-      auto lastSlash = strrchr(selfPath, '\\');
-      if (!lastSlash) {
-         debug_printf("D3D12: Unable to get path to self");
-         return;
-      }
-
-      *(lastSlash + 1) = '\0';
-      if (strcat_s(selfPath, "dxil.dll") != 0) {
-         debug_printf("D3D12: Unable to get path to dxil.dll next to self");
-         return;
-      }
-
-      dxil_module.load(selfPath);
-#endif
-   }
-}
-
-d3d12_validation_tools::d3d12_validation_tools()
-{
-   load_dxil_dll();
-   DxcCreateInstanceProc dxil_create_func = (DxcCreateInstanceProc)util_dl_get_proc_address(dxil_module, "DxcCreateInstance");
-
-   if (dxil_create_func) {
-      HRESULT hr = dxil_create_func(CLSID_DxcValidator,  IID_PPV_ARGS(&validator));
-      if (FAILED(hr)) {
-         debug_printf("D3D12: Unable to create validator\n");
-      }
-   }
-#ifdef _WIN32
-   else if (!(d3d12_debug & D3D12_DEBUG_EXPERIMENTAL)) {
-      debug_printf("D3D12: Unable to load DXIL.dll\n");
-   }
-#endif
-
-   DxcCreateInstanceProc compiler_create_func  = nullptr;
-   if(dxc_compiler_module.load("dxcompiler.dll"))
-      compiler_create_func = (DxcCreateInstanceProc)util_dl_get_proc_address(dxc_compiler_module, "DxcCreateInstance");
-
-   if (compiler_create_func) {
-      HRESULT hr = compiler_create_func(CLSID_DxcLibrary, IID_PPV_ARGS(&library));
-      if (FAILED(hr)) {
-         debug_printf("D3D12: Unable to create library instance: %x\n", hr);
-      }
-
-      if (d3d12_debug & D3D12_DEBUG_DISASS) {
-         hr = compiler_create_func(CLSID_DxcCompiler, IID_PPV_ARGS(&compiler));
-         if (FAILED(hr)) {
-            debug_printf("D3D12: Unable to create compiler instance\n");
-         }
-      }
-   } else if (d3d12_debug & D3D12_DEBUG_DISASS) {
-      debug_printf("D3D12: Disassembly requested but compiler couldn't be loaded\n");
-   }
-}
-
-d3d12_validation_tools::HModule::HModule():
-   module(0)
-{
-}
-
-d3d12_validation_tools::HModule::~HModule()
-{
-   if (module)
-      util_dl_close(module);
-}
-
-inline
-d3d12_validation_tools::HModule::operator util_dl_library * () const
-{
-   return module;
-}
-
-bool
-d3d12_validation_tools::HModule::load(LPCSTR file_name)
-{
-   module = util_dl_open(file_name);
-   return module != nullptr;
-}
-
-
-class ShaderBlob : public IDxcBlob {
-public:
-   ShaderBlob(blob* data) : m_data(data) {}
-
-   LPVOID STDMETHODCALLTYPE GetBufferPointer(void) override { return m_data->data; }
-
-   SIZE_T STDMETHODCALLTYPE GetBufferSize() override { return m_data->size; }
-
-   HRESULT STDMETHODCALLTYPE QueryInterface(REFIID, void**) override { return E_NOINTERFACE; }
-
-   ULONG STDMETHODCALLTYPE AddRef() override { return 1; }
-
-   ULONG STDMETHODCALLTYPE Release() override { return 0; }
-
-   blob* m_data;
-};
-
-bool d3d12_validation_tools::validate_and_sign(struct blob *dxil)
-{
-   ShaderBlob source(dxil);
-
-   ComPtr<IDxcOperationResult> result;
-
-   validator->Validate(&source, DxcValidatorFlags_InPlaceEdit, &result);
-   HRESULT validationStatus;
-   result->GetStatus(&validationStatus);
-   if (FAILED(validationStatus)) {
-      if (!library) {
-         debug_printf("D3D12: validation failed, but lacking "
-                      "IDxcLibrary for proper diagnostics.\n");
-         return false;
-      }
-
-      ComPtr<IDxcBlobEncoding> printBlob, printBlobUtf8;
-      result->GetErrorBuffer(&printBlob);
-      library->GetBlobAsUtf8(printBlob.Get(), printBlobUtf8.GetAddressOf());
-
-      char *errorString;
-      if (printBlobUtf8) {
-         errorString = reinterpret_cast<char*>(printBlobUtf8->GetBufferPointer());
-
-         errorString[printBlobUtf8->GetBufferSize() - 1] = 0;
-         debug_printf("== VALIDATION ERROR =============================================\n%s\n"
-                     "== END ==========================================================\n",
-                     errorString);
-      }
-
-      return false;
-   }
-   return true;
-
-}
-
-void d3d12_validation_tools::disassemble(struct blob *dxil)
-{
-   if (!compiler) {
-      fprintf(stderr, "D3D12: No Disassembler\n");
-      return;
-   }
-   ShaderBlob source(dxil);
-   IDxcBlobEncoding* pDisassembly = nullptr;
-
-   if (FAILED(compiler->Disassemble(&source, &pDisassembly))) {
-      fprintf(stderr, "D3D12: Disassembler failed\n");
-      return;
-   }
-
-   ComPtr<IDxcBlobEncoding> dissassably(pDisassembly);
-   ComPtr<IDxcBlobEncoding> blobUtf8;
-   library->GetBlobAsUtf8(pDisassembly, blobUtf8.GetAddressOf());
-   if (!blobUtf8) {
-      fprintf(stderr, "D3D12: Unable to get utf8 encoding\n");
-      return;
-   }
-
-   char *disassembly = reinterpret_cast<char*>(blobUtf8->GetBufferPointer());
-   disassembly[blobUtf8->GetBufferSize() - 1] = 0;
-
-   fprintf(stderr, "== BEGIN SHADER ============================================\n"
-           "%s\n"
-           "== END SHADER ==============================================\n",
-           disassembly);
-}
diff --git a/src/gallium/drivers/d3d12/d3d12_compiler.h b/src/gallium/drivers/d3d12/d3d12_compiler.h
index de16ff23711..9560b612256 100644
--- a/src/gallium/drivers/d3d12/d3d12_compiler.h
+++ b/src/gallium/drivers/d3d12/d3d12_compiler.h
@@ -59,10 +59,6 @@ enum d3d12_state_var {
 
 #define D3D12_MAX_POINT_SIZE 255.0f
 
-struct d3d12_validation_tools *d3d12_validator_create();
-
-void d3d12_validator_destroy(struct d3d12_validation_tools *validator);
-
 const void *
 d3d12_get_compiler_options(struct pipe_screen *screen,
                            enum pipe_shader_ir ir,
diff --git a/src/gallium/drivers/d3d12/d3d12_context.cpp b/src/gallium/drivers/d3d12/d3d12_context.cpp
index 1fe2195d296..0e86b29c5fe 100644
--- a/src/gallium/drivers/d3d12/d3d12_context.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_context.cpp
@@ -57,12 +57,19 @@ extern "C" {
 
 #include <string.h>
 
+#ifdef _WIN32
+#include "dxil_validator.h"
+#endif
+
 static void
 d3d12_context_destroy(struct pipe_context *pctx)
 {
    struct d3d12_context *ctx = d3d12_context(pctx);
-   if (ctx->validation_tools)
-      d3d12_validator_destroy(ctx->validation_tools);
+
+#ifdef _WIN32
+   if (ctx->dxil_validator)
+      dxil_destroy_validator(ctx->dxil_validator);
+#endif
 
    if (ctx->timestamp_query)
       pctx->destroy_query(pctx, ctx->timestamp_query);
@@ -2511,7 +2518,11 @@ d3d12_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
    }
    d3d12_init_null_sampler(ctx);
 
-   ctx->validation_tools = d3d12_validator_create();
+#ifdef _WIN32
+   if (!(d3d12_debug & D3D12_DEBUG_EXPERIMENTAL) ||
+       (d3d12_debug & D3D12_DEBUG_DISASS))
+      ctx->dxil_validator = dxil_create_validator(NULL);
+#endif
 
    ctx->blitter = util_blitter_create(&ctx->base);
    if (!ctx->blitter)
diff --git a/src/gallium/drivers/d3d12/d3d12_context.h b/src/gallium/drivers/d3d12/d3d12_context.h
index ec8a8240d48..46d06f70c26 100644
--- a/src/gallium/drivers/d3d12/d3d12_context.h
+++ b/src/gallium/drivers/d3d12/d3d12_context.h
@@ -151,7 +151,10 @@ struct d3d12_shader_state {
 
 struct blitter_context;
 struct primconvert_context;
-struct d3d12_validation_tools;
+
+#ifdef _WIN32
+struct dxil_validator;
+#endif
 
 #ifdef __cplusplus
 class ResourceStateManager;
@@ -246,7 +249,9 @@ struct d3d12_context {
    struct d3d12_descriptor_handle null_sampler;
 
    PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE D3D12SerializeVersionedRootSignature;
-   struct d3d12_validation_tools *validation_tools;
+#ifdef _WIN32
+   struct dxil_validator *dxil_validator;
+#endif
 
    struct d3d12_resource *current_predication;
    bool predication_condition;
diff --git a/src/gallium/drivers/d3d12/d3d12_screen.cpp b/src/gallium/drivers/d3d12/d3d12_screen.cpp
index 21d64ba6154..ed7c0ba028f 100644
--- a/src/gallium/drivers/d3d12/d3d12_screen.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_screen.cpp
@@ -813,14 +813,7 @@ create_device(IUnknown *adapter)
    }
 
 #ifdef _WIN32
-   if (!(d3d12_debug & D3D12_DEBUG_EXPERIMENTAL)) {
-      struct d3d12_validation_tools *validation_tools = d3d12_validator_create();
-      if (!validation_tools) {
-         debug_printf("D3D12: failed to initialize validator with experimental shader models disabled\n");
-         return nullptr;
-      }
-      d3d12_validator_destroy(validation_tools);
-   } else
+   if (d3d12_debug & D3D12_DEBUG_EXPERIMENTAL)
 #endif
    {
       D3D12EnableExperimentalFeatures = (PFN_D3D12ENABLEEXPERIMENTALFEATURES)util_dl_get_proc_address(d3d12_mod, "D3D12EnableExperimentalFeatures");



More information about the mesa-commit mailing list