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:
parent
e0e945f724
commit
11b269efd1
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user