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