[Mesa-dev] [PATCH] mesa/glsl: add ir_unop_round

Brian Paul brianp at vmware.com
Tue Jul 3 09:00:30 PDT 2012


The GLSL round() and roundEven() functions were both generating the
ir_unop_round_even instruction but the GLSL spec allows some leeway for
implementing round().  This change allows drivers to take advantage of
that.  For i965, they still equate to the same thing.

v2: implement ir_unop_round for constant expressions.
---
 src/glsl/builtins/ir/round.ir                      |    8 ++++----
 src/glsl/ir.cpp                                    |    2 ++
 src/glsl/ir.h                                      |    1 +
 src/glsl/ir_constant_expression.cpp                |    7 +++++++
 src/glsl/ir_validate.cpp                           |    1 +
 .../dri/i965/brw_fs_channel_expressions.cpp        |    1 +
 src/mesa/drivers/dri/i965/brw_fs_visitor.cpp       |    1 +
 src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp     |    1 +
 src/mesa/program/ir_to_mesa.cpp                    |    1 +
 src/mesa/state_tracker/st_glsl_to_tgsi.cpp         |    1 +
 10 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/src/glsl/builtins/ir/round.ir b/src/glsl/builtins/ir/round.ir
index d0d425b..becf064 100644
--- a/src/glsl/builtins/ir/round.ir
+++ b/src/glsl/builtins/ir/round.ir
@@ -2,20 +2,20 @@
    (signature float
      (parameters
        (declare (in) float arg0))
-     ((return (expression float round_even (var_ref arg0)))))
+     ((return (expression float round (var_ref arg0)))))
 
    (signature vec2
      (parameters
        (declare (in) vec2 arg0))
-     ((return (expression vec2 round_even (var_ref arg0)))))
+     ((return (expression vec2 round (var_ref arg0)))))
 
    (signature vec3
      (parameters
        (declare (in) vec3 arg0))
-     ((return (expression vec3 round_even (var_ref arg0)))))
+     ((return (expression vec3 round (var_ref arg0)))))
 
    (signature vec4
      (parameters
        (declare (in) vec4 arg0))
-     ((return (expression vec4 round_even (var_ref arg0)))))
+     ((return (expression vec4 round (var_ref arg0)))))
 ))
diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp
index 1c9eec6..1ae6197 100644
--- a/src/glsl/ir.cpp
+++ b/src/glsl/ir.cpp
@@ -265,6 +265,7 @@ ir_expression::ir_expression(int op, ir_rvalue *op0)
    case ir_unop_ceil:
    case ir_unop_floor:
    case ir_unop_fract:
+   case ir_unop_round:
    case ir_unop_round_even:
    case ir_unop_sin:
    case ir_unop_cos:
@@ -447,6 +448,7 @@ static const char *const operator_strs[] = {
    "ceil",
    "floor",
    "fract",
+   "round",
    "round_even",
    "sin",
    "cos",
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index 505d2e7..a7419bb 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -919,6 +919,7 @@ enum ir_expression_operation {
    ir_unop_ceil,
    ir_unop_floor,
    ir_unop_fract,
+   ir_unop_round,
    ir_unop_round_even,
    /*@}*/
 
diff --git a/src/glsl/ir_constant_expression.cpp b/src/glsl/ir_constant_expression.cpp
index 17b54b9..a8c9c7d 100644
--- a/src/glsl/ir_constant_expression.cpp
+++ b/src/glsl/ir_constant_expression.cpp
@@ -276,6 +276,13 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
       }
       break;
 
+   case ir_unop_round:
+      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+      for (unsigned c = 0; c < op[0]->type->components(); c++) {
+	 data.f[c] = roundf(op[0]->value.f[c]);
+      }
+      break;
+
    case ir_unop_round_even:
       assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
       for (unsigned c = 0; c < op[0]->type->components(); c++) {
diff --git a/src/glsl/ir_validate.cpp b/src/glsl/ir_validate.cpp
index 191d398..5a1f8ea 100644
--- a/src/glsl/ir_validate.cpp
+++ b/src/glsl/ir_validate.cpp
@@ -315,6 +315,7 @@ ir_validate::visit_leave(ir_expression *ir)
       break;
 
    case ir_unop_trunc:
+   case ir_unop_round:
    case ir_unop_round_even:
    case ir_unop_ceil:
    case ir_unop_floor:
diff --git a/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp b/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp
index 983d92e..f973567 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp
@@ -209,6 +209,7 @@ ir_channel_expressions_visitor::visit_leave(ir_assignment *ir)
    case ir_unop_ceil:
    case ir_unop_floor:
    case ir_unop_fract:
+   case ir_unop_round:
    case ir_unop_round_even:
    case ir_unop_sin:
    case ir_unop_cos:
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index 9bd1e67..9ed0c17 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -503,6 +503,7 @@ fs_visitor::visit(ir_expression *ir)
    case ir_unop_fract:
       inst = emit(BRW_OPCODE_FRC, this->result, op[0]);
       break;
+   case ir_unop_round:
    case ir_unop_round_even:
       emit(BRW_OPCODE_RNDE, this->result, op[0]);
       break;
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
index 25d3c92..66b657a 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
@@ -1302,6 +1302,7 @@ vec4_visitor::visit(ir_expression *ir)
    case ir_unop_fract:
       inst = emit(FRC(result_dst, op[0]));
       break;
+   case ir_unop_round:
    case ir_unop_round_even:
       emit(RNDE(result_dst, op[0]));
       break;
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index 217a264..ca272a7 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -1452,6 +1452,7 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
       break;
 
    case ir_unop_bit_not:
+   case ir_unop_round:
    case ir_unop_round_even:
       emit(ir, OPCODE_MOV, result_dst, op[0]);
       break;
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index 96977e4..4b8debc 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -1791,6 +1791,7 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
    case ir_unop_floor:
       emit(ir, TGSI_OPCODE_FLR, result_dst, op[0]);
       break;
+   case ir_unop_round:
    case ir_unop_round_even:
       emit(ir, TGSI_OPCODE_ROUND, result_dst, op[0]);
       break;
-- 
1.7.3.4



More information about the mesa-dev mailing list