mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-12 06:08:30 +09:00
[Fix] (MG_Impl, MG_Backend): let the backend that can honour a layered attachment have it
NamedFramebufferTextureLayer declined every attachment but layer zero, on both backends. That was right for DirectVulkan, which maps a GL layer onto a Vulkan array layer with no notion of a 3D depth slice, but wrong for DirectGLES: SyncAttachmentObject already routes a layered upload target to glFramebufferTextureLayer with the attachment's layer passed straight through, and array storage already carries the real layer count into glTexStorage3D. The one backend that could render to the layer was being told it could not. The decision now lives in a DynamicBackendParameters flag, so it is the backend that answers rather than the entry point guessing. DirectGLES sets it when the driver resolved glFramebufferTextureLayer; DirectVulkan leaves it false until VkRenderPassManager tells a depth slice from an array layer. framebuffers_texture_layer_attachment's colour checks now pass on Espryt for 3D, 2D array and 2D multisample array textures - the case still fails there on cube map arrays, which DirectGLES gives no storage at all, and on the depth and stencil halves. No case changes on DirectVulkan, which keeps the old behaviour.
This commit is contained in:
@@ -353,6 +353,12 @@ namespace MobileGL {
|
|||||||
// real ES drivers behind DirectGLES both do. Defaults to true so a backend
|
// real ES drivers behind DirectGLES both do. Defaults to true so a backend
|
||||||
// that never sets it keeps the permissive behaviour.
|
// that never sets it keeps the permissive behaviour.
|
||||||
Bool SupportsDistinctDepthStencilAttachments = true;
|
Bool SupportsDistinctDepthStencilAttachments = true;
|
||||||
|
// Whether attaching a single layer of a 3D or array texture to a framebuffer actually
|
||||||
|
// renders to that layer. DirectGLES hands the layer straight to
|
||||||
|
// glFramebufferTextureLayer, so it does; DirectVulkan maps a GL layer onto a Vulkan
|
||||||
|
// array layer with no notion of a 3D depth slice, so it does not yet. Defaults to false
|
||||||
|
// so a backend that never sets it gets the conservative answer.
|
||||||
|
Bool SupportsPerLayerFramebufferAttachment = false;
|
||||||
SizeT MaxShaderStorageBlockSize = 128 * 1024 * 1024;
|
SizeT MaxShaderStorageBlockSize = 128 * 1024 * 1024;
|
||||||
Uint32 SubgroupSize = 0;
|
Uint32 SubgroupSize = 0;
|
||||||
Uint32 SubgroupSupportedStages = 0;
|
Uint32 SubgroupSupportedStages = 0;
|
||||||
|
|||||||
@@ -1109,6 +1109,11 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
clampStageImageUniforms(m_GLESCapabilities.MaxComputeImageUniforms);
|
clampStageImageUniforms(m_GLESCapabilities.MaxComputeImageUniforms);
|
||||||
m_dynamicParameters.SupportsDistinctDepthStencilAttachments =
|
m_dynamicParameters.SupportsDistinctDepthStencilAttachments =
|
||||||
ProbeDistinctDepthStencilAttachments(DirectGLES::g_GLESFuncs);
|
ProbeDistinctDepthStencilAttachments(DirectGLES::g_GLESFuncs);
|
||||||
|
// SyncAttachmentObject routes a layered upload target to glFramebufferTextureLayer with the
|
||||||
|
// attachment's layer passed through, so this backend really does render to the layer it was
|
||||||
|
// given - provided the driver resolved the entry point at all.
|
||||||
|
m_dynamicParameters.SupportsPerLayerFramebufferAttachment =
|
||||||
|
DirectGLES::g_GLESFuncs.glFramebufferTextureLayer != nullptr;
|
||||||
m_dynamicParameters.MaxDrawBuffers = m_GLESCapabilities.MaxDrawBuffers;
|
m_dynamicParameters.MaxDrawBuffers = m_GLESCapabilities.MaxDrawBuffers;
|
||||||
m_dynamicParameters.MaxColorAttachments = m_GLESCapabilities.MaxColorAttachments;
|
m_dynamicParameters.MaxColorAttachments = m_GLESCapabilities.MaxColorAttachments;
|
||||||
m_dynamicParameters.MaxClipDistances = m_GLESCapabilities.MaxClipDistances;
|
m_dynamicParameters.MaxClipDistances = m_GLESCapabilities.MaxClipDistances;
|
||||||
|
|||||||
@@ -1398,21 +1398,20 @@ namespace MobileGL::MG_Impl::GLImpl {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Everything above is the spec's error set and is answered for every target and every
|
// Everything above is the spec's error set and is answered for every target and every layer
|
||||||
// layer. Actually attaching a layer other than the first is a different matter: no backend
|
// on every backend. Whether the attachment can actually be honoured is a backend question:
|
||||||
// resolves a GL layer onto its image yet. The Vulkan renderer treats the layer as an array
|
// DirectGLES hands the layer to glFramebufferTextureLayer and renders to it, while
|
||||||
// slice - so a 3D texture's z-slice lands outside its single-array-layer image - and the
|
// DirectVulkan maps a GL layer onto a Vulkan array layer with no notion of a 3D depth slice,
|
||||||
// array texture objects are still the one-image stubs in TextureObjectStubs.h, whose image
|
// so a slice lands outside the image and the renderer asserts on the clear. Letting it
|
||||||
// has one layer whatever GL thinks. Letting the attachment through only moves the failure
|
// through there would only move the failure downstream, so it is declined instead - layer
|
||||||
// downstream into a clear whose layer span is outside the image; declining keeps it a
|
// zero always works, being the plain first-slice attachment.
|
||||||
// reported error. Layer zero is the plain first-slice attachment the by-target
|
const Bool backsLayeredAttachment = limits.SupportsPerLayerFramebufferAttachment;
|
||||||
// glFramebufferTextureLayer already backs, so it goes through.
|
// A cube map array additionally has no image shape at all in VkTextureManager, so on that
|
||||||
// A cube map array has no Vulkan image shape at all (TryResolveTextureShapeInfo), so it
|
// backend it cannot be an attachment whatever the layer is.
|
||||||
// cannot be an attachment on that backend whatever the layer is.
|
const Bool isCubeMapArray = textureObject->GetTarget() == TextureTarget::TextureCubeMapArray;
|
||||||
if (layer != 0 || textureObject->GetTarget() == TextureTarget::TextureCubeMapArray) {
|
if ((layer != 0 && !backsLayeredAttachment) || (isCubeMapArray && !backsLayeredAttachment)) {
|
||||||
RecordUnsupportedFramebufferTextureAttachmentError(
|
RecordUnsupportedFramebufferTextureAttachmentError(
|
||||||
__func__, "Attaching a layer other than the first, or any layer of a cube map array, is not "
|
__func__, "This backend does not resolve a framebuffer attachment's layer onto its image.");
|
||||||
"represented by the current framebuffer attachment model.");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user