// This must handle names like "foo.bar[0]".
bool
ShaderValidator::FindUniformByMappedName(const std::string& mappedName,
                                         std::string* const out_userName,
                                         bool* const out_isArray) const
{
    const std::vector<sh::Uniform>& uniforms = *ShGetUniforms(mHandle);
    for (auto itr = uniforms.begin(); itr != uniforms.end(); ++itr) {
        const sh::ShaderVariable* found;
        if (!itr->findInfoByMappedName(mappedName, &found, out_userName))
            continue;

        *out_isArray = found->isArray();
        return true;
    }

    const std::vector<sh::InterfaceBlock>& interfaces = *ShGetInterfaceBlocks(mHandle);
    for (const auto& interface : interfaces) {
        for (const auto& field : interface.fields) {
            const sh::ShaderVariable* found;

            if (!field.findInfoByMappedName(mappedName, &found, out_userName))
                continue;

            *out_isArray = found->isArray();
            return true;
        }
    }

    return false;
}
Пример #2
0
static bool getSymbolInfo(ShHandle compiler, ANGLEShaderSymbolType symbolType, Vector<ANGLEShaderSymbol>& symbols)
{
    switch (symbolType) {
    case SHADER_SYMBOL_TYPE_UNIFORM: {
        auto uniforms = ShGetUniforms(compiler);
        if (!uniforms)
            return false;
        for (const auto& uniform : *uniforms)
            getSymbolInfo(uniform, symbolType, symbols);
        break;
    }
    case SHADER_SYMBOL_TYPE_VARYING: {
        auto varyings = ShGetVaryings(compiler);
        if (!varyings)
            return false;
        for (const auto& varying : *varyings)
            getSymbolInfo(varying, symbolType, symbols);
        break;
    }
    case SHADER_SYMBOL_TYPE_ATTRIBUTE: {
        auto attributes = ShGetAttributes(compiler);
        if (!attributes)
            return false;
        for (const auto& attribute : *attributes)
            getSymbolInfo(attribute, symbolType, symbols);
        break;
    }
    default:
        ASSERT_NOT_REACHED();
        return false;
    }
    return true;
}
Пример #3
0
// This must handle names like "foo.bar[0]".
bool
ShaderValidator::FindUniformByMappedName(const std::string& mappedName,
                                         std::string* const out_userName,
                                         bool* const out_isArray) const
{
    const std::vector<sh::Uniform>& uniforms = *ShGetUniforms(mHandle);
    for (auto itr = uniforms.begin(); itr != uniforms.end(); ++itr) {
        const sh::ShaderVariable* found;
        if (!itr->findInfoByMappedName(mappedName, &found, out_userName))
            continue;

        *out_isArray = found->isArray();
        return true;
    }

    const size_t dotPos = mappedName.find(".");

    const std::vector<sh::InterfaceBlock>& interfaces = *ShGetInterfaceBlocks(mHandle);
    for (const auto& interface : interfaces) {

        std::string mappedFieldName;
        const bool hasInstanceName = !interface.instanceName.empty();

        // If the InterfaceBlock has an instanceName, all variables defined
        // within the block are qualified with the block name, as opposed
        // to being placed in the global scope.
        if (hasInstanceName) {

            // If mappedName has no block name prefix, skip
            if (std::string::npos == dotPos)
                continue;

            // If mappedName has a block name prefix that doesn't match, skip
            const std::string mappedInterfaceBlockName = mappedName.substr(0, dotPos);
            if (interface.mappedName != mappedInterfaceBlockName)
                continue;

            mappedFieldName = mappedName.substr(dotPos + 1);
        } else {
            mappedFieldName = mappedName;
        }

        for (const auto& field : interface.fields) {
            const sh::ShaderVariable* found;

            if (!field.findInfoByMappedName(mappedFieldName, &found, out_userName))
                continue;

            if (hasInstanceName) {
                // Prepend the user name of the interface that matched
                *out_userName = interface.name + "." + *out_userName;
            }

            *out_isArray = found->isArray();
            return true;
        }
    }

    return false;
}
size_t
ShaderValidator::CalcNumSamplerUniforms() const
{
    size_t accum = 0;

    const std::vector<sh::Uniform>& uniforms = *ShGetUniforms(mHandle);

    for (auto itr = uniforms.begin(); itr != uniforms.end(); ++itr) {
        GLenum type = itr->type;
        if (type == LOCAL_GL_SAMPLER_2D ||
            type == LOCAL_GL_SAMPLER_CUBE)
        {
            accum += itr->arraySize;
        }
    }

    return accum;
}
static void PrintActiveVariables(ShHandle compiler)
{
    const std::vector<sh::Uniform> *uniforms = ShGetUniforms(compiler);
    const std::vector<sh::Varying> *varyings = ShGetVaryings(compiler);
    const std::vector<sh::Attribute> *attributes = ShGetAttributes(compiler);
    for (size_t varCategory = 0; varCategory < 3; ++varCategory)
    {
        size_t numVars = 0;
        std::string varCategoryName;
        if (varCategory == 0)
        {
            numVars = uniforms->size();
            varCategoryName = "uniform";
        }
        else if (varCategory == 1)
        {
            numVars = varyings->size();
            varCategoryName = "varying";
        }
        else
        {
            numVars = attributes->size();
            varCategoryName = "attribute";
        }
        for (size_t i = 0; i < numVars; ++i)
        {
            const sh::ShaderVariable *var;
            if (varCategory == 0)
                var = &((*uniforms)[i]);
            else if (varCategory == 1)
                var = &((*varyings)[i]);
            else
                var = &((*attributes)[i]);
            PrintVariable(varCategoryName, i, *var);
        }
        printf("\n");
    }
}
bool
ShaderValidator::CanLinkTo(const ShaderValidator* prev, nsCString* const out_log) const
{
    if (!prev) {
        nsPrintfCString error("Passed in NULL prev ShaderValidator.");
        *out_log = error;
        return false;
    }

    {
        const std::vector<sh::Uniform>* vertPtr = ShGetUniforms(prev->mHandle);
        const std::vector<sh::Uniform>* fragPtr = ShGetUniforms(mHandle);
        if (!vertPtr || !fragPtr) {
            nsPrintfCString error("Could not create uniform list.");
            *out_log = error;
            return false;
        }

        for (auto itrFrag = fragPtr->begin(); itrFrag != fragPtr->end(); ++itrFrag) {
            for (auto itrVert = vertPtr->begin(); itrVert != vertPtr->end(); ++itrVert) {
                if (itrVert->name != itrFrag->name)
                    continue;

                if (!itrVert->isSameUniformAtLinkTime(*itrFrag)) {
                    nsPrintfCString error("Uniform `%s`is not linkable between"
                                          " attached shaders.",
                                          itrFrag->name.c_str());
                    *out_log = error;
                    return false;
                }

                break;
            }
        }
    }
    {
        const std::vector<sh::Varying>* vertPtr = ShGetVaryings(prev->mHandle);
        const std::vector<sh::Varying>* fragPtr = ShGetVaryings(mHandle);
        if (!vertPtr || !fragPtr) {
            nsPrintfCString error("Could not create varying list.");
            *out_log = error;
            return false;
        }

        nsTArray<ShVariableInfo> staticUseVaryingList;

        for (auto itrFrag = fragPtr->begin(); itrFrag != fragPtr->end(); ++itrFrag) {
            const ShVariableInfo varInfo = { itrFrag->type,
                                             (int)itrFrag->elementCount() };

            static const char prefix[] = "gl_";
            if (StartsWith(itrFrag->name, prefix)) {
                if (itrFrag->staticUse)
                    staticUseVaryingList.AppendElement(varInfo);

                continue;
            }

            bool definedInVertShader = false;
            bool staticVertUse = false;

            for (auto itrVert = vertPtr->begin(); itrVert != vertPtr->end(); ++itrVert) {
                if (itrVert->name != itrFrag->name)
                    continue;

                if (!itrVert->isSameVaryingAtLinkTime(*itrFrag)) {
                    nsPrintfCString error("Varying `%s`is not linkable between"
                                          " attached shaders.",
                                          itrFrag->name.c_str());
                    *out_log = error;
                    return false;
                }

                definedInVertShader = true;
                staticVertUse = itrVert->staticUse;
                break;
            }

            if (!definedInVertShader && itrFrag->staticUse) {
                nsPrintfCString error("Varying `%s` has static-use in the frag"
                                      " shader, but is undeclared in the vert"
                                      " shader.", itrFrag->name.c_str());
                *out_log = error;
                return false;
            }

            if (staticVertUse && itrFrag->staticUse)
                staticUseVaryingList.AppendElement(varInfo);
        }

        if (!ShCheckVariablesWithinPackingLimits(mMaxVaryingVectors,
                                                 staticUseVaryingList.Elements(),
                                                 staticUseVaryingList.Length()))
        {
            *out_log = "Statically used varyings do not fit within packing limits. (see"
                       " GLSL ES Specification 1.0.17, p111)";
            return false;
        }
    }

    return true;
}
Пример #7
0
bool
ShaderValidator::CanLinkTo(const ShaderValidator* prev, nsCString* const out_log) const
{
    if (!prev) {
        nsPrintfCString error("Passed in NULL prev ShaderValidator.");
        *out_log = error;
        return false;
    }

    const auto shaderVersion = ShGetShaderVersion(mHandle);
    if (ShGetShaderVersion(prev->mHandle) != shaderVersion) {
        nsPrintfCString error("Vertex shader version %d does not match"
                              " fragment shader version %d.",
                              ShGetShaderVersion(prev->mHandle),
                              ShGetShaderVersion(mHandle));
        *out_log = error;
        return false;
    }

    {
        const std::vector<sh::Uniform>* vertPtr = ShGetUniforms(prev->mHandle);
        const std::vector<sh::Uniform>* fragPtr = ShGetUniforms(mHandle);
        if (!vertPtr || !fragPtr) {
            nsPrintfCString error("Could not create uniform list.");
            *out_log = error;
            return false;
        }

        for (auto itrFrag = fragPtr->begin(); itrFrag != fragPtr->end(); ++itrFrag) {
            for (auto itrVert = vertPtr->begin(); itrVert != vertPtr->end(); ++itrVert) {
                if (itrVert->name != itrFrag->name)
                    continue;

                if (!itrVert->isSameUniformAtLinkTime(*itrFrag)) {
                    nsPrintfCString error("Uniform `%s` is not linkable between"
                                          " attached shaders.",
                                          itrFrag->name.c_str());
                    *out_log = error;
                    return false;
                }

                break;
            }
        }
    }
    {
        const auto vertVars = sh::GetInterfaceBlocks(prev->mHandle);
        const auto fragVars = sh::GetInterfaceBlocks(mHandle);
        if (!vertVars || !fragVars) {
            nsPrintfCString error("Could not create uniform block list.");
            *out_log = error;
            return false;
        }

        for (const auto& fragVar : *fragVars) {
            for (const auto& vertVar : *vertVars) {
                if (vertVar.name != fragVar.name)
                    continue;

                if (!vertVar.isSameInterfaceBlockAtLinkTime(fragVar)) {
                    nsPrintfCString error("Interface block `%s` is not linkable between"
                                          " attached shaders.",
                                          fragVar.name.c_str());
                    *out_log = error;
                    return false;
                }

                break;
            }
        }
    }

    const auto& vertVaryings = ShGetVaryings(prev->mHandle);
    const auto& fragVaryings = ShGetVaryings(mHandle);
    if (!vertVaryings || !fragVaryings) {
        nsPrintfCString error("Could not create varying list.");
        *out_log = error;
        return false;
    }

    {
        std::vector<sh::ShaderVariable> staticUseVaryingList;

        for (const auto& fragVarying : *fragVaryings) {
            static const char prefix[] = "gl_";
            if (StartsWith(fragVarying.name, prefix)) {
                if (fragVarying.staticUse) {
                    staticUseVaryingList.push_back(fragVarying);
                }
                continue;
            }

            bool definedInVertShader = false;
            bool staticVertUse = false;

            for (const auto& vertVarying : *vertVaryings) {
                if (vertVarying.name != fragVarying.name)
                    continue;

                if (!vertVarying.isSameVaryingAtLinkTime(fragVarying, shaderVersion)) {
                    nsPrintfCString error("Varying `%s`is not linkable between"
                                          " attached shaders.",
                                          fragVarying.name.c_str());
                    *out_log = error;
                    return false;
                }

                definedInVertShader = true;
                staticVertUse = vertVarying.staticUse;
                break;
            }

            if (!definedInVertShader && fragVarying.staticUse) {
                nsPrintfCString error("Varying `%s` has static-use in the frag"
                                      " shader, but is undeclared in the vert"
                                      " shader.", fragVarying.name.c_str());
                *out_log = error;
                return false;
            }

            if (staticVertUse && fragVarying.staticUse) {
                staticUseVaryingList.push_back(fragVarying);
            }
        }

        if (!ShCheckVariablesWithinPackingLimits(mMaxVaryingVectors,
                                                 staticUseVaryingList))
        {
            *out_log = "Statically used varyings do not fit within packing limits. (see"
                       " GLSL ES Specification 1.0.17, p111)";
            return false;
        }
    }

    if (shaderVersion == 100) {
        // Enforce ESSL1 invariant linking rules.
        bool isInvariant_Position = false;
        bool isInvariant_PointSize = false;
        bool isInvariant_FragCoord = false;
        bool isInvariant_PointCoord = false;

        for (const auto& varying : *vertVaryings) {
            if (varying.name == "gl_Position") {
                isInvariant_Position = varying.isInvariant;
            } else if (varying.name == "gl_PointSize") {
                isInvariant_PointSize = varying.isInvariant;
            }
        }

        for (const auto& varying : *fragVaryings) {
            if (varying.name == "gl_FragCoord") {
                isInvariant_FragCoord = varying.isInvariant;
            } else if (varying.name == "gl_PointCoord") {
                isInvariant_PointCoord = varying.isInvariant;
            }
        }

        ////

        const auto fnCanBuiltInsLink = [](bool vertIsInvariant, bool fragIsInvariant) {
            if (vertIsInvariant)
                return true;

            return !fragIsInvariant;
        };

        if (!fnCanBuiltInsLink(isInvariant_Position, isInvariant_FragCoord)) {
            *out_log = "gl_Position must be invariant if gl_FragCoord is. (see GLSL ES"
                       " Specification 1.0.17, p39)";
            return false;
        }

        if (!fnCanBuiltInsLink(isInvariant_PointSize, isInvariant_PointCoord)) {
            *out_log = "gl_PointSize must be invariant if gl_PointCoord is. (see GLSL ES"
                       " Specification 1.0.17, p39)";
            return false;
        }
    }

    return true;
}
Пример #8
0
void ShaderD3D::compileToHLSL(ShHandle compiler, const std::string &source)
{
    int compileOptions = (SH_OBJECT_CODE | SH_VARIABLES);

    // D3D11 Feature Level 9_3 and below do not support non-constant loop indexers in fragment
    // shaders.
    // Shader compilation will fail. To provide a better error message we can instruct the
    // compiler to pre-validate.
    if (mRenderer->getRendererLimitations().shadersRequireIndexedLoopValidation)
    {
        compileOptions |= SH_VALIDATE_LOOP_INDEXING;
    }

    std::string sourcePath;

#if !defined (ANGLE_ENABLE_WINDOWS_STORE)
    if (gl::DebugAnnotationsActive())
    {
        sourcePath = getTempPath();
        writeFile(sourcePath.c_str(), source.c_str(), source.length());
        compileOptions |= SH_LINE_DIRECTIVES;
    }
#endif

    int result;
    if (sourcePath.empty())
    {
        const char* sourceStrings[] =
        {
            source.c_str(),
        };

        result = ShCompile(compiler, sourceStrings, ArraySize(sourceStrings), compileOptions);
    }
    else
    {
        const char* sourceStrings[] =
        {
            sourcePath.c_str(),
            source.c_str(),
        };

        result = ShCompile(compiler, sourceStrings, ArraySize(sourceStrings), compileOptions | SH_SOURCE_PATH);
    }

    mShaderVersion = ShGetShaderVersion(compiler);

    if (result)
    {
        mTranslatedSource = ShGetObjectCode(compiler);

#ifdef _DEBUG
        // Prefix hlsl shader with commented out glsl shader
        // Useful in diagnostics tools like pix which capture the hlsl shaders
        std::ostringstream hlslStream;
        hlslStream << "// GLSL\n";
        hlslStream << "//\n";

        size_t curPos = 0;
        while (curPos != std::string::npos)
        {
            size_t nextLine = source.find("\n", curPos);
            size_t len = (nextLine == std::string::npos) ? std::string::npos : (nextLine - curPos + 1);

            hlslStream << "// " << source.substr(curPos, len);

            curPos = (nextLine == std::string::npos) ? std::string::npos : (nextLine + 1);
        }
        hlslStream << "\n\n";
        hlslStream << mTranslatedSource;
        mTranslatedSource = hlslStream.str();
#endif

        mUniforms = *GetShaderVariables(ShGetUniforms(compiler));

        for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
        {
            const sh::Uniform &uniform = mUniforms[uniformIndex];

            if (uniform.staticUse && !uniform.isBuiltIn())
            {
                unsigned int index = static_cast<unsigned int>(-1);
                bool getUniformRegisterResult = ShGetUniformRegister(compiler, uniform.name, &index);
                UNUSED_ASSERTION_VARIABLE(getUniformRegisterResult);
                ASSERT(getUniformRegisterResult);

                mUniformRegisterMap[uniform.name] = index;
            }
        }

        mInterfaceBlocks = *GetShaderVariables(ShGetInterfaceBlocks(compiler));

        for (size_t blockIndex = 0; blockIndex < mInterfaceBlocks.size(); blockIndex++)
        {
            const sh::InterfaceBlock &interfaceBlock = mInterfaceBlocks[blockIndex];

            if (interfaceBlock.staticUse)
            {
                unsigned int index = static_cast<unsigned int>(-1);
                bool blockRegisterResult = ShGetInterfaceBlockRegister(compiler, interfaceBlock.name, &index);
                UNUSED_ASSERTION_VARIABLE(blockRegisterResult);
                ASSERT(blockRegisterResult);

                mInterfaceBlockRegisterMap[interfaceBlock.name] = index;
            }
        }
    }
    else
    {
        mInfoLog = ShGetInfoLog(compiler);

        TRACE("\n%s", mInfoLog.c_str());
    }
}
Пример #9
0
void Shader::compile(Compiler *compiler)
{
    mData.mTranslatedSource.clear();
    mInfoLog.clear();
    mData.mShaderVersion = 100;
    mData.mVaryings.clear();
    mData.mUniforms.clear();
    mData.mInterfaceBlocks.clear();
    mData.mActiveAttributes.clear();
    mData.mActiveOutputVariables.clear();

    ShHandle compilerHandle = compiler->getCompilerHandle(mData.mShaderType);

    std::stringstream sourceStream;

    std::string sourcePath;
    int additionalOptions =
        mImplementation->prepareSourceAndReturnOptions(&sourceStream, &sourcePath);
    int compileOptions    = (SH_OBJECT_CODE | SH_VARIABLES | additionalOptions);

    // Some targets (eg D3D11 Feature Level 9_3 and below) do not support non-constant loop indexes
    // in fragment shaders. Shader compilation will fail. To provide a better error message we can
    // instruct the compiler to pre-validate.
    if (mRendererLimitations.shadersRequireIndexedLoopValidation)
    {
        compileOptions |= SH_VALIDATE_LOOP_INDEXING;
    }

    std::string sourceString  = sourceStream.str();
    std::vector<const char *> sourceCStrings;

    if (!sourcePath.empty())
    {
        sourceCStrings.push_back(sourcePath.c_str());
    }

    sourceCStrings.push_back(sourceString.c_str());

    bool result =
        ShCompile(compilerHandle, &sourceCStrings[0], sourceCStrings.size(), compileOptions);

    if (!result)
    {
        mInfoLog = ShGetInfoLog(compilerHandle);
        TRACE("\n%s", mInfoLog.c_str());
        mCompiled = false;
        return;
    }

    mData.mTranslatedSource = ShGetObjectCode(compilerHandle);

#ifndef NDEBUG
    // Prefix translated shader with commented out un-translated shader.
    // Useful in diagnostics tools which capture the shader source.
    std::ostringstream shaderStream;
    shaderStream << "// GLSL\n";
    shaderStream << "//\n";

    size_t curPos = 0;
    while (curPos != std::string::npos)
    {
        size_t nextLine = mData.mSource.find("\n", curPos);
        size_t len      = (nextLine == std::string::npos) ? std::string::npos : (nextLine - curPos + 1);

        shaderStream << "// " << mData.mSource.substr(curPos, len);

        curPos = (nextLine == std::string::npos) ? std::string::npos : (nextLine + 1);
    }
    shaderStream << "\n\n";
    shaderStream << mData.mTranslatedSource;
    mData.mTranslatedSource = shaderStream.str();
#endif

    // Gather the shader information
    mData.mShaderVersion = ShGetShaderVersion(compilerHandle);

    mData.mVaryings        = GetShaderVariables(ShGetVaryings(compilerHandle));
    mData.mUniforms        = GetShaderVariables(ShGetUniforms(compilerHandle));
    mData.mInterfaceBlocks = GetShaderVariables(ShGetInterfaceBlocks(compilerHandle));

    if (mData.mShaderType == GL_VERTEX_SHADER)
    {
        mData.mActiveAttributes = GetActiveShaderVariables(ShGetAttributes(compilerHandle));
    }
    else
    {
        ASSERT(mData.mShaderType == GL_FRAGMENT_SHADER);

        // TODO(jmadill): Figure out why we only sort in the FS, and if we need to.
        std::sort(mData.mVaryings.begin(), mData.mVaryings.end(), CompareShaderVar);
        mData.mActiveOutputVariables =
            GetActiveShaderVariables(ShGetOutputVariables(compilerHandle));
    }

    ASSERT(!mData.mTranslatedSource.empty());

    mCompiled = mImplementation->postTranslateCompile(compiler, &mInfoLog);
}
Пример #10
0
void ShaderD3D::compileToHLSL(void *compiler, const std::string &source)
{
    // ensure the compiler is loaded
    initializeCompiler();

    int compileOptions = (SH_OBJECT_CODE | SH_VARIABLES);
    std::string sourcePath;

#if !defined (ANGLE_ENABLE_WINDOWS_STORE)
    if (gl::perfActive())
    {
        sourcePath = getTempPath();
        writeFile(sourcePath.c_str(), source.c_str(), source.length());
        compileOptions |= SH_LINE_DIRECTIVES;
    }
#endif

    int result;
    if (sourcePath.empty())
    {
        const char* sourceStrings[] =
        {
            source.c_str(),
        };

        result = ShCompile(compiler, sourceStrings, ArraySize(sourceStrings), compileOptions);
    }
    else
    {
        const char* sourceStrings[] =
        {
            sourcePath.c_str(),
            source.c_str(),
        };

        result = ShCompile(compiler, sourceStrings, ArraySize(sourceStrings), compileOptions | SH_SOURCE_PATH);
    }

    mShaderVersion = ShGetShaderVersion(compiler);

    if (mShaderVersion == 300 && mRenderer->getCurrentClientVersion() < 3)
    {
        mInfoLog = "GLSL ES 3.00 is not supported by OpenGL ES 2.0 contexts";
        TRACE("\n%s", mInfoLog.c_str());
    }
    else if (result)
    {
        mHlsl = ShGetObjectCode(compiler);

#ifdef _DEBUG
        // Prefix hlsl shader with commented out glsl shader
        // Useful in diagnostics tools like pix which capture the hlsl shaders
        std::ostringstream hlslStream;
        hlslStream << "// GLSL\n";
        hlslStream << "//\n";

        size_t curPos = 0;
        while (curPos != std::string::npos)
        {
            size_t nextLine = source.find("\n", curPos);
            size_t len = (nextLine == std::string::npos) ? std::string::npos : (nextLine - curPos + 1);

            hlslStream << "// " << source.substr(curPos, len);

            curPos = (nextLine == std::string::npos) ? std::string::npos : (nextLine + 1);
        }
        hlslStream << "\n\n";
        hlslStream << mHlsl;
        mHlsl = hlslStream.str();
#endif

        mUniforms = *GetShaderVariables(ShGetUniforms(compiler));

        for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
        {
            const sh::Uniform &uniform = mUniforms[uniformIndex];

            if (uniform.staticUse)
            {
                unsigned int index = -1;
                bool result = ShGetUniformRegister(compiler, uniform.name, &index);
                UNUSED_ASSERTION_VARIABLE(result);
                ASSERT(result);

                mUniformRegisterMap[uniform.name] = index;
            }
        }

        mInterfaceBlocks = *GetShaderVariables(ShGetInterfaceBlocks(compiler));

        for (size_t blockIndex = 0; blockIndex < mInterfaceBlocks.size(); blockIndex++)
        {
            const sh::InterfaceBlock &interfaceBlock = mInterfaceBlocks[blockIndex];

            if (interfaceBlock.staticUse)
            {
                unsigned int index = -1;
                bool result = ShGetInterfaceBlockRegister(compiler, interfaceBlock.name, &index);
                UNUSED_ASSERTION_VARIABLE(result);
                ASSERT(result);

                mInterfaceBlockRegisterMap[interfaceBlock.name] = index;
            }
        }
    }
    else
    {
        mInfoLog = ShGetInfoLog(compiler);

        TRACE("\n%s", mInfoLog.c_str());
    }
}