[Mesa-dev] [PATCH 1/1] radv/gfx9: fix texture buffer objects and image buffers with IDXEN==0

Samuel Pitoiset samuel.pitoiset at gmail.com
Tue Feb 20 11:33:32 UTC 2018


Ported from RadeonSI.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Cc: <mesa-stable at lists.freedesktop.org>
---
 src/amd/vulkan/radv_image.c | 35 ++++++++++++++++++++++++++++++++---
 1 file changed, 32 insertions(+), 3 deletions(-)

diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c
index 5ac0f72589..1aafd88a6f 100644
--- a/src/amd/vulkan/radv_image.c
+++ b/src/amd/vulkan/radv_image.c
@@ -209,6 +209,8 @@ radv_make_buffer_descriptor(struct radv_device *device,
 	uint64_t va = gpu_address + buffer->offset;
 	unsigned num_format, data_format;
 	int first_non_void;
+	unsigned num_records;
+
 	desc = vk_format_description(vk_format);
 	first_non_void = vk_format_get_first_non_void_channel(vk_format);
 	stride = desc->block.bits / 8;
@@ -216,16 +218,43 @@ radv_make_buffer_descriptor(struct radv_device *device,
 	num_format = radv_translate_buffer_numformat(desc, first_non_void);
 	data_format = radv_translate_buffer_dataformat(desc, first_non_void);
 
+	num_records = range / stride;
+
 	va += offset;
 	state[0] = va;
 	state[1] = S_008F04_BASE_ADDRESS_HI(va >> 32) |
 		S_008F04_STRIDE(stride);
 
-	if (device->physical_device->rad_info.chip_class != VI && stride) {
-		range /= stride;
+	/* The NUM_RECORDS field has a different meaning depending on the chip,
+	 * instruction type, STRIDE, and SWIZZLE_ENABLE.
+	 *
+	 * SI-CIK:
+	 * - If STRIDE == 0, it's in byte units.
+	 * - If STRIDE != 0, it's in units of STRIDE, used with inst.IDXEN.
+	 *
+	 * VI:
+	 * - For SMEM and STRIDE == 0, it's in byte units.
+	 * - For SMEM and STRIDE != 0, it's in units of STRIDE.
+	 * - For VMEM and STRIDE == 0 or SWIZZLE_ENABLE == 0, it's in byte units.
+	 * - For VMEM and STRIDE != 0 and SWIZZLE_ENABLE == 1, it's in units of STRIDE.
+	 * NOTE: There is incompatibility between VMEM and SMEM opcodes due to SWIZZLE_-
+	 *       ENABLE. The workaround is to set STRIDE = 0 if SWIZZLE_ENABLE == 0 when
+	 *       using SMEM. This can be done in the shader by clearing STRIDE with s_and.
+	 *       That way the same descriptor can be used by both SMEM and VMEM.
+	 *
+	 * GFX9:
+	 * - For SMEM and STRIDE == 0, it's in byte units.
+	 * - For SMEM and STRIDE != 0, it's in units of STRIDE.
+	 * - For VMEM and inst.IDXEN == 0 or STRIDE == 0, it's in byte units.
+	 * - For VMEM and inst.IDXEN == 1 and STRIDE != 0, it's in units of STRIDE.
+	 */
+	if (device->physical_device->rad_info.chip_class >= GFX9) {
+		num_records = num_records ? MAX2(num_records, stride) : 0;
+	} else if (device->physical_device->rad_info.chip_class == VI) {
+		num_records *= stride;
 	}
 
-	state[2] = range;
+	state[2] = num_records;
 	state[3] = S_008F0C_DST_SEL_X(radv_map_swizzle(desc->swizzle[0])) |
 		   S_008F0C_DST_SEL_Y(radv_map_swizzle(desc->swizzle[1])) |
 		   S_008F0C_DST_SEL_Z(radv_map_swizzle(desc->swizzle[2])) |
-- 
2.16.2



More information about the mesa-dev mailing list