microsoft/compiler: Blacklist DXIL validator 1.6 from 20348 SDK
authorJesse Natalie <jenatali@microsoft.com>
Mon, 18 Jul 2022 17:37:03 +0000 (10:37 -0700)
committerMarge Bot <emma+marge@anholt.net>
Sat, 23 Jul 2022 14:48:17 +0000 (14:48 +0000)
This version claims to support validator version 1.6, but doesn't
actually have the 1.6 changes (PSV v2, PSV resource v1, barycentrics).

Reviewed-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17603>

src/microsoft/compiler/dxil_validator.cpp
src/microsoft/compiler/meson.build

index bb01af5..85a0621 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "util/ralloc.h"
 #include "util/u_debug.h"
+#include "util/compiler.h"
 
 #include "dxcapi.h"
 
@@ -104,6 +105,63 @@ get_validator_version(IDxcValidator *val)
    return NO_DXIL_VALIDATION;
 }
 
+static uint64_t
+get_dll_version(HMODULE mod)
+{
+   WCHAR filename[MAX_PATH];
+   DWORD filename_length = GetModuleFileNameW(mod, filename, ARRAY_SIZE(filename));
+
+   if (filename_length == 0 || filename_length == ARRAY_SIZE(filename))
+      return 0;
+
+   DWORD version_handle = 0;
+   DWORD version_size = GetFileVersionInfoSizeW(filename, &version_handle);
+   if (version_size == 0)
+      return 0;
+
+   void *version_data = malloc(version_size);
+   if (!version_data)
+      return 0;
+
+   if (!GetFileVersionInfoW(filename, version_handle, version_size, version_data)) {
+      free(version_data);
+      return 0;
+   }
+
+   UINT value_size = 0;
+   VS_FIXEDFILEINFO *version_info = nullptr;
+   if (!VerQueryValueW(version_data, L"\\", reinterpret_cast<void **>(&version_info), &value_size) ||
+       !value_size ||
+       version_info->dwSignature != VS_FFI_SIGNATURE) {
+      free(version_data);
+      return 0;
+   }
+
+   uint64_t ret =
+      ((uint64_t)version_info->dwFileVersionMS << 32ull) |
+      (uint64_t)version_info->dwFileVersionLS;
+   free(version_data);
+   return ret;
+}
+
+static enum dxil_validator_version
+get_filtered_validator_version(HMODULE mod, enum dxil_validator_version raw)
+{
+   switch (raw) {
+   case DXIL_VALIDATOR_1_6: {
+      uint64_t dxil_version = get_dll_version(mod);
+      static constexpr uint64_t known_bad_version =
+         // 101.5.2005.60
+         (101ull << 48ull) | (5ull << 32ull) | (2005ull << 16ull) | 60ull;
+      if (dxil_version == known_bad_version)
+         return DXIL_VALIDATOR_1_5;
+      FALLTHROUGH;
+   }
+   default:
+      return raw;
+   }
+}
+
 struct dxil_validator *
 dxil_create_validator(const void *ctx)
 {
@@ -127,7 +185,9 @@ dxil_create_validator(const void *ctx)
    if (!val->dxc_validator)
       goto fail;
 
-   val->version = get_validator_version(val->dxc_validator);
+   val->version = get_filtered_validator_version(
+      val->dxil_mod,
+      get_validator_version(val->dxc_validator));
 
    /* Try to load dxcompiler.dll. This is just used for diagnostics, and
     * will fail on most end-users install. So we do not error out if this
index 5f4e343..391ac83 100644 (file)
@@ -61,7 +61,7 @@ libdxil_compiler = static_library(
 
 idep_libdxil_compiler = declare_dependency(
   link_with : libdxil_compiler,
-  dependencies : [idep_mesautil],
+  dependencies : [idep_mesautil, dep_version],
   include_directories : include_directories('.')
 )