mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-06 20:58:37 +01:00
[dxvk] Add barrier helpers for granular image access tracking
This commit is contained in:
parent
1be692801a
commit
d683c3f3df
2 changed files with 188 additions and 0 deletions
|
@ -7972,6 +7972,91 @@ namespace dxvk {
|
|||
}
|
||||
|
||||
|
||||
void DxvkContext::accessImageRegion(
|
||||
DxvkCmdBuffer cmdBuffer,
|
||||
DxvkImage& image,
|
||||
const VkImageSubresourceLayers& subresources,
|
||||
VkOffset3D offset,
|
||||
VkExtent3D extent,
|
||||
VkImageLayout srcLayout,
|
||||
VkPipelineStageFlags2 srcStages,
|
||||
VkAccessFlags2 srcAccess,
|
||||
DxvkAccessOp accessOp) {
|
||||
accessImageRegion(cmdBuffer, image, subresources,
|
||||
offset, extent, srcLayout, srcStages, srcAccess,
|
||||
image.info().layout, image.info().stages, image.info().access,
|
||||
accessOp);
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::accessImageRegion(
|
||||
DxvkCmdBuffer cmdBuffer,
|
||||
DxvkImage& image,
|
||||
const VkImageSubresourceLayers& subresources,
|
||||
VkOffset3D offset,
|
||||
VkExtent3D extent,
|
||||
VkImageLayout srcLayout,
|
||||
VkPipelineStageFlags2 srcStages,
|
||||
VkAccessFlags2 srcAccess,
|
||||
VkImageLayout dstLayout,
|
||||
VkPipelineStageFlags2 dstStages,
|
||||
VkAccessFlags2 dstAccess,
|
||||
DxvkAccessOp accessOp) {
|
||||
// If the image layout needs to change, access the entire image
|
||||
if (srcLayout != dstLayout) {
|
||||
accessImage(cmdBuffer, image, vk::makeSubresourceRange(subresources),
|
||||
srcLayout, srcStages, srcAccess,
|
||||
dstLayout, dstStages, dstAccess, accessOp);
|
||||
return;
|
||||
}
|
||||
|
||||
// No layout transition, just emit a plain memory barrier
|
||||
auto& batch = getBarrierBatch(cmdBuffer);
|
||||
|
||||
VkMemoryBarrier2 barrier = { VK_STRUCTURE_TYPE_MEMORY_BARRIER_2 };
|
||||
barrier.srcStageMask = srcStages;
|
||||
barrier.srcAccessMask = srcAccess;
|
||||
barrier.dstStageMask = dstStages;
|
||||
barrier.dstAccessMask = dstAccess;
|
||||
|
||||
batch.addMemoryBarrier(barrier);
|
||||
|
||||
if (cmdBuffer == DxvkCmdBuffer::ExecBuffer) {
|
||||
bool hasWrite = (srcAccess & vk::AccessWriteMask) || (srcLayout != dstLayout);
|
||||
bool hasRead = (srcAccess & vk::AccessReadMask);
|
||||
|
||||
DxvkAddressRange range;
|
||||
range.resource = image.getResourceId();
|
||||
range.accessOp = accessOp;
|
||||
|
||||
if (extent == image.mipLevelExtent(subresources.mipLevel)) {
|
||||
range.rangeStart = image.getTrackingAddress(subresources.mipLevel, subresources.baseArrayLayer);
|
||||
range.rangeEnd = image.getTrackingAddress(subresources.mipLevel, subresources.baseArrayLayer + subresources.layerCount) - 1u;
|
||||
|
||||
if (hasWrite)
|
||||
m_barrierTracker.insertRange(range, DxvkAccess::Write);
|
||||
if (hasRead)
|
||||
m_barrierTracker.insertRange(range, DxvkAccess::Read);
|
||||
} else {
|
||||
VkOffset3D maxCoord = offset;
|
||||
maxCoord.x += extent.width - 1u;
|
||||
maxCoord.y += extent.height - 1u;
|
||||
maxCoord.z += extent.depth - 1u;
|
||||
|
||||
for (uint32_t i = subresources.baseArrayLayer; i < subresources.baseArrayLayer + subresources.layerCount; i++) {
|
||||
range.rangeStart = image.getTrackingAddress(subresources.mipLevel, i, offset);
|
||||
range.rangeEnd = image.getTrackingAddress(subresources.mipLevel, i, maxCoord);
|
||||
|
||||
if (hasWrite)
|
||||
m_barrierTracker.insertRange(range, DxvkAccess::Write);
|
||||
if (hasRead)
|
||||
m_barrierTracker.insertRange(range, DxvkAccess::Read);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::accessBuffer(
|
||||
DxvkCmdBuffer cmdBuffer,
|
||||
DxvkBuffer& buffer,
|
||||
|
@ -8163,6 +8248,25 @@ namespace dxvk {
|
|||
}
|
||||
|
||||
|
||||
void DxvkContext::flushPendingAccesses(
|
||||
DxvkImage& image,
|
||||
const VkImageSubresourceLayers& subresources,
|
||||
VkOffset3D offset,
|
||||
VkExtent3D extent,
|
||||
DxvkAccess access) {
|
||||
bool flush = resourceHasAccess(image, subresources,
|
||||
offset, extent, DxvkAccess::Write, DxvkAccessOp::None);
|
||||
|
||||
if (access == DxvkAccess::Write && !flush) {
|
||||
flush = resourceHasAccess(image, subresources,
|
||||
offset, extent, DxvkAccess::Read, DxvkAccessOp::None);
|
||||
}
|
||||
|
||||
if (flush)
|
||||
flushBarriers();
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::flushPendingAccesses(
|
||||
DxvkImageView& imageView,
|
||||
DxvkAccess access) {
|
||||
|
@ -8247,6 +8351,50 @@ namespace dxvk {
|
|||
}
|
||||
|
||||
|
||||
bool DxvkContext::resourceHasAccess(
|
||||
DxvkImage& image,
|
||||
const VkImageSubresourceLayers& subresources,
|
||||
VkOffset3D offset,
|
||||
VkExtent3D extent,
|
||||
DxvkAccess access,
|
||||
DxvkAccessOp accessOp) {
|
||||
DxvkAddressRange range;
|
||||
range.resource = image.getResourceId();
|
||||
range.accessOp = accessOp;
|
||||
|
||||
// If there are multiple subresources, check whether any of them have been
|
||||
// touched before checking individual regions. If the given region covers
|
||||
// the entire image, there is also no need to check more granularly.
|
||||
bool isFullSize = image.mipLevelExtent(subresources.mipLevel) == extent;
|
||||
|
||||
if (subresources.layerCount > 1u || isFullSize) {
|
||||
range.rangeStart = image.getTrackingAddress(subresources.mipLevel, subresources.baseArrayLayer);
|
||||
range.rangeEnd = image.getTrackingAddress(subresources.mipLevel, subresources.baseArrayLayer + subresources.layerCount) - 1u;
|
||||
|
||||
bool dirty = m_barrierTracker.findRange(range, access);
|
||||
|
||||
if (!dirty || isFullSize)
|
||||
return dirty;
|
||||
}
|
||||
|
||||
// Check given image region in each subresource
|
||||
VkOffset3D maxCoord = offset;
|
||||
maxCoord.x += extent.width - 1u;
|
||||
maxCoord.y += extent.height - 1u;
|
||||
maxCoord.z += extent.depth - 1u;
|
||||
|
||||
for (uint32_t i = subresources.baseArrayLayer; i < subresources.baseArrayLayer + subresources.layerCount; i++) {
|
||||
range.rangeStart = image.getTrackingAddress(subresources.mipLevel, i, offset);
|
||||
range.rangeEnd = image.getTrackingAddress(subresources.mipLevel, i, maxCoord);
|
||||
|
||||
if (m_barrierTracker.findRange(range, access))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool DxvkContext::resourceHasAccess(
|
||||
DxvkImageView& imageView,
|
||||
DxvkAccess access,
|
||||
|
|
|
@ -1948,6 +1948,31 @@ namespace dxvk {
|
|||
VkAccessFlags2 dstAccess,
|
||||
DxvkAccessOp accessOp);
|
||||
|
||||
void accessImageRegion(
|
||||
DxvkCmdBuffer cmdBuffer,
|
||||
DxvkImage& image,
|
||||
const VkImageSubresourceLayers& subresources,
|
||||
VkOffset3D offset,
|
||||
VkExtent3D extent,
|
||||
VkImageLayout srcLayout,
|
||||
VkPipelineStageFlags2 srcStages,
|
||||
VkAccessFlags2 srcAccess,
|
||||
DxvkAccessOp accessOp);
|
||||
|
||||
void accessImageRegion(
|
||||
DxvkCmdBuffer cmdBuffer,
|
||||
DxvkImage& image,
|
||||
const VkImageSubresourceLayers& subresources,
|
||||
VkOffset3D offset,
|
||||
VkExtent3D extent,
|
||||
VkImageLayout srcLayout,
|
||||
VkPipelineStageFlags2 srcStages,
|
||||
VkAccessFlags2 srcAccess,
|
||||
VkImageLayout dstLayout,
|
||||
VkPipelineStageFlags2 dstStages,
|
||||
VkAccessFlags2 dstAccess,
|
||||
DxvkAccessOp accessOp);
|
||||
|
||||
void accessBuffer(
|
||||
DxvkCmdBuffer cmdBuffer,
|
||||
DxvkBuffer& buffer,
|
||||
|
@ -2024,6 +2049,13 @@ namespace dxvk {
|
|||
const VkImageSubresourceRange& subresources,
|
||||
DxvkAccess access);
|
||||
|
||||
void flushPendingAccesses(
|
||||
DxvkImage& image,
|
||||
const VkImageSubresourceLayers& subresources,
|
||||
VkOffset3D offset,
|
||||
VkExtent3D extent,
|
||||
DxvkAccess access);
|
||||
|
||||
void flushPendingAccesses(
|
||||
DxvkImageView& imageView,
|
||||
DxvkAccess access);
|
||||
|
@ -2048,6 +2080,14 @@ namespace dxvk {
|
|||
DxvkAccess access,
|
||||
DxvkAccessOp accessOp);
|
||||
|
||||
bool resourceHasAccess(
|
||||
DxvkImage& image,
|
||||
const VkImageSubresourceLayers& subresources,
|
||||
VkOffset3D offset,
|
||||
VkExtent3D extent,
|
||||
DxvkAccess access,
|
||||
DxvkAccessOp accessOp);
|
||||
|
||||
bool resourceHasAccess(
|
||||
DxvkImageView& imageView,
|
||||
DxvkAccess access,
|
||||
|
|
Loading…
Add table
Reference in a new issue