diff options
author | Marek Olšák <[email protected]> | 2017-02-23 23:37:59 +0100 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2017-03-03 15:29:30 +0100 |
commit | 4b2e5b93899eac2351a42f6ea3af9727a02d1fd5 (patch) | |
tree | f4b5821f70682f15fa0dee6769d298872a8ddd99 /src/amd | |
parent | c6a3911e5d1dc7a324be6015cb685a27f8627b51 (diff) |
ac: replace old image intrinsics with new ones
Reviewed-by: Dave Airlie <[email protected]>
Diffstat (limited to 'src/amd')
-rw-r--r-- | src/amd/common/ac_llvm_build.c | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/src/amd/common/ac_llvm_build.c b/src/amd/common/ac_llvm_build.c index 3a1ef938e99..187c2cb05e2 100644 --- a/src/amd/common/ac_llvm_build.c +++ b/src/amd/common/ac_llvm_build.c @@ -114,6 +114,20 @@ ac_emit_llvm_intrinsic(struct ac_llvm_context *ctx, const char *name, return call; } +static LLVMValueRef bitcast_to_float(struct ac_llvm_context *ctx, + LLVMValueRef value) +{ + LLVMTypeRef type = LLVMTypeOf(value); + LLVMTypeRef new_type; + + if (LLVMGetTypeKind(type) == LLVMVectorTypeKind) + new_type = LLVMVectorType(ctx->f32, LLVMGetVectorSize(type)); + else + new_type = ctx->f32; + + return LLVMBuildBitCast(ctx->builder, value, new_type, ""); +} + /** * Given the i32 or vNi32 \p type, generate the textual name (e.g. for use with * intrinsic names). @@ -942,6 +956,72 @@ LLVMValueRef ac_emit_image_opcode(struct ac_llvm_context *ctx, const char *name; char intr_name[128], type[64]; + if (HAVE_LLVM >= 0x0400) { + bool sample = a->opcode == ac_image_sample || + a->opcode == ac_image_gather4 || + a->opcode == ac_image_get_lod; + + if (sample) + args[num_args++] = bitcast_to_float(ctx, a->addr); + else + args[num_args++] = a->addr; + + args[num_args++] = a->resource; + if (sample) + args[num_args++] = a->sampler; + args[num_args++] = LLVMConstInt(ctx->i32, a->dmask, 0); + if (sample) + args[num_args++] = LLVMConstInt(ctx->i1, a->unorm, 0); + args[num_args++] = LLVMConstInt(ctx->i1, 0, 0); /* glc */ + args[num_args++] = LLVMConstInt(ctx->i1, 0, 0); /* slc */ + args[num_args++] = LLVMConstInt(ctx->i1, 0, 0); /* lwe */ + args[num_args++] = LLVMConstInt(ctx->i1, a->da, 0); + + switch (a->opcode) { + case ac_image_sample: + name = "llvm.amdgcn.image.sample"; + break; + case ac_image_gather4: + name = "llvm.amdgcn.image.gather4"; + break; + case ac_image_load: + name = "llvm.amdgcn.image.load"; + break; + case ac_image_load_mip: + name = "llvm.amdgcn.image.load.mip"; + break; + case ac_image_get_lod: + name = "llvm.amdgcn.image.getlod"; + break; + case ac_image_get_resinfo: + name = "llvm.amdgcn.image.getresinfo"; + break; + } + + ac_build_type_name_for_intr(LLVMTypeOf(args[0]), type, + sizeof(type)); + + snprintf(intr_name, sizeof(intr_name), "%s%s%s%s.v4f32.%s.v8i32", + name, + a->compare ? ".c" : "", + a->bias ? ".b" : + a->lod ? ".l" : + a->deriv ? ".d" : + a->level_zero ? ".lz" : "", + a->offset ? ".o" : "", + type); + + LLVMValueRef result = + ac_emit_llvm_intrinsic(ctx, intr_name, + ctx->v4f32, args, num_args, + AC_FUNC_ATTR_READNONE); + if (!sample) { + result = LLVMBuildBitCast(ctx->builder, result, + ctx->v4i32, ""); + } + return result; + } + args[num_args++] = a->addr; args[num_args++] = a->resource; |