glsl: fix the type of ir_constant_data::u16
[mesa.git] / src / compiler / glsl / link_varyings.h
1 /*
2 * Copyright © 2012 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
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 #ifndef GLSL_LINK_VARYINGS_H
25 #define GLSL_LINK_VARYINGS_H
26
27 /**
28 * \file link_varyings.h
29 *
30 * Linker functions related specifically to linking varyings between shader
31 * stages.
32 */
33
34
35 #include "main/glheader.h"
36 #include "program/prog_parameter.h"
37 #include "util/bitset.h"
38
39 struct gl_shader_program;
40 struct gl_shader;
41 class ir_variable;
42
43
44 /**
45 * Data structure describing a varying which is available for use in transform
46 * feedback.
47 *
48 * For example, if the vertex shader contains:
49 *
50 * struct S {
51 * vec4 foo;
52 * float[3] bar;
53 * };
54 *
55 * varying S[2] v;
56 *
57 * Then there would be tfeedback_candidate objects corresponding to the
58 * following varyings:
59 *
60 * v[0].foo
61 * v[0].bar
62 * v[1].foo
63 * v[1].bar
64 */
65 struct tfeedback_candidate
66 {
67 /**
68 * Toplevel variable containing this varying. In the above example, this
69 * would point to the declaration of the varying v.
70 */
71 ir_variable *toplevel_var;
72
73 /**
74 * Type of this varying. In the above example, this would point to the
75 * glsl_type for "vec4" or "float[3]".
76 */
77 const glsl_type *type;
78
79 /**
80 * Offset within the toplevel variable where this varying occurs (counted
81 * in multiples of the size of a float).
82 */
83 unsigned offset;
84 };
85
86
87 /**
88 * Data structure tracking information about a transform feedback declaration
89 * during linking.
90 */
91 class tfeedback_decl
92 {
93 public:
94 void init(struct gl_context *ctx, const void *mem_ctx, const char *input);
95 static bool is_same(const tfeedback_decl &x, const tfeedback_decl &y);
96 bool assign_location(struct gl_context *ctx,
97 struct gl_shader_program *prog);
98 unsigned get_num_outputs() const;
99 bool store(struct gl_context *ctx, struct gl_shader_program *prog,
100 struct gl_transform_feedback_info *info, unsigned buffer,
101 unsigned buffer_index, const unsigned max_outputs,
102 BITSET_WORD *used_components[MAX_FEEDBACK_BUFFERS],
103 bool *explicit_stride, bool has_xfb_qualifiers,
104 const void *mem_ctx) const;
105 const tfeedback_candidate *find_candidate(gl_shader_program *prog,
106 hash_table *tfeedback_candidates);
107 void set_lowered_candidate(const tfeedback_candidate *candidate);
108
109 bool is_next_buffer_separator() const
110 {
111 return this->next_buffer_separator;
112 }
113
114 bool is_varying_written() const
115 {
116 if (this->next_buffer_separator || this->skip_components)
117 return false;
118
119 return this->matched_candidate->toplevel_var->data.assigned;
120 }
121
122 bool is_varying() const
123 {
124 return !this->next_buffer_separator && !this->skip_components;
125 }
126
127 bool is_aligned(unsigned dmul, unsigned offset) const
128 {
129 return (dmul * (this->array_subscript + offset)) % 4 == 0;
130 }
131
132 const char *name() const
133 {
134 return this->orig_name;
135 }
136
137 unsigned get_stream_id() const
138 {
139 return this->stream_id;
140 }
141
142 unsigned get_buffer() const
143 {
144 return this->buffer;
145 }
146
147 unsigned get_offset() const
148 {
149 return this->offset;
150 }
151
152 /**
153 * The total number of varying components taken up by this variable. Only
154 * valid if assign_location() has been called.
155 */
156 unsigned num_components() const
157 {
158 if (this->lowered_builtin_array_variable)
159 return this->size;
160 else
161 return this->vector_elements * this->matrix_columns * this->size *
162 (this->is_64bit() ? 2 : 1);
163 }
164
165 unsigned get_location() const {
166 return this->location;
167 }
168
169 private:
170
171 bool is_64bit() const
172 {
173 return _mesa_gl_datatype_is_64bit(this->type);
174 }
175
176 /**
177 * The name that was supplied to glTransformFeedbackVaryings. Used for
178 * error reporting and glGetTransformFeedbackVarying().
179 */
180 const char *orig_name;
181
182 /**
183 * The name of the variable, parsed from orig_name.
184 */
185 const char *var_name;
186
187 /**
188 * True if the declaration in orig_name represents an array.
189 */
190 bool is_subscripted;
191
192 /**
193 * If is_subscripted is true, the subscript that was specified in orig_name.
194 */
195 unsigned array_subscript;
196
197 /**
198 * Non-zero if the variable is gl_ClipDistance, glTessLevelOuter or
199 * gl_TessLevelInner and the driver lowers it to gl_*MESA.
200 */
201 enum {
202 none,
203 clip_distance,
204 cull_distance,
205 tess_level_outer,
206 tess_level_inner,
207 } lowered_builtin_array_variable;
208
209 /**
210 * The vertex shader output location that the linker assigned for this
211 * variable. -1 if a location hasn't been assigned yet.
212 */
213 int location;
214
215 /**
216 * Used to store the buffer assigned by xfb_buffer.
217 */
218 unsigned buffer;
219
220 /**
221 * Used to store the offset assigned by xfb_offset.
222 */
223 unsigned offset;
224
225 /**
226 * If non-zero, then this variable may be packed along with other variables
227 * into a single varying slot, so this offset should be applied when
228 * accessing components. For example, an offset of 1 means that the x
229 * component of this variable is actually stored in component y of the
230 * location specified by \c location.
231 *
232 * Only valid if location != -1.
233 */
234 unsigned location_frac;
235
236 /**
237 * If location != -1, the number of vector elements in this variable, or 1
238 * if this variable is a scalar.
239 */
240 unsigned vector_elements;
241
242 /**
243 * If location != -1, the number of matrix columns in this variable, or 1
244 * if this variable is not a matrix.
245 */
246 unsigned matrix_columns;
247
248 /** Type of the varying returned by glGetTransformFeedbackVarying() */
249 GLenum type;
250
251 /**
252 * If location != -1, the size that should be returned by
253 * glGetTransformFeedbackVarying().
254 */
255 unsigned size;
256
257 /**
258 * How many components to skip. If non-zero, this is
259 * gl_SkipComponents{1,2,3,4} from ARB_transform_feedback3.
260 */
261 unsigned skip_components;
262
263 /**
264 * Whether this is gl_NextBuffer from ARB_transform_feedback3.
265 */
266 bool next_buffer_separator;
267
268 /**
269 * If find_candidate() has been called, pointer to the tfeedback_candidate
270 * data structure that was found. Otherwise NULL.
271 */
272 const tfeedback_candidate *matched_candidate;
273
274 /**
275 * StreamId assigned to this varying (defaults to 0). Can only be set to
276 * values other than 0 in geometry shaders that use the stream layout
277 * modifier. Accepted values must be in the range [0, MAX_VERTEX_STREAMS-1].
278 */
279 unsigned stream_id;
280 };
281
282 bool
283 link_varyings(struct gl_shader_program *prog, unsigned first, unsigned last,
284 struct gl_context *ctx, void *mem_ctx);
285
286 void
287 validate_first_and_last_interface_explicit_locations(struct gl_context *ctx,
288 struct gl_shader_program *prog,
289 gl_shader_stage first,
290 gl_shader_stage last);
291
292 void
293 cross_validate_outputs_to_inputs(struct gl_context *ctx,
294 struct gl_shader_program *prog,
295 gl_linked_shader *producer,
296 gl_linked_shader *consumer);
297
298 #endif /* GLSL_LINK_VARYINGS_H */