mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-20 19:54:19 +01:00
[dxvk] Use synchronization2 functions for barriers
We don't really use the new stage/access flags yet, and I'm not sure whether we will move to them since the benefits seem rather limited. However, using the functions means we can bypass a lot of internal translation inside some Vulkan drivers.
This commit is contained in:
parent
0d65142136
commit
adb906b18c
@ -44,13 +44,13 @@ namespace dxvk {
|
||||
VkAccessFlags dstAccess) {
|
||||
DxvkAccessFlags access = this->getAccessTypes(srcAccess);
|
||||
|
||||
m_srcStages |= srcStages;
|
||||
m_dstStages |= dstStages;
|
||||
|
||||
m_srcAccess |= srcAccess & AccessWriteMask;
|
||||
m_allBarrierSrcStages |= srcStages;
|
||||
m_memBarrier.srcStageMask |= srcStages;
|
||||
m_memBarrier.srcAccessMask |= srcAccess & AccessWriteMask;
|
||||
m_memBarrier.dstStageMask |= dstStages;
|
||||
|
||||
if (access.test(DxvkAccess::Write))
|
||||
m_dstAccess |= dstAccess;
|
||||
m_memBarrier.dstAccessMask |= dstAccess;
|
||||
}
|
||||
|
||||
|
||||
@ -62,17 +62,13 @@ namespace dxvk {
|
||||
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_allBarrierSrcStages |= srcStages;
|
||||
m_memBarrier.srcStageMask |= srcStages;
|
||||
m_memBarrier.srcAccessMask |= srcAccess & AccessWriteMask;
|
||||
m_memBarrier.dstStageMask |= dstStages;
|
||||
|
||||
m_srcStages |= srcStages;
|
||||
m_dstStages |= dstStages;
|
||||
|
||||
m_srcAccess |= srcAccess & AccessWriteMask;
|
||||
|
||||
if (access.test(DxvkAccess::Write))
|
||||
m_dstAccess |= dstAccess;
|
||||
m_memBarrier.dstAccessMask |= dstAccess;
|
||||
|
||||
m_bufSlices.insert(bufSlice.handle,
|
||||
DxvkBarrierBufferSlice(bufSlice.offset, bufSlice.length, access));
|
||||
@ -90,22 +86,20 @@ namespace dxvk {
|
||||
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;
|
||||
|
||||
m_allBarrierSrcStages |= srcStages;
|
||||
|
||||
if (srcLayout == dstLayout) {
|
||||
m_srcAccess |= srcAccess & AccessWriteMask;
|
||||
m_memBarrier.srcStageMask |= srcStages;
|
||||
m_memBarrier.srcAccessMask |= srcAccess & AccessWriteMask;
|
||||
m_memBarrier.dstStageMask |= dstStages;
|
||||
|
||||
if (access.test(DxvkAccess::Write))
|
||||
m_dstAccess |= dstAccess;
|
||||
m_memBarrier.dstAccessMask |= dstAccess;
|
||||
} else {
|
||||
VkImageMemoryBarrier barrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER };
|
||||
VkImageMemoryBarrier2 barrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2 };
|
||||
barrier.srcStageMask = srcStages;
|
||||
barrier.srcAccessMask = srcAccess & AccessWriteMask;
|
||||
barrier.dstStageMask = dstStages;
|
||||
barrier.dstAccessMask = dstAccess;
|
||||
barrier.oldLayout = srcLayout;
|
||||
barrier.newLayout = dstLayout;
|
||||
@ -115,6 +109,8 @@ namespace dxvk {
|
||||
barrier.subresourceRange = subresources;
|
||||
barrier.subresourceRange.aspectMask = image->formatInfo()->aspectMask;
|
||||
m_imgBarriers.push_back(barrier);
|
||||
|
||||
access.set(DxvkAccess::Write);
|
||||
}
|
||||
|
||||
m_imgSlices.insert(image->handle(),
|
||||
@ -133,11 +129,12 @@ namespace dxvk {
|
||||
VkAccessFlags dstAccess) {
|
||||
auto& release = *this;
|
||||
|
||||
release.m_srcStages |= srcStages;
|
||||
acquire.m_dstStages |= dstStages;
|
||||
m_allBarrierSrcStages |= srcStages;
|
||||
|
||||
VkBufferMemoryBarrier barrier = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER };
|
||||
VkBufferMemoryBarrier2 barrier = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2 };
|
||||
barrier.srcStageMask = srcStages;
|
||||
barrier.srcAccessMask = srcAccess & AccessWriteMask;
|
||||
barrier.dstStageMask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT;
|
||||
barrier.dstAccessMask = 0;
|
||||
barrier.srcQueueFamilyIndex = srcQueue;
|
||||
barrier.dstQueueFamilyIndex = dstQueue;
|
||||
@ -146,7 +143,9 @@ namespace dxvk {
|
||||
barrier.size = bufSlice.length;
|
||||
release.m_bufBarriers.push_back(barrier);
|
||||
|
||||
barrier.srcStageMask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT;
|
||||
barrier.srcAccessMask = 0;
|
||||
barrier.dstStageMask = dstStages;
|
||||
barrier.dstAccessMask = dstAccess;
|
||||
acquire.m_bufBarriers.push_back(barrier);
|
||||
|
||||
@ -172,13 +171,12 @@ namespace dxvk {
|
||||
VkAccessFlags dstAccess) {
|
||||
auto& release = *this;
|
||||
|
||||
release.m_srcStages |= srcStages;
|
||||
acquire.m_dstStages |= dstStages;
|
||||
m_allBarrierSrcStages |= srcStages;
|
||||
|
||||
VkImageMemoryBarrier barrier;
|
||||
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
barrier.pNext = nullptr;
|
||||
VkImageMemoryBarrier2 barrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2 };
|
||||
barrier.srcStageMask = srcStages;
|
||||
barrier.srcAccessMask = srcAccess & AccessWriteMask;
|
||||
barrier.dstStageMask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT;
|
||||
barrier.dstAccessMask = 0;
|
||||
barrier.oldLayout = srcLayout;
|
||||
barrier.newLayout = dstLayout;
|
||||
@ -192,7 +190,9 @@ namespace dxvk {
|
||||
if (srcQueue == dstQueue)
|
||||
barrier.oldLayout = dstLayout;
|
||||
|
||||
barrier.srcStageMask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT;
|
||||
barrier.srcAccessMask = 0;
|
||||
barrier.dstStageMask = dstStages;
|
||||
barrier.dstAccessMask = dstAccess;
|
||||
acquire.m_imgBarriers.push_back(barrier);
|
||||
|
||||
@ -237,29 +237,25 @@ namespace dxvk {
|
||||
|
||||
|
||||
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;
|
||||
VkDependencyInfo depInfo = { VK_STRUCTURE_TYPE_DEPENDENCY_INFO };
|
||||
|
||||
VkMemoryBarrier memBarrier = { VK_STRUCTURE_TYPE_MEMORY_BARRIER };
|
||||
memBarrier.srcAccessMask = m_srcAccess;
|
||||
memBarrier.dstAccessMask = m_dstAccess;
|
||||
if (m_memBarrier.srcStageMask | m_memBarrier.dstStageMask) {
|
||||
depInfo.memoryBarrierCount = 1;
|
||||
depInfo.pMemoryBarriers = &m_memBarrier;
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
if (!m_bufBarriers.empty()) {
|
||||
depInfo.bufferMemoryBarrierCount = m_bufBarriers.size();
|
||||
depInfo.pBufferMemoryBarriers = m_bufBarriers.data();
|
||||
}
|
||||
|
||||
if (!m_imgBarriers.empty()) {
|
||||
depInfo.imageMemoryBarrierCount = m_imgBarriers.size();
|
||||
depInfo.pImageMemoryBarriers = m_imgBarriers.data();
|
||||
}
|
||||
|
||||
if (depInfo.memoryBarrierCount + depInfo.bufferMemoryBarrierCount + depInfo.imageMemoryBarrierCount) {
|
||||
commandList->cmdPipelineBarrier(m_cmdBuffer, &depInfo);
|
||||
commandList->addStatCtr(DxvkStatCounter::CmdBarrierCount, 1);
|
||||
|
||||
this->reset();
|
||||
@ -268,11 +264,12 @@ namespace dxvk {
|
||||
|
||||
|
||||
void DxvkBarrierSet::reset() {
|
||||
m_srcStages = 0;
|
||||
m_dstStages = 0;
|
||||
m_allBarrierSrcStages = 0;
|
||||
|
||||
m_srcAccess = 0;
|
||||
m_dstAccess = 0;
|
||||
m_memBarrier.srcStageMask = 0;
|
||||
m_memBarrier.srcAccessMask = 0;
|
||||
m_memBarrier.dstStageMask = 0;
|
||||
m_memBarrier.dstAccessMask = 0;
|
||||
|
||||
m_bufBarriers.resize(0);
|
||||
m_imgBarriers.resize(0);
|
||||
|
@ -538,7 +538,7 @@ namespace dxvk {
|
||||
const VkImageSubresourceRange& imgSubres);
|
||||
|
||||
VkPipelineStageFlags getSrcStages() {
|
||||
return m_srcStages;
|
||||
return m_allBarrierSrcStages;
|
||||
}
|
||||
|
||||
void recordCommands(
|
||||
@ -567,15 +567,12 @@ namespace dxvk {
|
||||
};
|
||||
|
||||
DxvkCmdBuffer m_cmdBuffer;
|
||||
|
||||
VkPipelineStageFlags m_srcStages = 0;
|
||||
VkPipelineStageFlags m_dstStages = 0;
|
||||
|
||||
VkAccessFlags m_srcAccess = 0;
|
||||
VkAccessFlags m_dstAccess = 0;
|
||||
|
||||
std::vector<VkBufferMemoryBarrier> m_bufBarriers;
|
||||
std::vector<VkImageMemoryBarrier> m_imgBarriers;
|
||||
VkPipelineStageFlags2 m_allBarrierSrcStages = 0;
|
||||
|
||||
VkMemoryBarrier2 m_memBarrier = { VK_STRUCTURE_TYPE_MEMORY_BARRIER_2 };
|
||||
std::vector<VkBufferMemoryBarrier2> m_bufBarriers;
|
||||
std::vector<VkImageMemoryBarrier2> m_imgBarriers;
|
||||
|
||||
DxvkBarrierSubresourceSet<VkBuffer, DxvkBarrierBufferSlice> m_bufSlices;
|
||||
DxvkBarrierSubresourceSet<VkImage, DxvkBarrierImageSlice> m_imgSlices;
|
||||
|
@ -607,22 +607,10 @@ namespace dxvk {
|
||||
|
||||
void cmdPipelineBarrier(
|
||||
DxvkCmdBuffer cmdBuffer,
|
||||
VkPipelineStageFlags srcStageMask,
|
||||
VkPipelineStageFlags dstStageMask,
|
||||
VkDependencyFlags dependencyFlags,
|
||||
uint32_t memoryBarrierCount,
|
||||
const VkMemoryBarrier* pMemoryBarriers,
|
||||
uint32_t bufferMemoryBarrierCount,
|
||||
const VkBufferMemoryBarrier* pBufferMemoryBarriers,
|
||||
uint32_t imageMemoryBarrierCount,
|
||||
const VkImageMemoryBarrier* pImageMemoryBarriers) {
|
||||
const VkDependencyInfo* dependencyInfo) {
|
||||
m_cmdBuffersUsed.set(cmdBuffer);
|
||||
|
||||
m_vkd->vkCmdPipelineBarrier(getCmdBuffer(cmdBuffer),
|
||||
srcStageMask, dstStageMask, dependencyFlags,
|
||||
memoryBarrierCount, pMemoryBarriers,
|
||||
bufferMemoryBarrierCount, pBufferMemoryBarriers,
|
||||
imageMemoryBarrierCount, pImageMemoryBarriers);
|
||||
m_vkd->vkCmdPipelineBarrier2(getCmdBuffer(cmdBuffer), dependencyInfo);
|
||||
}
|
||||
|
||||
|
||||
|
@ -950,7 +950,7 @@ namespace dxvk {
|
||||
srcBufferSlice.handle, tmpBufferSlice.handle,
|
||||
1, ©Region);
|
||||
|
||||
emitMemoryBarrier(0,
|
||||
emitMemoryBarrier(
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
@ -1456,7 +1456,8 @@ namespace dxvk {
|
||||
VkImageLayout initialLayout) {
|
||||
if (initialLayout == VK_IMAGE_LAYOUT_PREINITIALIZED) {
|
||||
m_initBarriers.accessImage(image, subresources,
|
||||
initialLayout, 0, 0,
|
||||
initialLayout,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0,
|
||||
image->info().layout,
|
||||
image->info().stages,
|
||||
image->info().access);
|
||||
@ -1466,7 +1467,9 @@ namespace dxvk {
|
||||
VkImageLayout clearLayout = image->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
|
||||
m_execAcquires.accessImage(image, subresources,
|
||||
initialLayout, 0, 0, clearLayout,
|
||||
initialLayout,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0,
|
||||
clearLayout,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT);
|
||||
m_execAcquires.recordCommands(m_cmd);
|
||||
@ -2261,7 +2264,8 @@ namespace dxvk {
|
||||
// Discard previous subresource contents
|
||||
barriers->accessImage(image,
|
||||
vk::makeSubresourceRange(subresources),
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, 0, 0,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0,
|
||||
image->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL),
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT);
|
||||
@ -4545,14 +4549,16 @@ namespace dxvk {
|
||||
srcBarrier.stages |= pipelineBarrier.stages;
|
||||
srcBarrier.access |= pipelineBarrier.access;
|
||||
|
||||
DxvkAccessFlags access = DxvkBarrierSet::getAccessTypes(srcBarrier.access);
|
||||
DxvkGlobalPipelineBarrier dstBarrier = access.test(DxvkAccess::Write)
|
||||
? m_globalRwGraphicsBarrier
|
||||
: m_globalRoGraphicsBarrier;
|
||||
if (srcBarrier.stages) {
|
||||
DxvkAccessFlags access = DxvkBarrierSet::getAccessTypes(srcBarrier.access);
|
||||
DxvkGlobalPipelineBarrier dstBarrier = access.test(DxvkAccess::Write)
|
||||
? m_globalRwGraphicsBarrier
|
||||
: m_globalRoGraphicsBarrier;
|
||||
|
||||
m_execBarriers.accessMemory(
|
||||
srcBarrier.stages, srcBarrier.access,
|
||||
dstBarrier.stages, dstBarrier.access);
|
||||
m_execBarriers.accessMemory(
|
||||
srcBarrier.stages, srcBarrier.access,
|
||||
dstBarrier.stages, dstBarrier.access);
|
||||
}
|
||||
|
||||
m_flags.clr(DxvkContextFlag::GpDirtyPipelineState);
|
||||
return true;
|
||||
@ -5664,19 +5670,21 @@ namespace dxvk {
|
||||
|
||||
|
||||
void DxvkContext::emitMemoryBarrier(
|
||||
VkDependencyFlags flags,
|
||||
VkPipelineStageFlags srcStages,
|
||||
VkAccessFlags srcAccess,
|
||||
VkPipelineStageFlags dstStages,
|
||||
VkAccessFlags dstAccess) {
|
||||
VkMemoryBarrier barrier = { VK_STRUCTURE_TYPE_MEMORY_BARRIER };
|
||||
VkMemoryBarrier2 barrier = { VK_STRUCTURE_TYPE_MEMORY_BARRIER_2 };
|
||||
barrier.srcStageMask = srcStages;
|
||||
barrier.srcAccessMask = srcAccess;
|
||||
barrier.dstStageMask = dstStages;
|
||||
barrier.dstAccessMask = dstAccess;
|
||||
|
||||
m_cmd->cmdPipelineBarrier(
|
||||
DxvkCmdBuffer::ExecBuffer, srcStages, dstStages,
|
||||
flags, 1, &barrier, 0, nullptr, 0, nullptr);
|
||||
VkDependencyInfo depInfo = { VK_STRUCTURE_TYPE_DEPENDENCY_INFO };
|
||||
depInfo.memoryBarrierCount = 1;
|
||||
depInfo.pMemoryBarriers = &barrier;
|
||||
|
||||
m_cmd->cmdPipelineBarrier(DxvkCmdBuffer::ExecBuffer, &depInfo);
|
||||
m_cmd->addStatCtr(DxvkStatCounter::CmdBarrierCount, 1);
|
||||
}
|
||||
|
||||
|
@ -1404,7 +1404,6 @@ namespace dxvk {
|
||||
VkAccessFlags access);
|
||||
|
||||
void emitMemoryBarrier(
|
||||
VkDependencyFlags flags,
|
||||
VkPipelineStageFlags srcStages,
|
||||
VkAccessFlags srcAccess,
|
||||
VkPipelineStageFlags dstStages,
|
||||
|
Loading…
x
Reference in New Issue
Block a user