Path: blob/21.2-virgl/src/compiler/spirv/vtn_private.h
4545 views
/*1* Copyright © 2015 Intel Corporation2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*22* Authors:23* Jason Ekstrand ([email protected])24*25*/2627#ifndef _VTN_PRIVATE_H_28#define _VTN_PRIVATE_H_2930#include <setjmp.h>3132#include "nir/nir.h"33#include "nir/nir_builder.h"34#include "util/u_dynarray.h"35#include "nir_spirv.h"36#include "spirv.h"37#include "vtn_generator_ids.h"3839struct vtn_builder;40struct vtn_decoration;4142/* setjmp/longjmp is broken on MinGW: https://sourceforge.net/p/mingw-w64/bugs/406/ */43#ifdef __MINGW32__44#define vtn_setjmp __builtin_setjmp45#define vtn_longjmp __builtin_longjmp46#else47#define vtn_setjmp setjmp48#define vtn_longjmp longjmp49#endif5051void vtn_log(struct vtn_builder *b, enum nir_spirv_debug_level level,52size_t spirv_offset, const char *message);5354void vtn_logf(struct vtn_builder *b, enum nir_spirv_debug_level level,55size_t spirv_offset, const char *fmt, ...) PRINTFLIKE(4, 5);5657#define vtn_info(...) vtn_logf(b, NIR_SPIRV_DEBUG_LEVEL_INFO, 0, __VA_ARGS__)5859void _vtn_warn(struct vtn_builder *b, const char *file, unsigned line,60const char *fmt, ...) PRINTFLIKE(4, 5);61#define vtn_warn(...) _vtn_warn(b, __FILE__, __LINE__, __VA_ARGS__)6263void _vtn_err(struct vtn_builder *b, const char *file, unsigned line,64const char *fmt, ...) PRINTFLIKE(4, 5);65#define vtn_err(...) _vtn_err(b, __FILE__, __LINE__, __VA_ARGS__)6667/** Fail SPIR-V parsing68*69* This function logs an error and then bails out of the shader compile using70* longjmp. This being safe relies on two things:71*72* 1) We must guarantee that setjmp is called after allocating the builder73* and setting up b->debug (so that logging works) but before before any74* errors have a chance to occur.75*76* 2) While doing the SPIR-V -> NIR conversion, we need to be careful to77* ensure that all heap allocations happen through ralloc and are parented78* to the builder. This way they will get properly cleaned up on error.79*80* 3) We must ensure that _vtn_fail is never called while a mutex lock or a81* reference to any other resource is held with the exception of ralloc82* objects which are parented to the builder.83*84* So long as these two things continue to hold, we can easily longjmp back to85* spirv_to_nir(), clean up the builder, and return NULL.86*/87NORETURN void88_vtn_fail(struct vtn_builder *b, const char *file, unsigned line,89const char *fmt, ...) PRINTFLIKE(4, 5);9091#define vtn_fail(...) _vtn_fail(b, __FILE__, __LINE__, __VA_ARGS__)9293/** Fail if the given expression evaluates to true */94#define vtn_fail_if(expr, ...) \95do { \96if (unlikely(expr)) \97vtn_fail(__VA_ARGS__); \98} while (0)99100#define _vtn_fail_with(t, msg, v) \101vtn_fail("%s: %s (%u)\n", msg, spirv_ ## t ## _to_string(v), v)102103#define vtn_fail_with_decoration(msg, v) _vtn_fail_with(decoration, msg, v)104#define vtn_fail_with_opcode(msg, v) _vtn_fail_with(op, msg, v)105106/** Assert that a condition is true and, if it isn't, vtn_fail107*108* This macro is transitional only and should not be used in new code. Use109* vtn_fail_if and provide a real message instead.110*/111#define vtn_assert(expr) \112do { \113if (!likely(expr)) \114vtn_fail("%s", #expr); \115} while (0)116117enum vtn_value_type {118vtn_value_type_invalid = 0,119vtn_value_type_undef,120vtn_value_type_string,121vtn_value_type_decoration_group,122vtn_value_type_type,123vtn_value_type_constant,124vtn_value_type_pointer,125vtn_value_type_function,126vtn_value_type_block,127vtn_value_type_ssa,128vtn_value_type_extension,129vtn_value_type_image_pointer,130};131132enum vtn_branch_type {133vtn_branch_type_none,134vtn_branch_type_if_merge,135vtn_branch_type_switch_break,136vtn_branch_type_switch_fallthrough,137vtn_branch_type_loop_break,138vtn_branch_type_loop_continue,139vtn_branch_type_loop_back_edge,140vtn_branch_type_discard,141vtn_branch_type_terminate_invocation,142vtn_branch_type_ignore_intersection,143vtn_branch_type_terminate_ray,144vtn_branch_type_return,145};146147enum vtn_cf_node_type {148vtn_cf_node_type_block,149vtn_cf_node_type_if,150vtn_cf_node_type_loop,151vtn_cf_node_type_case,152vtn_cf_node_type_switch,153vtn_cf_node_type_function,154};155156struct vtn_cf_node {157struct list_head link;158struct vtn_cf_node *parent;159enum vtn_cf_node_type type;160};161162struct vtn_loop {163struct vtn_cf_node node;164165/* The main body of the loop */166struct list_head body;167168/* The "continue" part of the loop. This gets executed after the body169* and is where you go when you hit a continue.170*/171struct list_head cont_body;172173struct vtn_block *header_block;174struct vtn_block *cont_block;175struct vtn_block *break_block;176177SpvLoopControlMask control;178};179180struct vtn_if {181struct vtn_cf_node node;182183enum vtn_branch_type then_type;184struct list_head then_body;185186enum vtn_branch_type else_type;187struct list_head else_body;188189struct vtn_block *header_block;190struct vtn_block *merge_block;191192SpvSelectionControlMask control;193};194195struct vtn_case {196struct vtn_cf_node node;197198struct vtn_block *block;199200enum vtn_branch_type type;201struct list_head body;202203/* The fallthrough case, if any */204struct vtn_case *fallthrough;205206/* The uint32_t values that map to this case */207struct util_dynarray values;208209/* True if this is the default case */210bool is_default;211212/* Initialized to false; used when sorting the list of cases */213bool visited;214};215216struct vtn_switch {217struct vtn_cf_node node;218219uint32_t selector;220221struct list_head cases;222223struct vtn_block *break_block;224};225226struct vtn_block {227struct vtn_cf_node node;228229/** A pointer to the label instruction */230const uint32_t *label;231232/** A pointer to the merge instruction (or NULL if non exists) */233const uint32_t *merge;234235/** A pointer to the branch instruction that ends this block */236const uint32_t *branch;237238enum vtn_branch_type branch_type;239240/* The CF node for which this is a merge target241*242* The SPIR-V spec requires that any given block can be the merge target243* for at most one merge instruction. If this block is a merge target,244* this points back to the block containing that merge instruction.245*/246struct vtn_cf_node *merge_cf_node;247248/** Points to the loop that this block starts (if it starts a loop) */249struct vtn_loop *loop;250251/** Points to the switch case started by this block (if any) */252struct vtn_case *switch_case;253254/** Every block ends in a nop intrinsic so that we can find it again */255nir_intrinsic_instr *end_nop;256257/** attached nir_block */258struct nir_block *block;259};260261struct vtn_function {262struct vtn_cf_node node;263264struct vtn_type *type;265266bool referenced;267bool emitted;268269nir_function *nir_func;270struct vtn_block *start_block;271272struct list_head body;273274const uint32_t *end;275276SpvFunctionControlMask control;277};278279#define VTN_DECL_CF_NODE_CAST(_type) \280static inline struct vtn_##_type * \281vtn_cf_node_as_##_type(struct vtn_cf_node *node) \282{ \283assert(node->type == vtn_cf_node_type_##_type); \284return (struct vtn_##_type *)node; \285}286287VTN_DECL_CF_NODE_CAST(block)288VTN_DECL_CF_NODE_CAST(loop)289VTN_DECL_CF_NODE_CAST(if)290VTN_DECL_CF_NODE_CAST(case)291VTN_DECL_CF_NODE_CAST(switch)292VTN_DECL_CF_NODE_CAST(function)293294#define vtn_foreach_cf_node(node, cf_list) \295list_for_each_entry(struct vtn_cf_node, node, cf_list, link)296297typedef bool (*vtn_instruction_handler)(struct vtn_builder *, SpvOp,298const uint32_t *, unsigned);299300void vtn_build_cfg(struct vtn_builder *b, const uint32_t *words,301const uint32_t *end);302void vtn_function_emit(struct vtn_builder *b, struct vtn_function *func,303vtn_instruction_handler instruction_handler);304void vtn_handle_function_call(struct vtn_builder *b, SpvOp opcode,305const uint32_t *w, unsigned count);306307const uint32_t *308vtn_foreach_instruction(struct vtn_builder *b, const uint32_t *start,309const uint32_t *end, vtn_instruction_handler handler);310311struct vtn_ssa_value {312union {313nir_ssa_def *def;314struct vtn_ssa_value **elems;315};316317/* For matrices, if this is non-NULL, then this value is actually the318* transpose of some other value. The value that `transposed` points to319* always dominates this value.320*/321struct vtn_ssa_value *transposed;322323const struct glsl_type *type;324};325326enum vtn_base_type {327vtn_base_type_void,328vtn_base_type_scalar,329vtn_base_type_vector,330vtn_base_type_matrix,331vtn_base_type_array,332vtn_base_type_struct,333vtn_base_type_pointer,334vtn_base_type_image,335vtn_base_type_sampler,336vtn_base_type_sampled_image,337vtn_base_type_accel_struct,338vtn_base_type_function,339vtn_base_type_event,340};341342struct vtn_type {343enum vtn_base_type base_type;344345const struct glsl_type *type;346347/* The SPIR-V id of the given type. */348uint32_t id;349350/* Specifies the length of complex types.351*352* For Workgroup pointers, this is the size of the referenced type.353*/354unsigned length;355356/* for arrays, matrices and pointers, the array stride */357unsigned stride;358359/* Access qualifiers */360enum gl_access_qualifier access;361362union {363/* Members for scalar, vector, and array-like types */364struct {365/* for arrays, the vtn_type for the elements of the array */366struct vtn_type *array_element;367368/* for matrices, whether the matrix is stored row-major */369bool row_major:1;370371/* Whether this type, or a parent type, has been decorated as a372* builtin373*/374bool is_builtin:1;375376/* Which built-in to use */377SpvBuiltIn builtin;378};379380/* Members for struct types */381struct {382/* for structures, the vtn_type for each member */383struct vtn_type **members;384385/* for structs, the offset of each member */386unsigned *offsets;387388/* for structs, whether it was decorated as a "non-SSBO-like" block */389bool block:1;390391/* for structs, whether it was decorated as an "SSBO-like" block */392bool buffer_block:1;393394/* for structs with block == true, whether this is a builtin block395* (i.e. a block that contains only builtins).396*/397bool builtin_block:1;398399/* for structs and unions it specifies the minimum alignment of the400* members. 0 means packed.401*402* Set by CPacked and Alignment Decorations in kernels.403*/404bool packed:1;405};406407/* Members for pointer types */408struct {409/* For pointers, the vtn_type for dereferenced type */410struct vtn_type *deref;411412/* Storage class for pointers */413SpvStorageClass storage_class;414415/* Required alignment for pointers */416uint32_t align;417};418419/* Members for image types */420struct {421/* GLSL image type for this type. This is not to be confused with422* vtn_type::type which is actually going to be the GLSL type for a423* pointer to an image, likely a uint32_t.424*/425const struct glsl_type *glsl_image;426427/* Image format for image_load_store type images */428unsigned image_format;429430/* Access qualifier for storage images */431SpvAccessQualifier access_qualifier;432};433434/* Members for sampled image types */435struct {436/* For sampled images, the image type */437struct vtn_type *image;438};439440/* Members for function types */441struct {442/* For functions, the vtn_type for each parameter */443struct vtn_type **params;444445/* Return type for functions */446struct vtn_type *return_type;447};448};449};450451bool vtn_type_contains_block(struct vtn_builder *b, struct vtn_type *type);452453bool vtn_types_compatible(struct vtn_builder *b,454struct vtn_type *t1, struct vtn_type *t2);455456struct vtn_type *vtn_type_without_array(struct vtn_type *type);457458struct vtn_variable;459460enum vtn_access_mode {461vtn_access_mode_id,462vtn_access_mode_literal,463};464465struct vtn_access_link {466enum vtn_access_mode mode;467int64_t id;468};469470struct vtn_access_chain {471uint32_t length;472473/** Whether or not to treat the base pointer as an array. This is only474* true if this access chain came from an OpPtrAccessChain.475*/476bool ptr_as_array;477478/* Access qualifiers */479enum gl_access_qualifier access;480481/** Struct elements and array offsets.482*483* This is an array of 1 so that it can conveniently be created on the484* stack but the real length is given by the length field.485*/486struct vtn_access_link link[1];487};488489enum vtn_variable_mode {490vtn_variable_mode_function,491vtn_variable_mode_private,492vtn_variable_mode_uniform,493vtn_variable_mode_atomic_counter,494vtn_variable_mode_ubo,495vtn_variable_mode_ssbo,496vtn_variable_mode_phys_ssbo,497vtn_variable_mode_push_constant,498vtn_variable_mode_workgroup,499vtn_variable_mode_cross_workgroup,500vtn_variable_mode_generic,501vtn_variable_mode_constant,502vtn_variable_mode_input,503vtn_variable_mode_output,504vtn_variable_mode_image,505vtn_variable_mode_accel_struct,506vtn_variable_mode_call_data,507vtn_variable_mode_call_data_in,508vtn_variable_mode_ray_payload,509vtn_variable_mode_ray_payload_in,510vtn_variable_mode_hit_attrib,511vtn_variable_mode_shader_record,512};513514struct vtn_pointer {515/** The variable mode for the referenced data */516enum vtn_variable_mode mode;517518/** The dereferenced type of this pointer */519struct vtn_type *type;520521/** The pointer type of this pointer522*523* This may be NULL for some temporary pointers constructed as part of a524* large load, store, or copy. It MUST be valid for all pointers which are525* stored as SPIR-V SSA values.526*/527struct vtn_type *ptr_type;528529/** The referenced variable, if known530*531* This field may be NULL if the pointer uses a (block_index, offset) pair532* instead of an access chain or if the access chain starts at a deref.533*/534struct vtn_variable *var;535536/** The NIR deref corresponding to this pointer */537nir_deref_instr *deref;538539/** A (block_index, offset) pair representing a UBO or SSBO position. */540struct nir_ssa_def *block_index;541struct nir_ssa_def *offset;542543/* Access qualifiers */544enum gl_access_qualifier access;545};546547struct vtn_variable {548enum vtn_variable_mode mode;549550struct vtn_type *type;551552unsigned descriptor_set;553unsigned binding;554bool explicit_binding;555unsigned offset;556unsigned input_attachment_index;557558nir_variable *var;559560/* If the variable is a struct with a location set on it then this will be561* stored here. This will be used to calculate locations for members that562* don’t have their own explicit location.563*/564int base_location;565566/**567* In some early released versions of GLSLang, it implemented all function568* calls by making copies of all parameters into temporary variables and569* passing those variables into the function. It even did so for samplers570* and images which violates the SPIR-V spec. Unfortunately, two games571* (Talos Principle and Doom) shipped with this old version of GLSLang and572* also happen to pass samplers into functions. Talos Principle received573* an update fairly shortly after release with an updated GLSLang. Doom,574* on the other hand, has never received an update so we need to work575* around this GLSLang issue in SPIR-V -> NIR. Hopefully, we can drop this576* hack at some point in the future.577*/578struct vtn_pointer *copy_prop_sampler;579580/* Access qualifiers. */581enum gl_access_qualifier access;582};583584const struct glsl_type *585vtn_type_get_nir_type(struct vtn_builder *b, struct vtn_type *type,586enum vtn_variable_mode mode);587588struct vtn_image_pointer {589nir_deref_instr *image;590nir_ssa_def *coord;591nir_ssa_def *sample;592nir_ssa_def *lod;593};594595struct vtn_value {596enum vtn_value_type value_type;597598/* Workaround for https://gitlab.freedesktop.org/mesa/mesa/-/issues/3406599* Only set for OpImage / OpSampledImage. Note that this is in addition600* the existence of a NonUniform decoration on this value.*/601uint32_t propagated_non_uniform : 1;602603/* Valid for vtn_value_type_constant to indicate the value is OpConstantNull. */604bool is_null_constant:1;605606const char *name;607struct vtn_decoration *decoration;608struct vtn_type *type;609union {610const char *str;611nir_constant *constant;612struct vtn_pointer *pointer;613struct vtn_image_pointer *image;614struct vtn_function *func;615struct vtn_block *block;616struct vtn_ssa_value *ssa;617vtn_instruction_handler ext_handler;618};619};620621#define VTN_DEC_DECORATION -1622#define VTN_DEC_EXECUTION_MODE -2623#define VTN_DEC_STRUCT_MEMBER0 0624625struct vtn_decoration {626struct vtn_decoration *next;627628/* Specifies how to apply this decoration. Negative values represent a629* decoration or execution mode. (See the VTN_DEC_ #defines above.)630* Non-negative values specify that it applies to a structure member.631*/632int scope;633634const uint32_t *operands;635struct vtn_value *group;636637union {638SpvDecoration decoration;639SpvExecutionMode exec_mode;640};641};642643struct vtn_builder {644nir_builder nb;645646/* Used by vtn_fail to jump back to the beginning of SPIR-V compilation */647jmp_buf fail_jump;648649const uint32_t *spirv;650size_t spirv_word_count;651uint32_t version;652653nir_shader *shader;654struct spirv_to_nir_options *options;655struct vtn_block *block;656657/* Current offset, file, line, and column. Useful for debugging. Set658* automatically by vtn_foreach_instruction.659*/660size_t spirv_offset;661const char *file;662int line, col;663664/*665* In SPIR-V, constants are global, whereas in NIR, the load_const666* instruction we use is per-function. So while we parse each function, we667* keep a hash table of constants we've resolved to nir_ssa_value's so668* far, and we lazily resolve them when we see them used in a function.669*/670struct hash_table *const_table;671672/*673* Map from phi instructions (pointer to the start of the instruction)674* to the variable corresponding to it.675*/676struct hash_table *phi_table;677678/* In Vulkan, when lowering some modes variable access, the derefs of the679* variables are replaced with a resource index intrinsics, leaving the680* variable hanging. This set keeps track of them so they can be filtered681* (and not removed) in nir_remove_dead_variables.682*/683struct set *vars_used_indirectly;684685unsigned num_specializations;686struct nir_spirv_specialization *specializations;687688unsigned value_id_bound;689struct vtn_value *values;690691/* Information on the origin of the SPIR-V */692enum vtn_generator generator_id;693SpvSourceLanguage source_lang;694695/* True if we need to fix up CS OpControlBarrier */696bool wa_glslang_cs_barrier;697698/* Workaround discard bugs in HLSL -> SPIR-V compilers */699bool uses_demote_to_helper_invocation;700bool convert_discard_to_demote;701702gl_shader_stage entry_point_stage;703const char *entry_point_name;704struct vtn_value *entry_point;705struct vtn_value *workgroup_size_builtin;706bool variable_pointers;707708uint32_t *interface_ids;709size_t interface_ids_count;710711struct vtn_function *func;712struct list_head functions;713714/* Current function parameter index */715unsigned func_param_idx;716717/* false by default, set to true by the ContractionOff execution mode */718bool exact;719720/* when a physical memory model is choosen */721bool physical_ptrs;722723/* memory model specified by OpMemoryModel */724unsigned mem_model;725};726727nir_ssa_def *728vtn_pointer_to_ssa(struct vtn_builder *b, struct vtn_pointer *ptr);729struct vtn_pointer *730vtn_pointer_from_ssa(struct vtn_builder *b, nir_ssa_def *ssa,731struct vtn_type *ptr_type);732733static inline struct vtn_value *734vtn_untyped_value(struct vtn_builder *b, uint32_t value_id)735{736vtn_fail_if(value_id >= b->value_id_bound,737"SPIR-V id %u is out-of-bounds", value_id);738return &b->values[value_id];739}740741static inline uint32_t742vtn_id_for_value(struct vtn_builder *b, struct vtn_value *value)743{744vtn_fail_if(value <= b->values, "vtn_value pointer outside the range of valid values");745uint32_t value_id = value - b->values;746vtn_fail_if(value_id >= b->value_id_bound, "vtn_value pointer outside the range of valid values");747return value_id;748}749750/* Consider not using this function directly and instead use751* vtn_push_ssa/vtn_push_pointer so that appropriate applying of752* decorations is handled by common code.753*/754static inline struct vtn_value *755vtn_push_value(struct vtn_builder *b, uint32_t value_id,756enum vtn_value_type value_type)757{758struct vtn_value *val = vtn_untyped_value(b, value_id);759760vtn_fail_if(value_type == vtn_value_type_ssa,761"Do not call vtn_push_value for value_type_ssa. Use "762"vtn_push_ssa_value instead.");763764vtn_fail_if(val->value_type != vtn_value_type_invalid,765"SPIR-V id %u has already been written by another instruction",766value_id);767768val->value_type = value_type;769770return &b->values[value_id];771}772773static inline struct vtn_value *774vtn_value(struct vtn_builder *b, uint32_t value_id,775enum vtn_value_type value_type)776{777struct vtn_value *val = vtn_untyped_value(b, value_id);778vtn_fail_if(val->value_type != value_type,779"SPIR-V id %u is the wrong kind of value", value_id);780return val;781}782783bool784vtn_set_instruction_result_type(struct vtn_builder *b, SpvOp opcode,785const uint32_t *w, unsigned count);786787static inline uint64_t788vtn_constant_uint(struct vtn_builder *b, uint32_t value_id)789{790struct vtn_value *val = vtn_value(b, value_id, vtn_value_type_constant);791792vtn_fail_if(val->type->base_type != vtn_base_type_scalar ||793!glsl_type_is_integer(val->type->type),794"Expected id %u to be an integer constant", value_id);795796switch (glsl_get_bit_size(val->type->type)) {797case 8: return val->constant->values[0].u8;798case 16: return val->constant->values[0].u16;799case 32: return val->constant->values[0].u32;800case 64: return val->constant->values[0].u64;801default: unreachable("Invalid bit size");802}803}804805static inline int64_t806vtn_constant_int(struct vtn_builder *b, uint32_t value_id)807{808struct vtn_value *val = vtn_value(b, value_id, vtn_value_type_constant);809810vtn_fail_if(val->type->base_type != vtn_base_type_scalar ||811!glsl_type_is_integer(val->type->type),812"Expected id %u to be an integer constant", value_id);813814switch (glsl_get_bit_size(val->type->type)) {815case 8: return val->constant->values[0].i8;816case 16: return val->constant->values[0].i16;817case 32: return val->constant->values[0].i32;818case 64: return val->constant->values[0].i64;819default: unreachable("Invalid bit size");820}821}822823static inline struct vtn_type *824vtn_get_value_type(struct vtn_builder *b, uint32_t value_id)825{826struct vtn_value *val = vtn_untyped_value(b, value_id);827vtn_fail_if(val->type == NULL, "Value %u does not have a type", value_id);828return val->type;829}830831static inline struct vtn_type *832vtn_get_type(struct vtn_builder *b, uint32_t value_id)833{834return vtn_value(b, value_id, vtn_value_type_type)->type;835}836837struct vtn_ssa_value *vtn_ssa_value(struct vtn_builder *b, uint32_t value_id);838struct vtn_value *vtn_push_ssa_value(struct vtn_builder *b, uint32_t value_id,839struct vtn_ssa_value *ssa);840841nir_ssa_def *vtn_get_nir_ssa(struct vtn_builder *b, uint32_t value_id);842struct vtn_value *vtn_push_nir_ssa(struct vtn_builder *b, uint32_t value_id,843nir_ssa_def *def);844845struct vtn_value *vtn_push_pointer(struct vtn_builder *b,846uint32_t value_id,847struct vtn_pointer *ptr);848849struct vtn_sampled_image {850nir_deref_instr *image;851nir_deref_instr *sampler;852};853854nir_ssa_def *vtn_sampled_image_to_nir_ssa(struct vtn_builder *b,855struct vtn_sampled_image si);856857void858vtn_copy_value(struct vtn_builder *b, uint32_t src_value_id,859uint32_t dst_value_id);860861struct vtn_ssa_value *vtn_create_ssa_value(struct vtn_builder *b,862const struct glsl_type *type);863864struct vtn_ssa_value *vtn_ssa_transpose(struct vtn_builder *b,865struct vtn_ssa_value *src);866867nir_deref_instr *vtn_nir_deref(struct vtn_builder *b, uint32_t id);868869nir_deref_instr *vtn_pointer_to_deref(struct vtn_builder *b,870struct vtn_pointer *ptr);871nir_ssa_def *872vtn_pointer_to_offset(struct vtn_builder *b, struct vtn_pointer *ptr,873nir_ssa_def **index_out);874875nir_deref_instr *876vtn_get_call_payload_for_location(struct vtn_builder *b, uint32_t location_id);877878struct vtn_ssa_value *879vtn_local_load(struct vtn_builder *b, nir_deref_instr *src,880enum gl_access_qualifier access);881882void vtn_local_store(struct vtn_builder *b, struct vtn_ssa_value *src,883nir_deref_instr *dest,884enum gl_access_qualifier access);885886struct vtn_ssa_value *887vtn_variable_load(struct vtn_builder *b, struct vtn_pointer *src,888enum gl_access_qualifier access);889890void vtn_variable_store(struct vtn_builder *b, struct vtn_ssa_value *src,891struct vtn_pointer *dest, enum gl_access_qualifier access);892893void vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,894const uint32_t *w, unsigned count);895896897typedef void (*vtn_decoration_foreach_cb)(struct vtn_builder *,898struct vtn_value *,899int member,900const struct vtn_decoration *,901void *);902903void vtn_foreach_decoration(struct vtn_builder *b, struct vtn_value *value,904vtn_decoration_foreach_cb cb, void *data);905906typedef void (*vtn_execution_mode_foreach_cb)(struct vtn_builder *,907struct vtn_value *,908const struct vtn_decoration *,909void *);910911void vtn_foreach_execution_mode(struct vtn_builder *b, struct vtn_value *value,912vtn_execution_mode_foreach_cb cb, void *data);913914nir_op vtn_nir_alu_op_for_spirv_opcode(struct vtn_builder *b,915SpvOp opcode, bool *swap, bool *exact,916unsigned src_bit_size, unsigned dst_bit_size);917918void vtn_handle_alu(struct vtn_builder *b, SpvOp opcode,919const uint32_t *w, unsigned count);920921void vtn_handle_bitcast(struct vtn_builder *b, const uint32_t *w,922unsigned count);923924void vtn_handle_no_contraction(struct vtn_builder *b, struct vtn_value *val);925926void vtn_handle_subgroup(struct vtn_builder *b, SpvOp opcode,927const uint32_t *w, unsigned count);928929bool vtn_handle_glsl450_instruction(struct vtn_builder *b, SpvOp ext_opcode,930const uint32_t *words, unsigned count);931932bool vtn_handle_opencl_instruction(struct vtn_builder *b, SpvOp ext_opcode,933const uint32_t *words, unsigned count);934bool vtn_handle_opencl_core_instruction(struct vtn_builder *b, SpvOp opcode,935const uint32_t *w, unsigned count);936937struct vtn_builder* vtn_create_builder(const uint32_t *words, size_t word_count,938gl_shader_stage stage, const char *entry_point_name,939const struct spirv_to_nir_options *options);940941void vtn_handle_entry_point(struct vtn_builder *b, const uint32_t *w,942unsigned count);943944void vtn_handle_decoration(struct vtn_builder *b, SpvOp opcode,945const uint32_t *w, unsigned count);946947enum vtn_variable_mode vtn_storage_class_to_mode(struct vtn_builder *b,948SpvStorageClass class,949struct vtn_type *interface_type,950nir_variable_mode *nir_mode_out);951952nir_address_format vtn_mode_to_address_format(struct vtn_builder *b,953enum vtn_variable_mode);954955nir_rounding_mode vtn_rounding_mode_to_nir(struct vtn_builder *b,956SpvFPRoundingMode mode);957958static inline uint32_t959vtn_align_u32(uint32_t v, uint32_t a)960{961assert(a != 0 && a == (a & -((int32_t) a)));962return (v + a - 1) & ~(a - 1);963}964965static inline uint64_t966vtn_u64_literal(const uint32_t *w)967{968return (uint64_t)w[1] << 32 | w[0];969}970971bool vtn_handle_amd_gcn_shader_instruction(struct vtn_builder *b, SpvOp ext_opcode,972const uint32_t *words, unsigned count);973974bool vtn_handle_amd_shader_ballot_instruction(struct vtn_builder *b, SpvOp ext_opcode,975const uint32_t *w, unsigned count);976977bool vtn_handle_amd_shader_trinary_minmax_instruction(struct vtn_builder *b, SpvOp ext_opcode,978const uint32_t *words, unsigned count);979980bool vtn_handle_amd_shader_explicit_vertex_parameter_instruction(struct vtn_builder *b,981SpvOp ext_opcode,982const uint32_t *words,983unsigned count);984985SpvMemorySemanticsMask vtn_mode_to_memory_semantics(enum vtn_variable_mode mode);986987void vtn_emit_memory_barrier(struct vtn_builder *b, SpvScope scope,988SpvMemorySemanticsMask semantics);989990static inline int991cmp_uint32_t(const void *pa, const void *pb)992{993uint32_t a = *((const uint32_t *)pa);994uint32_t b = *((const uint32_t *)pb);995if (a < b)996return -1;997if (a > b)998return 1;999return 0;1000}10011002#endif /* _VTN_PRIVATE_H_ */100310041005