mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-12 06:08:30 +09:00
[Fix] (MG_Backend/DirectGLES, MG_Impl/GLImpl): sync GL_TEXTURE_2D_ARRAY textures to the ES backend - the target was skipped as unsupported so array textures never uploaded or bound (every KHR-GL33.pixelstoragemodes.teximage3d case failed); also keep array layer counts constant across mip levels in TexStorage3D and generated-mip storage allocation (only true 3D textures halve depth)
This commit is contained in:
@@ -1715,6 +1715,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
0, glFormat, glType, uploadData);
|
0, glFormat, glType, uploadData);
|
||||||
break;
|
break;
|
||||||
case TextureTarget::Texture3D:
|
case TextureTarget::Texture3D:
|
||||||
|
case TextureTarget::Texture2DArray:
|
||||||
g_GLESFuncs.glTexImage3D(
|
g_GLESFuncs.glTexImage3D(
|
||||||
glUploadTarget, static_cast<GLint>(level), (GLint)glInternalFormat,
|
glUploadTarget, static_cast<GLint>(level), (GLint)glInternalFormat,
|
||||||
static_cast<GLsizei>(levelTexelSize.x()), static_cast<GLsizei>(levelTexelSize.y()),
|
static_cast<GLsizei>(levelTexelSize.x()), static_cast<GLsizei>(levelTexelSize.y()),
|
||||||
@@ -1790,6 +1791,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
static_cast<GLsizei>(baseSize.y()));
|
static_cast<GLsizei>(baseSize.y()));
|
||||||
break;
|
break;
|
||||||
case TextureTarget::Texture3D:
|
case TextureTarget::Texture3D:
|
||||||
|
case TextureTarget::Texture2DArray:
|
||||||
g_GLESFuncs.glTexStorage3D(target, static_cast<GLsizei>(mipmapCount), glInternalFormat,
|
g_GLESFuncs.glTexStorage3D(target, static_cast<GLsizei>(mipmapCount), glInternalFormat,
|
||||||
static_cast<GLsizei>(baseSize.x()),
|
static_cast<GLsizei>(baseSize.x()),
|
||||||
static_cast<GLsizei>(baseSize.y()),
|
static_cast<GLsizei>(baseSize.y()),
|
||||||
@@ -1835,6 +1837,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
static_cast<GLsizei>(levelTexelSize.y()), glFormat, glType, uploadData);
|
static_cast<GLsizei>(levelTexelSize.y()), glFormat, glType, uploadData);
|
||||||
break;
|
break;
|
||||||
case TextureTarget::Texture3D:
|
case TextureTarget::Texture3D:
|
||||||
|
case TextureTarget::Texture2DArray:
|
||||||
g_GLESFuncs.glTexSubImage3D(
|
g_GLESFuncs.glTexSubImage3D(
|
||||||
glUploadTarget, static_cast<GLint>(level), 0, 0, 0,
|
glUploadTarget, static_cast<GLint>(level), 0, 0, 0,
|
||||||
static_cast<GLsizei>(levelTexelSize.x()),
|
static_cast<GLsizei>(levelTexelSize.x()),
|
||||||
@@ -1893,7 +1896,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
static_cast<GLsizei>(levelTexelSize.y()), 0, glFormat, glType, uploadData);
|
static_cast<GLsizei>(levelTexelSize.y()), 0, glFormat, glType, uploadData);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TextureTarget::Texture3D: {
|
case TextureTarget::Texture3D:
|
||||||
|
case TextureTarget::Texture2DArray: {
|
||||||
g_GLESFuncs.glTexImage3D(
|
g_GLESFuncs.glTexImage3D(
|
||||||
glUploadTarget, static_cast<GLint>(level), (GLint)glInternalFormat,
|
glUploadTarget, static_cast<GLint>(level), (GLint)glInternalFormat,
|
||||||
static_cast<GLsizei>(levelTexelSize.x()),
|
static_cast<GLsizei>(levelTexelSize.x()),
|
||||||
@@ -1987,6 +1991,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
uploadData);
|
uploadData);
|
||||||
break;
|
break;
|
||||||
case TextureTarget::Texture3D:
|
case TextureTarget::Texture3D:
|
||||||
|
case TextureTarget::Texture2DArray:
|
||||||
g_GLESFuncs.glTexSubImage3D(glUploadTarget, static_cast<GLint>(level), 0, 0, 0,
|
g_GLESFuncs.glTexSubImage3D(glUploadTarget, static_cast<GLint>(level), 0, 0, 0,
|
||||||
static_cast<GLsizei>(texelSize.x()),
|
static_cast<GLsizei>(texelSize.x()),
|
||||||
static_cast<GLsizei>(texelSize.y()),
|
static_cast<GLsizei>(texelSize.y()),
|
||||||
|
|||||||
@@ -255,7 +255,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
namespace TextureImpl {
|
namespace TextureImpl {
|
||||||
inline Bool IsSupportedTextureTarget(TextureTarget target) {
|
inline Bool IsSupportedTextureTarget(TextureTarget target) {
|
||||||
if (target == TextureTarget::Texture1D || target == TextureTarget::TextureRectangle ||
|
if (target == TextureTarget::Texture1D || target == TextureTarget::TextureRectangle ||
|
||||||
target == TextureTarget::Texture1DArray || target == TextureTarget::Texture2DArray)
|
target == TextureTarget::Texture1DArray)
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -284,10 +284,16 @@ namespace MobileGL::MG_Impl::GLImpl {
|
|||||||
MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS));
|
MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS));
|
||||||
}
|
}
|
||||||
|
|
||||||
Uint ComputeFullMipmapLevelCount(const IntVec3& baseTexelSize) {
|
// Array targets store their layer count in z; layers never participate in mip
|
||||||
|
// reduction (GL 3.3 §3.8.14), only true 3D textures halve their depth per level.
|
||||||
|
Bool DepthParticipatesInMipmapping(TextureTarget target) {
|
||||||
|
return target == TextureTarget::Texture3D;
|
||||||
|
}
|
||||||
|
|
||||||
|
Uint ComputeFullMipmapLevelCount(const IntVec3& baseTexelSize, Bool depthMips) {
|
||||||
Int maxDimension = std::max<Int>(
|
Int maxDimension = std::max<Int>(
|
||||||
baseTexelSize.x(),
|
baseTexelSize.x(),
|
||||||
std::max<Int>(baseTexelSize.y(), std::max<Int>(baseTexelSize.z(), 1)));
|
std::max<Int>(baseTexelSize.y(), depthMips ? std::max<Int>(baseTexelSize.z(), 1) : 1));
|
||||||
Uint mipLevelCount = 1;
|
Uint mipLevelCount = 1;
|
||||||
while (maxDimension > 1) {
|
while (maxDimension > 1) {
|
||||||
maxDimension = std::max<Int>(maxDimension / 2, 1);
|
maxDimension = std::max<Int>(maxDimension / 2, 1);
|
||||||
@@ -296,11 +302,12 @@ namespace MobileGL::MG_Impl::GLImpl {
|
|||||||
return mipLevelCount;
|
return mipLevelCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
IntVec3 ComputeMipmapTexelSize(const IntVec3& baseTexelSize, Uint relativeLevel) {
|
IntVec3 ComputeMipmapTexelSize(const IntVec3& baseTexelSize, Uint relativeLevel, Bool depthMips) {
|
||||||
return {
|
return {
|
||||||
std::max<Int>(baseTexelSize.x() >> static_cast<Int>(relativeLevel), 1),
|
std::max<Int>(baseTexelSize.x() >> static_cast<Int>(relativeLevel), 1),
|
||||||
std::max<Int>(baseTexelSize.y() >> static_cast<Int>(relativeLevel), 1),
|
std::max<Int>(baseTexelSize.y() >> static_cast<Int>(relativeLevel), 1),
|
||||||
std::max<Int>(baseTexelSize.z() >> static_cast<Int>(relativeLevel), 1),
|
depthMips ? std::max<Int>(baseTexelSize.z() >> static_cast<Int>(relativeLevel), 1)
|
||||||
|
: std::max<Int>(baseTexelSize.z(), 1),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,9 +330,10 @@ namespace MobileGL::MG_Impl::GLImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const SizeT bytesPerTexel = baseByteSize / baseTexelCount;
|
const SizeT bytesPerTexel = baseByteSize / baseTexelCount;
|
||||||
const Uint requiredLevelCount = ComputeFullMipmapLevelCount(baseTexelSize);
|
const Bool depthMips = DepthParticipatesInMipmapping(texture.GetTarget());
|
||||||
|
const Uint requiredLevelCount = ComputeFullMipmapLevelCount(baseTexelSize, depthMips);
|
||||||
for (Uint level = 1; level < requiredLevelCount; ++level) {
|
for (Uint level = 1; level < requiredLevelCount; ++level) {
|
||||||
const IntVec3 levelTexelSize = ComputeMipmapTexelSize(baseTexelSize, level);
|
const IntVec3 levelTexelSize = ComputeMipmapTexelSize(baseTexelSize, level, depthMips);
|
||||||
const SizeT levelByteSize = bytesPerTexel * static_cast<SizeT>(levelTexelSize.x()) *
|
const SizeT levelByteSize = bytesPerTexel * static_cast<SizeT>(levelTexelSize.x()) *
|
||||||
static_cast<SizeT>(levelTexelSize.y()) *
|
static_cast<SizeT>(levelTexelSize.y()) *
|
||||||
static_cast<SizeT>(levelTexelSize.z());
|
static_cast<SizeT>(levelTexelSize.z());
|
||||||
@@ -2939,10 +2947,13 @@ namespace MobileGL::MG_Impl::GLImpl {
|
|||||||
auto* textureMipmapObject = static_cast<MG_State::GLState::TextureObjectMipmap*>(textureObject.get());
|
auto* textureMipmapObject = static_cast<MG_State::GLState::TextureObjectMipmap*>(textureObject.get());
|
||||||
|
|
||||||
textureObject->SetInternalFormat(textureInternalFormat);
|
textureObject->SetInternalFormat(textureInternalFormat);
|
||||||
|
// Array targets keep their layer count constant across levels; only true 3D
|
||||||
|
// textures halve depth per level (GL 3.3 §3.9 glTexStorage3D).
|
||||||
|
const Bool depthMips = DepthParticipatesInMipmapping(textureObject->GetTarget());
|
||||||
for (GLsizei level = 0; level < levels; ++level) {
|
for (GLsizei level = 0; level < levels; ++level) {
|
||||||
const GLsizei levelWidth = std::max<GLsizei>(1, width >> level);
|
const GLsizei levelWidth = std::max<GLsizei>(1, width >> level);
|
||||||
const GLsizei levelHeight = std::max<GLsizei>(1, height >> level);
|
const GLsizei levelHeight = std::max<GLsizei>(1, height >> level);
|
||||||
const GLsizei levelDepth = std::max<GLsizei>(1, depth >> level);
|
const GLsizei levelDepth = depthMips ? std::max<GLsizei>(1, depth >> level) : depth;
|
||||||
const SizeT byteSize = ComputeTextureStorageByteSize(textureInternalFormat, levelWidth, levelHeight,
|
const SizeT byteSize = ComputeTextureStorageByteSize(textureInternalFormat, levelWidth, levelHeight,
|
||||||
levelDepth);
|
levelDepth);
|
||||||
textureMipmapObject->AllocateStorage(textureUploadTarget, level,
|
textureMipmapObject->AllocateStorage(textureUploadTarget, level,
|
||||||
|
|||||||
Reference in New Issue
Block a user