1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-01 08:52:11 +01:00

[dxvk] Add dedicated command buffers for initial layout transitions

This helps batch initial layout transitions for image uploads.
This commit is contained in:
Philip Rebohle 2024-10-28 13:31:50 +01:00 committed by Philip Rebohle
parent d85cabe457
commit 34b82a2b5b
4 changed files with 45 additions and 12 deletions

View File

@ -225,6 +225,9 @@ namespace dxvk {
} }
// Execute transfer command buffer, if any // Execute transfer command buffer, if any
if (cmd.usedFlags.test(DxvkCmdBuffer::SdmaBarriers))
m_commandSubmission.executeCommandBuffer(cmd.cmdBuffers[uint32_t(DxvkCmdBuffer::SdmaBarriers)]);
if (cmd.usedFlags.test(DxvkCmdBuffer::SdmaBuffer)) if (cmd.usedFlags.test(DxvkCmdBuffer::SdmaBuffer))
m_commandSubmission.executeCommandBuffer(cmd.cmdBuffers[uint32_t(DxvkCmdBuffer::SdmaBuffer)]); m_commandSubmission.executeCommandBuffer(cmd.cmdBuffers[uint32_t(DxvkCmdBuffer::SdmaBuffer)]);
@ -249,6 +252,9 @@ namespace dxvk {
} }
// Submit graphics commands // Submit graphics commands
if (cmd.usedFlags.test(DxvkCmdBuffer::InitBarriers))
m_commandSubmission.executeCommandBuffer(cmd.cmdBuffers[uint32_t(DxvkCmdBuffer::InitBarriers)]);
if (cmd.usedFlags.test(DxvkCmdBuffer::InitBuffer)) if (cmd.usedFlags.test(DxvkCmdBuffer::InitBuffer))
m_commandSubmission.executeCommandBuffer(cmd.cmdBuffers[uint32_t(DxvkCmdBuffer::InitBuffer)]); m_commandSubmission.executeCommandBuffer(cmd.cmdBuffers[uint32_t(DxvkCmdBuffer::InitBuffer)]);
@ -391,7 +397,7 @@ namespace dxvk {
VkCommandBuffer DxvkCommandList::allocateCommandBuffer(DxvkCmdBuffer type) { VkCommandBuffer DxvkCommandList::allocateCommandBuffer(DxvkCmdBuffer type) {
return type == DxvkCmdBuffer::SdmaBuffer return type == DxvkCmdBuffer::SdmaBuffer || type == DxvkCmdBuffer::SdmaBarriers
? m_transferPool->getCommandBuffer() ? m_transferPool->getCommandBuffer()
: m_graphicsPool->getCommandBuffer(); : m_graphicsPool->getCommandBuffer();
} }

View File

@ -47,7 +47,9 @@ namespace dxvk {
enum class DxvkCmdBuffer : uint32_t { enum class DxvkCmdBuffer : uint32_t {
ExecBuffer, ExecBuffer,
InitBuffer, InitBuffer,
InitBarriers,
SdmaBuffer, SdmaBuffer,
SdmaBarriers,
Count Count
}; };

View File

@ -10,7 +10,9 @@ namespace dxvk {
DxvkContext::DxvkContext(const Rc<DxvkDevice>& device) DxvkContext::DxvkContext(const Rc<DxvkDevice>& device)
: m_device (device), : m_device (device),
m_common (&device->m_objects), m_common (&device->m_objects),
m_sdmaAcquires(DxvkCmdBuffer::SdmaBarriers),
m_sdmaBarriers(DxvkCmdBuffer::SdmaBuffer), m_sdmaBarriers(DxvkCmdBuffer::SdmaBuffer),
m_initAcquires(DxvkCmdBuffer::InitBarriers),
m_initBarriers(DxvkCmdBuffer::InitBuffer), m_initBarriers(DxvkCmdBuffer::InitBuffer),
m_execBarriers(DxvkCmdBuffer::ExecBuffer), m_execBarriers(DxvkCmdBuffer::ExecBuffer),
m_queryManager(m_common->queryPool()) { m_queryManager(m_common->queryPool()) {
@ -6737,7 +6739,9 @@ namespace dxvk {
this->spillRenderPass(true); this->spillRenderPass(true);
this->flushSharedImages(); this->flushSharedImages();
m_sdmaAcquires.finalize(m_cmd);
m_sdmaBarriers.finalize(m_cmd); m_sdmaBarriers.finalize(m_cmd);
m_initAcquires.finalize(m_cmd);
m_initBarriers.finalize(m_cmd); m_initBarriers.finalize(m_cmd);
m_execBarriers.finalize(m_cmd); m_execBarriers.finalize(m_cmd);
@ -6762,12 +6766,29 @@ namespace dxvk {
if (m_imageLayoutTransitions.empty()) if (m_imageLayoutTransitions.empty())
return; return;
VkDependencyInfo depInfo = { VK_STRUCTURE_TYPE_DEPENDENCY_INFO }; if (cmdBuffer == DxvkCmdBuffer::ExecBuffer) {
depInfo.imageMemoryBarrierCount = m_imageLayoutTransitions.size(); VkDependencyInfo depInfo = { VK_STRUCTURE_TYPE_DEPENDENCY_INFO };
depInfo.pImageMemoryBarriers = m_imageLayoutTransitions.data(); depInfo.imageMemoryBarrierCount = m_imageLayoutTransitions.size();
depInfo.pImageMemoryBarriers = m_imageLayoutTransitions.data();
m_cmd->cmdPipelineBarrier(cmdBuffer, &depInfo); m_cmd->cmdPipelineBarrier(cmdBuffer, &depInfo);
m_cmd->addStatCtr(DxvkStatCounter::CmdBarrierCount, 1u); m_cmd->addStatCtr(DxvkStatCounter::CmdBarrierCount, 1u);
} else {
// If we're recording into an out-of-order command buffer, batch
// layout transitions into a dedicated command buffer in order to
// avoid pipeline stalls.
DxvkCmdBuffer barrierBuffer = cmdBuffer;
if (cmdBuffer == DxvkCmdBuffer::InitBuffer)
barrierBuffer = DxvkCmdBuffer::InitBarriers;
if (cmdBuffer == DxvkCmdBuffer::SdmaBuffer)
barrierBuffer = DxvkCmdBuffer::SdmaBarriers;
auto& batch = getBarrierBatch(barrierBuffer);
for (const auto& barrier : m_imageLayoutTransitions)
batch.addImageBarrier(barrier);
}
m_imageLayoutTransitions.clear(); m_imageLayoutTransitions.clear();
} }
@ -7143,12 +7164,14 @@ namespace dxvk {
DxvkBarrierBatch& DxvkContext::getBarrierBatch( DxvkBarrierBatch& DxvkContext::getBarrierBatch(
DxvkCmdBuffer cmdBuffer) { DxvkCmdBuffer cmdBuffer) {
if (cmdBuffer == DxvkCmdBuffer::ExecBuffer) switch (cmdBuffer) {
return m_execBarriers; default:
case DxvkCmdBuffer::ExecBuffer: return m_execBarriers;
return cmdBuffer == DxvkCmdBuffer::InitBuffer case DxvkCmdBuffer::InitBuffer: return m_initBarriers;
? m_initBarriers case DxvkCmdBuffer::InitBarriers: return m_initAcquires;
: m_sdmaBarriers; case DxvkCmdBuffer::SdmaBuffer: return m_sdmaBarriers;
case DxvkCmdBuffer::SdmaBarriers: return m_sdmaAcquires;
}
} }

View File

@ -1398,7 +1398,9 @@ namespace dxvk {
Rc<DxvkDescriptorPool> m_descriptorPool; Rc<DxvkDescriptorPool> m_descriptorPool;
Rc<DxvkDescriptorManager> m_descriptorManager; Rc<DxvkDescriptorManager> m_descriptorManager;
DxvkBarrierBatch m_sdmaAcquires;
DxvkBarrierBatch m_sdmaBarriers; DxvkBarrierBatch m_sdmaBarriers;
DxvkBarrierBatch m_initAcquires;
DxvkBarrierBatch m_initBarriers; DxvkBarrierBatch m_initBarriers;
DxvkBarrierBatch m_execBarriers; DxvkBarrierBatch m_execBarriers;
DxvkBarrierTracker m_barrierTracker; DxvkBarrierTracker m_barrierTracker;