1 // Copyright 2018 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 SHADERC_SPVC_HPP_ 16 #define SHADERC_SPVC_HPP_ 17 18 #include <functional> 19 #include <memory> 20 #include <string> 21 #include <vector> 22 23 #include "spvc.h" 24 25 namespace shaderc_spvc { 26 27 // A CompilationResult contains the compiler output, compilation status, 28 // and messages. 29 // 30 // The compiler output is stored as an array of elements and accessed 31 // via random access iterators provided by cbegin() and cend(). The iterators 32 // are contiguous in the sense of "Contiguous Iterators: A Refinement of 33 // Random Access Iterators", Nevin Liber, C++ Library Evolution Working 34 // Group Working Paper N3884. 35 // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3884.pdf 36 // 37 // Methods begin() and end() are also provided to enable range-based for. 38 // They are synonyms to cbegin() and cend(), respectively. 39 class CompilationResult { 40 public: 41 // Upon creation, the CompilationResult takes ownership of the 42 // shaderc_spvc_compilation_result instance. During destruction of the 43 // CompilationResult, the shaderc_spvc_compilation_result will be released. CompilationResult()44 explicit CompilationResult() 45 : result_(shaderc_spvc_result_create(), shaderc_spvc_result_destroy) {} ~CompilationResult()46 ~CompilationResult() {} 47 CompilationResult(CompilationResult && other)48 CompilationResult(CompilationResult&& other) 49 : result_(nullptr, shaderc_spvc_result_destroy) { 50 *this = std::move(other); 51 } 52 operator =(CompilationResult && other)53 CompilationResult& operator=(CompilationResult&& other) { 54 result_.reset(other.result_.release()); 55 return *this; 56 } 57 GetStringOutput(std::string * str) const58 shaderc_spvc_status GetStringOutput(std::string* str) const { 59 if (!str) return shaderc_spvc_status_invalid_out_param; 60 const char* inner_str; 61 shaderc_spvc_status status = 62 shaderc_spvc_result_get_string_output(result_.get(), &inner_str); 63 if (status != shaderc_spvc_status_success) { 64 return status; 65 } 66 *str = std::string(inner_str); 67 return shaderc_spvc_status_success; 68 } 69 GetBinaryOutput(std::vector<uint32_t> * data) const70 shaderc_spvc_status GetBinaryOutput(std::vector<uint32_t>* data) const { 71 if (!data) return shaderc_spvc_status_invalid_out_param; 72 const uint32_t* binary_output; 73 shaderc_spvc_status status = 74 shaderc_spvc_result_get_binary_output(result_.get(), &binary_output); 75 if (status != shaderc_spvc_status_success) { 76 return status; 77 } 78 uint32_t binary_length; 79 status = 80 shaderc_spvc_result_get_binary_length(result_.get(), &binary_length); 81 if (!binary_output || !binary_length) { 82 *data = std::vector<uint32_t>(); 83 } else { 84 *data = 85 std::vector<uint32_t>(binary_output, binary_output + binary_length); 86 } 87 return shaderc_spvc_status_success; 88 } 89 90 private: 91 friend class Context; 92 93 CompilationResult(const CompilationResult& other) = delete; 94 CompilationResult& operator=(const CompilationResult& other) = delete; 95 96 std::unique_ptr<shaderc_spvc_compilation_result, 97 void (*)(shaderc_spvc_compilation_result_t)> 98 result_; 99 }; 100 101 // Contains any options that can have default values for a compilation. 102 class CompileOptions { 103 public: CompileOptions(shaderc_spvc_spv_env source_env,shaderc_spvc_spv_env target_env)104 CompileOptions(shaderc_spvc_spv_env source_env, 105 shaderc_spvc_spv_env target_env) 106 : options_(shaderc_spvc_compile_options_create(source_env, target_env), 107 shaderc_spvc_compile_options_destroy) {} 108 // DEPRECATED CompileOptions()109 CompileOptions() 110 : CompileOptions(shaderc_spvc_spv_env_universal_1_0, 111 shaderc_spvc_spv_env_universal_1_0) {} CompileOptions(const CompileOptions & other)112 CompileOptions(const CompileOptions& other) 113 : options_(nullptr, shaderc_spvc_compile_options_destroy) { 114 options_.reset(shaderc_spvc_compile_options_clone(other.options_.get())); 115 } 116 CompileOptions(CompileOptions && other)117 CompileOptions(CompileOptions&& other) 118 : options_(nullptr, shaderc_spvc_compile_options_destroy) { 119 options_.reset(other.options_.release()); 120 } 121 122 // DEPRECATED 123 // Set the environment for the input SPIR-V. Default is Vulkan 1.0. SetSourceEnvironment(shaderc_target_env env,shaderc_env_version version)124 shaderc_spvc_status SetSourceEnvironment(shaderc_target_env env, 125 shaderc_env_version version) { 126 return shaderc_spvc_compile_options_set_source_env(options_.get(), env, 127 version); 128 } 129 130 // DEPRECATED 131 // Set the target environment for the SPIR-V to be cross-compiled. If this is 132 // different then the source a transformation will need to be applied. 133 // Currently only Vulkan 1.1 <-> WebGPU transforms are defined. Default is 134 // Vulkan 1.0. SetTargetEnvironment(shaderc_target_env env,shaderc_env_version version)135 shaderc_spvc_status SetTargetEnvironment(shaderc_target_env env, 136 shaderc_env_version version) { 137 return shaderc_spvc_compile_options_set_target_env(options_.get(), env, 138 version); 139 } 140 141 // Set the entry point. SetEntryPoint(const std::string & entry_point)142 shaderc_spvc_status SetEntryPoint(const std::string& entry_point) { 143 return shaderc_spvc_compile_options_set_entry_point(options_.get(), 144 entry_point.c_str()); 145 } 146 147 // If true, unused variables will not appear in the output. SetRemoveUnusedVariables(bool b)148 shaderc_spvc_status SetRemoveUnusedVariables(bool b) { 149 return shaderc_spvc_compile_options_set_remove_unused_variables( 150 options_.get(), b); 151 } 152 153 // If true, enable robust buffer access pass in the spirv-opt, meaning: 154 // Inject code to clamp indexed accesses to buffers and internal 155 // arrays, providing guarantees satisfying Vulkan's robustBufferAccess rules. 156 // This is useful when an implementation does not support robust-buffer access 157 // as a driver option. SetRobustBufferAccessPass(bool b)158 shaderc_spvc_status SetRobustBufferAccessPass(bool b) { 159 return shaderc_spvc_compile_options_set_robust_buffer_access_pass( 160 options_.get(), b); 161 } 162 SetEmitLineDirectives(bool b)163 shaderc_spvc_status SetEmitLineDirectives(bool b) { 164 return shaderc_spvc_compile_options_set_emit_line_directives(options_.get(), 165 b); 166 } 167 // If true, Vulkan GLSL features are used instead of GL-compatible features. SetVulkanSemantics(bool b)168 shaderc_spvc_status SetVulkanSemantics(bool b) { 169 return shaderc_spvc_compile_options_set_vulkan_semantics(options_.get(), b); 170 } 171 172 // If true, gl_PerVertex is explicitly redeclared in vertex, geometry and 173 // tessellation shaders. The members of gl_PerVertex is determined by which 174 // built-ins are declared by the shader. SetSeparateShaderObjects(bool b)175 shaderc_spvc_status SetSeparateShaderObjects(bool b) { 176 return shaderc_spvc_compile_options_set_separate_shader_objects( 177 options_.get(), b); 178 } 179 180 // Flatten uniform or push constant variable into (i|u)vec4 array. SetFlattenUbo(bool b)181 shaderc_spvc_status SetFlattenUbo(bool b) { 182 return shaderc_spvc_compile_options_set_flatten_ubo(options_.get(), b); 183 } 184 185 // Which GLSL version should be produced. Default is 450 (i.e. 4.5). SetGLSLLanguageVersion(uint32_t version)186 shaderc_spvc_status SetGLSLLanguageVersion(uint32_t version) { 187 return shaderc_spvc_compile_options_set_glsl_language_version( 188 options_.get(), version); 189 } 190 191 // If true, flatten multidimensional arrays, e.g. foo[a][b][c] -> foo[a*b*c]. 192 // Default is false. SetFlattenMultidimensionalArrays(bool b)193 shaderc_spvc_status SetFlattenMultidimensionalArrays(bool b) { 194 return shaderc_spvc_compile_options_set_flatten_multidimensional_arrays( 195 options_.get(), b); 196 } 197 198 // If true, initialize new variables from cross-compile to 0 if possible. 199 // Default is false. SetForceZeroInitializedVariables(bool b)200 shaderc_spvc_status SetForceZeroInitializedVariables(bool b) { 201 return shaderc_spvc_compile_options_set_force_zero_initialized_variables( 202 options_.get(), b); 203 } 204 205 // Force interpretion as ES, or not. Default is to detect from source. SetES(bool b)206 shaderc_spvc_status SetES(bool b) { 207 return shaderc_spvc_compile_options_set_es(options_.get(), b); 208 } 209 210 // If true, emit push constants as uniform buffer objects. Default is false. SetGLSLEmitPushConstantAsUBO(bool b)211 shaderc_spvc_status SetGLSLEmitPushConstantAsUBO(bool b) { 212 return shaderc_spvc_compile_options_set_glsl_emit_push_constant_as_ubo( 213 options_.get(), b); 214 } 215 216 // Which MSL version should be produced. Default is 10200 (i.e. 1.2). SetMSLLanguageVersion(uint32_t version)217 shaderc_spvc_status SetMSLLanguageVersion(uint32_t version) { 218 return shaderc_spvc_compile_options_set_msl_language_version(options_.get(), 219 version); 220 } 221 222 // If true, swizzle MSL texture samples. Default is false. SetMSLSwizzleTextureSamples(bool b)223 shaderc_spvc_status SetMSLSwizzleTextureSamples(bool b) { 224 return shaderc_spvc_compile_options_set_msl_swizzle_texture_samples( 225 options_.get(), b); 226 } 227 228 // Choose MSL platform. Default is MacOS. SetMSLPlatform(shaderc_spvc_msl_platform platform)229 shaderc_spvc_status SetMSLPlatform(shaderc_spvc_msl_platform platform) { 230 return shaderc_spvc_compile_options_set_msl_platform(options_.get(), 231 platform); 232 } 233 234 // If true, pad MSL fragment output. Default is false. SetMSLPadFragmentOutput(bool b)235 shaderc_spvc_status SetMSLPadFragmentOutput(bool b) { 236 return shaderc_spvc_compile_options_set_msl_pad_fragment_output( 237 options_.get(), b); 238 } 239 240 // If true, capture MSL output to buffer. Default is false. SetMSLCapture(bool b)241 shaderc_spvc_status SetMSLCapture(bool b) { 242 return shaderc_spvc_compile_options_set_msl_capture(options_.get(), b); 243 } 244 245 // If true, flip the Y-coord of the built-in "TessCoord." Default is top 246 // left. SetMSLDomainLowerLeft(bool b)247 shaderc_spvc_status SetMSLDomainLowerLeft(bool b) { 248 return shaderc_spvc_compile_options_set_msl_domain_lower_left( 249 options_.get(), b); 250 } 251 252 // Enable use of MSL 2.0 indirect argument buffers. Default is not to use 253 // them. SetMSLArgumentBuffers(bool b)254 shaderc_spvc_status SetMSLArgumentBuffers(bool b) { 255 return shaderc_spvc_compile_options_set_msl_argument_buffers(options_.get(), 256 b); 257 } 258 259 // When using MSL argument buffers, force "classic" MSL 1.0 binding for the 260 // given descriptor sets. This corresponds to VK_KHR_push_descriptor in 261 // Vulkan. SetMSLDiscreteDescriptorSets(const std::vector<uint32_t> descriptors)262 shaderc_spvc_status SetMSLDiscreteDescriptorSets( 263 const std::vector<uint32_t> descriptors) { 264 return shaderc_spvc_compile_options_set_msl_discrete_descriptor_sets( 265 options_.get(), descriptors.data(), descriptors.size()); 266 } 267 268 // Set whether or not PointSize builtin is used for MSL shaders SetMSLEnablePointSizeBuiltIn(bool b)269 shaderc_spvc_status SetMSLEnablePointSizeBuiltIn(bool b) { 270 return shaderc_spvc_compile_options_set_msl_enable_point_size_builtin( 271 options_.get(), b); 272 } 273 274 // Set the index in the buffer size in the buffer for MSL SetMSLBufferSizeBufferIndex(uint32_t index)275 shaderc_spvc_status SetMSLBufferSizeBufferIndex(uint32_t index) { 276 return shaderc_spvc_compile_options_set_msl_buffer_size_buffer_index( 277 options_.get(), index); 278 } 279 280 // Which HLSL shader model should be used. Default is 30. SetHLSLShaderModel(uint32_t model)281 shaderc_spvc_status SetHLSLShaderModel(uint32_t model) { 282 return shaderc_spvc_compile_options_set_hlsl_shader_model(options_.get(), 283 model); 284 } 285 286 // If true, ignore PointSize. Default is false. SetHLSLPointSizeCompat(bool b)287 shaderc_spvc_status SetHLSLPointSizeCompat(bool b) { 288 return shaderc_spvc_compile_options_set_hlsl_point_size_compat( 289 options_.get(), b); 290 } 291 292 // If true, ignore PointCoord. Default is false. SetHLSLPointCoordCompat(bool b)293 shaderc_spvc_status SetHLSLPointCoordCompat(bool b) { 294 return shaderc_spvc_compile_options_set_hlsl_point_coord_compat( 295 options_.get(), b); 296 } 297 298 // If true (default is false): 299 // GLSL: map depth from Vulkan/D3D style to GL style, i.e. [ 0,w] -> [-w,w] 300 // MSL : map depth from GL style to Vulkan/D3D style, i.e. [-w,w] -> [ 0,w] 301 // HLSL: map depth from GL style to Vulkan/D3D style, i.e. [-w,w] -> [ 0,w] SetFixupClipspace(bool b)302 shaderc_spvc_status SetFixupClipspace(bool b) { 303 return shaderc_spvc_compile_options_set_fixup_clipspace(options_.get(), b); 304 } 305 306 // If true invert gl_Position.y or equivalent. Default is false. SetFlipVertY(bool b)307 shaderc_spvc_status SetFlipVertY(bool b) { 308 return shaderc_spvc_compile_options_set_flip_vert_y(options_.get(), b); 309 } 310 311 // If true validate input and intermediate source. Default is true. SetValidate(bool b)312 shaderc_spvc_status SetValidate(bool b) { 313 return shaderc_spvc_compile_options_set_validate(options_.get(), b); 314 } 315 316 // If true optimize input and intermediate source. Default is true. SetOptimize(bool b)317 shaderc_spvc_status SetOptimize(bool b) { 318 return shaderc_spvc_compile_options_set_optimize(options_.get(), b); 319 } 320 321 // Fill options with given data. Return amount of data used, or zero 322 // if not enough data was given. SetForFuzzing(const uint8_t * data,size_t size)323 size_t SetForFuzzing(const uint8_t* data, size_t size) { 324 return shaderc_spvc_compile_options_set_for_fuzzing(options_.get(), data, 325 size); 326 } 327 328 private: 329 CompileOptions& operator=(const CompileOptions& other) = delete; 330 std::unique_ptr<shaderc_spvc_compile_options, 331 void (*)(shaderc_spvc_compile_options_t)> 332 options_; 333 334 friend class Context; 335 }; 336 337 // The compilation context for compiling SPIR-V. 338 class Context { 339 public: Context()340 Context() 341 : context_(shaderc_spvc_context_create(), shaderc_spvc_context_destroy) {} 342 Context(Context && other)343 Context(Context&& other) : context_(nullptr, shaderc_spvc_context_destroy) { 344 context_.reset(other.context_.release()); 345 } 346 IsValid() const347 bool IsValid() const { return context_ != nullptr; } 348 349 // Returns logged messages from operations GetMessages() const350 const std::string GetMessages() const { 351 return shaderc_spvc_context_get_messages(context_.get()); 352 } 353 354 // EXPERIMENTAL 355 // Returns the internal spirv_cross compiler reference, does NOT transfer 356 // ownership. 357 // This is being exposed temporarily to ease integration of spvc into Dawn, 358 // but this is will be removed in the future without warning. GetCompiler(void ** compiler)359 shaderc_spvc_status GetCompiler(void** compiler) { 360 return shaderc_spvc_context_get_compiler(context_.get(), compiler); 361 } 362 SetUseSpvcParser(bool b)363 shaderc_spvc_status SetUseSpvcParser(bool b) { 364 return shaderc_spvc_context_set_use_spvc_parser(context_.get(), b); 365 } 366 367 // Initializes state for compiling SPIR-V to GLSL. InitializeForGlsl(const uint32_t * source,size_t source_len,const CompileOptions & options) const368 shaderc_spvc_status InitializeForGlsl(const uint32_t* source, 369 size_t source_len, 370 const CompileOptions& options) const { 371 return shaderc_spvc_initialize_for_glsl(context_.get(), source, source_len, 372 options.options_.get()); 373 } 374 375 // Initializes state for compiling SPIR-V to HLSL. InitializeForHlsl(const uint32_t * source,size_t source_len,const CompileOptions & options) const376 shaderc_spvc_status InitializeForHlsl(const uint32_t* source, 377 size_t source_len, 378 const CompileOptions& options) const { 379 return shaderc_spvc_initialize_for_hlsl(context_.get(), source, source_len, 380 options.options_.get()); 381 } 382 383 // Initializes state for compiling SPIR-V to MSL. InitializeForMsl(const uint32_t * source,size_t source_len,const CompileOptions & options) const384 shaderc_spvc_status InitializeForMsl(const uint32_t* source, 385 size_t source_len, 386 const CompileOptions& options) const { 387 return shaderc_spvc_initialize_for_msl(context_.get(), source, source_len, 388 options.options_.get()); 389 } 390 391 // Initializes state for compiling SPIR-V to Vulkan. InitializeForVulkan(const uint32_t * source,size_t source_len,const CompileOptions & options) const392 shaderc_spvc_status InitializeForVulkan(const uint32_t* source, 393 size_t source_len, 394 const CompileOptions& options) const { 395 return shaderc_spvc_initialize_for_vulkan( 396 context_.get(), source, source_len, options.options_.get()); 397 } 398 399 // After initialization compile the shader to desired language. CompileShader(CompilationResult * result)400 shaderc_spvc_status CompileShader(CompilationResult* result) { 401 return shaderc_spvc_compile_shader(context_.get(), result->result_.get()); 402 } 403 404 // Set spirv_cross decoration (added for HLSL support in Dawn) 405 // Given an id, decoration and argument, the decoration flag on the id is set, 406 // assuming id is valid. SetDecoration(uint32_t id,shaderc_spvc_decoration decoration,uint32_t argument)407 shaderc_spvc_status SetDecoration(uint32_t id, 408 shaderc_spvc_decoration decoration, 409 uint32_t argument) { 410 return shaderc_spvc_set_decoration(context_.get(), id, decoration, argument); 411 } 412 413 // Get spirv_cross decoration (added for GLSL API support in Dawn). 414 // Given an id and a decoration, result is sent out through |argument| 415 // if |id| does not exist, returns an error. GetDecoration(uint32_t id,shaderc_spvc_decoration decoration,uint32_t * argument)416 shaderc_spvc_status GetDecoration(uint32_t id, 417 shaderc_spvc_decoration decoration, 418 uint32_t* argument) { 419 return shaderc_spvc_get_decoration(context_.get(), id, decoration, argument); 420 } 421 422 // Unset spirv_cross decoration (added for GLSL API support in Dawn). 423 // Given an id and a decoration. Assuming id is valid. UnsetDecoration(uint32_t id,shaderc_spvc_decoration decoration)424 shaderc_spvc_status UnsetDecoration(uint32_t id, 425 shaderc_spvc_decoration decoration) { 426 return shaderc_spvc_unset_decoration(context_.get(), id, decoration); 427 } 428 429 // spirv-cross comment: 430 // Analyzes all separate image and samplers used from the currently selected 431 // entry point, and re-routes them all to a combined image sampler instead. 432 // (added for GLSL API support in Dawn) BuildCombinedImageSamplers(void)433 shaderc_spvc_status BuildCombinedImageSamplers(void) { 434 return shaderc_spvc_build_combined_image_samplers(context_.get()); 435 } 436 437 // After call to BuildCombinedImageSamplers, fetch the ids associated with the 438 // combined image samplers. GetCombinedImageSamplers(std::vector<shaderc_spvc_combined_image_sampler> * samplers)439 shaderc_spvc_status GetCombinedImageSamplers( 440 std::vector<shaderc_spvc_combined_image_sampler>* samplers) { 441 size_t count; 442 shaderc_spvc_status status = shaderc_spvc_get_combined_image_samplers( 443 context_.get(), nullptr, &count); 444 if (status != shaderc_spvc_status_success) return status; 445 samplers->resize(count); 446 return shaderc_spvc_get_combined_image_samplers(context_.get(), 447 samplers->data(), &count); 448 } 449 450 // set |name| on a given |id| (added for GLSL support in Dawn). 451 // Assuming id is valid. SetName(uint32_t id,const std::string & name)452 shaderc_spvc_status SetName(uint32_t id, const std::string& name) { 453 return shaderc_spvc_set_name(context_.get(), id, name.c_str()); 454 } 455 456 // Adds a binding to indicate the MSL buffer, texture or sampler index to use 457 // for a particular SPIR-V description set and binding. AddMSLResourceBinding(const shaderc_spvc_msl_resource_binding binding)458 shaderc_spvc_status AddMSLResourceBinding( 459 const shaderc_spvc_msl_resource_binding binding) { 460 return shaderc_spvc_add_msl_resource_binding(context_.get(), binding); 461 } 462 463 // Gets workgroup size for an entry point defined by a given execution model 464 // and function name. GetWorkgroupSize(const std::string & function_name,shaderc_spvc_execution_model execution_model,shaderc_spvc_workgroup_size * workgroup_size)465 shaderc_spvc_status GetWorkgroupSize( 466 const std::string& function_name, 467 shaderc_spvc_execution_model execution_model, 468 shaderc_spvc_workgroup_size* workgroup_size) { 469 return shaderc_spvc_get_workgroup_size( 470 context_.get(), function_name.c_str(), execution_model, workgroup_size); 471 } 472 473 // Gets whether or not the shader needes a buffer of buffer sizes. NeedsBufferSizeBuffer(bool * b)474 shaderc_spvc_status NeedsBufferSizeBuffer(bool* b) { 475 return shaderc_spvc_needs_buffer_size_buffer(context_.get(), b); 476 } 477 478 // Gets the execution model for the shader. GetExecutionModel(shaderc_spvc_execution_model * model)479 shaderc_spvc_status GetExecutionModel(shaderc_spvc_execution_model* model) { 480 return shaderc_spvc_get_execution_model(context_.get(), model); 481 } 482 483 // Gets the number of push constant buffers used by the shader. GetPushConstantBufferCount(size_t * count)484 shaderc_spvc_status GetPushConstantBufferCount(size_t* count) { 485 return shaderc_spvc_get_push_constant_buffer_count(context_.get(), count); 486 } 487 488 // Gets all of the binding info for a given shader resource. GetBindingInfo(shaderc_spvc_shader_resource resource,shaderc_spvc_binding_type binding_type,std::vector<shaderc_spvc_binding_info> * bindings)489 shaderc_spvc_status GetBindingInfo( 490 shaderc_spvc_shader_resource resource, 491 shaderc_spvc_binding_type binding_type, 492 std::vector<shaderc_spvc_binding_info>* bindings) { 493 if (!bindings) { 494 return shaderc_spvc_status_invalid_out_param; 495 } 496 497 size_t binding_count; 498 shaderc_spvc_status status = shaderc_spvc_get_binding_info( 499 context_.get(), resource, binding_type, nullptr, &binding_count); 500 if (status != shaderc_spvc_status_success) { 501 return status; 502 } 503 504 bindings->resize(binding_count); 505 return shaderc_spvc_get_binding_info(context_.get(), resource, binding_type, 506 bindings->data(), &binding_count); 507 } 508 509 // Gets the Location decoration information for the stage inputs. GetInputStageLocationInfo(std::vector<shaderc_spvc_resource_location_info> * locations)510 shaderc_spvc_status GetInputStageLocationInfo( 511 std::vector<shaderc_spvc_resource_location_info>* locations) { 512 if (!locations) { 513 return shaderc_spvc_status_invalid_out_param; 514 } 515 516 size_t location_count; 517 shaderc_spvc_status status = shaderc_spvc_get_input_stage_location_info( 518 context_.get(), nullptr, &location_count); 519 if (status != shaderc_spvc_status_success) { 520 return status; 521 } 522 523 locations->resize(location_count); 524 return shaderc_spvc_get_input_stage_location_info( 525 context_.get(), locations->data(), &location_count); 526 } 527 528 // Gets the Location decoration information for the stage output. GetOutputStageLocationInfo(std::vector<shaderc_spvc_resource_location_info> * locations)529 shaderc_spvc_status GetOutputStageLocationInfo( 530 std::vector<shaderc_spvc_resource_location_info>* locations) { 531 if (!locations) { 532 return shaderc_spvc_status_invalid_out_param; 533 } 534 535 size_t location_count; 536 shaderc_spvc_status status = shaderc_spvc_get_output_stage_location_info( 537 context_.get(), nullptr, &location_count); 538 if (status != shaderc_spvc_status_success) { 539 return status; 540 } 541 542 locations->resize(location_count); 543 return shaderc_spvc_get_output_stage_location_info( 544 context_.get(), locations->data(), &location_count); 545 } 546 547 // Gets the type information for the stage output. GetOutputStageTypeInfo(std::vector<shaderc_spvc_resource_type_info> * types)548 shaderc_spvc_status GetOutputStageTypeInfo( 549 std::vector<shaderc_spvc_resource_type_info>* types) { 550 if (!types) { 551 return shaderc_spvc_status_invalid_out_param; 552 } 553 554 size_t type_count; 555 shaderc_spvc_status status = shaderc_spvc_get_output_stage_type_info( 556 context_.get(), nullptr, &type_count); 557 if (status != shaderc_spvc_status_success) { 558 return status; 559 } 560 561 types->resize(type_count); 562 return shaderc_spvc_get_output_stage_type_info(context_.get(), 563 types->data(), &type_count); 564 } 565 566 private: 567 Context(const Context&) = delete; 568 Context& operator=(const Context& other) = delete; 569 570 std::unique_ptr<shaderc_spvc_context, void (*)(shaderc_spvc_context_t)> 571 context_; 572 }; 573 574 } // namespace shaderc_spvc 575 576 #endif // SHADERC_SPVC_HPP_ 577