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
40struct gl_shader_program;
41struct gl_shader_stage;
42struct gl_shader;
43struct 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 */
67struct 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
100enum 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 */
112struct 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
214static inline bool
215xfb_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