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