libobs-d3d11: Check if device can perform fast clear on init

NVIDIA GPUs in multi-GPU setups cannot safely perform a fast clear until
driver 527.37. Implement a check against the Vendor ID and driver
version of the adapter to determine if the adapter can safely perform a
fast clear.

Co-authored-by: derrod <dennis@obsproject.com>
This commit is contained in:
Ryan Foster
2023-07-29 16:34:47 -07:00
committed by Lain
co-authored by derrod
parent 346b93c9c4
commit a8f770fdfc
2 changed files with 24 additions and 0 deletions
+23
View File
@@ -641,11 +641,28 @@ static bool CheckFormat(ID3D11Device *device, DXGI_FORMAT format)
((support & required) == required);
}
static bool FastClearSupported(UINT vendorId, uint64_t version)
{
/* Always true for non-NVIDIA GPUs */
if (vendorId != 0x10de)
return true;
const uint16_t aa = (version >> 48) & 0xffff;
const uint16_t bb = (version >> 32) & 0xffff;
const uint16_t ccccc = (version >> 16) & 0xffff;
const uint16_t ddddd = version & 0xffff;
/* Check for NVIDIA driver version >= 31.0.15.2737 */
return aa >= 31 && bb >= 0 && ccccc >= 15 && ddddd >= 2737;
}
void gs_device::InitDevice(uint32_t adapterIdx)
{
wstring adapterName;
DXGI_ADAPTER_DESC desc;
D3D_FEATURE_LEVEL levelUsed = D3D_FEATURE_LEVEL_10_0;
LARGE_INTEGER umd;
uint64_t driverVersion = 0;
HRESULT hr = 0;
adpIdx = adapterIdx;
@@ -663,6 +680,10 @@ void gs_device::InitDevice(uint32_t adapterIdx)
blog(LOG_INFO, "Loading up D3D11 on adapter %s (%" PRIu32 ")",
adapterNameUTF8.Get(), adapterIdx);
hr = adapter->CheckInterfaceSupport(__uuidof(IDXGIDevice), &umd);
if (SUCCEEDED(hr))
driverVersion = umd.QuadPart;
hr = D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL,
createFlags, featureLevels,
sizeof(featureLevels) /
@@ -725,6 +746,8 @@ void gs_device::InitDevice(uint32_t adapterIdx)
nv12Supported = CheckFormat(device, DXGI_FORMAT_NV12) &&
!HasBadNV12Output();
p010Supported = nv12Supported && CheckFormat(device, DXGI_FORMAT_P010);
fastClearSupported = FastClearSupported(desc.VendorId, driverVersion);
}
static inline void ConvertStencilSide(D3D11_DEPTH_STENCILOP_DESC &desc,
+1
View File
@@ -1022,6 +1022,7 @@ struct gs_device {
uint32_t adpIdx = 0;
bool nv12Supported = false;
bool p010Supported = false;
bool fastClearSupported = false;
gs_texture_2d *curRenderTarget = nullptr;
gs_zstencil_buffer *curZStencilBuffer = nullptr;