mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-11 21:58:31 +09:00
[Feat] (MG_Impl/Texture): implement glTexImage3D in the frontend
This commit is contained in:
@@ -319,7 +319,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
targetInternal == TextureTarget::Texture1DArray || targetInternal == TextureTarget::Texture3D ||
|
targetInternal == TextureTarget::Texture1DArray || targetInternal == TextureTarget::Texture3D ||
|
||||||
targetInternal == TextureTarget::Texture2DMultisample ||
|
targetInternal == TextureTarget::Texture2DMultisample ||
|
||||||
targetInternal == TextureTarget::Texture2DArray) {
|
targetInternal == TextureTarget::Texture2DArray) {
|
||||||
MGLOG_D(" Texture target %s is not supported, skipping.",
|
MGLOG_E(" Texture target %s is not supported, skipping.",
|
||||||
MG_Util::ConvertTextureTargetToString(targetInternal).c_str());
|
MG_Util::ConvertTextureTargetToString(targetInternal).c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ namespace MobileGL {
|
|||||||
if (!TextureImpl::ValidateTextureUploadTarget(textureUploadingTarget)) return;
|
if (!TextureImpl::ValidateTextureUploadTarget(textureUploadingTarget)) return;
|
||||||
if (!TextureImpl::ValidateTextureLevelNumber(level)) return;
|
if (!TextureImpl::ValidateTextureLevelNumber(level)) return;
|
||||||
if (!TextureImpl::ValidateTextureSizeWithTextureUploadTarget(textureUploadingTarget, width, height)) return;
|
if (!TextureImpl::ValidateTextureSizeWithTextureUploadTarget(textureUploadingTarget, width, height)) return;
|
||||||
if (!TextureImpl::ValidateTextureSizeRange(width, height)) return;
|
if (!TextureImpl::ValidateTextureSizeRange(width, height, 1)) return;
|
||||||
if (!TextureImpl::ValidateTextureLevelWithUploadTarget(textureUploadingTarget, level)) return;
|
if (!TextureImpl::ValidateTextureLevelWithUploadTarget(textureUploadingTarget, level)) return;
|
||||||
|
|
||||||
// TODO: GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to the
|
// TODO: GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to the
|
||||||
@@ -494,24 +494,16 @@ namespace MobileGL {
|
|||||||
|
|
||||||
void TexImage3D_State(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
|
void TexImage3D_State(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
|
||||||
GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels) {
|
GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels) {
|
||||||
// TODO: implement
|
|
||||||
}
|
|
||||||
|
|
||||||
void TexImage2D_State(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
|
|
||||||
GLint border, GLenum format, GLenum type, const void* pixels) {
|
|
||||||
MGLOG_D(
|
MGLOG_D(
|
||||||
"TexImage2D_State called with target: %s, level: %d, internalformat: %s, width: %d, height: %d, "
|
"%s called with target: %s, level: %d, internalformat: %s, width: %d, height: %d, depth: %d, "
|
||||||
"border: %d, format: %s, type: %s (%u), pixels: %p",
|
"border: %d, format: %s, type: %s (%u), pixels: %p", __func__,
|
||||||
MG_Util::ConvertTextureUploadTargetToString(MG_Util::ConvertGLEnumToTextureUploadTarget(target))
|
MG_Util::ConvertTextureUploadTargetToString(MG_Util::ConvertGLEnumToTextureUploadTarget(target)).c_str(),
|
||||||
.c_str(),
|
|
||||||
level,
|
level,
|
||||||
MG_Util::ConvertTextureInternalFormatToString(
|
MG_Util::ConvertTextureInternalFormatToString(
|
||||||
MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat))
|
MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat)).c_str(),
|
||||||
.c_str(),
|
width, height, depth, border,
|
||||||
width, height, border,
|
|
||||||
MG_Util::ConvertTextureInputFormatToString(MG_Util::ConvertGLEnumToTextureInputFormat(format)).c_str(),
|
MG_Util::ConvertTextureInputFormatToString(MG_Util::ConvertGLEnumToTextureInputFormat(format)).c_str(),
|
||||||
MG_Util::ConvertTexturePixelDataTypeToString(MG_Util::ConvertGLEnumToTexturePixelDataType(type))
|
MG_Util::ConvertTexturePixelDataTypeToString(MG_Util::ConvertGLEnumToTexturePixelDataType(type)).c_str(),
|
||||||
.c_str(),
|
|
||||||
type, pixels);
|
type, pixels);
|
||||||
// ======================= Converting ================================
|
// ======================= Converting ================================
|
||||||
TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target);
|
TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target);
|
||||||
@@ -526,7 +518,124 @@ namespace MobileGL {
|
|||||||
if (!TextureImpl::ValidateTextureUploadTarget(textureUploadingTarget)) return;
|
if (!TextureImpl::ValidateTextureUploadTarget(textureUploadingTarget)) return;
|
||||||
if (!TextureImpl::ValidateTextureLevelNumber(level)) return;
|
if (!TextureImpl::ValidateTextureLevelNumber(level)) return;
|
||||||
if (!TextureImpl::ValidateTextureSizeWithTextureUploadTarget(textureUploadingTarget, width, height)) return;
|
if (!TextureImpl::ValidateTextureSizeWithTextureUploadTarget(textureUploadingTarget, width, height)) return;
|
||||||
if (!TextureImpl::ValidateTextureSizeRange(width, height)) return;
|
if (!TextureImpl::ValidateTextureSizeRange(width, height, depth)) return;
|
||||||
|
if (!TextureImpl::ValidateTextureInternalFormat(textureInternalFormat)) return;
|
||||||
|
if (!TextureImpl::ValidateTextureBorderNumber(border)) return;
|
||||||
|
if (!TextureImpl::ValidateTextureInternalFormatCompatibleWithInput(
|
||||||
|
textureInputFormat, textureInternalFormat, texturePixelDataType))
|
||||||
|
return;
|
||||||
|
if (!TextureImpl::ValidateTextureLevelWithUploadTarget(textureUploadingTarget, level)) return;
|
||||||
|
|
||||||
|
// TODO: GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to the
|
||||||
|
// GL_PIXEL_UNPACK_BUFFER target and the buffer object's data store is currently mapped.
|
||||||
|
// GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to the GL_PIXEL_UNPACK_BUFFER
|
||||||
|
// target and the data would be unpacked from the buffer object such that the memory reads required would
|
||||||
|
// exceed the data store size.
|
||||||
|
// GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to the GL_PIXEL_UNPACK_BUFFER
|
||||||
|
// target and data is not evenly divisible into the number of bytes needed to store in memory a datum
|
||||||
|
// indicated by type.
|
||||||
|
// ======================= Processing ================================
|
||||||
|
SharedPtr<MG_State::GLState::ITextureObject> textureObject = nullptr;
|
||||||
|
Bool isProxy = TextureImpl::IsProxyTextureTarget(textureUploadingTarget);
|
||||||
|
if (isProxy) {
|
||||||
|
textureObject =
|
||||||
|
TextureImpl::pProxyTextureManager->CreateOrReplaceProxyTextureObject(textureUploadingTarget);
|
||||||
|
} else {
|
||||||
|
auto activeUnit =
|
||||||
|
MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit());
|
||||||
|
auto& bindingSlot = activeUnit.GetBindingSlot(textureTarget);
|
||||||
|
textureObject = bindingSlot.GetBoundObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===================== Error Checking ==============================
|
||||||
|
if (!TextureImpl::ValidateTextureObject(textureObject)) return;
|
||||||
|
|
||||||
|
// ======================= Processing ================================
|
||||||
|
|
||||||
|
SizeT imageSize = 0;
|
||||||
|
const SizeT inputBpp = MG_Util::GetInputBytesPerPixel(textureInputFormat, texturePixelDataType);
|
||||||
|
const SizeT internalBpp = MG_Util::GetInternalBytesPerPixel(textureInternalFormat, texturePixelDataType);
|
||||||
|
const SizeT internalBytes = width * height * depth * internalBpp;
|
||||||
|
|
||||||
|
textureObject->SetInternalFormat(textureInternalFormat);
|
||||||
|
|
||||||
|
// if isProxy, no more pixel transfer needed below
|
||||||
|
if (isProxy) return;
|
||||||
|
|
||||||
|
const void* originalPixels = pixels;
|
||||||
|
|
||||||
|
// PBO
|
||||||
|
const auto& pixelUnpackBufferObject =
|
||||||
|
MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelUnpack).GetBoundObject();
|
||||||
|
if (pixelUnpackBufferObject) {
|
||||||
|
MGLOG_D("%s: Using Pixel Unpack Buffer Object ID: %u", __func__,
|
||||||
|
pixelUnpackBufferObject->GetExternalIndex());
|
||||||
|
originalPixels = reinterpret_cast<const char*>(pixelUnpackBufferObject->GetDataReadOnly()->data()) +
|
||||||
|
reinterpret_cast<SizeT>(pixels);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MOBILEGL_ASSERT(nullptr != dynamic_cast<MG_State::GLState::TextureObjectMipmap*>(textureObject.get()),
|
||||||
|
"Texture object here should always be an object with mipmap");
|
||||||
|
auto textureMipmapObject = static_cast<MG_State::GLState::TextureObjectMipmap*>(textureObject.get());
|
||||||
|
|
||||||
|
// Allocate in TextureObject
|
||||||
|
textureMipmapObject->AllocateStorage(textureUploadingTarget, level, {{width, height, depth}, internalBytes});
|
||||||
|
|
||||||
|
if (!originalPixels) {
|
||||||
|
MGLOG_D("%s: No input pixel and no PBO bound, no pixel transfer", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* processedPixels = nullptr;
|
||||||
|
processedPixels = MG_Util::PixelStoreProcessor::ProcessTexturePixelsDataUnpack(
|
||||||
|
originalPixels, MG_State::pGLContext->GetPixelStoreParameters(true), textureInternalFormat,
|
||||||
|
textureInputFormat, texturePixelDataType, {width, height, depth}, false, imageSize);
|
||||||
|
|
||||||
|
if (processedPixels && imageSize > 0) {
|
||||||
|
if (imageSize != internalBytes) {
|
||||||
|
MGLOG_W("%s: Processed pixel data size (%zu) does not match expected size (%zu). "
|
||||||
|
"This may indicate an alignment or processing issue.", __func__,
|
||||||
|
imageSize, internalBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
const SizeT copySize = std::min(imageSize, internalBytes);
|
||||||
|
DataPtr texelInput{processedPixels, copySize};
|
||||||
|
textureMipmapObject->UpdateMipmapSubData(textureUploadingTarget, level, texelInput);
|
||||||
|
}
|
||||||
|
|
||||||
|
textureMipmapObject->MarkStorageDirty(textureUploadingTarget, level, true);
|
||||||
|
|
||||||
|
free(processedPixels);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TexImage2D_State(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
|
||||||
|
GLint border, GLenum format, GLenum type, const void* pixels) {
|
||||||
|
MGLOG_D(
|
||||||
|
"%s called with target: %s, level: %d, internalformat: %s, width: %d, height: %d, "
|
||||||
|
"border: %d, format: %s, type: %s (%u), pixels: %p", __func__,
|
||||||
|
MG_Util::ConvertTextureUploadTargetToString(MG_Util::ConvertGLEnumToTextureUploadTarget(target)).c_str(),
|
||||||
|
level,
|
||||||
|
MG_Util::ConvertTextureInternalFormatToString(
|
||||||
|
MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat)).c_str(),
|
||||||
|
width, height, border,
|
||||||
|
MG_Util::ConvertTextureInputFormatToString(MG_Util::ConvertGLEnumToTextureInputFormat(format)).c_str(),
|
||||||
|
MG_Util::ConvertTexturePixelDataTypeToString(MG_Util::ConvertGLEnumToTexturePixelDataType(type)).c_str(),
|
||||||
|
type, pixels);
|
||||||
|
// ======================= Converting ================================
|
||||||
|
TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target);
|
||||||
|
TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target);
|
||||||
|
TextureInputFormat textureInputFormat = MG_Util::ConvertGLEnumToTextureInputFormat(format);
|
||||||
|
TexturePixelDataType texturePixelDataType = MG_Util::ConvertGLEnumToTexturePixelDataType(type);
|
||||||
|
TextureInternalFormat textureInternalFormat = MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat);
|
||||||
|
|
||||||
|
// ===================== Error Checking ==============================
|
||||||
|
if (!TextureImpl::ValidateTexturePixelDataType(texturePixelDataType)) return;
|
||||||
|
if (!TextureImpl::ValidateTextureInputFormat(textureInputFormat)) return;
|
||||||
|
if (!TextureImpl::ValidateTextureUploadTarget(textureUploadingTarget)) return;
|
||||||
|
if (!TextureImpl::ValidateTextureLevelNumber(level)) return;
|
||||||
|
if (!TextureImpl::ValidateTextureSizeWithTextureUploadTarget(textureUploadingTarget, width, height)) return;
|
||||||
|
if (!TextureImpl::ValidateTextureSizeRange(width, height, 1)) return;
|
||||||
if (!TextureImpl::ValidateTextureInternalFormat(textureInternalFormat)) return;
|
if (!TextureImpl::ValidateTextureInternalFormat(textureInternalFormat)) return;
|
||||||
if (!TextureImpl::ValidateTextureBorderNumber(border)) return;
|
if (!TextureImpl::ValidateTextureBorderNumber(border)) return;
|
||||||
if (!TextureImpl::ValidateTextureInternalFormatCompatibleWithInput(
|
if (!TextureImpl::ValidateTextureInternalFormatCompatibleWithInput(
|
||||||
@@ -577,7 +686,7 @@ namespace MobileGL {
|
|||||||
const auto& pixelUnpackBufferObject =
|
const auto& pixelUnpackBufferObject =
|
||||||
MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelUnpack).GetBoundObject();
|
MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelUnpack).GetBoundObject();
|
||||||
if (pixelUnpackBufferObject) {
|
if (pixelUnpackBufferObject) {
|
||||||
MGLOG_D("TexImage2D_State: Using Pixel Unpack Buffer Object ID: %u",
|
MGLOG_D("%s: Using Pixel Unpack Buffer Object ID: %u", __func__,
|
||||||
pixelUnpackBufferObject->GetExternalIndex());
|
pixelUnpackBufferObject->GetExternalIndex());
|
||||||
originalPixels = reinterpret_cast<const char*>(pixelUnpackBufferObject->GetDataReadOnly()->data()) +
|
originalPixels = reinterpret_cast<const char*>(pixelUnpackBufferObject->GetDataReadOnly()->data()) +
|
||||||
reinterpret_cast<SizeT>(pixels);
|
reinterpret_cast<SizeT>(pixels);
|
||||||
@@ -591,7 +700,7 @@ namespace MobileGL {
|
|||||||
textureMipmapObject->AllocateStorage(textureUploadingTarget, level, {{width, height, 1}, internalBytes});
|
textureMipmapObject->AllocateStorage(textureUploadingTarget, level, {{width, height, 1}, internalBytes});
|
||||||
|
|
||||||
if (!originalPixels) {
|
if (!originalPixels) {
|
||||||
MGLOG_D("TexImage2D_State: No input pixel and no PBO bound, no pixel transfer");
|
MGLOG_D("%s: No input pixel and no PBO bound, no pixel transfer", __func__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1153,6 +1262,7 @@ namespace MobileGL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BindTexture_State(GLenum target, GLuint texture) {
|
void BindTexture_State(GLenum target, GLuint texture) {
|
||||||
|
// TODO: deal with condition where texture == 0
|
||||||
MGLOG_D("BindTexture_State called with target: 0x%X, texture: %u", target, texture);
|
MGLOG_D("BindTexture_State called with target: 0x%X, texture: %u", target, texture);
|
||||||
// ======================= Converting ================================
|
// ======================= Converting ================================
|
||||||
TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target);
|
TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target);
|
||||||
|
|||||||
@@ -134,8 +134,8 @@ namespace MobileGL::MG_Impl::GLImpl {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool ValidateTextureSizeRange(SizeT width, SizeT height) {
|
Bool ValidateTextureSizeRange(SizeT width, SizeT height, SizeT depth) {
|
||||||
if (width < 0 || height < 0) {
|
if (width < 0 || height < 0 || depth < 0) {
|
||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
ErrorCode::InvalidValue,
|
ErrorCode::InvalidValue,
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureSizeRange",
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureSizeRange",
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ namespace MobileGL::MG_Impl::GLImpl {
|
|||||||
Bool ValidateTexturePixelDataType(TexturePixelDataType texturePixelDataType);
|
Bool ValidateTexturePixelDataType(TexturePixelDataType texturePixelDataType);
|
||||||
Bool ValidateTextureLevelNumber(Int level);
|
Bool ValidateTextureLevelNumber(Int level);
|
||||||
Bool ValidateTextureSizeWithTextureUploadTarget(TextureUploadTarget target, GLsizei width, GLsizei height);
|
Bool ValidateTextureSizeWithTextureUploadTarget(TextureUploadTarget target, GLsizei width, GLsizei height);
|
||||||
Bool ValidateTextureSizeRange(SizeT width, SizeT height);
|
Bool ValidateTextureSizeRange(SizeT width, SizeT height, SizeT depth);
|
||||||
Bool ValidateTextureInternalFormat(TextureInternalFormat format);
|
Bool ValidateTextureInternalFormat(TextureInternalFormat format);
|
||||||
Bool ValidateTextureBorderNumber(Int border);
|
Bool ValidateTextureBorderNumber(Int border);
|
||||||
Bool ValidateTextureInternalFormatCompatibleWithInput(TextureInputFormat format, TextureInternalFormat internalFormat,
|
Bool ValidateTextureInternalFormatCompatibleWithInput(TextureInputFormat format, TextureInternalFormat internalFormat,
|
||||||
|
|||||||
@@ -148,13 +148,14 @@ namespace MobileGL::MG_Util::PixelStoreProcessor {
|
|||||||
if (textureInputFormat == TextureInputFormat::BGRA &&
|
if (textureInputFormat == TextureInputFormat::BGRA &&
|
||||||
targetInternalFormat == TextureInternalFormat::RGBA8) {
|
targetInternalFormat == TextureInternalFormat::RGBA8) {
|
||||||
MGLOG_D("%s: Swizzle (BGRA)", __func__);
|
MGLOG_D("%s: Swizzle (BGRA)", __func__);
|
||||||
MGLOG_D("%s: pixel0 before = %x", __func__, *((Uint32*)layerDst));
|
// MGLOG_D("%s: pixel0 before = %x", __func__, *((Uint32*)layerDst));
|
||||||
ProcessColorSwizzle(layerDst, static_cast<SizeT>(copyWidth),
|
ProcessColorSwizzle(layerDst, static_cast<SizeT>(copyWidth),
|
||||||
{TextureSwizzleParam::Green, TextureSwizzleParam::Blue,
|
{TextureSwizzleParam::Green, TextureSwizzleParam::Blue,
|
||||||
TextureSwizzleParam::Alpha, TextureSwizzleParam::Red});
|
TextureSwizzleParam::Alpha, TextureSwizzleParam::Red});
|
||||||
MGLOG_D("%s: pixel0 after = %x", __func__, *((Uint32*)layerDst));
|
// MGLOG_D("%s: pixel0 after = %x", __func__, *((Uint32*)layerDst));
|
||||||
} else
|
}
|
||||||
MGLOG_D("%s: pixel0 = %x", __func__, *((Uint32*)layerDst));
|
// else
|
||||||
|
// MGLOG_D("%s: pixel0 = %x", __func__, *((Uint32*)layerDst));
|
||||||
|
|
||||||
layerSrc += inputStride;
|
layerSrc += inputStride;
|
||||||
layerDst += static_cast<SizeT>(copyWidth) * pixelSize;
|
layerDst += static_cast<SizeT>(copyWidth) * pixelSize;
|
||||||
|
|||||||
Reference in New Issue
Block a user