[Mesa-dev] [PATCH 03/19] glsl: add ARB_shader_ballot operations

Nicolai Hähnle nhaehnle at gmail.com
Fri Mar 31 17:14:03 UTC 2017


From: Nicolai Hähnle <nicolai.haehnle at amd.com>

---
 src/compiler/glsl/ir.cpp                     | 12 ++++++++++++
 src/compiler/glsl/ir_expression_operation.py |  7 +++++++
 src/compiler/glsl/ir_validate.cpp            | 16 ++++++++++++++++
 src/mesa/program/ir_to_mesa.cpp              |  3 +++
 4 files changed, 38 insertions(+)

diff --git a/src/compiler/glsl/ir.cpp b/src/compiler/glsl/ir.cpp
index f80bd81..2bbc7a1 100644
--- a/src/compiler/glsl/ir.cpp
+++ b/src/compiler/glsl/ir.cpp
@@ -374,20 +374,28 @@ ir_expression::ir_expression(int op, ir_rvalue *op0)
    case ir_unop_frexp_exp:
       this->type = glsl_type::get_instance(GLSL_TYPE_INT,
 					   op0->type->vector_elements, 1);
       break;
 
    case ir_unop_get_buffer_size:
    case ir_unop_ssbo_unsized_array_length:
       this->type = glsl_type::int_type;
       break;
 
+   case ir_unop_ballot:
+      this->type = glsl_type::uint64_t_type;
+      break;
+
+   case ir_unop_read_first_invocation:
+      this->type = op0->type;
+      break;
+
    case ir_unop_vote_any:
    case ir_unop_vote_all:
    case ir_unop_vote_eq:
       this->type = glsl_type::bool_type;
       break;
 
    case ir_unop_bitcast_i642d:
    case ir_unop_bitcast_u642d:
       this->type = glsl_type::get_instance(GLSL_TYPE_DOUBLE,
                                            op0->type->vector_elements, 1);
@@ -489,20 +497,24 @@ ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1)
    case ir_binop_ldexp:
    case ir_binop_interpolate_at_offset:
    case ir_binop_interpolate_at_sample:
       this->type = op0->type;
       break;
 
    case ir_binop_vector_extract:
       this->type = op0->type->get_scalar_type();
       break;
 
