diff options
Diffstat (limited to 'src/amd/common')
-rw-r--r-- | src/amd/common/ac_llvm_build.c | 68 | ||||
-rw-r--r-- | src/amd/common/ac_llvm_build.h | 29 |
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 |