mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-12 06:08:30 +09:00
[Fix] (MG_Impl/GLImpl): validate DSA texture parameters
This commit is contained in:
@@ -439,10 +439,8 @@ namespace MobileGL::MG_Impl::GLImpl {
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
const SharedPtr<MG_State::GLState::ITextureObject>& GetTextureObjectByName(GLuint texture, const char* caller) {
|
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);
|
auto& textureObject = MG_State::pGLContext->GetTextureObject(texture);
|
||||||
if (!TextureImpl::ValidateTextureObject(textureObject)) {
|
if (!textureObject) {
|
||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
ErrorCode::InvalidOperation,
|
ErrorCode::InvalidOperation,
|
||||||
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", caller,
|
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", caller,
|
||||||
@@ -452,6 +450,67 @@ namespace MobileGL::MG_Impl::GLImpl {
|
|||||||
return textureObject;
|
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) {
|
TextureUploadTarget GetPrimaryUploadTarget(const SharedPtr<MG_State::GLState::ITextureObject>& textureObject) {
|
||||||
if (!textureObject) return TextureUploadTarget::Unknown;
|
if (!textureObject) return TextureUploadTarget::Unknown;
|
||||||
const auto& uploadTargets = textureObject->GetUploadTargets();
|
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,
|
void TextureParameterObject_State(const SharedPtr<MG_State::GLState::ITextureObject>& textureObject, GLenum pname,
|
||||||
GLint param, const char* caller) {
|
GLint param, const char* caller) {
|
||||||
if (!textureObject) return;
|
if (!textureObject) return;
|
||||||
|
if (!ValidateTextureParameterForTarget(textureObject, pname, param, caller)) return;
|
||||||
|
|
||||||
switch (pname) {
|
switch (pname) {
|
||||||
case GL_TEXTURE_MAG_FILTER:
|
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,
|
void TextureParameterObjectf_State(const SharedPtr<MG_State::GLState::ITextureObject>& textureObject, GLenum pname,
|
||||||
GLfloat param, const char* caller) {
|
GLfloat param, const char* caller) {
|
||||||
if (!textureObject) return;
|
if (!textureObject) return;
|
||||||
|
if (!ValidateTextureParameterForTarget(textureObject, pname, static_cast<GLint>(param), caller)) return;
|
||||||
|
|
||||||
switch (pname) {
|
switch (pname) {
|
||||||
case GL_TEXTURE_MAG_FILTER:
|
case GL_TEXTURE_MAG_FILTER:
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
// End of Source File Header
|
// End of Source File Header
|
||||||
|
|
||||||
#include "Validators.h"
|
#include "Validators.h"
|
||||||
|
#include <MG_Backend/BackendObjects.h>
|
||||||
#include <MG_State/GLState/Core.h>
|
#include <MG_State/GLState/Core.h>
|
||||||
#include <MG_State/GLState/ErrorState/Error.h>
|
#include <MG_State/GLState/ErrorState/Error.h>
|
||||||
#include <MG_Util/Converters/GLToStr/GLEnumConverter.h>
|
#include <MG_Util/Converters/GLToStr/GLEnumConverter.h>
|
||||||
@@ -83,8 +84,20 @@ namespace MobileGL::MG_Impl::GLImpl::TextureImpl {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: GL_INVALID_VALUE may be generated if level is greater than log2(max), where max is the returned
|
Int maxTextureSize = MG_Backend::DynamicBackendParameters{}.MaxTextureSize;
|
||||||
// value of GL_MAX_TEXTURE_SIZE.
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -129,7 +142,7 @@ namespace MobileGL::MG_Impl::GLImpl::TextureImpl {
|
|||||||
return true;
|
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) {
|
if (width < 0 || height < 0 || depth < 0) {
|
||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
ErrorCode::InvalidValue, MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureSizeRange",
|
ErrorCode::InvalidValue, MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureSizeRange",
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace MobileGL::MG_Impl::GLImpl::TextureImpl {
|
|||||||
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, SizeT depth);
|
Bool ValidateTextureSizeRange(Int width, Int height, Int depth);
|
||||||
Bool ValidateTextureInternalFormat(TextureInternalFormat format);
|
Bool ValidateTextureInternalFormat(TextureInternalFormat format);
|
||||||
Bool ValidateTextureBorderNumber(Int border);
|
Bool ValidateTextureBorderNumber(Int border);
|
||||||
Bool ValidateTextureInternalFormatCompatibleWithInput(TextureInputFormat format,
|
Bool ValidateTextureInternalFormatCompatibleWithInput(TextureInputFormat format,
|
||||||
|
|||||||
Reference in New Issue
Block a user