[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).
This commit is contained in:
BZLZHH
2026-08-01 01:50:34 -04:00
parent 107b56d603
commit 4532cae175
8 changed files with 37 additions and 1 deletions
@@ -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) {
@@ -162,6 +162,7 @@ namespace MobileGL {
DepthComponent32F,
Depth24Stencil8,
Depth32FStencil8,
StencilIndex8,
DepthComponent,
DepthStencil,
@@ -28,6 +28,7 @@ namespace MobileGL {
bool IsStencilFormatInternalFormat(TextureInternalFormat internalformat) {
switch (internalformat) {
case TextureInternalFormat::StencilIndex8:
case TextureInternalFormat::Depth24Stencil8:
case TextureInternalFormat::Depth32FStencil8:
case TextureInternalFormat::DepthStencil:
@@ -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:
@@ -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:
@@ -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:
@@ -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:
@@ -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.