summaryrefslogtreecommitdiffstats
path: root/src/amd/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/amd/common')
-rw-r--r--src/amd/common/ac_llvm_build.c68
-rw-r--r--src/amd/common/ac_llvm_build.h29
2 files changed, 97 insertions, 0 deletions
diff --git a/src/amd/common/ac_llvm_build.c b/src/amd/common/ac_llvm_build.c
index bd1b63d40fa..3a1ef938e99 100644
--- a/src/amd/common/ac_llvm_build.c
+++ b/src/amd/common/ac_llvm_build.c
@@ -932,3 +932,71 @@ void ac_emit_export(struct ac_llvm_context *ctx, struct ac_export_args *a)
ac_emit_llvm_intrinsic(ctx, "llvm.SI.export", ctx->voidt, args, 9,
AC_FUNC_ATTR_LEGACY);
}
+
+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];
+
+ 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;
+ }
+
+ args[num_args++] = LLVMConstInt(ctx->i32, a->dmask, 0);
+ args[num_args++] = LLVMConstInt(ctx->i32, a->unorm, 0);
+ args[num_args++] = LLVMConstInt(ctx->i32, 0, 0); /* r128 */
+ args[num_args++] = LLVMConstInt(ctx->i32, a->da, 0);
+ args[num_args++] = LLVMConstInt(ctx->i32, 0, 0); /* glc */
+ args[num_args++] = LLVMConstInt(ctx->i32, 0, 0); /* slc */
+ args[num_args++] = LLVMConstInt(ctx->i32, 0, 0); /* tfe */
+ args[num_args++] = LLVMConstInt(ctx->i32, 0, 0); /* lwe */
+
+ switch (a->opcode) {
+ case ac_image_sample:
+ name = "llvm.SI.image.sample";
+ break;
+ case ac_image_gather4:
+ name = "llvm.SI.gather4";
+ break;
+ case ac_image_load:
+ name = "llvm.SI.image.load";
+ break;
+ case ac_image_load_mip:
+ name = "llvm.SI.image.load.mip";
+ break;
+ case ac_image_get_lod:
+ name = "llvm.SI.getlod";
+ break;
+ case ac_image_get_resinfo:
+ name = "llvm.SI.getresinfo";
+ break;
+ }
+
+ ac_build_type_name_for_intr(LLVMTypeOf(a->addr), type, sizeof(type));
+ snprintf(intr_name, sizeof(intr_name), "%s%s%s%s.%s",
+ name,
+ a->compare ? ".c" : "",
+ a->bias ? ".b" :
+ a->lod ? ".l" :
+ a->deriv ? ".d" :
+ a->level_zero ? ".lz" : "",
+ a->offset ? ".o" : "",
+ type);
+
+ return ac_emit_llvm_intrinsic(ctx, intr_name,
+ dst_type, args, num_args,
+ AC_FUNC_ATTR_READNONE |
+ AC_FUNC_ATTR_LEGACY);
+}
diff --git a/src/amd/common/ac_llvm_build.h b/src/amd/common/ac_llvm_build.h
index 27f2097a1c6..f57acc20663 100644
--- a/src/amd/common/ac_llvm_build.h
+++ b/src/amd/common/ac_llvm_build.h
@@ -205,6 +205,35 @@ struct ac_export_args {
void ac_emit_export(struct ac_llvm_context *ctx, struct ac_export_args *a);
+enum ac_image_opcode {
+ ac_image_sample,
+ ac_image_gather4,
+ ac_image_load,
+ ac_image_load_mip,
+ ac_image_get_lod,
+ ac_image_get_resinfo,
+};
+
+struct ac_image_args {
+ enum ac_image_opcode opcode;
+ bool level_zero;
+ bool bias;
+ bool lod;
+ bool deriv;
+ bool compare;
+ bool offset;
+
+ LLVMValueRef resource;
+ LLVMValueRef sampler;
+ LLVMValueRef addr;
+ unsigned dmask;
+ bool unorm;
+ bool da;
+};
+
+LLVMValueRef ac_emit_image_opcode(struct ac_llvm_context *ctx,
+ struct ac_image_args *a);
+
#ifdef __cplusplus
}
#endif