Mesa (master): amd/common: Extract some helper functions to ac_shader_util.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Sep 26 13:58:00 UTC 2019


Module: Mesa
Branch: master
Commit: db1fddcf0fa91a71282b439fe0406d26585eab9f
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=db1fddcf0fa91a71282b439fe0406d26585eab9f

Author: Timur Kristóf <timur.kristof at gmail.com>
Date:   Wed Sep 25 14:10:18 2019 +0200

amd/common: Extract some helper functions to ac_shader_util.

This commit moves ac_get_tbuffer_format, ac_get_sampler_dim and
ac_get_image_dim into ac_shader_util, thus enabling them to be used
by compilers other than LLVM.

Signed-off-by: Timur Kristóf <timur.kristof at gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
Reviewed-by: Marek Olšák <marek.olsak at amd.com>

---

 src/amd/common/ac_llvm_build.c  | 50 +--------------------
 src/amd/common/ac_llvm_build.h  | 12 +----
 src/amd/common/ac_nir_to_llvm.c | 65 +++------------------------
 src/amd/common/ac_shader_util.c | 97 +++++++++++++++++++++++++++++++++++++++++
 src/amd/common/ac_shader_util.h | 24 ++++++++++
 5 files changed, 131 insertions(+), 117 deletions(-)

diff --git a/src/amd/common/ac_llvm_build.c b/src/amd/common/ac_llvm_build.c
index fb5479c8948..44092a39487 100644
--- a/src/amd/common/ac_llvm_build.c
+++ b/src/amd/common/ac_llvm_build.c
@@ -1383,52 +1383,6 @@ LLVMValueRef ac_build_buffer_load_format(struct ac_llvm_context *ctx,
 					   true, 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_INVALID: format = V_008F0C_IMG_FORMAT_INVALID; break;
-		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: format = V_008F0C_IMG_FORMAT_32_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;
-		case V_008F0C_BUF_DATA_FORMAT_2_10_10_10: format = V_008F0C_IMG_FORMAT_2_10_10_10_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_tbuffer_load(struct ac_llvm_context *ctx,
 			    LLVMValueRef rsrc,
@@ -1452,7 +1406,7 @@ ac_build_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, ac_get_tbuffer_format(ctx, dfmt, nfmt), 0);
+	args[idx++] = LLVMConstInt(ctx->i32, ac_get_tbuffer_format(ctx->chip_class, dfmt, nfmt), 0);
 	args[idx++] = LLVMConstInt(ctx->i32, get_load_cache_policy(ctx, cache_policy), 0);
 	unsigned func = !ac_has_vec3_support(ctx->chip_class, true) && num_channels == 3 ? 4 : num_channels;
 	const char *indexing_kind = structurized ? "struct" : "raw";
@@ -1896,7 +1850,7 @@ ac_build_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, ac_get_tbuffer_format(ctx, dfmt, nfmt), 0);
+	args[idx++] = LLVMConstInt(ctx->i32, ac_get_tbuffer_format(ctx->chip_class, dfmt, nfmt), 0);
 	args[idx++] = LLVMConstInt(ctx->i32, cache_policy, 0);
 	unsigned func = !ac_has_vec3_support(ctx->chip_class, true) && num_channels == 3 ? 4 : num_channels;
 	const char *indexing_kind = structurized ? "struct" : "raw";
diff --git a/src/amd/common/ac_llvm_build.h b/src/amd/common/ac_llvm_build.h
index 676c1ee2758..8d85ae62fc7 100644
--- a/src/amd/common/ac_llvm_build.h
+++ b/src/amd/common/ac_llvm_build.h
@@ -29,6 +29,7 @@
 #include <llvm-c/Core.h>
 #include "compiler/nir/nir.h"
 #include "amd_family.h"
+#include "ac_shader_util.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -521,17 +522,6 @@ enum ac_atomic_op {
 	ac_atomic_dec_wrap,
 };
 
