diff --git a/src/amd/compiler/aco_instruction_selection.cpp b/src/amd/compiler/aco_instruction_selection.cpp index f824ada5db2..4b3c5b366bb 100644 --- a/src/amd/compiler/aco_instruction_selection.cpp +++ b/src/amd/compiler/aco_instruction_selection.cpp @@ -6068,7 +6068,11 @@ static MIMG_instruction* emit_mimg(Builder& bld, aco_opcode op, Temp dst, Temp rsrc, Operand samp, std::vector coords, Operand vdata = Operand(v1)) { + bool is_vsample = !samp.isUndefined() || op == aco_opcode::image_msaa_load; + size_t nsa_size = bld.program->dev.max_nsa_vgprs; + if (!is_vsample && bld.program->gfx_level >= GFX12) + nsa_size++; /* VIMAGE can encode one more VADDR */ nsa_size = bld.program->gfx_level >= GFX11 || coords.size() <= nsa_size ? nsa_size : 0; const bool strict_wqm = coords[0].regClass().is_linear_vgpr(); diff --git a/src/amd/compiler/aco_ir.cpp b/src/amd/compiler/aco_ir.cpp index 09551902ba8..4dd55de7edb 100644 --- a/src/amd/compiler/aco_ir.cpp +++ b/src/amd/compiler/aco_ir.cpp @@ -175,7 +175,10 @@ init_program(Program* program, Stage stage, const struct aco_shader_info* info, program->dev.scratch_global_offset_max = 4095; } - if (program->gfx_level >= GFX11) { + if (program->gfx_level >= GFX12) { + /* Same as GFX11, except one less for VSAMPLE. */ + program->dev.max_nsa_vgprs = 3; + } else if (program->gfx_level >= GFX11) { /* GFX11 can have only 1 NSA dword. The last VGPR isn't included here because it contains the * rest of the address. */ diff --git a/src/amd/compiler/aco_validate.cpp b/src/amd/compiler/aco_validate.cpp index dd65110b237..53a92fa0c71 100644 --- a/src/amd/compiler/aco_validate.cpp +++ b/src/amd/compiler/aco_validate.cpp @@ -800,8 +800,11 @@ validate_ir(Program* program) check(instr->operands[i].regClass() == v1, "GFX10 MIMG VADDR must be v1 if NSA is used", instr.get()); } else { + unsigned num_scalar = + program->gfx_level >= GFX12 ? (instr->operands.size() - 4) : 4; if (instr->opcode != aco_opcode::image_bvh_intersect_ray && - instr->opcode != aco_opcode::image_bvh64_intersect_ray && i < 7) { + instr->opcode != aco_opcode::image_bvh64_intersect_ray && + i < 3 + num_scalar) { check(instr->operands[i].regClass() == v1, "first 4 GFX11 MIMG VADDR must be v1 if NSA is used", instr.get()); }