xref: /aosp_15_r20/external/mesa3d/src/asahi/vulkan/hk_cmd_clear.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright 2024 Valve Corporation
3  * Copyright 2024 Alyssa Rosenzweig
4  * Copyright 2022-2023 Collabora Ltd. and Red Hat Inc.
5  * SPDX-License-Identifier: MIT
6  */
7 #include "hk_cmd_buffer.h"
8 #include "layout.h"
9 
10 #include "hk_device.h"
11 #include "hk_entrypoints.h"
12 #include "hk_image.h"
13 #include "hk_image_view.h"
14 #include "hk_physical_device.h"
15 
16 #include "vk_format.h"
17 #include "vk_meta.h"
18 
19 static VkImageViewType
render_view_type(VkImageType image_type,unsigned layer_count)20 render_view_type(VkImageType image_type, unsigned layer_count)
21 {
22    switch (image_type) {
23    case VK_IMAGE_TYPE_1D:
24       return layer_count == 1 ? VK_IMAGE_VIEW_TYPE_1D
25                               : VK_IMAGE_VIEW_TYPE_1D_ARRAY;
26    case VK_IMAGE_TYPE_2D:
27       return layer_count == 1 ? VK_IMAGE_VIEW_TYPE_2D
28                               : VK_IMAGE_VIEW_TYPE_2D_ARRAY;
29    case VK_IMAGE_TYPE_3D:
30       return VK_IMAGE_VIEW_TYPE_3D;
31    default:
32       unreachable("Invalid image type");
33    }
34 }
35 
36 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)37 clear_image(struct hk_cmd_buffer *cmd, struct hk_image *image,
38             VkImageLayout image_layout, VkFormat format,
39             const VkClearValue *clear_value, uint32_t range_count,
40             const VkImageSubresourceRange *ranges)
41 {
42    struct hk_device *dev = hk_cmd_buffer_device(cmd);
43    ASSERTED VkResult result;
44 
45    for (uint32_t r = 0; r < range_count; r++) {
46       const uint32_t level_count =
47          vk_image_subresource_level_count(&image->vk, &ranges[r]);
48 
49       for (uint32_t l = 0; l < level_count; l++) {
50          const uint32_t level = ranges[r].baseMipLevel + l;
51 
52          const VkExtent3D level_extent =
53             vk_image_mip_level_extent(&image->vk, level);
54 
55          uint32_t base_array_layer, layer_count;
56          if (image->vk.image_type == VK_IMAGE_TYPE_3D) {
57             base_array_layer = 0;
58             layer_count = level_extent.depth;
59          } else {
60             base_array_layer = ranges[r].baseArrayLayer;
61             layer_count =
62                vk_image_subresource_layer_count(&image->vk, &ranges[r]);
63          }
64 
65          const VkImageViewUsageCreateInfo view_usage_info = {
66             .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO,
67             .usage = (ranges[r].aspectMask & VK_IMAGE_ASPECT_COLOR_BIT)
68                         ? VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
69                         : VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
70          };
71          const VkImageViewCreateInfo view_info = {
72             .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
73             .flags = VK_IMAGE_VIEW_CREATE_INTERNAL_MESA,
74             .pNext = &view_usage_info,
75             .image = hk_image_to_handle(image),
76             .viewType = render_view_type(image->vk.image_type, layer_count),
77             .format = format,
78             .subresourceRange =
79                {
80                   .aspectMask = image->vk.aspects,
81                   .baseMipLevel = level,
82                   .levelCount = 1,
83                   .baseArrayLayer = base_array_layer,
84                   .layerCount = layer_count,
85                },
86          };
87 
88          /* We use vk_meta_create_image_view here for lifetime managemnt */
89          VkImageView view;
90          result =
91             vk_meta_create_image_view(&cmd->vk, &dev->meta, &view_info, &view);
92          assert(result == VK_SUCCESS);
93 
94          VkRenderingInfo render = {
95             .sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
96             .renderArea =
97                {
98                   .offset = {0, 0},
99                   .extent = {level_extent.width, level_extent.height},
100                },
101             .layerCount = layer_count,
102          };
103 
104          VkRenderingAttachmentInfo vk_att = {
105             .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
106             .imageView = view,
107             .imageLayout = image_layout,
108             .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
109             .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
110             .clearValue = *clear_value,
111          };
112 
113          if (ranges[r].aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
114             render.colorAttachmentCount = 1;
115             render.pColorAttachments = &vk_att;
116          }
117          if (ranges[r].aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT)
118             render.pDepthAttachment = &vk_att;
119          if (ranges[r].aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT)
120             render.pStencilAttachment = &vk_att;
121 
122          hk_CmdBeginRendering(hk_cmd_buffer_to_handle(cmd), &render);
123          hk_CmdEndRendering(hk_cmd_buffer_to_handle(cmd));
124       }
125    }
126 }
127 
128 static VkFormat
vk_packed_int_format_for_size(unsigned size_B)129 vk_packed_int_format_for_size(unsigned size_B)
130 {
131    switch (size_B) {
132    case 1:
133       return VK_FORMAT_R8_UINT;
134    case 2:
135       return VK_FORMAT_R16_UINT;
136    case 4:
137       return VK_FORMAT_R32_UINT;
138    case 8:
139       return VK_FORMAT_R32G32_UINT;
140    case 16:
141       return VK_FORMAT_R32G32B32A32_UINT;
142    default:
143       unreachable("Invalid image format size");
144    }
145 }
146 
147 VKAPI_ATTR void VKAPI_CALL
hk_CmdClearColorImage(VkCommandBuffer commandBuffer,VkImage _image,VkImageLayout imageLayout,const VkClearColorValue * pColor,uint32_t rangeCount,const VkImageSubresourceRange * pRanges)148 hk_CmdClearColorImage(VkCommandBuffer commandBuffer, VkImage _image,
149                       VkImageLayout imageLayout,
150                       const VkClearColorValue *pColor, uint32_t rangeCount,
151                       const VkImageSubresourceRange *pRanges)
152 {
153    VK_FROM_HANDLE(hk_cmd_buffer, cmd, commandBuffer);
154    VK_FROM_HANDLE(hk_image, image, _image);
155 
156    VkClearValue clear_value = {
157       .color = *pColor,
158    };
159 
160    VkFormat vk_format = image->vk.format;
161    if (vk_format == VK_FORMAT_R64_UINT || vk_format == VK_FORMAT_R64_SINT)
162       vk_format = VK_FORMAT_R32G32_UINT;
163 
164    enum pipe_format p_format = vk_format_to_pipe_format(vk_format);
165    assert(p_format != PIPE_FORMAT_NONE);
166 
167    if (!ail_pixel_format[p_format].renderable) {
168       memset(&clear_value, 0, sizeof(clear_value));
169       util_format_pack_rgba(p_format, clear_value.color.uint32, pColor->uint32,
170                             1);
171 
172       unsigned bpp = util_format_get_blocksize(p_format);
173       vk_format = vk_packed_int_format_for_size(bpp);
174    }
175 
176    clear_image(cmd, image, imageLayout, vk_format, &clear_value, rangeCount,
177                pRanges);
178 }
179 
180 VKAPI_ATTR void VKAPI_CALL
hk_CmdClearDepthStencilImage(VkCommandBuffer commandBuffer,VkImage _image,VkImageLayout imageLayout,const VkClearDepthStencilValue * pDepthStencil,uint32_t rangeCount,const VkImageSubresourceRange * pRanges)181 hk_CmdClearDepthStencilImage(VkCommandBuffer commandBuffer, VkImage _image,
182                              VkImageLayout imageLayout,
183                              const VkClearDepthStencilValue *pDepthStencil,
184                              uint32_t rangeCount,
185                              const VkImageSubresourceRange *pRanges)
186 {
187    VK_FROM_HANDLE(hk_cmd_buffer, cmd, commandBuffer);
188    VK_FROM_HANDLE(hk_image, image, _image);
189 
190    const VkClearValue clear_value = {
191       .depthStencil = *pDepthStencil,
192    };
193 
194    clear_image(cmd, image, imageLayout, image->vk.format, &clear_value,
195                rangeCount, pRanges);
196 }
197