From 940ab5fd8e99e0fd6ac15daa14a898ab4030c847 Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Fri, 3 Jul 2026 10:38:51 +0800 Subject: [PATCH] [Fix] (MG_State/GLState, MG_Backend): track layered framebuffer textures --- MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp | 22 ++++++--- MobileGL/MG_Backend/DirectGLES/Managers.cpp | 22 +++++---- .../DirectVulkan/Renderer/VkClearManager.cpp | 25 ++++++++-- .../Renderer/VkRenderPassManager.cpp | 22 +++++++-- .../Renderer/VkTextureManager.cpp | 10 ++++ .../DirectVulkan/Renderer/VulkanRenderer.cpp | 17 ++++++- .../GLImpl/Framebuffer/GL_Framebuffer.cpp | 46 +++++++++++++++---- .../FramebufferState/FramebufferObject.cpp | 19 ++++++-- .../FramebufferState/FramebufferObject.h | 9 +++- .../GLState/TextureState/TextureObjectStubs.h | 2 +- 10 files changed, 155 insertions(+), 39 deletions(-) diff --git a/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp b/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp index 7ca9b980..60bc6453 100644 --- a/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp +++ b/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp @@ -1793,12 +1793,16 @@ namespace MobileGL::MG_Backend::DirectGLES { const GLuint backendFBOId = backendFBO->GetBackendFramebufferId(); g_GLESFuncs.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, backendFBOId); - g_GLESFuncs.glFramebufferTexture2D( - GL_DRAW_FRAMEBUFFER, backendAttachment, textureTarget, 0, 0); + if (attachmentObject.IsLayered()) { + g_GLESFuncs.glFramebufferTexture(GL_DRAW_FRAMEBUFFER, backendAttachment, 0, 0); + } else { + g_GLESFuncs.glFramebufferTexture2D( + GL_DRAW_FRAMEBUFFER, backendAttachment, textureTarget, 0, 0); + } ClearGLErrors(); m_detachedAttachments.push_back( {backendFBOId, backendAttachment, textureTarget, backendTextureId, - static_cast(attachmentObject.GetTextureLevel())}); + static_cast(attachmentObject.GetTextureLevel()), attachmentObject.IsLayered()}); } } } @@ -1806,9 +1810,14 @@ namespace MobileGL::MG_Backend::DirectGLES { ~ScopedDetachedTextureFramebufferAttachments() { for (const auto& attachment : m_detachedAttachments) { g_GLESFuncs.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, attachment.framebuffer); - g_GLESFuncs.glFramebufferTexture2D( - GL_DRAW_FRAMEBUFFER, attachment.attachment, attachment.textureTarget, - attachment.texture, attachment.level); + if (attachment.layered) { + g_GLESFuncs.glFramebufferTexture( + GL_DRAW_FRAMEBUFFER, attachment.attachment, attachment.texture, attachment.level); + } else { + g_GLESFuncs.glFramebufferTexture2D( + GL_DRAW_FRAMEBUFFER, attachment.attachment, attachment.textureTarget, + attachment.texture, attachment.level); + } } g_GLESFuncs.glBindFramebuffer(GL_READ_FRAMEBUFFER, m_prevReadFBO); g_GLESFuncs.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_prevDrawFBO); @@ -1821,6 +1830,7 @@ namespace MobileGL::MG_Backend::DirectGLES { GLenum textureTarget = GL_TEXTURE_2D; GLuint texture = 0; GLint level = 0; + Bool layered = false; }; GLuint m_prevReadFBO = 0; diff --git a/MobileGL/MG_Backend/DirectGLES/Managers.cpp b/MobileGL/MG_Backend/DirectGLES/Managers.cpp index e977a09a..255fd34d 100644 --- a/MobileGL/MG_Backend/DirectGLES/Managers.cpp +++ b/MobileGL/MG_Backend/DirectGLES/Managers.cpp @@ -1283,15 +1283,21 @@ namespace MobileGL::MG_Backend::DirectGLES { return false; } backendTextureObject->SyncMipmapsToBackend(textureObject); - auto glTextureTarget = - MG_Util::ConvertTextureUploadTargetToGLEnum(attachmentObject.GetTextureUploadTarget()); - if (glTextureTarget == GL_UNKNOWN_MGL) { - glTextureTarget = MG_Util::ConvertTextureTargetToGLEnum(textureObject->GetTarget()); + if (attachmentObject.IsLayered()) { + g_GLESFuncs.glFramebufferTexture(glFBOTarget, glBackendAttachment, + backendTextureObject->GetBackendTextureId(), + static_cast(attachmentObject.GetTextureLevel())); + } else { + auto glTextureTarget = + MG_Util::ConvertTextureUploadTargetToGLEnum(attachmentObject.GetTextureUploadTarget()); + if (glTextureTarget == GL_UNKNOWN_MGL) { + glTextureTarget = MG_Util::ConvertTextureTargetToGLEnum(textureObject->GetTarget()); + } + backendTextureObject->Bind(glTextureTarget); + g_GLESFuncs.glFramebufferTexture2D(glFBOTarget, glBackendAttachment, glTextureTarget, + backendTextureObject->GetBackendTextureId(), + static_cast(attachmentObject.GetTextureLevel())); } - backendTextureObject->Bind(glTextureTarget); - g_GLESFuncs.glFramebufferTexture2D(glFBOTarget, glBackendAttachment, glTextureTarget, - backendTextureObject->GetBackendTextureId(), - static_cast(attachmentObject.GetTextureLevel())); } else if (attachmentObject.IsRenderbuffer()) { const auto& renderbufferObject = attachmentObject.GetRenderbuffer(); const auto& backendRenderbufferIt = diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkClearManager.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkClearManager.cpp index 20c2a16d..35c97386 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkClearManager.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkClearManager.cpp @@ -28,6 +28,26 @@ namespace MobileGL::MG_Backend::DirectVulkan { return static_cast(target) - static_cast(TextureUploadTarget::CubeMapPositiveX); } + static Uint32 ResolveAttachmentBaseArrayLayer( + const MG_State::GLState::FramebufferAttachmentObject& attachment) { + if (attachment.IsLayered()) { + return 0; + } + const TextureUploadTarget uploadTarget = attachment.GetTextureUploadTarget(); + if (!IsCubeMapFaceUploadTarget(uploadTarget)) { + return static_cast(std::max(attachment.GetTextureLayer(), 0)); + } + return ResolveAttachmentBaseArrayLayer(uploadTarget); + } + + static Uint32 ResolveAttachmentLayerCount( + const MG_State::GLState::FramebufferAttachmentObject& attachment) { + if (attachment.IsLayered()) { + return static_cast(std::max(attachment.GetSize().z(), 1)); + } + return 1u; + } + static const MG_State::GLState::FramebufferAttachmentObject* GetClearableAttachment( const MG_State::GLState::FramebufferObject& drawFbo, FramebufferAttachmentType attachmentType) { if (attachmentType == FramebufferAttachmentType::None) { @@ -60,9 +80,8 @@ namespace MobileGL::MG_Backend::DirectVulkan { auto* texture = attachment.GetTexture().get(); MOBILEGL_ASSERT(texture != nullptr, "MakePendingClearKey: texture attachment resolved to null"); const Uint32 mipLevel = static_cast(std::max(attachment.GetTextureLevel(), 0)); - const TextureUploadTarget uploadTarget = attachment.GetTextureUploadTarget(); - const Uint32 baseArrayLayer = ResolveAttachmentBaseArrayLayer(uploadTarget); - const Uint32 layerCount = IsCubeMapFaceUploadTarget(uploadTarget) ? 1u : 1u; + const Uint32 baseArrayLayer = ResolveAttachmentBaseArrayLayer(attachment); + const Uint32 layerCount = ResolveAttachmentLayerCount(attachment); return MakePendingClearKey(texture, mipLevel, baseArrayLayer, layerCount); } diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkRenderPassManager.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkRenderPassManager.cpp index bd1d0f2c..63568666 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkRenderPassManager.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkRenderPassManager.cpp @@ -73,22 +73,27 @@ namespace MobileGL::MG_Backend::DirectVulkan { } static Uint32 ResolveAttachmentBaseArrayLayer(const MG_State::GLState::FramebufferAttachmentObject& attachment) { + if (attachment.IsLayered()) { + return 0; + } const TextureUploadTarget uploadTarget = attachment.GetTextureUploadTarget(); if (!IsCubeMapFaceUploadTarget(uploadTarget)) { - return 0; + return static_cast(std::max(attachment.GetTextureLayer(), 0)); } return static_cast(uploadTarget) - static_cast(TextureUploadTarget::CubeMapPositiveX); } static Uint32 ResolveAttachmentLayerCount(const MG_State::GLState::FramebufferAttachmentObject& attachment) { - static_cast(attachment); + if (attachment.IsLayered()) { + return static_cast(std::max(attachment.GetSize().z(), 1)); + } return 1u; } static VkImageViewType ResolveAttachmentViewType( const MG_State::GLState::FramebufferAttachmentObject& attachment, const VkTextureManager::TextureResource& resource) { - return IsCubeMapFaceUploadTarget(attachment.GetTextureUploadTarget()) ? + return !attachment.IsLayered() && IsCubeMapFaceUploadTarget(attachment.GetTextureUploadTarget()) ? VK_IMAGE_VIEW_TYPE_2D : resource.viewType; } @@ -438,6 +443,10 @@ namespace MobileGL::MG_Backend::DirectVulkan { XXHASH_VERIFY(XXH64_update(m_hashState, &textureLevel, sizeof(textureLevel))); const TextureUploadTarget textureUploadTarget = att.GetTextureUploadTarget(); XXHASH_VERIFY(XXH64_update(m_hashState, &textureUploadTarget, sizeof(textureUploadTarget))); + const Int textureLayer = att.GetTextureLayer(); + XXHASH_VERIFY(XXH64_update(m_hashState, &textureLayer, sizeof(textureLayer))); + const Bool textureLayered = att.IsLayered(); + XXHASH_VERIFY(XXH64_update(m_hashState, &textureLayered, sizeof(textureLayered))); Uint64 imageIdentity = 0; auto* texture = att.GetTexture().get(); @@ -621,6 +630,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { attachmentViews.reserve(colorAttachmentSlotCount + 1); VkSampleCountFlagBits renderPassSampleCount = VK_SAMPLE_COUNT_1_BIT; Bool hasRenderPassSampleCount = false; + Uint32 framebufferLayers = 1; const auto adoptRenderPassSampleCount = [&](VkSampleCountFlagBits sampleCount, const char* attachmentKind, Int attachmentId) { @@ -713,6 +723,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { }); const Uint32 baseArrayLayer = ResolveAttachmentBaseArrayLayer(att); const Uint32 layerCount = ResolveAttachmentLayerCount(att); + framebufferLayers = std::max(framebufferLayers, layerCount); const VkImageViewType attachmentViewType = ResolveAttachmentViewType(att, *textureResource); attachmentViews.emplace_back( m_textureManager.GetOrCreateAttachmentViewAtMipLevel( @@ -877,6 +888,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { textureResources.emplace_back(depthTextureResource); const Uint32 baseArrayLayer = ResolveAttachmentBaseArrayLayer(*selectedDepthStencilAttachment); const Uint32 layerCount = ResolveAttachmentLayerCount(*selectedDepthStencilAttachment); + framebufferLayers = std::max(framebufferLayers, layerCount); const VkImageViewType attachmentViewType = ResolveAttachmentViewType(*selectedDepthStencilAttachment, *depthTextureResource); attachmentViews.emplace_back( @@ -953,7 +965,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { framebufferCreateInfo.pAttachments = attachmentViews.data(); framebufferCreateInfo.width = width; framebufferCreateInfo.height = height; - framebufferCreateInfo.layers = 1; + framebufferCreateInfo.layers = framebufferLayers; VkFramebuffer framebuffer = VK_NULL_HANDLE; VK_VERIFY(vkCreateFramebuffer(m_device, &framebufferCreateInfo, nullptr, &framebuffer)); IntVec2 extent = {width, height}; @@ -969,7 +981,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { hasDepthStencilAttachment, renderPassSampleCount, extent, - 1 }; + static_cast(framebufferLayers) }; MGLOG_D("VkRenderPassManager::GetOrCreateRenderPass: hash=0x%llx compatibilityHash=0x%llx attachmentCount=%u colorAttachmentCount=%u samples=%d extent=%dx%d", static_cast(hash), static_cast(compatibilityHash), diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkTextureManager.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkTextureManager.cpp index f3e3ea0f..a7fff018 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkTextureManager.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkTextureManager.cpp @@ -522,6 +522,16 @@ namespace MobileGL::MG_Backend::DirectVulkan { case TextureUploadTarget::ProxyTexture2DMultisample: outShape = {}; return true; + case TextureUploadTarget::Texture2DArray: + case TextureUploadTarget::ProxyTexture2DArray: + MOBILEGL_ASSERT(texelSize.z() > 0, + "TryResolveTextureShapeInfo: invalid 2D array depth=%d for textureId=%d", + texelSize.z(), texture.GetExternalIndex()); + outShape.imageType = VK_IMAGE_TYPE_2D; + outShape.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY; + outShape.depth = 1; + outShape.arrayLayers = static_cast(texelSize.z()); + return true; case TextureUploadTarget::Texture2DMultisampleArray: case TextureUploadTarget::ProxyTexture2DMultisampleArray: MOBILEGL_ASSERT(texelSize.z() > 0, diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp index 400a6fc9..15c6e102 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp @@ -923,11 +923,26 @@ namespace MobileGL::MG_Backend::DirectVulkan { return false; } + static Bool HasLayeredTextureAttachment(const MG_State::GLState::FramebufferObject& framebufferObject) { + if (framebufferObject.GetExternalIndex() == 0) { + return false; + } + + for (const auto& attachment : framebufferObject.GetAllAttachmentObjects()) { + if (attachment.IsTexture() && attachment.IsLayered()) { + return true; + } + } + return false; + } + static Bool IsUnsupportedFramebufferForDirectVulkan( const MG_State::GLState::FramebufferObject& framebufferObject) { // TODO: Revisit this gate when DirectVulkan has full color renderbuffer render/blit/readback support. + // TODO: Implement DirectVulkan layered framebuffer rendering instead of rejecting layered draw targets. return HasDistinctCompleteDepthStencilTextureAttachments(framebufferObject) || - HasUnsupportedCompleteRenderbufferAttachment(framebufferObject); + HasUnsupportedCompleteRenderbufferAttachment(framebufferObject) || + HasLayeredTextureAttachment(framebufferObject); } static void RecordUnsupportedFramebufferError(const char* func) { diff --git a/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.cpp b/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.cpp index a08b0734..e06f9032 100644 --- a/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.cpp +++ b/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.cpp @@ -67,7 +67,9 @@ namespace MobileGL::MG_Impl::GLImpl { } Bool ResolveRepresentableFramebufferTextureUploadTarget(const MG_State::GLState::ITextureObject& textureObject, - TextureUploadTarget& outUploadTarget) { + TextureUploadTarget& outUploadTarget, + Bool& outLayered) { + outLayered = false; switch (textureObject.GetTarget()) { case TextureTarget::Texture1D: outUploadTarget = TextureUploadTarget::Texture1D; @@ -81,7 +83,12 @@ namespace MobileGL::MG_Impl::GLImpl { case TextureTarget::Texture2DMultisample: outUploadTarget = TextureUploadTarget::Texture2DMultisample; return true; + case TextureTarget::Texture2DArray: + outUploadTarget = TextureUploadTarget::Texture2DArray; + outLayered = true; + return true; default: + // TODO: Extend layered framebuffer attachment support to 3D, cube, 1D array, and multisample array textures. outUploadTarget = TextureUploadTarget::Unknown; return false; } @@ -89,7 +96,7 @@ namespace MobileGL::MG_Impl::GLImpl { void AttachFramebufferTextureWithUploadTarget(const char* functionName, GLenum target, GLenum attachment, GLuint texture, GLint level, - TextureUploadTarget textureUploadTarget) { + TextureUploadTarget textureUploadTarget, Bool layered = false) { if (target == GL_FRAMEBUFFER) { target = GL_DRAW_FRAMEBUFFER; } @@ -145,7 +152,7 @@ namespace MobileGL::MG_Impl::GLImpl { return; } - framebufferObject->AttachTexture(attachmentType, textureObject, textureUploadTarget, level); + framebufferObject->AttachTexture(attachmentType, textureObject, textureUploadTarget, level, 0, layered); } } // namespace @@ -406,7 +413,15 @@ namespace MobileGL::MG_Impl::GLImpl { } break; case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER: - *params = 0; + *params = (attachmentObject != nullptr && attachmentObject->IsTexture() && attachmentObject->IsValid()) + ? static_cast(attachmentObject->GetTextureLayer()) + : 0; + break; + case GL_FRAMEBUFFER_ATTACHMENT_LAYERED: + *params = (attachmentObject != nullptr && attachmentObject->IsTexture() && attachmentObject->IsValid() && + attachmentObject->IsLayered()) + ? GL_TRUE + : GL_FALSE; break; default: MG_State::pGLContext->RecordError( @@ -661,14 +676,16 @@ namespace MobileGL::MG_Impl::GLImpl { } TextureUploadTarget textureUploadTarget = TextureUploadTarget::Unknown; - if (!ResolveRepresentableFramebufferTextureUploadTarget(*textureObject, textureUploadTarget)) { + Bool layered = false; + if (!ResolveRepresentableFramebufferTextureUploadTarget(*textureObject, textureUploadTarget, layered)) { RecordUnsupportedFramebufferTextureAttachmentError( __func__, "Layered or multi-image framebuffer texture targets are not fully represented by the current framebuffer attachment model."); return; } - AttachFramebufferTextureWithUploadTarget(__func__, target, attachment, texture, level, textureUploadTarget); + AttachFramebufferTextureWithUploadTarget(__func__, target, attachment, texture, level, textureUploadTarget, + layered); } void NamedFramebufferTexture_State(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level) { @@ -700,14 +717,15 @@ namespace MobileGL::MG_Impl::GLImpl { } TextureUploadTarget textureUploadTarget = TextureUploadTarget::Unknown; - if (!ResolveRepresentableFramebufferTextureUploadTarget(*textureObject, textureUploadTarget)) { + Bool layered = false; + if (!ResolveRepresentableFramebufferTextureUploadTarget(*textureObject, textureUploadTarget, layered)) { RecordUnsupportedFramebufferTextureAttachmentError( "NamedFramebufferTexture_State", "Layered or multi-image framebuffer texture targets are not fully represented by the current framebuffer attachment model."); return; } - framebufferObject->AttachTexture(attachmentType, textureObject, textureUploadTarget, level); + framebufferObject->AttachTexture(attachmentType, textureObject, textureUploadTarget, level, 0, layered); } void NamedFramebufferTextureWithUploadTarget_State(const char* functionName, GLuint framebuffer, GLenum attachment, @@ -1322,9 +1340,19 @@ namespace MobileGL::MG_Impl::GLImpl { : 0; break; case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: - case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER: *params = 0; break; + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER: + *params = (attachmentObject != nullptr && attachmentObject->IsTexture() && attachmentObject->IsValid()) + ? static_cast(attachmentObject->GetTextureLayer()) + : 0; + break; + case GL_FRAMEBUFFER_ATTACHMENT_LAYERED: + *params = (attachmentObject != nullptr && attachmentObject->IsTexture() && attachmentObject->IsValid() && + attachmentObject->IsLayered()) + ? GL_TRUE + : GL_FALSE; + break; default: MG_State::pGLContext->RecordError( ErrorCode::InvalidEnum, diff --git a/MobileGL/MG_State/GLState/FramebufferState/FramebufferObject.cpp b/MobileGL/MG_State/GLState/FramebufferState/FramebufferObject.cpp index 6ee6f9c9..1988b9e2 100644 --- a/MobileGL/MG_State/GLState/FramebufferState/FramebufferObject.cpp +++ b/MobileGL/MG_State/GLState/FramebufferState/FramebufferObject.cpp @@ -12,8 +12,10 @@ namespace MobileGL::MG_State::GLState { // FramebufferAttachmentObject FramebufferAttachmentObject::FramebufferAttachmentObject( - const SharedPtr& texture, TextureUploadTarget textureUploadTarget, Int level) - : m_texture(texture), m_textureUploadTarget(textureUploadTarget), m_textureLevel(level) {} + const SharedPtr& texture, TextureUploadTarget textureUploadTarget, Int level, + Int layer, Bool layered) + : m_texture(texture), m_textureUploadTarget(textureUploadTarget), m_textureLevel(level), + m_textureLayer(layer), m_layered(layered) {} FramebufferAttachmentObject::FramebufferAttachmentObject(const SharedPtr& renderbuffer) : m_renderbuffer(renderbuffer) {} FramebufferAttachmentObject::FramebufferAttachmentObject(Bool IsValid) @@ -45,6 +47,14 @@ namespace MobileGL::MG_State::GLState { return m_textureLevel; } + Int FramebufferAttachmentObject::GetTextureLayer() const { + return m_textureLayer; + } + + Bool FramebufferAttachmentObject::IsLayered() const { + return m_layered; + } + TextureUploadTarget FramebufferAttachmentObject::GetTextureUploadTarget() const { return m_textureUploadTarget; } @@ -98,8 +108,9 @@ namespace MobileGL::MG_State::GLState { } void FramebufferObject::AttachTexture(FramebufferAttachmentType type, const SharedPtr& texture, - TextureUploadTarget textureUploadTarget, int level) { - m_attachmentObjects[static_cast(type)] = FramebufferAttachmentObject(texture, textureUploadTarget, level); + TextureUploadTarget textureUploadTarget, int level, int layer, Bool layered) { + m_attachmentObjects[static_cast(type)] = + FramebufferAttachmentObject(texture, textureUploadTarget, level, layer, layered); BumpAttachmentVersion(type); } diff --git a/MobileGL/MG_State/GLState/FramebufferState/FramebufferObject.h b/MobileGL/MG_State/GLState/FramebufferState/FramebufferObject.h index ef85ad40..3f699be4 100644 --- a/MobileGL/MG_State/GLState/FramebufferState/FramebufferObject.h +++ b/MobileGL/MG_State/GLState/FramebufferState/FramebufferObject.h @@ -74,7 +74,7 @@ namespace MobileGL { public: explicit FramebufferAttachmentObject(const SharedPtr& texture, TextureUploadTarget textureUploadTarget, - Int level = 0); + Int level = 0, Int layer = 0, Bool layered = false); explicit FramebufferAttachmentObject(const SharedPtr& renderbuffer); explicit FramebufferAttachmentObject(Bool IsValid = true); @@ -84,6 +84,8 @@ namespace MobileGL { const SharedPtr& GetTexture() const; const SharedPtr& GetRenderbuffer() const; Int GetTextureLevel() const; + Int GetTextureLayer() const; + Bool IsLayered() const; TextureUploadTarget GetTextureUploadTarget() const; Bool IsComplete() const; IntVec3 GetSize() const; @@ -94,6 +96,8 @@ namespace MobileGL { SharedPtr m_renderbuffer = nullptr; TextureUploadTarget m_textureUploadTarget = TextureUploadTarget::Unknown; Int m_textureLevel = 0; + Int m_textureLayer = 0; + Bool m_layered = false; Bool m_isValid = true; }; @@ -112,7 +116,8 @@ namespace MobileGL { FramebufferObject(Uint externalIndex); void AttachTexture(FramebufferAttachmentType type, const SharedPtr& texture, - TextureUploadTarget textureUploadTarget = TextureUploadTarget::Unknown, int level = 0); + TextureUploadTarget textureUploadTarget = TextureUploadTarget::Unknown, int level = 0, + int layer = 0, Bool layered = false); void AttachRenderbuffer(FramebufferAttachmentType type, const SharedPtr& renderbuffer); void Detach(FramebufferAttachmentType type); const FramebufferAttachmentObject& GetAttachment(FramebufferAttachmentType type) const; diff --git a/MobileGL/MG_State/GLState/TextureState/TextureObjectStubs.h b/MobileGL/MG_State/GLState/TextureState/TextureObjectStubs.h index b29d6764..3346b095 100644 --- a/MobileGL/MG_State/GLState/TextureState/TextureObjectStubs.h +++ b/MobileGL/MG_State/GLState/TextureState/TextureObjectStubs.h @@ -45,7 +45,7 @@ namespace MobileGL { {TextureUploadTarget::Texture1DArray}); STUB_TEXTURE_OBJECT_CLASS_DEFINITION(TextureObject2DArray, TextureTarget::Texture2DArray, - {TextureUploadTarget::Texture2D}); + {TextureUploadTarget::Texture2DArray}); STUB_TEXTURE_OBJECT_CLASS_DEFINITION(TextureObjectCubeMapArray, TextureTarget::TextureCubeMapArray, {TextureUploadTarget::CubeMapArray});