mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-11 01:24:12 +01:00
[d3d11] Use DxvkPhysicalBufferSlice for resource copies and buffer views
This commit is contained in:
parent
3212fc7444
commit
6e6c290e01
@ -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(),
|
||||
|
@ -26,7 +26,7 @@ namespace dxvk {
|
||||
|
||||
|
||||
D3D11UnorderedAccessView::~D3D11UnorderedAccessView() {
|
||||
if (m_counterSlice.handle() != VK_NULL_HANDLE)
|
||||
if (m_counterSlice.defined())
|
||||
m_device->FreeCounterSlice(m_counterSlice);
|
||||
}
|
||||
|
||||
|
@ -30,21 +30,33 @@ namespace dxvk {
|
||||
const Rc<DxvkBuffer>& 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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user