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

Side by Side 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" 5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
6 6
7 #include <limits.h> 7 #include <limits.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <stdint.h> 9 #include <stdint.h>
10 #include <stdio.h> 10 #include <stdio.h>
(...skipping 1356 matching lines...) Expand 10 before | Expand all | Expand 10 after
1367 1367
1368 // Checks if a draw buffer's format and its corresponding fragment shader 1368 // Checks if a draw buffer's format and its corresponding fragment shader
1369 // output's type are compatible, i.e., a signed integer typed variable is 1369 // output's type are compatible, i.e., a signed integer typed variable is
1370 // incompatible with a float or unsigned integer buffer. 1370 // incompatible with a float or unsigned integer buffer.
1371 // If incompaticle, generates an INVALID_OPERATION to avoid undefined buffer 1371 // If incompaticle, generates an INVALID_OPERATION to avoid undefined buffer
1372 // contents and return false. 1372 // contents and return false.
1373 // Otherwise, filter out the draw buffers that are not written to but are not 1373 // Otherwise, filter out the draw buffers that are not written to but are not
1374 // NONE through DrawBuffers, to be on the safe side. Return true. 1374 // NONE through DrawBuffers, to be on the safe side. Return true.
1375 bool ValidateAndAdjustDrawBuffers(const char* function_name); 1375 bool ValidateAndAdjustDrawBuffers(const char* function_name);
1376 1376
1377 // Checks if all active uniform blocks in the current program are backed by
1378 // a buffer of sufficient size.
1379 // If not, generates an INVALID_OPERATION to avoid undefined behavior in
1380 // shader execution and return false.
1381 bool ValidateUniformBlockBackings(const char* function_name);
1382
1377 // Checks if |api_type| is valid for the given uniform 1383 // Checks if |api_type| is valid for the given uniform
1378 // If the api type is not valid generates the appropriate GL 1384 // If the api type is not valid generates the appropriate GL
1379 // error. Returns true if |api_type| is valid for the uniform 1385 // error. Returns true if |api_type| is valid for the uniform
1380 bool CheckUniformForApiType(const Program::UniformInfo* info, 1386 bool CheckUniformForApiType(const Program::UniformInfo* info,
1381 const char* function_name, 1387 const char* function_name,
1382 Program::UniformApiType api_type); 1388 Program::UniformApiType api_type);
1383 1389
1384 // Gets the type of a uniform for a location in the current program. Sets GL 1390 // Gets the type of a uniform for a location in the current program. Sets GL
1385 // errors if the current program is not valid. Returns true if the current 1391 // errors if the current program is not valid. Returns true if the current
1386 // program is valid and the location exists. Adjusts count so it 1392 // program is valid and the location exists. Adjusts count so it
(...skipping 6675 matching lines...) Expand 10 before | Expand all | Expand 10 after
8062 state_.current_program->fragment_output_written_mask(); 8068 state_.current_program->fragment_output_written_mask();
8063 if (!framebuffer->ValidateAndAdjustDrawBuffers( 8069 if (!framebuffer->ValidateAndAdjustDrawBuffers(
8064 fragment_output_type_mask, fragment_output_written_mask)) { 8070 fragment_output_type_mask, fragment_output_written_mask)) {
8065 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, 8071 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
8066 "buffer format and fragment output variable type incompatible"); 8072 "buffer format and fragment output variable type incompatible");
8067 return false; 8073 return false;
8068 } 8074 }
8069 return true; 8075 return true;
8070 } 8076 }
8071 8077
8078 bool GLES2DecoderImpl::ValidateUniformBlockBackings(const char* func_name) {
8079 switch (feature_info_->context_type()) {
8080 case CONTEXT_TYPE_OPENGLES2:
8081 case CONTEXT_TYPE_WEBGL1:
8082 // Uniform blocks do not exist in ES2 contexts.
8083 return true;
8084 default:
8085 break;
8086 }
8087 DCHECK(state_.current_program.get());
8088 for (auto info : state_.current_program->uniform_block_size_info()) {
8089 uint32_t buffer_size = static_cast<uint32_t>(
8090 state_.indexed_uniform_buffer_bindings->GetEffectiveBufferSize(
8091 info.binding));
8092 if (info.data_size > buffer_size) {
8093 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
8094 "uniform blocks are not backed by a buffer with sufficient data");
8095 return false;
8096 }
8097 }
8098 return true;
8099 }
8100
8072 bool GLES2DecoderImpl::CheckUniformForApiType( 8101 bool GLES2DecoderImpl::CheckUniformForApiType(
8073 const Program::UniformInfo* info, 8102 const Program::UniformInfo* info,
8074 const char* function_name, 8103 const char* function_name,
8075 Program::UniformApiType api_type) { 8104 Program::UniformApiType api_type) {
8076 DCHECK(info); 8105 DCHECK(info);
8077 if ((api_type & info->accepts_api_type) == 0) { 8106 if ((api_type & info->accepts_api_type) == 0) {
8078 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, 8107 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
8079 "wrong uniform function for type"); 8108 "wrong uniform function for type");
8080 return false; 8109 return false;
8081 } 8110 }
(...skipping 1010 matching lines...) Expand 10 before | Expand all | Expand 10 after
9092 } 9121 }
9093 bool simulated_fixed_attribs = false; 9122 bool simulated_fixed_attribs = false;
9094 if (SimulateFixedAttribs( 9123 if (SimulateFixedAttribs(
9095 function_name, max_vertex_accessed, &simulated_fixed_attribs, 9124 function_name, max_vertex_accessed, &simulated_fixed_attribs,
9096 primcount)) { 9125 primcount)) {
9097 bool textures_set = !PrepareTexturesForRender(); 9126 bool textures_set = !PrepareTexturesForRender();
9098 ApplyDirtyState(); 9127 ApplyDirtyState();
9099 if (!ValidateAndAdjustDrawBuffers(function_name)) { 9128 if (!ValidateAndAdjustDrawBuffers(function_name)) {
9100 return error::kNoError; 9129 return error::kNoError;
9101 } 9130 }
9131 if (!ValidateUniformBlockBackings(function_name)) {
9132 return error::kNoError;
9133 }
9102 if (!instanced) { 9134 if (!instanced) {
9103 glDrawArrays(mode, first, count); 9135 glDrawArrays(mode, first, count);
9104 } else { 9136 } else {
9105 glDrawArraysInstancedANGLE(mode, first, count, primcount); 9137 glDrawArraysInstancedANGLE(mode, first, count, primcount);
9106 } 9138 }
9107 if (textures_set) { 9139 if (textures_set) {
9108 RestoreStateForTextures(); 9140 RestoreStateForTextures();
9109 } 9141 }
9110 if (simulated_fixed_attribs) { 9142 if (simulated_fixed_attribs) {
9111 RestoreStateForSimulatedFixedAttribs(); 9143 RestoreStateForSimulatedFixedAttribs();
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
9236 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset); 9268 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
9237 bool used_client_side_array = false; 9269 bool used_client_side_array = false;
9238 if (element_array_buffer->IsClientSideArray()) { 9270 if (element_array_buffer->IsClientSideArray()) {
9239 used_client_side_array = true; 9271 used_client_side_array = true;
9240 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 9272 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
9241 indices = element_array_buffer->GetRange(offset, 0); 9273 indices = element_array_buffer->GetRange(offset, 0);
9242 } 9274 }
9243 if (!ValidateAndAdjustDrawBuffers(function_name)) { 9275 if (!ValidateAndAdjustDrawBuffers(function_name)) {
9244 return error::kNoError; 9276 return error::kNoError;
9245 } 9277 }
9278 if (!ValidateUniformBlockBackings(function_name)) {
9279 return error::kNoError;
9280 }
9246 if (state_.enable_flags.primitive_restart_fixed_index && 9281 if (state_.enable_flags.primitive_restart_fixed_index &&
9247 feature_info_->feature_flags(). 9282 feature_info_->feature_flags().
9248 emulate_primitive_restart_fixed_index) { 9283 emulate_primitive_restart_fixed_index) {
9249 glEnable(GL_PRIMITIVE_RESTART); 9284 glEnable(GL_PRIMITIVE_RESTART);
9250 buffer_manager()->SetPrimitiveRestartFixedIndexIfNecessary(type); 9285 buffer_manager()->SetPrimitiveRestartFixedIndexIfNecessary(type);
9251 } 9286 }
9252 if (!instanced) { 9287 if (!instanced) {
9253 glDrawElements(mode, count, type, indices); 9288 glDrawElements(mode, count, type, indices);
9254 } else { 9289 } else {
9255 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount); 9290 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
(...skipping 6649 matching lines...) Expand 10 before | Expand all | Expand 10 after
15905 ? state_.projection_matrix 15940 ? state_.projection_matrix
15906 : state_.modelview_matrix; 15941 : state_.modelview_matrix;
15907 memcpy(target_matrix, kIdentityMatrix, sizeof(kIdentityMatrix)); 15942 memcpy(target_matrix, kIdentityMatrix, sizeof(kIdentityMatrix));
15908 // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV 15943 // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV
15909 // since the values of the _NV and _CHROMIUM tokens match. 15944 // since the values of the _NV and _CHROMIUM tokens match.
15910 glMatrixLoadIdentityEXT(matrix_mode); 15945 glMatrixLoadIdentityEXT(matrix_mode);
15911 } 15946 }
15912 15947
15913 error::Error GLES2DecoderImpl::HandleUniformBlockBinding( 15948 error::Error GLES2DecoderImpl::HandleUniformBlockBinding(
15914 uint32_t immediate_data_size, const void* cmd_data) { 15949 uint32_t immediate_data_size, const void* cmd_data) {
15950 const char* func_name = "glUniformBlockBinding";
15915 if (!unsafe_es3_apis_enabled()) 15951 if (!unsafe_es3_apis_enabled())
15916 return error::kUnknownCommand; 15952 return error::kUnknownCommand;
15917 const gles2::cmds::UniformBlockBinding& c = 15953 const gles2::cmds::UniformBlockBinding& c =
15918 *static_cast<const gles2::cmds::UniformBlockBinding*>(cmd_data); 15954 *static_cast<const gles2::cmds::UniformBlockBinding*>(cmd_data);
15919 GLuint client_id = c.program; 15955 GLuint client_id = c.program;
15920 GLuint index = static_cast<GLuint>(c.index); 15956 GLuint index = static_cast<GLuint>(c.index);
15921 GLuint binding = static_cast<GLuint>(c.binding); 15957 GLuint binding = static_cast<GLuint>(c.binding);
15922 Program* program = GetProgramInfoNotShader( 15958 Program* program = GetProgramInfoNotShader(client_id, func_name);
15923 client_id, "glUniformBlockBinding");
15924 if (!program) { 15959 if (!program) {
15925 return error::kNoError; 15960 return error::kNoError;
15926 } 15961 }
15962 if (index >= program->uniform_block_size_info().size()) {
15963 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name,
15964 "uniformBlockIndex is not an active uniform block index");
15965 return error::kNoError;
15966 }
15967 if (binding >= group_->max_uniform_buffer_bindings()) {
15968 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name,
15969 "uniformBlockBinding >= MAX_UNIFORM_BUFFER_BINDINGS");
15970 return error::kNoError;
15971 }
15927 GLuint service_id = program->service_id(); 15972 GLuint service_id = program->service_id();
15928 glUniformBlockBinding(service_id, index, binding); 15973 glUniformBlockBinding(service_id, index, binding);
15974 program->SetUniformBlockBinding(index, binding);
15929 return error::kNoError; 15975 return error::kNoError;
15930 } 15976 }
15931 15977
15932 error::Error GLES2DecoderImpl::HandleClientWaitSync( 15978 error::Error GLES2DecoderImpl::HandleClientWaitSync(
15933 uint32_t immediate_data_size, const void* cmd_data) { 15979 uint32_t immediate_data_size, const void* cmd_data) {
15934 const char* function_name = "glClientWaitSync"; 15980 const char* function_name = "glClientWaitSync";
15935 if (!unsafe_es3_apis_enabled()) 15981 if (!unsafe_es3_apis_enabled())
15936 return error::kUnknownCommand; 15982 return error::kUnknownCommand;
15937 const gles2::cmds::ClientWaitSync& c = 15983 const gles2::cmds::ClientWaitSync& c =
15938 *static_cast<const gles2::cmds::ClientWaitSync*>(cmd_data); 15984 *static_cast<const gles2::cmds::ClientWaitSync*>(cmd_data);
(...skipping 1466 matching lines...) Expand 10 before | Expand all | Expand 10 after
17405 } 17451 }
17406 17452
17407 // Include the auto-generated part of this file. We split this because it means 17453 // Include the auto-generated part of this file. We split this because it means
17408 // we can easily edit the non-auto generated parts right here in this file 17454 // we can easily edit the non-auto generated parts right here in this file
17409 // instead of having to edit some template or the code generator. 17455 // instead of having to edit some template or the code generator.
17410 #include "base/macros.h" 17456 #include "base/macros.h"
17411 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" 17457 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
17412 17458
17413 } // namespace gles2 17459 } // namespace gles2
17414 } // namespace gpu 17460 } // namespace gpu
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698