gfx/angle/src/compiler/ShaderLang.cpp

changeset 0
6474c204b198
     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 +}

mercurial