Commit 999b0fd2 by Frank Henigman Committed by Commit Bot

Validate uniform sampler values.

Generate GL_INVALID_VALUE when setting a sampler uniform with a value outside the range [0, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS). Add a test for the new behavior. Remove TextureLimitsTest.DrawWithTexturePastMaximum, which is made obsolete by the new test. BUG=angleproject:1711 Change-Id: I9a4ea13b8cb47742816476689bd3932ce267fd0a Reviewed-on: https://chromium-review.googlesource.com/430196 Commit-Queue: Frank Henigman <fjhenigman@chromium.org> Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent c2522477
...@@ -1417,7 +1417,7 @@ bool ValidateUniformCommonBase(gl::Context *context, ...@@ -1417,7 +1417,7 @@ bool ValidateUniformCommonBase(gl::Context *context,
return true; return true;
} }
bool ValidateUniform1ivValue(gl::Context *context, bool ValidateUniform1ivValue(ValidationContext *context,
GLenum uniformType, GLenum uniformType,
GLsizei count, GLsizei count,
const GLint *value) const GLint *value)
...@@ -1432,7 +1432,16 @@ bool ValidateUniform1ivValue(gl::Context *context, ...@@ -1432,7 +1432,16 @@ bool ValidateUniform1ivValue(gl::Context *context,
if (IsSamplerType(uniformType)) if (IsSamplerType(uniformType))
{ {
// TODO(fjhenigman): check values against GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS // Check that the values are in range.
const GLint max = context->getCaps().maxCombinedTextureImageUnits;
for (GLsizei i = 0; i < count; ++i)
{
if (value[i] < 0 || value[i] >= max)
{
context->handleError(Error(GL_INVALID_VALUE, "sampler uniform value out of range"));
return false;
}
}
return true; return true;
} }
......
...@@ -3218,41 +3218,6 @@ TEST_P(TextureLimitsTest, TextureTypeConflict) ...@@ -3218,41 +3218,6 @@ TEST_P(TextureLimitsTest, TextureTypeConflict)
EXPECT_GL_ERROR(GL_INVALID_OPERATION); EXPECT_GL_ERROR(GL_INVALID_OPERATION);
} }
// Negative test for rendering with texture outside the valid range.
// TODO(jmadill): Possibly adjust the test according to the spec:
// GLES 3.0.4 section 2.12.7 mentions that specifying an out-of-range sampler uniform value
// generates an INVALID_VALUE error - GLES 2.0 doesn't yet have this mention.
TEST_P(TextureLimitsTest, DrawWithTexturePastMaximum)
{
const std::string &vertexShader =
"attribute vec2 position;\n"
"varying float color;\n"
"uniform sampler2D tex2D;\n"
"void main() {\n"
" gl_Position = vec4(position, 0, 1);\n"
" vec2 texCoord = (position * 0.5) + 0.5;\n"
" color = texture2D(tex2D, texCoord).x;\n"
"}";
const std::string &fragmentShader =
"varying mediump float color;\n"
"void main() {\n"
" gl_FragColor = vec4(color, 0, 0, 1);\n"
"}";
mProgram = CompileProgram(vertexShader, fragmentShader);
ASSERT_NE(0u, mProgram);
glUseProgram(mProgram);
GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
ASSERT_NE(-1, tex2DLocation);
glUniform1i(tex2DLocation, mMaxCombinedTextures);
ASSERT_GL_NO_ERROR();
drawQuad(mProgram, "position", 0.5f);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
}
class Texture2DNorm16TestES3 : public Texture2DTestES3 class Texture2DNorm16TestES3 : public Texture2DTestES3
{ {
protected: protected:
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
// //
#include "test_utils/ANGLETest.h" #include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"
#include <array> #include <array>
#include <cmath> #include <cmath>
...@@ -507,6 +508,87 @@ TEST_P(UniformTestES3, OverflowArray) ...@@ -507,6 +508,87 @@ TEST_P(UniformTestES3, OverflowArray)
glUniformMatrix3x2fv(matLocationOffset, kOverflowSize, GL_TRUE, &values[0]); glUniformMatrix3x2fv(matLocationOffset, kOverflowSize, GL_TRUE, &values[0]);
} }
// Check setting a sampler uniform
TEST_P(UniformTest, Sampler)
{
const std::string &vertShader =
"uniform sampler2D tex2D;\n"
"void main() {\n"
" gl_Position = vec4(0, 0, 0, 1);\n"
"}";
const std::string &fragShader =
"precision mediump float;\n"
"uniform sampler2D tex2D;\n"
"void main() {\n"
" gl_FragColor = texture2D(tex2D, vec2(0, 0));\n"
"}";
ANGLE_GL_PROGRAM(program, vertShader, fragShader);
GLint location = glGetUniformLocation(program.get(), "tex2D");
ASSERT_NE(-1, location);
const GLint sampler[] = {0, 0, 0, 0};
// before UseProgram
glUniform1i(location, sampler[0]);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
glUseProgram(program.get());
// Uniform1i
glUniform1i(location, sampler[0]);
glUniform1iv(location, 1, sampler);
EXPECT_GL_NO_ERROR();
// Uniform{234}i
glUniform2i(location, sampler[0], sampler[0]);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
glUniform3i(location, sampler[0], sampler[0], sampler[0]);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
glUniform4i(location, sampler[0], sampler[0], sampler[0], sampler[0]);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
glUniform2iv(location, 1, sampler);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
glUniform3iv(location, 1, sampler);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
glUniform4iv(location, 1, sampler);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
// Uniform{1234}f
const GLfloat f[] = {0, 0, 0, 0};
glUniform1f(location, f[0]);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
glUniform2f(location, f[0], f[0]);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
glUniform3f(location, f[0], f[0], f[0]);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
glUniform4f(location, f[0], f[0], f[0], f[0]);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
glUniform1fv(location, 1, f);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
glUniform2fv(location, 1, f);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
glUniform3fv(location, 1, f);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
glUniform4fv(location, 1, f);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
// < 0 or >= max
GLint tooHigh;
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &tooHigh);
constexpr GLint tooLow[] = {-1};
glUniform1i(location, tooLow[0]);
EXPECT_GL_ERROR(GL_INVALID_VALUE);
glUniform1iv(location, 1, tooLow);
EXPECT_GL_ERROR(GL_INVALID_VALUE);
glUniform1i(location, tooHigh);
EXPECT_GL_ERROR(GL_INVALID_VALUE);
glUniform1iv(location, 1, &tooHigh);
EXPECT_GL_ERROR(GL_INVALID_VALUE);
}
// Check that sampler uniforms only show up one time in the list // Check that sampler uniforms only show up one time in the list
TEST_P(UniformTest, SamplerUniformsAppearOnce) TEST_P(UniformTest, SamplerUniformsAppearOnce)
{ {
......
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