mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-10 21:28:32 +09:00
[Fix] (*/Texture*): Correctly handle the format in CopyTexImage2D.
This commit is contained in:
@@ -879,13 +879,13 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
}
|
}
|
||||||
backendTextureIt->second->Bind(target, activeTextureUnit);
|
backendTextureIt->second->Bind(target, activeTextureUnit);
|
||||||
|
|
||||||
auto mglInternalFormat = MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat);
|
auto mgInternalFormat = textureObject->GetFormat();
|
||||||
GLenum format = GL_DEPTH_COMPONENT;
|
GLenum format = GL_DEPTH_COMPONENT;
|
||||||
GLenum type = GL_UNSIGNED_INT;
|
GLenum type = GL_UNSIGNED_INT;
|
||||||
TextureImpl::GenerateTextureFormatInfo(mglInternalFormat, &internalformat, &format, &type);
|
TextureImpl::GenerateTextureFormatInfo(mgInternalFormat, &internalformat, &format, &type);
|
||||||
MOBILEGL_ASSERT(format != GL_NONE && type != GL_NONE,
|
MOBILEGL_ASSERT(format != GL_NONE && type != GL_NONE,
|
||||||
"%s: cannot GenerateTextureFormatInfo(%s): out internalformat=%s, format=%s, type=%s",
|
"%s: cannot GenerateTextureFormatInfo(%s): out internalformat=%s, format=%s, type=%s",
|
||||||
MG_Util::ConvertTextureInternalFormatToString(mglInternalFormat).c_str(),
|
MG_Util::ConvertTextureInternalFormatToString(mgInternalFormat).c_str(),
|
||||||
MG_Util::ConvertGLEnumToString(internalformat).c_str(),
|
MG_Util::ConvertGLEnumToString(internalformat).c_str(),
|
||||||
MG_Util::ConvertGLEnumToString(format).c_str(), MG_Util::ConvertGLEnumToString(type).c_str());
|
MG_Util::ConvertGLEnumToString(format).c_str(), MG_Util::ConvertGLEnumToString(type).c_str());
|
||||||
TexturePixelDataType texturePixelDataType = MG_Util::ConvertGLEnumToTexturePixelDataType(type);
|
TexturePixelDataType texturePixelDataType = MG_Util::ConvertGLEnumToTexturePixelDataType(type);
|
||||||
@@ -976,10 +976,10 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) {
|
errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) {
|
||||||
MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str());
|
MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str());
|
||||||
});
|
});
|
||||||
auto mglInternalFormat = MG_Util::ConvertGLEnumToTextureInternalFormat(internalFormat);
|
auto mgInternalFormat = MG_Util::ConvertGLEnumToTextureInternalFormat(internalFormat);
|
||||||
|
|
||||||
Bool isDepthFormat = MG_Util::IsDepthFormatInternalFormat(mglInternalFormat);
|
Bool isDepthFormat = MG_Util::IsDepthFormatInternalFormat(mgInternalFormat);
|
||||||
Bool isStencilFormat = MG_Util::IsStencilFormatInternalFormat(mglInternalFormat);
|
Bool isStencilFormat = MG_Util::IsStencilFormatInternalFormat(mgInternalFormat);
|
||||||
|
|
||||||
if (!isDepthFormat) {
|
if (!isDepthFormat) {
|
||||||
MG_External::GLES::glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
|
MG_External::GLES::glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
|
||||||
|
|||||||
@@ -7,26 +7,27 @@
|
|||||||
// End of Source File Header
|
// End of Source File Header
|
||||||
|
|
||||||
#include "GL_Texture.h"
|
#include "GL_Texture.h"
|
||||||
#include "GL/gl.h"
|
|
||||||
#include "Config.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"
|
||||||
#include "MG_State/GLState/TextureState/TextureObjectBuffer.h"
|
|
||||||
#include "MG_Util/Converters/GLToStr/GLEnumConverter.h"
|
|
||||||
#include "MG_Util/Texture/TextureFormatProcessor.h"
|
|
||||||
|
|
||||||
#include <MG_State/GLState/Core.h>
|
#include <MG_State/GLState/Core.h>
|
||||||
#include <MG_Util/Metrics/TextureMetrics.h>
|
#include <MG_Util/Metrics/TextureMetrics.h>
|
||||||
#include <MG_State/GLState/ErrorState/Error.h>
|
#include <MG_State/GLState/ErrorState/Error.h>
|
||||||
#include <MG_Util/Texture/PixelStoreProcessor.h>
|
#include <MG_Util/Texture/PixelStoreProcessor.h>
|
||||||
|
#include <MG_Util/Texture/TextureFormatProcessor.h>
|
||||||
|
#include <MG_Util/Classifiers/TextureEnumClassifier.h>
|
||||||
|
#include <MG_Util/Converters/GLToStr/GLEnumConverter.h>
|
||||||
#include <MG_Util/Converters/MGToMG/TextureEnumConverter.h>
|
#include <MG_Util/Converters/MGToMG/TextureEnumConverter.h>
|
||||||
#include <MG_Util/Converters/GLToMG/TextureEnumConverter.h>
|
#include <MG_Util/Converters/GLToMG/TextureEnumConverter.h>
|
||||||
#include <MG_Util/Converters/MGToGL/TextureEnumConverter.h>
|
#include <MG_Util/Converters/MGToGL/TextureEnumConverter.h>
|
||||||
#include <MG_Util/Converters/MGToStr/TextureEnumConverter.h>
|
#include <MG_Util/Converters/MGToStr/TextureEnumConverter.h>
|
||||||
|
#include <MG_State/GLState/TextureState/TextureObjectBuffer.h>
|
||||||
|
|
||||||
|
#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES
|
||||||
|
#include <MG_Backend/DirectGLES/DirectGLES.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace MobileGL {
|
namespace MobileGL {
|
||||||
namespace MG_Impl::GLImpl {
|
namespace MG_Impl::GLImpl {
|
||||||
@@ -1228,12 +1229,57 @@ namespace MobileGL {
|
|||||||
|
|
||||||
void CopyTexImage2D_State(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width,
|
void CopyTexImage2D_State(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width,
|
||||||
GLsizei height, GLint border) {
|
GLsizei height, GLint border) {
|
||||||
GLenum outInternalFormat, format, type;
|
auto internalFormat = MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat);
|
||||||
MG_Util::TextureFormatProcessor::NormalizePixelFormat(internalformat, 0, &outInternalFormat, &format,
|
const auto& currentReadFBO =
|
||||||
&type);
|
MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Read).GetBoundObject();
|
||||||
|
if (!currentReadFBO) {
|
||||||
|
MG_State::pGLContext->RecordError(
|
||||||
|
ErrorCode::InvalidOperation,
|
||||||
|
MakeShared<GenericErrorInfo>(
|
||||||
|
"MG_Impl/GLImpl", "CopyTexImage2D_State",
|
||||||
|
"No framebuffer is currently bound to the GL_READ_FRAMEBUFFER target."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool isDepth = MG_Util::IsDepthFormatInternalFormat(internalFormat);
|
||||||
|
Bool isStencil = MG_Util::IsStencilFormatInternalFormat(internalFormat);
|
||||||
|
TextureInternalFormat srcInternalFormat = TextureInternalFormat::Unknown;
|
||||||
|
#define GET_SRC_INTERNAL_FORMAT(AttachmentType) \
|
||||||
|
const auto& srcAttachment = currentReadFBO->GetAttachment(AttachmentType); \
|
||||||
|
if (srcAttachment.IsTexture()) { \
|
||||||
|
const auto& texObj = srcAttachment.GetTexture(); \
|
||||||
|
srcInternalFormat = texObj->GetFormat(); \
|
||||||
|
} else if (srcAttachment.IsRenderbuffer()) { \
|
||||||
|
const auto& rboObj = srcAttachment.GetRenderbuffer(); \
|
||||||
|
srcInternalFormat = rboObj->GetInternalFormat(); \
|
||||||
|
} else { \
|
||||||
|
MG_State::pGLContext->RecordError( \
|
||||||
|
ErrorCode::InvalidOperation, \
|
||||||
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "CopyTexImage2D_State", \
|
||||||
|
"The attachment specified by the read buffer is incomplete.")); \
|
||||||
|
return; \
|
||||||
|
}
|
||||||
|
if (isDepth) {
|
||||||
|
GET_SRC_INTERNAL_FORMAT(FramebufferAttachmentType::Depth);
|
||||||
|
} else if (isStencil) {
|
||||||
|
GET_SRC_INTERNAL_FORMAT(FramebufferAttachmentType::Stencil);
|
||||||
|
} else {
|
||||||
|
const auto& readBufferType = currentReadFBO->GetReadBuffer();
|
||||||
|
GET_SRC_INTERNAL_FORMAT(readBufferType);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TextureImpl::ValidateBaseInternalFormatMatch(internalFormat, srcInternalFormat))
|
||||||
|
THROW_UNIMPL_EXCEPTION;
|
||||||
|
|
||||||
|
GLenum outInternalFormat = MG_Util::ConvertTextureInternalFormatToGLEnum(srcInternalFormat);
|
||||||
|
GLenum realInternalFormat = GL_RGBA8;
|
||||||
|
GLenum format = GL_DEPTH_COMPONENT;
|
||||||
|
GLenum type = GL_UNSIGNED_INT;
|
||||||
|
MG_Util::TextureFormatProcessor::NormalizePixelFormat(
|
||||||
|
outInternalFormat, PixelFormatNormalizeOptionBit::None, &realInternalFormat, &format, &type);
|
||||||
const auto pixelUnpackBufferObject =
|
const auto pixelUnpackBufferObject =
|
||||||
MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelUnpack).GetBoundObject();
|
MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelUnpack).GetBoundObject();
|
||||||
TexImage2D_State(target, level, outInternalFormat, width, height, border, format, type, nullptr);
|
TexImage2D_State(target, level, realInternalFormat, width, height, border, format, type, nullptr);
|
||||||
MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelUnpack).Bind(pixelUnpackBufferObject);
|
MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelUnpack).Bind(pixelUnpackBufferObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,13 +7,12 @@
|
|||||||
// End of Source File Header
|
// End of Source File Header
|
||||||
|
|
||||||
#include "Validators.h"
|
#include "Validators.h"
|
||||||
#include "MG_State/GLState/TextureState/TextureObject.h"
|
|
||||||
#include "MG_Util/Types.h"
|
|
||||||
#include <MG_State/GLState/Core.h>
|
#include <MG_State/GLState/Core.h>
|
||||||
#include <MG_State/GLState/ErrorState/Error.h>
|
#include <MG_State/GLState/ErrorState/Error.h>
|
||||||
#include <MG_Util/Converters/GLToStr/GLEnumConverter.h>
|
#include <MG_Util/Converters/GLToStr/GLEnumConverter.h>
|
||||||
#include <MG_Util/Converters/GLToMG/TextureEnumConverter.h>
|
#include <MG_Util/Converters/GLToMG/TextureEnumConverter.h>
|
||||||
#include <MG_Util/Converters/MGToGL/TextureEnumConverter.h>
|
#include <MG_Util/Converters/MGToGL/TextureEnumConverter.h>
|
||||||
|
#include <MG_Util/Converters/MGToMG/TextureEnumConverter.h>
|
||||||
#include <MG_Util/Converters/MGToStr/TextureEnumConverter.h>
|
#include <MG_Util/Converters/MGToStr/TextureEnumConverter.h>
|
||||||
|
|
||||||
namespace MobileGL::MG_Impl::GLImpl {
|
namespace MobileGL::MG_Impl::GLImpl {
|
||||||
@@ -170,6 +169,7 @@ namespace MobileGL::MG_Impl::GLImpl {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool ValidateTextureInternalFormatCompatibleWithInput(TextureInputFormat format,
|
Bool ValidateTextureInternalFormatCompatibleWithInput(TextureInputFormat format,
|
||||||
TextureInternalFormat internalFormat,
|
TextureInternalFormat internalFormat,
|
||||||
TexturePixelDataType type) {
|
TexturePixelDataType type) {
|
||||||
@@ -303,5 +303,21 @@ namespace MobileGL::MG_Impl::GLImpl {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Bool ValidateBaseInternalFormatMatch(TextureInternalFormat format1, TextureInternalFormat format2) {
|
||||||
|
auto unsizedFormat1 = MG_Util::ConvertInternalFormatToUnsized(format1);
|
||||||
|
auto unsizedFormat2 = MG_Util::ConvertInternalFormatToUnsized(format2);
|
||||||
|
if (unsizedFormat1 != unsizedFormat2) {
|
||||||
|
MG_State::pGLContext->RecordError(
|
||||||
|
ErrorCode::InvalidOperation,
|
||||||
|
MakeShared<GenericErrorInfo>(
|
||||||
|
std::format("MG_Impl/GLImpl", "ValidateBaseInternalFormatMatch",
|
||||||
|
"The base internal format of the two formats do not match ({} vs. {})",
|
||||||
|
MG_Util::ConvertTextureInternalFormatToString(unsizedFormat1).c_str(),
|
||||||
|
MG_Util::ConvertTextureInternalFormatToString(unsizedFormat2).c_str())));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} // namespace TextureImpl
|
||||||
} // namespace TextureImpl
|
} // namespace TextureImpl
|
||||||
} // namespace MobileGL::MG_Impl::GLImpl
|
} // namespace MobileGL::MG_Impl::GLImpl
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
// End of Source File Header
|
// End of Source File Header
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include "MG_State/GLState/TextureState/TextureEnum.h"
|
||||||
#include "MG_Util/Types.h"
|
#include "MG_Util/Types.h"
|
||||||
#include <Includes.h>
|
#include <Includes.h>
|
||||||
#include <MG_State/GLState/TextureState/TextureObject.h>
|
#include <MG_State/GLState/TextureState/TextureObject.h>
|
||||||
@@ -32,5 +33,6 @@ namespace MobileGL::MG_Impl::GLImpl {
|
|||||||
TextureTarget target);
|
TextureTarget target);
|
||||||
Bool ValidateTextureSubImageOffsets(SharedPtr<MG_State::GLState::ITextureObject> textureObject, Int xoffset,
|
Bool ValidateTextureSubImageOffsets(SharedPtr<MG_State::GLState::ITextureObject> textureObject, Int xoffset,
|
||||||
Int width, Int yoffset = 0, Int height = 0, Int zoffset = 0, Int depth = 0);
|
Int width, Int yoffset = 0, Int height = 0, Int zoffset = 0, Int depth = 0);
|
||||||
|
Bool ValidateBaseInternalFormatMatch(TextureInternalFormat format1, TextureInternalFormat format2);
|
||||||
} // namespace TextureImpl
|
} // namespace TextureImpl
|
||||||
} // namespace MobileGL::MG_Impl::GLImpl
|
} // namespace MobileGL::MG_Impl::GLImpl
|
||||||
@@ -71,7 +71,8 @@ namespace MobileGL {
|
|||||||
namespace GLState {
|
namespace GLState {
|
||||||
class FramebufferAttachmentObject {
|
class FramebufferAttachmentObject {
|
||||||
public:
|
public:
|
||||||
explicit FramebufferAttachmentObject(SharedPtr<MG_State::GLState::ITextureObject> texture, Int level = 0);
|
explicit FramebufferAttachmentObject(SharedPtr<MG_State::GLState::ITextureObject> texture,
|
||||||
|
Int level = 0);
|
||||||
explicit FramebufferAttachmentObject(SharedPtr<RenderbufferObject> renderbuffer);
|
explicit FramebufferAttachmentObject(SharedPtr<RenderbufferObject> renderbuffer);
|
||||||
explicit FramebufferAttachmentObject(Bool IsValid = true);
|
explicit FramebufferAttachmentObject(Bool IsValid = true);
|
||||||
|
|
||||||
@@ -98,10 +99,11 @@ namespace MobileGL {
|
|||||||
|
|
||||||
using TargetEnum = FramebufferTarget;
|
using TargetEnum = FramebufferTarget;
|
||||||
using FramebufferAttachmentObjectArray =
|
using FramebufferAttachmentObjectArray =
|
||||||
Array<FramebufferAttachmentObject, static_cast<SizeT>(FramebufferAttachmentType::FramebufferAttachmentTypeCount)>;
|
Array<FramebufferAttachmentObject,
|
||||||
|
static_cast<SizeT>(FramebufferAttachmentType::FramebufferAttachmentTypeCount)>;
|
||||||
using FramebufferAttachmentArray = Array<FramebufferAttachmentType, MAX_DRAW_BUFFERS>;
|
using FramebufferAttachmentArray = Array<FramebufferAttachmentType, MAX_DRAW_BUFFERS>;
|
||||||
using FramebufferAttachmentVersionArray =
|
using FramebufferAttachmentVersionArray =
|
||||||
Array<Uint16, static_cast<SizeT>(FramebufferAttachmentType::FramebufferAttachmentTypeCount)>;
|
Array<Uint16, static_cast<SizeT>(FramebufferAttachmentType::FramebufferAttachmentTypeCount)>;
|
||||||
|
|
||||||
FramebufferObject(Uint externalIndex);
|
FramebufferObject(Uint externalIndex);
|
||||||
|
|
||||||
|
|||||||
@@ -9,11 +9,14 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <Includes.h>
|
#include <Includes.h>
|
||||||
|
|
||||||
namespace MobileGL::MG_Util::TextureFormatProcessor {
|
namespace MobileGL {
|
||||||
enum class PixelFormatNormalizeOptionBit : Uint {
|
enum class PixelFormatNormalizeOptionBit : Uint {
|
||||||
NoNorm16 = 1 << 0,
|
NoNorm16 = 1 << 0,
|
||||||
None = 0,
|
None = 0,
|
||||||
};
|
};
|
||||||
void NormalizePixelFormat(GLenum internalFormat, Flags<PixelFormatNormalizeOptionBit> options,
|
|
||||||
GLenum* outInternalFormat, GLenum* outFormat, GLenum* outType);
|
namespace MG_Util::TextureFormatProcessor {
|
||||||
} // namespace MobileGL::MG_Util::TextureFormatProcessor
|
void NormalizePixelFormat(GLenum internalFormat, Flags<PixelFormatNormalizeOptionBit> options,
|
||||||
|
GLenum* outInternalFormat, GLenum* outFormat, GLenum* outType);
|
||||||
|
}
|
||||||
|
} // namespace MobileGL
|
||||||
Reference in New Issue
Block a user