• 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 "radv_entrypoints.h"
12 #include "radv_meta.h"
13 #include "sid.h"
14 #include "vk_common_entrypoints.h"
15 #include "vk_format.h"
16 
17 static nir_shader *
build_resolve_fragment_shader(struct radv_device * dev,bool is_integer,int samples)18 build_resolve_fragment_shader(struct radv_device *dev, bool is_integer, int samples)
19 {
20    enum glsl_base_type img_base_type = is_integer ? GLSL_TYPE_UINT : GLSL_TYPE_FLOAT;
21    const struct glsl_type *vec4 = glsl_vec4_type();
22    const struct glsl_type *sampler_type = glsl_sampler_type(GLSL_SAMPLER_DIM_MS, false, false, img_base_type);
23 
24    nir_builder b =
25       radv_meta_init_shader(dev, MESA_SHADER_FRAGMENT, "meta_resolve_fs-%d-%s", samples, is_integer ? "int" : "float");
26 
27    nir_variable *input_img = nir_variable_create(b.shader, nir_var_uniform, sampler_type, "s_tex");
28    input_img->data.descriptor_set = 0;
29    input_img->data.binding = 0;
30 
31    nir_variable *color_out = nir_variable_create(b.shader, nir_var_shader_out, vec4, "f_color");
32    color_out->data.location = FRAG_RESULT_DATA0;
33 
34    nir_def *pos_in = nir_trim_vector(&b, nir_load_frag_coord(&b), 2);
35    nir_def *src_offset = nir_load_push_constant(&b, 2, 32, nir_imm_int(&b, 0), .range = 8);
36 
37    nir_def *pos_int = nir_f2i32(&b, pos_in);
38 
39    nir_def *img_coord = nir_trim_vector(&b, nir_iadd(&b, pos_int, src_offset), 2);
40    nir_variable *color = nir_local_variable_create(b.impl, glsl_vec4_type(), "color");
41 
42    radv_meta_build_resolve_shader_core(dev, &b, is_integer, samples, input_img, color, img_coord);
43 
44    nir_def *outval = nir_load_var(&b, color);
45    nir_store_var(&b, color_out, outval, 0xf);
46    return b.shader;
47 }
48 
49 static VkResult
create_layout(struct radv_device * device,VkPipelineLayout * layout_out)50 create_layout(struct radv_device *device, VkPipelineLayout *layout_out)
51 {
52    enum radv_meta_object_key_type key = RADV_META_OBJECT_KEY_RESOLVE_FS;
53 
54    const VkDescriptorSetLayoutBinding binding = {.binding = 0,
55                                                  .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
56                                                  .descriptorCount = 1,
57                                                  .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT};
58 
59    const VkDescriptorSetLayoutCreateInfo desc_info = {
60       .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
61       .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT,
62       .bindingCount = 1,
63       .pBindings = &binding,
64    };
65 
66    const VkPushConstantRange pc_range = {
67       .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
68       .size = 8,
69    };
70 
71    return vk_meta_get_pipeline_layout(&device->vk, &device->meta_state.device, &desc_info, &pc_range, &key, sizeof(key),
72                                       layout_out);
73 }
74 
75 enum { DEPTH_RESOLVE, STENCIL_RESOLVE };
76 
77 static const char *
get_resolve_mode_str(VkResolveModeFlagBits resolve_mode)78 get_resolve_mode_str(VkResolveModeFlagBits resolve_mode)
79 {
80    switch (resolve_mode) {
81    case VK_RESOLVE_MODE_SAMPLE_ZERO_BIT:
82       return "zero";
83    case VK_RESOLVE_MODE_AVERAGE_BIT:
84       return "average";
85    case VK_RESOLVE_MODE_MIN_BIT:
86       return "min";
87    case VK_RESOLVE_MODE_MAX_BIT:
88       return "max";
89    default:
90       unreachable("invalid resolve mode");
91    }
92 }
93 
94 static nir_shader *
build_depth_stencil_resolve_fragment_shader(struct radv_device * dev,int samples,int index,VkResolveModeFlagBits resolve_mode)95 build_depth_stencil_resolve_fragment_shader(struct radv_device *dev, int samples, int index,
96                                             VkResolveModeFlagBits resolve_mode)
97 {
98    enum glsl_base_type img_base_type = index == DEPTH_RESOLVE ? GLSL_TYPE_FLOAT : GLSL_TYPE_UINT;
99    const struct glsl_type *vec4 = glsl_vec4_type();
100    const struct glsl_type *sampler_type = glsl_sampler_type(GLSL_SAMPLER_DIM_MS, false, false, img_base_type);
101 
102    nir_builder b =
103       radv_meta_init_shader(dev, MESA_SHADER_FRAGMENT, "meta_resolve_fs_%s-%s-%d",
104                             index == DEPTH_RESOLVE ? "depth" : "stencil", get_resolve_mode_str(resolve_mode), samples);
105 
106    nir_variable *input_img = nir_variable_create(b.shader, nir_var_uniform, sampler_type, "s_tex");
107    input_img->data.descriptor_set = 0;
108    input_img->data.binding = 0;
109 
110    nir_variable *fs_out = nir_variable_create(b.shader, nir_var_shader_out, vec4, "f_out");
111    fs_out->data.location = index == DEPTH_RESOLVE ? FRAG_RESULT_DEPTH : FRAG_RESULT_STENCIL;
112 
113    nir_def *pos_in = nir_trim_vector(&b, nir_load_frag_coord(&b), 2);
114 
115    nir_def *pos_int = nir_f2i32(&b, pos_in);
116 
117    nir_def *img_coord = nir_trim_vector(&b, pos_int, 2);
118 
119    nir_deref_instr *input_img_deref = nir_build_deref_var(&b, input_img);
120    nir_def *outval = nir_txf_ms_deref(&b, input_img_deref, img_coord, nir_imm_int(&b, 0));
121 
122    if (resolve_mode != VK_RESOLVE_MODE_SAMPLE_ZERO_BIT) {
123       for (int i = 1; i < samples; i++) {
124          nir_def *si = nir_txf_ms_deref(&b, input_img_deref, img_coord, nir_imm_int(&b, i));
125 
126          switch (resolve_mode) {
127          case VK_RESOLVE_MODE_AVERAGE_BIT:
128             assert(index == DEPTH_RESOLVE);
129             outval = nir_fadd(&b, outval, si);
130             break;
131          case VK_RESOLVE_MODE_MIN_BIT:
132             if (index == DEPTH_RESOLVE)
133                outval = nir_fmin(&b, outval, si);
134             else
135                outval = nir_umin(&b, outval, si);
136             break;
137          case VK_RESOLVE_MODE_MAX_BIT:
138             if (index == DEPTH_RESOLVE)
139                outval = nir_fmax(&b, outval, si);
140             else
141                outval = nir_umax(&b, outval, si);
142             break;
143          default:
144             unreachable("invalid resolve mode");
145          }
146       }
147 
148       if (resolve_mode == VK_RESOLVE_MODE_AVERAGE_BIT)
149          outval = nir_fdiv_imm(&b, outval, samples);
150    }
151 
152    nir_store_var(&b, fs_out, outval, 0x1);
153 
154    return b.shader;
155 }
156 
157 struct radv_resolve_ds_fs_key {
158    enum radv_meta_object_key_type type;
159    uint32_t samples;
160    VkImageAspectFlags aspects;
161    VkResolveModeFlagBits resolve_mode;
162 };
163 
164 static VkResult
get_depth_stencil_resolve_pipeline(struct radv_device * device,int samples,VkImageAspectFlags aspects,VkResolveModeFlagBits resolve_mode,VkPipeline * pipeline_out,VkPipelineLayout * layout_out)165 get_depth_stencil_resolve_pipeline(struct radv_device *device, int samples, VkImageAspectFlags aspects,
166                                    VkResolveModeFlagBits resolve_mode, VkPipeline *pipeline_out,
167                                    VkPipelineLayout *layout_out)
168 {
169    const int index = aspects == VK_IMAGE_ASPECT_DEPTH_BIT ? DEPTH_RESOLVE : STENCIL_RESOLVE;
170    struct radv_resolve_ds_fs_key key;
171    VkResult result;
172 
173    result = create_layout(device, layout_out);
174    if (result != VK_SUCCESS)
175       return result;
176 
177    memset(&key, 0, sizeof(key));
178    key.type = RADV_META_OBJECT_KEY_RESOLVE_DS_FS;
179    key.samples = samples;
180    key.aspects = aspects;
181    key.resolve_mode = resolve_mode;
182 
183    VkPipeline pipeline_from_cache = vk_meta_lookup_pipeline(&device->meta_state.device, &key, sizeof(key));
184    if (pipeline_from_cache != VK_NULL_HANDLE) {
185       *pipeline_out = pipeline_from_cache;
186       return VK_SUCCESS;
187    }
188 
189    nir_shader *fs_module = build_depth_stencil_resolve_fragment_shader(device, samples, index, resolve_mode);
190    nir_shader *vs_module = radv_meta_build_nir_vs_generate_vertices(device);
191 
192    const VkStencilOp stencil_op = index == DEPTH_RESOLVE ? VK_STENCIL_OP_KEEP : VK_STENCIL_OP_REPLACE;
193 
194    const VkGraphicsPipelineCreateInfo pipeline_create_info = {
195       .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
196       .stageCount = 2,
197       .pStages =
198          (VkPipelineShaderStageCreateInfo[]){
199             {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
200              .stage = VK_SHADER_STAGE_VERTEX_BIT,
201              .module = vk_shader_module_handle_from_nir(vs_module),
202              .pName = "main",
203              .pSpecializationInfo = NULL},
204             {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
205              .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
206              .module = vk_shader_module_handle_from_nir(fs_module),
207              .pName = "main",
208              .pSpecializationInfo = NULL},
209          },
210       .pVertexInputState =
211          &(VkPipelineVertexInputStateCreateInfo){
212             .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
213             .vertexBindingDescriptionCount = 0,
214             .vertexAttributeDescriptionCount = 0,
215 
216          },
217       .pInputAssemblyState =
218          &(VkPipelineInputAssemblyStateCreateInfo){
219             .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
220             .topology = VK_PRIMITIVE_TOPOLOGY_META_RECT_LIST_MESA,
221             .primitiveRestartEnable = false,
222          },
223       .pViewportState =
224          &(VkPipelineViewportStateCreateInfo){
225             .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
226             .viewportCount = 1,
227             .scissorCount = 1,
228          },
229       .pDepthStencilState =
230          &(VkPipelineDepthStencilStateCreateInfo){.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
231                                                   .depthTestEnable = true,
232                                                   .depthWriteEnable = index == DEPTH_RESOLVE,
233                                                   .stencilTestEnable = index == STENCIL_RESOLVE,
234                                                   .depthCompareOp = VK_COMPARE_OP_ALWAYS,
235                                                   .front =
236                                                      {
237                                                         .failOp = stencil_op,
238                                                         .passOp = stencil_op,
239                                                         .depthFailOp = stencil_op,
240                                                         .compareOp = VK_COMPARE_OP_ALWAYS,
241                                                         .compareMask = UINT32_MAX,
242                                                         .writeMask = UINT32_MAX,
243                                                         .reference = 0u,
244                                                      },
245                                                   .back =
246                                                      {
247                                                         .failOp = stencil_op,
248                                                         .passOp = stencil_op,
249                                                         .depthFailOp = stencil_op,
250                                                         .compareOp = VK_COMPARE_OP_ALWAYS,
251                                                         .compareMask = UINT32_MAX,
252                                                         .writeMask = UINT32_MAX,
253                                                         .reference = 0u,
254                                                      },
255                                                   .minDepthBounds = 0.0f,
256                                                   .maxDepthBounds = 1.0f},
257       .pRasterizationState =
258          &(VkPipelineRasterizationStateCreateInfo){.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
259                                                    .rasterizerDiscardEnable = false,
260                                                    .polygonMode = VK_POLYGON_MODE_FILL,
261                                                    .cullMode = VK_CULL_MODE_NONE,
262                                                    .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
263                                                    .depthBiasConstantFactor = 0.0f,
264                                                    .depthBiasClamp = 0.0f,
265                                                    .depthBiasSlopeFactor = 0.0f,
266                                                    .lineWidth = 1.0f},
267       .pMultisampleState =
268          &(VkPipelineMultisampleStateCreateInfo){
269             .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
270             .rasterizationSamples = 1,
271             .sampleShadingEnable = false,
272             .pSampleMask = (VkSampleMask[]){UINT32_MAX},
273          },
274       .pColorBlendState =
275          &(VkPipelineColorBlendStateCreateInfo){
276             .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
277             .attachmentCount = 0,
278             .pAttachments =
279                (VkPipelineColorBlendAttachmentState[]){
280                   {.colorWriteMask = VK_COLOR_COMPONENT_A_BIT | VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
281                                      VK_COLOR_COMPONENT_B_BIT},
282                },
283             .blendConstants = {0.0f, 0.0f, 0.0f, 0.0f}},
284       .pDynamicState =
285          &(VkPipelineDynamicStateCreateInfo){
286             .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
287             .dynamicStateCount = 2,
288             .pDynamicStates =
289                (VkDynamicState[]){
290                   VK_DYNAMIC_STATE_VIEWPORT,
291                   VK_DYNAMIC_STATE_SCISSOR,
292                },
293          },
294       .layout = *layout_out,
295    };
296 
297    struct vk_meta_rendering_info render = {
298       .depth_attachment_format = index == DEPTH_RESOLVE ? VK_FORMAT_D32_SFLOAT : VK_FORMAT_UNDEFINED,
299       .stencil_attachment_format = index == STENCIL_RESOLVE ? VK_FORMAT_S8_UINT : VK_FORMAT_UNDEFINED,
300    };
301 
302    result = vk_meta_create_graphics_pipeline(&device->vk, &device->meta_state.device, &pipeline_create_info, &render,
303                                              &key, sizeof(key), pipeline_out);
304 
305    ralloc_free(vs_module);
306    ralloc_free(fs_module);
307    return result;
308 }
309 
310 struct radv_resolve_color_fs_key {
311    enum radv_meta_object_key_type type;
312    uint32_t samples;
313    uint32_t fs_key;
314 };
315 
316 static VkResult
get_color_resolve_pipeline(struct radv_device * device,struct radv_image_view * src_iview,struct radv_image_view * dst_iview,VkPipeline * pipeline_out,VkPipelineLayout * layout_out)317 get_color_resolve_pipeline(struct radv_device *device, struct radv_image_view *src_iview,
318                            struct radv_image_view *dst_iview, VkPipeline *pipeline_out, VkPipelineLayout *layout_out)
319 {
320    const unsigned fs_key = radv_format_meta_fs_key(device, dst_iview->vk.format);
321    const uint32_t samples = src_iview->image->vk.samples;
322    const VkFormat format = radv_fs_key_format_exemplars[fs_key];
323    const bool is_integer = vk_format_is_int(format);
324    struct radv_resolve_color_fs_key key;
325    VkResult result;
326 
327    result = create_layout(device, layout_out);
328    if (result != VK_SUCCESS)
329       return result;
330 
331    memset(&key, 0, sizeof(key));
332    key.type = RADV_META_OBJECT_KEY_RESOLVE_COLOR_FS;
333    key.samples = samples;
334    key.fs_key = fs_key;
335 
336    VkPipeline pipeline_from_cache = vk_meta_lookup_pipeline(&device->meta_state.device, &key, sizeof(key));
337    if (pipeline_from_cache != VK_NULL_HANDLE) {
338       *pipeline_out = pipeline_from_cache;
339       return VK_SUCCESS;
340    }
341 
342    nir_shader *vs_module = radv_meta_build_nir_vs_generate_vertices(device);
343    nir_shader *fs_module = build_resolve_fragment_shader(device, is_integer, samples);
344 
345    const VkGraphicsPipelineCreateInfo pipeline_create_info = {
346       .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
347       .stageCount = 2,
348       .pStages =
349          (VkPipelineShaderStageCreateInfo[]){
350             {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
351              .stage = VK_SHADER_STAGE_VERTEX_BIT,
352              .module = vk_shader_module_handle_from_nir(vs_module),
353              .pName = "main",
354              .pSpecializationInfo = NULL},
355             {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
356              .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
357              .module = vk_shader_module_handle_from_nir(fs_module),
358              .pName = "main",
359              .pSpecializationInfo = NULL},
360 
361          },
362       .pVertexInputState =
363          &(VkPipelineVertexInputStateCreateInfo){
364             .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
365             .vertexBindingDescriptionCount = 0,
366             .vertexAttributeDescriptionCount = 0,
367          },
368       .pInputAssemblyState =
369          &(VkPipelineInputAssemblyStateCreateInfo){
370             .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
371             .topology = VK_PRIMITIVE_TOPOLOGY_META_RECT_LIST_MESA,
372             .primitiveRestartEnable = false,
373          },
374       .pViewportState =
375          &(VkPipelineViewportStateCreateInfo){
376             .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
377             .viewportCount = 1,
378             .scissorCount = 1,
379          },
380       .pRasterizationState =
381          &(VkPipelineRasterizationStateCreateInfo){.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
382                                                    .rasterizerDiscardEnable = false,
383                                                    .polygonMode = VK_POLYGON_MODE_FILL,
384                                                    .cullMode = VK_CULL_MODE_NONE,
385                                                    .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
386                                                    .depthBiasConstantFactor = 0.0f,
387                                                    .depthBiasClamp = 0.0f,
388                                                    .depthBiasSlopeFactor = 0.0f,
389                                                    .lineWidth = 1.0f},
390       .pMultisampleState =
391          &(VkPipelineMultisampleStateCreateInfo){
392             .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
393             .rasterizationSamples = 1,
394             .sampleShadingEnable = false,
395             .pSampleMask = (VkSampleMask[]){UINT32_MAX},
396          },
397       .pColorBlendState =
398          &(VkPipelineColorBlendStateCreateInfo){
399             .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
400             .attachmentCount = 1,
401             .pAttachments =
402                (VkPipelineColorBlendAttachmentState[]){
403                   {.colorWriteMask = VK_COLOR_COMPONENT_A_BIT | VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
404                                      VK_COLOR_COMPONENT_B_BIT},
405                },
406             .blendConstants = {0.0f, 0.0f, 0.0f, 0.0f}},
407       .pDynamicState =
408          &(VkPipelineDynamicStateCreateInfo){
409             .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
410             .dynamicStateCount = 2,
411             .pDynamicStates =
412                (VkDynamicState[]){
413                   VK_DYNAMIC_STATE_VIEWPORT,
414                   VK_DYNAMIC_STATE_SCISSOR,
415                },
416          },
417       .layout = *layout_out,
418    };
419 
420    struct vk_meta_rendering_info render = {
421       .color_attachment_count = 1,
422       .color_attachment_formats = {format},
423    };
424 
425    result = vk_meta_create_graphics_pipeline(&device->vk, &device->meta_state.device, &pipeline_create_info, &render,
426                                              &key, sizeof(key), pipeline_out);
427 
428    ralloc_free(vs_module);
429    ralloc_free(fs_module);
430    return result;
431 }
432 
433 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)434 emit_resolve(struct radv_cmd_buffer *cmd_buffer, struct radv_image_view *src_iview, struct radv_image_view *dst_iview,
435              const VkOffset2D *src_offset, const VkOffset2D *dst_offset)
436 {
437    struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
438    VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer);
439    VkPipelineLayout layout;
440    VkPipeline pipeline;
441    VkResult result;
442 
443    result = get_color_resolve_pipeline(device, src_iview, dst_iview, &pipeline, &layout);
444    if (result != VK_SUCCESS) {
445       vk_command_buffer_set_error(&cmd_buffer->vk, result);
446       return;
447    }
448 
449    radv_meta_push_descriptor_set(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, 1,
450                                  (VkWriteDescriptorSet[]){
451                                     {.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
452                                      .dstBinding = 0,
453                                      .dstArrayElement = 0,
454                                      .descriptorCount = 1,
455                                      .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
456                                      .pImageInfo =
457                                         (VkDescriptorImageInfo[]){
458                                            {
459                                               .sampler = VK_NULL_HANDLE,
460                                               .imageView = radv_image_view_to_handle(src_iview),
461                                               .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
462                                            },
463                                         }},
464                                  });
465 
466    const VkImageSubresourceRange src_range = vk_image_view_subresource_range(&src_iview->vk);
467    const VkImageSubresourceRange dst_range = vk_image_view_subresource_range(&dst_iview->vk);
468 
469    cmd_buffer->state.flush_bits |=
470       radv_dst_access_flush(cmd_buffer, VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, VK_ACCESS_2_SHADER_READ_BIT, 0,
471                             src_iview->image, &src_range) |
472       radv_dst_access_flush(cmd_buffer, VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
473                             VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT, 0, dst_iview->image, &dst_range);
474 
475    unsigned push_constants[2] = {
476       src_offset->x - dst_offset->x,
477       src_offset->y - dst_offset->y,
478    };
479    vk_common_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer), layout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, 8,
480                               push_constants);
481 
482    radv_CmdBindPipeline(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
483 
484    radv_CmdDraw(cmd_buffer_h, 3, 1, 0, 0);
485    cmd_buffer->state.flush_bits |=
486       radv_src_access_flush(cmd_buffer, VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
487                             VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, 0, dst_iview->image, &dst_range);
488 }
489 
490 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 VkExtent2D * resolve_extent,VkImageAspectFlags aspects,VkResolveModeFlagBits resolve_mode)491 emit_depth_stencil_resolve(struct radv_cmd_buffer *cmd_buffer, struct radv_image_view *src_iview,
492                            struct radv_image_view *dst_iview, const VkOffset2D *resolve_offset,
493                            const VkExtent2D *resolve_extent, VkImageAspectFlags aspects,
494                            VkResolveModeFlagBits resolve_mode)
495 {
496    struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
497    const uint32_t samples = src_iview->image->vk.samples;
498    VkPipelineLayout layout;
499    VkPipeline pipeline;
500    VkResult result;
501 
502    result = get_depth_stencil_resolve_pipeline(device, samples, aspects, resolve_mode, &pipeline, &layout);
503    if (result != VK_SUCCESS) {
504       vk_command_buffer_set_error(&cmd_buffer->vk, result);
505       return;
506    }
507 
508    radv_meta_push_descriptor_set(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, 1,
509                                  (VkWriteDescriptorSet[]){
510                                     {.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
511                                      .dstBinding = 0,
512                                      .dstArrayElement = 0,
513                                      .descriptorCount = 1,
514                                      .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
515                                      .pImageInfo =
516                                         (VkDescriptorImageInfo[]){
517                                            {
518                                               .sampler = VK_NULL_HANDLE,
519                                               .imageView = radv_image_view_to_handle(src_iview),
520                                               .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
521                                            },
522                                         }},
523                                  });
524 
525    radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
526 
527    radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1,
528                        &(VkViewport){.x = resolve_offset->x,
529                                      .y = resolve_offset->y,
530                                      .width = resolve_extent->width,
531                                      .height = resolve_extent->height,
532                                      .minDepth = 0.0f,
533                                      .maxDepth = 1.0f});
534 
535    radv_CmdSetScissor(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1,
536                       &(VkRect2D){
537                          .offset = *resolve_offset,
538                          .extent = *resolve_extent,
539                       });
540 
541    radv_CmdDraw(radv_cmd_buffer_to_handle(cmd_buffer), 3, 1, 0, 0);
542 }
543 
544 void
radv_meta_resolve_fragment_image(struct radv_cmd_buffer * cmd_buffer,struct radv_image * src_image,VkImageLayout src_image_layout,struct radv_image * dst_image,VkImageLayout dst_image_layout,const VkImageResolve2 * region)545 radv_meta_resolve_fragment_image(struct radv_cmd_buffer *cmd_buffer, struct radv_image *src_image,
546                                  VkImageLayout src_image_layout, struct radv_image *dst_image,
547                                  VkImageLayout dst_image_layout, const VkImageResolve2 *region)
548 {
549    struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
550    struct radv_meta_saved_state saved_state;
551    unsigned dst_layout = radv_meta_dst_layout_from_layout(dst_image_layout);
552    VkImageLayout layout = radv_meta_dst_layout_to_layout(dst_layout);
553 
554    radv_meta_save(&saved_state, cmd_buffer,
555                   RADV_META_SAVE_GRAPHICS_PIPELINE | RADV_META_SAVE_CONSTANTS | RADV_META_SAVE_DESCRIPTORS);
556 
557    assert(region->srcSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
558    assert(region->dstSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
559    /* Multi-layer resolves are handled by compute */
560    assert(vk_image_subresource_layer_count(&src_image->vk, &region->srcSubresource) == 1 &&
561           vk_image_subresource_layer_count(&dst_image->vk, &region->dstSubresource) == 1);
562 
563    const struct VkExtent3D extent = vk_image_sanitize_extent(&src_image->vk, region->extent);
564    const struct VkOffset3D srcOffset = vk_image_sanitize_offset(&src_image->vk, region->srcOffset);
565    const struct VkOffset3D dstOffset = vk_image_sanitize_offset(&dst_image->vk, region->dstOffset);
566 
567    VkRect2D resolve_area = {
568       .offset = {dstOffset.x, dstOffset.y},
569       .extent = {extent.width, extent.height},
570    };
571 
572    radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1,
573                        &(VkViewport){.x = resolve_area.offset.x,
574                                      .y = resolve_area.offset.y,
575                                      .width = resolve_area.extent.width,
576                                      .height = resolve_area.extent.height,
577                                      .minDepth = 0.0f,
578                                      .maxDepth = 1.0f});
579 
580    radv_CmdSetScissor(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &resolve_area);
581 
582    struct radv_image_view src_iview;
583    radv_image_view_init(&src_iview, device,
584                         &(VkImageViewCreateInfo){
585                            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
586                            .image = radv_image_to_handle(src_image),
587                            .viewType = VK_IMAGE_VIEW_TYPE_2D,
588                            .format = src_image->vk.format,
589                            .subresourceRange =
590                               {
591                                  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
592                                  .baseMipLevel = 0,
593                                  .levelCount = 1,
594                                  .baseArrayLayer = 0,
595                                  .layerCount = 1,
596                               },
597                         },
598                         NULL);
599 
600    struct radv_image_view dst_iview;
601    radv_image_view_init(&dst_iview, device,
602                         &(VkImageViewCreateInfo){
603                            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
604                            .image = radv_image_to_handle(dst_image),
605                            .viewType = radv_meta_get_view_type(dst_image),
606                            .format = dst_image->vk.format,
607                            .subresourceRange =
608                               {
609                                  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
610                                  .baseMipLevel = region->dstSubresource.mipLevel,
611                                  .levelCount = 1,
612                                  .baseArrayLayer = 0,
613                                  .layerCount = 1,
614                               },
615                         },
616                         NULL);
617 
618    const VkRenderingAttachmentInfo color_att = {
619       .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
620       .imageView = radv_image_view_to_handle(&dst_iview),
621       .imageLayout = layout,
622       .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
623       .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
624    };
625 
626    const VkRenderingInfo rendering_info = {
627       .sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
628       .flags = VK_RENDERING_INPUT_ATTACHMENT_NO_CONCURRENT_WRITES_BIT_MESA,
629       .renderArea = resolve_area,
630       .layerCount = 1,
631       .colorAttachmentCount = 1,
632       .pColorAttachments = &color_att,
633    };
634 
635    radv_CmdBeginRendering(radv_cmd_buffer_to_handle(cmd_buffer), &rendering_info);
636 
637    emit_resolve(cmd_buffer, &src_iview, &dst_iview, &(VkOffset2D){srcOffset.x, srcOffset.y},
638                 &(VkOffset2D){dstOffset.x, dstOffset.y});
639 
640    radv_CmdEndRendering(radv_cmd_buffer_to_handle(cmd_buffer));
641 
642    radv_image_view_finish(&src_iview);
643    radv_image_view_finish(&dst_iview);
644 
645    radv_meta_restore(&saved_state, cmd_buffer);
646 }
647 
648 void
radv_cmd_buffer_resolve_rendering_fs(struct radv_cmd_buffer * cmd_buffer,struct radv_image_view * src_iview,VkImageLayout src_layout,struct radv_image_view * dst_iview,VkImageLayout dst_layout)649 radv_cmd_buffer_resolve_rendering_fs(struct radv_cmd_buffer *cmd_buffer, struct radv_image_view *src_iview,
650                                      VkImageLayout src_layout, struct radv_image_view *dst_iview,
651                                      VkImageLayout dst_layout)
652 {
653    const struct radv_rendering_state *render = &cmd_buffer->state.render;
654    struct radv_meta_saved_state saved_state;
655    VkRect2D resolve_area = render->area;
656 
657    radv_meta_save(
658       &saved_state, cmd_buffer,
659       RADV_META_SAVE_GRAPHICS_PIPELINE | RADV_META_SAVE_CONSTANTS | RADV_META_SAVE_DESCRIPTORS | RADV_META_SAVE_RENDER);
660 
661    radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1,
662                        &(VkViewport){.x = resolve_area.offset.x,
663                                      .y = resolve_area.offset.y,
664                                      .width = resolve_area.extent.width,
665                                      .height = resolve_area.extent.height,
666                                      .minDepth = 0.0f,
667                                      .maxDepth = 1.0f});
668 
669    radv_CmdSetScissor(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &resolve_area);
670 
671    const VkRenderingAttachmentInfo color_att = {
672       .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
673       .imageView = radv_image_view_to_handle(dst_iview),
674       .imageLayout = dst_layout,
675       .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
676       .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
677    };
678 
679    const VkRenderingInfo rendering_info = {
680       .sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
681       .flags = VK_RENDERING_INPUT_ATTACHMENT_NO_CONCURRENT_WRITES_BIT_MESA,
682       .renderArea = saved_state.render.area,
683       .layerCount = 1,
684       .viewMask = saved_state.render.view_mask,
685       .colorAttachmentCount = 1,
686       .pColorAttachments = &color_att,
687    };
688 
689    radv_CmdBeginRendering(radv_cmd_buffer_to_handle(cmd_buffer), &rendering_info);
690 
691    emit_resolve(cmd_buffer, src_iview, dst_iview, &resolve_area.offset, &resolve_area.offset);
692 
693    radv_CmdEndRendering(radv_cmd_buffer_to_handle(cmd_buffer));
694 
695    radv_meta_restore(&saved_state, cmd_buffer);
696 }
697 
698 /**
699  * Depth/stencil resolves for the current rendering.
700  */
701 void
radv_depth_stencil_resolve_rendering_fs(struct radv_cmd_buffer * cmd_buffer,VkImageAspectFlags aspects,VkResolveModeFlagBits resolve_mode)702 radv_depth_stencil_resolve_rendering_fs(struct radv_cmd_buffer *cmd_buffer, VkImageAspectFlags aspects,
703                                         VkResolveModeFlagBits resolve_mode)
704 {
705    struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
706    const struct radv_rendering_state *render = &cmd_buffer->state.render;
707    VkRect2D resolve_area = render->area;
708    struct radv_meta_saved_state saved_state;
709    struct radv_resolve_barrier barrier;
710 
711    /* Resolves happen before rendering ends, so we have to make the attachment shader-readable */
712    barrier.src_stage_mask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
713    barrier.dst_stage_mask = VK_PIPELINE_STAGE_2_RESOLVE_BIT;
714    barrier.src_access_mask = VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
715    barrier.dst_access_mask = VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT;
716    radv_emit_resolve_barrier(cmd_buffer, &barrier);
717 
718    struct radv_image_view *src_iview = cmd_buffer->state.render.ds_att.iview;
719    VkImageLayout src_layout =
720       aspects & VK_IMAGE_ASPECT_DEPTH_BIT ? render->ds_att.layout : render->ds_att.stencil_layout;
721    struct radv_image *src_image = src_iview->image;
722 
723    VkImageResolve2 region = {0};
724    region.sType = VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2;
725    region.srcSubresource.aspectMask = aspects;
726    region.srcSubresource.mipLevel = 0;
727    region.srcSubresource.baseArrayLayer = 0;
728    region.srcSubresource.layerCount = 1;
729 
730    radv_decompress_resolve_src(cmd_buffer, src_image, src_layout, &region);
731 
732    radv_meta_save(&saved_state, cmd_buffer,
733                   RADV_META_SAVE_GRAPHICS_PIPELINE | RADV_META_SAVE_DESCRIPTORS | RADV_META_SAVE_RENDER);
734 
735    struct radv_image_view *dst_iview = saved_state.render.ds_att.resolve_iview;
736 
737    const VkRenderingAttachmentInfo depth_att = {
738       .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
739       .imageView = radv_image_view_to_handle(dst_iview),
740       .imageLayout = saved_state.render.ds_att.resolve_layout,
741       .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
742       .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
743    };
744 
745    const VkRenderingAttachmentInfo stencil_att = {
746       .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
747       .imageView = radv_image_view_to_handle(dst_iview),
748       .imageLayout = saved_state.render.ds_att.stencil_resolve_layout,
749       .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
750       .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
751    };
752 
753    const VkRenderingInfo rendering_info = {
754       .sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
755       .flags = VK_RENDERING_INPUT_ATTACHMENT_NO_CONCURRENT_WRITES_BIT_MESA,
756       .renderArea = saved_state.render.area,
757       .layerCount = 1,
758       .viewMask = saved_state.render.view_mask,
759       .pDepthAttachment = (dst_iview->image->vk.aspects & VK_IMAGE_ASPECT_DEPTH_BIT) ? &depth_att : NULL,
760       .pStencilAttachment = (dst_iview->image->vk.aspects & VK_IMAGE_ASPECT_STENCIL_BIT) ? &stencil_att : NULL,
761    };
762 
763    radv_CmdBeginRendering(radv_cmd_buffer_to_handle(cmd_buffer), &rendering_info);
764 
765    struct radv_image_view tsrc_iview;
766    radv_image_view_init(&tsrc_iview, device,
767                         &(VkImageViewCreateInfo){
768                            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
769                            .image = radv_image_to_handle(src_image),
770                            .viewType = VK_IMAGE_VIEW_TYPE_2D,
771                            .format = src_iview->vk.format,
772                            .subresourceRange =
773                               {
774                                  .aspectMask = aspects,
775                                  .baseMipLevel = 0,
776                                  .levelCount = 1,
777                                  .baseArrayLayer = 0,
778                                  .layerCount = 1,
779                               },
780                         },
781                         NULL);
782 
783    emit_depth_stencil_resolve(cmd_buffer, &tsrc_iview, dst_iview, &resolve_area.offset, &resolve_area.extent, aspects,
784                               resolve_mode);
785 
786    radv_CmdEndRendering(radv_cmd_buffer_to_handle(cmd_buffer));
787 
788    radv_image_view_finish(&tsrc_iview);
789 
790    radv_meta_restore(&saved_state, cmd_buffer);
791 }
792