1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-24 22:54:19 +01:00

[dxvk] Use secondary command buffers for rendering on tiling GPUs

This commit is contained in:
Philip Rebohle 2025-02-05 19:13:42 +01:00
parent e9fed62676
commit 62b7c493a1
3 changed files with 74 additions and 19 deletions

View File

@ -4912,28 +4912,37 @@ namespace dxvk {
this->renderPassEmitInitBarriers(framebufferInfo, ops); this->renderPassEmitInitBarriers(framebufferInfo, ops);
this->renderPassEmitPostBarriers(framebufferInfo, ops); this->renderPassEmitPostBarriers(framebufferInfo, ops);
VkCommandBufferInheritanceRenderingInfo renderingInheritance = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO };
VkCommandBufferInheritanceInfo inheritance = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, &renderingInheritance };
uint32_t colorInfoCount = 0; uint32_t colorInfoCount = 0;
uint32_t lateClearCount = 0; uint32_t lateClearCount = 0;
std::array<VkRenderingAttachmentInfo, MaxNumRenderTargets> colorInfos; std::array<VkFormat, MaxNumRenderTargets> colorFormats = { };
std::array<VkClearAttachment, MaxNumRenderTargets> lateClears; std::array<VkClearAttachment, MaxNumRenderTargets> lateClears = { };
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
const auto& colorTarget = framebufferInfo.getColorTarget(i); const auto& colorTarget = framebufferInfo.getColorTarget(i);
colorInfos[i] = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO };
auto& colorInfo = m_state.om.renderingInfo.color[i];
colorInfo = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO };
if (colorTarget.view != nullptr) { if (colorTarget.view != nullptr) {
colorInfos[i].imageView = colorTarget.view->handle(); colorFormats[i] = colorTarget.view->info().format;
colorInfos[i].imageLayout = colorTarget.layout;
colorInfos[i].loadOp = ops.colorOps[i].loadOp; colorInfo.imageView = colorTarget.view->handle();
colorInfos[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE; colorInfo.imageLayout = colorTarget.layout;
colorInfo.loadOp = ops.colorOps[i].loadOp;
colorInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
renderingInheritance.rasterizationSamples = colorTarget.view->image()->info().sampleCount;
if (ops.colorOps[i].loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) { if (ops.colorOps[i].loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) {
colorInfos[i].clearValue.color = ops.colorOps[i].clearValue; colorInfo.clearValue.color = ops.colorOps[i].clearValue;
if (m_device->perfHints().renderPassClearFormatBug if (m_device->perfHints().renderPassClearFormatBug
&& colorTarget.view->info().format != colorTarget.view->image()->info().format) { && colorTarget.view->info().format != colorTarget.view->image()->info().format) {
colorInfos[i].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; colorInfo.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
auto& clear = lateClears[lateClearCount++]; auto& clear = lateClears[lateClearCount++];
clear.colorAttachment = i; clear.colorAttachment = i;
@ -4946,11 +4955,15 @@ namespace dxvk {
} }
} }
VkRenderingAttachmentInfo depthInfo = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO }; VkFormat depthStencilFormat = VK_FORMAT_UNDEFINED;
VkImageAspectFlags depthStencilAspects = 0; VkImageAspectFlags depthStencilAspects = 0;
auto& depthInfo = m_state.om.renderingInfo.depth;
depthInfo = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO };
if (framebufferInfo.getDepthTarget().view != nullptr) { if (framebufferInfo.getDepthTarget().view != nullptr) {
const auto& depthTarget = framebufferInfo.getDepthTarget(); const auto& depthTarget = framebufferInfo.getDepthTarget();
depthStencilFormat = depthTarget.view->info().format;
depthStencilAspects = depthTarget.view->info().aspects; depthStencilAspects = depthTarget.view->info().aspects;
depthInfo.imageView = depthTarget.view->handle(); depthInfo.imageView = depthTarget.view->handle();
depthInfo.imageLayout = depthTarget.layout; depthInfo.imageLayout = depthTarget.layout;
@ -4959,9 +4972,12 @@ namespace dxvk {
if (ops.depthOps.loadOpD == VK_ATTACHMENT_LOAD_OP_CLEAR) if (ops.depthOps.loadOpD == VK_ATTACHMENT_LOAD_OP_CLEAR)
depthInfo.clearValue.depthStencil.depth = ops.depthOps.clearValue.depth; depthInfo.clearValue.depthStencil.depth = ops.depthOps.clearValue.depth;
renderingInheritance.rasterizationSamples = depthTarget.view->image()->info().sampleCount;
} }
VkRenderingAttachmentInfo stencilInfo = depthInfo; auto& stencilInfo = m_state.om.renderingInfo.stencil;
stencilInfo = depthInfo;
if (framebufferInfo.getDepthTarget().view != nullptr) { if (framebufferInfo.getDepthTarget().view != nullptr) {
stencilInfo.loadOp = ops.depthOps.loadOpS; stencilInfo.loadOp = ops.depthOps.loadOpS;
@ -4971,24 +4987,40 @@ namespace dxvk {
stencilInfo.clearValue.depthStencil.stencil = ops.depthOps.clearValue.stencil; stencilInfo.clearValue.depthStencil.stencil = ops.depthOps.clearValue.stencil;
} }
VkRenderingInfo renderingInfo = { VK_STRUCTURE_TYPE_RENDERING_INFO }; auto& renderingInfo = m_state.om.renderingInfo.rendering;
renderingInfo = { VK_STRUCTURE_TYPE_RENDERING_INFO };
renderingInfo.renderArea.offset = VkOffset2D { 0, 0 }; renderingInfo.renderArea.offset = VkOffset2D { 0, 0 };
renderingInfo.renderArea.extent = VkExtent2D { fbSize.width, fbSize.height }; renderingInfo.renderArea.extent = VkExtent2D { fbSize.width, fbSize.height };
renderingInfo.layerCount = fbSize.layers; renderingInfo.layerCount = fbSize.layers;
if (colorInfoCount) { if (colorInfoCount) {
renderingInfo.colorAttachmentCount = colorInfoCount; renderingInfo.colorAttachmentCount = colorInfoCount;
renderingInfo.pColorAttachments = colorInfos.data(); renderingInfo.pColorAttachments = m_state.om.renderingInfo.color.data();
renderingInheritance.colorAttachmentCount = colorInfoCount;
renderingInheritance.pColorAttachmentFormats = colorFormats.data();
} }
if (depthStencilAspects & VK_IMAGE_ASPECT_DEPTH_BIT) if (depthStencilAspects & VK_IMAGE_ASPECT_DEPTH_BIT) {
renderingInfo.pDepthAttachment = &depthInfo; renderingInfo.pDepthAttachment = &depthInfo;
renderingInheritance.depthAttachmentFormat = depthStencilFormat;
}
if (depthStencilAspects & VK_IMAGE_ASPECT_STENCIL_BIT) if (depthStencilAspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
renderingInfo.pStencilAttachment = &stencilInfo; renderingInfo.pStencilAttachment = &stencilInfo;
renderingInheritance.stencilAttachmentFormat = depthStencilFormat;
}
if (m_device->perfHints().preferRenderPassOps) {
// Begin secondary command buffer on tiling GPUs so that subsequent
// resolve, discard and clear commands can modify render pass ops.
renderingInfo.flags = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT;
m_cmd->beginSecondaryCommandBuffer(inheritance);
} else {
// Begin rendering right away on regular GPUs
m_cmd->cmdBeginRendering(&renderingInfo);
}
m_cmd->cmdBeginRendering(&renderingInfo);
if (lateClearCount) { if (lateClearCount) {
VkClearRect clearRect = { }; VkClearRect clearRect = { };
clearRect.rect.extent.width = fbSize.width; clearRect.rect.extent.width = fbSize.width;
@ -5004,6 +5036,17 @@ namespace dxvk {
void DxvkContext::renderPassUnbindFramebuffer() { void DxvkContext::renderPassUnbindFramebuffer() {
if (m_device->perfHints().preferRenderPassOps) {
VkCommandBuffer cmdBuffer = m_cmd->endSecondaryCommandBuffer();
// Record scoped rendering commands with potentially
// modified store or resolve ops here
auto& renderingInfo = m_state.om.renderingInfo.rendering;
m_cmd->cmdBeginRendering(&renderingInfo);
m_cmd->cmdExecuteCommands(1, &cmdBuffer);
}
// End actual rendering command
m_cmd->cmdEndRendering(); m_cmd->cmdEndRendering();
// If there are pending layout transitions, execute them immediately // If there are pending layout transitions, execute them immediately

View File

@ -111,6 +111,7 @@ namespace dxvk {
struct DxvkOutputMergerState { struct DxvkOutputMergerState {
DxvkRenderingInfo renderingInfo;
DxvkRenderTargets renderTargets; DxvkRenderTargets renderTargets;
DxvkRenderPassOps renderPassOps; DxvkRenderPassOps renderPassOps;
DxvkFramebufferInfo framebufferInfo; DxvkFramebufferInfo framebufferInfo;
@ -190,4 +191,4 @@ namespace dxvk {
DxvkComputePipelineState cp; DxvkComputePipelineState cp;
}; };
} }

View File

@ -53,6 +53,17 @@ namespace dxvk {
}; };
/**
* \brief Rendering info
*/
struct DxvkRenderingInfo {
std::array<VkRenderingAttachmentInfo, MaxNumRenderTargets> color = { };
VkRenderingAttachmentInfo depth = { };
VkRenderingAttachmentInfo stencil = { };
VkRenderingInfo rendering = { };
};
/** /**
* \brief Framebuffer key * \brief Framebuffer key
*/ */
@ -234,4 +245,4 @@ namespace dxvk {
}; };
} }