• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2021 Google
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 #include <assert.h>
25 #include <stdbool.h>
26 
27 #include "nir/nir_builder.h"
28 #include "radv_meta.h"
29 #include "radv_private.h"
30 #include "sid.h"
31 #include "vk_common_entrypoints.h"
32 #include "vk_format.h"
33 
34 VkResult
radv_device_init_meta_etc_decode_state(struct radv_device * device,bool on_demand)35 radv_device_init_meta_etc_decode_state(struct radv_device *device, bool on_demand)
36 {
37    struct radv_meta_state *state = &device->meta_state;
38 
39    if (!device->physical_device->emulate_etc2)
40       return VK_SUCCESS;
41 
42    state->etc_decode.allocator = &state->alloc;
43    state->etc_decode.nir_options = &device->physical_device->nir_options[MESA_SHADER_COMPUTE];
44    state->etc_decode.pipeline_cache = state->cache;
45    vk_texcompress_etc2_init(&device->vk, &state->etc_decode);
46 
47    if (on_demand)
48       return VK_SUCCESS;
49 
50    return vk_texcompress_etc2_late_init(&device->vk, &state->etc_decode);
51 }
52 
53 void
radv_device_finish_meta_etc_decode_state(struct radv_device * device)54 radv_device_finish_meta_etc_decode_state(struct radv_device *device)
55 {
56    struct radv_meta_state *state = &device->meta_state;
57    vk_texcompress_etc2_finish(&device->vk, &state->etc_decode);
58 }
59 
60 static VkPipeline
radv_get_etc_decode_pipeline(struct radv_cmd_buffer * cmd_buffer)61 radv_get_etc_decode_pipeline(struct radv_cmd_buffer *cmd_buffer)
62 {
63    struct radv_device *device = cmd_buffer->device;
64    struct radv_meta_state *state = &device->meta_state;
65    VkResult ret;
66 
67    ret = vk_texcompress_etc2_late_init(&device->vk, &state->etc_decode);
68    if (ret != VK_SUCCESS) {
69       vk_command_buffer_set_error(&cmd_buffer->vk, ret);
70       return VK_NULL_HANDLE;
71    }
72 
73    return state->etc_decode.pipeline;
74 }
75 
76 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)77 decode_etc(struct radv_cmd_buffer *cmd_buffer, struct radv_image_view *src_iview, struct radv_image_view *dst_iview,
78            const VkOffset3D *offset, const VkExtent3D *extent)
79 {
80    struct radv_device *device = cmd_buffer->device;
81    VkPipeline pipeline = radv_get_etc_decode_pipeline(cmd_buffer);
82 
83    radv_meta_push_descriptor_set(cmd_buffer, VK_PIPELINE_BIND_POINT_COMPUTE,
84                                  device->meta_state.etc_decode.pipeline_layout, 0, /* set */
85                                  2,                                                /* descriptorWriteCount */
86                                  (VkWriteDescriptorSet[]){{.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
87                                                            .dstBinding = 0,
88                                                            .dstArrayElement = 0,
89                                                            .descriptorCount = 1,
90                                                            .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
91                                                            .pImageInfo =
92                                                               (VkDescriptorImageInfo[]){
93                                                                  {.sampler = VK_NULL_HANDLE,
94                                                                   .imageView = radv_image_view_to_handle(src_iview),
95                                                                   .imageLayout = VK_IMAGE_LAYOUT_GENERAL},
96                                                               }},
97                                                           {.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
98                                                            .dstBinding = 1,
99                                                            .dstArrayElement = 0,
100                                                            .descriptorCount = 1,
101                                                            .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
102                                                            .pImageInfo = (VkDescriptorImageInfo[]){
103                                                               {
104                                                                  .sampler = VK_NULL_HANDLE,
105                                                                  .imageView = radv_image_view_to_handle(dst_iview),
106                                                                  .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
107                                                               },
108                                                            }}});
109 
110    radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);
111 
112    unsigned push_constants[5] = {
113       offset->x, offset->y, offset->z, src_iview->image->vk.format, src_iview->image->vk.image_type,
114    };
115 
116    vk_common_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer), device->meta_state.etc_decode.pipeline_layout,
117                               VK_SHADER_STAGE_COMPUTE_BIT, 0, 20, push_constants);
118    radv_unaligned_dispatch(cmd_buffer, extent->width, extent->height, extent->depth);
119 }
120 
121 void
radv_meta_decode_etc(struct radv_cmd_buffer * cmd_buffer,struct radv_image * image,VkImageLayout layout,const VkImageSubresourceLayers * subresource,VkOffset3D offset,VkExtent3D extent)122 radv_meta_decode_etc(struct radv_cmd_buffer *cmd_buffer, struct radv_image *image, VkImageLayout layout,
123                      const VkImageSubresourceLayers *subresource, VkOffset3D offset, VkExtent3D extent)
124 {
125    struct radv_meta_saved_state saved_state;
126    radv_meta_save(&saved_state, cmd_buffer,
127                   RADV_META_SAVE_COMPUTE_PIPELINE | RADV_META_SAVE_CONSTANTS | RADV_META_SAVE_DESCRIPTORS |
128                      RADV_META_SUSPEND_PREDICATING);
129 
130    uint32_t base_slice = radv_meta_get_iview_layer(image, subresource, &offset);
131    uint32_t slice_count = image->vk.image_type == VK_IMAGE_TYPE_3D
132                              ? extent.depth
133                              : vk_image_subresource_layer_count(&image->vk, subresource);
134 
135    extent = vk_image_sanitize_extent(&image->vk, extent);
136    offset = vk_image_sanitize_offset(&image->vk, offset);
137 
138    VkFormat load_format = vk_texcompress_etc2_load_format(image->vk.format);
139    struct radv_image_view src_iview;
140    radv_image_view_init(
141       &src_iview, cmd_buffer->device,
142       &(VkImageViewCreateInfo){
143          .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
144          .image = radv_image_to_handle(image),
145          .viewType = vk_texcompress_etc2_image_view_type(image->vk.image_type),
146          .format = load_format,
147          .subresourceRange =
148             {
149                .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
150                .baseMipLevel = subresource->mipLevel,
151                .levelCount = 1,
152                .baseArrayLayer = 0,
153                .layerCount = subresource->baseArrayLayer + vk_image_subresource_layer_count(&image->vk, subresource),
154             },
155       },
156       0, NULL);
157 
158    VkFormat store_format = vk_texcompress_etc2_store_format(image->vk.format);
159    struct radv_image_view dst_iview;
160    radv_image_view_init(
161       &dst_iview, cmd_buffer->device,
162       &(VkImageViewCreateInfo){
163          .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
164          .image = radv_image_to_handle(image),
165          .viewType = vk_texcompress_etc2_image_view_type(image->vk.image_type),
166          .format = store_format,
167          .subresourceRange =
168             {
169                .aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT,
170                .baseMipLevel = subresource->mipLevel,
171                .levelCount = 1,
172                .baseArrayLayer = 0,
173                .layerCount = subresource->baseArrayLayer + vk_image_subresource_layer_count(&image->vk, subresource),
174             },
175       },
176       0, NULL);
177 
178    decode_etc(cmd_buffer, &src_iview, &dst_iview, &(VkOffset3D){offset.x, offset.y, base_slice},
179               &(VkExtent3D){extent.width, extent.height, slice_count});
180 
181    radv_image_view_finish(&src_iview);
182    radv_image_view_finish(&dst_iview);
183 
184    radv_meta_restore(&saved_state, cmd_buffer);
185 }
186