[Fix] (MG_Backend/DirectVulkan): clear every layer of layered framebuffers in vkCmdClearAttachments paths (rename the never-read RenderPassEntry::subpass to layers)

This commit is contained in:
2026-07-16 21:17:59 -04:00
parent 4172959e49
commit 5184901a5b
3 changed files with 10 additions and 7 deletions
@@ -1015,7 +1015,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
hasDepthStencilAttachment,
renderPassSampleCount,
extent,
static_cast<Int>(framebufferLayers) };
framebufferLayers };
MGLOG_D("VkRenderPassManager::GetOrCreateRenderPass: hash=0x%llx compatibilityHash=0x%llx attachmentCount=%u colorAttachmentCount=%u samples=%d extent=%dx%d",
static_cast<unsigned long long>(hash),
static_cast<unsigned long long>(compatibilityHash),
@@ -68,7 +68,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
Bool hasDepthStencilAttachment = false;
VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
IntVec2 extent = {0, 0};
Uint32 subpass = 0;
// VkFramebufferCreateInfo::layers of the entry's framebuffer (>1 for layered GL attachments).
Uint32 layers = 1;
RenderPassEntry() = default;
RenderPassEntry(const RenderPassEntry&) = delete;
@@ -84,7 +85,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
std::swap(hasDepthStencilAttachment, that.hasDepthStencilAttachment);
std::swap(sampleCount, that.sampleCount);
std::swap(extent, that.extent);
std::swap(subpass, that.subpass);
std::swap(layers, that.layers);
}
RenderPassEntry(
Uint64 hash,
@@ -97,7 +98,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
Uint32 colorAttachmentCount,
Bool hasDepthStencilAttachment,
VkSampleCountFlagBits sampleCount,
IntVec2 extent, int subpass):
IntVec2 extent, Uint32 layers):
hash(hash),
renderPass(renderpass),
framebuffer(framebuffer),
@@ -109,7 +110,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
hasDepthStencilAttachment(hasDepthStencilAttachment),
sampleCount(sampleCount),
extent(extent),
subpass(subpass)
layers(layers)
{}
~RenderPassEntry() {
@@ -3646,7 +3646,8 @@ void main() {
m_swapchainObject.GetPreTransform())
: MakeClampedScissorRect(MG_State::pGLContext->GetScissorBox(), renderPassEntry->extent);
clearRect.baseArrayLayer = 0;
clearRect.layerCount = 1;
// GL 3.3 §4.4.7: clearing a layered framebuffer clears every layer.
clearRect.layerCount = renderPassEntry->layers;
if (clearRect.rect.extent.width == 0 || clearRect.rect.extent.height == 0) {
return;
}
@@ -6885,7 +6886,8 @@ void main() {
static_cast<Uint32>(activeRenderPass->extent.y())
};
clearRect.baseArrayLayer = 0;
clearRect.layerCount = 1;
// Compatible entries share the framebuffer layer count; layered attachments clear every layer.
clearRect.layerCount = compatibleRenderPassEntry.layers;
for (const auto& pending : compatibleRenderPassEntry.pendingClearAttachments) {
if (!pending.hasInlinePayload && pending.key.texture == nullptr) {