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:
parent
3a587c5116
commit
6540ab4f3e
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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(
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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(
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user