tor-browser

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

TranslatorESSL.cpp (8585B)


      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 #include "compiler/translator/TranslatorESSL.h"
      8 
      9 #include "angle_gl.h"
     10 #include "common/utilities.h"
     11 #include "compiler/translator/BuiltInFunctionEmulatorGLSL.h"
     12 #include "compiler/translator/OutputESSL.h"
     13 #include "compiler/translator/tree_ops/RecordConstantPrecision.h"
     14 
     15 namespace sh
     16 {
     17 
     18 TranslatorESSL::TranslatorESSL(sh::GLenum type, ShShaderSpec spec)
     19    : TCompiler(type, spec, SH_ESSL_OUTPUT)
     20 {}
     21 
     22 void TranslatorESSL::initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu,
     23                                                 const ShCompileOptions &compileOptions)
     24 {
     25    if (compileOptions.emulateAtan2FloatFunction)
     26    {
     27        InitBuiltInAtanFunctionEmulatorForGLSLWorkarounds(emu);
     28    }
     29 }
     30 
     31 bool TranslatorESSL::translate(TIntermBlock *root,
     32                               const ShCompileOptions &compileOptions,
     33                               PerformanceDiagnostics * /*perfDiagnostics*/)
     34 {
     35    TInfoSinkBase &sink = getInfoSink().obj;
     36 
     37    int shaderVer = getShaderVersion();  // Frontend shader version.
     38    if (hasPixelLocalStorageUniforms() &&
     39        ShPixelLocalStorageTypeUsesImages(compileOptions.pls.type))
     40    {
     41        // The backend translator emits shader image code. Use a minimum version of 310.
     42        shaderVer = std::max(shaderVer, 310);
     43    }
     44    if (shaderVer > 100)
     45    {
     46        sink << "#version " << shaderVer << " es\n";
     47    }
     48 
     49    // Write built-in extension behaviors.
     50    writeExtensionBehavior(compileOptions);
     51 
     52    // Write pragmas after extensions because some drivers consider pragmas
     53    // like non-preprocessor tokens.
     54    WritePragma(sink, compileOptions, getPragma());
     55 
     56    if (!RecordConstantPrecision(this, root, &getSymbolTable()))
     57    {
     58        return false;
     59    }
     60 
     61    // Write emulated built-in functions if needed.
     62    if (!getBuiltInFunctionEmulator().isOutputEmpty())
     63    {
     64        sink << "// BEGIN: Generated code for built-in function emulation\n\n";
     65        if (getShaderType() == GL_FRAGMENT_SHADER)
     66        {
     67            sink << "#if defined(GL_FRAGMENT_PRECISION_HIGH)\n"
     68                 << "#define emu_precision highp\n"
     69                 << "#else\n"
     70                 << "#define emu_precision mediump\n"
     71                 << "#endif\n\n";
     72        }
     73        else
     74        {
     75            sink << "#define emu_precision highp\n";
     76        }
     77 
     78        getBuiltInFunctionEmulator().outputEmulatedFunctions(sink);
     79        sink << "// END: Generated code for built-in function emulation\n\n";
     80    }
     81 
     82    if (getShaderType() == GL_FRAGMENT_SHADER)
     83    {
     84        EmitEarlyFragmentTestsGLSL(*this, sink);
     85    }
     86 
     87    if (getShaderType() == GL_COMPUTE_SHADER)
     88    {
     89        EmitWorkGroupSizeGLSL(*this, sink);
     90    }
     91 
     92    if (getShaderType() == GL_GEOMETRY_SHADER_EXT)
     93    {
     94        WriteGeometryShaderLayoutQualifiers(
     95            sink, getGeometryShaderInputPrimitiveType(), getGeometryShaderInvocations(),
     96            getGeometryShaderOutputPrimitiveType(), getGeometryShaderMaxVertices());
     97    }
     98 
     99    // Write translated shader.
    100    TOutputESSL outputESSL(this, sink, compileOptions);
    101 
    102    root->traverse(&outputESSL);
    103 
    104    return true;
    105 }
    106 
    107 bool TranslatorESSL::shouldFlattenPragmaStdglInvariantAll()
    108 {
    109    // If following the spec to the letter, we should not flatten this pragma.
    110    // However, the spec's wording means that the pragma applies only to outputs.
    111    // This contradicts the spirit of using the pragma,
    112    // because if the pragma is used in a vertex shader,
    113    // the only way to be able to link it to a fragment shader
    114    // is to manually qualify each of fragment shader's inputs as invariant.
    115    // Which defeats the purpose of this pragma - temporarily make all varyings
    116    // invariant for debugging.
    117    // Thus, we should be non-conformant to spec's letter here and flatten.
    118    return true;
    119 }
    120 
    121 void TranslatorESSL::writeExtensionBehavior(const ShCompileOptions &compileOptions)
    122 {
    123    TInfoSinkBase &sink                   = getInfoSink().obj;
    124    const TExtensionBehavior &extBehavior = getExtensionBehavior();
    125    for (TExtensionBehavior::const_iterator iter = extBehavior.begin(); iter != extBehavior.end();
    126         ++iter)
    127    {
    128        if (iter->second != EBhUndefined)
    129        {
    130            const bool isMultiview = (iter->first == TExtension::OVR_multiview) ||
    131                                     (iter->first == TExtension::OVR_multiview2);
    132            if (getResources().NV_shader_framebuffer_fetch &&
    133                iter->first == TExtension::EXT_shader_framebuffer_fetch)
    134            {
    135                sink << "#extension GL_NV_shader_framebuffer_fetch : "
    136                     << GetBehaviorString(iter->second) << "\n";
    137            }
    138            else if (getResources().NV_draw_buffers && iter->first == TExtension::EXT_draw_buffers)
    139            {
    140                sink << "#extension GL_NV_draw_buffers : " << GetBehaviorString(iter->second)
    141                     << "\n";
    142            }
    143            else if (isMultiview)
    144            {
    145                // Only either OVR_multiview OR OVR_multiview2 should be emitted.
    146                if ((iter->first != TExtension::OVR_multiview) ||
    147                    !IsExtensionEnabled(extBehavior, TExtension::OVR_multiview2))
    148                {
    149                    EmitMultiviewGLSL(*this, compileOptions, iter->first, iter->second, sink);
    150                }
    151            }
    152            else if (iter->first == TExtension::EXT_geometry_shader ||
    153                     iter->first == TExtension::OES_geometry_shader)
    154            {
    155                sink << "#ifdef GL_EXT_geometry_shader\n"
    156                     << "#extension GL_EXT_geometry_shader : " << GetBehaviorString(iter->second)
    157                     << "\n"
    158                     << "#elif defined GL_OES_geometry_shader\n"
    159                     << "#extension GL_OES_geometry_shader : " << GetBehaviorString(iter->second)
    160                     << "\n";
    161                if (iter->second == EBhRequire)
    162                {
    163                    sink << "#else\n"
    164                         << "#error \"No geometry shader extensions available.\" // Only generate "
    165                            "this if the extension is \"required\"\n";
    166                }
    167                sink << "#endif\n";
    168            }
    169            else if (iter->first == TExtension::ANGLE_multi_draw)
    170            {
    171                // Don't emit anything. This extension is emulated
    172                ASSERT(compileOptions.emulateGLDrawID);
    173                continue;
    174            }
    175            else if (iter->first == TExtension::ANGLE_base_vertex_base_instance_shader_builtin)
    176            {
    177                // Don't emit anything. This extension is emulated
    178                ASSERT(compileOptions.emulateGLBaseVertexBaseInstance);
    179                continue;
    180            }
    181            else if (iter->first == TExtension::ANGLE_shader_pixel_local_storage)
    182            {
    183                // TODO(anglebug.com/7279): future impl that uses EXT_shader_pixel_local_storage.
    184                if (compileOptions.pls.type == ShPixelLocalStorageType::FramebufferFetch)
    185                {
    186                    // Just enable the extension. Appropriate warnings will be generated by the
    187                    // frontend compiler for GL_ANGLE_shader_pixel_local_storage, if desired.
    188                    sink << "#extension GL_EXT_shader_framebuffer_fetch : enable\n";
    189                }
    190                continue;
    191            }
    192            else if (iter->first == TExtension::EXT_shader_framebuffer_fetch)
    193            {
    194                sink << "#extension GL_EXT_shader_framebuffer_fetch : "
    195                     << GetBehaviorString(iter->second) << "\n";
    196                continue;
    197            }
    198            else if (iter->first == TExtension::EXT_shader_framebuffer_fetch_non_coherent)
    199            {
    200                sink << "#extension GL_EXT_shader_framebuffer_fetch_non_coherent : "
    201                     << GetBehaviorString(iter->second) << "\n";
    202                continue;
    203            }
    204            else if (iter->first == TExtension::WEBGL_video_texture)
    205            {
    206                // Don't emit anything. This extension is emulated
    207                // TODO(crbug.com/776222): support external image.
    208                continue;
    209            }
    210            else
    211            {
    212                sink << "#extension " << GetExtensionNameString(iter->first) << " : "
    213                     << GetBehaviorString(iter->second) << "\n";
    214            }
    215        }
    216    }
    217 }
    218 
    219 }  // namespace sh