Merge remote-tracking branch 'mesa-public/master' into vulkan
[mesa.git] / src / glsl / nir / spirv_to_nir_private.h
1 /*
2 * Copyright © 2015 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 * Jason Ekstrand (jason@jlekstrand.net)
25 *
26 */
27
28 #include "nir.h"
29 #include "nir_spirv.h"
30 #include "nir_builder.h"
31 #include "spirv.h"
32
33 struct vtn_builder;
34 struct vtn_decoration;
35
36 enum vtn_value_type {
37 vtn_value_type_invalid = 0,
38 vtn_value_type_undef,
39 vtn_value_type_string,
40 vtn_value_type_decoration_group,
41 vtn_value_type_type,
42 vtn_value_type_constant,
43 vtn_value_type_deref,
44 vtn_value_type_function,
45 vtn_value_type_block,
46 vtn_value_type_ssa,
47 vtn_value_type_extension,
48 vtn_value_type_image_pointer,
49 };
50
51 struct vtn_block {
52 /* Merge opcode if this block contains a merge; SpvOpNop otherwise. */
53 SpvOp merge_op;
54 uint32_t merge_block_id;
55 const uint32_t *label;
56 const uint32_t *branch;
57 nir_block *block;
58 };
59
60 struct vtn_function {
61 struct exec_node node;
62
63 nir_function_overload *overload;
64 struct vtn_block *start_block;
65
66 const uint32_t *end;
67 };
68
69 typedef bool (*vtn_instruction_handler)(struct vtn_builder *, uint32_t,
70 const uint32_t *, unsigned);
71
72 struct vtn_ssa_value {
73 union {
74 nir_ssa_def *def;
75 struct vtn_ssa_value **elems;
76 };
77
78 /* For matrices, a transposed version of the value, or NULL if it hasn't
79 * been computed
80 */
81 struct vtn_ssa_value *transposed;
82
83 const struct glsl_type *type;
84 };
85
86 struct vtn_type {
87 const struct glsl_type *type;
88
89 /* for matrices, whether the matrix is stored row-major */
90 bool row_major;
91
92 /* for structs, the offset of each member */
93 unsigned *offsets;
94
95 /* for structs, whether it was decorated as a "non-SSBO-like" block */
96 bool block;
97
98 /* for structs, whether it was decorated as an "SSBO-like" block */
99 bool buffer_block;
100
101 /* for structs with block == true, whether this is a builtin block (i.e. a
102 * block that contains only builtins).
103 */
104 bool builtin_block;
105
106 /* Image format for image_load_store type images */
107 unsigned image_format;
108
109 /* for arrays and matrices, the array stride */
110 unsigned stride;
111
112 /* for arrays, the vtn_type for the elements of the array */
113 struct vtn_type *array_element;
114
115 /* for structures, the vtn_type for each member */
116 struct vtn_type **members;
117
118 /* Whether this type, or a parent type, has been decorated as a builtin */
119 bool is_builtin;
120
121 SpvBuiltIn builtin;
122 };
123
124 struct vtn_image_pointer {
125 nir_deref_var *deref;
126 nir_ssa_def *coord;
127 nir_ssa_def *sample;
128 };
129
130 struct vtn_value {
131 enum vtn_value_type value_type;
132 const char *name;
133 struct vtn_decoration *decoration;
134 union {
135 void *ptr;
136 char *str;
137 struct vtn_type *type;
138 struct {
139 nir_constant *constant;
140 const struct glsl_type *const_type;
141 };
142 struct {
143 nir_deref_var *deref;
144 struct vtn_type *deref_type;
145 };
146 struct vtn_image_pointer *image;
147 struct vtn_function *func;
148 struct vtn_block *block;
149 struct vtn_ssa_value *ssa;
150 vtn_instruction_handler ext_handler;
151 };
152 };
153
154 struct vtn_decoration {
155 struct vtn_decoration *next;
156 int member; /* -1 if not a member decoration */
157 const uint32_t *literals;
158 struct vtn_value *group;
159 SpvDecoration decoration;
160 };
161
162 struct vtn_builder {
163 nir_builder nb;
164
165 nir_shader *shader;
166 nir_function_impl *impl;
167 struct vtn_block *block;
168
169 /*
170 * In SPIR-V, constants are global, whereas in NIR, the load_const
171 * instruction we use is per-function. So while we parse each function, we
172 * keep a hash table of constants we've resolved to nir_ssa_value's so
173 * far, and we lazily resolve them when we see them used in a function.
174 */
175 struct hash_table *const_table;
176
177 /*
178 * Map from nir_block to the vtn_block which ends with it -- used for
179 * handling phi nodes.
180 */
181 struct hash_table *block_table;
182
183 /*
184 * NIR variable for each SPIR-V builtin.
185 */
186 struct {
187 nir_variable *in;
188 nir_variable *out;
189 } builtins[42]; /* XXX need symbolic constant from SPIR-V header */
190
191 unsigned value_id_bound;
192 struct vtn_value *values;
193
194 SpvExecutionModel execution_model;
195 bool origin_upper_left;
196 struct vtn_value *entry_point;
197
198 struct vtn_function *func;
199 struct exec_list functions;
200 };
201
202 static inline struct vtn_value *
203 vtn_push_value(struct vtn_builder *b, uint32_t value_id,
204 enum vtn_value_type value_type)
205 {
206 assert(value_id < b->value_id_bound);
207 assert(b->values[value_id].value_type == vtn_value_type_invalid);
208
209 b->values[value_id].value_type = value_type;
210
211 return &b->values[value_id];
212 }
213
214 static inline struct vtn_value *
215 vtn_untyped_value(struct vtn_builder *b, uint32_t value_id)
216 {
217 assert(value_id < b->value_id_bound);
218 return &b->values[value_id];
219 }
220
221 static inline struct vtn_value *
222 vtn_value(struct vtn_builder *b, uint32_t value_id,
223 enum vtn_value_type value_type)
224 {
225 struct vtn_value *val = vtn_untyped_value(b, value_id);
226 assert(val->value_type == value_type);
227 return val;
228 }
229
230 struct vtn_ssa_value *vtn_ssa_value(struct vtn_builder *b, uint32_t value_id);
231
232 typedef void (*vtn_decoration_foreach_cb)(struct vtn_builder *,
233 struct vtn_value *,
234 int member,
235 const struct vtn_decoration *,
236 void *);
237
238 void vtn_foreach_decoration(struct vtn_builder *b, struct vtn_value *value,
239 vtn_decoration_foreach_cb cb, void *data);
240
241 bool vtn_handle_glsl450_instruction(struct vtn_builder *b, uint32_t ext_opcode,
242 const uint32_t *words, unsigned count);