summaryrefslogtreecommitdiffstats
path: root/src/libs/dxvk-native-1.9.2a/src/dxvk/dxvk_barrier.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/dxvk-native-1.9.2a/src/dxvk/dxvk_barrier.cpp')
-rw-r--r--src/libs/dxvk-native-1.9.2a/src/dxvk/dxvk_barrier.cpp288
1 files changed, 288 insertions, 0 deletions
diff --git a/src/libs/dxvk-native-1.9.2a/src/dxvk/dxvk_barrier.cpp b/src/libs/dxvk-native-1.9.2a/src/dxvk/dxvk_barrier.cpp
new file mode 100644
index 00000000..b0be24d0
--- /dev/null
+++ b/src/libs/dxvk-native-1.9.2a/src/dxvk/dxvk_barrier.cpp
@@ -0,0 +1,288 @@
+#include "dxvk_barrier.h"
+
+namespace dxvk {
+
+ DxvkBarrierSet:: DxvkBarrierSet(DxvkCmdBuffer cmdBuffer)
+ : m_cmdBuffer(cmdBuffer) {
+
+ }
+
+
+ DxvkBarrierSet::~DxvkBarrierSet() {
+
+ }
+
+
+ void DxvkBarrierSet::accessMemory(
+ VkPipelineStageFlags srcStages,
+ VkAccessFlags srcAccess,
+ VkPipelineStageFlags dstStages,
+ VkAccessFlags dstAccess) {
+ m_srcStages |= srcStages;
+ m_dstStages |= dstStages;
+
+ m_srcAccess |= srcAccess;
+ m_dstAccess |= dstAccess;
+ }
+
+
+ void DxvkBarrierSet::accessBuffer(
+ const DxvkBufferSliceHandle& bufSlice,
+ VkPipelineStageFlags srcStages,
+ VkAccessFlags srcAccess,
+ VkPipelineStageFlags dstStages,
+ VkAccessFlags dstAccess) {
+ DxvkAccessFlags access = this->getAccessTypes(srcAccess);
+
+ if (srcStages == VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT
+ || dstStages == VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT)
+ access.set(DxvkAccess::Write);
+
+ m_srcStages |= srcStages;
+ m_dstStages |= dstStages;
+
+ m_srcAccess |= srcAccess;
+ m_dstAccess |= dstAccess;
+
+ m_bufSlices.insert(bufSlice.handle,
+ DxvkBarrierBufferSlice(bufSlice.offset, bufSlice.length, access));
+ }
+
+
+ void DxvkBarrierSet::accessImage(
+ const Rc<DxvkImage>& image,
+ const VkImageSubresourceRange& subresources,
+ VkImageLayout srcLayout,
+ VkPipelineStageFlags srcStages,
+ VkAccessFlags srcAccess,
+ VkImageLayout dstLayout,
+ VkPipelineStageFlags dstStages,
+ VkAccessFlags dstAccess) {
+ DxvkAccessFlags access = this->getAccessTypes(srcAccess);
+
+ if (srcStages == VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT
+ || dstStages == VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
+ || srcLayout != dstLayout)
+ access.set(DxvkAccess::Write);
+
+ m_srcStages |= srcStages;
+ m_dstStages |= dstStages;
+
+ if (srcLayout == dstLayout) {
+ m_srcAccess |= srcAccess;
+ m_dstAccess |= dstAccess;
+ } else {
+ VkImageMemoryBarrier barrier;
+ barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+ barrier.pNext = nullptr;
+ barrier.srcAccessMask = srcAccess;
+ barrier.dstAccessMask = dstAccess;
+ barrier.oldLayout = srcLayout;
+ barrier.newLayout = dstLayout;
+ barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ barrier.image = image->handle();
+ barrier.subresourceRange = subresources;
+ barrier.subresourceRange.aspectMask = image->formatInfo()->aspectMask;
+ m_imgBarriers.push_back(barrier);
+ }
+
+ m_imgSlices.insert(image->handle(),
+ DxvkBarrierImageSlice(subresources, access));
+ }
+
+
+ void DxvkBarrierSet::releaseBuffer(
+ DxvkBarrierSet& acquire,
+ const DxvkBufferSliceHandle& bufSlice,
+ uint32_t srcQueue,
+ VkPipelineStageFlags srcStages,
+ VkAccessFlags srcAccess,
+ uint32_t dstQueue,
+ VkPipelineStageFlags dstStages,
+ VkAccessFlags dstAccess) {
+ auto& release = *this;
+
+ release.m_srcStages |= srcStages;
+ acquire.m_dstStages |= dstStages;
+
+ VkBufferMemoryBarrier barrier;
+ barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
+ barrier.pNext = nullptr;
+ barrier.srcAccessMask = srcAccess;
+ barrier.dstAccessMask = 0;
+ barrier.srcQueueFamilyIndex = srcQueue;
+ barrier.dstQueueFamilyIndex = dstQueue;
+ barrier.buffer = bufSlice.handle;
+ barrier.offset = bufSlice.offset;
+ barrier.size = bufSlice.length;
+ release.m_bufBarriers.push_back(barrier);
+
+ barrier.srcAccessMask = 0;
+ barrier.dstAccessMask = dstAccess;
+ acquire.m_bufBarriers.push_back(barrier);
+
+ DxvkAccessFlags access(DxvkAccess::Read, DxvkAccess::Write);
+ release.m_bufSlices.insert(bufSlice.handle,
+ DxvkBarrierBufferSlice(bufSlice.offset, bufSlice.length, access));
+ acquire.m_bufSlices.insert(bufSlice.handle,
+ DxvkBarrierBufferSlice(bufSlice.offset, bufSlice.length, access));
+ }
+
+
+ void DxvkBarrierSet::releaseImage(
+ DxvkBarrierSet& acquire,
+ const Rc<DxvkImage>& image,
+ const VkImageSubresourceRange& subresources,
+ uint32_t srcQueue,
+ VkImageLayout srcLayout,
+ VkPipelineStageFlags srcStages,
+ VkAccessFlags srcAccess,
+ uint32_t dstQueue,
+ VkImageLayout dstLayout,
+ VkPipelineStageFlags dstStages,
+ VkAccessFlags dstAccess) {
+ auto& release = *this;
+
+ release.m_srcStages |= srcStages;
+ acquire.m_dstStages |= dstStages;
+
+ VkImageMemoryBarrier barrier;
+ barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+ barrier.pNext = nullptr;
+ barrier.srcAccessMask = srcAccess;
+ barrier.dstAccessMask = 0;
+ barrier.oldLayout = srcLayout;
+ barrier.newLayout = dstLayout;
+ barrier.srcQueueFamilyIndex = srcQueue;
+ barrier.dstQueueFamilyIndex = dstQueue;
+ barrier.image = image->handle();
+ barrier.subresourceRange = subresources;
+ barrier.subresourceRange.aspectMask = image->formatInfo()->aspectMask;
+ release.m_imgBarriers.push_back(barrier);
+
+ if (srcQueue == dstQueue)
+ barrier.oldLayout = dstLayout;
+
+ barrier.srcAccessMask = 0;
+ barrier.dstAccessMask = dstAccess;
+ acquire.m_imgBarriers.push_back(barrier);
+
+ DxvkAccessFlags access(DxvkAccess::Read, DxvkAccess::Write);
+ release.m_imgSlices.insert(image->handle(),
+ DxvkBarrierImageSlice(subresources, access));
+ acquire.m_imgSlices.insert(image->handle(),
+ DxvkBarrierImageSlice(subresources, access));
+ }
+
+
+ bool DxvkBarrierSet::isBufferDirty(
+ const DxvkBufferSliceHandle& bufSlice,
+ DxvkAccessFlags bufAccess) {
+ return m_bufSlices.isDirty(bufSlice.handle,
+ DxvkBarrierBufferSlice(bufSlice.offset, bufSlice.length, bufAccess));
+ }
+
+
+ bool DxvkBarrierSet::isImageDirty(
+ const Rc<DxvkImage>& image,
+ const VkImageSubresourceRange& imgSubres,
+ DxvkAccessFlags imgAccess) {
+ return m_imgSlices.isDirty(image->handle(),
+ DxvkBarrierImageSlice(imgSubres, imgAccess));
+ }
+
+
+ DxvkAccessFlags DxvkBarrierSet::getBufferAccess(
+ const DxvkBufferSliceHandle& bufSlice) {
+ return m_bufSlices.getAccess(bufSlice.handle,
+ DxvkBarrierBufferSlice(bufSlice.offset, bufSlice.length, 0));
+ }
+
+
+ DxvkAccessFlags DxvkBarrierSet::getImageAccess(
+ const Rc<DxvkImage>& image,
+ const VkImageSubresourceRange& imgSubres) {
+ return m_imgSlices.getAccess(image->handle(),
+ DxvkBarrierImageSlice(imgSubres, 0));
+ }
+
+
+ void DxvkBarrierSet::recordCommands(const Rc<DxvkCommandList>& commandList) {
+ if (m_srcStages | m_dstStages) {
+ VkPipelineStageFlags srcFlags = m_srcStages;
+ VkPipelineStageFlags dstFlags = m_dstStages;
+
+ if (!srcFlags) srcFlags = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
+ if (!dstFlags) dstFlags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
+
+ VkMemoryBarrier memBarrier;
+ memBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
+ memBarrier.pNext = nullptr;
+ memBarrier.srcAccessMask = m_srcAccess;
+ memBarrier.dstAccessMask = m_dstAccess;
+
+ VkMemoryBarrier* pMemBarrier = nullptr;
+ if (m_srcAccess | m_dstAccess)
+ pMemBarrier = &memBarrier;
+
+ commandList->cmdPipelineBarrier(
+ m_cmdBuffer, srcFlags, dstFlags, 0,
+ pMemBarrier ? 1 : 0, pMemBarrier,
+ m_bufBarriers.size(),
+ m_bufBarriers.data(),
+ m_imgBarriers.size(),
+ m_imgBarriers.data());
+
+ this->reset();
+ }
+ }
+
+
+ void DxvkBarrierSet::reset() {
+ m_srcStages = 0;
+ m_dstStages = 0;
+
+ m_srcAccess = 0;
+ m_dstAccess = 0;
+
+ m_bufBarriers.resize(0);
+ m_imgBarriers.resize(0);
+
+ m_bufSlices.clear();
+ m_imgSlices.clear();
+ }
+
+
+ DxvkAccessFlags DxvkBarrierSet::getAccessTypes(VkAccessFlags flags) {
+ const VkAccessFlags rflags
+ = VK_ACCESS_INDIRECT_COMMAND_READ_BIT
+ | VK_ACCESS_INDEX_READ_BIT
+ | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT
+ | VK_ACCESS_UNIFORM_READ_BIT
+ | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT
+ | VK_ACCESS_SHADER_READ_BIT
+ | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
+ | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
+ | VK_ACCESS_TRANSFER_READ_BIT
+ | VK_ACCESS_HOST_READ_BIT
+ | VK_ACCESS_MEMORY_READ_BIT
+ | VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT;
+
+ const VkAccessFlags wflags
+ = VK_ACCESS_SHADER_WRITE_BIT
+ | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
+ | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
+ | VK_ACCESS_TRANSFER_WRITE_BIT
+ | VK_ACCESS_HOST_WRITE_BIT
+ | VK_ACCESS_MEMORY_WRITE_BIT
+ | VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT
+ | VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT;
+
+ DxvkAccessFlags result;
+ if (flags & rflags) result.set(DxvkAccess::Read);
+ if (flags & wflags) result.set(DxvkAccess::Write);
+ return result;
+ }
+
+} \ No newline at end of file