glsl: Add unary operation ir_unop_f2u.
authorPaul Berry <stereotype441@gmail.com>
Wed, 13 Jun 2012 22:47:45 +0000 (15:47 -0700)
committerPaul Berry <stereotype441@gmail.com>
Fri, 15 Jun 2012 15:58:55 +0000 (08:58 -0700)
Previously, we performed conversions from float->uint by a two step
process: float->int->uint.  However, on platforms that use saturating
conversions (e.g. i965), this didn't work, because if the source value
was larger than the maximum representable int (0x7fffffff), then
converting it to an int would clamp it to 0x7fffffff.

This patch just adds the new opcode; further patches will adapt
optimization passes and back-ends to use it, and then finally the
ast_to_hir logic will be modified to emit the new opcode.

Reviewed-by: Brian Paul <brianp@vmware.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/glsl/ir.cpp
src/glsl/ir.h
src/glsl/ir_validate.cpp

index f81bfd1ab8a5af2cff81282fae46dd524f56b62e..1c9eec6e2d19b5e187b82209e827c4837a086a74 100644 (file)
@@ -299,6 +299,7 @@ ir_expression::ir_expression(int op, ir_rvalue *op0)
       break;
 
    case ir_unop_i2u:
+   case ir_unop_f2u:
    case ir_unop_bitcast_f2u:
       this->type = glsl_type::get_instance(GLSL_TYPE_UINT,
                                           op0->type->vector_elements, 1);
@@ -428,6 +429,7 @@ static const char *const operator_strs[] = {
    "exp2",
    "log2",
    "f2i",
+   "f2u",
    "i2f",
    "f2b",
    "b2f",
index 55535b2f5ce74a79be173806d97d38ed1021fa22..014f3630d7732a7123aecb826d736c4549aec938 100644 (file)
@@ -896,6 +896,7 @@ enum ir_expression_operation {
    ir_unop_exp2,
    ir_unop_log2,
    ir_unop_f2i,         /**< Float-to-integer conversion. */
+   ir_unop_f2u,         /**< Float-to-unsigned conversion. */
    ir_unop_i2f,         /**< Integer-to-float conversion. */
    ir_unop_f2b,         /**< Float-to-boolean conversion */
    ir_unop_b2f,         /**< Boolean-to-float conversion */
index 5721717a5acbdc61136cf3a26df4014d88d3fd59..191d398310978f0eb0999d7a4c2b2cbd8afbf655 100644 (file)
@@ -256,6 +256,10 @@ ir_validate::visit_leave(ir_expression *ir)
       assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
       assert(ir->type->base_type == GLSL_TYPE_INT);
       break;
+   case ir_unop_f2u:
+      assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
+      assert(ir->type->base_type == GLSL_TYPE_UINT);
+      break;
    case ir_unop_i2f:
       assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
       assert(ir->type->base_type == GLSL_TYPE_FLOAT);