OLD | NEW |
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/program_manager.h" | 5 #include "gpu/command_buffer/service/program_manager.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 if (hit == varyings.end()) | 110 if (hit == varyings.end()) |
111 return false; | 111 return false; |
112 return hit->second.isInvariant; | 112 return hit->second.isInvariant; |
113 } | 113 } |
114 | 114 |
115 uint32_t ComputeOffset(const void* start, const void* position) { | 115 uint32_t ComputeOffset(const void* start, const void* position) { |
116 return static_cast<const uint8_t*>(position) - | 116 return static_cast<const uint8_t*>(position) - |
117 static_cast<const uint8_t*>(start); | 117 static_cast<const uint8_t*>(start); |
118 } | 118 } |
119 | 119 |
| 120 ShaderVariableBaseType FragmentOutputTypeToBaseType(GLenum type) { |
| 121 switch (type) { |
| 122 case GL_INT: |
| 123 case GL_INT_VEC2: |
| 124 case GL_INT_VEC3: |
| 125 case GL_INT_VEC4: |
| 126 return SHADER_VARIABLE_INT; |
| 127 case GL_UNSIGNED_INT: |
| 128 case GL_UNSIGNED_INT_VEC2: |
| 129 case GL_UNSIGNED_INT_VEC3: |
| 130 case GL_UNSIGNED_INT_VEC4: |
| 131 return SHADER_VARIABLE_UINT; |
| 132 case GL_FLOAT: |
| 133 case GL_FLOAT_VEC2: |
| 134 case GL_FLOAT_VEC3: |
| 135 case GL_FLOAT_VEC4: |
| 136 return SHADER_VARIABLE_FLOAT; |
| 137 default: |
| 138 NOTREACHED(); |
| 139 return SHADER_VARIABLE_UNDEFINED_TYPE; |
| 140 } |
| 141 } |
| 142 |
120 } // anonymous namespace. | 143 } // anonymous namespace. |
121 | 144 |
122 Program::UniformInfo::UniformInfo() | 145 Program::UniformInfo::UniformInfo() |
123 : size(0), | 146 : size(0), |
124 type(GL_NONE), | 147 type(GL_NONE), |
125 accepts_api_type(0), | 148 accepts_api_type(0), |
126 fake_location_base(0), | 149 fake_location_base(0), |
127 is_array(false) {} | 150 is_array(false) {} |
128 | 151 |
129 Program::UniformInfo::UniformInfo(const std::string& client_name, | 152 Program::UniformInfo::UniformInfo(const std::string& client_name, |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 Program::Program(ProgramManager* manager, GLuint service_id) | 287 Program::Program(ProgramManager* manager, GLuint service_id) |
265 : manager_(manager), | 288 : manager_(manager), |
266 use_count_(0), | 289 use_count_(0), |
267 max_attrib_name_length_(0), | 290 max_attrib_name_length_(0), |
268 max_uniform_name_length_(0), | 291 max_uniform_name_length_(0), |
269 service_id_(service_id), | 292 service_id_(service_id), |
270 deleted_(false), | 293 deleted_(false), |
271 valid_(false), | 294 valid_(false), |
272 link_status_(false), | 295 link_status_(false), |
273 uniforms_cleared_(false), | 296 uniforms_cleared_(false), |
274 transform_feedback_buffer_mode_(GL_NONE) { | 297 transform_feedback_buffer_mode_(GL_NONE), |
| 298 fragment_output_type_mask_(0u), |
| 299 fragment_output_written_mask_(0u) { |
| 300 DCHECK(manager_); |
275 manager_->StartTracking(this); | 301 manager_->StartTracking(this); |
276 } | 302 } |
277 | 303 |
278 void Program::Reset() { | 304 void Program::Reset() { |
279 valid_ = false; | 305 valid_ = false; |
280 link_status_ = false; | 306 link_status_ = false; |
281 max_uniform_name_length_ = 0; | 307 max_uniform_name_length_ = 0; |
282 max_attrib_name_length_ = 0; | 308 max_attrib_name_length_ = 0; |
283 attrib_infos_.clear(); | 309 attrib_infos_.clear(); |
284 uniform_infos_.clear(); | 310 uniform_infos_.clear(); |
285 uniform_locations_.clear(); | 311 uniform_locations_.clear(); |
286 fragment_input_infos_.clear(); | 312 fragment_input_infos_.clear(); |
287 fragment_input_locations_.clear(); | 313 fragment_input_locations_.clear(); |
288 program_output_infos_.clear(); | 314 program_output_infos_.clear(); |
289 sampler_indices_.clear(); | 315 sampler_indices_.clear(); |
290 attrib_location_to_index_map_.clear(); | 316 attrib_location_to_index_map_.clear(); |
| 317 fragment_output_type_mask_ = 0u; |
| 318 fragment_output_written_mask_ = 0u; |
| 319 } |
| 320 |
| 321 void Program::UpdateFragmentOutputBaseTypes() { |
| 322 fragment_output_type_mask_ = 0u; |
| 323 fragment_output_written_mask_ = 0u; |
| 324 Shader* fragment_shader = |
| 325 attached_shaders_[ShaderTypeToIndex(GL_FRAGMENT_SHADER)].get(); |
| 326 DCHECK(fragment_shader); |
| 327 for (auto const& output : fragment_shader->output_variable_list()) { |
| 328 int location = output.location; |
| 329 DCHECK(location == -1 || |
| 330 (location >= 0 && |
| 331 location < static_cast<int>(manager_->max_draw_buffers()))); |
| 332 if (location == -1) |
| 333 location = 0; |
| 334 if (ProgramManager::HasBuiltInPrefix(output.name)) { |
| 335 if (output.name != "gl_FragColor" && output.name != "gl_FragData") |
| 336 continue; |
| 337 } |
| 338 int count = static_cast<int>(output.arraySize == 0 ? 1 : output.arraySize); |
| 339 // TODO(zmo): Handle the special case in ES2 where gl_FragColor could |
| 340 // be broadcasting to all draw buffers. |
| 341 DCHECK_LE(location + count, |
| 342 static_cast<int>(manager_->max_draw_buffers())); |
| 343 for (int ii = location; ii < location + count; ++ii) { |
| 344 // TODO(zmo): This does not work with glBindFragDataLocationIndexed. |
| 345 // crbug.com/628010 |
| 346 // For example: |
| 347 // glBindFragDataLocationIndexed(program, loc, 0, "FragData0"); |
| 348 // glBindFragDataLocationIndexed(program, loc, 1, "FragData1"); |
| 349 // The program links OK, but both calling glGetFragDataLocation on both |
| 350 // "FragData0" and "FragData1" returns 0. |
| 351 int shift_bits = ii * 2; |
| 352 fragment_output_written_mask_ |= 0x3 << shift_bits; |
| 353 fragment_output_type_mask_ |= |
| 354 FragmentOutputTypeToBaseType(output.type) << shift_bits; |
| 355 } |
| 356 } |
291 } | 357 } |
292 | 358 |
293 std::string Program::ProcessLogInfo( | 359 std::string Program::ProcessLogInfo( |
294 const std::string& log) { | 360 const std::string& log) { |
295 std::string output; | 361 std::string output; |
296 re2::StringPiece input(log); | 362 re2::StringPiece input(log); |
297 std::string prior_log; | 363 std::string prior_log; |
298 std::string hashed_name; | 364 std::string hashed_name; |
299 while (RE2::Consume(&input, | 365 while (RE2::Consume(&input, |
300 "(.*?)(webgl_[0123456789abcdefABCDEF]+)", | 366 "(.*?)(webgl_[0123456789abcdefABCDEF]+)", |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
516 for (const UniformInfo& info : uniform_infos_) { | 582 for (const UniformInfo& info : uniform_infos_) { |
517 DVLOG(1) << ii++ << ": loc = " << info.element_locations[0] | 583 DVLOG(1) << ii++ << ": loc = " << info.element_locations[0] |
518 << ", size = " << info.size | 584 << ", size = " << info.size |
519 << ", type = " << GLES2Util::GetStringEnum(info.type) | 585 << ", type = " << GLES2Util::GetStringEnum(info.type) |
520 << ", name = " << info.name; | 586 << ", name = " << info.name; |
521 } | 587 } |
522 } | 588 } |
523 | 589 |
524 UpdateFragmentInputs(); | 590 UpdateFragmentInputs(); |
525 UpdateProgramOutputs(); | 591 UpdateProgramOutputs(); |
| 592 UpdateFragmentOutputBaseTypes(); |
526 | 593 |
527 valid_ = true; | 594 valid_ = true; |
528 } | 595 } |
529 | 596 |
530 void Program::UpdateUniforms() { | 597 void Program::UpdateUniforms() { |
531 // Reserve each client-bound uniform location. This way unbound uniforms will | 598 // Reserve each client-bound uniform location. This way unbound uniforms will |
532 // not be allocated to locations that user expects bound uniforms to be, even | 599 // not be allocated to locations that user expects bound uniforms to be, even |
533 // if the expected uniforms are optimized away by the driver. | 600 // if the expected uniforms are optimized away by the driver. |
534 for (const auto& binding : bind_uniform_location_map_) { | 601 for (const auto& binding : bind_uniform_location_map_) { |
535 if (binding.second < 0) | 602 if (binding.second < 0) |
(...skipping 1738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2274 glDeleteProgram(service_id()); | 2341 glDeleteProgram(service_id()); |
2275 } | 2342 } |
2276 manager_->StopTracking(this); | 2343 manager_->StopTracking(this); |
2277 manager_ = NULL; | 2344 manager_ = NULL; |
2278 } | 2345 } |
2279 } | 2346 } |
2280 | 2347 |
2281 ProgramManager::ProgramManager( | 2348 ProgramManager::ProgramManager( |
2282 ProgramCache* program_cache, | 2349 ProgramCache* program_cache, |
2283 uint32_t max_varying_vectors, | 2350 uint32_t max_varying_vectors, |
| 2351 uint32_t max_draw_buffers, |
2284 uint32_t max_dual_source_draw_buffers, | 2352 uint32_t max_dual_source_draw_buffers, |
2285 const GpuPreferences& gpu_preferences, | 2353 const GpuPreferences& gpu_preferences, |
2286 FeatureInfo* feature_info) | 2354 FeatureInfo* feature_info) |
2287 : program_count_(0), | 2355 : program_count_(0), |
2288 have_context_(true), | 2356 have_context_(true), |
2289 program_cache_(program_cache), | 2357 program_cache_(program_cache), |
2290 max_varying_vectors_(max_varying_vectors), | 2358 max_varying_vectors_(max_varying_vectors), |
| 2359 max_draw_buffers_(max_draw_buffers), |
2291 max_dual_source_draw_buffers_(max_dual_source_draw_buffers), | 2360 max_dual_source_draw_buffers_(max_dual_source_draw_buffers), |
2292 gpu_preferences_(gpu_preferences), | 2361 gpu_preferences_(gpu_preferences), |
2293 feature_info_(feature_info) {} | 2362 feature_info_(feature_info) {} |
2294 | 2363 |
2295 ProgramManager::~ProgramManager() { | 2364 ProgramManager::~ProgramManager() { |
2296 DCHECK(programs_.empty()); | 2365 DCHECK(programs_.empty()); |
2297 } | 2366 } |
2298 | 2367 |
2299 void ProgramManager::Destroy(bool have_context) { | 2368 void ProgramManager::Destroy(bool have_context) { |
2300 have_context_ = have_context; | 2369 have_context_ = have_context; |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2397 DCHECK(program); | 2466 DCHECK(program); |
2398 program->ClearUniforms(&zero_); | 2467 program->ClearUniforms(&zero_); |
2399 } | 2468 } |
2400 | 2469 |
2401 int32_t ProgramManager::MakeFakeLocation(int32_t index, int32_t element) { | 2470 int32_t ProgramManager::MakeFakeLocation(int32_t index, int32_t element) { |
2402 return index + element * 0x10000; | 2471 return index + element * 0x10000; |
2403 } | 2472 } |
2404 | 2473 |
2405 } // namespace gles2 | 2474 } // namespace gles2 |
2406 } // namespace gpu | 2475 } // namespace gpu |
OLD | NEW |