mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-11 05:38:31 +09:00
Merge origin/dev (efd7b473) into readback overhaul - unify DirectGLES 2D-array target support under MapToBackendTextureTarget, keep canonical UNorm8 shadows for RGBA4/RGB565 (supersedes packed-word transfer types; GL_RGB565 aliases RGB5), keep upstream GLSL 330 normalization, anisotropy params, error-count semantics and VK clear/scissor fixes
This commit is contained in:
@@ -441,7 +441,10 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
for (SizeT i = 0; i < static_cast<SizeT>(n); ++i) {
|
||||
Uint bufferName = buffers[i];
|
||||
if (bufferName == 0) continue;
|
||||
if (!BufferImpl::ValidateBufferName(bufferName, true)) continue;
|
||||
// GL 3.3 core 2.9: names that do not correspond to an existing buffer are silently
|
||||
// ignored here, so probe with the non-recording query - the shared validator would
|
||||
// record INVALID_OPERATION, which is only correct on the bind path.
|
||||
if (!MG_State::pGLContext->ValidateBufferName(bufferName)) continue;
|
||||
MG_State::pGLContext->MarkBufferObjectForDeletion(bufferName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1364,7 +1364,9 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
for (SizeT i = 0; i < static_cast<SizeT>(n); ++i) {
|
||||
Uint bufferName = renderbuffers[i];
|
||||
if (bufferName == 0) continue;
|
||||
if (!FramebufferImpl::ValidateRenderbufferName(bufferName)) continue;
|
||||
// GL 3.3 core 4.4.2: unknown names are silently ignored on delete; the shared bind-path
|
||||
// validator would record INVALID_OPERATION instead.
|
||||
if (!MG_State::pGLContext->ValidateRenderbufferName(bufferName)) continue;
|
||||
MG_State::pGLContext->MarkRenderbufferObjectForDeletion(bufferName);
|
||||
}
|
||||
}
|
||||
@@ -1387,7 +1389,9 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
for (SizeT i = 0; i < static_cast<SizeT>(n); ++i) {
|
||||
Uint bufferName = framebuffers[i];
|
||||
if (bufferName == 0) continue;
|
||||
if (!FramebufferImpl::ValidateFramebufferName(bufferName)) continue;
|
||||
// GL 3.3 core 4.4.1: unknown names are silently ignored on delete; the shared bind-path
|
||||
// validator would record INVALID_OPERATION instead.
|
||||
if (!MG_State::pGLContext->ValidateFramebufferName(bufferName)) continue;
|
||||
MG_State::pGLContext->MarkFramebufferObjectForDeletion(bufferName);
|
||||
}
|
||||
}
|
||||
@@ -1877,6 +1881,13 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Packed-type/format pairing (GL CTS packed_pixels: e.g. GL_RED with GL_UNSIGNED_SHORT_5_6_5 must
|
||||
// raise an error instead of reaching the backend). Shared with the TexImage/GetTexImage validators;
|
||||
// runs after the depth-stencil branch above so DEPTH_STENCIL with a wrong type keeps GL_INVALID_ENUM.
|
||||
if (!TextureImpl::ValidateClientFormatTypePairing(textureInputFormat, texturePixelDataType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check PBO state
|
||||
const auto& pixelPackBufferObject =
|
||||
MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject();
|
||||
|
||||
@@ -649,7 +649,9 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
}
|
||||
|
||||
void ClearDepth_State(GLclampd depth) {
|
||||
MG_State::pGLContext->SetClearDepth(static_cast<Float>(depth));
|
||||
// GL 3.3 §4.2.3: the clear depth is clamped to [0,1] at specification time (Vulkan clear
|
||||
// values additionally require it: VUID-VkClearDepthStencilValue-depth-00022).
|
||||
MG_State::pGLContext->SetClearDepth(ClampUnitFloat(static_cast<Float>(depth)));
|
||||
}
|
||||
|
||||
void ClearColor_State(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
|
||||
|
||||
@@ -14,7 +14,13 @@
|
||||
|
||||
namespace MobileGL::MG_Impl::GLImpl {
|
||||
namespace {
|
||||
Bool ValidateSamplerParameterValue(GLenum pname, const void* param, Bool isFloat, Bool isInteger) {
|
||||
Float ReadSamplerScalar(const void* param, Bool isFloat, Bool isUnsignedInteger) {
|
||||
if (isFloat) return *(const GLfloat*)param;
|
||||
if (isUnsignedInteger) return static_cast<Float>(*(const GLuint*)param);
|
||||
return static_cast<Float>(*(const GLint*)param);
|
||||
}
|
||||
|
||||
Bool ValidateSamplerParameterValue(GLenum pname, const void* param, Bool isFloat, Bool isUnsignedInteger) {
|
||||
if (param == nullptr) return false;
|
||||
|
||||
switch (pname) {
|
||||
@@ -22,6 +28,13 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
case GL_TEXTURE_MAX_LOD:
|
||||
case GL_TEXTURE_LOD_BIAS:
|
||||
return true;
|
||||
case GL_TEXTURE_MAX_ANISOTROPY_EXT:
|
||||
if (ReadSamplerScalar(param, isFloat, isUnsignedInteger) >= 1.0f) return true;
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidValue,
|
||||
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "SetSamplerParam_State",
|
||||
"GL_TEXTURE_MAX_ANISOTROPY_EXT must be at least 1.0."));
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -29,14 +42,15 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
if (isFloat) {
|
||||
return SamplerImpl::ValidateSamplerFloatParam(pname, *(const GLfloat*)param);
|
||||
}
|
||||
if (isInteger) {
|
||||
if (isUnsignedInteger) {
|
||||
return SamplerImpl::ValidateSamplerIntParam(pname, static_cast<GLint>(*(const GLuint*)param));
|
||||
}
|
||||
return SamplerImpl::ValidateSamplerIntParam(pname, *(const GLint*)param);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void SetSamplerParam_State(GLuint sampler, GLenum pname, const void* param, bool isFloat, bool isInteger) {
|
||||
void SetSamplerParam_State(GLuint sampler, GLenum pname, const void* param, bool isFloat,
|
||||
bool isUnsignedInteger) {
|
||||
if (param == nullptr) return;
|
||||
if (!SamplerImpl::ValidateSamplerName(sampler)) return;
|
||||
|
||||
@@ -47,7 +61,7 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
}
|
||||
auto& samplerObj = MG_State::pGLContext->GetSamplerObject(sampler);
|
||||
if (!SamplerImpl::ValidateSamplerObject(sampler)) return;
|
||||
if (!ValidateSamplerParameterValue(pname, param, isFloat, isInteger)) return;
|
||||
if (!ValidateSamplerParameterValue(pname, param, isFloat, isUnsignedInteger)) return;
|
||||
|
||||
using namespace MG_Util;
|
||||
switch (pname) {
|
||||
@@ -76,6 +90,9 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
case GL_TEXTURE_LOD_BIAS:
|
||||
samplerObj->SetLodBias(*(const GLfloat*)param);
|
||||
break;
|
||||
case GL_TEXTURE_MAX_ANISOTROPY_EXT:
|
||||
samplerObj->SetMaxAnisotropy(ReadSamplerScalar(param, isFloat, isUnsignedInteger));
|
||||
break;
|
||||
case GL_TEXTURE_COMPARE_MODE:
|
||||
samplerObj->SetCompareMode(MG_Util::ConvertGLEnumToSamplerCompareMode(*(const GLint*)param));
|
||||
break;
|
||||
@@ -89,7 +106,8 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
}
|
||||
}
|
||||
|
||||
void GetSamplerParam_State(GLuint sampler, GLenum pname, void* params, bool isFloat, bool isInteger) {
|
||||
void GetSamplerParam_State(GLuint sampler, GLenum pname, void* params, bool isFloat,
|
||||
bool isUnsignedInteger) {
|
||||
if (params == nullptr) return;
|
||||
if (!SamplerImpl::ValidateSamplerName(sampler)) return;
|
||||
|
||||
@@ -129,6 +147,15 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
case GL_TEXTURE_LOD_BIAS:
|
||||
*(GLfloat*)params = samplerObj->GetLodBias();
|
||||
break;
|
||||
case GL_TEXTURE_MAX_ANISOTROPY_EXT:
|
||||
if (isFloat) {
|
||||
*(GLfloat*)params = samplerObj->GetMaxAnisotropy();
|
||||
} else if (isUnsignedInteger) {
|
||||
*(GLuint*)params = static_cast<GLuint>(samplerObj->GetMaxAnisotropy());
|
||||
} else {
|
||||
*(GLint*)params = static_cast<GLint>(samplerObj->GetMaxAnisotropy());
|
||||
}
|
||||
break;
|
||||
case GL_TEXTURE_COMPARE_MODE:
|
||||
*(GLuint*)params = MG_Util::ConvertSamplerCompareModeToGLEnum(samplerObj->GetCompareMode());
|
||||
break;
|
||||
@@ -206,7 +233,16 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
if (sampler == 0) {
|
||||
textureUnit.SetSamplerObject(nullptr);
|
||||
} else {
|
||||
if (!SamplerImpl::ValidateSamplerName(sampler)) return;
|
||||
// GL 3.3 core 3.8.2: BindSampler on a name GenSamplers never returned - or one already
|
||||
// deleted - is INVALID_OPERATION. SamplerParameter* raises INVALID_VALUE for the same
|
||||
// name, which is why this cannot go through the shared SamplerImpl validator.
|
||||
if (!MG_State::pGLContext->ValidateSamplerName(sampler)) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidOperation,
|
||||
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "BindSampler_State",
|
||||
std::format("Invalid sampler name {}", sampler)));
|
||||
return;
|
||||
}
|
||||
Bool doesSamplerObjectCreated = MG_State::pGLContext->ValidateSamplerObject(sampler);
|
||||
if (!doesSamplerObjectCreated) {
|
||||
MG_State::pGLContext->CreateSamplerObject(sampler);
|
||||
@@ -240,7 +276,7 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
}
|
||||
|
||||
void SamplerParameterIiv(GLuint sampler, GLenum pname, const GLint* param) {
|
||||
SetSamplerParam_State(sampler, pname, param, false, true);
|
||||
SetSamplerParam_State(sampler, pname, param, false, false);
|
||||
}
|
||||
|
||||
void SamplerParameteriv(GLuint sampler, GLenum pname, const GLint* param) {
|
||||
@@ -268,7 +304,7 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
}
|
||||
|
||||
void GetSamplerParameterIiv(GLuint sampler, GLenum pname, GLint* params) {
|
||||
GetSamplerParam_State(sampler, pname, params, false, true);
|
||||
GetSamplerParam_State(sampler, pname, params, false, false);
|
||||
}
|
||||
|
||||
void GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params) {
|
||||
|
||||
@@ -99,6 +99,16 @@ namespace MobileGL::MG_Impl::GLImpl::SamplerImpl {
|
||||
case GL_TEXTURE_LOD_BIAS:
|
||||
return true;
|
||||
|
||||
case GL_TEXTURE_MAX_ANISOTROPY_EXT:
|
||||
if (!(param >= 1.0f)) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidValue,
|
||||
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateSamplerFloatParam",
|
||||
"GL_TEXTURE_MAX_ANISOTROPY_EXT must be at least 1.0."));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
case GL_TEXTURE_BORDER_COLOR:
|
||||
if (param < 0.0f || param > 1.0f) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
@@ -125,6 +135,16 @@ namespace MobileGL::MG_Impl::GLImpl::SamplerImpl {
|
||||
}
|
||||
return true;
|
||||
|
||||
case GL_TEXTURE_MAX_ANISOTROPY_EXT:
|
||||
if (param < 1) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidValue,
|
||||
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateSamplerIntParam",
|
||||
"GL_TEXTURE_MAX_ANISOTROPY_EXT must be at least 1."));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
default:
|
||||
return ValidateSamplerParam(pname, static_cast<GLenum>(param));
|
||||
}
|
||||
|
||||
@@ -74,6 +74,16 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
return true;
|
||||
}
|
||||
|
||||
Bool ValidateMaxAnisotropy(Float maxAnisotropy, const char* caller) {
|
||||
if (maxAnisotropy >= 1.0f) return true;
|
||||
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidValue,
|
||||
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", caller,
|
||||
"GL_TEXTURE_MAX_ANISOTROPY_EXT must be at least 1.0."));
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Fn>
|
||||
void WithTemporarilyBoundNamedTexture(const SharedPtr<MG_State::GLState::ITextureObject>& textureObject,
|
||||
Fn&& fn) {
|
||||
@@ -284,10 +294,16 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
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>(
|
||||
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;
|
||||
while (maxDimension > 1) {
|
||||
maxDimension = std::max<Int>(maxDimension / 2, 1);
|
||||
@@ -296,11 +312,12 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
return mipLevelCount;
|
||||
}
|
||||
|
||||
IntVec3 ComputeMipmapTexelSize(const IntVec3& baseTexelSize, Uint relativeLevel) {
|
||||
IntVec3 ComputeMipmapTexelSize(const IntVec3& baseTexelSize, Uint relativeLevel, Bool depthMips) {
|
||||
return {
|
||||
std::max<Int>(baseTexelSize.x() >> 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 +340,10 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
}
|
||||
|
||||
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) {
|
||||
const IntVec3 levelTexelSize = ComputeMipmapTexelSize(baseTexelSize, level);
|
||||
const IntVec3 levelTexelSize = ComputeMipmapTexelSize(baseTexelSize, level, depthMips);
|
||||
const SizeT levelByteSize = bytesPerTexel * static_cast<SizeT>(levelTexelSize.x()) *
|
||||
static_cast<SizeT>(levelTexelSize.y()) *
|
||||
static_cast<SizeT>(levelTexelSize.z());
|
||||
@@ -453,6 +471,9 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
Bool ValidateTextureParameterForTarget(const SharedPtr<MG_State::GLState::ITextureObject>& textureObject,
|
||||
GLenum pname, GLint param, const char* caller) {
|
||||
const auto target = textureObject->GetTarget();
|
||||
if (pname == GL_TEXTURE_MAX_ANISOTROPY_EXT && !ValidateMaxAnisotropy(param, caller)) {
|
||||
return false;
|
||||
}
|
||||
if ((pname == GL_TEXTURE_BASE_LEVEL || pname == GL_TEXTURE_MAX_LEVEL) && param < 0) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidValue,
|
||||
@@ -482,7 +503,8 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
(pname == GL_TEXTURE_WRAP_S || pname == GL_TEXTURE_WRAP_T || pname == GL_TEXTURE_WRAP_R ||
|
||||
pname == GL_TEXTURE_MIN_FILTER || pname == GL_TEXTURE_MAG_FILTER || pname == GL_TEXTURE_MIN_LOD ||
|
||||
pname == GL_TEXTURE_MAX_LOD || pname == GL_TEXTURE_LOD_BIAS || pname == GL_TEXTURE_COMPARE_MODE ||
|
||||
pname == GL_TEXTURE_COMPARE_FUNC || pname == GL_TEXTURE_BORDER_COLOR)) {
|
||||
pname == GL_TEXTURE_COMPARE_FUNC || pname == GL_TEXTURE_BORDER_COLOR ||
|
||||
pname == GL_TEXTURE_MAX_ANISOTROPY_EXT)) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidOperation,
|
||||
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", caller,
|
||||
@@ -581,6 +603,9 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
case GL_TEXTURE_LOD_BIAS:
|
||||
textureObject->GetSamplerObject()->SetLodBias((GLfloat)param);
|
||||
break;
|
||||
case GL_TEXTURE_MAX_ANISOTROPY_EXT:
|
||||
textureObject->GetSamplerObject()->SetMaxAnisotropy(static_cast<GLfloat>(param));
|
||||
break;
|
||||
case GL_GENERATE_MIPMAP:
|
||||
g_autoGenerateMipmapByTextureId[textureObject->GetExternalIndex()] = (param != GL_FALSE);
|
||||
break;
|
||||
@@ -597,7 +622,10 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
void TextureParameterObjectf_State(const SharedPtr<MG_State::GLState::ITextureObject>& textureObject, GLenum pname,
|
||||
GLfloat param, const char* caller) {
|
||||
if (!textureObject) return;
|
||||
if (!ValidateTextureParameterForTarget(textureObject, pname, static_cast<GLint>(param), caller)) return;
|
||||
if (pname == GL_TEXTURE_MAX_ANISOTROPY_EXT && !ValidateMaxAnisotropy(param, caller)) return;
|
||||
const GLint validationParam =
|
||||
pname == GL_TEXTURE_MAX_ANISOTROPY_EXT ? 1 : static_cast<GLint>(param);
|
||||
if (!ValidateTextureParameterForTarget(textureObject, pname, validationParam, caller)) return;
|
||||
|
||||
switch (pname) {
|
||||
case GL_TEXTURE_MAG_FILTER:
|
||||
@@ -643,6 +671,9 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
case GL_TEXTURE_LOD_BIAS:
|
||||
textureObject->GetSamplerObject()->SetLodBias(param);
|
||||
break;
|
||||
case GL_TEXTURE_MAX_ANISOTROPY_EXT:
|
||||
textureObject->GetSamplerObject()->SetMaxAnisotropy(param);
|
||||
break;
|
||||
case GL_GENERATE_MIPMAP:
|
||||
g_autoGenerateMipmapByTextureId[textureObject->GetExternalIndex()] = (param != 0.0f);
|
||||
break;
|
||||
@@ -712,6 +743,9 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
*params = (GLint)MG_Util::ConvertSamplerCompareFuncToGLEnum(
|
||||
textureObject->GetSamplerObject()->GetSamplerCompareFunc());
|
||||
break;
|
||||
case GL_TEXTURE_MAX_ANISOTROPY_EXT:
|
||||
*params = static_cast<GLint>(textureObject->GetSamplerObject()->GetMaxAnisotropy());
|
||||
break;
|
||||
default:
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidEnum,
|
||||
@@ -898,11 +932,11 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
auto& activeUnit = MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit());
|
||||
auto& bindingSlot = activeUnit.GetBindingSlot(textureTarget);
|
||||
auto& textureObject = bindingSlot.GetBoundObject();
|
||||
if (!TextureImpl::ValidateTextureObject(textureObject)) return;
|
||||
TextureInternalFormat textureInternalFormat = textureObject->GetFormat();
|
||||
MGLOG_D("%s: working on texture %d", __func__, textureObject->GetExternalIndex());
|
||||
|
||||
// ===================== Error Checking ==============================
|
||||
if (!TextureImpl::ValidateTextureObject(textureObject)) return;
|
||||
if (!TextureImpl::ValidateTextureSubImageOffsets(textureObject, xoffset, width, yoffset, height)) return;
|
||||
if (!TextureImpl::ValidateTextureInternalFormatCompatibleWithInput(textureInputFormat, textureInternalFormat,
|
||||
texturePixelDataType))
|
||||
@@ -1122,6 +1156,10 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
case GL_TEXTURE_LOD_BIAS:
|
||||
textureObject->GetSamplerObject()->SetLodBias(param);
|
||||
break;
|
||||
case GL_TEXTURE_MAX_ANISOTROPY_EXT:
|
||||
if (!ValidateMaxAnisotropy(param, __func__)) return;
|
||||
textureObject->GetSamplerObject()->SetMaxAnisotropy(param);
|
||||
break;
|
||||
case GL_GENERATE_MIPMAP:
|
||||
g_autoGenerateMipmapByTextureId[textureObject->GetExternalIndex()] = (param != 0.0f);
|
||||
break;
|
||||
@@ -1762,7 +1800,9 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
|
||||
GLboolean IsTexture_State(GLuint texture) {
|
||||
// ======================= Processing ================================
|
||||
if (!TextureImpl::ValidateTextureName(texture, true)) return GL_FALSE;
|
||||
// GL 3.3 core 6.1.4: IsTexture generates no error - an unknown, deleted or merely reserved
|
||||
// name is just GL_FALSE. Probing with the recording validator (as every other Is* entry
|
||||
// point already avoids doing) would leave a spurious INVALID_VALUE behind.
|
||||
return MG_State::pGLContext->ValidateTextureObject(texture) ? GL_TRUE : GL_FALSE;
|
||||
}
|
||||
|
||||
@@ -1951,6 +1991,11 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
textureObject->GetSamplerObject()->GetSamplerCompareFunc());
|
||||
}
|
||||
break;
|
||||
case GL_TEXTURE_MAX_ANISOTROPY_EXT:
|
||||
if (params) {
|
||||
*params = static_cast<GLint>(textureObject->GetSamplerObject()->GetMaxAnisotropy());
|
||||
}
|
||||
break;
|
||||
case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE:
|
||||
if (params) {
|
||||
*params = GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE;
|
||||
@@ -2097,6 +2142,11 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
textureObject->GetSamplerObject()->GetSamplerCompareFunc());
|
||||
}
|
||||
break;
|
||||
case GL_TEXTURE_MAX_ANISOTROPY_EXT:
|
||||
if (params) {
|
||||
*params = textureObject->GetSamplerObject()->GetMaxAnisotropy();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
MG_State::pGLContext->RecordError(ErrorCode::InvalidEnum,
|
||||
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "GetTexParameterfv_State",
|
||||
@@ -2368,7 +2418,7 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
for (SizeT i = 0; i < static_cast<SizeT>(n); ++i) {
|
||||
Uint textureName = textures[i];
|
||||
if (textureName == 0) continue;
|
||||
if (!TextureImpl::ValidateTextureName(textureName, true)) continue;
|
||||
if (!MG_State::pGLContext->ValidateTextureName(textureName)) continue;
|
||||
MG_State::pGLContext->MarkTextureObjectForDeletion(textureName);
|
||||
}
|
||||
}
|
||||
@@ -2591,6 +2641,9 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
return;
|
||||
}
|
||||
|
||||
// GL 3.3 core 3.8.1: a name that GenTextures never returned - or that has since been deleted -
|
||||
// is not a legal bind target in the core profile (no application-generated names), and the error
|
||||
// is INVALID_OPERATION, not INVALID_VALUE.
|
||||
if (!MG_State::pGLContext->ValidateTextureName(texture)) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidOperation,
|
||||
@@ -2598,8 +2651,6 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TextureImpl::ValidateTextureName(texture, true)) return;
|
||||
|
||||
// ======================= Processing ================================
|
||||
Bool doesTextureExist = MG_State::pGLContext->ValidateTextureObject(texture);
|
||||
if (!doesTextureExist) {
|
||||
@@ -2994,10 +3045,13 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
auto* textureMipmapObject = static_cast<MG_State::GLState::TextureObjectMipmap*>(textureObject.get());
|
||||
|
||||
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) {
|
||||
const GLsizei levelWidth = std::max<GLsizei>(1, width >> 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,
|
||||
levelDepth);
|
||||
textureMipmapObject->AllocateStorage(textureUploadTarget, level,
|
||||
|
||||
@@ -283,7 +283,9 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
GLuint vao = arrays[i];
|
||||
if (vao == 0) continue;
|
||||
|
||||
if (!VertexArrayImpl::ValidateVertexArrayName(vao)) continue;
|
||||
// GL 3.3 core 2.10: unknown names are silently ignored on delete; the shared bind-path
|
||||
// validator would record INVALID_OPERATION instead.
|
||||
if (!MG_State::pGLContext->ValidateVertexArrayName(vao)) continue;
|
||||
|
||||
if (MG_State::pGLContext->GetBoundVertexArray() &&
|
||||
MG_State::pGLContext->GetBoundVertexArray() == MG_State::pGLContext->GetVertexArrayObject(vao)) {
|
||||
|
||||
Reference in New Issue
Block a user