aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src')
-rw-r--r--mesalib/src/glsl/ast_function.cpp35
-rw-r--r--mesalib/src/glsl/ast_to_hir.cpp87
-rwxr-xr-xmesalib/src/glsl/builtin_functions.cpp67
-rw-r--r--mesalib/src/glsl/glsl_parser.yy8
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.cpp2
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.h5
-rwxr-xr-x[-rw-r--r--]mesalib/src/glsl/ir.cpp6
-rw-r--r--mesalib/src/glsl/ir.h33
-rw-r--r--mesalib/src/glsl/ir_builder.cpp18
-rw-r--r--mesalib/src/glsl/ir_builder.h4
-rwxr-xr-xmesalib/src/glsl/ir_constant_expression.cpp2
-rw-r--r--mesalib/src/glsl/ir_hierarchical_visitor.cpp158
-rw-r--r--mesalib/src/glsl/ir_hierarchical_visitor.h29
-rw-r--r--mesalib/src/glsl/ir_reader.cpp7
-rw-r--r--mesalib/src/glsl/ir_validate.cpp30
-rw-r--r--mesalib/src/glsl/list.h40
-rw-r--r--mesalib/src/glsl/opt_function_inlining.cpp7
-rw-r--r--mesalib/src/glsl/opt_rebalance_tree.cpp23
-rwxr-xr-xmesalib/src/mapi/glapi/gen/gl_gentable.py4
-rw-r--r--mesalib/src/mesa/drivers/dri/Makefile.am3
-rw-r--r--mesalib/src/mesa/drivers/dri/common/drirc20
-rw-r--r--mesalib/src/mesa/drivers/dri/common/xmlpool/t_options.h5
-rw-r--r--mesalib/src/mesa/main/arrayobj.c15
-rw-r--r--mesalib/src/mesa/main/format_pack.c2
-rw-r--r--mesalib/src/mesa/main/mtypes.h19
-rw-r--r--mesalib/src/mesa/main/pack.c16
-rw-r--r--mesalib/src/mesa/main/texparam.c22
-rw-r--r--mesalib/src/mesa/program/ir_to_mesa.cpp8
-rw-r--r--mesalib/src/mesa/state_tracker/st_extensions.c3
-rw-r--r--mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp11
-rw-r--r--mesalib/src/mesa/vbo/vbo_context.h22
-rw-r--r--mesalib/src/mesa/vbo/vbo_exec.c15
32 files changed, 572 insertions, 154 deletions
diff --git a/mesalib/src/glsl/ast_function.cpp b/mesalib/src/glsl/ast_function.cpp
index cdb34cc69..4981fe174 100644
--- a/mesalib/src/glsl/ast_function.cpp
+++ b/mesalib/src/glsl/ast_function.cpp
@@ -178,6 +178,24 @@ verify_parameter_modes(_mesa_glsl_parse_state *state,
return false;
}
+ /* Verify that shader_in parameters are shader inputs */
+ if (formal->data.must_be_shader_input) {
+ ir_variable *var = actual->variable_referenced();
+ if (var && var->data.mode != ir_var_shader_in) {
+ _mesa_glsl_error(&loc, state,
+ "parameter `%s` must be a shader input",
+ formal->name);
+ return false;
+ }
+
+ if (actual->ir_type == ir_type_swizzle) {
+ _mesa_glsl_error(&loc, state,
+ "parameter `%s` must not be swizzled",
+ formal->name);
+ return false;
+ }
+ }
+
/* Verify that 'out' and 'inout' actual parameters are lvalues. */
if (formal->data.mode == ir_var_function_out
|| formal->data.mode == ir_var_function_inout) {
@@ -742,11 +760,22 @@ process_vec_mat_constructor(exec_list *instructions,
instructions->push_tail(var);
int i = 0;
+
foreach_in_list(ir_rvalue, rhs, &actual_parameters) {
- ir_rvalue *lhs = new(ctx) ir_dereference_array(var,
- new(ctx) ir_constant(i));
+ ir_instruction *assignment = NULL;
+
+ if (var->type->is_matrix()) {
+ ir_rvalue *lhs = new(ctx) ir_dereference_array(var,
+ new(ctx) ir_constant(i));
+ assignment = new(ctx) ir_assignment(lhs, rhs, NULL);
+ } else {
+ /* use writemask rather than index for vector */
+ assert(var->type->is_vector());
+ assert(i < 4);
+ ir_dereference *lhs = new(ctx) ir_dereference_variable(var);
+ assignment = new(ctx) ir_assignment(lhs, rhs, NULL, (unsigned)(1 << i));
+ }
- ir_instruction *assignment = new(ctx) ir_assignment(lhs, rhs, NULL);
instructions->push_tail(assignment);
i++;
diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp
index 885bee547..328cd1b1b 100644
--- a/mesalib/src/glsl/ast_to_hir.cpp
+++ b/mesalib/src/glsl/ast_to_hir.cpp
@@ -4513,6 +4513,12 @@ ast_switch_statement::hir(exec_list *instructions,
instructions->push_tail(new(ctx) ir_assignment(deref_is_break_var,
is_break_val));
+ state->switch_state.run_default =
+ new(ctx) ir_variable(glsl_type::bool_type,
+ "run_default_tmp",
+ ir_var_temporary);
+ instructions->push_tail(state->switch_state.run_default);
+
/* Cache test expression.
*/
test_to_hir(instructions, state);
@@ -4567,8 +4573,71 @@ ir_rvalue *
ast_case_statement_list::hir(exec_list *instructions,
struct _mesa_glsl_parse_state *state)
{
- foreach_list_typed (ast_case_statement, case_stmt, link, & this->cases)
- case_stmt->hir(instructions, state);
+ exec_list default_case, after_default, tmp;
+
+ foreach_list_typed (ast_case_statement, case_stmt, link, & this->cases) {
+ case_stmt->hir(&tmp, state);
+
+ /* Default case. */
+ if (state->switch_state.previous_default && default_case.is_empty()) {
+ default_case.append_list(&tmp);
+ continue;
+ }
+
+ /* If default case found, append 'after_default' list. */
+ if (!default_case.is_empty())
+ after_default.append_list(&tmp);
+ else
+ instructions->append_list(&tmp);
+ }
+
+ /* Handle the default case. This is done here because default might not be
+ * the last case. We need to add checks against following cases first to see
+ * if default should be chosen or not.
+ */
+ if (!default_case.is_empty()) {
+
+ /* Default case was the last one, no checks required. */
+ if (after_default.is_empty()) {
+ instructions->append_list(&default_case);
+ return NULL;
+ }
+
+ ir_rvalue *const true_val = new (state) ir_constant(true);
+ ir_dereference_variable *deref_run_default_var =
+ new(state) ir_dereference_variable(state->switch_state.run_default);
+
+ /* Choose to run default case initially, following conditional
+ * assignments might change this.
+ */
+ ir_assignment *const init_var =
+ new(state) ir_assignment(deref_run_default_var, true_val);
+ instructions->push_tail(init_var);
+
+ foreach_in_list(ir_instruction, ir, &after_default) {
+ ir_assignment *assign = ir->as_assignment();
+
+ if (!assign)
+ continue;
+
+ /* Clone the check between case label and init expression. */
+ ir_expression *exp = (ir_expression*) assign->condition;
+ ir_expression *clone = exp->clone(state, NULL);
+
+ ir_dereference_variable *deref_var =
+ new(state) ir_dereference_variable(state->switch_state.run_default);
+ ir_rvalue *const false_val = new (state) ir_constant(false);
+
+ ir_assignment *const set_false =
+ new(state) ir_assignment(deref_var, false_val, clone);
+
+ instructions->push_tail(set_false);
+ }
+
+ /* Append default case and all cases after it. */
+ instructions->append_list(&default_case);
+ instructions->append_list(&after_default);
+ }
/* Case statements do not have r-values. */
return NULL;
@@ -4728,9 +4797,17 @@ ast_case_label::hir(exec_list *instructions,
}
state->switch_state.previous_default = this;
+ /* Set fallthru condition on 'run_default' bool. */
+ ir_dereference_variable *deref_run_default =
+ new(ctx) ir_dereference_variable(state->switch_state.run_default);
+ ir_rvalue *const cond_true = new(ctx) ir_constant(true);
+ ir_expression *test_cond = new(ctx) ir_expression(ir_binop_all_equal,
+ cond_true,
+ deref_run_default);
+
/* Set falltrhu state. */
ir_assignment *set_fallthru =
- new(ctx) ir_assignment(deref_fallthru_var, true_val);
+ new(ctx) ir_assignment(deref_fallthru_var, true_val, test_cond);
instructions->push_tail(set_fallthru);
}
@@ -5007,9 +5084,7 @@ ast_process_structure_or_interface_block(exec_list *instructions,
* 'declarations' list in each of the elements.
*/
foreach_list_typed (ast_declarator_list, decl_list, link, declarations) {
- foreach_list_typed (ast_declaration, decl, link, &decl_list->declarations) {
- decl_count++;
- }
+ decl_count += decl_list->declarations.length();
}
/* Allocate storage for the fields and process the field
diff --git a/mesalib/src/glsl/builtin_functions.cpp b/mesalib/src/glsl/builtin_functions.cpp
index a987ab2c2..8fc9051bb 100755
--- a/mesalib/src/glsl/builtin_functions.cpp
+++ b/mesalib/src/glsl/builtin_functions.cpp
@@ -226,6 +226,14 @@ shader_packing_or_gpu_shader5(const _mesa_glsl_parse_state *state)
}
static bool
+fs_gpu_shader5(const _mesa_glsl_parse_state *state)
+{
+ return state->stage == MESA_SHADER_FRAGMENT &&
+ (state->is_version(400, 0) || state->ARB_gpu_shader5_enable);
+}
+
+
+static bool
texture_array_lod(const _mesa_glsl_parse_state *state)
{
return lod_exists_in_stage(state) &&
@@ -627,6 +635,9 @@ private:
B1(uaddCarry)
B1(usubBorrow)
B1(mulExtended)
+ B1(interpolateAtCentroid)
+ B1(interpolateAtOffset)
+ B1(interpolateAtSample)
ir_function_signature *_atomic_intrinsic(builtin_available_predicate avail);
ir_function_signature *_atomic_op(const char *intrinsic,
@@ -2186,6 +2197,24 @@ builtin_builder::create_builtins()
_mulExtended(glsl_type::uvec3_type),
_mulExtended(glsl_type::uvec4_type),
NULL);
+ add_function("interpolateAtCentroid",
+ _interpolateAtCentroid(glsl_type::float_type),
+ _interpolateAtCentroid(glsl_type::vec2_type),
+ _interpolateAtCentroid(glsl_type::vec3_type),
+ _interpolateAtCentroid(glsl_type::vec4_type),
+ NULL);
+ add_function("interpolateAtOffset",
+ _interpolateAtOffset(glsl_type::float_type),
+ _interpolateAtOffset(glsl_type::vec2_type),
+ _interpolateAtOffset(glsl_type::vec3_type),
+ _interpolateAtOffset(glsl_type::vec4_type),
+ NULL);
+ add_function("interpolateAtSample",
+ _interpolateAtSample(glsl_type::float_type),
+ _interpolateAtSample(glsl_type::vec2_type),
+ _interpolateAtSample(glsl_type::vec3_type),
+ _interpolateAtSample(glsl_type::vec4_type),
+ NULL);
add_function("atomicCounter",
_atomic_op("__intrinsic_atomic_read",
@@ -4260,6 +4289,44 @@ builtin_builder::_mulExtended(const glsl_type *type)
}
ir_function_signature *
+builtin_builder::_interpolateAtCentroid(const glsl_type *type)
+{
+ ir_variable *interpolant = in_var(type, "interpolant");
+ interpolant->data.must_be_shader_input = 1;
+ MAKE_SIG(type, fs_gpu_shader5, 1, interpolant);
+
+ body.emit(ret(interpolate_at_centroid(interpolant)));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_interpolateAtOffset(const glsl_type *type)
+{
+ ir_variable *interpolant = in_var(type, "interpolant");
+ interpolant->data.must_be_shader_input = 1;
+ ir_variable *offset = in_var(glsl_type::vec2_type, "offset");
+ MAKE_SIG(type, fs_gpu_shader5, 2, interpolant, offset);
+
+ body.emit(ret(interpolate_at_offset(interpolant, offset)));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_interpolateAtSample(const glsl_type *type)
+{
+ ir_variable *interpolant = in_var(type, "interpolant");
+ interpolant->data.must_be_shader_input = 1;
+ ir_variable *sample_num = in_var(glsl_type::int_type, "sample_num");
+ MAKE_SIG(type, fs_gpu_shader5, 2, interpolant, sample_num);
+
+ body.emit(ret(interpolate_at_sample(interpolant, sample_num)));
+
+ return sig;
+}
+
+ir_function_signature *
builtin_builder::_atomic_intrinsic(builtin_available_predicate avail)
{
ir_variable *counter = in_var(glsl_type::atomic_uint_type, "counter");
diff --git a/mesalib/src/glsl/glsl_parser.yy b/mesalib/src/glsl/glsl_parser.yy
index 980acc8ae..beabb5ffd 100644
--- a/mesalib/src/glsl/glsl_parser.yy
+++ b/mesalib/src/glsl/glsl_parser.yy
@@ -377,6 +377,14 @@ external_declaration_list:
if ($2 != NULL)
state->translation_unit.push_tail(& $2->link);
}
+ | external_declaration_list extension_statement {
+ if (!state->allow_extension_directive_midshader) {
+ _mesa_glsl_error(& @2, state,
+ "#extension directive is not allowed "
+ "in the middle of a shader");
+ YYERROR;
+ }
+ }
;
variable_identifier:
diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp
index b327c2b43..890123ad1 100644
--- a/mesalib/src/glsl/glsl_parser_extras.cpp
+++ b/mesalib/src/glsl/glsl_parser_extras.cpp
@@ -210,6 +210,8 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
this->early_fragment_tests = false;
memset(this->atomic_counter_offsets, 0,
sizeof(this->atomic_counter_offsets));
+ this->allow_extension_directive_midshader =
+ ctx->Const.AllowGLSLExtensionDirectiveMidShader;
}
/**
diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h
index 0ea3ce34a..ab5c006f5 100644
--- a/mesalib/src/glsl/glsl_parser_extras.h
+++ b/mesalib/src/glsl/glsl_parser_extras.h
@@ -43,6 +43,9 @@ struct glsl_switch_state {
ir_variable *is_break_var;
class ast_switch_statement *switch_nesting_ast;
+ /** Used to set condition if 'default' label should be chosen. */
+ ir_variable *run_default;
+
/** Table of constant values already used in case labels */
struct hash_table *labels_ht;
class ast_case_label *previous_default;
@@ -494,6 +497,8 @@ struct _mesa_glsl_parse_state {
/** Atomic counter offsets by binding */
unsigned atomic_counter_offsets[MAX_COMBINED_ATOMIC_BUFFERS];
+
+ bool allow_extension_directive_midshader;
};
# define YYLLOC_DEFAULT(Current, Rhs, N) \
diff --git a/mesalib/src/glsl/ir.cpp b/mesalib/src/glsl/ir.cpp
index 4b14668ea..578548b23 100644..100755
--- a/mesalib/src/glsl/ir.cpp
+++ b/mesalib/src/glsl/ir.cpp
@@ -250,6 +250,7 @@ ir_expression::ir_expression(int op, ir_rvalue *op0)
case ir_unop_dFdx:
case ir_unop_dFdy:
case ir_unop_bitfield_reverse:
+ case ir_unop_interpolate_at_centroid:
this->type = op0->type;
break;
@@ -403,6 +404,8 @@ ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1)
case ir_binop_rshift:
case ir_binop_bfm:
case ir_binop_ldexp:
+ case ir_binop_interpolate_at_offset:
+ case ir_binop_interpolate_at_sample:
this->type = op0->type;
break;
@@ -524,6 +527,7 @@ static const char *const operator_strs[] = {
"find_msb",
"find_lsb",
"noise",
+ "interpolate_at_centroid",
"+",
"-",
"*",
@@ -557,6 +561,8 @@ static const char *const operator_strs[] = {
"ubo_load",
"ldexp",
"vector_extract",
+ "interpolate_at_offset",
+ "interpolate_at_sample",
"fma_mesa",
"lrp",
"csel",
diff --git a/mesalib/src/glsl/ir.h b/mesalib/src/glsl/ir.h
index d5239d4de..ea19924ab 100644
--- a/mesalib/src/glsl/ir.h
+++ b/mesalib/src/glsl/ir.h
@@ -678,6 +678,12 @@ public:
unsigned from_named_ifc_block_array:1;
/**
+ * Non-zero if the variable must be a shader input. This is useful for
+ * constraints on function parameters.
+ */
+ unsigned must_be_shader_input:1;
+
+ /**
* \brief Layout qualifier for gl_FragDepth.
*
* This is not equal to \c ir_depth_layout_none if and only if this
@@ -1234,9 +1240,16 @@ enum ir_expression_operation {
ir_unop_noise,
/**
+ * Interpolate fs input at centroid
+ *
+ * operand0 is the fs input.
+ */
+ ir_unop_interpolate_at_centroid,
+
+ /**
* A sentinel marking the last of the unary operations.
*/
- ir_last_unop = ir_unop_noise,
+ ir_last_unop = ir_unop_interpolate_at_centroid,
ir_binop_add,
ir_binop_sub,
@@ -1355,9 +1368,25 @@ enum ir_expression_operation {
ir_binop_vector_extract,
/**
+ * Interpolate fs input at offset
+ *
+ * operand0 is the fs input
+ * operand1 is the offset from the pixel center
+ */
+ ir_binop_interpolate_at_offset,
+
+ /**
+ * Interpolate fs input at sample position
+ *
+ * operand0 is the fs input
+ * operand1 is the sample ID
+ */
+ ir_binop_interpolate_at_sample,
+
+ /**
* A sentinel marking the last of the binary operations.
*/
- ir_last_binop = ir_binop_vector_extract,
+ ir_last_binop = ir_binop_interpolate_at_sample,
/**
* \name Fused floating-point multiply-add, part of ARB_gpu_shader5.
diff --git a/mesalib/src/glsl/ir_builder.cpp b/mesalib/src/glsl/ir_builder.cpp
index f4a1c6efa..f03941443 100644
--- a/mesalib/src/glsl/ir_builder.cpp
+++ b/mesalib/src/glsl/ir_builder.cpp
@@ -501,6 +501,24 @@ b2f(operand a)
}
ir_expression *
+interpolate_at_centroid(operand a)
+{
+ return expr(ir_unop_interpolate_at_centroid, a);
+}
+
+ir_expression *
+interpolate_at_offset(operand a, operand b)
+{
+ return expr(ir_binop_interpolate_at_offset, a, b);
+}
+
+ir_expression *
+interpolate_at_sample(operand a, operand b)
+{
+ return expr(ir_binop_interpolate_at_sample, a, b);
+}
+
+ir_expression *
fma(operand a, operand b, operand c)
{
return expr(ir_triop_fma, a, b, c);
diff --git a/mesalib/src/glsl/ir_builder.h b/mesalib/src/glsl/ir_builder.h
index 108b53a5e..573596cf1 100644
--- a/mesalib/src/glsl/ir_builder.h
+++ b/mesalib/src/glsl/ir_builder.h
@@ -186,6 +186,10 @@ ir_expression *b2f(operand a);
ir_expression *min2(operand a, operand b);
ir_expression *max2(operand a, operand b);
+ir_expression *interpolate_at_centroid(operand a);
+ir_expression *interpolate_at_offset(operand a, operand b);
+ir_expression *interpolate_at_sample(operand a, operand b);
+
ir_expression *fma(operand a, operand b, operand c);
ir_expression *lrp(operand x, operand y, operand a);
ir_expression *csel(operand a, operand b, operand c);
diff --git a/mesalib/src/glsl/ir_constant_expression.cpp b/mesalib/src/glsl/ir_constant_expression.cpp
index fa59cc16a..13aa2b5bd 100755
--- a/mesalib/src/glsl/ir_constant_expression.cpp
+++ b/mesalib/src/glsl/ir_constant_expression.cpp
@@ -503,6 +503,8 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
case ir_binop_lshift:
case ir_binop_rshift:
case ir_binop_ldexp:
+ case ir_binop_interpolate_at_offset:
+ case ir_binop_interpolate_at_sample:
case ir_binop_vector_extract:
case ir_triop_csel:
case ir_triop_bitfield_extract:
diff --git a/mesalib/src/glsl/ir_hierarchical_visitor.cpp b/mesalib/src/glsl/ir_hierarchical_visitor.cpp
index d3c00ecdb..adb629414 100644
--- a/mesalib/src/glsl/ir_hierarchical_visitor.cpp
+++ b/mesalib/src/glsl/ir_hierarchical_visitor.cpp
@@ -27,16 +27,18 @@
ir_hierarchical_visitor::ir_hierarchical_visitor()
{
this->base_ir = NULL;
- this->callback = NULL;
- this->data = NULL;
+ this->callback_enter = NULL;
+ this->callback_leave = NULL;
+ this->data_enter = NULL;
+ this->data_leave = NULL;
this->in_assignee = false;
}
ir_visitor_status
ir_hierarchical_visitor::visit(ir_rvalue *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -44,8 +46,8 @@ ir_hierarchical_visitor::visit(ir_rvalue *ir)
ir_visitor_status
ir_hierarchical_visitor::visit(ir_variable *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -53,8 +55,8 @@ ir_hierarchical_visitor::visit(ir_variable *ir)
ir_visitor_status
ir_hierarchical_visitor::visit(ir_constant *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -62,8 +64,8 @@ ir_hierarchical_visitor::visit(ir_constant *ir)
ir_visitor_status
ir_hierarchical_visitor::visit(ir_loop_jump *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -71,8 +73,8 @@ ir_hierarchical_visitor::visit(ir_loop_jump *ir)
ir_visitor_status
ir_hierarchical_visitor::visit(ir_dereference_variable *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -80,8 +82,8 @@ ir_hierarchical_visitor::visit(ir_dereference_variable *ir)
ir_visitor_status
ir_hierarchical_visitor::visit_enter(ir_loop *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -89,15 +91,17 @@ ir_hierarchical_visitor::visit_enter(ir_loop *ir)
ir_visitor_status
ir_hierarchical_visitor::visit_leave(ir_loop *ir)
{
- (void) ir;
+ if (this->callback_leave != NULL)
+ this->callback_leave(ir, this->data_leave);
+
return visit_continue;
}
ir_visitor_status
ir_hierarchical_visitor::visit_enter(ir_function_signature *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -105,15 +109,17 @@ ir_hierarchical_visitor::visit_enter(ir_function_signature *ir)
ir_visitor_status
ir_hierarchical_visitor::visit_leave(ir_function_signature *ir)
{
- (void) ir;
+ if (this->callback_leave != NULL)
+ this->callback_leave(ir, this->data_leave);
+
return visit_continue;
}
ir_visitor_status
ir_hierarchical_visitor::visit_enter(ir_function *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -121,15 +127,17 @@ ir_hierarchical_visitor::visit_enter(ir_function *ir)
ir_visitor_status
ir_hierarchical_visitor::visit_leave(ir_function *ir)
{
- (void) ir;
+ if (this->callback_leave != NULL)
+ this->callback_leave(ir, this->data_leave);
+
return visit_continue;
}
ir_visitor_status
ir_hierarchical_visitor::visit_enter(ir_expression *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -137,15 +145,17 @@ ir_hierarchical_visitor::visit_enter(ir_expression *ir)
ir_visitor_status
ir_hierarchical_visitor::visit_leave(ir_expression *ir)
{
- (void) ir;
+ if (this->callback_leave != NULL)
+ this->callback_leave(ir, this->data_leave);
+
return visit_continue;
}
ir_visitor_status
ir_hierarchical_visitor::visit_enter(ir_texture *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -153,15 +163,17 @@ ir_hierarchical_visitor::visit_enter(ir_texture *ir)
ir_visitor_status
ir_hierarchical_visitor::visit_leave(ir_texture *ir)
{
- (void) ir;
+ if (this->callback_leave != NULL)
+ this->callback_leave(ir, this->data_leave);
+
return visit_continue;
}
ir_visitor_status
ir_hierarchical_visitor::visit_enter(ir_swizzle *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -169,15 +181,17 @@ ir_hierarchical_visitor::visit_enter(ir_swizzle *ir)
ir_visitor_status
ir_hierarchical_visitor::visit_leave(ir_swizzle *ir)
{
- (void) ir;
+ if (this->callback_leave != NULL)
+ this->callback_leave(ir, this->data_leave);
+
return visit_continue;
}
ir_visitor_status
ir_hierarchical_visitor::visit_enter(ir_dereference_array *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -185,15 +199,17 @@ ir_hierarchical_visitor::visit_enter(ir_dereference_array *ir)
ir_visitor_status
ir_hierarchical_visitor::visit_leave(ir_dereference_array *ir)
{
- (void) ir;
+ if (this->callback_leave != NULL)
+ this->callback_leave(ir, this->data_leave);
+
return visit_continue;
}
ir_visitor_status
ir_hierarchical_visitor::visit_enter(ir_dereference_record *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -201,15 +217,17 @@ ir_hierarchical_visitor::visit_enter(ir_dereference_record *ir)
ir_visitor_status
ir_hierarchical_visitor::visit_leave(ir_dereference_record *ir)
{
- (void) ir;
+ if (this->callback_leave != NULL)
+ this->callback_leave(ir, this->data_leave);
+
return visit_continue;
}
ir_visitor_status
ir_hierarchical_visitor::visit_enter(ir_assignment *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -217,15 +235,17 @@ ir_hierarchical_visitor::visit_enter(ir_assignment *ir)
ir_visitor_status
ir_hierarchical_visitor::visit_leave(ir_assignment *ir)
{
- (void) ir;
+ if (this->callback_leave != NULL)
+ this->callback_leave(ir, this->data_leave);
+
return visit_continue;
}
ir_visitor_status
ir_hierarchical_visitor::visit_enter(ir_call *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -233,15 +253,17 @@ ir_hierarchical_visitor::visit_enter(ir_call *ir)
ir_visitor_status
ir_hierarchical_visitor::visit_leave(ir_call *ir)
{
- (void) ir;
+ if (this->callback_leave != NULL)
+ this->callback_leave(ir, this->data_leave);
+
return visit_continue;
}
ir_visitor_status
ir_hierarchical_visitor::visit_enter(ir_return *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -249,15 +271,17 @@ ir_hierarchical_visitor::visit_enter(ir_return *ir)
ir_visitor_status
ir_hierarchical_visitor::visit_leave(ir_return *ir)
{
- (void) ir;
+ if (this->callback_leave != NULL)
+ this->callback_leave(ir, this->data_leave);
+
return visit_continue;
}
ir_visitor_status
ir_hierarchical_visitor::visit_enter(ir_discard *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -265,15 +289,17 @@ ir_hierarchical_visitor::visit_enter(ir_discard *ir)
ir_visitor_status
ir_hierarchical_visitor::visit_leave(ir_discard *ir)
{
- (void) ir;
+ if (this->callback_leave != NULL)
+ this->callback_leave(ir, this->data_leave);
+
return visit_continue;
}
ir_visitor_status
ir_hierarchical_visitor::visit_enter(ir_if *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -281,15 +307,17 @@ ir_hierarchical_visitor::visit_enter(ir_if *ir)
ir_visitor_status
ir_hierarchical_visitor::visit_leave(ir_if *ir)
{
- (void) ir;
+ if (this->callback_leave != NULL)
+ this->callback_leave(ir, this->data_leave);
+
return visit_continue;
}
ir_visitor_status
ir_hierarchical_visitor::visit_enter(ir_emit_vertex *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -297,15 +325,17 @@ ir_hierarchical_visitor::visit_enter(ir_emit_vertex *ir)
ir_visitor_status
ir_hierarchical_visitor::visit_leave(ir_emit_vertex *ir)
{
- (void) ir;
+ if (this->callback_leave != NULL)
+ this->callback_leave(ir, this->data_leave);
+
return visit_continue;
}
ir_visitor_status
ir_hierarchical_visitor::visit_enter(ir_end_primitive *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -313,7 +343,9 @@ ir_hierarchical_visitor::visit_enter(ir_end_primitive *ir)
ir_visitor_status
ir_hierarchical_visitor::visit_leave(ir_end_primitive *ir)
{
- (void) ir;
+ if (this->callback_leave != NULL)
+ this->callback_leave(ir, this->data_leave);
+
return visit_continue;
}
@@ -326,13 +358,17 @@ ir_hierarchical_visitor::run(exec_list *instructions)
void
visit_tree(ir_instruction *ir,
- void (*callback)(class ir_instruction *ir, void *data),
- void *data)
+ void (*callback_enter)(class ir_instruction *ir, void *data),
+ void *data_enter,
+ void (*callback_leave)(class ir_instruction *ir, void *data),
+ void *data_leave)
{
ir_hierarchical_visitor v;
- v.callback = callback;
- v.data = data;
+ v.callback_enter = callback_enter;
+ v.callback_leave = callback_leave;
+ v.data_enter = data_enter;
+ v.data_leave = data_leave;
ir->accept(&v);
}
diff --git a/mesalib/src/glsl/ir_hierarchical_visitor.h b/mesalib/src/glsl/ir_hierarchical_visitor.h
index bc89a04d8..faa52fd79 100644
--- a/mesalib/src/glsl/ir_hierarchical_visitor.h
+++ b/mesalib/src/glsl/ir_hierarchical_visitor.h
@@ -163,14 +163,29 @@ public:
* \warning
* Visitor classes derived from \c ir_hierarchical_visitor \b may \b not
* invoke this function. This can be used, for example, to cause the
- * callback to be invoked on every node type execpt one.
+ * callback to be invoked on every node type except one.
*/
- void (*callback)(class ir_instruction *ir, void *data);
+ void (*callback_enter)(class ir_instruction *ir, void *data);
/**
- * Extra data parameter passed to the per-node callback function
+ * Callback function that is invoked on exit of each node visited.
+ *
+ * \warning
+ * Visitor classes derived from \c ir_hierarchical_visitor \b may \b not
+ * invoke this function. This can be used, for example, to cause the
+ * callback to be invoked on every node type except one.
+ */
+ void (*callback_leave)(class ir_instruction *ir, void *data);
+
+ /**
+ * Extra data parameter passed to the per-node callback_enter function
+ */
+ void *data_enter;
+
+ /**
+ * Extra data parameter passed to the per-node callback_leave function
*/
- void *data;
+ void *data_leave;
/**
* Currently in the LHS of an assignment?
@@ -181,8 +196,10 @@ public:
};
void visit_tree(ir_instruction *ir,
- void (*callback)(class ir_instruction *ir, void *data),
- void *data);
+ void (*callback_enter)(class ir_instruction *ir, void *data),
+ void *data_enter,
+ void (*callback_leave)(class ir_instruction *ir, void *data) = NULL,
+ void *data_leave = NULL);
ir_visitor_status visit_list_elements(ir_hierarchical_visitor *v, exec_list *l,
bool statement_list = true);
diff --git a/mesalib/src/glsl/ir_reader.cpp b/mesalib/src/glsl/ir_reader.cpp
index 4017bdd73..e3566e1d6 100644
--- a/mesalib/src/glsl/ir_reader.cpp
+++ b/mesalib/src/glsl/ir_reader.cpp
@@ -723,10 +723,9 @@ ir_reader::read_expression(s_expression *expr)
ir_read_error(expr, "invalid operator: %s", s_op->value());
return NULL;
}
-
- int num_operands = -3; /* skip "expression" <type> <operation> */
- foreach_in_list(s_expression, e, &((s_list *) expr)->subexpressions)
- ++num_operands;
+
+ /* Skip "expression" <type> <operation> by subtracting 3. */
+ int num_operands = (int) ((s_list *) expr)->subexpressions.length() - 3;
int expected_operands = ir_expression::get_num_operands(op);
if (num_operands != expected_operands) {
diff --git a/mesalib/src/glsl/ir_validate.cpp b/mesalib/src/glsl/ir_validate.cpp
index 271dbe096..37e1ce33e 100644
--- a/mesalib/src/glsl/ir_validate.cpp
+++ b/mesalib/src/glsl/ir_validate.cpp
@@ -49,8 +49,8 @@ public:
this->current_function = NULL;
- this->callback = ir_validate::validate_ir;
- this->data = ht;
+ this->callback_enter = ir_validate::validate_ir;
+ this->data_enter = ht;
}
~ir_validate()
@@ -100,7 +100,7 @@ ir_validate::visit(ir_dereference_variable *ir)
abort();
}
- this->validate_ir(ir, this->data);
+ this->validate_ir(ir, this->data_enter);
return visit_continue;
}
@@ -167,7 +167,7 @@ ir_validate::visit_enter(ir_function *ir)
*/
this->current_function = ir;
- this->validate_ir(ir, this->data);
+ this->validate_ir(ir, this->data_enter);
/* Verify that all of the things stored in the list of signatures are,
* in fact, function signatures.
@@ -211,7 +211,7 @@ ir_validate::visit_enter(ir_function_signature *ir)
abort();
}
- this->validate_ir(ir, this->data);
+ this->validate_ir(ir, this->data_enter);
return visit_continue;
}
@@ -371,6 +371,11 @@ ir_validate::visit_leave(ir_expression *ir)
/* XXX what can we assert here? */
break;
+ case ir_unop_interpolate_at_centroid:
+ assert(ir->operands[0]->type == ir->type);
+ assert(ir->operands[0]->type->is_float());
+ break;
+
case ir_binop_add:
case ir_binop_sub:
case ir_binop_mul:
@@ -510,6 +515,19 @@ ir_validate::visit_leave(ir_expression *ir)
&& ir->operands[1]->type->is_integer());
break;
+ case ir_binop_interpolate_at_offset:
+ assert(ir->operands[0]->type == ir->type);
+ assert(ir->operands[0]->type->is_float());
+ assert(ir->operands[1]->type->components() == 2);
+ assert(ir->operands[1]->type->is_float());
+ break;
+
+ case ir_binop_interpolate_at_sample:
+ assert(ir->operands[0]->type == ir->type);
+ assert(ir->operands[0]->type->is_float());
+ assert(ir->operands[1]->type == glsl_type::int_type);
+ break;
+
case ir_triop_fma:
assert(ir->type->base_type == GLSL_TYPE_FLOAT);
assert(ir->type == ir->operands[0]->type);
@@ -708,7 +726,7 @@ ir_validate::visit_enter(ir_assignment *ir)
}
}
- this->validate_ir(ir, this->data);
+ this->validate_ir(ir, this->data_enter);
return visit_continue;
}
diff --git a/mesalib/src/glsl/list.h b/mesalib/src/glsl/list.h
index 9f08d45f7..500a85717 100644
--- a/mesalib/src/glsl/list.h
+++ b/mesalib/src/glsl/list.h
@@ -333,6 +333,8 @@ struct exec_list {
const exec_node *get_tail() const;
exec_node *get_tail();
+ unsigned length() const;
+
void push_head(exec_node *n);
void push_tail(exec_node *n);
void push_degenerate_list_at_head(exec_node *n);
@@ -353,9 +355,15 @@ struct exec_list {
void move_nodes_to(exec_list *target);
/**
- * Append all nodes from the source list to the target list
+ * Append all nodes from the source list to the end of the target list
*/
void append_list(exec_list *source);
+
+ /**
+ * Prepend all nodes from the source list to the beginning of the target
+ * list
+ */
+ void prepend_list(exec_list *source);
#endif
};
@@ -407,6 +415,19 @@ exec_list_get_tail(struct exec_list *list)
return !exec_list_is_empty(list) ? list->tail_pred : NULL;
}
+static inline unsigned
+exec_list_length(const struct exec_list *list)
+{
+ unsigned size = 0;
+ struct exec_node *node;
+
+ for (node = list->head; node->next != NULL; node = node->next) {
+ size++;
+ }
+
+ return size;
+}
+
static inline void
exec_list_push_head(struct exec_list *list, struct exec_node *n)
{
@@ -487,6 +508,13 @@ exec_list_append(struct exec_list *list, struct exec_list *source)
}
static inline void
+exec_list_prepend(struct exec_list *list, struct exec_list *source)
+{
+ exec_list_append(source, list);
+ exec_list_move_nodes_to(source, list);
+}
+
+static inline void
exec_node_insert_list_before(struct exec_node *n, struct exec_list *before)
{
if (exec_list_is_empty(before))
@@ -532,6 +560,11 @@ inline exec_node *exec_list::get_tail()
return exec_list_get_tail(this);
}
+inline unsigned exec_list::length() const
+{
+ return exec_list_length(this);
+}
+
inline void exec_list::push_head(exec_node *n)
{
exec_list_push_head(this, n);
@@ -562,6 +595,11 @@ inline void exec_list::append_list(exec_list *source)
exec_list_append(this, source);
}
+inline void exec_list::prepend_list(exec_list *source)
+{
+ exec_list_prepend(this, source);
+}
+
inline void exec_node::insert_before(exec_list *before)
{
exec_node_insert_list_before(this, before);
diff --git a/mesalib/src/glsl/opt_function_inlining.cpp b/mesalib/src/glsl/opt_function_inlining.cpp
index b84bb8e11..64b4907ba 100644
--- a/mesalib/src/glsl/opt_function_inlining.cpp
+++ b/mesalib/src/glsl/opt_function_inlining.cpp
@@ -100,16 +100,13 @@ ir_call::generate_inline(ir_instruction *next_ir)
{
void *ctx = ralloc_parent(this);
ir_variable **parameters;
- int num_parameters;
+ unsigned num_parameters;
int i;
struct hash_table *ht;
ht = hash_table_ctor(0, hash_table_pointer_hash, hash_table_pointer_compare);
- num_parameters = 0;
- foreach_in_list(ir_rvalue, param, &this->callee->parameters)
- num_parameters++;
-
+ num_parameters = this->callee->parameters.length();
parameters = new ir_variable *[num_parameters];
/* Generate the declarations for the parameters to our inlined code,
diff --git a/mesalib/src/glsl/opt_rebalance_tree.cpp b/mesalib/src/glsl/opt_rebalance_tree.cpp
index 773aab3f6..095f2d7d2 100644
--- a/mesalib/src/glsl/opt_rebalance_tree.cpp
+++ b/mesalib/src/glsl/opt_rebalance_tree.cpp
@@ -60,6 +60,7 @@
#include "ir_visitor.h"
#include "ir_rvalue_visitor.h"
#include "ir_optimization.h"
+#include "main/macros.h" /* for MAX2 */
/* The DSW algorithm generates a degenerate tree (really, a linked list) in
* tree_to_vine(). We'd rather not leave a binary expression with only one
@@ -216,7 +217,9 @@ is_reduction(ir_instruction *ir, void *data)
* constant fold once split up. Handling matrices will need some more
* work.
*/
- if (expr->type->is_matrix()) {
+ if (expr->type->is_matrix() ||
+ expr->operands[0]->type->is_matrix() ||
+ (expr->operands[1] && expr->operands[1]->type->is_matrix())) {
ird->is_reduction = false;
return;
}
@@ -261,6 +264,22 @@ handle_expression(ir_expression *expr)
return expr;
}
+static void
+update_types(ir_instruction *ir, void *)
+{
+ ir_expression *expr = ir->as_expression();
+ if (!expr)
+ return;
+
+ const glsl_type *const new_type =
+ glsl_type::get_instance(expr->type->base_type,
+ MAX2(expr->operands[0]->type->vector_elements,
+ expr->operands[1]->type->vector_elements),
+ 1);
+ assert(new_type != glsl_type::error_type);
+ expr->type = new_type;
+}
+
void
ir_rebalance_visitor::handle_rvalue(ir_rvalue **rvalue)
{
@@ -285,6 +304,8 @@ ir_rebalance_visitor::handle_rvalue(ir_rvalue **rvalue)
if (new_rvalue == *rvalue)
return;
+ visit_tree(new_rvalue, NULL, NULL, update_types);
+
*rvalue = new_rvalue;
this->progress = true;
}
diff --git a/mesalib/src/mapi/glapi/gen/gl_gentable.py b/mesalib/src/mapi/glapi/gen/gl_gentable.py
index bbf985d77..cac7bf9e6 100755
--- a/mesalib/src/mapi/glapi/gen/gl_gentable.py
+++ b/mesalib/src/mapi/glapi/gen/gl_gentable.py
@@ -134,7 +134,11 @@ body_template = """
if(!disp->%(name)s) {
void ** procp = (void **) &disp->%(name)s;
snprintf(symboln, sizeof(symboln), "%%s%(entry_point)s", symbol_prefix);
+#ifdef _WIN32
+ *procp = GetProcAddress(handle, symboln);
+#else
*procp = dlsym(handle, symboln);
+#endif
}
"""
diff --git a/mesalib/src/mesa/drivers/dri/Makefile.am b/mesalib/src/mesa/drivers/dri/Makefile.am
index 70039f9ad..2009da921 100644
--- a/mesalib/src/mesa/drivers/dri/Makefile.am
+++ b/mesalib/src/mesa/drivers/dri/Makefile.am
@@ -85,7 +85,6 @@ install-data-hook:
ln -f $(DESTDIR)$(dridir)/mesa_dri_drivers.so \
$(DESTDIR)$(dridir)/$$i; \
done;
- $(RM) -f $(DESTDIR)$(dridir)/mesa_dri_drivers.so
- $(RM) -f $(DESTDIR)$(dridir)/mesa_dri_drivers.la
+ $(RM) -f $(DESTDIR)$(dridir)/mesa_dri_drivers.*
endif
diff --git a/mesalib/src/mesa/drivers/dri/common/drirc b/mesalib/src/mesa/drivers/dri/common/drirc
index ebc04cd9b..4b9841bd2 100644
--- a/mesalib/src/mesa/drivers/dri/common/drirc
+++ b/mesalib/src/mesa/drivers/dri/common/drirc
@@ -11,17 +11,21 @@ Application bugs worked around in this file:
is still 1.10.
* Unigine Heaven 3.0 with ARB_texture_multisample uses a "ivec4 * vec4"
- expression, which fails to compile with GLSL 1.10.
+ expression, which is illegal in GLSL 1.10.
Adding "#version 130" fixes this.
* Unigine Heaven 3.0 with ARB_shader_bit_encoding uses the uint keyword, which
- fails to compile with GLSL 1.10.
+ is illegal in GLSL 1.10.
Adding "#version 130" fixes this.
* Unigine Heaven 3.0 with ARB_shader_bit_encoding uses a "uint & int"
- expression, which fails (and should fail) to compile with any GLSL version.
+ expression, which is illegal in any GLSL version.
Disabling ARB_shader_bit_encoding fixes this.
+* If ARB_sample_shading is supported, Unigine Heaven 4.0 and Valley 1.0 uses
+ an #extension directive in the middle of its shaders, which is illegal
+ in GLSL.
+
TODO: document the other workarounds.
-->
@@ -45,6 +49,7 @@ TODO: document the other workarounds.
<option name="disable_blend_func_extended" value="true" />
<option name="force_glsl_version" value="130" />
<option name="disable_shader_bit_encoding" value="true" />
+ <option name="allow_glsl_extension_directive_midshader" value="true" />
</application>
<application name="Unigine Heaven (64-bit)" executable="heaven_x64">
@@ -52,6 +57,15 @@ TODO: document the other workarounds.
<option name="disable_blend_func_extended" value="true" />
<option name="force_glsl_version" value="130" />
<option name="disable_shader_bit_encoding" value="true" />
+ <option name="allow_glsl_extension_directive_midshader" value="true" />
+ </application>
+
+ <application name="Unigine Valley (32-bit)" executable="valley_x86">
+ <option name="allow_glsl_extension_directive_midshader" value="true" />
+ </application>
+
+ <application name="Unigine Valley (64-bit)" executable="valley_x64">
+ <option name="allow_glsl_extension_directive_midshader" value="true" />
</application>
<application name="Unigine OilRush (32-bit)" executable="OilRush_x86">
diff --git a/mesalib/src/mesa/drivers/dri/common/xmlpool/t_options.h b/mesalib/src/mesa/drivers/dri/common/xmlpool/t_options.h
index fc9e10461..b73a6620c 100644
--- a/mesalib/src/mesa/drivers/dri/common/xmlpool/t_options.h
+++ b/mesalib/src/mesa/drivers/dri/common/xmlpool/t_options.h
@@ -105,6 +105,11 @@ DRI_CONF_OPT_BEGIN_V(force_glsl_version, int, def, "0:999") \
DRI_CONF_DESC(en,gettext("Force a default GLSL version for shaders that lack an explicit #version line")) \
DRI_CONF_OPT_END
+#define DRI_CONF_ALLOW_GLSL_EXTENSION_DIRECTIVE_MIDSHADER(def) \
+DRI_CONF_OPT_BEGIN_B(allow_glsl_extension_directive_midshader, def) \
+ DRI_CONF_DESC(en,gettext("Allow GLSL #extension directives in the middle of shaders")) \
+DRI_CONF_OPT_END
+
/**
diff --git a/mesalib/src/mesa/main/arrayobj.c b/mesalib/src/mesa/main/arrayobj.c
index efb993012..1ea319a74 100644
--- a/mesalib/src/mesa/main/arrayobj.c
+++ b/mesalib/src/mesa/main/arrayobj.c
@@ -427,6 +427,21 @@ bind_vertex_array(struct gl_context *ctx, GLuint id, GLboolean genRequired)
}
}
+ if (ctx->Array.DrawMethod == DRAW_ARRAYS) {
+ /* The _DrawArrays pointer is pointing at the VAO being unbound and
+ * that VAO may be in the process of being deleted. If it's not going
+ * to be deleted, this will have no effect, because the pointer needs
+ * to be updated by the VBO module anyway.
+ *
+ * Before the VBO module can update the pointer, we have to set it
+ * to NULL for drivers not to set up arrays which are not bound,
+ * or to prevent a crash if the VAO being unbound is going to be
+ * deleted.
+ */
+ ctx->Array._DrawArrays = NULL;
+ ctx->Array.DrawMethod = DRAW_NONE;
+ }
+
ctx->NewState |= _NEW_ARRAY;
_mesa_reference_vao(ctx, &ctx->Array.VAO, newObj);
diff --git a/mesalib/src/mesa/main/format_pack.c b/mesalib/src/mesa/main/format_pack.c
index 6b28592a6..c97c05297 100644
--- a/mesalib/src/mesa/main/format_pack.c
+++ b/mesalib/src/mesa/main/format_pack.c
@@ -888,7 +888,7 @@ pack_float_R_UNORM8(const GLfloat src[4], void *dst)
static void
pack_ubyte_R8G8_UNORM(const GLubyte src[4], void *dst)
{
- GLubyte *d = ((GLubyte *) dst);
+ GLushort *d = ((GLushort *) dst);
*d = PACK_COLOR_88(src[GCOMP], src[RCOMP]);
}
diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h
index a7126fd55..91d9172f9 100644
--- a/mesalib/src/mesa/main/mtypes.h
+++ b/mesalib/src/mesa/main/mtypes.h
@@ -1640,6 +1640,17 @@ struct gl_vertex_array_object
};
+/** Used to signal when transitioning from one kind of drawing method
+ * to another.
+ */
+typedef enum {
+ DRAW_NONE, /**< Initial value only */
+ DRAW_BEGIN_END,
+ DRAW_DISPLAY_LIST,
+ DRAW_ARRAYS
+} gl_draw_method;
+
+
/**
* Vertex array state
*/
@@ -1679,6 +1690,9 @@ struct gl_array_attrib
* The array pointer is set up only by the VBO module.
*/
const struct gl_client_array **_DrawArrays; /**< 0..VERT_ATTRIB_MAX-1 */
+
+ /** One of the DRAW_xxx flags, not consumed by drivers */
+ gl_draw_method DrawMethod;
};
@@ -3349,6 +3363,11 @@ struct gl_constants
GLuint ForceGLSLVersion;
/**
+ * Allow GLSL #extension directives in the middle of shaders.
+ */
+ GLboolean AllowGLSLExtensionDirectiveMidShader;
+
+ /**
* Does the driver support real 32-bit integers? (Otherwise, integers are
* simulated via floats.)
*/
diff --git a/mesalib/src/mesa/main/pack.c b/mesalib/src/mesa/main/pack.c
index 5ebaaf6e5..649a74cce 100644
--- a/mesalib/src/mesa/main/pack.c
+++ b/mesalib/src/mesa/main/pack.c
@@ -3183,10 +3183,10 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
PROCESS(aSrc, ACOMP, 1.0F, 255, GLubyte, UBYTE_TO_FLOAT);
break;
case GL_BYTE:
- PROCESS(rSrc, RCOMP, 0.0F, 0, GLbyte, BYTE_TO_FLOATZ);
- PROCESS(gSrc, GCOMP, 0.0F, 0, GLbyte, BYTE_TO_FLOATZ);
- PROCESS(bSrc, BCOMP, 0.0F, 0, GLbyte, BYTE_TO_FLOATZ);
- PROCESS(aSrc, ACOMP, 1.0F, 127, GLbyte, BYTE_TO_FLOATZ);
+ PROCESS(rSrc, RCOMP, 0.0F, 0, GLbyte, BYTE_TO_FLOAT_TEX);
+ PROCESS(gSrc, GCOMP, 0.0F, 0, GLbyte, BYTE_TO_FLOAT_TEX);
+ PROCESS(bSrc, BCOMP, 0.0F, 0, GLbyte, BYTE_TO_FLOAT_TEX);
+ PROCESS(aSrc, ACOMP, 1.0F, 127, GLbyte, BYTE_TO_FLOAT_TEX);
break;
case GL_UNSIGNED_SHORT:
PROCESS(rSrc, RCOMP, 0.0F, 0, GLushort, USHORT_TO_FLOAT);
@@ -3195,10 +3195,10 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
PROCESS(aSrc, ACOMP, 1.0F, 0xffff, GLushort, USHORT_TO_FLOAT);
break;
case GL_SHORT:
- PROCESS(rSrc, RCOMP, 0.0F, 0, GLshort, SHORT_TO_FLOATZ);
- PROCESS(gSrc, GCOMP, 0.0F, 0, GLshort, SHORT_TO_FLOATZ);
- PROCESS(bSrc, BCOMP, 0.0F, 0, GLshort, SHORT_TO_FLOATZ);
- PROCESS(aSrc, ACOMP, 1.0F, 32767, GLshort, SHORT_TO_FLOATZ);
+ PROCESS(rSrc, RCOMP, 0.0F, 0, GLshort, SHORT_TO_FLOAT_TEX);
+ PROCESS(gSrc, GCOMP, 0.0F, 0, GLshort, SHORT_TO_FLOAT_TEX);
+ PROCESS(bSrc, BCOMP, 0.0F, 0, GLshort, SHORT_TO_FLOAT_TEX);
+ PROCESS(aSrc, ACOMP, 1.0F, 32767, GLshort, SHORT_TO_FLOAT_TEX);
break;
case GL_UNSIGNED_INT:
PROCESS(rSrc, RCOMP, 0.0F, 0, GLuint, UINT_TO_FLOAT);
diff --git a/mesalib/src/mesa/main/texparam.c b/mesalib/src/mesa/main/texparam.c
index dc17ea584..30dd0b9b3 100644
--- a/mesalib/src/mesa/main/texparam.c
+++ b/mesalib/src/mesa/main/texparam.c
@@ -1051,6 +1051,7 @@ get_tex_level_parameter_image(struct gl_context *ctx,
GLenum pname, GLint *params)
{
const struct gl_texture_image *img = NULL;
+ struct gl_texture_image dummy_image;
mesa_format texFormat;
img = _mesa_select_tex_image(ctx, texObj, target, level);
@@ -1062,12 +1063,12 @@ get_tex_level_parameter_image(struct gl_context *ctx,
* instead of 1. TEXTURE_COMPONENTS is deprecated; always
* use TEXTURE_INTERNAL_FORMAT."
*/
+ memset(&dummy_image, 0, sizeof(dummy_image));
+ dummy_image.TexFormat = MESA_FORMAT_NONE;
+ dummy_image.InternalFormat = GL_RGBA;
+ dummy_image._BaseFormat = GL_NONE;
- if (pname == GL_TEXTURE_INTERNAL_FORMAT)
- *params = GL_RGBA;
- else
- *params = 0;
- return;
+ img = &dummy_image;
}
texFormat = img->TexFormat;
@@ -1107,6 +1108,8 @@ get_tex_level_parameter_image(struct gl_context *ctx,
}
break;
case GL_TEXTURE_BORDER:
+ if (ctx->API != API_OPENGL_COMPAT)
+ goto invalid_pname;
*params = img->Border;
break;
case GL_TEXTURE_RED_SIZE:
@@ -1120,6 +1123,8 @@ get_tex_level_parameter_image(struct gl_context *ctx,
break;
case GL_TEXTURE_INTENSITY_SIZE:
case GL_TEXTURE_LUMINANCE_SIZE:
+ if (ctx->API != API_OPENGL_COMPAT)
+ goto invalid_pname;
if (_mesa_base_format_has_channel(img->_BaseFormat, pname)) {
*params = _mesa_get_format_bits(texFormat, pname);
if (*params == 0) {
@@ -1166,12 +1171,15 @@ get_tex_level_parameter_image(struct gl_context *ctx,
break;
/* GL_ARB_texture_float */
+ case GL_TEXTURE_LUMINANCE_TYPE_ARB:
+ case GL_TEXTURE_INTENSITY_TYPE_ARB:
+ if (ctx->API != API_OPENGL_COMPAT)
+ goto invalid_pname;
+ /* FALLTHROUGH */
case GL_TEXTURE_RED_TYPE_ARB:
case GL_TEXTURE_GREEN_TYPE_ARB:
case GL_TEXTURE_BLUE_TYPE_ARB:
case GL_TEXTURE_ALPHA_TYPE_ARB:
- case GL_TEXTURE_LUMINANCE_TYPE_ARB:
- case GL_TEXTURE_INTENSITY_TYPE_ARB:
case GL_TEXTURE_DEPTH_TYPE_ARB:
if (!ctx->Extensions.ARB_texture_float)
goto invalid_pname;
diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp
index 1109051e9..2a82e9d9d 100644
--- a/mesalib/src/mesa/program/ir_to_mesa.cpp
+++ b/mesalib/src/mesa/program/ir_to_mesa.cpp
@@ -1456,6 +1456,9 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
case ir_binop_carry:
case ir_binop_borrow:
case ir_binop_imul_high:
+ case ir_unop_interpolate_at_centroid:
+ case ir_binop_interpolate_at_offset:
+ case ir_binop_interpolate_at_sample:
assert(!"not supported");
break;
@@ -2814,10 +2817,7 @@ get_mesa_program(struct gl_context *ctx,
prog->NumTemporaries = v.next_temp;
- int num_instructions = 0;
- foreach_in_list(ir_instruction, node, &v.instructions) {
- num_instructions++;
- }
+ unsigned num_instructions = v.instructions.length();
mesa_instructions =
(struct prog_instruction *)calloc(num_instructions,
diff --git a/mesalib/src/mesa/state_tracker/st_extensions.c b/mesalib/src/mesa/state_tracker/st_extensions.c
index 4207cb64a..aa59fbfa9 100644
--- a/mesalib/src/mesa/state_tracker/st_extensions.c
+++ b/mesalib/src/mesa/state_tracker/st_extensions.c
@@ -772,6 +772,9 @@ void st_init_extensions(struct st_context *st)
if (st->options.disable_glsl_line_continuations)
ctx->Const.DisableGLSLLineContinuations = 1;
+ if (st->options.allow_glsl_extension_directive_midshader)
+ ctx->Const.AllowGLSLExtensionDirectiveMidShader = GL_TRUE;
+
ctx->Const.MinMapBufferAlignment =
screen->get_param(screen, PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT);
diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index f47cd7d53..5c51e63d9 100644
--- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -2049,6 +2049,9 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
case ir_binop_ldexp:
case ir_binop_carry:
case ir_binop_borrow:
+ case ir_unop_interpolate_at_centroid:
+ case ir_binop_interpolate_at_offset:
+ case ir_binop_interpolate_at_sample:
/* This operation is not supported, or should have already been handled.
*/
assert(!"Invalid ir opcode in glsl_to_tgsi_visitor::visit()");
@@ -2820,7 +2823,13 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
}
break;
case ir_txb:
- opcode = is_cube_array ? TGSI_OPCODE_TXB2 : TGSI_OPCODE_TXB;
+ if (is_cube_array ||
+ sampler_type == glsl_type::samplerCubeShadow_type) {
+ opcode = TGSI_OPCODE_TXB2;
+ }
+ else {
+ opcode = TGSI_OPCODE_TXB;
+ }
ir->lod_info.bias->accept(this);
lod_info = this->result;
if (ir->offset) {
diff --git a/mesalib/src/mesa/vbo/vbo_context.h b/mesalib/src/mesa/vbo/vbo_context.h
index 1680e23dc..e22451305 100644
--- a/mesalib/src/mesa/vbo/vbo_context.h
+++ b/mesalib/src/mesa/vbo/vbo_context.h
@@ -57,18 +57,6 @@
#include "vbo_save.h"
-/** Used to signal when transitioning from one kind of drawing method
- * to another.
- */
-enum draw_method
-{
- DRAW_NONE, /**< Initial value only */
- DRAW_BEGIN_END,
- DRAW_DISPLAY_LIST,
- DRAW_ARRAYS
-};
-
-
struct vbo_context {
struct gl_client_array currval[VBO_ATTRIB_MAX];
@@ -83,8 +71,6 @@ struct vbo_context {
* is responsible for initiating any fallback actions required:
*/
vbo_draw_func draw_prims;
-
- enum draw_method last_draw_method;
};
@@ -122,11 +108,11 @@ get_program_mode( struct gl_context *ctx )
* that arrays may be changing.
*/
static inline void
-vbo_draw_method(struct vbo_context *vbo, enum draw_method method)
+vbo_draw_method(struct vbo_context *vbo, gl_draw_method method)
{
- if (vbo->last_draw_method != method) {
- struct gl_context *ctx = vbo->exec.ctx;
+ struct gl_context *ctx = vbo->exec.ctx;
+ if (ctx->Array.DrawMethod != method) {
switch (method) {
case DRAW_ARRAYS:
ctx->Array._DrawArrays = vbo->exec.array.inputs;
@@ -142,7 +128,7 @@ vbo_draw_method(struct vbo_context *vbo, enum draw_method method)
}
ctx->NewDriverState |= ctx->DriverFlags.NewArray;
- vbo->last_draw_method = method;
+ ctx->Array.DrawMethod = method;
}
}
diff --git a/mesalib/src/mesa/vbo/vbo_exec.c b/mesalib/src/mesa/vbo/vbo_exec.c
index bd2b1b1a9..eb9035043 100644
--- a/mesalib/src/mesa/vbo/vbo_exec.c
+++ b/mesalib/src/mesa/vbo/vbo_exec.c
@@ -82,21 +82,6 @@ void vbo_exec_invalidate_state( struct gl_context *ctx, GLuint new_state )
if (!exec->validating && new_state & (_NEW_PROGRAM|_NEW_ARRAY)) {
exec->array.recalculate_inputs = GL_TRUE;
-
- /* If we ended up here because a VAO was deleted, the _DrawArrays
- * pointer which pointed to the VAO might be invalid now, so set it
- * to NULL. This prevents crashes in driver functions like Clear
- * where driver state validation might occur, but the vbo module is
- * still in an invalid state.
- *
- * Drivers should skip vertex array state validation if _DrawArrays
- * is NULL. It also has no effect on performance, because attrib
- * bindings will be recalculated anyway.
- */
- if (vbo->last_draw_method == DRAW_ARRAYS) {
- ctx->Array._DrawArrays = NULL;
- vbo->last_draw_method = DRAW_NONE;
- }
}
if (new_state & _NEW_EVAL)