From b52bf8f12a60fae4048ee99455a3b1334941f383 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Nicolai=20H=C3=A4hnle?= Date: Mon, 25 Mar 2019 18:12:07 +0100 Subject: [PATCH] amd/common/gfx10: support new tbuffer encoding Acked-by: Bas Nieuwenhuizen --- src/amd/common/ac_llvm_build.c | 47 ++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/src/amd/common/ac_llvm_build.c b/src/amd/common/ac_llvm_build.c index f0c96442b2e..ecb72395867 100644 --- a/src/amd/common/ac_llvm_build.c +++ b/src/amd/common/ac_llvm_build.c @@ -1486,6 +1486,49 @@ LLVMValueRef ac_build_buffer_load_format_gfx9_safe(struct ac_llvm_context *ctx, can_speculate, true); } +/// Translate a (dfmt, nfmt) pair into a chip-appropriate combined format +/// value for LLVM8+ tbuffer intrinsics. +static unsigned +ac_get_tbuffer_format(struct ac_llvm_context *ctx, + unsigned dfmt, unsigned nfmt) +{ + if (ctx->chip_class >= GFX10) { + unsigned format; + switch (dfmt) { + default: unreachable("bad dfmt"); + case V_008F0C_BUF_DATA_FORMAT_8: format = V_008F0C_IMG_FORMAT_8_UINT; break; + case V_008F0C_BUF_DATA_FORMAT_8_8: format = V_008F0C_IMG_FORMAT_8_8_UINT; break; + case V_008F0C_BUF_DATA_FORMAT_8_8_8_8: format = V_008F0C_IMG_FORMAT_8_8_8_8_UINT; break; + case V_008F0C_BUF_DATA_FORMAT_16: format = V_008F0C_IMG_FORMAT_16_UINT; break; + case V_008F0C_BUF_DATA_FORMAT_16_16: format = V_008F0C_IMG_FORMAT_16_16_UINT; break; + case V_008F0C_BUF_DATA_FORMAT_16_16_16_16: format = V_008F0C_IMG_FORMAT_16_16_16_16_UINT; break; + case V_008F0C_BUF_DATA_FORMAT_32: format = V_008F0C_IMG_FORMAT_32_UINT; break; + case V_008F0C_BUF_DATA_FORMAT_32_32: format = V_008F0C_IMG_FORMAT_32_32_UINT; break; + case V_008F0C_BUF_DATA_FORMAT_32_32_32_32: format = V_008F0C_IMG_FORMAT_32_32_32_32_UINT; break; + } + + // Use the regularity properties of the combined format enum. + // + // Note: float is incompatible with 8-bit data formats, + // [us]{norm,scaled} are incomparible with 32-bit data formats. + // [us]scaled are not writable. + switch (nfmt) { + case V_008F0C_BUF_NUM_FORMAT_UNORM: format -= 4; break; + case V_008F0C_BUF_NUM_FORMAT_SNORM: format -= 3; break; + case V_008F0C_BUF_NUM_FORMAT_USCALED: format -= 2; break; + case V_008F0C_BUF_NUM_FORMAT_SSCALED: format -= 1; break; + default: unreachable("bad nfmt"); + case V_008F0C_BUF_NUM_FORMAT_UINT: break; + case V_008F0C_BUF_NUM_FORMAT_SINT: format += 1; break; + case V_008F0C_BUF_NUM_FORMAT_FLOAT: format += 2; break; + } + + return format; + } else { + return dfmt | (nfmt << 4); + } +} + static LLVMValueRef ac_build_llvm8_tbuffer_load(struct ac_llvm_context *ctx, LLVMValueRef rsrc, @@ -1507,7 +1550,7 @@ ac_build_llvm8_tbuffer_load(struct ac_llvm_context *ctx, args[idx++] = vindex ? vindex : ctx->i32_0; args[idx++] = voffset ? voffset : ctx->i32_0; args[idx++] = soffset ? soffset : ctx->i32_0; - args[idx++] = LLVMConstInt(ctx->i32, dfmt | (nfmt << 4), 0); + args[idx++] = LLVMConstInt(ctx->i32, ac_get_tbuffer_format(ctx, dfmt, nfmt), 0); args[idx++] = LLVMConstInt(ctx->i32, (glc ? 1 : 0) + (slc ? 2 : 0), 0); unsigned func = !ac_has_vec3_support(ctx->chip_class, true) && num_channels == 3 ? 4 : num_channels; const char *indexing_kind = structurized ? "struct" : "raw"; @@ -2005,7 +2048,7 @@ ac_build_llvm8_tbuffer_store(struct ac_llvm_context *ctx, args[idx++] = vindex ? vindex : ctx->i32_0; args[idx++] = voffset ? voffset : ctx->i32_0; args[idx++] = soffset ? soffset : ctx->i32_0; - args[idx++] = LLVMConstInt(ctx->i32, dfmt | (nfmt << 4), 0); + args[idx++] = LLVMConstInt(ctx->i32, ac_get_tbuffer_format(ctx, dfmt, nfmt), 0); args[idx++] = LLVMConstInt(ctx->i32, (glc ? 1 : 0) + (slc ? 2 : 0), 0); unsigned func = !ac_has_vec3_support(ctx->chip_class, true) && num_channels == 3 ? 4 : num_channels; const char *indexing_kind = structurized ? "struct" : "raw"; -- 2.30.2