1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/angle/src/compiler/ShaderLang.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,363 @@ 1.4 +// 1.5 +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. 1.6 +// Use of this source code is governed by a BSD-style license that can be 1.7 +// found in the LICENSE file. 1.8 +// 1.9 + 1.10 +// 1.11 +// Implement the top-level of interface to the compiler, 1.12 +// as defined in ShaderLang.h 1.13 +// 1.14 + 1.15 +#include "GLSLANG/ShaderLang.h" 1.16 + 1.17 +#include "compiler/InitializeDll.h" 1.18 +#include "compiler/preprocessor/length_limits.h" 1.19 +#include "compiler/ShHandle.h" 1.20 +#include "compiler/TranslatorHLSL.h" 1.21 + 1.22 +// 1.23 +// This is the platform independent interface between an OGL driver 1.24 +// and the shading language compiler. 1.25 +// 1.26 + 1.27 +static bool checkActiveUniformAndAttribMaxLengths(const ShHandle handle, 1.28 + size_t expectedValue) 1.29 +{ 1.30 + size_t activeUniformLimit = 0; 1.31 + ShGetInfo(handle, SH_ACTIVE_UNIFORM_MAX_LENGTH, &activeUniformLimit); 1.32 + size_t activeAttribLimit = 0; 1.33 + ShGetInfo(handle, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, &activeAttribLimit); 1.34 + return (expectedValue == activeUniformLimit && expectedValue == activeAttribLimit); 1.35 +} 1.36 + 1.37 +static bool checkMappedNameMaxLength(const ShHandle handle, size_t expectedValue) 1.38 +{ 1.39 + size_t mappedNameMaxLength = 0; 1.40 + ShGetInfo(handle, SH_MAPPED_NAME_MAX_LENGTH, &mappedNameMaxLength); 1.41 + return (expectedValue == mappedNameMaxLength); 1.42 +} 1.43 + 1.44 +static void getVariableInfo(ShShaderInfo varType, 1.45 + const ShHandle handle, 1.46 + int index, 1.47 + size_t* length, 1.48 + int* size, 1.49 + ShDataType* type, 1.50 + char* name, 1.51 + char* mappedName) 1.52 +{ 1.53 + if (!handle || !size || !type || !name) 1.54 + return; 1.55 + ASSERT((varType == SH_ACTIVE_ATTRIBUTES) || 1.56 + (varType == SH_ACTIVE_UNIFORMS)); 1.57 + 1.58 + TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle); 1.59 + TCompiler* compiler = base->getAsCompiler(); 1.60 + if (compiler == 0) 1.61 + return; 1.62 + 1.63 + const TVariableInfoList& varList = varType == SH_ACTIVE_ATTRIBUTES ? 1.64 + compiler->getAttribs() : compiler->getUniforms(); 1.65 + if (index < 0 || index >= static_cast<int>(varList.size())) 1.66 + return; 1.67 + 1.68 + const TVariableInfo& varInfo = varList[index]; 1.69 + if (length) *length = varInfo.name.size(); 1.70 + *size = varInfo.size; 1.71 + *type = varInfo.type; 1.72 + 1.73 + // This size must match that queried by 1.74 + // SH_ACTIVE_UNIFORM_MAX_LENGTH and SH_ACTIVE_ATTRIBUTE_MAX_LENGTH 1.75 + // in ShGetInfo, below. 1.76 + size_t activeUniformAndAttribLength = 1 + MAX_SYMBOL_NAME_LEN; 1.77 + ASSERT(checkActiveUniformAndAttribMaxLengths(handle, activeUniformAndAttribLength)); 1.78 + strncpy(name, varInfo.name.c_str(), activeUniformAndAttribLength); 1.79 + name[activeUniformAndAttribLength - 1] = 0; 1.80 + if (mappedName) { 1.81 + // This size must match that queried by 1.82 + // SH_MAPPED_NAME_MAX_LENGTH in ShGetInfo, below. 1.83 + size_t maxMappedNameLength = 1 + MAX_SYMBOL_NAME_LEN; 1.84 + ASSERT(checkMappedNameMaxLength(handle, maxMappedNameLength)); 1.85 + strncpy(mappedName, varInfo.mappedName.c_str(), maxMappedNameLength); 1.86 + mappedName[maxMappedNameLength - 1] = 0; 1.87 + } 1.88 +} 1.89 + 1.90 +// 1.91 +// Driver must call this first, once, before doing any other compiler operations. 1.92 +// Subsequent calls to this function are no-op. 1.93 +// 1.94 +int ShInitialize() 1.95 +{ 1.96 + static const bool kInitialized = InitProcess(); 1.97 + return kInitialized ? 1 : 0; 1.98 +} 1.99 + 1.100 +// 1.101 +// Cleanup symbol tables 1.102 +// 1.103 +int ShFinalize() 1.104 +{ 1.105 + DetachProcess(); 1.106 + return 1; 1.107 +} 1.108 + 1.109 +// 1.110 +// Initialize built-in resources with minimum expected values. 1.111 +// 1.112 +void ShInitBuiltInResources(ShBuiltInResources* resources) 1.113 +{ 1.114 + // Constants. 1.115 + resources->MaxVertexAttribs = 8; 1.116 + resources->MaxVertexUniformVectors = 128; 1.117 + resources->MaxVaryingVectors = 8; 1.118 + resources->MaxVertexTextureImageUnits = 0; 1.119 + resources->MaxCombinedTextureImageUnits = 8; 1.120 + resources->MaxTextureImageUnits = 8; 1.121 + resources->MaxFragmentUniformVectors = 16; 1.122 + resources->MaxDrawBuffers = 1; 1.123 + 1.124 + // Extensions. 1.125 + resources->OES_standard_derivatives = 0; 1.126 + resources->OES_EGL_image_external = 0; 1.127 + resources->ARB_texture_rectangle = 0; 1.128 + resources->EXT_draw_buffers = 0; 1.129 + resources->EXT_frag_depth = 0; 1.130 + 1.131 + // Disable highp precision in fragment shader by default. 1.132 + resources->FragmentPrecisionHigh = 0; 1.133 + 1.134 + // Disable name hashing by default. 1.135 + resources->HashFunction = NULL; 1.136 + 1.137 + resources->ArrayIndexClampingStrategy = SH_CLAMP_WITH_CLAMP_INTRINSIC; 1.138 +} 1.139 + 1.140 +// 1.141 +// Driver calls these to create and destroy compiler objects. 1.142 +// 1.143 +ShHandle ShConstructCompiler(ShShaderType type, ShShaderSpec spec, 1.144 + ShShaderOutput output, 1.145 + const ShBuiltInResources* resources) 1.146 +{ 1.147 + TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(type, spec, output)); 1.148 + TCompiler* compiler = base->getAsCompiler(); 1.149 + if (compiler == 0) 1.150 + return 0; 1.151 + 1.152 + // Generate built-in symbol table. 1.153 + if (!compiler->Init(*resources)) { 1.154 + ShDestruct(base); 1.155 + return 0; 1.156 + } 1.157 + 1.158 + return reinterpret_cast<void*>(base); 1.159 +} 1.160 + 1.161 +void ShDestruct(ShHandle handle) 1.162 +{ 1.163 + if (handle == 0) 1.164 + return; 1.165 + 1.166 + TShHandleBase* base = static_cast<TShHandleBase*>(handle); 1.167 + 1.168 + if (base->getAsCompiler()) 1.169 + DeleteCompiler(base->getAsCompiler()); 1.170 +} 1.171 + 1.172 +// 1.173 +// Do an actual compile on the given strings. The result is left 1.174 +// in the given compile object. 1.175 +// 1.176 +// Return: The return value of ShCompile is really boolean, indicating 1.177 +// success or failure. 1.178 +// 1.179 +int ShCompile( 1.180 + const ShHandle handle, 1.181 + const char* const shaderStrings[], 1.182 + size_t numStrings, 1.183 + int compileOptions) 1.184 +{ 1.185 + if (handle == 0) 1.186 + return 0; 1.187 + 1.188 + TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle); 1.189 + TCompiler* compiler = base->getAsCompiler(); 1.190 + if (compiler == 0) 1.191 + return 0; 1.192 + 1.193 + bool success = compiler->compile(shaderStrings, numStrings, compileOptions); 1.194 + return success ? 1 : 0; 1.195 +} 1.196 + 1.197 +void ShGetInfo(const ShHandle handle, ShShaderInfo pname, size_t* params) 1.198 +{ 1.199 + if (!handle || !params) 1.200 + return; 1.201 + 1.202 + TShHandleBase* base = static_cast<TShHandleBase*>(handle); 1.203 + TCompiler* compiler = base->getAsCompiler(); 1.204 + if (!compiler) return; 1.205 + 1.206 + switch(pname) 1.207 + { 1.208 + case SH_INFO_LOG_LENGTH: 1.209 + *params = compiler->getInfoSink().info.size() + 1; 1.210 + break; 1.211 + case SH_OBJECT_CODE_LENGTH: 1.212 + *params = compiler->getInfoSink().obj.size() + 1; 1.213 + break; 1.214 + case SH_ACTIVE_UNIFORMS: 1.215 + *params = compiler->getUniforms().size(); 1.216 + break; 1.217 + case SH_ACTIVE_UNIFORM_MAX_LENGTH: 1.218 + *params = 1 + MAX_SYMBOL_NAME_LEN; 1.219 + break; 1.220 + case SH_ACTIVE_ATTRIBUTES: 1.221 + *params = compiler->getAttribs().size(); 1.222 + break; 1.223 + case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH: 1.224 + *params = 1 + MAX_SYMBOL_NAME_LEN; 1.225 + break; 1.226 + case SH_MAPPED_NAME_MAX_LENGTH: 1.227 + // Use longer length than MAX_SHORTENED_IDENTIFIER_SIZE to 1.228 + // handle array and struct dereferences. 1.229 + *params = 1 + MAX_SYMBOL_NAME_LEN; 1.230 + break; 1.231 + case SH_NAME_MAX_LENGTH: 1.232 + *params = 1 + MAX_SYMBOL_NAME_LEN; 1.233 + break; 1.234 + case SH_HASHED_NAME_MAX_LENGTH: 1.235 + if (compiler->getHashFunction() == NULL) { 1.236 + *params = 0; 1.237 + } else { 1.238 + // 64 bits hashing output requires 16 bytes for hex 1.239 + // representation. 1.240 + const char HashedNamePrefix[] = HASHED_NAME_PREFIX; 1.241 + *params = 16 + sizeof(HashedNamePrefix); 1.242 + } 1.243 + break; 1.244 + case SH_HASHED_NAMES_COUNT: 1.245 + *params = compiler->getNameMap().size(); 1.246 + break; 1.247 + default: UNREACHABLE(); 1.248 + } 1.249 +} 1.250 + 1.251 +// 1.252 +// Return any compiler log of messages for the application. 1.253 +// 1.254 +void ShGetInfoLog(const ShHandle handle, char* infoLog) 1.255 +{ 1.256 + if (!handle || !infoLog) 1.257 + return; 1.258 + 1.259 + TShHandleBase* base = static_cast<TShHandleBase*>(handle); 1.260 + TCompiler* compiler = base->getAsCompiler(); 1.261 + if (!compiler) return; 1.262 + 1.263 + TInfoSink& infoSink = compiler->getInfoSink(); 1.264 + strcpy(infoLog, infoSink.info.c_str()); 1.265 +} 1.266 + 1.267 +// 1.268 +// Return any object code. 1.269 +// 1.270 +void ShGetObjectCode(const ShHandle handle, char* objCode) 1.271 +{ 1.272 + if (!handle || !objCode) 1.273 + return; 1.274 + 1.275 + TShHandleBase* base = static_cast<TShHandleBase*>(handle); 1.276 + TCompiler* compiler = base->getAsCompiler(); 1.277 + if (!compiler) return; 1.278 + 1.279 + TInfoSink& infoSink = compiler->getInfoSink(); 1.280 + strcpy(objCode, infoSink.obj.c_str()); 1.281 +} 1.282 + 1.283 +void ShGetActiveAttrib(const ShHandle handle, 1.284 + int index, 1.285 + size_t* length, 1.286 + int* size, 1.287 + ShDataType* type, 1.288 + char* name, 1.289 + char* mappedName) 1.290 +{ 1.291 + getVariableInfo(SH_ACTIVE_ATTRIBUTES, 1.292 + handle, index, length, size, type, name, mappedName); 1.293 +} 1.294 + 1.295 +void ShGetActiveUniform(const ShHandle handle, 1.296 + int index, 1.297 + size_t* length, 1.298 + int* size, 1.299 + ShDataType* type, 1.300 + char* name, 1.301 + char* mappedName) 1.302 +{ 1.303 + getVariableInfo(SH_ACTIVE_UNIFORMS, 1.304 + handle, index, length, size, type, name, mappedName); 1.305 +} 1.306 + 1.307 +void ShGetNameHashingEntry(const ShHandle handle, 1.308 + int index, 1.309 + char* name, 1.310 + char* hashedName) 1.311 +{ 1.312 + if (!handle || !name || !hashedName || index < 0) 1.313 + return; 1.314 + 1.315 + TShHandleBase* base = static_cast<TShHandleBase*>(handle); 1.316 + TCompiler* compiler = base->getAsCompiler(); 1.317 + if (!compiler) return; 1.318 + 1.319 + const NameMap& nameMap = compiler->getNameMap(); 1.320 + if (index >= static_cast<int>(nameMap.size())) 1.321 + return; 1.322 + 1.323 + NameMap::const_iterator it = nameMap.begin(); 1.324 + for (int i = 0; i < index; ++i) 1.325 + ++it; 1.326 + 1.327 + size_t len = it->first.length() + 1; 1.328 + size_t max_len = 0; 1.329 + ShGetInfo(handle, SH_NAME_MAX_LENGTH, &max_len); 1.330 + if (len > max_len) { 1.331 + ASSERT(false); 1.332 + len = max_len; 1.333 + } 1.334 + strncpy(name, it->first.c_str(), len); 1.335 + // To be on the safe side in case the source is longer than expected. 1.336 + name[len - 1] = '\0'; 1.337 + 1.338 + len = it->second.length() + 1; 1.339 + max_len = 0; 1.340 + ShGetInfo(handle, SH_HASHED_NAME_MAX_LENGTH, &max_len); 1.341 + if (len > max_len) { 1.342 + ASSERT(false); 1.343 + len = max_len; 1.344 + } 1.345 + strncpy(hashedName, it->second.c_str(), len); 1.346 + // To be on the safe side in case the source is longer than expected. 1.347 + hashedName[len - 1] = '\0'; 1.348 +} 1.349 + 1.350 +void ShGetInfoPointer(const ShHandle handle, ShShaderInfo pname, void** params) 1.351 +{ 1.352 + if (!handle || !params) 1.353 + return; 1.354 + 1.355 + TShHandleBase* base = static_cast<TShHandleBase*>(handle); 1.356 + TranslatorHLSL* translator = base->getAsTranslatorHLSL(); 1.357 + if (!translator) return; 1.358 + 1.359 + switch(pname) 1.360 + { 1.361 + case SH_ACTIVE_UNIFORMS_ARRAY: 1.362 + *params = (void*)&translator->getUniforms(); 1.363 + break; 1.364 + default: UNREACHABLE(); 1.365 + } 1.366 +}