mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-08 20:28:32 +09:00
[Fix] (DirectVulkan): stop replaying consumed renderbuffer clears mid-pass
A cached RenderPassEntry bakes renderbuffer clear payloads inline into its pendingClearAttachments, and that list outlives the clear's consumption at pass begin (loadOp CLEAR). Every subsequent draw that reused the entry while its pass was still active replayed the stale clear through vkCmdClearAttachments, wiping the color and depth of everything drawn so far in the pass. Texture-keyed clears already re-checked the clear manager before clearing; do the same for inline renderbuffer payloads: only clear while the renderbuffer clear is still actually pending, and take the live payload so a newer glClear's values win. On lavapipe this takes KHR-GL33.shaders.fragdepth.* from 0/18 to 18/18; the same defect hit any renderbuffer-FBO case with several draws per pass.
This commit is contained in:
@@ -9256,7 +9256,20 @@ void main() {
|
||||
ClearAttachmentPayload clearPayload{};
|
||||
SharedPtr<MG_State::GLState::ITextureObject> liveTexture;
|
||||
if (pending.hasInlinePayload) {
|
||||
clearPayload = pending.inlinePayload;
|
||||
// The inline payload is baked into the cached RenderPassEntry and outlives
|
||||
// its consumption at pass begin (loadOp CLEAR). Replaying it here would
|
||||
// wipe every draw already recorded in the pass, so only clear while the
|
||||
// renderbuffer's clear is still actually pending, and take the live
|
||||
// payload (a newer glClear may carry different values).
|
||||
if (!m_renderPassManager->GetPendingRenderbufferClear(pending.renderbuffer, clearPayload)) {
|
||||
continue;
|
||||
}
|
||||
if ((clearPayload.mask & GL_COLOR_BUFFER_BIT) != 0 && pending.renderbuffer != nullptr &&
|
||||
MG_Util::GetBaseInternalFormatComponentCount(pending.renderbuffer->GetInternalFormat()) == 3) {
|
||||
// RGB renderbuffers are backed by an RGBA image; the missing alpha reads as 1.
|
||||
clearPayload.color = FloatVec4(clearPayload.color.x(), clearPayload.color.y(),
|
||||
clearPayload.color.z(), 1.0f);
|
||||
}
|
||||
} else {
|
||||
if (!m_clearManager->GetPendingClear(pending.key, clearPayload, liveTexture)) {
|
||||
continue;
|
||||
|
||||
Reference in New Issue
Block a user