[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