tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ShaderLang.cpp (32765B)


      1 //
      2 // Copyright 2002 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/translator/Compiler.h"
     15 #include "compiler/translator/InitializeDll.h"
     16 #include "compiler/translator/glslang_wrapper.h"
     17 #include "compiler/translator/length_limits.h"
     18 #ifdef ANGLE_ENABLE_HLSL
     19 #    include "compiler/translator/TranslatorHLSL.h"
     20 #endif  // ANGLE_ENABLE_HLSL
     21 #include "angle_gl.h"
     22 #include "compiler/translator/VariablePacker.h"
     23 
     24 namespace sh
     25 {
     26 
     27 namespace
     28 {
     29 
     30 bool isInitialized = false;
     31 
     32 // glslang can only be initialized/finalized once per process. Otherwise, the following EGL commands
     33 // will call GlslangFinalize() without ever being able to GlslangInitialize() again, leading to
     34 // crashes since GlslangFinalize() cleans up glslang for the entire process.
     35 //   dpy1 = eglGetPlatformDisplay()   |
     36 //   eglInitialize(dpy1)              | GlslangInitialize()
     37 //   dpy2 = eglGetPlatformDisplay()   |
     38 //   eglInitialize(dpy2)              | GlslangInitialize()
     39 //   eglTerminate(dpy2)               | GlslangFinalize()
     40 //   eglInitialize(dpy1)              | Display::isInitialized() == true, no GlslangInitialize()
     41 int initializeGlslangRefCount = 0;
     42 
     43 //
     44 // This is the platform independent interface between an OGL driver
     45 // and the shading language compiler.
     46 //
     47 
     48 template <typename VarT>
     49 const std::vector<VarT> *GetVariableList(const TCompiler *compiler);
     50 
     51 template <>
     52 const std::vector<InterfaceBlock> *GetVariableList(const TCompiler *compiler)
     53 {
     54    return &compiler->getInterfaceBlocks();
     55 }
     56 
     57 TCompiler *GetCompilerFromHandle(ShHandle handle)
     58 {
     59    if (!handle)
     60    {
     61        return nullptr;
     62    }
     63 
     64    TShHandleBase *base = static_cast<TShHandleBase *>(handle);
     65    return base->getAsCompiler();
     66 }
     67 
     68 template <typename VarT>
     69 const std::vector<VarT> *GetShaderVariables(const ShHandle handle)
     70 {
     71    TCompiler *compiler = GetCompilerFromHandle(handle);
     72    if (!compiler)
     73    {
     74        return nullptr;
     75    }
     76 
     77    return GetVariableList<VarT>(compiler);
     78 }
     79 
     80 #ifdef ANGLE_ENABLE_HLSL
     81 TranslatorHLSL *GetTranslatorHLSLFromHandle(ShHandle handle)
     82 {
     83    if (!handle)
     84        return nullptr;
     85    TShHandleBase *base = static_cast<TShHandleBase *>(handle);
     86    return base->getAsTranslatorHLSL();
     87 }
     88 #endif  // ANGLE_ENABLE_HLSL
     89 
     90 GLenum GetGeometryShaderPrimitiveTypeEnum(sh::TLayoutPrimitiveType primitiveType)
     91 {
     92    switch (primitiveType)
     93    {
     94        case EptPoints:
     95            return GL_POINTS;
     96        case EptLines:
     97            return GL_LINES;
     98        case EptLinesAdjacency:
     99            return GL_LINES_ADJACENCY_EXT;
    100        case EptTriangles:
    101            return GL_TRIANGLES;
    102        case EptTrianglesAdjacency:
    103            return GL_TRIANGLES_ADJACENCY_EXT;
    104 
    105        case EptLineStrip:
    106            return GL_LINE_STRIP;
    107        case EptTriangleStrip:
    108            return GL_TRIANGLE_STRIP;
    109 
    110        case EptUndefined:
    111        default:
    112            UNREACHABLE();
    113            return GL_INVALID_VALUE;
    114    }
    115 }
    116 
    117 GLenum GetTessellationShaderTypeEnum(sh::TLayoutTessEvaluationType type)
    118 {
    119    switch (type)
    120    {
    121        case EtetTriangles:
    122            return GL_TRIANGLES;
    123        case EtetQuads:
    124            return GL_QUADS;
    125        case EtetIsolines:
    126            return GL_ISOLINES;
    127        case EtetEqualSpacing:
    128            return GL_EQUAL;
    129        case EtetFractionalEvenSpacing:
    130            return GL_FRACTIONAL_EVEN;
    131        case EtetFractionalOddSpacing:
    132            return GL_FRACTIONAL_ODD;
    133        case EtetCw:
    134            return GL_CW;
    135        case EtetCcw:
    136            return GL_CCW;
    137        case EtetPointMode:
    138            return GL_TESS_GEN_POINT_MODE;
    139 
    140        case EtetUndefined:
    141        default:
    142            UNREACHABLE();
    143            return GL_INVALID_VALUE;
    144    }
    145 }
    146 
    147 }  // anonymous namespace
    148 
    149 //
    150 // Driver must call this first, once, before doing any other compiler operations.
    151 // Subsequent calls to this function are no-op.
    152 //
    153 bool Initialize()
    154 {
    155    if (!isInitialized)
    156    {
    157        isInitialized = InitProcess();
    158    }
    159    return isInitialized;
    160 }
    161 
    162 //
    163 // Cleanup symbol tables
    164 //
    165 bool Finalize()
    166 {
    167    if (isInitialized)
    168    {
    169        DetachProcess();
    170        isInitialized = false;
    171    }
    172    return true;
    173 }
    174 
    175 //
    176 // Initialize built-in resources with minimum expected values.
    177 //
    178 void InitBuiltInResources(ShBuiltInResources *resources)
    179 {
    180    // Make comparable.
    181    memset(resources, 0, sizeof(*resources));
    182 
    183    // Constants.
    184    resources->MaxVertexAttribs             = 8;
    185    resources->MaxVertexUniformVectors      = 128;
    186    resources->MaxVaryingVectors            = 8;
    187    resources->MaxVertexTextureImageUnits   = 0;
    188    resources->MaxCombinedTextureImageUnits = 8;
    189    resources->MaxTextureImageUnits         = 8;
    190    resources->MaxFragmentUniformVectors    = 16;
    191    resources->MaxDrawBuffers               = 1;
    192 
    193    // Extensions.
    194    resources->OES_standard_derivatives                       = 0;
    195    resources->OES_EGL_image_external                         = 0;
    196    resources->OES_EGL_image_external_essl3                   = 0;
    197    resources->NV_EGL_stream_consumer_external                = 0;
    198    resources->ARB_texture_rectangle                          = 0;
    199    resources->EXT_blend_func_extended                        = 0;
    200    resources->EXT_draw_buffers                               = 0;
    201    resources->EXT_frag_depth                                 = 0;
    202    resources->EXT_shader_texture_lod                         = 0;
    203    resources->EXT_shader_framebuffer_fetch                   = 0;
    204    resources->EXT_shader_framebuffer_fetch_non_coherent      = 0;
    205    resources->NV_shader_framebuffer_fetch                    = 0;
    206    resources->ARM_shader_framebuffer_fetch                   = 0;
    207    resources->OVR_multiview                                  = 0;
    208    resources->OVR_multiview2                                 = 0;
    209    resources->EXT_YUV_target                                 = 0;
    210    resources->EXT_geometry_shader                            = 0;
    211    resources->OES_geometry_shader                            = 0;
    212    resources->EXT_gpu_shader5                                = 0;
    213    resources->OES_shader_io_blocks                           = 0;
    214    resources->EXT_shader_io_blocks                           = 0;
    215    resources->EXT_shader_non_constant_global_initializers    = 0;
    216    resources->NV_shader_noperspective_interpolation          = 0;
    217    resources->OES_texture_storage_multisample_2d_array       = 0;
    218    resources->OES_texture_3D                                 = 0;
    219    resources->ANGLE_shader_pixel_local_storage               = 0;
    220    resources->ANGLE_texture_multisample                      = 0;
    221    resources->ANGLE_multi_draw                               = 0;
    222    resources->ANGLE_base_vertex_base_instance                = 0;
    223    resources->ANGLE_base_vertex_base_instance_shader_builtin = 0;
    224    resources->WEBGL_video_texture                            = 0;
    225    resources->APPLE_clip_distance                            = 0;
    226    resources->OES_texture_cube_map_array                     = 0;
    227    resources->EXT_texture_cube_map_array                     = 0;
    228    resources->EXT_shadow_samplers                            = 0;
    229    resources->OES_shader_multisample_interpolation           = 0;
    230    resources->NV_draw_buffers                                = 0;
    231    resources->OES_shader_image_atomic                        = 0;
    232    resources->EXT_tessellation_shader                        = 0;
    233    resources->OES_texture_buffer                             = 0;
    234    resources->EXT_texture_buffer                             = 0;
    235    resources->OES_sample_variables                           = 0;
    236    resources->EXT_clip_cull_distance                         = 0;
    237    resources->KHR_blend_equation_advanced                    = 0;
    238 
    239    resources->MaxClipDistances                = 8;
    240    resources->MaxCullDistances                = 8;
    241    resources->MaxCombinedClipAndCullDistances = 8;
    242 
    243    // Disable highp precision in fragment shader by default.
    244    resources->FragmentPrecisionHigh = 0;
    245 
    246    // GLSL ES 3.0 constants.
    247    resources->MaxVertexOutputVectors  = 16;
    248    resources->MaxFragmentInputVectors = 15;
    249    resources->MinProgramTexelOffset   = -8;
    250    resources->MaxProgramTexelOffset   = 7;
    251 
    252    // Extensions constants.
    253    resources->MaxDualSourceDrawBuffers = 0;
    254 
    255    resources->MaxViewsOVR = 4;
    256 
    257    // Disable name hashing by default.
    258    resources->HashFunction = nullptr;
    259 
    260    resources->MaxExpressionComplexity = 256;
    261    resources->MaxCallStackDepth       = 256;
    262    resources->MaxFunctionParameters   = 1024;
    263 
    264    // ES 3.1 Revision 4, 7.2 Built-in Constants
    265 
    266    // ES 3.1, Revision 4, 8.13 Texture minification
    267    // "The value of MIN_PROGRAM_TEXTURE_GATHER_OFFSET must be less than or equal to the value of
    268    // MIN_PROGRAM_TEXEL_OFFSET. The value of MAX_PROGRAM_TEXTURE_GATHER_OFFSET must be greater than
    269    // or equal to the value of MAX_PROGRAM_TEXEL_OFFSET"
    270    resources->MinProgramTextureGatherOffset = -8;
    271    resources->MaxProgramTextureGatherOffset = 7;
    272 
    273    resources->MaxImageUnits            = 4;
    274    resources->MaxVertexImageUniforms   = 0;
    275    resources->MaxFragmentImageUniforms = 0;
    276    resources->MaxComputeImageUniforms  = 4;
    277    resources->MaxCombinedImageUniforms = 4;
    278 
    279    resources->MaxUniformLocations = 1024;
    280 
    281    resources->MaxCombinedShaderOutputResources = 4;
    282 
    283    resources->MaxComputeWorkGroupCount[0] = 65535;
    284    resources->MaxComputeWorkGroupCount[1] = 65535;
    285    resources->MaxComputeWorkGroupCount[2] = 65535;
    286    resources->MaxComputeWorkGroupSize[0]  = 128;
    287    resources->MaxComputeWorkGroupSize[1]  = 128;
    288    resources->MaxComputeWorkGroupSize[2]  = 64;
    289    resources->MaxComputeUniformComponents = 512;
    290    resources->MaxComputeTextureImageUnits = 16;
    291 
    292    resources->MaxComputeAtomicCounters       = 8;
    293    resources->MaxComputeAtomicCounterBuffers = 1;
    294 
    295    resources->MaxVertexAtomicCounters   = 0;
    296    resources->MaxFragmentAtomicCounters = 0;
    297    resources->MaxCombinedAtomicCounters = 8;
    298    resources->MaxAtomicCounterBindings  = 1;
    299 
    300    resources->MaxVertexAtomicCounterBuffers   = 0;
    301    resources->MaxFragmentAtomicCounterBuffers = 0;
    302    resources->MaxCombinedAtomicCounterBuffers = 1;
    303    resources->MaxAtomicCounterBufferSize      = 32;
    304 
    305    resources->MaxUniformBufferBindings       = 32;
    306    resources->MaxShaderStorageBufferBindings = 4;
    307 
    308    resources->MaxGeometryUniformComponents     = 1024;
    309    resources->MaxGeometryUniformBlocks         = 12;
    310    resources->MaxGeometryInputComponents       = 64;
    311    resources->MaxGeometryOutputComponents      = 64;
    312    resources->MaxGeometryOutputVertices        = 256;
    313    resources->MaxGeometryTotalOutputComponents = 1024;
    314    resources->MaxGeometryTextureImageUnits     = 16;
    315    resources->MaxGeometryAtomicCounterBuffers  = 0;
    316    resources->MaxGeometryAtomicCounters        = 0;
    317    resources->MaxGeometryShaderStorageBlocks   = 0;
    318    resources->MaxGeometryShaderInvocations     = 32;
    319    resources->MaxGeometryImageUniforms         = 0;
    320 
    321    resources->MaxTessControlInputComponents       = 64;
    322    resources->MaxTessControlOutputComponents      = 64;
    323    resources->MaxTessControlTextureImageUnits     = 16;
    324    resources->MaxTessControlUniformComponents     = 1024;
    325    resources->MaxTessControlTotalOutputComponents = 2048;
    326    resources->MaxTessControlImageUniforms         = 0;
    327    resources->MaxTessControlAtomicCounters        = 0;
    328    resources->MaxTessControlAtomicCounterBuffers  = 0;
    329 
    330    resources->MaxTessPatchComponents = 120;
    331    resources->MaxPatchVertices       = 32;
    332    resources->MaxTessGenLevel        = 64;
    333 
    334    resources->MaxTessEvaluationInputComponents      = 64;
    335    resources->MaxTessEvaluationOutputComponents     = 64;
    336    resources->MaxTessEvaluationTextureImageUnits    = 16;
    337    resources->MaxTessEvaluationUniformComponents    = 1024;
    338    resources->MaxTessEvaluationImageUniforms        = 0;
    339    resources->MaxTessEvaluationAtomicCounters       = 0;
    340    resources->MaxTessEvaluationAtomicCounterBuffers = 0;
    341 
    342    resources->SubPixelBits = 8;
    343 
    344    resources->MaxSamples = 4;
    345 
    346    // Arbitrarily enforce that all types declared with a size in bytes of over 2 GB will cause
    347    // compilation failure.
    348    //
    349    // For local and global variables, the limit is much lower (1MB) as that much memory won't fit in
    350    // the GPU registers anyway.
    351    resources->MaxVariableSizeInBytes        = static_cast<size_t>(2) * 1024 * 1024 * 1024;
    352    resources->MaxPrivateVariableSizeInBytes = static_cast<size_t>(1) * 1024 * 1024;
    353 }
    354 
    355 //
    356 // Driver calls these to create and destroy compiler objects.
    357 //
    358 ShHandle ConstructCompiler(sh::GLenum type,
    359                           ShShaderSpec spec,
    360                           ShShaderOutput output,
    361                           const ShBuiltInResources *resources)
    362 {
    363    TShHandleBase *base = static_cast<TShHandleBase *>(ConstructCompiler(type, spec, output));
    364    if (base == nullptr)
    365    {
    366        return 0;
    367    }
    368 
    369    TCompiler *compiler = base->getAsCompiler();
    370    if (compiler == nullptr)
    371    {
    372        return 0;
    373    }
    374 
    375    // Generate built-in symbol table.
    376    if (!compiler->Init(*resources))
    377    {
    378        Destruct(base);
    379        return 0;
    380    }
    381 
    382    return base;
    383 }
    384 
    385 void Destruct(ShHandle handle)
    386 {
    387    if (handle == 0)
    388        return;
    389 
    390    TShHandleBase *base = static_cast<TShHandleBase *>(handle);
    391 
    392    if (base->getAsCompiler())
    393        DeleteCompiler(base->getAsCompiler());
    394 }
    395 
    396 ShBuiltInResources GetBuiltInResources(const ShHandle handle)
    397 {
    398    TCompiler *compiler = GetCompilerFromHandle(handle);
    399    ASSERT(compiler);
    400    return compiler->getBuiltInResources();
    401 }
    402 
    403 const std::string &GetBuiltInResourcesString(const ShHandle handle)
    404 {
    405    TCompiler *compiler = GetCompilerFromHandle(handle);
    406    ASSERT(compiler);
    407    return compiler->getBuiltInResourcesString();
    408 }
    409 
    410 //
    411 // Do an actual compile on the given strings.  The result is left
    412 // in the given compile object.
    413 //
    414 // Return:  The return value of ShCompile is really boolean, indicating
    415 // success or failure.
    416 //
    417 bool Compile(const ShHandle handle,
    418             const char *const shaderStrings[],
    419             size_t numStrings,
    420             const ShCompileOptions &compileOptions)
    421 {
    422    TCompiler *compiler = GetCompilerFromHandle(handle);
    423    ASSERT(compiler);
    424 
    425    return compiler->compile(shaderStrings, numStrings, compileOptions);
    426 }
    427 
    428 void ClearResults(const ShHandle handle)
    429 {
    430    TCompiler *compiler = GetCompilerFromHandle(handle);
    431    ASSERT(compiler);
    432    compiler->clearResults();
    433 }
    434 
    435 int GetShaderVersion(const ShHandle handle)
    436 {
    437    TCompiler *compiler = GetCompilerFromHandle(handle);
    438    ASSERT(compiler);
    439    return compiler->getShaderVersion();
    440 }
    441 
    442 ShShaderOutput GetShaderOutputType(const ShHandle handle)
    443 {
    444    TCompiler *compiler = GetCompilerFromHandle(handle);
    445    ASSERT(compiler);
    446    return compiler->getOutputType();
    447 }
    448 
    449 //
    450 // Return any compiler log of messages for the application.
    451 //
    452 const std::string &GetInfoLog(const ShHandle handle)
    453 {
    454    TCompiler *compiler = GetCompilerFromHandle(handle);
    455    ASSERT(compiler);
    456 
    457    TInfoSink &infoSink = compiler->getInfoSink();
    458    return infoSink.info.str();
    459 }
    460 
    461 //
    462 // Return any object code.
    463 //
    464 const std::string &GetObjectCode(const ShHandle handle)
    465 {
    466    TCompiler *compiler = GetCompilerFromHandle(handle);
    467    ASSERT(compiler);
    468 
    469    TInfoSink &infoSink = compiler->getInfoSink();
    470    return infoSink.obj.str();
    471 }
    472 
    473 //
    474 // Return any object binary code.
    475 //
    476 const BinaryBlob &GetObjectBinaryBlob(const ShHandle handle)
    477 {
    478    TCompiler *compiler = GetCompilerFromHandle(handle);
    479    ASSERT(compiler);
    480 
    481    TInfoSink &infoSink = compiler->getInfoSink();
    482    return infoSink.obj.getBinary();
    483 }
    484 
    485 const std::map<std::string, std::string> *GetNameHashingMap(const ShHandle handle)
    486 {
    487    TCompiler *compiler = GetCompilerFromHandle(handle);
    488    ASSERT(compiler);
    489    return &(compiler->getNameMap());
    490 }
    491 
    492 const std::vector<ShaderVariable> *GetUniforms(const ShHandle handle)
    493 {
    494    TCompiler *compiler = GetCompilerFromHandle(handle);
    495    if (!compiler)
    496    {
    497        return nullptr;
    498    }
    499    return &compiler->getUniforms();
    500 }
    501 
    502 const std::vector<ShaderVariable> *GetInputVaryings(const ShHandle handle)
    503 {
    504    TCompiler *compiler = GetCompilerFromHandle(handle);
    505    if (compiler == nullptr)
    506    {
    507        return nullptr;
    508    }
    509    return &compiler->getInputVaryings();
    510 }
    511 
    512 const std::vector<ShaderVariable> *GetOutputVaryings(const ShHandle handle)
    513 {
    514    TCompiler *compiler = GetCompilerFromHandle(handle);
    515    if (compiler == nullptr)
    516    {
    517        return nullptr;
    518    }
    519    return &compiler->getOutputVaryings();
    520 }
    521 
    522 const std::vector<ShaderVariable> *GetVaryings(const ShHandle handle)
    523 {
    524    TCompiler *compiler = GetCompilerFromHandle(handle);
    525    if (compiler == nullptr)
    526    {
    527        return nullptr;
    528    }
    529 
    530    switch (compiler->getShaderType())
    531    {
    532        case GL_VERTEX_SHADER:
    533            return &compiler->getOutputVaryings();
    534        case GL_FRAGMENT_SHADER:
    535            return &compiler->getInputVaryings();
    536        case GL_COMPUTE_SHADER:
    537            ASSERT(compiler->getOutputVaryings().empty() && compiler->getInputVaryings().empty());
    538            return &compiler->getOutputVaryings();
    539        // Since geometry shaders have both input and output varyings, we shouldn't call GetVaryings
    540        // on a geometry shader.
    541        default:
    542            return nullptr;
    543    }
    544 }
    545 
    546 const std::vector<ShaderVariable> *GetAttributes(const ShHandle handle)
    547 {
    548    TCompiler *compiler = GetCompilerFromHandle(handle);
    549    if (!compiler)
    550    {
    551        return nullptr;
    552    }
    553    return &compiler->getAttributes();
    554 }
    555 
    556 const std::vector<ShaderVariable> *GetOutputVariables(const ShHandle handle)
    557 {
    558    TCompiler *compiler = GetCompilerFromHandle(handle);
    559    if (!compiler)
    560    {
    561        return nullptr;
    562    }
    563    return &compiler->getOutputVariables();
    564 }
    565 
    566 const std::vector<InterfaceBlock> *GetInterfaceBlocks(const ShHandle handle)
    567 {
    568    return GetShaderVariables<InterfaceBlock>(handle);
    569 }
    570 
    571 const std::vector<InterfaceBlock> *GetUniformBlocks(const ShHandle handle)
    572 {
    573    ASSERT(handle);
    574    TShHandleBase *base = static_cast<TShHandleBase *>(handle);
    575    TCompiler *compiler = base->getAsCompiler();
    576    ASSERT(compiler);
    577 
    578    return &compiler->getUniformBlocks();
    579 }
    580 
    581 const std::vector<InterfaceBlock> *GetShaderStorageBlocks(const ShHandle handle)
    582 {
    583    ASSERT(handle);
    584    TShHandleBase *base = static_cast<TShHandleBase *>(handle);
    585    TCompiler *compiler = base->getAsCompiler();
    586    ASSERT(compiler);
    587 
    588    return &compiler->getShaderStorageBlocks();
    589 }
    590 
    591 WorkGroupSize GetComputeShaderLocalGroupSize(const ShHandle handle)
    592 {
    593    ASSERT(handle);
    594 
    595    TShHandleBase *base = static_cast<TShHandleBase *>(handle);
    596    TCompiler *compiler = base->getAsCompiler();
    597    ASSERT(compiler);
    598 
    599    return compiler->getComputeShaderLocalSize();
    600 }
    601 
    602 int GetVertexShaderNumViews(const ShHandle handle)
    603 {
    604    ASSERT(handle);
    605    TShHandleBase *base = static_cast<TShHandleBase *>(handle);
    606    TCompiler *compiler = base->getAsCompiler();
    607    ASSERT(compiler);
    608 
    609    return compiler->getNumViews();
    610 }
    611 
    612 bool EnablesPerSampleShading(const ShHandle handle)
    613 {
    614    TCompiler *compiler = GetCompilerFromHandle(handle);
    615    if (compiler == nullptr)
    616    {
    617        return false;
    618    }
    619    return compiler->enablesPerSampleShading();
    620 }
    621 
    622 uint32_t GetShaderSpecConstUsageBits(const ShHandle handle)
    623 {
    624    TCompiler *compiler = GetCompilerFromHandle(handle);
    625    if (compiler == nullptr)
    626    {
    627        return 0;
    628    }
    629    return compiler->getSpecConstUsageBits().bits();
    630 }
    631 
    632 bool CheckVariablesWithinPackingLimits(int maxVectors, const std::vector<ShaderVariable> &variables)
    633 {
    634    return CheckVariablesInPackingLimits(maxVectors, variables);
    635 }
    636 
    637 bool GetShaderStorageBlockRegister(const ShHandle handle,
    638                                   const std::string &shaderStorageBlockName,
    639                                   unsigned int *indexOut)
    640 {
    641 #ifdef ANGLE_ENABLE_HLSL
    642    ASSERT(indexOut);
    643 
    644    TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
    645    ASSERT(translator);
    646 
    647    if (!translator->hasShaderStorageBlock(shaderStorageBlockName))
    648    {
    649        return false;
    650    }
    651 
    652    *indexOut = translator->getShaderStorageBlockRegister(shaderStorageBlockName);
    653    return true;
    654 #else
    655    return false;
    656 #endif  // ANGLE_ENABLE_HLSL
    657 }
    658 
    659 bool GetUniformBlockRegister(const ShHandle handle,
    660                             const std::string &uniformBlockName,
    661                             unsigned int *indexOut)
    662 {
    663 #ifdef ANGLE_ENABLE_HLSL
    664    ASSERT(indexOut);
    665 
    666    TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
    667    ASSERT(translator);
    668 
    669    if (!translator->hasUniformBlock(uniformBlockName))
    670    {
    671        return false;
    672    }
    673 
    674    *indexOut = translator->getUniformBlockRegister(uniformBlockName);
    675    return true;
    676 #else
    677    return false;
    678 #endif  // ANGLE_ENABLE_HLSL
    679 }
    680 
    681 bool ShouldUniformBlockUseStructuredBuffer(const ShHandle handle,
    682                                           const std::string &uniformBlockName)
    683 {
    684 #ifdef ANGLE_ENABLE_HLSL
    685    TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
    686    ASSERT(translator);
    687 
    688    return translator->shouldUniformBlockUseStructuredBuffer(uniformBlockName);
    689 #else
    690    return false;
    691 #endif  // ANGLE_ENABLE_HLSL
    692 }
    693 
    694 const std::map<std::string, unsigned int> *GetUniformRegisterMap(const ShHandle handle)
    695 {
    696 #ifdef ANGLE_ENABLE_HLSL
    697    TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
    698    ASSERT(translator);
    699 
    700    return translator->getUniformRegisterMap();
    701 #else
    702    return nullptr;
    703 #endif  // ANGLE_ENABLE_HLSL
    704 }
    705 
    706 const std::set<std::string> *GetSlowCompilingUniformBlockSet(const ShHandle handle)
    707 {
    708 #ifdef ANGLE_ENABLE_HLSL
    709    TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
    710    ASSERT(translator);
    711 
    712    return translator->getSlowCompilingUniformBlockSet();
    713 #else
    714    return nullptr;
    715 #endif  // ANGLE_ENABLE_HLSL
    716 }
    717 
    718 unsigned int GetReadonlyImage2DRegisterIndex(const ShHandle handle)
    719 {
    720 #ifdef ANGLE_ENABLE_HLSL
    721    TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
    722    ASSERT(translator);
    723 
    724    return translator->getReadonlyImage2DRegisterIndex();
    725 #else
    726    return 0;
    727 #endif  // ANGLE_ENABLE_HLSL
    728 }
    729 
    730 unsigned int GetImage2DRegisterIndex(const ShHandle handle)
    731 {
    732 #ifdef ANGLE_ENABLE_HLSL
    733    TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
    734    ASSERT(translator);
    735 
    736    return translator->getImage2DRegisterIndex();
    737 #else
    738    return 0;
    739 #endif  // ANGLE_ENABLE_HLSL
    740 }
    741 
    742 const std::set<std::string> *GetUsedImage2DFunctionNames(const ShHandle handle)
    743 {
    744 #ifdef ANGLE_ENABLE_HLSL
    745    TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
    746    ASSERT(translator);
    747 
    748    return translator->getUsedImage2DFunctionNames();
    749 #else
    750    return nullptr;
    751 #endif  // ANGLE_ENABLE_HLSL
    752 }
    753 
    754 bool HasDiscardInFragmentShader(const ShHandle handle)
    755 {
    756    ASSERT(handle);
    757 
    758    TShHandleBase *base = static_cast<TShHandleBase *>(handle);
    759    TCompiler *compiler = base->getAsCompiler();
    760    ASSERT(compiler);
    761 
    762    return compiler->getShaderType() == GL_FRAGMENT_SHADER && compiler->hasDiscard();
    763 }
    764 
    765 bool HasValidGeometryShaderInputPrimitiveType(const ShHandle handle)
    766 {
    767    ASSERT(handle);
    768 
    769    TShHandleBase *base = static_cast<TShHandleBase *>(handle);
    770    TCompiler *compiler = base->getAsCompiler();
    771    ASSERT(compiler);
    772 
    773    return compiler->getGeometryShaderInputPrimitiveType() != EptUndefined;
    774 }
    775 
    776 bool HasValidGeometryShaderOutputPrimitiveType(const ShHandle handle)
    777 {
    778    ASSERT(handle);
    779 
    780    TShHandleBase *base = static_cast<TShHandleBase *>(handle);
    781    TCompiler *compiler = base->getAsCompiler();
    782    ASSERT(compiler);
    783 
    784    return compiler->getGeometryShaderOutputPrimitiveType() != EptUndefined;
    785 }
    786 
    787 bool HasValidGeometryShaderMaxVertices(const ShHandle handle)
    788 {
    789    ASSERT(handle);
    790 
    791    TShHandleBase *base = static_cast<TShHandleBase *>(handle);
    792    TCompiler *compiler = base->getAsCompiler();
    793    ASSERT(compiler);
    794 
    795    return compiler->getGeometryShaderMaxVertices() >= 0;
    796 }
    797 
    798 bool HasValidTessGenMode(const ShHandle handle)
    799 {
    800    ASSERT(handle);
    801 
    802    TShHandleBase *base = static_cast<TShHandleBase *>(handle);
    803    TCompiler *compiler = base->getAsCompiler();
    804    ASSERT(compiler);
    805 
    806    return compiler->getTessEvaluationShaderInputPrimitiveType() != EtetUndefined;
    807 }
    808 
    809 bool HasValidTessGenSpacing(const ShHandle handle)
    810 {
    811    ASSERT(handle);
    812 
    813    TShHandleBase *base = static_cast<TShHandleBase *>(handle);
    814    TCompiler *compiler = base->getAsCompiler();
    815    ASSERT(compiler);
    816 
    817    return compiler->getTessEvaluationShaderInputVertexSpacingType() != EtetUndefined;
    818 }
    819 
    820 bool HasValidTessGenVertexOrder(const ShHandle handle)
    821 {
    822    ASSERT(handle);
    823 
    824    TShHandleBase *base = static_cast<TShHandleBase *>(handle);
    825    TCompiler *compiler = base->getAsCompiler();
    826    ASSERT(compiler);
    827 
    828    return compiler->getTessEvaluationShaderInputOrderingType() != EtetUndefined;
    829 }
    830 
    831 bool HasValidTessGenPointMode(const ShHandle handle)
    832 {
    833    ASSERT(handle);
    834 
    835    TShHandleBase *base = static_cast<TShHandleBase *>(handle);
    836    TCompiler *compiler = base->getAsCompiler();
    837    ASSERT(compiler);
    838 
    839    return compiler->getTessEvaluationShaderInputPointType() != EtetUndefined;
    840 }
    841 
    842 GLenum GetGeometryShaderInputPrimitiveType(const ShHandle handle)
    843 {
    844    ASSERT(handle);
    845 
    846    TShHandleBase *base = static_cast<TShHandleBase *>(handle);
    847    TCompiler *compiler = base->getAsCompiler();
    848    ASSERT(compiler);
    849 
    850    return GetGeometryShaderPrimitiveTypeEnum(compiler->getGeometryShaderInputPrimitiveType());
    851 }
    852 
    853 GLenum GetGeometryShaderOutputPrimitiveType(const ShHandle handle)
    854 {
    855    ASSERT(handle);
    856 
    857    TShHandleBase *base = static_cast<TShHandleBase *>(handle);
    858    TCompiler *compiler = base->getAsCompiler();
    859    ASSERT(compiler);
    860 
    861    return GetGeometryShaderPrimitiveTypeEnum(compiler->getGeometryShaderOutputPrimitiveType());
    862 }
    863 
    864 int GetGeometryShaderInvocations(const ShHandle handle)
    865 {
    866    ASSERT(handle);
    867 
    868    TShHandleBase *base = static_cast<TShHandleBase *>(handle);
    869    TCompiler *compiler = base->getAsCompiler();
    870    ASSERT(compiler);
    871 
    872    return compiler->getGeometryShaderInvocations();
    873 }
    874 
    875 int GetGeometryShaderMaxVertices(const ShHandle handle)
    876 {
    877    ASSERT(handle);
    878 
    879    TShHandleBase *base = static_cast<TShHandleBase *>(handle);
    880    TCompiler *compiler = base->getAsCompiler();
    881    ASSERT(compiler);
    882 
    883    int maxVertices = compiler->getGeometryShaderMaxVertices();
    884    ASSERT(maxVertices >= 0);
    885    return maxVertices;
    886 }
    887 
    888 int GetTessControlShaderVertices(const ShHandle handle)
    889 {
    890    ASSERT(handle);
    891 
    892    TShHandleBase *base = static_cast<TShHandleBase *>(handle);
    893    TCompiler *compiler = base->getAsCompiler();
    894    ASSERT(compiler);
    895 
    896    int vertices = compiler->getTessControlShaderOutputVertices();
    897    return vertices;
    898 }
    899 
    900 GLenum GetTessGenMode(const ShHandle handle)
    901 {
    902    ASSERT(handle);
    903 
    904    TShHandleBase *base = static_cast<TShHandleBase *>(handle);
    905    TCompiler *compiler = base->getAsCompiler();
    906    ASSERT(compiler);
    907 
    908    return GetTessellationShaderTypeEnum(compiler->getTessEvaluationShaderInputPrimitiveType());
    909 }
    910 
    911 GLenum GetTessGenSpacing(const ShHandle handle)
    912 {
    913    ASSERT(handle);
    914 
    915    TShHandleBase *base = static_cast<TShHandleBase *>(handle);
    916    TCompiler *compiler = base->getAsCompiler();
    917    ASSERT(compiler);
    918 
    919    return GetTessellationShaderTypeEnum(compiler->getTessEvaluationShaderInputVertexSpacingType());
    920 }
    921 
    922 GLenum GetTessGenVertexOrder(const ShHandle handle)
    923 {
    924    ASSERT(handle);
    925 
    926    TShHandleBase *base = static_cast<TShHandleBase *>(handle);
    927    TCompiler *compiler = base->getAsCompiler();
    928    ASSERT(compiler);
    929 
    930    return GetTessellationShaderTypeEnum(compiler->getTessEvaluationShaderInputOrderingType());
    931 }
    932 
    933 GLenum GetTessGenPointMode(const ShHandle handle)
    934 {
    935    ASSERT(handle);
    936 
    937    TShHandleBase *base = static_cast<TShHandleBase *>(handle);
    938    TCompiler *compiler = base->getAsCompiler();
    939    ASSERT(compiler);
    940 
    941    return GetTessellationShaderTypeEnum(compiler->getTessEvaluationShaderInputPointType());
    942 }
    943 
    944 unsigned int GetShaderSharedMemorySize(const ShHandle handle)
    945 {
    946    ASSERT(handle);
    947 
    948    TShHandleBase *base = static_cast<TShHandleBase *>(handle);
    949    TCompiler *compiler = base->getAsCompiler();
    950    ASSERT(compiler);
    951 
    952    unsigned int sharedMemorySize = compiler->getSharedMemorySize();
    953    return sharedMemorySize;
    954 }
    955 
    956 uint32_t GetAdvancedBlendEquations(const ShHandle handle)
    957 {
    958    TCompiler *compiler = GetCompilerFromHandle(handle);
    959    ASSERT(compiler);
    960 
    961    return compiler->getAdvancedBlendEquations().bits();
    962 }
    963 
    964 void InitializeGlslang()
    965 {
    966    if (initializeGlslangRefCount == 0)
    967    {
    968        GlslangInitialize();
    969    }
    970    ++initializeGlslangRefCount;
    971    ASSERT(initializeGlslangRefCount < std::numeric_limits<int>::max());
    972 }
    973 
    974 void FinalizeGlslang()
    975 {
    976    --initializeGlslangRefCount;
    977    ASSERT(initializeGlslangRefCount >= 0);
    978    if (initializeGlslangRefCount == 0)
    979    {
    980        GlslangFinalize();
    981    }
    982 }
    983 
    984 // Can't prefix with just _ because then we might introduce a double underscore, which is not safe
    985 // in GLSL (ESSL 3.00.6 section 3.8: All identifiers containing a double underscore are reserved for
    986 // use by the underlying implementation). u is short for user-defined.
    987 const char kUserDefinedNamePrefix[] = "_u";
    988 
    989 namespace vk
    990 {
    991 // Interface block name containing the aggregate default uniforms
    992 const char kDefaultUniformsNameVS[]  = "defaultUniformsVS";
    993 const char kDefaultUniformsNameTCS[] = "defaultUniformsTCS";
    994 const char kDefaultUniformsNameTES[] = "defaultUniformsTES";
    995 const char kDefaultUniformsNameGS[]  = "defaultUniformsGS";
    996 const char kDefaultUniformsNameFS[]  = "defaultUniformsFS";
    997 const char kDefaultUniformsNameCS[]  = "defaultUniformsCS";
    998 
    999 // Interface block and variable names containing driver uniforms
   1000 const char kDriverUniformsBlockName[] = "ANGLEUniformBlock";
   1001 const char kDriverUniformsVarName[]   = "ANGLEUniforms";
   1002 
   1003 // Interface block array name used for atomic counter emulation
   1004 const char kAtomicCountersBlockName[] = "ANGLEAtomicCounters";
   1005 
   1006 const char kXfbEmulationGetOffsetsFunctionName[] = "ANGLEGetXfbOffsets";
   1007 const char kXfbEmulationCaptureFunctionName[]    = "ANGLECaptureXfb";
   1008 const char kXfbEmulationBufferBlockName[]        = "ANGLEXfbBuffer";
   1009 const char kXfbEmulationBufferName[]             = "ANGLEXfb";
   1010 const char kXfbEmulationBufferFieldName[]        = "xfbOut";
   1011 
   1012 const char kTransformPositionFunctionName[] = "ANGLETransformPosition";
   1013 
   1014 const char kXfbExtensionPositionOutName[] = "ANGLEXfbPosition";
   1015 
   1016 // EXT_shader_framebuffer_fetch / EXT_shader_framebuffer_fetch_non_coherent
   1017 const char kInputAttachmentName[] = "ANGLEInputAttachment";
   1018 
   1019 }  // namespace vk
   1020 
   1021 const char *BlockLayoutTypeToString(BlockLayoutType type)
   1022 {
   1023    switch (type)
   1024    {
   1025        case BlockLayoutType::BLOCKLAYOUT_STD140:
   1026            return "std140";
   1027        case BlockLayoutType::BLOCKLAYOUT_STD430:
   1028            return "std430";
   1029        case BlockLayoutType::BLOCKLAYOUT_PACKED:
   1030            return "packed";
   1031        case BlockLayoutType::BLOCKLAYOUT_SHARED:
   1032            return "shared";
   1033        default:
   1034            return "invalid";
   1035    }
   1036 }
   1037 
   1038 const char *BlockTypeToString(BlockType type)
   1039 {
   1040    switch (type)
   1041    {
   1042        case BlockType::BLOCK_BUFFER:
   1043            return "buffer";
   1044        case BlockType::BLOCK_UNIFORM:
   1045            return "uniform";
   1046        default:
   1047            return "invalid";
   1048    }
   1049 }
   1050 
   1051 const char *InterpolationTypeToString(InterpolationType type)
   1052 {
   1053    switch (type)
   1054    {
   1055        case InterpolationType::INTERPOLATION_SMOOTH:
   1056            return "smooth";
   1057        case InterpolationType::INTERPOLATION_CENTROID:
   1058            return "centroid";
   1059        case InterpolationType::INTERPOLATION_SAMPLE:
   1060            return "sample";
   1061        case InterpolationType::INTERPOLATION_FLAT:
   1062            return "flat";
   1063        case InterpolationType::INTERPOLATION_NOPERSPECTIVE:
   1064            return "noperspective";
   1065        default:
   1066            return "invalid";
   1067    }
   1068 }
   1069 }  // namespace sh
   1070 
   1071 ShCompileOptions::ShCompileOptions()
   1072 {
   1073    memset(this, 0, sizeof(*this));
   1074 }
   1075 
   1076 ShCompileOptions::ShCompileOptions(const ShCompileOptions &other)
   1077 {
   1078    memcpy(this, &other, sizeof(*this));
   1079 }
   1080 ShCompileOptions &ShCompileOptions::operator=(const ShCompileOptions &other)
   1081 {
   1082    memcpy(this, &other, sizeof(*this));
   1083    return *this;
   1084 }
   1085 
   1086 ShBuiltInResources::ShBuiltInResources()
   1087 {
   1088    memset(this, 0, sizeof(*this));
   1089 }
   1090 
   1091 ShBuiltInResources::ShBuiltInResources(const ShBuiltInResources &other)
   1092 {
   1093    memcpy(this, &other, sizeof(*this));
   1094 }
   1095 ShBuiltInResources &ShBuiltInResources::operator=(const ShBuiltInResources &other)
   1096 {
   1097    memcpy(this, &other, sizeof(*this));
   1098    return *this;
   1099 }