Home | History | Annotate | Download | only in MachineIndependent
      1 //
      2 // Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
      3 // Copyright (C) 2012-2013 LunarG, Inc.
      4 // Copyright (C) 2017 ARM Limited.
      5 // Copyright (C) 2015-2018 Google, Inc.
      6 //
      7 // All rights reserved.
      8 //
      9 // Redistribution and use in source and binary forms, with or without
     10 // modification, are permitted provided that the following conditions
     11 // are met:
     12 //
     13 //    Redistributions of source code must retain the above copyright
     14 //    notice, this list of conditions and the following disclaimer.
     15 //
     16 //    Redistributions in binary form must reproduce the above
     17 //    copyright notice, this list of conditions and the following
     18 //    disclaimer in the documentation and/or other materials provided
     19 //    with the distribution.
     20 //
     21 //    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
     22 //    contributors may be used to endorse or promote products derived
     23 //    from this software without specific prior written permission.
     24 //
     25 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     26 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     27 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     28 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     29 // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     30 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     31 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     32 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
     33 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     34 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
     35 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36 // POSSIBILITY OF SUCH DAMAGE.
     37 //
     38 
     39 //
     40 // Help manage multiple profiles, versions, extensions etc.
     41 //
     42 // These don't return error codes, as the presumption is parsing will
     43 // always continue as if the tested feature were enabled, and thus there
     44 // is no error recovery needed.
     45 //
     46 
     47 //
     48 // HOW TO add a feature enabled by an extension.
     49 //
     50 // To add a new hypothetical "Feature F" to the front end, where an extension
     51 // "XXX_extension_X" can be used to enable the feature, do the following.
     52 //
     53 // OVERVIEW: Specific features are what are error-checked for, not
     54 //    extensions:  A specific Feature F might be enabled by an extension, or a
     55 //    particular version in a particular profile, or a stage, or combinations, etc.
     56 //
     57 //    The basic mechanism is to use the following to "declare" all the things that
     58 //    enable/disable Feature F, in a code path that implements Feature F:
     59 //
     60 //        requireProfile()
     61 //        profileRequires()
     62 //        requireStage()
     63 //        checkDeprecated()
     64 //        requireNotRemoved()
     65 //        requireExtensions()
     66 //
     67 //    Typically, only the first two calls are needed.  They go into a code path that
     68 //    implements Feature F, and will log the proper error/warning messages.  Parsing
     69 //    will then always continue as if the tested feature was enabled.
     70 //
     71 //    There is typically no if-testing or conditional parsing, just insertion of the calls above.
     72 //    However, if symbols specific to the extension are added (step 5), they will
     73 //    only be added under tests that the minimum version and profile are present.
     74 //
     75 // 1) Add a symbol name for the extension string at the bottom of Versions.h:
     76 //
     77 //     const char* const XXX_extension_X = "XXX_extension_X";
     78 //
     79 // 2) Add extension initialization to TParseVersions::initializeExtensionBehavior(),
     80 //    the first function below:
     81 //
     82 //     extensionBehavior[XXX_extension_X] = EBhDisable;
     83 //
     84 // 3) Add any preprocessor directives etc. in the next function, TParseVersions::getPreamble():
     85 //
     86 //           "#define XXX_extension_X 1\n"
     87 //
     88 //    The new-line is important, as that ends preprocess tokens.
     89 //
     90 // 4) Insert a profile check in the feature's path (unless all profiles support the feature,
     91 //    for some version level).  That is, call requireProfile() to constrain the profiles, e.g.:
     92 //
     93 //         // ... in a path specific to Feature F...
     94 //         requireProfile(loc,
     95 //                        ECoreProfile | ECompatibilityProfile,
     96 //                        "Feature F");
     97 //
     98 // 5) For each profile that supports the feature, insert version/extension checks:
     99 //
    100 //    The mostly likely scenario is that Feature F can only be used with a
    101 //    particular profile if XXX_extension_X is present or the version is
    102 //    high enough that the core specification already incorporated it.
    103 //
    104 //        // following the requireProfile() call...
    105 //        profileRequires(loc,
    106 //                        ECoreProfile | ECompatibilityProfile,
    107 //                        420,             // 0 if no version incorporated the feature into the core spec.
    108 //                        XXX_extension_X, // can be a list of extensions that all add the feature
    109 //                        "Feature F Description");
    110 //
    111 //    This allows the feature if either A) one of the extensions is enabled or
    112 //    B) the version is high enough.  If no version yet incorporates the feature
    113 //    into core, pass in 0.
    114 //
    115 //    This can be called multiple times, if different profiles support the
    116 //    feature starting at different version numbers or with different
    117 //    extensions.
    118 //
    119 //    This must be called for each profile allowed by the initial call to requireProfile().
    120 //
    121 //    Profiles are all masks, which can be "or"-ed together.
    122 //
    123 //        ENoProfile
    124 //        ECoreProfile
    125 //        ECompatibilityProfile
    126 //        EEsProfile
    127 //
    128 //    The ENoProfile profile is only for desktop, before profiles showed up in version 150;
    129 //    All other #version with no profile default to either es or core, and so have profiles.
    130 //
    131 //    You can select all but a particular profile using ~.  The following basically means "desktop":
    132 //
    133 //        ~EEsProfile
    134 //
    135 // 6) If built-in symbols are added by the extension, add them in Initialize.cpp:  Their use
    136 //    will be automatically error checked against the extensions enabled at that moment.
    137 //    see the comment at the top of Initialize.cpp for where to put them.  Establish them at
    138 //    the earliest release that supports the extension.  Then, tag them with the
    139 //    set of extensions that both enable them and are necessary, given the version of the symbol
    140 //    table. (There is a different symbol table for each version.)
    141 //
    142 
    143 #include "parseVersions.h"
    144 #include "localintermediate.h"
    145 
    146 namespace glslang {
    147 
    148 //
    149 // Initialize all extensions, almost always to 'disable', as once their features
    150 // are incorporated into a core version, their features are supported through allowing that
    151 // core version, not through a pseudo-enablement of the extension.
    152 //
    153 void TParseVersions::initializeExtensionBehavior()
    154 {
    155     extensionBehavior[E_GL_OES_texture_3D]                   = EBhDisable;
    156     extensionBehavior[E_GL_OES_standard_derivatives]         = EBhDisable;
    157     extensionBehavior[E_GL_EXT_frag_depth]                   = EBhDisable;
    158     extensionBehavior[E_GL_OES_EGL_image_external]           = EBhDisable;
    159     extensionBehavior[E_GL_OES_EGL_image_external_essl3]     = EBhDisable;
    160     extensionBehavior[E_GL_EXT_shader_texture_lod]           = EBhDisable;
    161     extensionBehavior[E_GL_EXT_shadow_samplers]              = EBhDisable;
    162     extensionBehavior[E_GL_ARB_texture_rectangle]            = EBhDisable;
    163     extensionBehavior[E_GL_3DL_array_objects]                = EBhDisable;
    164     extensionBehavior[E_GL_ARB_shading_language_420pack]     = EBhDisable;
    165     extensionBehavior[E_GL_ARB_texture_gather]               = EBhDisable;
    166     extensionBehavior[E_GL_ARB_gpu_shader5]                  = EBhDisablePartial;
    167     extensionBehavior[E_GL_ARB_separate_shader_objects]      = EBhDisable;
    168     extensionBehavior[E_GL_ARB_compute_shader]               = EBhDisable;
    169     extensionBehavior[E_GL_ARB_tessellation_shader]          = EBhDisable;
    170     extensionBehavior[E_GL_ARB_enhanced_layouts]             = EBhDisable;
    171     extensionBehavior[E_GL_ARB_texture_cube_map_array]       = EBhDisable;
    172     extensionBehavior[E_GL_ARB_shader_texture_lod]           = EBhDisable;
    173     extensionBehavior[E_GL_ARB_explicit_attrib_location]     = EBhDisable;
    174     extensionBehavior[E_GL_ARB_shader_image_load_store]      = EBhDisable;
    175     extensionBehavior[E_GL_ARB_shader_atomic_counters]       = EBhDisable;
    176     extensionBehavior[E_GL_ARB_shader_draw_parameters]       = EBhDisable;
    177     extensionBehavior[E_GL_ARB_shader_group_vote]            = EBhDisable;
    178     extensionBehavior[E_GL_ARB_derivative_control]           = EBhDisable;
    179     extensionBehavior[E_GL_ARB_shader_texture_image_samples] = EBhDisable;
    180     extensionBehavior[E_GL_ARB_viewport_array]               = EBhDisable;
    181     extensionBehavior[E_GL_ARB_gpu_shader_int64]             = EBhDisable;
    182     extensionBehavior[E_GL_ARB_shader_ballot]                = EBhDisable;
    183     extensionBehavior[E_GL_ARB_sparse_texture2]              = EBhDisable;
    184     extensionBehavior[E_GL_ARB_sparse_texture_clamp]         = EBhDisable;
    185     extensionBehavior[E_GL_ARB_shader_stencil_export]        = EBhDisable;
    186 //    extensionBehavior[E_GL_ARB_cull_distance]                = EBhDisable;    // present for 4.5, but need extension control over block members
    187     extensionBehavior[E_GL_ARB_post_depth_coverage]          = EBhDisable;
    188     extensionBehavior[E_GL_ARB_shader_viewport_layer_array]  = EBhDisable;
    189 
    190     extensionBehavior[E_GL_KHR_shader_subgroup_basic]            = EBhDisable;
    191     extensionBehavior[E_GL_KHR_shader_subgroup_vote]             = EBhDisable;
    192     extensionBehavior[E_GL_KHR_shader_subgroup_arithmetic]       = EBhDisable;
    193     extensionBehavior[E_GL_KHR_shader_subgroup_ballot]           = EBhDisable;
    194     extensionBehavior[E_GL_KHR_shader_subgroup_shuffle]          = EBhDisable;
    195     extensionBehavior[E_GL_KHR_shader_subgroup_shuffle_relative] = EBhDisable;
    196     extensionBehavior[E_GL_KHR_shader_subgroup_clustered]        = EBhDisable;
    197     extensionBehavior[E_GL_KHR_shader_subgroup_quad]             = EBhDisable;
    198     extensionBehavior[E_GL_KHR_memory_scope_semantics]           = EBhDisable;
    199 
    200     extensionBehavior[E_GL_EXT_shader_atomic_int64]              = EBhDisable;
    201 
    202     extensionBehavior[E_GL_EXT_shader_non_constant_global_initializers] = EBhDisable;
    203     extensionBehavior[E_GL_EXT_shader_image_load_formatted]             = EBhDisable;
    204     extensionBehavior[E_GL_EXT_post_depth_coverage]                     = EBhDisable;
    205     extensionBehavior[E_GL_EXT_control_flow_attributes]                 = EBhDisable;
    206     extensionBehavior[E_GL_EXT_nonuniform_qualifier]                    = EBhDisable;
    207     extensionBehavior[E_GL_EXT_samplerless_texture_functions]           = EBhDisable;
    208     extensionBehavior[E_GL_EXT_scalar_block_layout]                     = EBhDisable;
    209     extensionBehavior[E_GL_EXT_fragment_invocation_density]             = EBhDisable;
    210     extensionBehavior[E_GL_EXT_buffer_reference]                        = EBhDisable;
    211 
    212     extensionBehavior[E_GL_EXT_shader_16bit_storage]                    = EBhDisable;
    213     extensionBehavior[E_GL_EXT_shader_8bit_storage]                     = EBhDisable;
    214 
    215     // #line and #include
    216     extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive]          = EBhDisable;
    217     extensionBehavior[E_GL_GOOGLE_include_directive]                 = EBhDisable;
    218 
    219 #ifdef AMD_EXTENSIONS
    220     extensionBehavior[E_GL_AMD_shader_ballot]                        = EBhDisable;
    221     extensionBehavior[E_GL_AMD_shader_trinary_minmax]                = EBhDisable;
    222     extensionBehavior[E_GL_AMD_shader_explicit_vertex_parameter]     = EBhDisable;
    223     extensionBehavior[E_GL_AMD_gcn_shader]                           = EBhDisable;
    224     extensionBehavior[E_GL_AMD_gpu_shader_half_float]                = EBhDisable;
    225     extensionBehavior[E_GL_AMD_texture_gather_bias_lod]              = EBhDisable;
    226     extensionBehavior[E_GL_AMD_gpu_shader_int16]                     = EBhDisable;
    227     extensionBehavior[E_GL_AMD_shader_image_load_store_lod]          = EBhDisable;
    228     extensionBehavior[E_GL_AMD_shader_fragment_mask]                 = EBhDisable;
    229     extensionBehavior[E_GL_AMD_gpu_shader_half_float_fetch]          = EBhDisable;
    230 #endif
    231 
    232 #ifdef NV_EXTENSIONS
    233     extensionBehavior[E_GL_NV_sample_mask_override_coverage]         = EBhDisable;
    234     extensionBehavior[E_SPV_NV_geometry_shader_passthrough]          = EBhDisable;
    235     extensionBehavior[E_GL_NV_viewport_array2]                       = EBhDisable;
    236     extensionBehavior[E_GL_NV_stereo_view_rendering]                 = EBhDisable;
    237     extensionBehavior[E_GL_NVX_multiview_per_view_attributes]        = EBhDisable;
    238     extensionBehavior[E_GL_NV_shader_atomic_int64]                   = EBhDisable;
    239     extensionBehavior[E_GL_NV_conservative_raster_underestimation]   = EBhDisable;
    240     extensionBehavior[E_GL_NV_shader_noperspective_interpolation]    = EBhDisable;
    241     extensionBehavior[E_GL_NV_shader_subgroup_partitioned]           = EBhDisable;
    242     extensionBehavior[E_GL_NV_shading_rate_image]                    = EBhDisable;
    243     extensionBehavior[E_GL_NV_ray_tracing]                           = EBhDisable;
    244     extensionBehavior[E_GL_NV_fragment_shader_barycentric]           = EBhDisable;
    245     extensionBehavior[E_GL_NV_compute_shader_derivatives]            = EBhDisable;
    246     extensionBehavior[E_GL_NV_shader_texture_footprint]              = EBhDisable;
    247     extensionBehavior[E_GL_NV_mesh_shader]                           = EBhDisable;
    248 #endif
    249 
    250     // AEP
    251     extensionBehavior[E_GL_ANDROID_extension_pack_es31a]             = EBhDisable;
    252     extensionBehavior[E_GL_KHR_blend_equation_advanced]              = EBhDisable;
    253     extensionBehavior[E_GL_OES_sample_variables]                     = EBhDisable;
    254     extensionBehavior[E_GL_OES_shader_image_atomic]                  = EBhDisable;
    255     extensionBehavior[E_GL_OES_shader_multisample_interpolation]     = EBhDisable;
    256     extensionBehavior[E_GL_OES_texture_storage_multisample_2d_array] = EBhDisable;
    257     extensionBehavior[E_GL_EXT_geometry_shader]                      = EBhDisable;
    258     extensionBehavior[E_GL_EXT_geometry_point_size]                  = EBhDisable;
    259     extensionBehavior[E_GL_EXT_gpu_shader5]                          = EBhDisable;
    260     extensionBehavior[E_GL_EXT_primitive_bounding_box]               = EBhDisable;
    261     extensionBehavior[E_GL_EXT_shader_io_blocks]                     = EBhDisable;
    262     extensionBehavior[E_GL_EXT_tessellation_shader]                  = EBhDisable;
    263     extensionBehavior[E_GL_EXT_tessellation_point_size]              = EBhDisable;
    264     extensionBehavior[E_GL_EXT_texture_buffer]                       = EBhDisable;
    265     extensionBehavior[E_GL_EXT_texture_cube_map_array]               = EBhDisable;
    266 
    267     // OES matching AEP
    268     extensionBehavior[E_GL_OES_geometry_shader]          = EBhDisable;
    269     extensionBehavior[E_GL_OES_geometry_point_size]      = EBhDisable;
    270     extensionBehavior[E_GL_OES_gpu_shader5]              = EBhDisable;
    271     extensionBehavior[E_GL_OES_primitive_bounding_box]   = EBhDisable;
    272     extensionBehavior[E_GL_OES_shader_io_blocks]         = EBhDisable;
    273     extensionBehavior[E_GL_OES_tessellation_shader]      = EBhDisable;
    274     extensionBehavior[E_GL_OES_tessellation_point_size]  = EBhDisable;
    275     extensionBehavior[E_GL_OES_texture_buffer]           = EBhDisable;
    276     extensionBehavior[E_GL_OES_texture_cube_map_array]   = EBhDisable;
    277 
    278     // EXT extensions
    279     extensionBehavior[E_GL_EXT_device_group]             = EBhDisable;
    280     extensionBehavior[E_GL_EXT_multiview]                = EBhDisable;
    281 
    282     // OVR extensions
    283     extensionBehavior[E_GL_OVR_multiview]                = EBhDisable;
    284     extensionBehavior[E_GL_OVR_multiview2]               = EBhDisable;
    285 
    286     // explicit types
    287     extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types]         = EBhDisable;
    288     extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types_int8]    = EBhDisable;
    289     extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types_int16]   = EBhDisable;
    290     extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types_int32]   = EBhDisable;
    291     extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types_int64]   = EBhDisable;
    292     extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types_float16] = EBhDisable;
    293     extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types_float32] = EBhDisable;
    294     extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types_float64] = EBhDisable;
    295 }
    296 
    297 // Get code that is not part of a shared symbol table, is specific to this shader,
    298 // or needed by the preprocessor (which does not use a shared symbol table).
    299 void TParseVersions::getPreamble(std::string& preamble)
    300 {
    301     if (profile == EEsProfile) {
    302         preamble =
    303             "#define GL_ES 1\n"
    304             "#define GL_FRAGMENT_PRECISION_HIGH 1\n"
    305             "#define GL_OES_texture_3D 1\n"
    306             "#define GL_OES_standard_derivatives 1\n"
    307             "#define GL_EXT_frag_depth 1\n"
    308             "#define GL_OES_EGL_image_external 1\n"
    309             "#define GL_OES_EGL_image_external_essl3 1\n"
    310             "#define GL_EXT_shader_texture_lod 1\n"
    311             "#define GL_EXT_shadow_samplers 1\n"
    312 
    313             // AEP
    314             "#define GL_ANDROID_extension_pack_es31a 1\n"
    315             "#define GL_KHR_blend_equation_advanced 1\n"
    316             "#define GL_OES_sample_variables 1\n"
    317             "#define GL_OES_shader_image_atomic 1\n"
    318             "#define GL_OES_shader_multisample_interpolation 1\n"
    319             "#define GL_OES_texture_storage_multisample_2d_array 1\n"
    320             "#define GL_EXT_geometry_shader 1\n"
    321             "#define GL_EXT_geometry_point_size 1\n"
    322             "#define GL_EXT_gpu_shader5 1\n"
    323             "#define GL_EXT_primitive_bounding_box 1\n"
    324             "#define GL_EXT_shader_io_blocks 1\n"
    325             "#define GL_EXT_tessellation_shader 1\n"
    326             "#define GL_EXT_tessellation_point_size 1\n"
    327             "#define GL_EXT_texture_buffer 1\n"
    328             "#define GL_EXT_texture_cube_map_array 1\n"
    329 
    330             // OES matching AEP
    331             "#define GL_OES_geometry_shader 1\n"
    332             "#define GL_OES_geometry_point_size 1\n"
    333             "#define GL_OES_gpu_shader5 1\n"
    334             "#define GL_OES_primitive_bounding_box 1\n"
    335             "#define GL_OES_shader_io_blocks 1\n"
    336             "#define GL_OES_tessellation_shader 1\n"
    337             "#define GL_OES_tessellation_point_size 1\n"
    338             "#define GL_OES_texture_buffer 1\n"
    339             "#define GL_OES_texture_cube_map_array 1\n"
    340             "#define GL_EXT_shader_non_constant_global_initializers 1\n"
    341             ;
    342 
    343 #ifdef NV_EXTENSIONS
    344             if (profile == EEsProfile && version >= 300) {
    345                 preamble += "#define GL_NV_shader_noperspective_interpolation 1\n";
    346             }
    347 #endif
    348 
    349     } else {
    350         preamble =
    351             "#define GL_FRAGMENT_PRECISION_HIGH 1\n"
    352             "#define GL_ARB_texture_rectangle 1\n"
    353             "#define GL_ARB_shading_language_420pack 1\n"
    354             "#define GL_ARB_texture_gather 1\n"
    355             "#define GL_ARB_gpu_shader5 1\n"
    356             "#define GL_ARB_separate_shader_objects 1\n"
    357             "#define GL_ARB_compute_shader 1\n"
    358             "#define GL_ARB_tessellation_shader 1\n"
    359             "#define GL_ARB_enhanced_layouts 1\n"
    360             "#define GL_ARB_texture_cube_map_array 1\n"
    361             "#define GL_ARB_shader_texture_lod 1\n"
    362             "#define GL_ARB_explicit_attrib_location 1\n"
    363             "#define GL_ARB_shader_image_load_store 1\n"
    364             "#define GL_ARB_shader_atomic_counters 1\n"
    365             "#define GL_ARB_shader_draw_parameters 1\n"
    366             "#define GL_ARB_shader_group_vote 1\n"
    367             "#define GL_ARB_derivative_control 1\n"
    368             "#define GL_ARB_shader_texture_image_samples 1\n"
    369             "#define GL_ARB_viewport_array 1\n"
    370             "#define GL_ARB_gpu_shader_int64 1\n"
    371             "#define GL_ARB_shader_ballot 1\n"
    372             "#define GL_ARB_sparse_texture2 1\n"
    373             "#define GL_ARB_sparse_texture_clamp 1\n"
    374             "#define GL_ARB_shader_stencil_export 1\n"
    375 //            "#define GL_ARB_cull_distance 1\n"    // present for 4.5, but need extension control over block members
    376             "#define GL_ARB_post_depth_coverage 1\n"
    377             "#define GL_EXT_shader_non_constant_global_initializers 1\n"
    378             "#define GL_EXT_shader_image_load_formatted 1\n"
    379             "#define GL_EXT_post_depth_coverage 1\n"
    380             "#define GL_EXT_control_flow_attributes 1\n"
    381             "#define GL_EXT_nonuniform_qualifier 1\n"
    382             "#define GL_EXT_shader_16bit_storage 1\n"
    383             "#define GL_EXT_shader_8bit_storage 1\n"
    384             "#define GL_EXT_samplerless_texture_functions 1\n"
    385             "#define GL_EXT_scalar_block_layout 1\n"
    386             "#define GL_EXT_fragment_invocation_density 1\n"
    387             "#define GL_EXT_buffer_reference 1\n"
    388 
    389             // GL_KHR_shader_subgroup
    390             "#define GL_KHR_shader_subgroup_basic 1\n"
    391             "#define GL_KHR_shader_subgroup_vote 1\n"
    392             "#define GL_KHR_shader_subgroup_arithmetic 1\n"
    393             "#define GL_KHR_shader_subgroup_ballot 1\n"
    394             "#define GL_KHR_shader_subgroup_shuffle 1\n"
    395             "#define GL_KHR_shader_subgroup_shuffle_relative 1\n"
    396             "#define GL_KHR_shader_subgroup_clustered 1\n"
    397             "#define GL_KHR_shader_subgroup_quad 1\n"
    398 
    399             "#define E_GL_EXT_shader_atomic_int64 1\n"
    400 
    401 #ifdef AMD_EXTENSIONS
    402             "#define GL_AMD_shader_ballot 1\n"
    403             "#define GL_AMD_shader_trinary_minmax 1\n"
    404             "#define GL_AMD_shader_explicit_vertex_parameter 1\n"
    405             "#define GL_AMD_gcn_shader 1\n"
    406             "#define GL_AMD_gpu_shader_half_float 1\n"
    407             "#define GL_AMD_texture_gather_bias_lod 1\n"
    408             "#define GL_AMD_gpu_shader_int16 1\n"
    409             "#define GL_AMD_shader_image_load_store_lod 1\n"
    410             "#define GL_AMD_shader_fragment_mask 1\n"
    411             "#define GL_AMD_gpu_shader_half_float_fetch 1\n"
    412 #endif
    413 
    414 #ifdef NV_EXTENSIONS
    415             "#define GL_NV_sample_mask_override_coverage 1\n"
    416             "#define GL_NV_geometry_shader_passthrough 1\n"
    417             "#define GL_NV_viewport_array2 1\n"
    418             "#define GL_NV_shader_atomic_int64 1\n"
    419             "#define GL_NV_conservative_raster_underestimation 1\n"
    420             "#define GL_NV_shader_subgroup_partitioned 1\n"
    421             "#define GL_NV_shading_rate_image 1\n"
    422             "#define GL_NV_ray_tracing 1\n"
    423             "#define GL_NV_fragment_shader_barycentric 1\n"
    424             "#define GL_NV_compute_shader_derivatives 1\n"
    425             "#define GL_NV_shader_texture_footprint 1\n"
    426             "#define GL_NV_mesh_shader 1\n"
    427 #endif
    428             "#define GL_EXT_shader_explicit_arithmetic_types 1\n"
    429             "#define GL_EXT_shader_explicit_arithmetic_types_int8 1\n"
    430             "#define GL_EXT_shader_explicit_arithmetic_types_int16 1\n"
    431             "#define GL_EXT_shader_explicit_arithmetic_types_int32 1\n"
    432             "#define GL_EXT_shader_explicit_arithmetic_types_int64 1\n"
    433             "#define GL_EXT_shader_explicit_arithmetic_types_float16 1\n"
    434             "#define GL_EXT_shader_explicit_arithmetic_types_float32 1\n"
    435             "#define GL_EXT_shader_explicit_arithmetic_types_float64 1\n"
    436             ;
    437 
    438         if (version >= 150) {
    439             // define GL_core_profile and GL_compatibility_profile
    440             preamble += "#define GL_core_profile 1\n";
    441 
    442             if (profile == ECompatibilityProfile)
    443                 preamble += "#define GL_compatibility_profile 1\n";
    444         }
    445     }
    446 
    447     if ((profile != EEsProfile && version >= 140) ||
    448         (profile == EEsProfile && version >= 310)) {
    449         preamble +=
    450             "#define GL_EXT_device_group 1\n"
    451             "#define GL_EXT_multiview 1\n"
    452             ;
    453     }
    454 
    455     if (version >= 300 /* both ES and non-ES */) {
    456         preamble +=
    457             "#define GL_OVR_multiview 1\n"
    458             "#define GL_OVR_multiview2 1\n"
    459             ;
    460     }
    461 
    462     // #line and #include
    463     preamble +=
    464             "#define GL_GOOGLE_cpp_style_line_directive 1\n"
    465             "#define GL_GOOGLE_include_directive 1\n"
    466             ;
    467 
    468     // #define VULKAN XXXX
    469     const int numberBufSize = 12;
    470     char numberBuf[numberBufSize];
    471     if (spvVersion.vulkanGlsl > 0) {
    472         preamble += "#define VULKAN ";
    473         snprintf(numberBuf, numberBufSize, "%d", spvVersion.vulkanGlsl);
    474         preamble += numberBuf;
    475         preamble += "\n";
    476     }
    477     // #define GL_SPIRV XXXX
    478     if (spvVersion.openGl > 0) {
    479         preamble += "#define GL_SPIRV ";
    480         snprintf(numberBuf, numberBufSize, "%d", spvVersion.openGl);
    481         preamble += numberBuf;
    482         preamble += "\n";
    483     }
    484 
    485 }
    486 
    487 //
    488 // When to use requireProfile():
    489 //
    490 //     Use if only some profiles support a feature.  However, if within a profile the feature
    491 //     is version or extension specific, follow this call with calls to profileRequires().
    492 //
    493 // Operation:  If the current profile is not one of the profileMask,
    494 // give an error message.
    495 //
    496 void TParseVersions::requireProfile(const TSourceLoc& loc, int profileMask, const char* featureDesc)
    497 {
    498     if (! (profile & profileMask))
    499         error(loc, "not supported with this profile:", featureDesc, ProfileName(profile));
    500 }
    501 
    502 //
    503 // Map from stage enum to externally readable text name.
    504 //
    505 const char* StageName(EShLanguage stage)
    506 {
    507     switch(stage) {
    508     case EShLangVertex:         return "vertex";
    509     case EShLangTessControl:    return "tessellation control";
    510     case EShLangTessEvaluation: return "tessellation evaluation";
    511     case EShLangGeometry:       return "geometry";
    512     case EShLangFragment:       return "fragment";
    513     case EShLangCompute:        return "compute";
    514 #ifdef NV_EXTENSIONS
    515     case EShLangRayGenNV:       return "ray-generation";
    516     case EShLangIntersectNV:    return "intersection";
    517     case EShLangAnyHitNV:       return "any-hit";
    518     case EShLangClosestHitNV:   return "closest-hit";
    519     case EShLangMissNV:         return "miss";
    520     case EShLangCallableNV:     return "callable";
    521     case EShLangMeshNV:         return "mesh";
    522     case EShLangTaskNV:         return "task";
    523 #endif
    524     default:                    return "unknown stage";
    525     }
    526 }
    527 
    528 //
    529 // When to use profileRequires():
    530 //
    531 //     If a set of profiles have the same requirements for what version or extensions
    532 //     are needed to support a feature.
    533 //
    534 //     It must be called for each profile that needs protection.  Use requireProfile() first
    535 //     to reduce that set of profiles.
    536 //
    537 // Operation: Will issue warnings/errors based on the current profile, version, and extension
    538 // behaviors.  It only checks extensions when the current profile is one of the profileMask.
    539 //
    540 // A minVersion of 0 means no version of the profileMask support this in core,
    541 // the extension must be present.
    542 //
    543 
    544 // entry point that takes multiple extensions
    545 void TParseVersions::profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, int numExtensions, const char* const extensions[], const char* featureDesc)
    546 {
    547     if (profile & profileMask) {
    548         bool okay = false;
    549         if (minVersion > 0 && version >= minVersion)
    550             okay = true;
    551         for (int i = 0; i < numExtensions; ++i) {
    552             switch (getExtensionBehavior(extensions[i])) {
    553             case EBhWarn:
    554                 infoSink.info.message(EPrefixWarning, ("extension " + TString(extensions[i]) + " is being used for " + featureDesc).c_str(), loc);
    555                 // fall through
    556             case EBhRequire:
    557             case EBhEnable:
    558                 okay = true;
    559                 break;
    560             default: break; // some compilers want this
    561             }
    562         }
    563 
    564         if (! okay)
    565             error(loc, "not supported for this version or the enabled extensions", featureDesc, "");
    566     }
    567 }
    568 
    569 // entry point for the above that takes a single extension
    570 void TParseVersions::profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, const char* extension, const char* featureDesc)
    571 {
    572     profileRequires(loc, profileMask, minVersion, extension ? 1 : 0, &extension, featureDesc);
    573 }
    574 
    575 //
    576 // When to use requireStage()
    577 //
    578 //     If only some stages support a feature.
    579 //
    580 // Operation: If the current stage is not present, give an error message.
    581 //
    582 void TParseVersions::requireStage(const TSourceLoc& loc, EShLanguageMask languageMask, const char* featureDesc)
    583 {
    584     if (((1 << language) & languageMask) == 0)
    585         error(loc, "not supported in this stage:", featureDesc, StageName(language));
    586 }
    587 
    588 // If only one stage supports a feature, this can be called.  But, all supporting stages
    589 // must be specified with one call.
    590 void TParseVersions::requireStage(const TSourceLoc& loc, EShLanguage stage, const char* featureDesc)
    591 {
    592     requireStage(loc, static_cast<EShLanguageMask>(1 << stage), featureDesc);
    593 }
    594 
    595 //
    596 // Within a set of profiles, see if a feature is deprecated and give an error or warning based on whether
    597 // a future compatibility context is being use.
    598 //
    599 void TParseVersions::checkDeprecated(const TSourceLoc& loc, int profileMask, int depVersion, const char* featureDesc)
    600 {
    601     if (profile & profileMask) {
    602         if (version >= depVersion) {
    603             if (forwardCompatible)
    604                 error(loc, "deprecated, may be removed in future release", featureDesc, "");
    605             else if (! suppressWarnings())
    606                 infoSink.info.message(EPrefixWarning, (TString(featureDesc) + " deprecated in version " +
    607                                                        String(depVersion) + "; may be removed in future release").c_str(), loc);
    608         }
    609     }
    610 }
    611 
    612 //
    613 // Within a set of profiles, see if a feature has now been removed and if so, give an error.
    614 // The version argument is the first version no longer having the feature.
    615 //
    616 void TParseVersions::requireNotRemoved(const TSourceLoc& loc, int profileMask, int removedVersion, const char* featureDesc)
    617 {
    618     if (profile & profileMask) {
    619         if (version >= removedVersion) {
    620             const int maxSize = 60;
    621             char buf[maxSize];
    622             snprintf(buf, maxSize, "%s profile; removed in version %d", ProfileName(profile), removedVersion);
    623             error(loc, "no longer supported in", featureDesc, buf);
    624         }
    625     }
    626 }
    627 
    628 void TParseVersions::unimplemented(const TSourceLoc& loc, const char* featureDesc)
    629 {
    630     error(loc, "feature not yet implemented", featureDesc, "");
    631 }
    632 
    633 // Returns true if at least one of the extensions in the extensions parameter is requested. Otherwise, returns false.
    634 // Warns appropriately if the requested behavior of an extension is "warn".
    635 bool TParseVersions::checkExtensionsRequested(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc)
    636 {
    637     // First, see if any of the extensions are enabled
    638     for (int i = 0; i < numExtensions; ++i) {
    639         TExtensionBehavior behavior = getExtensionBehavior(extensions[i]);
    640         if (behavior == EBhEnable || behavior == EBhRequire)
    641             return true;
    642     }
    643 
    644     // See if any extensions want to give a warning on use; give warnings for all such extensions
    645     bool warned = false;
    646     for (int i = 0; i < numExtensions; ++i) {
    647         TExtensionBehavior behavior = getExtensionBehavior(extensions[i]);
    648         if (behavior == EBhDisable && relaxedErrors()) {
    649             infoSink.info.message(EPrefixWarning, "The following extension must be enabled to use this feature:", loc);
    650             behavior = EBhWarn;
    651         }
    652         if (behavior == EBhWarn) {
    653             infoSink.info.message(EPrefixWarning, ("extension " + TString(extensions[i]) + " is being used for " + featureDesc).c_str(), loc);
    654             warned = true;
    655         }
    656     }
    657     if (warned)
    658         return true;
    659     return false;
    660 }
    661 
    662 //
    663 // Use when there are no profile/version to check, it's just an error if one of the
    664 // extensions is not present.
    665 //
    666 void TParseVersions::requireExtensions(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc)
    667 {
    668     if (checkExtensionsRequested(loc, numExtensions, extensions, featureDesc))
    669         return;
    670 
    671     // If we get this far, give errors explaining what extensions are needed
    672     if (numExtensions == 1)
    673         error(loc, "required extension not requested:", featureDesc, extensions[0]);
    674     else {
    675         error(loc, "required extension not requested:", featureDesc, "Possible extensions include:");
    676         for (int i = 0; i < numExtensions; ++i)
    677             infoSink.info.message(EPrefixNone, extensions[i]);
    678     }
    679 }
    680 
    681 //
    682 // Use by preprocessor when there are no profile/version to check, it's just an error if one of the
    683 // extensions is not present.
    684 //
    685 void TParseVersions::ppRequireExtensions(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc)
    686 {
    687     if (checkExtensionsRequested(loc, numExtensions, extensions, featureDesc))
    688         return;
    689 
    690     // If we get this far, give errors explaining what extensions are needed
    691     if (numExtensions == 1)
    692         ppError(loc, "required extension not requested:", featureDesc, extensions[0]);
    693     else {
    694         ppError(loc, "required extension not requested:", featureDesc, "Possible extensions include:");
    695         for (int i = 0; i < numExtensions; ++i)
    696             infoSink.info.message(EPrefixNone, extensions[i]);
    697     }
    698 }
    699 
    700 TExtensionBehavior TParseVersions::getExtensionBehavior(const char* extension)
    701 {
    702     auto iter = extensionBehavior.find(TString(extension));
    703     if (iter == extensionBehavior.end())
    704         return EBhMissing;
    705     else
    706         return iter->second;
    707 }
    708 
    709 // Returns true if the given extension is set to enable, require, or warn.
    710 bool TParseVersions::extensionTurnedOn(const char* const extension)
    711 {
    712       switch (getExtensionBehavior(extension)) {
    713       case EBhEnable:
    714       case EBhRequire:
    715       case EBhWarn:
    716           return true;
    717       default:
    718           break;
    719       }
    720       return false;
    721 }
    722 // See if any of the extensions are set to enable, require, or warn.
    723 bool TParseVersions::extensionsTurnedOn(int numExtensions, const char* const extensions[])
    724 {
    725     for (int i = 0; i < numExtensions; ++i) {
    726         if (extensionTurnedOn(extensions[i]))
    727             return true;
    728     }
    729     return false;
    730 }
    731 
    732 //
    733 // Change the current state of an extension's behavior.
    734 //
    735 void TParseVersions::updateExtensionBehavior(int line, const char* extension, const char* behaviorString)
    736 {
    737     // Translate from text string of extension's behavior to an enum.
    738     TExtensionBehavior behavior = EBhDisable;
    739     if (! strcmp("require", behaviorString))
    740         behavior = EBhRequire;
    741     else if (! strcmp("enable", behaviorString))
    742         behavior = EBhEnable;
    743     else if (! strcmp("disable", behaviorString))
    744         behavior = EBhDisable;
    745     else if (! strcmp("warn", behaviorString))
    746         behavior = EBhWarn;
    747     else {
    748         error(getCurrentLoc(), "behavior not supported:", "#extension", behaviorString);
    749         return;
    750     }
    751 
    752     // check if extension is used with correct shader stage
    753     checkExtensionStage(getCurrentLoc(), extension);
    754 
    755     // update the requested extension
    756     updateExtensionBehavior(extension, behavior);
    757 
    758     // see if need to propagate to implicitly modified things
    759     if (strcmp(extension, "GL_ANDROID_extension_pack_es31a") == 0) {
    760         // to everything in AEP
    761         updateExtensionBehavior(line, "GL_KHR_blend_equation_advanced", behaviorString);
    762         updateExtensionBehavior(line, "GL_OES_sample_variables", behaviorString);
    763         updateExtensionBehavior(line, "GL_OES_shader_image_atomic", behaviorString);
    764         updateExtensionBehavior(line, "GL_OES_shader_multisample_interpolation", behaviorString);
    765         updateExtensionBehavior(line, "GL_OES_texture_storage_multisample_2d_array", behaviorString);
    766         updateExtensionBehavior(line, "GL_EXT_geometry_shader", behaviorString);
    767         updateExtensionBehavior(line, "GL_EXT_gpu_shader5", behaviorString);
    768         updateExtensionBehavior(line, "GL_EXT_primitive_bounding_box", behaviorString);
    769         updateExtensionBehavior(line, "GL_EXT_shader_io_blocks", behaviorString);
    770         updateExtensionBehavior(line, "GL_EXT_tessellation_shader", behaviorString);
    771         updateExtensionBehavior(line, "GL_EXT_texture_buffer", behaviorString);
    772         updateExtensionBehavior(line, "GL_EXT_texture_cube_map_array", behaviorString);
    773     }
    774     // geometry to io_blocks
    775     else if (strcmp(extension, "GL_EXT_geometry_shader") == 0)
    776         updateExtensionBehavior(line, "GL_EXT_shader_io_blocks", behaviorString);
    777     else if (strcmp(extension, "GL_OES_geometry_shader") == 0)
    778         updateExtensionBehavior(line, "GL_OES_shader_io_blocks", behaviorString);
    779     // tessellation to io_blocks
    780     else if (strcmp(extension, "GL_EXT_tessellation_shader") == 0)
    781         updateExtensionBehavior(line, "GL_EXT_shader_io_blocks", behaviorString);
    782     else if (strcmp(extension, "GL_OES_tessellation_shader") == 0)
    783         updateExtensionBehavior(line, "GL_OES_shader_io_blocks", behaviorString);
    784     else if (strcmp(extension, "GL_GOOGLE_include_directive") == 0)
    785         updateExtensionBehavior(line, "GL_GOOGLE_cpp_style_line_directive", behaviorString);
    786     // subgroup_* to subgroup_basic
    787     else if (strcmp(extension, "GL_KHR_shader_subgroup_vote") == 0)
    788         updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString);
    789     else if (strcmp(extension, "GL_KHR_shader_subgroup_arithmetic") == 0)
    790         updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString);
    791     else if (strcmp(extension, "GL_KHR_shader_subgroup_ballot") == 0)
    792         updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString);
    793     else if (strcmp(extension, "GL_KHR_shader_subgroup_shuffle") == 0)
    794         updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString);
    795     else if (strcmp(extension, "GL_KHR_shader_subgroup_shuffle_relative") == 0)
    796         updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString);
    797     else if (strcmp(extension, "GL_KHR_shader_subgroup_clustered") == 0)
    798         updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString);
    799     else if (strcmp(extension, "GL_KHR_shader_subgroup_quad") == 0)
    800         updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString);
    801 #ifdef NV_EXTENSIONS
    802     else if (strcmp(extension, "GL_NV_shader_subgroup_partitioned") == 0)
    803         updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString);
    804 #endif
    805 }
    806 
    807 void TParseVersions::updateExtensionBehavior(const char* extension, TExtensionBehavior behavior)
    808 {
    809     // Update the current behavior
    810     if (strcmp(extension, "all") == 0) {
    811         // special case for the 'all' extension; apply it to every extension present
    812         if (behavior == EBhRequire || behavior == EBhEnable) {
    813             error(getCurrentLoc(), "extension 'all' cannot have 'require' or 'enable' behavior", "#extension", "");
    814             return;
    815         } else {
    816             for (auto iter = extensionBehavior.begin(); iter != extensionBehavior.end(); ++iter)
    817                 iter->second = behavior;
    818         }
    819     } else {
    820         // Do the update for this single extension
    821         auto iter = extensionBehavior.find(TString(extension));
    822         if (iter == extensionBehavior.end()) {
    823             switch (behavior) {
    824             case EBhRequire:
    825                 error(getCurrentLoc(), "extension not supported:", "#extension", extension);
    826                 break;
    827             case EBhEnable:
    828             case EBhWarn:
    829             case EBhDisable:
    830                 warn(getCurrentLoc(), "extension not supported:", "#extension", extension);
    831                 break;
    832             default:
    833                 assert(0 && "unexpected behavior");
    834             }
    835 
    836             return;
    837         } else {
    838             if (iter->second == EBhDisablePartial)
    839                 warn(getCurrentLoc(), "extension is only partially supported:", "#extension", extension);
    840             if (behavior == EBhEnable || behavior == EBhRequire)
    841                 intermediate.addRequestedExtension(extension);
    842             iter->second = behavior;
    843         }
    844     }
    845 }
    846 
    847 // Check if extension is used with correct shader stage.
    848 void TParseVersions::checkExtensionStage(const TSourceLoc& loc, const char * const extension)
    849 {
    850 #ifdef NV_EXTENSIONS
    851     // GL_NV_mesh_shader extension is only allowed in task/mesh shaders
    852     if (strcmp(extension, "GL_NV_mesh_shader") == 0) {
    853         requireStage(loc, (EShLanguageMask)(EShLangTaskNVMask | EShLangMeshNVMask | EShLangFragmentMask),
    854                      "#extension GL_NV_mesh_shader");
    855         profileRequires(loc, ECoreProfile, 450, 0, "#extension GL_NV_mesh_shader");
    856         profileRequires(loc, EEsProfile, 320, 0, "#extension GL_NV_mesh_shader");
    857     }
    858 #endif
    859 }
    860 
    861 // Call for any operation needing full GLSL integer data-type support.
    862 void TParseVersions::fullIntegerCheck(const TSourceLoc& loc, const char* op)
    863 {
    864     profileRequires(loc, ENoProfile, 130, nullptr, op);
    865     profileRequires(loc, EEsProfile, 300, nullptr, op);
    866 }
    867 
    868 // Call for any operation needing GLSL double data-type support.
    869 void TParseVersions::doubleCheck(const TSourceLoc& loc, const char* op)
    870 {
    871     requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
    872     profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, nullptr, op);
    873 }
    874 
    875 // Call for any operation needing GLSL float16 data-type support.
    876 void TParseVersions::float16Check(const TSourceLoc& loc, const char* op, bool builtIn)
    877 {
    878     if (!builtIn) {
    879         const char* const extensions[] = {
    880 #if AMD_EXTENSIONS
    881                                            E_GL_AMD_gpu_shader_half_float,
    882 #endif
    883                                            E_GL_EXT_shader_explicit_arithmetic_types,
    884                                            E_GL_EXT_shader_explicit_arithmetic_types_float16};
    885         requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
    886     }
    887 }
    888 
    889 bool TParseVersions::float16Arithmetic()
    890 {
    891     const char* const extensions[] = {
    892 #if AMD_EXTENSIONS
    893                                        E_GL_AMD_gpu_shader_half_float,
    894 #endif
    895                                        E_GL_EXT_shader_explicit_arithmetic_types,
    896                                        E_GL_EXT_shader_explicit_arithmetic_types_float16};
    897     return extensionsTurnedOn(sizeof(extensions)/sizeof(extensions[0]), extensions);
    898 }
    899 
    900 bool TParseVersions::int16Arithmetic()
    901 {
    902     const char* const extensions[] = {
    903 #if AMD_EXTENSIONS
    904                                        E_GL_AMD_gpu_shader_int16,
    905 #endif
    906                                        E_GL_EXT_shader_explicit_arithmetic_types,
    907                                        E_GL_EXT_shader_explicit_arithmetic_types_int16};
    908     return extensionsTurnedOn(sizeof(extensions)/sizeof(extensions[0]), extensions);
    909 }
    910 
    911 bool TParseVersions::int8Arithmetic()
    912 {
    913     const char* const extensions[] = {
    914                                        E_GL_EXT_shader_explicit_arithmetic_types,
    915                                        E_GL_EXT_shader_explicit_arithmetic_types_int8};
    916     return extensionsTurnedOn(sizeof(extensions)/sizeof(extensions[0]), extensions);
    917 }
    918 
    919 void TParseVersions::requireFloat16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc)
    920 {
    921     TString combined;
    922     combined = op;
    923     combined += ": ";
    924     combined += featureDesc;
    925 
    926     const char* const extensions[] = {
    927 #if AMD_EXTENSIONS
    928                                        E_GL_AMD_gpu_shader_half_float,
    929 #endif
    930                                        E_GL_EXT_shader_explicit_arithmetic_types,
    931                                        E_GL_EXT_shader_explicit_arithmetic_types_float16};
    932     requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, combined.c_str());
    933 }
    934 
    935 void TParseVersions::requireInt16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc)
    936 {
    937     TString combined;
    938     combined = op;
    939     combined += ": ";
    940     combined += featureDesc;
    941 
    942     const char* const extensions[] = {
    943 #if AMD_EXTENSIONS
    944                                        E_GL_AMD_gpu_shader_int16,
    945 #endif
    946                                        E_GL_EXT_shader_explicit_arithmetic_types,
    947                                        E_GL_EXT_shader_explicit_arithmetic_types_int16};
    948     requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, combined.c_str());
    949 }
    950 
    951 void TParseVersions::requireInt8Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc)
    952 {
    953     TString combined;
    954     combined = op;
    955     combined += ": ";
    956     combined += featureDesc;
    957 
    958     const char* const extensions[] = {
    959                                        E_GL_EXT_shader_explicit_arithmetic_types,
    960                                        E_GL_EXT_shader_explicit_arithmetic_types_int8};
    961     requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, combined.c_str());
    962 }
    963 
    964 void TParseVersions::float16ScalarVectorCheck(const TSourceLoc& loc, const char* op, bool builtIn)
    965 {
    966     if (!builtIn) {
    967         const char* const extensions[] = {
    968 #if AMD_EXTENSIONS
    969                                            E_GL_AMD_gpu_shader_half_float,
    970 #endif
    971                                            E_GL_EXT_shader_16bit_storage,
    972                                            E_GL_EXT_shader_explicit_arithmetic_types,
    973                                            E_GL_EXT_shader_explicit_arithmetic_types_float16};
    974         requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
    975     }
    976 }
    977 
    978 // Call for any operation needing GLSL float32 data-type support.
    979 void TParseVersions::explicitFloat32Check(const TSourceLoc& loc, const char* op, bool builtIn)
    980 {
    981     if (!builtIn) {
    982         const char* const extensions[2] = {E_GL_EXT_shader_explicit_arithmetic_types,
    983                                            E_GL_EXT_shader_explicit_arithmetic_types_float32};
    984         requireExtensions(loc, 2, extensions, op);
    985     }
    986 }
    987 
    988 // Call for any operation needing GLSL float64 data-type support.
    989 void TParseVersions::explicitFloat64Check(const TSourceLoc& loc, const char* op, bool builtIn)
    990 {
    991     if (!builtIn) {
    992         const char* const extensions[2] = {E_GL_EXT_shader_explicit_arithmetic_types,
    993                                            E_GL_EXT_shader_explicit_arithmetic_types_float64};
    994         requireExtensions(loc, 2, extensions, op);
    995         requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
    996         profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, nullptr, op);
    997     }
    998 }
    999 
   1000 // Call for any operation needing GLSL explicit int8 data-type support.
   1001 void TParseVersions::explicitInt8Check(const TSourceLoc& loc, const char* op, bool builtIn)
   1002 {
   1003     if (! builtIn) {
   1004         const char* const extensions[2] = {E_GL_EXT_shader_explicit_arithmetic_types,
   1005                                            E_GL_EXT_shader_explicit_arithmetic_types_int8};
   1006         requireExtensions(loc, 2, extensions, op);
   1007     }
   1008 }
   1009 
   1010 #ifdef AMD_EXTENSIONS
   1011 // Call for any operation needing GLSL float16 opaque-type support
   1012 void TParseVersions::float16OpaqueCheck(const TSourceLoc& loc, const char* op, bool builtIn)
   1013 {
   1014     if (! builtIn) {
   1015         requireExtensions(loc, 1, &E_GL_AMD_gpu_shader_half_float_fetch, op);
   1016         requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
   1017         profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, nullptr, op);
   1018     }
   1019 }
   1020 #endif
   1021 
   1022 // Call for any operation needing GLSL explicit int16 data-type support.
   1023 void TParseVersions::explicitInt16Check(const TSourceLoc& loc, const char* op, bool builtIn)
   1024 {
   1025     if (! builtIn) {
   1026     	const char* const extensions[] = {
   1027 #if AMD_EXTENSIONS
   1028                                            E_GL_AMD_gpu_shader_int16,
   1029 #endif
   1030                                            E_GL_EXT_shader_explicit_arithmetic_types,
   1031                                            E_GL_EXT_shader_explicit_arithmetic_types_int16};
   1032         requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
   1033     }
   1034 }
   1035 
   1036 void TParseVersions::int16ScalarVectorCheck(const TSourceLoc& loc, const char* op, bool builtIn)
   1037 {
   1038     if (! builtIn) {
   1039     	const char* const extensions[] = {
   1040 #if AMD_EXTENSIONS
   1041                                            E_GL_AMD_gpu_shader_int16,
   1042 #endif
   1043                                            E_GL_EXT_shader_16bit_storage,
   1044                                            E_GL_EXT_shader_explicit_arithmetic_types,
   1045                                            E_GL_EXT_shader_explicit_arithmetic_types_int16};
   1046         requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
   1047     }
   1048 }
   1049 
   1050 void TParseVersions::int8ScalarVectorCheck(const TSourceLoc& loc, const char* op, bool builtIn)
   1051 {
   1052     if (! builtIn) {
   1053     	const char* const extensions[] = {
   1054                                            E_GL_EXT_shader_8bit_storage,
   1055                                            E_GL_EXT_shader_explicit_arithmetic_types,
   1056                                            E_GL_EXT_shader_explicit_arithmetic_types_int8};
   1057         requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
   1058     }
   1059 }
   1060 
   1061 // Call for any operation needing GLSL explicit int32 data-type support.
   1062 void TParseVersions::explicitInt32Check(const TSourceLoc& loc, const char* op, bool builtIn)
   1063 {
   1064     if (! builtIn) {
   1065         const char* const extensions[2] = {E_GL_EXT_shader_explicit_arithmetic_types,
   1066                                            E_GL_EXT_shader_explicit_arithmetic_types_int32};
   1067         requireExtensions(loc, 2, extensions, op);
   1068     }
   1069 }
   1070 
   1071 // Call for any operation needing GLSL 64-bit integer data-type support.
   1072 void TParseVersions::int64Check(const TSourceLoc& loc, const char* op, bool builtIn)
   1073 {
   1074     if (! builtIn) {
   1075         const char* const extensions[3] = {E_GL_ARB_gpu_shader_int64,
   1076                                            E_GL_EXT_shader_explicit_arithmetic_types,
   1077                                            E_GL_EXT_shader_explicit_arithmetic_types_int64};
   1078         requireExtensions(loc, 3, extensions, op);
   1079         requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
   1080         profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, nullptr, op);
   1081     }
   1082 }
   1083 
   1084 // Call for any operation removed because SPIR-V is in use.
   1085 void TParseVersions::spvRemoved(const TSourceLoc& loc, const char* op)
   1086 {
   1087     if (spvVersion.spv != 0)
   1088         error(loc, "not allowed when generating SPIR-V", op, "");
   1089 }
   1090 
   1091 // Call for any operation removed because Vulkan SPIR-V is being generated.
   1092 void TParseVersions::vulkanRemoved(const TSourceLoc& loc, const char* op)
   1093 {
   1094     if (spvVersion.vulkan > 0)
   1095         error(loc, "not allowed when using GLSL for Vulkan", op, "");
   1096 }
   1097 
   1098 // Call for any operation that requires Vulkan.
   1099 void TParseVersions::requireVulkan(const TSourceLoc& loc, const char* op)
   1100 {
   1101     if (spvVersion.vulkan == 0)
   1102         error(loc, "only allowed when using GLSL for Vulkan", op, "");
   1103 }
   1104 
   1105 // Call for any operation that requires SPIR-V.
   1106 void TParseVersions::requireSpv(const TSourceLoc& loc, const char* op)
   1107 {
   1108     if (spvVersion.spv == 0)
   1109         error(loc, "only allowed when generating SPIR-V", op, "");
   1110 }
   1111 
   1112 } // end namespace glslang
   1113