From 872752cd51cdf11c17f7d61226331a6e69262ee9 Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 22 Sep 2025 14:21:36 +0100 Subject: [PATCH] Add version check for -select-validator which was annoyingly removed --- renderdoc/core/core.cpp | 83 ++--------------- renderdoc/driver/d3d12/d3d12_shader_cache.cpp | 14 ++- renderdoc/os/win32/win32_specific.h | 11 +++ renderdoc/os/win32/win32_stringio.cpp | 91 +++++++++++++++++++ util/test/demos/d3d12/d3d12_test.cpp | 9 +- 5 files changed, 132 insertions(+), 76 deletions(-) diff --git a/renderdoc/core/core.cpp b/renderdoc/core/core.cpp index c010bea88..dbaa95a0b 100644 --- a/renderdoc/core/core.cpp +++ b/renderdoc/core/core.cpp @@ -805,84 +805,21 @@ void RenderDoc::InitialiseReplay(GlobalEnvironment env, const rdcarray & #if ENABLED(RDOC_WIN32) { - using PFN_GetFileVersionInfoSizeW = decltype(&GetFileVersionInfoSizeW); - using PFN_GetFileVersionInfoW = decltype(&GetFileVersionInfoW); - using PFN_VerQueryValueA = decltype(&VerQueryValueA); + // only print unique versions to avoid the case of loading multiple driver files and + // printing redundantly. + rdcarray versions; - PFN_GetFileVersionInfoSizeW getSize = NULL; - PFN_GetFileVersionInfoW getData = NULL; - PFN_VerQueryValueA queryValue = NULL; - - HMODULE version = LoadLibraryA("version.dll"); - if(version) + for(rdcstr &path : driverFilePaths) { - getSize = (PFN_GetFileVersionInfoSizeW)GetProcAddress(version, "GetFileVersionInfoSizeW"); - getData = (PFN_GetFileVersionInfoW)GetProcAddress(version, "GetFileVersionInfoW"); - queryValue = (PFN_VerQueryValueA)GetProcAddress(version, "VerQueryValueA"); + OSUtility::DLLFileVersion ret = OSUtility::GetDLLVersion(path); - if(getSize && getData && queryValue) + if(!versions.contains(ret)) { - // only print unique versions to avoid the case of loading multiple driver files and - // printing redundantly. - rdcarray versions; - - for(rdcstr &path : driverFilePaths) - { - rdcwstr wpath = StringFormat::UTF82Wide(path); - DWORD bytesNeeded = getSize(wpath.c_str(), NULL); - - if(bytesNeeded > 0 && bytesNeeded < 1024 * 1024) - { - bytebuf blockData; - blockData.resize(bytesNeeded); - - VS_FIXEDFILEINFO *verInfo = NULL; - UINT size = 0; - if(getData(wpath.c_str(), 0, bytesNeeded, blockData.data()) && - queryValue(blockData.data(), "\\", (void **)&verInfo, &size)) - { - if(size > 0 && verInfo && verInfo->dwSignature == 0xFEEF04BD) - { - uint64_t ver = - uint64_t(verInfo->dwFileVersionMS) << 32 | verInfo->dwFileVersionLS; - - if(!versions.contains(ver)) - { - versions.push_back(ver); - RDCLOG("Driver: '%s' %u.%u.%u.%u %s", path.c_str(), - verInfo->dwFileVersionMS >> 16, verInfo->dwFileVersionMS & 0xffff, - verInfo->dwFileVersionLS >> 16, verInfo->dwFileVersionLS & 0xffff, - StringFormat::sntimef(FileIO::GetModifiedTimestamp(path), "%Y-%m-%d") - .c_str()); - } - } - else - { - RDCWARN("Version data for '%s' invalid: %u %p %u", path.c_str(), size, verInfo, - verInfo ? verInfo->dwSignature : 0); - } - } - else - { - RDCWARN("Couldn't get version data for '%s'", path.c_str()); - } - } - else - { - RDCWARN("Bytes needed for '%s': %u", path.c_str(), bytesNeeded); - } - } + versions.push_back(ret); + RDCLOG("Driver: '%s' %u.%u.%u.%u %s", path.c_str(), ret.major, ret.minor, ret.build, + ret.revision, + StringFormat::sntimef(FileIO::GetModifiedTimestamp(path), "%Y-%m-%d").c_str()); } - else - { - RDCWARN("Couldn't get version API"); - } - - FreeLibrary(version); - } - else - { - RDCWARN("Couldn't load version.dll"); } } #endif diff --git a/renderdoc/driver/d3d12/d3d12_shader_cache.cpp b/renderdoc/driver/d3d12/d3d12_shader_cache.cpp index 81694b233..927e46bbe 100644 --- a/renderdoc/driver/d3d12/d3d12_shader_cache.cpp +++ b/renderdoc/driver/d3d12/d3d12_shader_cache.cpp @@ -520,7 +520,19 @@ rdcstr D3D12ShaderCache::GetShaderBlob(const char *source, const char *entry, if(flag.name == "@compile_option") argsData.push_back(StringFormat::UTF82Wide(flag.value)); } - argsData.push_back(L"-select-validator internal"); + + OSUtility::DLLFileVersion version = OSUtility::GetDLLVersion(dxc); + + // this parameter is _necessary_ on older versions of dxc to not use dxil.dll but _invalid_ on + // old versions, and then again invalid but not necessary for newer versions + // + // dxc versions named 10.x.x.x by windows SDKs are considered old, pre 1.7 at least + if(version.major != 10 && version.major == 1 && version.minor == 8 && version.build >= 2403) + { + if(version.build < 2505) + argsData.push_back(L"-select-validator internal"); + } + rdcarray arguments; for(const rdcwstr &arg : argsData) arguments.push_back(arg.c_str()); diff --git a/renderdoc/os/win32/win32_specific.h b/renderdoc/os/win32/win32_specific.h index 036f5111f..adbc0b162 100644 --- a/renderdoc/os/win32/win32_specific.h +++ b/renderdoc/os/win32/win32_specific.h @@ -53,6 +53,17 @@ inline bool DebuggerPresent() { return ::IsDebuggerPresent() == TRUE; } +struct DLLFileVersion +{ + uint16_t major, minor, build, revision; + + bool operator==(const DLLFileVersion &o) const + { + return major == o.major && minor == o.minor && build == o.build && revision == o.revision; + } +}; +DLLFileVersion GetDLLVersion(const rdcstr &path); +DLLFileVersion GetDLLVersion(HMODULE mod); }; namespace Threading diff --git a/renderdoc/os/win32/win32_stringio.cpp b/renderdoc/os/win32/win32_stringio.cpp index e08564e75..cd3791d59 100644 --- a/renderdoc/os/win32/win32_stringio.cpp +++ b/renderdoc/os/win32/win32_stringio.cpp @@ -1000,4 +1000,95 @@ uint64_t GetMachineIdent() return ret; } + +bool loaded = false; +HMODULE version = NULL; + +using PFN_GetFileVersionInfoSizeW = decltype(&GetFileVersionInfoSizeW); +using PFN_GetFileVersionInfoW = decltype(&GetFileVersionInfoW); +using PFN_VerQueryValueA = decltype(&VerQueryValueA); + +PFN_GetFileVersionInfoSizeW getSize = NULL; +PFN_GetFileVersionInfoW getData = NULL; +PFN_VerQueryValueA queryValue = NULL; + +void Load() +{ + if(loaded) + return; + loaded = true; + + version = LoadLibraryA("version.dll"); + if(version) + { + getSize = (PFN_GetFileVersionInfoSizeW)GetProcAddress(version, "GetFileVersionInfoSizeW"); + getData = (PFN_GetFileVersionInfoW)GetProcAddress(version, "GetFileVersionInfoW"); + queryValue = (PFN_VerQueryValueA)GetProcAddress(version, "VerQueryValueA"); + + if(!getSize || !getData || !queryValue) + { + RDCWARN("Couldn't get version API"); + } + } + else + { + RDCWARN("Couldn't load version.dll"); + } +} + +DLLFileVersion GetDLLVersion(const rdcstr &path) +{ + DLLFileVersion ret = {}; + + Load(); + + if(!version) + return {}; + + rdcwstr wpath = StringFormat::UTF82Wide(path); + DWORD bytesNeeded = getSize(wpath.c_str(), NULL); + + if(bytesNeeded > 0 && bytesNeeded < 1024 * 1024) + { + bytebuf blockData; + blockData.resize(bytesNeeded); + + VS_FIXEDFILEINFO *verInfo = NULL; + UINT size = 0; + if(getData(wpath.c_str(), 0, bytesNeeded, blockData.data()) && + queryValue(blockData.data(), "\\", (void **)&verInfo, &size)) + { + if(size > 0 && verInfo && verInfo->dwSignature == 0xFEEF04BD) + { + ret = {verInfo->dwFileVersionMS >> 16, verInfo->dwFileVersionMS & 0xffff, + verInfo->dwFileVersionLS >> 16, verInfo->dwFileVersionLS & 0xffff}; + } + else + { + RDCWARN("Version data for '%s' invalid: %u %p %u", path.c_str(), size, verInfo, + verInfo ? verInfo->dwSignature : 0); + } + } + else + { + RDCWARN("Couldn't get version data for '%s'", path.c_str()); + } + } + else + { + RDCWARN("Bytes needed for '%s': %u", path.c_str(), bytesNeeded); + } + + return ret; +} + +DLLFileVersion GetDLLVersion(HMODULE mod) +{ + wchar_t curFile[512] = {0}; + GetModuleFileNameW(mod, curFile, 511); + + rdcstr path = StringFormat::Wide2UTF8(curFile); + + return GetDLLVersion(path); +} }; diff --git a/util/test/demos/d3d12/d3d12_test.cpp b/util/test/demos/d3d12/d3d12_test.cpp index de6548c25..42fc5ec50 100644 --- a/util/test/demos/d3d12/d3d12_test.cpp +++ b/util/test/demos/d3d12/d3d12_test.cpp @@ -1481,8 +1481,13 @@ ID3DBlobPtr D3D12GraphicsTest::Compile(std::string src, std::string entry, std:: // // as extra fun, some versions are 1.7.x or 1.8.x and some are 10.0.y from SDKs. These versions // are not comparable! ha ha ha. - if(version.major != 10 && (version.major > 1 || version.minor > 8 || version.build >= 2403)) - argStorage.push_back(L"-select-validator internal"); + if(version.major != 10 && version.major == 1 && version.minor == 8 && version.build >= 2403) + { + // for extremely stupid reasons, this option was _removed_ in newer versions which breaks + // compilation for absolutely no discernable benefit + if(version.build < 2505) + argStorage.push_back(L"-select-validator internal"); + } // Must be the final option argStorage.push_back(L"-Qembed_debug");