diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 3636db34..d157d033 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -2004,7 +2004,7 @@ namespace dxvk { const DxvkBufferSlice counterSlice = uav->GetCounterSlice(); const D3D11UavCounter counterValue = { pUAVInitialCounts[i] }; - if (counterSlice.handle() != VK_NULL_HANDLE + if (counterSlice.defined() && counterValue.atomicCtr != 0xFFFFFFFFu) { m_context->updateBuffer( counterSlice.buffer(), diff --git a/src/d3d11/d3d11_uav.cpp b/src/d3d11/d3d11_uav.cpp index cf10c959..f1f4544c 100644 --- a/src/d3d11/d3d11_uav.cpp +++ b/src/d3d11/d3d11_uav.cpp @@ -26,7 +26,7 @@ namespace dxvk { D3D11UnorderedAccessView::~D3D11UnorderedAccessView() { - if (m_counterSlice.handle() != VK_NULL_HANDLE) + if (m_counterSlice.defined()) m_device->FreeCounterSlice(m_counterSlice); } diff --git a/src/dxvk/dxvk_buffer.cpp b/src/dxvk/dxvk_buffer.cpp index 58d9112e..240e8d00 100644 --- a/src/dxvk/dxvk_buffer.cpp +++ b/src/dxvk/dxvk_buffer.cpp @@ -30,21 +30,33 @@ namespace dxvk { const Rc& buffer, const DxvkBufferViewCreateInfo& info) : m_vkd(vkd), m_buffer(buffer), m_info(info) { + this->createBufferView(); + } + + + DxvkBufferView::~DxvkBufferView() { + this->destroyBufferView(); + } + + + void DxvkBufferView::createBufferView() { + auto physicalSlice = this->slice(); + VkBufferViewCreateInfo viewInfo; viewInfo.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO; viewInfo.pNext = nullptr; viewInfo.flags = 0; - viewInfo.buffer = buffer->handle(); - viewInfo.format = info.format; - viewInfo.offset = info.rangeOffset; - viewInfo.range = info.rangeLength; + viewInfo.buffer = physicalSlice.handle(); + viewInfo.format = m_info.format; + viewInfo.offset = physicalSlice.offset(); + viewInfo.range = physicalSlice.length(); if (m_vkd->vkCreateBufferView(m_vkd->device(), &viewInfo, nullptr, &m_view) != VK_SUCCESS) throw DxvkError("DxvkBufferView::DxvkBufferView: Failed to create buffer view"); } - DxvkBufferView::~DxvkBufferView() { + void DxvkBufferView::destroyBufferView() { m_vkd->vkDestroyBufferView( m_vkd->device(), m_view, nullptr); } diff --git a/src/dxvk/dxvk_buffer.h b/src/dxvk/dxvk_buffer.h index da217e61..9276e159 100644 --- a/src/dxvk/dxvk_buffer.h +++ b/src/dxvk/dxvk_buffer.h @@ -39,14 +39,6 @@ namespace dxvk { return m_memFlags; } - /** - * \brief Buffer handle - * \returns Buffer handle - */ - VkBuffer handle() const { - return m_resource.handle(); - } - /** * \brief Map pointer * @@ -195,6 +187,9 @@ namespace dxvk { DxvkBufferViewCreateInfo m_info; VkBufferView m_view; + void createBufferView(); + void destroyBufferView(); + }; @@ -240,12 +235,6 @@ namespace dxvk { : 0; } - VkBuffer handle() const { - return m_buffer != nullptr - ? m_buffer->handle() - : VK_NULL_HANDLE; - } - size_t offset() const { return m_offset; } diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 1c733c68..f80a2f70 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -262,25 +262,26 @@ namespace dxvk { if (numBytes != 0) { this->renderPassEnd(); + auto dstSlice = dstBuffer->subSlice(dstOffset, numBytes); + auto srcSlice = srcBuffer->subSlice(srcOffset, numBytes); + VkBufferCopy bufferRegion; - bufferRegion.srcOffset = srcOffset; - bufferRegion.dstOffset = dstOffset; - bufferRegion.size = numBytes; + bufferRegion.srcOffset = srcSlice.offset(); + bufferRegion.dstOffset = dstSlice.offset(); + bufferRegion.size = dstSlice.length(); m_cmd->cmdCopyBuffer( - srcBuffer->handle(), - dstBuffer->handle(), + srcSlice.handle(), + dstSlice.handle(), 1, &bufferRegion); - m_barriers.accessBuffer( - srcBuffer->subSlice(srcOffset, numBytes), + m_barriers.accessBuffer(srcSlice, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_READ_BIT, srcBuffer->info().stages, srcBuffer->info().access); - m_barriers.accessBuffer( - dstBuffer->subSlice(dstOffset, numBytes), + m_barriers.accessBuffer(dstSlice, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, dstBuffer->info().stages, @@ -304,6 +305,8 @@ namespace dxvk { VkExtent2D srcExtent) { this->renderPassEnd(); + auto srcSlice = srcBuffer->subSlice(srcOffset, 0); + const VkImageSubresourceRange dstSubresourceRange = { dstSubresource.aspectMask, dstSubresource.mipLevel, 1, @@ -331,7 +334,7 @@ namespace dxvk { copyRegion.imageExtent = dstExtent; m_cmd->cmdCopyBufferToImage( - srcBuffer->handle(), + srcSlice.handle(), dstImage->handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©Region); @@ -347,7 +350,7 @@ namespace dxvk { m_barriers.recordCommands(m_cmd); m_cmd->trackResource(dstImage); - m_cmd->trackResource(srcBuffer->resource()); + m_cmd->trackResource(srcSlice.resource()); } @@ -639,6 +642,8 @@ namespace dxvk { this->renderPassEnd(); if (size != 0) { + auto physicalSlice = buffer->subSlice(offset, size); + // Vulkan specifies that small amounts of data (up to 64kB) can // be copied to a buffer directly if the size is a multiple of // four. Anything else must be copied through a staging buffer. @@ -646,19 +651,23 @@ namespace dxvk { // reasonably small, we do not know how much data apps may upload. if ((size <= 4096) && ((size & 0x3) == 0) && ((offset & 0x3) == 0)) { m_cmd->cmdUpdateBuffer( - buffer->handle(), - offset, size, data); + physicalSlice.handle(), + physicalSlice.offset(), + physicalSlice.length(), + data); } else { auto slice = m_cmd->stagedAlloc(size); std::memcpy(slice.mapPtr, data, size); m_cmd->stagedBufferCopy( - buffer->handle(), - offset, size, slice); + physicalSlice.handle(), + physicalSlice.offset(), + physicalSlice.length(), + slice); } m_barriers.accessBuffer( - buffer->subSlice(offset, size), + physicalSlice, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, buffer->info().stages, diff --git a/src/dxvk/dxvk_staging.cpp b/src/dxvk/dxvk_staging.cpp index 6f27d419..2d7c8d6d 100644 --- a/src/dxvk/dxvk_staging.cpp +++ b/src/dxvk/dxvk_staging.cpp @@ -31,9 +31,10 @@ namespace dxvk { if (m_bufferOffset + size > m_bufferSize) return false; - slice.buffer = m_buffer->handle(); - slice.offset = m_bufferOffset; - slice.mapPtr = m_buffer->mapPtr(m_bufferOffset); + auto physicalSlice = m_buffer->subSlice(m_bufferOffset, size); + slice.buffer = physicalSlice.handle(); + slice.offset = physicalSlice.offset(); + slice.mapPtr = physicalSlice.mapPtr(0); m_bufferOffset = align(m_bufferOffset + size, 64); return true;