Commit 08528e17 by Austin Kinross Committed by Jamie Madill

glTexSubImage2D should always allow non-power-of-two inputs

If GL_OES_texture_npot isn't active then ANGLE currently prevents calls to glTexSubImage2D with: - level > 0 - width/height NPOT This isn't correct. It is legitimate to supply data to a NPOT subregion of a POT texture via glTexSubImage2D. Fixes these dEQP tests on 9_3: dEQP-GLES2.functional.texture.specification.basic_texsubimage2d.a8_2d dEQP-GLES2.functional.texture.specification.basic_texsubimage2d.a8_cube dEQP-GLES2.functional.texture.specification.basic_texsubimage2d.l8_2d dEQP-GLES2.functional.texture.specification.basic_texsubimage2d.l8_cube dEQP-GLES2.functional.texture.specification.basic_texsubimage2d.la88_2d dEQP-GLES2.functional.texture.specification.basic_texsubimage2d.la88_cube dEQP-GLES2.functional.texture.specification.basic_texsubimage2d.rgb565_2d dEQP-GLES2.functional.texture.specification.basic_texsubimage2d.rgb565_cube dEQP-GLES2.functional.texture.specification.basic_texsubimage2d.rgb888_2d dEQP-GLES2.functional.texture.specification.basic_texsubimage2d.rgb888_cube dEQP-GLES2.functional.texture.specification.basic_texsubimage2d.rgba4444_2d dEQP-GLES2.functional.texture.specification.basic_texsubimage2d.rgba4444_cube dEQP-GLES2.functional.texture.specification.basic_texsubimage2d.rgba5551_2d dEQP-GLES2.functional.texture.specification.basic_texsubimage2d.rgba5551_cube dEQP-GLES2.functional.texture.specification.basic_texsubimage2d.rgba8888_2d dEQP-GLES2.functional.texture.specification.basic_texsubimage2d.rgba8888_cube Change-Id: I5889a27edbfa807995fa20b16f36456f676b80fc Reviewed-on: https://chromium-review.googlesource.com/304612Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarAustin Kinross <aukinros@microsoft.com> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 2f6ddf31
...@@ -243,15 +243,22 @@ bool ValidMipLevel(const Context *context, GLenum target, GLint level) ...@@ -243,15 +243,22 @@ bool ValidMipLevel(const Context *context, GLenum target, GLint level)
return level <= gl::log2(static_cast<int>(maxDimension)); return level <= gl::log2(static_cast<int>(maxDimension));
} }
bool ValidImageSize(const Context *context, GLenum target, GLint level, bool ValidImageSizeParameters(const Context *context,
GLsizei width, GLsizei height, GLsizei depth) GLenum target,
GLint level,
GLsizei width,
GLsizei height,
GLsizei depth,
bool isSubImage)
{ {
if (level < 0 || width < 0 || height < 0 || depth < 0) if (level < 0 || width < 0 || height < 0 || depth < 0)
{ {
return false; return false;
} }
if (!context->getExtensions().textureNPOT && // TexSubImage parameters can be NPOT without textureNPOT extension,
// as long as the destination texture is POT.
if (!isSubImage && !context->getExtensions().textureNPOT &&
(level != 0 && (!gl::isPow2(width) || !gl::isPow2(height) || !gl::isPow2(depth)))) (level != 0 && (!gl::isPow2(width) || !gl::isPow2(height) || !gl::isPow2(depth))))
{ {
return false; return false;
......
...@@ -34,7 +34,13 @@ bool ValidFramebufferTarget(GLenum target); ...@@ -34,7 +34,13 @@ bool ValidFramebufferTarget(GLenum target);
bool ValidBufferTarget(const Context *context, GLenum target); bool ValidBufferTarget(const Context *context, GLenum target);
bool ValidBufferParameter(const Context *context, GLenum pname); bool ValidBufferParameter(const Context *context, GLenum pname);
bool ValidMipLevel(const Context *context, GLenum target, GLint level); bool ValidMipLevel(const Context *context, GLenum target, GLint level);
bool ValidImageSize(const Context *context, GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth); bool ValidImageSizeParameters(const Context *context,
GLenum target,
GLint level,
GLsizei width,
GLsizei height,
GLsizei depth,
bool isSubImage);
bool ValidCompressedImageSize(const Context *context, GLenum internalFormat, GLsizei width, GLsizei height); bool ValidCompressedImageSize(const Context *context, GLenum internalFormat, GLsizei width, GLsizei height);
bool ValidQueryType(const Context *context, GLenum queryType); bool ValidQueryType(const Context *context, GLenum queryType);
......
...@@ -31,7 +31,7 @@ bool ValidateES2TexImageParameters(Context *context, GLenum target, GLint level, ...@@ -31,7 +31,7 @@ bool ValidateES2TexImageParameters(Context *context, GLenum target, GLint level,
return false; return false;
} }
if (!ValidImageSize(context, target, level, width, height, 1)) if (!ValidImageSizeParameters(context, target, level, width, height, 1, isSubImage))
{ {
context->recordError(Error(GL_INVALID_VALUE)); context->recordError(Error(GL_INVALID_VALUE));
return false; return false;
......
...@@ -296,7 +296,7 @@ bool ValidateES3TexImageParameters(Context *context, GLenum target, GLint level, ...@@ -296,7 +296,7 @@ bool ValidateES3TexImageParameters(Context *context, GLenum target, GLint level,
} }
// Validate image size // Validate image size
if (!ValidImageSize(context, target, level, width, height, depth)) if (!ValidImageSizeParameters(context, target, level, width, height, depth, isSubImage))
{ {
context->recordError(Error(GL_INVALID_VALUE)); context->recordError(Error(GL_INVALID_VALUE));
return false; return false;
......
...@@ -668,6 +668,26 @@ TEST_P(TextureTest, TextureNPOT_GL_ALPHA_UBYTE) ...@@ -668,6 +668,26 @@ TEST_P(TextureTest, TextureNPOT_GL_ALPHA_UBYTE)
EXPECT_GL_NO_ERROR(); EXPECT_GL_NO_ERROR();
} }
// Test to ensure that glTexSubImage2D always accepts data for non-power-of-two subregions.
// ANGLE previously rejected this if GL_OES_texture_npot wasn't active, which is incorrect.
TEST_P(TextureTest, NPOTSubImageParameters)
{
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, mTexture2D);
// Create an 8x8 (i.e. power-of-two) texture.
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glGenerateMipmap(GL_TEXTURE_2D);
// Supply a 3x3 (i.e. non-power-of-two) subimage to the texture.
// This should always work, even if GL_OES_texture_npot isn't active.
glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 3, 3, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
EXPECT_GL_NO_ERROR();
}
// In the D3D11 renderer, we need to initialize some texture formats, to fill empty channels. EG RBA->RGBA8, with 1.0 // In the D3D11 renderer, we need to initialize some texture formats, to fill empty channels. EG RBA->RGBA8, with 1.0
// in the alpha channel. This test covers a bug where redefining array textures with these formats does not work as // in the alpha channel. This test covers a bug where redefining array textures with these formats does not work as
// expected. // expected.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment