From ff8aa15fa0d3f813efb45878d77111af6575a049 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Fri, 24 Sep 2021 19:34:12 +0200 Subject: [PATCH] panvk: Add support for texel buffers Signed-off-by: Boris Brezillon Reviewed-by: Jason Ekstrand Part-of: --- src/panfrost/ci/deqp-panfrost-g52-vk.toml | 8 +- src/panfrost/vulkan/panvk_descriptor_set.c | 14 ++- src/panfrost/vulkan/panvk_device.c | 2 +- src/panfrost/vulkan/panvk_image.c | 19 ++-- src/panfrost/vulkan/panvk_private.h | 12 ++- src/panfrost/vulkan/panvk_vX_descriptor_set.c | 56 +++++++++--- src/panfrost/vulkan/panvk_vX_image.c | 86 +++++++++++++++++++ 7 files changed, 161 insertions(+), 36 deletions(-) diff --git a/src/panfrost/ci/deqp-panfrost-g52-vk.toml b/src/panfrost/ci/deqp-panfrost-g52-vk.toml index 9145930e8b4..897667a5e2a 100644 --- a/src/panfrost/ci/deqp-panfrost-g52-vk.toml +++ b/src/panfrost/ci/deqp-panfrost-g52-vk.toml @@ -4,16 +4,12 @@ caselists = ["/deqp/mustpass/vk-master.txt"] renderer_check = "Mali-G52" include = [ "dEQP-VK.pipeline.blend.*", + "dEQP-VK.api.buffer_view.*", "dEQP-VK.api.copy_and_blit.core.*", "dEQP-VK.compute.builtin_var.*", "dEQP-VK.glsl.builtin.function.integer.usubborrow.*", "dEQP-VK.glsl.builtin.precision.frexp.*", "dEQP-VK.glsl.builtin.precision.ldexp.*", - "dEQP-VK.image.load_store.with_format.1d.*", - "dEQP-VK.image.load_store.with_format.1d_array.*", - "dEQP-VK.image.load_store.with_format.2d.*", - "dEQP-VK.image.load_store.with_format.2d_array.*", - "dEQP-VK.image.load_store.with_format.3d.*", - "dEQP-VK.image.load_store.with_format.cube.*", + "dEQP-VK.image.load_store.with_format.*", "dEQP-VK.ssbo.layout.single_basic_type.*", ] diff --git a/src/panfrost/vulkan/panvk_descriptor_set.c b/src/panfrost/vulkan/panvk_descriptor_set.c index cdf987416bb..5474b9ffa01 100644 --- a/src/panfrost/vulkan/panvk_descriptor_set.c +++ b/src/panfrost/vulkan/panvk_descriptor_set.c @@ -120,12 +120,14 @@ panvk_CreateDescriptorSetLayout(VkDevice _device, tex_idx += binding_layout->array_size; break; case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: - case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: - case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: binding_layout->tex_idx = tex_idx; tex_idx += binding_layout->array_size; break; + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: + binding_layout->tex_idx = tex_idx; + tex_idx += binding_layout->array_size; + break; case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: binding_layout->dyn_ubo_idx = dyn_ubo_idx; dyn_ubo_idx += binding_layout->array_size; @@ -146,6 +148,10 @@ panvk_CreateDescriptorSetLayout(VkDevice _device, binding_layout->img_idx = img_idx; img_idx += binding_layout->array_size; break; + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: + binding_layout->img_idx = img_idx; + img_idx += binding_layout->array_size; + break; default: unreachable("Invalid descriptor type"); } @@ -223,9 +229,8 @@ panvk_GetDescriptorSetLayoutSupport(VkDevice _device, tex_idx += binding->descriptorCount; break; case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: - case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: - case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: tex_idx += binding->descriptorCount; break; case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: @@ -241,6 +246,7 @@ panvk_GetDescriptorSetLayoutSupport(VkDevice _device, ssbo_idx += binding->descriptorCount; break; case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: img_idx += binding->descriptorCount; break; default: diff --git a/src/panfrost/vulkan/panvk_device.c b/src/panfrost/vulkan/panvk_device.c index 362892f74b4..55f119fd782 100644 --- a/src/panfrost/vulkan/panvk_device.c +++ b/src/panfrost/vulkan/panvk_device.c @@ -790,7 +790,7 @@ panvk_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice, .viewportBoundsRange = { INT16_MIN, INT16_MAX }, .viewportSubPixelBits = 8, .minMemoryMapAlignment = 4096, /* A page */ - .minTexelBufferOffsetAlignment = 1, + .minTexelBufferOffsetAlignment = 64, .minUniformBufferOffsetAlignment = 4, .minStorageBufferOffsetAlignment = 4, .minTexelOffset = -32, diff --git a/src/panfrost/vulkan/panvk_image.c b/src/panfrost/vulkan/panvk_image.c index 3581e35d7b8..a8b322e4c17 100644 --- a/src/panfrost/vulkan/panvk_image.c +++ b/src/panfrost/vulkan/panvk_image.c @@ -290,22 +290,19 @@ panvk_DestroyImageView(VkDevice _device, vk_object_free(&device->vk, pAllocator, view); } -VkResult -panvk_CreateBufferView(VkDevice _device, - const VkBufferViewCreateInfo *pCreateInfo, - const VkAllocationCallbacks *pAllocator, - VkBufferView *pView) -{ - panvk_stub(); - return VK_SUCCESS; -} - void panvk_DestroyBufferView(VkDevice _device, VkBufferView bufferView, const VkAllocationCallbacks *pAllocator) { - panvk_stub(); + VK_FROM_HANDLE(panvk_device, device, _device); + VK_FROM_HANDLE(panvk_buffer_view, view, bufferView); + + if (!view) + return; + + panfrost_bo_unreference(view->bo); + vk_object_free(&device->vk, pAllocator, view); } VkResult diff --git a/src/panfrost/vulkan/panvk_private.h b/src/panfrost/vulkan/panvk_private.h index d7162fee975..8e3150c853a 100644 --- a/src/panfrost/vulkan/panvk_private.h +++ b/src/panfrost/vulkan/panvk_private.h @@ -378,14 +378,16 @@ struct panvk_descriptor_set_binding_layout { unsigned desc_idx; union { struct { - unsigned sampler_idx; + union { + unsigned sampler_idx; + unsigned img_idx; + }; unsigned tex_idx; }; unsigned ssbo_idx; unsigned dyn_ssbo_idx; unsigned ubo_idx; unsigned dyn_ubo_idx; - unsigned img_idx; }; /* Shader stages affected by this set+binding */ @@ -980,6 +982,12 @@ struct panvk_sampler { struct panvk_buffer_view { struct vk_object_base base; + struct panfrost_bo *bo; + struct { + uint32_t tex[TEXTURE_DESC_WORDS]; + uint32_t img_attrib_buf[ATTRIB_BUF_DESC_WORDS * 2]; + } descs; + enum pipe_format fmt; }; struct panvk_attachment_info { diff --git a/src/panfrost/vulkan/panvk_vX_descriptor_set.c b/src/panfrost/vulkan/panvk_vX_descriptor_set.c index 37ef98eae46..7ecc3fe99ca 100644 --- a/src/panfrost/vulkan/panvk_vX_descriptor_set.c +++ b/src/panfrost/vulkan/panvk_vX_descriptor_set.c @@ -189,14 +189,6 @@ err_free_sets: return result; } -static void -panvk_set_texel_buffer_view_desc(struct panvk_descriptor *desc, - const VkBufferView *pTexelBufferView) -{ - VK_FROM_HANDLE(panvk_buffer_view, buffer_view, *pTexelBufferView); - desc->buffer_view = buffer_view; -} - static void panvk_set_buffer_desc(struct panvk_buffer_desc *bdesc, const VkDescriptorBufferInfo *pBufferInfo) @@ -244,6 +236,22 @@ panvk_per_arch(set_texture_desc)(struct panvk_descriptor_set *set, #endif } +static void +panvk_set_tex_buf_desc(struct panvk_device *dev, + struct panvk_descriptor_set *set, + unsigned idx, + const VkBufferView bufferView) +{ + VK_FROM_HANDLE(panvk_buffer_view, view, bufferView); + +#if PAN_ARCH >= 6 + memcpy(&((struct mali_texture_packed *)set->textures)[idx], + view->descs.tex, pan_size(TEXTURE)); +#else + ((mali_ptr *)set->textures)[idx] = view->bo->ptr.gpu; +#endif +} + static void panvk_set_img_desc(struct panvk_device *dev, struct panvk_descriptor_set *set, @@ -258,6 +266,21 @@ panvk_set_img_desc(struct panvk_device *dev, memcpy(attrib_buf, view->descs.img_attrib_buf, pan_size(ATTRIBUTE_BUFFER) * 2); } +static void +panvk_set_img_buf_desc(struct panvk_device *dev, + struct panvk_descriptor_set *set, + unsigned idx, + const VkBufferView bufferView) +{ + const struct panfrost_device *pdev = &dev->physical_device->pdev; + VK_FROM_HANDLE(panvk_buffer_view, view, bufferView); + + void *attrib_buf = (uint8_t *)set->img_attrib_bufs + (pan_size(ATTRIBUTE_BUFFER) * 2 * idx); + + set->img_fmts[idx] = pdev->formats[view->fmt].hw; + memcpy(attrib_buf, view->descs.img_attrib_buf, pan_size(ATTRIBUTE_BUFFER) * 2); +} + static void panvk_per_arch(write_descriptor_set)(struct panvk_device *dev, const VkWriteDescriptorSet *pDescriptorWrite) @@ -284,7 +307,6 @@ panvk_per_arch(write_descriptor_set)(struct panvk_device *dev, assert(pDescriptorWrite->descriptorType == binding_layout->type); unsigned ndescs = MIN2(pDescriptorWrite->descriptorCount - src_offset, binding_layout->array_size - dest_offset); - struct panvk_descriptor *descs = &set->descs[binding_layout->desc_idx + dest_offset]; assert(binding_layout->desc_idx + dest_offset + ndescs <= set->layout->num_descs); switch (pDescriptorWrite->descriptorType) { @@ -311,6 +333,14 @@ panvk_per_arch(write_descriptor_set)(struct panvk_device *dev, } break; + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: + for (unsigned i = 0; i < ndescs; i++) { + unsigned tex = binding_layout->tex_idx + dest_offset + i; + panvk_set_tex_buf_desc(dev, set, tex, + pDescriptorWrite->pTexelBufferView[src_offset + i]); + } + break; + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: for (unsigned i = 0; i < ndescs; i++) { @@ -321,10 +351,12 @@ panvk_per_arch(write_descriptor_set)(struct panvk_device *dev, } break; - case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: - for (unsigned i = 0; i < ndescs; i++) - panvk_set_texel_buffer_view_desc(&descs[i], &pDescriptorWrite->pTexelBufferView[src_offset + i]); + for (unsigned i = 0; i < ndescs; i++) { + unsigned img = binding_layout->img_idx + dest_offset + i; + panvk_set_img_buf_desc(dev, set, img, + pDescriptorWrite->pTexelBufferView[src_offset + i]); + } break; case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: diff --git a/src/panfrost/vulkan/panvk_vX_image.c b/src/panfrost/vulkan/panvk_vX_image.c index dc2cb31849f..c13cac950cc 100644 --- a/src/panfrost/vulkan/panvk_vX_image.c +++ b/src/panfrost/vulkan/panvk_vX_image.c @@ -192,3 +192,89 @@ panvk_per_arch(CreateImageView)(VkDevice _device, *pView = panvk_image_view_to_handle(view); return VK_SUCCESS; } + +VkResult +panvk_per_arch(CreateBufferView)(VkDevice _device, + const VkBufferViewCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkBufferView *pView) +{ + VK_FROM_HANDLE(panvk_device, device, _device); + VK_FROM_HANDLE(panvk_buffer, buffer, pCreateInfo->buffer); + + struct panvk_buffer_view *view = + vk_object_zalloc(&device->vk, pAllocator, sizeof(*view), + VK_OBJECT_TYPE_BUFFER_VIEW); + + if (!view) + return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY); + + view->fmt = vk_format_to_pipe_format(pCreateInfo->format); + + struct panfrost_device *pdev = &device->physical_device->pdev; + unsigned offset = buffer->bo_offset + pCreateInfo->offset; + mali_ptr address = buffer->bo->ptr.gpu + offset; + unsigned size = pCreateInfo->range == VK_WHOLE_SIZE ? + buffer->bo->size - offset : pCreateInfo->range; + unsigned blksz = util_format_get_blocksize(view->fmt); + unsigned width = size / blksz; + + assert(!(address & 63)); + + if (buffer->usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) { + unsigned bo_size = + PAN_ARCH <= 5 ? (pan_size(SURFACE) + pan_size(TEXTURE)) : + pan_size(SURFACE_WITH_STRIDE); + view->bo = panfrost_bo_create(pdev, bo_size, 0, "Texture descriptor"); + + void *surf = view->bo->ptr.cpu + (PAN_ARCH <= 5 ? pan_size(TEXTURE) : 0); + void *tex = PAN_ARCH <= 5 ? view->bo->ptr.cpu : &view->descs.tex; + +#if PAN_ARCH <= 5 + pan_pack(surf, SURFACE, cfg) { +#else + pan_pack(surf, SURFACE_WITH_STRIDE, cfg) { +#endif + cfg.pointer = address; + } + + pan_pack(tex, TEXTURE, cfg) { + cfg.dimension = MALI_TEXTURE_DIMENSION_1D; + cfg.format = pdev->formats[view->fmt].hw; + cfg.width = width; + cfg.depth = cfg.height = 1; + cfg.swizzle = PAN_V6_SWIZZLE(R, G, B, A); + cfg.texel_ordering = MALI_TEXTURE_LAYOUT_LINEAR; + cfg.levels = 1; + cfg.array_size = 1; +#if PAN_ARCH >= 6 + cfg.surfaces = view->bo->ptr.gpu; + cfg.maximum_lod = cfg.minimum_lod = FIXED_16(0, false); +#else + cfg.manual_stride = false; +#endif + } + } + + if (buffer->usage & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) { + uint8_t *attrib_buf = (uint8_t *)view->descs.img_attrib_buf; + + pan_pack(attrib_buf, ATTRIBUTE_BUFFER, cfg) { + cfg.type = MALI_ATTRIBUTE_TYPE_3D_LINEAR; + cfg.pointer = address; + cfg.stride = blksz; + cfg.size = width * blksz; + } + + attrib_buf += pan_size(ATTRIBUTE_BUFFER); + pan_pack(attrib_buf, ATTRIBUTE_BUFFER_CONTINUATION_3D, cfg) { + cfg.s_dimension = width; + cfg.t_dimension = 1; + cfg.r_dimension = 1; + cfg.row_stride = width * blksz; + } + } + + *pView = panvk_buffer_view_to_handle(view); + return VK_SUCCESS; +}