101e04c3fSmrg/* 201e04c3fSmrg * Copyright © 2015 Intel Corporation 301e04c3fSmrg * 401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 501e04c3fSmrg * copy of this software and associated documentation files (the "Software"), 601e04c3fSmrg * to deal in the Software without restriction, including without limitation 701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the 901e04c3fSmrg * Software is furnished to do so, subject to the following conditions: 1001e04c3fSmrg * 1101e04c3fSmrg * The above copyright notice and this permission notice (including the next 1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the 1301e04c3fSmrg * Software. 1401e04c3fSmrg * 1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 2101e04c3fSmrg * IN THE SOFTWARE. 2201e04c3fSmrg * 2301e04c3fSmrg * Authors: 2401e04c3fSmrg * Jason Ekstrand (jason@jlekstrand.net) 2501e04c3fSmrg * 2601e04c3fSmrg */ 2701e04c3fSmrg 2801e04c3fSmrg#ifndef _VTN_PRIVATE_H_ 2901e04c3fSmrg#define _VTN_PRIVATE_H_ 3001e04c3fSmrg 3101e04c3fSmrg#include <setjmp.h> 3201e04c3fSmrg 3301e04c3fSmrg#include "nir/nir.h" 3401e04c3fSmrg#include "nir/nir_builder.h" 3501e04c3fSmrg#include "util/u_dynarray.h" 3601e04c3fSmrg#include "nir_spirv.h" 3701e04c3fSmrg#include "spirv.h" 387ec681f3Smrg#include "vtn_generator_ids.h" 3901e04c3fSmrg 4001e04c3fSmrgstruct vtn_builder; 4101e04c3fSmrgstruct vtn_decoration; 4201e04c3fSmrg 437ec681f3Smrg/* setjmp/longjmp is broken on MinGW: https://sourceforge.net/p/mingw-w64/bugs/406/ */ 447ec681f3Smrg#ifdef __MINGW32__ 457ec681f3Smrg #define vtn_setjmp __builtin_setjmp 467ec681f3Smrg #define vtn_longjmp __builtin_longjmp 477ec681f3Smrg#else 487ec681f3Smrg #define vtn_setjmp setjmp 497ec681f3Smrg #define vtn_longjmp longjmp 507ec681f3Smrg#endif 517ec681f3Smrg 5201e04c3fSmrgvoid vtn_log(struct vtn_builder *b, enum nir_spirv_debug_level level, 5301e04c3fSmrg size_t spirv_offset, const char *message); 5401e04c3fSmrg 5501e04c3fSmrgvoid vtn_logf(struct vtn_builder *b, enum nir_spirv_debug_level level, 5601e04c3fSmrg size_t spirv_offset, const char *fmt, ...) PRINTFLIKE(4, 5); 5701e04c3fSmrg 5801e04c3fSmrg#define vtn_info(...) vtn_logf(b, NIR_SPIRV_DEBUG_LEVEL_INFO, 0, __VA_ARGS__) 5901e04c3fSmrg 6001e04c3fSmrgvoid _vtn_warn(struct vtn_builder *b, const char *file, unsigned line, 6101e04c3fSmrg const char *fmt, ...) PRINTFLIKE(4, 5); 6201e04c3fSmrg#define vtn_warn(...) _vtn_warn(b, __FILE__, __LINE__, __VA_ARGS__) 6301e04c3fSmrg 6401e04c3fSmrgvoid _vtn_err(struct vtn_builder *b, const char *file, unsigned line, 6501e04c3fSmrg const char *fmt, ...) PRINTFLIKE(4, 5); 6601e04c3fSmrg#define vtn_err(...) _vtn_err(b, __FILE__, __LINE__, __VA_ARGS__) 6701e04c3fSmrg 6801e04c3fSmrg/** Fail SPIR-V parsing 6901e04c3fSmrg * 7001e04c3fSmrg * This function logs an error and then bails out of the shader compile using 7101e04c3fSmrg * longjmp. This being safe relies on two things: 7201e04c3fSmrg * 7301e04c3fSmrg * 1) We must guarantee that setjmp is called after allocating the builder 7401e04c3fSmrg * and setting up b->debug (so that logging works) but before before any 7501e04c3fSmrg * errors have a chance to occur. 7601e04c3fSmrg * 7701e04c3fSmrg * 2) While doing the SPIR-V -> NIR conversion, we need to be careful to 7801e04c3fSmrg * ensure that all heap allocations happen through ralloc and are parented 7901e04c3fSmrg * to the builder. This way they will get properly cleaned up on error. 8001e04c3fSmrg * 8101e04c3fSmrg * 3) We must ensure that _vtn_fail is never called while a mutex lock or a 8201e04c3fSmrg * reference to any other resource is held with the exception of ralloc 8301e04c3fSmrg * objects which are parented to the builder. 8401e04c3fSmrg * 8501e04c3fSmrg * So long as these two things continue to hold, we can easily longjmp back to 8601e04c3fSmrg * spirv_to_nir(), clean up the builder, and return NULL. 8701e04c3fSmrg */ 8801e04c3fSmrgNORETURN void 8901e04c3fSmrg_vtn_fail(struct vtn_builder *b, const char *file, unsigned line, 9001e04c3fSmrg const char *fmt, ...) PRINTFLIKE(4, 5); 9101e04c3fSmrg 9201e04c3fSmrg#define vtn_fail(...) _vtn_fail(b, __FILE__, __LINE__, __VA_ARGS__) 9301e04c3fSmrg 9401e04c3fSmrg/** Fail if the given expression evaluates to true */ 9501e04c3fSmrg#define vtn_fail_if(expr, ...) \ 9601e04c3fSmrg do { \ 9701e04c3fSmrg if (unlikely(expr)) \ 9801e04c3fSmrg vtn_fail(__VA_ARGS__); \ 9901e04c3fSmrg } while (0) 10001e04c3fSmrg 1017e102996Smaya#define _vtn_fail_with(t, msg, v) \ 1027e102996Smaya vtn_fail("%s: %s (%u)\n", msg, spirv_ ## t ## _to_string(v), v) 1037e102996Smaya 1047e102996Smaya#define vtn_fail_with_decoration(msg, v) _vtn_fail_with(decoration, msg, v) 1057e102996Smaya#define vtn_fail_with_opcode(msg, v) _vtn_fail_with(op, msg, v) 1067e102996Smaya 10701e04c3fSmrg/** Assert that a condition is true and, if it isn't, vtn_fail 10801e04c3fSmrg * 10901e04c3fSmrg * This macro is transitional only and should not be used in new code. Use 11001e04c3fSmrg * vtn_fail_if and provide a real message instead. 11101e04c3fSmrg */ 11201e04c3fSmrg#define vtn_assert(expr) \ 11301e04c3fSmrg do { \ 11401e04c3fSmrg if (!likely(expr)) \ 11501e04c3fSmrg vtn_fail("%s", #expr); \ 11601e04c3fSmrg } while (0) 11701e04c3fSmrg 11801e04c3fSmrgenum vtn_value_type { 11901e04c3fSmrg vtn_value_type_invalid = 0, 12001e04c3fSmrg vtn_value_type_undef, 12101e04c3fSmrg vtn_value_type_string, 12201e04c3fSmrg vtn_value_type_decoration_group, 12301e04c3fSmrg vtn_value_type_type, 12401e04c3fSmrg vtn_value_type_constant, 12501e04c3fSmrg vtn_value_type_pointer, 12601e04c3fSmrg vtn_value_type_function, 12701e04c3fSmrg vtn_value_type_block, 12801e04c3fSmrg vtn_value_type_ssa, 12901e04c3fSmrg vtn_value_type_extension, 13001e04c3fSmrg vtn_value_type_image_pointer, 13101e04c3fSmrg}; 13201e04c3fSmrg 13301e04c3fSmrgenum vtn_branch_type { 13401e04c3fSmrg vtn_branch_type_none, 1357ec681f3Smrg vtn_branch_type_if_merge, 13601e04c3fSmrg vtn_branch_type_switch_break, 13701e04c3fSmrg vtn_branch_type_switch_fallthrough, 13801e04c3fSmrg vtn_branch_type_loop_break, 13901e04c3fSmrg vtn_branch_type_loop_continue, 1407ec681f3Smrg vtn_branch_type_loop_back_edge, 14101e04c3fSmrg vtn_branch_type_discard, 1427ec681f3Smrg vtn_branch_type_terminate_invocation, 1437ec681f3Smrg vtn_branch_type_ignore_intersection, 1447ec681f3Smrg vtn_branch_type_terminate_ray, 14501e04c3fSmrg vtn_branch_type_return, 14601e04c3fSmrg}; 14701e04c3fSmrg 14801e04c3fSmrgenum vtn_cf_node_type { 14901e04c3fSmrg vtn_cf_node_type_block, 15001e04c3fSmrg vtn_cf_node_type_if, 15101e04c3fSmrg vtn_cf_node_type_loop, 1527ec681f3Smrg vtn_cf_node_type_case, 15301e04c3fSmrg vtn_cf_node_type_switch, 1547ec681f3Smrg vtn_cf_node_type_function, 15501e04c3fSmrg}; 15601e04c3fSmrg 15701e04c3fSmrgstruct vtn_cf_node { 15801e04c3fSmrg struct list_head link; 1597ec681f3Smrg struct vtn_cf_node *parent; 16001e04c3fSmrg enum vtn_cf_node_type type; 16101e04c3fSmrg}; 16201e04c3fSmrg 16301e04c3fSmrgstruct vtn_loop { 16401e04c3fSmrg struct vtn_cf_node node; 16501e04c3fSmrg 16601e04c3fSmrg /* The main body of the loop */ 16701e04c3fSmrg struct list_head body; 16801e04c3fSmrg 16901e04c3fSmrg /* The "continue" part of the loop. This gets executed after the body 17001e04c3fSmrg * and is where you go when you hit a continue. 17101e04c3fSmrg */ 17201e04c3fSmrg struct list_head cont_body; 17301e04c3fSmrg 1747ec681f3Smrg struct vtn_block *header_block; 1757ec681f3Smrg struct vtn_block *cont_block; 1767ec681f3Smrg struct vtn_block *break_block; 1777ec681f3Smrg 17801e04c3fSmrg SpvLoopControlMask control; 17901e04c3fSmrg}; 18001e04c3fSmrg 18101e04c3fSmrgstruct vtn_if { 18201e04c3fSmrg struct vtn_cf_node node; 18301e04c3fSmrg 18401e04c3fSmrg enum vtn_branch_type then_type; 18501e04c3fSmrg struct list_head then_body; 18601e04c3fSmrg 18701e04c3fSmrg enum vtn_branch_type else_type; 18801e04c3fSmrg struct list_head else_body; 18901e04c3fSmrg 1907ec681f3Smrg struct vtn_block *header_block; 1917ec681f3Smrg struct vtn_block *merge_block; 1927ec681f3Smrg 19301e04c3fSmrg SpvSelectionControlMask control; 19401e04c3fSmrg}; 19501e04c3fSmrg 19601e04c3fSmrgstruct vtn_case { 1977ec681f3Smrg struct vtn_cf_node node; 19801e04c3fSmrg 1997ec681f3Smrg struct vtn_block *block; 20001e04c3fSmrg 2017ec681f3Smrg enum vtn_branch_type type; 2027ec681f3Smrg struct list_head body; 20301e04c3fSmrg 20401e04c3fSmrg /* The fallthrough case, if any */ 20501e04c3fSmrg struct vtn_case *fallthrough; 20601e04c3fSmrg 20701e04c3fSmrg /* The uint32_t values that map to this case */ 20801e04c3fSmrg struct util_dynarray values; 20901e04c3fSmrg 21001e04c3fSmrg /* True if this is the default case */ 21101e04c3fSmrg bool is_default; 21201e04c3fSmrg 21301e04c3fSmrg /* Initialized to false; used when sorting the list of cases */ 21401e04c3fSmrg bool visited; 21501e04c3fSmrg}; 21601e04c3fSmrg 21701e04c3fSmrgstruct vtn_switch { 21801e04c3fSmrg struct vtn_cf_node node; 21901e04c3fSmrg 22001e04c3fSmrg uint32_t selector; 22101e04c3fSmrg 22201e04c3fSmrg struct list_head cases; 2237ec681f3Smrg 2247ec681f3Smrg struct vtn_block *break_block; 22501e04c3fSmrg}; 22601e04c3fSmrg 22701e04c3fSmrgstruct vtn_block { 22801e04c3fSmrg struct vtn_cf_node node; 22901e04c3fSmrg 23001e04c3fSmrg /** A pointer to the label instruction */ 23101e04c3fSmrg const uint32_t *label; 23201e04c3fSmrg 23301e04c3fSmrg /** A pointer to the merge instruction (or NULL if non exists) */ 23401e04c3fSmrg const uint32_t *merge; 23501e04c3fSmrg 23601e04c3fSmrg /** A pointer to the branch instruction that ends this block */ 23701e04c3fSmrg const uint32_t *branch; 23801e04c3fSmrg 23901e04c3fSmrg enum vtn_branch_type branch_type; 24001e04c3fSmrg 2417ec681f3Smrg /* The CF node for which this is a merge target 2427ec681f3Smrg * 2437ec681f3Smrg * The SPIR-V spec requires that any given block can be the merge target 2447ec681f3Smrg * for at most one merge instruction. If this block is a merge target, 2457ec681f3Smrg * this points back to the block containing that merge instruction. 2467ec681f3Smrg */ 2477ec681f3Smrg struct vtn_cf_node *merge_cf_node; 2487ec681f3Smrg 24901e04c3fSmrg /** Points to the loop that this block starts (if it starts a loop) */ 25001e04c3fSmrg struct vtn_loop *loop; 25101e04c3fSmrg 25201e04c3fSmrg /** Points to the switch case started by this block (if any) */ 25301e04c3fSmrg struct vtn_case *switch_case; 25401e04c3fSmrg 25501e04c3fSmrg /** Every block ends in a nop intrinsic so that we can find it again */ 25601e04c3fSmrg nir_intrinsic_instr *end_nop; 2577ec681f3Smrg 2587ec681f3Smrg /** attached nir_block */ 2597ec681f3Smrg struct nir_block *block; 26001e04c3fSmrg}; 26101e04c3fSmrg 26201e04c3fSmrgstruct vtn_function { 2637ec681f3Smrg struct vtn_cf_node node; 26401e04c3fSmrg 26501e04c3fSmrg struct vtn_type *type; 26601e04c3fSmrg 26701e04c3fSmrg bool referenced; 26801e04c3fSmrg bool emitted; 26901e04c3fSmrg 2707ec681f3Smrg nir_function *nir_func; 27101e04c3fSmrg struct vtn_block *start_block; 27201e04c3fSmrg 27301e04c3fSmrg struct list_head body; 27401e04c3fSmrg 27501e04c3fSmrg const uint32_t *end; 27601e04c3fSmrg 27701e04c3fSmrg SpvFunctionControlMask control; 27801e04c3fSmrg}; 27901e04c3fSmrg 2807ec681f3Smrg#define VTN_DECL_CF_NODE_CAST(_type) \ 2817ec681f3Smrgstatic inline struct vtn_##_type * \ 2827ec681f3Smrgvtn_cf_node_as_##_type(struct vtn_cf_node *node) \ 2837ec681f3Smrg{ \ 2847ec681f3Smrg assert(node->type == vtn_cf_node_type_##_type); \ 2857ec681f3Smrg return (struct vtn_##_type *)node; \ 2867ec681f3Smrg} 2877ec681f3Smrg 2887ec681f3SmrgVTN_DECL_CF_NODE_CAST(block) 2897ec681f3SmrgVTN_DECL_CF_NODE_CAST(loop) 2907ec681f3SmrgVTN_DECL_CF_NODE_CAST(if) 2917ec681f3SmrgVTN_DECL_CF_NODE_CAST(case) 2927ec681f3SmrgVTN_DECL_CF_NODE_CAST(switch) 2937ec681f3SmrgVTN_DECL_CF_NODE_CAST(function) 2947ec681f3Smrg 2957ec681f3Smrg#define vtn_foreach_cf_node(node, cf_list) \ 2967ec681f3Smrg list_for_each_entry(struct vtn_cf_node, node, cf_list, link) 2977ec681f3Smrg 29801e04c3fSmrgtypedef bool (*vtn_instruction_handler)(struct vtn_builder *, SpvOp, 29901e04c3fSmrg const uint32_t *, unsigned); 30001e04c3fSmrg 30101e04c3fSmrgvoid vtn_build_cfg(struct vtn_builder *b, const uint32_t *words, 30201e04c3fSmrg const uint32_t *end); 30301e04c3fSmrgvoid vtn_function_emit(struct vtn_builder *b, struct vtn_function *func, 30401e04c3fSmrg vtn_instruction_handler instruction_handler); 30501e04c3fSmrgvoid vtn_handle_function_call(struct vtn_builder *b, SpvOp opcode, 30601e04c3fSmrg const uint32_t *w, unsigned count); 30701e04c3fSmrg 30801e04c3fSmrgconst uint32_t * 30901e04c3fSmrgvtn_foreach_instruction(struct vtn_builder *b, const uint32_t *start, 31001e04c3fSmrg const uint32_t *end, vtn_instruction_handler handler); 31101e04c3fSmrg 31201e04c3fSmrgstruct vtn_ssa_value { 31301e04c3fSmrg union { 31401e04c3fSmrg nir_ssa_def *def; 31501e04c3fSmrg struct vtn_ssa_value **elems; 31601e04c3fSmrg }; 31701e04c3fSmrg 31801e04c3fSmrg /* For matrices, if this is non-NULL, then this value is actually the 31901e04c3fSmrg * transpose of some other value. The value that `transposed` points to 32001e04c3fSmrg * always dominates this value. 32101e04c3fSmrg */ 32201e04c3fSmrg struct vtn_ssa_value *transposed; 32301e04c3fSmrg 32401e04c3fSmrg const struct glsl_type *type; 32501e04c3fSmrg}; 32601e04c3fSmrg 32701e04c3fSmrgenum vtn_base_type { 32801e04c3fSmrg vtn_base_type_void, 32901e04c3fSmrg vtn_base_type_scalar, 33001e04c3fSmrg vtn_base_type_vector, 33101e04c3fSmrg vtn_base_type_matrix, 33201e04c3fSmrg vtn_base_type_array, 33301e04c3fSmrg vtn_base_type_struct, 33401e04c3fSmrg vtn_base_type_pointer, 33501e04c3fSmrg vtn_base_type_image, 33601e04c3fSmrg vtn_base_type_sampler, 33701e04c3fSmrg vtn_base_type_sampled_image, 3387ec681f3Smrg vtn_base_type_accel_struct, 33901e04c3fSmrg vtn_base_type_function, 3407ec681f3Smrg vtn_base_type_event, 34101e04c3fSmrg}; 34201e04c3fSmrg 34301e04c3fSmrgstruct vtn_type { 34401e04c3fSmrg enum vtn_base_type base_type; 34501e04c3fSmrg 34601e04c3fSmrg const struct glsl_type *type; 34701e04c3fSmrg 34801e04c3fSmrg /* The SPIR-V id of the given type. */ 34901e04c3fSmrg uint32_t id; 35001e04c3fSmrg 35101e04c3fSmrg /* Specifies the length of complex types. 35201e04c3fSmrg * 35301e04c3fSmrg * For Workgroup pointers, this is the size of the referenced type. 35401e04c3fSmrg */ 35501e04c3fSmrg unsigned length; 35601e04c3fSmrg 35701e04c3fSmrg /* for arrays, matrices and pointers, the array stride */ 35801e04c3fSmrg unsigned stride; 35901e04c3fSmrg 36001e04c3fSmrg /* Access qualifiers */ 36101e04c3fSmrg enum gl_access_qualifier access; 36201e04c3fSmrg 36301e04c3fSmrg union { 36401e04c3fSmrg /* Members for scalar, vector, and array-like types */ 36501e04c3fSmrg struct { 36601e04c3fSmrg /* for arrays, the vtn_type for the elements of the array */ 36701e04c3fSmrg struct vtn_type *array_element; 36801e04c3fSmrg 36901e04c3fSmrg /* for matrices, whether the matrix is stored row-major */ 37001e04c3fSmrg bool row_major:1; 37101e04c3fSmrg 37201e04c3fSmrg /* Whether this type, or a parent type, has been decorated as a 37301e04c3fSmrg * builtin 37401e04c3fSmrg */ 37501e04c3fSmrg bool is_builtin:1; 37601e04c3fSmrg 37701e04c3fSmrg /* Which built-in to use */ 37801e04c3fSmrg SpvBuiltIn builtin; 37901e04c3fSmrg }; 38001e04c3fSmrg 38101e04c3fSmrg /* Members for struct types */ 38201e04c3fSmrg struct { 38301e04c3fSmrg /* for structures, the vtn_type for each member */ 38401e04c3fSmrg struct vtn_type **members; 38501e04c3fSmrg 38601e04c3fSmrg /* for structs, the offset of each member */ 38701e04c3fSmrg unsigned *offsets; 38801e04c3fSmrg 38901e04c3fSmrg /* for structs, whether it was decorated as a "non-SSBO-like" block */ 39001e04c3fSmrg bool block:1; 39101e04c3fSmrg 39201e04c3fSmrg /* for structs, whether it was decorated as an "SSBO-like" block */ 39301e04c3fSmrg bool buffer_block:1; 39401e04c3fSmrg 39501e04c3fSmrg /* for structs with block == true, whether this is a builtin block 39601e04c3fSmrg * (i.e. a block that contains only builtins). 39701e04c3fSmrg */ 39801e04c3fSmrg bool builtin_block:1; 3997e102996Smaya 4007e102996Smaya /* for structs and unions it specifies the minimum alignment of the 4017e102996Smaya * members. 0 means packed. 4027e102996Smaya * 4037e102996Smaya * Set by CPacked and Alignment Decorations in kernels. 4047e102996Smaya */ 4057e102996Smaya bool packed:1; 40601e04c3fSmrg }; 40701e04c3fSmrg 40801e04c3fSmrg /* Members for pointer types */ 40901e04c3fSmrg struct { 41001e04c3fSmrg /* For pointers, the vtn_type for dereferenced type */ 41101e04c3fSmrg struct vtn_type *deref; 41201e04c3fSmrg 41301e04c3fSmrg /* Storage class for pointers */ 41401e04c3fSmrg SpvStorageClass storage_class; 41501e04c3fSmrg 41601e04c3fSmrg /* Required alignment for pointers */ 41701e04c3fSmrg uint32_t align; 41801e04c3fSmrg }; 41901e04c3fSmrg 42001e04c3fSmrg /* Members for image types */ 42101e04c3fSmrg struct { 4227ec681f3Smrg /* GLSL image type for this type. This is not to be confused with 4237ec681f3Smrg * vtn_type::type which is actually going to be the GLSL type for a 4247ec681f3Smrg * pointer to an image, likely a uint32_t. 4257ec681f3Smrg */ 4267ec681f3Smrg const struct glsl_type *glsl_image; 42701e04c3fSmrg 42801e04c3fSmrg /* Image format for image_load_store type images */ 42901e04c3fSmrg unsigned image_format; 43001e04c3fSmrg 43101e04c3fSmrg /* Access qualifier for storage images */ 43201e04c3fSmrg SpvAccessQualifier access_qualifier; 43301e04c3fSmrg }; 43401e04c3fSmrg 43501e04c3fSmrg /* Members for sampled image types */ 43601e04c3fSmrg struct { 43701e04c3fSmrg /* For sampled images, the image type */ 43801e04c3fSmrg struct vtn_type *image; 43901e04c3fSmrg }; 44001e04c3fSmrg 44101e04c3fSmrg /* Members for function types */ 44201e04c3fSmrg struct { 44301e04c3fSmrg /* For functions, the vtn_type for each parameter */ 44401e04c3fSmrg struct vtn_type **params; 44501e04c3fSmrg 44601e04c3fSmrg /* Return type for functions */ 44701e04c3fSmrg struct vtn_type *return_type; 44801e04c3fSmrg }; 44901e04c3fSmrg }; 45001e04c3fSmrg}; 45101e04c3fSmrg 4527e102996Smayabool vtn_type_contains_block(struct vtn_builder *b, struct vtn_type *type); 4537e102996Smaya 45401e04c3fSmrgbool vtn_types_compatible(struct vtn_builder *b, 45501e04c3fSmrg struct vtn_type *t1, struct vtn_type *t2); 45601e04c3fSmrg 4577ec681f3Smrgstruct vtn_type *vtn_type_without_array(struct vtn_type *type); 4587ec681f3Smrg 45901e04c3fSmrgstruct vtn_variable; 46001e04c3fSmrg 46101e04c3fSmrgenum vtn_access_mode { 46201e04c3fSmrg vtn_access_mode_id, 46301e04c3fSmrg vtn_access_mode_literal, 46401e04c3fSmrg}; 46501e04c3fSmrg 46601e04c3fSmrgstruct vtn_access_link { 46701e04c3fSmrg enum vtn_access_mode mode; 4687e102996Smaya int64_t id; 46901e04c3fSmrg}; 47001e04c3fSmrg 47101e04c3fSmrgstruct vtn_access_chain { 47201e04c3fSmrg uint32_t length; 47301e04c3fSmrg 47401e04c3fSmrg /** Whether or not to treat the base pointer as an array. This is only 47501e04c3fSmrg * true if this access chain came from an OpPtrAccessChain. 47601e04c3fSmrg */ 47701e04c3fSmrg bool ptr_as_array; 47801e04c3fSmrg 4797e102996Smaya /* Access qualifiers */ 4807e102996Smaya enum gl_access_qualifier access; 4817e102996Smaya 48201e04c3fSmrg /** Struct elements and array offsets. 48301e04c3fSmrg * 48401e04c3fSmrg * This is an array of 1 so that it can conveniently be created on the 48501e04c3fSmrg * stack but the real length is given by the length field. 48601e04c3fSmrg */ 48701e04c3fSmrg struct vtn_access_link link[1]; 48801e04c3fSmrg}; 48901e04c3fSmrg 49001e04c3fSmrgenum vtn_variable_mode { 4917e102996Smaya vtn_variable_mode_function, 4927e102996Smaya vtn_variable_mode_private, 49301e04c3fSmrg vtn_variable_mode_uniform, 4947ec681f3Smrg vtn_variable_mode_atomic_counter, 49501e04c3fSmrg vtn_variable_mode_ubo, 49601e04c3fSmrg vtn_variable_mode_ssbo, 4977e102996Smaya vtn_variable_mode_phys_ssbo, 49801e04c3fSmrg vtn_variable_mode_push_constant, 49901e04c3fSmrg vtn_variable_mode_workgroup, 5007e102996Smaya vtn_variable_mode_cross_workgroup, 5017ec681f3Smrg vtn_variable_mode_generic, 5027ec681f3Smrg vtn_variable_mode_constant, 50301e04c3fSmrg vtn_variable_mode_input, 50401e04c3fSmrg vtn_variable_mode_output, 5057ec681f3Smrg vtn_variable_mode_image, 5067ec681f3Smrg vtn_variable_mode_accel_struct, 5077ec681f3Smrg vtn_variable_mode_call_data, 5087ec681f3Smrg vtn_variable_mode_call_data_in, 5097ec681f3Smrg vtn_variable_mode_ray_payload, 5107ec681f3Smrg vtn_variable_mode_ray_payload_in, 5117ec681f3Smrg vtn_variable_mode_hit_attrib, 5127ec681f3Smrg vtn_variable_mode_shader_record, 51301e04c3fSmrg}; 51401e04c3fSmrg 51501e04c3fSmrgstruct vtn_pointer { 51601e04c3fSmrg /** The variable mode for the referenced data */ 51701e04c3fSmrg enum vtn_variable_mode mode; 51801e04c3fSmrg 51901e04c3fSmrg /** The dereferenced type of this pointer */ 52001e04c3fSmrg struct vtn_type *type; 52101e04c3fSmrg 52201e04c3fSmrg /** The pointer type of this pointer 52301e04c3fSmrg * 52401e04c3fSmrg * This may be NULL for some temporary pointers constructed as part of a 52501e04c3fSmrg * large load, store, or copy. It MUST be valid for all pointers which are 52601e04c3fSmrg * stored as SPIR-V SSA values. 52701e04c3fSmrg */ 52801e04c3fSmrg struct vtn_type *ptr_type; 52901e04c3fSmrg 53001e04c3fSmrg /** The referenced variable, if known 53101e04c3fSmrg * 53201e04c3fSmrg * This field may be NULL if the pointer uses a (block_index, offset) pair 53301e04c3fSmrg * instead of an access chain or if the access chain starts at a deref. 53401e04c3fSmrg */ 53501e04c3fSmrg struct vtn_variable *var; 53601e04c3fSmrg 5377e102996Smaya /** The NIR deref corresponding to this pointer */ 53801e04c3fSmrg nir_deref_instr *deref; 53901e04c3fSmrg 54001e04c3fSmrg /** A (block_index, offset) pair representing a UBO or SSBO position. */ 54101e04c3fSmrg struct nir_ssa_def *block_index; 54201e04c3fSmrg struct nir_ssa_def *offset; 54301e04c3fSmrg 54401e04c3fSmrg /* Access qualifiers */ 54501e04c3fSmrg enum gl_access_qualifier access; 54601e04c3fSmrg}; 54701e04c3fSmrg 54801e04c3fSmrgstruct vtn_variable { 54901e04c3fSmrg enum vtn_variable_mode mode; 55001e04c3fSmrg 55101e04c3fSmrg struct vtn_type *type; 55201e04c3fSmrg 55301e04c3fSmrg unsigned descriptor_set; 55401e04c3fSmrg unsigned binding; 55501e04c3fSmrg bool explicit_binding; 55601e04c3fSmrg unsigned offset; 55701e04c3fSmrg unsigned input_attachment_index; 55801e04c3fSmrg 55901e04c3fSmrg nir_variable *var; 56001e04c3fSmrg 5617e102996Smaya /* If the variable is a struct with a location set on it then this will be 5627e102996Smaya * stored here. This will be used to calculate locations for members that 5637e102996Smaya * don’t have their own explicit location. 5647e102996Smaya */ 5657e102996Smaya int base_location; 5667e102996Smaya 56701e04c3fSmrg /** 56801e04c3fSmrg * In some early released versions of GLSLang, it implemented all function 56901e04c3fSmrg * calls by making copies of all parameters into temporary variables and 57001e04c3fSmrg * passing those variables into the function. It even did so for samplers 57101e04c3fSmrg * and images which violates the SPIR-V spec. Unfortunately, two games 57201e04c3fSmrg * (Talos Principle and Doom) shipped with this old version of GLSLang and 57301e04c3fSmrg * also happen to pass samplers into functions. Talos Principle received 57401e04c3fSmrg * an update fairly shortly after release with an updated GLSLang. Doom, 57501e04c3fSmrg * on the other hand, has never received an update so we need to work 57601e04c3fSmrg * around this GLSLang issue in SPIR-V -> NIR. Hopefully, we can drop this 57701e04c3fSmrg * hack at some point in the future. 57801e04c3fSmrg */ 57901e04c3fSmrg struct vtn_pointer *copy_prop_sampler; 58001e04c3fSmrg 58101e04c3fSmrg /* Access qualifiers. */ 58201e04c3fSmrg enum gl_access_qualifier access; 58301e04c3fSmrg}; 58401e04c3fSmrg 5857ec681f3Smrgconst struct glsl_type * 5867ec681f3Smrgvtn_type_get_nir_type(struct vtn_builder *b, struct vtn_type *type, 5877ec681f3Smrg enum vtn_variable_mode mode); 5887ec681f3Smrg 58901e04c3fSmrgstruct vtn_image_pointer { 5907ec681f3Smrg nir_deref_instr *image; 59101e04c3fSmrg nir_ssa_def *coord; 59201e04c3fSmrg nir_ssa_def *sample; 5937ec681f3Smrg nir_ssa_def *lod; 59401e04c3fSmrg}; 59501e04c3fSmrg 59601e04c3fSmrgstruct vtn_value { 59701e04c3fSmrg enum vtn_value_type value_type; 5987ec681f3Smrg 5997ec681f3Smrg /* Workaround for https://gitlab.freedesktop.org/mesa/mesa/-/issues/3406 6007ec681f3Smrg * Only set for OpImage / OpSampledImage. Note that this is in addition 6017ec681f3Smrg * the existence of a NonUniform decoration on this value.*/ 6027ec681f3Smrg uint32_t propagated_non_uniform : 1; 6037ec681f3Smrg 6047ec681f3Smrg /* Valid for vtn_value_type_constant to indicate the value is OpConstantNull. */ 6057ec681f3Smrg bool is_null_constant:1; 6067ec681f3Smrg 6077ec681f3Smrg /* Valid when all the members of the value are undef. */ 6087ec681f3Smrg bool is_undef_constant:1; 6097ec681f3Smrg 61001e04c3fSmrg const char *name; 61101e04c3fSmrg struct vtn_decoration *decoration; 61201e04c3fSmrg struct vtn_type *type; 61301e04c3fSmrg union { 6147ec681f3Smrg const char *str; 61501e04c3fSmrg nir_constant *constant; 61601e04c3fSmrg struct vtn_pointer *pointer; 61701e04c3fSmrg struct vtn_image_pointer *image; 61801e04c3fSmrg struct vtn_function *func; 61901e04c3fSmrg struct vtn_block *block; 62001e04c3fSmrg struct vtn_ssa_value *ssa; 62101e04c3fSmrg vtn_instruction_handler ext_handler; 62201e04c3fSmrg }; 62301e04c3fSmrg}; 62401e04c3fSmrg 62501e04c3fSmrg#define VTN_DEC_DECORATION -1 62601e04c3fSmrg#define VTN_DEC_EXECUTION_MODE -2 62701e04c3fSmrg#define VTN_DEC_STRUCT_MEMBER0 0 62801e04c3fSmrg 62901e04c3fSmrgstruct vtn_decoration { 63001e04c3fSmrg struct vtn_decoration *next; 63101e04c3fSmrg 63201e04c3fSmrg /* Specifies how to apply this decoration. Negative values represent a 63301e04c3fSmrg * decoration or execution mode. (See the VTN_DEC_ #defines above.) 63401e04c3fSmrg * Non-negative values specify that it applies to a structure member. 63501e04c3fSmrg */ 63601e04c3fSmrg int scope; 63701e04c3fSmrg 6387e102996Smaya const uint32_t *operands; 63901e04c3fSmrg struct vtn_value *group; 64001e04c3fSmrg 64101e04c3fSmrg union { 64201e04c3fSmrg SpvDecoration decoration; 64301e04c3fSmrg SpvExecutionMode exec_mode; 64401e04c3fSmrg }; 64501e04c3fSmrg}; 64601e04c3fSmrg 64701e04c3fSmrgstruct vtn_builder { 64801e04c3fSmrg nir_builder nb; 64901e04c3fSmrg 65001e04c3fSmrg /* Used by vtn_fail to jump back to the beginning of SPIR-V compilation */ 65101e04c3fSmrg jmp_buf fail_jump; 65201e04c3fSmrg 65301e04c3fSmrg const uint32_t *spirv; 65401e04c3fSmrg size_t spirv_word_count; 6557ec681f3Smrg uint32_t version; 65601e04c3fSmrg 65701e04c3fSmrg nir_shader *shader; 6587e102996Smaya struct spirv_to_nir_options *options; 65901e04c3fSmrg struct vtn_block *block; 66001e04c3fSmrg 66101e04c3fSmrg /* Current offset, file, line, and column. Useful for debugging. Set 66201e04c3fSmrg * automatically by vtn_foreach_instruction. 66301e04c3fSmrg */ 66401e04c3fSmrg size_t spirv_offset; 6657ec681f3Smrg const char *file; 66601e04c3fSmrg int line, col; 66701e04c3fSmrg 66801e04c3fSmrg /* 66901e04c3fSmrg * In SPIR-V, constants are global, whereas in NIR, the load_const 67001e04c3fSmrg * instruction we use is per-function. So while we parse each function, we 67101e04c3fSmrg * keep a hash table of constants we've resolved to nir_ssa_value's so 67201e04c3fSmrg * far, and we lazily resolve them when we see them used in a function. 67301e04c3fSmrg */ 67401e04c3fSmrg struct hash_table *const_table; 67501e04c3fSmrg 67601e04c3fSmrg /* 67701e04c3fSmrg * Map from phi instructions (pointer to the start of the instruction) 67801e04c3fSmrg * to the variable corresponding to it. 67901e04c3fSmrg */ 68001e04c3fSmrg struct hash_table *phi_table; 68101e04c3fSmrg 6827ec681f3Smrg /* In Vulkan, when lowering some modes variable access, the derefs of the 6837ec681f3Smrg * variables are replaced with a resource index intrinsics, leaving the 6847ec681f3Smrg * variable hanging. This set keeps track of them so they can be filtered 6857ec681f3Smrg * (and not removed) in nir_remove_dead_variables. 6867ec681f3Smrg */ 6877ec681f3Smrg struct set *vars_used_indirectly; 6887ec681f3Smrg 68901e04c3fSmrg unsigned num_specializations; 69001e04c3fSmrg struct nir_spirv_specialization *specializations; 69101e04c3fSmrg 69201e04c3fSmrg unsigned value_id_bound; 69301e04c3fSmrg struct vtn_value *values; 69401e04c3fSmrg 6957ec681f3Smrg /* Information on the origin of the SPIR-V */ 6967ec681f3Smrg enum vtn_generator generator_id; 6977ec681f3Smrg SpvSourceLanguage source_lang; 6987ec681f3Smrg 6997ec681f3Smrg /* True if we need to fix up CS OpControlBarrier */ 7007ec681f3Smrg bool wa_glslang_cs_barrier; 7017ec681f3Smrg 7027ec681f3Smrg /* True if we need to ignore undef initializers */ 7037ec681f3Smrg bool wa_llvm_spirv_ignore_workgroup_initializer; 7047ec681f3Smrg 7057ec681f3Smrg /* Workaround discard bugs in HLSL -> SPIR-V compilers */ 7067ec681f3Smrg bool uses_demote_to_helper_invocation; 7077ec681f3Smrg bool convert_discard_to_demote; 7087e102996Smaya 70901e04c3fSmrg gl_shader_stage entry_point_stage; 71001e04c3fSmrg const char *entry_point_name; 71101e04c3fSmrg struct vtn_value *entry_point; 7127e102996Smaya struct vtn_value *workgroup_size_builtin; 7137e102996Smaya bool variable_pointers; 71401e04c3fSmrg 7157ec681f3Smrg uint32_t *interface_ids; 7167ec681f3Smrg size_t interface_ids_count; 7177ec681f3Smrg 71801e04c3fSmrg struct vtn_function *func; 7197ec681f3Smrg struct list_head functions; 72001e04c3fSmrg 72101e04c3fSmrg /* Current function parameter index */ 72201e04c3fSmrg unsigned func_param_idx; 72301e04c3fSmrg 7247e102996Smaya /* false by default, set to true by the ContractionOff execution mode */ 7257e102996Smaya bool exact; 7267e102996Smaya 7277e102996Smaya /* when a physical memory model is choosen */ 7287e102996Smaya bool physical_ptrs; 7297ec681f3Smrg 7307ec681f3Smrg /* memory model specified by OpMemoryModel */ 7317ec681f3Smrg unsigned mem_model; 73201e04c3fSmrg}; 73301e04c3fSmrg 73401e04c3fSmrgnir_ssa_def * 73501e04c3fSmrgvtn_pointer_to_ssa(struct vtn_builder *b, struct vtn_pointer *ptr); 73601e04c3fSmrgstruct vtn_pointer * 73701e04c3fSmrgvtn_pointer_from_ssa(struct vtn_builder *b, nir_ssa_def *ssa, 73801e04c3fSmrg struct vtn_type *ptr_type); 73901e04c3fSmrg 7407ec681f3Smrgstruct vtn_ssa_value * 7417ec681f3Smrgvtn_const_ssa_value(struct vtn_builder *b, nir_constant *constant, 7427ec681f3Smrg const struct glsl_type *type); 7437ec681f3Smrg 74401e04c3fSmrgstatic inline struct vtn_value * 74501e04c3fSmrgvtn_untyped_value(struct vtn_builder *b, uint32_t value_id) 74601e04c3fSmrg{ 74701e04c3fSmrg vtn_fail_if(value_id >= b->value_id_bound, 74801e04c3fSmrg "SPIR-V id %u is out-of-bounds", value_id); 74901e04c3fSmrg return &b->values[value_id]; 75001e04c3fSmrg} 75101e04c3fSmrg 7527ec681f3Smrgstatic inline uint32_t 7537ec681f3Smrgvtn_id_for_value(struct vtn_builder *b, struct vtn_value *value) 7547ec681f3Smrg{ 7557ec681f3Smrg vtn_fail_if(value <= b->values, "vtn_value pointer outside the range of valid values"); 7567ec681f3Smrg uint32_t value_id = value - b->values; 7577ec681f3Smrg vtn_fail_if(value_id >= b->value_id_bound, "vtn_value pointer outside the range of valid values"); 7587ec681f3Smrg return value_id; 7597ec681f3Smrg} 7607ec681f3Smrg 7617e102996Smaya/* Consider not using this function directly and instead use 7627ec681f3Smrg * vtn_push_ssa/vtn_push_pointer so that appropriate applying of 7637e102996Smaya * decorations is handled by common code. 7647e102996Smaya */ 76501e04c3fSmrgstatic inline struct vtn_value * 76601e04c3fSmrgvtn_push_value(struct vtn_builder *b, uint32_t value_id, 76701e04c3fSmrg enum vtn_value_type value_type) 76801e04c3fSmrg{ 76901e04c3fSmrg struct vtn_value *val = vtn_untyped_value(b, value_id); 77001e04c3fSmrg 7717ec681f3Smrg vtn_fail_if(value_type == vtn_value_type_ssa, 7727ec681f3Smrg "Do not call vtn_push_value for value_type_ssa. Use " 7737ec681f3Smrg "vtn_push_ssa_value instead."); 7747ec681f3Smrg 77501e04c3fSmrg vtn_fail_if(val->value_type != vtn_value_type_invalid, 77601e04c3fSmrg "SPIR-V id %u has already been written by another instruction", 77701e04c3fSmrg value_id); 77801e04c3fSmrg 77901e04c3fSmrg val->value_type = value_type; 78001e04c3fSmrg 7817e102996Smaya return &b->values[value_id]; 78201e04c3fSmrg} 78301e04c3fSmrg 78401e04c3fSmrgstatic inline struct vtn_value * 78501e04c3fSmrgvtn_value(struct vtn_builder *b, uint32_t value_id, 78601e04c3fSmrg enum vtn_value_type value_type) 78701e04c3fSmrg{ 78801e04c3fSmrg struct vtn_value *val = vtn_untyped_value(b, value_id); 78901e04c3fSmrg vtn_fail_if(val->value_type != value_type, 79001e04c3fSmrg "SPIR-V id %u is the wrong kind of value", value_id); 79101e04c3fSmrg return val; 79201e04c3fSmrg} 79301e04c3fSmrg 7947ec681f3Smrgstatic inline struct vtn_value * 7957ec681f3Smrgvtn_pointer_value(struct vtn_builder *b, uint32_t value_id) 7967ec681f3Smrg{ 7977ec681f3Smrg struct vtn_value *val = vtn_untyped_value(b, value_id); 7987ec681f3Smrg vtn_fail_if(val->value_type != vtn_value_type_pointer && 7997ec681f3Smrg !val->is_null_constant, 8007ec681f3Smrg "SPIR-V id %u is the wrong kind of value", value_id); 8017ec681f3Smrg return val; 8027ec681f3Smrg} 8037ec681f3Smrg 8047ec681f3Smrgstatic inline struct vtn_pointer * 8057ec681f3Smrgvtn_value_to_pointer(struct vtn_builder *b, struct vtn_value *value) 8067ec681f3Smrg{ 8077ec681f3Smrg if (value->is_null_constant) { 8087ec681f3Smrg vtn_assert(glsl_type_is_vector_or_scalar(value->type->type)); 8097ec681f3Smrg nir_ssa_def *const_ssa = 8107ec681f3Smrg vtn_const_ssa_value(b, value->constant, value->type->type)->def; 8117ec681f3Smrg return vtn_pointer_from_ssa(b, const_ssa, value->type); 8127ec681f3Smrg } 8137ec681f3Smrg vtn_assert(value->value_type == vtn_value_type_pointer); 8147ec681f3Smrg return value->pointer; 8157ec681f3Smrg} 8167ec681f3Smrg 8177ec681f3Smrgstatic inline struct vtn_pointer * 8187ec681f3Smrgvtn_pointer(struct vtn_builder *b, uint32_t value_id) 8197ec681f3Smrg{ 8207ec681f3Smrg return vtn_value_to_pointer(b, vtn_pointer_value(b, value_id)); 8217ec681f3Smrg} 8227ec681f3Smrg 82301e04c3fSmrgbool 82401e04c3fSmrgvtn_set_instruction_result_type(struct vtn_builder *b, SpvOp opcode, 82501e04c3fSmrg const uint32_t *w, unsigned count); 82601e04c3fSmrg 8277e102996Smayastatic inline uint64_t 8287e102996Smayavtn_constant_uint(struct vtn_builder *b, uint32_t value_id) 82901e04c3fSmrg{ 8307e102996Smaya struct vtn_value *val = vtn_value(b, value_id, vtn_value_type_constant); 8317e102996Smaya 8327e102996Smaya vtn_fail_if(val->type->base_type != vtn_base_type_scalar || 8337e102996Smaya !glsl_type_is_integer(val->type->type), 8347e102996Smaya "Expected id %u to be an integer constant", value_id); 8357e102996Smaya 8367e102996Smaya switch (glsl_get_bit_size(val->type->type)) { 8377ec681f3Smrg case 8: return val->constant->values[0].u8; 8387ec681f3Smrg case 16: return val->constant->values[0].u16; 8397ec681f3Smrg case 32: return val->constant->values[0].u32; 8407ec681f3Smrg case 64: return val->constant->values[0].u64; 8417e102996Smaya default: unreachable("Invalid bit size"); 8427e102996Smaya } 8437e102996Smaya} 8447e102996Smaya 8457ec681f3Smrgstatic inline int64_t 8467ec681f3Smrgvtn_constant_int(struct vtn_builder *b, uint32_t value_id) 8477e102996Smaya{ 8487ec681f3Smrg struct vtn_value *val = vtn_value(b, value_id, vtn_value_type_constant); 8497ec681f3Smrg 8507ec681f3Smrg vtn_fail_if(val->type->base_type != vtn_base_type_scalar || 8517ec681f3Smrg !glsl_type_is_integer(val->type->type), 8527ec681f3Smrg "Expected id %u to be an integer constant", value_id); 8537ec681f3Smrg 8547ec681f3Smrg switch (glsl_get_bit_size(val->type->type)) { 8557ec681f3Smrg case 8: return val->constant->values[0].i8; 8567ec681f3Smrg case 16: return val->constant->values[0].i16; 8577ec681f3Smrg case 32: return val->constant->values[0].i32; 8587ec681f3Smrg case 64: return val->constant->values[0].i64; 8597ec681f3Smrg default: unreachable("Invalid bit size"); 8607e102996Smaya } 8617ec681f3Smrg} 8627ec681f3Smrg 8637ec681f3Smrgstatic inline struct vtn_type * 8647ec681f3Smrgvtn_get_value_type(struct vtn_builder *b, uint32_t value_id) 8657ec681f3Smrg{ 8667ec681f3Smrg struct vtn_value *val = vtn_untyped_value(b, value_id); 8677ec681f3Smrg vtn_fail_if(val->type == NULL, "Value %u does not have a type", value_id); 8687ec681f3Smrg return val->type; 8697ec681f3Smrg} 8707e102996Smaya 8717ec681f3Smrgstatic inline struct vtn_type * 8727ec681f3Smrgvtn_get_type(struct vtn_builder *b, uint32_t value_id) 8737ec681f3Smrg{ 8747ec681f3Smrg return vtn_value(b, value_id, vtn_value_type_type)->type; 87501e04c3fSmrg} 87601e04c3fSmrg 87701e04c3fSmrgstruct vtn_ssa_value *vtn_ssa_value(struct vtn_builder *b, uint32_t value_id); 8787ec681f3Smrgstruct vtn_value *vtn_push_ssa_value(struct vtn_builder *b, uint32_t value_id, 8797ec681f3Smrg struct vtn_ssa_value *ssa); 88001e04c3fSmrg 8817ec681f3Smrgnir_ssa_def *vtn_get_nir_ssa(struct vtn_builder *b, uint32_t value_id); 8827ec681f3Smrgstruct vtn_value *vtn_push_nir_ssa(struct vtn_builder *b, uint32_t value_id, 8837ec681f3Smrg nir_ssa_def *def); 8847e102996Smaya 8857ec681f3Smrgstruct vtn_value *vtn_push_pointer(struct vtn_builder *b, 8867ec681f3Smrg uint32_t value_id, 8877ec681f3Smrg struct vtn_pointer *ptr); 8887ec681f3Smrg 8897ec681f3Smrgstruct vtn_sampled_image { 8907ec681f3Smrg nir_deref_instr *image; 8917ec681f3Smrg nir_deref_instr *sampler; 8927ec681f3Smrg}; 8937ec681f3Smrg 8947ec681f3Smrgnir_ssa_def *vtn_sampled_image_to_nir_ssa(struct vtn_builder *b, 8957ec681f3Smrg struct vtn_sampled_image si); 8967ec681f3Smrg 8977ec681f3Smrgvoid 8987ec681f3Smrgvtn_copy_value(struct vtn_builder *b, uint32_t src_value_id, 8997ec681f3Smrg uint32_t dst_value_id); 9007e102996Smaya 90101e04c3fSmrgstruct vtn_ssa_value *vtn_create_ssa_value(struct vtn_builder *b, 90201e04c3fSmrg const struct glsl_type *type); 90301e04c3fSmrg 90401e04c3fSmrgstruct vtn_ssa_value *vtn_ssa_transpose(struct vtn_builder *b, 90501e04c3fSmrg struct vtn_ssa_value *src); 90601e04c3fSmrg 90701e04c3fSmrgnir_deref_instr *vtn_nir_deref(struct vtn_builder *b, uint32_t id); 90801e04c3fSmrg 90901e04c3fSmrgnir_deref_instr *vtn_pointer_to_deref(struct vtn_builder *b, 91001e04c3fSmrg struct vtn_pointer *ptr); 91101e04c3fSmrgnir_ssa_def * 91201e04c3fSmrgvtn_pointer_to_offset(struct vtn_builder *b, struct vtn_pointer *ptr, 91301e04c3fSmrg nir_ssa_def **index_out); 91401e04c3fSmrg 9157ec681f3Smrgnir_deref_instr * 9167ec681f3Smrgvtn_get_call_payload_for_location(struct vtn_builder *b, uint32_t location_id); 9177ec681f3Smrg 91801e04c3fSmrgstruct vtn_ssa_value * 9197e102996Smayavtn_local_load(struct vtn_builder *b, nir_deref_instr *src, 9207e102996Smaya enum gl_access_qualifier access); 92101e04c3fSmrg 92201e04c3fSmrgvoid vtn_local_store(struct vtn_builder *b, struct vtn_ssa_value *src, 9237e102996Smaya nir_deref_instr *dest, 9247e102996Smaya enum gl_access_qualifier access); 92501e04c3fSmrg 92601e04c3fSmrgstruct vtn_ssa_value * 9277ec681f3Smrgvtn_variable_load(struct vtn_builder *b, struct vtn_pointer *src, 9287ec681f3Smrg enum gl_access_qualifier access); 92901e04c3fSmrg 93001e04c3fSmrgvoid vtn_variable_store(struct vtn_builder *b, struct vtn_ssa_value *src, 9317ec681f3Smrg struct vtn_pointer *dest, enum gl_access_qualifier access); 93201e04c3fSmrg 93301e04c3fSmrgvoid vtn_handle_variables(struct vtn_builder *b, SpvOp opcode, 93401e04c3fSmrg const uint32_t *w, unsigned count); 93501e04c3fSmrg 93601e04c3fSmrg 93701e04c3fSmrgtypedef void (*vtn_decoration_foreach_cb)(struct vtn_builder *, 93801e04c3fSmrg struct vtn_value *, 93901e04c3fSmrg int member, 94001e04c3fSmrg const struct vtn_decoration *, 94101e04c3fSmrg void *); 94201e04c3fSmrg 94301e04c3fSmrgvoid vtn_foreach_decoration(struct vtn_builder *b, struct vtn_value *value, 94401e04c3fSmrg vtn_decoration_foreach_cb cb, void *data); 94501e04c3fSmrg 94601e04c3fSmrgtypedef void (*vtn_execution_mode_foreach_cb)(struct vtn_builder *, 94701e04c3fSmrg struct vtn_value *, 94801e04c3fSmrg const struct vtn_decoration *, 94901e04c3fSmrg void *); 95001e04c3fSmrg 95101e04c3fSmrgvoid vtn_foreach_execution_mode(struct vtn_builder *b, struct vtn_value *value, 95201e04c3fSmrg vtn_execution_mode_foreach_cb cb, void *data); 95301e04c3fSmrg 95401e04c3fSmrgnir_op vtn_nir_alu_op_for_spirv_opcode(struct vtn_builder *b, 9557ec681f3Smrg SpvOp opcode, bool *swap, bool *exact, 95601e04c3fSmrg unsigned src_bit_size, unsigned dst_bit_size); 95701e04c3fSmrg 95801e04c3fSmrgvoid vtn_handle_alu(struct vtn_builder *b, SpvOp opcode, 95901e04c3fSmrg const uint32_t *w, unsigned count); 96001e04c3fSmrg 9617ec681f3Smrgvoid vtn_handle_integer_dot(struct vtn_builder *b, SpvOp opcode, 9627ec681f3Smrg const uint32_t *w, unsigned count); 9637ec681f3Smrg 9647e102996Smayavoid vtn_handle_bitcast(struct vtn_builder *b, const uint32_t *w, 9657e102996Smaya unsigned count); 9667e102996Smaya 9677ec681f3Smrgvoid vtn_handle_no_contraction(struct vtn_builder *b, struct vtn_value *val); 9687ec681f3Smrg 96901e04c3fSmrgvoid vtn_handle_subgroup(struct vtn_builder *b, SpvOp opcode, 97001e04c3fSmrg const uint32_t *w, unsigned count); 97101e04c3fSmrg 97201e04c3fSmrgbool vtn_handle_glsl450_instruction(struct vtn_builder *b, SpvOp ext_opcode, 97301e04c3fSmrg const uint32_t *words, unsigned count); 97401e04c3fSmrg 9757ec681f3Smrgbool vtn_handle_opencl_instruction(struct vtn_builder *b, SpvOp ext_opcode, 9767e102996Smaya const uint32_t *words, unsigned count); 9777ec681f3Smrgbool vtn_handle_opencl_core_instruction(struct vtn_builder *b, SpvOp opcode, 9787ec681f3Smrg const uint32_t *w, unsigned count); 9797e102996Smaya 98001e04c3fSmrgstruct vtn_builder* vtn_create_builder(const uint32_t *words, size_t word_count, 98101e04c3fSmrg gl_shader_stage stage, const char *entry_point_name, 98201e04c3fSmrg const struct spirv_to_nir_options *options); 98301e04c3fSmrg 98401e04c3fSmrgvoid vtn_handle_entry_point(struct vtn_builder *b, const uint32_t *w, 98501e04c3fSmrg unsigned count); 98601e04c3fSmrg 98701e04c3fSmrgvoid vtn_handle_decoration(struct vtn_builder *b, SpvOp opcode, 98801e04c3fSmrg const uint32_t *w, unsigned count); 98901e04c3fSmrg 9907ec681f3Smrgenum vtn_variable_mode vtn_storage_class_to_mode(struct vtn_builder *b, 9917ec681f3Smrg SpvStorageClass class, 9927ec681f3Smrg struct vtn_type *interface_type, 9937ec681f3Smrg nir_variable_mode *nir_mode_out); 9947ec681f3Smrg 9957ec681f3Smrgnir_address_format vtn_mode_to_address_format(struct vtn_builder *b, 9967ec681f3Smrg enum vtn_variable_mode); 9977ec681f3Smrg 9987ec681f3Smrgnir_rounding_mode vtn_rounding_mode_to_nir(struct vtn_builder *b, 9997ec681f3Smrg SpvFPRoundingMode mode); 10007ec681f3Smrg 100101e04c3fSmrgstatic inline uint32_t 100201e04c3fSmrgvtn_align_u32(uint32_t v, uint32_t a) 100301e04c3fSmrg{ 100401e04c3fSmrg assert(a != 0 && a == (a & -((int32_t) a))); 100501e04c3fSmrg return (v + a - 1) & ~(a - 1); 100601e04c3fSmrg} 100701e04c3fSmrg 100801e04c3fSmrgstatic inline uint64_t 100901e04c3fSmrgvtn_u64_literal(const uint32_t *w) 101001e04c3fSmrg{ 101101e04c3fSmrg return (uint64_t)w[1] << 32 | w[0]; 101201e04c3fSmrg} 101301e04c3fSmrg 101401e04c3fSmrgbool vtn_handle_amd_gcn_shader_instruction(struct vtn_builder *b, SpvOp ext_opcode, 101501e04c3fSmrg const uint32_t *words, unsigned count); 101601e04c3fSmrg 10177ec681f3Smrgbool vtn_handle_amd_shader_ballot_instruction(struct vtn_builder *b, SpvOp ext_opcode, 10187ec681f3Smrg const uint32_t *w, unsigned count); 10197ec681f3Smrg 102001e04c3fSmrgbool vtn_handle_amd_shader_trinary_minmax_instruction(struct vtn_builder *b, SpvOp ext_opcode, 102101e04c3fSmrg const uint32_t *words, unsigned count); 10227ec681f3Smrg 10237ec681f3Smrgbool vtn_handle_amd_shader_explicit_vertex_parameter_instruction(struct vtn_builder *b, 10247ec681f3Smrg SpvOp ext_opcode, 10257ec681f3Smrg const uint32_t *words, 10267ec681f3Smrg unsigned count); 10277ec681f3Smrg 10287ec681f3SmrgSpvMemorySemanticsMask vtn_mode_to_memory_semantics(enum vtn_variable_mode mode); 10297ec681f3Smrg 10307ec681f3Smrgvoid vtn_emit_memory_barrier(struct vtn_builder *b, SpvScope scope, 10317ec681f3Smrg SpvMemorySemanticsMask semantics); 10327ec681f3Smrg 10337ec681f3Smrgstatic inline int 10347ec681f3Smrgcmp_uint32_t(const void *pa, const void *pb) 10357ec681f3Smrg{ 10367ec681f3Smrg uint32_t a = *((const uint32_t *)pa); 10377ec681f3Smrg uint32_t b = *((const uint32_t *)pb); 10387ec681f3Smrg if (a < b) 10397ec681f3Smrg return -1; 10407ec681f3Smrg if (a > b) 10417ec681f3Smrg return 1; 10427ec681f3Smrg return 0; 10437ec681f3Smrg} 10447ec681f3Smrg 104501e04c3fSmrg#endif /* _VTN_PRIVATE_H_ */ 1046