mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-11 21:58:31 +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/GLToMG/ProgramEnumConverter.cpp
|
||||||
MobileGL/MG_Util/Converters/MGToMG/TextureEnumConverter.cpp
|
MobileGL/MG_Util/Converters/MGToMG/TextureEnumConverter.cpp
|
||||||
|
|
||||||
|
MobileGL/MG_Util/Classifiers/TextureEnumClassifier.cpp
|
||||||
|
|
||||||
MobileGL/MG_Util/ShaderTranspiler/ShaderCompiler.cpp
|
MobileGL/MG_Util/ShaderTranspiler/ShaderCompiler.cpp
|
||||||
MobileGL/MG_Util/ShaderTranspiler/SpvcSession.cpp
|
MobileGL/MG_Util/ShaderTranspiler/SpvcSession.cpp
|
||||||
MobileGL/MG_Util/ShaderTranspiler/ShaderSourceProcessor.cpp
|
MobileGL/MG_Util/ShaderTranspiler/ShaderSourceProcessor.cpp
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
#include "DirectGLES.h"
|
#include "DirectGLES.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
#include "Managers.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_State/GLState/Core.h>
|
||||||
#include <MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.h>
|
#include <MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.h>
|
||||||
#include <MG_Util/BackendLoaders/OpenGL/Loader.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);
|
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) {
|
const GLubyte* GetString(GLenum name) {
|
||||||
return MG_External::GLES::glGetString(name);
|
return MG_External::GLES::glGetString(name);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,5 +16,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
GLsizei drawcount, const GLint* basevertex);
|
GLsizei drawcount, const GLint* basevertex);
|
||||||
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);
|
||||||
|
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);
|
const GLubyte* GetString(GLenum name);
|
||||||
} // namespace MobileGL::MG_Backend::DirectGLES
|
} // namespace MobileGL::MG_Backend::DirectGLES
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
#include "DirectGLES.h"
|
#include "DirectGLES.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
#include "Managers.h"
|
#include "Managers.h"
|
||||||
|
#include "MG_Util/Converters/GLToMG/FramebufferEnumConverter.h"
|
||||||
#include <MG_State/GLState/Core.h>
|
#include <MG_State/GLState/Core.h>
|
||||||
#include <MG_Util/BackendLoaders/OpenGL/Loader.h>
|
#include <MG_Util/BackendLoaders/OpenGL/Loader.h>
|
||||||
#include <MG_Util/Converters/GLToStr/GLEnumConverter.h>
|
#include <MG_Util/Converters/GLToStr/GLEnumConverter.h>
|
||||||
#include <MG_Util/Converters/MGToGL/TextureEnumConverter.h>
|
#include <MG_Util/Converters/MGToGL/TextureEnumConverter.h>
|
||||||
|
#include <MG_Util/Converters/MGToGL/FramebufferEnumConverter.h>
|
||||||
|
|
||||||
namespace MobileGL::MG_Backend::DirectGLES {
|
namespace MobileGL::MG_Backend::DirectGLES {
|
||||||
namespace BufferImpl {
|
namespace BufferImpl {
|
||||||
@@ -291,6 +293,21 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
BackendFramebufferBindingProtector::~BackendFramebufferBindingProtector() {
|
BackendFramebufferBindingProtector::~BackendFramebufferBindingProtector() {
|
||||||
MG_External::GLES::glBindFramebuffer(m_target, m_previousBinding);
|
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 FramebufferImpl
|
||||||
|
|
||||||
namespace PrgramImpl {
|
namespace PrgramImpl {
|
||||||
|
|||||||
@@ -54,9 +54,13 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
|
|
||||||
~BackendFramebufferBindingProtector();
|
~BackendFramebufferBindingProtector();
|
||||||
|
|
||||||
|
static GLuint GetTempFBO(FramebufferTarget target);
|
||||||
|
static void BindTempFBO(FramebufferTarget target);
|
||||||
private:
|
private:
|
||||||
GLenum m_target;
|
GLenum m_target;
|
||||||
GLint m_previousBinding = 0;
|
GLint m_previousBinding = 0;
|
||||||
|
inline static GLuint s_tempReadFBO = 0;
|
||||||
|
inline static GLuint s_tempDrawFBO = 0;
|
||||||
};
|
};
|
||||||
} // namespace FramebufferImpl
|
} // namespace FramebufferImpl
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
#include "GL_Texture.h"
|
#include "GL_Texture.h"
|
||||||
#include "GL/gl.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 "MG_Util/Types.h"
|
||||||
#include "Validators.h"
|
#include "Validators.h"
|
||||||
#include "ProxyTexture.h"
|
#include "ProxyTexture.h"
|
||||||
@@ -804,18 +808,22 @@ namespace MobileGL {
|
|||||||
// TODO: implement
|
// TODO: implement
|
||||||
}
|
}
|
||||||
|
|
||||||
void CopyTexSubImage2D_State(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y,
|
void CopyTexSubImage2D_Backend(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y,
|
||||||
GLsizei width, GLsizei height) {
|
GLsizei width, GLsizei height) {
|
||||||
// TODO: implement
|
#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) {
|
void CopyTexSubImage1D_State(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) {
|
||||||
// TODO: implement
|
// TODO: implement
|
||||||
}
|
}
|
||||||
|
|
||||||
void CopyTexImage2D_State(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width,
|
void CopyTexImage2D_Backend(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width,
|
||||||
GLsizei height, GLint border) {
|
GLsizei height, GLint border) {
|
||||||
// TODO: implement
|
#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,
|
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,
|
void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y,
|
||||||
GLsizei width, GLsizei height) {
|
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) {
|
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,
|
void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width,
|
||||||
GLsizei height, GLint border) {
|
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,
|
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