| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
|
|
| #ifndef SPIRV_HLSL_HPP |
| #define SPIRV_HLSL_HPP |
|
|
| #include "spirv_glsl.hpp" |
| #include <utility> |
|
|
| namespace SPIRV_CROSS_NAMESPACE |
| { |
| |
| struct HLSLVertexAttributeRemap |
| { |
| uint32_t location; |
| std::string semantic; |
| }; |
| |
| |
| |
| |
| struct RootConstants |
| { |
| uint32_t start; |
| uint32_t end; |
|
|
| uint32_t binding; |
| uint32_t space; |
| }; |
|
|
| |
| enum HLSLBindingFlagBits |
| { |
| HLSL_BINDING_AUTO_NONE_BIT = 0, |
|
|
| |
| |
| |
| HLSL_BINDING_AUTO_PUSH_CONSTANT_BIT = 1 << 0, |
|
|
| |
| |
| HLSL_BINDING_AUTO_CBV_BIT = 1 << 1, |
|
|
| |
| HLSL_BINDING_AUTO_SRV_BIT = 1 << 2, |
|
|
| |
| HLSL_BINDING_AUTO_UAV_BIT = 1 << 3, |
|
|
| |
| HLSL_BINDING_AUTO_SAMPLER_BIT = 1 << 4, |
|
|
| |
| HLSL_BINDING_AUTO_ALL = 0x7fffffff |
| }; |
| using HLSLBindingFlags = uint32_t; |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| struct HLSLResourceBinding |
| { |
| spv::ExecutionModel stage = spv::ExecutionModelMax; |
| uint32_t desc_set = 0; |
| uint32_t binding = 0; |
|
|
| struct Binding |
| { |
| uint32_t register_space = 0; |
| uint32_t register_binding = 0; |
| } cbv, uav, srv, sampler; |
| }; |
|
|
| enum HLSLAuxBinding |
| { |
| HLSL_AUX_BINDING_BASE_VERTEX_INSTANCE = 0 |
| }; |
|
|
| class CompilerHLSL : public CompilerGLSL |
| { |
| public: |
| struct Options |
| { |
| uint32_t shader_model = 30; |
|
|
| |
| bool point_size_compat = false; |
|
|
| |
| bool point_coord_compat = false; |
|
|
| |
| |
| |
| |
| bool support_nonzero_base_vertex_base_instance = false; |
|
|
| |
| |
| |
| bool force_storage_buffer_as_uav = false; |
| |
| |
| |
| |
| bool nonwritable_uav_texture_as_srv = false; |
|
|
| |
| |
| |
| bool enable_16bit_types = false; |
|
|
| |
| |
| |
| |
| bool flatten_matrix_vertex_input_semantics = false; |
|
|
| |
| bool use_entry_point_name = false; |
|
|
| |
| |
| |
| bool preserve_structured_buffers = false; |
| }; |
|
|
| explicit CompilerHLSL(std::vector<uint32_t> spirv_) |
| : CompilerGLSL(std::move(spirv_)) |
| { |
| } |
|
|
| CompilerHLSL(const uint32_t *ir_, size_t size) |
| : CompilerGLSL(ir_, size) |
| { |
| } |
|
|
| explicit CompilerHLSL(const ParsedIR &ir_) |
| : CompilerGLSL(ir_) |
| { |
| } |
|
|
| explicit CompilerHLSL(ParsedIR &&ir_) |
| : CompilerGLSL(std::move(ir_)) |
| { |
| } |
|
|
| const Options &get_hlsl_options() const |
| { |
| return hlsl_options; |
| } |
|
|
| void set_hlsl_options(const Options &opts) |
| { |
| hlsl_options = opts; |
| } |
|
|
| |
| |
| |
| |
| void set_root_constant_layouts(std::vector<RootConstants> layout); |
|
|
| |
| |
| |
| |
| void add_vertex_attribute_remap(const HLSLVertexAttributeRemap &vertex_attributes); |
| std::string compile() override; |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| VariableID remap_num_workgroups_builtin(); |
|
|
| |
| void set_resource_binding_flags(HLSLBindingFlags flags); |
|
|
| |
| |
| |
| |
| |
| void add_hlsl_resource_binding(const HLSLResourceBinding &resource); |
| bool is_hlsl_resource_binding_used(spv::ExecutionModel model, uint32_t set, uint32_t binding) const; |
|
|
| |
| void set_hlsl_force_storage_buffer_as_uav(uint32_t desc_set, uint32_t binding); |
|
|
| |
| void set_hlsl_aux_buffer_binding(HLSLAuxBinding binding, uint32_t register_index, uint32_t register_space); |
| void unset_hlsl_aux_buffer_binding(HLSLAuxBinding binding); |
| bool is_hlsl_aux_buffer_binding_used(HLSLAuxBinding binding) const; |
|
|
| private: |
| std::string type_to_glsl(const SPIRType &type, uint32_t id = 0) override; |
| std::string image_type_hlsl(const SPIRType &type, uint32_t id); |
| std::string image_type_hlsl_modern(const SPIRType &type, uint32_t id); |
| std::string image_type_hlsl_legacy(const SPIRType &type, uint32_t id); |
| void emit_function_prototype(SPIRFunction &func, const Bitset &return_flags) override; |
| void emit_hlsl_entry_point(); |
| void emit_header() override; |
| void emit_resources(); |
| void emit_interface_block_globally(const SPIRVariable &type); |
| void emit_interface_block_in_struct(const SPIRVariable &var, std::unordered_set<uint32_t> &active_locations); |
| void emit_interface_block_member_in_struct(const SPIRVariable &var, uint32_t member_index, uint32_t location, |
| std::unordered_set<uint32_t> &active_locations); |
| void emit_builtin_inputs_in_struct(); |
| void emit_builtin_outputs_in_struct(); |
| void emit_builtin_primitive_outputs_in_struct(); |
| void emit_texture_op(const Instruction &i, bool sparse) override; |
| void emit_instruction(const Instruction &instruction) override; |
| void emit_glsl_op(uint32_t result_type, uint32_t result_id, uint32_t op, const uint32_t *args, |
| uint32_t count) override; |
| void emit_buffer_block(const SPIRVariable &type) override; |
| void emit_push_constant_block(const SPIRVariable &var) override; |
| void emit_uniform(const SPIRVariable &var) override; |
| void emit_modern_uniform(const SPIRVariable &var); |
| void emit_legacy_uniform(const SPIRVariable &var); |
| void emit_specialization_constants_and_structs(); |
| void emit_composite_constants(); |
| void emit_fixup() override; |
| std::string builtin_to_glsl(spv::BuiltIn builtin, spv::StorageClass storage) override; |
| std::string layout_for_member(const SPIRType &type, uint32_t index) override; |
| std::string to_interpolation_qualifiers(const Bitset &flags) override; |
| std::string bitcast_glsl_op(const SPIRType &result_type, const SPIRType &argument_type) override; |
| bool emit_complex_bitcast(uint32_t result_type, uint32_t id, uint32_t op0) override; |
| std::string to_func_call_arg(const SPIRFunction::Parameter &arg, uint32_t id) override; |
| std::string to_sampler_expression(uint32_t id); |
| std::string to_resource_binding(const SPIRVariable &var); |
| std::string to_resource_binding_sampler(const SPIRVariable &var); |
| std::string to_resource_register(HLSLBindingFlagBits flag, char space, uint32_t binding, uint32_t set); |
| std::string to_initializer_expression(const SPIRVariable &var) override; |
| void emit_sampled_image_op(uint32_t result_type, uint32_t result_id, uint32_t image_id, uint32_t samp_id) override; |
| void emit_access_chain(const Instruction &instruction); |
| void emit_load(const Instruction &instruction); |
| void read_access_chain(std::string *expr, const std::string &lhs, const SPIRAccessChain &chain); |
| void read_access_chain_struct(const std::string &lhs, const SPIRAccessChain &chain); |
| void read_access_chain_array(const std::string &lhs, const SPIRAccessChain &chain); |
| void write_access_chain(const SPIRAccessChain &chain, uint32_t value, const SmallVector<uint32_t> &composite_chain); |
| void write_access_chain_struct(const SPIRAccessChain &chain, uint32_t value, |
| const SmallVector<uint32_t> &composite_chain); |
| void write_access_chain_array(const SPIRAccessChain &chain, uint32_t value, |
| const SmallVector<uint32_t> &composite_chain); |
| std::string write_access_chain_value(uint32_t value, const SmallVector<uint32_t> &composite_chain, bool enclose); |
| void emit_store(const Instruction &instruction); |
| void emit_atomic(const uint32_t *ops, uint32_t length, spv::Op op); |
| void emit_subgroup_op(const Instruction &i) override; |
| void emit_block_hints(const SPIRBlock &block) override; |
|
|
| void emit_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index, const std::string &qualifier, |
| uint32_t base_offset = 0) override; |
| void emit_rayquery_function(const char *commited, const char *candidate, const uint32_t *ops); |
| void emit_mesh_tasks(SPIRBlock &block) override; |
|
|
| const char *to_storage_qualifiers_glsl(const SPIRVariable &var) override; |
| void replace_illegal_names() override; |
|
|
| SPIRType::BaseType get_builtin_basetype(spv::BuiltIn builtin, SPIRType::BaseType default_type) override; |
|
|
| bool is_hlsl_force_storage_buffer_as_uav(ID id) const; |
|
|
| Options hlsl_options; |
|
|
| |
| bool requires_op_fmod = false; |
| bool requires_fp16_packing = false; |
| bool requires_uint2_packing = false; |
| bool requires_explicit_fp16_packing = false; |
| bool requires_unorm8_packing = false; |
| bool requires_snorm8_packing = false; |
| bool requires_unorm16_packing = false; |
| bool requires_snorm16_packing = false; |
| bool requires_bitfield_insert = false; |
| bool requires_bitfield_extract = false; |
| bool requires_inverse_2x2 = false; |
| bool requires_inverse_3x3 = false; |
| bool requires_inverse_4x4 = false; |
| bool requires_scalar_reflect = false; |
| bool requires_scalar_refract = false; |
| bool requires_scalar_faceforward = false; |
|
|
| struct TextureSizeVariants |
| { |
| |
| TextureSizeVariants() |
| { |
| srv = 0; |
| for (auto &unorm : uav) |
| for (auto &u : unorm) |
| u = 0; |
| } |
| uint64_t srv; |
| uint64_t uav[3][4]; |
| } required_texture_size_variants; |
|
|
| void require_texture_query_variant(uint32_t var_id); |
| void emit_texture_size_variants(uint64_t variant_mask, const char *vecsize_qualifier, bool uav, |
| const char *type_qualifier); |
|
|
| enum TextureQueryVariantDim |
| { |
| Query1D = 0, |
| Query1DArray, |
| Query2D, |
| Query2DArray, |
| Query3D, |
| QueryBuffer, |
| QueryCube, |
| QueryCubeArray, |
| Query2DMS, |
| Query2DMSArray, |
| QueryDimCount |
| }; |
|
|
| enum TextureQueryVariantType |
| { |
| QueryTypeFloat = 0, |
| QueryTypeInt = 16, |
| QueryTypeUInt = 32, |
| QueryTypeCount = 3 |
| }; |
|
|
| enum BitcastType |
| { |
| TypeNormal, |
| TypePackUint2x32, |
| TypeUnpackUint64 |
| }; |
|
|
| void analyze_meshlet_writes(); |
| void analyze_meshlet_writes(uint32_t func_id, uint32_t id_per_vertex, uint32_t id_per_primitive, |
| std::unordered_set<uint32_t> &processed_func_ids); |
|
|
| BitcastType get_bitcast_type(uint32_t result_type, uint32_t op0); |
|
|
| void emit_builtin_variables(); |
| bool require_output = false; |
| bool require_input = false; |
| SmallVector<HLSLVertexAttributeRemap> remap_vertex_attributes; |
|
|
| uint32_t type_to_consumed_locations(const SPIRType &type) const; |
|
|
| std::string to_semantic(uint32_t location, spv::ExecutionModel em, spv::StorageClass sc); |
|
|
| uint32_t num_workgroups_builtin = 0; |
| HLSLBindingFlags resource_binding_flags = 0; |
|
|
| |
| |
| std::vector<RootConstants> root_constants_layout; |
|
|
| void validate_shader_model(); |
|
|
| std::string get_unique_identifier(); |
| uint32_t unique_identifier_count = 0; |
|
|
| std::unordered_map<StageSetBinding, std::pair<HLSLResourceBinding, bool>, InternalHasher> resource_bindings; |
| void remap_hlsl_resource_binding(HLSLBindingFlagBits type, uint32_t &desc_set, uint32_t &binding); |
|
|
| std::unordered_set<SetBindingPair, InternalHasher> force_uav_buffer_bindings; |
|
|
| struct |
| { |
| uint32_t register_index = 0; |
| uint32_t register_space = 0; |
| bool explicit_binding = false; |
| bool used = false; |
| } base_vertex_info; |
|
|
| |
| bool is_user_type_structured(uint32_t id) const override; |
|
|
| std::vector<TypeID> composite_selection_workaround_types; |
|
|
| std::string get_inner_entry_point_name() const; |
| }; |
| } |
|
|
| #endif |
|
|