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 vtn_value_type_sampled_image,
50 };
51
52 struct vtn_block {
53 /* Merge opcode if this block contains a merge; SpvOpNop otherwise. */
54 SpvOp merge_op;
55 uint32_t merge_block_id;
56 const uint32_t *label;
57 const uint32_t *branch;
58 nir_block *block;
59 };
60
61 struct vtn_function {
62 struct exec_node node;
63
64 nir_function_overload *overload;
65 struct vtn_block *start_block;
66
67 const uint32_t *end;
68 };
69
70 typedef bool (*vtn_instruction_handler)(struct vtn_builder *, uint32_t,
71 const uint32_t *, unsigned);
72
73 struct vtn_ssa_value {
74 union {
75 nir_ssa_def *def;
76 struct vtn_ssa_value **elems;
77 };
78
79 /* For matrices, a transposed version of the value, or NULL if it hasn't
80 * been computed
81 */
82 struct vtn_ssa_value *transposed;
83
84 const struct glsl_type *type;
85 };
86
87 struct vtn_type {
88 const struct glsl_type *type;
89
90 /* for matrices, whether the matrix is stored row-major */
91 bool row_major;
92
93 /* for structs, the offset of each member */
94 unsigned *offsets;
95
96 /* for structs, whether it was decorated as a "non-SSBO-like" block */
97 bool block;
98
99 /* for structs, whether it was decorated as an "SSBO-like" block */
100 bool buffer_block;
101
102 /* for structs with block == true, whether this is a builtin block (i.e. a
103 * block that contains only builtins).
104 */
105 bool builtin_block;
106
107 /* Image format for image_load_store type images */
108 unsigned image_format;
109
110 /* for arrays and matrices, the array stride */
111 unsigned stride;
112
113 /* for arrays, the vtn_type for the elements of the array */
114 struct vtn_type *array_element;
115
116 /* for structures, the vtn_type for each member */
117 struct vtn_type **members;
118
119 /* Whether this type, or a parent type, has been decorated as a builtin */
120 bool is_builtin;
121
122 SpvBuiltIn builtin;
123 };
124
125 struct vtn_image_pointer {
126 nir_deref_var *deref;
127 nir_ssa_def *coord;
128 nir_ssa_def *sample;
129 };
130
131 struct vtn_sampled_image {
132 nir_deref_var *image; /* Image or array of images */
133 nir_deref_var *sampler; /* Sampler */
134 };
135
136 struct vtn_value {
137 enum vtn_value_type value_type;
138 const char *name;
139 struct vtn_decoration *decoration;
140 union {
141 void *ptr;
142 char *str;
143 struct vtn_type *type;
144 struct {
145 nir_constant *constant;
146 const struct glsl_type *const_type;
147 };
148 struct {
149 nir_deref_var *deref;
150 struct vtn_type *deref_type;
151 };
152 struct vtn_image_pointer *image;
153 struct vtn_sampled_image *sampled_image;
154 struct vtn_function *func;
155 struct vtn_block *block;
156 struct vtn_ssa_value *ssa;
157 vtn_instruction_handler ext_handler;
158 };
159 };
160
161 struct vtn_decoration {
162 struct vtn_decoration *next;
163 int member; /* -1 if not a member decoration */
164 const uint32_t *literals;
165 struct vtn_value *group;
166 SpvDecoration decoration;
167 };
168
169 struct vtn_builder {
170 nir_builder nb;
171
172 nir_shader *shader;
173 nir_function_impl *impl;
174 struct vtn_block *block;
175
176 /*
177 * In SPIR-V, constants are global, whereas in NIR, the load_const
178 * instruction we use is per-function. So while we parse each function, we
179 * keep a hash table of constants we've resolved to nir_ssa_value's so
180 * far, and we lazily resolve them when we see them used in a function.
181 */
182 struct hash_table *const_table;
183
184 /*
185 * Map from nir_block to the vtn_block which ends with it -- used for
186 * handling phi nodes.
187 */
188 struct hash_table *block_table;
189
190 /*
191 * NIR variable for each SPIR-V builtin.
192 */
193 struct {
194 nir_variable *in;
195 nir_variable *out;
196 } builtins[42]; /* XXX need symbolic constant from SPIR-V header */
197
198 unsigned value_id_bound;
199 struct vtn_value *values;
200
201 SpvExecutionModel execution_model;
202 bool origin_upper_left;
203 struct vtn_value *entry_point;
204
205 struct vtn_function *func;
206 struct exec_list functions;
207 };
208
209 static inline struct vtn_value *
210 vtn_push_value(struct vtn_builder *b, uint32_t value_id,
211 enum vtn_value_type value_type)
212 {
213 assert(value_id < b->value_id_bound);
214 assert(b->values[value_id].value_type == vtn_value_type_invalid);
215
216 b->values[value_id].value_type = value_type;
217
218 return &b->values[value_id];
219 }
220
221 static inline struct vtn_value *
222 vtn_untyped_value(struct vtn_builder *b, uint32_t value_id)
223 {
224 assert(value_id < b->value_id_bound);
225 return &b->values[value_id];
226 }
227
228 static inline struct vtn_value *
229 vtn_value(struct vtn_builder *b, uint32_t value_id,
230 enum vtn_value_type value_type)
231 {
232 struct vtn_value *val = vtn_untyped_value(b, value_id);
233 assert(val->value_type == value_type);
234 return val;
235 }
236
237 struct vtn_ssa_value *vtn_ssa_value(struct vtn_builder *b, uint32_t value_id);
238
239 typedef void (*vtn_decoration_foreach_cb)(struct vtn_builder *,
240 struct vtn_value *,
241 int member,
242 const struct vtn_decoration *,
243 void *);
244
245 void vtn_foreach_decoration(struct vtn_builder *b, struct vtn_value *value,
246 vtn_decoration_foreach_cb cb, void *data);
247
248 bool vtn_handle_glsl450_instruction(struct vtn_builder *b, uint32_t ext_opcode,
249 const uint32_t *words, unsigned count);