diff --git a/src/asahi/vulkan/hk_cmd_clear.c b/src/asahi/vulkan/hk_cmd_clear.c index c59d5cf8779..a1fab549c53 100644 --- a/src/asahi/vulkan/hk_cmd_clear.c +++ b/src/asahi/vulkan/hk_cmd_clear.c @@ -4,6 +4,10 @@ * Copyright 2022-2023 Collabora Ltd. and Red Hat Inc. * SPDX-License-Identifier: MIT */ +#include "util/format/u_formats.h" +#include "util/macros.h" +#include "util/u_math.h" +#include "vulkan/vulkan_core.h" #include "hk_cmd_buffer.h" #include "layout.h" @@ -13,141 +17,113 @@ #include "hk_image_view.h" #include "hk_physical_device.h" -#include "vk_format.h" -#include "vk_meta.h" +#include "libagx_dgc.h" +#include "libagx_shaders.h" -static VkImageViewType -render_view_type(VkImageType image_type, unsigned layer_count) +void +hk_clear_image(struct hk_cmd_buffer *cmd, struct hk_image *image, + enum pipe_format view_format, const uint32_t *clear_value, + const VkImageSubresourceRange *range, bool whole_3d) { - switch (image_type) { - case VK_IMAGE_TYPE_1D: - return layer_count == 1 ? VK_IMAGE_VIEW_TYPE_1D - : VK_IMAGE_VIEW_TYPE_1D_ARRAY; - case VK_IMAGE_TYPE_2D: - return layer_count == 1 ? VK_IMAGE_VIEW_TYPE_2D - : VK_IMAGE_VIEW_TYPE_2D_ARRAY; - case VK_IMAGE_TYPE_3D: - return VK_IMAGE_VIEW_TYPE_3D; - default: - unreachable("Invalid image type"); + const uint32_t level_count = + vk_image_subresource_level_count(&image->vk, range); + + bool z = (range->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT); + bool s = (range->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT); + + unsigned first_plane = (s && !z) ? 1 : 0; + unsigned last_plane = s ? 1 : 0; + + if (image->plane_count == 1) { + first_plane = 0; + last_plane = 0; } -} -static void -clear_image(struct hk_cmd_buffer *cmd, struct hk_image *image, - VkImageLayout image_layout, VkFormat format, - const VkClearValue *clear_value, uint32_t range_count, - const VkImageSubresourceRange *ranges) -{ - struct hk_device *dev = hk_cmd_buffer_device(cmd); - ASSERTED VkResult result; - - /* TODO: Use fast clear */ - bool compressed = image->planes[0].layout.compressed; - perf_debug(cmd, "Image clear (%scompressed)", compressed ? "" : "un"); - - for (uint32_t r = 0; r < range_count; r++) { - const uint32_t level_count = - vk_image_subresource_level_count(&image->vk, &ranges[r]); + for (unsigned plane = first_plane; plane <= last_plane; ++plane) { + struct ail_layout *layout = &image->planes[plane].layout; + perf_debug(cmd, "Image clear (%scompressed)", + layout->compressed ? "" : "un"); for (uint32_t l = 0; l < level_count; l++) { - const uint32_t level = ranges[r].baseMipLevel + l; + const uint32_t level = range->baseMipLevel + l; const VkExtent3D level_extent = vk_image_mip_level_extent(&image->vk, level); uint32_t base_array_layer, layer_count; - if (image->vk.image_type == VK_IMAGE_TYPE_3D) { + if (image->vk.image_type == VK_IMAGE_TYPE_3D && whole_3d) { base_array_layer = 0; layer_count = level_extent.depth; } else { - base_array_layer = ranges[r].baseArrayLayer; - layer_count = - vk_image_subresource_layer_count(&image->vk, &ranges[r]); + base_array_layer = range->baseArrayLayer; + layer_count = vk_image_subresource_layer_count(&image->vk, range); } - const VkImageViewUsageCreateInfo view_usage_info = { - .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO, - .usage = (ranges[r].aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) - ? VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT - : VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, - }; - const VkImageViewCreateInfo view_info = { - .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, - .flags = VK_IMAGE_VIEW_CREATE_DRIVER_INTERNAL_BIT_MESA, - .pNext = &view_usage_info, - .image = hk_image_to_handle(image), - .viewType = render_view_type(image->vk.image_type, layer_count), - .format = format, - .subresourceRange = - { - .aspectMask = image->vk.aspects, - .baseMipLevel = level, - .levelCount = 1, - .baseArrayLayer = base_array_layer, - .layerCount = layer_count, - }, - }; + enum pipe_format format = view_format ? view_format : layout->format; + bool stencil = format == PIPE_FORMAT_S8_UINT; - /* We use vk_meta_create_image_view here for lifetime managemnt */ - VkImageView view; - result = - vk_meta_create_image_view(&cmd->vk, &dev->meta, &view_info, &view); - assert(result == VK_SUCCESS); - - VkRenderingInfo render = { - .sType = VK_STRUCTURE_TYPE_RENDERING_INFO, - .renderArea = - { - .offset = {0, 0}, - .extent = {level_extent.width, level_extent.height}, - }, - .layerCount = layer_count, - }; - - VkRenderingAttachmentInfo vk_att = { - .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, - .imageView = view, - .imageLayout = image_layout, - .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, - .storeOp = VK_ATTACHMENT_STORE_OP_STORE, - .clearValue = *clear_value, - }; - - if (ranges[r].aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) { - render.colorAttachmentCount = 1; - render.pColorAttachments = &vk_att; + if (stencil) { + format = PIPE_FORMAT_R8_UINT; + } else if (format == PIPE_FORMAT_Z16_UNORM) { + format = PIPE_FORMAT_R16_UNORM; + } else if (format == PIPE_FORMAT_Z32_FLOAT) { + format = PIPE_FORMAT_R32_FLOAT; } - if (ranges[r].aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) - render.pDepthAttachment = &vk_att; - if (ranges[r].aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) - render.pStencilAttachment = &vk_att; - hk_CmdBeginRendering(hk_cmd_buffer_to_handle(cmd), &render); - hk_CmdEndRendering(hk_cmd_buffer_to_handle(cmd)); + uint32_t c[4]; + util_format_pack_rgba(format, c, &clear_value[stencil ? 1 : 0], 1); + + unsigned blocksize_B = util_format_get_blocksize(format); + assert(util_is_power_of_two_nonzero(blocksize_B) && blocksize_B <= 16); + + /* Splat out to 128-bit */ + uint8_t *bytes = (uint8_t *)c; + for (unsigned i = 1; i < 16; ++i) { + bytes[i] = bytes[i % blocksize_B]; + } + + uint64_t address = + image->planes[plane].addr + + ail_get_layer_level_B(layout, base_array_layer, level); + + uint32_t size = ail_get_level_size_B(layout, level); + + assert((layout->layer_stride_B % 16) == 0 && "aligned"); + uint32_t layer_stride_uint4 = layout->layer_stride_B / 16; + + if (ail_is_level_logically_compressed(layout, level)) { + assert((layout->compression_layer_stride_B % 16) == 0 && "aligned"); + uint32_t meta_layer_stride_tl = + layout->compression_layer_stride_B / 8; + + uint64_t meta_addr = + image->planes[plane].addr + layout->metadata_offset_B + + (base_array_layer * layout->compression_layer_stride_B) + + layout->level_offsets_compressed_B[level]; + + uint32_t word = (uint32_t)ail_tile_mode_solid(format); + + struct agx_grid grid = + agx_3d(ail_metadata_width_tl(layout, level), + ail_metadata_height_tl(layout, level), layer_count); + + struct ail_tile tilesize = layout->tilesize_el[level]; + + libagx_fast_clear(cmd, grid, AGX_BARRIER_ALL, meta_addr, address, + grid.count[0], grid.count[1], tilesize.width_el, + tilesize.height_el, meta_layer_stride_tl, + layer_stride_uint4, util_logbase2(blocksize_B), + util_logbase2(layout->sample_count_sa), c[0], + c[1], c[2], c[3], word); + } else { + libagx_fill_uint4(cmd, agx_2d(DIV_ROUND_UP(size, 16), layer_count), + AGX_BARRIER_ALL, address, layer_stride_uint4, + c[0], c[1], c[2], c[3]); + } } } } -static VkFormat -vk_packed_int_format_for_size(unsigned size_B) -{ - switch (size_B) { - case 1: - return VK_FORMAT_R8_UINT; - case 2: - return VK_FORMAT_R16_UINT; - case 4: - return VK_FORMAT_R32_UINT; - case 8: - return VK_FORMAT_R32G32_UINT; - case 16: - return VK_FORMAT_R32G32B32A32_UINT; - default: - unreachable("Invalid image format size"); - } -} - VKAPI_ATTR void VKAPI_CALL hk_CmdClearColorImage(VkCommandBuffer commandBuffer, VkImage _image, VkImageLayout imageLayout, @@ -157,28 +133,10 @@ hk_CmdClearColorImage(VkCommandBuffer commandBuffer, VkImage _image, VK_FROM_HANDLE(hk_cmd_buffer, cmd, commandBuffer); VK_FROM_HANDLE(hk_image, image, _image); - VkClearValue clear_value = { - .color = *pColor, - }; - - VkFormat vk_format = image->vk.format; - if (vk_format == VK_FORMAT_R64_UINT || vk_format == VK_FORMAT_R64_SINT) - vk_format = VK_FORMAT_R32G32_UINT; - - enum pipe_format p_format = hk_format_to_pipe_format(vk_format); - assert(p_format != PIPE_FORMAT_NONE); - - if (!ail_pixel_format[p_format].renderable) { - memset(&clear_value, 0, sizeof(clear_value)); - util_format_pack_rgba(p_format, clear_value.color.uint32, pColor->uint32, - 1); - - unsigned bpp = util_format_get_blocksize(p_format); - vk_format = vk_packed_int_format_for_size(bpp); + for (uint32_t r = 0; r < rangeCount; r++) { + hk_clear_image(cmd, image, PIPE_FORMAT_NONE, pColor->uint32, &pRanges[r], + true /* whole 3D */); } - - clear_image(cmd, image, imageLayout, vk_format, &clear_value, rangeCount, - pRanges); } VKAPI_ATTR void VKAPI_CALL @@ -191,10 +149,9 @@ hk_CmdClearDepthStencilImage(VkCommandBuffer commandBuffer, VkImage _image, VK_FROM_HANDLE(hk_cmd_buffer, cmd, commandBuffer); VK_FROM_HANDLE(hk_image, image, _image); - const VkClearValue clear_value = { - .depthStencil = *pDepthStencil, - }; - - clear_image(cmd, image, imageLayout, image->vk.format, &clear_value, - rangeCount, pRanges); + for (uint32_t r = 0; r < rangeCount; r++) { + uint32_t colour[4] = {fui(pDepthStencil->depth), pDepthStencil->stencil}; + hk_clear_image(cmd, image, PIPE_FORMAT_NONE, colour, &pRanges[r], + true /* whole 3D */); + } } diff --git a/src/asahi/vulkan/hk_image.h b/src/asahi/vulkan/hk_image.h index b8ac4d1434f..a28add8b990 100644 --- a/src/asahi/vulkan/hk_image.h +++ b/src/asahi/vulkan/hk_image.h @@ -135,3 +135,8 @@ hk_image_aspects_to_plane(const struct hk_image *image, struct agx_device; bool hk_can_compress_format(const struct agx_device *dev, VkFormat format); + +struct hk_cmd_buffer; +void hk_clear_image(struct hk_cmd_buffer *cmd, struct hk_image *image, + enum pipe_format view_format, const uint32_t *clear_value, + const VkImageSubresourceRange *range, bool whole_3d);