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. 81 * Counted in floats. 82 */ 83 unsigned struct_offset_floats; 84 85 /** 86 * Offset within the xfb with respect to alignment requirements. 87 * Counted in floats. 88 */ 89 unsigned xfb_offset_floats; 90 }; 91 92 93 /** 94 * Data structure tracking information about a transform feedback declaration 95 * during linking. 96 */ 97 class tfeedback_decl 98 { 99 public: 100 void init(struct gl_context *ctx, const void *mem_ctx, const char *input); 101 static bool is_same(const tfeedback_decl &x, const tfeedback_decl &y); 102 bool assign_location(struct gl_context *ctx, 103 struct gl_shader_program *prog); 104 unsigned get_num_outputs() const; 105 bool store(struct gl_context *ctx, struct gl_shader_program *prog, 106 struct gl_transform_feedback_info *info, unsigned buffer, 107 unsigned buffer_index, const unsigned max_outputs, 108 BITSET_WORD *used_components[MAX_FEEDBACK_BUFFERS], 109 bool *explicit_stride, unsigned *max_member_alignment, 110 bool has_xfb_qualifiers, const void *mem_ctx) const; 111 const tfeedback_candidate *find_candidate(gl_shader_program *prog, 112 hash_table *tfeedback_candidates); 113 void set_lowered_candidate(const tfeedback_candidate *candidate); 114 is_next_buffer_separator()115 bool is_next_buffer_separator() const 116 { 117 return this->next_buffer_separator; 118 } 119 is_varying_written()120 bool is_varying_written() const 121 { 122 if (this->next_buffer_separator || this->skip_components) 123 return false; 124 125 return this->matched_candidate->toplevel_var->data.assigned; 126 } 127 is_varying()128 bool is_varying() const 129 { 130 return !this->next_buffer_separator && !this->skip_components; 131 } 132 subscripted()133 bool subscripted() const 134 { 135 return this->is_subscripted; 136 } 137 name()138 const char *name() const 139 { 140 return this->orig_name; 141 } 142 get_stream_id()143 unsigned get_stream_id() const 144 { 145 return this->stream_id; 146 } 147 get_buffer()148 unsigned get_buffer() const 149 { 150 return this->buffer; 151 } 152 get_offset()153 unsigned get_offset() const 154 { 155 return this->offset; 156 } 157 158 /** 159 * The total number of varying components taken up by this variable. Only 160 * valid if assign_location() has been called. 161 */ num_components()162 unsigned num_components() const 163 { 164 if (this->lowered_builtin_array_variable) 165 return this->size; 166 else 167 return this->vector_elements * this->matrix_columns * this->size * 168 (this->is_64bit() ? 2 : 1); 169 } 170 get_location()171 unsigned get_location() const { 172 return this->location; 173 } 174 175 private: 176 is_64bit()177 bool is_64bit() const 178 { 179 return _mesa_gl_datatype_is_64bit(this->type); 180 } 181 182 /** 183 * The name that was supplied to glTransformFeedbackVaryings. Used for 184 * error reporting and glGetTransformFeedbackVarying(). 185 */ 186 const char *orig_name; 187 188 /** 189 * The name of the variable, parsed from orig_name. 190 */ 191 const char *var_name; 192 193 /** 194 * True if the declaration in orig_name represents an array. 195 */ 196 bool is_subscripted; 197 198 /** 199 * If is_subscripted is true, the subscript that was specified in orig_name. 200 */ 201 unsigned array_subscript; 202 203 /** 204 * Non-zero if the variable is gl_ClipDistance, glTessLevelOuter or 205 * gl_TessLevelInner and the driver lowers it to gl_*MESA. 206 */ 207 enum { 208 none, 209 clip_distance, 210 cull_distance, 211 tess_level_outer, 212 tess_level_inner, 213 } lowered_builtin_array_variable; 214 215 /** 216 * The vertex shader output location that the linker assigned for this 217 * variable. -1 if a location hasn't been assigned yet. 218 */ 219 int location; 220 221 /** 222 * Used to store the buffer assigned by xfb_buffer. 223 */ 224 unsigned buffer; 225 226 /** 227 * Used to store the offset assigned by xfb_offset. 228 */ 229 unsigned offset; 230 231 /** 232 * If non-zero, then this variable may be packed along with other variables 233 * into a single varying slot, so this offset should be applied when 234 * accessing components. For example, an offset of 1 means that the x 235 * component of this variable is actually stored in component y of the 236 * location specified by \c location. 237 * 238 * Only valid if location != -1. 239 */ 240 unsigned location_frac; 241 242 /** 243 * If location != -1, the number of vector elements in this variable, or 1 244 * if this variable is a scalar. 245 */ 246 unsigned vector_elements; 247 248 /** 249 * If location != -1, the number of matrix columns in this variable, or 1 250 * if this variable is not a matrix. 251 */ 252 unsigned matrix_columns; 253 254 /** Type of the varying returned by glGetTransformFeedbackVarying() */ 255 GLenum type; 256 257 /** 258 * If location != -1, the size that should be returned by 259 * glGetTransformFeedbackVarying(). 260 */ 261 unsigned size; 262 263 /** 264 * How many components to skip. If non-zero, this is 265 * gl_SkipComponents{1,2,3,4} from ARB_transform_feedback3. 266 */ 267 unsigned skip_components; 268 269 /** 270 * Whether this is gl_NextBuffer from ARB_transform_feedback3. 271 */ 272 bool next_buffer_separator; 273 274 /** 275 * If find_candidate() has been called, pointer to the tfeedback_candidate 276 * data structure that was found. Otherwise NULL. 277 */ 278 const tfeedback_candidate *matched_candidate; 279 280 /** 281 * StreamId assigned to this varying (defaults to 0). Can only be set to 282 * values other than 0 in geometry shaders that use the stream layout 283 * modifier. Accepted values must be in the range [0, MAX_VERTEX_STREAMS-1]. 284 */ 285 unsigned stream_id; 286 }; 287 288 bool 289 link_varyings(struct gl_shader_program *prog, unsigned first, unsigned last, 290 struct gl_context *ctx, void *mem_ctx); 291 292 void 293 validate_first_and_last_interface_explicit_locations(struct gl_context *ctx, 294 struct gl_shader_program *prog, 295 gl_shader_stage first, 296 gl_shader_stage last); 297 298 void 299 cross_validate_outputs_to_inputs(struct gl_context *ctx, 300 struct gl_shader_program *prog, 301 gl_linked_shader *producer, 302 gl_linked_shader *consumer); 303 304 #endif /* GLSL_LINK_VARYINGS_H */ 305