From b8328c9664ed3f11924be37a243464236812a3a2 Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Mon, 18 Jul 2022 10:37:03 -0700 Subject: [PATCH] microsoft/compiler: Blacklist DXIL validator 1.6 from 20348 SDK 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 Part-of: --- src/microsoft/compiler/dxil_validator.cpp | 62 ++++++++++++++++++++++- src/microsoft/compiler/meson.build | 2 +- 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/src/microsoft/compiler/dxil_validator.cpp b/src/microsoft/compiler/dxil_validator.cpp index bb01af57fd7..85a0621dcc8 100644 --- a/src/microsoft/compiler/dxil_validator.cpp +++ b/src/microsoft/compiler/dxil_validator.cpp @@ -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(&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 diff --git a/src/microsoft/compiler/meson.build b/src/microsoft/compiler/meson.build index 5f4e3432d4c..391ac83e936 100644 --- a/src/microsoft/compiler/meson.build +++ b/src/microsoft/compiler/meson.build @@ -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('.') )