Home | History | Annotate | Download | only in compiler
      1 //
      2 // Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 //
      8 // Implement the top-level of interface to the compiler,
      9 // as defined in ShaderLang.h
     10 //
     11 
     12 #include "GLSLANG/ShaderLang.h"
     13 
     14 #include "compiler/InitializeDll.h"
     15 #include "compiler/ShHandle.h"
     16 
     17 //
     18 // This is the platform independent interface between an OGL driver
     19 // and the shading language compiler.
     20 //
     21 
     22 static int getVariableMaxLength(const TVariableInfoList& varList)
     23 {
     24     TString::size_type maxLen = 0;
     25     for (TVariableInfoList::const_iterator i = varList.begin();
     26          i != varList.end(); ++i)
     27     {
     28         maxLen = std::max(maxLen, i->name.size());
     29     }
     30     // Add 1 to include null-termination character.
     31     return static_cast<int>(maxLen) + 1;
     32 }
     33 
     34 static void getVariableInfo(ShShaderInfo varType,
     35                             const ShHandle handle,
     36                             int index,
     37                             int* length,
     38                             int* size,
     39                             ShDataType* type,
     40                             char* name)
     41 {
     42     if (!handle || !size || !type || !name)
     43         return;
     44     ASSERT((varType == SH_ACTIVE_ATTRIBUTES) ||
     45            (varType == SH_ACTIVE_UNIFORMS));
     46 
     47     TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
     48     TCompiler* compiler = base->getAsCompiler();
     49     if (compiler == 0)
     50         return;
     51 
     52     const TVariableInfoList& varList = varType == SH_ACTIVE_ATTRIBUTES ?
     53         compiler->getAttribs() : compiler->getUniforms();
     54     if (index < 0 || index >= static_cast<int>(varList.size()))
     55         return;
     56 
     57     const TVariableInfo& varInfo = varList[index];
     58     if (length) *length = varInfo.name.size();
     59     *size = varInfo.size;
     60     *type = varInfo.type;
     61     strcpy(name, varInfo.name.c_str());
     62 }
     63 
     64 //
     65 // Driver must call this first, once, before doing any other
     66 // compiler operations.
     67 //
     68 int ShInitialize()
     69 {
     70     if (!InitProcess())
     71         return 0;
     72 
     73     return 1;
     74 }
     75 
     76 //
     77 // Cleanup symbol tables
     78 //
     79 int ShFinalize()
     80 {
     81     if (!DetachProcess())
     82         return 0;
     83 
     84     return 1;
     85 }
     86 
     87 //
     88 // Initialize built-in resources with minimum expected values.
     89 //
     90 void ShInitBuiltInResources(ShBuiltInResources* resources)
     91 {
     92     // Constants.
     93     resources->MaxVertexAttribs = 8;
     94     resources->MaxVertexUniformVectors = 128;
     95     resources->MaxVaryingVectors = 8;
     96     resources->MaxVertexTextureImageUnits = 0;
     97     resources->MaxCombinedTextureImageUnits = 8;
     98     resources->MaxTextureImageUnits = 8;
     99     resources->MaxFragmentUniformVectors = 16;
    100     resources->MaxDrawBuffers = 1;
    101 
    102     // Extensions.
    103     resources->OES_standard_derivatives = 0;
    104 }
    105 
    106 //
    107 // Driver calls these to create and destroy compiler objects.
    108 //
    109 ShHandle ShConstructCompiler(ShShaderType type, ShShaderSpec spec,
    110                              const ShBuiltInResources* resources)
    111 {
    112     if (!InitThread())
    113         return 0;
    114 
    115     TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(type, spec));
    116     TCompiler* compiler = base->getAsCompiler();
    117     if (compiler == 0)
    118         return 0;
    119 
    120     // Generate built-in symbol table.
    121     if (!compiler->Init(*resources)) {
    122         ShDestruct(base);
    123         return 0;
    124     }
    125 
    126     return reinterpret_cast<void*>(base);
    127 }
    128 
    129 void ShDestruct(ShHandle handle)
    130 {
    131     if (handle == 0)
    132         return;
    133 
    134     TShHandleBase* base = static_cast<TShHandleBase*>(handle);
    135 
    136     if (base->getAsCompiler())
    137         DeleteCompiler(base->getAsCompiler());
    138 }
    139 
    140 //
    141 // Do an actual compile on the given strings.  The result is left
    142 // in the given compile object.
    143 //
    144 // Return:  The return value of ShCompile is really boolean, indicating
    145 // success or failure.
    146 //
    147 int ShCompile(
    148     const ShHandle handle,
    149     const char* const shaderStrings[],
    150     const int numStrings,
    151     int compileOptions)
    152 {
    153     if (!InitThread())
    154         return 0;
    155 
    156     if (handle == 0)
    157         return 0;
    158 
    159     TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
    160     TCompiler* compiler = base->getAsCompiler();
    161     if (compiler == 0)
    162         return 0;
    163 
    164     bool success = compiler->compile(shaderStrings, numStrings, compileOptions);
    165     return success ? 1 : 0;
    166 }
    167 
    168 void ShGetInfo(const ShHandle handle, ShShaderInfo pname, int* params)
    169 {
    170     if (!handle || !params)
    171         return;
    172 
    173     TShHandleBase* base = static_cast<TShHandleBase*>(handle);
    174     TCompiler* compiler = base->getAsCompiler();
    175     if (!compiler) return;
    176 
    177     switch(pname)
    178     {
    179     case SH_INFO_LOG_LENGTH:
    180         *params = compiler->getInfoSink().info.size() + 1;
    181         break;
    182     case SH_OBJECT_CODE_LENGTH:
    183         *params = compiler->getInfoSink().obj.size() + 1;
    184         break;
    185     case SH_ACTIVE_UNIFORMS:
    186         *params = compiler->getUniforms().size();
    187         break;
    188     case SH_ACTIVE_UNIFORM_MAX_LENGTH:
    189         *params = getVariableMaxLength(compiler->getUniforms());
    190         break;
    191     case SH_ACTIVE_ATTRIBUTES:
    192         *params = compiler->getAttribs().size();
    193         break;
    194     case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH:
    195         *params = getVariableMaxLength(compiler->getAttribs());
    196         break;
    197 
    198     default: UNREACHABLE();
    199     }
    200 }
    201 
    202 //
    203 // Return any compiler log of messages for the application.
    204 //
    205 void ShGetInfoLog(const ShHandle handle, char* infoLog)
    206 {
    207     if (!handle || !infoLog)
    208         return;
    209 
    210     TShHandleBase* base = static_cast<TShHandleBase*>(handle);
    211     TCompiler* compiler = base->getAsCompiler();
    212     if (!compiler) return;
    213 
    214     TInfoSink& infoSink = compiler->getInfoSink();
    215     strcpy(infoLog, infoSink.info.c_str());
    216 }
    217 
    218 //
    219 // Return any object code.
    220 //
    221 void ShGetObjectCode(const ShHandle handle, char* objCode)
    222 {
    223     if (!handle || !objCode)
    224         return;
    225 
    226     TShHandleBase* base = static_cast<TShHandleBase*>(handle);
    227     TCompiler* compiler = base->getAsCompiler();
    228     if (!compiler) return;
    229 
    230     TInfoSink& infoSink = compiler->getInfoSink();
    231     strcpy(objCode, infoSink.obj.c_str());
    232 }
    233 
    234 void ShGetActiveAttrib(const ShHandle handle,
    235                        int index,
    236                        int* length,
    237                        int* size,
    238                        ShDataType* type,
    239                        char* name)
    240 {
    241     getVariableInfo(SH_ACTIVE_ATTRIBUTES,
    242                     handle, index, length, size, type, name);
    243 }
    244 
    245 void ShGetActiveUniform(const ShHandle handle,
    246                         int index,
    247                         int* length,
    248                         int* size,
    249                         ShDataType* type,
    250                         char* name)
    251 {
    252     getVariableInfo(SH_ACTIVE_UNIFORMS,
    253                     handle, index, length, size, type, name);
    254 }
    255