summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/SPIRV-Cross/spirv_cross_parsed_ir.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/SPIRV-Cross/spirv_cross_parsed_ir.hpp')
-rw-r--r--src/3rdparty/SPIRV-Cross/spirv_cross_parsed_ir.hpp186
1 files changed, 186 insertions, 0 deletions
diff --git a/src/3rdparty/SPIRV-Cross/spirv_cross_parsed_ir.hpp b/src/3rdparty/SPIRV-Cross/spirv_cross_parsed_ir.hpp
new file mode 100644
index 0000000..c3c4612
--- /dev/null
+++ b/src/3rdparty/SPIRV-Cross/spirv_cross_parsed_ir.hpp
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2018-2019 Arm Limited
+ *
+ * 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 SPIRV_CROSS_PARSED_IR_HPP
+#define SPIRV_CROSS_PARSED_IR_HPP
+
+#include "spirv_common.hpp"
+#include <stdint.h>
+#include <unordered_map>
+#include <vector>
+
+namespace spirv_cross
+{
+
+// This data structure holds all information needed to perform cross-compilation and reflection.
+// It is the output of the Parser, but any implementation could create this structure.
+// It is intentionally very "open" and struct-like with some helper functions to deal with decorations.
+// Parser is the reference implementation of how this data structure should be filled in.
+
+class ParsedIR
+{
+public:
+ // Resizes ids, meta and block_meta.
+ void set_id_bounds(uint32_t bounds);
+
+ // The raw SPIR-V, instructions and opcodes refer to this by offset + count.
+ std::vector<uint32_t> spirv;
+
+ // Holds various data structures which inherit from IVariant.
+ std::vector<Variant> ids;
+
+ // Various meta data for IDs, decorations, names, etc.
+ std::unordered_map<uint32_t, Meta> meta;
+
+ // Holds all IDs which have a certain type.
+ // This is needed so we can iterate through a specific kind of resource quickly,
+ // and in-order of module declaration.
+ std::vector<uint32_t> ids_for_type[TypeCount];
+
+ // Special purpose lists which contain a union of types.
+ // This is needed so we can declare specialization constants and structs in an interleaved fashion,
+ // among other things.
+ // Constants can be of struct type, and struct array sizes can use specialization constants.
+ std::vector<uint32_t> ids_for_constant_or_type;
+ std::vector<uint32_t> ids_for_constant_or_variable;
+
+ // Declared capabilities and extensions in the SPIR-V module.
+ // Not really used except for reflection at the moment.
+ std::vector<spv::Capability> declared_capabilities;
+ std::vector<std::string> declared_extensions;
+
+ // Meta data about blocks. The cross-compiler needs to query if a block is either of these types.
+ // It is a bitset as there can be more than one tag per block.
+ enum BlockMetaFlagBits
+ {
+ BLOCK_META_LOOP_HEADER_BIT = 1 << 0,
+ BLOCK_META_CONTINUE_BIT = 1 << 1,
+ BLOCK_META_LOOP_MERGE_BIT = 1 << 2,
+ BLOCK_META_SELECTION_MERGE_BIT = 1 << 3,
+ BLOCK_META_MULTISELECT_MERGE_BIT = 1 << 4
+ };
+ using BlockMetaFlags = uint8_t;
+ std::vector<BlockMetaFlags> block_meta;
+ std::unordered_map<uint32_t, uint32_t> continue_block_to_loop_header;
+
+ // Normally, we'd stick SPIREntryPoint in ids array, but it conflicts with SPIRFunction.
+ // Entry points can therefore be seen as some sort of meta structure.
+ std::unordered_map<uint32_t, SPIREntryPoint> entry_points;
+ uint32_t default_entry_point = 0;
+
+ struct Source
+ {
+ uint32_t version = 0;
+ bool es = false;
+ bool known = false;
+ bool hlsl = false;
+
+ Source() = default;
+ };
+
+ Source source;
+
+ // Decoration handling methods.
+ // Can be useful for simple "raw" reflection.
+ // However, most members are here because the Parser needs most of these,
+ // and might as well just have the whole suite of decoration/name handling in one place.
+ void set_name(uint32_t id, const std::string &name);
+ const std::string &get_name(uint32_t id) const;
+ void set_decoration(uint32_t id, spv::Decoration decoration, uint32_t argument = 0);
+ void set_decoration_string(uint32_t id, spv::Decoration decoration, const std::string &argument);
+ bool has_decoration(uint32_t id, spv::Decoration decoration) const;
+ uint32_t get_decoration(uint32_t id, spv::Decoration decoration) const;
+ const std::string &get_decoration_string(uint32_t id, spv::Decoration decoration) const;
+ const Bitset &get_decoration_bitset(uint32_t id) const;
+ void unset_decoration(uint32_t id, spv::Decoration decoration);
+
+ // Decoration handling methods (for members of a struct).
+ void set_member_name(uint32_t id, uint32_t index, const std::string &name);
+ const std::string &get_member_name(uint32_t id, uint32_t index) const;
+ void set_member_decoration(uint32_t id, uint32_t index, spv::Decoration decoration, uint32_t argument = 0);
+ void set_member_decoration_string(uint32_t id, uint32_t index, spv::Decoration decoration,
+ const std::string &argument);
+ uint32_t get_member_decoration(uint32_t id, uint32_t index, spv::Decoration decoration) const;
+ const std::string &get_member_decoration_string(uint32_t id, uint32_t index, spv::Decoration decoration) const;
+ bool has_member_decoration(uint32_t id, uint32_t index, spv::Decoration decoration) const;
+ const Bitset &get_member_decoration_bitset(uint32_t id, uint32_t index) const;
+ void unset_member_decoration(uint32_t id, uint32_t index, spv::Decoration decoration);
+
+ void mark_used_as_array_length(uint32_t id);
+ uint32_t increase_bound_by(uint32_t count);
+ Bitset get_buffer_block_flags(const SPIRVariable &var) const;
+
+ void add_typed_id(Types type, uint32_t id);
+ void remove_typed_id(Types type, uint32_t id);
+
+ template <typename T, typename Op>
+ void for_each_typed_id(const Op &op)
+ {
+ loop_iteration_depth++;
+ for (auto &id : ids_for_type[T::type])
+ {
+ if (ids[id].get_type() == static_cast<Types>(T::type))
+ op(id, get<T>(id));
+ }
+ loop_iteration_depth--;
+ }
+
+ template <typename T, typename Op>
+ void for_each_typed_id(const Op &op) const
+ {
+ for (auto &id : ids_for_type[T::type])
+ {
+ if (ids[id].get_type() == static_cast<Types>(T::type))
+ op(id, get<T>(id));
+ }
+ }
+
+ template <typename T>
+ void reset_all_of_type()
+ {
+ reset_all_of_type(static_cast<Types>(T::type));
+ }
+
+ void reset_all_of_type(Types type);
+
+ Meta *find_meta(uint32_t id);
+ const Meta *find_meta(uint32_t id) const;
+
+ const std::string &get_empty_string() const
+ {
+ return empty_string;
+ }
+
+private:
+ template <typename T>
+ T &get(uint32_t id)
+ {
+ return variant_get<T>(ids[id]);
+ }
+
+ template <typename T>
+ const T &get(uint32_t id) const
+ {
+ return variant_get<T>(ids[id]);
+ }
+
+ uint32_t loop_iteration_depth = 0;
+ std::string empty_string;
+ Bitset cleared_bitset;
+};
+} // namespace spirv_cross
+
+#endif