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

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

Issue 2958763003: Fix a bug in shader/program relationship. (Closed)
Patch Set: Fix a bug in shader/program relationship. Created 3 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
« no previous file with comments | « gpu/command_buffer/service/program_manager.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/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 402 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 for (uint32_t ii = 0; ii < vertex_input_base_type_mask_.size(); ++ii) { 413 for (uint32_t ii = 0; ii < vertex_input_base_type_mask_.size(); ++ii) {
414 vertex_input_base_type_mask_[ii] = 0u; 414 vertex_input_base_type_mask_[ii] = 0u;
415 vertex_input_active_mask_[ii] = 0u; 415 vertex_input_active_mask_[ii] = 0u;
416 } 416 }
417 } 417 }
418 418
419 void Program::UpdateFragmentOutputBaseTypes() { 419 void Program::UpdateFragmentOutputBaseTypes() {
420 fragment_output_type_mask_ = 0u; 420 fragment_output_type_mask_ = 0u;
421 fragment_output_written_mask_ = 0u; 421 fragment_output_written_mask_ = 0u;
422 Shader* fragment_shader = 422 Shader* fragment_shader =
423 attached_shaders_[ShaderTypeToIndex(GL_FRAGMENT_SHADER)].get(); 423 shaders_from_last_successful_link_[ShaderTypeToIndex(GL_FRAGMENT_SHADER)]
424 .get();
424 DCHECK(fragment_shader); 425 DCHECK(fragment_shader);
425 for (auto const& output : fragment_shader->output_variable_list()) { 426 for (auto const& output : fragment_shader->output_variable_list()) {
426 int location = output.location; 427 int location = output.location;
427 DCHECK(location == -1 || 428 DCHECK(location == -1 ||
428 (location >= 0 && 429 (location >= 0 &&
429 location < static_cast<int>(manager_->max_draw_buffers()))); 430 location < static_cast<int>(manager_->max_draw_buffers())));
430 if (location == -1) 431 if (location == -1)
431 location = 0; 432 location = 0;
432 if (ProgramManager::HasBuiltInPrefix(output.name)) { 433 if (ProgramManager::HasBuiltInPrefix(output.name)) {
433 if (output.name != "gl_FragColor" && output.name != "gl_FragData") 434 if (output.name != "gl_FragColor" && output.name != "gl_FragData")
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 496
496 void Program::SetUniformBlockBinding(GLuint index, GLuint binding) { 497 void Program::SetUniformBlockBinding(GLuint index, GLuint binding) {
497 DCHECK_GT(uniform_block_size_info_.size(), index); 498 DCHECK_GT(uniform_block_size_info_.size(), index);
498 uniform_block_size_info_[index].binding = binding; 499 uniform_block_size_info_[index].binding = binding;
499 } 500 }
500 501
501 void Program::UpdateTransformFeedbackInfo() { 502 void Program::UpdateTransformFeedbackInfo() {
502 effective_transform_feedback_buffer_mode_ = transform_feedback_buffer_mode_; 503 effective_transform_feedback_buffer_mode_ = transform_feedback_buffer_mode_;
503 effective_transform_feedback_varyings_ = transform_feedback_varyings_; 504 effective_transform_feedback_varyings_ = transform_feedback_varyings_;
504 505
505 Shader* vertex_shader = attached_shaders_[0].get(); 506 Shader* vertex_shader = shaders_from_last_successful_link_[0].get();
506 DCHECK(vertex_shader); 507 DCHECK(vertex_shader);
507 508
508 if (effective_transform_feedback_buffer_mode_ == GL_INTERLEAVED_ATTRIBS) { 509 if (effective_transform_feedback_buffer_mode_ == GL_INTERLEAVED_ATTRIBS) {
509 transform_feedback_data_size_per_vertex_.resize(1); 510 transform_feedback_data_size_per_vertex_.resize(1);
510 } else { 511 } else {
511 transform_feedback_data_size_per_vertex_.resize( 512 transform_feedback_data_size_per_vertex_.resize(
512 effective_transform_feedback_varyings_.size()); 513 effective_transform_feedback_varyings_.size());
513 } 514 }
514 515
515 base::CheckedNumeric<GLsizeiptr> total = 0; 516 base::CheckedNumeric<GLsizeiptr> total = 0;
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
819 if (!ProgramManager::HasBuiltInPrefix(service_name)) { 820 if (!ProgramManager::HasBuiltInPrefix(service_name)) {
820 service_location = 821 service_location =
821 glGetUniformLocation(service_id_, service_name.c_str()); 822 glGetUniformLocation(service_id_, service_name.c_str());
822 } 823 }
823 824
824 // Determine the client name of the uniform and whether it is an array 825 // Determine the client name of the uniform and whether it is an array
825 // or not. 826 // or not.
826 bool is_array = false; 827 bool is_array = false;
827 std::string client_name; 828 std::string client_name;
828 for (size_t i = 0; i < kMaxAttachedShaders && client_name.empty(); ++i) { 829 for (size_t i = 0; i < kMaxAttachedShaders && client_name.empty(); ++i) {
829 const auto& shader = attached_shaders_[i]; 830 const auto& shader = shaders_from_last_successful_link_[i];
830 if (!shader) 831 if (!shader)
831 continue; 832 continue;
832 const sh::ShaderVariable* info = nullptr; 833 const sh::ShaderVariable* info = nullptr;
833 const sh::Uniform* uniform = shader->GetUniformInfo(service_name); 834 const sh::Uniform* uniform = shader->GetUniformInfo(service_name);
834 if (uniform && 835 if (uniform &&
835 uniform->findInfoByMappedName(service_name, &info, &client_name)) { 836 uniform->findInfoByMappedName(service_name, &info, &client_name)) {
836 DCHECK(!client_name.empty()); 837 DCHECK(!client_name.empty());
837 is_array = info->arraySize > 0; 838 is_array = info->arraySize > 0;
838 type = info->type; 839 type = info->type;
839 size = std::max(1u, info->arraySize); 840 size = std::max(1u, info->arraySize);
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
970 return; 971 return;
971 972
972 GLint max_len = 0; 973 GLint max_len = 0;
973 glGetProgramInterfaceiv(service_id_, GL_FRAGMENT_INPUT_NV, GL_MAX_NAME_LENGTH, 974 glGetProgramInterfaceiv(service_id_, GL_FRAGMENT_INPUT_NV, GL_MAX_NAME_LENGTH,
974 &max_len); 975 &max_len);
975 DCHECK(max_len > 0); 976 DCHECK(max_len > 0);
976 977
977 std::unique_ptr<char[]> name_buffer(new char[max_len]); 978 std::unique_ptr<char[]> name_buffer(new char[max_len]);
978 979
979 Shader* fragment_shader = 980 Shader* fragment_shader =
980 attached_shaders_[ShaderTypeToIndex(GL_FRAGMENT_SHADER)].get(); 981 shaders_from_last_successful_link_[ShaderTypeToIndex(GL_FRAGMENT_SHADER)]
982 .get();
981 983
982 const GLenum kQueryProperties[] = {GL_LOCATION, GL_TYPE, GL_ARRAY_SIZE}; 984 const GLenum kQueryProperties[] = {GL_LOCATION, GL_TYPE, GL_ARRAY_SIZE};
983 985
984 std::vector<size_t> client_location_indices; 986 std::vector<size_t> client_location_indices;
985 for (GLint ii = 0; ii < num_fragment_inputs; ++ii) { 987 for (GLint ii = 0; ii < num_fragment_inputs; ++ii) {
986 GLsizei name_length = 0; 988 GLsizei name_length = 0;
987 glGetProgramResourceName(service_id_, GL_FRAGMENT_INPUT_NV, ii, max_len, 989 glGetProgramResourceName(service_id_, GL_FRAGMENT_INPUT_NV, ii, max_len,
988 &name_length, name_buffer.get()); 990 &name_length, name_buffer.get());
989 DCHECK(name_length < max_len); 991 DCHECK(name_length < max_len);
990 DCHECK(name_length == 0 || name_buffer[name_length] == '\0'); 992 DCHECK(name_length == 0 || name_buffer[name_length] == '\0');
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1077 &fragment_input_infos_[i]); 1079 &fragment_input_infos_[i]);
1078 } 1080 }
1079 } 1081 }
1080 1082
1081 void Program::UpdateProgramOutputs() { 1083 void Program::UpdateProgramOutputs() {
1082 if (!feature_info().gl_version_info().is_es3_capable || 1084 if (!feature_info().gl_version_info().is_es3_capable ||
1083 feature_info().disable_shader_translator()) 1085 feature_info().disable_shader_translator())
1084 return; 1086 return;
1085 1087
1086 Shader* fragment_shader = 1088 Shader* fragment_shader =
1087 attached_shaders_[ShaderTypeToIndex(GL_FRAGMENT_SHADER)].get(); 1089 shaders_from_last_successful_link_[ShaderTypeToIndex(GL_FRAGMENT_SHADER)]
1090 .get();
1088 1091
1089 for (auto const& output_var : fragment_shader->output_variable_list()) { 1092 for (auto const& output_var : fragment_shader->output_variable_list()) {
1090 const std::string& service_name = output_var.mappedName; 1093 const std::string& service_name = output_var.mappedName;
1091 // A fragment shader can have gl_FragColor, gl_SecondaryFragColor, etc 1094 // A fragment shader can have gl_FragColor, gl_SecondaryFragColor, etc
1092 // built-ins as its output, as well as custom varyings. We are interested 1095 // built-ins as its output, as well as custom varyings. We are interested
1093 // only in custom varyings, client is allowed to bind only them. 1096 // only in custom varyings, client is allowed to bind only them.
1094 if (ProgramManager::HasBuiltInPrefix(service_name)) 1097 if (ProgramManager::HasBuiltInPrefix(service_name))
1095 continue; 1098 continue;
1096 1099
1097 std::string client_name = output_var.name; 1100 std::string client_name = output_var.name;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1143 void Program::ExecuteBindAttribLocationCalls() { 1146 void Program::ExecuteBindAttribLocationCalls() {
1144 for (const auto& key_value : bind_attrib_location_map_) { 1147 for (const auto& key_value : bind_attrib_location_map_) {
1145 const std::string* mapped_name = GetAttribMappedName(key_value.first); 1148 const std::string* mapped_name = GetAttribMappedName(key_value.first);
1146 if (mapped_name) 1149 if (mapped_name)
1147 glBindAttribLocation(service_id_, key_value.second, mapped_name->c_str()); 1150 glBindAttribLocation(service_id_, key_value.second, mapped_name->c_str());
1148 } 1151 }
1149 } 1152 }
1150 1153
1151 bool Program::ExecuteTransformFeedbackVaryingsCall() { 1154 bool Program::ExecuteTransformFeedbackVaryingsCall() {
1152 if (!transform_feedback_varyings_.empty()) { 1155 if (!transform_feedback_varyings_.empty()) {
1153 Shader* vertex_shader = attached_shaders_[0].get(); 1156 Shader* vertex_shader = attached_shaders_[0].get();
Ken Russell (switch to Gerrit) 2017/06/26 22:56:20 Here and in several more places, there are some me
1154 if (!vertex_shader) { 1157 if (!vertex_shader) {
1155 set_log_info("TransformFeedbackVaryings: missing vertex shader"); 1158 set_log_info("TransformFeedbackVaryings: missing vertex shader");
1156 return false; 1159 return false;
1157 } 1160 }
1158 1161
1159 std::vector<const char*> mapped_names; 1162 std::vector<const char*> mapped_names;
1160 mapped_names.reserve(transform_feedback_varyings_.size()); 1163 mapped_names.reserve(transform_feedback_varyings_.size());
1161 for (StringVector::const_iterator it = 1164 for (StringVector::const_iterator it =
1162 transform_feedback_varyings_.begin(); 1165 transform_feedback_varyings_.begin();
1163 it != transform_feedback_varyings_.end(); ++it) { 1166 it != transform_feedback_varyings_.end(); ++it) {
(...skipping 14 matching lines...) Expand all
1178 1181
1179 return true; 1182 return true;
1180 } 1183 }
1181 1184
1182 void Program::ExecuteProgramOutputBindCalls() { 1185 void Program::ExecuteProgramOutputBindCalls() {
1183 if (feature_info().disable_shader_translator()) { 1186 if (feature_info().disable_shader_translator()) {
1184 return; 1187 return;
1185 } 1188 }
1186 1189
1187 Shader* fragment_shader = 1190 Shader* fragment_shader =
1188 attached_shaders_[ShaderTypeToIndex(GL_FRAGMENT_SHADER)].get(); 1191 attached_shaders_[ShaderTypeToIndex(GL_FRAGMENT_SHADER)].get();
Ken Russell (switch to Gerrit) 2017/06/26 22:56:20 Same here.
1189 DCHECK(fragment_shader && fragment_shader->valid()); 1192 DCHECK(fragment_shader && fragment_shader->valid());
1190 1193
1191 if (fragment_shader->shader_version() != 100) { 1194 if (fragment_shader->shader_version() != 100) {
1192 // ES SL 1.00 does not have mechanism for introducing variables that could 1195 // ES SL 1.00 does not have mechanism for introducing variables that could
1193 // be bound. This means that ES SL 1.00 binding calls would be to 1196 // be bound. This means that ES SL 1.00 binding calls would be to
1194 // non-existing variable names. Binding calls are only executed with ES SL 1197 // non-existing variable names. Binding calls are only executed with ES SL
1195 // 3.00 and higher. 1198 // 3.00 and higher.
1196 for (auto const& output_var : fragment_shader->output_variable_list()) { 1199 for (auto const& output_var : fragment_shader->output_variable_list()) {
1197 size_t count = std::max(output_var.arraySize, 1u); 1200 size_t count = std::max(output_var.arraySize, 1u);
1198 bool is_array = output_var.arraySize > 0; 1201 bool is_array = output_var.arraySize > 0;
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
1383 glProgramParameteri(service_id(), 1386 glProgramParameteri(service_id(),
1384 PROGRAM_BINARY_RETRIEVABLE_HINT, 1387 PROGRAM_BINARY_RETRIEVABLE_HINT,
1385 GL_TRUE); 1388 GL_TRUE);
1386 } 1389 }
1387 glLinkProgram(service_id()); 1390 glLinkProgram(service_id());
1388 } 1391 }
1389 1392
1390 GLint success = 0; 1393 GLint success = 0;
1391 glGetProgramiv(service_id(), GL_LINK_STATUS, &success); 1394 glGetProgramiv(service_id(), GL_LINK_STATUS, &success);
1392 if (success == GL_TRUE) { 1395 if (success == GL_TRUE) {
1396 for (size_t ii = 0; ii < kMaxAttachedShaders; ++ii)
1397 shaders_from_last_successful_link_[ii] = attached_shaders_[ii];
1393 Update(); 1398 Update();
1394 if (link) { 1399 if (link) {
1395 // ANGLE updates the translated shader sources on link. 1400 // ANGLE updates the translated shader sources on link.
1396 for (auto shader : attached_shaders_) { 1401 for (auto shader : attached_shaders_) {
1397 shader->RefreshTranslatedShaderSource(); 1402 shader->RefreshTranslatedShaderSource();
1398 } 1403 }
1399 if (cache) { 1404 if (cache) {
1400 cache->SaveLinkedProgram( 1405 cache->SaveLinkedProgram(
1401 service_id(), attached_shaders_[0].get(), 1406 service_id(), attached_shaders_[0].get(),
1402 attached_shaders_[1].get(), &bind_attrib_location_map_, 1407 attached_shaders_[1].get(), &bind_attrib_location_map_,
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1505 return true; 1510 return true;
1506 size_t location_index = 1511 size_t location_index =
1507 GetUniformLocationIndexFromFakeLocation(fake_location); 1512 GetUniformLocationIndexFromFakeLocation(fake_location);
1508 if (location_index >= uniform_locations_.size()) 1513 if (location_index >= uniform_locations_.size())
1509 return false; 1514 return false;
1510 return uniform_locations_[location_index].IsInactive(); 1515 return uniform_locations_[location_index].IsInactive();
1511 } 1516 }
1512 1517
1513 const std::string* Program::GetAttribMappedName( 1518 const std::string* Program::GetAttribMappedName(
1514 const std::string& original_name) const { 1519 const std::string& original_name) const {
1515 for (auto shader : attached_shaders_) { 1520 for (auto shader : attached_shaders_) {
Ken Russell (switch to Gerrit) 2017/06/26 22:56:20 Same here.
1516 if (shader) { 1521 if (shader) {
1517 const std::string* mapped_name = 1522 const std::string* mapped_name =
1518 shader->GetAttribMappedName(original_name); 1523 shader->GetAttribMappedName(original_name);
1519 if (mapped_name) 1524 if (mapped_name)
1520 return mapped_name; 1525 return mapped_name;
1521 } 1526 }
1522 } 1527 }
1523 return nullptr; 1528 return nullptr;
1524 } 1529 }
1525 1530
1526 const std::string* Program::GetUniformMappedName( 1531 const std::string* Program::GetUniformMappedName(
1527 const std::string& original_name) const { 1532 const std::string& original_name) const {
1528 for (auto shader : attached_shaders_) { 1533 for (auto shader : attached_shaders_) {
Ken Russell (switch to Gerrit) 2017/06/26 22:56:20 Same here.
1529 if (shader) { 1534 if (shader) {
1530 const std::string* mapped_name = 1535 const std::string* mapped_name =
1531 shader->GetUniformMappedName(original_name); 1536 shader->GetUniformMappedName(original_name);
1532 if (mapped_name) 1537 if (mapped_name)
1533 return mapped_name; 1538 return mapped_name;
1534 } 1539 }
1535 } 1540 }
1536 return nullptr; 1541 return nullptr;
1537 } 1542 }
1538 1543
1539 const std::string* Program::GetOriginalNameFromHashedName( 1544 const std::string* Program::GetOriginalNameFromHashedName(
1540 const std::string& hashed_name) const { 1545 const std::string& hashed_name) const {
1541 for (auto shader : attached_shaders_) { 1546 for (auto shader : attached_shaders_) {
Ken Russell (switch to Gerrit) 2017/06/26 22:56:20 Same here. There are more places, too.
1542 if (shader) { 1547 if (shader) {
1543 const std::string* original_name = 1548 const std::string* original_name =
1544 shader->GetOriginalNameFromHashedName(hashed_name); 1549 shader->GetOriginalNameFromHashedName(hashed_name);
1545 if (original_name) 1550 if (original_name)
1546 return original_name; 1551 return original_name;
1547 } 1552 }
1548 } 1553 }
1549 return nullptr; 1554 return nullptr;
1550 } 1555 }
1551 1556
1552 const sh::Varying* Program::GetVaryingInfo( 1557 const sh::Varying* Program::GetVaryingInfo(
1553 const std::string& hashed_name) const { 1558 const std::string& hashed_name) const {
1554 for (auto shader : attached_shaders_) { 1559 for (auto shader : shaders_from_last_successful_link_) {
1555 if (shader) { 1560 if (shader) {
1556 const sh::Varying* info = shader->GetVaryingInfo(hashed_name); 1561 const sh::Varying* info = shader->GetVaryingInfo(hashed_name);
1557 if (info) 1562 if (info)
1558 return info; 1563 return info;
1559 } 1564 }
1560 } 1565 }
1561 return nullptr; 1566 return nullptr;
1562 } 1567 }
1563 1568
1564 const sh::InterfaceBlock* Program::GetInterfaceBlockInfo( 1569 const sh::InterfaceBlock* Program::GetInterfaceBlockInfo(
1565 const std::string& hashed_name) const { 1570 const std::string& hashed_name) const {
1566 for (auto shader : attached_shaders_) { 1571 for (auto shader : shaders_from_last_successful_link_) {
1567 if (shader) { 1572 if (shader) {
1568 const sh::InterfaceBlock* info = 1573 const sh::InterfaceBlock* info =
1569 shader->GetInterfaceBlockInfo(hashed_name); 1574 shader->GetInterfaceBlockInfo(hashed_name);
1570 if (info) 1575 if (info)
1571 return info; 1576 return info;
1572 } 1577 }
1573 } 1578 }
1574 return nullptr; 1579 return nullptr;
1575 } 1580 }
1576 1581
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1634 bind_program_output_location_index_map_[name] = 1639 bind_program_output_location_index_map_[name] =
1635 std::make_pair(color_name, index); 1640 std::make_pair(color_name, index);
1636 bind_program_output_location_index_map_[name + "[0]"] = 1641 bind_program_output_location_index_map_[name + "[0]"] =
1637 std::make_pair(color_name, index); 1642 std::make_pair(color_name, index);
1638 } 1643 }
1639 1644
1640 void Program::GetVertexAttribData( 1645 void Program::GetVertexAttribData(
1641 const std::string& name, std::string* original_name, GLenum* type) const { 1646 const std::string& name, std::string* original_name, GLenum* type) const {
1642 DCHECK(original_name); 1647 DCHECK(original_name);
1643 DCHECK(type); 1648 DCHECK(type);
1644 Shader* shader = attached_shaders_[ShaderTypeToIndex(GL_VERTEX_SHADER)].get(); 1649 Shader* shader =
1650 shaders_from_last_successful_link_[ShaderTypeToIndex(GL_VERTEX_SHADER)]
1651 .get();
1645 if (shader) { 1652 if (shader) {
1646 // Vertex attributes can not be arrays or structs (GLSL ES 3.00.4, section 1653 // Vertex attributes can not be arrays or structs (GLSL ES 3.00.4, section
1647 // 4.3.4, "Input Variables"), so the top level sh::Attribute returns the 1654 // 4.3.4, "Input Variables"), so the top level sh::Attribute returns the
1648 // information we need. 1655 // information we need.
1649 const sh::Attribute* info = shader->GetAttribInfo(name); 1656 const sh::Attribute* info = shader->GetAttribInfo(name);
1650 if (info) { 1657 if (info) {
1651 *original_name = info->name; 1658 *original_name = info->name;
1652 *type = info->type; 1659 *type = info->type;
1653 return; 1660 return;
1654 } 1661 }
(...skipping 1022 matching lines...) Expand 10 before | Expand all | Expand 10 after
2677 DCHECK(program); 2684 DCHECK(program);
2678 program->ClearUniforms(&zero_); 2685 program->ClearUniforms(&zero_);
2679 } 2686 }
2680 2687
2681 int32_t ProgramManager::MakeFakeLocation(int32_t index, int32_t element) { 2688 int32_t ProgramManager::MakeFakeLocation(int32_t index, int32_t element) {
2682 return index + element * 0x10000; 2689 return index + element * 0x10000;
2683 } 2690 }
2684 2691
2685 } // namespace gles2 2692 } // namespace gles2
2686 } // namespace gpu 2693 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/program_manager.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698