nir: add skip_lower_packing_ops shader compile option

Drivers like radeonsi and radv prefer to not lowering
some packing ops.

Signed-off-by: Qiang Yu <yuq825@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30885>
This commit is contained in:
Qiang Yu
2024-08-28 11:35:07 +08:00
committed by Marge Bot
parent 6c1d0b82fb
commit d43c5003fc
2 changed files with 62 additions and 38 deletions

View File

@@ -3803,6 +3803,18 @@ typedef enum {
nir_io_glsl_opt_varyings = BITFIELD_BIT(17),
} nir_io_options;
typedef enum {
nir_lower_packing_op_pack_64_2x32,
nir_lower_packing_op_unpack_64_2x32,
nir_lower_packing_op_pack_64_4x16,
nir_lower_packing_op_unpack_64_4x16,
nir_lower_packing_op_pack_32_2x16,
nir_lower_packing_op_unpack_32_2x16,
nir_lower_packing_op_pack_32_4x8,
nir_lower_packing_op_unpack_32_4x8,
nir_lower_packing_num_ops,
} nir_lower_packing_op;
/** An instruction filtering callback
*
* Returns true if the instruction should be processed and false otherwise.
@@ -4330,6 +4342,12 @@ typedef struct nir_shader_compiler_options {
/** Options determining lowering and behavior of inputs and outputs. */
nir_io_options io_options;
/**
* Bit mask of nir_lower_packing_op to skip lowering some nir ops in
* nir_lower_packing().
*/
unsigned skip_lower_packing_ops;
/** Driver callback where drivers can define how to lower mediump.
* Used by nir_lower_io_passes.
*/

View File

@@ -131,49 +131,55 @@ lower_unpack_32_to_8(nir_builder *b, nir_def *src)
static bool
lower_pack_instr(nir_builder *b, nir_alu_instr *alu_instr, void *data)
{
if (alu_instr->op != nir_op_pack_64_2x32 &&
alu_instr->op != nir_op_unpack_64_2x32 &&
alu_instr->op != nir_op_pack_64_4x16 &&
alu_instr->op != nir_op_unpack_64_4x16 &&
alu_instr->op != nir_op_pack_32_2x16 &&
alu_instr->op != nir_op_unpack_32_2x16 &&
alu_instr->op != nir_op_pack_32_4x8 &&
alu_instr->op != nir_op_unpack_32_4x8)
nir_lower_packing_op op;
switch (alu_instr->op) {
case nir_op_pack_64_2x32:
op = nir_lower_packing_op_pack_64_2x32;
break;
case nir_op_unpack_64_2x32:
op = nir_lower_packing_op_unpack_64_2x32;
break;
case nir_op_pack_64_4x16:
op = nir_lower_packing_op_pack_64_4x16;
break;
case nir_op_unpack_64_4x16:
op = nir_lower_packing_op_unpack_64_4x16;
break;
case nir_op_pack_32_2x16:
op = nir_lower_packing_op_pack_32_2x16;
break;
case nir_op_unpack_32_2x16:
op = nir_lower_packing_op_unpack_32_2x16;
break;
case nir_op_pack_32_4x8:
op = nir_lower_packing_op_pack_32_4x8;
break;
case nir_op_unpack_32_4x8:
op = nir_lower_packing_op_unpack_32_4x8;
break;
default:
return false;
}
if (b->shader->options->skip_lower_packing_ops & BITFIELD_BIT(op))
return false;
b->cursor = nir_before_instr(&alu_instr->instr);
nir_def *src = nir_ssa_for_alu_src(b, alu_instr, 0);
nir_def *dest;
typedef nir_def *(*lower_func_t)(nir_builder *b, nir_def *src);
static const lower_func_t lower_funcs[nir_lower_packing_num_ops] = {
[nir_lower_packing_op_pack_64_2x32] = lower_pack_64_from_32,
[nir_lower_packing_op_unpack_64_2x32] = lower_unpack_64_to_32,
[nir_lower_packing_op_pack_64_4x16] = lower_pack_64_from_16,
[nir_lower_packing_op_unpack_64_4x16] = lower_unpack_64_to_16,
[nir_lower_packing_op_pack_32_2x16] = lower_pack_32_from_16,
[nir_lower_packing_op_unpack_32_2x16] = lower_unpack_32_to_16,
[nir_lower_packing_op_pack_32_4x8] = lower_pack_32_from_8,
[nir_lower_packing_op_unpack_32_4x8] = lower_unpack_32_to_8,
};
switch (alu_instr->op) {
case nir_op_pack_64_2x32:
dest = lower_pack_64_from_32(b, src);
break;
case nir_op_unpack_64_2x32:
dest = lower_unpack_64_to_32(b, src);
break;
case nir_op_pack_64_4x16:
dest = lower_pack_64_from_16(b, src);
break;
case nir_op_unpack_64_4x16:
dest = lower_unpack_64_to_16(b, src);
break;
case nir_op_pack_32_2x16:
dest = lower_pack_32_from_16(b, src);
break;
case nir_op_unpack_32_2x16:
dest = lower_unpack_32_to_16(b, src);
break;
case nir_op_pack_32_4x8:
dest = lower_pack_32_from_8(b, src);
break;
case nir_op_unpack_32_4x8:
dest = lower_unpack_32_to_8(b, src);
break;
default:
unreachable("Impossible opcode");
}
nir_def *src = nir_ssa_for_alu_src(b, alu_instr, 0);
nir_def *dest = lower_funcs[op](b, src);
nir_def_replace(&alu_instr->def, dest);
return true;