[Mesa-dev] [PATCH 06/14] glsl: Add a pass to lower bitfield-insert into bfm+bfi.
Matt Turner
mattst88 at gmail.com
Sun Apr 28 15:29:43 PDT 2013
i965/Gen7+ and Radeon/Evergreen+ have bfm/bfi instructions to implement
bitfieldInsert() from ARB_gpu_shader5.
v2: Add ir_binop_bfm and ir_triop_bfi to st_glsl_to_tgsi.cpp.
Remove spurious temporary assignment and dereference.
---
src/glsl/ir.cpp | 2 ++
src/glsl/ir.h | 18 ++++++++++++++
src/glsl/ir_optimization.h | 1 +
src/glsl/ir_validate.cpp | 12 ++++++++++
src/glsl/lower_instructions.cpp | 38 ++++++++++++++++++++++++++++++
src/mesa/program/ir_to_mesa.cpp | 2 ++
src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 2 ++
7 files changed, 75 insertions(+)
diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp
index 2c989c9..2c54525 100644
--- a/src/glsl/ir.cpp
+++ b/src/glsl/ir.cpp
@@ -508,8 +508,10 @@ static const char *const operator_strs[] = {
"max",
"pow",
"packHalf2x16_split",
+ "bfm",
"ubo_load",
"lrp",
+ "bfi",
"bitfield_extract",
"bitfield_insert",
"vector",
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index 470c08c..6783eca 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -1119,6 +1119,15 @@ enum ir_expression_operation {
/*@}*/
/**
+ * \name First half of a lowered bitfieldInsert() operation.
+ *
+ * \see lower_instructions::bitfield_insert_to_bfm_bfi
+ */
+ /*@{*/
+ ir_binop_bfm,
+ /*@}*/
+
+ /**
* Load a value the size of a given GLSL type from a uniform block.
*
* operand0 is the ir_constant uniform block index in the linked shader.
@@ -1133,6 +1142,15 @@ enum ir_expression_operation {
ir_triop_lrp,
+ /**
+ * \name Second half of a lowered bitfieldInsert() operation.
+ *
+ * \see lower_instructions::bitfield_insert_to_bfm_bfi
+ */
+ /*@{*/
+ ir_triop_bfi,
+ /*@}*/
+
ir_triop_bitfield_extract,
/**
diff --git a/src/glsl/ir_optimization.h b/src/glsl/ir_optimization.h
index a8885d7..49b1475 100644
--- a/src/glsl/ir_optimization.h
+++ b/src/glsl/ir_optimization.h
@@ -37,6 +37,7 @@
#define MOD_TO_FRACT 0x20
#define INT_DIV_TO_MUL_RCP 0x40
#define LRP_TO_ARITH 0x80
+#define BITFIELD_INSERT_TO_BFM_BFI 0x100
/**
* \see class lower_packing_builtins_visitor
diff --git a/src/glsl/ir_validate.cpp b/src/glsl/ir_validate.cpp
index 4a8df69..26f09c7 100644
--- a/src/glsl/ir_validate.cpp
+++ b/src/glsl/ir_validate.cpp
@@ -474,6 +474,12 @@ ir_validate::visit_leave(ir_expression *ir)
assert(ir->operands[1]->type == glsl_type::float_type);
break;
+ case ir_binop_bfm:
+ assert(ir->type->is_integer());
+ assert(ir->operands[0]->type->is_integer());
+ assert(ir->operands[1]->type->is_integer());
+ break;
+
case ir_binop_ubo_load:
assert(ir->operands[0]->as_constant());
assert(ir->operands[0]->type == glsl_type::uint_type);
@@ -487,6 +493,12 @@ ir_validate::visit_leave(ir_expression *ir)
assert(ir->operands[2]->type == ir->operands[0]->type || ir->operands[2]->type == glsl_type::float_type);
break;
+ case ir_triop_bfi:
+ assert(ir->operands[0]->type->is_integer());
+ assert(ir->operands[1]->type == ir->operands[2]->type);
+ assert(ir->operands[1]->type == ir->type);
+ break;
+
case ir_triop_bitfield_extract:
assert(ir->operands[0]->type == ir->type);
assert(ir->operands[1]->type == glsl_type::int_type);
diff --git a/src/glsl/lower_instructions.cpp b/src/glsl/lower_instructions.cpp
index 1ce7b7c..6c70a4a 100644
--- a/src/glsl/lower_instructions.cpp
+++ b/src/glsl/lower_instructions.cpp
@@ -38,6 +38,7 @@
* - LOG_TO_LOG2
* - MOD_TO_FRACT
* - LRP_TO_ARITH
+ * - BITFIELD_INSERT_TO_BFM_BFI
*
* SUB_TO_ADD_NEG:
* ---------------
@@ -84,6 +85,15 @@
* LRP_TO_ARITH:
* -------------
* Converts ir_triop_lrp to (op0 * (1.0f - op2)) + (op1 * op2).
+ *
+ * BITFIELD_INSERT_TO_BFM_BFI:
+ * ---------------------------
+ * Breaks ir_quadop_bitfield_insert into ir_binop_bfm (bitfield mask) and
+ * ir_triop_bfi (bitfield insert).
+ *
+ * Many GPUs implement the bitfieldInsert() built-in from ARB_gpu_shader_5
+ * with a pair of instructions.
+ *
*/
#include "main/core.h" /* for M_LOG2E */
@@ -114,6 +124,7 @@ private:
void pow_to_exp2(ir_expression *);
void log_to_log2(ir_expression *);
void lrp_to_arith(ir_expression *);
+ void bitfield_insert_to_bfm_bfi(ir_expression *);
};
/**
@@ -298,6 +309,28 @@ lower_instructions_visitor::lrp_to_arith(ir_expression *ir)
this->progress = true;
}
+void
+lower_instructions_visitor::bitfield_insert_to_bfm_bfi(ir_expression *ir)
+{
+ /* Translates
+ * ir_quadop_bitfield_insert base insert offset bits
+ * into
+ * ir_triop_bfi (ir_binop_bfm bits offset) insert base
+ */
+
+ ir_rvalue *base_expr = ir->operands[0];
+
+ ir->operation = ir_triop_bfi;
+ ir->operands[0] = new(ir) ir_expression(ir_binop_bfm, ir->type,
+ swizzle_xxxx(ir->operands[3]),
+ swizzle_xxxx(ir->operands[2]));
+ /* ir->operands[1] is still the value to insert. */
+ ir->operands[2] = base_expr;
+ ir->operands[3] = NULL;
+
+ this->progress = true;
+}
+
ir_visitor_status
lower_instructions_visitor::visit_leave(ir_expression *ir)
{
@@ -339,6 +372,11 @@ lower_instructions_visitor::visit_leave(ir_expression *ir)
lrp_to_arith(ir);
break;
+ case ir_quadop_bitfield_insert:
+ if (lowering(BITFIELD_INSERT_TO_BFM_BFI))
+ bitfield_insert_to_bfm_bfi(ir);
+ break;
+
default:
return visit_continue;
}
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index c6f6bf4..0848462 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -1489,6 +1489,8 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
emit(ir, OPCODE_LRP, result_dst, op[2], op[1], op[0]);
break;
+ case ir_binop_bfm:
+ case ir_triop_bfi:
case ir_triop_bitfield_extract:
case ir_quadop_bitfield_insert:
assert(!"not supported");
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index ad936bd..ed314a0 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -1973,6 +1973,8 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
case ir_unop_bit_count:
case ir_unop_find_msb:
case ir_unop_find_lsb:
+ case ir_binop_bfm:
+ case ir_triop_bfi:
case ir_triop_bitfield_extract:
case ir_quadop_bitfield_insert:
case ir_quadop_vector:
--
1.8.1.5
More information about the mesa-dev
mailing list