Skip to content

Commit

Permalink
Fix D3D12 debug crash due to validation layers SDK bug (#3222)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
RazielXYZ authored Dec 14, 2023
1 parent e2631c1 commit f4a9bfc
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 21 deletions.
46 changes: 30 additions & 16 deletions src/bgfx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
bx::memSet(&ovi, 0, sizeof(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
}
Expand Down
2 changes: 1 addition & 1 deletion src/bgfx_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
15 changes: 11 additions & 4 deletions src/renderer_d3d12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -844,13 +844,20 @@ 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
debug1->SetEnableSynchronizedCommandQueueValidation(false);
// 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);
Expand Down

0 comments on commit f4a9bfc

Please sign in to comment.