Fix GPU Buffer Map/Unmap pair to prevent stall if map fails on DX11

#942
This commit is contained in:
Wojtek Figat
2023-02-17 16:28:48 +01:00
parent 5dc63da4bf
commit 679757942f
7 changed files with 19 additions and 16 deletions

View File

@@ -377,12 +377,9 @@ void GPUBuffer::SetData(const void* data, uint32 size)
Log::ArgumentOutOfRangeException(TEXT("Buffer.SetData"));
return;
}
void* mapped = Map(GPUResourceMapMode::Write);
if (!mapped)
{
return;
}
Platform::MemoryCopy(mapped, data, size);
Unmap();
}

View File

@@ -190,6 +190,7 @@ public:
/// <summary>
/// Gets a CPU pointer to the resource by mapping its contents. Denies the GPU access to that resource.
/// </summary>
/// <remarks>Always call Unmap if the returned pointer is valid to release resources.</remarks>
/// <param name="mode">The map operation mode.</param>
/// <returns>The pointer of the mapped CPU buffer with resource data or null if failed.</returns>
API_FUNCTION() virtual void* Map(GPUResourceMapMode mode) = 0;

View File

@@ -48,18 +48,19 @@ void* GPUBufferDX11::Map(GPUResourceMapMode mode)
const HRESULT result = _device->GetIM()->Map(_resource, 0, mapType, mapFlags, &map);
if (result != DXGI_ERROR_WAS_STILL_DRAWING)
LOG_DIRECTX_RESULT(result);
_mapped = map.pData != nullptr;
if (!_mapped && !isMainThread)
_device->Locker.Unlock();
return map.pData;
}
void GPUBufferDX11::Unmap()
{
if (_mapped)
{
_mapped = false;
_device->GetIM()->Unmap(_resource, 0);
}
ASSERT(_mapped);
_mapped = false;
_device->GetIM()->Unmap(_resource, 0);
if (!IsInMainThread())
_device->Locker.Unlock();
}

View File

@@ -104,15 +104,18 @@ int32 ParticleSystemInstance::GetParticlesCount() const
if (GPUParticlesCountReadback && GPUParticlesCountReadback->IsAllocated())
{
auto data = static_cast<uint32*>(GPUParticlesCountReadback->Map(GPUResourceMapMode::Read));
for (const auto& emitter : Emitters)
if (data)
{
if (emitter.Buffer && emitter.Buffer->Mode == ParticlesSimulationMode::GPU && emitter.Buffer->GPU.HasValidCount)
for (const auto& emitter : Emitters)
{
result += *data;
if (emitter.Buffer && emitter.Buffer->Mode == ParticlesSimulationMode::GPU && emitter.Buffer->GPU.HasValidCount)
{
result += *data;
}
++data;
}
++data;
GPUParticlesCountReadback->Unmap();
}
GPUParticlesCountReadback->Unmap();
}
else if (Emitters.HasItems())
{

View File

@@ -689,8 +689,8 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co
objectsBufferCapacity = counter;
notReady = false;
}
_culledObjectsSizeBuffer->Unmap();
}
_culledObjectsSizeBuffer->Unmap();
// Allow to be ready if the buffer was already used
if (notReady && surfaceAtlasData.CulledObjectsBuffer && surfaceAtlasData.CulledObjectsBuffer->IsAllocated())

View File

@@ -152,7 +152,7 @@ void ShadowsOfMordor::Builder::updateLightmaps()
{
auto texture = textures[textureIndex];
GPUDevice::Instance->Locker.Unlock();
if (!texture || texture->WaitForLoaded())
if (texture == nullptr || texture->WaitForLoaded())
{
LOG(Error, "Lightmap load failed.");
return;

View File

@@ -276,6 +276,7 @@ void ShadowsOfMordor::Builder::saveState()
context->Flush();
Platform::Sleep(10);
void* mapped = lightmapDataStaging->Map(GPUResourceMapMode::Read);
ASSERT(mapped);
stream->WriteInt32(lightmapDataSize);
stream->WriteBytes(mapped, lightmapDataSize);
lightmapDataStaging->Unmap();