intel/brw: Add builder helpers that allocate temporary destinations

In many cases, we calculate an expression by generating a series of
instructions.  We'd either overwrite the same register repeatedly,
or call vgrf(BRW_TYPE_X) repeatedly to allocate temporaries for each
intermediate step.  In many cases, we overwrote the same register simply
because allocating and naming temporaries for each step was annoying.

This commit adds new builder helpers that will allocate a temporary
destination for you, using simple type interference: unary operations
use the source type, and binary operations require a matching base type
and return the largest of the two types.

The helpers return the destination register, allowing us to write in an
expression-tree style, chaining together builder operations to produce
whole values.  Sort of like nir_builder.  We still optionally will write
out the fs_inst pointer in case the caller wants to do things like set
predicates or saturation.

Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28957>
This commit is contained in:
Kenneth Graunke
2024-04-12 15:41:34 -07:00
committed by Marge Bot
parent 319ba85e10
commit 4c2c49f7bc

View File

@@ -553,15 +553,30 @@ namespace brw {
(dst.file >= VGRF && dst.stride != 0) || \
(dst.file < VGRF && dst.hstride != 0)); \
return emit(prefix##op, dst, src0); \
} \
fs_reg \
op(const fs_reg &src0, fs_inst **out = NULL) const \
{ \
fs_inst *inst = op(vgrf(src0.type), src0); \
if (out) *out = inst; \
return inst->dst; \
}
#define ALU1(op) _ALU1(BRW_OPCODE_, op)
#define VIRT1(op) _ALU1(SHADER_OPCODE_, op)
#define _ALU2(prefix, op) \
fs_inst * \
op(const fs_reg &dst, const fs_reg &src0, const fs_reg &src1) const \
{ \
return emit(prefix##op, dst, src0, src1); \
#define _ALU2(prefix, op) \
fs_inst * \
op(const fs_reg &dst, const fs_reg &src0, const fs_reg &src1) const \
{ \
return emit(prefix##op, dst, src0, src1); \
} \
fs_reg \
op(const fs_reg &src0, const fs_reg &src1, fs_inst **out = NULL) const \
{ \
assert(src0.type == src1.type); \
fs_inst *inst = op(vgrf(src0.type), src0, src1); \
if (out) *out = inst; \
return inst->dst; \
}
#define ALU2(op) _ALU2(BRW_OPCODE_, op)
#define VIRT2(op) _ALU2(SHADER_OPCODE_, op)