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 <algorithm> | 7 #include <algorithm> |
8 #include <set> | 8 #include <set> |
9 #include <utility> | 9 #include <utility> |
10 #include <vector> | 10 #include <vector> |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 return false; | 111 return false; |
112 } | 112 } |
113 index = index * 10 + digit; | 113 index = index * 10 + digit; |
114 } | 114 } |
115 | 115 |
116 *element_index = index; | 116 *element_index = index; |
117 *new_name = name.substr(0, open_pos); | 117 *new_name = name.substr(0, open_pos); |
118 return true; | 118 return true; |
119 } | 119 } |
120 | 120 |
| 121 bool IsBuiltInVarying(const std::string& name) { |
| 122 // Built-in variables. |
| 123 const char* kBuiltInVaryings[] = { |
| 124 "gl_FragCoord", |
| 125 "gl_FrontFacing", |
| 126 "gl_PointCoord" |
| 127 }; |
| 128 for (size_t ii = 0; ii < arraysize(kBuiltInVaryings); ++ii) { |
| 129 if (name == kBuiltInVaryings[ii]) |
| 130 return true; |
| 131 } |
| 132 return false; |
| 133 } |
| 134 |
121 } // anonymous namespace. | 135 } // anonymous namespace. |
122 | 136 |
123 Program::UniformInfo::UniformInfo() | 137 Program::UniformInfo::UniformInfo() |
124 : size(0), | 138 : size(0), |
125 type(GL_NONE), | 139 type(GL_NONE), |
126 fake_location_base(0), | 140 fake_location_base(0), |
127 is_array(false) { | 141 is_array(false) { |
128 } | 142 } |
129 | 143 |
130 Program::UniformInfo::UniformInfo( | 144 Program::UniformInfo::UniformInfo( |
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
537 if (DetectUniformsMismatch()) { | 551 if (DetectUniformsMismatch()) { |
538 set_log_info("Uniforms with the same name but different type/precision"); | 552 set_log_info("Uniforms with the same name but different type/precision"); |
539 return false; | 553 return false; |
540 } | 554 } |
541 if (DetectVaryingsMismatch()) { | 555 if (DetectVaryingsMismatch()) { |
542 set_log_info("Varyings with the same name but different type, " | 556 set_log_info("Varyings with the same name but different type, " |
543 "or statically used varyings in fragment shader are not " | 557 "or statically used varyings in fragment shader are not " |
544 "declared in vertex shader"); | 558 "declared in vertex shader"); |
545 return false; | 559 return false; |
546 } | 560 } |
| 561 if (!CheckVaryingsPacking()) { |
| 562 set_log_info("Varyings over maximum register limit"); |
| 563 return false; |
| 564 } |
547 | 565 |
548 TimeTicks before_time = TimeTicks::HighResNow(); | 566 TimeTicks before_time = TimeTicks::HighResNow(); |
549 bool link = true; | 567 bool link = true; |
550 ProgramCache* cache = manager_->program_cache_; | 568 ProgramCache* cache = manager_->program_cache_; |
551 if (cache) { | 569 if (cache) { |
552 DCHECK(attached_shaders_[0]->signature_source() && | 570 DCHECK(attached_shaders_[0]->signature_source() && |
553 attached_shaders_[1]->signature_source()); | 571 attached_shaders_[1]->signature_source()); |
554 ProgramCache::LinkedProgramStatus status = cache->GetLinkedProgramStatus( | 572 ProgramCache::LinkedProgramStatus status = cache->GetLinkedProgramStatus( |
555 *attached_shaders_[0]->signature_source(), | 573 *attached_shaders_[0]->signature_source(), |
556 vertex_translator, | 574 vertex_translator, |
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1027 attached_shaders_[1] && | 1045 attached_shaders_[1] && |
1028 attached_shaders_[1]->shader_type() == GL_FRAGMENT_SHADER); | 1046 attached_shaders_[1]->shader_type() == GL_FRAGMENT_SHADER); |
1029 const ShaderTranslator::VariableMap* vertex_varyings = | 1047 const ShaderTranslator::VariableMap* vertex_varyings = |
1030 &(attached_shaders_[0]->varying_map()); | 1048 &(attached_shaders_[0]->varying_map()); |
1031 const ShaderTranslator::VariableMap* fragment_varyings = | 1049 const ShaderTranslator::VariableMap* fragment_varyings = |
1032 &(attached_shaders_[1]->varying_map()); | 1050 &(attached_shaders_[1]->varying_map()); |
1033 | 1051 |
1034 for (ShaderTranslator::VariableMap::const_iterator iter = | 1052 for (ShaderTranslator::VariableMap::const_iterator iter = |
1035 fragment_varyings->begin(); | 1053 fragment_varyings->begin(); |
1036 iter != fragment_varyings->end(); ++iter) { | 1054 iter != fragment_varyings->end(); ++iter) { |
1037 // Built-in variables. | |
1038 const char* kBuiltInVaryings[] = { | |
1039 "gl_FragCoord", | |
1040 "gl_FrontFacing", | |
1041 "gl_PointCoord" | |
1042 }; | |
1043 const std::string& name = iter->first; | 1055 const std::string& name = iter->first; |
1044 bool is_built_in = false; | 1056 if (IsBuiltInVarying(name)) |
1045 for (size_t ii = 0; ii < arraysize(kBuiltInVaryings); ++ii) { | |
1046 if (name == kBuiltInVaryings[ii]) { | |
1047 is_built_in = true; | |
1048 break; | |
1049 } | |
1050 } | |
1051 if (is_built_in) | |
1052 continue; | 1057 continue; |
1053 | 1058 |
1054 ShaderTranslator::VariableMap::const_iterator hit = | 1059 ShaderTranslator::VariableMap::const_iterator hit = |
1055 vertex_varyings->find(name); | 1060 vertex_varyings->find(name); |
1056 if (hit == vertex_varyings->end()) { | 1061 if (hit == vertex_varyings->end()) { |
1057 if (iter->second.static_use) | 1062 if (iter->second.static_use) |
1058 return true; | 1063 return true; |
1059 continue; | 1064 continue; |
1060 } | 1065 } |
1061 | 1066 |
1062 if (hit->second.type != iter->second.type || | 1067 if (hit->second.type != iter->second.type || |
1063 hit->second.size != iter->second.size) | 1068 hit->second.size != iter->second.size) |
1064 return true; | 1069 return true; |
1065 | 1070 |
1066 } | 1071 } |
1067 return false; | 1072 return false; |
1068 } | 1073 } |
1069 | 1074 |
| 1075 bool Program::CheckVaryingsPacking() const { |
| 1076 DCHECK(attached_shaders_[0] && |
| 1077 attached_shaders_[0]->shader_type() == GL_VERTEX_SHADER && |
| 1078 attached_shaders_[1] && |
| 1079 attached_shaders_[1]->shader_type() == GL_FRAGMENT_SHADER); |
| 1080 const ShaderTranslator::VariableMap* vertex_varyings = |
| 1081 &(attached_shaders_[0]->varying_map()); |
| 1082 const ShaderTranslator::VariableMap* fragment_varyings = |
| 1083 &(attached_shaders_[1]->varying_map()); |
| 1084 |
| 1085 std::map<std::string, ShVariableInfo> combined_map; |
| 1086 |
| 1087 for (ShaderTranslator::VariableMap::const_iterator iter = |
| 1088 fragment_varyings->begin(); |
| 1089 iter != fragment_varyings->end(); ++iter) { |
| 1090 if (!iter->second.static_use) |
| 1091 continue; |
| 1092 if (!IsBuiltInVarying(iter->first)) { |
| 1093 ShaderTranslator::VariableMap::const_iterator vertex_iter = |
| 1094 vertex_varyings->find(iter->first); |
| 1095 if (vertex_iter == vertex_varyings->end() || |
| 1096 !vertex_iter->second.static_use) |
| 1097 continue; |
| 1098 } |
| 1099 |
| 1100 ShVariableInfo var; |
| 1101 var.type = static_cast<ShDataType>(iter->second.type); |
| 1102 var.size = iter->second.size; |
| 1103 combined_map[iter->first] = var; |
| 1104 } |
| 1105 |
| 1106 if (combined_map.size() == 0) |
| 1107 return true; |
| 1108 scoped_ptr<ShVariableInfo[]> variables( |
| 1109 new ShVariableInfo[combined_map.size()]); |
| 1110 size_t index = 0; |
| 1111 for (std::map<std::string, ShVariableInfo>::const_iterator iter = |
| 1112 combined_map.begin(); |
| 1113 iter != combined_map.end(); ++iter) { |
| 1114 variables[index].type = iter->second.type; |
| 1115 variables[index].size = iter->second.size; |
| 1116 ++index; |
| 1117 } |
| 1118 return ShCheckVariablesWithinPackingLimits( |
| 1119 static_cast<int>(manager_->max_varying_vectors()), |
| 1120 variables.get(), |
| 1121 combined_map.size()) == 1; |
| 1122 } |
| 1123 |
1070 static uint32 ComputeOffset(const void* start, const void* position) { | 1124 static uint32 ComputeOffset(const void* start, const void* position) { |
1071 return static_cast<const uint8*>(position) - | 1125 return static_cast<const uint8*>(position) - |
1072 static_cast<const uint8*>(start); | 1126 static_cast<const uint8*>(start); |
1073 } | 1127 } |
1074 | 1128 |
1075 void Program::GetProgramInfo( | 1129 void Program::GetProgramInfo( |
1076 ProgramManager* manager, CommonDecoder::Bucket* bucket) const { | 1130 ProgramManager* manager, CommonDecoder::Bucket* bucket) const { |
1077 // NOTE: It seems to me the math in here does not need check for overflow | 1131 // NOTE: It seems to me the math in here does not need check for overflow |
1078 // because the data being calucated from has various small limits. The max | 1132 // because the data being calucated from has various small limits. The max |
1079 // number of attribs + uniforms is somewhere well under 1024. The maximum size | 1133 // number of attribs + uniforms is somewhere well under 1024. The maximum size |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1157 if (manager_) { | 1211 if (manager_) { |
1158 if (manager_->have_context_) { | 1212 if (manager_->have_context_) { |
1159 glDeleteProgram(service_id()); | 1213 glDeleteProgram(service_id()); |
1160 } | 1214 } |
1161 manager_->StopTracking(this); | 1215 manager_->StopTracking(this); |
1162 manager_ = NULL; | 1216 manager_ = NULL; |
1163 } | 1217 } |
1164 } | 1218 } |
1165 | 1219 |
1166 | 1220 |
1167 ProgramManager::ProgramManager(ProgramCache* program_cache) | 1221 ProgramManager::ProgramManager(ProgramCache* program_cache, |
| 1222 uint32 max_varying_vectors) |
1168 : program_count_(0), | 1223 : program_count_(0), |
1169 have_context_(true), | 1224 have_context_(true), |
1170 disable_workarounds_( | 1225 disable_workarounds_( |
1171 CommandLine::ForCurrentProcess()->HasSwitch( | 1226 CommandLine::ForCurrentProcess()->HasSwitch( |
1172 switches::kDisableGpuDriverBugWorkarounds)), | 1227 switches::kDisableGpuDriverBugWorkarounds)), |
1173 program_cache_(program_cache) { } | 1228 program_cache_(program_cache), |
| 1229 max_varying_vectors_(max_varying_vectors) { } |
1174 | 1230 |
1175 ProgramManager::~ProgramManager() { | 1231 ProgramManager::~ProgramManager() { |
1176 DCHECK(programs_.empty()); | 1232 DCHECK(programs_.empty()); |
1177 } | 1233 } |
1178 | 1234 |
1179 void ProgramManager::Destroy(bool have_context) { | 1235 void ProgramManager::Destroy(bool have_context) { |
1180 have_context_ = have_context; | 1236 have_context_ = have_context; |
1181 programs_.clear(); | 1237 programs_.clear(); |
1182 } | 1238 } |
1183 | 1239 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1282 program->ClearUniforms(&zero_); | 1338 program->ClearUniforms(&zero_); |
1283 } | 1339 } |
1284 } | 1340 } |
1285 | 1341 |
1286 int32 ProgramManager::MakeFakeLocation(int32 index, int32 element) { | 1342 int32 ProgramManager::MakeFakeLocation(int32 index, int32 element) { |
1287 return index + element * 0x10000; | 1343 return index + element * 0x10000; |
1288 } | 1344 } |
1289 | 1345 |
1290 } // namespace gles2 | 1346 } // namespace gles2 |
1291 } // namespace gpu | 1347 } // namespace gpu |
OLD | NEW |