xref: /aosp_15_r20/external/mesa3d/src/amd/vulkan/meta/radv_meta_resolve_fs.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
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)50 create_layout(struct radv_device *device)
51 {
52    VkResult result = VK_SUCCESS;
53 
54    if (!device->meta_state.resolve_fragment.ds_layout) {
55       const VkDescriptorSetLayoutBinding binding = {.binding = 0,
56                                                     .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
57                                                     .descriptorCount = 1,
58                                                     .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT};
59 
60       result =
61          radv_meta_create_descriptor_set_layout(device, 1, &binding, &device->meta_state.resolve_fragment.ds_layout);
62       if (result != VK_SUCCESS)
63          return result;
64    }
65 
66    if (!device->meta_state.resolve_fragment.p_layout) {
67       const VkPushConstantRange pc_range = {
68          .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
69          .size = 8,
70       };
71 
72       result = radv_meta_create_pipeline_layout(device, &device->meta_state.resolve_fragment.ds_layout, 1, &pc_range,
73                                                 &device->meta_state.resolve_fragment.p_layout);
74    }
75 
76    return result;
77 }
78 
79 static const VkPipelineVertexInputStateCreateInfo normal_vi_create_info = {
80    .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
81    .vertexBindingDescriptionCount = 0,
82    .vertexAttributeDescriptionCount = 0,
83 };
84 
85 static VkResult
create_resolve_pipeline(struct radv_device * device,int samples_log2,VkFormat format)86 create_resolve_pipeline(struct radv_device *device, int samples_log2, VkFormat format)
87 {
88    unsigned fs_key = radv_format_meta_fs_key(device, format);
89    VkPipeline *pipeline = &device->meta_state.resolve_fragment.rc[samples_log2].pipeline[fs_key];
90    VkResult result;
91 
92    result = create_layout(device);
93    if (result != VK_SUCCESS)
94       return result;
95 
96    bool is_integer = false;
97    uint32_t samples = 1 << samples_log2;
98    const VkPipelineVertexInputStateCreateInfo *vi_create_info;
99    vi_create_info = &normal_vi_create_info;
100    if (vk_format_is_int(format))
101       is_integer = true;
102 
103    nir_shader *fs = build_resolve_fragment_shader(device, is_integer, samples);
104    nir_shader *vs = radv_meta_build_nir_vs_generate_vertices(device);
105 
106    VkPipelineShaderStageCreateInfo pipeline_shader_stages[] = {
107       {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
108        .stage = VK_SHADER_STAGE_VERTEX_BIT,
109        .module = vk_shader_module_handle_from_nir(vs),
110        .pName = "main",
111        .pSpecializationInfo = NULL},
112       {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
113        .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
114        .module = vk_shader_module_handle_from_nir(fs),
115        .pName = "main",
116        .pSpecializationInfo = NULL},
117    };
118 
119    const VkPipelineRenderingCreateInfo rendering_create_info = {
120       .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
121       .colorAttachmentCount = 1,
122       .pColorAttachmentFormats = &format,
123    };
124 
125    const VkGraphicsPipelineCreateInfo vk_pipeline_info = {
126       .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
127       .pNext = &rendering_create_info,
128       .stageCount = ARRAY_SIZE(pipeline_shader_stages),
129       .pStages = pipeline_shader_stages,
130       .pVertexInputState = vi_create_info,
131       .pInputAssemblyState =
132          &(VkPipelineInputAssemblyStateCreateInfo){
133             .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
134             .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
135             .primitiveRestartEnable = false,
136          },
137       .pViewportState =
138          &(VkPipelineViewportStateCreateInfo){
139             .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
140             .viewportCount = 1,
141             .scissorCount = 1,
142          },
143       .pRasterizationState =
144          &(VkPipelineRasterizationStateCreateInfo){.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
145                                                    .rasterizerDiscardEnable = false,
146                                                    .polygonMode = VK_POLYGON_MODE_FILL,
147                                                    .cullMode = VK_CULL_MODE_NONE,
148                                                    .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
149                                                    .depthBiasConstantFactor = 0.0f,
150                                                    .depthBiasClamp = 0.0f,
151                                                    .depthBiasSlopeFactor = 0.0f,
152                                                    .lineWidth = 1.0f},
153       .pMultisampleState =
154          &(VkPipelineMultisampleStateCreateInfo){
155             .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
156             .rasterizationSamples = 1,
157             .sampleShadingEnable = false,
158             .pSampleMask = (VkSampleMask[]){UINT32_MAX},
159          },
160       .pColorBlendState =
161          &(VkPipelineColorBlendStateCreateInfo){
162             .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
163             .attachmentCount = 1,
164             .pAttachments =
165                (VkPipelineColorBlendAttachmentState[]){
166                   {.colorWriteMask = VK_COLOR_COMPONENT_A_BIT | VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
167                                      VK_COLOR_COMPONENT_B_BIT},
168                },
169             .blendConstants = {0.0f, 0.0f, 0.0f, 0.0f}},
170       .pDynamicState =
171          &(VkPipelineDynamicStateCreateInfo){
172             .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
173             .dynamicStateCount = 2,
174             .pDynamicStates =
175                (VkDynamicState[]){
176                   VK_DYNAMIC_STATE_VIEWPORT,
177                   VK_DYNAMIC_STATE_SCISSOR,
178                },
179          },
180       .flags = 0,
181       .layout = device->meta_state.resolve_fragment.p_layout,
182       .renderPass = VK_NULL_HANDLE,
183       .subpass = 0,
184    };
185 
186    const struct radv_graphics_pipeline_create_info radv_pipeline_info = {.use_rectlist = true};
187 
188    result = radv_graphics_pipeline_create(radv_device_to_handle(device), device->meta_state.cache, &vk_pipeline_info,
189                                           &radv_pipeline_info, &device->meta_state.alloc, pipeline);
190    ralloc_free(vs);
191    ralloc_free(fs);
192    return result;
193 }
194 
195 enum { DEPTH_RESOLVE, STENCIL_RESOLVE };
196 
197 static const char *
get_resolve_mode_str(VkResolveModeFlagBits resolve_mode)198 get_resolve_mode_str(VkResolveModeFlagBits resolve_mode)
199 {
200    switch (resolve_mode) {
201    case VK_RESOLVE_MODE_SAMPLE_ZERO_BIT:
202       return "zero";
203    case VK_RESOLVE_MODE_AVERAGE_BIT:
204       return "average";
205    case VK_RESOLVE_MODE_MIN_BIT:
206       return "min";
207    case VK_RESOLVE_MODE_MAX_BIT:
208       return "max";
209    default:
210       unreachable("invalid resolve mode");
211    }
212 }
213 
214 static nir_shader *
build_depth_stencil_resolve_fragment_shader(struct radv_device * dev,int samples,int index,VkResolveModeFlagBits resolve_mode)215 build_depth_stencil_resolve_fragment_shader(struct radv_device *dev, int samples, int index,
216                                             VkResolveModeFlagBits resolve_mode)
217 {
218    enum glsl_base_type img_base_type = index == DEPTH_RESOLVE ? GLSL_TYPE_FLOAT : GLSL_TYPE_UINT;
219    const struct glsl_type *vec4 = glsl_vec4_type();
220    const struct glsl_type *sampler_type = glsl_sampler_type(GLSL_SAMPLER_DIM_MS, false, false, img_base_type);
221 
222    nir_builder b =
223       radv_meta_init_shader(dev, MESA_SHADER_FRAGMENT, "meta_resolve_fs_%s-%s-%d",
224                             index == DEPTH_RESOLVE ? "depth" : "stencil", get_resolve_mode_str(resolve_mode), samples);
225 
226    nir_variable *input_img = nir_variable_create(b.shader, nir_var_uniform, sampler_type, "s_tex");
227    input_img->data.descriptor_set = 0;
228    input_img->data.binding = 0;
229 
230    nir_variable *fs_out = nir_variable_create(b.shader, nir_var_shader_out, vec4, "f_out");
231    fs_out->data.location = index == DEPTH_RESOLVE ? FRAG_RESULT_DEPTH : FRAG_RESULT_STENCIL;
232 
233    nir_def *pos_in = nir_trim_vector(&b, nir_load_frag_coord(&b), 2);
234 
235    nir_def *pos_int = nir_f2i32(&b, pos_in);
236 
237    nir_def *img_coord = nir_trim_vector(&b, pos_int, 2);
238 
239    nir_deref_instr *input_img_deref = nir_build_deref_var(&b, input_img);
240    nir_def *outval = nir_txf_ms_deref(&b, input_img_deref, img_coord, nir_imm_int(&b, 0));
241 
242    if (resolve_mode != VK_RESOLVE_MODE_SAMPLE_ZERO_BIT) {
243       for (int i = 1; i < samples; i++) {
244          nir_def *si = nir_txf_ms_deref(&b, input_img_deref, img_coord, nir_imm_int(&b, i));
245 
246          switch (resolve_mode) {
247          case VK_RESOLVE_MODE_AVERAGE_BIT:
248             assert(index == DEPTH_RESOLVE);
249             outval = nir_fadd(&b, outval, si);
250             break;
251          case VK_RESOLVE_MODE_MIN_BIT:
252             if (index == DEPTH_RESOLVE)
253                outval = nir_fmin(&b, outval, si);
254             else
255                outval = nir_umin(&b, outval, si);
256             break;
257          case VK_RESOLVE_MODE_MAX_BIT:
258             if (index == DEPTH_RESOLVE)
259                outval = nir_fmax(&b, outval, si);
260             else
261                outval = nir_umax(&b, outval, si);
262             break;
263          default:
264             unreachable("invalid resolve mode");
265          }
266       }
267 
268       if (resolve_mode == VK_RESOLVE_MODE_AVERAGE_BIT)
269          outval = nir_fdiv_imm(&b, outval, samples);
270    }
271 
272    nir_store_var(&b, fs_out, outval, 0x1);
273 
274    return b.shader;
275 }
276 
277 static VkResult
create_depth_stencil_resolve_pipeline(struct radv_device * device,int samples_log2,int index,VkResolveModeFlagBits resolve_mode,VkPipeline * _pipeline)278 create_depth_stencil_resolve_pipeline(struct radv_device *device, int samples_log2, int index,
279                                       VkResolveModeFlagBits resolve_mode, VkPipeline *_pipeline)
280 {
281    VkPipeline *pipeline;
282    VkResult result;
283 
284    result = create_layout(device);
285    if (result != VK_SUCCESS)
286       return result;
287 
288    switch (resolve_mode) {
289    case VK_RESOLVE_MODE_SAMPLE_ZERO_BIT:
290       if (index == DEPTH_RESOLVE)
291          pipeline = &device->meta_state.resolve_fragment.depth_zero_pipeline;
292       else
293          pipeline = &device->meta_state.resolve_fragment.stencil_zero_pipeline;
294       break;
295    case VK_RESOLVE_MODE_AVERAGE_BIT:
296       assert(index == DEPTH_RESOLVE);
297       pipeline = &device->meta_state.resolve_fragment.depth[samples_log2].average_pipeline;
298       break;
299    case VK_RESOLVE_MODE_MIN_BIT:
300       if (index == DEPTH_RESOLVE)
301          pipeline = &device->meta_state.resolve_fragment.depth[samples_log2].min_pipeline;
302       else
303          pipeline = &device->meta_state.resolve_fragment.stencil[samples_log2].min_pipeline;
304       break;
305    case VK_RESOLVE_MODE_MAX_BIT:
306       if (index == DEPTH_RESOLVE)
307          pipeline = &device->meta_state.resolve_fragment.depth[samples_log2].max_pipeline;
308       else
309          pipeline = &device->meta_state.resolve_fragment.stencil[samples_log2].max_pipeline;
310       break;
311    default:
312       unreachable("invalid resolve mode");
313    }
314 
315    if (*pipeline) {
316       return VK_SUCCESS;
317    }
318 
319    uint32_t samples = 1 << samples_log2;
320    nir_shader *fs = build_depth_stencil_resolve_fragment_shader(device, samples, index, resolve_mode);
321    nir_shader *vs = radv_meta_build_nir_vs_generate_vertices(device);
322 
323    VkPipelineShaderStageCreateInfo pipeline_shader_stages[] = {
324       {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
325        .stage = VK_SHADER_STAGE_VERTEX_BIT,
326        .module = vk_shader_module_handle_from_nir(vs),
327        .pName = "main",
328        .pSpecializationInfo = NULL},
329       {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
330        .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
331        .module = vk_shader_module_handle_from_nir(fs),
332        .pName = "main",
333        .pSpecializationInfo = NULL},
334    };
335 
336    VkStencilOp stencil_op = index == DEPTH_RESOLVE ? VK_STENCIL_OP_KEEP : VK_STENCIL_OP_REPLACE;
337 
338    VkPipelineDepthStencilStateCreateInfo depth_stencil_state = {
339       .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
340       .depthTestEnable = true,
341       .depthWriteEnable = index == DEPTH_RESOLVE,
342       .stencilTestEnable = index == STENCIL_RESOLVE,
343       .depthCompareOp = VK_COMPARE_OP_ALWAYS,
344       .front =
345          {
346             .failOp = stencil_op,
347             .passOp = stencil_op,
348             .depthFailOp = stencil_op,
349             .compareOp = VK_COMPARE_OP_ALWAYS,
350             .compareMask = UINT32_MAX,
351             .writeMask = UINT32_MAX,
352             .reference = 0u,
353          },
354       .back =
355          {
356             .failOp = stencil_op,
357             .passOp = stencil_op,
358             .depthFailOp = stencil_op,
359             .compareOp = VK_COMPARE_OP_ALWAYS,
360             .compareMask = UINT32_MAX,
361             .writeMask = UINT32_MAX,
362             .reference = 0u,
363          },
364       .minDepthBounds = 0.0f,
365       .maxDepthBounds = 1.0f};
366 
367    const VkPipelineVertexInputStateCreateInfo *vi_create_info;
368    vi_create_info = &normal_vi_create_info;
369 
370    const VkPipelineRenderingCreateInfo rendering_create_info = {
371       .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
372       .depthAttachmentFormat = index == DEPTH_RESOLVE ? VK_FORMAT_D32_SFLOAT : VK_FORMAT_UNDEFINED,
373       .stencilAttachmentFormat = index == STENCIL_RESOLVE ? VK_FORMAT_S8_UINT : VK_FORMAT_UNDEFINED,
374    };
375 
376    const VkGraphicsPipelineCreateInfo vk_pipeline_info = {
377       .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
378       .pNext = &rendering_create_info,
379       .stageCount = ARRAY_SIZE(pipeline_shader_stages),
380       .pStages = pipeline_shader_stages,
381       .pVertexInputState = vi_create_info,
382       .pInputAssemblyState =
383          &(VkPipelineInputAssemblyStateCreateInfo){
384             .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
385             .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
386             .primitiveRestartEnable = false,
387          },
388       .pViewportState =
389          &(VkPipelineViewportStateCreateInfo){
390             .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
391             .viewportCount = 1,
392             .scissorCount = 1,
393          },
394       .pDepthStencilState = &depth_stencil_state,
395       .pRasterizationState =
396          &(VkPipelineRasterizationStateCreateInfo){.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
397                                                    .rasterizerDiscardEnable = false,
398                                                    .polygonMode = VK_POLYGON_MODE_FILL,
399                                                    .cullMode = VK_CULL_MODE_NONE,
400                                                    .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
401                                                    .depthBiasConstantFactor = 0.0f,
402                                                    .depthBiasClamp = 0.0f,
403                                                    .depthBiasSlopeFactor = 0.0f,
404                                                    .lineWidth = 1.0f},
405       .pMultisampleState =
406          &(VkPipelineMultisampleStateCreateInfo){
407             .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
408             .rasterizationSamples = 1,
409             .sampleShadingEnable = false,
410             .pSampleMask = (VkSampleMask[]){UINT32_MAX},
411          },
412       .pColorBlendState =
413          &(VkPipelineColorBlendStateCreateInfo){
414             .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
415             .attachmentCount = 0,
416             .pAttachments =
417                (VkPipelineColorBlendAttachmentState[]){
418                   {.colorWriteMask = VK_COLOR_COMPONENT_A_BIT | VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
419                                      VK_COLOR_COMPONENT_B_BIT},
420                },
421             .blendConstants = {0.0f, 0.0f, 0.0f, 0.0f}},
422       .pDynamicState =
423          &(VkPipelineDynamicStateCreateInfo){
424             .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
425             .dynamicStateCount = 2,
426             .pDynamicStates =
427                (VkDynamicState[]){
428                   VK_DYNAMIC_STATE_VIEWPORT,
429                   VK_DYNAMIC_STATE_SCISSOR,
430                },
431          },
432       .flags = 0,
433       .layout = device->meta_state.resolve_fragment.p_layout,
434       .renderPass = VK_NULL_HANDLE,
435       .subpass = 0,
436    };
437 
438    const struct radv_graphics_pipeline_create_info radv_pipeline_info = {.use_rectlist = true};
439 
440    result = radv_graphics_pipeline_create(radv_device_to_handle(device), device->meta_state.cache, &vk_pipeline_info,
441                                           &radv_pipeline_info, &device->meta_state.alloc, pipeline);
442 
443    ralloc_free(vs);
444    ralloc_free(fs);
445 
446    return result;
447 }
448 
449 static VkResult
get_depth_stencil_resolve_pipeline(struct radv_device * device,int samples_log2,VkImageAspectFlags aspects,VkResolveModeFlagBits resolve_mode,VkPipeline * pipeline_out)450 get_depth_stencil_resolve_pipeline(struct radv_device *device, int samples_log2, VkImageAspectFlags aspects,
451                                    VkResolveModeFlagBits resolve_mode, VkPipeline *pipeline_out)
452 {
453    struct radv_meta_state *state = &device->meta_state;
454    const int index = aspects == VK_IMAGE_ASPECT_DEPTH_BIT ? DEPTH_RESOLVE : STENCIL_RESOLVE;
455    VkResult result = VK_SUCCESS;
456    VkPipeline *pipeline;
457 
458    mtx_lock(&state->mtx);
459    switch (resolve_mode) {
460    case VK_RESOLVE_MODE_SAMPLE_ZERO_BIT:
461       if (aspects == VK_IMAGE_ASPECT_DEPTH_BIT)
462          pipeline = &device->meta_state.resolve_fragment.depth_zero_pipeline;
463       else
464          pipeline = &device->meta_state.resolve_fragment.stencil_zero_pipeline;
465       break;
466    case VK_RESOLVE_MODE_AVERAGE_BIT:
467       assert(aspects == VK_IMAGE_ASPECT_DEPTH_BIT);
468       pipeline = &device->meta_state.resolve_fragment.depth[samples_log2].average_pipeline;
469       break;
470    case VK_RESOLVE_MODE_MIN_BIT:
471       if (aspects == VK_IMAGE_ASPECT_DEPTH_BIT)
472          pipeline = &device->meta_state.resolve_fragment.depth[samples_log2].min_pipeline;
473       else
474          pipeline = &device->meta_state.resolve_fragment.stencil[samples_log2].min_pipeline;
475       break;
476    case VK_RESOLVE_MODE_MAX_BIT:
477       if (aspects == VK_IMAGE_ASPECT_DEPTH_BIT)
478          pipeline = &device->meta_state.resolve_fragment.depth[samples_log2].max_pipeline;
479       else
480          pipeline = &device->meta_state.resolve_fragment.stencil[samples_log2].max_pipeline;
481       break;
482    default:
483       unreachable("invalid resolve mode");
484    }
485 
486    if (!*pipeline) {
487       result = create_depth_stencil_resolve_pipeline(device, samples_log2, index, resolve_mode, pipeline);
488       if (result != VK_SUCCESS)
489          goto fail;
490    }
491 
492    *pipeline_out = *pipeline;
493 
494 fail:
495    mtx_unlock(&state->mtx);
496    return result;
497 }
498 
499 VkResult
radv_device_init_meta_resolve_fragment_state(struct radv_device * device,bool on_demand)500 radv_device_init_meta_resolve_fragment_state(struct radv_device *device, bool on_demand)
501 {
502    VkResult res;
503 
504    if (on_demand)
505       return VK_SUCCESS;
506 
507    for (uint32_t i = 0; i < MAX_SAMPLES_LOG2; ++i) {
508       for (unsigned j = 0; j < NUM_META_FS_KEYS; ++j) {
509          res = create_resolve_pipeline(device, i, radv_fs_key_format_exemplars[j]);
510          if (res != VK_SUCCESS)
511             return res;
512       }
513 
514       res = create_depth_stencil_resolve_pipeline(device, i, DEPTH_RESOLVE, VK_RESOLVE_MODE_AVERAGE_BIT,
515                                                   &device->meta_state.resolve_fragment.depth[i].average_pipeline);
516       if (res != VK_SUCCESS)
517          return res;
518 
519       res = create_depth_stencil_resolve_pipeline(device, i, DEPTH_RESOLVE, VK_RESOLVE_MODE_MIN_BIT,
520                                                   &device->meta_state.resolve_fragment.depth[i].min_pipeline);
521       if (res != VK_SUCCESS)
522          return res;
523 
524       res = create_depth_stencil_resolve_pipeline(device, i, DEPTH_RESOLVE, VK_RESOLVE_MODE_MAX_BIT,
525                                                   &device->meta_state.resolve_fragment.depth[i].max_pipeline);
526       if (res != VK_SUCCESS)
527          return res;
528 
529       res = create_depth_stencil_resolve_pipeline(device, i, STENCIL_RESOLVE, VK_RESOLVE_MODE_MIN_BIT,
530                                                   &device->meta_state.resolve_fragment.stencil[i].min_pipeline);
531       if (res != VK_SUCCESS)
532          return res;
533 
534       res = create_depth_stencil_resolve_pipeline(device, i, STENCIL_RESOLVE, VK_RESOLVE_MODE_MAX_BIT,
535                                                   &device->meta_state.resolve_fragment.stencil[i].max_pipeline);
536       if (res != VK_SUCCESS)
537          return res;
538    }
539 
540    res = create_depth_stencil_resolve_pipeline(device, 0, DEPTH_RESOLVE, VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,
541                                                &device->meta_state.resolve_fragment.depth_zero_pipeline);
542    if (res != VK_SUCCESS)
543       return res;
544 
545    return create_depth_stencil_resolve_pipeline(device, 0, STENCIL_RESOLVE, VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,
546                                                 &device->meta_state.resolve_fragment.stencil_zero_pipeline);
547 }
548 
549 void
radv_device_finish_meta_resolve_fragment_state(struct radv_device * device)550 radv_device_finish_meta_resolve_fragment_state(struct radv_device *device)
551 {
552    struct radv_meta_state *state = &device->meta_state;
553    for (uint32_t i = 0; i < MAX_SAMPLES_LOG2; ++i) {
554       for (unsigned j = 0; j < NUM_META_FS_KEYS; ++j) {
555          radv_DestroyPipeline(radv_device_to_handle(device), state->resolve_fragment.rc[i].pipeline[j], &state->alloc);
556       }
557 
558       radv_DestroyPipeline(radv_device_to_handle(device), state->resolve_fragment.depth[i].average_pipeline,
559                            &state->alloc);
560 
561       radv_DestroyPipeline(radv_device_to_handle(device), state->resolve_fragment.depth[i].max_pipeline, &state->alloc);
562 
563       radv_DestroyPipeline(radv_device_to_handle(device), state->resolve_fragment.depth[i].min_pipeline, &state->alloc);
564 
565       radv_DestroyPipeline(radv_device_to_handle(device), state->resolve_fragment.stencil[i].max_pipeline,
566                            &state->alloc);
567 
568       radv_DestroyPipeline(radv_device_to_handle(device), state->resolve_fragment.stencil[i].min_pipeline,
569                            &state->alloc);
570    }
571 
572    radv_DestroyPipeline(radv_device_to_handle(device), state->resolve_fragment.depth_zero_pipeline, &state->alloc);
573    radv_DestroyPipeline(radv_device_to_handle(device), state->resolve_fragment.stencil_zero_pipeline, &state->alloc);
574 
575    device->vk.dispatch_table.DestroyDescriptorSetLayout(radv_device_to_handle(device),
576                                                         state->resolve_fragment.ds_layout, &state->alloc);
577    radv_DestroyPipelineLayout(radv_device_to_handle(device), state->resolve_fragment.p_layout, &state->alloc);
578 }
579 
580 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)581 get_color_resolve_pipeline(struct radv_device *device, struct radv_image_view *src_iview,
582                            struct radv_image_view *dst_iview, VkPipeline *pipeline_out)
583 {
584    struct radv_meta_state *state = &device->meta_state;
585    unsigned fs_key = radv_format_meta_fs_key(device, dst_iview->vk.format);
586    const uint32_t samples = src_iview->image->vk.samples;
587    const uint32_t samples_log2 = ffs(samples) - 1;
588    VkResult result = VK_SUCCESS;
589 
590    mtx_lock(&state->mtx);
591 
592    if (!state->resolve_fragment.rc[samples_log2].pipeline[fs_key]) {
593       result = create_resolve_pipeline(device, samples_log2, radv_fs_key_format_exemplars[fs_key]);
594       if (result != VK_SUCCESS)
595          goto fail;
596    }
597 
598    *pipeline_out = state->resolve_fragment.rc[samples_log2].pipeline[fs_key];
599 
600 fail:
601    mtx_unlock(&state->mtx);
602    return result;
603 }
604 
605 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)606 emit_resolve(struct radv_cmd_buffer *cmd_buffer, struct radv_image_view *src_iview, struct radv_image_view *dst_iview,
607              const VkOffset2D *src_offset, const VkOffset2D *dst_offset)
608 {
609    struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
610    VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer);
611    VkPipeline pipeline;
612    VkResult result;
613 
614    result = get_color_resolve_pipeline(device, src_iview, dst_iview, &pipeline);
615    if (result != VK_SUCCESS) {
616       vk_command_buffer_set_error(&cmd_buffer->vk, result);
617       return;
618    }
619 
620    radv_meta_push_descriptor_set(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
621                                  device->meta_state.resolve_fragment.p_layout, 0, 1,
622                                  (VkWriteDescriptorSet[]){
623                                     {.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
624                                      .dstBinding = 0,
625                                      .dstArrayElement = 0,
626                                      .descriptorCount = 1,
627                                      .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
628                                      .pImageInfo =
629                                         (VkDescriptorImageInfo[]){
630                                            {
631                                               .sampler = VK_NULL_HANDLE,
632                                               .imageView = radv_image_view_to_handle(src_iview),
633                                               .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
634                                            },
635                                         }},
636                                  });
637 
638    cmd_buffer->state.flush_bits |= radv_dst_access_flush(cmd_buffer, VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
639                                                          VK_ACCESS_2_SHADER_READ_BIT, src_iview->image) |
640                                    radv_dst_access_flush(cmd_buffer, VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
641                                                          VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT, dst_iview->image);
642 
643    unsigned push_constants[2] = {
644       src_offset->x - dst_offset->x,
645       src_offset->y - dst_offset->y,
646    };
647    vk_common_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer), device->meta_state.resolve_fragment.p_layout,
648                               VK_SHADER_STAGE_FRAGMENT_BIT, 0, 8, push_constants);
649 
650    radv_CmdBindPipeline(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
651 
652    radv_CmdDraw(cmd_buffer_h, 3, 1, 0, 0);
653    cmd_buffer->state.flush_bits |= radv_src_access_flush(cmd_buffer, VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
654                                                          VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, dst_iview->image);
655 }
656 
657 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)658 emit_depth_stencil_resolve(struct radv_cmd_buffer *cmd_buffer, struct radv_image_view *src_iview,
659                            struct radv_image_view *dst_iview, const VkOffset2D *resolve_offset,
660                            const VkExtent2D *resolve_extent, VkImageAspectFlags aspects,
661                            VkResolveModeFlagBits resolve_mode)
662 {
663    struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
664    const uint32_t samples = src_iview->image->vk.samples;
665    const uint32_t samples_log2 = ffs(samples) - 1;
666    VkPipeline pipeline;
667    VkResult result;
668 
669    result = get_depth_stencil_resolve_pipeline(device, samples_log2, aspects, resolve_mode, &pipeline);
670    if (result != VK_SUCCESS) {
671       vk_command_buffer_set_error(&cmd_buffer->vk, result);
672       return;
673    }
674 
675    radv_meta_push_descriptor_set(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
676                                  device->meta_state.resolve_fragment.p_layout, 0, 1,
677                                  (VkWriteDescriptorSet[]){
678                                     {.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
679                                      .dstBinding = 0,
680                                      .dstArrayElement = 0,
681                                      .descriptorCount = 1,
682                                      .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
683                                      .pImageInfo =
684                                         (VkDescriptorImageInfo[]){
685                                            {
686                                               .sampler = VK_NULL_HANDLE,
687                                               .imageView = radv_image_view_to_handle(src_iview),
688                                               .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
689                                            },
690                                         }},
691                                  });
692 
693    radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
694 
695    radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1,
696                        &(VkViewport){.x = resolve_offset->x,
697                                      .y = resolve_offset->y,
698                                      .width = resolve_extent->width,
699                                      .height = resolve_extent->height,
700                                      .minDepth = 0.0f,
701                                      .maxDepth = 1.0f});
702 
703    radv_CmdSetScissor(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1,
704                       &(VkRect2D){
705                          .offset = *resolve_offset,
706                          .extent = *resolve_extent,
707                       });
708 
709    radv_CmdDraw(radv_cmd_buffer_to_handle(cmd_buffer), 3, 1, 0, 0);
710 }
711 
712 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)713 radv_meta_resolve_fragment_image(struct radv_cmd_buffer *cmd_buffer, struct radv_image *src_image,
714                                  VkImageLayout src_image_layout, struct radv_image *dst_image,
715                                  VkImageLayout dst_image_layout, const VkImageResolve2 *region)
716 {
717    struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
718    struct radv_meta_saved_state saved_state;
719    unsigned dst_layout = radv_meta_dst_layout_from_layout(dst_image_layout);
720    VkImageLayout layout = radv_meta_dst_layout_to_layout(dst_layout);
721 
722    radv_meta_save(&saved_state, cmd_buffer,
723                   RADV_META_SAVE_GRAPHICS_PIPELINE | RADV_META_SAVE_CONSTANTS | RADV_META_SAVE_DESCRIPTORS);
724 
725    assert(region->srcSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
726    assert(region->dstSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
727    /* Multi-layer resolves are handled by compute */
728    assert(vk_image_subresource_layer_count(&src_image->vk, &region->srcSubresource) == 1 &&
729           vk_image_subresource_layer_count(&dst_image->vk, &region->dstSubresource) == 1);
730 
731    const struct VkExtent3D extent = vk_image_sanitize_extent(&src_image->vk, region->extent);
732    const struct VkOffset3D srcOffset = vk_image_sanitize_offset(&src_image->vk, region->srcOffset);
733    const struct VkOffset3D dstOffset = vk_image_sanitize_offset(&dst_image->vk, region->dstOffset);
734 
735    VkRect2D resolve_area = {
736       .offset = {dstOffset.x, dstOffset.y},
737       .extent = {extent.width, extent.height},
738    };
739 
740    radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1,
741                        &(VkViewport){.x = resolve_area.offset.x,
742                                      .y = resolve_area.offset.y,
743                                      .width = resolve_area.extent.width,
744                                      .height = resolve_area.extent.height,
745                                      .minDepth = 0.0f,
746                                      .maxDepth = 1.0f});
747 
748    radv_CmdSetScissor(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &resolve_area);
749 
750    struct radv_image_view src_iview;
751    radv_image_view_init(&src_iview, device,
752                         &(VkImageViewCreateInfo){
753                            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
754                            .image = radv_image_to_handle(src_image),
755                            .viewType = VK_IMAGE_VIEW_TYPE_2D,
756                            .format = src_image->vk.format,
757                            .subresourceRange =
758                               {
759                                  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
760                                  .baseMipLevel = 0,
761                                  .levelCount = 1,
762                                  .baseArrayLayer = 0,
763                                  .layerCount = 1,
764                               },
765                         },
766                         0, NULL);
767 
768    struct radv_image_view dst_iview;
769    radv_image_view_init(&dst_iview, device,
770                         &(VkImageViewCreateInfo){
771                            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
772                            .image = radv_image_to_handle(dst_image),
773                            .viewType = radv_meta_get_view_type(dst_image),
774                            .format = dst_image->vk.format,
775                            .subresourceRange =
776                               {
777                                  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
778                                  .baseMipLevel = region->dstSubresource.mipLevel,
779                                  .levelCount = 1,
780                                  .baseArrayLayer = 0,
781                                  .layerCount = 1,
782                               },
783                         },
784                         0, NULL);
785 
786    const VkRenderingAttachmentInfo color_att = {
787       .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
788       .imageView = radv_image_view_to_handle(&dst_iview),
789       .imageLayout = layout,
790       .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
791       .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
792    };
793 
794    const VkRenderingInfo rendering_info = {
795       .sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
796       .flags = VK_RENDERING_INPUT_ATTACHMENT_NO_CONCURRENT_WRITES_BIT_MESA,
797       .renderArea = resolve_area,
798       .layerCount = 1,
799       .colorAttachmentCount = 1,
800       .pColorAttachments = &color_att,
801    };
802 
803    radv_CmdBeginRendering(radv_cmd_buffer_to_handle(cmd_buffer), &rendering_info);
804 
805    emit_resolve(cmd_buffer, &src_iview, &dst_iview, &(VkOffset2D){srcOffset.x, srcOffset.y},
806                 &(VkOffset2D){dstOffset.x, dstOffset.y});
807 
808    radv_CmdEndRendering(radv_cmd_buffer_to_handle(cmd_buffer));
809 
810    radv_image_view_finish(&src_iview);
811    radv_image_view_finish(&dst_iview);
812 
813    radv_meta_restore(&saved_state, cmd_buffer);
814 }
815 
816 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)817 radv_cmd_buffer_resolve_rendering_fs(struct radv_cmd_buffer *cmd_buffer, struct radv_image_view *src_iview,
818                                      VkImageLayout src_layout, struct radv_image_view *dst_iview,
819                                      VkImageLayout dst_layout)
820 {
821    const struct radv_rendering_state *render = &cmd_buffer->state.render;
822    struct radv_meta_saved_state saved_state;
823    VkRect2D resolve_area = render->area;
824 
825    radv_meta_save(
826       &saved_state, cmd_buffer,
827       RADV_META_SAVE_GRAPHICS_PIPELINE | RADV_META_SAVE_CONSTANTS | RADV_META_SAVE_DESCRIPTORS | RADV_META_SAVE_RENDER);
828 
829    radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1,
830                        &(VkViewport){.x = resolve_area.offset.x,
831                                      .y = resolve_area.offset.y,
832                                      .width = resolve_area.extent.width,
833                                      .height = resolve_area.extent.height,
834                                      .minDepth = 0.0f,
835                                      .maxDepth = 1.0f});
836 
837    radv_CmdSetScissor(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &resolve_area);
838 
839    const VkRenderingAttachmentInfo color_att = {
840       .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
841       .imageView = radv_image_view_to_handle(dst_iview),
842       .imageLayout = dst_layout,
843       .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
844       .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
845    };
846 
847    const VkRenderingInfo rendering_info = {
848       .sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
849       .flags = VK_RENDERING_INPUT_ATTACHMENT_NO_CONCURRENT_WRITES_BIT_MESA,
850       .renderArea = saved_state.render.area,
851       .layerCount = 1,
852       .viewMask = saved_state.render.view_mask,
853       .colorAttachmentCount = 1,
854       .pColorAttachments = &color_att,
855    };
856 
857    radv_CmdBeginRendering(radv_cmd_buffer_to_handle(cmd_buffer), &rendering_info);
858 
859    emit_resolve(cmd_buffer, src_iview, dst_iview, &resolve_area.offset, &resolve_area.offset);
860 
861    radv_CmdEndRendering(radv_cmd_buffer_to_handle(cmd_buffer));
862 
863    radv_meta_restore(&saved_state, cmd_buffer);
864 }
865 
866 /**
867  * Depth/stencil resolves for the current rendering.
868  */
869 void
radv_depth_stencil_resolve_rendering_fs(struct radv_cmd_buffer * cmd_buffer,VkImageAspectFlags aspects,VkResolveModeFlagBits resolve_mode)870 radv_depth_stencil_resolve_rendering_fs(struct radv_cmd_buffer *cmd_buffer, VkImageAspectFlags aspects,
871                                         VkResolveModeFlagBits resolve_mode)
872 {
873    struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
874    const struct radv_rendering_state *render = &cmd_buffer->state.render;
875    VkRect2D resolve_area = render->area;
876    struct radv_meta_saved_state saved_state;
877    struct radv_resolve_barrier barrier;
878 
879    /* Resolves happen before rendering ends, so we have to make the attachment shader-readable */
880    barrier.src_stage_mask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
881    barrier.dst_stage_mask = VK_PIPELINE_STAGE_2_RESOLVE_BIT;
882    barrier.src_access_mask = VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
883    barrier.dst_access_mask = VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT;
884    radv_emit_resolve_barrier(cmd_buffer, &barrier);
885 
886    struct radv_image_view *src_iview = cmd_buffer->state.render.ds_att.iview;
887    VkImageLayout src_layout =
888       aspects & VK_IMAGE_ASPECT_DEPTH_BIT ? render->ds_att.layout : render->ds_att.stencil_layout;
889    struct radv_image *src_image = src_iview->image;
890 
891    VkImageResolve2 region = {0};
892    region.sType = VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2;
893    region.srcSubresource.aspectMask = aspects;
894    region.srcSubresource.mipLevel = 0;
895    region.srcSubresource.baseArrayLayer = 0;
896    region.srcSubresource.layerCount = 1;
897 
898    radv_decompress_resolve_src(cmd_buffer, src_image, src_layout, &region);
899 
900    radv_meta_save(&saved_state, cmd_buffer,
901                   RADV_META_SAVE_GRAPHICS_PIPELINE | RADV_META_SAVE_DESCRIPTORS | RADV_META_SAVE_RENDER);
902 
903    struct radv_image_view *dst_iview = saved_state.render.ds_att.resolve_iview;
904 
905    const VkRenderingAttachmentInfo depth_att = {
906       .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
907       .imageView = radv_image_view_to_handle(dst_iview),
908       .imageLayout = saved_state.render.ds_att.resolve_layout,
909       .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
910       .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
911    };
912 
913    const VkRenderingAttachmentInfo stencil_att = {
914       .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
915       .imageView = radv_image_view_to_handle(dst_iview),
916       .imageLayout = saved_state.render.ds_att.stencil_resolve_layout,
917       .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
918       .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
919    };
920 
921    const VkRenderingInfo rendering_info = {
922       .sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
923       .flags = VK_RENDERING_INPUT_ATTACHMENT_NO_CONCURRENT_WRITES_BIT_MESA,
924       .renderArea = saved_state.render.area,
925       .layerCount = 1,
926       .viewMask = saved_state.render.view_mask,
927       .pDepthAttachment = (dst_iview->image->vk.aspects & VK_IMAGE_ASPECT_DEPTH_BIT) ? &depth_att : NULL,
928       .pStencilAttachment = (dst_iview->image->vk.aspects & VK_IMAGE_ASPECT_STENCIL_BIT) ? &stencil_att : NULL,
929    };
930 
931    radv_CmdBeginRendering(radv_cmd_buffer_to_handle(cmd_buffer), &rendering_info);
932 
933    struct radv_image_view tsrc_iview;
934    radv_image_view_init(&tsrc_iview, device,
935                         &(VkImageViewCreateInfo){
936                            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
937                            .image = radv_image_to_handle(src_image),
938                            .viewType = VK_IMAGE_VIEW_TYPE_2D,
939                            .format = src_iview->vk.format,
940                            .subresourceRange =
941                               {
942                                  .aspectMask = aspects,
943                                  .baseMipLevel = 0,
944                                  .levelCount = 1,
945                                  .baseArrayLayer = 0,
946                                  .layerCount = 1,
947                               },
948                         },
949                         0, NULL);
950 
951    emit_depth_stencil_resolve(cmd_buffer, &tsrc_iview, dst_iview, &resolve_area.offset, &resolve_area.extent, aspects,
952                               resolve_mode);
953 
954    radv_CmdEndRendering(radv_cmd_buffer_to_handle(cmd_buffer));
955 
956    radv_image_view_finish(&tsrc_iview);
957 
958    radv_meta_restore(&saved_state, cmd_buffer);
959 }
960