mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-12 14:18:31 +09:00
[Fix] (DirectVulkan): declare only the used colour attachment span per subpass
- every render pass declared colorAttachmentCount=8 (the full GL draw-buffer slot span) with trailing VK_ATTACHMENT_UNUSED references, and Adreno configures its per-pixel render-backend/export path from the DECLARED count - so every fragment of every pass paid an 8-render-target export cost; this was the bulk of the 1.5x per-pixel gap against MobileGlues+ANGLE on the same Qualcomm driver (their subpasses declare exactly the used span) - measured on Adreno 650 / MC 26.2 / 1440x3044: total GPU frame time 11.9 -> 7.5 ms (-37%, now below ANGLE's 7.87 ms), the single-quad swapchain blit pass alone 1.26 -> 0.40 ms, steady in-world FPS 82.8 -> 123 under the standard cooled-start protocol, matching the MobileGlues+ANGLE+system-Vulkan benchmark of 123.8 - trailing UNUSED references are popped before the subpass is built (the entry's colorAttachmentCount and every pipeline's colour-blend span follow it); interior GL_NONE holes keep their slots so fragment-output locations still line up - the pipeline-side fragmentOutputMask check downgrades from assert to a debug log: an output at a location past the trimmed span is discarded, which is GL's defined behaviour for a draw buffer set to GL_NONE
This commit is contained in:
@@ -1187,6 +1187,22 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
}
|
}
|
||||||
const Bool hasDepthStencilAttachment = depthAttachmentRef.attachment != VK_ATTACHMENT_UNUSED;
|
const Bool hasDepthStencilAttachment = depthAttachmentRef.attachment != VK_ATTACHMENT_UNUSED;
|
||||||
|
|
||||||
|
// Declare only the used colour-reference span. The GL draw-buffer array
|
||||||
|
// always spans 8 slots, so passes used to declare colorAttachmentCount=8
|
||||||
|
// with trailing VK_ATTACHMENT_UNUSED holes - and Adreno configures its
|
||||||
|
// per-pixel render-backend/export path from the DECLARED count, so every
|
||||||
|
// fragment of every pass paid the 8-target export cost (measured on
|
||||||
|
// Adreno 650 / MC 26.2: 11.9 -> 7.5 ms of GPU time per frame, with the
|
||||||
|
// single-quad swapchain blit pass alone dropping 1.26 -> 0.40 ms).
|
||||||
|
// Interior GL_NONE holes keep their slots so fragment-output locations
|
||||||
|
// still line up; a fragment output at a location past the trimmed count
|
||||||
|
// is discarded, which is exactly GL's semantic for writing to a draw
|
||||||
|
// buffer set to GL_NONE.
|
||||||
|
while (!colorAttachmentRefs.empty() &&
|
||||||
|
colorAttachmentRefs.back().attachment == VK_ATTACHMENT_UNUSED) {
|
||||||
|
colorAttachmentRefs.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
// Subpass
|
// Subpass
|
||||||
VkSubpassDescription subpassDesc;
|
VkSubpassDescription subpassDesc;
|
||||||
subpassDesc.flags = 0;
|
subpassDesc.flags = 0;
|
||||||
|
|||||||
@@ -4041,12 +4041,15 @@ void main() {
|
|||||||
payload.backStencilCompareOp = VK_COMPARE_OP_ALWAYS;
|
payload.backStencilCompareOp = VK_COMPARE_OP_ALWAYS;
|
||||||
}
|
}
|
||||||
const Uint32 fragmentOutputMask = programObj.activeFragmentOutputLocationMask;
|
const Uint32 fragmentOutputMask = programObj.activeFragmentOutputLocationMask;
|
||||||
MOBILEGL_ASSERT(
|
// Outputs at locations past the render pass's trimmed colour span are
|
||||||
(fragmentOutputMask >> payload.colorAttachmentCount) == 0,
|
// simply discarded - GL's semantic for a fragment output whose draw
|
||||||
"GetOrCreatePipeline: fragmentOutputMask=0x%x exceeds colorAttachmentCount=%u for program=%u",
|
// buffer is GL_NONE (the trailing UNUSED slots no longer occupy
|
||||||
fragmentOutputMask,
|
// references, see GetOrCreateRenderPass).
|
||||||
payload.colorAttachmentCount,
|
if ((fragmentOutputMask >> payload.colorAttachmentCount) != 0) {
|
||||||
program.GetExternalIndex());
|
MGLOG_D("GetOrCreatePipeline: fragmentOutputMask=0x%x exceeds colorAttachmentCount=%u for program=%u; "
|
||||||
|
"outputs past the span are discarded",
|
||||||
|
fragmentOutputMask, payload.colorAttachmentCount, program.GetExternalIndex());
|
||||||
|
}
|
||||||
MOBILEGL_ASSERT(payload.colorAttachmentCount <= PipelineFactory::PipelineCreatePayload::kMaxColorAttachments,
|
MOBILEGL_ASSERT(payload.colorAttachmentCount <= PipelineFactory::PipelineCreatePayload::kMaxColorAttachments,
|
||||||
"GetOrCreatePipeline: colorAttachmentCount=%u exceeds payload capacity",
|
"GetOrCreatePipeline: colorAttachmentCount=%u exceeds payload capacity",
|
||||||
payload.colorAttachmentCount);
|
payload.colorAttachmentCount);
|
||||||
|
|||||||
Reference in New Issue
Block a user