aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/glsl
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/glsl')
-rw-r--r--mesalib/src/glsl/ir_clone.cpp2
-rw-r--r--mesalib/src/glsl/ir_print_visitor.cpp3
-rw-r--r--mesalib/src/glsl/ir_set_program_inouts.cpp2
-rw-r--r--mesalib/src/glsl/ir_variable.cpp25
-rw-r--r--mesalib/src/glsl/linker.cpp8
-rw-r--r--mesalib/src/glsl/opt_tree_grafting.cpp39
6 files changed, 58 insertions, 21 deletions
diff --git a/mesalib/src/glsl/ir_clone.cpp b/mesalib/src/glsl/ir_clone.cpp
index c1befa95c..9adf47050 100644
--- a/mesalib/src/glsl/ir_clone.cpp
+++ b/mesalib/src/glsl/ir_clone.cpp
@@ -25,9 +25,7 @@
#include "main/compiler.h"
#include "ir.h"
#include "glsl_types.h"
-extern "C" {
#include "program/hash_table.h"
-}
/**
* Duplicate an IR variable
diff --git a/mesalib/src/glsl/ir_print_visitor.cpp b/mesalib/src/glsl/ir_print_visitor.cpp
index ea7858224..b713bd03b 100644
--- a/mesalib/src/glsl/ir_print_visitor.cpp
+++ b/mesalib/src/glsl/ir_print_visitor.cpp
@@ -24,10 +24,7 @@
#include "ir_print_visitor.h"
#include "glsl_types.h"
#include "glsl_parser_extras.h"
-
-extern "C" {
#include "program/hash_table.h"
-}
static void print_type(const glsl_type *t);
diff --git a/mesalib/src/glsl/ir_set_program_inouts.cpp b/mesalib/src/glsl/ir_set_program_inouts.cpp
index 3b10b9097..ae3ef74c7 100644
--- a/mesalib/src/glsl/ir_set_program_inouts.cpp
+++ b/mesalib/src/glsl/ir_set_program_inouts.cpp
@@ -34,10 +34,8 @@
* from the GLSL IR.
*/
-extern "C" {
#include "main/core.h" /* for struct gl_program */
#include "program/hash_table.h"
-}
#include "ir.h"
#include "ir_visitor.h"
#include "glsl_types.h"
diff --git a/mesalib/src/glsl/ir_variable.cpp b/mesalib/src/glsl/ir_variable.cpp
index 58be64bfa..6ae3b1f9e 100644
--- a/mesalib/src/glsl/ir_variable.cpp
+++ b/mesalib/src/glsl/ir_variable.cpp
@@ -178,6 +178,14 @@ static struct gl_builtin_uniform_element gl_MESAFogParamsOptimized_elements[] =
{NULL, {STATE_INTERNAL, STATE_FOG_PARAMS_OPTIMIZED}, SWIZZLE_XYZW},
};
+static struct gl_builtin_uniform_element gl_CurrentAttribVertMESA_elements[] = {
+ {NULL, {STATE_INTERNAL, STATE_CURRENT_ATTRIB, 0}, SWIZZLE_XYZW},
+};
+
+static struct gl_builtin_uniform_element gl_CurrentAttribFragMESA_elements[] = {
+ {NULL, {STATE_INTERNAL, STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED, 0}, SWIZZLE_XYZW},
+};
+
#define MATRIX(name, statevar, modifier) \
static struct gl_builtin_uniform_element name ## _elements[] = { \
{ NULL, { statevar, 0, 0, 0, modifier}, SWIZZLE_XYZW }, \
@@ -284,6 +292,8 @@ const struct gl_builtin_uniform_desc _mesa_builtin_uniform_desc[] = {
STATEVAR(gl_MESABumpRotMatrix0),
STATEVAR(gl_MESABumpRotMatrix1),
STATEVAR(gl_MESAFogParamsOptimized),
+ STATEVAR(gl_CurrentAttribVertMESA),
+ STATEVAR(gl_CurrentAttribFragMESA),
{NULL, NULL, 0}
};
@@ -355,7 +365,12 @@ add_uniform(exec_list *instructions, glsl_symbol_table *symtab,
memcpy(slots->tokens, element->tokens, sizeof(element->tokens));
if (type->is_array()) {
- slots->tokens[1] = a;
+ if (strcmp(name, "gl_CurrentAttribVertMESA") == 0 ||
+ strcmp(name, "gl_CurrentAttribFragMESA") == 0) {
+ slots->tokens[2] = a;
+ } else {
+ slots->tokens[1] = a;
+ }
}
slots->swizzle = element->swizzle;
@@ -518,6 +533,14 @@ generate_110_uniforms(exec_list *instructions,
add_uniform(instructions, symtab, "gl_Fog",
symtab->get_type("gl_FogParameters"));
+
+ /* Mesa-internal current attrib state */
+ const glsl_type *const vert_attribs =
+ glsl_type::get_array_instance(glsl_type::vec4_type, VERT_ATTRIB_MAX);
+ add_uniform(instructions, symtab, "gl_CurrentAttribVertMESA", vert_attribs);
+ const glsl_type *const frag_attribs =
+ glsl_type::get_array_instance(glsl_type::vec4_type, FRAG_ATTRIB_MAX);
+ add_uniform(instructions, symtab, "gl_CurrentAttribFragMESA", frag_attribs);
}
/* This function should only be called for ES, not desktop GL. */
diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp
index 9463f5305..a7c38a342 100644
--- a/mesalib/src/glsl/linker.cpp
+++ b/mesalib/src/glsl/linker.cpp
@@ -1342,7 +1342,10 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
}
}
- /* The location was explicitly assigned, nothing to do here.
+ /* If the variable is not a built-in and has a location statically
+ * assigned in the shader (presumably via a layout qualifier), make sure
+ * that it doesn't collide with other assigned locations. Otherwise,
+ * add it to the list of variables that need linker-assigned locations.
*/
const unsigned slots = count_attribute_slots(var->type);
if (var->location != -1) {
@@ -1802,7 +1805,8 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
* present in a linked program. By checking for use of shading language
* version 1.00, we also catch the GL_ARB_ES2_compatibility case.
*/
- if (ctx->API == API_OPENGLES2 || prog->Version == 100) {
+ if (!prog->InternalSeparateShader &&
+ (ctx->API == API_OPENGLES2 || prog->Version == 100)) {
if (prog->_LinkedShaders[MESA_SHADER_VERTEX] == NULL) {
linker_error(prog, "program lacks a vertex shader\n");
} else if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL) {
diff --git a/mesalib/src/glsl/opt_tree_grafting.cpp b/mesalib/src/glsl/opt_tree_grafting.cpp
index 22a1749b9..d32d14e88 100644
--- a/mesalib/src/glsl/opt_tree_grafting.cpp
+++ b/mesalib/src/glsl/opt_tree_grafting.cpp
@@ -76,6 +76,8 @@ public:
virtual ir_visitor_status visit_enter(class ir_swizzle *);
virtual ir_visitor_status visit_enter(class ir_texture *);
+ ir_visitor_status check_graft(ir_instruction *ir, ir_variable *var);
+
bool do_graft(ir_rvalue **rvalue);
bool progress;
@@ -148,18 +150,17 @@ ir_tree_grafting_visitor::visit_enter(ir_loop *ir)
return visit_stop;
}
+/**
+ * Check if we can continue grafting after writing to a variable. If the
+ * expression we're trying to graft references the variable, we must stop.
+ *
+ * \param ir An instruction that writes to a variable.
+ * \param var The variable being updated.
+ */
ir_visitor_status
-ir_tree_grafting_visitor::visit_leave(ir_assignment *ir)
+ir_tree_grafting_visitor::check_graft(ir_instruction *ir, ir_variable *var)
{
- if (do_graft(&ir->rhs) ||
- do_graft(&ir->condition))
- return visit_stop;
-
- /* If this assignment updates a variable used in the assignment
- * we're trying to graft, then we're done.
- */
- if (dereferences_variable(this->graft_assign->rhs,
- ir->lhs->variable_referenced())) {
+ if (dereferences_variable(this->graft_assign->rhs, var)) {
if (debug) {
printf("graft killed by: ");
ir->print();
@@ -172,6 +173,19 @@ ir_tree_grafting_visitor::visit_leave(ir_assignment *ir)
}
ir_visitor_status
+ir_tree_grafting_visitor::visit_leave(ir_assignment *ir)
+{
+ if (do_graft(&ir->rhs) ||
+ do_graft(&ir->condition))
+ return visit_stop;
+
+ /* If this assignment updates a variable used in the assignment
+ * we're trying to graft, then we're done.
+ */
+ return check_graft(ir, ir->lhs->variable_referenced());
+}
+
+ir_visitor_status
ir_tree_grafting_visitor::visit_enter(ir_function *ir)
{
(void) ir;
@@ -195,8 +209,11 @@ ir_tree_grafting_visitor::visit_enter(ir_call *ir)
ir_rvalue *ir = (ir_rvalue *)iter.get();
ir_rvalue *new_ir = ir;
- if (sig_param->mode != ir_var_in && sig_param->mode != ir_var_const_in)
+ if (sig_param->mode != ir_var_in && sig_param->mode != ir_var_const_in) {
+ if (check_graft(ir, sig_param) == visit_stop)
+ return visit_stop;
continue;
+ }
if (do_graft(&new_ir)) {
ir->replace_with(new_ir);