mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-14 22:29:15 +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 {
|
const D3D11_BUFFER_DESC* Desc() const {
|
||||||
return &m_desc;
|
return &m_desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
Rc<DxvkBuffer> GetBuffer() const {
|
Rc<DxvkBuffer> GetBuffer() const {
|
||||||
return m_buffer;
|
return m_buffer;
|
||||||
}
|
}
|
||||||
@ -80,17 +80,18 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
VkDeviceSize GetSize() const {
|
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 {
|
DxvkPhysicalBufferSlice GetMappedSlice() const {
|
||||||
return m_mapped;
|
return m_mapped;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetMappedSlice(const DxvkPhysicalBufferSlice& slice) {
|
|
||||||
m_mapped = slice;
|
|
||||||
}
|
|
||||||
|
|
||||||
D3D10Buffer* GetD3D10Iface() {
|
D3D10Buffer* GetD3D10Iface() {
|
||||||
return &m_d3d10;
|
return &m_d3d10;
|
||||||
}
|
}
|
||||||
|
@ -159,9 +159,6 @@ namespace dxvk {
|
|||||||
D3D11Buffer* pBuffer = static_cast<D3D11Buffer*>(pResource);
|
D3D11Buffer* pBuffer = static_cast<D3D11Buffer*>(pResource);
|
||||||
const Rc<DxvkBuffer> buffer = pBuffer->GetBuffer();
|
const Rc<DxvkBuffer> buffer = pBuffer->GetBuffer();
|
||||||
|
|
||||||
D3D11_BUFFER_DESC bufferDesc;
|
|
||||||
pBuffer->GetDesc(&bufferDesc);
|
|
||||||
|
|
||||||
if (!(buffer->memFlags() & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) {
|
if (!(buffer->memFlags() & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) {
|
||||||
Logger::err("D3D11: Cannot map a device-local buffer");
|
Logger::err("D3D11: Cannot map a device-local buffer");
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
@ -173,7 +170,7 @@ namespace dxvk {
|
|||||||
pMapEntry->RowPitch = pBuffer->GetSize();
|
pMapEntry->RowPitch = pBuffer->GetSize();
|
||||||
pMapEntry->DepthPitch = 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,
|
// For resources that cannot be written by the GPU,
|
||||||
// we may write to the buffer resource directly and
|
// we may write to the buffer resource directly and
|
||||||
// just swap in the physical buffer slice as needed.
|
// just swap in the physical buffer slice as needed.
|
||||||
@ -240,10 +237,7 @@ namespace dxvk {
|
|||||||
const D3D11DeferredContextMapEntry* pMapEntry) {
|
const D3D11DeferredContextMapEntry* pMapEntry) {
|
||||||
D3D11Buffer* pBuffer = static_cast<D3D11Buffer*>(pResource);
|
D3D11Buffer* pBuffer = static_cast<D3D11Buffer*>(pResource);
|
||||||
|
|
||||||
D3D11_BUFFER_DESC bufferDesc;
|
if (pBuffer->Desc()->Usage == D3D11_USAGE_DYNAMIC && m_parent->GetOptions()->dcMapSpeedHack) {
|
||||||
pBuffer->GetDesc(&bufferDesc);
|
|
||||||
|
|
||||||
if (bufferDesc.Usage == D3D11_USAGE_DYNAMIC && m_parent->GetOptions()->dcMapSpeedHack) {
|
|
||||||
EmitCs([
|
EmitCs([
|
||||||
cDstBuffer = pBuffer->GetBuffer(),
|
cDstBuffer = pBuffer->GetBuffer(),
|
||||||
cPhysSlice = pMapEntry->BufferSlice
|
cPhysSlice = pMapEntry->BufferSlice
|
||||||
|
@ -157,28 +157,32 @@ namespace dxvk {
|
|||||||
D3D11_MAP MapType,
|
D3D11_MAP MapType,
|
||||||
UINT MapFlags,
|
UINT MapFlags,
|
||||||
D3D11_MAPPED_SUBRESOURCE* pMappedResource) {
|
D3D11_MAPPED_SUBRESOURCE* pMappedResource) {
|
||||||
if (pResource == nullptr)
|
if (!pResource || !pMappedResource)
|
||||||
return DXGI_ERROR_INVALID_CALL;
|
return E_INVALIDARG;
|
||||||
|
|
||||||
if (pMappedResource != nullptr) {
|
|
||||||
pMappedResource->pData = nullptr;
|
|
||||||
pMappedResource->RowPitch = 0;
|
|
||||||
pMappedResource->DepthPitch = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
D3D11_RESOURCE_DIMENSION resourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN;
|
D3D11_RESOURCE_DIMENSION resourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN;
|
||||||
pResource->GetType(&resourceDim);
|
pResource->GetType(&resourceDim);
|
||||||
|
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
if (resourceDim == D3D11_RESOURCE_DIMENSION_BUFFER) {
|
if (resourceDim == D3D11_RESOURCE_DIMENSION_BUFFER) {
|
||||||
return MapBuffer(
|
hr = MapBuffer(
|
||||||
static_cast<D3D11Buffer*>(pResource),
|
static_cast<D3D11Buffer*>(pResource),
|
||||||
MapType, MapFlags, pMappedResource);
|
MapType, MapFlags, pMappedResource);
|
||||||
} else {
|
} else {
|
||||||
return MapImage(
|
hr = MapImage(
|
||||||
GetCommonTexture(pResource),
|
GetCommonTexture(pResource),
|
||||||
Subresource, MapType, MapFlags,
|
Subresource, MapType, MapFlags,
|
||||||
pMappedResource);
|
pMappedResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
pMappedResource->pData = nullptr;
|
||||||
|
pMappedResource->RowPitch = 0;
|
||||||
|
pMappedResource->DepthPitch = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -328,7 +332,7 @@ namespace dxvk {
|
|||||||
UINT MapFlags,
|
UINT MapFlags,
|
||||||
D3D11_MAPPED_SUBRESOURCE* pMappedResource) {
|
D3D11_MAPPED_SUBRESOURCE* pMappedResource) {
|
||||||
Rc<DxvkBuffer> buffer = pResource->GetBuffer();
|
Rc<DxvkBuffer> buffer = pResource->GetBuffer();
|
||||||
|
|
||||||
if (!(buffer->memFlags() & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) {
|
if (!(buffer->memFlags() & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) {
|
||||||
Logger::err("D3D11: Cannot map a device-local buffer");
|
Logger::err("D3D11: Cannot map a device-local buffer");
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
@ -338,29 +342,36 @@ namespace dxvk {
|
|||||||
// Allocate a new backing slice for the buffer and set
|
// Allocate a new backing slice for the buffer and set
|
||||||
// it as the 'new' mapped slice. This assumes that the
|
// it as the 'new' mapped slice. This assumes that the
|
||||||
// only way to invalidate a buffer is by mapping it.
|
// only way to invalidate a buffer is by mapping it.
|
||||||
auto physicalSlice = buffer->allocPhysicalSlice();
|
auto physicalSlice = pResource->DiscardSlice();
|
||||||
pResource->SetMappedSlice(physicalSlice);
|
pMappedResource->pData = physicalSlice.mapPtr(0);
|
||||||
|
pMappedResource->RowPitch = pResource->GetSize();
|
||||||
|
pMappedResource->DepthPitch = pResource->GetSize();
|
||||||
|
|
||||||
EmitCs([
|
EmitCs([
|
||||||
cBuffer = buffer,
|
cBuffer = std::move(buffer),
|
||||||
cPhysicalSlice = physicalSlice
|
cPhysicalSlice = std::move(physicalSlice)
|
||||||
] (DxvkContext* ctx) {
|
] (DxvkContext* ctx) {
|
||||||
ctx->invalidateBuffer(cBuffer, cPhysicalSlice);
|
ctx->invalidateBuffer(cBuffer, cPhysicalSlice);
|
||||||
});
|
});
|
||||||
} else if (MapType != D3D11_MAP_WRITE_NO_OVERWRITE) {
|
|
||||||
if (!WaitForResource(buffer->resource(), MapFlags))
|
return S_OK;
|
||||||
return DXGI_ERROR_WAS_STILL_DRAWING;
|
} 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