mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-20 19:54:19 +01:00
[dxvk] Make external subpass dependencies part of DxvkRenderPassOps
This will allow us to use finer-grained synchronization around certain meta operations involving render targets, such as clears.
This commit is contained in:
parent
a79409ad02
commit
5b90b6a7ce
@ -549,12 +549,22 @@ namespace dxvk {
|
||||
if (clearAspects & VK_IMAGE_ASPECT_COLOR_BIT) {
|
||||
attachments.color[0].view = imageView;
|
||||
attachments.color[0].layout = imageView->pickLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
|
||||
ops.barrier.srcStages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
ops.barrier.srcAccess = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
ops.colorOps[0] = colorOp;
|
||||
} else {
|
||||
attachments.depth.view = imageView;
|
||||
attachments.depth.layout = imageView->pickLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
|
||||
ops.barrier.srcStages = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
|
||||
| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
|
||||
ops.barrier.srcAccess = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||
ops.depthOps = depthOp;
|
||||
}
|
||||
|
||||
ops.barrier.dstStages = imageView->imageInfo().stages;
|
||||
ops.barrier.dstAccess = imageView->imageInfo().access;
|
||||
|
||||
this->renderPassBindFramebuffer(
|
||||
m_device->createFramebuffer(attachments),
|
||||
@ -1762,6 +1772,10 @@ namespace dxvk {
|
||||
attachments.color[0].view = imageView;
|
||||
attachments.color[0].layout = imageView->pickLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
|
||||
ops.barrier.srcStages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
ops.barrier.srcAccess = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
|
||||
| VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
|
||||
ops.colorOps[0].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
ops.colorOps[0].loadLayout = imageView->imageInfo().layout;
|
||||
ops.colorOps[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
@ -1770,6 +1784,11 @@ namespace dxvk {
|
||||
attachments.depth.view = imageView;
|
||||
attachments.depth.layout = imageView->pickLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
|
||||
ops.barrier.srcStages = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
|
||||
| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
|
||||
ops.barrier.srcAccess = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
|
||||
| VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
|
||||
ops.depthOps.loadOpD = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
ops.depthOps.loadOpS = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
ops.depthOps.loadLayout = imageView->imageInfo().layout;
|
||||
@ -1778,6 +1797,9 @@ namespace dxvk {
|
||||
ops.depthOps.storeLayout = imageView->imageInfo().layout;
|
||||
}
|
||||
|
||||
ops.barrier.dstStages = imageView->imageInfo().stages;
|
||||
ops.barrier.dstAccess = imageView->imageInfo().access;
|
||||
|
||||
// We cannot leverage render pass clears
|
||||
// because we clear only part of the view
|
||||
this->renderPassBindFramebuffer(
|
||||
@ -2435,6 +2457,25 @@ namespace dxvk {
|
||||
void DxvkContext::resetRenderPassOps(
|
||||
const DxvkRenderTargets& renderTargets,
|
||||
DxvkRenderPassOps& renderPassOps) {
|
||||
renderPassOps.barrier.srcStages = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
|
||||
renderPassOps.barrier.srcAccess = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
|
||||
| VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
|
||||
| VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
|
||||
| VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
|
||||
| VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT
|
||||
| VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT
|
||||
| VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT
|
||||
| VK_ACCESS_INDIRECT_COMMAND_READ_BIT
|
||||
| VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT
|
||||
| VK_ACCESS_INDEX_READ_BIT
|
||||
| VK_ACCESS_UNIFORM_READ_BIT
|
||||
| VK_ACCESS_SHADER_READ_BIT
|
||||
| VK_ACCESS_SHADER_WRITE_BIT;
|
||||
renderPassOps.barrier.dstStages = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
|
||||
renderPassOps.barrier.dstAccess = renderPassOps.barrier.srcAccess
|
||||
| VK_ACCESS_TRANSFER_READ_BIT
|
||||
| VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
|
||||
renderPassOps.depthOps = renderTargets.depth.view != nullptr
|
||||
? DxvkDepthAttachmentOps {
|
||||
VK_ATTACHMENT_LOAD_OP_LOAD,
|
||||
|
@ -121,44 +121,39 @@ namespace dxvk {
|
||||
if (m_format.depth.format == VK_FORMAT_UNDEFINED)
|
||||
subpass.pDepthStencilAttachment = nullptr;
|
||||
|
||||
const std::array<VkSubpassDependency, 4> subpassDeps = {{
|
||||
{ VK_SUBPASS_EXTERNAL, 0,
|
||||
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||
VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
|
||||
0,
|
||||
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
|
||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
|
||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, 0 },
|
||||
{ 0, 0,
|
||||
std::array<VkSubpassDependency, 3> subpassDeps;
|
||||
uint32_t subpassDepCount = 0;
|
||||
|
||||
if (ops.barrier.srcStages & (
|
||||
VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT |
|
||||
VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT |
|
||||
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT)) {
|
||||
subpassDeps[subpassDepCount++] = { 0, 0,
|
||||
VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT,
|
||||
VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, /* XXX */
|
||||
VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT,
|
||||
VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT, 0 },
|
||||
{ 0, 0,
|
||||
VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT, 0 };
|
||||
}
|
||||
|
||||
if (ops.barrier.srcStages & (
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
|
||||
VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT |
|
||||
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT)) {
|
||||
subpassDeps[subpassDepCount++] = { 0, 0,
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||
VK_ACCESS_SHADER_WRITE_BIT,
|
||||
VK_ACCESS_SHADER_READ_BIT, 0 },
|
||||
{ 0, VK_SUBPASS_EXTERNAL,
|
||||
VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
|
||||
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
|
||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
|
||||
VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT |
|
||||
VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT |
|
||||
VK_ACCESS_SHADER_WRITE_BIT,
|
||||
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
|
||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
VK_ACCESS_HOST_READ_BIT |
|
||||
VK_ACCESS_INDEX_READ_BIT |
|
||||
VK_ACCESS_INDIRECT_COMMAND_READ_BIT |
|
||||
VK_ACCESS_SHADER_READ_BIT |
|
||||
VK_ACCESS_TRANSFER_READ_BIT |
|
||||
VK_ACCESS_UNIFORM_READ_BIT |
|
||||
VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT |
|
||||
VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT, 0 },
|
||||
}};
|
||||
VK_ACCESS_SHADER_READ_BIT, 0 };
|
||||
}
|
||||
|
||||
if (ops.barrier.srcStages && ops.barrier.dstStages) {
|
||||
subpassDeps[subpassDepCount++] = {
|
||||
0, VK_SUBPASS_EXTERNAL,
|
||||
ops.barrier.srcStages,
|
||||
ops.barrier.dstStages,
|
||||
ops.barrier.srcAccess,
|
||||
ops.barrier.dstAccess, 0 };
|
||||
}
|
||||
|
||||
VkRenderPassCreateInfo info;
|
||||
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
||||
@ -168,8 +163,8 @@ namespace dxvk {
|
||||
info.pAttachments = attachments.data();
|
||||
info.subpassCount = 1;
|
||||
info.pSubpasses = &subpass;
|
||||
info.dependencyCount = subpassDeps.size();
|
||||
info.pDependencies = subpassDeps.data();
|
||||
info.dependencyCount = subpassDepCount;
|
||||
info.pDependencies = subpassDepCount ? subpassDeps.data() : nullptr;
|
||||
|
||||
VkRenderPass renderPass = VK_NULL_HANDLE;
|
||||
|
||||
@ -185,12 +180,19 @@ namespace dxvk {
|
||||
bool DxvkRenderPass::compareOps(
|
||||
const DxvkRenderPassOps& a,
|
||||
const DxvkRenderPassOps& b) {
|
||||
bool eq = a.depthOps.loadOpD == b.depthOps.loadOpD
|
||||
&& a.depthOps.loadOpS == b.depthOps.loadOpS
|
||||
&& a.depthOps.loadLayout == b.depthOps.loadLayout
|
||||
&& a.depthOps.storeOpD == b.depthOps.storeOpD
|
||||
&& a.depthOps.storeOpS == b.depthOps.storeOpS
|
||||
&& a.depthOps.storeLayout == b.depthOps.storeLayout;
|
||||
bool eq = a.barrier.srcStages == b.barrier.srcStages
|
||||
&& a.barrier.srcAccess == b.barrier.srcAccess
|
||||
&& a.barrier.dstStages == b.barrier.dstStages
|
||||
&& a.barrier.dstAccess == b.barrier.dstAccess;
|
||||
|
||||
if (eq) {
|
||||
eq &= a.depthOps.loadOpD == b.depthOps.loadOpD
|
||||
&& a.depthOps.loadOpS == b.depthOps.loadOpS
|
||||
&& a.depthOps.loadLayout == b.depthOps.loadLayout
|
||||
&& a.depthOps.storeOpD == b.depthOps.storeOpD
|
||||
&& a.depthOps.storeOpS == b.depthOps.storeOpS
|
||||
&& a.depthOps.storeLayout == b.depthOps.storeLayout;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < MaxNumRenderTargets && eq; i++) {
|
||||
eq &= a.colorOps[i].loadOp == b.colorOps[i].loadOp
|
||||
|
@ -66,6 +66,20 @@ namespace dxvk {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Render pass barrier
|
||||
*
|
||||
* External subpass dependency that is to be
|
||||
* executed after a render pass has completed.
|
||||
*/
|
||||
struct DxvkRenderPassBarrier {
|
||||
VkPipelineStageFlags srcStages = 0;
|
||||
VkAccessFlags srcAccess = 0;
|
||||
VkPipelineStageFlags dstStages = 0;
|
||||
VkAccessFlags dstAccess = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Render pass transitions
|
||||
*
|
||||
@ -74,6 +88,7 @@ namespace dxvk {
|
||||
* from a group of render passes with the same format.
|
||||
*/
|
||||
struct DxvkRenderPassOps {
|
||||
DxvkRenderPassBarrier barrier;
|
||||
DxvkDepthAttachmentOps depthOps;
|
||||
DxvkColorAttachmentOps colorOps[MaxNumRenderTargets];
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user