diff options
author | Matt Turner <[email protected]> | 2013-04-09 19:22:34 -0700 |
---|---|---|
committer | Matt Turner <[email protected]> | 2013-05-06 10:17:14 -0700 |
commit | 1f0f26d60c148e360908af34130c4e00dba8f3df (patch) | |
tree | 02817e6857e0ad7e9ffe18bf3f47a69007366d7e /src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp | |
parent | fa958182b7e7a9a177ec45ffd39d42f15ca756b3 (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.cpp | 37 |
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; |