1 /*
2 * Copyright © 2012 Intel Corporation
3 * Copyright © 2022 Valve Corporation
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25 #ifndef GLSL_LINK_VARYINGS_H
26 #define GLSL_LINK_VARYINGS_H
27
28 /**
29 * Linker functions related specifically to linking varyings between shader
30 * stages.
31 */
32
33
34 #include "main/glheader.h"
35 #include "program/prog_parameter.h"
36 #include "util/bitset.h"
37
38 #include "nir.h"
39
40 struct gl_shader_program;
41 struct gl_shader_stage;
42 struct gl_shader;
43 struct gl_type;
44
45
46 /**
47 * Data structure describing a varying which is available for use in transform
48 * feedback.
49 *
50 * For example, if the vertex shader contains:
51 *
52 * struct S {
53 * vec4 foo;
54 * float[3] bar;
55 * };
56 *
57 * varying S[2] v;
58 *
59 * Then there would be tfeedback_candidate objects corresponding to the
60 * following varyings:
61 *
62 * v[0].foo
63 * v[0].bar
64 * v[1].foo
65 * v[1].bar
66 */
67 struct tfeedback_candidate
68 {
69 /**
70 * Toplevel variable containing this varying. In the above example, this
71 * would point to the declaration of the varying v.
72 */
73 nir_variable *toplevel_var;
74
75 /**
76 * Type of this varying. In the above example, this would point to the
77 * glsl_type for "vec4" or "float[3]".
78 */
79 const struct glsl_type *type;
80
81 /**
82 * Offset within the toplevel variable where this varying occurs.
83 * Counted in floats.
84 */
85 unsigned struct_offset_floats;
86
87 /**
88 * Offset within the xfb with respect to alignment requirements.
89 * Counted in floats.
90 */
91 unsigned xfb_offset_floats;
92
93 /* Used to match varyings and update toplevel_var pointer after NIR
94 * optimisations have been performed.
95 */
96 unsigned initial_location;
97 unsigned initial_location_frac;
98 };
99
100 enum lowered_builtin_array_var {
101 none,
102 clip_distance,
103 cull_distance,
104 tess_level_outer,
105 tess_level_inner,
106 };
107
108 /**
109 * Data structure tracking information about a transform feedback declaration
110 * during linking.
111 */
112 struct xfb_decl
113 {
114 /**
115 * The name that was supplied to glTransformFeedbackVaryings. Used for
116 * error reporting and glGetTransformFeedbackVarying().
117 */
118 const char *orig_name;
119
120 /**
121 * The name of the variable, parsed from orig_name.
122 */
123 const char *var_name;
124
125 /**
126 * True if the declaration in orig_name represents an array.
127 */
128 bool is_subscripted;
129
130 /**
131 * If is_subscripted is true, the subscript that was specified in orig_name.
132 */
133 unsigned array_subscript;
134
135 /**
136 * Non-zero if the variable is gl_ClipDistance, glTessLevelOuter or
137 * gl_TessLevelInner and the driver lowers it to gl_*MESA.
138 */
139 enum lowered_builtin_array_var lowered_builtin_array_variable;
140
141 /**
142 * The vertex shader output location that the linker assigned for this
143 * variable. -1 if a location hasn't been assigned yet.
144 */
145 int location;
146
147 /**
148 * Used to store the buffer assigned by xfb_buffer.
149 */
150 unsigned buffer;
151
152 /**
153 * Used to store the offset assigned by xfb_offset.
154 */
155 unsigned offset;
156
157 /**
158 * If non-zero, then this variable may be packed along with other variables
159 * into a single varying slot, so this offset should be applied when
160 * accessing components. For example, an offset of 1 means that the x
161 * component of this variable is actually stored in component y of the
162 * location specified by \c location.
163 *
164 * Only valid if location != -1.
165 */
166 unsigned location_frac;
167
168 /**
169 * If location != -1, the number of vector elements in this variable, or 1
170 * if this variable is a scalar.
171 */
172 unsigned vector_elements;
173
174 /**
175 * If location != -1, the number of matrix columns in this variable, or 1
176 * if this variable is not a matrix.
177 */
178 unsigned matrix_columns;
179
180 /** Type of the varying returned by glGetTransformFeedbackVarying() */
181 GLenum type;
182
183 /**
184 * If location != -1, the size that should be returned by
185 * glGetTransformFeedbackVarying().
186 */
187 unsigned size;
188
189 /**
190 * How many components to skip. If non-zero, this is
191 * gl_SkipComponents{1,2,3,4} from ARB_transform_feedback3.
192 */
193 unsigned skip_components;
194
195 /**
196 * Whether this is gl_NextBuffer from ARB_transform_feedback3.
197 */
198 bool next_buffer_separator;
199
200 /**
201 * If find_candidate() has been called, pointer to the tfeedback_candidate
202 * data structure that was found. Otherwise NULL.
203 */
204 struct tfeedback_candidate *matched_candidate;
205
206 /**
207 * StreamId assigned to this varying (defaults to 0). Can only be set to
208 * values other than 0 in geometry shaders that use the stream layout
209 * modifier. Accepted values must be in the range [0, MAX_VERTEX_STREAMS-1].
210 */
211 unsigned stream_id;
212 };
213
214 static inline bool
xfb_decl_is_varying(const struct xfb_decl * xfb_decl)215 xfb_decl_is_varying(const struct xfb_decl *xfb_decl)
216 {
217 return !xfb_decl->next_buffer_separator && !xfb_decl->skip_components;
218 }
219
220 #endif /* GLSL_LINK_VARYINGS_H */
221