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