gfx/angle/src/compiler/ShaderLang.cpp

Wed, 31 Dec 2014 07:16:47 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:16:47 +0100
branch
TOR_BUG_9701
changeset 3
141e0f1194b1
permissions
-rw-r--r--

Revert simplistic fix pending revisit of Mozilla integration attempt.

michael@0 1 //
michael@0 2 // Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
michael@0 3 // Use of this source code is governed by a BSD-style license that can be
michael@0 4 // found in the LICENSE file.
michael@0 5 //
michael@0 6
michael@0 7 //
michael@0 8 // Implement the top-level of interface to the compiler,
michael@0 9 // as defined in ShaderLang.h
michael@0 10 //
michael@0 11
michael@0 12 #include "GLSLANG/ShaderLang.h"
michael@0 13
michael@0 14 #include "compiler/InitializeDll.h"
michael@0 15 #include "compiler/preprocessor/length_limits.h"
michael@0 16 #include "compiler/ShHandle.h"
michael@0 17 #include "compiler/TranslatorHLSL.h"
michael@0 18
michael@0 19 //
michael@0 20 // This is the platform independent interface between an OGL driver
michael@0 21 // and the shading language compiler.
michael@0 22 //
michael@0 23
michael@0 24 static bool checkActiveUniformAndAttribMaxLengths(const ShHandle handle,
michael@0 25 size_t expectedValue)
michael@0 26 {
michael@0 27 size_t activeUniformLimit = 0;
michael@0 28 ShGetInfo(handle, SH_ACTIVE_UNIFORM_MAX_LENGTH, &activeUniformLimit);
michael@0 29 size_t activeAttribLimit = 0;
michael@0 30 ShGetInfo(handle, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, &activeAttribLimit);
michael@0 31 return (expectedValue == activeUniformLimit && expectedValue == activeAttribLimit);
michael@0 32 }
michael@0 33
michael@0 34 static bool checkMappedNameMaxLength(const ShHandle handle, size_t expectedValue)
michael@0 35 {
michael@0 36 size_t mappedNameMaxLength = 0;
michael@0 37 ShGetInfo(handle, SH_MAPPED_NAME_MAX_LENGTH, &mappedNameMaxLength);
michael@0 38 return (expectedValue == mappedNameMaxLength);
michael@0 39 }
michael@0 40
michael@0 41 static void getVariableInfo(ShShaderInfo varType,
michael@0 42 const ShHandle handle,
michael@0 43 int index,
michael@0 44 size_t* length,
michael@0 45 int* size,
michael@0 46 ShDataType* type,
michael@0 47 char* name,
michael@0 48 char* mappedName)
michael@0 49 {
michael@0 50 if (!handle || !size || !type || !name)
michael@0 51 return;
michael@0 52 ASSERT((varType == SH_ACTIVE_ATTRIBUTES) ||
michael@0 53 (varType == SH_ACTIVE_UNIFORMS));
michael@0 54
michael@0 55 TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
michael@0 56 TCompiler* compiler = base->getAsCompiler();
michael@0 57 if (compiler == 0)
michael@0 58 return;
michael@0 59
michael@0 60 const TVariableInfoList& varList = varType == SH_ACTIVE_ATTRIBUTES ?
michael@0 61 compiler->getAttribs() : compiler->getUniforms();
michael@0 62 if (index < 0 || index >= static_cast<int>(varList.size()))
michael@0 63 return;
michael@0 64
michael@0 65 const TVariableInfo& varInfo = varList[index];
michael@0 66 if (length) *length = varInfo.name.size();
michael@0 67 *size = varInfo.size;
michael@0 68 *type = varInfo.type;
michael@0 69
michael@0 70 // This size must match that queried by
michael@0 71 // SH_ACTIVE_UNIFORM_MAX_LENGTH and SH_ACTIVE_ATTRIBUTE_MAX_LENGTH
michael@0 72 // in ShGetInfo, below.
michael@0 73 size_t activeUniformAndAttribLength = 1 + MAX_SYMBOL_NAME_LEN;
michael@0 74 ASSERT(checkActiveUniformAndAttribMaxLengths(handle, activeUniformAndAttribLength));
michael@0 75 strncpy(name, varInfo.name.c_str(), activeUniformAndAttribLength);
michael@0 76 name[activeUniformAndAttribLength - 1] = 0;
michael@0 77 if (mappedName) {
michael@0 78 // This size must match that queried by
michael@0 79 // SH_MAPPED_NAME_MAX_LENGTH in ShGetInfo, below.
michael@0 80 size_t maxMappedNameLength = 1 + MAX_SYMBOL_NAME_LEN;
michael@0 81 ASSERT(checkMappedNameMaxLength(handle, maxMappedNameLength));
michael@0 82 strncpy(mappedName, varInfo.mappedName.c_str(), maxMappedNameLength);
michael@0 83 mappedName[maxMappedNameLength - 1] = 0;
michael@0 84 }
michael@0 85 }
michael@0 86
michael@0 87 //
michael@0 88 // Driver must call this first, once, before doing any other compiler operations.
michael@0 89 // Subsequent calls to this function are no-op.
michael@0 90 //
michael@0 91 int ShInitialize()
michael@0 92 {
michael@0 93 static const bool kInitialized = InitProcess();
michael@0 94 return kInitialized ? 1 : 0;
michael@0 95 }
michael@0 96
michael@0 97 //
michael@0 98 // Cleanup symbol tables
michael@0 99 //
michael@0 100 int ShFinalize()
michael@0 101 {
michael@0 102 DetachProcess();
michael@0 103 return 1;
michael@0 104 }
michael@0 105
michael@0 106 //
michael@0 107 // Initialize built-in resources with minimum expected values.
michael@0 108 //
michael@0 109 void ShInitBuiltInResources(ShBuiltInResources* resources)
michael@0 110 {
michael@0 111 // Constants.
michael@0 112 resources->MaxVertexAttribs = 8;
michael@0 113 resources->MaxVertexUniformVectors = 128;
michael@0 114 resources->MaxVaryingVectors = 8;
michael@0 115 resources->MaxVertexTextureImageUnits = 0;
michael@0 116 resources->MaxCombinedTextureImageUnits = 8;
michael@0 117 resources->MaxTextureImageUnits = 8;
michael@0 118 resources->MaxFragmentUniformVectors = 16;
michael@0 119 resources->MaxDrawBuffers = 1;
michael@0 120
michael@0 121 // Extensions.
michael@0 122 resources->OES_standard_derivatives = 0;
michael@0 123 resources->OES_EGL_image_external = 0;
michael@0 124 resources->ARB_texture_rectangle = 0;
michael@0 125 resources->EXT_draw_buffers = 0;
michael@0 126 resources->EXT_frag_depth = 0;
michael@0 127
michael@0 128 // Disable highp precision in fragment shader by default.
michael@0 129 resources->FragmentPrecisionHigh = 0;
michael@0 130
michael@0 131 // Disable name hashing by default.
michael@0 132 resources->HashFunction = NULL;
michael@0 133
michael@0 134 resources->ArrayIndexClampingStrategy = SH_CLAMP_WITH_CLAMP_INTRINSIC;
michael@0 135 }
michael@0 136
michael@0 137 //
michael@0 138 // Driver calls these to create and destroy compiler objects.
michael@0 139 //
michael@0 140 ShHandle ShConstructCompiler(ShShaderType type, ShShaderSpec spec,
michael@0 141 ShShaderOutput output,
michael@0 142 const ShBuiltInResources* resources)
michael@0 143 {
michael@0 144 TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(type, spec, output));
michael@0 145 TCompiler* compiler = base->getAsCompiler();
michael@0 146 if (compiler == 0)
michael@0 147 return 0;
michael@0 148
michael@0 149 // Generate built-in symbol table.
michael@0 150 if (!compiler->Init(*resources)) {
michael@0 151 ShDestruct(base);
michael@0 152 return 0;
michael@0 153 }
michael@0 154
michael@0 155 return reinterpret_cast<void*>(base);
michael@0 156 }
michael@0 157
michael@0 158 void ShDestruct(ShHandle handle)
michael@0 159 {
michael@0 160 if (handle == 0)
michael@0 161 return;
michael@0 162
michael@0 163 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
michael@0 164
michael@0 165 if (base->getAsCompiler())
michael@0 166 DeleteCompiler(base->getAsCompiler());
michael@0 167 }
michael@0 168
michael@0 169 //
michael@0 170 // Do an actual compile on the given strings. The result is left
michael@0 171 // in the given compile object.
michael@0 172 //
michael@0 173 // Return: The return value of ShCompile is really boolean, indicating
michael@0 174 // success or failure.
michael@0 175 //
michael@0 176 int ShCompile(
michael@0 177 const ShHandle handle,
michael@0 178 const char* const shaderStrings[],
michael@0 179 size_t numStrings,
michael@0 180 int compileOptions)
michael@0 181 {
michael@0 182 if (handle == 0)
michael@0 183 return 0;
michael@0 184
michael@0 185 TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
michael@0 186 TCompiler* compiler = base->getAsCompiler();
michael@0 187 if (compiler == 0)
michael@0 188 return 0;
michael@0 189
michael@0 190 bool success = compiler->compile(shaderStrings, numStrings, compileOptions);
michael@0 191 return success ? 1 : 0;
michael@0 192 }
michael@0 193
michael@0 194 void ShGetInfo(const ShHandle handle, ShShaderInfo pname, size_t* params)
michael@0 195 {
michael@0 196 if (!handle || !params)
michael@0 197 return;
michael@0 198
michael@0 199 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
michael@0 200 TCompiler* compiler = base->getAsCompiler();
michael@0 201 if (!compiler) return;
michael@0 202
michael@0 203 switch(pname)
michael@0 204 {
michael@0 205 case SH_INFO_LOG_LENGTH:
michael@0 206 *params = compiler->getInfoSink().info.size() + 1;
michael@0 207 break;
michael@0 208 case SH_OBJECT_CODE_LENGTH:
michael@0 209 *params = compiler->getInfoSink().obj.size() + 1;
michael@0 210 break;
michael@0 211 case SH_ACTIVE_UNIFORMS:
michael@0 212 *params = compiler->getUniforms().size();
michael@0 213 break;
michael@0 214 case SH_ACTIVE_UNIFORM_MAX_LENGTH:
michael@0 215 *params = 1 + MAX_SYMBOL_NAME_LEN;
michael@0 216 break;
michael@0 217 case SH_ACTIVE_ATTRIBUTES:
michael@0 218 *params = compiler->getAttribs().size();
michael@0 219 break;
michael@0 220 case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH:
michael@0 221 *params = 1 + MAX_SYMBOL_NAME_LEN;
michael@0 222 break;
michael@0 223 case SH_MAPPED_NAME_MAX_LENGTH:
michael@0 224 // Use longer length than MAX_SHORTENED_IDENTIFIER_SIZE to
michael@0 225 // handle array and struct dereferences.
michael@0 226 *params = 1 + MAX_SYMBOL_NAME_LEN;
michael@0 227 break;
michael@0 228 case SH_NAME_MAX_LENGTH:
michael@0 229 *params = 1 + MAX_SYMBOL_NAME_LEN;
michael@0 230 break;
michael@0 231 case SH_HASHED_NAME_MAX_LENGTH:
michael@0 232 if (compiler->getHashFunction() == NULL) {
michael@0 233 *params = 0;
michael@0 234 } else {
michael@0 235 // 64 bits hashing output requires 16 bytes for hex
michael@0 236 // representation.
michael@0 237 const char HashedNamePrefix[] = HASHED_NAME_PREFIX;
michael@0 238 *params = 16 + sizeof(HashedNamePrefix);
michael@0 239 }
michael@0 240 break;
michael@0 241 case SH_HASHED_NAMES_COUNT:
michael@0 242 *params = compiler->getNameMap().size();
michael@0 243 break;
michael@0 244 default: UNREACHABLE();
michael@0 245 }
michael@0 246 }
michael@0 247
michael@0 248 //
michael@0 249 // Return any compiler log of messages for the application.
michael@0 250 //
michael@0 251 void ShGetInfoLog(const ShHandle handle, char* infoLog)
michael@0 252 {
michael@0 253 if (!handle || !infoLog)
michael@0 254 return;
michael@0 255
michael@0 256 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
michael@0 257 TCompiler* compiler = base->getAsCompiler();
michael@0 258 if (!compiler) return;
michael@0 259
michael@0 260 TInfoSink& infoSink = compiler->getInfoSink();
michael@0 261 strcpy(infoLog, infoSink.info.c_str());
michael@0 262 }
michael@0 263
michael@0 264 //
michael@0 265 // Return any object code.
michael@0 266 //
michael@0 267 void ShGetObjectCode(const ShHandle handle, char* objCode)
michael@0 268 {
michael@0 269 if (!handle || !objCode)
michael@0 270 return;
michael@0 271
michael@0 272 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
michael@0 273 TCompiler* compiler = base->getAsCompiler();
michael@0 274 if (!compiler) return;
michael@0 275
michael@0 276 TInfoSink& infoSink = compiler->getInfoSink();
michael@0 277 strcpy(objCode, infoSink.obj.c_str());
michael@0 278 }
michael@0 279
michael@0 280 void ShGetActiveAttrib(const ShHandle handle,
michael@0 281 int index,
michael@0 282 size_t* length,
michael@0 283 int* size,
michael@0 284 ShDataType* type,
michael@0 285 char* name,
michael@0 286 char* mappedName)
michael@0 287 {
michael@0 288 getVariableInfo(SH_ACTIVE_ATTRIBUTES,
michael@0 289 handle, index, length, size, type, name, mappedName);
michael@0 290 }
michael@0 291
michael@0 292 void ShGetActiveUniform(const ShHandle handle,
michael@0 293 int index,
michael@0 294 size_t* length,
michael@0 295 int* size,
michael@0 296 ShDataType* type,
michael@0 297 char* name,
michael@0 298 char* mappedName)
michael@0 299 {
michael@0 300 getVariableInfo(SH_ACTIVE_UNIFORMS,
michael@0 301 handle, index, length, size, type, name, mappedName);
michael@0 302 }
michael@0 303
michael@0 304 void ShGetNameHashingEntry(const ShHandle handle,
michael@0 305 int index,
michael@0 306 char* name,
michael@0 307 char* hashedName)
michael@0 308 {
michael@0 309 if (!handle || !name || !hashedName || index < 0)
michael@0 310 return;
michael@0 311
michael@0 312 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
michael@0 313 TCompiler* compiler = base->getAsCompiler();
michael@0 314 if (!compiler) return;
michael@0 315
michael@0 316 const NameMap& nameMap = compiler->getNameMap();
michael@0 317 if (index >= static_cast<int>(nameMap.size()))
michael@0 318 return;
michael@0 319
michael@0 320 NameMap::const_iterator it = nameMap.begin();
michael@0 321 for (int i = 0; i < index; ++i)
michael@0 322 ++it;
michael@0 323
michael@0 324 size_t len = it->first.length() + 1;
michael@0 325 size_t max_len = 0;
michael@0 326 ShGetInfo(handle, SH_NAME_MAX_LENGTH, &max_len);
michael@0 327 if (len > max_len) {
michael@0 328 ASSERT(false);
michael@0 329 len = max_len;
michael@0 330 }
michael@0 331 strncpy(name, it->first.c_str(), len);
michael@0 332 // To be on the safe side in case the source is longer than expected.
michael@0 333 name[len - 1] = '\0';
michael@0 334
michael@0 335 len = it->second.length() + 1;
michael@0 336 max_len = 0;
michael@0 337 ShGetInfo(handle, SH_HASHED_NAME_MAX_LENGTH, &max_len);
michael@0 338 if (len > max_len) {
michael@0 339 ASSERT(false);
michael@0 340 len = max_len;
michael@0 341 }
michael@0 342 strncpy(hashedName, it->second.c_str(), len);
michael@0 343 // To be on the safe side in case the source is longer than expected.
michael@0 344 hashedName[len - 1] = '\0';
michael@0 345 }
michael@0 346
michael@0 347 void ShGetInfoPointer(const ShHandle handle, ShShaderInfo pname, void** params)
michael@0 348 {
michael@0 349 if (!handle || !params)
michael@0 350 return;
michael@0 351
michael@0 352 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
michael@0 353 TranslatorHLSL* translator = base->getAsTranslatorHLSL();
michael@0 354 if (!translator) return;
michael@0 355
michael@0 356 switch(pname)
michael@0 357 {
michael@0 358 case SH_ACTIVE_UNIFORMS_ARRAY:
michael@0 359 *params = (void*)&translator->getUniforms();
michael@0 360 break;
michael@0 361 default: UNREACHABLE();
michael@0 362 }
michael@0 363 }

mercurial