|  | // Copyright (c) 2016 Google Inc. | 
|  | // | 
|  | // Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | // you may not use this file except in compliance with the License. | 
|  | // You may obtain a copy of the License at | 
|  | // | 
|  | //     http://www.apache.org/licenses/LICENSE-2.0 | 
|  | // | 
|  | // Unless required by applicable law or agreed to in writing, software | 
|  | // distributed under the License is distributed on an "AS IS" BASIS, | 
|  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | // See the License for the specific language governing permissions and | 
|  | // limitations under the License. | 
|  |  | 
|  | #ifndef INCLUDE_SPIRV_TOOLS_LIBSPIRV_HPP_ | 
|  | #define INCLUDE_SPIRV_TOOLS_LIBSPIRV_HPP_ | 
|  |  | 
|  | #include <functional> | 
|  | #include <memory> | 
|  | #include <string> | 
|  | #include <vector> | 
|  |  | 
|  | #include "spirv-tools/libspirv.h" | 
|  |  | 
|  | namespace spvtools { | 
|  |  | 
|  | // Message consumer. The C strings for source and message are only alive for the | 
|  | // specific invocation. | 
|  | using MessageConsumer = std::function<void( | 
|  | spv_message_level_t /* level */, const char* /* source */, | 
|  | const spv_position_t& /* position */, const char* /* message */ | 
|  | )>; | 
|  |  | 
|  | // C++ RAII wrapper around the C context object spv_context. | 
|  | class Context { | 
|  | public: | 
|  | // Constructs a context targeting the given environment |env|. | 
|  | // | 
|  | // The constructed instance will have an empty message consumer, which just | 
|  | // ignores all messages from the library. Use SetMessageConsumer() to supply | 
|  | // one if messages are of concern. | 
|  | explicit Context(spv_target_env env); | 
|  |  | 
|  | // Enables move constructor/assignment operations. | 
|  | Context(Context&& other); | 
|  | Context& operator=(Context&& other); | 
|  |  | 
|  | // Disables copy constructor/assignment operations. | 
|  | Context(const Context&) = delete; | 
|  | Context& operator=(const Context&) = delete; | 
|  |  | 
|  | // Destructs this instance. | 
|  | ~Context(); | 
|  |  | 
|  | // Sets the message consumer to the given |consumer|. The |consumer| will be | 
|  | // invoked once for each message communicated from the library. | 
|  | void SetMessageConsumer(MessageConsumer consumer); | 
|  |  | 
|  | // Returns the underlying spv_context. | 
|  | spv_context& CContext(); | 
|  | const spv_context& CContext() const; | 
|  |  | 
|  | private: | 
|  | spv_context context_; | 
|  | }; | 
|  |  | 
|  | // A RAII wrapper around a validator options object. | 
|  | class ValidatorOptions { | 
|  | public: | 
|  | ValidatorOptions() : options_(spvValidatorOptionsCreate()) {} | 
|  | ~ValidatorOptions() { spvValidatorOptionsDestroy(options_); } | 
|  | // Allow implicit conversion to the underlying object. | 
|  | operator spv_validator_options() const { return options_; } | 
|  |  | 
|  | // Sets a limit. | 
|  | void SetUniversalLimit(spv_validator_limit limit_type, uint32_t limit) { | 
|  | spvValidatorOptionsSetUniversalLimit(options_, limit_type, limit); | 
|  | } | 
|  |  | 
|  | void SetRelaxStructStore(bool val) { | 
|  | spvValidatorOptionsSetRelaxStoreStruct(options_, val); | 
|  | } | 
|  |  | 
|  | // Enables VK_KHR_relaxed_block_layout when validating standard | 
|  | // uniform/storage buffer/push-constant layout.  If true, disables | 
|  | // scalar block layout rules. | 
|  | void SetRelaxBlockLayout(bool val) { | 
|  | spvValidatorOptionsSetRelaxBlockLayout(options_, val); | 
|  | } | 
|  |  | 
|  | // Enables VK_EXT_scalar_block_layout when validating standard | 
|  | // uniform/storage buffer/push-constant layout.  If true, disables | 
|  | // relaxed block layout rules. | 
|  | void SetScalarBlockLayout(bool val) { | 
|  | spvValidatorOptionsSetScalarBlockLayout(options_, val); | 
|  | } | 
|  |  | 
|  | // Skips validating standard uniform/storage buffer/push-constant layout. | 
|  | void SetSkipBlockLayout(bool val) { | 
|  | spvValidatorOptionsSetSkipBlockLayout(options_, val); | 
|  | } | 
|  |  | 
|  | // Records whether or not the validator should relax the rules on pointer | 
|  | // usage in logical addressing mode. | 
|  | // | 
|  | // When relaxed, it will allow the following usage cases of pointers: | 
|  | // 1) OpVariable allocating an object whose type is a pointer type | 
|  | // 2) OpReturnValue returning a pointer value | 
|  | void SetRelaxLogicalPointer(bool val) { | 
|  | spvValidatorOptionsSetRelaxLogicalPointer(options_, val); | 
|  | } | 
|  |  | 
|  | private: | 
|  | spv_validator_options options_; | 
|  | }; | 
|  |  | 
|  | // A C++ wrapper around an optimization options object. | 
|  | class OptimizerOptions { | 
|  | public: | 
|  | OptimizerOptions() : options_(spvOptimizerOptionsCreate()) {} | 
|  | ~OptimizerOptions() { spvOptimizerOptionsDestroy(options_); } | 
|  |  | 
|  | // Allow implicit conversion to the underlying object. | 
|  | operator spv_optimizer_options() const { return options_; } | 
|  |  | 
|  | // Records whether or not the optimizer should run the validator before | 
|  | // optimizing.  If |run| is true, the validator will be run. | 
|  | void set_run_validator(bool run) { | 
|  | spvOptimizerOptionsSetRunValidator(options_, run); | 
|  | } | 
|  |  | 
|  | // Records the validator options that should be passed to the validator if it | 
|  | // is run. | 
|  | void set_validator_options(const ValidatorOptions& val_options) { | 
|  | spvOptimizerOptionsSetValidatorOptions(options_, val_options); | 
|  | } | 
|  |  | 
|  | // Records the maximum possible value for the id bound. | 
|  | void set_max_id_bound(uint32_t new_bound) { | 
|  | spvOptimizerOptionsSetMaxIdBound(options_, new_bound); | 
|  | } | 
|  |  | 
|  | private: | 
|  | spv_optimizer_options options_; | 
|  | }; | 
|  |  | 
|  | // A C++ wrapper around a reducer options object. | 
|  | class ReducerOptions { | 
|  | public: | 
|  | ReducerOptions() : options_(spvReducerOptionsCreate()) {} | 
|  | ~ReducerOptions() { spvReducerOptionsDestroy(options_); } | 
|  |  | 
|  | // Allow implicit conversion to the underlying object. | 
|  | operator spv_reducer_options() const { return options_; } | 
|  |  | 
|  | // Records the maximum number of reduction steps that should | 
|  | // run before the reducer gives up. | 
|  | void set_step_limit(uint32_t step_limit) { | 
|  | spvReducerOptionsSetStepLimit(options_, step_limit); | 
|  | } | 
|  |  | 
|  | // Sets a seed to be used for random number generation. | 
|  | void set_seed(uint32_t seed) { spvReducerOptionsSetSeed(options_, seed); } | 
|  |  | 
|  | private: | 
|  | spv_reducer_options options_; | 
|  | }; | 
|  |  | 
|  | // C++ interface for SPIRV-Tools functionalities. It wraps the context | 
|  | // (including target environment and the corresponding SPIR-V grammar) and | 
|  | // provides methods for assembling, disassembling, and validating. | 
|  | // | 
|  | // Instances of this class provide basic thread-safety guarantee. | 
|  | class SpirvTools { | 
|  | public: | 
|  | enum { | 
|  | // Default assembling option used by assemble(): | 
|  | kDefaultAssembleOption = SPV_TEXT_TO_BINARY_OPTION_NONE, | 
|  |  | 
|  | // Default disassembling option used by Disassemble(): | 
|  | // * Avoid prefix comments from decoding the SPIR-V module header, and | 
|  | // * Use friendly names for variables. | 
|  | kDefaultDisassembleOption = SPV_BINARY_TO_TEXT_OPTION_NO_HEADER | | 
|  | SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES | 
|  | }; | 
|  |  | 
|  | // Constructs an instance targeting the given environment |env|. | 
|  | // | 
|  | // The constructed instance will have an empty message consumer, which just | 
|  | // ignores all messages from the library. Use SetMessageConsumer() to supply | 
|  | // one if messages are of concern. | 
|  | explicit SpirvTools(spv_target_env env); | 
|  |  | 
|  | // Disables copy/move constructor/assignment operations. | 
|  | SpirvTools(const SpirvTools&) = delete; | 
|  | SpirvTools(SpirvTools&&) = delete; | 
|  | SpirvTools& operator=(const SpirvTools&) = delete; | 
|  | SpirvTools& operator=(SpirvTools&&) = delete; | 
|  |  | 
|  | // Destructs this instance. | 
|  | ~SpirvTools(); | 
|  |  | 
|  | // Sets the message consumer to the given |consumer|. The |consumer| will be | 
|  | // invoked once for each message communicated from the library. | 
|  | void SetMessageConsumer(MessageConsumer consumer); | 
|  |  | 
|  | // Assembles the given assembly |text| and writes the result to |binary|. | 
|  | // Returns true on successful assembling. |binary| will be kept untouched if | 
|  | // assembling is unsuccessful. | 
|  | bool Assemble(const std::string& text, std::vector<uint32_t>* binary, | 
|  | uint32_t options = kDefaultAssembleOption) const; | 
|  | // |text_size| specifies the number of bytes in |text|. A terminating null | 
|  | // character is not required to present in |text| as long as |text| is valid. | 
|  | bool Assemble(const char* text, size_t text_size, | 
|  | std::vector<uint32_t>* binary, | 
|  | uint32_t options = kDefaultAssembleOption) const; | 
|  |  | 
|  | // Disassembles the given SPIR-V |binary| with the given |options| and writes | 
|  | // the assembly to |text|. Returns ture on successful disassembling. |text| | 
|  | // will be kept untouched if diassembling is unsuccessful. | 
|  | bool Disassemble(const std::vector<uint32_t>& binary, std::string* text, | 
|  | uint32_t options = kDefaultDisassembleOption) const; | 
|  | // |binary_size| specifies the number of words in |binary|. | 
|  | bool Disassemble(const uint32_t* binary, size_t binary_size, | 
|  | std::string* text, | 
|  | uint32_t options = kDefaultDisassembleOption) const; | 
|  |  | 
|  | // Validates the given SPIR-V |binary|. Returns true if no issues are found. | 
|  | // Otherwise, returns false and communicates issues via the message consumer | 
|  | // registered. | 
|  | bool Validate(const std::vector<uint32_t>& binary) const; | 
|  | // |binary_size| specifies the number of words in |binary|. | 
|  | bool Validate(const uint32_t* binary, size_t binary_size) const; | 
|  | // Like the previous overload, but takes an options object. | 
|  | bool Validate(const uint32_t* binary, size_t binary_size, | 
|  | spv_validator_options options) const; | 
|  |  | 
|  | private: | 
|  | struct Impl;  // Opaque struct for holding the data fields used by this class. | 
|  | std::unique_ptr<Impl> impl_;  // Unique pointer to implementation data. | 
|  | }; | 
|  |  | 
|  | }  // namespace spvtools | 
|  |  | 
|  | #endif  // INCLUDE_SPIRV_TOOLS_LIBSPIRV_HPP_ |