summaryrefslogtreecommitdiffstats
path: root/src/amd
diff options
context:
space:
mode:
Diffstat (limited to 'src/amd')
-rw-r--r--src/amd/common/ac_llvm_build.c80
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;