mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-12 06:08:30 +09:00
[Fix] (MG_State/GLState, MG_Backend): track layered framebuffer textures
This commit is contained in:
@@ -1793,12 +1793,16 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
|
|
||||||
const GLuint backendFBOId = backendFBO->GetBackendFramebufferId();
|
const GLuint backendFBOId = backendFBO->GetBackendFramebufferId();
|
||||||
g_GLESFuncs.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, backendFBOId);
|
g_GLESFuncs.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, backendFBOId);
|
||||||
g_GLESFuncs.glFramebufferTexture2D(
|
if (attachmentObject.IsLayered()) {
|
||||||
GL_DRAW_FRAMEBUFFER, backendAttachment, textureTarget, 0, 0);
|
g_GLESFuncs.glFramebufferTexture(GL_DRAW_FRAMEBUFFER, backendAttachment, 0, 0);
|
||||||
|
} else {
|
||||||
|
g_GLESFuncs.glFramebufferTexture2D(
|
||||||
|
GL_DRAW_FRAMEBUFFER, backendAttachment, textureTarget, 0, 0);
|
||||||
|
}
|
||||||
ClearGLErrors();
|
ClearGLErrors();
|
||||||
m_detachedAttachments.push_back(
|
m_detachedAttachments.push_back(
|
||||||
{backendFBOId, backendAttachment, textureTarget, backendTextureId,
|
{backendFBOId, backendAttachment, textureTarget, backendTextureId,
|
||||||
static_cast<GLint>(attachmentObject.GetTextureLevel())});
|
static_cast<GLint>(attachmentObject.GetTextureLevel()), attachmentObject.IsLayered()});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1806,9 +1810,14 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
~ScopedDetachedTextureFramebufferAttachments() {
|
~ScopedDetachedTextureFramebufferAttachments() {
|
||||||
for (const auto& attachment : m_detachedAttachments) {
|
for (const auto& attachment : m_detachedAttachments) {
|
||||||
g_GLESFuncs.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, attachment.framebuffer);
|
g_GLESFuncs.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, attachment.framebuffer);
|
||||||
g_GLESFuncs.glFramebufferTexture2D(
|
if (attachment.layered) {
|
||||||
GL_DRAW_FRAMEBUFFER, attachment.attachment, attachment.textureTarget,
|
g_GLESFuncs.glFramebufferTexture(
|
||||||
attachment.texture, attachment.level);
|
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_READ_FRAMEBUFFER, m_prevReadFBO);
|
||||||
g_GLESFuncs.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_prevDrawFBO);
|
g_GLESFuncs.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_prevDrawFBO);
|
||||||
@@ -1821,6 +1830,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
GLenum textureTarget = GL_TEXTURE_2D;
|
GLenum textureTarget = GL_TEXTURE_2D;
|
||||||
GLuint texture = 0;
|
GLuint texture = 0;
|
||||||
GLint level = 0;
|
GLint level = 0;
|
||||||
|
Bool layered = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
GLuint m_prevReadFBO = 0;
|
GLuint m_prevReadFBO = 0;
|
||||||
|
|||||||
@@ -1283,15 +1283,21 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
backendTextureObject->SyncMipmapsToBackend(textureObject);
|
backendTextureObject->SyncMipmapsToBackend(textureObject);
|
||||||
auto glTextureTarget =
|
if (attachmentObject.IsLayered()) {
|
||||||
MG_Util::ConvertTextureUploadTargetToGLEnum(attachmentObject.GetTextureUploadTarget());
|
g_GLESFuncs.glFramebufferTexture(glFBOTarget, glBackendAttachment,
|
||||||
if (glTextureTarget == GL_UNKNOWN_MGL) {
|
backendTextureObject->GetBackendTextureId(),
|
||||||
glTextureTarget = MG_Util::ConvertTextureTargetToGLEnum(textureObject->GetTarget());
|
static_cast<GLint>(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<GLint>(attachmentObject.GetTextureLevel()));
|
||||||
}
|
}
|
||||||
backendTextureObject->Bind(glTextureTarget);
|
|
||||||
g_GLESFuncs.glFramebufferTexture2D(glFBOTarget, glBackendAttachment, glTextureTarget,
|
|
||||||
backendTextureObject->GetBackendTextureId(),
|
|
||||||
static_cast<GLint>(attachmentObject.GetTextureLevel()));
|
|
||||||
} else if (attachmentObject.IsRenderbuffer()) {
|
} else if (attachmentObject.IsRenderbuffer()) {
|
||||||
const auto& renderbufferObject = attachmentObject.GetRenderbuffer();
|
const auto& renderbufferObject = attachmentObject.GetRenderbuffer();
|
||||||
const auto& backendRenderbufferIt =
|
const auto& backendRenderbufferIt =
|
||||||
|
|||||||
@@ -28,6 +28,26 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
return static_cast<Uint32>(target) - static_cast<Uint32>(TextureUploadTarget::CubeMapPositiveX);
|
return static_cast<Uint32>(target) - static_cast<Uint32>(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<Uint32>(std::max(attachment.GetTextureLayer(), 0));
|
||||||
|
}
|
||||||
|
return ResolveAttachmentBaseArrayLayer(uploadTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Uint32 ResolveAttachmentLayerCount(
|
||||||
|
const MG_State::GLState::FramebufferAttachmentObject& attachment) {
|
||||||
|
if (attachment.IsLayered()) {
|
||||||
|
return static_cast<Uint32>(std::max(attachment.GetSize().z(), 1));
|
||||||
|
}
|
||||||
|
return 1u;
|
||||||
|
}
|
||||||
|
|
||||||
static const MG_State::GLState::FramebufferAttachmentObject* GetClearableAttachment(
|
static const MG_State::GLState::FramebufferAttachmentObject* GetClearableAttachment(
|
||||||
const MG_State::GLState::FramebufferObject& drawFbo, FramebufferAttachmentType attachmentType) {
|
const MG_State::GLState::FramebufferObject& drawFbo, FramebufferAttachmentType attachmentType) {
|
||||||
if (attachmentType == FramebufferAttachmentType::None) {
|
if (attachmentType == FramebufferAttachmentType::None) {
|
||||||
@@ -60,9 +80,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
auto* texture = attachment.GetTexture().get();
|
auto* texture = attachment.GetTexture().get();
|
||||||
MOBILEGL_ASSERT(texture != nullptr, "MakePendingClearKey: texture attachment resolved to null");
|
MOBILEGL_ASSERT(texture != nullptr, "MakePendingClearKey: texture attachment resolved to null");
|
||||||
const Uint32 mipLevel = static_cast<Uint32>(std::max(attachment.GetTextureLevel(), 0));
|
const Uint32 mipLevel = static_cast<Uint32>(std::max(attachment.GetTextureLevel(), 0));
|
||||||
const TextureUploadTarget uploadTarget = attachment.GetTextureUploadTarget();
|
const Uint32 baseArrayLayer = ResolveAttachmentBaseArrayLayer(attachment);
|
||||||
const Uint32 baseArrayLayer = ResolveAttachmentBaseArrayLayer(uploadTarget);
|
const Uint32 layerCount = ResolveAttachmentLayerCount(attachment);
|
||||||
const Uint32 layerCount = IsCubeMapFaceUploadTarget(uploadTarget) ? 1u : 1u;
|
|
||||||
return MakePendingClearKey(texture, mipLevel, baseArrayLayer, layerCount);
|
return MakePendingClearKey(texture, mipLevel, baseArrayLayer, layerCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -73,22 +73,27 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Uint32 ResolveAttachmentBaseArrayLayer(const MG_State::GLState::FramebufferAttachmentObject& attachment) {
|
static Uint32 ResolveAttachmentBaseArrayLayer(const MG_State::GLState::FramebufferAttachmentObject& attachment) {
|
||||||
|
if (attachment.IsLayered()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
const TextureUploadTarget uploadTarget = attachment.GetTextureUploadTarget();
|
const TextureUploadTarget uploadTarget = attachment.GetTextureUploadTarget();
|
||||||
if (!IsCubeMapFaceUploadTarget(uploadTarget)) {
|
if (!IsCubeMapFaceUploadTarget(uploadTarget)) {
|
||||||
return 0;
|
return static_cast<Uint32>(std::max(attachment.GetTextureLayer(), 0));
|
||||||
}
|
}
|
||||||
return static_cast<Uint32>(uploadTarget) - static_cast<Uint32>(TextureUploadTarget::CubeMapPositiveX);
|
return static_cast<Uint32>(uploadTarget) - static_cast<Uint32>(TextureUploadTarget::CubeMapPositiveX);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Uint32 ResolveAttachmentLayerCount(const MG_State::GLState::FramebufferAttachmentObject& attachment) {
|
static Uint32 ResolveAttachmentLayerCount(const MG_State::GLState::FramebufferAttachmentObject& attachment) {
|
||||||
static_cast<void>(attachment);
|
if (attachment.IsLayered()) {
|
||||||
|
return static_cast<Uint32>(std::max(attachment.GetSize().z(), 1));
|
||||||
|
}
|
||||||
return 1u;
|
return 1u;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VkImageViewType ResolveAttachmentViewType(
|
static VkImageViewType ResolveAttachmentViewType(
|
||||||
const MG_State::GLState::FramebufferAttachmentObject& attachment,
|
const MG_State::GLState::FramebufferAttachmentObject& attachment,
|
||||||
const VkTextureManager::TextureResource& resource) {
|
const VkTextureManager::TextureResource& resource) {
|
||||||
return IsCubeMapFaceUploadTarget(attachment.GetTextureUploadTarget()) ?
|
return !attachment.IsLayered() && IsCubeMapFaceUploadTarget(attachment.GetTextureUploadTarget()) ?
|
||||||
VK_IMAGE_VIEW_TYPE_2D :
|
VK_IMAGE_VIEW_TYPE_2D :
|
||||||
resource.viewType;
|
resource.viewType;
|
||||||
}
|
}
|
||||||
@@ -438,6 +443,10 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
XXHASH_VERIFY(XXH64_update(m_hashState, &textureLevel, sizeof(textureLevel)));
|
XXHASH_VERIFY(XXH64_update(m_hashState, &textureLevel, sizeof(textureLevel)));
|
||||||
const TextureUploadTarget textureUploadTarget = att.GetTextureUploadTarget();
|
const TextureUploadTarget textureUploadTarget = att.GetTextureUploadTarget();
|
||||||
XXHASH_VERIFY(XXH64_update(m_hashState, &textureUploadTarget, sizeof(textureUploadTarget)));
|
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;
|
Uint64 imageIdentity = 0;
|
||||||
auto* texture = att.GetTexture().get();
|
auto* texture = att.GetTexture().get();
|
||||||
@@ -621,6 +630,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
attachmentViews.reserve(colorAttachmentSlotCount + 1);
|
attachmentViews.reserve(colorAttachmentSlotCount + 1);
|
||||||
VkSampleCountFlagBits renderPassSampleCount = VK_SAMPLE_COUNT_1_BIT;
|
VkSampleCountFlagBits renderPassSampleCount = VK_SAMPLE_COUNT_1_BIT;
|
||||||
Bool hasRenderPassSampleCount = false;
|
Bool hasRenderPassSampleCount = false;
|
||||||
|
Uint32 framebufferLayers = 1;
|
||||||
const auto adoptRenderPassSampleCount = [&](VkSampleCountFlagBits sampleCount,
|
const auto adoptRenderPassSampleCount = [&](VkSampleCountFlagBits sampleCount,
|
||||||
const char* attachmentKind,
|
const char* attachmentKind,
|
||||||
Int attachmentId) {
|
Int attachmentId) {
|
||||||
@@ -713,6 +723,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
});
|
});
|
||||||
const Uint32 baseArrayLayer = ResolveAttachmentBaseArrayLayer(att);
|
const Uint32 baseArrayLayer = ResolveAttachmentBaseArrayLayer(att);
|
||||||
const Uint32 layerCount = ResolveAttachmentLayerCount(att);
|
const Uint32 layerCount = ResolveAttachmentLayerCount(att);
|
||||||
|
framebufferLayers = std::max(framebufferLayers, layerCount);
|
||||||
const VkImageViewType attachmentViewType = ResolveAttachmentViewType(att, *textureResource);
|
const VkImageViewType attachmentViewType = ResolveAttachmentViewType(att, *textureResource);
|
||||||
attachmentViews.emplace_back(
|
attachmentViews.emplace_back(
|
||||||
m_textureManager.GetOrCreateAttachmentViewAtMipLevel(
|
m_textureManager.GetOrCreateAttachmentViewAtMipLevel(
|
||||||
@@ -877,6 +888,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
textureResources.emplace_back(depthTextureResource);
|
textureResources.emplace_back(depthTextureResource);
|
||||||
const Uint32 baseArrayLayer = ResolveAttachmentBaseArrayLayer(*selectedDepthStencilAttachment);
|
const Uint32 baseArrayLayer = ResolveAttachmentBaseArrayLayer(*selectedDepthStencilAttachment);
|
||||||
const Uint32 layerCount = ResolveAttachmentLayerCount(*selectedDepthStencilAttachment);
|
const Uint32 layerCount = ResolveAttachmentLayerCount(*selectedDepthStencilAttachment);
|
||||||
|
framebufferLayers = std::max(framebufferLayers, layerCount);
|
||||||
const VkImageViewType attachmentViewType =
|
const VkImageViewType attachmentViewType =
|
||||||
ResolveAttachmentViewType(*selectedDepthStencilAttachment, *depthTextureResource);
|
ResolveAttachmentViewType(*selectedDepthStencilAttachment, *depthTextureResource);
|
||||||
attachmentViews.emplace_back(
|
attachmentViews.emplace_back(
|
||||||
@@ -953,7 +965,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
framebufferCreateInfo.pAttachments = attachmentViews.data();
|
framebufferCreateInfo.pAttachments = attachmentViews.data();
|
||||||
framebufferCreateInfo.width = width;
|
framebufferCreateInfo.width = width;
|
||||||
framebufferCreateInfo.height = height;
|
framebufferCreateInfo.height = height;
|
||||||
framebufferCreateInfo.layers = 1;
|
framebufferCreateInfo.layers = framebufferLayers;
|
||||||
VkFramebuffer framebuffer = VK_NULL_HANDLE;
|
VkFramebuffer framebuffer = VK_NULL_HANDLE;
|
||||||
VK_VERIFY(vkCreateFramebuffer(m_device, &framebufferCreateInfo, nullptr, &framebuffer));
|
VK_VERIFY(vkCreateFramebuffer(m_device, &framebufferCreateInfo, nullptr, &framebuffer));
|
||||||
IntVec2 extent = {width, height};
|
IntVec2 extent = {width, height};
|
||||||
@@ -969,7 +981,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
hasDepthStencilAttachment,
|
hasDepthStencilAttachment,
|
||||||
renderPassSampleCount,
|
renderPassSampleCount,
|
||||||
extent,
|
extent,
|
||||||
1 };
|
static_cast<Int>(framebufferLayers) };
|
||||||
MGLOG_D("VkRenderPassManager::GetOrCreateRenderPass: hash=0x%llx compatibilityHash=0x%llx attachmentCount=%u colorAttachmentCount=%u samples=%d extent=%dx%d",
|
MGLOG_D("VkRenderPassManager::GetOrCreateRenderPass: hash=0x%llx compatibilityHash=0x%llx attachmentCount=%u colorAttachmentCount=%u samples=%d extent=%dx%d",
|
||||||
static_cast<unsigned long long>(hash),
|
static_cast<unsigned long long>(hash),
|
||||||
static_cast<unsigned long long>(compatibilityHash),
|
static_cast<unsigned long long>(compatibilityHash),
|
||||||
|
|||||||
@@ -522,6 +522,16 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
case TextureUploadTarget::ProxyTexture2DMultisample:
|
case TextureUploadTarget::ProxyTexture2DMultisample:
|
||||||
outShape = {};
|
outShape = {};
|
||||||
return true;
|
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<Uint32>(texelSize.z());
|
||||||
|
return true;
|
||||||
case TextureUploadTarget::Texture2DMultisampleArray:
|
case TextureUploadTarget::Texture2DMultisampleArray:
|
||||||
case TextureUploadTarget::ProxyTexture2DMultisampleArray:
|
case TextureUploadTarget::ProxyTexture2DMultisampleArray:
|
||||||
MOBILEGL_ASSERT(texelSize.z() > 0,
|
MOBILEGL_ASSERT(texelSize.z() > 0,
|
||||||
|
|||||||
@@ -923,11 +923,26 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
return false;
|
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(
|
static Bool IsUnsupportedFramebufferForDirectVulkan(
|
||||||
const MG_State::GLState::FramebufferObject& framebufferObject) {
|
const MG_State::GLState::FramebufferObject& framebufferObject) {
|
||||||
// TODO: Revisit this gate when DirectVulkan has full color renderbuffer render/blit/readback support.
|
// 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) ||
|
return HasDistinctCompleteDepthStencilTextureAttachments(framebufferObject) ||
|
||||||
HasUnsupportedCompleteRenderbufferAttachment(framebufferObject);
|
HasUnsupportedCompleteRenderbufferAttachment(framebufferObject) ||
|
||||||
|
HasLayeredTextureAttachment(framebufferObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RecordUnsupportedFramebufferError(const char* func) {
|
static void RecordUnsupportedFramebufferError(const char* func) {
|
||||||
|
|||||||
@@ -67,7 +67,9 @@ namespace MobileGL::MG_Impl::GLImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Bool ResolveRepresentableFramebufferTextureUploadTarget(const MG_State::GLState::ITextureObject& textureObject,
|
Bool ResolveRepresentableFramebufferTextureUploadTarget(const MG_State::GLState::ITextureObject& textureObject,
|
||||||
TextureUploadTarget& outUploadTarget) {
|
TextureUploadTarget& outUploadTarget,
|
||||||
|
Bool& outLayered) {
|
||||||
|
outLayered = false;
|
||||||
switch (textureObject.GetTarget()) {
|
switch (textureObject.GetTarget()) {
|
||||||
case TextureTarget::Texture1D:
|
case TextureTarget::Texture1D:
|
||||||
outUploadTarget = TextureUploadTarget::Texture1D;
|
outUploadTarget = TextureUploadTarget::Texture1D;
|
||||||
@@ -81,7 +83,12 @@ namespace MobileGL::MG_Impl::GLImpl {
|
|||||||
case TextureTarget::Texture2DMultisample:
|
case TextureTarget::Texture2DMultisample:
|
||||||
outUploadTarget = TextureUploadTarget::Texture2DMultisample;
|
outUploadTarget = TextureUploadTarget::Texture2DMultisample;
|
||||||
return true;
|
return true;
|
||||||
|
case TextureTarget::Texture2DArray:
|
||||||
|
outUploadTarget = TextureUploadTarget::Texture2DArray;
|
||||||
|
outLayered = true;
|
||||||
|
return true;
|
||||||
default:
|
default:
|
||||||
|
// TODO: Extend layered framebuffer attachment support to 3D, cube, 1D array, and multisample array textures.
|
||||||
outUploadTarget = TextureUploadTarget::Unknown;
|
outUploadTarget = TextureUploadTarget::Unknown;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -89,7 +96,7 @@ namespace MobileGL::MG_Impl::GLImpl {
|
|||||||
|
|
||||||
void AttachFramebufferTextureWithUploadTarget(const char* functionName, GLenum target, GLenum attachment,
|
void AttachFramebufferTextureWithUploadTarget(const char* functionName, GLenum target, GLenum attachment,
|
||||||
GLuint texture, GLint level,
|
GLuint texture, GLint level,
|
||||||
TextureUploadTarget textureUploadTarget) {
|
TextureUploadTarget textureUploadTarget, Bool layered = false) {
|
||||||
if (target == GL_FRAMEBUFFER) {
|
if (target == GL_FRAMEBUFFER) {
|
||||||
target = GL_DRAW_FRAMEBUFFER;
|
target = GL_DRAW_FRAMEBUFFER;
|
||||||
}
|
}
|
||||||
@@ -145,7 +152,7 @@ namespace MobileGL::MG_Impl::GLImpl {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
framebufferObject->AttachTexture(attachmentType, textureObject, textureUploadTarget, level);
|
framebufferObject->AttachTexture(attachmentType, textureObject, textureUploadTarget, level, 0, layered);
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
@@ -406,7 +413,15 @@ namespace MobileGL::MG_Impl::GLImpl {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
|
case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
|
||||||
*params = 0;
|
*params = (attachmentObject != nullptr && attachmentObject->IsTexture() && attachmentObject->IsValid())
|
||||||
|
? static_cast<GLint>(attachmentObject->GetTextureLayer())
|
||||||
|
: 0;
|
||||||
|
break;
|
||||||
|
case GL_FRAMEBUFFER_ATTACHMENT_LAYERED:
|
||||||
|
*params = (attachmentObject != nullptr && attachmentObject->IsTexture() && attachmentObject->IsValid() &&
|
||||||
|
attachmentObject->IsLayered())
|
||||||
|
? GL_TRUE
|
||||||
|
: GL_FALSE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
@@ -661,14 +676,16 @@ namespace MobileGL::MG_Impl::GLImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TextureUploadTarget textureUploadTarget = TextureUploadTarget::Unknown;
|
TextureUploadTarget textureUploadTarget = TextureUploadTarget::Unknown;
|
||||||
if (!ResolveRepresentableFramebufferTextureUploadTarget(*textureObject, textureUploadTarget)) {
|
Bool layered = false;
|
||||||
|
if (!ResolveRepresentableFramebufferTextureUploadTarget(*textureObject, textureUploadTarget, layered)) {
|
||||||
RecordUnsupportedFramebufferTextureAttachmentError(
|
RecordUnsupportedFramebufferTextureAttachmentError(
|
||||||
__func__,
|
__func__,
|
||||||
"Layered or multi-image framebuffer texture targets are not fully represented by the current framebuffer attachment model.");
|
"Layered or multi-image framebuffer texture targets are not fully represented by the current framebuffer attachment model.");
|
||||||
return;
|
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) {
|
void NamedFramebufferTexture_State(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level) {
|
||||||
@@ -700,14 +717,15 @@ namespace MobileGL::MG_Impl::GLImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TextureUploadTarget textureUploadTarget = TextureUploadTarget::Unknown;
|
TextureUploadTarget textureUploadTarget = TextureUploadTarget::Unknown;
|
||||||
if (!ResolveRepresentableFramebufferTextureUploadTarget(*textureObject, textureUploadTarget)) {
|
Bool layered = false;
|
||||||
|
if (!ResolveRepresentableFramebufferTextureUploadTarget(*textureObject, textureUploadTarget, layered)) {
|
||||||
RecordUnsupportedFramebufferTextureAttachmentError(
|
RecordUnsupportedFramebufferTextureAttachmentError(
|
||||||
"NamedFramebufferTexture_State",
|
"NamedFramebufferTexture_State",
|
||||||
"Layered or multi-image framebuffer texture targets are not fully represented by the current framebuffer attachment model.");
|
"Layered or multi-image framebuffer texture targets are not fully represented by the current framebuffer attachment model.");
|
||||||
return;
|
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,
|
void NamedFramebufferTextureWithUploadTarget_State(const char* functionName, GLuint framebuffer, GLenum attachment,
|
||||||
@@ -1322,9 +1340,19 @@ namespace MobileGL::MG_Impl::GLImpl {
|
|||||||
: 0;
|
: 0;
|
||||||
break;
|
break;
|
||||||
case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
|
case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
|
||||||
case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
|
|
||||||
*params = 0;
|
*params = 0;
|
||||||
break;
|
break;
|
||||||
|
case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
|
||||||
|
*params = (attachmentObject != nullptr && attachmentObject->IsTexture() && attachmentObject->IsValid())
|
||||||
|
? static_cast<GLint>(attachmentObject->GetTextureLayer())
|
||||||
|
: 0;
|
||||||
|
break;
|
||||||
|
case GL_FRAMEBUFFER_ATTACHMENT_LAYERED:
|
||||||
|
*params = (attachmentObject != nullptr && attachmentObject->IsTexture() && attachmentObject->IsValid() &&
|
||||||
|
attachmentObject->IsLayered())
|
||||||
|
? GL_TRUE
|
||||||
|
: GL_FALSE;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
ErrorCode::InvalidEnum,
|
ErrorCode::InvalidEnum,
|
||||||
|
|||||||
@@ -12,8 +12,10 @@
|
|||||||
namespace MobileGL::MG_State::GLState {
|
namespace MobileGL::MG_State::GLState {
|
||||||
// FramebufferAttachmentObject
|
// FramebufferAttachmentObject
|
||||||
FramebufferAttachmentObject::FramebufferAttachmentObject(
|
FramebufferAttachmentObject::FramebufferAttachmentObject(
|
||||||
const SharedPtr<MG_State::GLState::ITextureObject>& texture, TextureUploadTarget textureUploadTarget, Int level)
|
const SharedPtr<MG_State::GLState::ITextureObject>& texture, TextureUploadTarget textureUploadTarget, Int level,
|
||||||
: m_texture(texture), m_textureUploadTarget(textureUploadTarget), m_textureLevel(level) {}
|
Int layer, Bool layered)
|
||||||
|
: m_texture(texture), m_textureUploadTarget(textureUploadTarget), m_textureLevel(level),
|
||||||
|
m_textureLayer(layer), m_layered(layered) {}
|
||||||
FramebufferAttachmentObject::FramebufferAttachmentObject(const SharedPtr<RenderbufferObject>& renderbuffer)
|
FramebufferAttachmentObject::FramebufferAttachmentObject(const SharedPtr<RenderbufferObject>& renderbuffer)
|
||||||
: m_renderbuffer(renderbuffer) {}
|
: m_renderbuffer(renderbuffer) {}
|
||||||
FramebufferAttachmentObject::FramebufferAttachmentObject(Bool IsValid)
|
FramebufferAttachmentObject::FramebufferAttachmentObject(Bool IsValid)
|
||||||
@@ -45,6 +47,14 @@ namespace MobileGL::MG_State::GLState {
|
|||||||
return m_textureLevel;
|
return m_textureLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Int FramebufferAttachmentObject::GetTextureLayer() const {
|
||||||
|
return m_textureLayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool FramebufferAttachmentObject::IsLayered() const {
|
||||||
|
return m_layered;
|
||||||
|
}
|
||||||
|
|
||||||
TextureUploadTarget FramebufferAttachmentObject::GetTextureUploadTarget() const {
|
TextureUploadTarget FramebufferAttachmentObject::GetTextureUploadTarget() const {
|
||||||
return m_textureUploadTarget;
|
return m_textureUploadTarget;
|
||||||
}
|
}
|
||||||
@@ -98,8 +108,9 @@ namespace MobileGL::MG_State::GLState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void FramebufferObject::AttachTexture(FramebufferAttachmentType type, const SharedPtr<ITextureObject>& texture,
|
void FramebufferObject::AttachTexture(FramebufferAttachmentType type, const SharedPtr<ITextureObject>& texture,
|
||||||
TextureUploadTarget textureUploadTarget, int level) {
|
TextureUploadTarget textureUploadTarget, int level, int layer, Bool layered) {
|
||||||
m_attachmentObjects[static_cast<SizeT>(type)] = FramebufferAttachmentObject(texture, textureUploadTarget, level);
|
m_attachmentObjects[static_cast<SizeT>(type)] =
|
||||||
|
FramebufferAttachmentObject(texture, textureUploadTarget, level, layer, layered);
|
||||||
BumpAttachmentVersion(type);
|
BumpAttachmentVersion(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ namespace MobileGL {
|
|||||||
public:
|
public:
|
||||||
explicit FramebufferAttachmentObject(const SharedPtr<MG_State::GLState::ITextureObject>& texture,
|
explicit FramebufferAttachmentObject(const SharedPtr<MG_State::GLState::ITextureObject>& texture,
|
||||||
TextureUploadTarget textureUploadTarget,
|
TextureUploadTarget textureUploadTarget,
|
||||||
Int level = 0);
|
Int level = 0, Int layer = 0, Bool layered = false);
|
||||||
explicit FramebufferAttachmentObject(const SharedPtr<RenderbufferObject>& renderbuffer);
|
explicit FramebufferAttachmentObject(const SharedPtr<RenderbufferObject>& renderbuffer);
|
||||||
explicit FramebufferAttachmentObject(Bool IsValid = true);
|
explicit FramebufferAttachmentObject(Bool IsValid = true);
|
||||||
|
|
||||||
@@ -84,6 +84,8 @@ namespace MobileGL {
|
|||||||
const SharedPtr<MG_State::GLState::ITextureObject>& GetTexture() const;
|
const SharedPtr<MG_State::GLState::ITextureObject>& GetTexture() const;
|
||||||
const SharedPtr<RenderbufferObject>& GetRenderbuffer() const;
|
const SharedPtr<RenderbufferObject>& GetRenderbuffer() const;
|
||||||
Int GetTextureLevel() const;
|
Int GetTextureLevel() const;
|
||||||
|
Int GetTextureLayer() const;
|
||||||
|
Bool IsLayered() const;
|
||||||
TextureUploadTarget GetTextureUploadTarget() const;
|
TextureUploadTarget GetTextureUploadTarget() const;
|
||||||
Bool IsComplete() const;
|
Bool IsComplete() const;
|
||||||
IntVec3 GetSize() const;
|
IntVec3 GetSize() const;
|
||||||
@@ -94,6 +96,8 @@ namespace MobileGL {
|
|||||||
SharedPtr<RenderbufferObject> m_renderbuffer = nullptr;
|
SharedPtr<RenderbufferObject> m_renderbuffer = nullptr;
|
||||||
TextureUploadTarget m_textureUploadTarget = TextureUploadTarget::Unknown;
|
TextureUploadTarget m_textureUploadTarget = TextureUploadTarget::Unknown;
|
||||||
Int m_textureLevel = 0;
|
Int m_textureLevel = 0;
|
||||||
|
Int m_textureLayer = 0;
|
||||||
|
Bool m_layered = false;
|
||||||
Bool m_isValid = true;
|
Bool m_isValid = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -112,7 +116,8 @@ namespace MobileGL {
|
|||||||
FramebufferObject(Uint externalIndex);
|
FramebufferObject(Uint externalIndex);
|
||||||
|
|
||||||
void AttachTexture(FramebufferAttachmentType type, const SharedPtr<ITextureObject>& texture,
|
void AttachTexture(FramebufferAttachmentType type, const SharedPtr<ITextureObject>& 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<RenderbufferObject>& renderbuffer);
|
void AttachRenderbuffer(FramebufferAttachmentType type, const SharedPtr<RenderbufferObject>& renderbuffer);
|
||||||
void Detach(FramebufferAttachmentType type);
|
void Detach(FramebufferAttachmentType type);
|
||||||
const FramebufferAttachmentObject& GetAttachment(FramebufferAttachmentType type) const;
|
const FramebufferAttachmentObject& GetAttachment(FramebufferAttachmentType type) const;
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ namespace MobileGL {
|
|||||||
{TextureUploadTarget::Texture1DArray});
|
{TextureUploadTarget::Texture1DArray});
|
||||||
|
|
||||||
STUB_TEXTURE_OBJECT_CLASS_DEFINITION(TextureObject2DArray, TextureTarget::Texture2DArray,
|
STUB_TEXTURE_OBJECT_CLASS_DEFINITION(TextureObject2DArray, TextureTarget::Texture2DArray,
|
||||||
{TextureUploadTarget::Texture2D});
|
{TextureUploadTarget::Texture2DArray});
|
||||||
|
|
||||||
STUB_TEXTURE_OBJECT_CLASS_DEFINITION(TextureObjectCubeMapArray, TextureTarget::TextureCubeMapArray,
|
STUB_TEXTURE_OBJECT_CLASS_DEFINITION(TextureObjectCubeMapArray, TextureTarget::TextureCubeMapArray,
|
||||||
{TextureUploadTarget::CubeMapArray});
|
{TextureUploadTarget::CubeMapArray});
|
||||||
|
|||||||
Reference in New Issue
Block a user