Update TexImage2D Parameter Checking
Update the parameter checking performed within ValidateTexImage2D() to
pass the following tests:
dEQP-GLES2.functional.negative_api.texture.teximage2d_invalid_format
dEQP-GLES2.functional.negative_api.texture.teximage2d_invalid_internalformat
dEQP-GLES2.functional.negative_api.texture.texsubimage2d_invalid_type
Bug: angleproject:3250
Bug: angleproject:3251
Test: angle_deqp_gles2_tests --use-angle=vulkan
Change-Id: I4d9be4fe0a9b377e61e3132db262750e6285464b
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1534519
Commit-Queue: Tim Van Patten <timvp@google.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
diff --git a/src/libANGLE/validationES2.cpp b/src/libANGLE/validationES2.cpp
index 4455d8b..82c8347 100644
--- a/src/libANGLE/validationES2.cpp
+++ b/src/libANGLE/validationES2.cpp
@@ -1155,21 +1155,6 @@
return false;
}
- // From GL_CHROMIUM_color_buffer_float_rgb[a]:
- // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
- // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
- // internalformat parameter and format parameter of TexImage2D must match is lifted for this
- // case.
- bool nonEqualFormatsAllowed =
- (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
- (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
-
- if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
- {
- context->validationError(GL_INVALID_OPERATION, kInvalidFormatCombination);
- return false;
- }
-
const gl::Caps &caps = context->getCaps();
switch (texType)
@@ -1225,48 +1210,6 @@
return false;
}
- if (isSubImage)
- {
- const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
- if (textureInternalFormat.internalFormat == GL_NONE)
- {
- context->validationError(GL_INVALID_OPERATION, kInvalidTextureLevel);
- return false;
- }
-
- if (format != GL_NONE)
- {
- if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
- textureInternalFormat.sizedInternalFormat)
- {
- context->validationError(GL_INVALID_OPERATION, kTypeMismatch);
- return false;
- }
- }
-
- if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
- static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
- {
- context->validationError(GL_INVALID_VALUE, kOffsetOverflow);
- return false;
- }
-
- if (width > 0 && height > 0 && pixels == nullptr &&
- context->getState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
- {
- context->validationError(GL_INVALID_VALUE, kPixelDataNull);
- return false;
- }
- }
- else
- {
- if (texture->getImmutableFormat())
- {
- context->validationError(GL_INVALID_OPERATION, kTextureIsImmutable);
- return false;
- }
- }
-
// Verify zero border
if (border != 0)
{
@@ -1274,6 +1217,8 @@
return false;
}
+ bool nonEqualFormatsAllowed = false;
+
if (isCompressed)
{
GLenum actualInternalFormat =
@@ -1583,12 +1528,23 @@
{
switch (internalformat)
{
+ // Core ES 2.0 formats
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ case GL_RGB:
+ case GL_RGBA:
+ break;
+
case GL_RGBA32F:
if (!context->getExtensions().colorBufferFloatRGBA)
{
context->validationError(GL_INVALID_ENUM, kInvalidFormat);
return false;
}
+
+ nonEqualFormatsAllowed = true;
+
if (type != GL_FLOAT)
{
context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
@@ -1607,6 +1563,9 @@
context->validationError(GL_INVALID_ENUM, kInvalidFormat);
return false;
}
+
+ nonEqualFormatsAllowed = true;
+
if (type != GL_FLOAT)
{
context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
@@ -1619,8 +1578,44 @@
}
break;
- default:
+ case GL_BGRA_EXT:
+ if (!context->getExtensions().textureFormatBGRA8888)
+ {
+ context->validationError(GL_INVALID_ENUM, kInvalidFormat);
+ return false;
+ }
break;
+
+ case GL_DEPTH_COMPONENT:
+ case GL_DEPTH_STENCIL:
+ if (!context->getExtensions().depthTextures)
+ {
+ context->validationError(GL_INVALID_ENUM, kInvalidFormat);
+ return false;
+ }
+ break;
+
+ case GL_RED:
+ case GL_RG:
+ if (!context->getExtensions().textureRG)
+ {
+ context->validationError(GL_INVALID_ENUM, kInvalidFormat);
+ return false;
+ }
+ break;
+
+ case GL_SRGB_EXT:
+ case GL_SRGB_ALPHA_EXT:
+ if (!context->getExtensions().sRGB)
+ {
+ context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
+ return false;
+ }
+ break;
+
+ default:
+ context->validationError(GL_INVALID_VALUE, kInvalidInternalFormat);
+ return false;
}
}
@@ -1642,14 +1637,62 @@
}
}
- GLenum sizeCheckFormat = isSubImage ? format : internalformat;
- if (!ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
- imageSize))
+ if (isSubImage)
{
+ const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
+ if (textureInternalFormat.internalFormat == GL_NONE)
+ {
+ context->validationError(GL_INVALID_OPERATION, kInvalidTextureLevel);
+ return false;
+ }
+
+ if (format != GL_NONE)
+ {
+ if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
+ textureInternalFormat.sizedInternalFormat)
+ {
+ context->validationError(GL_INVALID_OPERATION, kTypeMismatch);
+ return false;
+ }
+ }
+
+ if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
+ static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
+ {
+ context->validationError(GL_INVALID_VALUE, kOffsetOverflow);
+ return false;
+ }
+
+ if (width > 0 && height > 0 && pixels == nullptr &&
+ context->getState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
+ {
+ context->validationError(GL_INVALID_VALUE, kPixelDataNull);
+ return false;
+ }
+ }
+ else
+ {
+ if (texture->getImmutableFormat())
+ {
+ context->validationError(GL_INVALID_OPERATION, kTextureIsImmutable);
+ return false;
+ }
+ }
+
+ // From GL_CHROMIUM_color_buffer_float_rgb[a]:
+ // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
+ // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
+ // internalformat parameter and format parameter of TexImage2D must match is lifted for this
+ // case.
+ if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
+ {
+ context->validationError(GL_INVALID_OPERATION, kInvalidFormatCombination);
return false;
}
- return true;
+ GLenum sizeCheckFormat = isSubImage ? format : internalformat;
+ return ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
+ imageSize);
}
bool ValidateES2TexStorageParameters(Context *context,