ctx->f32 = LLVMFloatTypeInContext(ctx->context);
ctx->f64 = LLVMDoubleTypeInContext(ctx->context);
ctx->v2i16 = LLVMVectorType(ctx->i16, 2);
+ ctx->v4i16 = LLVMVectorType(ctx->i16, 4);
+ ctx->v2f16 = LLVMVectorType(ctx->f16, 2);
+ ctx->v4f16 = LLVMVectorType(ctx->f16, 4);
ctx->v2i32 = LLVMVectorType(ctx->i32, 2);
ctx->v3i32 = LLVMVectorType(ctx->i32, 3);
ctx->v4i32 = LLVMVectorType(ctx->i32, 4);
}
LLVMValueRef
-ac_build_shader_clock(struct ac_llvm_context *ctx)
+ac_build_shader_clock(struct ac_llvm_context *ctx, nir_scope scope)
{
- LLVMValueRef tmp = ac_build_intrinsic(ctx, "llvm.amdgcn.s.memtime", ctx->i64, NULL, 0, 0);
+ const char *name = scope == NIR_SCOPE_DEVICE ? "llvm.amdgcn.s.memrealtime" : "llvm.amdgcn.s.memtime";
+ LLVMValueRef tmp = ac_build_intrinsic(ctx, name, ctx->i64, NULL, 0, 0);
return LLVMBuildBitCast(ctx->builder, tmp, ctx->v2i32, "");
}
LLVMValueRef vindex,
LLVMValueRef voffset,
LLVMValueRef soffset,
- unsigned num_channels,
- LLVMTypeRef return_channel_type,
unsigned cache_policy,
bool use_format,
bool structurized)
args[idx++] = voffset ? voffset : ctx->i32_0;
args[idx++] = soffset ? soffset : ctx->i32_0;
args[idx++] = LLVMConstInt(ctx->i32, cache_policy, 0);
- unsigned func = !ac_has_vec3_support(ctx->chip_class, use_format) && num_channels == 3 ? 4 : num_channels;
const char *indexing_kind = structurized ? "struct" : "raw";
char name[256], type_name[8];
- LLVMTypeRef type = func > 1 ? LLVMVectorType(return_channel_type, func) : return_channel_type;
- ac_build_type_name_for_intr(type, type_name, sizeof(type_name));
+ ac_build_type_name_for_intr(LLVMTypeOf(data), type_name, sizeof(type_name));
if (use_format) {
snprintf(name, sizeof(name), "llvm.amdgcn.%s.buffer.store.format.%s",
LLVMValueRef data,
LLVMValueRef vindex,
LLVMValueRef voffset,
- unsigned num_channels,
unsigned cache_policy)
{
- ac_build_buffer_store_common(ctx, rsrc, data, vindex,
- voffset, NULL, num_channels,
- ctx->f32, cache_policy,
- true, true);
+ ac_build_buffer_store_common(ctx, rsrc, data, vindex, voffset, NULL,
+ cache_policy, true, true);
}
/* TBUFFER_STORE_FORMAT_{X,XY,XYZ,XYZW} <- the suffix is selected by num_channels=1..4.
ac_build_buffer_store_common(ctx, rsrc, ac_to_float(ctx, vdata),
ctx->i32_0, voffset, offset,
- num_channels, ctx->f32,
cache_policy, false, false);
return;
}
const char *indexing_kind = structurized ? "struct" : "raw";
char name[256], type_name[8];
+ /* D16 is only supported on gfx8+ */
+ assert(!use_format ||
+ (channel_type != ctx->f16 && channel_type != ctx->i16) ||
+ ctx->chip_class >= GFX8);
+
LLVMTypeRef type = func > 1 ? LLVMVectorType(channel_type, func) : channel_type;
ac_build_type_name_for_intr(type, type_name, sizeof(type_name));
LLVMValueRef voffset,
unsigned num_channels,
unsigned cache_policy,
- bool can_speculate)
+ bool can_speculate,
+ bool d16)
{
return ac_build_buffer_load_common(ctx, rsrc, vindex, voffset,
- ctx->i32_0, num_channels, ctx->f32,
+ ctx->i32_0, num_channels,
+ d16 ? ctx->f16 : ctx->f32,
cache_policy, can_speculate,
true, true);
}
}
int log_recombine = 0;
- if (ctx->chip_class == GFX6 && !known_aligned) {
+ if ((ctx->chip_class == GFX6 || ctx->chip_class == GFX10) && !known_aligned) {
/* Avoid alignment restrictions by loading one byte at a time. */
load_num_channels <<= load_log_size;
log_recombine = load_log_size;
if (LLVM_VERSION_MAJOR >= 9) {
/* LLVM 9+ supports i8/i16 with struct/raw intrinsics. */
ac_build_buffer_store_common(ctx, rsrc, vdata, NULL,
- voffset, soffset, 1,
- ctx->i16, cache_policy,
+ voffset, soffset, cache_policy,
false, false);
} else {
unsigned dfmt = V_008F0C_BUF_DATA_FORMAT_16;
if (LLVM_VERSION_MAJOR >= 9) {
/* LLVM 9+ supports i8/i16 with struct/raw intrinsics. */
ac_build_buffer_store_common(ctx, rsrc, vdata, NULL,
- voffset, soffset, 1,
- ctx->i8, cache_policy,
+ voffset, soffset, cache_policy,
false, false);
} else {
unsigned dfmt = V_008F0C_BUF_DATA_FORMAT_8;
if (result_type == ctx->f16)
val = LLVMBuildZExt(ctx->builder, val, ctx->i32, "");
+ else if (result_type == ctx->v2f16)
+ val = LLVMBuildBitCast(ctx->builder, val, ctx->i32, "");
for (unsigned i = 0; i < 4; ++i) {
tl_lanes[i] = i & mask;
LLVMValueRef ac_build_fmin(struct ac_llvm_context *ctx, LLVMValueRef a,
LLVMValueRef b)
{
- char name[64];
- snprintf(name, sizeof(name), "llvm.minnum.f%d", ac_get_elem_bits(ctx, LLVMTypeOf(a)));
+ char name[64], type[64];
+
+ ac_build_type_name_for_intr(LLVMTypeOf(a), type, sizeof(type));
+ snprintf(name, sizeof(name), "llvm.minnum.%s", type);
LLVMValueRef args[2] = {a, b};
return ac_build_intrinsic(ctx, name, LLVMTypeOf(a), args, 2,
AC_FUNC_ATTR_READNONE);
LLVMValueRef ac_build_fmax(struct ac_llvm_context *ctx, LLVMValueRef a,
LLVMValueRef b)
{
- char name[64];
- snprintf(name, sizeof(name), "llvm.maxnum.f%d", ac_get_elem_bits(ctx, LLVMTypeOf(a)));
+ char name[64], type[64];
+
+ ac_build_type_name_for_intr(LLVMTypeOf(a), type, sizeof(type));
+ snprintf(name, sizeof(name), "llvm.maxnum.%s", type);
LLVMValueRef args[2] = {a, b};
return ac_build_intrinsic(ctx, name, LLVMTypeOf(a), args, 2,
AC_FUNC_ATTR_READNONE);
args[1] = LLVMConstInt(ctx->i32, a->enabled_channels, 0);
if (a->compr) {
- LLVMTypeRef i16 = LLVMInt16TypeInContext(ctx->context);
- LLVMTypeRef v2i16 = LLVMVectorType(i16, 2);
-
args[2] = LLVMBuildBitCast(ctx->builder, a->out[0],
- v2i16, "");
+ ctx->v2i16, "");
args[3] = LLVMBuildBitCast(ctx->builder, a->out[1],
- v2i16, "");
+ ctx->v2i16, "");
args[4] = LLVMConstInt(ctx->i1, a->done, 0);
args[5] = LLVMConstInt(ctx->i1, a->valid_mask, 0);
assert((a->min_lod ? 1 : 0) +
(a->lod ? 1 : 0) +
(a->level_zero ? 1 : 0) <= 1);
+ assert(!a->d16 || (ctx->chip_class >= GFX8 &&
+ a->opcode != ac_image_atomic &&
+ a->opcode != ac_image_atomic_cmpswap &&
+ a->opcode != ac_image_get_lod &&
+ a->opcode != ac_image_get_resinfo));
if (a->opcode == ac_image_get_lod) {
switch (dim) {
a->min_lod ? ".cl" : "",
a->offset ? ".o" : "",
dimname,
- atomic ? "i32" : "v4f32",
+ atomic ? "i32" : (a->d16 ? "v4f16" : "v4f32"),
overload[0], overload[1], overload[2]);
LLVMTypeRef retty;
else if (a->opcode == ac_image_store || a->opcode == ac_image_store_mip)
retty = ctx->voidt;
else
- retty = ctx->v4f32;
+ retty = a->d16 ? ctx->v4f16 : ctx->v4f32;
LLVMValueRef result =
ac_build_intrinsic(ctx, intr_name, retty, args, num_args,
a->attributes);
- if (!sample && retty == ctx->v4f32) {
- result = LLVMBuildBitCast(ctx->builder, result,
- ctx->v4i32, "");
- }
+ if (!sample && !atomic && retty != ctx->voidt)
+ result = ac_to_integer(ctx, result);
+
return result;
}
LLVMValueRef ac_build_cvt_pkrtz_f16(struct ac_llvm_context *ctx,
LLVMValueRef args[2])
{
- LLVMTypeRef v2f16 =
- LLVMVectorType(LLVMHalfTypeInContext(ctx->context), 2);
-
- return ac_build_intrinsic(ctx, "llvm.amdgcn.cvt.pkrtz", v2f16,
+ return ac_build_intrinsic(ctx, "llvm.amdgcn.cvt.pkrtz", ctx->v2f16,
args, 2, AC_FUNC_ATTR_READNONE);
}
(LLVMValueRef []) { mask, ctx->i32_0 },
2, AC_FUNC_ATTR_READNONE);
}
- LLVMValueRef mask_vec = LLVMBuildBitCast(ctx->builder, mask,
- LLVMVectorType(ctx->i32, 2),
- "");
+ LLVMValueRef mask_vec = LLVMBuildBitCast(ctx->builder, mask, ctx->v2i32, "");
LLVMValueRef mask_lo = LLVMBuildExtractElement(ctx->builder, mask_vec,
ctx->i32_0, "");
LLVMValueRef mask_hi = LLVMBuildExtractElement(ctx->builder, mask_vec,