From d6727373725e080b46f010651d8ceab3e1a5da24 Mon Sep 17 00:00:00 2001 From: Georg Lehmann Date: Mon, 14 Jul 2025 13:49:53 +0200 Subject: [PATCH] nir,aco: add byte_perm_amd MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Acked-by: Daniel Schürmann Part-of: --- .../instruction_selection/aco_isel_setup.cpp | 1 + .../aco_select_nir_alu.cpp | 8 +++++++ src/compiler/nir/nir_opcodes.py | 22 +++++++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/src/amd/compiler/instruction_selection/aco_isel_setup.cpp b/src/amd/compiler/instruction_selection/aco_isel_setup.cpp index 50b2c0a5f54..d351dccf21d 100644 --- a/src/amd/compiler/instruction_selection/aco_isel_setup.cpp +++ b/src/amd/compiler/instruction_selection/aco_isel_setup.cpp @@ -447,6 +447,7 @@ init_context(isel_context* ctx, nir_shader* shader) case nir_op_udot_2x16_uadd_sat: case nir_op_sdot_2x16_iadd_sat: case nir_op_bfdot2_bfadd: + case nir_op_byte_perm_amd: case nir_op_alignbyte_amd: type = RegType::vgpr; break; case nir_op_fmul: case nir_op_ffma: diff --git a/src/amd/compiler/instruction_selection/aco_select_nir_alu.cpp b/src/amd/compiler/instruction_selection/aco_select_nir_alu.cpp index eb5baa76db0..74ff68baf71 100644 --- a/src/amd/compiler/instruction_selection/aco_select_nir_alu.cpp +++ b/src/amd/compiler/instruction_selection/aco_select_nir_alu.cpp @@ -3261,6 +3261,14 @@ visit_alu_instr(isel_context* ctx, nir_alu_instr* instr) } break; } + case nir_op_byte_perm_amd: { + if (dst.regClass() == v1) { + emit_vop3a_instruction(ctx, instr, aco_opcode::v_perm_b32, dst, false, 3u); + } else { + isel_err(&instr->instr, "Unimplemented NIR instr bit size"); + } + break; + } case nir_op_fquantize2f16: { Temp src = get_alu_src(ctx, instr->src[0]); if (dst.regClass() == v1) { diff --git a/src/compiler/nir/nir_opcodes.py b/src/compiler/nir/nir_opcodes.py index 05a100201dd..a0a06439f60 100644 --- a/src/compiler/nir/nir_opcodes.py +++ b/src/compiler/nir/nir_opcodes.py @@ -1327,6 +1327,28 @@ opcode("alignbyte_amd", 0, tuint32, [0, 0, 0], [tuint32, tuint32, tuint32], Fals dst = src >> ((src2 & 0x3) * 8); """) +# AMD specific: Byte swizzle within 64-bits of source data +# Operand order matches v_perm_b32, src0 contains the MSBs +# and src1 the LSBs of the data. +opcode("byte_perm_amd", 0, tuint32, [0, 0, 0], [tuint32, tuint32, tuint32], False, "", """ + uint64_t src = src1 | ((uint64_t)src0 << 32); + dst = 0; + for (unsigned i = 0; i < 4; i++) { + uint8_t sel = (src2 >> (i * 8)) & 0xff; + unsigned res; + if (sel >= 13) { + res = 0xff; + } else if (sel == 12) { + res = 0; + } else if (sel >= 8) { + res = ((src >> (((sel - 8) * 2 + 1) * 8 + 7)) & 1) * 0xff; + } else { + res = (src >> (sel * 8)) & 0xff; + } + dst |= res << (i * 8); + } +""") + # Midgard specific sin and cos # These expect their inputs to be divided by pi. unop("fsin_mdg", tfloat, "sinf(3.141592653589793 * src0)")