[Mesa-dev] [PATCH 09/24] ac: replace old image intrinsics with new ones

Marek Olšák maraeo at gmail.com
Sat Feb 25 23:58:07 UTC 2017


From: Marek Olšák <marek.olsak at amd.com>

---
 src/amd/common/ac_llvm_build.c | 80 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 80 insertions(+)

diff --git a/src/amd/common/ac_llvm_build.c b/src/amd/common/ac_llvm_build.c
index 3a1ef93..187c2cb 100644
--- a/src/amd/common/ac_llvm_build.c
+++ b/src/amd/common/ac_llvm_build.c
@@ -107,20 +107,34 @@ ac_emit_llvm_intrinsic(struct ac_llvm_context *ctx, const char *name,
 		if (!set_callsite_attrs)
 			ac_add_func_attributes(ctx->context, function, attrib_mask);
 	}
 
 	call = LLVMBuildCall(ctx->builder, function, params, param_count, "");
 	if (set_callsite_attrs)
 		ac_add_func_attributes(ctx->context, call, attrib_mask);
 	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).
  */
 void ac_build_type_name_for_intr(LLVMTypeRef type, char *buf, unsigned bufsize)
 {
 	LLVMTypeRef elem_type = type;
 
 	assert(bufsize >= 8);
 
@@ -935,20 +949,86 @@ void ac_emit_export(struct ac_llvm_context *ctx, struct ac_export_args *a)
 
 LLVMValueRef ac_emit_image_opcode(struct ac_llvm_context *ctx,
 				  struct ac_image_args *a)
 {
 	LLVMTypeRef dst_type;
 	LLVMValueRef args[11];
 	unsigned num_args = 0;
 	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;
 
 	if (a->opcode == ac_image_load ||
 	    a->opcode == ac_image_load_mip ||
 	    a->opcode == ac_image_get_resinfo) {
 		dst_type = ctx->v4i32;
 	} else {
 		dst_type = ctx->v4f32;
 		args[num_args++] = a->sampler;
-- 
2.7.4



More information about the mesa-dev mailing list