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