From f3f0617b3778fb5b468b43901dc23de19d1b7e27 Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 13 Jan 2025 11:02:22 +0000 Subject: [PATCH] Do extremely stupid version checking to workaround dxc nonsense in tests * On a new enough dxc we can pass a flag to tell it to ignore dxil.dll * This allows the tests to run on the test machine with an old windows SDK (where the demos project copies the dxcompiler.dll + dxil.dll from) but still pull in a new dxcompiler.dll without having it break on an old dxil.dll --- util/test/demos/d3d12/d3d12_test.cpp | 115 +++++++++++++++++---------- 1 file changed, 71 insertions(+), 44 deletions(-) diff --git a/util/test/demos/d3d12/d3d12_test.cpp b/util/test/demos/d3d12/d3d12_test.cpp index ee1f14d48c..0a01aee823 100644 --- a/util/test/demos/d3d12/d3d12_test.cpp +++ b/util/test/demos/d3d12/d3d12_test.cpp @@ -66,6 +66,59 @@ struct DevicePointers ID3D12DeviceConfigurationPtr config; }; +struct DLLFileVersion +{ + uint16_t major, minor, build, revision; +}; + +DLLFileVersion GetDLLFileVersion(HMODULE mod) +{ + DLLFileVersion ret = {}; + + using PFN_VerQueryValueA = decltype(&VerQueryValueA); + + PFN_VerQueryValueA queryValue = NULL; + + HMODULE version = LoadLibraryA("version.dll"); + if(version) + { + queryValue = (PFN_VerQueryValueA)GetProcAddress(version, "VerQueryValueA"); + + if(queryValue) + { + HRSRC verRes = FindResource(mod, MAKEINTRESOURCE(1), RT_VERSION); + if(verRes) + { + DWORD sz = SizeofResource(mod, verRes); + HGLOBAL data = LoadResource(mod, verRes); + + if(data && sz > 0) + { + void *buf = LockResource(data); + + byte *tmpBuf = new byte[sz]; + memcpy(tmpBuf, buf, sz); + + VS_FIXEDFILEINFO *verInfo = NULL; + UINT size = 0; + if(queryValue(data, "\\", (void **)&verInfo, &size)) + { + if(size > 0 && verInfo && verInfo->dwSignature == 0xFEEF04BD) + { + ret = {verInfo->dwFileVersionMS >> 16, verInfo->dwFileVersionMS & 0xffff, + verInfo->dwFileVersionLS >> 16, verInfo->dwFileVersionLS & 0xffff}; + } + } + + delete[] tmpBuf; + } + } + } + } + + return ret; +} + DevicePointers PrepareCreateDeviceFromDLL(const std::string &d3d12path, bool debug, bool gpuValidation) { DevicePointers ret; @@ -137,52 +190,15 @@ DevicePointers PrepareCreateDeviceFromDLL(const std::string &d3d12path, bool deb { DWORD *sdkVersion = (DWORD *)GetProcAddress(mod, "D3D12SDKVersion"); - std::string d3d12CoreVersion = fmt::format("1.{0}", *sdkVersion); - - { - using PFN_VerQueryValueA = decltype(&VerQueryValueA); + DLLFileVersion version = GetDLLFileVersion(mod); - PFN_VerQueryValueA queryValue = NULL; + std::string d3d12CoreVersion; - HMODULE version = LoadLibraryA("version.dll"); - if(version) - { - queryValue = (PFN_VerQueryValueA)GetProcAddress(version, "VerQueryValueA"); - - if(queryValue) - { - HRSRC verRes = FindResource(mod, MAKEINTRESOURCE(1), RT_VERSION); - if(verRes) - { - DWORD sz = SizeofResource(mod, verRes); - HGLOBAL data = LoadResource(mod, verRes); - - if(data && sz > 0) - { - void *buf = LockResource(data); - - byte *tmpBuf = new byte[sz]; - memcpy(tmpBuf, buf, sz); - - VS_FIXEDFILEINFO *verInfo = NULL; - UINT size = 0; - if(queryValue(data, "\\", (void **)&verInfo, &size)) - { - if(size > 0 && verInfo && verInfo->dwSignature == 0xFEEF04BD) - { - d3d12CoreVersion = fmt::format( - "{0}.{1}.{2}.{3}", verInfo->dwFileVersionMS >> 16, - verInfo->dwFileVersionMS & 0xffff, verInfo->dwFileVersionLS >> 16, - verInfo->dwFileVersionLS & 0xffff); - } - } - - delete[] tmpBuf; - } - } - } - } - } + if(version.major >= 1) + d3d12CoreVersion = fmt::format("{0}.{1}.{2}.{3}", version.major, version.minor, + version.build, version.revision); + else + d3d12CoreVersion = fmt::format("1.{0}", *sdkVersion); TEST_LOG("Using D3D12Core.dll from %s (version %s)", path.c_str(), d3d12CoreVersion.c_str()); @@ -1451,6 +1467,17 @@ ID3DBlobPtr D3D12GraphicsTest::Compile(std::string src, std::string entry, std:: if(enable16BitTypes) argStorage.push_back(L"-enable-16bit-types"); + DLLFileVersion version = GetDLLFileVersion(dxcompiler); + + // if the version is new enough we can tell it to not load dxil.dll. Have to do this absolutely + // ridiculous dll version dance because if we pass this option on a dxc too early it will fail + // to compile. + // + // 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"); + // Must be the final option argStorage.push_back(L"-Qembed_debug");