diff options
Diffstat (limited to 'mesalib/src')
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) |