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 37 38 struct gl_shader_program; 39 struct gl_shader; 40 class ir_variable; 41 42 43 /** 44 * Data structure describing a varying which is available for use in transform 45 * feedback. 46 * 47 * For example, if the vertex shader contains: 48 * 49 * struct S { 50 * vec4 foo; 51 * float[3] bar; 52 * }; 53 * 54 * varying S[2] v; 55 * 56 * Then there would be tfeedback_candidate objects corresponding to the 57 * following varyings: 58 * 59 * v[0].foo 60 * v[0].bar 61 * v[1].foo 62 * v[1].bar 63 */ 64 struct tfeedback_candidate 65 { 66 /** 67 * Toplevel variable containing this varying. In the above example, this 68 * would point to the declaration of the varying v. 69 */ 70 ir_variable *toplevel_var; 71 72 /** 73 * Type of this varying. In the above example, this would point to the 74 * glsl_type for "vec4" or "float[3]". 75 */ 76 const glsl_type *type; 77 78 /** 79 * Offset within the toplevel variable where this varying occurs (counted 80 * in multiples of the size of a float). 81 */ 82 unsigned offset; 83 }; 84 85 86 /** 87 * Data structure tracking information about a transform feedback declaration 88 * during linking. 89 */ 90 class tfeedback_decl 91 { 92 public: 93 void init(struct gl_context *ctx, const void *mem_ctx, const char *input); 94 static bool is_same(const tfeedback_decl &x, const tfeedback_decl &y); 95 bool assign_location(struct gl_context *ctx, 96 struct gl_shader_program *prog); 97 unsigned get_num_outputs() const; 98 bool store(struct gl_context *ctx, struct gl_shader_program *prog, 99 struct gl_transform_feedback_info *info, unsigned buffer, 100 unsigned buffer_index, const unsigned max_outputs, 101 bool *explicit_stride, bool has_xfb_qualifiers) const; 102 const tfeedback_candidate *find_candidate(gl_shader_program *prog, 103 hash_table *tfeedback_candidates); 104 is_next_buffer_separator()105 bool is_next_buffer_separator() const 106 { 107 return this->next_buffer_separator; 108 } 109 is_varying_written()110 bool is_varying_written() const 111 { 112 if (this->next_buffer_separator || this->skip_components) 113 return false; 114 115 return this->matched_candidate->toplevel_var->data.assigned; 116 } 117 is_varying()118 bool is_varying() const 119 { 120 return !this->next_buffer_separator && !this->skip_components; 121 } 122 name()123 const char *name() const 124 { 125 return this->orig_name; 126 } 127 get_stream_id()128 unsigned get_stream_id() const 129 { 130 return this->stream_id; 131 } 132 get_buffer()133 unsigned get_buffer() const 134 { 135 return this->buffer; 136 } 137 get_offset()138 unsigned get_offset() const 139 { 140 return this->offset; 141 } 142 143 /** 144 * The total number of varying components taken up by this variable. Only 145 * valid if assign_location() has been called. 146 */ num_components()147 unsigned num_components() const 148 { 149 if (this->lowered_builtin_array_variable) 150 return this->size; 151 else 152 return this->vector_elements * this->matrix_columns * this->size * 153 (this->is_64bit() ? 2 : 1); 154 } 155 get_location()156 unsigned get_location() const { 157 return this->location; 158 } 159 160 private: 161 is_64bit()162 bool is_64bit() const 163 { 164 switch (this->type) { 165 case GL_DOUBLE: 166 case GL_DOUBLE_VEC2: 167 case GL_DOUBLE_VEC3: 168 case GL_DOUBLE_VEC4: 169 case GL_DOUBLE_MAT2: 170 case GL_DOUBLE_MAT2x3: 171 case GL_DOUBLE_MAT2x4: 172 case GL_DOUBLE_MAT3: 173 case GL_DOUBLE_MAT3x2: 174 case GL_DOUBLE_MAT3x4: 175 case GL_DOUBLE_MAT4: 176 case GL_DOUBLE_MAT4x2: 177 case GL_DOUBLE_MAT4x3: 178 case GL_INT64_ARB: 179 case GL_INT64_VEC2_ARB: 180 case GL_INT64_VEC3_ARB: 181 case GL_INT64_VEC4_ARB: 182 case GL_UNSIGNED_INT64_ARB: 183 case GL_UNSIGNED_INT64_VEC2_ARB: 184 case GL_UNSIGNED_INT64_VEC3_ARB: 185 case GL_UNSIGNED_INT64_VEC4_ARB: 186 return true; 187 default: 188 return false; 189 } 190 } 191 192 /** 193 * The name that was supplied to glTransformFeedbackVaryings. Used for 194 * error reporting and glGetTransformFeedbackVarying(). 195 */ 196 const char *orig_name; 197 198 /** 199 * The name of the variable, parsed from orig_name. 200 */ 201 const char *var_name; 202 203 /** 204 * True if the declaration in orig_name represents an array. 205 */ 206 bool is_subscripted; 207 208 /** 209 * If is_subscripted is true, the subscript that was specified in orig_name. 210 */ 211 unsigned array_subscript; 212 213 /** 214 * Non-zero if the variable is gl_ClipDistance, glTessLevelOuter or 215 * gl_TessLevelInner and the driver lowers it to gl_*MESA. 216 */ 217 enum { 218 none, 219 clip_distance, 220 cull_distance, 221 tess_level_outer, 222 tess_level_inner, 223 } lowered_builtin_array_variable; 224 225 /** 226 * The vertex shader output location that the linker assigned for this 227 * variable. -1 if a location hasn't been assigned yet. 228 */ 229 int location; 230 231 /** 232 * Used to store the buffer assigned by xfb_buffer. 233 */ 234 unsigned buffer; 235 236 /** 237 * Used to store the offset assigned by xfb_offset. 238 */ 239 unsigned offset; 240 241 /** 242 * If non-zero, then this variable may be packed along with other variables 243 * into a single varying slot, so this offset should be applied when 244 * accessing components. For example, an offset of 1 means that the x 245 * component of this variable is actually stored in component y of the 246 * location specified by \c location. 247 * 248 * Only valid if location != -1. 249 */ 250 unsigned location_frac; 251 252 /** 253 * If location != -1, the number of vector elements in this variable, or 1 254 * if this variable is a scalar. 255 */ 256 unsigned vector_elements; 257 258 /** 259 * If location != -1, the number of matrix columns in this variable, or 1 260 * if this variable is not a matrix. 261 */ 262 unsigned matrix_columns; 263 264 /** Type of the varying returned by glGetTransformFeedbackVarying() */ 265 GLenum type; 266 267 /** 268 * If location != -1, the size that should be returned by 269 * glGetTransformFeedbackVarying(). 270 */ 271 unsigned size; 272 273 /** 274 * How many components to skip. If non-zero, this is 275 * gl_SkipComponents{1,2,3,4} from ARB_transform_feedback3. 276 */ 277 unsigned skip_components; 278 279 /** 280 * Whether this is gl_NextBuffer from ARB_transform_feedback3. 281 */ 282 bool next_buffer_separator; 283 284 /** 285 * If find_candidate() has been called, pointer to the tfeedback_candidate 286 * data structure that was found. Otherwise NULL. 287 */ 288 const tfeedback_candidate *matched_candidate; 289 290 /** 291 * StreamId assigned to this varying (defaults to 0). Can only be set to 292 * values other than 0 in geometry shaders that use the stream layout 293 * modifier. Accepted values must be in the range [0, MAX_VERTEX_STREAMS-1]. 294 */ 295 unsigned stream_id; 296 }; 297 298 bool 299 link_varyings(struct gl_shader_program *prog, unsigned first, unsigned last, 300 struct gl_context *ctx, void *mem_ctx); 301 302 void 303 validate_sso_explicit_locations(struct gl_context *ctx, 304 struct gl_shader_program *prog, 305 gl_shader_stage first, 306 gl_shader_stage last); 307 308 void 309 cross_validate_outputs_to_inputs(struct gl_context *ctx, 310 struct gl_shader_program *prog, 311 gl_linked_shader *producer, 312 gl_linked_shader *consumer); 313 314 #endif /* GLSL_LINK_VARYINGS_H */ 315