summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2012-03-24 13:33:41 +0000
committerDave Airlie <airlied@redhat.com>2012-04-13 17:19:01 +0100
commit1256a5dcc86014d48bdc6fd10ea5a2fa11241667 (patch)
tree8739552f09debe93734d1b338ac0e2787fc8a80f
parentf8cf79936b42405a8366613b80e3bde21aadaa02 (diff)
glsl: add support for ARB_blend_func_extended (v3)
This adds index support to the GLSL compiler. I'm not 100% sure of my approach here, esp without how output ordering happens wrt location, index pairs, in the "mark" function. Since current hw doesn't ever have a location > 0 with an index > 0, we don't have to work out if the output ordering the hw requires is location, index, location, index or location, location, index, index. But we have no hw to know, so punt on it for now. v2: index requires layout - catch and error setup explicit index properly. v3: drop idx_offset stuff, assume index follow location Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--src/glsl/ast.h12
-rw-r--r--src/glsl/ast_to_hir.cpp9
-rw-r--r--src/glsl/builtin_variables.cpp1
-rw-r--r--src/glsl/glsl_parser.yy20
-rw-r--r--src/glsl/ir.h1
-rw-r--r--src/glsl/ir_clone.cpp4
-rw-r--r--src/glsl/ir_set_program_inouts.cpp4
-rw-r--r--src/glsl/linker.cpp13
8 files changed, 57 insertions, 7 deletions
diff --git a/src/glsl/ast.h b/src/glsl/ast.h
index 9b1e0b1920..b096c838c0 100644
--- a/src/glsl/ast.h
+++ b/src/glsl/ast.h
@@ -363,6 +363,11 @@ struct ast_type_qualifier {
* qualifier is used.
*/
unsigned explicit_location:1;
+ /**
+ * Flag set if GL_ARB_explicit_attrib_location "index" layout
+ * qualifier is used.
+ */
+ unsigned explicit_index:1;
/** \name Layout qualifiers for GL_AMD_conservative_depth */
/** \{ */
@@ -386,6 +391,13 @@ struct ast_type_qualifier {
* This field is only valid if \c explicit_location is set.
*/
int location;
+ /**
+ * Index specified via GL_ARB_explicit_attrib_location layout
+ *
+ * \note
+ * This field is only valid if \c explicit_index is set.
+ */
+ int index;
/**
* Return true if and only if an interpolation qualifier is present.
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index f4dfc4ce34..820c86c5e6 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -2092,14 +2092,21 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
} else {
var->location = qual->location;
}
+ if (qual->flags.q.explicit_index) {
+ var->explicit_index = true;
+ var->index = qual->index;
+ }
}
+ } else if (qual->flags.q.explicit_index) {
+ _mesa_glsl_error(loc, state,
+ "explicit index requires explicit location\n");
}
/* Does the declaration use the 'layout' keyword?
*/
const bool uses_layout = qual->flags.q.pixel_center_integer
|| qual->flags.q.origin_upper_left
- || qual->flags.q.explicit_location;
+ || qual->flags.q.explicit_location; /* no need for index since it relies on location */
/* Does the declaration use the deprecated 'attribute' or 'varying'
* keywords?
diff --git a/src/glsl/builtin_variables.cpp b/src/glsl/builtin_variables.cpp
index 516a69caff..03b64c931a 100644
--- a/src/glsl/builtin_variables.cpp
+++ b/src/glsl/builtin_variables.cpp
@@ -408,6 +408,7 @@ add_variable(exec_list *instructions, glsl_symbol_table *symtab,
var->location = slot;
var->explicit_location = (slot >= 0);
+ var->explicit_index = 0;
/* Once the variable is created an initialized, add it to the symbol table
* and add the declaration to the IR stream.
diff --git a/src/glsl/glsl_parser.yy b/src/glsl/glsl_parser.yy
index 920213c303..5753acf3cd 100644
--- a/src/glsl/glsl_parser.yy
+++ b/src/glsl/glsl_parser.yy
@@ -1103,8 +1103,14 @@ layout_qualifier_id_list:
if ($1.flags.q.explicit_location)
$$.location = $1.location;
+ if ($1.flags.q.explicit_index)
+ $$.index = $1.index;
+
if ($3.flags.q.explicit_location)
$$.location = $3.location;
+
+ if ($3.flags.q.explicit_index)
+ $$.index = $3.index;
}
;
@@ -1191,6 +1197,20 @@ layout_qualifier_id:
YYERROR;
}
}
+
+ if (strcmp("index", $1) == 0) {
+ got_one = true;
+
+ $$.flags.q.explicit_index = 1;
+
+ if ($3 >= 0) {
+ $$.index = $3;
+ } else {
+ _mesa_glsl_error(& @3, state,
+ "invalid index %d specified\n", $3);
+ YYERROR;
+ }
+ }
}
/* If the identifier didn't match any known layout identifiers,
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index 9450e8f843..d6c6a607ae 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -386,6 +386,7 @@ public:
* no effect).
*/
unsigned explicit_location:1;
+ unsigned explicit_index:1;
/**
* Does this variable have an initializer?
diff --git a/src/glsl/ir_clone.cpp b/src/glsl/ir_clone.cpp
index 26b0d8f5f3..5a7a71cf6b 100644
--- a/src/glsl/ir_clone.cpp
+++ b/src/glsl/ir_clone.cpp
@@ -57,6 +57,7 @@ ir_variable::clone(void *mem_ctx, struct hash_table *ht) const
var->origin_upper_left = this->origin_upper_left;
var->pixel_center_integer = this->pixel_center_integer;
var->explicit_location = this->explicit_location;
+ var->explicit_index = this->explicit_index;
var->has_initializer = this->has_initializer;
var->depth_layout = this->depth_layout;
@@ -74,6 +75,9 @@ ir_variable::clone(void *mem_ctx, struct hash_table *ht) const
if (this->explicit_location)
var->location = this->location;
+ if (this->explicit_index)
+ var->index = this->index;
+
if (this->constant_value)
var->constant_value = this->constant_value->clone(mem_ctx, ht);
diff --git a/src/glsl/ir_set_program_inouts.cpp b/src/glsl/ir_set_program_inouts.cpp
index 8c2bc30d61..8f3edb9693 100644
--- a/src/glsl/ir_set_program_inouts.cpp
+++ b/src/glsl/ir_set_program_inouts.cpp
@@ -81,12 +81,12 @@ mark(struct gl_program *prog, ir_variable *var, int offset, int len,
*/
for (int i = 0; i < len; i++) {
- GLbitfield64 bitfield = BITFIELD64_BIT(var->location + offset + i);
+ GLbitfield64 bitfield = BITFIELD64_BIT(var->location + var->index + offset + i);
if (var->mode == ir_var_in) {
prog->InputsRead |= bitfield;
if (is_fragment_shader) {
gl_fragment_program *fprog = (gl_fragment_program *) prog;
- fprog->InterpQualifier[var->location + offset + i] =
+ fprog->InterpQualifier[var->location + var->index + offset + i] =
(glsl_interp_qualifier) var->interpolation;
}
} else if (var->mode == ir_var_system_value) {
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index 49b6b8f4a5..6ba297237c 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -1274,10 +1274,15 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
}
} else if (target_index == MESA_SHADER_FRAGMENT) {
unsigned binding;
+ unsigned index;
if (prog->FragDataBindings->get(binding, var->name)) {
assert(binding >= FRAG_RESULT_DATA0);
var->location = binding;
+
+ if (prog->FragDataIndexBindings->get(index, var->name)) {
+ var->index = index;
+ }
}
}
@@ -1288,7 +1293,7 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
*/
const unsigned slots = count_attribute_slots(var->type);
if (var->location != -1) {
- if (var->location >= generic_base) {
+ if (var->location >= generic_base && var->index < 1) {
/* From page 61 of the OpenGL 4.0 spec:
*
* "LinkProgram will fail if the attribute bindings assigned
@@ -1333,8 +1338,8 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
? "vertex shader input" : "fragment shader output";
linker_error(prog,
"insufficient contiguous locations "
- "available for %s `%s'", string,
- var->name);
+ "available for %s `%s' %d %d %d", string,
+ var->name, used_locations, use_mask, attr);
return false;
}
@@ -2321,7 +2326,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
goto done;
}
- if (!assign_attribute_or_color_locations(prog, MESA_SHADER_FRAGMENT, ctx->Const.MaxDrawBuffers)) {
+ if (!assign_attribute_or_color_locations(prog, MESA_SHADER_FRAGMENT, MAX2(ctx->Const.MaxDrawBuffers, ctx->Const.MaxDualSourceDrawBuffers))) {
goto done;
}