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