mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-08 04:08:32 +09:00
[Fix] (MG_Backend/DirectVulkan): render passes had zero subpass dependencies and same-layout transitions emit no barrier, so tilers could race tile loads against prior passes' stores (flickering artifacts in multi-pass chains like MC 26.3 OIT); add conservative external dependencies both ways
This commit is contained in:
@@ -979,6 +979,52 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
subpassDesc.preserveAttachmentCount = 0;
|
||||
subpassDesc.pPreserveAttachments = nullptr;
|
||||
|
||||
// External subpass dependencies. Without them there is NO execution/memory
|
||||
// dependency between consecutive render passes (or a pass and a transfer)
|
||||
// touching the same attachments when the image layout does not change — the
|
||||
// layout-transition helper no-ops on identical layouts and no other barrier
|
||||
// exists. Tile-based GPUs then race tile loads against the previous pass's
|
||||
// stores (multi-pass FBO chains like MC 26.3's OIT flicker on Adreno).
|
||||
// Conservative both-ways dependencies: prior writes (attachment output,
|
||||
// depth/stencil, transfer, shader) are made visible to this pass's loads,
|
||||
// and this pass's attachment writes to subsequent sampling/transfer/loads.
|
||||
VkSubpassDependency subpassDependencies[2];
|
||||
subpassDependencies[0] = {};
|
||||
subpassDependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL;
|
||||
subpassDependencies[0].dstSubpass = 0;
|
||||
subpassDependencies[0].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
|
||||
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
subpassDependencies[0].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
|
||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
|
||||
VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
subpassDependencies[0].dstStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
|
||||
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
subpassDependencies[0].dstAccessMask =
|
||||
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_SHADER_READ_BIT;
|
||||
subpassDependencies[0].dependencyFlags = 0;
|
||||
subpassDependencies[1] = {};
|
||||
subpassDependencies[1].srcSubpass = 0;
|
||||
subpassDependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL;
|
||||
subpassDependencies[1].srcStageMask =
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
|
||||
subpassDependencies[1].srcAccessMask =
|
||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||
subpassDependencies[1].dstStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
|
||||
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
subpassDependencies[1].dstAccessMask =
|
||||
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_SHADER_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
subpassDependencies[1].dependencyFlags = 0;
|
||||
|
||||
// Render Pass
|
||||
VkRenderPassCreateInfo renderPassCreateInfo;
|
||||
renderPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
||||
@@ -988,8 +1034,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
renderPassCreateInfo.pAttachments = attachmentDescriptions.data();
|
||||
renderPassCreateInfo.subpassCount = 1;
|
||||
renderPassCreateInfo.pSubpasses = &subpassDesc;
|
||||
renderPassCreateInfo.dependencyCount = 0;
|
||||
renderPassCreateInfo.pDependencies = nullptr;
|
||||
renderPassCreateInfo.dependencyCount = 2;
|
||||
renderPassCreateInfo.pDependencies = subpassDependencies;
|
||||
|
||||
VkRenderPass renderPass = VK_NULL_HANDLE;
|
||||
VK_VERIFY(vkCreateRenderPass(m_device, &renderPassCreateInfo, nullptr, &renderPass));
|
||||
|
||||
Reference in New Issue
Block a user