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 is_next_buffer_separator()109 bool is_next_buffer_separator() const 110 { 111 return this->next_buffer_separator; 112 } 113 is_varying_written()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 is_varying()122 bool is_varying() const 123 { 124 return !this->next_buffer_separator && !this->skip_components; 125 } 126 is_aligned(unsigned dmul,unsigned offset)127 bool is_aligned(unsigned dmul, unsigned offset) const 128 { 129 return (dmul * (this->array_subscript + offset)) % 4 == 0; 130 } 131 name()132 const char *name() const 133 { 134 return this->orig_name; 135 } 136 get_stream_id()137 unsigned get_stream_id() const 138 { 139 return this->stream_id; 140 } 141 get_buffer()142 unsigned get_buffer() const 143 { 144 return this->buffer; 145 } 146 get_offset()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 */ num_components()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 get_location()165 unsigned get_location() const { 166 return this->location; 167 } 168 169 private: 170 is_64bit()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 */ 299