From 7168425dd77f37fa048de5a4639619763556c331 Mon Sep 17 00:00:00 2001 From: Connor Abbott Date: Wed, 7 Jun 2017 14:16:31 -0700 Subject: [PATCH] ac/nir: implement 64-bit packing and unpacking We implement the split opcodes, and tell NIR to lower the original ones. The lowering to LLVM is a little more complicated, but NIR can optimize the split ones a little better, and some NIR lowering passes that we might want to use (particularly for doubles) emit the split ones. This should fix pack/unpackDouble2x32, which seems like a bug since when we enabled the Float64 capability. It will also fix pack/unpackInt2x32 when we enable the Int64 capability. Fixes: 798ae37c ("radv: Enable Float64 support.") Signed-off-by: Connor Abbott Reviewed-by: Bas Nieuwenhuizen --- src/amd/common/ac_nir_to_llvm.c | 31 +++++++++++++++++++++++++++++++ src/amd/vulkan/radv_pipeline.c | 1 + 2 files changed, 32 insertions(+) diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c index 51daa3cff36..88f3f44e92c 100644 --- a/src/amd/common/ac_nir_to_llvm.c +++ b/src/amd/common/ac_nir_to_llvm.c @@ -1866,6 +1866,37 @@ static void visit_alu(struct nir_to_llvm_context *ctx, const nir_alu_instr *inst case nir_op_fddy_coarse: result = emit_ddxy(ctx, instr->op, src[0]); break; + + case nir_op_unpack_64_2x32_split_x: { + assert(instr->src[0].src.ssa->num_components == 1); + LLVMValueRef tmp = LLVMBuildBitCast(ctx->builder, src[0], + LLVMVectorType(ctx->i32, 2), + ""); + result = LLVMBuildExtractElement(ctx->builder, tmp, + ctx->i32zero, ""); + break; + } + + case nir_op_unpack_64_2x32_split_y: { + assert(instr->src[0].src.ssa->num_components == 1); + LLVMValueRef tmp = LLVMBuildBitCast(ctx->builder, src[0], + LLVMVectorType(ctx->i32, 2), + ""); + result = LLVMBuildExtractElement(ctx->builder, tmp, + ctx->i32one, ""); + break; + } + + case nir_op_pack_64_2x32_split: { + LLVMValueRef tmp = LLVMGetUndef(LLVMVectorType(ctx->i32, 2)); + tmp = LLVMBuildInsertElement(ctx->builder, tmp, + src[0], ctx->i32zero, ""); + tmp = LLVMBuildInsertElement(ctx->builder, tmp, + src[1], ctx->i32one, ""); + result = LLVMBuildBitCast(ctx->builder, tmp, ctx->i64, ""); + break; + } + default: fprintf(stderr, "Unknown NIR alu instr: "); nir_print_instr(&instr->instr, stderr); diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c index efe641dc0be..d05acd28506 100644 --- a/src/amd/vulkan/radv_pipeline.c +++ b/src/amd/vulkan/radv_pipeline.c @@ -151,6 +151,7 @@ radv_optimize_nir(struct nir_shader *shader) progress = false; NIR_PASS_V(shader, nir_lower_vars_to_ssa); + NIR_PASS_V(shader, nir_lower_64bit_pack); NIR_PASS_V(shader, nir_lower_alu_to_scalar); NIR_PASS_V(shader, nir_lower_phis_to_scalar); -- 2.30.2