+   case ir_binop_read_invocation:
+      this->type = op0->type;
+      break;
+
    default:
       assert(!"not reached: missing automatic type setup for ir_expression");
       this->type = glsl_type::float_type;
    }
 }
 
 ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1,
                              ir_rvalue *op2)
    : ir_rvalue(ir_type_expression)
 {
diff --git a/src/compiler/glsl/ir_expression_operation.py b/src/compiler/glsl/ir_expression_operation.py
index bde9c01..1d29560 100644
--- a/src/compiler/glsl/ir_expression_operation.py
+++ b/src/compiler/glsl/ir_expression_operation.py
@@ -563,20 +563,24 @@ ir_expression_operation = [
    operation("get_buffer_size", 1),
 
    # Calculate length of an unsized array inside a buffer block.
    # This opcode is going to be replaced in a lowering pass inside
    # the linker.
    #
    # operand0 is the unsized array's ir_value for the calculation
    # of its length.
    operation("ssbo_unsized_array_length", 1),
 
+   # ARB_shader_ballot operations
+   operation("ballot", 1, source_types=(bool_type,), dest_type=uint64_type),
+   operation("read_first_invocation", 1),
+
    # Vote among threads on the value of the boolean argument.
    operation("vote_any", 1),
    operation("vote_all", 1),
    operation("vote_eq", 1),
 
    # 64-bit integer packing ops.
    operation("pack_int_2x32", 1, printable_name="packInt2x32", source_types=(int_type,), dest_type=int64_type, c_expression="memcpy(&data.i64[0], &op[0]->value.i[0], sizeof(int64_t))", flags=frozenset((horizontal_operation, non_assign_operation))),
    operation("pack_uint_2x32", 1, printable_name="packUint2x32", source_types=(uint_type,), dest_type=uint64_type, c_expression="memcpy(&data.u64[0], &op[0]->value.u[0], sizeof(uint64_t))", flags=frozenset((horizontal_operation, non_assign_operation))),
    operation("unpack_int_2x32", 1, printable_name="unpackInt2x32", source_types=(int64_type,), dest_type=int_type, c_expression="memcpy(&data.i[0], &op[0]->value.i64[0], sizeof(int64_t))", flags=frozenset((horizontal_operation, non_assign_operation))),
    operation("unpack_uint_2x32", 1, printable_name="unpackUint2x32", source_types=(uint64_type,), dest_type=uint_type, c_expression="memcpy(&data.u[0], &op[0]->value.u64[0], sizeof(uint64_t))", flags=frozenset((horizontal_operation, non_assign_operation))),
@@ -659,20 +663,23 @@ ir_expression_operation = [
    # operand0 is the fs input
    # operand1 is the offset from the pixel center
    operation("interpolate_at_offset", 2),
 
    # Interpolate fs input at sample position
    #
    # operand0 is the fs input
    # operand1 is the sample ID
    operation("interpolate_at_sample", 2),
 
+   # ARB_shader_ballot operation
+   operation("read_invocation", 2),
+
    # Fused floating-point multiply-add, part of ARB_gpu_shader5.
    operation("fma", 3, source_types=real_types, c_expression="{src0} * {src1} + {src2}"),
 
    operation("lrp", 3, source_types=real_types, c_expression={'f': "{src0} * (1.0f - {src2}) + ({src1} * {src2})", 'd': "{src0} * (1.0 - {src2}) + ({src1} * {src2})"}),
 
    # Conditional Select
    #
    # A vector conditional select instruction (like ?:, but operating per-
    # component on vectors).
    #
diff --git a/src/compiler/glsl/ir_validate.cpp b/src/compiler/glsl/ir_validate.cpp
index 5a1202b..76a4ed1 100644
--- a/src/compiler/glsl/ir_validate.cpp
+++ b/src/compiler/glsl/ir_validate.cpp
@@ -575,20 +575,36 @@ ir_validate::visit_leave(ir_expression *ir)
    case ir_unop_frexp_exp:
       assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT ||
              ir->operands[0]->type->base_type == GLSL_TYPE_DOUBLE);
       assert(ir->type->base_type == GLSL_TYPE_INT);
       break;
    case ir_unop_subroutine_to_int:
       assert(ir->operands[0]->type->base_type == GLSL_TYPE_SUBROUTINE);
       assert(ir->type->base_type == GLSL_TYPE_INT);
       break;
 
+   case ir_unop_ballot:
+      assert(ir->type == glsl_type::uint64_t_type);
+      assert(ir->operands[0]->type == glsl_type::bool_type);
+      break;
+
+   case ir_binop_read_invocation:
+      assert(ir->operands[1]->type == glsl_type::uint_type);
+      /* fall-through */
+   case ir_unop_read_first_invocation:
+      assert(ir->type == ir->operands[0]->type);
+      assert(ir->type->is_scalar() || ir->type->is_vector());
+      assert(ir->type->base_type == GLSL_TYPE_FLOAT ||
+             ir->type->base_type == GLSL_TYPE_INT ||
+             ir->type->base_type == GLSL_TYPE_UINT);
+      break;
+
    case ir_unop_vote_any:
    case ir_unop_vote_all:
    case ir_unop_vote_eq:
       assert(ir->type == glsl_type::bool_type);
       assert(ir->operands[0]->type == glsl_type::bool_type);
       break;
 
    case ir_binop_add:
    case ir_binop_sub:
    case ir_binop_mul:
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index a2476dd..4d0c44d 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -1380,20 +1380,23 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
    case ir_binop_imul_high:
    case ir_unop_interpolate_at_centroid:
    case ir_binop_interpolate_at_offset:
    case ir_binop_interpolate_at_sample:
    case ir_unop_dFdx_coarse:
    case ir_unop_dFdx_fine:
    case ir_unop_dFdy_coarse:
    case ir_unop_dFdy_fine:
    case ir_unop_subroutine_to_int:
    case ir_unop_get_buffer_size:
+   case ir_unop_ballot:
+   case ir_binop_read_invocation:
+   case ir_unop_read_first_invocation:
    case ir_unop_vote_any:
    case ir_unop_vote_all:
    case ir_unop_vote_eq:
    case ir_unop_bitcast_u642d:
    case ir_unop_bitcast_i642d:
    case ir_unop_bitcast_d2u64:
    case ir_unop_bitcast_d2i64:
    case ir_unop_i642i:
    case ir_unop_u642i:
    case ir_unop_i642u:
-- 
2.9.3



More information about the mesa-dev mailing list