• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2016 Dave Airlie
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 "nir/nir_format_convert.h"
12 
13 #include "radv_entrypoints.h"
14 #include "radv_formats.h"
15 #include "radv_meta.h"
16 #include "sid.h"
17 #include "vk_common_entrypoints.h"
18 #include "vk_format.h"
19 #include "vk_shader_module.h"
20 
21 static nir_def *
radv_meta_build_resolve_srgb_conversion(nir_builder * b,nir_def * input)22 radv_meta_build_resolve_srgb_conversion(nir_builder *b, nir_def *input)
23 {
24    unsigned i;
25    nir_def *comp[4];
26    for (i = 0; i < 3; i++)
27       comp[i] = nir_format_linear_to_srgb(b, nir_channel(b, input, i));
28    comp[3] = nir_channels(b, input, 1 << 3);
29    return nir_vec(b, comp, 4);
30 }
31 
32 static nir_shader *
build_resolve_compute_shader(struct radv_device * dev,bool is_integer,bool is_srgb,int samples)33 build_resolve_compute_shader(struct radv_device *dev, bool is_integer, bool is_srgb, int samples)
34 {
35    enum glsl_base_type img_base_type = is_integer ? GLSL_TYPE_UINT : GLSL_TYPE_FLOAT;
36    const struct glsl_type *sampler_type = glsl_sampler_type(GLSL_SAMPLER_DIM_MS, false, false, img_base_type);
37    const struct glsl_type *img_type = glsl_image_type(GLSL_SAMPLER_DIM_2D, false, img_base_type);
38    nir_builder b = radv_meta_init_shader(dev, MESA_SHADER_COMPUTE, "meta_resolve_cs-%d-%s", samples,
39                                          is_integer ? "int" : (is_srgb ? "srgb" : "float"));
40    b.shader->info.workgroup_size[0] = 8;
41    b.shader->info.workgroup_size[1] = 8;
42 
43    nir_variable *input_img = nir_variable_create(b.shader, nir_var_uniform, sampler_type, "s_tex");
44    input_img->data.descriptor_set = 0;
45    input_img->data.binding = 0;
46 
47    nir_variable *output_img = nir_variable_create(b.shader, nir_var_image, img_type, "out_img");
48    output_img->data.descriptor_set = 0;
49    output_img->data.binding = 1;
50 
51    nir_def *global_id = get_global_ids(&b, 2);
52 
53    nir_def *src_offset = nir_load_push_constant(&b, 2, 32, nir_imm_int(&b, 0), .range = 8);
54    nir_def *dst_offset = nir_load_push_constant(&b, 2, 32, nir_imm_int(&b, 8), .range = 16);
55 
56    nir_def *src_coord = nir_iadd(&b, global_id, src_offset);
57    nir_def *dst_coord = nir_iadd(&b, global_id, dst_offset);
58 
59    nir_variable *color = nir_local_variable_create(b.impl, glsl_vec4_type(), "color");
60 
61    radv_meta_build_resolve_shader_core(dev, &b, is_integer, samples, input_img, color, src_coord);
62 
63    nir_def *outval = nir_load_var(&b, color);
64    if (is_srgb)
65       outval = radv_meta_build_resolve_srgb_conversion(&b, outval);
66 
67    nir_def *img_coord = nir_vec4(&b, nir_channel(&b, dst_coord, 0), nir_channel(&b, dst_coord, 1), nir_undef(&b, 1, 32),
68                                  nir_undef(&b, 1, 32));
69 
70    nir_image_deref_store(&b, &nir_build_deref_var(&b, output_img)->def, img_coord, nir_undef(&b, 1, 32), outval,
71                          nir_imm_int(&b, 0), .image_dim = GLSL_SAMPLER_DIM_2D);
72    return b.shader;
73 }
74 
75 enum {
76    DEPTH_RESOLVE,
77    STENCIL_RESOLVE,
78 };
79 
80 static const char *
get_resolve_mode_str(VkResolveModeFlagBits resolve_mode)81 get_resolve_mode_str(VkResolveModeFlagBits resolve_mode)
82 {
83    switch (resolve_mode) {
84    case VK_RESOLVE_MODE_SAMPLE_ZERO_BIT:
85       return "zero";
86    case VK_RESOLVE_MODE_AVERAGE_BIT:
87       return "average";
88    case VK_RESOLVE_MODE_MIN_BIT:
89       return "min";
90    case VK_RESOLVE_MODE_MAX_BIT:
91       return "max";
92    default:
93       unreachable("invalid resolve mode");
94    }
95 }
96 
97 static nir_shader *
build_depth_stencil_resolve_compute_shader(struct radv_device * dev,int samples,int index,VkResolveModeFlagBits resolve_mode)98 build_depth_stencil_resolve_compute_shader(struct radv_device *dev, int samples, int index,
99                                            VkResolveModeFlagBits resolve_mode)
100 {
101    enum glsl_base_type img_base_type = index == DEPTH_RESOLVE ? GLSL_TYPE_FLOAT : GLSL_TYPE_UINT;
102    const struct glsl_type *sampler_type = glsl_sampler_type(GLSL_SAMPLER_DIM_MS, false, true, img_base_type);
103    const struct glsl_type *img_type = glsl_image_type(GLSL_SAMPLER_DIM_2D, true, img_base_type);
104 
105    nir_builder b =
106       radv_meta_init_shader(dev, MESA_SHADER_COMPUTE, "meta_resolve_cs_%s-%s-%d",
107                             index == DEPTH_RESOLVE ? "depth" : "stencil", get_resolve_mode_str(resolve_mode), samples);
108    b.shader->info.workgroup_size[0] = 8;
109    b.shader->info.workgroup_size[1] = 8;
110 
111    nir_variable *input_img = nir_variable_create(b.shader, nir_var_uniform, sampler_type, "s_tex");
112    input_img->data.descriptor_set = 0;
113    input_img->data.binding = 0;
114 
115    nir_variable *output_img = nir_variable_create(b.shader, nir_var_image, img_type, "out_img");
116    output_img->data.descriptor_set = 0;
117    output_img->data.binding = 1;
118 
119    nir_def *global_id = get_global_ids(&b, 3);
120 
121    nir_def *offset = nir_load_push_constant(&b, 2, 32, nir_imm_int(&b, 0), .range = 8);
122 
123    nir_def *resolve_coord = nir_iadd(&b, nir_trim_vector(&b, global_id, 2), offset);
124 
125    nir_def *img_coord =
126       nir_vec3(&b, nir_channel(&b, resolve_coord, 0), nir_channel(&b, resolve_coord, 1), nir_channel(&b, global_id, 2));
127 
128    nir_deref_instr *input_img_deref = nir_build_deref_var(&b, input_img);
129    nir_def *outval = nir_txf_ms_deref(&b, input_img_deref, img_coord, nir_imm_int(&b, 0));
130 
131    if (resolve_mode != VK_RESOLVE_MODE_SAMPLE_ZERO_BIT) {
132       for (int i = 1; i < samples; i++) {
133          nir_def *si = nir_txf_ms_deref(&b, input_img_deref, img_coord, nir_imm_int(&b, i));
134 
135          switch (resolve_mode) {
136          case VK_RESOLVE_MODE_AVERAGE_BIT:
137             assert(index == DEPTH_RESOLVE);
138             outval = nir_fadd(&b, outval, si);
139             break;
140          case VK_RESOLVE_MODE_MIN_BIT:
141             if (index == DEPTH_RESOLVE)
142                outval = nir_fmin(&b, outval, si);
143             else
144                outval = nir_umin(&b, outval, si);
145             break;
146          case VK_RESOLVE_MODE_MAX_BIT:
147             if (index == DEPTH_RESOLVE)
148                outval = nir_fmax(&b, outval, si);
149             else
150                outval = nir_umax(&b, outval, si);
151             break;
152          default:
153             unreachable("invalid resolve mode");
154          }
155       }
156 
157       if (resolve_mode == VK_RESOLVE_MODE_AVERAGE_BIT)
158          outval = nir_fdiv_imm(&b, outval, samples);
159    }
160 
161    nir_def *coord = nir_vec4(&b, nir_channel(&b, img_coord, 0), nir_channel(&b, img_coord, 1),
162                              nir_channel(&b, img_coord, 2), nir_undef(&b, 1, 32));
163    nir_image_deref_store(&b, &nir_build_deref_var(&b, output_img)->def, coord, nir_undef(&b, 1, 32), outval,
164                          nir_imm_int(&b, 0), .image_dim = GLSL_SAMPLER_DIM_2D, .image_array = true);
165    return b.shader;
166 }
167 
168 static VkResult
create_layout(struct radv_device * device,VkPipelineLayout * layout_out)169 create_layout(struct radv_device *device, VkPipelineLayout *layout_out)
170 {
171    enum radv_meta_object_key_type key = RADV_META_OBJECT_KEY_RESOLVE_CS;
172 
173    const VkDescriptorSetLayoutBinding bindings[] = {
174       {
175          .binding = 0,
176          .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
177          .descriptorCount = 1,
178          .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
179       },
180       {
181          .binding = 1,
182          .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
183          .descriptorCount = 1,
184          .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
185       },
186    };
187 
188    const VkDescriptorSetLayoutCreateInfo desc_info = {
189       .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
190       .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT,
191       .bindingCount = 2,
192       .pBindings = bindings,
193    };
194 
195    const VkPushConstantRange pc_range = {
196       .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
197       .size = 16,
198    };
199 
200    return vk_meta_get_pipeline_layout(&device->vk, &device->meta_state.device, &desc_info, &pc_range, &key, sizeof(key),
201                                       layout_out);
202 }
203 
204 struct radv_resolve_color_cs_key {
205    enum radv_meta_object_key_type type;
206    bool is_integer;
207    bool is_srgb;
208    uint8_t samples;
209 };
210 
211 static VkResult
get_color_resolve_pipeline(struct radv_device * device,struct radv_image_view * src_iview,VkPipeline * pipeline_out,VkPipelineLayout * layout_out)212 get_color_resolve_pipeline(struct radv_device *device, struct radv_image_view *src_iview, VkPipeline *pipeline_out,
213                            VkPipelineLayout *layout_out)
214 {
215    const bool is_integer = vk_format_is_int(src_iview->vk.format);
216    const bool is_srgb = vk_format_is_srgb(src_iview->vk.format);
217    uint32_t samples = src_iview->image->vk.samples;
218    struct radv_resolve_color_cs_key key;
219    VkResult result;
220 
221    result = create_layout(device, layout_out);
222    if (result != VK_SUCCESS)
223       return result;
224 
225    memset(&key, 0, sizeof(key));
226    key.type = RADV_META_OBJECT_KEY_RESOLVE_COLOR_CS;
227    key.is_integer = is_integer;
228    key.is_srgb = is_srgb;
229    key.samples = samples;
230 
231    VkPipeline pipeline_from_cache = vk_meta_lookup_pipeline(&device->meta_state.device, &key, sizeof(key));
232    if (pipeline_from_cache != VK_NULL_HANDLE) {
233       *pipeline_out = pipeline_from_cache;
234       return VK_SUCCESS;
235    }
236 
237    nir_shader *cs = build_resolve_compute_shader(device, is_integer, is_srgb, samples);
238 
239    const VkPipelineShaderStageCreateInfo stage_info = {
240       .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
241       .stage = VK_SHADER_STAGE_COMPUTE_BIT,
242       .module = vk_shader_module_handle_from_nir(cs),
243       .pName = "main",
244       .pSpecializationInfo = NULL,
245    };
246 
247    const VkComputePipelineCreateInfo pipeline_info = {
248       .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
249       .stage = stage_info,
250       .flags = 0,
251       .layout = *layout_out,
252    };
253 
254    result = vk_meta_create_compute_pipeline(&device->vk, &device->meta_state.device, &pipeline_info, &key, sizeof(key),
255                                             pipeline_out);
256 
257    ralloc_free(cs);
258    return result;
259 }
260 
261 static void
emit_resolve(struct radv_cmd_buffer * cmd_buffer,struct radv_image_view * src_iview,struct radv_image_view * dst_iview,const VkOffset2D * src_offset,const VkOffset2D * dst_offset,const VkExtent2D * resolve_extent)262 emit_resolve(struct radv_cmd_buffer *cmd_buffer, struct radv_image_view *src_iview, struct radv_image_view *dst_iview,
263              const VkOffset2D *src_offset, const VkOffset2D *dst_offset, const VkExtent2D *resolve_extent)
264 {
265    struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
266    VkPipelineLayout layout;
267    VkPipeline pipeline;
268    VkResult result;
269 
270    result = get_color_resolve_pipeline(device, src_iview, &pipeline, &layout);
271    if (result != VK_SUCCESS) {
272       vk_command_buffer_set_error(&cmd_buffer->vk, result);
273       return;
274    }
275 
276    radv_meta_push_descriptor_set(cmd_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, layout, 0, 2,
277                                  (VkWriteDescriptorSet[]){{.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
278                                                            .dstBinding = 0,
279                                                            .dstArrayElement = 0,
280                                                            .descriptorCount = 1,
281                                                            .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
282                                                            .pImageInfo =
283                                                               (VkDescriptorImageInfo[]){
284                                                                  {.sampler = VK_NULL_HANDLE,
285                                                                   .imageView = radv_image_view_to_handle(src_iview),
286                                                                   .imageLayout = VK_IMAGE_LAYOUT_GENERAL},
287                                                               }},
288                                                           {.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
289                                                            .dstBinding = 1,
290                                                            .dstArrayElement = 0,
291                                                            .descriptorCount = 1,
292                                                            .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
293                                                            .pImageInfo = (VkDescriptorImageInfo[]){
294                                                               {
295                                                                  .sampler = VK_NULL_HANDLE,
296                                                                  .imageView = radv_image_view_to_handle(dst_iview),
297                                                                  .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
298                                                               },
299                                                            }}});
300 
301    radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);
302 
303    unsigned push_constants[4] = {
304       src_offset->x,
305       src_offset->y,
306       dst_offset->x,
307       dst_offset->y,
308    };
309    vk_common_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer), layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, 16,
310                               push_constants);
311    radv_unaligned_dispatch(cmd_buffer, resolve_extent->width, resolve_extent->height, 1);
312 }
313 
314 struct radv_resolve_ds_cs_key {
315    enum radv_meta_object_key_type type;
316    uint8_t index;
317    uint8_t samples;
318    VkResolveModeFlagBits resolve_mode;
319 };
320 
321 static VkResult
get_depth_stencil_resolve_pipeline(struct radv_device * device,int samples,VkImageAspectFlags aspects,VkResolveModeFlagBits resolve_mode,VkPipeline * pipeline_out,VkPipelineLayout * layout_out)322 get_depth_stencil_resolve_pipeline(struct radv_device *device, int samples, VkImageAspectFlags aspects,
323                                    VkResolveModeFlagBits resolve_mode, VkPipeline *pipeline_out,
324                                    VkPipelineLayout *layout_out)
325 
326 {
327    const int index = aspects == VK_IMAGE_ASPECT_DEPTH_BIT ? DEPTH_RESOLVE : STENCIL_RESOLVE;
328    struct radv_resolve_ds_cs_key key;
329    VkResult result;
330 
331    result = create_layout(device, layout_out);
332    if (result != VK_SUCCESS)
333       return result;
334 
335    memset(&key, 0, sizeof(key));
336    key.type = RADV_META_OBJECT_KEY_RESOLVE_DS_CS;
337    key.index = index;
338    key.samples = samples;
339    key.resolve_mode = resolve_mode;
340 
341    VkPipeline pipeline_from_cache = vk_meta_lookup_pipeline(&device->meta_state.device, &key, sizeof(key));
342    if (pipeline_from_cache != VK_NULL_HANDLE) {
343       *pipeline_out = pipeline_from_cache;
344       return VK_SUCCESS;
345    }
346 
347    nir_shader *cs = build_depth_stencil_resolve_compute_shader(device, samples, index, resolve_mode);
348 
349    const VkPipelineShaderStageCreateInfo stage_info = {
350       .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
351       .stage = VK_SHADER_STAGE_COMPUTE_BIT,
352       .module = vk_shader_module_handle_from_nir(cs),
353       .pName = "main",
354       .pSpecializationInfo = NULL,
355    };
356 
357    const VkComputePipelineCreateInfo pipeline_info = {
358       .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
359       .stage = stage_info,
360       .flags = 0,
361       .layout = *layout_out,
362    };
363 
364    result = vk_meta_create_compute_pipeline(&device->vk, &device->meta_state.device, &pipeline_info, &key, sizeof(key),
365                                             pipeline_out);
366 
367    ralloc_free(cs);
368    return result;
369 }
370 
371 static void
emit_depth_stencil_resolve(struct radv_cmd_buffer * cmd_buffer,struct radv_image_view * src_iview,struct radv_image_view * dst_iview,const VkOffset2D * resolve_offset,const VkExtent3D * resolve_extent,VkImageAspectFlags aspects,VkResolveModeFlagBits resolve_mode)372 emit_depth_stencil_resolve(struct radv_cmd_buffer *cmd_buffer, struct radv_image_view *src_iview,
373                            struct radv_image_view *dst_iview, const VkOffset2D *resolve_offset,
374                            const VkExtent3D *resolve_extent, VkImageAspectFlags aspects,
375                            VkResolveModeFlagBits resolve_mode)
376 {
377    struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
378    const uint32_t samples = src_iview->image->vk.samples;
379    VkPipelineLayout layout;
380    VkPipeline pipeline;
381    VkResult result;
382 
383    result = get_depth_stencil_resolve_pipeline(device, samples, aspects, resolve_mode, &pipeline, &layout);
384    if (result != VK_SUCCESS) {
385       vk_command_buffer_set_error(&cmd_buffer->vk, result);
386       return;
387    }
388 
389    radv_meta_push_descriptor_set(cmd_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, layout, 0, 2,
390                                  (VkWriteDescriptorSet[]){{.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
391                                                            .dstBinding = 0,
392                                                            .dstArrayElement = 0,
393                                                            .descriptorCount = 1,
394                                                            .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
395                                                            .pImageInfo =
396                                                               (VkDescriptorImageInfo[]){
397                                                                  {.sampler = VK_NULL_HANDLE,
398                                                                   .imageView = radv_image_view_to_handle(src_iview),
399                                                                   .imageLayout = VK_IMAGE_LAYOUT_GENERAL},
400                                                               }},
401                                                           {.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
402                                                            .dstBinding = 1,
403                                                            .dstArrayElement = 0,
404                                                            .descriptorCount = 1,
405                                                            .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
406                                                            .pImageInfo = (VkDescriptorImageInfo[]){
407                                                               {
408                                                                  .sampler = VK_NULL_HANDLE,
409                                                                  .imageView = radv_image_view_to_handle(dst_iview),
410                                                                  .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
411                                                               },
412                                                            }}});
413 
414    radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);
415 
416    uint32_t push_constants[2] = {resolve_offset->x, resolve_offset->y};
417 
418    vk_common_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer), layout, VK_SHADER_STAGE_COMPUTE_BIT, 0,
419                               sizeof(push_constants), push_constants);
420 
421    radv_unaligned_dispatch(cmd_buffer, resolve_extent->width, resolve_extent->height, resolve_extent->depth);
422 }
423 
424 void
radv_meta_resolve_compute_image(struct radv_cmd_buffer * cmd_buffer,struct radv_image * src_image,VkFormat src_format,VkImageLayout src_image_layout,struct radv_image * dst_image,VkFormat dst_format,VkImageLayout dst_image_layout,const VkImageResolve2 * region)425 radv_meta_resolve_compute_image(struct radv_cmd_buffer *cmd_buffer, struct radv_image *src_image, VkFormat src_format,
426                                 VkImageLayout src_image_layout, struct radv_image *dst_image, VkFormat dst_format,
427                                 VkImageLayout dst_image_layout, const VkImageResolve2 *region)
428 {
429    struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
430    struct radv_meta_saved_state saved_state;
431 
432    /* For partial resolves, DCC should be decompressed before resolving
433     * because the metadata is re-initialized to the uncompressed after.
434     */
435    uint32_t queue_mask = radv_image_queue_family_mask(dst_image, cmd_buffer->qf, cmd_buffer->qf);
436 
437    if (!radv_image_use_dcc_image_stores(device, dst_image) &&
438        radv_layout_dcc_compressed(device, dst_image, region->dstSubresource.mipLevel, dst_image_layout, queue_mask) &&
439        (region->dstOffset.x || region->dstOffset.y || region->dstOffset.z ||
440         region->extent.width != dst_image->vk.extent.width || region->extent.height != dst_image->vk.extent.height ||
441         region->extent.depth != dst_image->vk.extent.depth)) {
442       radv_decompress_dcc(cmd_buffer, dst_image,
443                           &(VkImageSubresourceRange){
444                              .aspectMask = region->dstSubresource.aspectMask,
445                              .baseMipLevel = region->dstSubresource.mipLevel,
446                              .levelCount = 1,
447                              .baseArrayLayer = region->dstSubresource.baseArrayLayer,
448                              .layerCount = vk_image_subresource_layer_count(&dst_image->vk, &region->dstSubresource),
449                           });
450    }
451 
452    radv_meta_save(&saved_state, cmd_buffer,
453                   RADV_META_SAVE_COMPUTE_PIPELINE | RADV_META_SAVE_CONSTANTS | RADV_META_SAVE_DESCRIPTORS);
454 
455    assert(region->srcSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
456    assert(region->dstSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
457    assert(vk_image_subresource_layer_count(&src_image->vk, &region->srcSubresource) ==
458           vk_image_subresource_layer_count(&dst_image->vk, &region->dstSubresource));
459 
460    const uint32_t dst_base_layer = radv_meta_get_iview_layer(dst_image, &region->dstSubresource, &region->dstOffset);
461 
462    const struct VkExtent3D extent = vk_image_sanitize_extent(&src_image->vk, region->extent);
463    const struct VkOffset3D srcOffset = vk_image_sanitize_offset(&src_image->vk, region->srcOffset);
464    const struct VkOffset3D dstOffset = vk_image_sanitize_offset(&dst_image->vk, region->dstOffset);
465    const unsigned src_layer_count = vk_image_subresource_layer_count(&src_image->vk, &region->srcSubresource);
466 
467    for (uint32_t layer = 0; layer < src_layer_count; ++layer) {
468 
469       struct radv_image_view src_iview;
470       radv_image_view_init(&src_iview, device,
471                            &(VkImageViewCreateInfo){
472                               .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
473                               .image = radv_image_to_handle(src_image),
474                               .viewType = VK_IMAGE_VIEW_TYPE_2D,
475                               .format = src_format,
476                               .subresourceRange =
477                                  {
478                                     .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
479                                     .baseMipLevel = 0,
480                                     .levelCount = 1,
481                                     .baseArrayLayer = region->srcSubresource.baseArrayLayer + layer,
482                                     .layerCount = 1,
483                                  },
484                            },
485                            NULL);
486 
487       struct radv_image_view dst_iview;
488       radv_image_view_init(&dst_iview, device,
489                            &(VkImageViewCreateInfo){
490                               .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
491                               .image = radv_image_to_handle(dst_image),
492                               .viewType = radv_meta_get_view_type(dst_image),
493                               .format = vk_format_no_srgb(dst_format),
494                               .subresourceRange =
495                                  {
496                                     .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
497                                     .baseMipLevel = region->dstSubresource.mipLevel,
498                                     .levelCount = 1,
499                                     .baseArrayLayer = dst_base_layer + layer,
500                                     .layerCount = 1,
501                                  },
502                            },
503                            NULL);
504 
505       emit_resolve(cmd_buffer, &src_iview, &dst_iview, &(VkOffset2D){srcOffset.x, srcOffset.y},
506                    &(VkOffset2D){dstOffset.x, dstOffset.y}, &(VkExtent2D){extent.width, extent.height});
507 
508       radv_image_view_finish(&src_iview);
509       radv_image_view_finish(&dst_iview);
510    }
511 
512    radv_meta_restore(&saved_state, cmd_buffer);
513 
514    if (!radv_image_use_dcc_image_stores(device, dst_image) &&
515        radv_layout_dcc_compressed(device, dst_image, region->dstSubresource.mipLevel, dst_image_layout, queue_mask)) {
516 
517       cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_CS_PARTIAL_FLUSH | RADV_CMD_FLAG_INV_VCACHE;
518 
519       VkImageSubresourceRange range = {
520          .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
521          .baseMipLevel = region->dstSubresource.mipLevel,
522          .levelCount = 1,
523          .baseArrayLayer = dst_base_layer,
524          .layerCount = vk_image_subresource_layer_count(&dst_image->vk, &region->dstSubresource),
525       };
526 
527       cmd_buffer->state.flush_bits |= radv_init_dcc(cmd_buffer, dst_image, &range, 0xffffffff);
528    }
529 }
530 
531 void
radv_cmd_buffer_resolve_rendering_cs(struct radv_cmd_buffer * cmd_buffer,struct radv_image_view * src_iview,VkImageLayout src_layout,struct radv_image_view * dst_iview,VkImageLayout dst_layout,const VkImageResolve2 * region)532 radv_cmd_buffer_resolve_rendering_cs(struct radv_cmd_buffer *cmd_buffer, struct radv_image_view *src_iview,
533                                      VkImageLayout src_layout, struct radv_image_view *dst_iview,
534                                      VkImageLayout dst_layout, const VkImageResolve2 *region)
535 {
536    radv_meta_resolve_compute_image(cmd_buffer, src_iview->image, src_iview->vk.format, src_layout, dst_iview->image,
537                                    dst_iview->vk.format, dst_layout, region);
538 
539    cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_CS_PARTIAL_FLUSH | RADV_CMD_FLAG_INV_VCACHE |
540                                    radv_src_access_flush(cmd_buffer, VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
541                                                          VK_ACCESS_2_SHADER_WRITE_BIT, 0, NULL, NULL);
542 }
543 
544 void
radv_depth_stencil_resolve_rendering_cs(struct radv_cmd_buffer * cmd_buffer,VkImageAspectFlags aspects,VkResolveModeFlagBits resolve_mode)545 radv_depth_stencil_resolve_rendering_cs(struct radv_cmd_buffer *cmd_buffer, VkImageAspectFlags aspects,
546                                         VkResolveModeFlagBits resolve_mode)
547 {
548    struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
549    const struct radv_rendering_state *render = &cmd_buffer->state.render;
550    VkRect2D resolve_area = render->area;
551    struct radv_meta_saved_state saved_state;
552 
553    uint32_t layer_count = render->layer_count;
554    if (render->view_mask)
555       layer_count = util_last_bit(render->view_mask);
556 
557    /* Resolves happen before the end-of-subpass barriers get executed, so
558     * we have to make the attachment shader-readable.
559     */
560    cmd_buffer->state.flush_bits |=
561       radv_src_access_flush(cmd_buffer, VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
562                             VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, 0, NULL, NULL) |
563       radv_dst_access_flush(cmd_buffer, VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, VK_ACCESS_2_SHADER_READ_BIT, 0, NULL,
564                             NULL);
565 
566    struct radv_image_view *src_iview = render->ds_att.iview;
567    VkImageLayout src_layout =
568       aspects & VK_IMAGE_ASPECT_DEPTH_BIT ? render->ds_att.layout : render->ds_att.stencil_layout;
569    struct radv_image *src_image = src_iview->image;
570 
571    VkImageResolve2 region = {0};
572    region.sType = VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2;
573    region.srcSubresource.aspectMask = aspects;
574    region.srcSubresource.mipLevel = 0;
575    region.srcSubresource.baseArrayLayer = src_iview->vk.base_array_layer;
576    region.srcSubresource.layerCount = layer_count;
577 
578    radv_decompress_resolve_src(cmd_buffer, src_image, src_layout, &region);
579 
580    radv_meta_save(&saved_state, cmd_buffer, RADV_META_SAVE_COMPUTE_PIPELINE | RADV_META_SAVE_DESCRIPTORS);
581 
582    struct radv_image_view *dst_iview = render->ds_att.resolve_iview;
583    VkImageLayout dst_layout =
584       aspects & VK_IMAGE_ASPECT_DEPTH_BIT ? render->ds_att.resolve_layout : render->ds_att.stencil_resolve_layout;
585    struct radv_image *dst_image = dst_iview->image;
586 
587    struct radv_image_view tsrc_iview;
588    radv_image_view_init(&tsrc_iview, device,
589                         &(VkImageViewCreateInfo){
590                            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
591                            .image = radv_image_to_handle(src_image),
592                            .viewType = VK_IMAGE_VIEW_TYPE_2D,
593                            .format = src_iview->vk.format,
594                            .subresourceRange =
595                               {
596                                  .aspectMask = aspects,
597                                  .baseMipLevel = 0,
598                                  .levelCount = 1,
599                                  .baseArrayLayer = src_iview->vk.base_array_layer,
600                                  .layerCount = layer_count,
601                               },
602                         },
603                         NULL);
604 
605    struct radv_image_view tdst_iview;
606    radv_image_view_init(&tdst_iview, device,
607                         &(VkImageViewCreateInfo){
608                            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
609                            .image = radv_image_to_handle(dst_image),
610                            .viewType = radv_meta_get_view_type(dst_image),
611                            .format = dst_iview->vk.format,
612                            .subresourceRange =
613                               {
614                                  .aspectMask = aspects,
615                                  .baseMipLevel = dst_iview->vk.base_mip_level,
616                                  .levelCount = 1,
617                                  .baseArrayLayer = dst_iview->vk.base_array_layer,
618                                  .layerCount = layer_count,
619                               },
620                         },
621                         NULL);
622 
623    emit_depth_stencil_resolve(cmd_buffer, &tsrc_iview, &tdst_iview, &resolve_area.offset,
624                               &(VkExtent3D){resolve_area.extent.width, resolve_area.extent.height, layer_count},
625                               aspects, resolve_mode);
626 
627    cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_CS_PARTIAL_FLUSH | RADV_CMD_FLAG_INV_VCACHE |
628                                    radv_src_access_flush(cmd_buffer, VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
629                                                          VK_ACCESS_2_SHADER_WRITE_BIT, 0, NULL, NULL);
630 
631    uint32_t queue_mask = radv_image_queue_family_mask(dst_image, cmd_buffer->qf, cmd_buffer->qf);
632 
633    if (radv_layout_is_htile_compressed(device, dst_image, dst_layout, queue_mask)) {
634       VkImageSubresourceRange range = {0};
635       range.aspectMask = aspects;
636       range.baseMipLevel = dst_iview->vk.base_mip_level;
637       range.levelCount = 1;
638       range.baseArrayLayer = dst_iview->vk.base_array_layer;
639       range.layerCount = layer_count;
640 
641       uint32_t htile_value = radv_get_htile_initial_value(device, dst_image);
642 
643       cmd_buffer->state.flush_bits |= radv_clear_htile(cmd_buffer, dst_image, &range, htile_value, false);
644    }
645 
646    radv_image_view_finish(&tsrc_iview);
647    radv_image_view_finish(&tdst_iview);
648 
649    radv_meta_restore(&saved_state, cmd_buffer);
650 }
651