summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/SPIRV-Cross/spirv_common.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/SPIRV-Cross/spirv_common.hpp')
-rw-r--r--src/3rdparty/SPIRV-Cross/spirv_common.hpp430
1 files changed, 317 insertions, 113 deletions
diff --git a/src/3rdparty/SPIRV-Cross/spirv_common.hpp b/src/3rdparty/SPIRV-Cross/spirv_common.hpp
index 0cf1f56..c1c6fc8 100644
--- a/src/3rdparty/SPIRV-Cross/spirv_common.hpp
+++ b/src/3rdparty/SPIRV-Cross/spirv_common.hpp
@@ -20,6 +20,7 @@
#include "spirv.hpp"
#include "spirv_cross_containers.hpp"
#include "spirv_cross_error_handling.hpp"
+#include <functional>
// A bit crude, but allows projects which embed SPIRV-Cross statically to
// effectively hide all the symbols from other projects.
@@ -183,14 +184,14 @@ std::string join(Ts &&... ts)
return stream.str();
}
-inline std::string merge(const SmallVector<std::string> &list)
+inline std::string merge(const SmallVector<std::string> &list, const char *between = ", ")
{
StringStream<> stream;
for (auto &elem : list)
{
stream << elem;
if (&elem != &list.back())
- stream << ", ";
+ stream << between;
}
return stream.str();
}
@@ -270,20 +271,6 @@ struct Instruction
uint32_t length = 0;
};
-// Helper for Variant interface.
-struct IVariant
-{
- virtual ~IVariant() = default;
- virtual IVariant *clone(ObjectPoolBase *pool) = 0;
- uint32_t self = 0;
-};
-
-#define SPIRV_CROSS_DECLARE_CLONE(T) \
- IVariant *clone(ObjectPoolBase *pool) override \
- { \
- return static_cast<ObjectPool<T> *>(pool)->allocate(*this); \
- }
-
enum Types
{
TypeNone,
@@ -299,9 +286,140 @@ enum Types
TypeCombinedImageSampler,
TypeAccessChain,
TypeUndef,
+ TypeString,
TypeCount
};
+template <Types type>
+class TypedID;
+
+template <>
+class TypedID<TypeNone>
+{
+public:
+ TypedID() = default;
+ TypedID(uint32_t id_)
+ : id(id_)
+ {
+ }
+
+ template <Types U>
+ TypedID(const TypedID<U> &other)
+ {
+ *this = other;
+ }
+
+ template <Types U>
+ TypedID &operator=(const TypedID<U> &other)
+ {
+ id = uint32_t(other);
+ return *this;
+ }
+
+ // Implicit conversion to u32 is desired here.
+ // As long as we block implicit conversion between TypedID<A> and TypedID<B> we're good.
+ operator uint32_t() const
+ {
+ return id;
+ }
+
+ template <Types U>
+ operator TypedID<U>() const
+ {
+ return TypedID<U>(*this);
+ }
+
+ bool operator==(const TypedID &other) const
+ {
+ return id == other.id;
+ }
+
+ bool operator!=(const TypedID &other) const
+ {
+ return id != other.id;
+ }
+
+ template <Types type>
+ bool operator==(const TypedID<type> &other) const
+ {
+ return id == uint32_t(other);
+ }
+
+ template <Types type>
+ bool operator!=(const TypedID<type> &other) const
+ {
+ return id != uint32_t(other);
+ }
+
+private:
+ uint32_t id = 0;
+};
+
+template <Types type>
+class TypedID
+{
+public:
+ TypedID() = default;
+ TypedID(uint32_t id_)
+ : id(id_)
+ {
+ }
+
+ explicit TypedID(const TypedID<TypeNone> &other)
+ : id(uint32_t(other))
+ {
+ }
+
+ operator uint32_t() const
+ {
+ return id;
+ }
+
+ bool operator==(const TypedID &other) const
+ {
+ return id == other.id;
+ }
+
+ bool operator!=(const TypedID &other) const
+ {
+ return id != other.id;
+ }
+
+ bool operator==(const TypedID<TypeNone> &other) const
+ {
+ return id == uint32_t(other);
+ }
+
+ bool operator!=(const TypedID<TypeNone> &other) const
+ {
+ return id != uint32_t(other);
+ }
+
+private:
+ uint32_t id = 0;
+};
+
+using VariableID = TypedID<TypeVariable>;
+using TypeID = TypedID<TypeType>;
+using ConstantID = TypedID<TypeConstant>;
+using FunctionID = TypedID<TypeFunction>;
+using BlockID = TypedID<TypeBlock>;
+using ID = TypedID<TypeNone>;
+
+// Helper for Variant interface.
+struct IVariant
+{
+ virtual ~IVariant() = default;
+ virtual IVariant *clone(ObjectPoolBase *pool) = 0;
+ ID self = 0;
+};
+
+#define SPIRV_CROSS_DECLARE_CLONE(T) \
+ IVariant *clone(ObjectPoolBase *pool) override \
+ { \
+ return static_cast<ObjectPool<T> *>(pool)->allocate(*this); \
+ }
+
struct SPIRUndef : IVariant
{
enum
@@ -309,15 +427,32 @@ struct SPIRUndef : IVariant
type = TypeUndef
};
- explicit SPIRUndef(uint32_t basetype_)
+ explicit SPIRUndef(TypeID basetype_)
: basetype(basetype_)
{
}
- uint32_t basetype;
+ TypeID basetype;
SPIRV_CROSS_DECLARE_CLONE(SPIRUndef)
};
+struct SPIRString : IVariant
+{
+ enum
+ {
+ type = TypeString
+ };
+
+ explicit SPIRString(std::string str_)
+ : str(std::move(str_))
+ {
+ }
+
+ std::string str;
+
+ SPIRV_CROSS_DECLARE_CLONE(SPIRString)
+};
+
// This type is only used by backends which need to access the combined image and sampler IDs separately after
// the OpSampledImage opcode.
struct SPIRCombinedImageSampler : IVariant
@@ -326,15 +461,15 @@ struct SPIRCombinedImageSampler : IVariant
{
type = TypeCombinedImageSampler
};
- SPIRCombinedImageSampler(uint32_t type_, uint32_t image_, uint32_t sampler_)
+ SPIRCombinedImageSampler(TypeID type_, VariableID image_, VariableID sampler_)
: combined_type(type_)
, image(image_)
, sampler(sampler_)
{
}
- uint32_t combined_type;
- uint32_t image;
- uint32_t sampler;
+ TypeID combined_type;
+ VariableID image;
+ VariableID sampler;
SPIRV_CROSS_DECLARE_CLONE(SPIRCombinedImageSampler)
};
@@ -346,16 +481,18 @@ struct SPIRConstantOp : IVariant
type = TypeConstantOp
};
- SPIRConstantOp(uint32_t result_type, spv::Op op, const uint32_t *args, uint32_t length)
+ SPIRConstantOp(TypeID result_type, spv::Op op, const uint32_t *args, uint32_t length)
: opcode(op)
- , arguments(args, args + length)
, basetype(result_type)
{
+ arguments.reserve(length);
+ for (uint32_t i = 0; i < length; i++)
+ arguments.push_back(args[i]);
}
spv::Op opcode;
SmallVector<uint32_t> arguments;
- uint32_t basetype;
+ TypeID basetype;
SPIRV_CROSS_DECLARE_CLONE(SPIRConstantOp)
};
@@ -418,11 +555,11 @@ struct SPIRType : IVariant
spv::StorageClass storage = spv::StorageClassGeneric;
- SmallVector<uint32_t> member_types;
+ SmallVector<TypeID> member_types;
struct ImageType
{
- uint32_t type;
+ TypeID type;
spv::Dim dim;
bool depth;
bool arrayed;
@@ -435,11 +572,11 @@ struct SPIRType : IVariant
// Structs can be declared multiple times if they are used as part of interface blocks.
// We want to detect this so that we only emit the struct definition once.
// Since we cannot rely on OpName to be equal, we need to figure out aliases.
- uint32_t type_alias = 0;
+ TypeID type_alias = 0;
// Denotes the type which this type is based on.
// Allows the backend to traverse how a complex type is built up during access chains.
- uint32_t parent_type = 0;
+ TypeID parent_type = 0;
// Used in backends to avoid emitting members with conflicting names.
std::unordered_set<std::string> member_name_cache;
@@ -458,6 +595,7 @@ struct SPIRExtension : IVariant
{
Unsupported,
GLSL,
+ SPV_debug_info,
SPV_AMD_shader_ballot,
SPV_AMD_shader_explicit_vertex_parameter,
SPV_AMD_shader_trinary_minmax,
@@ -477,7 +615,7 @@ struct SPIRExtension : IVariant
// so in order to avoid conflicts, we can't stick them in the ids array.
struct SPIREntryPoint
{
- SPIREntryPoint(uint32_t self_, spv::ExecutionModel execution_model, const std::string &entry_name)
+ SPIREntryPoint(FunctionID self_, spv::ExecutionModel execution_model, const std::string &entry_name)
: self(self_)
, name(entry_name)
, orig_name(entry_name)
@@ -486,10 +624,10 @@ struct SPIREntryPoint
}
SPIREntryPoint() = default;
- uint32_t self = 0;
+ FunctionID self = 0;
std::string name;
std::string orig_name;
- SmallVector<uint32_t> interface_variables;
+ SmallVector<VariableID> interface_variables;
Bitset flags;
struct
@@ -510,7 +648,7 @@ struct SPIRExpression : IVariant
};
// Only created by the backend target to avoid creating tons of temporaries.
- SPIRExpression(std::string expr, uint32_t expression_type_, bool immutable_)
+ SPIRExpression(std::string expr, TypeID expression_type_, bool immutable_)
: expression(move(expr))
, expression_type(expression_type_)
, immutable(immutable_)
@@ -520,14 +658,14 @@ struct SPIRExpression : IVariant
// If non-zero, prepend expression with to_expression(base_expression).
// Used in amortizing multiple calls to to_expression()
// where in certain cases that would quickly force a temporary when not needed.
- uint32_t base_expression = 0;
+ ID base_expression = 0;
std::string expression;
- uint32_t expression_type = 0;
+ TypeID expression_type = 0;
// If this expression is a forwarded load,
// allow us to reference the original variable.
- uint32_t loaded_from = 0;
+ ID loaded_from = 0;
// If this expression will never change, we can avoid lots of temporaries
// in high level source.
@@ -543,11 +681,11 @@ struct SPIRExpression : IVariant
bool access_chain = false;
// A list of expressions which this expression depends on.
- SmallVector<uint32_t> expression_dependencies;
+ SmallVector<ID> expression_dependencies;
// By reading this expression, we implicitly read these expressions as well.
// Used by access chain Store and Load since we read multiple expressions in this case.
- SmallVector<uint32_t> implied_read_expressions;
+ SmallVector<ID> implied_read_expressions;
SPIRV_CROSS_DECLARE_CLONE(SPIRExpression)
};
@@ -559,12 +697,12 @@ struct SPIRFunctionPrototype : IVariant
type = TypeFunctionPrototype
};
- explicit SPIRFunctionPrototype(uint32_t return_type_)
+ explicit SPIRFunctionPrototype(TypeID return_type_)
: return_type(return_type_)
{
}
- uint32_t return_type;
+ TypeID return_type;
SmallVector<uint32_t> parameter_types;
SPIRV_CROSS_DECLARE_CLONE(SPIRFunctionPrototype)
@@ -639,23 +777,23 @@ struct SPIRBlock : IVariant
Terminator terminator = Unknown;
Merge merge = MergeNone;
Hints hint = HintNone;
- uint32_t next_block = 0;
- uint32_t merge_block = 0;
- uint32_t continue_block = 0;
+ BlockID next_block = 0;
+ BlockID merge_block = 0;
+ BlockID continue_block = 0;
- uint32_t return_value = 0; // If 0, return nothing (void).
- uint32_t condition = 0;
- uint32_t true_block = 0;
- uint32_t false_block = 0;
- uint32_t default_block = 0;
+ ID return_value = 0; // If 0, return nothing (void).
+ ID condition = 0;
+ BlockID true_block = 0;
+ BlockID false_block = 0;
+ BlockID default_block = 0;
SmallVector<Instruction> ops;
struct Phi
{
- uint32_t local_variable; // flush local variable ...
- uint32_t parent; // If we're in from_block and want to branch into this block ...
- uint32_t function_variable; // to this function-global "phi" variable first.
+ ID local_variable; // flush local variable ...
+ BlockID parent; // If we're in from_block and want to branch into this block ...
+ VariableID function_variable; // to this function-global "phi" variable first.
};
// Before entering this block flush out local variables to magical "phi" variables.
@@ -663,16 +801,16 @@ struct SPIRBlock : IVariant
// Declare these temporaries before beginning the block.
// Used for handling complex continue blocks which have side effects.
- SmallVector<std::pair<uint32_t, uint32_t>> declare_temporary;
+ SmallVector<std::pair<TypeID, ID>> declare_temporary;
// Declare these temporaries, but only conditionally if this block turns out to be
// a complex loop header.
- SmallVector<std::pair<uint32_t, uint32_t>> potential_declare_temporary;
+ SmallVector<std::pair<TypeID, ID>> potential_declare_temporary;
struct Case
{
uint32_t value;
- uint32_t block;
+ BlockID block;
};
SmallVector<Case> cases;
@@ -686,23 +824,27 @@ struct SPIRBlock : IVariant
// Do we need a ladder variable to defer breaking out of a loop construct after a switch block?
bool need_ladder_break = false;
+ // If marked, we have explicitly handled Phi from this block, so skip any flushes related to that on a branch.
+ // Used to handle an edge case with switch and case-label fallthrough where fall-through writes to Phi.
+ BlockID ignore_phi_from_block = 0;
+
// The dominating block which this block might be within.
// Used in continue; blocks to determine if we really need to write continue.
- uint32_t loop_dominator = 0;
+ BlockID loop_dominator = 0;
// All access to these variables are dominated by this block,
// so before branching anywhere we need to make sure that we declare these variables.
- SmallVector<uint32_t> dominated_variables;
+ SmallVector<VariableID> dominated_variables;
// These are variables which should be declared in a for loop header, if we
// fail to use a classic for-loop,
// we remove these variables, and fall back to regular variables outside the loop.
- SmallVector<uint32_t> loop_variables;
+ SmallVector<VariableID> loop_variables;
// Some expressions are control-flow dependent, i.e. any instruction which relies on derivatives or
// sub-group-like operations.
// Make sure that we only use these expressions in the original block.
- SmallVector<uint32_t> invalidate_expressions;
+ SmallVector<ID> invalidate_expressions;
SPIRV_CROSS_DECLARE_CLONE(SPIRBlock)
};
@@ -714,7 +856,7 @@ struct SPIRFunction : IVariant
type = TypeFunction
};
- SPIRFunction(uint32_t return_type_, uint32_t function_type_)
+ SPIRFunction(TypeID return_type_, TypeID function_type_)
: return_type(return_type_)
, function_type(function_type_)
{
@@ -722,8 +864,8 @@ struct SPIRFunction : IVariant
struct Parameter
{
- uint32_t type;
- uint32_t id;
+ TypeID type;
+ ID id;
uint32_t read_count;
uint32_t write_count;
@@ -745,33 +887,40 @@ struct SPIRFunction : IVariant
// or a global ID.
struct CombinedImageSamplerParameter
{
- uint32_t id;
- uint32_t image_id;
- uint32_t sampler_id;
+ VariableID id;
+ VariableID image_id;
+ VariableID sampler_id;
bool global_image;
bool global_sampler;
bool depth;
};
- uint32_t return_type;
- uint32_t function_type;
+ TypeID return_type;
+ TypeID function_type;
SmallVector<Parameter> arguments;
// Can be used by backends to add magic arguments.
// Currently used by combined image/sampler implementation.
SmallVector<Parameter> shadow_arguments;
- SmallVector<uint32_t> local_variables;
- uint32_t entry_block = 0;
- SmallVector<uint32_t> blocks;
+ SmallVector<VariableID> local_variables;
+ BlockID entry_block = 0;
+ SmallVector<BlockID> blocks;
SmallVector<CombinedImageSamplerParameter> combined_parameters;
- void add_local_variable(uint32_t id)
+ struct EntryLine
+ {
+ uint32_t file_id = 0;
+ uint32_t line_literal = 0;
+ };
+ EntryLine entry_line;
+
+ void add_local_variable(VariableID id)
{
local_variables.push_back(id);
}
- void add_parameter(uint32_t parameter_type, uint32_t id, bool alias_global_variable = false)
+ void add_parameter(TypeID parameter_type, ID id, bool alias_global_variable = false)
{
// Arguments are read-only until proven otherwise.
arguments.push_back({ parameter_type, id, 0u, 0u, alias_global_variable });
@@ -792,7 +941,7 @@ struct SPIRFunction : IVariant
// On function entry, make sure to copy a constant array into thread addr space to work around
// the case where we are passing a constant array by value to a function on backends which do not
// consider arrays value types.
- SmallVector<uint32_t> constant_arrays_needed_on_stack;
+ SmallVector<ID> constant_arrays_needed_on_stack;
bool active = false;
bool flush_undeclared = true;
@@ -808,7 +957,7 @@ struct SPIRAccessChain : IVariant
type = TypeAccessChain
};
- SPIRAccessChain(uint32_t basetype_, spv::StorageClass storage_, std::string base_, std::string dynamic_index_,
+ SPIRAccessChain(TypeID basetype_, spv::StorageClass storage_, std::string base_, std::string dynamic_index_,
int32_t static_index_)
: basetype(basetype_)
, storage(storage_)
@@ -823,20 +972,20 @@ struct SPIRAccessChain : IVariant
// which has no usable buffer type ala GLSL SSBOs.
// StructuredBuffer is too limited, so our only option is to deal with ByteAddressBuffer which works with raw addresses.
- uint32_t basetype;
+ TypeID basetype;
spv::StorageClass storage;
std::string base;
std::string dynamic_index;
int32_t static_index;
- uint32_t loaded_from = 0;
+ VariableID loaded_from = 0;
uint32_t matrix_stride = 0;
bool row_major_matrix = false;
bool immutable = false;
// By reading this expression, we implicitly read these expressions as well.
// Used by access chain Store and Load since we read multiple expressions in this case.
- SmallVector<uint32_t> implied_read_expressions;
+ SmallVector<ID> implied_read_expressions;
SPIRV_CROSS_DECLARE_CLONE(SPIRAccessChain)
};
@@ -849,7 +998,7 @@ struct SPIRVariable : IVariant
};
SPIRVariable() = default;
- SPIRVariable(uint32_t basetype_, spv::StorageClass storage_, uint32_t initializer_ = 0, uint32_t basevariable_ = 0)
+ SPIRVariable(TypeID basetype_, spv::StorageClass storage_, ID initializer_ = 0, VariableID basevariable_ = 0)
: basetype(basetype_)
, storage(storage_)
, initializer(initializer_)
@@ -857,11 +1006,11 @@ struct SPIRVariable : IVariant
{
}
- uint32_t basetype = 0;
+ TypeID basetype = 0;
spv::StorageClass storage = spv::StorageClassGeneric;
uint32_t decoration = 0;
- uint32_t initializer = 0;
- uint32_t basevariable = 0;
+ ID initializer = 0;
+ VariableID basevariable = 0;
SmallVector<uint32_t> dereference_chain;
bool compat_builtin = false;
@@ -871,10 +1020,10 @@ struct SPIRVariable : IVariant
// When we read the variable as an expression, just forward
// shadowed_id as the expression.
bool statically_assigned = false;
- uint32_t static_expression = 0;
+ ID static_expression = 0;
// Temporaries which can remain forwarded as long as this variable is not modified.
- SmallVector<uint32_t> dependees;
+ SmallVector<ID> dependees;
bool forwardable = true;
bool deferred_declaration = false;
@@ -887,7 +1036,7 @@ struct SPIRVariable : IVariant
uint32_t remapped_components = 0;
// The block which dominates all access to this variable.
- uint32_t dominator = 0;
+ BlockID dominator = 0;
// If true, this variable is a loop variable, when accessing the variable
// outside a loop,
// we should statically forward it.
@@ -907,7 +1056,8 @@ struct SPIRConstant : IVariant
type = TypeConstant
};
- union Constant {
+ union Constant
+ {
uint32_t u32;
int32_t i32;
float f32;
@@ -921,15 +1071,12 @@ struct SPIRConstant : IVariant
{
Constant r[4];
// If != 0, this element is a specialization constant, and we should keep track of it as such.
- uint32_t id[4];
+ ID id[4];
uint32_t vecsize = 1;
- // Workaround for MSVC 2013, initializing an array breaks.
ConstantVector()
{
memset(r, 0, sizeof(r));
- for (unsigned i = 0; i < 4; i++)
- id[i] = 0;
}
};
@@ -937,15 +1084,8 @@ struct SPIRConstant : IVariant
{
ConstantVector c[4];
// If != 0, this column is a specialization constant, and we should keep track of it as such.
- uint32_t id[4];
+ ID id[4];
uint32_t columns = 1;
-
- // Workaround for MSVC 2013, initializing an array breaks.
- ConstantMatrix()
- {
- for (unsigned i = 0; i < 4; i++)
- id[i] = 0;
- }
};
static inline float f16_to_f32(uint16_t u16_value)
@@ -955,7 +1095,8 @@ struct SPIRConstant : IVariant
int e = (u16_value >> 10) & 0x1f;
int m = (u16_value >> 0) & 0x3ff;
- union {
+ union
+ {
float f32;
uint32_t u32;
} u;
@@ -1109,16 +1250,18 @@ struct SPIRConstant : IVariant
SPIRConstant() = default;
- SPIRConstant(uint32_t constant_type_, const uint32_t *elements, uint32_t num_elements, bool specialized)
+ SPIRConstant(TypeID constant_type_, const uint32_t *elements, uint32_t num_elements, bool specialized)
: constant_type(constant_type_)
, specialization(specialized)
{
- subconstants.insert(std::end(subconstants), elements, elements + num_elements);
+ subconstants.reserve(num_elements);
+ for (uint32_t i = 0; i < num_elements; i++)
+ subconstants.push_back(elements[i]);
specialization = specialized;
}
// Construct scalar (32-bit).
- SPIRConstant(uint32_t constant_type_, uint32_t v0, bool specialized)
+ SPIRConstant(TypeID constant_type_, uint32_t v0, bool specialized)
: constant_type(constant_type_)
, specialization(specialized)
{
@@ -1128,7 +1271,7 @@ struct SPIRConstant : IVariant
}
// Construct scalar (64-bit).
- SPIRConstant(uint32_t constant_type_, uint64_t v0, bool specialized)
+ SPIRConstant(TypeID constant_type_, uint64_t v0, bool specialized)
: constant_type(constant_type_)
, specialization(specialized)
{
@@ -1138,7 +1281,7 @@ struct SPIRConstant : IVariant
}
// Construct vectors and matrices.
- SPIRConstant(uint32_t constant_type_, const SPIRConstant *const *vector_elements, uint32_t num_elements,
+ SPIRConstant(TypeID constant_type_, const SPIRConstant *const *vector_elements, uint32_t num_elements,
bool specialized)
: constant_type(constant_type_)
, specialization(specialized)
@@ -1170,7 +1313,7 @@ struct SPIRConstant : IVariant
}
}
- uint32_t constant_type = 0;
+ TypeID constant_type = 0;
ConstantMatrix m;
// If this constant is a specialization constant (i.e. created with OpSpecConstant*).
@@ -1182,7 +1325,7 @@ struct SPIRConstant : IVariant
bool is_used_as_lut = false;
// For composites which are constant arrays, etc.
- SmallVector<uint32_t> subconstants;
+ SmallVector<ConstantID> subconstants;
// Non-Vulkan GLSL, HLSL and sometimes MSL emits defines for each specialization constant,
// and uses them to initialize the constant. This allows the user
@@ -1317,9 +1460,9 @@ public:
return type;
}
- uint32_t get_id() const
+ ID get_id() const
{
- return holder ? holder->self : 0;
+ return holder ? holder->self : ID(0);
}
bool empty() const
@@ -1368,12 +1511,57 @@ T &variant_set(Variant &var, P &&... args)
struct AccessChainMeta
{
- uint32_t storage_packed_type = 0;
+ uint32_t storage_physical_type = 0;
bool need_transpose = false;
bool storage_is_packed = false;
bool storage_is_invariant = false;
};
+enum ExtendedDecorations
+{
+ // Marks if a buffer block is re-packed, i.e. member declaration might be subject to PhysicalTypeID remapping and padding.
+ SPIRVCrossDecorationBufferBlockRepacked = 0,
+
+ // A type in a buffer block might be declared with a different physical type than the logical type.
+ // If this is not set, PhysicalTypeID == the SPIR-V type as declared.
+ SPIRVCrossDecorationPhysicalTypeID,
+
+ // Marks if the physical type is to be declared with tight packing rules, i.e. packed_floatN on MSL and friends.
+ // If this is set, PhysicalTypeID might also be set. It can be set to same as logical type if all we're doing
+ // is converting float3 to packed_float3 for example.
+ // If this is marked on a struct, it means the struct itself must use only Packed types for all its members.
+ SPIRVCrossDecorationPhysicalTypePacked,
+
+ // The padding in bytes before declaring this struct member.
+ // If used on a struct type, marks the target size of a struct.
+ SPIRVCrossDecorationPaddingTarget,
+
+ SPIRVCrossDecorationInterfaceMemberIndex,
+ SPIRVCrossDecorationInterfaceOrigID,
+ SPIRVCrossDecorationResourceIndexPrimary,
+ // Used for decorations like resource indices for samplers when part of combined image samplers.
+ // A variable might need to hold two resource indices in this case.
+ SPIRVCrossDecorationResourceIndexSecondary,
+ // Used for resource indices for multiplanar images when part of combined image samplers.
+ SPIRVCrossDecorationResourceIndexTertiary,
+ SPIRVCrossDecorationResourceIndexQuaternary,
+
+ // Marks a buffer block for using explicit offsets (GLSL/HLSL).
+ SPIRVCrossDecorationExplicitOffset,
+
+ // Apply to a variable in the Input storage class; marks it as holding the base group passed to vkCmdDispatchBase().
+ // In MSL, this is used to adjust the WorkgroupId and GlobalInvocationId variables.
+ SPIRVCrossDecorationBuiltInDispatchBase,
+
+ // Apply to a variable that is a function parameter; marks it as being a "dynamic"
+ // combined image-sampler. In MSL, this is used when a function parameter might hold
+ // either a regular combined image-sampler or one that has an attached sampler
+ // Y'CbCr conversion.
+ SPIRVCrossDecorationDynamicImageSampler,
+
+ SPIRVCrossDecorationCount
+};
+
struct Meta
{
struct Decoration
@@ -1396,13 +1584,17 @@ struct Meta
spv::FPRoundingMode fp_rounding_mode = spv::FPRoundingModeMax;
bool builtin = false;
- struct
+ struct Extended
{
- uint32_t packed_type = 0;
- bool packed = false;
- uint32_t ib_member_index = ~(0u);
- uint32_t ib_orig_id = 0;
- uint32_t argument_buffer_id = ~(0u);
+ Extended()
+ {
+ // MSVC 2013 workaround to init like this.
+ for (auto &v : values)
+ v = 0;
+ }
+
+ Bitset flags;
+ uint32_t values[SPIRVCrossDecorationCount];
} extended;
};
@@ -1510,4 +1702,16 @@ static inline bool opcode_is_sign_invariant(spv::Op opcode)
}
} // namespace SPIRV_CROSS_NAMESPACE
+namespace std
+{
+template <SPIRV_CROSS_NAMESPACE::Types type>
+struct hash<SPIRV_CROSS_NAMESPACE::TypedID<type>>
+{
+ size_t operator()(const SPIRV_CROSS_NAMESPACE::TypedID<type> &value) const
+ {
+ return std::hash<uint32_t>()(value);
+ }
+};
+} // namespace std
+
#endif