[Fix] (MG_Impl/Texture): support anisotropic sampler parameters

This commit is contained in:
2026-07-16 21:39:38 -04:00
parent 346cd417ca
commit 5d6b544021
11 changed files with 284 additions and 13 deletions
+34 -7
View File
@@ -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;
@@ -240,7 +267,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 +295,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));
}
+42 -2
View File
@@ -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) {
@@ -466,6 +476,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,
@@ -495,7 +508,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,
@@ -586,6 +600,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;
@@ -602,7 +619,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:
@@ -648,6 +668,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;
@@ -717,6 +740,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,
@@ -1105,6 +1131,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;
@@ -1912,6 +1942,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;
@@ -2058,6 +2093,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",