diff options
Diffstat (limited to 'src/compiler/glsl/link_varyings.h')
-rw-r--r-- | src/compiler/glsl/link_varyings.h | 299 |
1 files changed, 299 insertions, 0 deletions
diff --git a/src/compiler/glsl/link_varyings.h b/src/compiler/glsl/link_varyings.h new file mode 100644 index 00000000000..b2812614ecc --- /dev/null +++ b/src/compiler/glsl/link_varyings.h @@ -0,0 +1,299 @@ +/* + * Copyright © 2012 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#pragma once +#ifndef GLSL_LINK_VARYINGS_H +#define GLSL_LINK_VARYINGS_H + +/** + * \file link_varyings.h + * + * Linker functions related specifically to linking varyings between shader + * stages. + */ + + +#include "main/glheader.h" + + +struct gl_shader_program; +struct gl_shader; +class ir_variable; + + +/** + * Data structure describing a varying which is available for use in transform + * feedback. + * + * For example, if the vertex shader contains: + * + * struct S { + * vec4 foo; + * float[3] bar; + * }; + * + * varying S[2] v; + * + * Then there would be tfeedback_candidate objects corresponding to the + * following varyings: + * + * v[0].foo + * v[0].bar + * v[1].foo + * v[1].bar + */ +struct tfeedback_candidate +{ + /** + * Toplevel variable containing this varying. In the above example, this + * would point to the declaration of the varying v. + */ + ir_variable *toplevel_var; + + /** + * Type of this varying. In the above example, this would point to the + * glsl_type for "vec4" or "float[3]". + */ + const glsl_type *type; + + /** + * Offset within the toplevel variable where this varying occurs (counted + * in multiples of the size of a float). + */ + unsigned offset; +}; + + +/** + * Data structure tracking information about a transform feedback declaration + * during linking. + */ +class tfeedback_decl +{ +public: + void init(struct gl_context *ctx, const void *mem_ctx, const char *input); + static bool is_same(const tfeedback_decl &x, const tfeedback_decl &y); + bool assign_location(struct gl_context *ctx, + struct gl_shader_program *prog); + unsigned get_num_outputs() const; + bool store(struct gl_context *ctx, struct gl_shader_program *prog, + struct gl_transform_feedback_info *info, unsigned buffer, + const unsigned max_outputs) const; + const tfeedback_candidate *find_candidate(gl_shader_program *prog, + hash_table *tfeedback_candidates); + + bool is_next_buffer_separator() const + { + return this->next_buffer_separator; + } + + bool is_varying() const + { + return !this->next_buffer_separator && !this->skip_components; + } + + const char *name() const + { + return this->orig_name; + } + + unsigned get_stream_id() const + { + return this->stream_id; + } + + /** + * The total number of varying components taken up by this variable. Only + * valid if assign_location() has been called. + */ + unsigned num_components() const + { + if (this->lowered_builtin_array_variable) + return this->size; + else + return this->vector_elements * this->matrix_columns * this->size * + (this->is_double() ? 2 : 1); + } + + unsigned get_location() const { + return this->location; + } + +private: + + bool is_double() const + { + switch (this->type) { + case GL_DOUBLE: + case GL_DOUBLE_VEC2: + case GL_DOUBLE_VEC3: + case GL_DOUBLE_VEC4: + case GL_DOUBLE_MAT2: + case GL_DOUBLE_MAT2x3: + case GL_DOUBLE_MAT2x4: + case GL_DOUBLE_MAT3: + case GL_DOUBLE_MAT3x2: + case GL_DOUBLE_MAT3x4: + case GL_DOUBLE_MAT4: + case GL_DOUBLE_MAT4x2: + case GL_DOUBLE_MAT4x3: + return true; + default: + return false; + } + } + + /** + * The name that was supplied to glTransformFeedbackVaryings. Used for + * error reporting and glGetTransformFeedbackVarying(). + */ + const char *orig_name; + + /** + * The name of the variable, parsed from orig_name. + */ + const char *var_name; + + /** + * True if the declaration in orig_name represents an array. + */ + bool is_subscripted; + + /** + * If is_subscripted is true, the subscript that was specified in orig_name. + */ + unsigned array_subscript; + + /** + * Non-zero if the variable is gl_ClipDistance, glTessLevelOuter or + * gl_TessLevelInner and the driver lowers it to gl_*MESA. + */ + enum { + none, + clip_distance, + tess_level_outer, + tess_level_inner, + } lowered_builtin_array_variable; + + /** + * The vertex shader output location that the linker assigned for this + * variable. -1 if a location hasn't been assigned yet. + */ + int location; + + /** + * If non-zero, then this variable may be packed along with other variables + * into a single varying slot, so this offset should be applied when + * accessing components. For example, an offset of 1 means that the x + * component of this variable is actually stored in component y of the + * location specified by \c location. + * + * Only valid if location != -1. + */ + unsigned location_frac; + + /** + * If location != -1, the number of vector elements in this variable, or 1 + * if this variable is a scalar. + */ + unsigned vector_elements; + + /** + * If location != -1, the number of matrix columns in this variable, or 1 + * if this variable is not a matrix. + */ + unsigned matrix_columns; + + /** Type of the varying returned by glGetTransformFeedbackVarying() */ + GLenum type; + + /** + * If location != -1, the size that should be returned by + * glGetTransformFeedbackVarying(). + */ + unsigned size; + + /** + * How many components to skip. If non-zero, this is + * gl_SkipComponents{1,2,3,4} from ARB_transform_feedback3. + */ + unsigned skip_components; + + /** + * Whether this is gl_NextBuffer from ARB_transform_feedback3. + */ + bool next_buffer_separator; + + /** + * If find_candidate() has been called, pointer to the tfeedback_candidate + * data structure that was found. Otherwise NULL. + */ + const tfeedback_candidate *matched_candidate; + + /** + * StreamId assigned to this varying (defaults to 0). Can only be set to + * values other than 0 in geometry shaders that use the stream layout + * modifier. Accepted values must be in the range [0, MAX_VERTEX_STREAMS-1]. + */ + unsigned stream_id; +}; + + +void +cross_validate_outputs_to_inputs(struct gl_shader_program *prog, + gl_shader *producer, gl_shader *consumer); + +bool +parse_tfeedback_decls(struct gl_context *ctx, struct gl_shader_program *prog, + const void *mem_ctx, unsigned num_names, + char **varying_names, tfeedback_decl *decls); + +void +remove_unused_shader_inputs_and_outputs(bool is_separate_shader_object, + gl_shader *sh, + enum ir_variable_mode mode); + +bool +store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog, + unsigned num_tfeedback_decls, + tfeedback_decl *tfeedback_decls); + +bool +assign_varying_locations(struct gl_context *ctx, + void *mem_ctx, + struct gl_shader_program *prog, + gl_shader *producer, gl_shader *consumer, + unsigned num_tfeedback_decls, + tfeedback_decl *tfeedback_decls); + +bool +check_against_output_limit(struct gl_context *ctx, + struct gl_shader_program *prog, + gl_shader *producer); + +bool +check_against_input_limit(struct gl_context *ctx, + struct gl_shader_program *prog, + gl_shader *consumer); + +#endif /* GLSL_LINK_VARYINGS_H */ |