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, 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 bool *explicit_stride, bool has_xfb_qualifiers) const; 103 const tfeedback_candidate *find_candidate(gl_shader_program *prog, 104 hash_table *tfeedback_candidates); 105 is_next_buffer_separator()106 bool is_next_buffer_separator() const 107 { 108 return this->next_buffer_separator; 109 } 110 is_varying_written()111 bool is_varying_written() const 112 { 113 if (this->next_buffer_separator || this->skip_components) 114 return false; 115 116 return this->matched_candidate->toplevel_var->data.assigned; 117 } 118 is_varying()119 bool is_varying() const 120 { 121 return !this->next_buffer_separator && !this->skip_components; 122 } 123 name()124 const char *name() const 125 { 126 return this->orig_name; 127 } 128 get_stream_id()129 unsigned get_stream_id() const 130 { 131 return this->stream_id; 132 } 133 get_buffer()134 unsigned get_buffer() const 135 { 136 return this->buffer; 137 } 138 get_offset()139 unsigned get_offset() const 140 { 141 return this->offset; 142 } 143 144 /** 145 * The total number of varying components taken up by this variable. Only 146 * valid if assign_location() has been called. 147 */ num_components()148 unsigned num_components() const 149 { 150 if (this->lowered_builtin_array_variable) 151 return this->size; 152 else 153 return this->vector_elements * this->matrix_columns * this->size * 154 (this->is_64bit() ? 2 : 1); 155 } 156 get_location()157 unsigned get_location() const { 158 return this->location; 159 } 160 161 private: 162 is_64bit()163 bool is_64bit() const 164 { 165 switch (this->type) { 166 case GL_DOUBLE: 167 case GL_DOUBLE_VEC2: 168 case GL_DOUBLE_VEC3: 169 case GL_DOUBLE_VEC4: 170 case GL_DOUBLE_MAT2: 171 case GL_DOUBLE_MAT2x3: 172 case GL_DOUBLE_MAT2x4: 173 case GL_DOUBLE_MAT3: 174 case GL_DOUBLE_MAT3x2: 175 case GL_DOUBLE_MAT3x4: 176 case GL_DOUBLE_MAT4: 177 case GL_DOUBLE_MAT4x2: 178 case GL_DOUBLE_MAT4x3: 179 return true; 180 default: 181 return false; 182 } 183 } 184 185 /** 186 * The name that was supplied to glTransformFeedbackVaryings. Used for 187 * error reporting and glGetTransformFeedbackVarying(). 188 */ 189 const char *orig_name; 190 191 /** 192 * The name of the variable, parsed from orig_name. 193 */ 194 const char *var_name; 195 196 /** 197 * True if the declaration in orig_name represents an array. 198 */ 199 bool is_subscripted; 200 201 /** 202 * If is_subscripted is true, the subscript that was specified in orig_name. 203 */ 204 unsigned array_subscript; 205 206 /** 207 * Non-zero if the variable is gl_ClipDistance, glTessLevelOuter or 208 * gl_TessLevelInner and the driver lowers it to gl_*MESA. 209 */ 210 enum { 211 none, 212 clip_distance, 213 cull_distance, 214 tess_level_outer, 215 tess_level_inner, 216 } lowered_builtin_array_variable; 217 218 /** 219 * The vertex shader output location that the linker assigned for this 220 * variable. -1 if a location hasn't been assigned yet. 221 */ 222 int location; 223 224 /** 225 * Used to store the buffer assigned by xfb_buffer. 226 */ 227 unsigned buffer; 228 229 /** 230 * Used to store the offset assigned by xfb_offset. 231 */ 232 unsigned offset; 233 234 /** 235 * If non-zero, then this variable may be packed along with other variables 236 * into a single varying slot, so this offset should be applied when 237 * accessing components. For example, an offset of 1 means that the x 238 * component of this variable is actually stored in component y of the 239 * location specified by \c location. 240 * 241 * Only valid if location != -1. 242 */ 243 unsigned location_frac; 244 245 /** 246 * If location != -1, the number of vector elements in this variable, or 1 247 * if this variable is a scalar. 248 */ 249 unsigned vector_elements; 250 251 /** 252 * If location != -1, the number of matrix columns in this variable, or 1 253 * if this variable is not a matrix. 254 */ 255 unsigned matrix_columns; 256 257 /** Type of the varying returned by glGetTransformFeedbackVarying() */ 258 GLenum type; 259 260 /** 261 * If location != -1, the size that should be returned by 262 * glGetTransformFeedbackVarying(). 263 */ 264 unsigned size; 265 266 /** 267 * How many components to skip. If non-zero, this is 268 * gl_SkipComponents{1,2,3,4} from ARB_transform_feedback3. 269 */ 270 unsigned skip_components; 271 272 /** 273 * Whether this is gl_NextBuffer from ARB_transform_feedback3. 274 */ 275 bool next_buffer_separator; 276 277 /** 278 * If find_candidate() has been called, pointer to the tfeedback_candidate 279 * data structure that was found. Otherwise NULL. 280 */ 281 const tfeedback_candidate *matched_candidate; 282 283 /** 284 * StreamId assigned to this varying (defaults to 0). Can only be set to 285 * values other than 0 in geometry shaders that use the stream layout 286 * modifier. Accepted values must be in the range [0, MAX_VERTEX_STREAMS-1]. 287 */ 288 unsigned stream_id; 289 }; 290 291 292 void 293 cross_validate_outputs_to_inputs(struct gl_shader_program *prog, 294 gl_linked_shader *producer, 295 gl_linked_shader *consumer); 296 297 bool 298 parse_tfeedback_decls(struct gl_context *ctx, struct gl_shader_program *prog, 299 const void *mem_ctx, unsigned num_names, 300 char **varying_names, tfeedback_decl *decls); 301 302 bool 303 process_xfb_layout_qualifiers(void *mem_ctx, const gl_linked_shader *sh, 304 unsigned *num_tfeedback_decls, 305 char ***varying_names); 306 307 void 308 remove_unused_shader_inputs_and_outputs(bool is_separate_shader_object, 309 gl_linked_shader *sh, 310 enum ir_variable_mode mode); 311 312 bool 313 store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog, 314 unsigned num_tfeedback_decls, 315 tfeedback_decl *tfeedback_decls, 316 bool has_xfb_qualifiers); 317 318 bool 319 assign_varying_locations(struct gl_context *ctx, 320 void *mem_ctx, 321 struct gl_shader_program *prog, 322 gl_linked_shader *producer, 323 gl_linked_shader *consumer, 324 unsigned num_tfeedback_decls, 325 tfeedback_decl *tfeedback_decls, 326 const uint64_t reserved_slots); 327 328 uint64_t 329 reserved_varying_slot(struct gl_linked_shader *stage, 330 ir_variable_mode io_mode); 331 332 bool 333 check_against_output_limit(struct gl_context *ctx, 334 struct gl_shader_program *prog, 335 gl_linked_shader *producer, 336 unsigned num_explicit_locations); 337 338 bool 339 check_against_input_limit(struct gl_context *ctx, 340 struct gl_shader_program *prog, 341 gl_linked_shader *consumer, 342 unsigned num_explicit_locations); 343 344 #endif /* GLSL_LINK_VARYINGS_H */ 345