From 046c75e95c0c7faf16bc64ac620ded7d128e2e19 Mon Sep 17 00:00:00 2001 From: Connor Abbott Date: Thu, 1 Dec 2022 12:27:57 +0100 Subject: [PATCH] tu: Use start offset for storage buffers This lets us expose a minStorageBufferOffsetAlignment of 4 which is what vkd3d-proton expects. Part-of: --- src/freedreno/vulkan/tu_cmd_buffer.c | 19 +++++++++++++++++++ src/freedreno/vulkan/tu_descriptor_set.c | 16 ++++++++++++---- src/freedreno/vulkan/tu_device.c | 2 +- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/freedreno/vulkan/tu_cmd_buffer.c b/src/freedreno/vulkan/tu_cmd_buffer.c index 458beb2e278..5f0dde3b589 100644 --- a/src/freedreno/vulkan/tu_cmd_buffer.c +++ b/src/freedreno/vulkan/tu_cmd_buffer.c @@ -2189,9 +2189,28 @@ tu_CmdBindDescriptorSets(VkCommandBuffer commandBuffer, i++, dst_desc += A6XX_TEX_CONST_DWORDS) { /* Note: A6XX_TEX_CONST_5_DEPTH is always 0 */ uint64_t va = dst_desc[4] | ((uint64_t)dst_desc[5] << 32); + uint32_t desc_offset = + (dst_desc[2] & + A6XX_TEX_CONST_2_STARTOFFSETTEXELS__MASK) >> + A6XX_TEX_CONST_2_STARTOFFSETTEXELS__SHIFT; + + /* Without the ability to cast 16-bit as 32-bit, there is + * only one descriptor whose texels are 32 bits (4 + * bytes). With casting, there are two descriptors, the + * first being 16-bit and the second being 32-bit. + */ + unsigned offset_shift = + binding->size == 4 * A6XX_TEX_CONST_DWORDS || i == 1 ? 2 : 1; + + va += desc_offset << offset_shift; va += offset; + unsigned new_offset = (va & 0x3f) >> offset_shift; + va &= ~0x3full; dst_desc[4] = va; dst_desc[5] = va >> 32; + dst_desc[2] = + (dst_desc[2] & ~A6XX_TEX_CONST_2_STARTOFFSETTEXELS__MASK) | + A6XX_TEX_CONST_2_STARTOFFSETTEXELS(new_offset); } } diff --git a/src/freedreno/vulkan/tu_descriptor_set.c b/src/freedreno/vulkan/tu_descriptor_set.c index eb279d74c39..d4becab491f 100644 --- a/src/freedreno/vulkan/tu_descriptor_set.c +++ b/src/freedreno/vulkan/tu_descriptor_set.c @@ -1035,21 +1035,29 @@ write_buffer_descriptor_addr(const struct tu_device *device, } uint64_t va = buffer_info->address; + uint64_t base_va = va & ~0x3full; + unsigned offset = va & 0x3f; uint32_t range = buffer_info->range; for (unsigned i = 0; i < descriptors; i++) { if (storage_16bit && i == 0) { dst[0] = A6XX_TEX_CONST_0_TILE_MODE(TILE6_LINEAR) | A6XX_TEX_CONST_0_FMT(FMT6_16_UINT); dst[1] = DIV_ROUND_UP(range, 2); + dst[2] = + A6XX_TEX_CONST_2_STRUCTSIZETEXELS(1) | + A6XX_TEX_CONST_2_STARTOFFSETTEXELS(offset / 2) | + A6XX_TEX_CONST_2_TYPE(A6XX_TEX_BUFFER); } else { dst[0] = A6XX_TEX_CONST_0_TILE_MODE(TILE6_LINEAR) | A6XX_TEX_CONST_0_FMT(FMT6_32_UINT); dst[1] = DIV_ROUND_UP(range, 4); + dst[2] = + A6XX_TEX_CONST_2_STRUCTSIZETEXELS(1) | + A6XX_TEX_CONST_2_STARTOFFSETTEXELS(offset / 4) | + A6XX_TEX_CONST_2_TYPE(A6XX_TEX_BUFFER); } - dst[2] = - A6XX_TEX_CONST_2_STRUCTSIZETEXELS(1) | A6XX_TEX_CONST_2_TYPE(A6XX_TEX_BUFFER); dst[3] = 0; - dst[4] = A6XX_TEX_CONST_4_BASE_LO(va); - dst[5] = A6XX_TEX_CONST_5_BASE_HI(va >> 32); + dst[4] = A6XX_TEX_CONST_4_BASE_LO(base_va); + dst[5] = A6XX_TEX_CONST_5_BASE_HI(base_va >> 32); for (int j = 6; j < A6XX_TEX_CONST_DWORDS; j++) dst[j] = 0; dst += A6XX_TEX_CONST_DWORDS; diff --git a/src/freedreno/vulkan/tu_device.c b/src/freedreno/vulkan/tu_device.c index f120ddf6de4..11ef2ff5a53 100644 --- a/src/freedreno/vulkan/tu_device.c +++ b/src/freedreno/vulkan/tu_device.c @@ -1267,7 +1267,7 @@ tu_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice, .minMemoryMapAlignment = 4096, /* A page */ .minTexelBufferOffsetAlignment = 64, .minUniformBufferOffsetAlignment = 64, - .minStorageBufferOffsetAlignment = 64, + .minStorageBufferOffsetAlignment = 4, .minTexelOffset = -16, .maxTexelOffset = 15, .minTexelGatherOffset = -32,