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