OSDN Git Service

glsl linker: compare interface blocks during intrastage linking
[android-x86/external-mesa.git] / src / 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 #pragma once
25 #ifndef GLSL_LINK_VARYINGS_H
26 #define GLSL_LINK_VARYINGS_H
27
28 /**
29  * \file link_varyings.h
30  *
31  * Linker functions related specifically to linking varyings between shader
32  * stages.
33  */
34
35
36 #include "main/glheader.h"
37
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, struct gl_shader_program *prog,
95              const void *mem_ctx, const char *input);
96    static bool is_same(const tfeedback_decl &x, const tfeedback_decl &y);
97    bool assign_location(struct gl_context *ctx,
98                         struct gl_shader_program *prog);
99    unsigned get_num_outputs() const;
100    bool store(struct gl_context *ctx, struct gl_shader_program *prog,
101               struct gl_transform_feedback_info *info, unsigned buffer,
102               const unsigned max_outputs) const;
103    const tfeedback_candidate *find_candidate(gl_shader_program *prog,
104                                              hash_table *tfeedback_candidates);
105
106    bool is_next_buffer_separator() const
107    {
108       return this->next_buffer_separator;
109    }
110
111    bool is_varying() const
112    {
113       return !this->next_buffer_separator && !this->skip_components;
114    }
115
116    /**
117     * The total number of varying components taken up by this variable.  Only
118     * valid if assign_location() has been called.
119     */
120    unsigned num_components() const
121    {
122       if (this->is_clip_distance_mesa)
123          return this->size;
124       else
125          return this->vector_elements * this->matrix_columns * this->size;
126    }
127
128 private:
129    /**
130     * The name that was supplied to glTransformFeedbackVaryings.  Used for
131     * error reporting and glGetTransformFeedbackVarying().
132     */
133    const char *orig_name;
134
135    /**
136     * The name of the variable, parsed from orig_name.
137     */
138    const char *var_name;
139
140    /**
141     * True if the declaration in orig_name represents an array.
142     */
143    bool is_subscripted;
144
145    /**
146     * If is_subscripted is true, the subscript that was specified in orig_name.
147     */
148    unsigned array_subscript;
149
150    /**
151     * True if the variable is gl_ClipDistance and the driver lowers
152     * gl_ClipDistance to gl_ClipDistanceMESA.
153     */
154    bool is_clip_distance_mesa;
155
156    /**
157     * The vertex shader output location that the linker assigned for this
158     * variable.  -1 if a location hasn't been assigned yet.
159     */
160    int location;
161
162    /**
163     * If non-zero, then this variable may be packed along with other variables
164     * into a single varying slot, so this offset should be applied when
165     * accessing components.  For example, an offset of 1 means that the x
166     * component of this variable is actually stored in component y of the
167     * location specified by \c location.
168     *
169     * Only valid if location != -1.
170     */
171    unsigned location_frac;
172
173    /**
174     * If location != -1, the number of vector elements in this variable, or 1
175     * if this variable is a scalar.
176     */
177    unsigned vector_elements;
178
179    /**
180     * If location != -1, the number of matrix columns in this variable, or 1
181     * if this variable is not a matrix.
182     */
183    unsigned matrix_columns;
184
185    /** Type of the varying returned by glGetTransformFeedbackVarying() */
186    GLenum type;
187
188    /**
189     * If location != -1, the size that should be returned by
190     * glGetTransformFeedbackVarying().
191     */
192    unsigned size;
193
194    /**
195     * How many components to skip. If non-zero, this is
196     * gl_SkipComponents{1,2,3,4} from ARB_transform_feedback3.
197     */
198    unsigned skip_components;
199
200    /**
201     * Whether this is gl_NextBuffer from ARB_transform_feedback3.
202     */
203    bool next_buffer_separator;
204
205    /**
206     * If find_candidate() has been called, pointer to the tfeedback_candidate
207     * data structure that was found.  Otherwise NULL.
208     */
209    const tfeedback_candidate *matched_candidate;
210 };
211
212
213 bool
214 cross_validate_outputs_to_inputs(struct gl_shader_program *prog,
215                                  gl_shader *producer, gl_shader *consumer);
216
217 bool
218 parse_tfeedback_decls(struct gl_context *ctx, struct gl_shader_program *prog,
219                       const void *mem_ctx, unsigned num_names,
220                       char **varying_names, tfeedback_decl *decls);
221
222 bool
223 store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
224                      unsigned num_tfeedback_decls,
225                      tfeedback_decl *tfeedback_decls);
226
227 bool
228 assign_varying_locations(struct gl_context *ctx,
229                          void *mem_ctx,
230                          struct gl_shader_program *prog,
231                          gl_shader *producer, gl_shader *consumer,
232                          unsigned num_tfeedback_decls,
233                          tfeedback_decl *tfeedback_decls);
234
235 #endif /* GLSL_LINK_VARYINGS_H */