1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2015 Intel Corporation
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
5*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
6*61046927SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
7*61046927SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*61046927SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
9*61046927SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker *
11*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker * Software.
14*61046927SAndroid Build Coastguard Worker *
15*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18*61046927SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*61046927SAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*61046927SAndroid Build Coastguard Worker * IN THE SOFTWARE.
22*61046927SAndroid Build Coastguard Worker */
23*61046927SAndroid Build Coastguard Worker
24*61046927SAndroid Build Coastguard Worker #ifndef _VTN_PRIVATE_H_
25*61046927SAndroid Build Coastguard Worker #define _VTN_PRIVATE_H_
26*61046927SAndroid Build Coastguard Worker
27*61046927SAndroid Build Coastguard Worker #include <setjmp.h>
28*61046927SAndroid Build Coastguard Worker
29*61046927SAndroid Build Coastguard Worker #include "nir/nir.h"
30*61046927SAndroid Build Coastguard Worker #include "nir/nir_builder.h"
31*61046927SAndroid Build Coastguard Worker #include "util/u_dynarray.h"
32*61046927SAndroid Build Coastguard Worker #include "nir_spirv.h"
33*61046927SAndroid Build Coastguard Worker #include "spirv.h"
34*61046927SAndroid Build Coastguard Worker #include "spirv_info.h"
35*61046927SAndroid Build Coastguard Worker #include "vtn_generator_ids.h"
36*61046927SAndroid Build Coastguard Worker
37*61046927SAndroid Build Coastguard Worker extern uint32_t mesa_spirv_debug;
38*61046927SAndroid Build Coastguard Worker
39*61046927SAndroid Build Coastguard Worker #define MESA_SPIRV_DEBUG(flag) unlikely(mesa_spirv_debug & (MESA_SPIRV_DEBUG_ ## flag))
40*61046927SAndroid Build Coastguard Worker
41*61046927SAndroid Build Coastguard Worker #define MESA_SPIRV_DEBUG_STRUCTURED (1u << 0)
42*61046927SAndroid Build Coastguard Worker #define MESA_SPIRV_DEBUG_VALUES (1u << 1)
43*61046927SAndroid Build Coastguard Worker #define MESA_SPIRV_DEBUG_ASM (1u << 2)
44*61046927SAndroid Build Coastguard Worker #define MESA_SPIRV_DEBUG_COLOR (1u << 3)
45*61046927SAndroid Build Coastguard Worker
46*61046927SAndroid Build Coastguard Worker struct vtn_builder;
47*61046927SAndroid Build Coastguard Worker struct vtn_decoration;
48*61046927SAndroid Build Coastguard Worker
49*61046927SAndroid Build Coastguard Worker /* setjmp/longjmp is broken on MinGW: https://sourceforge.net/p/mingw-w64/bugs/406/ */
50*61046927SAndroid Build Coastguard Worker #if defined(__MINGW32__) && !defined(_UCRT)
51*61046927SAndroid Build Coastguard Worker #define vtn_setjmp __builtin_setjmp
52*61046927SAndroid Build Coastguard Worker #define vtn_longjmp __builtin_longjmp
53*61046927SAndroid Build Coastguard Worker #else
54*61046927SAndroid Build Coastguard Worker #define vtn_setjmp setjmp
55*61046927SAndroid Build Coastguard Worker #define vtn_longjmp longjmp
56*61046927SAndroid Build Coastguard Worker #endif
57*61046927SAndroid Build Coastguard Worker
58*61046927SAndroid Build Coastguard Worker void vtn_log(struct vtn_builder *b, enum nir_spirv_debug_level level,
59*61046927SAndroid Build Coastguard Worker size_t spirv_offset, const char *message);
60*61046927SAndroid Build Coastguard Worker
61*61046927SAndroid Build Coastguard Worker void vtn_logf(struct vtn_builder *b, enum nir_spirv_debug_level level,
62*61046927SAndroid Build Coastguard Worker size_t spirv_offset, const char *fmt, ...) PRINTFLIKE(4, 5);
63*61046927SAndroid Build Coastguard Worker
64*61046927SAndroid Build Coastguard Worker #define vtn_info(...) vtn_logf(b, NIR_SPIRV_DEBUG_LEVEL_INFO, 0, __VA_ARGS__)
65*61046927SAndroid Build Coastguard Worker
66*61046927SAndroid Build Coastguard Worker void _vtn_warn(struct vtn_builder *b, const char *file, unsigned line,
67*61046927SAndroid Build Coastguard Worker const char *fmt, ...) PRINTFLIKE(4, 5);
68*61046927SAndroid Build Coastguard Worker #define vtn_warn(...) _vtn_warn(b, __FILE__, __LINE__, __VA_ARGS__)
69*61046927SAndroid Build Coastguard Worker
70*61046927SAndroid Build Coastguard Worker void _vtn_err(struct vtn_builder *b, const char *file, unsigned line,
71*61046927SAndroid Build Coastguard Worker const char *fmt, ...) PRINTFLIKE(4, 5);
72*61046927SAndroid Build Coastguard Worker #define vtn_err(...) _vtn_err(b, __FILE__, __LINE__, __VA_ARGS__)
73*61046927SAndroid Build Coastguard Worker
74*61046927SAndroid Build Coastguard Worker /** Fail SPIR-V parsing
75*61046927SAndroid Build Coastguard Worker *
76*61046927SAndroid Build Coastguard Worker * This function logs an error and then bails out of the shader compile using
77*61046927SAndroid Build Coastguard Worker * longjmp. This being safe relies on two things:
78*61046927SAndroid Build Coastguard Worker *
79*61046927SAndroid Build Coastguard Worker * 1) We must guarantee that setjmp is called after allocating the builder
80*61046927SAndroid Build Coastguard Worker * and setting up b->debug (so that logging works) but before before any
81*61046927SAndroid Build Coastguard Worker * errors have a chance to occur.
82*61046927SAndroid Build Coastguard Worker *
83*61046927SAndroid Build Coastguard Worker * 2) While doing the SPIR-V -> NIR conversion, we need to be careful to
84*61046927SAndroid Build Coastguard Worker * ensure that all heap allocations happen through ralloc and are parented
85*61046927SAndroid Build Coastguard Worker * to the builder. This way they will get properly cleaned up on error.
86*61046927SAndroid Build Coastguard Worker *
87*61046927SAndroid Build Coastguard Worker * 3) We must ensure that _vtn_fail is never called while a mutex lock or a
88*61046927SAndroid Build Coastguard Worker * reference to any other resource is held with the exception of ralloc
89*61046927SAndroid Build Coastguard Worker * objects which are parented to the builder.
90*61046927SAndroid Build Coastguard Worker *
91*61046927SAndroid Build Coastguard Worker * So long as these two things continue to hold, we can easily longjmp back to
92*61046927SAndroid Build Coastguard Worker * spirv_to_nir(), clean up the builder, and return NULL.
93*61046927SAndroid Build Coastguard Worker */
94*61046927SAndroid Build Coastguard Worker NORETURN void
95*61046927SAndroid Build Coastguard Worker _vtn_fail(struct vtn_builder *b, const char *file, unsigned line,
96*61046927SAndroid Build Coastguard Worker const char *fmt, ...) PRINTFLIKE(4, 5);
97*61046927SAndroid Build Coastguard Worker
98*61046927SAndroid Build Coastguard Worker #define vtn_fail(...) _vtn_fail(b, __FILE__, __LINE__, __VA_ARGS__)
99*61046927SAndroid Build Coastguard Worker
100*61046927SAndroid Build Coastguard Worker /** Fail if the given expression evaluates to true */
101*61046927SAndroid Build Coastguard Worker #define vtn_fail_if(expr, ...) \
102*61046927SAndroid Build Coastguard Worker do { \
103*61046927SAndroid Build Coastguard Worker if (unlikely(expr)) \
104*61046927SAndroid Build Coastguard Worker vtn_fail(__VA_ARGS__); \
105*61046927SAndroid Build Coastguard Worker } while (0)
106*61046927SAndroid Build Coastguard Worker
107*61046927SAndroid Build Coastguard Worker #define _vtn_fail_with(t, msg, v) \
108*61046927SAndroid Build Coastguard Worker vtn_fail("%s: %s (%u)\n", msg, spirv_ ## t ## _to_string(v), v)
109*61046927SAndroid Build Coastguard Worker
110*61046927SAndroid Build Coastguard Worker #define vtn_fail_with_decoration(msg, v) _vtn_fail_with(decoration, msg, v)
111*61046927SAndroid Build Coastguard Worker #define vtn_fail_with_opcode(msg, v) _vtn_fail_with(op, msg, v)
112*61046927SAndroid Build Coastguard Worker
113*61046927SAndroid Build Coastguard Worker /** Assert that a condition is true and, if it isn't, vtn_fail
114*61046927SAndroid Build Coastguard Worker *
115*61046927SAndroid Build Coastguard Worker * This macro is transitional only and should not be used in new code. Use
116*61046927SAndroid Build Coastguard Worker * vtn_fail_if and provide a real message instead.
117*61046927SAndroid Build Coastguard Worker */
118*61046927SAndroid Build Coastguard Worker #define vtn_assert(expr) \
119*61046927SAndroid Build Coastguard Worker do { \
120*61046927SAndroid Build Coastguard Worker if (!likely(expr)) \
121*61046927SAndroid Build Coastguard Worker vtn_fail("%s", #expr); \
122*61046927SAndroid Build Coastguard Worker } while (0)
123*61046927SAndroid Build Coastguard Worker
124*61046927SAndroid Build Coastguard Worker /* These are used to allocate data that can be dropped at the end of
125*61046927SAndroid Build Coastguard Worker * the parsing. Any NIR data structure should keep using the ralloc,
126*61046927SAndroid Build Coastguard Worker * since they will outlive the parsing.
127*61046927SAndroid Build Coastguard Worker */
128*61046927SAndroid Build Coastguard Worker #define vtn_alloc(B, TYPE) linear_alloc(B->lin_ctx, TYPE)
129*61046927SAndroid Build Coastguard Worker #define vtn_zalloc(B, TYPE) linear_zalloc(B->lin_ctx, TYPE)
130*61046927SAndroid Build Coastguard Worker #define vtn_alloc_array(B, TYPE, ELEMS) linear_alloc_array(B->lin_ctx, TYPE, ELEMS)
131*61046927SAndroid Build Coastguard Worker #define vtn_zalloc_array(B, TYPE, ELEMS) linear_zalloc_array(B->lin_ctx, TYPE, ELEMS)
132*61046927SAndroid Build Coastguard Worker #define vtn_alloc_size(B, SIZE) linear_alloc_child(B->lin_ctx, SIZE)
133*61046927SAndroid Build Coastguard Worker #define vtn_zalloc_size(B, SIZE) linear_zalloc_child(B->lin_ctx, SIZE)
134*61046927SAndroid Build Coastguard Worker
135*61046927SAndroid Build Coastguard Worker enum vtn_value_type {
136*61046927SAndroid Build Coastguard Worker vtn_value_type_invalid = 0,
137*61046927SAndroid Build Coastguard Worker vtn_value_type_undef,
138*61046927SAndroid Build Coastguard Worker vtn_value_type_string,
139*61046927SAndroid Build Coastguard Worker vtn_value_type_decoration_group,
140*61046927SAndroid Build Coastguard Worker vtn_value_type_type,
141*61046927SAndroid Build Coastguard Worker vtn_value_type_constant,
142*61046927SAndroid Build Coastguard Worker vtn_value_type_pointer,
143*61046927SAndroid Build Coastguard Worker vtn_value_type_function,
144*61046927SAndroid Build Coastguard Worker vtn_value_type_block,
145*61046927SAndroid Build Coastguard Worker vtn_value_type_ssa,
146*61046927SAndroid Build Coastguard Worker vtn_value_type_extension,
147*61046927SAndroid Build Coastguard Worker vtn_value_type_image_pointer,
148*61046927SAndroid Build Coastguard Worker };
149*61046927SAndroid Build Coastguard Worker
150*61046927SAndroid Build Coastguard Worker const char *vtn_value_type_to_string(enum vtn_value_type t);
151*61046927SAndroid Build Coastguard Worker
152*61046927SAndroid Build Coastguard Worker struct vtn_case {
153*61046927SAndroid Build Coastguard Worker struct list_head link;
154*61046927SAndroid Build Coastguard Worker
155*61046927SAndroid Build Coastguard Worker struct vtn_block *block;
156*61046927SAndroid Build Coastguard Worker
157*61046927SAndroid Build Coastguard Worker /* The uint32_t values that map to this case */
158*61046927SAndroid Build Coastguard Worker struct util_dynarray values;
159*61046927SAndroid Build Coastguard Worker
160*61046927SAndroid Build Coastguard Worker /* True if this is the default case */
161*61046927SAndroid Build Coastguard Worker bool is_default;
162*61046927SAndroid Build Coastguard Worker
163*61046927SAndroid Build Coastguard Worker /* Initialized to false; used when sorting the list of cases */
164*61046927SAndroid Build Coastguard Worker bool visited;
165*61046927SAndroid Build Coastguard Worker };
166*61046927SAndroid Build Coastguard Worker
167*61046927SAndroid Build Coastguard Worker struct vtn_block {
168*61046927SAndroid Build Coastguard Worker struct list_head link;
169*61046927SAndroid Build Coastguard Worker
170*61046927SAndroid Build Coastguard Worker /** A pointer to the label instruction */
171*61046927SAndroid Build Coastguard Worker const uint32_t *label;
172*61046927SAndroid Build Coastguard Worker
173*61046927SAndroid Build Coastguard Worker /** A pointer to the merge instruction (or NULL if non exists) */
174*61046927SAndroid Build Coastguard Worker const uint32_t *merge;
175*61046927SAndroid Build Coastguard Worker
176*61046927SAndroid Build Coastguard Worker /** A pointer to the branch instruction that ends this block */
177*61046927SAndroid Build Coastguard Worker const uint32_t *branch;
178*61046927SAndroid Build Coastguard Worker
179*61046927SAndroid Build Coastguard Worker /** Points to the switch case started by this block (if any) */
180*61046927SAndroid Build Coastguard Worker struct vtn_case *switch_case;
181*61046927SAndroid Build Coastguard Worker
182*61046927SAndroid Build Coastguard Worker /** Every block ends in a nop intrinsic so that we can find it again */
183*61046927SAndroid Build Coastguard Worker nir_intrinsic_instr *end_nop;
184*61046927SAndroid Build Coastguard Worker
185*61046927SAndroid Build Coastguard Worker /** attached nir_block */
186*61046927SAndroid Build Coastguard Worker struct nir_block *block;
187*61046927SAndroid Build Coastguard Worker
188*61046927SAndroid Build Coastguard Worker /* Inner-most construct that this block is part of. */
189*61046927SAndroid Build Coastguard Worker struct vtn_construct *parent;
190*61046927SAndroid Build Coastguard Worker
191*61046927SAndroid Build Coastguard Worker /* Blocks that succeed this block. Used by structured control flow. */
192*61046927SAndroid Build Coastguard Worker struct vtn_successor *successors;
193*61046927SAndroid Build Coastguard Worker unsigned successors_count;
194*61046927SAndroid Build Coastguard Worker
195*61046927SAndroid Build Coastguard Worker /* Position of this block in the structured post-order traversal. */
196*61046927SAndroid Build Coastguard Worker unsigned pos;
197*61046927SAndroid Build Coastguard Worker
198*61046927SAndroid Build Coastguard Worker bool visited;
199*61046927SAndroid Build Coastguard Worker };
200*61046927SAndroid Build Coastguard Worker
201*61046927SAndroid Build Coastguard Worker struct vtn_function {
202*61046927SAndroid Build Coastguard Worker struct list_head link;
203*61046927SAndroid Build Coastguard Worker
204*61046927SAndroid Build Coastguard Worker struct vtn_type *type;
205*61046927SAndroid Build Coastguard Worker
206*61046927SAndroid Build Coastguard Worker bool referenced;
207*61046927SAndroid Build Coastguard Worker bool emitted;
208*61046927SAndroid Build Coastguard Worker
209*61046927SAndroid Build Coastguard Worker nir_function *nir_func;
210*61046927SAndroid Build Coastguard Worker struct vtn_block *start_block;
211*61046927SAndroid Build Coastguard Worker
212*61046927SAndroid Build Coastguard Worker struct list_head body;
213*61046927SAndroid Build Coastguard Worker
214*61046927SAndroid Build Coastguard Worker const uint32_t *end;
215*61046927SAndroid Build Coastguard Worker
216*61046927SAndroid Build Coastguard Worker SpvLinkageType linkage;
217*61046927SAndroid Build Coastguard Worker SpvFunctionControlMask control;
218*61046927SAndroid Build Coastguard Worker
219*61046927SAndroid Build Coastguard Worker unsigned block_count;
220*61046927SAndroid Build Coastguard Worker
221*61046927SAndroid Build Coastguard Worker /* Ordering of blocks to be processed by structured control flow. See
222*61046927SAndroid Build Coastguard Worker * vtn_structured_cfg.c for details.
223*61046927SAndroid Build Coastguard Worker */
224*61046927SAndroid Build Coastguard Worker unsigned ordered_blocks_count;
225*61046927SAndroid Build Coastguard Worker struct vtn_block **ordered_blocks;
226*61046927SAndroid Build Coastguard Worker
227*61046927SAndroid Build Coastguard Worker /* Structured control flow constructs. See struct vtn_construct. */
228*61046927SAndroid Build Coastguard Worker struct list_head constructs;
229*61046927SAndroid Build Coastguard Worker };
230*61046927SAndroid Build Coastguard Worker
231*61046927SAndroid Build Coastguard Worker #define vtn_foreach_function(func, func_list) \
232*61046927SAndroid Build Coastguard Worker list_for_each_entry(struct vtn_function, func, func_list, link)
233*61046927SAndroid Build Coastguard Worker
234*61046927SAndroid Build Coastguard Worker #define vtn_foreach_case(cse, case_list) \
235*61046927SAndroid Build Coastguard Worker list_for_each_entry(struct vtn_case, cse, case_list, link)
236*61046927SAndroid Build Coastguard Worker
237*61046927SAndroid Build Coastguard Worker #define vtn_foreach_case_safe(cse, case_list) \
238*61046927SAndroid Build Coastguard Worker list_for_each_entry_safe(struct vtn_case, cse, case_list, link)
239*61046927SAndroid Build Coastguard Worker
240*61046927SAndroid Build Coastguard Worker typedef bool (*vtn_instruction_handler)(struct vtn_builder *, SpvOp,
241*61046927SAndroid Build Coastguard Worker const uint32_t *, unsigned);
242*61046927SAndroid Build Coastguard Worker
243*61046927SAndroid Build Coastguard Worker void vtn_build_cfg(struct vtn_builder *b, const uint32_t *words,
244*61046927SAndroid Build Coastguard Worker const uint32_t *end);
245*61046927SAndroid Build Coastguard Worker void vtn_function_emit(struct vtn_builder *b, struct vtn_function *func,
246*61046927SAndroid Build Coastguard Worker vtn_instruction_handler instruction_handler);
247*61046927SAndroid Build Coastguard Worker void vtn_handle_function_call(struct vtn_builder *b, SpvOp opcode,
248*61046927SAndroid Build Coastguard Worker const uint32_t *w, unsigned count);
249*61046927SAndroid Build Coastguard Worker
250*61046927SAndroid Build Coastguard Worker bool vtn_cfg_handle_prepass_instruction(struct vtn_builder *b, SpvOp opcode,
251*61046927SAndroid Build Coastguard Worker const uint32_t *w, unsigned count);
252*61046927SAndroid Build Coastguard Worker void vtn_emit_cf_func_structured(struct vtn_builder *b, struct vtn_function *func,
253*61046927SAndroid Build Coastguard Worker vtn_instruction_handler handler);
254*61046927SAndroid Build Coastguard Worker bool vtn_handle_phis_first_pass(struct vtn_builder *b, SpvOp opcode,
255*61046927SAndroid Build Coastguard Worker const uint32_t *w, unsigned count);
256*61046927SAndroid Build Coastguard Worker void vtn_emit_ret_store(struct vtn_builder *b, const struct vtn_block *block);
257*61046927SAndroid Build Coastguard Worker void vtn_build_structured_cfg(struct vtn_builder *b, const uint32_t *words,
258*61046927SAndroid Build Coastguard Worker const uint32_t *end);
259*61046927SAndroid Build Coastguard Worker
260*61046927SAndroid Build Coastguard Worker const uint32_t *
261*61046927SAndroid Build Coastguard Worker vtn_foreach_instruction(struct vtn_builder *b, const uint32_t *start,
262*61046927SAndroid Build Coastguard Worker const uint32_t *end, vtn_instruction_handler handler);
263*61046927SAndroid Build Coastguard Worker
264*61046927SAndroid Build Coastguard Worker struct vtn_ssa_value {
265*61046927SAndroid Build Coastguard Worker bool is_variable;
266*61046927SAndroid Build Coastguard Worker
267*61046927SAndroid Build Coastguard Worker union {
268*61046927SAndroid Build Coastguard Worker nir_def *def;
269*61046927SAndroid Build Coastguard Worker nir_variable *var;
270*61046927SAndroid Build Coastguard Worker struct vtn_ssa_value **elems;
271*61046927SAndroid Build Coastguard Worker };
272*61046927SAndroid Build Coastguard Worker
273*61046927SAndroid Build Coastguard Worker /* For matrices, if this is non-NULL, then this value is actually the
274*61046927SAndroid Build Coastguard Worker * transpose of some other value. The value that `transposed` points to
275*61046927SAndroid Build Coastguard Worker * always dominates this value.
276*61046927SAndroid Build Coastguard Worker */
277*61046927SAndroid Build Coastguard Worker struct vtn_ssa_value *transposed;
278*61046927SAndroid Build Coastguard Worker
279*61046927SAndroid Build Coastguard Worker const struct glsl_type *type;
280*61046927SAndroid Build Coastguard Worker };
281*61046927SAndroid Build Coastguard Worker
282*61046927SAndroid Build Coastguard Worker enum vtn_base_type {
283*61046927SAndroid Build Coastguard Worker vtn_base_type_void,
284*61046927SAndroid Build Coastguard Worker vtn_base_type_scalar,
285*61046927SAndroid Build Coastguard Worker vtn_base_type_vector,
286*61046927SAndroid Build Coastguard Worker vtn_base_type_matrix,
287*61046927SAndroid Build Coastguard Worker vtn_base_type_array,
288*61046927SAndroid Build Coastguard Worker vtn_base_type_struct,
289*61046927SAndroid Build Coastguard Worker vtn_base_type_pointer,
290*61046927SAndroid Build Coastguard Worker vtn_base_type_image,
291*61046927SAndroid Build Coastguard Worker vtn_base_type_sampler,
292*61046927SAndroid Build Coastguard Worker vtn_base_type_sampled_image,
293*61046927SAndroid Build Coastguard Worker vtn_base_type_accel_struct,
294*61046927SAndroid Build Coastguard Worker vtn_base_type_ray_query,
295*61046927SAndroid Build Coastguard Worker vtn_base_type_function,
296*61046927SAndroid Build Coastguard Worker vtn_base_type_event,
297*61046927SAndroid Build Coastguard Worker vtn_base_type_cooperative_matrix,
298*61046927SAndroid Build Coastguard Worker };
299*61046927SAndroid Build Coastguard Worker
300*61046927SAndroid Build Coastguard Worker struct vtn_type {
301*61046927SAndroid Build Coastguard Worker enum vtn_base_type base_type;
302*61046927SAndroid Build Coastguard Worker
303*61046927SAndroid Build Coastguard Worker const struct glsl_type *type;
304*61046927SAndroid Build Coastguard Worker
305*61046927SAndroid Build Coastguard Worker /* The SPIR-V id of the given type. */
306*61046927SAndroid Build Coastguard Worker uint32_t id;
307*61046927SAndroid Build Coastguard Worker
308*61046927SAndroid Build Coastguard Worker /* Specifies the length of complex types.
309*61046927SAndroid Build Coastguard Worker *
310*61046927SAndroid Build Coastguard Worker * For Workgroup pointers, this is the size of the referenced type.
311*61046927SAndroid Build Coastguard Worker */
312*61046927SAndroid Build Coastguard Worker unsigned length;
313*61046927SAndroid Build Coastguard Worker
314*61046927SAndroid Build Coastguard Worker /* for arrays, matrices and pointers, the array stride */
315*61046927SAndroid Build Coastguard Worker unsigned stride;
316*61046927SAndroid Build Coastguard Worker
317*61046927SAndroid Build Coastguard Worker /* Access qualifiers */
318*61046927SAndroid Build Coastguard Worker enum gl_access_qualifier access;
319*61046927SAndroid Build Coastguard Worker
320*61046927SAndroid Build Coastguard Worker union {
321*61046927SAndroid Build Coastguard Worker /* Members for scalar, vector, and array-like types */
322*61046927SAndroid Build Coastguard Worker struct {
323*61046927SAndroid Build Coastguard Worker /* for arrays, the vtn_type for the elements of the array */
324*61046927SAndroid Build Coastguard Worker struct vtn_type *array_element;
325*61046927SAndroid Build Coastguard Worker
326*61046927SAndroid Build Coastguard Worker /* for matrices, whether the matrix is stored row-major */
327*61046927SAndroid Build Coastguard Worker bool row_major:1;
328*61046927SAndroid Build Coastguard Worker
329*61046927SAndroid Build Coastguard Worker /* Whether this type, or a parent type, has been decorated as a
330*61046927SAndroid Build Coastguard Worker * builtin
331*61046927SAndroid Build Coastguard Worker */
332*61046927SAndroid Build Coastguard Worker bool is_builtin:1;
333*61046927SAndroid Build Coastguard Worker
334*61046927SAndroid Build Coastguard Worker /* Which built-in to use */
335*61046927SAndroid Build Coastguard Worker SpvBuiltIn builtin;
336*61046927SAndroid Build Coastguard Worker };
337*61046927SAndroid Build Coastguard Worker
338*61046927SAndroid Build Coastguard Worker /* Members for struct types */
339*61046927SAndroid Build Coastguard Worker struct {
340*61046927SAndroid Build Coastguard Worker /* for structures, the vtn_type for each member */
341*61046927SAndroid Build Coastguard Worker struct vtn_type **members;
342*61046927SAndroid Build Coastguard Worker
343*61046927SAndroid Build Coastguard Worker /* for structs, the offset of each member */
344*61046927SAndroid Build Coastguard Worker unsigned *offsets;
345*61046927SAndroid Build Coastguard Worker
346*61046927SAndroid Build Coastguard Worker /* for structs, whether it was decorated as a "non-SSBO-like" block */
347*61046927SAndroid Build Coastguard Worker bool block:1;
348*61046927SAndroid Build Coastguard Worker
349*61046927SAndroid Build Coastguard Worker /* for structs, whether it was decorated as an "SSBO-like" block */
350*61046927SAndroid Build Coastguard Worker bool buffer_block:1;
351*61046927SAndroid Build Coastguard Worker
352*61046927SAndroid Build Coastguard Worker /* for structs with block == true, whether this is a builtin block
353*61046927SAndroid Build Coastguard Worker * (i.e. a block that contains only builtins).
354*61046927SAndroid Build Coastguard Worker */
355*61046927SAndroid Build Coastguard Worker bool builtin_block:1;
356*61046927SAndroid Build Coastguard Worker
357*61046927SAndroid Build Coastguard Worker /* for structs and unions it specifies the minimum alignment of the
358*61046927SAndroid Build Coastguard Worker * members. 0 means packed.
359*61046927SAndroid Build Coastguard Worker *
360*61046927SAndroid Build Coastguard Worker * Set by CPacked and Alignment Decorations in kernels.
361*61046927SAndroid Build Coastguard Worker */
362*61046927SAndroid Build Coastguard Worker bool packed:1;
363*61046927SAndroid Build Coastguard Worker };
364*61046927SAndroid Build Coastguard Worker
365*61046927SAndroid Build Coastguard Worker /* Members for pointer types */
366*61046927SAndroid Build Coastguard Worker struct {
367*61046927SAndroid Build Coastguard Worker /* For pointers, the vtn_type of the object pointed to. */
368*61046927SAndroid Build Coastguard Worker struct vtn_type *pointed;
369*61046927SAndroid Build Coastguard Worker
370*61046927SAndroid Build Coastguard Worker /* Storage class for pointers */
371*61046927SAndroid Build Coastguard Worker SpvStorageClass storage_class;
372*61046927SAndroid Build Coastguard Worker
373*61046927SAndroid Build Coastguard Worker /* Required alignment for pointers */
374*61046927SAndroid Build Coastguard Worker uint32_t align;
375*61046927SAndroid Build Coastguard Worker };
376*61046927SAndroid Build Coastguard Worker
377*61046927SAndroid Build Coastguard Worker /* Members for image types */
378*61046927SAndroid Build Coastguard Worker struct {
379*61046927SAndroid Build Coastguard Worker /* GLSL image type for this type. This is not to be confused with
380*61046927SAndroid Build Coastguard Worker * vtn_type::type which is actually going to be the GLSL type for a
381*61046927SAndroid Build Coastguard Worker * pointer to an image, likely a uint32_t.
382*61046927SAndroid Build Coastguard Worker */
383*61046927SAndroid Build Coastguard Worker const struct glsl_type *glsl_image;
384*61046927SAndroid Build Coastguard Worker
385*61046927SAndroid Build Coastguard Worker /* Image format for image_load_store type images */
386*61046927SAndroid Build Coastguard Worker unsigned image_format;
387*61046927SAndroid Build Coastguard Worker
388*61046927SAndroid Build Coastguard Worker /* Access qualifier for storage images */
389*61046927SAndroid Build Coastguard Worker SpvAccessQualifier access_qualifier;
390*61046927SAndroid Build Coastguard Worker };
391*61046927SAndroid Build Coastguard Worker
392*61046927SAndroid Build Coastguard Worker /* Members for sampled image types */
393*61046927SAndroid Build Coastguard Worker struct {
394*61046927SAndroid Build Coastguard Worker /* For sampled images, the image type */
395*61046927SAndroid Build Coastguard Worker struct vtn_type *image;
396*61046927SAndroid Build Coastguard Worker };
397*61046927SAndroid Build Coastguard Worker
398*61046927SAndroid Build Coastguard Worker /* Members for function types */
399*61046927SAndroid Build Coastguard Worker struct {
400*61046927SAndroid Build Coastguard Worker /* For functions, the vtn_type for each parameter */
401*61046927SAndroid Build Coastguard Worker struct vtn_type **params;
402*61046927SAndroid Build Coastguard Worker
403*61046927SAndroid Build Coastguard Worker /* Return type for functions */
404*61046927SAndroid Build Coastguard Worker struct vtn_type *return_type;
405*61046927SAndroid Build Coastguard Worker };
406*61046927SAndroid Build Coastguard Worker
407*61046927SAndroid Build Coastguard Worker /* Members for cooperative matrix types. */
408*61046927SAndroid Build Coastguard Worker struct {
409*61046927SAndroid Build Coastguard Worker struct glsl_cmat_description desc;
410*61046927SAndroid Build Coastguard Worker struct vtn_type *component_type;
411*61046927SAndroid Build Coastguard Worker };
412*61046927SAndroid Build Coastguard Worker };
413*61046927SAndroid Build Coastguard Worker };
414*61046927SAndroid Build Coastguard Worker
415*61046927SAndroid Build Coastguard Worker bool vtn_type_contains_block(struct vtn_builder *b, struct vtn_type *type);
416*61046927SAndroid Build Coastguard Worker
417*61046927SAndroid Build Coastguard Worker bool vtn_types_compatible(struct vtn_builder *b,
418*61046927SAndroid Build Coastguard Worker struct vtn_type *t1, struct vtn_type *t2);
419*61046927SAndroid Build Coastguard Worker
420*61046927SAndroid Build Coastguard Worker struct vtn_type *vtn_type_without_array(struct vtn_type *type);
421*61046927SAndroid Build Coastguard Worker
422*61046927SAndroid Build Coastguard Worker struct vtn_variable;
423*61046927SAndroid Build Coastguard Worker
424*61046927SAndroid Build Coastguard Worker enum vtn_access_mode {
425*61046927SAndroid Build Coastguard Worker vtn_access_mode_id,
426*61046927SAndroid Build Coastguard Worker vtn_access_mode_literal,
427*61046927SAndroid Build Coastguard Worker };
428*61046927SAndroid Build Coastguard Worker
429*61046927SAndroid Build Coastguard Worker struct vtn_access_link {
430*61046927SAndroid Build Coastguard Worker enum vtn_access_mode mode;
431*61046927SAndroid Build Coastguard Worker int64_t id;
432*61046927SAndroid Build Coastguard Worker };
433*61046927SAndroid Build Coastguard Worker
434*61046927SAndroid Build Coastguard Worker struct vtn_access_chain {
435*61046927SAndroid Build Coastguard Worker uint32_t length;
436*61046927SAndroid Build Coastguard Worker
437*61046927SAndroid Build Coastguard Worker /** Whether or not to treat the base pointer as an array. This is only
438*61046927SAndroid Build Coastguard Worker * true if this access chain came from an OpPtrAccessChain.
439*61046927SAndroid Build Coastguard Worker */
440*61046927SAndroid Build Coastguard Worker bool ptr_as_array;
441*61046927SAndroid Build Coastguard Worker
442*61046927SAndroid Build Coastguard Worker /* Access qualifiers */
443*61046927SAndroid Build Coastguard Worker enum gl_access_qualifier access;
444*61046927SAndroid Build Coastguard Worker
445*61046927SAndroid Build Coastguard Worker bool in_bounds;
446*61046927SAndroid Build Coastguard Worker
447*61046927SAndroid Build Coastguard Worker /** Struct elements and array offsets.
448*61046927SAndroid Build Coastguard Worker *
449*61046927SAndroid Build Coastguard Worker * This is an array of 1 so that it can conveniently be created on the
450*61046927SAndroid Build Coastguard Worker * stack but the real length is given by the length field.
451*61046927SAndroid Build Coastguard Worker */
452*61046927SAndroid Build Coastguard Worker struct vtn_access_link link[1];
453*61046927SAndroid Build Coastguard Worker };
454*61046927SAndroid Build Coastguard Worker
455*61046927SAndroid Build Coastguard Worker enum vtn_variable_mode {
456*61046927SAndroid Build Coastguard Worker vtn_variable_mode_function,
457*61046927SAndroid Build Coastguard Worker vtn_variable_mode_private,
458*61046927SAndroid Build Coastguard Worker vtn_variable_mode_uniform,
459*61046927SAndroid Build Coastguard Worker vtn_variable_mode_atomic_counter,
460*61046927SAndroid Build Coastguard Worker vtn_variable_mode_ubo,
461*61046927SAndroid Build Coastguard Worker vtn_variable_mode_ssbo,
462*61046927SAndroid Build Coastguard Worker vtn_variable_mode_phys_ssbo,
463*61046927SAndroid Build Coastguard Worker vtn_variable_mode_push_constant,
464*61046927SAndroid Build Coastguard Worker vtn_variable_mode_workgroup,
465*61046927SAndroid Build Coastguard Worker vtn_variable_mode_cross_workgroup,
466*61046927SAndroid Build Coastguard Worker vtn_variable_mode_task_payload,
467*61046927SAndroid Build Coastguard Worker vtn_variable_mode_generic,
468*61046927SAndroid Build Coastguard Worker vtn_variable_mode_constant,
469*61046927SAndroid Build Coastguard Worker vtn_variable_mode_input,
470*61046927SAndroid Build Coastguard Worker vtn_variable_mode_output,
471*61046927SAndroid Build Coastguard Worker vtn_variable_mode_image,
472*61046927SAndroid Build Coastguard Worker vtn_variable_mode_accel_struct,
473*61046927SAndroid Build Coastguard Worker vtn_variable_mode_call_data,
474*61046927SAndroid Build Coastguard Worker vtn_variable_mode_call_data_in,
475*61046927SAndroid Build Coastguard Worker vtn_variable_mode_ray_payload,
476*61046927SAndroid Build Coastguard Worker vtn_variable_mode_ray_payload_in,
477*61046927SAndroid Build Coastguard Worker vtn_variable_mode_hit_attrib,
478*61046927SAndroid Build Coastguard Worker vtn_variable_mode_shader_record,
479*61046927SAndroid Build Coastguard Worker vtn_variable_mode_node_payload,
480*61046927SAndroid Build Coastguard Worker };
481*61046927SAndroid Build Coastguard Worker
482*61046927SAndroid Build Coastguard Worker struct vtn_pointer {
483*61046927SAndroid Build Coastguard Worker /** The variable mode for the referenced data */
484*61046927SAndroid Build Coastguard Worker enum vtn_variable_mode mode;
485*61046927SAndroid Build Coastguard Worker
486*61046927SAndroid Build Coastguard Worker /** The pointer type of this pointer */
487*61046927SAndroid Build Coastguard Worker struct vtn_type *type;
488*61046927SAndroid Build Coastguard Worker
489*61046927SAndroid Build Coastguard Worker /** The referenced variable, if known
490*61046927SAndroid Build Coastguard Worker *
491*61046927SAndroid Build Coastguard Worker * This field may be NULL if the pointer uses a (block_index, offset) pair
492*61046927SAndroid Build Coastguard Worker * instead of an access chain or if the access chain starts at a deref.
493*61046927SAndroid Build Coastguard Worker */
494*61046927SAndroid Build Coastguard Worker struct vtn_variable *var;
495*61046927SAndroid Build Coastguard Worker
496*61046927SAndroid Build Coastguard Worker /** The NIR deref corresponding to this pointer */
497*61046927SAndroid Build Coastguard Worker nir_deref_instr *deref;
498*61046927SAndroid Build Coastguard Worker
499*61046927SAndroid Build Coastguard Worker /** A (block_index, offset) pair representing a UBO or SSBO position. */
500*61046927SAndroid Build Coastguard Worker struct nir_def *block_index;
501*61046927SAndroid Build Coastguard Worker struct nir_def *offset;
502*61046927SAndroid Build Coastguard Worker
503*61046927SAndroid Build Coastguard Worker /* Access qualifiers */
504*61046927SAndroid Build Coastguard Worker enum gl_access_qualifier access;
505*61046927SAndroid Build Coastguard Worker };
506*61046927SAndroid Build Coastguard Worker
507*61046927SAndroid Build Coastguard Worker struct vtn_variable {
508*61046927SAndroid Build Coastguard Worker enum vtn_variable_mode mode;
509*61046927SAndroid Build Coastguard Worker
510*61046927SAndroid Build Coastguard Worker struct vtn_type *type;
511*61046927SAndroid Build Coastguard Worker
512*61046927SAndroid Build Coastguard Worker unsigned descriptor_set;
513*61046927SAndroid Build Coastguard Worker unsigned binding;
514*61046927SAndroid Build Coastguard Worker bool explicit_binding;
515*61046927SAndroid Build Coastguard Worker unsigned offset;
516*61046927SAndroid Build Coastguard Worker unsigned input_attachment_index;
517*61046927SAndroid Build Coastguard Worker
518*61046927SAndroid Build Coastguard Worker nir_variable *var;
519*61046927SAndroid Build Coastguard Worker
520*61046927SAndroid Build Coastguard Worker /* If the variable is a struct with a location set on it then this will be
521*61046927SAndroid Build Coastguard Worker * stored here. This will be used to calculate locations for members that
522*61046927SAndroid Build Coastguard Worker * don’t have their own explicit location.
523*61046927SAndroid Build Coastguard Worker */
524*61046927SAndroid Build Coastguard Worker int base_location;
525*61046927SAndroid Build Coastguard Worker
526*61046927SAndroid Build Coastguard Worker /**
527*61046927SAndroid Build Coastguard Worker * In some early released versions of GLSLang, it implemented all function
528*61046927SAndroid Build Coastguard Worker * calls by making copies of all parameters into temporary variables and
529*61046927SAndroid Build Coastguard Worker * passing those variables into the function. It even did so for samplers
530*61046927SAndroid Build Coastguard Worker * and images which violates the SPIR-V spec. Unfortunately, two games
531*61046927SAndroid Build Coastguard Worker * (Talos Principle and Doom) shipped with this old version of GLSLang and
532*61046927SAndroid Build Coastguard Worker * also happen to pass samplers into functions. Talos Principle received
533*61046927SAndroid Build Coastguard Worker * an update fairly shortly after release with an updated GLSLang. Doom,
534*61046927SAndroid Build Coastguard Worker * on the other hand, has never received an update so we need to work
535*61046927SAndroid Build Coastguard Worker * around this GLSLang issue in SPIR-V -> NIR. Hopefully, we can drop this
536*61046927SAndroid Build Coastguard Worker * hack at some point in the future.
537*61046927SAndroid Build Coastguard Worker */
538*61046927SAndroid Build Coastguard Worker struct vtn_pointer *copy_prop_sampler;
539*61046927SAndroid Build Coastguard Worker
540*61046927SAndroid Build Coastguard Worker /* Access qualifiers. */
541*61046927SAndroid Build Coastguard Worker enum gl_access_qualifier access;
542*61046927SAndroid Build Coastguard Worker };
543*61046927SAndroid Build Coastguard Worker
544*61046927SAndroid Build Coastguard Worker const struct glsl_type *
545*61046927SAndroid Build Coastguard Worker vtn_type_get_nir_type(struct vtn_builder *b, struct vtn_type *type,
546*61046927SAndroid Build Coastguard Worker enum vtn_variable_mode mode);
547*61046927SAndroid Build Coastguard Worker
548*61046927SAndroid Build Coastguard Worker mesa_scope
549*61046927SAndroid Build Coastguard Worker vtn_translate_scope(struct vtn_builder *b, SpvScope scope);
550*61046927SAndroid Build Coastguard Worker
551*61046927SAndroid Build Coastguard Worker struct vtn_image_pointer {
552*61046927SAndroid Build Coastguard Worker nir_deref_instr *image;
553*61046927SAndroid Build Coastguard Worker nir_def *coord;
554*61046927SAndroid Build Coastguard Worker nir_def *sample;
555*61046927SAndroid Build Coastguard Worker nir_def *lod;
556*61046927SAndroid Build Coastguard Worker };
557*61046927SAndroid Build Coastguard Worker
558*61046927SAndroid Build Coastguard Worker struct vtn_value {
559*61046927SAndroid Build Coastguard Worker enum vtn_value_type value_type;
560*61046927SAndroid Build Coastguard Worker
561*61046927SAndroid Build Coastguard Worker /* Workaround for https://gitlab.freedesktop.org/mesa/mesa/-/issues/3406
562*61046927SAndroid Build Coastguard Worker * Only set for OpImage / OpSampledImage. Note that this is in addition
563*61046927SAndroid Build Coastguard Worker * the existence of a NonUniform decoration on this value.*/
564*61046927SAndroid Build Coastguard Worker uint32_t propagated_non_uniform : 1;
565*61046927SAndroid Build Coastguard Worker
566*61046927SAndroid Build Coastguard Worker /* Valid for vtn_value_type_constant to indicate the value is OpConstantNull. */
567*61046927SAndroid Build Coastguard Worker bool is_null_constant:1;
568*61046927SAndroid Build Coastguard Worker
569*61046927SAndroid Build Coastguard Worker /* Valid when all the members of the value are undef. */
570*61046927SAndroid Build Coastguard Worker bool is_undef_constant:1;
571*61046927SAndroid Build Coastguard Worker
572*61046927SAndroid Build Coastguard Worker const char *name;
573*61046927SAndroid Build Coastguard Worker struct vtn_decoration *decoration;
574*61046927SAndroid Build Coastguard Worker struct vtn_type *type;
575*61046927SAndroid Build Coastguard Worker union {
576*61046927SAndroid Build Coastguard Worker const char *str;
577*61046927SAndroid Build Coastguard Worker nir_constant *constant;
578*61046927SAndroid Build Coastguard Worker struct vtn_pointer *pointer;
579*61046927SAndroid Build Coastguard Worker struct vtn_image_pointer *image;
580*61046927SAndroid Build Coastguard Worker struct vtn_function *func;
581*61046927SAndroid Build Coastguard Worker struct vtn_block *block;
582*61046927SAndroid Build Coastguard Worker struct vtn_ssa_value *ssa;
583*61046927SAndroid Build Coastguard Worker vtn_instruction_handler ext_handler;
584*61046927SAndroid Build Coastguard Worker };
585*61046927SAndroid Build Coastguard Worker };
586*61046927SAndroid Build Coastguard Worker
587*61046927SAndroid Build Coastguard Worker #define VTN_DEC_DECORATION -1
588*61046927SAndroid Build Coastguard Worker #define VTN_DEC_EXECUTION_MODE -2
589*61046927SAndroid Build Coastguard Worker #define VTN_DEC_STRUCT_MEMBER_NAME0 -3
590*61046927SAndroid Build Coastguard Worker #define VTN_DEC_STRUCT_MEMBER0 0
591*61046927SAndroid Build Coastguard Worker
592*61046927SAndroid Build Coastguard Worker struct vtn_decoration {
593*61046927SAndroid Build Coastguard Worker struct vtn_decoration *next;
594*61046927SAndroid Build Coastguard Worker
595*61046927SAndroid Build Coastguard Worker /* Different kinds of decorations are stored in a value,
596*61046927SAndroid Build Coastguard Worker the scope defines what decoration it refers to:
597*61046927SAndroid Build Coastguard Worker
598*61046927SAndroid Build Coastguard Worker - VTN_DEC_DECORATION:
599*61046927SAndroid Build Coastguard Worker decoration associated with the value
600*61046927SAndroid Build Coastguard Worker - VTN_DEC_EXECUTION_MODE:
601*61046927SAndroid Build Coastguard Worker an execution mode associated with an entrypoint value
602*61046927SAndroid Build Coastguard Worker - VTN_DEC_STRUCT_MEMBER0 + m:
603*61046927SAndroid Build Coastguard Worker decoration associated with member m of a struct value
604*61046927SAndroid Build Coastguard Worker - VTN_DEC_STRUCT_MEMBER_NAME0 - m:
605*61046927SAndroid Build Coastguard Worker name of m'th member of a struct value
606*61046927SAndroid Build Coastguard Worker */
607*61046927SAndroid Build Coastguard Worker int scope;
608*61046927SAndroid Build Coastguard Worker
609*61046927SAndroid Build Coastguard Worker uint32_t num_operands;
610*61046927SAndroid Build Coastguard Worker const uint32_t *operands;
611*61046927SAndroid Build Coastguard Worker struct vtn_value *group;
612*61046927SAndroid Build Coastguard Worker
613*61046927SAndroid Build Coastguard Worker union {
614*61046927SAndroid Build Coastguard Worker SpvDecoration decoration;
615*61046927SAndroid Build Coastguard Worker SpvExecutionMode exec_mode;
616*61046927SAndroid Build Coastguard Worker const char *member_name;
617*61046927SAndroid Build Coastguard Worker };
618*61046927SAndroid Build Coastguard Worker };
619*61046927SAndroid Build Coastguard Worker
620*61046927SAndroid Build Coastguard Worker struct vtn_builder {
621*61046927SAndroid Build Coastguard Worker nir_builder nb;
622*61046927SAndroid Build Coastguard Worker
623*61046927SAndroid Build Coastguard Worker linear_ctx *lin_ctx;
624*61046927SAndroid Build Coastguard Worker
625*61046927SAndroid Build Coastguard Worker /* Used by vtn_fail to jump back to the beginning of SPIR-V compilation */
626*61046927SAndroid Build Coastguard Worker jmp_buf fail_jump;
627*61046927SAndroid Build Coastguard Worker
628*61046927SAndroid Build Coastguard Worker const uint32_t *spirv;
629*61046927SAndroid Build Coastguard Worker size_t spirv_word_count;
630*61046927SAndroid Build Coastguard Worker uint32_t version;
631*61046927SAndroid Build Coastguard Worker
632*61046927SAndroid Build Coastguard Worker nir_shader *shader;
633*61046927SAndroid Build Coastguard Worker struct spirv_to_nir_options *options;
634*61046927SAndroid Build Coastguard Worker struct vtn_block *block;
635*61046927SAndroid Build Coastguard Worker
636*61046927SAndroid Build Coastguard Worker /* Current offset, file, line, and column. Useful for debugging. Set
637*61046927SAndroid Build Coastguard Worker * automatically by vtn_foreach_instruction.
638*61046927SAndroid Build Coastguard Worker */
639*61046927SAndroid Build Coastguard Worker size_t spirv_offset;
640*61046927SAndroid Build Coastguard Worker const char *file;
641*61046927SAndroid Build Coastguard Worker int line, col;
642*61046927SAndroid Build Coastguard Worker
643*61046927SAndroid Build Coastguard Worker /*
644*61046927SAndroid Build Coastguard Worker * Map from phi instructions (pointer to the start of the instruction)
645*61046927SAndroid Build Coastguard Worker * to the variable corresponding to it.
646*61046927SAndroid Build Coastguard Worker */
647*61046927SAndroid Build Coastguard Worker struct hash_table *phi_table;
648*61046927SAndroid Build Coastguard Worker
649*61046927SAndroid Build Coastguard Worker /* In Vulkan, when lowering some modes variable access, the derefs of the
650*61046927SAndroid Build Coastguard Worker * variables are replaced with a resource index intrinsics, leaving the
651*61046927SAndroid Build Coastguard Worker * variable hanging. This set keeps track of them so they can be filtered
652*61046927SAndroid Build Coastguard Worker * (and not removed) in nir_remove_dead_variables.
653*61046927SAndroid Build Coastguard Worker */
654*61046927SAndroid Build Coastguard Worker struct set *vars_used_indirectly;
655*61046927SAndroid Build Coastguard Worker
656*61046927SAndroid Build Coastguard Worker unsigned num_specializations;
657*61046927SAndroid Build Coastguard Worker struct nir_spirv_specialization *specializations;
658*61046927SAndroid Build Coastguard Worker
659*61046927SAndroid Build Coastguard Worker unsigned value_id_bound;
660*61046927SAndroid Build Coastguard Worker struct vtn_value *values;
661*61046927SAndroid Build Coastguard Worker
662*61046927SAndroid Build Coastguard Worker /* Information on the origin of the SPIR-V */
663*61046927SAndroid Build Coastguard Worker enum vtn_generator generator_id;
664*61046927SAndroid Build Coastguard Worker SpvSourceLanguage source_lang;
665*61046927SAndroid Build Coastguard Worker
666*61046927SAndroid Build Coastguard Worker struct spirv_capabilities supported_capabilities;
667*61046927SAndroid Build Coastguard Worker struct spirv_capabilities enabled_capabilities;
668*61046927SAndroid Build Coastguard Worker
669*61046927SAndroid Build Coastguard Worker /* True if we need to fix up CS OpControlBarrier */
670*61046927SAndroid Build Coastguard Worker bool wa_glslang_cs_barrier;
671*61046927SAndroid Build Coastguard Worker
672*61046927SAndroid Build Coastguard Worker /* True if we need to ignore undef initializers */
673*61046927SAndroid Build Coastguard Worker bool wa_llvm_spirv_ignore_workgroup_initializer;
674*61046927SAndroid Build Coastguard Worker
675*61046927SAndroid Build Coastguard Worker /* True if we need to ignore OpReturn after OpEmitMeshTasksEXT. */
676*61046927SAndroid Build Coastguard Worker bool wa_ignore_return_after_emit_mesh_tasks;
677*61046927SAndroid Build Coastguard Worker
678*61046927SAndroid Build Coastguard Worker /* Workaround discard bugs in HLSL -> SPIR-V compilers */
679*61046927SAndroid Build Coastguard Worker bool convert_discard_to_demote;
680*61046927SAndroid Build Coastguard Worker
681*61046927SAndroid Build Coastguard Worker gl_shader_stage entry_point_stage;
682*61046927SAndroid Build Coastguard Worker const char *entry_point_name;
683*61046927SAndroid Build Coastguard Worker struct vtn_value *entry_point;
684*61046927SAndroid Build Coastguard Worker struct vtn_value *workgroup_size_builtin;
685*61046927SAndroid Build Coastguard Worker
686*61046927SAndroid Build Coastguard Worker uint32_t *interface_ids;
687*61046927SAndroid Build Coastguard Worker size_t interface_ids_count;
688*61046927SAndroid Build Coastguard Worker
689*61046927SAndroid Build Coastguard Worker struct vtn_function *func;
690*61046927SAndroid Build Coastguard Worker struct list_head functions;
691*61046927SAndroid Build Coastguard Worker
692*61046927SAndroid Build Coastguard Worker struct hash_table *strings;
693*61046927SAndroid Build Coastguard Worker
694*61046927SAndroid Build Coastguard Worker /* Current function parameter index */
695*61046927SAndroid Build Coastguard Worker unsigned func_param_idx;
696*61046927SAndroid Build Coastguard Worker
697*61046927SAndroid Build Coastguard Worker /* false by default, set to true by the ContractionOff execution mode */
698*61046927SAndroid Build Coastguard Worker bool exact;
699*61046927SAndroid Build Coastguard Worker
700*61046927SAndroid Build Coastguard Worker /* when a physical memory model is choosen */
701*61046927SAndroid Build Coastguard Worker bool physical_ptrs;
702*61046927SAndroid Build Coastguard Worker
703*61046927SAndroid Build Coastguard Worker /* memory model specified by OpMemoryModel */
704*61046927SAndroid Build Coastguard Worker unsigned mem_model;
705*61046927SAndroid Build Coastguard Worker };
706*61046927SAndroid Build Coastguard Worker
707*61046927SAndroid Build Coastguard Worker const char *
708*61046927SAndroid Build Coastguard Worker vtn_string_literal(struct vtn_builder *b, const uint32_t *words,
709*61046927SAndroid Build Coastguard Worker unsigned word_count, unsigned *words_used);
710*61046927SAndroid Build Coastguard Worker
711*61046927SAndroid Build Coastguard Worker nir_def *
712*61046927SAndroid Build Coastguard Worker vtn_pointer_to_ssa(struct vtn_builder *b, struct vtn_pointer *ptr);
713*61046927SAndroid Build Coastguard Worker struct vtn_pointer *
714*61046927SAndroid Build Coastguard Worker vtn_pointer_from_ssa(struct vtn_builder *b, nir_def *ssa,
715*61046927SAndroid Build Coastguard Worker struct vtn_type *ptr_type);
716*61046927SAndroid Build Coastguard Worker
717*61046927SAndroid Build Coastguard Worker struct vtn_ssa_value *
718*61046927SAndroid Build Coastguard Worker vtn_const_ssa_value(struct vtn_builder *b, nir_constant *constant,
719*61046927SAndroid Build Coastguard Worker const struct glsl_type *type);
720*61046927SAndroid Build Coastguard Worker
721*61046927SAndroid Build Coastguard Worker static inline struct vtn_value *
vtn_untyped_value(struct vtn_builder * b,uint32_t value_id)722*61046927SAndroid Build Coastguard Worker vtn_untyped_value(struct vtn_builder *b, uint32_t value_id)
723*61046927SAndroid Build Coastguard Worker {
724*61046927SAndroid Build Coastguard Worker vtn_fail_if(value_id >= b->value_id_bound,
725*61046927SAndroid Build Coastguard Worker "SPIR-V id %u is out-of-bounds", value_id);
726*61046927SAndroid Build Coastguard Worker return &b->values[value_id];
727*61046927SAndroid Build Coastguard Worker }
728*61046927SAndroid Build Coastguard Worker
729*61046927SAndroid Build Coastguard Worker void vtn_print_value(struct vtn_builder *b, struct vtn_value *val, FILE *f);
730*61046927SAndroid Build Coastguard Worker void vtn_dump_values(struct vtn_builder *b, FILE *f);
731*61046927SAndroid Build Coastguard Worker
732*61046927SAndroid Build Coastguard Worker static inline uint32_t
vtn_id_for_value(struct vtn_builder * b,struct vtn_value * value)733*61046927SAndroid Build Coastguard Worker vtn_id_for_value(struct vtn_builder *b, struct vtn_value *value)
734*61046927SAndroid Build Coastguard Worker {
735*61046927SAndroid Build Coastguard Worker vtn_fail_if(value <= b->values, "vtn_value pointer outside the range of valid values");
736*61046927SAndroid Build Coastguard Worker uint32_t value_id = value - b->values;
737*61046927SAndroid Build Coastguard Worker vtn_fail_if(value_id >= b->value_id_bound, "vtn_value pointer outside the range of valid values");
738*61046927SAndroid Build Coastguard Worker return value_id;
739*61046927SAndroid Build Coastguard Worker }
740*61046927SAndroid Build Coastguard Worker
741*61046927SAndroid Build Coastguard Worker /* Consider not using this function directly and instead use
742*61046927SAndroid Build Coastguard Worker * vtn_push_ssa/vtn_push_pointer so that appropriate applying of
743*61046927SAndroid Build Coastguard Worker * decorations is handled by common code.
744*61046927SAndroid Build Coastguard Worker */
745*61046927SAndroid Build Coastguard Worker static inline struct vtn_value *
vtn_push_value(struct vtn_builder * b,uint32_t value_id,enum vtn_value_type value_type)746*61046927SAndroid Build Coastguard Worker vtn_push_value(struct vtn_builder *b, uint32_t value_id,
747*61046927SAndroid Build Coastguard Worker enum vtn_value_type value_type)
748*61046927SAndroid Build Coastguard Worker {
749*61046927SAndroid Build Coastguard Worker struct vtn_value *val = vtn_untyped_value(b, value_id);
750*61046927SAndroid Build Coastguard Worker
751*61046927SAndroid Build Coastguard Worker vtn_fail_if(value_type == vtn_value_type_ssa,
752*61046927SAndroid Build Coastguard Worker "Do not call vtn_push_value for value_type_ssa. Use "
753*61046927SAndroid Build Coastguard Worker "vtn_push_ssa_value instead.");
754*61046927SAndroid Build Coastguard Worker
755*61046927SAndroid Build Coastguard Worker vtn_fail_if(val->value_type != vtn_value_type_invalid,
756*61046927SAndroid Build Coastguard Worker "SPIR-V id %u has already been written by another instruction",
757*61046927SAndroid Build Coastguard Worker value_id);
758*61046927SAndroid Build Coastguard Worker
759*61046927SAndroid Build Coastguard Worker val->value_type = value_type;
760*61046927SAndroid Build Coastguard Worker
761*61046927SAndroid Build Coastguard Worker return &b->values[value_id];
762*61046927SAndroid Build Coastguard Worker }
763*61046927SAndroid Build Coastguard Worker
764*61046927SAndroid Build Coastguard Worker /* These separated fail functions exist so the helpers like vtn_value()
765*61046927SAndroid Build Coastguard Worker * can be inlined with minimal code size impact. This allows the failure
766*61046927SAndroid Build Coastguard Worker * handling to have more detailed output without harming callers.
767*61046927SAndroid Build Coastguard Worker */
768*61046927SAndroid Build Coastguard Worker
769*61046927SAndroid Build Coastguard Worker void _vtn_fail_value_type_mismatch(struct vtn_builder *b, uint32_t value_id,
770*61046927SAndroid Build Coastguard Worker enum vtn_value_type value_type);
771*61046927SAndroid Build Coastguard Worker void _vtn_fail_value_not_pointer(struct vtn_builder *b, uint32_t value_id);
772*61046927SAndroid Build Coastguard Worker
773*61046927SAndroid Build Coastguard Worker static inline struct vtn_value *
vtn_value(struct vtn_builder * b,uint32_t value_id,enum vtn_value_type value_type)774*61046927SAndroid Build Coastguard Worker vtn_value(struct vtn_builder *b, uint32_t value_id,
775*61046927SAndroid Build Coastguard Worker enum vtn_value_type value_type)
776*61046927SAndroid Build Coastguard Worker {
777*61046927SAndroid Build Coastguard Worker struct vtn_value *val = vtn_untyped_value(b, value_id);
778*61046927SAndroid Build Coastguard Worker if (unlikely(val->value_type != value_type))
779*61046927SAndroid Build Coastguard Worker _vtn_fail_value_type_mismatch(b, value_id, value_type);
780*61046927SAndroid Build Coastguard Worker return val;
781*61046927SAndroid Build Coastguard Worker }
782*61046927SAndroid Build Coastguard Worker
783*61046927SAndroid Build Coastguard Worker static inline struct vtn_value *
vtn_pointer_value(struct vtn_builder * b,uint32_t value_id)784*61046927SAndroid Build Coastguard Worker vtn_pointer_value(struct vtn_builder *b, uint32_t value_id)
785*61046927SAndroid Build Coastguard Worker {
786*61046927SAndroid Build Coastguard Worker struct vtn_value *val = vtn_untyped_value(b, value_id);
787*61046927SAndroid Build Coastguard Worker if (unlikely(val->value_type != vtn_value_type_pointer &&
788*61046927SAndroid Build Coastguard Worker !val->is_null_constant))
789*61046927SAndroid Build Coastguard Worker _vtn_fail_value_not_pointer(b, value_id);
790*61046927SAndroid Build Coastguard Worker return val;
791*61046927SAndroid Build Coastguard Worker }
792*61046927SAndroid Build Coastguard Worker
793*61046927SAndroid Build Coastguard Worker static inline struct vtn_pointer *
vtn_value_to_pointer(struct vtn_builder * b,struct vtn_value * value)794*61046927SAndroid Build Coastguard Worker vtn_value_to_pointer(struct vtn_builder *b, struct vtn_value *value)
795*61046927SAndroid Build Coastguard Worker {
796*61046927SAndroid Build Coastguard Worker if (value->is_null_constant) {
797*61046927SAndroid Build Coastguard Worker vtn_assert(glsl_type_is_vector_or_scalar(value->type->type));
798*61046927SAndroid Build Coastguard Worker nir_def *const_ssa =
799*61046927SAndroid Build Coastguard Worker vtn_const_ssa_value(b, value->constant, value->type->type)->def;
800*61046927SAndroid Build Coastguard Worker return vtn_pointer_from_ssa(b, const_ssa, value->type);
801*61046927SAndroid Build Coastguard Worker }
802*61046927SAndroid Build Coastguard Worker vtn_assert(value->value_type == vtn_value_type_pointer);
803*61046927SAndroid Build Coastguard Worker return value->pointer;
804*61046927SAndroid Build Coastguard Worker }
805*61046927SAndroid Build Coastguard Worker
806*61046927SAndroid Build Coastguard Worker static inline struct vtn_pointer *
vtn_pointer(struct vtn_builder * b,uint32_t value_id)807*61046927SAndroid Build Coastguard Worker vtn_pointer(struct vtn_builder *b, uint32_t value_id)
808*61046927SAndroid Build Coastguard Worker {
809*61046927SAndroid Build Coastguard Worker return vtn_value_to_pointer(b, vtn_pointer_value(b, value_id));
810*61046927SAndroid Build Coastguard Worker }
811*61046927SAndroid Build Coastguard Worker
812*61046927SAndroid Build Coastguard Worker bool
813*61046927SAndroid Build Coastguard Worker vtn_set_instruction_result_type(struct vtn_builder *b, SpvOp opcode,
814*61046927SAndroid Build Coastguard Worker const uint32_t *w, unsigned count);
815*61046927SAndroid Build Coastguard Worker
816*61046927SAndroid Build Coastguard Worker static inline uint64_t
vtn_constant_uint(struct vtn_builder * b,uint32_t value_id)817*61046927SAndroid Build Coastguard Worker vtn_constant_uint(struct vtn_builder *b, uint32_t value_id)
818*61046927SAndroid Build Coastguard Worker {
819*61046927SAndroid Build Coastguard Worker struct vtn_value *val = vtn_value(b, value_id, vtn_value_type_constant);
820*61046927SAndroid Build Coastguard Worker
821*61046927SAndroid Build Coastguard Worker vtn_fail_if(val->type->base_type != vtn_base_type_scalar ||
822*61046927SAndroid Build Coastguard Worker !glsl_type_is_integer(val->type->type),
823*61046927SAndroid Build Coastguard Worker "Expected id %u to be an integer constant", value_id);
824*61046927SAndroid Build Coastguard Worker
825*61046927SAndroid Build Coastguard Worker switch (glsl_get_bit_size(val->type->type)) {
826*61046927SAndroid Build Coastguard Worker case 8: return val->constant->values[0].u8;
827*61046927SAndroid Build Coastguard Worker case 16: return val->constant->values[0].u16;
828*61046927SAndroid Build Coastguard Worker case 32: return val->constant->values[0].u32;
829*61046927SAndroid Build Coastguard Worker case 64: return val->constant->values[0].u64;
830*61046927SAndroid Build Coastguard Worker default: unreachable("Invalid bit size");
831*61046927SAndroid Build Coastguard Worker }
832*61046927SAndroid Build Coastguard Worker }
833*61046927SAndroid Build Coastguard Worker
834*61046927SAndroid Build Coastguard Worker static inline int64_t
vtn_constant_int(struct vtn_builder * b,uint32_t value_id)835*61046927SAndroid Build Coastguard Worker vtn_constant_int(struct vtn_builder *b, uint32_t value_id)
836*61046927SAndroid Build Coastguard Worker {
837*61046927SAndroid Build Coastguard Worker struct vtn_value *val = vtn_value(b, value_id, vtn_value_type_constant);
838*61046927SAndroid Build Coastguard Worker
839*61046927SAndroid Build Coastguard Worker vtn_fail_if(val->type->base_type != vtn_base_type_scalar ||
840*61046927SAndroid Build Coastguard Worker !glsl_type_is_integer(val->type->type),
841*61046927SAndroid Build Coastguard Worker "Expected id %u to be an integer constant", value_id);
842*61046927SAndroid Build Coastguard Worker
843*61046927SAndroid Build Coastguard Worker switch (glsl_get_bit_size(val->type->type)) {
844*61046927SAndroid Build Coastguard Worker case 8: return val->constant->values[0].i8;
845*61046927SAndroid Build Coastguard Worker case 16: return val->constant->values[0].i16;
846*61046927SAndroid Build Coastguard Worker case 32: return val->constant->values[0].i32;
847*61046927SAndroid Build Coastguard Worker case 64: return val->constant->values[0].i64;
848*61046927SAndroid Build Coastguard Worker default: unreachable("Invalid bit size");
849*61046927SAndroid Build Coastguard Worker }
850*61046927SAndroid Build Coastguard Worker }
851*61046927SAndroid Build Coastguard Worker
852*61046927SAndroid Build Coastguard Worker static inline struct vtn_type *
vtn_get_value_type(struct vtn_builder * b,uint32_t value_id)853*61046927SAndroid Build Coastguard Worker vtn_get_value_type(struct vtn_builder *b, uint32_t value_id)
854*61046927SAndroid Build Coastguard Worker {
855*61046927SAndroid Build Coastguard Worker struct vtn_value *val = vtn_untyped_value(b, value_id);
856*61046927SAndroid Build Coastguard Worker vtn_fail_if(val->type == NULL, "Value %u does not have a type", value_id);
857*61046927SAndroid Build Coastguard Worker return val->type;
858*61046927SAndroid Build Coastguard Worker }
859*61046927SAndroid Build Coastguard Worker
860*61046927SAndroid Build Coastguard Worker static inline struct vtn_type *
vtn_get_type(struct vtn_builder * b,uint32_t value_id)861*61046927SAndroid Build Coastguard Worker vtn_get_type(struct vtn_builder *b, uint32_t value_id)
862*61046927SAndroid Build Coastguard Worker {
863*61046927SAndroid Build Coastguard Worker return vtn_value(b, value_id, vtn_value_type_type)->type;
864*61046927SAndroid Build Coastguard Worker }
865*61046927SAndroid Build Coastguard Worker
866*61046927SAndroid Build Coastguard Worker static inline struct vtn_block *
vtn_block(struct vtn_builder * b,uint32_t value_id)867*61046927SAndroid Build Coastguard Worker vtn_block(struct vtn_builder *b, uint32_t value_id)
868*61046927SAndroid Build Coastguard Worker {
869*61046927SAndroid Build Coastguard Worker return vtn_value(b, value_id, vtn_value_type_block)->block;
870*61046927SAndroid Build Coastguard Worker }
871*61046927SAndroid Build Coastguard Worker
872*61046927SAndroid Build Coastguard Worker struct vtn_ssa_value *vtn_ssa_value(struct vtn_builder *b, uint32_t value_id);
873*61046927SAndroid Build Coastguard Worker struct vtn_value *vtn_push_ssa_value(struct vtn_builder *b, uint32_t value_id,
874*61046927SAndroid Build Coastguard Worker struct vtn_ssa_value *ssa);
875*61046927SAndroid Build Coastguard Worker
876*61046927SAndroid Build Coastguard Worker nir_def *vtn_get_nir_ssa(struct vtn_builder *b, uint32_t value_id);
877*61046927SAndroid Build Coastguard Worker struct vtn_value *vtn_push_nir_ssa(struct vtn_builder *b, uint32_t value_id,
878*61046927SAndroid Build Coastguard Worker nir_def *def);
879*61046927SAndroid Build Coastguard Worker nir_deref_instr *vtn_get_deref_for_id(struct vtn_builder *b, uint32_t value_id);
880*61046927SAndroid Build Coastguard Worker nir_deref_instr *vtn_get_deref_for_ssa_value(struct vtn_builder *b, struct vtn_ssa_value *ssa);
881*61046927SAndroid Build Coastguard Worker struct vtn_value *vtn_push_var_ssa(struct vtn_builder *b, uint32_t value_id,
882*61046927SAndroid Build Coastguard Worker nir_variable *var);
883*61046927SAndroid Build Coastguard Worker
884*61046927SAndroid Build Coastguard Worker struct vtn_value *vtn_push_pointer(struct vtn_builder *b,
885*61046927SAndroid Build Coastguard Worker uint32_t value_id,
886*61046927SAndroid Build Coastguard Worker struct vtn_pointer *ptr);
887*61046927SAndroid Build Coastguard Worker
888*61046927SAndroid Build Coastguard Worker struct vtn_sampled_image {
889*61046927SAndroid Build Coastguard Worker nir_deref_instr *image;
890*61046927SAndroid Build Coastguard Worker nir_deref_instr *sampler;
891*61046927SAndroid Build Coastguard Worker };
892*61046927SAndroid Build Coastguard Worker
893*61046927SAndroid Build Coastguard Worker nir_def *vtn_sampled_image_to_nir_ssa(struct vtn_builder *b,
894*61046927SAndroid Build Coastguard Worker struct vtn_sampled_image si);
895*61046927SAndroid Build Coastguard Worker
896*61046927SAndroid Build Coastguard Worker void
897*61046927SAndroid Build Coastguard Worker vtn_copy_value(struct vtn_builder *b, uint32_t src_value_id,
898*61046927SAndroid Build Coastguard Worker uint32_t dst_value_id);
899*61046927SAndroid Build Coastguard Worker
900*61046927SAndroid Build Coastguard Worker struct vtn_ssa_value *vtn_create_ssa_value(struct vtn_builder *b,
901*61046927SAndroid Build Coastguard Worker const struct glsl_type *type);
902*61046927SAndroid Build Coastguard Worker void vtn_set_ssa_value_var(struct vtn_builder *b, struct vtn_ssa_value *ssa, nir_variable *var);
903*61046927SAndroid Build Coastguard Worker
904*61046927SAndroid Build Coastguard Worker struct vtn_ssa_value *vtn_ssa_transpose(struct vtn_builder *b,
905*61046927SAndroid Build Coastguard Worker struct vtn_ssa_value *src);
906*61046927SAndroid Build Coastguard Worker
907*61046927SAndroid Build Coastguard Worker nir_deref_instr *vtn_nir_deref(struct vtn_builder *b, uint32_t id);
908*61046927SAndroid Build Coastguard Worker
909*61046927SAndroid Build Coastguard Worker nir_deref_instr *vtn_pointer_to_deref(struct vtn_builder *b,
910*61046927SAndroid Build Coastguard Worker struct vtn_pointer *ptr);
911*61046927SAndroid Build Coastguard Worker nir_def *
912*61046927SAndroid Build Coastguard Worker vtn_pointer_to_offset(struct vtn_builder *b, struct vtn_pointer *ptr,
913*61046927SAndroid Build Coastguard Worker nir_def **index_out);
914*61046927SAndroid Build Coastguard Worker
915*61046927SAndroid Build Coastguard Worker nir_deref_instr *
916*61046927SAndroid Build Coastguard Worker vtn_get_call_payload_for_location(struct vtn_builder *b, uint32_t location_id);
917*61046927SAndroid Build Coastguard Worker
918*61046927SAndroid Build Coastguard Worker struct vtn_ssa_value *
919*61046927SAndroid Build Coastguard Worker vtn_local_load(struct vtn_builder *b, nir_deref_instr *src,
920*61046927SAndroid Build Coastguard Worker enum gl_access_qualifier access);
921*61046927SAndroid Build Coastguard Worker
922*61046927SAndroid Build Coastguard Worker void vtn_local_store(struct vtn_builder *b, struct vtn_ssa_value *src,
923*61046927SAndroid Build Coastguard Worker nir_deref_instr *dest,
924*61046927SAndroid Build Coastguard Worker enum gl_access_qualifier access);
925*61046927SAndroid Build Coastguard Worker
926*61046927SAndroid Build Coastguard Worker struct vtn_ssa_value *
927*61046927SAndroid Build Coastguard Worker vtn_variable_load(struct vtn_builder *b, struct vtn_pointer *src,
928*61046927SAndroid Build Coastguard Worker enum gl_access_qualifier access);
929*61046927SAndroid Build Coastguard Worker
930*61046927SAndroid Build Coastguard Worker void vtn_variable_store(struct vtn_builder *b, struct vtn_ssa_value *src,
931*61046927SAndroid Build Coastguard Worker struct vtn_pointer *dest, enum gl_access_qualifier access);
932*61046927SAndroid Build Coastguard Worker
933*61046927SAndroid Build Coastguard Worker void vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
934*61046927SAndroid Build Coastguard Worker const uint32_t *w, unsigned count);
935*61046927SAndroid Build Coastguard Worker
936*61046927SAndroid Build Coastguard Worker
937*61046927SAndroid Build Coastguard Worker typedef void (*vtn_decoration_foreach_cb)(struct vtn_builder *,
938*61046927SAndroid Build Coastguard Worker struct vtn_value *,
939*61046927SAndroid Build Coastguard Worker int member,
940*61046927SAndroid Build Coastguard Worker const struct vtn_decoration *,
941*61046927SAndroid Build Coastguard Worker void *);
942*61046927SAndroid Build Coastguard Worker
943*61046927SAndroid Build Coastguard Worker void vtn_foreach_decoration(struct vtn_builder *b, struct vtn_value *value,
944*61046927SAndroid Build Coastguard Worker vtn_decoration_foreach_cb cb, void *data);
945*61046927SAndroid Build Coastguard Worker
946*61046927SAndroid Build Coastguard Worker typedef void (*vtn_execution_mode_foreach_cb)(struct vtn_builder *,
947*61046927SAndroid Build Coastguard Worker struct vtn_value *,
948*61046927SAndroid Build Coastguard Worker const struct vtn_decoration *,
949*61046927SAndroid Build Coastguard Worker void *);
950*61046927SAndroid Build Coastguard Worker
951*61046927SAndroid Build Coastguard Worker void vtn_foreach_execution_mode(struct vtn_builder *b, struct vtn_value *value,
952*61046927SAndroid Build Coastguard Worker vtn_execution_mode_foreach_cb cb, void *data);
953*61046927SAndroid Build Coastguard Worker
954*61046927SAndroid Build Coastguard Worker nir_op vtn_nir_alu_op_for_spirv_opcode(struct vtn_builder *b,
955*61046927SAndroid Build Coastguard Worker SpvOp opcode, bool *swap, bool *exact,
956*61046927SAndroid Build Coastguard Worker unsigned src_bit_size, unsigned dst_bit_size);
957*61046927SAndroid Build Coastguard Worker
958*61046927SAndroid Build Coastguard Worker void vtn_handle_alu(struct vtn_builder *b, SpvOp opcode,
959*61046927SAndroid Build Coastguard Worker const uint32_t *w, unsigned count);
960*61046927SAndroid Build Coastguard Worker
961*61046927SAndroid Build Coastguard Worker void vtn_handle_integer_dot(struct vtn_builder *b, SpvOp opcode,
962*61046927SAndroid Build Coastguard Worker const uint32_t *w, unsigned count);
963*61046927SAndroid Build Coastguard Worker
964*61046927SAndroid Build Coastguard Worker void vtn_handle_bitcast(struct vtn_builder *b, const uint32_t *w,
965*61046927SAndroid Build Coastguard Worker unsigned count);
966*61046927SAndroid Build Coastguard Worker
967*61046927SAndroid Build Coastguard Worker void vtn_handle_no_contraction(struct vtn_builder *b, struct vtn_value *val);
968*61046927SAndroid Build Coastguard Worker
969*61046927SAndroid Build Coastguard Worker void vtn_handle_fp_fast_math(struct vtn_builder *b, struct vtn_value *val);
970*61046927SAndroid Build Coastguard Worker
971*61046927SAndroid Build Coastguard Worker void vtn_handle_subgroup(struct vtn_builder *b, SpvOp opcode,
972*61046927SAndroid Build Coastguard Worker const uint32_t *w, unsigned count);
973*61046927SAndroid Build Coastguard Worker
974*61046927SAndroid Build Coastguard Worker bool vtn_handle_glsl450_instruction(struct vtn_builder *b, SpvOp ext_opcode,
975*61046927SAndroid Build Coastguard Worker const uint32_t *words, unsigned count);
976*61046927SAndroid Build Coastguard Worker
977*61046927SAndroid Build Coastguard Worker bool vtn_handle_opencl_instruction(struct vtn_builder *b, SpvOp ext_opcode,
978*61046927SAndroid Build Coastguard Worker const uint32_t *words, unsigned count);
979*61046927SAndroid Build Coastguard Worker bool vtn_handle_opencl_core_instruction(struct vtn_builder *b, SpvOp opcode,
980*61046927SAndroid Build Coastguard Worker const uint32_t *w, unsigned count);
981*61046927SAndroid Build Coastguard Worker
982*61046927SAndroid Build Coastguard Worker struct vtn_builder* vtn_create_builder(const uint32_t *words, size_t word_count,
983*61046927SAndroid Build Coastguard Worker gl_shader_stage stage, const char *entry_point_name,
984*61046927SAndroid Build Coastguard Worker const struct spirv_to_nir_options *options);
985*61046927SAndroid Build Coastguard Worker
986*61046927SAndroid Build Coastguard Worker void vtn_handle_entry_point(struct vtn_builder *b, const uint32_t *w,
987*61046927SAndroid Build Coastguard Worker unsigned count);
988*61046927SAndroid Build Coastguard Worker
989*61046927SAndroid Build Coastguard Worker void vtn_handle_debug_text(struct vtn_builder *b, SpvOp opcode,
990*61046927SAndroid Build Coastguard Worker const uint32_t *w, unsigned count);
991*61046927SAndroid Build Coastguard Worker
992*61046927SAndroid Build Coastguard Worker void vtn_handle_decoration(struct vtn_builder *b, SpvOp opcode,
993*61046927SAndroid Build Coastguard Worker const uint32_t *w, unsigned count);
994*61046927SAndroid Build Coastguard Worker
995*61046927SAndroid Build Coastguard Worker enum vtn_variable_mode vtn_storage_class_to_mode(struct vtn_builder *b,
996*61046927SAndroid Build Coastguard Worker SpvStorageClass class,
997*61046927SAndroid Build Coastguard Worker struct vtn_type *interface_type,
998*61046927SAndroid Build Coastguard Worker nir_variable_mode *nir_mode_out);
999*61046927SAndroid Build Coastguard Worker
1000*61046927SAndroid Build Coastguard Worker nir_address_format vtn_mode_to_address_format(struct vtn_builder *b,
1001*61046927SAndroid Build Coastguard Worker enum vtn_variable_mode);
1002*61046927SAndroid Build Coastguard Worker
1003*61046927SAndroid Build Coastguard Worker nir_rounding_mode vtn_rounding_mode_to_nir(struct vtn_builder *b,
1004*61046927SAndroid Build Coastguard Worker SpvFPRoundingMode mode);
1005*61046927SAndroid Build Coastguard Worker
1006*61046927SAndroid Build Coastguard Worker static inline uint32_t
vtn_align_u32(uint32_t v,uint32_t a)1007*61046927SAndroid Build Coastguard Worker vtn_align_u32(uint32_t v, uint32_t a)
1008*61046927SAndroid Build Coastguard Worker {
1009*61046927SAndroid Build Coastguard Worker assert(a != 0 && a == (a & -((int32_t) a)));
1010*61046927SAndroid Build Coastguard Worker return (v + a - 1) & ~(a - 1);
1011*61046927SAndroid Build Coastguard Worker }
1012*61046927SAndroid Build Coastguard Worker
1013*61046927SAndroid Build Coastguard Worker static inline uint64_t
vtn_u64_literal(const uint32_t * w)1014*61046927SAndroid Build Coastguard Worker vtn_u64_literal(const uint32_t *w)
1015*61046927SAndroid Build Coastguard Worker {
1016*61046927SAndroid Build Coastguard Worker return (uint64_t)w[1] << 32 | w[0];
1017*61046927SAndroid Build Coastguard Worker }
1018*61046927SAndroid Build Coastguard Worker
1019*61046927SAndroid Build Coastguard Worker bool vtn_handle_amd_gcn_shader_instruction(struct vtn_builder *b, SpvOp ext_opcode,
1020*61046927SAndroid Build Coastguard Worker const uint32_t *words, unsigned count);
1021*61046927SAndroid Build Coastguard Worker
1022*61046927SAndroid Build Coastguard Worker bool vtn_handle_amd_shader_ballot_instruction(struct vtn_builder *b, SpvOp ext_opcode,
1023*61046927SAndroid Build Coastguard Worker const uint32_t *w, unsigned count);
1024*61046927SAndroid Build Coastguard Worker
1025*61046927SAndroid Build Coastguard Worker bool vtn_handle_amd_shader_trinary_minmax_instruction(struct vtn_builder *b, SpvOp ext_opcode,
1026*61046927SAndroid Build Coastguard Worker const uint32_t *words, unsigned count);
1027*61046927SAndroid Build Coastguard Worker
1028*61046927SAndroid Build Coastguard Worker bool vtn_handle_amd_shader_explicit_vertex_parameter_instruction(struct vtn_builder *b,
1029*61046927SAndroid Build Coastguard Worker SpvOp ext_opcode,
1030*61046927SAndroid Build Coastguard Worker const uint32_t *words,
1031*61046927SAndroid Build Coastguard Worker unsigned count);
1032*61046927SAndroid Build Coastguard Worker
1033*61046927SAndroid Build Coastguard Worker SpvMemorySemanticsMask vtn_mode_to_memory_semantics(enum vtn_variable_mode mode);
1034*61046927SAndroid Build Coastguard Worker
1035*61046927SAndroid Build Coastguard Worker void vtn_emit_memory_barrier(struct vtn_builder *b, SpvScope scope,
1036*61046927SAndroid Build Coastguard Worker SpvMemorySemanticsMask semantics);
1037*61046927SAndroid Build Coastguard Worker
1038*61046927SAndroid Build Coastguard Worker bool vtn_value_is_relaxed_precision(struct vtn_builder *b, struct vtn_value *val);
1039*61046927SAndroid Build Coastguard Worker nir_def *
1040*61046927SAndroid Build Coastguard Worker vtn_mediump_downconvert(struct vtn_builder *b, enum glsl_base_type base_type, nir_def *def);
1041*61046927SAndroid Build Coastguard Worker struct vtn_ssa_value *
1042*61046927SAndroid Build Coastguard Worker vtn_mediump_downconvert_value(struct vtn_builder *b, struct vtn_ssa_value *src);
1043*61046927SAndroid Build Coastguard Worker void vtn_mediump_upconvert_value(struct vtn_builder *b, struct vtn_ssa_value *value);
1044*61046927SAndroid Build Coastguard Worker
1045*61046927SAndroid Build Coastguard Worker static inline int
cmp_uint32_t(const void * pa,const void * pb)1046*61046927SAndroid Build Coastguard Worker cmp_uint32_t(const void *pa, const void *pb)
1047*61046927SAndroid Build Coastguard Worker {
1048*61046927SAndroid Build Coastguard Worker uint32_t a = *((const uint32_t *)pa);
1049*61046927SAndroid Build Coastguard Worker uint32_t b = *((const uint32_t *)pb);
1050*61046927SAndroid Build Coastguard Worker if (a < b)
1051*61046927SAndroid Build Coastguard Worker return -1;
1052*61046927SAndroid Build Coastguard Worker if (a > b)
1053*61046927SAndroid Build Coastguard Worker return 1;
1054*61046927SAndroid Build Coastguard Worker return 0;
1055*61046927SAndroid Build Coastguard Worker }
1056*61046927SAndroid Build Coastguard Worker
1057*61046927SAndroid Build Coastguard Worker void
1058*61046927SAndroid Build Coastguard Worker vtn_parse_switch(struct vtn_builder *b,
1059*61046927SAndroid Build Coastguard Worker const uint32_t *branch,
1060*61046927SAndroid Build Coastguard Worker struct list_head *case_list);
1061*61046927SAndroid Build Coastguard Worker
1062*61046927SAndroid Build Coastguard Worker bool vtn_get_mem_operands(struct vtn_builder *b, const uint32_t *w, unsigned count,
1063*61046927SAndroid Build Coastguard Worker unsigned *idx, SpvMemoryAccessMask *access, unsigned *alignment,
1064*61046927SAndroid Build Coastguard Worker SpvScope *dest_scope, SpvScope *src_scope);
1065*61046927SAndroid Build Coastguard Worker void vtn_emit_make_visible_barrier(struct vtn_builder *b, SpvMemoryAccessMask access,
1066*61046927SAndroid Build Coastguard Worker SpvScope scope, enum vtn_variable_mode mode);
1067*61046927SAndroid Build Coastguard Worker void vtn_emit_make_available_barrier(struct vtn_builder *b, SpvMemoryAccessMask access,
1068*61046927SAndroid Build Coastguard Worker SpvScope scope, enum vtn_variable_mode mode);
1069*61046927SAndroid Build Coastguard Worker
1070*61046927SAndroid Build Coastguard Worker
1071*61046927SAndroid Build Coastguard Worker void vtn_handle_cooperative_type(struct vtn_builder *b, struct vtn_value *val,
1072*61046927SAndroid Build Coastguard Worker SpvOp opcode, const uint32_t *w, unsigned count);
1073*61046927SAndroid Build Coastguard Worker void vtn_handle_cooperative_instruction(struct vtn_builder *b, SpvOp opcode,
1074*61046927SAndroid Build Coastguard Worker const uint32_t *w, unsigned count);
1075*61046927SAndroid Build Coastguard Worker void vtn_handle_cooperative_alu(struct vtn_builder *b, struct vtn_value *dest_val,
1076*61046927SAndroid Build Coastguard Worker const struct glsl_type *dest_type, SpvOp opcode,
1077*61046927SAndroid Build Coastguard Worker const uint32_t *w, unsigned count);
1078*61046927SAndroid Build Coastguard Worker struct vtn_ssa_value *vtn_cooperative_matrix_extract(struct vtn_builder *b, struct vtn_ssa_value *mat,
1079*61046927SAndroid Build Coastguard Worker const uint32_t *indices, unsigned num_indices);
1080*61046927SAndroid Build Coastguard Worker struct vtn_ssa_value *vtn_cooperative_matrix_insert(struct vtn_builder *b, struct vtn_ssa_value *mat,
1081*61046927SAndroid Build Coastguard Worker struct vtn_ssa_value *insert,
1082*61046927SAndroid Build Coastguard Worker const uint32_t *indices, unsigned num_indices);
1083*61046927SAndroid Build Coastguard Worker nir_deref_instr *vtn_create_cmat_temporary(struct vtn_builder *b,
1084*61046927SAndroid Build Coastguard Worker const struct glsl_type *t, const char *name);
1085*61046927SAndroid Build Coastguard Worker
1086*61046927SAndroid Build Coastguard Worker gl_shader_stage vtn_stage_for_execution_model(SpvExecutionModel model);
1087*61046927SAndroid Build Coastguard Worker
1088*61046927SAndroid Build Coastguard Worker #endif /* _VTN_PRIVATE_H_ */
1089