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. | |
piman
2016/07/14 23:41:14
I'm not sure why that is unexpected? Your usage of
| |
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 |