1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-05 01:24:14 +01:00

[dxvk] Use DxvkBufferSliceHandle for buffer memory barriers

This commit is contained in:
Philip Rebohle 2019-01-09 15:03:17 +01:00
parent bbb7728b58
commit 17398e47bd
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
3 changed files with 60 additions and 58 deletions

View File

@ -6,7 +6,7 @@ namespace dxvk {
DxvkBarrierSet::~DxvkBarrierSet() { } DxvkBarrierSet::~DxvkBarrierSet() { }
void DxvkBarrierSet::accessBuffer( void DxvkBarrierSet::accessBuffer(
const DxvkPhysicalBufferSlice& bufSlice, const DxvkBufferSliceHandle& bufSlice,
VkPipelineStageFlags srcStages, VkPipelineStageFlags srcStages,
VkAccessFlags srcAccess, VkAccessFlags srcAccess,
VkPipelineStageFlags dstStages, VkPipelineStageFlags dstStages,
@ -24,9 +24,9 @@ namespace dxvk {
barrier.dstAccessMask = dstAccess; barrier.dstAccessMask = dstAccess;
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.buffer = bufSlice.handle(); barrier.buffer = bufSlice.handle;
barrier.offset = bufSlice.offset(); barrier.offset = bufSlice.offset;
barrier.size = bufSlice.length(); barrier.size = bufSlice.length;
m_bufBarriers.push_back(barrier); m_bufBarriers.push_back(barrier);
} }
@ -72,13 +72,16 @@ namespace dxvk {
bool DxvkBarrierSet::isBufferDirty( bool DxvkBarrierSet::isBufferDirty(
const DxvkPhysicalBufferSlice& bufSlice, const DxvkBufferSliceHandle& bufSlice,
DxvkAccessFlags bufAccess) { DxvkAccessFlags bufAccess) {
bool result = false; bool result = false;
for (uint32_t i = 0; i < m_bufSlices.size() && !result; i++) { for (uint32_t i = 0; i < m_bufSlices.size() && !result; i++) {
result = (bufSlice.overlaps(m_bufSlices[i].slice)) const DxvkBufferSliceHandle& dstSlice = m_bufSlices[i].slice;
&& (bufAccess | m_bufSlices[i].access).test(DxvkAccess::Write);
result = (bufSlice.handle == dstSlice.handle) && (bufAccess | m_bufSlices[i].access).test(DxvkAccess::Write)
&& (bufSlice.offset + bufSlice.length > dstSlice.offset)
&& (bufSlice.offset < dstSlice.offset + dstSlice.length);
} }
return result; return result;
@ -95,10 +98,10 @@ namespace dxvk {
const VkImageSubresourceRange& dstSubres = m_imgSlices[i].subres; const VkImageSubresourceRange& dstSubres = m_imgSlices[i].subres;
result = (image == m_imgSlices[i].image) && (imgAccess | m_imgSlices[i].access).test(DxvkAccess::Write) result = (image == m_imgSlices[i].image) && (imgAccess | m_imgSlices[i].access).test(DxvkAccess::Write)
&& imgSubres.baseArrayLayer < dstSubres.baseArrayLayer + dstSubres.layerCount && (imgSubres.baseArrayLayer < dstSubres.baseArrayLayer + dstSubres.layerCount)
&& imgSubres.baseArrayLayer + imgSubres.layerCount > dstSubres.baseArrayLayer && (imgSubres.baseArrayLayer + imgSubres.layerCount > dstSubres.baseArrayLayer)
&& imgSubres.baseMipLevel < dstSubres.baseMipLevel + dstSubres.levelCount && (imgSubres.baseMipLevel < dstSubres.baseMipLevel + dstSubres.levelCount)
&& imgSubres.baseMipLevel + imgSubres.levelCount > dstSubres.baseMipLevel; && (imgSubres.baseMipLevel + imgSubres.levelCount > dstSubres.baseMipLevel);
} }
return result; return result;

View File

@ -21,7 +21,7 @@ namespace dxvk {
~DxvkBarrierSet(); ~DxvkBarrierSet();
void accessBuffer( void accessBuffer(
const DxvkPhysicalBufferSlice& bufSlice, const DxvkBufferSliceHandle& bufSlice,
VkPipelineStageFlags srcStages, VkPipelineStageFlags srcStages,
VkAccessFlags srcAccess, VkAccessFlags srcAccess,
VkPipelineStageFlags dstStages, VkPipelineStageFlags dstStages,
@ -38,7 +38,7 @@ namespace dxvk {
VkAccessFlags dstAccess); VkAccessFlags dstAccess);
bool isBufferDirty( bool isBufferDirty(
const DxvkPhysicalBufferSlice& bufSlice, const DxvkBufferSliceHandle& bufSlice,
DxvkAccessFlags bufAccess); DxvkAccessFlags bufAccess);
bool isImageDirty( bool isImageDirty(
@ -54,7 +54,7 @@ namespace dxvk {
private: private:
struct BufSlice { struct BufSlice {
DxvkPhysicalBufferSlice slice; DxvkBufferSliceHandle slice;
DxvkAccessFlags access; DxvkAccessFlags access;
}; };

View File

@ -259,15 +259,15 @@ namespace dxvk {
if (length == buffer->info().size) if (length == buffer->info().size)
length = align(length, 4); length = align(length, 4);
auto slice = buffer->subSlice(offset, length); auto slice = buffer->getSliceHandle(offset, length);
if (m_barriers.isBufferDirty(slice, DxvkAccess::Write)) if (m_barriers.isBufferDirty(slice, DxvkAccess::Write))
m_barriers.recordCommands(m_cmd); m_barriers.recordCommands(m_cmd);
m_cmd->cmdFillBuffer( m_cmd->cmdFillBuffer(
slice.handle(), slice.handle,
slice.offset(), slice.offset,
slice.length(), slice.length,
value); value);
m_barriers.accessBuffer(slice, m_barriers.accessBuffer(slice,
@ -276,7 +276,7 @@ namespace dxvk {
buffer->info().stages, buffer->info().stages,
buffer->info().access); buffer->info().access);
m_cmd->trackResource(slice.resource()); m_cmd->trackResource(buffer->resource());
} }
@ -288,7 +288,7 @@ namespace dxvk {
this->spillRenderPass(); this->spillRenderPass();
this->unbindComputePipeline(); this->unbindComputePipeline();
auto bufferSlice = bufferView->physicalSlice(); auto bufferSlice = bufferView->getSliceHandle();
if (m_barriers.isBufferDirty(bufferSlice, DxvkAccess::Write)) if (m_barriers.isBufferDirty(bufferSlice, DxvkAccess::Write))
m_barriers.recordCommands(m_cmd); m_barriers.recordCommands(m_cmd);
@ -340,8 +340,7 @@ namespace dxvk {
workgroups.height, workgroups.height,
workgroups.depth); workgroups.depth);
m_barriers.accessBuffer( m_barriers.accessBuffer(bufferSlice,
bufferSlice,
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_SHADER_WRITE_BIT,
bufferView->bufferInfo().stages, bufferView->bufferInfo().stages,
@ -629,21 +628,21 @@ namespace dxvk {
this->spillRenderPass(); this->spillRenderPass();
auto dstSlice = dstBuffer->subSlice(dstOffset, numBytes); auto dstSlice = dstBuffer->getSliceHandle(dstOffset, numBytes);
auto srcSlice = srcBuffer->subSlice(srcOffset, numBytes); auto srcSlice = srcBuffer->getSliceHandle(srcOffset, numBytes);
if (m_barriers.isBufferDirty(srcSlice, DxvkAccess::Read) if (m_barriers.isBufferDirty(srcSlice, DxvkAccess::Read)
|| m_barriers.isBufferDirty(dstSlice, DxvkAccess::Write)) || m_barriers.isBufferDirty(dstSlice, DxvkAccess::Write))
m_barriers.recordCommands(m_cmd); m_barriers.recordCommands(m_cmd);
VkBufferCopy bufferRegion; VkBufferCopy bufferRegion;
bufferRegion.srcOffset = srcSlice.offset(); bufferRegion.srcOffset = srcSlice.offset;
bufferRegion.dstOffset = dstSlice.offset(); bufferRegion.dstOffset = dstSlice.offset;
bufferRegion.size = dstSlice.length(); bufferRegion.size = dstSlice.length;
m_cmd->cmdCopyBuffer( m_cmd->cmdCopyBuffer(
srcSlice.handle(), srcSlice.handle,
dstSlice.handle(), dstSlice.handle,
1, &bufferRegion); 1, &bufferRegion);
m_barriers.accessBuffer(srcSlice, m_barriers.accessBuffer(srcSlice,
@ -703,7 +702,7 @@ namespace dxvk {
VkExtent2D srcExtent) { VkExtent2D srcExtent) {
this->spillRenderPass(); this->spillRenderPass();
auto srcSlice = srcBuffer->subSlice(srcOffset, 0); auto srcSlice = srcBuffer->getSliceHandle(srcOffset, 0);
// We may copy to only one aspect of a depth-stencil image, // We may copy to only one aspect of a depth-stencil image,
// but pipeline barriers need to have all aspect bits set // but pipeline barriers need to have all aspect bits set
@ -733,7 +732,7 @@ namespace dxvk {
m_transitions.recordCommands(m_cmd); m_transitions.recordCommands(m_cmd);
VkBufferImageCopy copyRegion; VkBufferImageCopy copyRegion;
copyRegion.bufferOffset = srcSlice.offset(); copyRegion.bufferOffset = srcSlice.offset;
copyRegion.bufferRowLength = srcExtent.width; copyRegion.bufferRowLength = srcExtent.width;
copyRegion.bufferImageHeight = srcExtent.height; copyRegion.bufferImageHeight = srcExtent.height;
copyRegion.imageSubresource = dstSubresource; copyRegion.imageSubresource = dstSubresource;
@ -741,7 +740,7 @@ namespace dxvk {
copyRegion.imageExtent = dstExtent; copyRegion.imageExtent = dstExtent;
m_cmd->cmdCopyBufferToImage( m_cmd->cmdCopyBufferToImage(
srcSlice.handle(), srcSlice.handle,
dstImage->handle(), dstImage->handle(),
dstImageLayoutTransfer, dstImageLayoutTransfer,
1, &copyRegion); 1, &copyRegion);
@ -762,7 +761,7 @@ namespace dxvk {
srcBuffer->info().access); srcBuffer->info().access);
m_cmd->trackResource(dstImage); m_cmd->trackResource(dstImage);
m_cmd->trackResource(srcSlice.resource()); m_cmd->trackResource(srcBuffer->resource());
} }
@ -866,7 +865,7 @@ namespace dxvk {
VkExtent3D srcExtent) { VkExtent3D srcExtent) {
this->spillRenderPass(); this->spillRenderPass();
auto dstSlice = dstBuffer->subSlice(dstOffset, 0); auto dstSlice = dstBuffer->getSliceHandle(dstOffset, 0);
// We may copy to only one aspect of a depth-stencil image, // We may copy to only one aspect of a depth-stencil image,
// but pipeline barriers need to have all aspect bits set // but pipeline barriers need to have all aspect bits set
@ -892,7 +891,7 @@ namespace dxvk {
m_transitions.recordCommands(m_cmd); m_transitions.recordCommands(m_cmd);
VkBufferImageCopy copyRegion; VkBufferImageCopy copyRegion;
copyRegion.bufferOffset = dstSlice.offset(); copyRegion.bufferOffset = dstSlice.offset;
copyRegion.bufferRowLength = dstExtent.width; copyRegion.bufferRowLength = dstExtent.width;
copyRegion.bufferImageHeight = dstExtent.height; copyRegion.bufferImageHeight = dstExtent.height;
copyRegion.imageSubresource = srcSubresource; copyRegion.imageSubresource = srcSubresource;
@ -902,7 +901,7 @@ namespace dxvk {
m_cmd->cmdCopyImageToBuffer( m_cmd->cmdCopyImageToBuffer(
srcImage->handle(), srcImage->handle(),
srcImageLayoutTransfer, srcImageLayoutTransfer,
dstSlice.handle(), dstSlice.handle,
1, &copyRegion); 1, &copyRegion);
m_barriers.accessImage( m_barriers.accessImage(
@ -921,7 +920,7 @@ namespace dxvk {
dstBuffer->info().access); dstBuffer->info().access);
m_cmd->trackResource(srcImage); m_cmd->trackResource(srcImage);
m_cmd->trackResource(dstSlice.resource()); m_cmd->trackResource(dstBuffer->resource());
} }
@ -1021,7 +1020,7 @@ namespace dxvk {
srcImage->info().access); srcImage->info().access);
m_barriers.accessBuffer( m_barriers.accessBuffer(
dstBuffer->slice(), dstBuffer->getSliceHandle(),
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_SHADER_WRITE_BIT,
dstBuffer->info().stages, dstBuffer->info().stages,
@ -1037,7 +1036,7 @@ namespace dxvk {
void DxvkContext::discardBuffer( void DxvkContext::discardBuffer(
const Rc<DxvkBuffer>& buffer) { const Rc<DxvkBuffer>& buffer) {
if (m_barriers.isBufferDirty(buffer->slice(), DxvkAccess::Write)) if (m_barriers.isBufferDirty(buffer->getSliceHandle(), DxvkAccess::Write))
this->invalidateBuffer(buffer, buffer->allocPhysicalSlice()); this->invalidateBuffer(buffer, buffer->allocPhysicalSlice());
} }
@ -1088,10 +1087,10 @@ namespace dxvk {
VkDeviceSize offset) { VkDeviceSize offset) {
this->commitComputeState(); this->commitComputeState();
auto physicalSlice = m_state.id.argBuffer.physicalSlice() auto bufferSlice = m_state.id.argBuffer.getSliceHandle(
.subSlice(offset, sizeof(VkDispatchIndirectCommand)); offset, sizeof(VkDispatchIndirectCommand));
if (m_barriers.isBufferDirty(physicalSlice, DxvkAccess::Read)) if (m_barriers.isBufferDirty(bufferSlice, DxvkAccess::Read))
m_barriers.recordCommands(m_cmd); m_barriers.recordCommands(m_cmd);
if (this->validateComputeState()) { if (this->validateComputeState()) {
@ -1101,15 +1100,15 @@ namespace dxvk {
VK_QUERY_TYPE_PIPELINE_STATISTICS); VK_QUERY_TYPE_PIPELINE_STATISTICS);
m_cmd->cmdDispatchIndirect( m_cmd->cmdDispatchIndirect(
physicalSlice.handle(), bufferSlice.handle,
physicalSlice.offset()); bufferSlice.offset);
m_queries.endQueries(m_cmd, m_queries.endQueries(m_cmd,
VK_QUERY_TYPE_PIPELINE_STATISTICS); VK_QUERY_TYPE_PIPELINE_STATISTICS);
this->commitComputePostBarriers(); this->commitComputePostBarriers();
m_barriers.accessBuffer(physicalSlice, m_barriers.accessBuffer(bufferSlice,
VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT,
VK_ACCESS_INDIRECT_COMMAND_READ_BIT, VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
m_state.id.argBuffer.bufferInfo().stages, m_state.id.argBuffer.bufferInfo().stages,
@ -1444,30 +1443,30 @@ namespace dxvk {
// four. Anything else must be copied through a staging buffer. // four. Anything else must be copied through a staging buffer.
// We'll limit the size to 4kB in order to keep command buffers // We'll limit the size to 4kB in order to keep command buffers
// reasonably small, we do not know how much data apps may upload. // reasonably small, we do not know how much data apps may upload.
auto physicalSlice = buffer->subSlice(offset, size); auto bufferSlice = buffer->getSliceHandle(offset, size);
if (m_barriers.isBufferDirty(physicalSlice, DxvkAccess::Write)) if (m_barriers.isBufferDirty(bufferSlice, DxvkAccess::Write))
m_barriers.recordCommands(m_cmd); m_barriers.recordCommands(m_cmd);
if ((size <= 4096) && ((size & 0x3) == 0) && ((offset & 0x3) == 0)) { if ((size <= 4096) && ((size & 0x3) == 0) && ((offset & 0x3) == 0)) {
m_cmd->cmdUpdateBuffer( m_cmd->cmdUpdateBuffer(
physicalSlice.handle(), bufferSlice.handle,
physicalSlice.offset(), bufferSlice.offset,
physicalSlice.length(), bufferSlice.length,
data); 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(
physicalSlice.handle(), bufferSlice.handle,
physicalSlice.offset(), bufferSlice.offset,
physicalSlice.length(), bufferSlice.length,
slice); slice);
} }
m_barriers.accessBuffer( m_barriers.accessBuffer(
physicalSlice, bufferSlice,
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,
@ -3133,7 +3132,7 @@ namespace dxvk {
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
requiresBarrier = m_barriers.isBufferDirty( requiresBarrier = m_barriers.isBufferDirty(
slot.bufferSlice.physicalSlice(), access); slot.bufferSlice.getSliceHandle(), access);
break; break;
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
@ -3143,7 +3142,7 @@ namespace dxvk {
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
requiresBarrier = m_barriers.isBufferDirty( requiresBarrier = m_barriers.isBufferDirty(
slot.bufferView->physicalSlice(), access); slot.bufferView->getSliceHandle(), access);
break; break;
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
@ -3190,7 +3189,7 @@ namespace dxvk {
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
m_barriers.accessBuffer( m_barriers.accessBuffer(
slot.bufferSlice.physicalSlice(), slot.bufferSlice.getSliceHandle(),
stages, access, stages, access,
slot.bufferSlice.bufferInfo().stages, slot.bufferSlice.bufferInfo().stages,
slot.bufferSlice.bufferInfo().access); slot.bufferSlice.bufferInfo().access);
@ -3203,7 +3202,7 @@ namespace dxvk {
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
m_barriers.accessBuffer( m_barriers.accessBuffer(
slot.bufferView->physicalSlice(), slot.bufferView->getSliceHandle(),
stages, access, stages, access,
slot.bufferView->bufferInfo().stages, slot.bufferView->bufferInfo().stages,
slot.bufferView->bufferInfo().access); slot.bufferView->bufferInfo().access);