summaryrefslogtreecommitdiffstats
path: root/src/compiler/glsl/link_varyings.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/glsl/link_varyings.h')
-rw-r--r--src/compiler/glsl/link_varyings.h299
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 */