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