mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-04-12 03:02:33 +02:00
[dxvk] Split barriers with very large VkDependencyInfo structures
Works around an AMD driver bug. Fixes #3138.
This commit is contained in:
parent
f4f4f3647f
commit
12901b52f1
@ -327,12 +327,49 @@ namespace dxvk {
|
|||||||
depInfo.pImageMemoryBarriers = m_imgBarriers.data();
|
depInfo.pImageMemoryBarriers = m_imgBarriers.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (depInfo.memoryBarrierCount + depInfo.bufferMemoryBarrierCount + depInfo.imageMemoryBarrierCount) {
|
uint32_t totalBarrierCount = depInfo.memoryBarrierCount
|
||||||
commandList->cmdPipelineBarrier(m_cmdBuffer, &depInfo);
|
+ depInfo.bufferMemoryBarrierCount
|
||||||
commandList->addStatCtr(DxvkStatCounter::CmdBarrierCount, 1);
|
+ depInfo.imageMemoryBarrierCount;
|
||||||
|
|
||||||
this->reset();
|
if (!totalBarrierCount)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// AMDVLK (and -PRO) will just crash if they encounter a very large structure
|
||||||
|
// in one vkCmdPipelineBarrier2 call, so we need to split the barrier into parts.
|
||||||
|
constexpr uint32_t MaxBarriersPerCall = 512;
|
||||||
|
|
||||||
|
if (unlikely(totalBarrierCount > MaxBarriersPerCall)) {
|
||||||
|
VkDependencyInfo splitDepInfo = { VK_STRUCTURE_TYPE_DEPENDENCY_INFO };
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < depInfo.memoryBarrierCount; i += MaxBarriersPerCall) {
|
||||||
|
splitDepInfo.memoryBarrierCount = std::min(depInfo.memoryBarrierCount - i, MaxBarriersPerCall);
|
||||||
|
splitDepInfo.pMemoryBarriers = depInfo.pMemoryBarriers + i;
|
||||||
|
commandList->cmdPipelineBarrier(m_cmdBuffer, &splitDepInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
splitDepInfo = { VK_STRUCTURE_TYPE_DEPENDENCY_INFO };
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < depInfo.bufferMemoryBarrierCount; i += MaxBarriersPerCall) {
|
||||||
|
splitDepInfo.bufferMemoryBarrierCount = std::min(depInfo.bufferMemoryBarrierCount - i, MaxBarriersPerCall);
|
||||||
|
splitDepInfo.pBufferMemoryBarriers = depInfo.pBufferMemoryBarriers + i;
|
||||||
|
commandList->cmdPipelineBarrier(m_cmdBuffer, &splitDepInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
splitDepInfo = { VK_STRUCTURE_TYPE_DEPENDENCY_INFO };
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < depInfo.imageMemoryBarrierCount; i += MaxBarriersPerCall) {
|
||||||
|
splitDepInfo.imageMemoryBarrierCount = std::min(depInfo.imageMemoryBarrierCount - i, MaxBarriersPerCall);
|
||||||
|
splitDepInfo.pImageMemoryBarriers = depInfo.pImageMemoryBarriers + i;
|
||||||
|
commandList->cmdPipelineBarrier(m_cmdBuffer, &splitDepInfo);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Otherwise, issue the barrier as-is
|
||||||
|
commandList->cmdPipelineBarrier(m_cmdBuffer, &depInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
commandList->addStatCtr(DxvkStatCounter::CmdBarrierCount, 1);
|
||||||
|
|
||||||
|
this->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user