From 4532cae1754d5ce8b8f05f4235f3c9987580b33f Mon Sep 17 00:00:00 2001 From: BZLZHH Date: Sat, 1 Aug 2026 01:50:34 -0400 Subject: [PATCH] [Feat] (MG_Impl, MG_Util): STENCIL_INDEX8 renderbuffers; report distinct D/S renderbuffers unsupported GL_STENCIL_INDEX8 becomes a first-class internal format (VK_FORMAT_S8_UINT backing, metrics, classifiers, converters), so glRenderbufferStorage accepts it instead of leaving GL_INVALID_ENUM behind. Framebuffer completeness now also mirrors the renderer's gate for renderbuffers: distinct depth/stencil renderbuffer attachments (or a renderbuffer paired with a texture) report GL_FRAMEBUFFER_UNSUPPORTED - the spec only requires the same-image case - instead of passing completeness and then failing at draw/clear (verify_mixed_attachments.* now passes). --- .../GLImpl/Framebuffer/GL_Framebuffer.cpp | 24 ++++++++++++++++++- .../GLState/TextureState/TextureEnum.h | 1 + .../Classifiers/TextureEnumClassifier.cpp | 1 + .../GLToMG/TextureEnumConverter.cpp | 2 ++ .../MGToGL/TextureEnumConverter.cpp | 2 ++ .../MGToStr/TextureEnumConverter.cpp | 2 ++ .../MGToVk/TextureEnumConverter.cpp | 2 ++ MobileGL/MG_Util/Metrics/TextureMetrics.cpp | 4 ++++ 8 files changed, 37 insertions(+), 1 deletion(-) diff --git a/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.cpp b/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.cpp index 168dae63..3155751a 100644 --- a/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.cpp +++ b/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.cpp @@ -45,10 +45,32 @@ namespace MobileGL::MG_Impl::GLImpl { depthAttachment.GetTextureLevel() != stencilAttachment.GetTextureLevel(); } + // Mirrors the renderer-side gate: distinct depth/stencil renderbuffers (or a + // renderbuffer paired with a texture) cannot form one Vulkan depth-stencil + // attachment, and GL permits reporting such framebuffers as UNSUPPORTED. + Bool HasDistinctCompleteDepthStencilRenderbufferAttachments( + const MG_State::GLState::FramebufferObject& framebufferObject) { + if (framebufferObject.GetExternalIndex() == 0) { + return false; + } + + const auto& depthAttachment = framebufferObject.GetAttachment(FramebufferAttachmentType::Depth); + const auto& stencilAttachment = framebufferObject.GetAttachment(FramebufferAttachmentType::Stencil); + if (!depthAttachment.IsComplete() || !stencilAttachment.IsComplete()) { + return false; + } + if (depthAttachment.IsRenderbuffer() && stencilAttachment.IsRenderbuffer()) { + return depthAttachment.GetRenderbuffer().get() != stencilAttachment.GetRenderbuffer().get(); + } + return (depthAttachment.IsRenderbuffer() || stencilAttachment.IsRenderbuffer()) && + (depthAttachment.IsTexture() || stencilAttachment.IsTexture()); + } + Bool IsUnsupportedFramebufferForDirectVulkan( const MG_State::GLState::FramebufferObject& framebufferObject) { // TODO: Keep this in sync with DirectVulkan renderbuffer support as color renderbuffer rendering lands. - return HasDistinctCompleteDepthStencilTextureAttachments(framebufferObject); + return HasDistinctCompleteDepthStencilTextureAttachments(framebufferObject) || + HasDistinctCompleteDepthStencilRenderbufferAttachments(framebufferObject); } Bool HasDefinedAttachment(const MG_State::GLState::FramebufferObject& framebufferObject) { diff --git a/MobileGL/MG_State/GLState/TextureState/TextureEnum.h b/MobileGL/MG_State/GLState/TextureState/TextureEnum.h index 945d1b59..5934be40 100644 --- a/MobileGL/MG_State/GLState/TextureState/TextureEnum.h +++ b/MobileGL/MG_State/GLState/TextureState/TextureEnum.h @@ -162,6 +162,7 @@ namespace MobileGL { DepthComponent32F, Depth24Stencil8, Depth32FStencil8, + StencilIndex8, DepthComponent, DepthStencil, diff --git a/MobileGL/MG_Util/Classifiers/TextureEnumClassifier.cpp b/MobileGL/MG_Util/Classifiers/TextureEnumClassifier.cpp index 2c6fc424..ed7ec4a7 100644 --- a/MobileGL/MG_Util/Classifiers/TextureEnumClassifier.cpp +++ b/MobileGL/MG_Util/Classifiers/TextureEnumClassifier.cpp @@ -28,6 +28,7 @@ namespace MobileGL { bool IsStencilFormatInternalFormat(TextureInternalFormat internalformat) { switch (internalformat) { + case TextureInternalFormat::StencilIndex8: case TextureInternalFormat::Depth24Stencil8: case TextureInternalFormat::Depth32FStencil8: case TextureInternalFormat::DepthStencil: diff --git a/MobileGL/MG_Util/Converters/GLToMG/TextureEnumConverter.cpp b/MobileGL/MG_Util/Converters/GLToMG/TextureEnumConverter.cpp index 48ace6bd..48ffa047 100644 --- a/MobileGL/MG_Util/Converters/GLToMG/TextureEnumConverter.cpp +++ b/MobileGL/MG_Util/Converters/GLToMG/TextureEnumConverter.cpp @@ -251,6 +251,8 @@ namespace MobileGL { return TextureInternalFormat::Depth24Stencil8; case GL_DEPTH32F_STENCIL8: return TextureInternalFormat::Depth32FStencil8; + case GL_STENCIL_INDEX8: + return TextureInternalFormat::StencilIndex8; case GL_DEPTH_COMPONENT: return TextureInternalFormat::DepthComponent; case GL_DEPTH_STENCIL: diff --git a/MobileGL/MG_Util/Converters/MGToGL/TextureEnumConverter.cpp b/MobileGL/MG_Util/Converters/MGToGL/TextureEnumConverter.cpp index bee9ac88..daea937f 100644 --- a/MobileGL/MG_Util/Converters/MGToGL/TextureEnumConverter.cpp +++ b/MobileGL/MG_Util/Converters/MGToGL/TextureEnumConverter.cpp @@ -233,6 +233,8 @@ namespace MobileGL { return GL_DEPTH24_STENCIL8; case TextureInternalFormat::Depth32FStencil8: return GL_DEPTH32F_STENCIL8; + case TextureInternalFormat::StencilIndex8: + return GL_STENCIL_INDEX8; case TextureInternalFormat::DepthComponent32: return GL_DEPTH_COMPONENT32; case TextureInternalFormat::DepthStencil: diff --git a/MobileGL/MG_Util/Converters/MGToStr/TextureEnumConverter.cpp b/MobileGL/MG_Util/Converters/MGToStr/TextureEnumConverter.cpp index 92b9efb6..2eda2552 100644 --- a/MobileGL/MG_Util/Converters/MGToStr/TextureEnumConverter.cpp +++ b/MobileGL/MG_Util/Converters/MGToStr/TextureEnumConverter.cpp @@ -234,6 +234,8 @@ namespace MobileGL { return "Depth24Stencil8"; case TextureInternalFormat::Depth32FStencil8: return "Depth32FStencil8"; + case TextureInternalFormat::StencilIndex8: + return "StencilIndex8"; case TextureInternalFormat::Red: return "Red"; case TextureInternalFormat::RG: diff --git a/MobileGL/MG_Util/Converters/MGToVk/TextureEnumConverter.cpp b/MobileGL/MG_Util/Converters/MGToVk/TextureEnumConverter.cpp index 7a7041fb..ab57de7f 100644 --- a/MobileGL/MG_Util/Converters/MGToVk/TextureEnumConverter.cpp +++ b/MobileGL/MG_Util/Converters/MGToVk/TextureEnumConverter.cpp @@ -226,6 +226,8 @@ namespace MobileGL { return VK_FORMAT_D24_UNORM_S8_UINT; case TextureInternalFormat::Depth32FStencil8: return VK_FORMAT_D32_SFLOAT_S8_UINT; + case TextureInternalFormat::StencilIndex8: + return VK_FORMAT_S8_UINT; case TextureInternalFormat::DepthComponent32: return VK_FORMAT_D32_SFLOAT; case TextureInternalFormat::DepthStencil: diff --git a/MobileGL/MG_Util/Metrics/TextureMetrics.cpp b/MobileGL/MG_Util/Metrics/TextureMetrics.cpp index af7645d0..4e9d5ac0 100644 --- a/MobileGL/MG_Util/Metrics/TextureMetrics.cpp +++ b/MobileGL/MG_Util/Metrics/TextureMetrics.cpp @@ -18,6 +18,7 @@ namespace MobileGL { case TextureInternalFormat::Red: // UNorm8 shadow layout case TextureInternalFormat::R8Snorm: case TextureInternalFormat::R8I: + case TextureInternalFormat::StencilIndex8: case TextureInternalFormat::R8UI: return 1; @@ -508,6 +509,9 @@ namespace MobileGL { s.Depth = 32; s.Stencil = 8; break; + case TextureInternalFormat::StencilIndex8: + s.Stencil = 8; + break; case TextureInternalFormat::Unknown: // Queried for attachments that have no storage yet (e.g. framebuffer // parameter queries on the initial state); every size stays 0.