xref: /aosp_15_r20/external/mesa3d/src/amd/vulkan/meta/radv_meta_astc_decode.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /* Copyright (c) 2017-2023 Hans-Kristian Arntzen
2  *
3  * SPDX-License-Identifier: MIT
4  */
5 
6 #include <assert.h>
7 #include <stdbool.h>
8 
9 #include "radv_meta.h"
10 #include "sid.h"
11 #include "vk_common_entrypoints.h"
12 #include "vk_format.h"
13 
14 VkResult
radv_device_init_meta_astc_decode_state(struct radv_device * device,bool on_demand)15 radv_device_init_meta_astc_decode_state(struct radv_device *device, bool on_demand)
16 {
17    const struct radv_physical_device *pdev = radv_device_physical(device);
18    struct radv_meta_state *state = &device->meta_state;
19 
20    if (!pdev->emulate_astc)
21       return VK_SUCCESS;
22 
23    return vk_texcompress_astc_init(&device->vk, &state->alloc, state->cache, &state->astc_decode);
24 }
25 
26 void
radv_device_finish_meta_astc_decode_state(struct radv_device * device)27 radv_device_finish_meta_astc_decode_state(struct radv_device *device)
28 {
29    const struct radv_physical_device *pdev = radv_device_physical(device);
30    struct radv_meta_state *state = &device->meta_state;
31    struct vk_texcompress_astc_state *astc = state->astc_decode;
32 
33    if (!pdev->emulate_astc)
34       return;
35 
36    vk_texcompress_astc_finish(&device->vk, &state->alloc, astc);
37 }
38 
39 static void
decode_astc(struct radv_cmd_buffer * cmd_buffer,struct radv_image_view * src_iview,struct radv_image_view * dst_iview,VkImageLayout layout,const VkOffset3D * offset,const VkExtent3D * extent)40 decode_astc(struct radv_cmd_buffer *cmd_buffer, struct radv_image_view *src_iview, struct radv_image_view *dst_iview,
41             VkImageLayout layout, const VkOffset3D *offset, const VkExtent3D *extent)
42 {
43    struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
44    struct radv_meta_state *state = &device->meta_state;
45    struct vk_texcompress_astc_write_descriptor_set write_desc_set;
46    VkFormat format = src_iview->image->vk.format;
47    int blk_w = vk_format_get_blockwidth(format);
48    int blk_h = vk_format_get_blockheight(format);
49 
50    vk_texcompress_astc_fill_write_descriptor_sets(state->astc_decode, &write_desc_set,
51                                                   radv_image_view_to_handle(src_iview), layout,
52                                                   radv_image_view_to_handle(dst_iview), format);
53    radv_meta_push_descriptor_set(cmd_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, state->astc_decode->p_layout, 0,
54                                  VK_TEXCOMPRESS_ASTC_WRITE_DESC_SET_COUNT, write_desc_set.descriptor_set);
55 
56    VkPipeline pipeline =
57       vk_texcompress_astc_get_decode_pipeline(&device->vk, &state->alloc, state->astc_decode, state->cache, format);
58    if (pipeline == VK_NULL_HANDLE)
59       return;
60 
61    radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);
62 
63    bool is_3Dimage = (src_iview->image->vk.image_type == VK_IMAGE_TYPE_3D) ? true : false;
64    int push_constants[5] = {offset->x / blk_w, offset->y / blk_h, extent->width + offset->x, extent->height + offset->y,
65                             is_3Dimage};
66    vk_common_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer), device->meta_state.etc_decode.pipeline_layout,
67                               VK_SHADER_STAGE_COMPUTE_BIT, 0, 20, push_constants);
68 
69    struct radv_dispatch_info info = {
70       .blocks[0] = DIV_ROUND_UP(extent->width, blk_w * 2),
71       .blocks[1] = DIV_ROUND_UP(extent->height, blk_h * 2),
72       .blocks[2] = extent->depth,
73       .offsets[0] = 0,
74       .offsets[1] = 0,
75       .offsets[2] = offset->z,
76       .unaligned = 0,
77    };
78    radv_compute_dispatch(cmd_buffer, &info);
79 }
80 
81 static VkImageViewType
get_view_type(const struct radv_image * image)82 get_view_type(const struct radv_image *image)
83 {
84    switch (image->vk.image_type) {
85    case VK_IMAGE_TYPE_2D:
86       return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
87    case VK_IMAGE_TYPE_3D:
88       return VK_IMAGE_VIEW_TYPE_3D;
89    default:
90       unreachable("bad VkImageViewType");
91    }
92 }
93 
94 static void
image_view_init(struct radv_device * device,struct radv_image * image,VkFormat format,VkImageAspectFlags aspectMask,uint32_t baseMipLevel,uint32_t baseArrayLayer,uint32_t layerCount,struct radv_image_view * iview)95 image_view_init(struct radv_device *device, struct radv_image *image, VkFormat format, VkImageAspectFlags aspectMask,
96                 uint32_t baseMipLevel, uint32_t baseArrayLayer, uint32_t layerCount, struct radv_image_view *iview)
97 {
98    VkImageViewCreateInfo iview_create_info = {
99       .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
100       .image = radv_image_to_handle(image),
101       .viewType = get_view_type(image),
102       .format = format,
103       .subresourceRange =
104          {
105             .aspectMask = aspectMask,
106             .baseMipLevel = baseMipLevel,
107             .levelCount = 1,
108             .baseArrayLayer = 0,
109             .layerCount = baseArrayLayer + layerCount,
110          },
111    };
112 
113    radv_image_view_init(iview, device, &iview_create_info, 0, NULL);
114 }
115 
116 void
radv_meta_decode_astc(struct radv_cmd_buffer * cmd_buffer,struct radv_image * image,VkImageLayout layout,const VkImageSubresourceLayers * subresource,VkOffset3D offset,VkExtent3D extent)117 radv_meta_decode_astc(struct radv_cmd_buffer *cmd_buffer, struct radv_image *image, VkImageLayout layout,
118                       const VkImageSubresourceLayers *subresource, VkOffset3D offset, VkExtent3D extent)
119 {
120    struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
121    struct radv_meta_saved_state saved_state;
122    radv_meta_save(&saved_state, cmd_buffer,
123                   RADV_META_SAVE_COMPUTE_PIPELINE | RADV_META_SAVE_CONSTANTS | RADV_META_SAVE_DESCRIPTORS |
124                      RADV_META_SUSPEND_PREDICATING);
125 
126    uint32_t base_slice = radv_meta_get_iview_layer(image, subresource, &offset);
127    uint32_t slice_count = image->vk.image_type == VK_IMAGE_TYPE_3D
128                              ? extent.depth
129                              : vk_image_subresource_layer_count(&image->vk, subresource);
130 
131    extent = vk_image_sanitize_extent(&image->vk, extent);
132    offset = vk_image_sanitize_offset(&image->vk, offset);
133 
134    struct radv_image_view src_iview, dst_iview;
135    image_view_init(device, image, VK_FORMAT_R32G32B32A32_UINT, VK_IMAGE_ASPECT_COLOR_BIT, subresource->mipLevel,
136                    subresource->baseArrayLayer, vk_image_subresource_layer_count(&image->vk, subresource), &src_iview);
137    image_view_init(device, image, VK_FORMAT_R8G8B8A8_UINT, VK_IMAGE_ASPECT_PLANE_1_BIT, subresource->mipLevel,
138                    subresource->baseArrayLayer, vk_image_subresource_layer_count(&image->vk, subresource), &dst_iview);
139 
140    VkExtent3D extent_copy = {
141       .width = extent.width,
142       .height = extent.height,
143       .depth = slice_count,
144    };
145    decode_astc(cmd_buffer, &src_iview, &dst_iview, layout, &(VkOffset3D){offset.x, offset.y, base_slice}, &extent_copy);
146 
147    radv_image_view_finish(&src_iview);
148    radv_image_view_finish(&dst_iview);
149 
150    radv_meta_restore(&saved_state, cmd_buffer);
151 }
152