Fix D3D12 debug crash due to validation layers SDK bug (#3222)
* Fix D3D12 debug crash due to validation layers SDK bug * Change LONG to FARPROC to be technically correct * Make requested changes: Move windows version checking to function in bgfx.cpp Change windowsVersionIs to also use this technique Use bgfx code style Specify dwOSVersionInfoSize prior to calling rtlGetVersion * Merge both functions into one Use bx::dlsym instead of GetProcAddress directly Fix major & minor comparison logic * Fix win10 version comment * Revert rendererCreate check back to Win 0x0602 * Clean up logic as per suggestion
This commit is contained in:
parent
e2631c1a56
commit
f4a9bfc4bc
44
src/bgfx.cpp
44
src/bgfx.cpp
@ -2653,30 +2653,44 @@ namespace bgfx
|
||||
};
|
||||
BX_STATIC_ASSERT(BX_COUNTOF(s_rendererCreator) == RendererType::Count);
|
||||
|
||||
bool windowsVersionIs(Condition::Enum _op, uint32_t _version)
|
||||
bool windowsVersionIs(Condition::Enum _op, uint32_t _version, uint32_t _build)
|
||||
{
|
||||
#if BX_PLATFORM_WINDOWS
|
||||
static const uint8_t s_condition[] =
|
||||
{
|
||||
VER_LESS_EQUAL,
|
||||
VER_GREATER_EQUAL,
|
||||
};
|
||||
|
||||
OSVERSIONINFOEXA ovi;
|
||||
RTL_OSVERSIONINFOW ovi;
|
||||
bx::memSet(&ovi, 0 , sizeof(ovi));
|
||||
ovi.dwOSVersionInfoSize = sizeof(ovi);
|
||||
const HMODULE hMod = GetModuleHandleW(L"ntdll.dll");
|
||||
if (NULL != hMod)
|
||||
{
|
||||
FARPROC (WINAPI* rtlGetVersionPtr) (PRTL_OSVERSIONINFOW) = reinterpret_cast<FARPROC (WINAPI*)(PRTL_OSVERSIONINFOW)>(bx::dlsym(hMod, "RtlGetVersion"));
|
||||
if (NULL != rtlGetVersionPtr)
|
||||
{
|
||||
rtlGetVersionPtr(&ovi);
|
||||
if (ovi.dwMajorVersion == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
ovi.dwBuildNumber = UINT32_MAX == _build ? UINT32_MAX : ovi.dwBuildNumber;
|
||||
}
|
||||
}
|
||||
// _WIN32_WINNT_WIN10 0x0A00
|
||||
// _WIN32_WINNT_WINBLUE 0x0603
|
||||
// _WIN32_WINNT_WIN8 0x0602
|
||||
// _WIN32_WINNT_WIN7 0x0601
|
||||
// _WIN32_WINNT_VISTA 0x0600
|
||||
ovi.dwMajorVersion = HIBYTE(_version);
|
||||
ovi.dwMinorVersion = LOBYTE(_version);
|
||||
DWORDLONG cond = 0;
|
||||
VER_SET_CONDITION(cond, VER_MAJORVERSION, s_condition[_op]);
|
||||
VER_SET_CONDITION(cond, VER_MINORVERSION, s_condition[_op]);
|
||||
return !!VerifyVersionInfoA(&ovi, VER_MAJORVERSION | VER_MINORVERSION, cond);
|
||||
const DWORD cMajorVersion = HIBYTE(_version);
|
||||
const DWORD cMinorVersion = LOBYTE(_version);
|
||||
switch (_op)
|
||||
{
|
||||
case Condition::LessEqual:
|
||||
return (ovi.dwMajorVersion < cMajorVersion || (ovi.dwMajorVersion == cMajorVersion && ovi.dwMinorVersion <= cMinorVersion)) && ovi.dwBuildNumber <= _build;
|
||||
case Condition::GreaterEqual:
|
||||
return (ovi.dwMajorVersion > cMajorVersion || (ovi.dwMajorVersion == cMajorVersion && ovi.dwMinorVersion >= cMinorVersion)) && ovi.dwBuildNumber >= _build;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
BX_UNUSED(_op, _version);
|
||||
BX_UNUSED(_op, _version, _build);
|
||||
return false;
|
||||
#endif // BX_PLATFORM_WINDOWS
|
||||
}
|
||||
|
@ -427,7 +427,7 @@ namespace bgfx
|
||||
};
|
||||
};
|
||||
|
||||
bool windowsVersionIs(Condition::Enum _op, uint32_t _version);
|
||||
bool windowsVersionIs(Condition::Enum _op, uint32_t _version, uint32_t _build = UINT32_MAX);
|
||||
|
||||
constexpr bool isShaderType(uint32_t _magic, char _type)
|
||||
{
|
||||
|
@ -844,14 +844,21 @@ namespace bgfx { namespace d3d12
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
// debug1->SetEnableGPUBasedValidation(true);
|
||||
|
||||
// https://discordapp.com/channels/590611987420020747/593519198995742733/703642988345032804
|
||||
// D3D12 Bug Number: 26131261
|
||||
// There is a bug in the D3D12 validation that causes example-21 to fail when using UAV
|
||||
// Setting this function below to false avoids the bug
|
||||
// Setting SetEnableSynchronizedCommandQueueValidation below to false avoids the bug
|
||||
// It was fixed in (probably) the first windows 11 sdk, 22000
|
||||
// However, the fix causes any dx12 context with validation to break if this is set to false, so we can't do that anymore
|
||||
if (windowsVersionIs(Condition::GreaterEqual, 0x0A00, 22000))
|
||||
{
|
||||
debug1->SetEnableGPUBasedValidation(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
debug1->SetEnableSynchronizedCommandQueueValidation(false);
|
||||
}
|
||||
}
|
||||
|
||||
DX_RELEASE(debug1, 1);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user