--- src/glsl/ir_optimization.h | 1 + src/glsl/lower_instructions.cpp | 61 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 0 deletions(-)
diff --git a/src/glsl/ir_optimization.h b/src/glsl/ir_optimization.h index 49b1475..445dc49 100644 --- a/src/glsl/ir_optimization.h +++ b/src/glsl/ir_optimization.h @@ -38,6 +38,7 @@ #define INT_DIV_TO_MUL_RCP 0x40 #define LRP_TO_ARITH 0x80 #define BITFIELD_INSERT_TO_BFM_BFI 0x100 +#define BITFIELD_INSERT_TO_BFM_BITOPS 0x200 /** * \see class lower_packing_builtins_visitor diff --git a/src/glsl/lower_instructions.cpp b/src/glsl/lower_instructions.cpp index ff9715d..1c1cad8 100644 --- a/src/glsl/lower_instructions.cpp +++ b/src/glsl/lower_instructions.cpp @@ -39,6 +39,7 @@ * - MOD_TO_FRACT * - LRP_TO_ARITH * - BITFIELD_INSERT_TO_BFM_BFI + * - BITFIELD_INSERT_TO_BFM_BITOPS * * SUB_TO_ADD_NEG: * --------------- @@ -91,9 +92,20 @@ * Breaks ir_quadop_bitfield_insert into ir_binop_bfm (bitfield mask) and * ir_triop_bfi (bitfield insert). * + * Mutually exclusive with BITFIELD_INSERT_TO_BFM_BITOPS. + * * Many GPUs implement the bitfieldInsert() built-in from ARB_gpu_shader_5 * with a pair of instructions. * + * BITFIELD_INSERT_TO_BFM_BITOPS: + * ------------------------------ + * Breaks ir_quadop_bitfield_insert into ir_binop_bfm (bitfield mask) and + * bit operations simulating ir_triop_bfi (bitfield insert). + * + * Mutually exclusive with BITFIELD_INSERT_TO_BFM_BITOPS. + * + * It's difficult to use vector three-source instructions in i965's vertex + * shader, so don't emit ir_triop_bfi, but rather bit operations. */ #include "main/core.h" /* for M_LOG2E */ @@ -125,6 +137,7 @@ private: void log_to_log2(ir_expression *); void lrp_to_arith(ir_expression *); void bitfield_insert_to_bfm_bfi(ir_expression *); + void bitfield_insert_to_bfm_bitops(ir_expression *ir); }; /** @@ -335,6 +348,52 @@ lower_instructions_visitor::bitfield_insert_to_bfm_bfi(ir_expression *ir) this->progress = true; } +void lower_instructions_visitor::bitfield_insert_to_bfm_bitops(ir_expression *ir) +{ + /* Translates + * ir_quadop_bitfield_insert base insert offset bits + * into + * (or (and base (not insert_mask)) + * (and (<< insert offset) insert_mask)) + * where insert_mask is + * (bfm bits offset) + */ + ir_variable *base = new(ir) ir_variable(ir->operands[0]->type, "bfi_base", + ir_var_temporary); + this->base_ir->insert_before(base); + this->base_ir->insert_before(assign(base, ir->operands[0])); + + ir_variable *insert = new(ir) ir_variable(ir->operands[1]->type, "bfi_insert", + ir_var_temporary); + this->base_ir->insert_before(insert); + this->base_ir->insert_before(assign(insert, ir->operands[1])); + + ir_variable *offset = new(ir) ir_variable(ir->operands[2]->type, "bfi_offset", + ir_var_temporary); + this->base_ir->insert_before(offset); + this->base_ir->insert_before(assign(offset, ir->operands[2])); + + ir_variable *bits = new(ir) ir_variable(ir->operands[3]->type, "bfi_bits", + ir_var_temporary); + this->base_ir->insert_before(bits); + this->base_ir->insert_before(assign(bits, ir->operands[3])); + + ir_variable *insert_mask = new(ir) ir_variable(glsl_type::int_type, + "insert_mask", + ir_var_temporary); + this->base_ir->insert_before(insert_mask); + this->base_ir->insert_before(assign(insert_mask, + new(ir) ir_expression(ir_binop_bfm, ir->type, + swizzle_xxxx(bits), + swizzle_xxxx(offset)))); + + ir->operation = ir_binop_bit_or; + ir->operands[0] = bit_and(base, bit_not(insert_mask)); + ir->operands[1] = bit_and(lshift(insert, offset), insert_mask); + ir->operands[2] = NULL; + ir->operands[3] = NULL; +} + ir_visitor_status lower_instructions_visitor::visit_leave(ir_expression *ir) { @@ -379,6 +438,8 @@ lower_instructions_visitor::visit_leave(ir_expression *ir) case ir_quadop_bitfield_insert: if (lowering(BITFIELD_INSERT_TO_BFM_BFI)) bitfield_insert_to_bfm_bfi(ir); + else if (lowering(BITFIELD_INSERT_TO_BFM_BITOPS)) + bitfield_insert_to_bfm_bitops(ir); break; default: -- 1.7.8.6 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev