aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/glsl
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/glsl')
-rw-r--r--mesalib/src/glsl/Makefile.am18
-rw-r--r--mesalib/src/glsl/ast_to_hir.cpp1
-rw-r--r--mesalib/src/glsl/builtin_variables.cpp1
-rw-r--r--mesalib/src/glsl/glsl_parser.yy35
-rw-r--r--mesalib/src/glsl/ir.cpp11
-rw-r--r--mesalib/src/glsl/linker.cpp60
-rw-r--r--mesalib/src/glsl/linker.h3
-rw-r--r--mesalib/src/glsl/opt_algebraic.cpp40
8 files changed, 120 insertions, 49 deletions
diff --git a/mesalib/src/glsl/Makefile.am b/mesalib/src/glsl/Makefile.am
index cbf253cb5..b9ed5b62b 100644
--- a/mesalib/src/glsl/Makefile.am
+++ b/mesalib/src/glsl/Makefile.am
@@ -32,6 +32,7 @@ AM_CXXFLAGS = $(VISIBILITY_CXXFLAGS)
include Makefile.sources
TESTS = glcpp/tests/glcpp-test \
+ tests/general-ir-test \
tests/optimization-test \
tests/ralloc-test \
tests/sampler-types-test \
@@ -45,12 +46,29 @@ noinst_LTLIBRARIES = libglsl.la libglcpp.la
check_PROGRAMS = \
glcpp/glcpp \
glsl_test \
+ tests/general-ir-test \
tests/ralloc-test \
tests/sampler-types-test \
tests/uniform-initializer-test
noinst_PROGRAMS = glsl_compiler
+tests_general_ir_test_SOURCES = \
+ $(top_srcdir)/src/mesa/main/hash_table.c \
+ $(top_srcdir)/src/mesa/main/imports.c \
+ $(top_srcdir)/src/mesa/program/prog_hash_table.c\
+ $(top_srcdir)/src/mesa/program/symbol_table.c \
+ $(GLSL_SRCDIR)/standalone_scaffolding.cpp \
+ tests/builtin_variable_test.cpp \
+ tests/invalidate_locations_test.cpp \
+ tests/general_ir_test.cpp
+tests_general_ir_test_CFLAGS = \
+ $(PTHREAD_CFLAGS)
+tests_general_ir_test_LDADD = \
+ $(top_builddir)/src/gtest/libgtest.la \
+ $(top_builddir)/src/glsl/libglsl.la \
+ $(PTHREAD_LIBS)
+
tests_uniform_initializer_test_SOURCES = \
$(top_srcdir)/src/mesa/main/hash_table.c \
$(top_srcdir)/src/mesa/main/imports.c \
diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp
index dfa32d920..b644b22c7 100644
--- a/mesalib/src/glsl/ast_to_hir.cpp
+++ b/mesalib/src/glsl/ast_to_hir.cpp
@@ -4876,7 +4876,6 @@ ast_interface_block::hir(exec_list *instructions,
var_mode);
}
- var->init_interface_type(block_type);
if (state->target == geometry_shader && var_mode == ir_var_shader_in)
handle_geometry_shader_input_decl(state, loc, var);
diff --git a/mesalib/src/glsl/builtin_variables.cpp b/mesalib/src/glsl/builtin_variables.cpp
index 64f34061a..fc1115bc4 100644
--- a/mesalib/src/glsl/builtin_variables.cpp
+++ b/mesalib/src/glsl/builtin_variables.cpp
@@ -890,7 +890,6 @@ builtin_variable_generator::generate_varyings()
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 =
diff --git a/mesalib/src/glsl/glsl_parser.yy b/mesalib/src/glsl/glsl_parser.yy
index 00589e28e..0a0708e95 100644
--- a/mesalib/src/glsl/glsl_parser.yy
+++ b/mesalib/src/glsl/glsl_parser.yy
@@ -2372,6 +2372,7 @@ layout_defaults:
| layout_qualifier IN_TOK ';'
{
void *ctx = state;
+ $$ = NULL;
if (state->target != geometry_shader) {
_mesa_glsl_error(& @1, state,
"input layout qualifiers only valid in "
@@ -2380,8 +2381,22 @@ layout_defaults:
_mesa_glsl_error(& @1, state,
"input layout qualifiers must specify a primitive"
" type");
+ } else {
+ /* Make sure this is a valid input primitive type. */
+ switch ($1.prim_type) {
+ case GL_POINTS:
+ case GL_LINES:
+ case GL_LINES_ADJACENCY:
+ case GL_TRIANGLES:
+ case GL_TRIANGLES_ADJACENCY:
+ $$ = new(ctx) ast_gs_input_layout(@1, $1.prim_type);
+ break;
+ default:
+ _mesa_glsl_error(&@1, state,
+ "invalid geometry shader input primitive type");
+ break;
+ }
}
- $$ = new(ctx) ast_gs_input_layout(@1, $1.prim_type);
}
| layout_qualifier OUT_TOK ';'
@@ -2390,8 +2405,22 @@ layout_defaults:
_mesa_glsl_error(& @1, state,
"out layout qualifiers only valid in "
"geometry shaders");
- } else if (!state->out_qualifier->merge_qualifier(& @1, state, $1)) {
- YYERROR;
+ } else {
+ if ($1.flags.q.prim_type) {
+ /* Make sure this is a valid output primitive type. */
+ switch ($1.prim_type) {
+ case GL_POINTS:
+ case GL_LINE_STRIP:
+ case GL_TRIANGLE_STRIP:
+ break;
+ default:
+ _mesa_glsl_error(&@1, state, "invalid geometry shader output "
+ "primitive type");
+ break;
+ }
+ }
+ if (!state->out_qualifier->merge_qualifier(& @1, state, $1))
+ YYERROR;
}
$$ = NULL;
}
diff --git a/mesalib/src/glsl/ir.cpp b/mesalib/src/glsl/ir.cpp
index de9613e8f..54a8e400c 100644
--- a/mesalib/src/glsl/ir.cpp
+++ b/mesalib/src/glsl/ir.cpp
@@ -1603,8 +1603,15 @@ ir_variable::ir_variable(const struct glsl_type *type, const char *name,
this->depth_layout = ir_depth_layout_none;
this->used = false;
- if (type && type->base_type == GLSL_TYPE_SAMPLER)
- this->read_only = true;
+ if (type != NULL) {
+ if (type->base_type == GLSL_TYPE_SAMPLER)
+ this->read_only = true;
+
+ if (type->is_interface())
+ this->init_interface_type(type);
+ else if (type->is_array() && type->fields.array->is_interface())
+ this->init_interface_type(type->fields.array);
+ }
}
diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp
index 9095a4015..b23c31a16 100644
--- a/mesalib/src/glsl/linker.cpp
+++ b/mesalib/src/glsl/linker.cpp
@@ -366,35 +366,38 @@ parse_program_resource_name(const GLchar *name,
void
-link_invalidate_variable_locations(gl_shader *sh, int input_base,
- int output_base)
+link_invalidate_variable_locations(exec_list *ir)
{
- foreach_list(node, sh->ir) {
+ foreach_list(node, ir) {
ir_variable *const var = ((ir_instruction *) node)->as_variable();
if (var == NULL)
continue;
- int base;
- switch (var->mode) {
- case ir_var_shader_in:
- base = input_base;
- break;
- case ir_var_shader_out:
- base = output_base;
- break;
- default:
- continue;
- }
-
- /* Only assign locations for generic attributes / varyings / etc.
+ /* Only assign locations for variables that lack an explicit location.
+ * Explicit locations are set for all built-in variables, generic vertex
+ * shader inputs (via layout(location=...)), and generic fragment shader
+ * outputs (also via layout(location=...)).
*/
- if ((var->location >= base) && !var->explicit_location)
+ if (!var->explicit_location) {
var->location = -1;
+ var->location_frac = 0;
+ }
- if ((var->location == -1) && !var->explicit_location) {
+ /* ir_variable::is_unmatched_generic_inout is used by the linker while
+ * connecting outputs from one stage to inputs of the next stage.
+ *
+ * There are two implicit assumptions here. First, we assume that any
+ * built-in variable (i.e., non-generic in or out) will have
+ * explicit_location set. Second, we assume that any generic in or out
+ * will not have explicit_location set.
+ *
+ * This second assumption will only be valid until
+ * GL_ARB_separate_shader_objects is supported. When that extension is
+ * implemented, this function will need some modifications.
+ */
+ if (!var->explicit_location) {
var->is_unmatched_generic_inout = 1;
- var->location_frac = 0;
} else {
var->is_unmatched_generic_inout = 0;
}
@@ -2057,14 +2060,10 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
}
}
- /* Previous to GLSL version 1.30, different compilation units could mix and
- * match shading language versions. With GLSL 1.30 and later, the versions
- * of all shaders must match.
- *
- * GLSL ES has never allowed mixing of shading language versions.
+ /* In desktop GLSL, different shader versions may be linked together. In
+ * GLSL ES, all shader versions must be the same.
*/
- if ((is_es_prog || max_version >= 130)
- && min_version != max_version) {
+ if (is_es_prog && min_version != max_version) {
linker_error(prog, "all shaders must use same shading "
"language version\n");
goto done;
@@ -2221,18 +2220,15 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
/* Mark all generic shader inputs and outputs as unpaired. */
if (prog->_LinkedShaders[MESA_SHADER_VERTEX] != NULL) {
link_invalidate_variable_locations(
- prog->_LinkedShaders[MESA_SHADER_VERTEX],
- VERT_ATTRIB_GENERIC0, VARYING_SLOT_VAR0);
+ prog->_LinkedShaders[MESA_SHADER_VERTEX]->ir);
}
if (prog->_LinkedShaders[MESA_SHADER_GEOMETRY] != NULL) {
link_invalidate_variable_locations(
- prog->_LinkedShaders[MESA_SHADER_GEOMETRY],
- VARYING_SLOT_VAR0, VARYING_SLOT_VAR0);
+ prog->_LinkedShaders[MESA_SHADER_GEOMETRY]->ir);
}
if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] != NULL) {
link_invalidate_variable_locations(
- prog->_LinkedShaders[MESA_SHADER_FRAGMENT],
- VARYING_SLOT_VAR0, FRAG_RESULT_DATA0);
+ prog->_LinkedShaders[MESA_SHADER_FRAGMENT]->ir);
}
/* FINISHME: The value of the max_attribute_index parameter is
diff --git a/mesalib/src/glsl/linker.h b/mesalib/src/glsl/linker.h
index 8a0027d2b..887cd33d1 100644
--- a/mesalib/src/glsl/linker.h
+++ b/mesalib/src/glsl/linker.h
@@ -31,8 +31,7 @@ link_function_calls(gl_shader_program *prog, gl_shader *main,
gl_shader **shader_list, unsigned num_shaders);
extern void
-link_invalidate_variable_locations(gl_shader *sh, enum ir_variable_mode mode,
- int generic_base);
+link_invalidate_variable_locations(exec_list *ir);
extern void
link_assign_uniform_locations(struct gl_shader_program *prog);
diff --git a/mesalib/src/glsl/opt_algebraic.cpp b/mesalib/src/glsl/opt_algebraic.cpp
index 3e5802e18..37b2f02c6 100644
--- a/mesalib/src/glsl/opt_algebraic.cpp
+++ b/mesalib/src/glsl/opt_algebraic.cpp
@@ -210,6 +210,34 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
this->mem_ctx = ralloc_parent(ir);
switch (ir->operation) {
+ case ir_unop_abs:
+ if (op_expr[0] == NULL)
+ break;
+
+ switch (op_expr[0]->operation) {
+ case ir_unop_abs:
+ case ir_unop_neg:
+ this->progress = true;
+ temp = new(mem_ctx) ir_expression(ir_unop_abs,
+ ir->type,
+ op_expr[0]->operands[0],
+ NULL);
+ return swizzle_if_required(ir, temp);
+ default:
+ break;
+ }
+ break;
+
+ case ir_unop_neg:
+ if (op_expr[0] == NULL)
+ break;
+
+ if (op_expr[0]->operation == ir_unop_neg) {
+ this->progress = true;
+ return swizzle_if_required(ir, op_expr[0]->operands[0]);
+ }
+ break;
+
case ir_unop_logic_not: {
enum ir_expression_operation new_op = ir_unop_logic_not;
@@ -257,11 +285,9 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
* folding.
*/
if (op_const[0] && !op_const[1])
- reassociate_constant(ir, 0, op_const[0],
- ir->operands[1]->as_expression());
+ reassociate_constant(ir, 0, op_const[0], op_expr[1]);
if (op_const[1] && !op_const[0])
- reassociate_constant(ir, 1, op_const[1],
- ir->operands[0]->as_expression());
+ reassociate_constant(ir, 1, op_const[1], op_expr[0]);
break;
case ir_binop_sub:
@@ -315,11 +341,9 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
* constant folding.
*/
if (op_const[0] && !op_const[1])
- reassociate_constant(ir, 0, op_const[0],
- ir->operands[1]->as_expression());
+ reassociate_constant(ir, 0, op_const[0], op_expr[1]);
if (op_const[1] && !op_const[0])
- reassociate_constant(ir, 1, op_const[1],
- ir->operands[0]->as_expression());
+ reassociate_constant(ir, 1, op_const[1], op_expr[0]);
break;