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

Side by Side Diff: gpu/command_buffer/service/gles2_cmd_decoder.cc

Issue 2142353002: Validate fbo color image format and fragment shader output variable type. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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 1348 matching lines...) Expand 10 before | Expand all | Expand 10 after
1359 // -1. If the current program is not valid generates the appropriate GL 1359 // -1. If the current program is not valid generates the appropriate GL
1360 // error. Returns true if the current program is in a usable state and 1360 // error. Returns true if the current program is in a usable state and
1361 // location is not -1. 1361 // location is not -1.
1362 bool CheckCurrentProgramForUniform(GLint location, const char* function_name); 1362 bool CheckCurrentProgramForUniform(GLint location, const char* function_name);
1363 1363
1364 // Checks if the current program samples a texture that is also the color 1364 // Checks if the current program samples a texture that is also the color
1365 // image of the current bound framebuffer, i.e., the source and destination 1365 // image of the current bound framebuffer, i.e., the source and destination
1366 // of the draw operation are the same. 1366 // of the draw operation are the same.
1367 bool CheckDrawingFeedbackLoops(); 1367 bool CheckDrawingFeedbackLoops();
1368 1368
1369 // Checks if a draw buffer's format and its corresponding fragment shader
1370 // output's type are compatible, i.e., a signed integer typed variable is
1371 // incompatible with a float or unsigned integer buffer.
1372 // If incompaticle, generates an INVALID_OPERATION to avoid undefined buffer
1373 // contents and return false.
1374 // Otherwise, filter out the draw buffers that are not written to but are not
1375 // NONE through DrawBuffers, to be on the safe side; set |adjusted| to true
1376 // if such adjustments happen. Return true.
1377 bool ValidateAndAdjustDrawBuffers(const char* function_name, bool* adjusted);
1378
1369 // Checks if |api_type| is valid for the given uniform 1379 // Checks if |api_type| is valid for the given uniform
1370 // If the api type is not valid generates the appropriate GL 1380 // If the api type is not valid generates the appropriate GL
1371 // error. Returns true if |api_type| is valid for the uniform 1381 // error. Returns true if |api_type| is valid for the uniform
1372 bool CheckUniformForApiType(const Program::UniformInfo* info, 1382 bool CheckUniformForApiType(const Program::UniformInfo* info,
1373 const char* function_name, 1383 const char* function_name,
1374 Program::UniformApiType api_type); 1384 Program::UniformApiType api_type);
1375 1385
1376 // Gets the type of a uniform for a location in the current program. Sets GL 1386 // Gets the type of a uniform for a location in the current program. Sets GL
1377 // errors if the current program is not valid. Returns true if the current 1387 // errors if the current program is not valid. Returns true if the current
1378 // program is valid and the location exists. Adjusts count so it 1388 // program is valid and the location exists. Adjusts count so it
(...skipping 5710 matching lines...) Expand 10 before | Expand all | Expand 10 after
7089 // TODO(zmo): There is no guarantee that an FBO that is complete on the 7099 // TODO(zmo): There is no guarantee that an FBO that is complete on the
7090 // READ attachment will be complete as a DRAW attachment. 7100 // READ attachment will be complete as a DRAW attachment.
7091 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, framebuffer->service_id()); 7101 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, framebuffer->service_id());
7092 } 7102 }
7093 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false); 7103 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
7094 glClear(clear_bits); 7104 glClear(clear_bits);
7095 } 7105 }
7096 7106
7097 if (cleared_int_renderbuffers || clear_bits) { 7107 if (cleared_int_renderbuffers || clear_bits) {
7098 if (reset_draw_buffers) 7108 if (reset_draw_buffers)
7099 framebuffer->RestoreDrawBuffersAfterClear(); 7109 framebuffer->RestoreDrawBuffers();
7100 RestoreClearState(); 7110 RestoreClearState();
7101 if (target == GL_READ_FRAMEBUFFER && draw_framebuffer != framebuffer) { 7111 if (target == GL_READ_FRAMEBUFFER && draw_framebuffer != framebuffer) {
7102 GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() : 7112 GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() :
7103 GetBackbufferServiceId(); 7113 GetBackbufferServiceId();
7104 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id); 7114 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id);
7105 } 7115 }
7106 } 7116 }
7107 7117
7108 framebuffer_manager()->MarkAttachmentsAsCleared( 7118 framebuffer_manager()->MarkAttachmentsAsCleared(
7109 framebuffer, renderbuffer_manager(), texture_manager()); 7119 framebuffer, renderbuffer_manager(), texture_manager());
(...skipping 909 matching lines...) Expand 10 before | Expand all | Expand 10 after
8019 TextureUnit& texture_unit = state_.texture_units[texture_unit_index]; 8029 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
8020 TextureRef* texture_ref = 8030 TextureRef* texture_ref =
8021 texture_unit.GetInfoForSamplerType(uniform_info->type).get(); 8031 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
8022 if (attachment->IsTexture(texture_ref)) 8032 if (attachment->IsTexture(texture_ref))
8023 return true; 8033 return true;
8024 } 8034 }
8025 } 8035 }
8026 return false; 8036 return false;
8027 } 8037 }
8028 8038
8039 bool GLES2DecoderImpl::ValidateAndAdjustDrawBuffers(
8040 const char* function_name, bool* adjusted) {
8041 bool validation = true;
8042 bool my_adjusted = false;
8043 switch (feature_info_->context_type()) {
8044 case CONTEXT_TYPE_OPENGLES2:
8045 case CONTEXT_TYPE_WEBGL1:
8046 // Int and unsigned int formats are not available in ES2/WebGL1.
8047 validation = false;
8048 break;
8049 default:
8050 break;
8051 }
8052 Framebuffer* framebuffer = framebuffer_state_.bound_draw_framebuffer.get();
8053 if (!state_.current_program.get() || !framebuffer) {
8054 return true;
8055 }
8056 const std::vector<ShaderVariableBaseType>& fragment_output_base_types =
8057 state_.current_program->GetFragmentOutputBaseTypes();
8058 const std::vector<ShaderVariableBaseType>& color_attachment_base_types =
8059 framebuffer->GetColorAttachmentBaseTypes();
8060 DCHECK_EQ(fragment_output_base_types.size(),
8061 color_attachment_base_types.size());
8062 size_t count = color_attachment_base_types.size();
8063 std::unique_ptr<GLenum[]> adjusted_draw_buffers(new GLenum[count]);
8064 for (size_t ii = 0; ii < count; ++ii) {
8065 adjusted_draw_buffers[ii] =
8066 framebuffer->GetDrawBuffer(GL_DRAW_BUFFER0 + ii);
8067 if (adjusted_draw_buffers[ii] == GL_NONE)
8068 continue;
8069 if (fragment_output_base_types[ii] == SHADER_VARIABLE_UNDEFINED_TYPE) {
8070 adjusted_draw_buffers[ii] = GL_NONE;
Corentin Wallez 2016/07/13 14:50:07 This looks like it will be doing an allocation for
8071 my_adjusted = true;
8072 continue;
8073 }
8074 if (!validation)
8075 continue;
8076 if (color_attachment_base_types[ii] == SHADER_VARIABLE_UNDEFINED_TYPE)
8077 continue;
8078 if (fragment_output_base_types[ii] != color_attachment_base_types[ii]) {
8079 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
8080 "buffer format and fragment output variable type incompatible");
8081 return false;
8082 }
8083 }
8084 if (my_adjusted) {
8085 glDrawBuffersARB(count, adjusted_draw_buffers.get());
8086 }
8087 *adjusted = my_adjusted;
8088 return true;
8089 }
8090
8029 bool GLES2DecoderImpl::CheckUniformForApiType( 8091 bool GLES2DecoderImpl::CheckUniformForApiType(
8030 const Program::UniformInfo* info, 8092 const Program::UniformInfo* info,
8031 const char* function_name, 8093 const char* function_name,
8032 Program::UniformApiType api_type) { 8094 Program::UniformApiType api_type) {
8033 DCHECK(info); 8095 DCHECK(info);
8034 if ((api_type & info->accepts_api_type) == 0) { 8096 if ((api_type & info->accepts_api_type) == 0) {
8035 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, 8097 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
8036 "wrong uniform function for type"); 8098 "wrong uniform function for type");
8037 return false; 8099 return false;
8038 } 8100 }
(...skipping 1007 matching lines...) Expand 10 before | Expand all | Expand 10 after
9046 if (!SimulateAttrib0( 9108 if (!SimulateAttrib0(
9047 function_name, max_vertex_accessed, &simulated_attrib_0)) { 9109 function_name, max_vertex_accessed, &simulated_attrib_0)) {
9048 return error::kNoError; 9110 return error::kNoError;
9049 } 9111 }
9050 bool simulated_fixed_attribs = false; 9112 bool simulated_fixed_attribs = false;
9051 if (SimulateFixedAttribs( 9113 if (SimulateFixedAttribs(
9052 function_name, max_vertex_accessed, &simulated_fixed_attribs, 9114 function_name, max_vertex_accessed, &simulated_fixed_attribs,
9053 primcount)) { 9115 primcount)) {
9054 bool textures_set = !PrepareTexturesForRender(); 9116 bool textures_set = !PrepareTexturesForRender();
9055 ApplyDirtyState(); 9117 ApplyDirtyState();
9118 bool adjusted = false;
9119 if (!ValidateAndAdjustDrawBuffers(function_name, &adjusted)) {
9120 return error::kNoError;
9121 }
9056 if (!instanced) { 9122 if (!instanced) {
9057 glDrawArrays(mode, first, count); 9123 glDrawArrays(mode, first, count);
9058 } else { 9124 } else {
9059 glDrawArraysInstancedANGLE(mode, first, count, primcount); 9125 glDrawArraysInstancedANGLE(mode, first, count, primcount);
9060 } 9126 }
9127 if (adjusted) {
9128 DCHECK(framebuffer_state_.bound_draw_framebuffer.get());
9129 framebuffer_state_.bound_draw_framebuffer->RestoreDrawBuffers();
9130 }
9061 if (textures_set) { 9131 if (textures_set) {
9062 RestoreStateForTextures(); 9132 RestoreStateForTextures();
9063 } 9133 }
9064 if (simulated_fixed_attribs) { 9134 if (simulated_fixed_attribs) {
9065 RestoreStateForSimulatedFixedAttribs(); 9135 RestoreStateForSimulatedFixedAttribs();
9066 } 9136 }
9067 } 9137 }
9068 if (simulated_attrib_0) { 9138 if (simulated_attrib_0) {
9069 // We don't have to restore attrib 0 generic data at the end of this 9139 // We don't have to restore attrib 0 generic data at the end of this
9070 // function even if it is simulated. This is because we will simulate 9140 // function even if it is simulated. This is because we will simulate
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
9187 ApplyDirtyState(); 9257 ApplyDirtyState();
9188 // TODO(gman): Refactor to hide these details in BufferManager or 9258 // TODO(gman): Refactor to hide these details in BufferManager or
9189 // VertexAttribManager. 9259 // VertexAttribManager.
9190 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset); 9260 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
9191 bool used_client_side_array = false; 9261 bool used_client_side_array = false;
9192 if (element_array_buffer->IsClientSideArray()) { 9262 if (element_array_buffer->IsClientSideArray()) {
9193 used_client_side_array = true; 9263 used_client_side_array = true;
9194 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 9264 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
9195 indices = element_array_buffer->GetRange(offset, 0); 9265 indices = element_array_buffer->GetRange(offset, 0);
9196 } 9266 }
9197 9267 bool adjusted = false;
9268 if (!ValidateAndAdjustDrawBuffers(function_name, &adjusted)) {
9269 return error::kNoError;
9270 }
9198 if (state_.enable_flags.primitive_restart_fixed_index && 9271 if (state_.enable_flags.primitive_restart_fixed_index &&
9199 feature_info_->feature_flags(). 9272 feature_info_->feature_flags().
9200 emulate_primitive_restart_fixed_index) { 9273 emulate_primitive_restart_fixed_index) {
9201 glEnable(GL_PRIMITIVE_RESTART); 9274 glEnable(GL_PRIMITIVE_RESTART);
9202 buffer_manager()->SetPrimitiveRestartFixedIndexIfNecessary(type); 9275 buffer_manager()->SetPrimitiveRestartFixedIndexIfNecessary(type);
9203 } 9276 }
9204
9205 if (!instanced) { 9277 if (!instanced) {
9206 glDrawElements(mode, count, type, indices); 9278 glDrawElements(mode, count, type, indices);
9207 } else { 9279 } else {
9208 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount); 9280 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
9209 } 9281 }
9210 if (state_.enable_flags.primitive_restart_fixed_index && 9282 if (state_.enable_flags.primitive_restart_fixed_index &&
9211 feature_info_->feature_flags(). 9283 feature_info_->feature_flags().
9212 emulate_primitive_restart_fixed_index) { 9284 emulate_primitive_restart_fixed_index) {
9213 glDisable(GL_PRIMITIVE_RESTART); 9285 glDisable(GL_PRIMITIVE_RESTART);
9214 } 9286 }
9215 9287 if (adjusted) {
9288 DCHECK(framebuffer_state_.bound_draw_framebuffer.get());
9289 framebuffer_state_.bound_draw_framebuffer->RestoreDrawBuffers();
9290 }
9216 if (used_client_side_array) { 9291 if (used_client_side_array) {
9217 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 9292 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
9218 element_array_buffer->service_id()); 9293 element_array_buffer->service_id());
9219 } 9294 }
9220
9221 if (textures_set) { 9295 if (textures_set) {
9222 RestoreStateForTextures(); 9296 RestoreStateForTextures();
9223 } 9297 }
9224 if (simulated_fixed_attribs) { 9298 if (simulated_fixed_attribs) {
9225 RestoreStateForSimulatedFixedAttribs(); 9299 RestoreStateForSimulatedFixedAttribs();
9226 } 9300 }
9227 } 9301 }
9228 if (simulated_attrib_0) { 9302 if (simulated_attrib_0) {
9229 // We don't have to restore attrib 0 generic data at the end of this 9303 // We don't have to restore attrib 0 generic data at the end of this
9230 // function even if it is simulated. This is because we will simulate 9304 // function even if it is simulated. This is because we will simulate
(...skipping 7875 matching lines...) Expand 10 before | Expand all | Expand 10 after
17106 } 17180 }
17107 17181
17108 // Include the auto-generated part of this file. We split this because it means 17182 // Include the auto-generated part of this file. We split this because it means
17109 // we can easily edit the non-auto generated parts right here in this file 17183 // we can easily edit the non-auto generated parts right here in this file
17110 // instead of having to edit some template or the code generator. 17184 // instead of having to edit some template or the code generator.
17111 #include "base/macros.h" 17185 #include "base/macros.h"
17112 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" 17186 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
17113 17187
17114 } // namespace gles2 17188 } // namespace gles2
17115 } // namespace gpu 17189 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/framebuffer_manager.cc ('k') | gpu/command_buffer/service/program_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698