diff options
Diffstat (limited to 'mesalib/src/glsl')
23 files changed, 224 insertions, 86 deletions
diff --git a/mesalib/src/glsl/builtin_types.h b/mesalib/src/glsl/builtin_types.h index c78c2d270..acd2d76d5 100644 --- a/mesalib/src/glsl/builtin_types.h +++ b/mesalib/src/glsl/builtin_types.h @@ -347,3 +347,22 @@ const glsl_type glsl_type::builtin_ARB_texture_cube_map_array_types[] = { GLSL_SAMPLER_DIM_CUBE, 0, 1, GLSL_TYPE_UINT, "usamplerCubeArray"), }; /*@}*/ + +/** \name Sampler types added by GL_ARB_texture_multisample + */ +/*@{*/ +const glsl_type glsl_type::builtin_ARB_texture_multisample_types[] = { + glsl_type(GL_SAMPLER_2D_MULTISAMPLE, + GLSL_SAMPLER_DIM_MS, 0, 0, GLSL_TYPE_FLOAT, "sampler2DMS"), + glsl_type(GL_INT_SAMPLER_2D_MULTISAMPLE, + GLSL_SAMPLER_DIM_MS, 0, 0, GLSL_TYPE_INT, "isampler2DMS"), + glsl_type(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE, + GLSL_SAMPLER_DIM_MS, 0, 0, GLSL_TYPE_UINT, "usampler2DMS"), + glsl_type(GL_SAMPLER_2D_MULTISAMPLE_ARRAY, + GLSL_SAMPLER_DIM_MS, 0, 1, GLSL_TYPE_FLOAT, "sampler2DMSArray"), + glsl_type(GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, + GLSL_SAMPLER_DIM_MS, 0, 1, GLSL_TYPE_INT, "isampler2DMSArray"), + glsl_type(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, + GLSL_SAMPLER_DIM_MS, 0, 1, GLSL_TYPE_UINT, "usampler2DMSArray"), +}; +/*@}*/ diff --git a/mesalib/src/glsl/builtin_variables.cpp b/mesalib/src/glsl/builtin_variables.cpp index ccee7746e..53c4c51cd 100644 --- a/mesalib/src/glsl/builtin_variables.cpp +++ b/mesalib/src/glsl/builtin_variables.cpp @@ -849,6 +849,7 @@ initialize_vs_variables(exec_list *instructions, generate_130_vs_variables(instructions, state, true); break; case 140: + case 150: generate_130_vs_variables(instructions, state, false); break; default: @@ -1140,6 +1141,7 @@ initialize_fs_variables(exec_list *instructions, generate_130_fs_variables(instructions, state); break; case 140: + case 150: generate_140_fs_variables(instructions, state); break; default: diff --git a/mesalib/src/glsl/glcpp/glcpp-parse.y b/mesalib/src/glsl/glcpp/glcpp-parse.y index e927c7cb7..d6afe8814 100644 --- a/mesalib/src/glsl/glcpp/glcpp-parse.y +++ b/mesalib/src/glsl/glcpp/glcpp-parse.y @@ -1230,6 +1230,9 @@ glcpp_parser_create (const struct gl_extensions *extensions, int api) if (extensions->ARB_shading_language_packing) add_builtin_define(parser, "GL_ARB_shading_language_packing", 1); + + if (extensions->ARB_texture_multisample) + add_builtin_define(parser, "GL_ARB_texture_multisample", 1); } } diff --git a/mesalib/src/glsl/glsl_lexer.ll b/mesalib/src/glsl/glsl_lexer.ll index ddc9f8073..008ef303d 100644 --- a/mesalib/src/glsl/glsl_lexer.ll +++ b/mesalib/src/glsl/glsl_lexer.ll @@ -315,6 +315,15 @@ usamplerCube KEYWORD(130, 300, 130, 300, USAMPLERCUBE); usampler1DArray KEYWORD(130, 300, 130, 0, USAMPLER1DARRAY); usampler2DArray KEYWORD(130, 300, 130, 300, USAMPLER2DARRAY); + /* additional keywords in ARB_texture_multisample, included in GLSL 1.50 */ + /* these are reserved but not defined in GLSL 3.00 */ +sampler2DMS KEYWORD_WITH_ALT(150, 300, 150, 0, yyextra->ARB_texture_multisample_enable, SAMPLER2DMS); +isampler2DMS KEYWORD_WITH_ALT(150, 300, 150, 0, yyextra->ARB_texture_multisample_enable, ISAMPLER2DMS); +usampler2DMS KEYWORD_WITH_ALT(150, 300, 150, 0, yyextra->ARB_texture_multisample_enable, USAMPLER2DMS); +sampler2DMSArray KEYWORD_WITH_ALT(150, 300, 150, 0, yyextra->ARB_texture_multisample_enable, SAMPLER2DMSARRAY); +isampler2DMSArray KEYWORD_WITH_ALT(150, 300, 150, 0, yyextra->ARB_texture_multisample_enable, ISAMPLER2DMSARRAY); +usampler2DMSArray KEYWORD_WITH_ALT(150, 300, 150, 0, yyextra->ARB_texture_multisample_enable, USAMPLER2DMSARRAY); + samplerCubeArray { if (yyextra->ARB_texture_cube_map_array_enable) return SAMPLERCUBEARRAY; @@ -531,12 +540,6 @@ atomic_uint KEYWORD(0, 300, 0, 0, ATOMIC_UINT); patch KEYWORD(0, 300, 0, 0, PATCH); sample KEYWORD(0, 300, 0, 0, SAMPLE); subroutine KEYWORD(0, 300, 0, 0, SUBROUTINE); -sampler2DMS KEYWORD(0, 300, 0, 0, SAMPLER2DMS); -isampler2DMS KEYWORD(0, 300, 0, 0, ISAMPLER2DMS); -usampler2DMS KEYWORD(0, 300, 0, 0, USAMPLER2DMS); -sampler2DMSArray KEYWORD(0, 300, 0, 0, SAMPLER2DMSARRAY); -isampler2DMSArray KEYWORD(0, 300, 0, 0, ISAMPLER2DMSARRAY); -usampler2DMSArray KEYWORD(0, 300, 0, 0, USAMPLER2DMSARRAY); [_a-zA-Z][_a-zA-Z0-9]* { diff --git a/mesalib/src/glsl/glsl_parser.yy b/mesalib/src/glsl/glsl_parser.yy index 154ce2d09..f52ed9b0a 100644 --- a/mesalib/src/glsl/glsl_parser.yy +++ b/mesalib/src/glsl/glsl_parser.yy @@ -109,6 +109,8 @@ static void yyerror(YYLTYPE *loc, _mesa_glsl_parse_state *st, const char *msg) %token USAMPLER2DARRAY USAMPLERCUBEARRAY %token SAMPLER2DRECT ISAMPLER2DRECT USAMPLER2DRECT SAMPLER2DRECTSHADOW %token SAMPLERBUFFER ISAMPLERBUFFER USAMPLERBUFFER +%token SAMPLER2DMS ISAMPLER2DMS USAMPLER2DMS +%token SAMPLER2DMSARRAY ISAMPLER2DMSARRAY USAMPLER2DMSARRAY %token SAMPLEREXTERNALOES %token STRUCT VOID_TOK WHILE %token <identifier> IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER @@ -140,8 +142,7 @@ static void yyerror(YYLTYPE *loc, _mesa_glsl_parse_state *st, const char *msg) %token SAMPLER3DRECT %token SIZEOF CAST NAMESPACE USING %token COHERENT RESTRICT READONLY WRITEONLY RESOURCE ATOMIC_UINT PATCH SAMPLE -%token SUBROUTINE SAMPLER2DMS ISAMPLER2DMS USAMPLER2DMS SAMPLER2DMSARRAY -%token ISAMPLER2DMSARRAY USAMPLER2DMSARRAY +%token SUBROUTINE %token ERROR_TOK @@ -1462,6 +1463,12 @@ basic_type_specifier_nonarray: | USAMPLER2DARRAY { $$ = "usampler2DArray"; } | USAMPLERBUFFER { $$ = "usamplerBuffer"; } | USAMPLERCUBEARRAY { $$ = "usamplerCubeArray"; } + | SAMPLER2DMS { $$ = "sampler2DMS"; } + | ISAMPLER2DMS { $$ = "isampler2DMS"; } + | USAMPLER2DMS { $$ = "usampler2DMS"; } + | SAMPLER2DMSARRAY { $$ = "sampler2DMSArray"; } + | ISAMPLER2DMSARRAY { $$ = "isampler2DMSArray"; } + | USAMPLER2DMSARRAY { $$ = "usampler2DMSArray"; } ; precision_qualifier: diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp index df1714850..9d7de3381 100644 --- a/mesalib/src/glsl/glsl_parser_extras.cpp +++ b/mesalib/src/glsl/glsl_parser_extras.cpp @@ -467,6 +467,7 @@ static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = { EXT(OES_standard_derivatives, false, false, true, false, true, OES_standard_derivatives), EXT(ARB_texture_cube_map_array, true, false, true, true, false, ARB_texture_cube_map_array), EXT(ARB_shading_language_packing, true, false, true, true, false, ARB_shading_language_packing), + EXT(ARB_texture_multisample, true, false, true, true, false, ARB_texture_multisample), }; #undef EXT diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h index 3ebc27e1a..1765cdf16 100644 --- a/mesalib/src/glsl/glsl_parser_extras.h +++ b/mesalib/src/glsl/glsl_parser_extras.h @@ -280,6 +280,8 @@ struct _mesa_glsl_parse_state { bool ARB_texture_cube_map_array_warn; bool ARB_shading_language_packing_enable; bool ARB_shading_language_packing_warn; + bool ARB_texture_multisample_enable; + bool ARB_texture_multisample_warn; /*@}*/ /** Extensions supported by the OpenGL implementation. */ diff --git a/mesalib/src/glsl/glsl_types.cpp b/mesalib/src/glsl/glsl_types.cpp index 82aeb84ed..a783dcc3b 100644 --- a/mesalib/src/glsl/glsl_types.cpp +++ b/mesalib/src/glsl/glsl_types.cpp @@ -198,6 +198,8 @@ glsl_type::sampler_index() const return TEXTURE_BUFFER_INDEX; case GLSL_SAMPLER_DIM_EXTERNAL: return TEXTURE_EXTERNAL_INDEX; + case GLSL_SAMPLER_DIM_MS: + return (t->sampler_array) ? TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX : TEXTURE_2D_MULTISAMPLE_INDEX; default: assert(!"Should not get here."); return TEXTURE_BUFFER_INDEX; @@ -345,6 +347,16 @@ glsl_type::generate_ARB_texture_cube_map_array_types(glsl_symbol_table *symtab, } void +glsl_type::generate_ARB_texture_multisample_types(glsl_symbol_table *symtab, + bool warn) +{ + bool skip_1d = false; + add_types_to_symbol_table(symtab, builtin_ARB_texture_multisample_types, + Elements(builtin_ARB_texture_multisample_types), + warn, skip_1d); +} + +void _mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state) { if (state->es_shader) { @@ -373,6 +385,7 @@ _mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state) glsl_type::generate_130_types(state->symbols, true, skip_1d); break; case 140: + case 150: glsl_type::generate_140_types(state->symbols); break; default: @@ -412,6 +425,11 @@ _mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state) glsl_type::generate_ARB_texture_cube_map_array_types(state->symbols, state->ARB_texture_cube_map_array_warn); } + + if (state->ARB_texture_multisample_enable) { + glsl_type::generate_ARB_texture_multisample_types(state->symbols, + state->ARB_texture_multisample_warn); + } } diff --git a/mesalib/src/glsl/glsl_types.h b/mesalib/src/glsl/glsl_types.h index 8cfd8dd02..79304269d 100644 --- a/mesalib/src/glsl/glsl_types.h +++ b/mesalib/src/glsl/glsl_types.h @@ -67,7 +67,8 @@ enum glsl_sampler_dim { GLSL_SAMPLER_DIM_CUBE, GLSL_SAMPLER_DIM_RECT, GLSL_SAMPLER_DIM_BUF, - GLSL_SAMPLER_DIM_EXTERNAL + GLSL_SAMPLER_DIM_EXTERNAL, + GLSL_SAMPLER_DIM_MS }; enum glsl_interface_packing { @@ -561,6 +562,7 @@ private: static const glsl_type builtin_EXT_texture_buffer_object_types[]; static const glsl_type builtin_OES_EGL_image_external_types[]; static const glsl_type builtin_ARB_texture_cube_map_array_types[]; + static const glsl_type builtin_ARB_texture_multisample_types[]; /*@}*/ /** @@ -586,6 +588,7 @@ private: static void generate_OES_texture_3D_types(glsl_symbol_table *, bool); static void generate_OES_EGL_image_external_types(glsl_symbol_table *, bool); static void generate_ARB_texture_cube_map_array_types(glsl_symbol_table *, bool); + static void generate_ARB_texture_multisample_types(glsl_symbol_table *, bool); /*@}*/ /** diff --git a/mesalib/src/glsl/ir.cpp b/mesalib/src/glsl/ir.cpp index 954995db3..2eb3af695 100644 --- a/mesalib/src/glsl/ir.cpp +++ b/mesalib/src/glsl/ir.cpp @@ -195,34 +195,6 @@ ir_assignment::ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, this->set_lhs(lhs); } - -ir_expression::ir_expression(int op, const struct glsl_type *type, - ir_rvalue *op0) -{ - assert(get_num_operands(ir_expression_operation(op)) == 1); - this->ir_type = ir_type_expression; - this->type = type; - this->operation = ir_expression_operation(op); - this->operands[0] = op0; - this->operands[1] = NULL; - this->operands[2] = NULL; - this->operands[3] = NULL; -} - -ir_expression::ir_expression(int op, const struct glsl_type *type, - ir_rvalue *op0, ir_rvalue *op1) -{ - assert(((op1 == NULL) && (get_num_operands(ir_expression_operation(op)) == 1)) - || (get_num_operands(ir_expression_operation(op)) == 2)); - this->ir_type = ir_type_expression; - this->type = type; - this->operation = ir_expression_operation(op); - this->operands[0] = op0; - this->operands[1] = op1; - this->operands[2] = NULL; - this->operands[3] = NULL; -} - ir_expression::ir_expression(int op, const struct glsl_type *type, ir_rvalue *op0, ir_rvalue *op1, ir_rvalue *op2, ir_rvalue *op3) @@ -234,6 +206,12 @@ ir_expression::ir_expression(int op, const struct glsl_type *type, this->operands[1] = op1; this->operands[2] = op2; this->operands[3] = op3; +#ifndef NDEBUG + int num_operands = get_num_operands(this->operation); + for (int i = num_operands; i < 4; i++) { + assert(this->operands[i] == NULL); + } +#endif } ir_expression::ir_expression(int op, ir_rvalue *op0) @@ -438,6 +416,9 @@ ir_expression::get_num_operands(ir_expression_operation op) if (op <= ir_last_binop) return 2; + if (op <= ir_last_triop) + return 3; + if (op == ir_quadop_vector) return 4; @@ -524,6 +505,7 @@ static const char *const operator_strs[] = { "pow", "packHalf2x16_split", "ubo_load", + "lrp", "vector", }; @@ -1325,7 +1307,7 @@ ir_dereference::is_lvalue() const } -static const char *tex_opcode_strs[] = { "tex", "txb", "txl", "txd", "txf", "txs" }; +static const char *tex_opcode_strs[] = { "tex", "txb", "txl", "txd", "txf", "txf_ms", "txs" }; const char *ir_texture::opcode_string() { diff --git a/mesalib/src/glsl/ir.h b/mesalib/src/glsl/ir.h index 1e09988e5..393b48673 100644 --- a/mesalib/src/glsl/ir.h +++ b/mesalib/src/glsl/ir.h @@ -1118,6 +1118,13 @@ enum ir_expression_operation { */ ir_last_binop = ir_binop_ubo_load, + ir_triop_lrp, + + /** + * A sentinel marking the last of the ternary operations. + */ + ir_last_triop = ir_triop_lrp, + ir_quadop_vector, /** @@ -1128,25 +1135,20 @@ enum ir_expression_operation { class ir_expression : public ir_rvalue { public: + ir_expression(int op, const struct glsl_type *type, + ir_rvalue *op0, ir_rvalue *op1 = NULL, + ir_rvalue *op2 = NULL, ir_rvalue *op3 = NULL); + /** * Constructor for unary operation expressions */ - ir_expression(int op, const struct glsl_type *type, ir_rvalue *); ir_expression(int op, ir_rvalue *); /** * Constructor for binary operation expressions */ - ir_expression(int op, const struct glsl_type *type, - ir_rvalue *, ir_rvalue *); ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1); - /** - * Constructor for quad operator expressions - */ - ir_expression(int op, const struct glsl_type *type, - ir_rvalue *, ir_rvalue *, ir_rvalue *, ir_rvalue *); - virtual ir_expression *as_expression() { return this; @@ -1422,6 +1424,7 @@ enum ir_texture_opcode { ir_txl, /**< Texture look-up with explicit LOD */ ir_txd, /**< Texture look-up with partial derivatvies */ ir_txf, /**< Texel fetch with explicit LOD */ + ir_txf_ms, /**< Multisample texture fetch */ ir_txs /**< Texture size */ }; @@ -1443,6 +1446,8 @@ enum ir_texture_opcode { * (txl <type> <sampler> <coordinate> 0 1 ( ) <lod>) * (txd <type> <sampler> <coordinate> 0 1 ( ) (dPdx dPdy)) * (txf <type> <sampler> <coordinate> 0 <lod>) + * (txf_ms + * <type> <sampler> <coordinate> <sample_index>) * (txs <type> <sampler> <lod>) */ class ir_texture : public ir_rvalue { @@ -1509,6 +1514,7 @@ public: union { ir_rvalue *lod; /**< Floating point LOD */ ir_rvalue *bias; /**< Floating point LOD bias */ + ir_rvalue *sample_index; /**< MSAA sample index */ struct { ir_rvalue *dPdx; /**< Partial derivative of coordinate wrt X */ ir_rvalue *dPdy; /**< Partial derivative of coordinate wrt Y */ diff --git a/mesalib/src/glsl/ir_clone.cpp b/mesalib/src/glsl/ir_clone.cpp index b94ff05df..4797451d7 100644 --- a/mesalib/src/glsl/ir_clone.cpp +++ b/mesalib/src/glsl/ir_clone.cpp @@ -252,6 +252,9 @@ ir_texture::clone(void *mem_ctx, struct hash_table *ht) const case ir_txs: new_tex->lod_info.lod = this->lod_info.lod->clone(mem_ctx, ht); break; + case ir_txf_ms: + new_tex->lod_info.sample_index = this->lod_info.sample_index->clone(mem_ctx, ht); + break; case ir_txd: new_tex->lod_info.grad.dPdx = this->lod_info.grad.dPdx->clone(mem_ctx, ht); new_tex->lod_info.grad.dPdy = this->lod_info.grad.dPdy->clone(mem_ctx, ht); diff --git a/mesalib/src/glsl/ir_constant_expression.cpp b/mesalib/src/glsl/ir_constant_expression.cpp index 86b863f31..c2d0dc46c 100644 --- a/mesalib/src/glsl/ir_constant_expression.cpp +++ b/mesalib/src/glsl/ir_constant_expression.cpp @@ -1248,6 +1248,19 @@ ir_expression::constant_expression_value(struct hash_table *variable_context) } break; + case ir_triop_lrp: { + assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); + assert(op[1]->type->base_type == GLSL_TYPE_FLOAT); + assert(op[2]->type->base_type == GLSL_TYPE_FLOAT); + + unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1; + for (unsigned c = 0, c2 = 0; c < components; c2 += c2_inc, c++) { + data.f[c] = op[0]->value.f[c] * (1.0f - op[2]->value.f[c2]) + + (op[1]->value.f[c] * op[2]->value.f[c2]); + } + break; + } + case ir_quadop_vector: for (unsigned c = 0; c < this->type->vector_elements; c++) { switch (this->type->base_type) { diff --git a/mesalib/src/glsl/ir_hv_accept.cpp b/mesalib/src/glsl/ir_hv_accept.cpp index 3ce895924..5fa75011e 100644 --- a/mesalib/src/glsl/ir_hv_accept.cpp +++ b/mesalib/src/glsl/ir_hv_accept.cpp @@ -226,6 +226,11 @@ ir_texture::accept(ir_hierarchical_visitor *v) if (s != visit_continue) return (s == visit_continue_with_parent) ? visit_continue : s; break; + case ir_txf_ms: + s = this->lod_info.sample_index->accept(v); + if (s != visit_continue) + return (s == visit_continue_with_parent) ? visit_continue : s; + break; case ir_txd: s = this->lod_info.grad.dPdx->accept(v); if (s != visit_continue) diff --git a/mesalib/src/glsl/ir_optimization.h b/mesalib/src/glsl/ir_optimization.h index 8f3301840..2454bbe6f 100644 --- a/mesalib/src/glsl/ir_optimization.h +++ b/mesalib/src/glsl/ir_optimization.h @@ -36,6 +36,7 @@ #define LOG_TO_LOG2 0x10 #define MOD_TO_FRACT 0x20 #define INT_DIV_TO_MUL_RCP 0x40 +#define LRP_TO_ARITH 0x80 /** * \see class lower_packing_builtins_visitor diff --git a/mesalib/src/glsl/ir_print_visitor.cpp b/mesalib/src/glsl/ir_print_visitor.cpp index acc92dbf1..3bdea9bbc 100644 --- a/mesalib/src/glsl/ir_print_visitor.cpp +++ b/mesalib/src/glsl/ir_print_visitor.cpp @@ -260,7 +260,7 @@ void ir_print_visitor::visit(ir_texture *ir) printf(" "); } - if (ir->op != ir_txf && ir->op != ir_txs) { + if (ir->op != ir_txf && ir->op != ir_txf_ms && ir->op != ir_txs) { if (ir->projector) ir->projector->accept(this); else @@ -287,6 +287,9 @@ void ir_print_visitor::visit(ir_texture *ir) case ir_txs: ir->lod_info.lod->accept(this); break; + case ir_txf_ms: + ir->lod_info.sample_index->accept(this); + break; case ir_txd: printf("("); ir->lod_info.grad.dPdx->accept(this); diff --git a/mesalib/src/glsl/ir_reader.cpp b/mesalib/src/glsl/ir_reader.cpp index 405e75b64..22ce03b0d 100644 --- a/mesalib/src/glsl/ir_reader.cpp +++ b/mesalib/src/glsl/ir_reader.cpp @@ -676,15 +676,16 @@ ir_reader::read_expression(s_expression *expr) { s_expression *s_type; s_symbol *s_op; - s_expression *s_arg1; + s_expression *s_arg[3]; - s_pattern pat[] = { "expression", s_type, s_op, s_arg1 }; + s_pattern pat[] = { "expression", s_type, s_op, s_arg[0] }; if (!PARTIAL_MATCH(expr, pat)) { ir_read_error(expr, "expected (expression <type> <operator> " "<operand> [<operand>])"); return NULL; } - s_expression *s_arg2 = (s_expression *) s_arg1->next; // may be tail sentinel + s_arg[1] = (s_expression *) s_arg[0]->next; // may be tail sentinel + s_arg[2] = (s_expression *) s_arg[1]->next; // may be tail sentinel or NULL const glsl_type *type = read_type(s_type); if (type == NULL) @@ -697,35 +698,27 @@ ir_reader::read_expression(s_expression *expr) return NULL; } - unsigned num_operands = ir_expression::get_num_operands(op); - if (num_operands == 1 && !s_arg1->next->is_tail_sentinel()) { - ir_read_error(expr, "expected (expression <type> %s <operand>)", - s_op->value()); + int num_operands = -3; /* skip "expression" <type> <operation> */ + foreach_list(n, &((s_list *) expr)->subexpressions) + ++num_operands; + + int expected_operands = ir_expression::get_num_operands(op); + if (num_operands != expected_operands) { + ir_read_error(expr, "found %d expression operands, expected %d", + num_operands, expected_operands); return NULL; } - ir_rvalue *arg1 = read_rvalue(s_arg1); - ir_rvalue *arg2 = NULL; - if (arg1 == NULL) { - ir_read_error(NULL, "when reading first operand of %s", s_op->value()); - return NULL; - } - - if (num_operands == 2) { - if (s_arg2->is_tail_sentinel() || !s_arg2->next->is_tail_sentinel()) { - ir_read_error(expr, "expected (expression <type> %s <operand> " - "<operand>)", s_op->value()); - return NULL; - } - arg2 = read_rvalue(s_arg2); - if (arg2 == NULL) { - ir_read_error(NULL, "when reading second operand of %s", - s_op->value()); - return NULL; + ir_rvalue *arg[3] = {NULL, NULL, NULL}; + for (int i = 0; i < num_operands; i++) { + arg[i] = read_rvalue(s_arg[i]); + if (arg[i] == NULL) { + ir_read_error(NULL, "when reading operand #%d of %s", i, s_op->value()); + return NULL; } } - return new(mem_ctx) ir_expression(op, type, arg1, arg2); + return new(mem_ctx) ir_expression(op, type, arg[0], arg[1], arg[2]); } ir_swizzle * @@ -918,6 +911,7 @@ ir_reader::read_texture(s_expression *expr) s_expression *s_proj = NULL; s_list *s_shadow = NULL; s_expression *s_lod = NULL; + s_expression *s_sample_index = NULL; ir_texture_opcode op = ir_tex; /* silence warning */ @@ -925,6 +919,8 @@ ir_reader::read_texture(s_expression *expr) { "tex", s_type, s_sampler, s_coord, s_offset, s_proj, s_shadow }; s_pattern txf_pattern[] = { "txf", s_type, s_sampler, s_coord, s_offset, s_lod }; + s_pattern txf_ms_pattern[] = + { "txf_ms", s_type, s_sampler, s_coord, s_sample_index }; s_pattern txs_pattern[] = { "txs", s_type, s_sampler, s_lod }; s_pattern other_pattern[] = @@ -934,6 +930,8 @@ ir_reader::read_texture(s_expression *expr) op = ir_tex; } else if (MATCH(expr, txf_pattern)) { op = ir_txf; + } else if (MATCH(expr, txf_ms_pattern)) { + op = ir_txf_ms; } else if (MATCH(expr, txs_pattern)) { op = ir_txs; } else if (MATCH(expr, other_pattern)) { @@ -973,18 +971,20 @@ ir_reader::read_texture(s_expression *expr) return NULL; } - // Read texel offset - either 0 or an rvalue. - s_int *si_offset = SX_AS_INT(s_offset); - if (si_offset == NULL || si_offset->value() != 0) { - tex->offset = read_rvalue(s_offset); - if (tex->offset == NULL) { - ir_read_error(s_offset, "expected 0 or an expression"); - return NULL; - } + if (op != ir_txf_ms) { + // Read texel offset - either 0 or an rvalue. + s_int *si_offset = SX_AS_INT(s_offset); + if (si_offset == NULL || si_offset->value() != 0) { + tex->offset = read_rvalue(s_offset); + if (tex->offset == NULL) { + ir_read_error(s_offset, "expected 0 or an expression"); + return NULL; + } + } } } - if (op != ir_txf && op != ir_txs) { + if (op != ir_txf && op != ir_txf_ms && op != ir_txs) { s_int *proj_as_int = SX_AS_INT(s_proj); if (proj_as_int && proj_as_int->value() == 1) { tex->projector = NULL; @@ -1027,6 +1027,13 @@ ir_reader::read_texture(s_expression *expr) return NULL; } break; + case ir_txf_ms: + tex->lod_info.sample_index = read_rvalue(s_sample_index); + if (tex->lod_info.sample_index == NULL) { + ir_read_error(NULL, "when reading sample_index in (txf_ms ...)"); + return NULL; + } + break; case ir_txd: { s_expression *s_dx, *s_dy; s_pattern dxdy_pat[] = { s_dx, s_dy }; diff --git a/mesalib/src/glsl/ir_rvalue_visitor.cpp b/mesalib/src/glsl/ir_rvalue_visitor.cpp index b34a419e8..543c54496 100644 --- a/mesalib/src/glsl/ir_rvalue_visitor.cpp +++ b/mesalib/src/glsl/ir_rvalue_visitor.cpp @@ -66,6 +66,9 @@ ir_rvalue_base_visitor::rvalue_visit(ir_texture *ir) case ir_txs: handle_rvalue(&ir->lod_info.lod); break; + case ir_txf_ms: + handle_rvalue(&ir->lod_info.sample_index); + break; case ir_txd: handle_rvalue(&ir->lod_info.grad.dPdx); handle_rvalue(&ir->lod_info.grad.dPdy); diff --git a/mesalib/src/glsl/ir_validate.cpp b/mesalib/src/glsl/ir_validate.cpp index d8cafd55f..24ea506dc 100644 --- a/mesalib/src/glsl/ir_validate.cpp +++ b/mesalib/src/glsl/ir_validate.cpp @@ -468,6 +468,12 @@ ir_validate::visit_leave(ir_expression *ir) assert(ir->operands[1]->type == glsl_type::uint_type); break; + case ir_triop_lrp: + assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT); + assert(ir->operands[0]->type == ir->operands[1]->type); + assert(ir->operands[2]->type == ir->operands[0]->type || ir->operands[2]->type == glsl_type::float_type); + break; + case ir_quadop_vector: /* The vector operator collects some number of scalars and generates a * vector from them. diff --git a/mesalib/src/glsl/lower_instructions.cpp b/mesalib/src/glsl/lower_instructions.cpp index a8ef7654e..1ce7b7c9d 100644 --- a/mesalib/src/glsl/lower_instructions.cpp +++ b/mesalib/src/glsl/lower_instructions.cpp @@ -37,6 +37,7 @@ * - POW_TO_EXP2 * - LOG_TO_LOG2 * - MOD_TO_FRACT + * - LRP_TO_ARITH * * SUB_TO_ADD_NEG: * --------------- @@ -79,13 +80,20 @@ * Many GPUs don't have a MOD instruction (945 and 965 included), and * if we have to break it down like this anyway, it gives an * opportunity to do things like constant fold the (1.0 / op1) easily. + * + * LRP_TO_ARITH: + * ------------- + * Converts ir_triop_lrp to (op0 * (1.0f - op2)) + (op1 * op2). */ #include "main/core.h" /* for M_LOG2E */ #include "glsl_types.h" #include "ir.h" +#include "ir_builder.h" #include "ir_optimization.h" +using namespace ir_builder; + class lower_instructions_visitor : public ir_hierarchical_visitor { public: lower_instructions_visitor(unsigned lower) @@ -105,6 +113,7 @@ private: void exp_to_exp2(ir_expression *); void pow_to_exp2(ir_expression *); void log_to_log2(ir_expression *); + void lrp_to_arith(ir_expression *); }; /** @@ -268,6 +277,27 @@ lower_instructions_visitor::mod_to_fract(ir_expression *ir) this->progress = true; } +void +lower_instructions_visitor::lrp_to_arith(ir_expression *ir) +{ + /* (lrp x y a) -> x*(1-a) + y*a */ + + /* Save op2 */ + ir_variable *temp = new(ir) ir_variable(ir->operands[2]->type, "lrp_factor", + ir_var_temporary); + this->base_ir->insert_before(temp); + this->base_ir->insert_before(assign(temp, ir->operands[2])); + + ir_constant *one = new(ir) ir_constant(1.0f); + + ir->operation = ir_binop_add; + ir->operands[0] = mul(ir->operands[0], sub(one, temp)); + ir->operands[1] = mul(ir->operands[1], temp); + ir->operands[2] = NULL; + + this->progress = true; +} + ir_visitor_status lower_instructions_visitor::visit_leave(ir_expression *ir) { @@ -304,6 +334,11 @@ lower_instructions_visitor::visit_leave(ir_expression *ir) pow_to_exp2(ir); break; + case ir_triop_lrp: + if (lowering(LRP_TO_ARITH)) + lrp_to_arith(ir); + break; + default: return visit_continue; } diff --git a/mesalib/src/glsl/opt_algebraic.cpp b/mesalib/src/glsl/opt_algebraic.cpp index 75948db16..70e016d22 100644 --- a/mesalib/src/glsl/opt_algebraic.cpp +++ b/mesalib/src/glsl/opt_algebraic.cpp @@ -186,12 +186,12 @@ ir_algebraic_visitor::swizzle_if_required(ir_expression *expr, ir_rvalue * ir_algebraic_visitor::handle_expression(ir_expression *ir) { - ir_constant *op_const[2] = {NULL, NULL}; - ir_expression *op_expr[2] = {NULL, NULL}; + ir_constant *op_const[3] = {NULL, NULL, NULL}; + ir_expression *op_expr[3] = {NULL, NULL, NULL}; ir_expression *temp; unsigned int i; - assert(ir->get_num_operands() <= 2); + assert(ir->get_num_operands() <= 3); for (i = 0; i < ir->get_num_operands(); i++) { if (ir->operands[i]->type->is_matrix()) return ir; @@ -415,6 +415,17 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir) break; + case ir_triop_lrp: + /* Operands are (x, y, a). */ + if (is_vec_zero(op_const[2])) { + this->progress = true; + return swizzle_if_required(ir, ir->operands[0]); + } else if (is_vec_one(op_const[2])) { + this->progress = true; + return swizzle_if_required(ir, ir->operands[1]); + } + break; + default: break; } diff --git a/mesalib/src/glsl/opt_tree_grafting.cpp b/mesalib/src/glsl/opt_tree_grafting.cpp index 113abb7b0..985540196 100644 --- a/mesalib/src/glsl/opt_tree_grafting.cpp +++ b/mesalib/src/glsl/opt_tree_grafting.cpp @@ -285,6 +285,10 @@ ir_tree_grafting_visitor::visit_enter(ir_texture *ir) if (do_graft(&ir->lod_info.lod)) return visit_stop; break; + case ir_txf_ms: + if (do_graft(&ir->lod_info.sample_index)) + return visit_stop; + break; case ir_txd: if (do_graft(&ir->lod_info.grad.dPdx) || do_graft(&ir->lod_info.grad.dPdy)) diff --git a/mesalib/src/glsl/standalone_scaffolding.cpp b/mesalib/src/glsl/standalone_scaffolding.cpp index 0fb4f5b16..8c0091e84 100644 --- a/mesalib/src/glsl/standalone_scaffolding.cpp +++ b/mesalib/src/glsl/standalone_scaffolding.cpp @@ -102,6 +102,7 @@ void initialize_context_to_defaults(struct gl_context *ctx, gl_api api) ctx->Extensions.ARB_shading_language_packing = true; ctx->Extensions.OES_standard_derivatives = true; ctx->Extensions.ARB_texture_cube_map_array = true; + ctx->Extensions.ARB_texture_multisample = true; ctx->Const.GLSLVersion = 120; |