1
0
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:
Philip Rebohle 2019-01-22 15:44:19 +01:00
parent a79409ad02
commit 5b90b6a7ce
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
3 changed files with 98 additions and 40 deletions

View File

@ -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,

View File

@ -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

View File

@ -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];
};