summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authorgman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-02 20:17:46 +0000
committergman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-02 20:17:46 +0000
commitd20a6514672aa08c208e9d7b5708e1de33dd9cf7 (patch)
tree099c171cc8a2998f96922fde5a632ede57509937 /gpu
parent15bb050eb0943488ee773de7943854d1c074de2a (diff)
downloadchromium_src-d20a6514672aa08c208e9d7b5708e1de33dd9cf7.zip
chromium_src-d20a6514672aa08c208e9d7b5708e1de33dd9cf7.tar.gz
chromium_src-d20a6514672aa08c208e9d7b5708e1de33dd9cf7.tar.bz2
generate INVALID_VALUE if calling Uniform1i/v on sampler > MAX_IMAGE_TEXTURE_UNITS
TEST=unit tests BUG=125900 Review URL: http://codereview.chromium.org/10314004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@134977 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc12
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc20
-rw-r--r--gpu/command_buffer/service/program_manager.cc12
-rw-r--r--gpu/command_buffer/service/program_manager.h6
4 files changed, 44 insertions, 6 deletions
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 18c799d..e683128 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -4615,7 +4615,11 @@ void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
fake_location, "glUniform1iv", &real_location, &type, &count)) {
return;
}
- current_program_->SetSamplers(fake_location, 1, &v0);
+ if (!current_program_->SetSamplers(
+ group_->max_texture_units(), fake_location, 1, &v0)) {
+ SetGLError(GL_INVALID_VALUE, "glUniform1i: texture unit out of range");
+ return;
+ }
glUniform1i(real_location, v0);
}
@@ -4629,7 +4633,11 @@ void GLES2DecoderImpl::DoUniform1iv(
}
if (type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
type == GL_SAMPLER_EXTERNAL_OES) {
- current_program_->SetSamplers(fake_location, count, value);
+ if (!current_program_->SetSamplers(
+ group_->max_texture_units(), fake_location, count, value)) {
+ SetGLError(GL_INVALID_VALUE, "glUniform1iv: texture unit out of range");
+ return;
+ }
}
glUniform1iv(real_location, count, value);
}
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
index 08bd91c..a1b6613 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
@@ -1863,6 +1863,26 @@ TEST_F(GLES2DecoderWithShaderTest, Uniform1ivZeroCount) {
EXPECT_EQ(GL_NO_ERROR, GetGLError());
}
+TEST_F(GLES2DecoderWithShaderTest, Uniform1iSamplerIsLmited) {
+ EXPECT_CALL(*gl_, Uniform1i(_, _)).Times(0);
+ Uniform1i cmd;
+ cmd.Init(
+ program_manager()->SwizzleLocation(kUniform1FakeLocation),
+ kNumTextureUnits);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+}
+
+TEST_F(GLES2DecoderWithShaderTest, Uniform1ivSamplerIsLimited) {
+ EXPECT_CALL(*gl_, Uniform1iv(_, _, _)).Times(0);
+ Uniform1ivImmediate& cmd = *GetImmediateAs<Uniform1ivImmediate>();
+ GLint temp[] = { kNumTextureUnits };
+ cmd.Init(program_manager()->SwizzleLocation(kUniform1FakeLocation), 1,
+ &temp[0]);
+ EXPECT_EQ(error::kNoError,
+ ExecuteImmediateCmd(cmd, sizeof(temp)));
+ EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+}
TEST_F(GLES2DecoderWithShaderTest, BindBufferToDifferentTargetFails) {
// Bind the buffer to GL_ARRAY_BUFFER
diff --git a/gpu/command_buffer/service/program_manager.cc b/gpu/command_buffer/service/program_manager.cc
index 1669173..05ab6a6 100644
--- a/gpu/command_buffer/service/program_manager.cc
+++ b/gpu/command_buffer/service/program_manager.cc
@@ -446,9 +446,10 @@ const ProgramManager::ProgramInfo::UniformInfo*
}
bool ProgramManager::ProgramInfo::SetSamplers(
- GLint fake_location, GLsizei count, const GLint* value) {
+ GLint num_texture_units, GLint fake_location,
+ GLsizei count, const GLint* value) {
if (fake_location < 0) {
- return false;
+ return true;
}
GLint uniform_index = GetUniformInfoIndexFromFakeLocation(fake_location);
if (uniform_index >= 0 &&
@@ -458,13 +459,18 @@ bool ProgramManager::ProgramInfo::SetSamplers(
if (element_index < info.size) {
count = std::min(info.size - element_index, count);
if (info.IsSampler() && count > 0) {
+ for (GLsizei ii = 0; ii < count; ++ii) {
+ if (value[ii] < 0 || value[ii] >= num_texture_units) {
+ return false;
+ }
+ }
std::copy(value, value + count,
info.texture_units.begin() + element_index);
return true;
}
}
}
- return false;
+ return true;
}
void ProgramManager::ProgramInfo::GetProgramiv(GLenum pname, GLint* params) {
diff --git a/gpu/command_buffer/service/program_manager.h b/gpu/command_buffer/service/program_manager.h
index 43433f8..63471fc 100644
--- a/gpu/command_buffer/service/program_manager.h
+++ b/gpu/command_buffer/service/program_manager.h
@@ -126,7 +126,11 @@ class GPU_EXPORT ProgramManager {
// Sets the sampler values for a uniform.
// This is safe to call for any location. If the location is not
// a sampler uniform nothing will happen.
- bool SetSamplers(GLint fake_location, GLsizei count, const GLint* value);
+ // Returns false if fake_location is a sampler and any value
+ // is >= num_texture_units. Returns true otherwise.
+ bool SetSamplers(
+ GLint num_texture_units, GLint fake_location,
+ GLsizei count, const GLint* value);
bool IsDeleted() const {
return deleted_;