Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/shaderc
Path: blob/main/libshaderc/src/shaderc.cc
1558 views
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
#include "shaderc/shaderc.h"
16
17
#include <algorithm>
18
#include <cassert>
19
#include <cstdint>
20
#include <memory>
21
#include <sstream>
22
#include <vector>
23
24
#include "libshaderc_util/compiler.h"
25
#include "libshaderc_util/counting_includer.h"
26
#include "libshaderc_util/resources.h"
27
#include "libshaderc_util/spirv_tools_wrapper.h"
28
#include "libshaderc_util/version_profile.h"
29
#include "shaderc_private.h"
30
#include "spirv/unified1/spirv.hpp"
31
32
#if (defined(_MSC_VER) && !defined(_CPPUNWIND)) || !defined(__EXCEPTIONS)
33
#define TRY_IF_EXCEPTIONS_ENABLED
34
#define CATCH_IF_EXCEPTIONS_ENABLED(X) if (0)
35
#else
36
#define TRY_IF_EXCEPTIONS_ENABLED try
37
#define CATCH_IF_EXCEPTIONS_ENABLED(X) catch (X)
38
#endif
39
40
namespace {
41
42
// Returns shader stage (ie: vertex, fragment, etc.) in response to forced
43
// shader kinds. If the shader kind is not a forced kind, returns EshLangCount
44
// to let #pragma annotation or shader stage deducer determine the stage to
45
// use.
46
EShLanguage GetForcedStage(shaderc_shader_kind kind) {
47
switch (kind) {
48
case shaderc_glsl_vertex_shader:
49
return EShLangVertex;
50
case shaderc_glsl_fragment_shader:
51
return EShLangFragment;
52
case shaderc_glsl_compute_shader:
53
return EShLangCompute;
54
case shaderc_glsl_geometry_shader:
55
return EShLangGeometry;
56
case shaderc_glsl_tess_control_shader:
57
return EShLangTessControl;
58
case shaderc_glsl_tess_evaluation_shader:
59
return EShLangTessEvaluation;
60
61
case shaderc_glsl_raygen_shader:
62
return EShLangRayGenNV;
63
case shaderc_glsl_anyhit_shader:
64
return EShLangAnyHitNV;
65
case shaderc_glsl_closesthit_shader:
66
return EShLangClosestHitNV;
67
case shaderc_glsl_miss_shader:
68
return EShLangMissNV;
69
case shaderc_glsl_intersection_shader:
70
return EShLangIntersectNV;
71
case shaderc_glsl_callable_shader:
72
return EShLangCallableNV;
73
case shaderc_glsl_task_shader:
74
return EShLangTaskNV;
75
case shaderc_glsl_mesh_shader:
76
return EShLangMeshNV;
77
78
case shaderc_glsl_infer_from_source:
79
case shaderc_glsl_default_vertex_shader:
80
case shaderc_glsl_default_fragment_shader:
81
case shaderc_glsl_default_compute_shader:
82
case shaderc_glsl_default_geometry_shader:
83
case shaderc_glsl_default_tess_control_shader:
84
case shaderc_glsl_default_tess_evaluation_shader:
85
case shaderc_glsl_default_raygen_shader:
86
case shaderc_glsl_default_anyhit_shader:
87
case shaderc_glsl_default_closesthit_shader:
88
case shaderc_glsl_default_miss_shader:
89
case shaderc_glsl_default_intersection_shader:
90
case shaderc_glsl_default_callable_shader:
91
case shaderc_glsl_default_task_shader:
92
case shaderc_glsl_default_mesh_shader:
93
case shaderc_spirv_assembly:
94
return EShLangCount;
95
}
96
assert(0 && "Unhandled shaderc_shader_kind");
97
return EShLangCount;
98
}
99
100
// A wrapper functor class to be used as stage deducer for libshaderc_util
101
// Compile() interface. When the given shader kind is one of the default shader
102
// kinds, this functor will be called if #pragma is not found in the source
103
// code. And it returns the corresponding shader stage. When the shader kind is
104
// a forced shader kind, this functor won't be called and it simply returns
105
// EShLangCount to make the syntax correct. When the shader kind is set to
106
// shaderc_glsl_deduce_from_pragma, this functor also returns EShLangCount, but
107
// the compiler should emit error if #pragma annotation is not found in this
108
// case.
109
class StageDeducer {
110
public:
111
explicit StageDeducer(
112
shaderc_shader_kind kind = shaderc_glsl_infer_from_source)
113
: kind_(kind), error_(false){}
114
// The method that underlying glslang will call to determine the shader stage
115
// to be used in current compilation. It is called only when there is neither
116
// forced shader kind (or say stage, in the view of glslang), nor #pragma
117
// annotation in the source code. This method transforms an user defined
118
// 'default' shader kind to the corresponding shader stage. As this is the
119
// last trial to determine the shader stage, failing to find the corresponding
120
// shader stage will record an error.
121
// Note that calling this method more than once during one compilation will
122
// have the error recorded for the previous call been overwriten by the next
123
// call.
124
EShLanguage operator()(std::ostream* /*error_stream*/,
125
const shaderc_util::string_piece& /*error_tag*/) {
126
EShLanguage stage = GetDefaultStage(kind_);
127
if (stage == EShLangCount) {
128
error_ = true;
129
} else {
130
error_ = false;
131
}
132
return stage;
133
}
134
135
// Returns true if there is error during shader stage deduction.
136
bool error() const { return error_; }
137
138
private:
139
// Gets the corresponding shader stage for a given 'default' shader kind. All
140
// other kinds are mapped to EShLangCount which should not be used.
141
EShLanguage GetDefaultStage(shaderc_shader_kind kind) const {
142
switch (kind) {
143
case shaderc_glsl_vertex_shader:
144
case shaderc_glsl_fragment_shader:
145
case shaderc_glsl_compute_shader:
146
case shaderc_glsl_geometry_shader:
147
case shaderc_glsl_tess_control_shader:
148
case shaderc_glsl_tess_evaluation_shader:
149
case shaderc_glsl_infer_from_source:
150
case shaderc_glsl_raygen_shader:
151
case shaderc_glsl_anyhit_shader:
152
case shaderc_glsl_closesthit_shader:
153
case shaderc_glsl_miss_shader:
154
case shaderc_glsl_intersection_shader:
155
case shaderc_glsl_callable_shader:
156
case shaderc_glsl_task_shader:
157
case shaderc_glsl_mesh_shader:
158
return EShLangCount;
159
case shaderc_glsl_default_vertex_shader:
160
return EShLangVertex;
161
case shaderc_glsl_default_fragment_shader:
162
return EShLangFragment;
163
case shaderc_glsl_default_compute_shader:
164
return EShLangCompute;
165
case shaderc_glsl_default_geometry_shader:
166
return EShLangGeometry;
167
case shaderc_glsl_default_tess_control_shader:
168
return EShLangTessControl;
169
case shaderc_glsl_default_tess_evaluation_shader:
170
return EShLangTessEvaluation;
171
case shaderc_glsl_default_raygen_shader:
172
return EShLangRayGenNV;
173
case shaderc_glsl_default_anyhit_shader:
174
return EShLangAnyHitNV;
175
case shaderc_glsl_default_closesthit_shader:
176
return EShLangClosestHitNV;
177
case shaderc_glsl_default_miss_shader:
178
return EShLangMissNV;
179
case shaderc_glsl_default_intersection_shader:
180
return EShLangIntersectNV;
181
case shaderc_glsl_default_callable_shader:
182
return EShLangCallableNV;
183
case shaderc_glsl_default_task_shader:
184
return EShLangTaskNV;
185
case shaderc_glsl_default_mesh_shader:
186
return EShLangMeshNV;
187
case shaderc_spirv_assembly:
188
return EShLangCount;
189
}
190
assert(0 && "Unhandled shaderc_shader_kind");
191
return EShLangCount;
192
}
193
194
shaderc_shader_kind kind_;
195
bool error_;
196
};
197
198
// A bridge between the libshaderc includer and libshaderc_util includer.
199
class InternalFileIncluder : public shaderc_util::CountingIncluder {
200
public:
201
InternalFileIncluder(const shaderc_include_resolve_fn resolver,
202
const shaderc_include_result_release_fn result_releaser,
203
void* user_data)
204
: resolver_(resolver),
205
result_releaser_(result_releaser),
206
user_data_(user_data){}
207
InternalFileIncluder()
208
: resolver_(nullptr), result_releaser_(nullptr), user_data_(nullptr){}
209
210
private:
211
// Check the validity of the callbacks.
212
bool AreValidCallbacks() const {
213
return resolver_ != nullptr && result_releaser_ != nullptr;
214
}
215
216
// Maps CountingIncluder IncludeType value to a shaderc_include_type
217
// value.
218
shaderc_include_type GetIncludeType(IncludeType type) {
219
switch (type) {
220
case IncludeType::Local:
221
return shaderc_include_type_relative;
222
case IncludeType::System:
223
return shaderc_include_type_standard;
224
default:
225
break;
226
}
227
assert(0 && "Unhandled IncludeType");
228
return shaderc_include_type_relative;
229
}
230
231
// Resolves an include request for the requested source of the given
232
// type in the context of the specified requesting source. On success,
233
// returns a newly allocated IncludeResponse containing the fully resolved
234
// name of the requested source and the contents of that source.
235
// On failure, returns a newly allocated IncludeResponse where the
236
// resolved name member is an empty string, and the contents members
237
// contains error details.
238
virtual glslang::TShader::Includer::IncludeResult* include_delegate(
239
const char* requested_source, const char* requesting_source,
240
IncludeType type, size_t include_depth) override {
241
if (!AreValidCallbacks()) {
242
static const char kUnexpectedIncludeError[] =
243
"#error unexpected include directive";
244
return new glslang::TShader::Includer::IncludeResult{
245
"", kUnexpectedIncludeError, strlen(kUnexpectedIncludeError),
246
nullptr};
247
}
248
shaderc_include_result* include_result =
249
resolver_(user_data_, requested_source, GetIncludeType(type),
250
requesting_source, include_depth);
251
// Make a glslang IncludeResult from a shaderc_include_result. The
252
// user_data member of the IncludeResult is a pointer to the
253
// shaderc_include_result object, so we can later release the latter.
254
return new glslang::TShader::Includer::IncludeResult{
255
std::string(include_result->source_name,
256
include_result->source_name_length),
257
include_result->content, include_result->content_length,
258
include_result};
259
}
260
261
// Releases the given IncludeResult.
262
virtual void release_delegate(
263
glslang::TShader::Includer::IncludeResult* result) override {
264
if (result && result_releaser_) {
265
result_releaser_(user_data_,
266
static_cast<shaderc_include_result*>(result->userData));
267
}
268
delete result;
269
}
270
271
const shaderc_include_resolve_fn resolver_;
272
const shaderc_include_result_release_fn result_releaser_;
273
void* user_data_;
274
};
275
276
// Converts the target env to the corresponding one in shaderc_util::Compiler.
277
shaderc_util::Compiler::TargetEnv GetCompilerTargetEnv(shaderc_target_env env) {
278
switch (env) {
279
case shaderc_target_env_opengl:
280
return shaderc_util::Compiler::TargetEnv::OpenGL;
281
case shaderc_target_env_opengl_compat:
282
return shaderc_util::Compiler::TargetEnv::OpenGLCompat;
283
case shaderc_target_env_webgpu:
284
assert(false);
285
break;
286
case shaderc_target_env_vulkan:
287
default:
288
break;
289
}
290
291
return shaderc_util::Compiler::TargetEnv::Vulkan;
292
}
293
294
shaderc_util::Compiler::TargetEnvVersion GetCompilerTargetEnvVersion(
295
uint32_t version_number) {
296
using namespace shaderc_util;
297
298
if (static_cast<uint32_t>(Compiler::TargetEnvVersion::Vulkan_1_0) ==
299
version_number) {
300
return Compiler::TargetEnvVersion::Vulkan_1_0;
301
}
302
if (static_cast<uint32_t>(Compiler::TargetEnvVersion::Vulkan_1_1) ==
303
version_number) {
304
return Compiler::TargetEnvVersion::Vulkan_1_1;
305
}
306
if (static_cast<uint32_t>(Compiler::TargetEnvVersion::Vulkan_1_2) ==
307
version_number) {
308
return Compiler::TargetEnvVersion::Vulkan_1_2;
309
}
310
if (static_cast<uint32_t>(Compiler::TargetEnvVersion::Vulkan_1_3) ==
311
version_number) {
312
return Compiler::TargetEnvVersion::Vulkan_1_3;
313
}
314
if (static_cast<uint32_t>(Compiler::TargetEnvVersion::OpenGL_4_5) ==
315
version_number) {
316
return Compiler::TargetEnvVersion::OpenGL_4_5;
317
}
318
319
return Compiler::TargetEnvVersion::Default;
320
}
321
322
// Returns the Compiler::Limit enum for the given shaderc_limit enum.
323
shaderc_util::Compiler::Limit CompilerLimit(shaderc_limit limit) {
324
switch (limit) {
325
#define RESOURCE(NAME, FIELD, CNAME) \
326
case shaderc_limit_##CNAME: \
327
return shaderc_util::Compiler::Limit::NAME;
328
#include "libshaderc_util/resources.inc"
329
#undef RESOURCE
330
default:
331
break;
332
}
333
assert(0 && "Should not have reached here");
334
return static_cast<shaderc_util::Compiler::Limit>(0);
335
}
336
337
// Returns the Compiler::UniformKind for the given shaderc_uniform_kind.
338
shaderc_util::Compiler::UniformKind GetUniformKind(shaderc_uniform_kind kind) {
339
switch (kind) {
340
case shaderc_uniform_kind_texture:
341
return shaderc_util::Compiler::UniformKind::Texture;
342
case shaderc_uniform_kind_sampler:
343
return shaderc_util::Compiler::UniformKind::Sampler;
344
case shaderc_uniform_kind_image:
345
return shaderc_util::Compiler::UniformKind::Image;
346
case shaderc_uniform_kind_buffer:
347
return shaderc_util::Compiler::UniformKind::Buffer;
348
case shaderc_uniform_kind_storage_buffer:
349
return shaderc_util::Compiler::UniformKind::StorageBuffer;
350
case shaderc_uniform_kind_unordered_access_view:
351
return shaderc_util::Compiler::UniformKind::UnorderedAccessView;
352
}
353
assert(0 && "Should not have reached here");
354
return static_cast<shaderc_util::Compiler::UniformKind>(0);
355
}
356
357
// Returns the Compiler::Stage for generic stage values in shaderc_shader_kind.
358
shaderc_util::Compiler::Stage GetStage(shaderc_shader_kind kind) {
359
switch (kind) {
360
case shaderc_vertex_shader:
361
return shaderc_util::Compiler::Stage::Vertex;
362
case shaderc_fragment_shader:
363
return shaderc_util::Compiler::Stage::Fragment;
364
case shaderc_compute_shader:
365
return shaderc_util::Compiler::Stage::Compute;
366
case shaderc_tess_control_shader:
367
return shaderc_util::Compiler::Stage::TessControl;
368
case shaderc_tess_evaluation_shader:
369
return shaderc_util::Compiler::Stage::TessEval;
370
case shaderc_geometry_shader:
371
return shaderc_util::Compiler::Stage::Geometry;
372
default:
373
break;
374
}
375
assert(0 && "Should not have reached here");
376
return static_cast<shaderc_util::Compiler::Stage>(0);
377
}
378
379
} // anonymous namespace
380
381
struct shaderc_compile_options {
382
shaderc_target_env target_env = shaderc_target_env_default;
383
uint32_t target_env_version = 0;
384
shaderc_util::Compiler compiler;
385
shaderc_include_resolve_fn include_resolver = nullptr;
386
shaderc_include_result_release_fn include_result_releaser = nullptr;
387
void* include_user_data = nullptr;
388
};
389
390
shaderc_compile_options_t shaderc_compile_options_initialize() {
391
return new (std::nothrow) shaderc_compile_options;
392
}
393
394
shaderc_compile_options_t shaderc_compile_options_clone(
395
const shaderc_compile_options_t options) {
396
if (!options) {
397
return shaderc_compile_options_initialize();
398
}
399
return new (std::nothrow) shaderc_compile_options(*options);
400
}
401
402
void shaderc_compile_options_release(shaderc_compile_options_t options) {
403
delete options;
404
}
405
406
void shaderc_compile_options_add_macro_definition(
407
shaderc_compile_options_t options, const char* name, size_t name_length,
408
const char* value, size_t value_length) {
409
options->compiler.AddMacroDefinition(name, name_length, value, value_length);
410
}
411
412
void shaderc_compile_options_set_source_language(
413
shaderc_compile_options_t options, shaderc_source_language set_lang) {
414
auto lang = shaderc_util::Compiler::SourceLanguage::GLSL;
415
if (set_lang == shaderc_source_language_hlsl)
416
lang = shaderc_util::Compiler::SourceLanguage::HLSL;
417
options->compiler.SetSourceLanguage(lang);
418
}
419
420
void shaderc_compile_options_set_generate_debug_info(
421
shaderc_compile_options_t options) {
422
options->compiler.SetGenerateDebugInfo();
423
}
424
425
void shaderc_compile_options_set_optimization_level(
426
shaderc_compile_options_t options, shaderc_optimization_level level) {
427
auto opt_level = shaderc_util::Compiler::OptimizationLevel::Zero;
428
switch (level) {
429
case shaderc_optimization_level_size:
430
opt_level = shaderc_util::Compiler::OptimizationLevel::Size;
431
break;
432
case shaderc_optimization_level_performance:
433
opt_level = shaderc_util::Compiler::OptimizationLevel::Performance;
434
break;
435
default:
436
break;
437
}
438
439
options->compiler.SetOptimizationLevel(opt_level);
440
}
441
442
void shaderc_compile_options_set_forced_version_profile(
443
shaderc_compile_options_t options, int version, shaderc_profile profile) {
444
// Transfer the profile parameter from public enum type to glslang internal
445
// enum type. No default case here so that compiler will complain if new enum
446
// member is added later but not handled here.
447
switch (profile) {
448
case shaderc_profile_none:
449
options->compiler.SetForcedVersionProfile(version, ENoProfile);
450
break;
451
case shaderc_profile_core:
452
options->compiler.SetForcedVersionProfile(version, ECoreProfile);
453
break;
454
case shaderc_profile_compatibility:
455
options->compiler.SetForcedVersionProfile(version, ECompatibilityProfile);
456
break;
457
case shaderc_profile_es:
458
options->compiler.SetForcedVersionProfile(version, EEsProfile);
459
break;
460
}
461
}
462
463
void shaderc_compile_options_set_include_callbacks(
464
shaderc_compile_options_t options, shaderc_include_resolve_fn resolver,
465
shaderc_include_result_release_fn result_releaser, void* user_data) {
466
options->include_resolver = resolver;
467
options->include_result_releaser = result_releaser;
468
options->include_user_data = user_data;
469
}
470
471
void shaderc_compile_options_set_suppress_warnings(
472
shaderc_compile_options_t options) {
473
options->compiler.SetSuppressWarnings();
474
}
475
476
void shaderc_compile_options_set_target_env(shaderc_compile_options_t options,
477
shaderc_target_env target,
478
uint32_t version) {
479
options->target_env = target;
480
options->compiler.SetTargetEnv(GetCompilerTargetEnv(target),
481
GetCompilerTargetEnvVersion(version));
482
}
483
484
void shaderc_compile_options_set_target_spirv(shaderc_compile_options_t options,
485
shaderc_spirv_version ver) {
486
// We made the values match, so we can get away with a static cast.
487
options->compiler.SetTargetSpirv(
488
static_cast<shaderc_util::Compiler::SpirvVersion>(ver));
489
}
490
491
void shaderc_compile_options_set_warnings_as_errors(
492
shaderc_compile_options_t options) {
493
options->compiler.SetWarningsAsErrors();
494
}
495
496
void shaderc_compile_options_set_limit(shaderc_compile_options_t options,
497
shaderc_limit limit, int value) {
498
options->compiler.SetLimit(CompilerLimit(limit), value);
499
}
500
501
void shaderc_compile_options_set_auto_bind_uniforms(
502
shaderc_compile_options_t options, bool auto_bind) {
503
options->compiler.SetAutoBindUniforms(auto_bind);
504
}
505
506
void shaderc_compile_options_set_auto_combined_image_sampler(
507
shaderc_compile_options_t options, bool upgrade) {
508
options->compiler.SetAutoCombinedImageSampler(upgrade);
509
}
510
511
void shaderc_compile_options_set_hlsl_io_mapping(
512
shaderc_compile_options_t options, bool hlsl_iomap) {
513
options->compiler.SetHlslIoMapping(hlsl_iomap);
514
}
515
516
void shaderc_compile_options_set_hlsl_offsets(shaderc_compile_options_t options,
517
bool hlsl_offsets) {
518
options->compiler.SetHlslOffsets(hlsl_offsets);
519
}
520
521
void shaderc_compile_options_set_binding_base(shaderc_compile_options_t options,
522
shaderc_uniform_kind kind,
523
uint32_t base) {
524
options->compiler.SetAutoBindingBase(GetUniformKind(kind), base);
525
}
526
527
void shaderc_compile_options_set_binding_base_for_stage(
528
shaderc_compile_options_t options, shaderc_shader_kind shader_kind,
529
shaderc_uniform_kind kind, uint32_t base) {
530
options->compiler.SetAutoBindingBaseForStage(GetStage(shader_kind),
531
GetUniformKind(kind), base);
532
}
533
534
void shaderc_compile_options_set_preserve_bindings(
535
shaderc_compile_options_t options, bool preserve_bindings) {
536
options->compiler.SetPreserveBindings(preserve_bindings);
537
}
538
539
void shaderc_compile_options_set_auto_map_locations(
540
shaderc_compile_options_t options, bool auto_map) {
541
options->compiler.SetAutoMapLocations(auto_map);
542
}
543
544
void shaderc_compile_options_set_hlsl_register_set_and_binding_for_stage(
545
shaderc_compile_options_t options, shaderc_shader_kind shader_kind,
546
const char* reg, const char* set, const char* binding) {
547
options->compiler.SetHlslRegisterSetAndBindingForStage(GetStage(shader_kind),
548
reg, set, binding);
549
}
550
551
void shaderc_compile_options_set_hlsl_register_set_and_binding(
552
shaderc_compile_options_t options, const char* reg, const char* set,
553
const char* binding) {
554
options->compiler.SetHlslRegisterSetAndBinding(reg, set, binding);
555
}
556
557
void shaderc_compile_options_set_hlsl_functionality1(
558
shaderc_compile_options_t options, bool enable) {
559
options->compiler.EnableHlslFunctionality1(enable);
560
}
561
562
void shaderc_compile_options_set_hlsl_16bit_types(
563
shaderc_compile_options_t options, bool enable) {
564
options->compiler.EnableHlsl16BitTypes(enable);
565
}
566
567
void shaderc_compile_options_set_vulkan_rules_relaxed(
568
shaderc_compile_options_t options, bool enable) {
569
options->compiler.SetVulkanRulesRelaxed(enable);
570
}
571
572
void shaderc_compile_options_set_invert_y(
573
shaderc_compile_options_t options, bool enable) {
574
options->compiler.EnableInvertY(enable);
575
}
576
577
void shaderc_compile_options_set_nan_clamp(shaderc_compile_options_t options,
578
bool enable) {
579
options->compiler.SetNanClamp(enable);
580
}
581
582
shaderc_compiler_t shaderc_compiler_initialize() {
583
shaderc_compiler_t compiler = new (std::nothrow) shaderc_compiler;
584
if (compiler) {
585
compiler->initializer.reset(new shaderc_util::GlslangInitializer);
586
}
587
return compiler;
588
}
589
590
void shaderc_compiler_release(shaderc_compiler_t compiler) {
591
delete compiler;
592
}
593
594
namespace {
595
shaderc_compilation_result_t CompileToSpecifiedOutputType(
596
const shaderc_compiler_t compiler, const char* source_text,
597
size_t source_text_size, shaderc_shader_kind shader_kind,
598
const char* input_file_name, const char* entry_point_name,
599
const shaderc_compile_options_t additional_options,
600
shaderc_util::Compiler::OutputType output_type) {
601
auto* result = new (std::nothrow) shaderc_compilation_result_vector;
602
if (!result) return nullptr;
603
604
if (!input_file_name) {
605
result->messages = "Input file name string was null.";
606
result->num_errors = 1;
607
result->compilation_status = shaderc_compilation_status_compilation_error;
608
return result;
609
}
610
result->compilation_status = shaderc_compilation_status_invalid_stage;
611
bool compilation_succeeded = false; // In case we exit early.
612
std::vector<uint32_t> compilation_output_data;
613
size_t compilation_output_data_size_in_bytes = 0u;
614
if (!compiler->initializer) return result;
615
TRY_IF_EXCEPTIONS_ENABLED {
616
std::stringstream errors;
617
size_t total_warnings = 0;
618
size_t total_errors = 0;
619
std::string input_file_name_str(input_file_name);
620
EShLanguage forced_stage = GetForcedStage(shader_kind);
621
shaderc_util::string_piece source_string =
622
shaderc_util::string_piece(source_text, source_text + source_text_size);
623
StageDeducer stage_deducer(shader_kind);
624
if (additional_options) {
625
InternalFileIncluder includer(additional_options->include_resolver,
626
additional_options->include_result_releaser,
627
additional_options->include_user_data);
628
// Depends on return value optimization to avoid extra copy.
629
std::tie(compilation_succeeded, compilation_output_data,
630
compilation_output_data_size_in_bytes) =
631
additional_options->compiler.Compile(
632
source_string, forced_stage, input_file_name_str, entry_point_name,
633
// stage_deducer has a flag: error_, which we need to check later.
634
// We need to make this a reference wrapper, so that std::function
635
// won't make a copy for this callable object.
636
std::ref(stage_deducer), includer, output_type, &errors,
637
&total_warnings, &total_errors);
638
} else {
639
// Compile with default options.
640
InternalFileIncluder includer;
641
std::tie(compilation_succeeded, compilation_output_data,
642
compilation_output_data_size_in_bytes) =
643
shaderc_util::Compiler().Compile(
644
source_string, forced_stage, input_file_name_str, entry_point_name,
645
std::ref(stage_deducer), includer, output_type, &errors,
646
&total_warnings, &total_errors);
647
}
648
649
result->messages = errors.str();
650
result->SetOutputData(std::move(compilation_output_data));
651
result->output_data_size = compilation_output_data_size_in_bytes;
652
result->num_warnings = total_warnings;
653
result->num_errors = total_errors;
654
if (compilation_succeeded) {
655
result->compilation_status = shaderc_compilation_status_success;
656
} else {
657
// Check whether the error is caused by failing to deduce the shader
658
// stage. If it is the case, set the error type to shader kind error.
659
// Otherwise, set it to compilation error.
660
result->compilation_status =
661
stage_deducer.error() ? shaderc_compilation_status_invalid_stage
662
: shaderc_compilation_status_compilation_error;
663
}
664
}
665
CATCH_IF_EXCEPTIONS_ENABLED(...) {
666
result->compilation_status = shaderc_compilation_status_internal_error;
667
}
668
return result;
669
}
670
} // anonymous namespace
671
672
shaderc_compilation_result_t shaderc_compile_into_spv(
673
const shaderc_compiler_t compiler, const char* source_text,
674
size_t source_text_size, shaderc_shader_kind shader_kind,
675
const char* input_file_name, const char* entry_point_name,
676
const shaderc_compile_options_t additional_options) {
677
return CompileToSpecifiedOutputType(
678
compiler, source_text, source_text_size, shader_kind, input_file_name,
679
entry_point_name, additional_options,
680
shaderc_util::Compiler::OutputType::SpirvBinary);
681
}
682
683
shaderc_compilation_result_t shaderc_compile_into_spv_assembly(
684
const shaderc_compiler_t compiler, const char* source_text,
685
size_t source_text_size, shaderc_shader_kind shader_kind,
686
const char* input_file_name, const char* entry_point_name,
687
const shaderc_compile_options_t additional_options) {
688
return CompileToSpecifiedOutputType(
689
compiler, source_text, source_text_size, shader_kind, input_file_name,
690
entry_point_name, additional_options,
691
shaderc_util::Compiler::OutputType::SpirvAssemblyText);
692
}
693
694
shaderc_compilation_result_t shaderc_compile_into_preprocessed_text(
695
const shaderc_compiler_t compiler, const char* source_text,
696
size_t source_text_size, shaderc_shader_kind shader_kind,
697
const char* input_file_name, const char* entry_point_name,
698
const shaderc_compile_options_t additional_options) {
699
return CompileToSpecifiedOutputType(
700
compiler, source_text, source_text_size, shader_kind, input_file_name,
701
entry_point_name, additional_options,
702
shaderc_util::Compiler::OutputType::PreprocessedText);
703
}
704
705
shaderc_compilation_result_t shaderc_assemble_into_spv(
706
const shaderc_compiler_t compiler, const char* source_assembly,
707
size_t source_assembly_size,
708
const shaderc_compile_options_t additional_options) {
709
auto* result = new (std::nothrow) shaderc_compilation_result_spv_binary;
710
if (!result) return nullptr;
711
result->compilation_status = shaderc_compilation_status_invalid_assembly;
712
if (!compiler->initializer) return result;
713
if (source_assembly == nullptr) return result;
714
715
TRY_IF_EXCEPTIONS_ENABLED {
716
spv_binary assembling_output_data = nullptr;
717
std::string errors;
718
const auto target_env = additional_options ? additional_options->target_env
719
: shaderc_target_env_default;
720
const uint32_t target_env_version =
721
additional_options ? additional_options->target_env_version : 0;
722
const bool assembling_succeeded = shaderc_util::SpirvToolsAssemble(
723
GetCompilerTargetEnv(target_env),
724
GetCompilerTargetEnvVersion(target_env_version),
725
{source_assembly, source_assembly + source_assembly_size},
726
&assembling_output_data, &errors);
727
result->num_errors = !assembling_succeeded;
728
if (assembling_succeeded) {
729
result->SetOutputData(assembling_output_data);
730
result->output_data_size =
731
assembling_output_data->wordCount * sizeof(uint32_t);
732
result->compilation_status = shaderc_compilation_status_success;
733
} else {
734
result->messages = std::move(errors);
735
result->compilation_status = shaderc_compilation_status_invalid_assembly;
736
}
737
}
738
CATCH_IF_EXCEPTIONS_ENABLED(...) {
739
result->compilation_status = shaderc_compilation_status_internal_error;
740
}
741
742
return result;
743
}
744
745
size_t shaderc_result_get_length(const shaderc_compilation_result_t result) {
746
return result->output_data_size;
747
}
748
749
size_t shaderc_result_get_num_warnings(
750
const shaderc_compilation_result_t result) {
751
return result->num_warnings;
752
}
753
754
size_t shaderc_result_get_num_errors(
755
const shaderc_compilation_result_t result) {
756
return result->num_errors;
757
}
758
759
const char* shaderc_result_get_bytes(
760
const shaderc_compilation_result_t result) {
761
return result->GetBytes();
762
}
763
764
void shaderc_result_release(shaderc_compilation_result_t result) {
765
delete result;
766
}
767
768
const char* shaderc_result_get_error_message(
769
const shaderc_compilation_result_t result) {
770
return result->messages.c_str();
771
}
772
773
shaderc_compilation_status shaderc_result_get_compilation_status(
774
const shaderc_compilation_result_t result) {
775
return result->compilation_status;
776
}
777
778
void shaderc_get_spv_version(unsigned int* version, unsigned int* revision) {
779
*version = spv::Version;
780
*revision = spv::Revision;
781
}
782
783
bool shaderc_parse_version_profile(const char* str, int* version,
784
shaderc_profile* profile) {
785
EProfile glslang_profile;
786
bool success = shaderc_util::ParseVersionProfile(
787
std::string(str, strlen(str)), version, &glslang_profile);
788
if (!success) return false;
789
790
switch (glslang_profile) {
791
case EEsProfile:
792
*profile = shaderc_profile_es;
793
return true;
794
case ECoreProfile:
795
*profile = shaderc_profile_core;
796
return true;
797
case ECompatibilityProfile:
798
*profile = shaderc_profile_compatibility;
799
return true;
800
case ENoProfile:
801
*profile = shaderc_profile_none;
802
return true;
803
case EBadProfile:
804
case EProfileCount:
805
return false;
806
}
807
808
// Shouldn't reach here, all profile enum should be handled above.
809
// Be strict to return false.
810
return false;
811
}
812
813