aboutsummaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp
diff options
context:
space:
mode:
authorMatt Turner <[email protected]>2013-04-09 19:22:34 -0700
committerMatt Turner <[email protected]>2013-05-06 10:17:14 -0700
commit1f0f26d60c148e360908af34130c4e00dba8f3df (patch)
tree02817e6857e0ad7e9ffe18bf3f47a69007366d7e /src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp
parentfa958182b7e7a9a177ec45ffd39d42f15ca756b3 (diff)
i965/fs: Add support for bit instructions.
Don't bother scalarizing ir_binop_bfm, since its results are identical for all channels. v2: Subtract result of FBH from 31 (unless an error) to convert MSB counts to LSB counts. v3: Use op0->clone() in ir_triop_bfi to prevent (var_ref channel_expressions) from appearing multiple times in the IR. Reviewed-by: Chris Forbes <[email protected]> [v2]
Diffstat (limited to 'src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp')
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp37
1 files changed, 37 insertions, 0 deletions
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 30d8d9bf527..0f3d4abdd26 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp
@@ -216,6 +216,10 @@ ir_channel_expressions_visitor::visit_leave(ir_assignment *ir)
case ir_unop_cos_reduced:
case ir_unop_dFdx:
case ir_unop_dFdy:
+ case ir_unop_bitfield_reverse:
+ case ir_unop_bit_count:
+ case ir_unop_find_msb:
+ case ir_unop_find_lsb:
for (i = 0; i < vector_elements; i++) {
ir_rvalue *op0 = get_element(op_var[0], i);
@@ -338,11 +342,26 @@ ir_channel_expressions_visitor::visit_leave(ir_assignment *ir)
assert(!"noise should have been broken down to function call");
break;
+ case ir_binop_bfm: {
+ /* Does not need to be scalarized, since its result will be identical
+ * for all channels.
+ */
+ ir_rvalue *op0 = get_element(op_var[0], 0);
+ ir_rvalue *op1 = get_element(op_var[1], 0);
+
+ assign(ir, 0, new(mem_ctx) ir_expression(expr->operation,
+ element_type,
+ op0,
+ op1));
+ break;
+ }
+
case ir_binop_ubo_load:
assert(!"not yet supported");
break;
case ir_triop_lrp:
+ case ir_triop_bitfield_extract:
for (i = 0; i < vector_elements; i++) {
ir_rvalue *op0 = get_element(op_var[0], i);
ir_rvalue *op1 = get_element(op_var[1], i);
@@ -356,6 +375,23 @@ ir_channel_expressions_visitor::visit_leave(ir_assignment *ir)
}
break;
+ case ir_triop_bfi: {
+ /* Only a single BFM is needed for multiple BFIs. */
+ ir_rvalue *op0 = get_element(op_var[0], 0);
+
+ for (i = 0; i < vector_elements; i++) {
+ ir_rvalue *op1 = get_element(op_var[1], i);
+ ir_rvalue *op2 = get_element(op_var[2], i);
+
+ assign(ir, i, new(mem_ctx) ir_expression(expr->operation,
+ element_type,
+ op0->clone(mem_ctx, NULL),
+ op1,
+ op2));
+ }
+ break;
+ }
+
case ir_unop_pack_snorm_2x16:
case ir_unop_pack_snorm_4x8:
case ir_unop_pack_unorm_2x16:
@@ -366,6 +402,7 @@ ir_channel_expressions_visitor::visit_leave(ir_assignment *ir)
case ir_unop_unpack_unorm_2x16:
case ir_unop_unpack_unorm_4x8:
case ir_unop_unpack_half_2x16:
+ case ir_quadop_bitfield_insert:
case ir_quadop_vector:
assert(!"should have been lowered");
break;