1
0
mirror of https://github.com/EduApps-CDG/OpenDX synced 2024-12-30 09:45:37 +01:00

[d3d11] Map() optimization removed, needs buffer renaming

The naive optimization to use staging buffers rather than actual mapping
turned out to be no more efficient than the previous approach. In order
to achieve good performance, buffer renaming must be implemented instead.
This commit is contained in:
Philip Rebohle 2017-12-14 12:29:41 +01:00
parent 4172b99952
commit bdce9a69fb
2 changed files with 29 additions and 34 deletions

View File

@ -91,44 +91,41 @@ namespace dxvk {
if (MapFlags & D3D11_MAP_FLAG_DO_NOT_WAIT) if (MapFlags & D3D11_MAP_FLAG_DO_NOT_WAIT)
return DXGI_ERROR_WAS_STILL_DRAWING; return DXGI_ERROR_WAS_STILL_DRAWING;
if (MapType == D3D11_MAP_WRITE_DISCARD) { // TODO optimize this. In order to properly cover common use cases
// Instead of synchronizing with the device, which is // like frequent constant buffer updates, we must implement buffer
// highly inefficient, return a host-local buffer to // renaming techniques. The current approach is inefficient as it
// the application and upload its contents on unmap() // leads to a lot of Flush() and Synchronize() calls.
// TODO evaluate whether this improves performance //
m_mapData = new DxvkDataBuffer(buffer->info().size); // Possible solution:
// (1) Create buffers with a significantly larger size if they
pMappedSubresource->pData = m_mapData->data(); // can be mapped by the host for writing. If mapping the
pMappedSubresource->RowPitch = buffer->info().size; // buffer would stall on D3D11_MAP_WRITE_DISCARD, map the
pMappedSubresource->DepthPitch = buffer->info().size; // next slice. on D3D11_MAP_WRITE_NO_OVERWRITE, return the
return S_OK; // current slice. If the buffer is bound, update bindings.
} else { // (2) If no more slices are available, create a new buffer.
// We have to wait for the device to complete // Limit the number of buffers to a small, fixed number.
pContext->Flush(); // (3) If no more buffers are available, flush and synchronize.
pContext->Synchronize(); // (4) When renaming the buffer internally, all active bindings
// need to be updated internally as well.
pMappedSubresource->pData = buffer->mapPtr(0); //
pMappedSubresource->RowPitch = buffer->info().size; // In order to support deferred contexts, the immediate context
pMappedSubresource->DepthPitch = buffer->info().size; // must commit all changes to the initial buffer slice prior to
return S_OK; // executing a command list. When mapping on deferred contexts,
} // the deferred context shall create local buffer objects.
pContext->Flush();
pContext->Synchronize();
pMappedSubresource->pData = buffer->mapPtr(0);
pMappedSubresource->RowPitch = buffer->info().size;
pMappedSubresource->DepthPitch = buffer->info().size;
return S_OK;
} }
} }
void D3D11Buffer::Unmap( void D3D11Buffer::Unmap(
D3D11DeviceContext* pContext) { D3D11DeviceContext* pContext) {
if (m_mapData != nullptr) { // Nothing to see here, folks
const Rc<DxvkContext> context
= pContext->GetDXVKContext();
context->updateBuffer(
m_resource->GetDXVKBuffer(),
0, m_mapData->size(),
m_mapData->data());
m_mapData = nullptr;
}
} }

View File

@ -55,8 +55,6 @@ namespace dxvk {
Com<IDXGIBufferResourcePrivate> m_resource; Com<IDXGIBufferResourcePrivate> m_resource;
D3D11_BUFFER_DESC m_desc; D3D11_BUFFER_DESC m_desc;
Rc<DxvkDataBuffer> m_mapData;
}; };
} }