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",
|
"max",
|
||||||
"pow",
|
"pow",
|
||||||
"packHalf2x16_split",
|
"packHalf2x16_split",
|
||||||
|
"bfm",
|
||||||
"ubo_load",
|
"ubo_load",
|
||||||
"lrp",
|
"lrp",
|
||||||
|
"bfi",
|
||||||
"bitfield_extract",
|
"bitfield_extract",
|
||||||
"bitfield_insert",
|
"bitfield_insert",
|
||||||
"vector",
|
"vector",
|
||||||
|
@@ -1118,6 +1118,15 @@ enum ir_expression_operation {
|
|||||||
ir_binop_pack_half_2x16_split,
|
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.
|
* 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,
|
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,
|
ir_triop_bitfield_extract,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -37,6 +37,7 @@
|
|||||||
#define MOD_TO_FRACT 0x20
|
#define MOD_TO_FRACT 0x20
|
||||||
#define INT_DIV_TO_MUL_RCP 0x40
|
#define INT_DIV_TO_MUL_RCP 0x40
|
||||||
#define LRP_TO_ARITH 0x80
|
#define LRP_TO_ARITH 0x80
|
||||||
|
#define BITFIELD_INSERT_TO_BFM_BFI 0x100
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \see class lower_packing_builtins_visitor
|
* \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);
|
assert(ir->operands[1]->type == glsl_type::float_type);
|
||||||
break;
|
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:
|
case ir_binop_ubo_load:
|
||||||
assert(ir->operands[0]->as_constant());
|
assert(ir->operands[0]->as_constant());
|
||||||
assert(ir->operands[0]->type == glsl_type::uint_type);
|
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);
|
assert(ir->operands[2]->type == ir->operands[0]->type || ir->operands[2]->type == glsl_type::float_type);
|
||||||
break;
|
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:
|
case ir_triop_bitfield_extract:
|
||||||
assert(ir->operands[0]->type == ir->type);
|
assert(ir->operands[0]->type == ir->type);
|
||||||
assert(ir->operands[1]->type == glsl_type::int_type);
|
assert(ir->operands[1]->type == glsl_type::int_type);
|
||||||
|
@@ -38,6 +38,7 @@
|
|||||||
* - LOG_TO_LOG2
|
* - LOG_TO_LOG2
|
||||||
* - MOD_TO_FRACT
|
* - MOD_TO_FRACT
|
||||||
* - LRP_TO_ARITH
|
* - LRP_TO_ARITH
|
||||||
|
* - BITFIELD_INSERT_TO_BFM_BFI
|
||||||
*
|
*
|
||||||
* SUB_TO_ADD_NEG:
|
* SUB_TO_ADD_NEG:
|
||||||
* ---------------
|
* ---------------
|
||||||
@@ -84,6 +85,15 @@
|
|||||||
* LRP_TO_ARITH:
|
* LRP_TO_ARITH:
|
||||||
* -------------
|
* -------------
|
||||||
* Converts ir_triop_lrp to (op0 * (1.0f - op2)) + (op1 * op2).
|
* 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 */
|
#include "main/core.h" /* for M_LOG2E */
|
||||||
@@ -114,6 +124,7 @@ private:
|
|||||||
void pow_to_exp2(ir_expression *);
|
void pow_to_exp2(ir_expression *);
|
||||||
void log_to_log2(ir_expression *);
|
void log_to_log2(ir_expression *);
|
||||||
void lrp_to_arith(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;
|
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
|
ir_visitor_status
|
||||||
lower_instructions_visitor::visit_leave(ir_expression *ir)
|
lower_instructions_visitor::visit_leave(ir_expression *ir)
|
||||||
{
|
{
|
||||||
@@ -339,6 +373,11 @@ lower_instructions_visitor::visit_leave(ir_expression *ir)
|
|||||||
lrp_to_arith(ir);
|
lrp_to_arith(ir);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ir_quadop_bitfield_insert:
|
||||||
|
if (lowering(BITFIELD_INSERT_TO_BFM_BFI))
|
||||||
|
bitfield_insert_to_bfm_bfi(ir);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return visit_continue;
|
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]);
|
emit(ir, OPCODE_LRP, result_dst, op[2], op[1], op[0]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ir_binop_bfm:
|
||||||
|
case ir_triop_bfi:
|
||||||
case ir_triop_bitfield_extract:
|
case ir_triop_bitfield_extract:
|
||||||
case ir_quadop_bitfield_insert:
|
case ir_quadop_bitfield_insert:
|
||||||
assert(!"not supported");
|
assert(!"not supported");
|
||||||
|
@@ -1973,6 +1973,8 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
|
|||||||
case ir_unop_bit_count:
|
case ir_unop_bit_count:
|
||||||
case ir_unop_find_msb:
|
case ir_unop_find_msb:
|
||||||
case ir_unop_find_lsb:
|
case ir_unop_find_lsb:
|
||||||
|
case ir_binop_bfm:
|
||||||
|
case ir_triop_bfi:
|
||||||
case ir_triop_bitfield_extract:
|
case ir_triop_bitfield_extract:
|
||||||
case ir_quadop_bitfield_insert:
|
case ir_quadop_bitfield_insert:
|
||||||
case ir_quadop_vector:
|
case ir_quadop_vector:
|
||||||
|
Reference in New Issue
Block a user