mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-08 04:08:32 +09:00
[Fix] (MG_Impl): ask whether a colour format is renderable per target
The framebuffer-completeness check scanned every row of the backend's format-capability cache and called the format renderable if any target said so. That was already loose, and it broke outright once DirectGLES started widening three-channel formats so they stay renderable as multisample storage: the caveat capability recorded for the multisample target made GL_RGB8_SNORM look renderable everywhere, so an ordinary 2D GL_RGB8_SNORM texture attachment reported GL_FRAMEBUFFER_COMPLETE while the driver's own framebuffer was INCOMPLETE_ATTACHMENT. KHR-GL3x.packed_pixels stopped skipping those formats and read a framebuffer that could not be read, so all 18 of its rgb8_snorm cases got back an untouched buffer. Pass the row the attachment actually lives in - the texture's target, or the renderbuffer row - and consult only that one; a format is still asked about in general when the caller has no target.
This commit is contained in:
@@ -101,7 +101,14 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
// shared-exponent, SNORM, three-channel norm16/float32/sRGB and three-channel integer formats.
|
||||
// Desktop GL treats those as texture-only too (not in the GL 3.3 required-renderable list), so
|
||||
// reporting GL_FRAMEBUFFER_UNSUPPORTED for them is legal.
|
||||
Bool IsColorInternalFormatRenderable(TextureInternalFormat format) {
|
||||
//
|
||||
// `capabilityTargetIndex` is the row of the cache the attachment actually lives in;
|
||||
// kFormatCapabilityTargetCount asks about the format in general. Asking per target matters
|
||||
// because a capability recorded for one of them says nothing about the others: DirectGLES
|
||||
// widens three-channel formats to four channels to keep them renderable as *multisample*
|
||||
// storage, and a format that survives only through that substitution is still texture-only
|
||||
// on every ordinary target.
|
||||
Bool IsColorInternalFormatRenderable(TextureInternalFormat format, SizeT capabilityTargetIndex) {
|
||||
const SizeT formatIndex = static_cast<SizeT>(format);
|
||||
if (MG_Backend::pActiveBackendObject && formatIndex < MG_Backend::kFormatCapabilityFormatCount) {
|
||||
const auto& cache = MG_Backend::pActiveBackendObject->GetFormatCapabilities();
|
||||
@@ -113,8 +120,11 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
MG_Backend::FormatCapability::Creatable);
|
||||
}
|
||||
if (cachePopulated) {
|
||||
for (SizeT targetIndex = 0; targetIndex < MG_Backend::kFormatCapabilityTargetCount;
|
||||
++targetIndex) {
|
||||
const Bool singleTarget = capabilityTargetIndex < MG_Backend::kFormatCapabilityTargetCount;
|
||||
const SizeT firstTarget = singleTarget ? capabilityTargetIndex : 0;
|
||||
const SizeT lastTarget =
|
||||
singleTarget ? capabilityTargetIndex + 1 : MG_Backend::kFormatCapabilityTargetCount;
|
||||
for (SizeT targetIndex = firstTarget; targetIndex < lastTarget; ++targetIndex) {
|
||||
if (MG_Backend::HasFormatCapability(cache.FullCaps[targetIndex][formatIndex],
|
||||
MG_Backend::FormatCapability::FramebufferRenderable) ||
|
||||
MG_Backend::HasFormatCapability(cache.CaveatCaps[targetIndex][formatIndex],
|
||||
@@ -163,12 +173,17 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
const auto& attachment = attachments[i];
|
||||
if (!attachment.IsValid()) continue;
|
||||
TextureInternalFormat format = TextureInternalFormat::Unknown;
|
||||
SizeT capabilityTargetIndex = MG_Backend::kFormatCapabilityTargetCount;
|
||||
if (attachment.IsTexture() && attachment.GetTexture()) {
|
||||
format = attachment.GetTexture()->GetFormat();
|
||||
capabilityTargetIndex =
|
||||
MG_Backend::GetFormatCapabilityTargetIndex(attachment.GetTexture()->GetTarget());
|
||||
} else if (attachment.IsRenderbuffer() && attachment.GetRenderbuffer()) {
|
||||
format = attachment.GetRenderbuffer()->GetInternalFormat();
|
||||
capabilityTargetIndex = MG_Backend::GetRenderbufferFormatCapabilityTargetIndex();
|
||||
}
|
||||
if (format != TextureInternalFormat::Unknown && !IsColorInternalFormatRenderable(format)) {
|
||||
if (format != TextureInternalFormat::Unknown &&
|
||||
!IsColorInternalFormatRenderable(format, capabilityTargetIndex)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user