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, ®ion->srcSubresource) == 1 &&
729 vk_image_subresource_layer_count(&dst_image->vk, ®ion->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, ®ion);
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