[Fix] (MG_Impl/GLImpl): validate DSA texture parameters

This commit is contained in:
2026-07-03 09:05:52 +08:00
parent 51d9fa91ed
commit bdf29fc4d5
3 changed files with 81 additions and 7 deletions
+64 -3
View File
@@ -439,10 +439,8 @@ namespace MobileGL::MG_Impl::GLImpl {
} // namespace
const SharedPtr<MG_State::GLState::ITextureObject>& GetTextureObjectByName(GLuint texture, const char* caller) {
if (texture == 0 || !TextureImpl::ValidateTextureName(texture, true)) return nullTextureObject;
auto& textureObject = MG_State::pGLContext->GetTextureObject(texture);
if (!TextureImpl::ValidateTextureObject(textureObject)) {
if (!textureObject) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", caller,
@@ -452,6 +450,67 @@ namespace MobileGL::MG_Impl::GLImpl {
return textureObject;
}
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_BASE_LEVEL || pname == GL_TEXTURE_MAX_LEVEL) && param < 0) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", caller, "Texture level parameter must be non-negative."));
return false;
}
if ((target == TextureTarget::Texture2DMultisample ||
target == TextureTarget::Texture2DMultisampleArray) &&
pname == GL_TEXTURE_BASE_LEVEL && param != 0) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", caller,
"Multisample texture base level must be zero."));
return false;
}
if (target == TextureTarget::TextureRectangle && pname == GL_TEXTURE_BASE_LEVEL && param != 0) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", caller, "Rectangle texture base level must be zero."));
return false;
}
if ((target == TextureTarget::Texture2DMultisample ||
target == TextureTarget::Texture2DMultisampleArray) &&
(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)) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", caller,
"Sampler state is invalid for multisample textures."));
return false;
}
if (target == TextureTarget::TextureRectangle) {
if ((pname == GL_TEXTURE_WRAP_S || pname == GL_TEXTURE_WRAP_T) &&
(param == GL_MIRROR_CLAMP_TO_EDGE || param == GL_MIRRORED_REPEAT || param == GL_REPEAT)) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", caller,
"Invalid wrap mode for rectangle texture."));
return false;
}
if (pname == GL_TEXTURE_MIN_FILTER && param != GL_NEAREST && param != GL_LINEAR) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", caller,
"Invalid min filter for rectangle texture."));
return false;
}
}
return true;
}
TextureUploadTarget GetPrimaryUploadTarget(const SharedPtr<MG_State::GLState::ITextureObject>& textureObject) {
if (!textureObject) return TextureUploadTarget::Unknown;
const auto& uploadTargets = textureObject->GetUploadTargets();
@@ -461,6 +520,7 @@ namespace MobileGL::MG_Impl::GLImpl {
void TextureParameterObject_State(const SharedPtr<MG_State::GLState::ITextureObject>& textureObject, GLenum pname,
GLint param, const char* caller) {
if (!textureObject) return;
if (!ValidateTextureParameterForTarget(textureObject, pname, param, caller)) return;
switch (pname) {
case GL_TEXTURE_MAG_FILTER:
@@ -529,6 +589,7 @@ 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;
switch (pname) {
case GL_TEXTURE_MAG_FILTER:
+16 -3
View File
@@ -7,6 +7,7 @@
// End of Source File Header
#include "Validators.h"
#include <MG_Backend/BackendObjects.h>
#include <MG_State/GLState/Core.h>
#include <MG_State/GLState/ErrorState/Error.h>
#include <MG_Util/Converters/GLToStr/GLEnumConverter.h>
@@ -83,8 +84,20 @@ namespace MobileGL::MG_Impl::GLImpl::TextureImpl {
return false;
}
// TODO: GL_INVALID_VALUE may be generated if level is greater than log2(max), where max is the returned
// value of GL_MAX_TEXTURE_SIZE.
Int maxTextureSize = MG_Backend::DynamicBackendParameters{}.MaxTextureSize;
if (MG_Backend::pActiveBackendObject) {
maxTextureSize = MG_Backend::pActiveBackendObject->GetDynamicParameters().MaxTextureSize;
}
Int maxLevel = 0;
for (Int size = std::max(maxTextureSize, 1); size > 1; size >>= 1) {
++maxLevel;
}
if (level > maxLevel) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue, MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureLevelNumber",
"Texture level exceeds GL_MAX_TEXTURE_SIZE"));
return false;
}
return true;
}
@@ -129,7 +142,7 @@ namespace MobileGL::MG_Impl::GLImpl::TextureImpl {
return true;
}
Bool ValidateTextureSizeRange(SizeT width, SizeT height, SizeT depth) {
Bool ValidateTextureSizeRange(Int width, Int height, Int depth) {
if (width < 0 || height < 0 || depth < 0) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue, MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureSizeRange",
+1 -1
View File
@@ -20,7 +20,7 @@ namespace MobileGL::MG_Impl::GLImpl::TextureImpl {
Bool ValidateTexturePixelDataType(TexturePixelDataType texturePixelDataType);
Bool ValidateTextureLevelNumber(Int level);
Bool ValidateTextureSizeWithTextureUploadTarget(TextureUploadTarget target, GLsizei width, GLsizei height);
Bool ValidateTextureSizeRange(SizeT width, SizeT height, SizeT depth);
Bool ValidateTextureSizeRange(Int width, Int height, Int depth);
Bool ValidateTextureInternalFormat(TextureInternalFormat format);
Bool ValidateTextureBorderNumber(Int border);
Bool ValidateTextureInternalFormatCompatibleWithInput(TextureInputFormat format,