Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(198)

Unified Diff: gpu/command_buffer/service/gles2_cmd_decoder.cc

Issue 2165873002: Validate UniformBlocks being backed by sufficient data (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix a bug Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: gpu/command_buffer/service/gles2_cmd_decoder.cc
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index fbc923f2dd80355732042450e7138640512206c5..c6ee2b886bb338416d22af49fad3ff53d92090ba 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -1374,6 +1374,12 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient {
// NONE through DrawBuffers, to be on the safe side. Return true.
bool ValidateAndAdjustDrawBuffers(const char* function_name);
+ // Checks if all active uniform blocks in the current program are backed by
+ // a buffer of sufficient size.
+ // If not, generates an INVALID_OPERATION to avoid undefined behavior in
+ // shader execution and return false.
+ bool ValidateUniformBlockBackings(const char* function_name);
+
// Checks if |api_type| is valid for the given uniform
// If the api type is not valid generates the appropriate GL
// error. Returns true if |api_type| is valid for the uniform
@@ -8069,6 +8075,29 @@ bool GLES2DecoderImpl::ValidateAndAdjustDrawBuffers(const char* func_name) {
return true;
}
+bool GLES2DecoderImpl::ValidateUniformBlockBackings(const char* func_name) {
+ switch (feature_info_->context_type()) {
+ case CONTEXT_TYPE_OPENGLES2:
+ case CONTEXT_TYPE_WEBGL1:
+ // Uniform blocks do not exist in ES2 contexts.
+ return true;
+ default:
+ break;
+ }
+ DCHECK(state_.current_program.get());
+ for (auto info : state_.current_program->uniform_block_size_info()) {
+ uint32_t buffer_size = static_cast<uint32_t>(
+ state_.indexed_uniform_buffer_bindings->GetEffectiveBufferSize(
+ info.binding));
+ if (info.data_size > buffer_size) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
+ "uniform blocks are not backed by a buffer with sufficient data");
+ return false;
+ }
+ }
+ return true;
+}
+
bool GLES2DecoderImpl::CheckUniformForApiType(
const Program::UniformInfo* info,
const char* function_name,
@@ -9099,6 +9128,9 @@ error::Error GLES2DecoderImpl::DoDrawArrays(
if (!ValidateAndAdjustDrawBuffers(function_name)) {
return error::kNoError;
}
+ if (!ValidateUniformBlockBackings(function_name)) {
+ return error::kNoError;
+ }
if (!instanced) {
glDrawArrays(mode, first, count);
} else {
@@ -9243,6 +9275,9 @@ error::Error GLES2DecoderImpl::DoDrawElements(const char* function_name,
if (!ValidateAndAdjustDrawBuffers(function_name)) {
return error::kNoError;
}
+ if (!ValidateUniformBlockBackings(function_name)) {
+ return error::kNoError;
+ }
if (state_.enable_flags.primitive_restart_fixed_index &&
feature_info_->feature_flags().
emulate_primitive_restart_fixed_index) {
@@ -15912,6 +15947,7 @@ void GLES2DecoderImpl::DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode) {
error::Error GLES2DecoderImpl::HandleUniformBlockBinding(
uint32_t immediate_data_size, const void* cmd_data) {
+ const char* func_name = "glUniformBlockBinding";
if (!unsafe_es3_apis_enabled())
return error::kUnknownCommand;
const gles2::cmds::UniformBlockBinding& c =
@@ -15919,13 +15955,23 @@ error::Error GLES2DecoderImpl::HandleUniformBlockBinding(
GLuint client_id = c.program;
GLuint index = static_cast<GLuint>(c.index);
GLuint binding = static_cast<GLuint>(c.binding);
- Program* program = GetProgramInfoNotShader(
- client_id, "glUniformBlockBinding");
+ Program* program = GetProgramInfoNotShader(client_id, func_name);
if (!program) {
return error::kNoError;
}
+ if (index >= program->uniform_block_size_info().size()) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name,
+ "uniformBlockIndex is not an active uniform block index");
+ return error::kNoError;
+ }
+ if (binding >= group_->max_uniform_buffer_bindings()) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name,
+ "uniformBlockBinding >= MAX_UNIFORM_BUFFER_BINDINGS");
+ return error::kNoError;
+ }
GLuint service_id = program->service_id();
glUniformBlockBinding(service_id, index, binding);
+ program->SetUniformBlockBinding(index, binding);
return error::kNoError;
}

Powered by Google App Engine
This is Rietveld 408576698