From 7540be22d16bce68163a6478fa2d7a5aa1d9844d Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Sun, 6 Apr 2014 18:34:59 -0700 Subject: [PATCH] glsl: Make is_16bit_constant from i965 an ir_constant method. The i965 MUL instruction doesn't natively support 32-bit by 32-bit integer multiplication; additional instructions (MACH/MOV) are required. However, we can avoid those if we know one of the operands can be represented in 16 bits or less. The vector backend's is_16bit_constant static helper function checks for this. We want to be able to use it in the scalar backend as well, which means moving the function to a more generally-usable location. Since it isn't i965 specific, I decided to make it an ir_constant method, in case it ends up being useful to other people as well. v2: Rename from is_16bit_integer_constant to is_uint16_constant, as suggested by Ilia Mirkin. Update comments to clarify that it does apply to both int and uint types, as long as the value is non-negative and fits in 16-bits. Signed-off-by: Kenneth Graunke Reviewed-by: Ian Romanick Reviewed-by: Matt Turner --- src/glsl/ir.cpp | 9 +++++++++ src/glsl/ir.h | 15 +++++++++++++++ src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp | 18 ++---------------- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp index a41eddfcb73..1a18b47f790 100644 --- a/src/glsl/ir.cpp +++ b/src/glsl/ir.cpp @@ -1223,6 +1223,15 @@ ir_constant::is_basis() const return ones == 1; } +bool +ir_constant::is_uint16_constant() const +{ + if (!type->is_integer()) + return false; + + return value.u[0] < (1 << 16); +} + ir_loop::ir_loop() { this->ir_type = ir_type_loop; diff --git a/src/glsl/ir.h b/src/glsl/ir.h index ee276d2be2d..6c7c60a27d9 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -265,6 +265,13 @@ public: */ virtual bool is_basis() const; + /** + * Determine if an r-value is an unsigned integer constant which can be + * stored in 16 bits. + * + * \sa ir_constant::is_uint16_constant. + */ + virtual bool is_uint16_constant() const { return false; } /** * Return a generic value of error_type. @@ -2164,6 +2171,14 @@ public: virtual bool is_negative_one() const; virtual bool is_basis() const; + /** + * Return true for constants that could be stored as 16-bit unsigned values. + * + * Note that this will return true even for signed integer ir_constants, as + * long as the value is non-negative and fits in 16-bits. + */ + virtual bool is_uint16_constant() const; + /** * Value of the constant. * diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp index c73e58d6cf7..edace108f19 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp @@ -1174,20 +1174,6 @@ vec4_visitor::emit_lrp(const dst_reg &dst, } } -static bool -is_16bit_constant(ir_rvalue *rvalue) -{ - ir_constant *constant = rvalue->as_constant(); - if (!constant) - return false; - - if (constant->type != glsl_type::int_type && - constant->type != glsl_type::uint_type) - return false; - - return constant->value.u[0] < (1 << 16); -} - void vec4_visitor::visit(ir_expression *ir) { @@ -1371,12 +1357,12 @@ vec4_visitor::visit(ir_expression *ir) * operand. If we can determine that one of the args is in the low * 16 bits, though, we can just emit a single MUL. */ - if (is_16bit_constant(ir->operands[0])) { + if (ir->operands[0]->is_uint16_constant()) { if (brw->gen < 7) emit(MUL(result_dst, op[0], op[1])); else emit(MUL(result_dst, op[1], op[0])); - } else if (is_16bit_constant(ir->operands[1])) { + } else if (ir->operands[1]->is_uint16_constant()) { if (brw->gen < 7) emit(MUL(result_dst, op[1], op[0])); else -- 2.30.2