1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-20 19:54:19 +01:00

[d3d11] Use DxvkBufferAllocation where appropriate

This commit is contained in:
Philip Rebohle 2024-09-22 12:03:17 +02:00 committed by Philip Rebohle
parent eae66201f6
commit 8e45a60542
7 changed files with 66 additions and 61 deletions

View File

@ -98,7 +98,7 @@ namespace dxvk {
info.usage |= VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
m_buffer = m_parent->GetDXVKDevice()->importBuffer(info, importInfo, GetMemoryFlags());
m_mapped = m_buffer->getSliceHandle();
m_allocation = m_buffer->getAllocation();
m_mapMode = DetermineMapMode(m_buffer->memFlags());
} else if (!(pDesc->MiscFlags & D3D11_RESOURCE_MISC_TILE_POOL)) {
@ -114,12 +114,12 @@ namespace dxvk {
// Create the buffer and set the entire buffer slice as mapped,
// so that we only have to update it when invalidating the buffer
m_buffer = m_parent->GetDXVKDevice()->createBuffer(info, memoryFlags);
m_mapped = m_buffer->getSliceHandle();
m_allocation = m_buffer->getAllocation();
} else {
m_sparseAllocator = m_parent->GetDXVKDevice()->createSparsePageAllocator();
m_sparseAllocator->setCapacity(info.size / SparseMemoryPageSize);
m_mapped = DxvkBufferSliceHandle();
m_allocation = DxvkBufferAllocation();
m_mapMode = D3D11_COMMON_BUFFER_MAP_MODE_NONE;
}

View File

@ -113,17 +113,17 @@ namespace dxvk {
: DxvkBufferSlice();
}
DxvkBufferSliceHandle AllocSlice() {
return m_buffer->allocSlice();
DxvkBufferAllocation AllocSlice() {
return m_buffer->allocateSlice();
}
DxvkBufferSliceHandle DiscardSlice() {
m_mapped = m_buffer->allocSlice();
return m_mapped;
DxvkBufferAllocation DiscardSlice() {
m_allocation = m_buffer->allocateSlice();
return m_allocation;
}
DxvkBufferSliceHandle GetMappedSlice() const {
return m_mapped;
DxvkBufferAllocation GetMappedSlice() const {
return m_allocation;
}
D3D10Buffer* GetD3D10Iface() {
@ -184,7 +184,7 @@ namespace dxvk {
Rc<DxvkBuffer> m_buffer;
Rc<DxvkBuffer> m_soCounter;
Rc<DxvkSparsePageAllocator> m_sparseAllocator;
DxvkBufferSliceHandle m_mapped;
DxvkBufferAllocation m_allocation;
uint64_t m_seq = 0ull;
D3D11DXGIResource m_resource;

View File

@ -279,13 +279,13 @@ namespace dxvk {
// we may write to the buffer resource directly and
// just swap in the buffer slice as needed.
auto bufferSlice = pBuffer->AllocSlice();
pMappedResource->pData = bufferSlice.mapPtr;
pMappedResource->pData = bufferSlice.mapPtr();
EmitCs([
cDstBuffer = pBuffer->GetBuffer(),
cPhysSlice = bufferSlice
cDstSlice = std::move(bufferSlice)
] (DxvkContext* ctx) {
ctx->invalidateBuffer(cDstBuffer, cPhysSlice);
ctx->invalidateBuffer(cDstBuffer, DxvkBufferAllocation(cDstSlice));
});
} else {
// For GPU-writable resources, we need a data slice
@ -297,9 +297,9 @@ namespace dxvk {
cDstBuffer = pBuffer->GetBuffer(),
cDataSlice = dataSlice
] (DxvkContext* ctx) {
DxvkBufferSliceHandle slice = cDstBuffer->allocSlice();
std::memcpy(slice.mapPtr, cDataSlice.ptr(), cDataSlice.length());
ctx->invalidateBuffer(cDstBuffer, slice);
DxvkBufferAllocation slice = cDstBuffer->allocateSlice();
std::memcpy(slice.mapPtr(), cDataSlice.ptr(), cDataSlice.length());
ctx->invalidateBuffer(cDstBuffer, std::move(slice));
});
}

View File

@ -332,24 +332,23 @@ 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 physSlice = pResource->DiscardSlice();
pMappedResource->pData = physSlice.mapPtr;
auto bufferSlice = pResource->DiscardSlice();
pMappedResource->pData = bufferSlice.mapPtr();
pMappedResource->RowPitch = bufferSize;
pMappedResource->DepthPitch = bufferSize;
EmitCs([
cBuffer = pResource->GetBuffer(),
cBufferSlice = physSlice
] (DxvkContext* ctx) {
ctx->invalidateBuffer(cBuffer, cBufferSlice);
cBufferSlice = std::move(bufferSlice)
] (DxvkContext* ctx) mutable {
ctx->invalidateBuffer(cBuffer, std::move(cBufferSlice));
});
return S_OK;
} else if (likely(MapType == D3D11_MAP_WRITE_NO_OVERWRITE)) {
// Put this on a fast path without any extra checks since it's
// a somewhat desired method to partially update large buffers
DxvkBufferSliceHandle physSlice = pResource->GetMappedSlice();
pMappedResource->pData = physSlice.mapPtr;
pMappedResource->pData = pResource->GetMappedSlice().mapPtr();
pMappedResource->RowPitch = bufferSize;
pMappedResource->DepthPitch = bufferSize;
return S_OK;
@ -377,18 +376,21 @@ namespace dxvk {
}
if (doInvalidatePreserve) {
auto prevSlice = pResource->GetMappedSlice();
auto physSlice = pResource->DiscardSlice();
auto srcSlice = pResource->GetMappedSlice();
auto dstSlice = pResource->DiscardSlice();
auto srcPtr = srcSlice.mapPtr();
auto dstPtr = dstSlice.mapPtr();
EmitCs([
cBuffer = std::move(buffer),
cBufferSlice = physSlice
] (DxvkContext* ctx) {
ctx->invalidateBuffer(cBuffer, cBufferSlice);
cBufferSlice = std::move(dstSlice)
] (DxvkContext* ctx) mutable {
ctx->invalidateBuffer(cBuffer, std::move(cBufferSlice));
});
std::memcpy(physSlice.mapPtr, prevSlice.mapPtr, physSlice.length);
pMappedResource->pData = physSlice.mapPtr;
std::memcpy(dstPtr, srcPtr, bufferSize);
pMappedResource->pData = dstPtr;
pMappedResource->RowPitch = bufferSize;
pMappedResource->DepthPitch = bufferSize;
return S_OK;
@ -396,8 +398,7 @@ namespace dxvk {
if (!WaitForResource(buffer, sequenceNumber, MapType, MapFlags))
return DXGI_ERROR_WAS_STILL_DRAWING;
DxvkBufferSliceHandle physSlice = pResource->GetMappedSlice();
pMappedResource->pData = physSlice.mapPtr;
pMappedResource->pData = pResource->GetMappedSlice().mapPtr();
pMappedResource->RowPitch = bufferSize;
pMappedResource->DepthPitch = bufferSize;
return S_OK;
@ -497,7 +498,7 @@ namespace dxvk {
// Don't implicitly discard large buffers or buffers of images with
// multiple subresources, as that is likely to cause memory issues.
VkDeviceSize bufferSize = pResource->GetMappedSlice(Subresource).length;
VkDeviceSize bufferSize = mappedBuffer->info().size;
if (bufferSize >= m_maxImplicitDiscardSize || pResource->CountSubresources() > 1) {
// Don't check access flags, WaitForResource will return
@ -522,20 +523,23 @@ namespace dxvk {
}
if (doFlags & DoInvalidate) {
DxvkBufferSliceHandle prevSlice = pResource->GetMappedSlice(Subresource);
DxvkBufferSliceHandle physSlice = pResource->DiscardSlice(Subresource);
VkDeviceSize bufferSize = mappedBuffer->info().size;
auto srcSlice = pResource->GetMappedSlice(Subresource);
auto dstSlice = pResource->DiscardSlice(Subresource);
auto srcPtr = srcSlice.mapPtr();
mapPtr = dstSlice.mapPtr();
EmitCs([
cImageBuffer = mappedBuffer,
cBufferSlice = physSlice
] (DxvkContext* ctx) {
ctx->invalidateBuffer(cImageBuffer, cBufferSlice);
cImageBuffer = mappedBuffer,
cImageBufferSlice = std::move(dstSlice)
] (DxvkContext* ctx) mutable {
ctx->invalidateBuffer(cImageBuffer, std::move(cImageBufferSlice));
});
if (doFlags & DoPreserve)
std::memcpy(physSlice.mapPtr, prevSlice.mapPtr, physSlice.length);
mapPtr = physSlice.mapPtr;
std::memcpy(mapPtr, srcPtr, bufferSize);
} else {
if (doFlags & DoWait) {
// We cannot respect DO_NOT_WAIT for buffer-mapped resources since
@ -548,7 +552,7 @@ namespace dxvk {
return DXGI_ERROR_WAS_STILL_DRAWING;
}
mapPtr = pResource->GetMappedSlice(Subresource).mapPtr;
mapPtr = pResource->GetMappedSlice(Subresource).mapPtr();
}
}
@ -696,22 +700,23 @@ namespace dxvk {
UINT Length,
const void* pSrcData,
UINT CopyFlags) {
DxvkBufferSliceHandle slice;
void* mapPtr = nullptr;
if (likely(CopyFlags != D3D11_COPY_NO_OVERWRITE)) {
slice = pDstBuffer->DiscardSlice();
auto bufferSlice = pDstBuffer->DiscardSlice();
mapPtr = bufferSlice.mapPtr();
EmitCs([
cBuffer = pDstBuffer->GetBuffer(),
cBufferSlice = slice
] (DxvkContext* ctx) {
ctx->invalidateBuffer(cBuffer, cBufferSlice);
cBufferSlice = std::move(bufferSlice)
] (DxvkContext* ctx) mutable {
ctx->invalidateBuffer(cBuffer, std::move(cBufferSlice));
});
} else {
slice = pDstBuffer->GetMappedSlice();
mapPtr = pDstBuffer->GetMappedSlice().mapPtr();
}
std::memcpy(reinterpret_cast<char*>(slice.mapPtr) + Offset, pSrcData, Length);
std::memcpy(reinterpret_cast<char*>(mapPtr) + Offset, pSrcData, Length);
}

View File

@ -782,7 +782,7 @@ namespace dxvk {
MappedBuffer result;
result.buffer = m_device->GetDXVKDevice()->createBuffer(info, memType);
result.slice = result.buffer->getSliceHandle();
result.slice = result.buffer->getAllocation();
return result;
}

View File

@ -219,13 +219,13 @@ namespace dxvk {
* \param [in] Subresource Subresource to discard
* \returns Newly allocated mapped buffer slice
*/
DxvkBufferSliceHandle DiscardSlice(UINT Subresource) {
DxvkBufferAllocation DiscardSlice(UINT Subresource) {
if (Subresource < m_buffers.size()) {
DxvkBufferSliceHandle slice = m_buffers[Subresource].buffer->allocSlice();
DxvkBufferAllocation slice = m_buffers[Subresource].buffer->allocateSlice();
m_buffers[Subresource].slice = slice;
return slice;
} else {
return DxvkBufferSliceHandle();
return DxvkBufferAllocation();
}
}
@ -235,10 +235,10 @@ namespace dxvk {
* \param [in] Subresource Subresource index to query
* \returns Currently mapped buffer slice
*/
DxvkBufferSliceHandle GetMappedSlice(UINT Subresource) const {
DxvkBufferAllocation GetMappedSlice(UINT Subresource) const {
return Subresource < m_buffers.size()
? m_buffers[Subresource].slice
: DxvkBufferSliceHandle();
: DxvkBufferAllocation();
}
/**
@ -474,7 +474,7 @@ namespace dxvk {
struct MappedBuffer {
Rc<DxvkBuffer> buffer;
DxvkBufferSliceHandle slice;
DxvkBufferAllocation slice;
std::vector<D3D11_COMMON_TEXTURE_REGION> dirtyRegions;
};

View File

@ -1296,10 +1296,10 @@ namespace dxvk {
uboData.yMax = 0.9215686f;
}
DxvkBufferSliceHandle uboSlice = m_ubo->allocSlice();
memcpy(uboSlice.mapPtr, &uboData, sizeof(uboData));
DxvkBufferAllocation uboSlice = m_ubo->allocateSlice();
memcpy(uboSlice.mapPtr(), &uboData, sizeof(uboData));
ctx->invalidateBuffer(m_ubo, uboSlice);
ctx->invalidateBuffer(m_ubo, std::move(uboSlice));
ctx->setViewports(1, &viewport, &scissor);
ctx->bindShader<VK_SHADER_STAGE_VERTEX_BIT>(Rc<DxvkShader>(m_vs));