glsl: Add a pass to lower bitfield-insert into bfm+bfi.
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. Reviewed-by: Chris Forbes <chrisf@ijw.co.nz>
This commit is contained in:
@@ -508,8 +508,10 @@ static const char *const operator_strs[] = {
|
||||
"max",
|
||||
"pow",
|
||||
"packHalf2x16_split",
|
||||
"bfm",
|
||||
"ubo_load",
|
||||
"lrp",
|
||||
"bfi",
|
||||
"bitfield_extract",
|
||||
"bitfield_insert",
|
||||
"vector",
|
||||
|
@@ -1118,6 +1118,15 @@ enum ir_expression_operation {
|
||||
ir_binop_pack_half_2x16_split,
|
||||
/*@}*/
|
||||
|
||||
/**
|
||||
* \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.
|
||||
*
|
||||
@@ -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,
|
||||
|
||||
/**
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
@@ -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,29 @@ 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->get_base_type(),
|
||||
ir->operands[3],
|
||||
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 +373,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;
|
||||
}
|
||||
|
@@ -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");
|
||||
|
@@ -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:
|
||||
|
Reference in New Issue
Block a user