aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/glsl/builtin_variables.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/glsl/builtin_variables.cpp')
-rw-r--r--mesalib/src/glsl/builtin_variables.cpp113
1 files changed, 106 insertions, 7 deletions
diff --git a/mesalib/src/glsl/builtin_variables.cpp b/mesalib/src/glsl/builtin_variables.cpp
index 6a808c072..f06d2ab05 100644
--- a/mesalib/src/glsl/builtin_variables.cpp
+++ b/mesalib/src/glsl/builtin_variables.cpp
@@ -293,6 +293,51 @@ static const struct gl_builtin_uniform_desc _mesa_builtin_uniform_desc[] = {
namespace {
+/**
+ * Data structure that accumulates fields for the gl_PerVertex interface
+ * block.
+ */
+class per_vertex_accumulator
+{
+public:
+ per_vertex_accumulator();
+ void add_field(int slot, const glsl_type *type, const char *name);
+ const glsl_type *construct_interface_instance() const;
+
+private:
+ glsl_struct_field fields[10];
+ unsigned num_fields;
+};
+
+
+per_vertex_accumulator::per_vertex_accumulator()
+ : num_fields(0)
+{
+}
+
+
+void
+per_vertex_accumulator::add_field(int slot, const glsl_type *type,
+ const char *name)
+{
+ assert(this->num_fields < ARRAY_SIZE(this->fields));
+ this->fields[this->num_fields].type = type;
+ this->fields[this->num_fields].name = name;
+ this->fields[this->num_fields].row_major = false;
+ this->fields[this->num_fields].location = slot;
+ this->num_fields++;
+}
+
+
+const glsl_type *
+per_vertex_accumulator::construct_interface_instance() const
+{
+ return glsl_type::get_interface_instance(this->fields, this->num_fields,
+ GLSL_INTERFACE_PACKING_STD140,
+ "gl_PerVertex");
+}
+
+
class builtin_variable_generator
{
public:
@@ -358,6 +403,9 @@ private:
const glsl_type * const vec4_t;
const glsl_type * const mat3_t;
const glsl_type * const mat4_t;
+
+ per_vertex_accumulator per_vertex_in;
+ per_vertex_accumulator per_vertex_out;
};
@@ -497,11 +545,12 @@ builtin_variable_generator::generate_constants()
*/
if (state->is_version(0, 300)) {
add_const("gl_MaxVertexOutputVectors",
- state->Const.MaxVaryingFloats / 4);
+ state->ctx->Const.VertexProgram.MaxOutputComponents / 4);
add_const("gl_MaxFragmentInputVectors",
- state->Const.MaxVaryingFloats / 4);
+ state->ctx->Const.FragmentProgram.MaxInputComponents / 4);
} else {
- add_const("gl_MaxVaryingVectors", state->Const.MaxVaryingFloats / 4);
+ add_const("gl_MaxVaryingVectors",
+ state->ctx->Const.MaxVarying);
}
} else {
add_const("gl_MaxVertexUniformComponents",
@@ -510,7 +559,7 @@ builtin_variable_generator::generate_constants()
/* Note: gl_MaxVaryingFloats was deprecated in GLSL 1.30+, but not
* removed
*/
- add_const("gl_MaxVaryingFloats", state->Const.MaxVaryingFloats);
+ add_const("gl_MaxVaryingFloats", state->ctx->Const.MaxVarying * 4);
add_const("gl_MaxFragmentUniformComponents",
state->Const.MaxFragmentUniformComponents);
@@ -531,7 +580,38 @@ builtin_variable_generator::generate_constants()
if (state->is_version(130, 0)) {
add_const("gl_MaxClipDistances", state->Const.MaxClipPlanes);
- add_const("gl_MaxVaryingComponents", state->Const.MaxVaryingFloats);
+ add_const("gl_MaxVaryingComponents", state->ctx->Const.MaxVarying * 4);
+ }
+
+ if (state->is_version(150, 0)) {
+ add_const("gl_MaxVertexOutputComponents",
+ state->Const.MaxVertexOutputComponents);
+ add_const("gl_MaxGeometryInputComponents",
+ state->Const.MaxGeometryInputComponents);
+ add_const("gl_MaxGeometryOutputComponents",
+ state->Const.MaxGeometryOutputComponents);
+ add_const("gl_MaxFragmentInputComponents",
+ state->Const.MaxFragmentInputComponents);
+ add_const("gl_MaxGeometryTextureImageUnits",
+ state->Const.MaxGeometryTextureImageUnits);
+ add_const("gl_MaxGeometryOutputVertices",
+ state->Const.MaxGeometryOutputVertices);
+ add_const("gl_MaxGeometryTotalOutputComponents",
+ state->Const.MaxGeometryTotalOutputComponents);
+ add_const("gl_MaxGeometryUniformComponents",
+ state->Const.MaxGeometryUniformComponents);
+
+ /* Note: the GLSL 1.50-4.40 specs require
+ * gl_MaxGeometryVaryingComponents to be present, and to be at least 64.
+ * But they do not define what it means (and there does not appear to be
+ * any corresponding constant in the GL specs). However,
+ * ARB_geometry_shader4 defines MAX_GEOMETRY_VARYING_COMPONENTS_ARB to
+ * be the maximum number of components available for use as geometry
+ * outputs. So we assume this is a synonym for
+ * gl_MaxGeometryOutputComponents.
+ */
+ add_const("gl_MaxGeometryVaryingComponents",
+ state->Const.MaxGeometryOutputComponents);
}
if (compatibility) {
@@ -756,10 +836,10 @@ builtin_variable_generator::add_varying(int slot, const glsl_type *type,
{
switch (state->target) {
case geometry_shader:
- add_input(slot, array(type, 0), name_as_gs_input);
+ this->per_vertex_in.add_field(slot, type, name);
/* FALLTHROUGH */
case vertex_shader:
- add_output(slot, type, name);
+ this->per_vertex_out.add_field(slot, type, name);
break;
case fragment_shader:
add_input(slot, type, name);
@@ -803,6 +883,25 @@ builtin_variable_generator::generate_varyings()
ADD_VARYING(VARYING_SLOT_BFC1, vec4_t, "gl_BackSecondaryColor");
}
}
+
+ if (state->target == geometry_shader) {
+ const glsl_type *per_vertex_in_type =
+ this->per_vertex_in.construct_interface_instance();
+ ir_variable *var = add_variable("gl_in", array(per_vertex_in_type, 0),
+ ir_var_shader_in, -1);
+ var->init_interface_type(per_vertex_in_type);
+ }
+ if (state->target == vertex_shader || state->target == geometry_shader) {
+ const glsl_type *per_vertex_out_type =
+ this->per_vertex_out.construct_interface_instance();
+ const glsl_struct_field *fields = per_vertex_out_type->fields.structure;
+ for (unsigned i = 0; i < per_vertex_out_type->length; i++) {
+ ir_variable *var =
+ add_variable(fields[i].name, fields[i].type, ir_var_shader_out,
+ fields[i].location);
+ var->init_interface_type(per_vertex_out_type);
+ }
+ }
}