mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-10 05:08:31 +09:00
[Fix] (MG_Impl/GLImpl, MG_Backend/DirectVulkan): allow color renderbuffer framebuffers [skip ci]
This commit is contained in:
@@ -12,6 +12,8 @@
|
|||||||
#include "MG_State/GLState/Core.h"
|
#include "MG_State/GLState/Core.h"
|
||||||
#include "MG_State/GLState/ErrorState/ErrorInfo.h"
|
#include "MG_State/GLState/ErrorState/ErrorInfo.h"
|
||||||
#include "MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.h"
|
#include "MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.h"
|
||||||
|
#include "MG_Util/Converters/GLToMG/TextureEnumConverter.h"
|
||||||
|
#include "MG_Util/Metrics/TextureMetrics.h"
|
||||||
#include "MG_Util/Miscellany/IndexGenerator.h"
|
#include "MG_Util/Miscellany/IndexGenerator.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <spirv_reflect.h>
|
#include <spirv_reflect.h>
|
||||||
@@ -58,6 +60,19 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
|
|
||||||
UnorderedMap<GLuint, ProgramResourceCache> g_programResourceCaches;
|
UnorderedMap<GLuint, ProgramResourceCache> g_programResourceCaches;
|
||||||
|
|
||||||
|
void ClearReadPixelsOutput(GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) {
|
||||||
|
if (!pixels || width <= 0 || height <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto inputFormat = MG_Util::ConvertGLEnumToTextureInputFormat(format);
|
||||||
|
const auto inputType = MG_Util::ConvertGLEnumToTexturePixelDataType(type);
|
||||||
|
const SizeT size = MG_Util::CalculateInputTextureImageSize(inputFormat, inputType,
|
||||||
|
IntVec3(width, height, 1));
|
||||||
|
if (size > 0) {
|
||||||
|
std::memset(pixels, 0, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String NormalizeDescriptorName(const SpvReflectDescriptorBinding& binding) {
|
String NormalizeDescriptorName(const SpvReflectDescriptorBinding& binding) {
|
||||||
const char* rawName = binding.name;
|
const char* rawName = binding.name;
|
||||||
if (binding.type_description != nullptr && binding.type_description->type_name != nullptr) {
|
if (binding.type_description != nullptr && binding.type_description->type_name != nullptr) {
|
||||||
@@ -1145,8 +1160,11 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
cache.storageBlocks[storageBlockIndex].binding = storageBlockBinding;
|
cache.storageBlocks[storageBlockIndex].binding = storageBlockBinding;
|
||||||
}
|
}
|
||||||
void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) {
|
void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) {
|
||||||
MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::ReadPixels called with null VulkanRenderer");
|
if (!pVulkanRenderer || !MG_State::pGLContext) {
|
||||||
MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::ReadPixels called with null GL context");
|
// TODO: Route early/default-FBO readbacks through a real DirectVulkan read path instead of returning zeros.
|
||||||
|
ClearReadPixelsOutput(width, height, format, type, pixels);
|
||||||
|
return;
|
||||||
|
}
|
||||||
pVulkanRenderer->ReadPixels(x, y, width, height, format, type, pixels);
|
pVulkanRenderer->ReadPixels(x, y, width, height, format, type, pixels);
|
||||||
}
|
}
|
||||||
void GetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels) {
|
void GetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels) {
|
||||||
@@ -1162,8 +1180,10 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Clear(GLbitfield mask) {
|
void Clear(GLbitfield mask) {
|
||||||
MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::Clear called with null VulkanRenderer");
|
if (!pVulkanRenderer || !MG_State::pGLContext) {
|
||||||
MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::Clear called with null GL context");
|
// TODO: Preserve pending clears issued before the Vulkan renderer/context is fully attached.
|
||||||
|
return;
|
||||||
|
}
|
||||||
pVulkanRenderer->Clear(mask);
|
pVulkanRenderer->Clear(mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1277,8 +1297,10 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
|
|
||||||
void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1,
|
void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1,
|
||||||
GLint dstY1, GLbitfield mask, GLenum filter) {
|
GLint dstY1, GLbitfield mask, GLenum filter) {
|
||||||
MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::BlitFramebuffer called with null VulkanRenderer");
|
if (!pVulkanRenderer || !MG_State::pGLContext) {
|
||||||
MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::BlitFramebuffer called with null GL context");
|
// TODO: Support pre-renderer/default-FBO blits instead of dropping them at the DirectVulkan boundary.
|
||||||
|
return;
|
||||||
|
}
|
||||||
pVulkanRenderer->BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
|
pVulkanRenderer->BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -908,17 +908,6 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& attachments = framebufferObject.GetAllAttachmentObjects();
|
|
||||||
for (SizeT i = 0; i < attachments.size(); ++i) {
|
|
||||||
const auto attachmentType = static_cast<FramebufferAttachmentType>(i);
|
|
||||||
const auto& attachment = attachments[i];
|
|
||||||
if (attachment.IsRenderbuffer() && attachment.IsComplete()) {
|
|
||||||
if (IsColorAttachment(attachmentType)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto& depthAttachment = framebufferObject.GetAttachment(FramebufferAttachmentType::Depth);
|
const auto& depthAttachment = framebufferObject.GetAttachment(FramebufferAttachmentType::Depth);
|
||||||
const auto& stencilAttachment = framebufferObject.GetAttachment(FramebufferAttachmentType::Stencil);
|
const auto& stencilAttachment = framebufferObject.GetAttachment(FramebufferAttachmentType::Stencil);
|
||||||
if (!depthAttachment.IsComplete() || !stencilAttachment.IsComplete()) {
|
if (!depthAttachment.IsComplete() || !stencilAttachment.IsComplete()) {
|
||||||
@@ -936,6 +925,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
|
|
||||||
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.
|
||||||
return HasDistinctCompleteDepthStencilTextureAttachments(framebufferObject) ||
|
return HasDistinctCompleteDepthStencilTextureAttachments(framebufferObject) ||
|
||||||
HasUnsupportedCompleteRenderbufferAttachment(framebufferObject);
|
HasUnsupportedCompleteRenderbufferAttachment(framebufferObject);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,23 +45,10 @@ namespace MobileGL::MG_Impl::GLImpl {
|
|||||||
depthAttachment.GetTextureLevel() != stencilAttachment.GetTextureLevel();
|
depthAttachment.GetTextureLevel() != stencilAttachment.GetTextureLevel();
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool HasCompleteRenderbufferAttachment(const MG_State::GLState::FramebufferObject& framebufferObject) {
|
|
||||||
if (framebufferObject.GetExternalIndex() == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& attachment : framebufferObject.GetAllAttachmentObjects()) {
|
|
||||||
if (attachment.IsRenderbuffer() && attachment.IsComplete()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Bool IsUnsupportedFramebufferForDirectVulkan(
|
Bool IsUnsupportedFramebufferForDirectVulkan(
|
||||||
const MG_State::GLState::FramebufferObject& framebufferObject) {
|
const MG_State::GLState::FramebufferObject& framebufferObject) {
|
||||||
return HasDistinctCompleteDepthStencilTextureAttachments(framebufferObject) ||
|
// TODO: Keep this in sync with DirectVulkan renderbuffer support as color renderbuffer rendering lands.
|
||||||
HasCompleteRenderbufferAttachment(framebufferObject);
|
return HasDistinctCompleteDepthStencilTextureAttachments(framebufferObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool HasDefinedAttachment(const MG_State::GLState::FramebufferObject& framebufferObject) {
|
Bool HasDefinedAttachment(const MG_State::GLState::FramebufferObject& framebufferObject) {
|
||||||
|
|||||||
Reference in New Issue
Block a user