1
0
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:
Philip Rebohle 2018-01-18 18:33:13 +01:00
parent 3212fc7444
commit 6e6c290e01
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
6 changed files with 51 additions and 40 deletions

View File

@ -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(),

View File

@ -26,7 +26,7 @@ namespace dxvk {
D3D11UnorderedAccessView::~D3D11UnorderedAccessView() {
if (m_counterSlice.handle() != VK_NULL_HANDLE)
if (m_counterSlice.defined())
m_device->FreeCounterSlice(m_counterSlice);
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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, &copyRegion);
@ -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,

View File

@ -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;