mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-08 04:08:32 +09:00
[Feat] (MG_Backend/DirectGLES): implement glCopyTexImage2D/CopyTexSubImage2D
This commit is contained in:
@@ -85,6 +85,8 @@ set(SOURCE_FILES
|
||||
MobileGL/MG_Util/Converters/GLToMG/ProgramEnumConverter.cpp
|
||||
MobileGL/MG_Util/Converters/MGToMG/TextureEnumConverter.cpp
|
||||
|
||||
MobileGL/MG_Util/Classifiers/TextureEnumClassifier.cpp
|
||||
|
||||
MobileGL/MG_Util/ShaderTranspiler/ShaderCompiler.cpp
|
||||
MobileGL/MG_Util/ShaderTranspiler/SpvcSession.cpp
|
||||
MobileGL/MG_Util/ShaderTranspiler/ShaderSourceProcessor.cpp
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#include "DirectGLES.h"
|
||||
#include "Utils.h"
|
||||
#include "Managers.h"
|
||||
#include "MG_Util/Converters/GLToMG/TextureEnumConverter.h"
|
||||
#include "MG_Util/Classifiers/TextureEnumClassifier.h"
|
||||
#include "MG_Util/Metrics/TextureMetrics.h"
|
||||
#include <MG_State/GLState/Core.h>
|
||||
#include <MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.h>
|
||||
#include <MG_Util/BackendLoaders/OpenGL/Loader.h>
|
||||
@@ -471,6 +474,106 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
MG_External::GLES::glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
|
||||
}
|
||||
|
||||
void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width,
|
||||
GLsizei height, GLint border) {
|
||||
MGLOG_D("%s: Backend", __func__);
|
||||
TextureImpl::SyncNeccessaryTextures();
|
||||
FramebufferImpl::SyncCurrentFBO();
|
||||
RenderStateImpl::SyncRenderState();
|
||||
|
||||
GLint realInternalFormat;
|
||||
MG_External::GLES::glGetTexLevelParameteriv(target, level, GL_TEXTURE_INTERNAL_FORMAT, &realInternalFormat);
|
||||
internalformat = (GLenum)realInternalFormat;
|
||||
auto mglInternalFormat = MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat);
|
||||
|
||||
GLenum format = GL_DEPTH_COMPONENT;
|
||||
GLenum type = GL_UNSIGNED_INT;
|
||||
TextureImpl::GenerateTextureFormatInfo(mglInternalFormat, &internalformat, &format, &type);
|
||||
TexturePixelDataType texturePixelDataType = MG_Util::ConvertGLEnumToTexturePixelDataType(type);
|
||||
|
||||
bool isDepthFormat = MG_Util::IsDepthFormatInternalFormat(
|
||||
MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat));
|
||||
|
||||
if (!isDepthFormat) {
|
||||
MG_External::GLES::glCopyTexImage2D(
|
||||
target, level, internalformat, x, y, width, height, border);
|
||||
} else {
|
||||
MGLOG_D("%s: Backend depth", __func__);
|
||||
MG_External::GLES::glTexImage2D(target, level, (GLint)internalformat, width, height, border, format, type, nullptr);
|
||||
FramebufferImpl::BackendFramebufferBindingProtector drawFboProtector(GL_DRAW_FRAMEBUFFER);
|
||||
FramebufferImpl::BackendFramebufferBindingProtector readFboProtector(GL_READ_FRAMEBUFFER);
|
||||
|
||||
FramebufferImpl::BackendFramebufferBindingProtector::BindTempFBO(FramebufferTarget::Draw);
|
||||
GLint currentTex;
|
||||
MG_External::GLES::glGetIntegerv(Utils::GetBindingQuery(target, false), ¤tTex);
|
||||
MG_External::GLES::glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, target, currentTex, level);
|
||||
if (MG_External::GLES::glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||
// Protector will automatically revert to previous fbo states
|
||||
return;
|
||||
}
|
||||
|
||||
MG_External::GLES::glBlitFramebuffer(x, y, x + width, y + height, 0, 0, width, height, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
|
||||
// Protector will automatically revert to previous fbo states
|
||||
}
|
||||
|
||||
// TODO: potential desync between MG_State and backend
|
||||
auto activeUnit =
|
||||
MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit());
|
||||
TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target);
|
||||
auto& bindingSlot = activeUnit.GetBindingSlot(textureTarget);
|
||||
auto textureObject = bindingSlot.GetBoundObject();
|
||||
|
||||
|
||||
const SizeT bytesPerPixel = MG_Util::GetInputBytesPerPixel(mglInternalFormat, texturePixelDataType);
|
||||
const SizeT totalBytes = width * height * bytesPerPixel;
|
||||
|
||||
MG_State::GLState::MipmapLevelInput mipmap =
|
||||
MG_State::GLState::MipmapLevelInput({width, height, 1}, level, false, 0,
|
||||
{nullptr, totalBytes});
|
||||
|
||||
textureObject->SetInternalFormat(mglInternalFormat);
|
||||
textureObject->SetMipmapLevel(mipmap);
|
||||
}
|
||||
|
||||
void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y,
|
||||
GLsizei width, GLsizei height) {
|
||||
MGLOG_D("%s: Backend", __func__);
|
||||
TextureImpl::SyncNeccessaryTextures();
|
||||
FramebufferImpl::SyncCurrentFBO();
|
||||
RenderStateImpl::SyncRenderState();
|
||||
|
||||
BindCurrentFBO(FramebufferTarget::Read);
|
||||
|
||||
GLenum internalFormat;
|
||||
MG_External::GLES::glGetTexLevelParameteriv(target, level, GL_TEXTURE_INTERNAL_FORMAT, (GLint *)&internalFormat);
|
||||
|
||||
auto mglInternalFormat = MG_Util::ConvertGLEnumToTextureInternalFormat(internalFormat);
|
||||
|
||||
bool isDepthFormat = MG_Util::IsDepthFormatInternalFormat(mglInternalFormat);
|
||||
bool isStencilFormat = MG_Util::IsStencilFormatInternalFormat(mglInternalFormat);
|
||||
|
||||
if (!isDepthFormat) {
|
||||
MG_External::GLES::glCopyTexSubImage2D(
|
||||
target, level, xoffset, yoffset, x, y, width, height);
|
||||
} else {
|
||||
MGLOG_D("%s: Backend depth", __func__);
|
||||
FramebufferImpl::BackendFramebufferBindingProtector drawFboProtector(GL_DRAW_FRAMEBUFFER);
|
||||
FramebufferImpl::BackendFramebufferBindingProtector readFboProtector(GL_READ_FRAMEBUFFER);
|
||||
FramebufferImpl::BackendFramebufferBindingProtector::BindTempFBO(FramebufferTarget::Draw);
|
||||
GLint currentTex;
|
||||
MG_External::GLES::glGetIntegerv(Utils::GetBindingQuery(target, false), ¤tTex);
|
||||
MG_External::GLES::glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, target, currentTex, level);
|
||||
if (MG_External::GLES::glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||
// Protector will automatically revert to previous fbo states
|
||||
return;
|
||||
}
|
||||
|
||||
MG_External::GLES::glBlitFramebuffer(x, y, x + width, y + height, xoffset, yoffset, xoffset + width, yoffset + height,
|
||||
GL_DEPTH_BUFFER_BIT | (isStencilFormat ? GL_STENCIL_BUFFER_BIT : 0), GL_NEAREST);
|
||||
// Protector will automatically revert to previous fbo states
|
||||
}
|
||||
}
|
||||
|
||||
const GLubyte* GetString(GLenum name) {
|
||||
return MG_External::GLES::glGetString(name);
|
||||
}
|
||||
|
||||
@@ -16,5 +16,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
GLsizei drawcount, const GLint* basevertex);
|
||||
void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1,
|
||||
GLint dstY1, GLbitfield mask, GLenum filter);
|
||||
void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width,
|
||||
GLsizei height, GLint border);
|
||||
void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y,
|
||||
GLsizei width, GLsizei height);
|
||||
const GLubyte* GetString(GLenum name);
|
||||
} // namespace MobileGL::MG_Backend::DirectGLES
|
||||
@@ -1,10 +1,12 @@
|
||||
#include "DirectGLES.h"
|
||||
#include "Utils.h"
|
||||
#include "Managers.h"
|
||||
#include "MG_Util/Converters/GLToMG/FramebufferEnumConverter.h"
|
||||
#include <MG_State/GLState/Core.h>
|
||||
#include <MG_Util/BackendLoaders/OpenGL/Loader.h>
|
||||
#include <MG_Util/Converters/GLToStr/GLEnumConverter.h>
|
||||
#include <MG_Util/Converters/MGToGL/TextureEnumConverter.h>
|
||||
#include <MG_Util/Converters/MGToGL/FramebufferEnumConverter.h>
|
||||
|
||||
namespace MobileGL::MG_Backend::DirectGLES {
|
||||
namespace BufferImpl {
|
||||
@@ -291,6 +293,21 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
BackendFramebufferBindingProtector::~BackendFramebufferBindingProtector() {
|
||||
MG_External::GLES::glBindFramebuffer(m_target, m_previousBinding);
|
||||
}
|
||||
|
||||
GLuint BackendFramebufferBindingProtector::GetTempFBO(FramebufferTarget target) {
|
||||
GLenum glTarget = MG_Util::ConvertFramebufferTargetToGLEnum(target);
|
||||
GLuint& fbo = (glTarget == GL_DRAW_FRAMEBUFFER) ? s_tempDrawFBO : s_tempReadFBO;
|
||||
if (fbo == 0) {
|
||||
MG_External::GLES::glGenFramebuffers(1, &fbo);
|
||||
}
|
||||
return fbo;
|
||||
}
|
||||
|
||||
void BackendFramebufferBindingProtector::BindTempFBO(MobileGL::FramebufferTarget target) {
|
||||
GLuint fbo = GetTempFBO(target);
|
||||
GLenum glTarget = MG_Util::ConvertFramebufferTargetToGLEnum(target);
|
||||
MG_External::GLES::glBindFramebuffer(glTarget, fbo);
|
||||
}
|
||||
} // namespace FramebufferImpl
|
||||
|
||||
namespace PrgramImpl {
|
||||
|
||||
@@ -54,9 +54,13 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
|
||||
~BackendFramebufferBindingProtector();
|
||||
|
||||
static GLuint GetTempFBO(FramebufferTarget target);
|
||||
static void BindTempFBO(FramebufferTarget target);
|
||||
private:
|
||||
GLenum m_target;
|
||||
GLint m_previousBinding = 0;
|
||||
inline static GLuint s_tempReadFBO = 0;
|
||||
inline static GLuint s_tempDrawFBO = 0;
|
||||
};
|
||||
} // namespace FramebufferImpl
|
||||
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
#include "GL_Texture.h"
|
||||
#include "GL/gl.h"
|
||||
#include "Config.h"
|
||||
#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES
|
||||
#include <MG_Backend/DirectGLES/DirectGLES.h>
|
||||
#endif
|
||||
#include "MG_Util/Types.h"
|
||||
#include "Validators.h"
|
||||
#include "ProxyTexture.h"
|
||||
@@ -804,18 +808,22 @@ namespace MobileGL {
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
void CopyTexSubImage2D_State(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y,
|
||||
GLsizei width, GLsizei height) {
|
||||
// TODO: implement
|
||||
void CopyTexSubImage2D_Backend(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y,
|
||||
GLsizei width, GLsizei height) {
|
||||
#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES
|
||||
MG_Backend::DirectGLES::CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CopyTexSubImage1D_State(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) {
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
void CopyTexImage2D_State(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width,
|
||||
GLsizei height, GLint border) {
|
||||
// TODO: implement
|
||||
void CopyTexImage2D_Backend(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width,
|
||||
GLsizei height, GLint border) {
|
||||
#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES
|
||||
MG_Backend::DirectGLES::CopyTexImage2D(target, level, internalformat, x, y, width, height, border);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CopyTexImage1D_State(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width,
|
||||
@@ -1004,7 +1012,7 @@ namespace MobileGL {
|
||||
|
||||
void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y,
|
||||
GLsizei width, GLsizei height) {
|
||||
CopyTexSubImage2D_State(target, level, xoffset, yoffset, x, y, width, height);
|
||||
CopyTexSubImage2D_Backend(target, level, xoffset, yoffset, x, y, width, height);
|
||||
}
|
||||
|
||||
void CopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) {
|
||||
@@ -1013,7 +1021,7 @@ namespace MobileGL {
|
||||
|
||||
void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width,
|
||||
GLsizei height, GLint border) {
|
||||
CopyTexImage2D_State(target, level, internalformat, x, y, width, height, border);
|
||||
CopyTexImage2D_Backend(target, level, internalformat, x, y, width, height, border);
|
||||
}
|
||||
|
||||
void CopyTexImage1D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width,
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
#include "TextureEnumClassifier.h"
|
||||
|
||||
namespace MobileGL {
|
||||
namespace MG_Util {
|
||||
bool IsDepthFormatInternalFormat(TextureInternalFormat internalformat) {
|
||||
switch (internalformat) {
|
||||
case TextureInternalFormat::DepthComponent16:
|
||||
case TextureInternalFormat::DepthComponent24:
|
||||
case TextureInternalFormat::DepthComponent32:
|
||||
case TextureInternalFormat::DepthComponent32F:
|
||||
case TextureInternalFormat::Depth24Stencil8:
|
||||
case TextureInternalFormat::Depth32FStencil8:
|
||||
case TextureInternalFormat::DepthComponent:
|
||||
case TextureInternalFormat::DepthStencil:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsStencilFormatInternalFormat(TextureInternalFormat internalformat) {
|
||||
switch (internalformat) {
|
||||
case TextureInternalFormat::Depth24Stencil8:
|
||||
case TextureInternalFormat::Depth32FStencil8:
|
||||
case TextureInternalFormat::DepthStencil:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} // namespace MG_Util
|
||||
} // namespace MobileGL
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include <Includes.h>
|
||||
#include <MG_State/GLState/TextureState/TextureObject.h>
|
||||
|
||||
namespace MobileGL {
|
||||
namespace MG_Util {
|
||||
bool IsDepthFormatInternalFormat(TextureInternalFormat internalformat);
|
||||
bool IsStencilFormatInternalFormat(TextureInternalFormat internalformat);
|
||||
} // namespace MG_Util
|
||||
} // namespace MobileGL
|
||||
Reference in New Issue
Block a user