/src/shaderc/libshaderc_util/include/libshaderc_util/compiler.h
Line | Count | Source |
1 | | // Copyright 2015 The Shaderc Authors. All rights reserved. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | // you may not use this file except in compliance with the License. |
5 | | // You may obtain a copy of the License at |
6 | | // |
7 | | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software |
10 | | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | // See the License for the specific language governing permissions and |
13 | | // limitations under the License. |
14 | | |
15 | | #ifndef LIBSHADERC_UTIL_INC_COMPILER_H |
16 | | #define LIBSHADERC_UTIL_INC_COMPILER_H |
17 | | |
18 | | #include <array> |
19 | | #include <cassert> |
20 | | #include <functional> |
21 | | #include <mutex> |
22 | | #include <ostream> |
23 | | #include <string> |
24 | | #include <unordered_map> |
25 | | #include <utility> |
26 | | |
27 | | #include "counting_includer.h" |
28 | | #include "file_finder.h" |
29 | | #include "glslang/Public/ShaderLang.h" |
30 | | #include "mutex.h" |
31 | | #include "resources.h" |
32 | | #include "string_piece.h" |
33 | | |
34 | | // Fix a typo in glslang/Public/ShaderLang.h |
35 | | #define EShTargetClientVersion EshTargetClientVersion |
36 | | |
37 | | namespace shaderc_util { |
38 | | |
39 | | // To break recursive including. This header is already included in |
40 | | // spirv_tools_wrapper.h, so cannot include spirv_tools_wrapper.h here. |
41 | | enum class PassId; |
42 | | |
43 | | // Initializes glslang on creation, and destroys it on completion. |
44 | | // Used to tie gslang process operations to object lifetimes. |
45 | | // Additionally initialization/finalization of glslang is not thread safe, so |
46 | | // synchronizes these operations. |
47 | | class GlslangInitializer { |
48 | | public: |
49 | | GlslangInitializer(); |
50 | | ~GlslangInitializer(); |
51 | | |
52 | | private: |
53 | | static unsigned int initialize_count_; |
54 | | |
55 | | // Using a bare pointer here to avoid any global class construction at the |
56 | | // beginning of the execution. |
57 | | static std::mutex* glslang_mutex_; |
58 | | }; |
59 | | |
60 | | // Maps macro names to their definitions. Stores string_pieces, so the |
61 | | // underlying strings must outlive it. |
62 | | using MacroDictionary = std::unordered_map<std::string, std::string>; |
63 | | |
64 | | // Holds all of the state required to compile source GLSL into SPIR-V. |
65 | | class Compiler { |
66 | | public: |
67 | | // Source language |
68 | | enum class SourceLanguage { |
69 | | GLSL, // The default |
70 | | HLSL, |
71 | | }; |
72 | | |
73 | | // Target environment. |
74 | | enum class TargetEnv { |
75 | | Vulkan, // Default to Vulkan 1.0 |
76 | | OpenGL, // Default to OpenGL 4.5 |
77 | | OpenGLCompat, // Support removed. Generates error if used. |
78 | | }; |
79 | | |
80 | | // Target environment versions. These numbers match those used by Glslang. |
81 | | enum class TargetEnvVersion : uint32_t { |
82 | | Default = 0, // Default for the corresponding target environment |
83 | | // For Vulkan, use numbering scheme from vulkan.h |
84 | | Vulkan_1_0 = ((1 << 22)), // Vulkan 1.0 |
85 | | Vulkan_1_1 = ((1 << 22) | (1 << 12)), // Vulkan 1.1 |
86 | | Vulkan_1_2 = ((1 << 22) | (2 << 12)), // Vulkan 1.2 |
87 | | Vulkan_1_3 = ((1 << 22) | (3 << 12)), // Vulkan 1.3 |
88 | | Vulkan_1_4 = ((1 << 22) | (4 << 12)), // Vulkan 1.4 |
89 | | // For OpenGL, use the numbering from #version in shaders. |
90 | | OpenGL_4_5 = 450, |
91 | | }; |
92 | | |
93 | | // SPIR-V version. |
94 | | enum class SpirvVersion : uint32_t { |
95 | | v1_0 = 0x010000u, |
96 | | v1_1 = 0x010100u, |
97 | | v1_2 = 0x010200u, |
98 | | v1_3 = 0x010300u, |
99 | | v1_4 = 0x010400u, |
100 | | v1_5 = 0x010500u, |
101 | | v1_6 = 0x010600u, |
102 | | }; |
103 | | |
104 | | enum class OutputType { |
105 | | SpirvBinary, // A binary module, as defined by the SPIR-V specification. |
106 | | SpirvAssemblyText, // Assembly syntax defined by the SPIRV-Tools project. |
107 | | PreprocessedText, // Preprocessed source code. |
108 | | }; |
109 | | |
110 | | // Supported optimization levels. |
111 | | enum class OptimizationLevel { |
112 | | Zero, // No optimization. |
113 | | Size, // Optimization towards reducing code size. |
114 | | Performance, // Optimization towards better performance. |
115 | | }; |
116 | | |
117 | | // Resource limits. These map to the "max*" fields in |
118 | | // glslang::TBuiltInResource. |
119 | | enum class Limit { |
120 | | #define RESOURCE(NAME, FIELD, CNAME) NAME, |
121 | | #include "resources.inc" |
122 | | #undef RESOURCE |
123 | | }; |
124 | | |
125 | | // Types of uniform variables. |
126 | | enum class UniformKind { |
127 | | // Image, and image buffer. |
128 | | Image = 0, |
129 | | // Pure sampler. |
130 | | Sampler = 1, |
131 | | // Sampled texture in GLSL. |
132 | | // Shader Resource View, for HLSL. (Read-only image or storage buffer.) |
133 | | Texture = 2, |
134 | | // Uniform Buffer Object, or UBO, in GLSL. |
135 | | // Also a Cbuffer in HLSL. |
136 | | Buffer = 3, |
137 | | // Shader Storage Buffer Object, or SSBO |
138 | | StorageBuffer = 4, |
139 | | // Uniform Access View, in HLSL. (Writable storage image or storage |
140 | | // buffer.) |
141 | | UnorderedAccessView = 5, |
142 | | }; |
143 | | enum { kNumUniformKinds = int(UniformKind::UnorderedAccessView) + 1 }; |
144 | | |
145 | | // Shader pipeline stage. |
146 | | // TODO(dneto): Replaces interface uses of EShLanguage with this enum. |
147 | | enum class Stage { |
148 | | Vertex, |
149 | | TessEval, |
150 | | TessControl, |
151 | | Geometry, |
152 | | Fragment, |
153 | | Compute, |
154 | | RayGenNV, |
155 | | IntersectNV, |
156 | | AnyHitNV, |
157 | | ClosestHitNV, |
158 | | MissNV, |
159 | | CallableNV, |
160 | | TaskNV, |
161 | | MeshNV, |
162 | | StageEnd, |
163 | | }; |
164 | | enum { kNumStages = int(Stage::StageEnd) }; |
165 | | |
166 | | // Returns a std::array of all the Stage values. |
167 | 0 | const std::array<Stage, kNumStages>& stages() const { |
168 | 0 | static std::array<Stage, kNumStages> values{{ |
169 | 0 | Stage::Vertex, |
170 | 0 | Stage::TessEval, |
171 | 0 | Stage::TessControl, |
172 | 0 | Stage::Geometry, |
173 | 0 | Stage::Fragment, |
174 | 0 | Stage::Compute, |
175 | 0 | Stage::RayGenNV, |
176 | 0 | Stage::IntersectNV, |
177 | 0 | Stage::AnyHitNV, |
178 | 0 | Stage::ClosestHitNV, |
179 | 0 | Stage::MissNV, |
180 | 0 | Stage::CallableNV, |
181 | 0 | Stage::TaskNV, |
182 | 0 | Stage::MeshNV, |
183 | 0 | }}; |
184 | 0 | return values; |
185 | 0 | } |
186 | | |
187 | | // Creates an default compiler instance targeting at Vulkan environment. Uses |
188 | | // version 110 and no profile specification as the default for GLSL. |
189 | | Compiler() |
190 | | // The default version for glsl is 110, or 100 if you are using an es |
191 | | // profile. But we want to default to a non-es profile. |
192 | 4.27k | : default_version_(110), |
193 | 4.27k | default_profile_(ENoProfile), |
194 | 4.27k | force_version_profile_(false), |
195 | 4.27k | warnings_as_errors_(false), |
196 | 4.27k | suppress_warnings_(false), |
197 | 4.27k | generate_debug_info_(false), |
198 | 4.27k | enabled_opt_passes_(), |
199 | 4.27k | target_env_(TargetEnv::Vulkan), |
200 | 4.27k | target_env_version_(TargetEnvVersion::Default), |
201 | 4.27k | target_spirv_version_(SpirvVersion::v1_0), |
202 | 4.27k | target_spirv_version_is_forced_(false), |
203 | 4.27k | source_language_(SourceLanguage::GLSL), |
204 | 4.27k | limits_(kDefaultTBuiltInResource), |
205 | 4.27k | auto_bind_uniforms_(false), |
206 | 4.27k | auto_combined_image_sampler_(false), |
207 | | auto_binding_base_(), |
208 | 4.27k | auto_map_locations_(false), |
209 | 4.27k | preserve_bindings_(false), |
210 | 4.27k | hlsl_iomap_(false), |
211 | 4.27k | hlsl_offsets_(false), |
212 | 4.27k | hlsl_legalization_enabled_(true), |
213 | 4.27k | hlsl_functionality1_enabled_(false), |
214 | 4.27k | hlsl_16bit_types_enabled_(false), |
215 | 4.27k | invert_y_enabled_(false), |
216 | 4.27k | nan_clamp_(false), |
217 | 4.27k | hlsl_explicit_bindings_() {} |
218 | | |
219 | | // Requests that the compiler place debug information into the object code, |
220 | | // such as identifier names and line numbers. |
221 | | void SetGenerateDebugInfo(); |
222 | | |
223 | | // Sets the optimization level to the given level. Only the last one takes |
224 | | // effect if multiple calls of this method exist. |
225 | | void SetOptimizationLevel(OptimizationLevel level); |
226 | | |
227 | | // Enables or disables HLSL legalization passes. |
228 | | void EnableHlslLegalization(bool hlsl_legalization_enabled); |
229 | | |
230 | | // Enables or disables extension SPV_GOOGLE_hlsl_functionality1 |
231 | | void EnableHlslFunctionality1(bool enable); |
232 | | |
233 | | // Enables or disables HLSL 16-bit types. |
234 | | void EnableHlsl16BitTypes(bool enable); |
235 | | |
236 | | // Enables or disables relaxed Vulkan rules. |
237 | | // |
238 | | // This allows most OpenGL shaders to compile under Vulkan semantics. |
239 | | void SetVulkanRulesRelaxed(bool enable); |
240 | | |
241 | | // Enables or disables invert position.Y output in vertex shader. |
242 | | void EnableInvertY(bool enable); |
243 | | |
244 | | // Sets whether the compiler generates code for max and min builtins which, |
245 | | // if given a NaN operand, will return the other operand. Also, the clamp |
246 | | // builtin will favour the non-NaN operands, as if clamp were implemented |
247 | | // as a composition of max and min. |
248 | | void SetNanClamp(bool enable); |
249 | | |
250 | | // When a warning is encountered it treat it as an error. |
251 | | void SetWarningsAsErrors(); |
252 | | |
253 | | // Any warning message generated is suppressed before it is output. |
254 | | void SetSuppressWarnings(); |
255 | | |
256 | | // Adds an implicit macro definition obeyed by subsequent CompileShader() |
257 | | // calls. The macro and definition should be passed in with their char* |
258 | | // pointer and their lengths. They can be modified or deleted after this |
259 | | // function has returned. |
260 | | void AddMacroDefinition(const char* macro, size_t macro_length, |
261 | | const char* definition, size_t definition_length); |
262 | | |
263 | | // Sets the target environment, including version. The version value should |
264 | | // be 0 or one of the values from TargetEnvVersion. The default value maps |
265 | | // to Vulkan 1.0 if the target environment is Vulkan, and it maps to OpenGL |
266 | | // 4.5 if the target environment is OpenGL. |
267 | | void SetTargetEnv(TargetEnv env, |
268 | | TargetEnvVersion version = TargetEnvVersion::Default); |
269 | | |
270 | | // Sets the target version of SPIR-V. The module will use this version |
271 | | // of SPIR-V. Defaults to the highest version of SPIR-V required to be |
272 | | // supported by the target environment. E.g. default to SPIR-V 1.0 for |
273 | | // Vulkan 1.0, and SPIR-V 1.3 for Vulkan 1.1. |
274 | | void SetTargetSpirv(SpirvVersion version); |
275 | | |
276 | | // Sets the souce language. |
277 | | void SetSourceLanguage(SourceLanguage lang); |
278 | | |
279 | | // Forces (without any verification) the default version and profile for |
280 | | // subsequent CompileShader() calls. |
281 | | void SetForcedVersionProfile(int version, EProfile profile); |
282 | | |
283 | | // Sets a resource limit. |
284 | | void SetLimit(Limit limit, int value); |
285 | | |
286 | | // Returns the current limit. |
287 | | int GetLimit(Limit limit) const; |
288 | | |
289 | | // Set whether the compiler automatically assigns bindings to |
290 | | // uniform variables that don't have explicit bindings. |
291 | 1.22k | void SetAutoBindUniforms(bool auto_bind) { auto_bind_uniforms_ = auto_bind; } |
292 | | |
293 | | // Sets whether the compiler should automatically remove sampler variables |
294 | | // and convert image variables to combined image-sampler variables. |
295 | 0 | void SetAutoCombinedImageSampler(bool auto_combine) { |
296 | 0 | auto_combined_image_sampler_ = auto_combine; |
297 | 0 | } |
298 | | |
299 | | // Sets the lowest binding number used when automatically assigning bindings |
300 | | // for uniform resources of the given type, for all shader stages. The |
301 | | // default base is zero. |
302 | 0 | void SetAutoBindingBase(UniformKind kind, uint32_t base) { |
303 | 0 | for (auto stage : stages()) { |
304 | 0 | SetAutoBindingBaseForStage(stage, kind, base); |
305 | 0 | } |
306 | 0 | } |
307 | | |
308 | | // Sets the lowest binding number used when automatically assigning bindings |
309 | | // for uniform resources of the given type for a specific shader stage. The |
310 | | // default base is zero. |
311 | | void SetAutoBindingBaseForStage(Stage stage, UniformKind kind, |
312 | 0 | uint32_t base) { |
313 | 0 | auto_binding_base_[static_cast<int>(stage)][static_cast<int>(kind)] = base; |
314 | 0 | } |
315 | | |
316 | | // Sets whether the compiler should preserve all bindings, even when those |
317 | | // bindings are not used. |
318 | 1.22k | void SetPreserveBindings(bool preserve_bindings) { |
319 | 1.22k | preserve_bindings_ = preserve_bindings; |
320 | 1.22k | } |
321 | | |
322 | 0 | void SetMaxIdBound(uint32_t max_id_bound) { max_id_bound_ = max_id_bound; } |
323 | | |
324 | | // Sets whether the compiler automatically assigns locations to |
325 | | // uniform variables that don't have explicit locations. |
326 | 1.22k | void SetAutoMapLocations(bool auto_map) { auto_map_locations_ = auto_map; } |
327 | | |
328 | | // Use HLSL IO mapping rules for bindings. Default is false. |
329 | 0 | void SetHlslIoMapping(bool hlsl_iomap) { hlsl_iomap_ = hlsl_iomap; } |
330 | | |
331 | | // Use HLSL rules for offsets in "transparent" memory. These allow for |
332 | | // tighter packing of some combinations of types than standard GLSL packings. |
333 | 1.22k | void SetHlslOffsets(bool hlsl_offsets) { hlsl_offsets_ = hlsl_offsets; } |
334 | | |
335 | | // Sets an explicit set and binding for the given HLSL register. |
336 | | void SetHlslRegisterSetAndBinding(const std::string& reg, |
337 | | const std::string& set, |
338 | 0 | const std::string& binding) { |
339 | 0 | for (auto stage : stages()) { |
340 | 0 | SetHlslRegisterSetAndBindingForStage(stage, reg, set, binding); |
341 | 0 | } |
342 | 0 | } |
343 | | |
344 | | // Sets an explicit set and binding for the given HLSL register in the given |
345 | | // shader stage. For example, |
346 | | // SetHlslRegisterSetAndBinding(Stage::Fragment, "t1", "4", "5") |
347 | | // means register "t1" in a fragment shader should map to binding 5 in set 4. |
348 | | // (Glslang wants this data as strings, not ints or enums.) The string data |
349 | | // is copied. |
350 | | void SetHlslRegisterSetAndBindingForStage(Stage stage, const std::string& reg, |
351 | | const std::string& set, |
352 | 0 | const std::string& binding) { |
353 | 0 | hlsl_explicit_bindings_[static_cast<int>(stage)].push_back(reg); |
354 | 0 | hlsl_explicit_bindings_[static_cast<int>(stage)].push_back(set); |
355 | 0 | hlsl_explicit_bindings_[static_cast<int>(stage)].push_back(binding); |
356 | 0 | } |
357 | | |
358 | | // Compiles the shader source in the input_source_string parameter. |
359 | | // |
360 | | // If the forced_shader stage parameter is not EShLangCount then |
361 | | // the shader is assumed to be of the given stage. |
362 | | // |
363 | | // For HLSL compilation, entry_point_name is the null-terminated string for |
364 | | // the entry point. For GLSL compilation, entry_point_name is ignored, and |
365 | | // compilation assumes the entry point is named "main". |
366 | | // |
367 | | // The stage_callback function will be called if a shader_stage has |
368 | | // not been forced and the stage can not be determined |
369 | | // from the shader text. Any #include directives are parsed with the given |
370 | | // includer. |
371 | | // |
372 | | // The initializer parameter must be a valid GlslangInitializer object. |
373 | | // Acquire will be called on the initializer and the result will be |
374 | | // destroyed before the function ends. |
375 | | // |
376 | | // The output_type parameter determines what kind of output should be |
377 | | // produced. |
378 | | // |
379 | | // Any error messages are written as if the file name were error_tag. |
380 | | // Any errors are written to the error_stream parameter. |
381 | | // total_warnings and total_errors are incremented once for every |
382 | | // warning or error encountered respectively. |
383 | | // |
384 | | // Returns a tuple consisting of three fields. 1) a boolean which is true when |
385 | | // the compilation succeeded, and false otherwise; 2) a vector of 32-bit words |
386 | | // which contains the compilation output data, either compiled SPIR-V binary |
387 | | // code, or the text string generated in preprocessing-only or disassembly |
388 | | // mode; 3) the size of the output data in bytes. When the output is SPIR-V |
389 | | // binary code, the size is the number of bytes of valid data in the vector. |
390 | | // If the output is a text string, the size equals the length of that string. |
391 | | std::tuple<bool, std::vector<uint32_t>, size_t> Compile( |
392 | | const string_piece& input_source_string, EShLanguage forced_shader_stage, |
393 | | const std::string& error_tag, const char* entry_point_name, |
394 | | const std::function<EShLanguage(std::ostream* error_stream, |
395 | | const string_piece& error_tag)>& |
396 | | stage_callback, |
397 | | CountingIncluder& includer, OutputType output_type, |
398 | | std::ostream* error_stream, size_t* total_warnings, |
399 | | size_t* total_errors) const; |
400 | | |
401 | 0 | static EShMessages GetDefaultRules() { |
402 | 0 | return static_cast<EShMessages>(EShMsgSpvRules | EShMsgVulkanRules | |
403 | 0 | EShMsgCascadingErrors); |
404 | 0 | } |
405 | | |
406 | | protected: |
407 | | // Preprocesses a shader whose filename is filename and content is |
408 | | // shader_source. If preprocessing is successful, returns true, the |
409 | | // preprocessed shader, and any warning message as a tuple. Otherwise, |
410 | | // returns false, an empty string, and error messages as a tuple. |
411 | | // |
412 | | // The error_tag parameter is the name to use for outputting errors. |
413 | | // The shader_source parameter is the input shader's source text. |
414 | | // The shader_preamble parameter is a context-specific preamble internally |
415 | | // prepended to shader_text without affecting the validity of its #version |
416 | | // position. |
417 | | // |
418 | | // Any #include directives are processed with the given includer. |
419 | | // |
420 | | // If force_version_profile_ is set, the shader's version/profile is forced |
421 | | // to be default_version_/default_profile_ regardless of the #version |
422 | | // directive in the source code. |
423 | | std::tuple<bool, std::string, std::string> PreprocessShader( |
424 | | const std::string& error_tag, const string_piece& shader_source, |
425 | | const string_piece& shader_preamble, CountingIncluder& includer) const; |
426 | | |
427 | | // Cleans up the preamble in a given preprocessed shader. |
428 | | // |
429 | | // The error_tag parameter is the name to be given for the main file. |
430 | | // The pound_extension parameter is the #extension directive we prepended to |
431 | | // the original shader source code via preamble. |
432 | | // The num_include_directives parameter is the number of #include directives |
433 | | // appearing in the original shader source code. |
434 | | // The is_for_next_line means whether the #line sets the line number for the |
435 | | // next line. |
436 | | // |
437 | | // If no #include directive is used in the shader source code, we can safely |
438 | | // delete the #extension directive we injected via preamble. Otherwise, we |
439 | | // need to adjust it if there exists a #version directive in the original |
440 | | // shader source code. |
441 | | std::string CleanupPreamble(const string_piece& preprocessed_shader, |
442 | | const string_piece& error_tag, |
443 | | const string_piece& pound_extension, |
444 | | int num_include_directives, |
445 | | bool is_for_next_line) const; |
446 | | |
447 | | // Determines version and profile from command line, or the source code. |
448 | | // Returns the decoded version and profile pair on success. Otherwise, |
449 | | // returns (0, ENoProfile). |
450 | | std::pair<int, EProfile> DeduceVersionProfile( |
451 | | const std::string& preprocessed_shader) const; |
452 | | |
453 | | // Determines the shader stage from pragmas embedded in the source text if |
454 | | // possible. In the returned pair, the glslang EShLanguage is the shader |
455 | | // stage deduced. If no #pragma directives for shader stage exist, it's |
456 | | // EShLangCount. If errors occur, the second element in the pair is the |
457 | | // error message. Otherwise, it's an empty string. |
458 | | std::pair<EShLanguage, std::string> GetShaderStageFromSourceCode( |
459 | | string_piece filename, const std::string& preprocessed_shader) const; |
460 | | |
461 | | // Determines version and profile from command line, or the source code. |
462 | | // Returns the decoded version and profile pair on success. Otherwise, |
463 | | // returns (0, ENoProfile). |
464 | | std::pair<int, EProfile> DeduceVersionProfile( |
465 | | const std::string& preprocessed_shader); |
466 | | |
467 | | // Gets version and profile specification from the given preprocessedshader. |
468 | | // Returns the decoded version and profile pair on success. Otherwise, |
469 | | // returns (0, ENoProfile). |
470 | | std::pair<int, EProfile> GetVersionProfileFromSourceCode( |
471 | | const std::string& preprocessed_shader) const; |
472 | | |
473 | | // Version to use when force_version_profile_ is true. |
474 | | int default_version_; |
475 | | // Profile to use when force_version_profile_ is true. |
476 | | EProfile default_profile_; |
477 | | // When true, use the default version and profile from eponymous data members. |
478 | | bool force_version_profile_; |
479 | | |
480 | | // Macro definitions that must be available to reference in the shader source. |
481 | | MacroDictionary predefined_macros_; |
482 | | |
483 | | // When true, treat warnings as errors. |
484 | | bool warnings_as_errors_; |
485 | | // Supress warnings when true. |
486 | | bool suppress_warnings_; |
487 | | |
488 | | // When true, compilation will generate debug info with the binary SPIR-V |
489 | | // output. |
490 | | bool generate_debug_info_; |
491 | | |
492 | | // Optimization passes to be applied. |
493 | | std::vector<PassId> enabled_opt_passes_; |
494 | | |
495 | | // The target environment to compile with. This controls the glslang |
496 | | // EshMessages bitmask, which determines which dialect of GLSL and which |
497 | | // SPIR-V codegen semantics are used. This impacts the warning & error |
498 | | // messages as well as the set of available builtins, as per the |
499 | | // implementation of glslang. |
500 | | TargetEnv target_env_; |
501 | | |
502 | | // The version number of the target environment. The numbering scheme is |
503 | | // particular to each target environment. If this is 0, then use a default |
504 | | // for that particular target environment. See libshaders/shaderc/shaderc.h |
505 | | // for those defaults. |
506 | | TargetEnvVersion target_env_version_; |
507 | | |
508 | | // The SPIR-V version to be used for the generated module. Defaults to 1.0. |
509 | | SpirvVersion target_spirv_version_; |
510 | | // True if the user explicitly set the target SPIR-V version. |
511 | | bool target_spirv_version_is_forced_; |
512 | | |
513 | | // The source language. Defaults to GLSL. |
514 | | SourceLanguage source_language_; |
515 | | |
516 | | // The resource limits to be used. |
517 | | TBuiltInResource limits_; |
518 | | |
519 | | // True if the compiler should automatically bind uniforms that don't |
520 | | // have explicit bindings. |
521 | | bool auto_bind_uniforms_; |
522 | | |
523 | | // True if the compiler should automatically remove sampler variables |
524 | | // and convert image variables to combined image-sampler variables. |
525 | | bool auto_combined_image_sampler_; |
526 | | |
527 | | // The base binding number per uniform type, per stage, used when |
528 | | // automatically binding uniforms that don't hzve explicit bindings in the |
529 | | // shader source. The default is zero. |
530 | | uint32_t auto_binding_base_[kNumStages][kNumUniformKinds]; |
531 | | |
532 | | // True if the compiler should automatically map uniforms that don't |
533 | | // have explicit locations. |
534 | | bool auto_map_locations_; |
535 | | |
536 | | // True if the compiler should preserve all bindings, even when unused. |
537 | | bool preserve_bindings_; |
538 | | |
539 | | uint32_t max_id_bound_ = 0x3FFFFF; |
540 | | |
541 | | // True if the compiler should use HLSL IO mapping rules when compiling HLSL. |
542 | | bool hlsl_iomap_; |
543 | | |
544 | | // True if the compiler should determine block member offsets using HLSL |
545 | | // packing rules instead of standard GLSL rules. |
546 | | bool hlsl_offsets_; |
547 | | |
548 | | // True if the compiler should perform legalization optimization passes if |
549 | | // source language is HLSL. |
550 | | bool hlsl_legalization_enabled_; |
551 | | |
552 | | // True if the compiler should support extension |
553 | | // SPV_GOOGLE_hlsl_functionality1. |
554 | | bool hlsl_functionality1_enabled_; |
555 | | |
556 | | // True if the compiler should support 16-bit HLSL types. |
557 | | bool hlsl_16bit_types_enabled_; |
558 | | |
559 | | // True if the compiler should relax Vulkan rules to allow OGL shaders to |
560 | | // compile. |
561 | | bool vulkan_rules_relaxed_ = false; |
562 | | |
563 | | // True if the compiler should invert position.Y output in vertex shader. |
564 | | bool invert_y_enabled_; |
565 | | |
566 | | // True if the compiler generates code for max and min builtins which, |
567 | | // if given a NaN operand, will return the other operand. Also, the clamp |
568 | | // builtin will favour the non-NaN operands, as if clamp were implemented |
569 | | // as a composition of max and min. |
570 | | bool nan_clamp_; |
571 | | |
572 | | // A sequence of triples, each triple representing a specific HLSL register |
573 | | // name, and the set and binding numbers it should be mapped to, but in |
574 | | // the form of strings. This is how Glslang wants to consume the data. |
575 | | std::vector<std::string> hlsl_explicit_bindings_[kNumStages]; |
576 | | }; |
577 | | |
578 | | // Converts a string to a vector of uint32_t by copying the content of a given |
579 | | // string to the vector and returns it. Appends '\0' at the end if extra bytes |
580 | | // are required to complete the last element. |
581 | | std::vector<uint32_t> ConvertStringToVector(const std::string& str); |
582 | | |
583 | | // Converts a valid Glslang shader stage value to a Compiler::Stage value. |
584 | 0 | inline Compiler::Stage ConvertToStage(EShLanguage stage) { |
585 | 0 | switch (stage) { |
586 | 0 | case EShLangVertex: |
587 | 0 | return Compiler::Stage::Vertex; |
588 | 0 | case EShLangTessControl: |
589 | 0 | return Compiler::Stage::TessEval; |
590 | 0 | case EShLangTessEvaluation: |
591 | 0 | return Compiler::Stage::TessControl; |
592 | 0 | case EShLangGeometry: |
593 | 0 | return Compiler::Stage::Geometry; |
594 | 0 | case EShLangFragment: |
595 | 0 | return Compiler::Stage::Fragment; |
596 | 0 | case EShLangCompute: |
597 | 0 | return Compiler::Stage::Compute; |
598 | 0 | case EShLangRayGenNV: |
599 | 0 | return Compiler::Stage::RayGenNV; |
600 | 0 | case EShLangIntersectNV: |
601 | 0 | return Compiler::Stage::IntersectNV; |
602 | 0 | case EShLangAnyHitNV: |
603 | 0 | return Compiler::Stage::AnyHitNV; |
604 | 0 | case EShLangClosestHitNV: |
605 | 0 | return Compiler::Stage::ClosestHitNV; |
606 | 0 | case EShLangMissNV: |
607 | 0 | return Compiler::Stage::MissNV; |
608 | 0 | case EShLangCallableNV: |
609 | 0 | return Compiler::Stage::CallableNV; |
610 | 0 | case EShLangTaskNV: |
611 | 0 | return Compiler::Stage::TaskNV; |
612 | 0 | case EShLangMeshNV: |
613 | 0 | return Compiler::Stage::MeshNV; |
614 | 0 | default: |
615 | 0 | break; |
616 | 0 | } |
617 | 0 | assert(false && "Invalid case"); |
618 | 0 | return Compiler::Stage::Compute; |
619 | 0 | } |
620 | | |
621 | | // A GlslangClientInfo captures target client version and desired SPIR-V |
622 | | // version. |
623 | | struct GlslangClientInfo { |
624 | 17.0k | GlslangClientInfo() {} |
625 | | GlslangClientInfo(const std::string& e, glslang::EShClient c, |
626 | | glslang::EShTargetClientVersion cv, |
627 | | glslang::EShTargetLanguage l, |
628 | | glslang::EShTargetLanguageVersion lv) |
629 | | : error(e), |
630 | | client(c), |
631 | | client_version(cv), |
632 | | target_language(l), |
633 | 0 | target_language_version(lv) {} |
634 | | |
635 | | std::string error; // Empty if ok, otherwise contains the error message. |
636 | | glslang::EShClient client = glslang::EShClientNone; |
637 | | glslang::EShTargetClientVersion client_version; |
638 | | glslang::EShTargetLanguage target_language = glslang::EShTargetSpv; |
639 | | glslang::EShTargetLanguageVersion target_language_version = |
640 | | glslang::EShTargetSpv_1_0; |
641 | | }; |
642 | | |
643 | | // Returns the mappings to Glslang client, client version, and SPIR-V version. |
644 | | // Also indicates whether the input values were valid. |
645 | | GlslangClientInfo GetGlslangClientInfo( |
646 | | const std::string& error_tag, // Indicates source location, for errors. |
647 | | shaderc_util::Compiler::TargetEnv env, |
648 | | shaderc_util::Compiler::TargetEnvVersion env_version, |
649 | | shaderc_util::Compiler::SpirvVersion spv_version, |
650 | | bool spv_version_is_forced); |
651 | | |
652 | | } // namespace shaderc_util |
653 | | #endif // LIBSHADERC_UTIL_INC_COMPILER_H |