• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 //
initializeExtensionBehavior()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).
getPreamble(std::string & preamble)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 //
requireProfile(const TSourceLoc & loc,int profileMask,const char * featureDesc)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 //
StageName(EShLanguage stage)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
profileRequires(const TSourceLoc & loc,int profileMask,int minVersion,int numExtensions,const char * const extensions[],const char * featureDesc)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
profileRequires(const TSourceLoc & loc,int profileMask,int minVersion,const char * extension,const char * featureDesc)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 //
requireStage(const TSourceLoc & loc,EShLanguageMask languageMask,const char * featureDesc)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.
requireStage(const TSourceLoc & loc,EShLanguage stage,const char * featureDesc)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 //
checkDeprecated(const TSourceLoc & loc,int profileMask,int depVersion,const char * featureDesc)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 //
requireNotRemoved(const TSourceLoc & loc,int profileMask,int removedVersion,const char * featureDesc)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 
unimplemented(const TSourceLoc & loc,const char * featureDesc)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".
checkExtensionsRequested(const TSourceLoc & loc,int numExtensions,const char * const extensions[],const char * featureDesc)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 //
requireExtensions(const TSourceLoc & loc,int numExtensions,const char * const extensions[],const char * featureDesc)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 //
ppRequireExtensions(const TSourceLoc & loc,int numExtensions,const char * const extensions[],const char * featureDesc)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 
getExtensionBehavior(const char * extension)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.
extensionTurnedOn(const char * const extension)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.
extensionsTurnedOn(int numExtensions,const char * const extensions[])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 //
updateExtensionBehavior(int line,const char * extension,const char * behaviorString)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 
updateExtensionBehavior(const char * extension,TExtensionBehavior behavior)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.
checkExtensionStage(const TSourceLoc & loc,const char * const extension)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.
fullIntegerCheck(const TSourceLoc & loc,const char * op)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.
doubleCheck(const TSourceLoc & loc,const char * op)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.
float16Check(const TSourceLoc & loc,const char * op,bool builtIn)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 
float16Arithmetic()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 
int16Arithmetic()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 
int8Arithmetic()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 
requireFloat16Arithmetic(const TSourceLoc & loc,const char * op,const char * featureDesc)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 
requireInt16Arithmetic(const TSourceLoc & loc,const char * op,const char * featureDesc)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 
requireInt8Arithmetic(const TSourceLoc & loc,const char * op,const char * featureDesc)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 
float16ScalarVectorCheck(const TSourceLoc & loc,const char * op,bool builtIn)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.
explicitFloat32Check(const TSourceLoc & loc,const char * op,bool builtIn)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.
explicitFloat64Check(const TSourceLoc & loc,const char * op,bool builtIn)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.
explicitInt8Check(const TSourceLoc & loc,const char * op,bool builtIn)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
float16OpaqueCheck(const TSourceLoc & loc,const char * op,bool builtIn)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.
explicitInt16Check(const TSourceLoc & loc,const char * op,bool builtIn)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 
int16ScalarVectorCheck(const TSourceLoc & loc,const char * op,bool builtIn)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 
int8ScalarVectorCheck(const TSourceLoc & loc,const char * op,bool builtIn)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.
explicitInt32Check(const TSourceLoc & loc,const char * op,bool builtIn)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.
int64Check(const TSourceLoc & loc,const char * op,bool builtIn)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.
spvRemoved(const TSourceLoc & loc,const char * op)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.
vulkanRemoved(const TSourceLoc & loc,const char * op)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.
requireVulkan(const TSourceLoc & loc,const char * op)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.
requireSpv(const TSourceLoc & loc,const char * op)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