Home | History | Annotate | Download | only in glsl
      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 
    106    bool is_next_buffer_separator() const
    107    {
    108       return this->next_buffer_separator;
    109    }
    110 
    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 
    119    bool is_varying() const
    120    {
    121       return !this->next_buffer_separator && !this->skip_components;
    122    }
    123 
    124    const char *name() const
    125    {
    126       return this->orig_name;
    127    }
    128 
    129    unsigned get_stream_id() const
    130    {
    131       return this->stream_id;
    132    }
    133 
    134    unsigned get_buffer() const
    135    {
    136       return this->buffer;
    137    }
    138 
    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     */
    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 
    157    unsigned get_location() const {
    158       return this->location;
    159    }
    160 
    161 private:
    162 
    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