Optimize GPUBuffer on D3D11 to not stall CPU on reading staging readback buffer

This commit is contained in:
Wojtek Figat
2022-11-01 21:31:42 +01:00
parent a0a3457733
commit f37ed16270
2 changed files with 13 additions and 5 deletions

View File

@@ -25,10 +25,13 @@ void* GPUBufferDX11::Map(GPUResourceMapMode mode)
D3D11_MAPPED_SUBRESOURCE map;
map.pData = nullptr;
D3D11_MAP mapType;
UINT mapFlags = 0;
switch (mode)
{
case GPUResourceMapMode::Read:
mapType = D3D11_MAP_READ;
if (_desc.Usage == GPUResourceUsage::StagingReadback)
mapFlags = D3D11_MAP_FLAG_DO_NOT_WAIT;
break;
case GPUResourceMapMode::Write:
mapType = D3D11_MAP_WRITE_DISCARD;
@@ -37,12 +40,12 @@ void* GPUBufferDX11::Map(GPUResourceMapMode mode)
mapType = D3D11_MAP_READ_WRITE;
break;
default:
CRASH;
return nullptr;
}
const HRESULT result = _device->GetIM()->Map(_resource, 0, mapType, 0, &map);
LOG_DIRECTX_RESULT(result);
const HRESULT result = _device->GetIM()->Map(_resource, 0, mapType, mapFlags, &map);
if (result != DXGI_ERROR_WAS_STILL_DRAWING)
LOG_DIRECTX_RESULT(result);
return map.pData;
}

View File

@@ -672,7 +672,7 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co
}
if (surfaceAtlasData.CulledObjectsCounterIndex != -1)
{
// Get the last counter value (accept staging readback delay)
// Get the last counter value (accept staging readback delay or not available data yet)
notReady = true;
auto data = (uint32*)_culledObjectsSizeBuffer->Map(GPUResourceMapMode::Read);
if (data)
@@ -685,6 +685,10 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co
notReady = false;
}
}
// Allow to be ready if the buffer was already used
if (notReady && surfaceAtlasData.CulledObjectsBuffer && surfaceAtlasData.CulledObjectsBuffer->IsAllocated())
notReady = false;
}
if (surfaceAtlasData.CulledObjectsCounterIndex == -1)
{
@@ -717,7 +721,8 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co
if (surfaceAtlasData.CulledObjectsBuffer->Init(desc))
return true;
}
ZoneValue(surfaceAtlasData.CulledObjectsBuffer->GetSize() / 1024); // CulledObjectsBuffer size in kB
objectsBufferCapacity = surfaceAtlasData.CulledObjectsBuffer->GetSize();
ZoneValue(objectsBufferCapacity / 1024); // CulledObjectsBuffer size in kB
// Clear chunks counter (uint at 0 is used for a counter)
uint32 counter = 1; // Move write location for culled objects after counter