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:
parent
e9fed62676
commit
62b7c493a1
@ -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
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user