• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2021 Google
3  *
4  * SPDX-License-Identifier: MIT
5  */
6 
7 #include <assert.h>
8 #include <stdbool.h>
9 
10 #include "nir/nir_builder.h"
11 #include "radv_meta.h"
12 #include "sid.h"
13 #include "vk_common_entrypoints.h"
14 #include "vk_format.h"
15 
16 static VkPipeline
radv_get_etc_decode_pipeline(struct radv_cmd_buffer * cmd_buffer)17 radv_get_etc_decode_pipeline(struct radv_cmd_buffer *cmd_buffer)
18 {
19    struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
20    struct radv_meta_state *state = &device->meta_state;
21    VkResult ret;
22 
23    ret = vk_texcompress_etc2_late_init(&device->vk, &state->etc_decode);
24    if (ret != VK_SUCCESS) {
25       vk_command_buffer_set_error(&cmd_buffer->vk, ret);
26       return VK_NULL_HANDLE;
27    }
28 
29    return state->etc_decode.pipeline;
30 }
31 
32 static void
decode_etc(struct radv_cmd_buffer * cmd_buffer,struct radv_image_view * src_iview,struct radv_image_view * dst_iview,const VkOffset3D * offset,const VkExtent3D * extent)33 decode_etc(struct radv_cmd_buffer *cmd_buffer, struct radv_image_view *src_iview, struct radv_image_view *dst_iview,
34            const VkOffset3D *offset, const VkExtent3D *extent)
35 {
36    struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
37    VkPipeline pipeline = radv_get_etc_decode_pipeline(cmd_buffer);
38 
39    radv_meta_push_descriptor_set(cmd_buffer, VK_PIPELINE_BIND_POINT_COMPUTE,
40                                  device->meta_state.etc_decode.pipeline_layout, 0, 2,
41                                  (VkWriteDescriptorSet[]){{.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
42                                                            .dstBinding = 0,
43                                                            .dstArrayElement = 0,
44                                                            .descriptorCount = 1,
45                                                            .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
46                                                            .pImageInfo =
47                                                               (VkDescriptorImageInfo[]){
48                                                                  {.sampler = VK_NULL_HANDLE,
49                                                                   .imageView = radv_image_view_to_handle(src_iview),
50                                                                   .imageLayout = VK_IMAGE_LAYOUT_GENERAL},
51                                                               }},
52                                                           {.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
53                                                            .dstBinding = 1,
54                                                            .dstArrayElement = 0,
55                                                            .descriptorCount = 1,
56                                                            .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
57                                                            .pImageInfo = (VkDescriptorImageInfo[]){
58                                                               {
59                                                                  .sampler = VK_NULL_HANDLE,
60                                                                  .imageView = radv_image_view_to_handle(dst_iview),
61                                                                  .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
62                                                               },
63                                                            }}});
64 
65    radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);
66 
67    unsigned push_constants[5] = {
68       offset->x, offset->y, offset->z, src_iview->image->vk.format, src_iview->image->vk.image_type,
69    };
70 
71    vk_common_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer), device->meta_state.etc_decode.pipeline_layout,
72                               VK_SHADER_STAGE_COMPUTE_BIT, 0, 20, push_constants);
73    radv_unaligned_dispatch(cmd_buffer, extent->width, extent->height, extent->depth);
74 }
75 
76 void
radv_meta_decode_etc(struct radv_cmd_buffer * cmd_buffer,struct radv_image * image,VkImageLayout layout,const VkImageSubresourceLayers * subresource,VkOffset3D offset,VkExtent3D extent)77 radv_meta_decode_etc(struct radv_cmd_buffer *cmd_buffer, struct radv_image *image, VkImageLayout layout,
78                      const VkImageSubresourceLayers *subresource, VkOffset3D offset, VkExtent3D extent)
79 {
80    struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
81    struct radv_meta_saved_state saved_state;
82    radv_meta_save(&saved_state, cmd_buffer,
83                   RADV_META_SAVE_COMPUTE_PIPELINE | RADV_META_SAVE_CONSTANTS | RADV_META_SAVE_DESCRIPTORS |
84                      RADV_META_SUSPEND_PREDICATING);
85 
86    uint32_t base_slice = radv_meta_get_iview_layer(image, subresource, &offset);
87    uint32_t slice_count = image->vk.image_type == VK_IMAGE_TYPE_3D
88                              ? extent.depth
89                              : vk_image_subresource_layer_count(&image->vk, subresource);
90 
91    extent = vk_image_sanitize_extent(&image->vk, extent);
92    offset = vk_image_sanitize_offset(&image->vk, offset);
93 
94    VkFormat load_format = vk_texcompress_etc2_load_format(image->vk.format);
95    struct radv_image_view src_iview;
96    radv_image_view_init(
97       &src_iview, device,
98       &(VkImageViewCreateInfo){
99          .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
100          .image = radv_image_to_handle(image),
101          .viewType = vk_texcompress_etc2_image_view_type(image->vk.image_type),
102          .format = load_format,
103          .subresourceRange =
104             {
105                .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
106                .baseMipLevel = subresource->mipLevel,
107                .levelCount = 1,
108                .baseArrayLayer = 0,
109                .layerCount = subresource->baseArrayLayer + vk_image_subresource_layer_count(&image->vk, subresource),
110             },
111       },
112       NULL);
113 
114    VkFormat store_format = vk_texcompress_etc2_store_format(image->vk.format);
115    struct radv_image_view dst_iview;
116    radv_image_view_init(
117       &dst_iview, device,
118       &(VkImageViewCreateInfo){
119          .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
120          .image = radv_image_to_handle(image),
121          .viewType = vk_texcompress_etc2_image_view_type(image->vk.image_type),
122          .format = store_format,
123          .subresourceRange =
124             {
125                .aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT,
126                .baseMipLevel = subresource->mipLevel,
127                .levelCount = 1,
128                .baseArrayLayer = 0,
129                .layerCount = subresource->baseArrayLayer + vk_image_subresource_layer_count(&image->vk, subresource),
130             },
131       },
132       NULL);
133 
134    decode_etc(cmd_buffer, &src_iview, &dst_iview, &(VkOffset3D){offset.x, offset.y, base_slice},
135               &(VkExtent3D){extent.width, extent.height, slice_count});
136 
137    radv_image_view_finish(&src_iview);
138    radv_image_view_finish(&dst_iview);
139 
140    radv_meta_restore(&saved_state, cmd_buffer);
141 }
142