diff --git a/src/d3d11/d3d11_initializer.cpp b/src/d3d11/d3d11_initializer.cpp index 105485fabb9..49a4b68665b 100644 --- a/src/d3d11/d3d11_initializer.cpp +++ b/src/d3d11/d3d11_initializer.cpp @@ -50,7 +50,7 @@ namespace dxvk { else InitDeviceLocalTexture(pTexture, pInitialData); - SyncKeyedMutex(pTexture->GetInterface()); + SyncSharedTexture(pTexture); } @@ -287,13 +287,30 @@ namespace dxvk { } - void D3D11Initializer::SyncKeyedMutex(ID3D11Resource *pResource) { - Com keyedMutex; - if (pResource->QueryInterface(__uuidof(IDXGIKeyedMutex), reinterpret_cast(&keyedMutex)) != S_OK) + void D3D11Initializer::SyncSharedTexture(D3D11CommonTexture* pResource) { + if (!(pResource->Desc()->MiscFlags & (D3D11_RESOURCE_MISC_SHARED | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX | D3D11_RESOURCE_MISC_SHARED_NTHANDLE))) return; - keyedMutex->AcquireSync(0, 0); - keyedMutex->ReleaseSync(0); + // Ensure that initialization commands are submitted and waited on before + // returning control to the application in order to avoid race conditions + // in case the texture is used immediately on a secondary device. + auto mapMode = pResource->GetMapMode(); + + if (mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_NONE + || mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER) { + FlushInternal(); + + m_device->waitForResource(pResource->GetImage(), DxvkAccess::Write); + } + + // If a keyed mutex is used, initialize that to the correct state as well. + Com keyedMutex; + + if (SUCCEEDED(pResource->GetInterface()->QueryInterface( + __uuidof(IDXGIKeyedMutex), reinterpret_cast(&keyedMutex)))) { + keyedMutex->AcquireSync(0, 0); + keyedMutex->ReleaseSync(0); + } } } \ No newline at end of file diff --git a/src/d3d11/d3d11_initializer.h b/src/d3d11/d3d11_initializer.h index 1cd94d8008f..fd3d4dfa2db 100644 --- a/src/d3d11/d3d11_initializer.h +++ b/src/d3d11/d3d11_initializer.h @@ -71,7 +71,8 @@ namespace dxvk { void FlushImplicit(); void FlushInternal(); - void SyncKeyedMutex(ID3D11Resource *pResource); + void SyncSharedTexture( + D3D11CommonTexture* pResource); };