-enum ac_image_dim {
-	ac_image_1d,
-	ac_image_2d,
-	ac_image_3d,
-	ac_image_cube, // includes cube arrays
-	ac_image_1darray,
-	ac_image_2darray,
-	ac_image_2dmsaa,
-	ac_image_2darraymsaa,
-};
-
 /* These cache policy bits match the definitions used by the LLVM intrinsics. */
 enum ac_image_cache_policy {
 	ac_glc = 1 << 0, /* per-CU cache control */
diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c
index 074584227c1..781f9ae1258 100644
--- a/src/amd/common/ac_nir_to_llvm.c
+++ b/src/amd/common/ac_nir_to_llvm.c
@@ -83,57 +83,6 @@ build_store_values_extended(struct ac_llvm_context *ac,
 	}
 }
 
-static enum ac_image_dim
-get_ac_sampler_dim(const struct ac_llvm_context *ctx, enum glsl_sampler_dim dim,
-		   bool is_array)
-{
-	switch (dim) {
-	case GLSL_SAMPLER_DIM_1D:
-		if (ctx->chip_class == GFX9)
-			return is_array ? ac_image_2darray : ac_image_2d;
-		return is_array ? ac_image_1darray : ac_image_1d;
-	case GLSL_SAMPLER_DIM_2D:
-	case GLSL_SAMPLER_DIM_RECT:
-	case GLSL_SAMPLER_DIM_EXTERNAL:
-		return is_array ? ac_image_2darray : ac_image_2d;
-	case GLSL_SAMPLER_DIM_3D:
-		return ac_image_3d;
-	case GLSL_SAMPLER_DIM_CUBE:
-		return ac_image_cube;
-	case GLSL_SAMPLER_DIM_MS:
-		return is_array ? ac_image_2darraymsaa : ac_image_2dmsaa;
-	case GLSL_SAMPLER_DIM_SUBPASS:
-		return ac_image_2darray;
-	case GLSL_SAMPLER_DIM_SUBPASS_MS:
-		return ac_image_2darraymsaa;
-	default:
-		unreachable("bad sampler dim");
-	}
-}
-
-static enum ac_image_dim
-get_ac_image_dim(const struct ac_llvm_context *ctx, enum glsl_sampler_dim sdim,
-		 bool is_array)
-{
-	enum ac_image_dim dim = get_ac_sampler_dim(ctx, sdim, is_array);
-
-	/* Match the resource type set in the descriptor. */
-	if (dim == ac_image_cube ||
-	    (ctx->chip_class <= GFX8 && dim == ac_image_3d))
-		dim = ac_image_2darray;
-	else if (sdim == GLSL_SAMPLER_DIM_2D && !is_array && ctx->chip_class == GFX9) {
-		/* When a single layer of a 3D texture is bound, the shader
-		 * will refer to a 2D target, but the descriptor has a 3D type.
-		 * Since the HW ignores BASE_ARRAY in this case, we need to
-		 * send 3 coordinates. This doesn't hurt when the underlying
-		 * texture is non-3D.
-		 */
-		dim = ac_image_3d;
-	}
-
-	return dim;
-}
-
 static LLVMTypeRef get_def_type(struct ac_nir_context *ctx,
                                 const nir_ssa_def *def)
 {
@@ -1282,7 +1231,7 @@ static LLVMValueRef lower_gather4_integer(struct ac_llvm_context *ctx,
 		}
 
 		/* Query the texture size. */
-		resinfo.dim = get_ac_sampler_dim(ctx, instr->sampler_dim, instr->is_array);
+		resinfo.dim = ac_get_sampler_dim(ctx->chip_class, instr->sampler_dim, instr->is_array);
 		resinfo.opcode = ac_image_get_resinfo;
 		resinfo.dmask = 0xf;
 		resinfo.lod = ctx->i32_0;
@@ -2612,7 +2561,7 @@ static LLVMValueRef visit_image_load(struct ac_nir_context *ctx,
 		args.opcode = ac_image_load;
 		args.resource = get_image_descriptor(ctx, instr, AC_DESC_IMAGE, false);
 		get_image_coords(ctx, instr, &args, dim, is_array);
-		args.dim = get_ac_image_dim(&ctx->ac, dim, is_array);
+		args.dim = ac_get_image_dim(ctx->ac.chip_class, dim, is_array);
 		args.dmask = 15;
 		args.attributes = AC_FUNC_ATTR_READONLY;
 
@@ -2669,7 +2618,7 @@ static void visit_image_store(struct ac_nir_context *ctx,
 		args.data[0] = ac_to_float(&ctx->ac, get_src(ctx, instr->src[3]));
 		args.resource = get_image_descriptor(ctx, instr, AC_DESC_IMAGE, true);
 		get_image_coords(ctx, instr, &args, dim, is_array);
-		args.dim = get_ac_image_dim(&ctx->ac, dim, is_array);
+		args.dim = ac_get_image_dim(ctx->ac.chip_class, dim, is_array);
 		args.dmask = 15;
 
 		ac_build_image_opcode(&ctx->ac, &args);
@@ -2822,7 +2771,7 @@ static LLVMValueRef visit_image_atomic(struct ac_nir_context *ctx,
 			args.data[1] = params[1];
 		args.resource = get_image_descriptor(ctx, instr, AC_DESC_IMAGE, true);
 		get_image_coords(ctx, instr, &args, dim, is_array);
-		args.dim = get_ac_image_dim(&ctx->ac, dim, is_array);
+		args.dim = ac_get_image_dim(ctx->ac.chip_class, dim, is_array);
 
 		return ac_build_image_opcode(&ctx->ac, &args);
 	}
@@ -2844,7 +2793,7 @@ static LLVMValueRef visit_image_samples(struct ac_nir_context *ctx,
 	}
 
 	struct ac_image_args args = { 0 };
-	args.dim = get_ac_sampler_dim(&ctx->ac, dim, is_array);
+	args.dim = ac_get_sampler_dim(ctx->ac.chip_class, dim, is_array);
 	args.dmask = 0xf;
 	args.resource = get_image_descriptor(ctx, instr, AC_DESC_IMAGE, false);
 	args.opcode = ac_image_get_resinfo;
@@ -2876,7 +2825,7 @@ static LLVMValueRef visit_image_size(struct ac_nir_context *ctx,
 
 	struct ac_image_args args = { 0 };
 
-	args.dim = get_ac_image_dim(&ctx->ac, dim, is_array);
+	args.dim = ac_get_image_dim(ctx->ac.chip_class, dim, is_array);
 	args.dmask = 0xf;
 	args.resource = get_image_descriptor(ctx, instr, AC_DESC_IMAGE, false);
 	args.opcode = ac_image_get_resinfo;
@@ -4267,7 +4216,7 @@ static void visit_tex(struct ac_nir_context *ctx, nir_tex_instr *instr)
 	}
 
 	if (instr->sampler_dim != GLSL_SAMPLER_DIM_BUF) {
-		args.dim = get_ac_sampler_dim(&ctx->ac, instr->sampler_dim, instr->is_array);
+		args.dim = ac_get_sampler_dim(ctx->ac.chip_class, instr->sampler_dim, instr->is_array);
 		args.unorm = instr->sampler_dim == GLSL_SAMPLER_DIM_RECT;
 	}
 	result = build_tex_intrinsic(ctx, instr, &args);
diff --git a/src/amd/common/ac_shader_util.c b/src/amd/common/ac_shader_util.c
index c94feb06f17..e9fcae6469a 100644
--- a/src/amd/common/ac_shader_util.c
+++ b/src/amd/common/ac_shader_util.c
@@ -108,3 +108,100 @@ ac_vgt_gs_mode(unsigned gs_max_vert_out, enum chip_class chip_class)
 	       S_028A40_ONCHIP(chip_class >= GFX9 ? 1 : 0);
 }
 
+/// Translate a (dfmt, nfmt) pair into a chip-appropriate combined format
+/// value for LLVM8+ tbuffer intrinsics.
+unsigned
+ac_get_tbuffer_format(enum chip_class chip_class,
+		      unsigned dfmt, unsigned nfmt)
+{
+	if (chip_class >= GFX10) {
+		unsigned format;
+		switch (dfmt) {
+		default: unreachable("bad dfmt");
+		case V_008F0C_BUF_DATA_FORMAT_INVALID: format = V_008F0C_IMG_FORMAT_INVALID; break;
+		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: format = V_008F0C_IMG_FORMAT_32_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;
+		case V_008F0C_BUF_DATA_FORMAT_2_10_10_10: format = V_008F0C_IMG_FORMAT_2_10_10_10_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);
+	}
+}
+
+enum ac_image_dim
+ac_get_sampler_dim(enum chip_class chip_class, enum glsl_sampler_dim dim,
+		   bool is_array)
+{
+	switch (dim) {
+	case GLSL_SAMPLER_DIM_1D:
+		if (chip_class == GFX9)
+			return is_array ? ac_image_2darray : ac_image_2d;
+		return is_array ? ac_image_1darray : ac_image_1d;
+	case GLSL_SAMPLER_DIM_2D:
+	case GLSL_SAMPLER_DIM_RECT:
+	case GLSL_SAMPLER_DIM_EXTERNAL:
+		return is_array ? ac_image_2darray : ac_image_2d;
+	case GLSL_SAMPLER_DIM_3D:
+		return ac_image_3d;
+	case GLSL_SAMPLER_DIM_CUBE:
+		return ac_image_cube;
+	case GLSL_SAMPLER_DIM_MS:
+		return is_array ? ac_image_2darraymsaa : ac_image_2dmsaa;
+	case GLSL_SAMPLER_DIM_SUBPASS:
+		return ac_image_2darray;
+	case GLSL_SAMPLER_DIM_SUBPASS_MS:
+		return ac_image_2darraymsaa;
+	default:
+		unreachable("bad sampler dim");
+	}
+}
+
+enum ac_image_dim
+ac_get_image_dim(enum chip_class chip_class, enum glsl_sampler_dim sdim,
+		 bool is_array)
+{
+	enum ac_image_dim dim = ac_get_sampler_dim(chip_class, sdim, is_array);
+
+	/* Match the resource type set in the descriptor. */
+	if (dim == ac_image_cube ||
+	    (chip_class <= GFX8 && dim == ac_image_3d))
+		dim = ac_image_2darray;
+	else if (sdim == GLSL_SAMPLER_DIM_2D && !is_array && chip_class == GFX9) {
+		/* When a single layer of a 3D texture is bound, the shader
+		 * will refer to a 2D target, but the descriptor has a 3D type.
+		 * Since the HW ignores BASE_ARRAY in this case, we need to
+		 * send 3 coordinates. This doesn't hurt when the underlying
+		 * texture is non-3D.
+		 */
+		dim = ac_image_3d;
+	}
+
+	return dim;
+}
+
diff --git a/src/amd/common/ac_shader_util.h b/src/amd/common/ac_shader_util.h
index 1bdf909e099..9a9d3f1b232 100644
--- a/src/amd/common/ac_shader_util.h
+++ b/src/amd/common/ac_shader_util.h
@@ -28,6 +28,18 @@
 #include <stdint.h>
 
 #include "amd_family.h"
+#include "compiler/nir/nir.h"
+
+enum ac_image_dim {
+	ac_image_1d,
+	ac_image_2d,
+	ac_image_3d,
+	ac_image_cube, // includes cube arrays
+	ac_image_1darray,
+	ac_image_2darray,
+	ac_image_2dmsaa,
+	ac_image_2darraymsaa,
+};
 
 unsigned
 ac_get_spi_shader_z_format(bool writes_z, bool writes_stencil,
@@ -39,4 +51,16 @@ ac_get_cb_shader_mask(unsigned spi_shader_col_format);
 uint32_t
 ac_vgt_gs_mode(unsigned gs_max_vert_out, enum chip_class chip_class);
 
+unsigned
+ac_get_tbuffer_format(enum chip_class chip_class,
+		      unsigned dfmt, unsigned nfmt);
+
+enum ac_image_dim
+ac_get_sampler_dim(enum chip_class chip_class, enum glsl_sampler_dim dim,
+		   bool is_array);
+
+enum ac_image_dim
+ac_get_image_dim(enum chip_class chip_class, enum glsl_sampler_dim sdim,
+		 bool is_array);
+
 #endif




More information about the mesa-commit mailing list