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,
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";
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";
#include <llvm-c/Core.h>
#include "compiler/nir/nir.h"
#include "amd_family.h"
+#include "ac_shader_util.h"
#ifdef __cplusplus
extern "C" {
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 */
}
}
-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)
{
}
/* 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;
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;
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);
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);
}
}
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;
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;
}
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);
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;
+}
+
#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,
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