1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-03-13 19:29:14 +01:00

[d3d11] Save a few CPU cycles in Map/MapBuffer

This commit is contained in:
Philip Rebohle 2018-10-16 12:29:04 +02:00
parent e0e945f724
commit 11b269efd1
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
3 changed files with 48 additions and 42 deletions

View File

@ -58,7 +58,7 @@ namespace dxvk {
const D3D11_BUFFER_DESC* Desc() const {
return &m_desc;
}
Rc<DxvkBuffer> GetBuffer() const {
return m_buffer;
}
@ -80,17 +80,18 @@ namespace dxvk {
}
VkDeviceSize GetSize() const {
return m_buffer->info().size;
return m_desc.ByteWidth;
}
DxvkPhysicalBufferSlice DiscardSlice() {
m_mapped = m_buffer->allocPhysicalSlice();
return m_mapped;
}
DxvkPhysicalBufferSlice GetMappedSlice() const {
return m_mapped;
}
void SetMappedSlice(const DxvkPhysicalBufferSlice& slice) {
m_mapped = slice;
}
D3D10Buffer* GetD3D10Iface() {
return &m_d3d10;
}

View File

@ -159,9 +159,6 @@ namespace dxvk {
D3D11Buffer* pBuffer = static_cast<D3D11Buffer*>(pResource);
const Rc<DxvkBuffer> buffer = pBuffer->GetBuffer();
D3D11_BUFFER_DESC bufferDesc;
pBuffer->GetDesc(&bufferDesc);
if (!(buffer->memFlags() & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) {
Logger::err("D3D11: Cannot map a device-local buffer");
return E_INVALIDARG;
@ -173,7 +170,7 @@ namespace dxvk {
pMapEntry->RowPitch = pBuffer->GetSize();
pMapEntry->DepthPitch = pBuffer->GetSize();
if (bufferDesc.Usage == D3D11_USAGE_DYNAMIC && m_parent->GetOptions()->dcMapSpeedHack) {
if (pBuffer->Desc()->Usage == D3D11_USAGE_DYNAMIC && m_parent->GetOptions()->dcMapSpeedHack) {
// For resources that cannot be written by the GPU,
// we may write to the buffer resource directly and
// just swap in the physical buffer slice as needed.
@ -240,10 +237,7 @@ namespace dxvk {
const D3D11DeferredContextMapEntry* pMapEntry) {
D3D11Buffer* pBuffer = static_cast<D3D11Buffer*>(pResource);
D3D11_BUFFER_DESC bufferDesc;
pBuffer->GetDesc(&bufferDesc);
if (bufferDesc.Usage == D3D11_USAGE_DYNAMIC && m_parent->GetOptions()->dcMapSpeedHack) {
if (pBuffer->Desc()->Usage == D3D11_USAGE_DYNAMIC && m_parent->GetOptions()->dcMapSpeedHack) {
EmitCs([
cDstBuffer = pBuffer->GetBuffer(),
cPhysSlice = pMapEntry->BufferSlice

View File

@ -157,28 +157,32 @@ namespace dxvk {
D3D11_MAP MapType,
UINT MapFlags,
D3D11_MAPPED_SUBRESOURCE* pMappedResource) {
if (pResource == nullptr)
return DXGI_ERROR_INVALID_CALL;
if (pMappedResource != nullptr) {
pMappedResource->pData = nullptr;
pMappedResource->RowPitch = 0;
pMappedResource->DepthPitch = 0;
}
if (!pResource || !pMappedResource)
return E_INVALIDARG;
D3D11_RESOURCE_DIMENSION resourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN;
pResource->GetType(&resourceDim);
HRESULT hr;
if (resourceDim == D3D11_RESOURCE_DIMENSION_BUFFER) {
return MapBuffer(
hr = MapBuffer(
static_cast<D3D11Buffer*>(pResource),
MapType, MapFlags, pMappedResource);
} else {
return MapImage(
hr = MapImage(
GetCommonTexture(pResource),
Subresource, MapType, MapFlags,
pMappedResource);
}
if (FAILED(hr)) {
pMappedResource->pData = nullptr;
pMappedResource->RowPitch = 0;
pMappedResource->DepthPitch = 0;
}
return hr;
}
@ -328,7 +332,7 @@ namespace dxvk {
UINT MapFlags,
D3D11_MAPPED_SUBRESOURCE* pMappedResource) {
Rc<DxvkBuffer> buffer = pResource->GetBuffer();
if (!(buffer->memFlags() & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) {
Logger::err("D3D11: Cannot map a device-local buffer");
return E_INVALIDARG;
@ -338,29 +342,36 @@ namespace dxvk {
// Allocate a new backing slice for the buffer and set
// it as the 'new' mapped slice. This assumes that the
// only way to invalidate a buffer is by mapping it.
auto physicalSlice = buffer->allocPhysicalSlice();
pResource->SetMappedSlice(physicalSlice);
auto physicalSlice = pResource->DiscardSlice();
pMappedResource->pData = physicalSlice.mapPtr(0);
pMappedResource->RowPitch = pResource->GetSize();
pMappedResource->DepthPitch = pResource->GetSize();
EmitCs([
cBuffer = buffer,
cPhysicalSlice = physicalSlice
cBuffer = std::move(buffer),
cPhysicalSlice = std::move(physicalSlice)
] (DxvkContext* ctx) {
ctx->invalidateBuffer(cBuffer, cPhysicalSlice);
});
} else if (MapType != D3D11_MAP_WRITE_NO_OVERWRITE) {
if (!WaitForResource(buffer->resource(), MapFlags))
return DXGI_ERROR_WAS_STILL_DRAWING;
return S_OK;
} else {
// Wait until the resource is no longer in use
if (MapType != D3D11_MAP_WRITE_NO_OVERWRITE) {
if (!WaitForResource(buffer->resource(), MapFlags))
return DXGI_ERROR_WAS_STILL_DRAWING;
}
// Use map pointer from previous map operation. This
// way we don't have to synchronize with the CS thread
// if the map mode is D3D11_MAP_WRITE_NO_OVERWRITE.
DxvkPhysicalBufferSlice physicalSlice = pResource->GetMappedSlice();
pMappedResource->pData = physicalSlice.mapPtr(0);
pMappedResource->RowPitch = pResource->GetSize();
pMappedResource->DepthPitch = pResource->GetSize();
return S_OK;
}
// Use map pointer from previous map operation. This
// way we don't have to synchronize with the CS thread
// if the map mode is D3D11_MAP_WRITE_NO_OVERWRITE.
DxvkPhysicalBufferSlice physicalSlice = pResource->GetMappedSlice();
pMappedResource->pData = physicalSlice.mapPtr(0);
pMappedResource->RowPitch = pResource->GetSize();
pMappedResource->DepthPitch = pResource->GetSize();
return S_OK;
}