<div dir="ltr"><div><div>For the series:<br><br></div>Acked-by: Marek Olšák <<a href="mailto:marek.olsak@amd.com">marek.olsak@amd.com</a>><br><br></div><div>Marek<br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Apr 11, 2018 at 7:13 AM, Nicolai Hähnle <span dir="ltr"><<a href="mailto:nhaehnle@gmail.com" target="_blank">nhaehnle@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">From: Nicolai Hähnle <<a href="mailto:nicolai.haehnle@amd.com">nicolai.haehnle@amd.com</a>><br>
<br>
Requires LLVM trunk r329166.<br>
---<br>
src/amd/common/ac_llvm_build.c | 189 ++++++++++++++++++++++++++++++<wbr>+++++------<br>
1 file changed, 165 insertions(+), 24 deletions(-)<br>
<br>
diff --git a/src/amd/common/ac_llvm_<wbr>build.c b/src/amd/common/ac_llvm_<wbr>build.c<br>
index b5561533437..15768d1d26d 100644<br>
--- a/src/amd/common/ac_llvm_<wbr>build.c<br>
+++ b/src/amd/common/ac_llvm_<wbr>build.c<br>
@@ -1462,39 +1462,47 @@ static unsigned ac_num_derivs(enum ac_image_dim dim)<br>
return 4;<br>
case ac_image_3d:<br>
return 6;<br>
case ac_image_2dmsaa:<br>
case ac_image_2darraymsaa:<br>
default:<br>
unreachable("derivatives not supported");<br>
}<br>
}<br>
<br>
-LLVMValueRef ac_build_image_opcode(struct ac_llvm_context *ctx,<br>
- struct ac_image_args *a)<br>
+static const char *get_atomic_name(enum ac_atomic_op op)<br>
+{<br>
+ switch (op) {<br>
+ case ac_atomic_swap: return "swap";<br>
+ case ac_atomic_add: return "add";<br>
+ case ac_atomic_sub: return "sub";<br>
+ case ac_atomic_smin: return "smin";<br>
+ case ac_atomic_umin: return "umin";<br>
+ case ac_atomic_smax: return "smax";<br>
+ case ac_atomic_umax: return "umax";<br>
+ case ac_atomic_and: return "and";<br>
+ case ac_atomic_or: return "or";<br>
+ case ac_atomic_xor: return "xor";<br>
+ }<br>
+ unreachable("bad atomic op");<br>
+}<br>
+<br>
+/* LLVM 6 and older */<br>
+static LLVMValueRef ac_build_image_opcode_llvm6(<wbr>struct ac_llvm_context *ctx,<br>
+ struct ac_image_args *a)<br>
{<br>
LLVMValueRef args[16];<br>
LLVMTypeRef retty = ctx->v4f32;<br>
const char *name = NULL;<br>
const char *atomic_subop = "";<br>
char intr_name[128], coords_type[64];<br>
<br>
- assert(!a->lod || a->lod == ctx->i32_0 || a->lod == ctx->f32_0 ||<br>
- !a->level_zero);<br>
- assert((a->opcode != ac_image_get_resinfo && a->opcode != ac_image_load_mip &&<br>
- a->opcode != ac_image_store_mip) ||<br>
- a->lod);<br>
- assert((a->bias ? 1 : 0) +<br>
- (a->lod ? 1 : 0) +<br>
- (a->level_zero ? 1 : 0) +<br>
- (a->derivs[0] ? 1 : 0) <= 1);<br>
-<br>
bool sample = a->opcode == ac_image_sample ||<br>
a->opcode == ac_image_gather4 ||<br>
a->opcode == ac_image_get_lod;<br>
bool atomic = a->opcode == ac_image_atomic ||<br>
a->opcode == ac_image_atomic_cmpswap;<br>
bool da = a->dim == ac_image_cube ||<br>
a->dim == ac_image_1darray ||<br>
a->dim == ac_image_2darray ||<br>
a->dim == ac_image_2darraymsaa;<br>
if (a->opcode == ac_image_get_lod)<br>
@@ -1578,32 +1586,21 @@ LLVMValueRef ac_build_image_opcode(struct ac_llvm_context *ctx,<br>
name = "llvm.amdgcn.image.store.mip";<br>
retty = ctx->voidt;<br>
break;<br>
case ac_image_atomic:<br>
case ac_image_atomic_cmpswap:<br>
name = "llvm.amdgcn.image.atomic.";<br>
retty = ctx->i32;<br>
if (a->opcode == ac_image_atomic_cmpswap) {<br>
atomic_subop = "cmpswap";<br>
} else {<br>
- switch (a->atomic) {<br>
- case ac_atomic_swap: atomic_subop = "swap"; break;<br>
- case ac_atomic_add: atomic_subop = "add"; break;<br>
- case ac_atomic_sub: atomic_subop = "sub"; break;<br>
- case ac_atomic_smin: atomic_subop = "smin"; break;<br>
- case ac_atomic_umin: atomic_subop = "umin"; break;<br>
- case ac_atomic_smax: atomic_subop = "smax"; break;<br>
- case ac_atomic_umax: atomic_subop = "umax"; break;<br>
- case ac_atomic_and: atomic_subop = "and"; break;<br>
- case ac_atomic_or: atomic_subop = "or"; break;<br>
- case ac_atomic_xor: atomic_subop = "xor"; break;<br>
- }<br>
+ atomic_subop = get_atomic_name(a->atomic);<br>
}<br>
break;<br>
case ac_image_get_lod:<br>
name = "llvm.amdgcn.image.getlod";<br>
break;<br>
case ac_image_get_resinfo:<br>
name = "llvm.amdgcn.image.getresinfo"<wbr>;<br>
break;<br>
default:<br>
unreachable("invalid image opcode");<br>
@@ -1633,20 +1630,164 @@ LLVMValueRef ac_build_image_opcode(struct ac_llvm_context *ctx,<br>
LLVMValueRef result =<br>
ac_build_intrinsic(ctx, intr_name, retty, args, num_args,<br>
a->attributes);<br>
if (!sample && retty == ctx->v4f32) {<br>
result = LLVMBuildBitCast(ctx->builder, result,<br>
ctx->v4i32, "");<br>
}<br>
return result;<br>
}<br>
<br>
+LLVMValueRef ac_build_image_opcode(struct ac_llvm_context *ctx,<br>
+ struct ac_image_args *a)<br>
+{<br>
+ const char *overload[3] = { "", "", "" };<br>
+ unsigned num_overloads = 0;<br>
+ LLVMValueRef args[18];<br>
+ unsigned num_args = 0;<br>
+<br>
+ assert(!a->lod || a->lod == ctx->i32_0 || a->lod == ctx->f32_0 ||<br>
+ !a->level_zero);<br>
+ assert((a->opcode != ac_image_get_resinfo && a->opcode != ac_image_load_mip &&<br>
+ a->opcode != ac_image_store_mip) ||<br>
+ a->lod);<br>
+ assert(a->opcode == ac_image_sample || a->opcode == ac_image_gather4 ||<br>
+ (!a->compare && !a->offset));<br>
+ assert((a->opcode == ac_image_sample || a->opcode == ac_image_gather4 ||<br>
+ a->opcode == ac_image_get_lod) ||<br>
+ !a->bias);<br>
+ assert((a->bias ? 1 : 0) +<br>
+ (a->lod ? 1 : 0) +<br>
+ (a->level_zero ? 1 : 0) +<br>
+ (a->derivs[0] ? 1 : 0) <= 1);<br>
+<br>
+ if (HAVE_LLVM < 0x0700)<br>
+ return ac_build_image_opcode_llvm6(<wbr>ctx, a);<br>
+<br>
+ bool sample = a->opcode == ac_image_sample ||<br>
+ a->opcode == ac_image_gather4 ||<br>
+ a->opcode == ac_image_get_lod;<br>
+ bool atomic = a->opcode == ac_image_atomic ||<br>
+ a->opcode == ac_image_atomic_cmpswap;<br>
+ LLVMTypeRef coord_type = sample ? ctx->f32 : ctx->i32;<br>
+<br>
+ if (atomic || a->opcode == ac_image_store || a->opcode == ac_image_store_mip) {<br>
+ args[num_args++] = a->data[0];<br>
+ if (a->opcode == ac_image_atomic_cmpswap)<br>
+ args[num_args++] = a->data[1];<br>
+ }<br>
+<br>
+ if (!atomic)<br>
+ args[num_args++] = LLVMConstInt(ctx->i32, a->dmask, false);<br>
+<br>
+ if (a->offset)<br>
+ args[num_args++] = ac_to_integer(ctx, a->offset);<br>
+ if (a->bias) {<br>
+ args[num_args++] = ac_to_float(ctx, a->bias);<br>
+ overload[num_overloads++] = ".f32";<br>
+ }<br>
+ if (a->compare)<br>
+ args[num_args++] = ac_to_float(ctx, a->compare);<br>
+ if (a->derivs[0]) {<br>
+ unsigned count = ac_num_derivs(a->dim);<br>
+ for (unsigned i = 0; i < count; ++i)<br>
+ args[num_args++] = ac_to_float(ctx, a->derivs[i]);<br>
+ overload[num_overloads++] = ".f32";<br>
+ }<br>
+ unsigned num_coords =<br>
+ a->opcode != ac_image_get_resinfo ? ac_num_coords(a->dim) : 0;<br>
+ for (unsigned i = 0; i < num_coords; ++i)<br>
+ args[num_args++] = LLVMBuildBitCast(ctx->builder, a->coords[i], coord_type, "");<br>
+ if (a->lod)<br>
+ args[num_args++] = LLVMBuildBitCast(ctx->builder, a->lod, coord_type, "");<br>
+ overload[num_overloads++] = sample ? ".f32" : ".i32";<br>
+<br>
+ args[num_args++] = a->resource;<br>
+ if (sample) {<br>
+ args[num_args++] = a->sampler;<br>
+ args[num_args++] = LLVMConstInt(ctx->i1, a->unorm, false);<br>
+ }<br>
+<br>
+ args[num_args++] = ctx->i32_0; /* texfailctrl */<br>
+ args[num_args++] = LLVMConstInt(ctx->i32, a->cache_policy, false);<br>
+<br>
+ const char *name;<br>
+ const char *atomic_subop = "";<br>
+ switch (a->opcode) {<br>
+ case ac_image_sample: name = "sample"; break;<br>
+ case ac_image_gather4: name = "gather4"; break;<br>
+ case ac_image_load: name = "load"; break;<br>
+ case ac_image_load_mip: name = "load.mip"; break;<br>
+ case ac_image_store: name = "store"; break;<br>
+ case ac_image_store_mip: name = "store.mip"; break;<br>
+ case ac_image_atomic:<br>
+ name = "atomic.";<br>
+ atomic_subop = get_atomic_name(a->atomic);<br>
+ break;<br>
+ case ac_image_atomic_cmpswap:<br>
+ name = "atomic.";<br>
+ atomic_subop = "cmpswap";<br>
+ break;<br>
+ case ac_image_get_lod: name = "getlod"; break;<br>
+ case ac_image_get_resinfo: name = "getresinfo"; break;<br>
+ default: unreachable("invalid image opcode");<br>
+ }<br>
+<br>
+ const char *dimname;<br>
+ switch (a->dim) {<br>
+ case ac_image_1d: dimname = "1d"; break;<br>
+ case ac_image_2d: dimname = "2d"; break;<br>
+ case ac_image_3d: dimname = "3d"; break;<br>
+ case ac_image_cube: dimname = "cube"; break;<br>
+ case ac_image_1darray: dimname = "1darray"; break;<br>
+ case ac_image_2darray: dimname = "2darray"; break;<br>
+ case ac_image_2dmsaa: dimname = "2dmsaa"; break;<br>
+ case ac_image_2darraymsaa: dimname = "2darraymsaa"; break;<br>
+ default: unreachable("invalid dim");<br>
+ }<br>
+<br>
+ bool lod_suffix =<br>
+ a->lod && (a->opcode == ac_image_sample || a->opcode == ac_image_gather4);<br>
+ char intr_name[96];<br>
+ snprintf(intr_name, sizeof(intr_name),<br>
+ "llvm.amdgcn.image.%s%s" /* base name */<br>
+ "%s%s%s" /* sample/gather modifiers */<br>
+ ".%s.%s%s%s%s", /* dimension and type overloads */<br>
+ name, atomic_subop,<br>
+ a->compare ? ".c" : "",<br>
+ a->bias ? ".b" :<br>
+ lod_suffix ? ".l" :<br>
+ a->derivs[0] ? ".d" :<br>
+ a->level_zero ? ".lz" : "",<br>
+ a->offset ? ".o" : "",<br>
+ dimname,<br>
+ atomic ? "i32" : "v4f32",<br>
+ overload[0], overload[1], overload[2]);<br>
+<br>
+ LLVMTypeRef retty;<br>
+ if (atomic)<br>
+ retty = ctx->i32;<br>
+ else if (a->opcode == ac_image_store || a->opcode == ac_image_store_mip)<br>
+ retty = ctx->voidt;<br>
+ else<br>
+ retty = ctx->v4f32;<br>
+<br>
+ LLVMValueRef result =<br>
+ ac_build_intrinsic(ctx, intr_name, retty, args, num_args,<br>
+ a->attributes);<br>
+ if (!sample && retty == ctx->v4f32) {<br>
+ result = LLVMBuildBitCast(ctx->builder, result,<br>
+ ctx->v4i32, "");<br>
+ }<br>
+ return result;<br>
+}<br>
+<br>
LLVMValueRef ac_build_cvt_pkrtz_f16(struct ac_llvm_context *ctx,<br>
LLVMValueRef args[2])<br>
{<br>
if (HAVE_LLVM >= 0x0500) {<br>
LLVMTypeRef v2f16 =<br>
LLVMVectorType(<wbr>LLVMHalfTypeInContext(ctx-><wbr>context), 2);<br>
LLVMValueRef res =<br>
ac_build_intrinsic(ctx, "llvm.amdgcn.cvt.pkrtz",<br>
v2f16, args, 2,<br>
AC_FUNC_ATTR_READNONE);<br>
<span class="HOEnZb"><font color="#888888">-- <br>
2.14.1<br>
<br>
______________________________<wbr>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div>