1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-01-31 14:52:11 +01:00

[dxvk] Use DxvkPagedResource for CPU synchronization

This commit is contained in:
Philip Rebohle 2024-10-17 16:22:37 +02:00 committed by Philip Rebohle
parent 3a587c5116
commit 6540ab4f3e
10 changed files with 29 additions and 29 deletions

View File

@ -399,7 +399,7 @@ namespace dxvk {
pMappedResource->DepthPitch = bufferSize;
return S_OK;
} else {
if (!WaitForResource(buffer, sequenceNumber, MapType, MapFlags))
if (!WaitForResource(*buffer, sequenceNumber, MapType, MapFlags))
return DXGI_ERROR_WAS_STILL_DRAWING;
pMappedResource->pData = pResource->GetMapPtr();
@ -455,7 +455,7 @@ namespace dxvk {
MapFlags &= ~D3D11_MAP_FLAG_DO_NOT_WAIT;
if (MapType != D3D11_MAP_WRITE_NO_OVERWRITE) {
if (!WaitForResource(mappedImage, sequenceNumber, MapType, MapFlags))
if (!WaitForResource(*mappedImage, sequenceNumber, MapType, MapFlags))
return DXGI_ERROR_WAS_STILL_DRAWING;
}
@ -552,7 +552,7 @@ namespace dxvk {
MapFlags &= ~D3D11_MAP_FLAG_DO_NOT_WAIT;
// Wait for mapped buffer to become available
if (!WaitForResource(mappedBuffer, sequenceNumber, MapType, MapFlags))
if (!WaitForResource(*mappedBuffer, sequenceNumber, MapType, MapFlags))
return DXGI_ERROR_WAS_STILL_DRAWING;
}
@ -829,7 +829,7 @@ namespace dxvk {
bool D3D11ImmediateContext::WaitForResource(
const Rc<DxvkResource>& Resource,
const DxvkPagedResource& Resource,
uint64_t SequenceNumber,
D3D11_MAP MapType,
UINT MapFlags) {
@ -841,11 +841,11 @@ namespace dxvk {
// Wait for any CS chunk using the resource to execute, since
// otherwise we cannot accurately determine if the resource is
// actually being used by the GPU right now.
bool isInUse = Resource->isInUse(access);
bool isInUse = Resource.isInUse(access);
if (!isInUse) {
SynchronizeCsThread(SequenceNumber);
isInUse = Resource->isInUse(access);
isInUse = Resource.isInUse(access);
}
if (MapFlags & D3D11_MAP_FLAG_DO_NOT_WAIT) {

View File

@ -171,7 +171,7 @@ namespace dxvk {
void EndFrame();
bool WaitForResource(
const Rc<DxvkResource>& Resource,
const DxvkPagedResource& Resource,
uint64_t SequenceNumber,
D3D11_MAP MapType,
UINT MapFlags);

View File

@ -360,7 +360,7 @@ namespace dxvk {
|| mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER) {
ExecuteFlush();
m_device->waitForResource(pResource->GetImage(), DxvkAccess::Write);
m_device->waitForResource(*pResource->GetImage(), DxvkAccess::Write);
}
// If a keyed mutex is used, initialize that to the correct state as well.

View File

@ -122,7 +122,7 @@ namespace dxvk {
Logger::warn("D3D11DXGIKeyedMutex::ReleaseSync: Called without context locking enabled.");
D3D10DeviceLock lock = context->LockContext();
context->WaitForResource(texture->GetImage(), DxvkCsThread::SynchronizeAll, D3D11_MAP_READ_WRITE, 0);
context->WaitForResource(*texture->GetImage(), DxvkCsThread::SynchronizeAll, D3D11_MAP_READ_WRITE, 0);
}
VkResult vr = dxvkDevice->vkd()->wine_vkReleaseKeyedMutex(

View File

@ -4554,9 +4554,9 @@ namespace dxvk {
}
bool D3D9DeviceEx::WaitForResource(
const Rc<DxvkResource>& Resource,
uint64_t SequenceNumber,
DWORD MapFlags) {
const DxvkPagedResource& Resource,
uint64_t SequenceNumber,
DWORD MapFlags) {
// Wait for the any pending D3D9 command to be executed
// on the CS thread so that we can determine whether the
// resource is currently in use or not.
@ -4566,10 +4566,10 @@ namespace dxvk {
? DxvkAccess::Write
: DxvkAccess::Read;
if (!Resource->isInUse(access))
if (!Resource.isInUse(access))
SynchronizeCsThread(SequenceNumber);
if (Resource->isInUse(access)) {
if (Resource.isInUse(access)) {
if (MapFlags & D3DLOCK_DONOTWAIT) {
// We don't have to wait, but misbehaving games may
// still try to spin on `Map` until the resource is
@ -4790,7 +4790,7 @@ namespace dxvk {
TrackTextureMappingBufferSequenceNumber(pResource, Subresource);
}
if (!WaitForResource(mappedBuffer, pResource->GetMappingBufferSequenceNumber(Subresource), Flags))
if (!WaitForResource(*mappedBuffer, pResource->GetMappingBufferSequenceNumber(Subresource), Flags))
return D3DERR_WASSTILLDRAWING;
}
@ -4963,7 +4963,7 @@ namespace dxvk {
// That means that NeedsReadback is only true if the texture has been used with GetRTData or GetFrontbufferData before.
// Those functions create a buffer, so the buffer always exists here.
const Rc<DxvkBuffer>& buffer = pSrcTexture->GetBuffer();
WaitForResource(buffer, pSrcTexture->GetMappingBufferSequenceNumber(SrcSubresource), 0);
WaitForResource(*buffer, pSrcTexture->GetMappingBufferSequenceNumber(SrcSubresource), 0);
pSrcTexture->SetNeedsReadback(SrcSubresource, false);
}
@ -5180,7 +5180,7 @@ namespace dxvk {
const bool skipWait = (!needsReadback && (readOnly || !directMapping)) || noOverwrite;
if (!skipWait) {
const Rc<DxvkBuffer> mappingBuffer = pResource->GetBuffer<D3D9_COMMON_BUFFER_TYPE_MAPPING>();
if (!WaitForResource(mappingBuffer, pResource->GetMappingBufferSequenceNumber(), Flags))
if (!WaitForResource(*mappingBuffer, pResource->GetMappingBufferSequenceNumber(), Flags))
return D3DERR_WASSTILLDRAWING;
pResource->SetNeedsReadback(false);
@ -5324,7 +5324,7 @@ namespace dxvk {
// - Write to the primary buffer using ProcessVertices which gets copied over to the staging buffer at the end.
// So it could end up writing to the buffer on the GPU while the same buffer gets read here on the CPU.
// That is why we need to ensure the staging buffer is idle here.
WaitForResource(vbo->GetBuffer<D3D9_COMMON_BUFFER_TYPE_STAGING>(), vbo->GetMappingBufferSequenceNumber(), D3DLOCK_READONLY);
WaitForResource(*vbo->GetBuffer<D3D9_COMMON_BUFFER_TYPE_STAGING>(), vbo->GetMappingBufferSequenceNumber(), D3DLOCK_READONLY);
}
const uint32_t vertexSize = m_state.vertexDecl->GetSize(i);

View File

@ -690,9 +690,9 @@ namespace dxvk {
D3D9Format Format) const;
bool WaitForResource(
const Rc<DxvkResource>& Resource,
uint64_t SequenceNumber,
DWORD MapFlags);
const DxvkPagedResource& Resource,
uint64_t SequenceNumber,
DWORD MapFlags);
/**
* \brief Locks a subresource of an image

View File

@ -180,7 +180,7 @@ namespace dxvk {
// in case the texture is used immediately on a secondary device.
ExecuteFlush();
m_device->waitForResource(pResource->GetImage(), DxvkAccess::Write);
m_device->waitForResource(*pResource->GetImage(), DxvkAccess::Write);
}

View File

@ -220,7 +220,7 @@ namespace dxvk {
m_lock = D3D9DeviceLock();
}
static Rc<DxvkResource> GetDxvkResource(IDirect3DResource9 *pResource) {
static Rc<DxvkPagedResource> GetDxvkResource(IDirect3DResource9 *pResource) {
switch (pResource->GetType()) {
case D3DRTYPE_SURFACE: return static_cast<D3D9Surface*> (pResource)->GetCommonTexture()->GetImage();
// Does not inherit from IDirect3DResource9... lol.
@ -237,7 +237,7 @@ namespace dxvk {
bool STDMETHODCALLTYPE D3D9VkInteropDevice::WaitForResource(
IDirect3DResource9* pResource,
DWORD MapFlags) {
return m_device->WaitForResource(GetDxvkResource(pResource), DxvkCsThread::SynchronizeAll, MapFlags);
return m_device->WaitForResource(*GetDxvkResource(pResource), DxvkCsThread::SynchronizeAll, MapFlags);
}
HRESULT STDMETHODCALLTYPE D3D9VkInteropDevice::CreateImage(

View File

@ -300,12 +300,12 @@ namespace dxvk {
}
void DxvkDevice::waitForResource(const Rc<DxvkResource>& resource, DxvkAccess access) {
if (resource->isInUse(access)) {
void DxvkDevice::waitForResource(const DxvkPagedResource& resource, DxvkAccess access) {
if (resource.isInUse(access)) {
auto t0 = dxvk::high_resolution_clock::now();
m_submissionQueue.synchronizeUntil([resource, access] {
return !resource->isInUse(access);
m_submissionQueue.synchronizeUntil([&resource, access] {
return !resource.isInUse(access);
});
auto t1 = dxvk::high_resolution_clock::now();

View File

@ -538,7 +538,7 @@ namespace dxvk {
* \param [in] resource Resource to wait for
* \param [in] access Access mode to check
*/
void waitForResource(const Rc<DxvkResource>& resource, DxvkAccess access);
void waitForResource(const DxvkPagedResource& resource, DxvkAccess access);
/**
* \brief Waits until the device becomes idle