Skip to content

Commit

Permalink
Do extremely stupid version checking to workaround dxc nonsense in tests
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
baldurk committed Jan 13, 2025
1 parent cd84566 commit f3f0617
Showing 1 changed file with 71 additions and 44 deletions.
115 changes: 71 additions & 44 deletions util/test/demos/d3d12/d3d12_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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());

Expand Down Expand Up @@ -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");

Expand Down

0 comments on commit f3f0617

Please sign in to comment.