radv: do not recursively begin/end render pass for meta operations
[mesa.git] / src / amd / vulkan / radv_meta_clear.c
1 /*
2 * Copyright © 2015 Intel Corporation
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 "radv_debug.h"
25 #include "radv_meta.h"
26 #include "radv_private.h"
27 #include "nir/nir_builder.h"
28
29 #include "util/format_rgb9e5.h"
30 #include "vk_format.h"
31
32 enum {
33 DEPTH_CLEAR_SLOW,
34 DEPTH_CLEAR_FAST_EXPCLEAR,
35 DEPTH_CLEAR_FAST_NO_EXPCLEAR
36 };
37
38 static void
39 build_color_shaders(struct nir_shader **out_vs,
40 struct nir_shader **out_fs,
41 uint32_t frag_output)
42 {
43 nir_builder vs_b;
44 nir_builder fs_b;
45
46 nir_builder_init_simple_shader(&vs_b, NULL, MESA_SHADER_VERTEX, NULL);
47 nir_builder_init_simple_shader(&fs_b, NULL, MESA_SHADER_FRAGMENT, NULL);
48
49 vs_b.shader->info.name = ralloc_strdup(vs_b.shader, "meta_clear_color_vs");
50 fs_b.shader->info.name = ralloc_strdup(fs_b.shader, "meta_clear_color_fs");
51
52 const struct glsl_type *position_type = glsl_vec4_type();
53 const struct glsl_type *color_type = glsl_vec4_type();
54
55 nir_variable *vs_out_pos =
56 nir_variable_create(vs_b.shader, nir_var_shader_out, position_type,
57 "gl_Position");
58 vs_out_pos->data.location = VARYING_SLOT_POS;
59
60 nir_intrinsic_instr *in_color_load = nir_intrinsic_instr_create(fs_b.shader, nir_intrinsic_load_push_constant);
61 nir_intrinsic_set_base(in_color_load, 0);
62 nir_intrinsic_set_range(in_color_load, 16);
63 in_color_load->src[0] = nir_src_for_ssa(nir_imm_int(&fs_b, 0));
64 in_color_load->num_components = 4;
65 nir_ssa_dest_init(&in_color_load->instr, &in_color_load->dest, 4, 32, "clear color");
66 nir_builder_instr_insert(&fs_b, &in_color_load->instr);
67
68 nir_variable *fs_out_color =
69 nir_variable_create(fs_b.shader, nir_var_shader_out, color_type,
70 "f_color");
71 fs_out_color->data.location = FRAG_RESULT_DATA0 + frag_output;
72
73 nir_store_var(&fs_b, fs_out_color, &in_color_load->dest.ssa, 0xf);
74
75 nir_ssa_def *outvec = radv_meta_gen_rect_vertices(&vs_b);
76 nir_store_var(&vs_b, vs_out_pos, outvec, 0xf);
77
78 const struct glsl_type *layer_type = glsl_int_type();
79 nir_variable *vs_out_layer =
80 nir_variable_create(vs_b.shader, nir_var_shader_out, layer_type,
81 "v_layer");
82 vs_out_layer->data.location = VARYING_SLOT_LAYER;
83 vs_out_layer->data.interpolation = INTERP_MODE_FLAT;
84 nir_ssa_def *inst_id = nir_load_instance_id(&vs_b);
85 nir_ssa_def *base_instance = nir_load_base_instance(&vs_b);
86
87 nir_ssa_def *layer_id = nir_iadd(&vs_b, inst_id, base_instance);
88 nir_store_var(&vs_b, vs_out_layer, layer_id, 0x1);
89
90 *out_vs = vs_b.shader;
91 *out_fs = fs_b.shader;
92 }
93
94 static VkResult
95 create_pipeline(struct radv_device *device,
96 struct radv_render_pass *render_pass,
97 uint32_t samples,
98 struct nir_shader *vs_nir,
99 struct nir_shader *fs_nir,
100 const VkPipelineVertexInputStateCreateInfo *vi_state,
101 const VkPipelineDepthStencilStateCreateInfo *ds_state,
102 const VkPipelineColorBlendStateCreateInfo *cb_state,
103 const VkPipelineLayout layout,
104 const struct radv_graphics_pipeline_create_info *extra,
105 const VkAllocationCallbacks *alloc,
106 VkPipeline *pipeline)
107 {
108 VkDevice device_h = radv_device_to_handle(device);
109 VkResult result;
110
111 struct radv_shader_module vs_m = { .nir = vs_nir };
112 struct radv_shader_module fs_m = { .nir = fs_nir };
113
114 result = radv_graphics_pipeline_create(device_h,
115 radv_pipeline_cache_to_handle(&device->meta_state.cache),
116 &(VkGraphicsPipelineCreateInfo) {
117 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
118 .stageCount = fs_nir ? 2 : 1,
119 .pStages = (VkPipelineShaderStageCreateInfo[]) {
120 {
121 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
122 .stage = VK_SHADER_STAGE_VERTEX_BIT,
123 .module = radv_shader_module_to_handle(&vs_m),
124 .pName = "main",
125 },
126 {
127 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
128 .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
129 .module = radv_shader_module_to_handle(&fs_m),
130 .pName = "main",
131 },
132 },
133 .pVertexInputState = vi_state,
134 .pInputAssemblyState = &(VkPipelineInputAssemblyStateCreateInfo) {
135 .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
136 .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
137 .primitiveRestartEnable = false,
138 },
139 .pViewportState = &(VkPipelineViewportStateCreateInfo) {
140 .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
141 .viewportCount = 1,
142 .scissorCount = 1,
143 },
144 .pRasterizationState = &(VkPipelineRasterizationStateCreateInfo) {
145 .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
146 .rasterizerDiscardEnable = false,
147 .polygonMode = VK_POLYGON_MODE_FILL,
148 .cullMode = VK_CULL_MODE_NONE,
149 .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
150 .depthBiasEnable = false,
151 },
152 .pMultisampleState = &(VkPipelineMultisampleStateCreateInfo) {
153 .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
154 .rasterizationSamples = samples,
155 .sampleShadingEnable = false,
156 .pSampleMask = NULL,
157 .alphaToCoverageEnable = false,
158 .alphaToOneEnable = false,
159 },
160 .pDepthStencilState = ds_state,
161 .pColorBlendState = cb_state,
162 .pDynamicState = &(VkPipelineDynamicStateCreateInfo) {
163 /* The meta clear pipeline declares all state as dynamic.
164 * As a consequence, vkCmdBindPipeline writes no dynamic state
165 * to the cmd buffer. Therefore, at the end of the meta clear,
166 * we need only restore dynamic state was vkCmdSet.
167 */
168 .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
169 .dynamicStateCount = 8,
170 .pDynamicStates = (VkDynamicState[]) {
171 /* Everything except stencil write mask */
172 VK_DYNAMIC_STATE_VIEWPORT,
173 VK_DYNAMIC_STATE_SCISSOR,
174 VK_DYNAMIC_STATE_LINE_WIDTH,
175 VK_DYNAMIC_STATE_DEPTH_BIAS,
176 VK_DYNAMIC_STATE_BLEND_CONSTANTS,
177 VK_DYNAMIC_STATE_DEPTH_BOUNDS,
178 VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
179 VK_DYNAMIC_STATE_STENCIL_REFERENCE,
180 },
181 },
182 .layout = layout,
183 .flags = 0,
184 .renderPass = radv_render_pass_to_handle(render_pass),
185 .subpass = 0,
186 },
187 extra,
188 alloc,
189 pipeline);
190
191 ralloc_free(vs_nir);
192 ralloc_free(fs_nir);
193
194 return result;
195 }
196
197 static VkResult
198 create_color_renderpass(struct radv_device *device,
199 VkFormat vk_format,
200 uint32_t samples,
201 VkRenderPass *pass)
202 {
203 mtx_lock(&device->meta_state.mtx);
204 if (*pass) {
205 mtx_unlock (&device->meta_state.mtx);
206 return VK_SUCCESS;
207 }
208
209 VkResult result = radv_CreateRenderPass(radv_device_to_handle(device),
210 &(VkRenderPassCreateInfo) {
211 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
212 .attachmentCount = 1,
213 .pAttachments = &(VkAttachmentDescription) {
214 .format = vk_format,
215 .samples = samples,
216 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
217 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
218 .initialLayout = VK_IMAGE_LAYOUT_GENERAL,
219 .finalLayout = VK_IMAGE_LAYOUT_GENERAL,
220 },
221 .subpassCount = 1,
222 .pSubpasses = &(VkSubpassDescription) {
223 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
224 .inputAttachmentCount = 0,
225 .colorAttachmentCount = 1,
226 .pColorAttachments = &(VkAttachmentReference) {
227 .attachment = 0,
228 .layout = VK_IMAGE_LAYOUT_GENERAL,
229 },
230 .pResolveAttachments = NULL,
231 .pDepthStencilAttachment = &(VkAttachmentReference) {
232 .attachment = VK_ATTACHMENT_UNUSED,
233 .layout = VK_IMAGE_LAYOUT_GENERAL,
234 },
235 .preserveAttachmentCount = 0,
236 .pPreserveAttachments = NULL,
237 },
238 .dependencyCount = 2,
239 .pDependencies = (VkSubpassDependency[]) {
240 {
241 .srcSubpass = VK_SUBPASS_EXTERNAL,
242 .dstSubpass = 0,
243 .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
244 .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
245 .srcAccessMask = 0,
246 .dstAccessMask = 0,
247 .dependencyFlags = 0
248 },
249 {
250 .srcSubpass = 0,
251 .dstSubpass = VK_SUBPASS_EXTERNAL,
252 .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
253 .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
254 .srcAccessMask = 0,
255 .dstAccessMask = 0,
256 .dependencyFlags = 0
257 }
258 },
259 }, &device->meta_state.alloc, pass);
260 mtx_unlock(&device->meta_state.mtx);
261 return result;
262 }
263
264 static VkResult
265 create_color_pipeline(struct radv_device *device,
266 uint32_t samples,
267 uint32_t frag_output,
268 VkPipeline *pipeline,
269 VkRenderPass pass)
270 {
271 struct nir_shader *vs_nir;
272 struct nir_shader *fs_nir;
273 VkResult result;
274
275 mtx_lock(&device->meta_state.mtx);
276 if (*pipeline) {
277 mtx_unlock(&device->meta_state.mtx);
278 return VK_SUCCESS;
279 }
280
281 build_color_shaders(&vs_nir, &fs_nir, frag_output);
282
283 const VkPipelineVertexInputStateCreateInfo vi_state = {
284 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
285 .vertexBindingDescriptionCount = 0,
286 .vertexAttributeDescriptionCount = 0,
287 };
288
289 const VkPipelineDepthStencilStateCreateInfo ds_state = {
290 .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
291 .depthTestEnable = false,
292 .depthWriteEnable = false,
293 .depthBoundsTestEnable = false,
294 .stencilTestEnable = false,
295 };
296
297 VkPipelineColorBlendAttachmentState blend_attachment_state[MAX_RTS] = { 0 };
298 blend_attachment_state[frag_output] = (VkPipelineColorBlendAttachmentState) {
299 .blendEnable = false,
300 .colorWriteMask = VK_COLOR_COMPONENT_A_BIT |
301 VK_COLOR_COMPONENT_R_BIT |
302 VK_COLOR_COMPONENT_G_BIT |
303 VK_COLOR_COMPONENT_B_BIT,
304 };
305
306 const VkPipelineColorBlendStateCreateInfo cb_state = {
307 .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
308 .logicOpEnable = false,
309 .attachmentCount = MAX_RTS,
310 .pAttachments = blend_attachment_state
311 };
312
313
314 struct radv_graphics_pipeline_create_info extra = {
315 .use_rectlist = true,
316 };
317 result = create_pipeline(device, radv_render_pass_from_handle(pass),
318 samples, vs_nir, fs_nir, &vi_state, &ds_state, &cb_state,
319 device->meta_state.clear_color_p_layout,
320 &extra, &device->meta_state.alloc, pipeline);
321
322 mtx_unlock(&device->meta_state.mtx);
323 return result;
324 }
325
326 static void
327 finish_meta_clear_htile_mask_state(struct radv_device *device)
328 {
329 struct radv_meta_state *state = &device->meta_state;
330
331 radv_DestroyPipeline(radv_device_to_handle(device),
332 state->clear_htile_mask_pipeline,
333 &state->alloc);
334 radv_DestroyPipelineLayout(radv_device_to_handle(device),
335 state->clear_htile_mask_p_layout,
336 &state->alloc);
337 radv_DestroyDescriptorSetLayout(radv_device_to_handle(device),
338 state->clear_htile_mask_ds_layout,
339 &state->alloc);
340 }
341
342 void
343 radv_device_finish_meta_clear_state(struct radv_device *device)
344 {
345 struct radv_meta_state *state = &device->meta_state;
346
347 for (uint32_t i = 0; i < ARRAY_SIZE(state->clear); ++i) {
348 for (uint32_t j = 0; j < ARRAY_SIZE(state->clear[i].color_pipelines); ++j) {
349 radv_DestroyPipeline(radv_device_to_handle(device),
350 state->clear[i].color_pipelines[j],
351 &state->alloc);
352 radv_DestroyRenderPass(radv_device_to_handle(device),
353 state->clear[i].render_pass[j],
354 &state->alloc);
355 }
356
357 for (uint32_t j = 0; j < NUM_DEPTH_CLEAR_PIPELINES; j++) {
358 radv_DestroyPipeline(radv_device_to_handle(device),
359 state->clear[i].depth_only_pipeline[j],
360 &state->alloc);
361 radv_DestroyPipeline(radv_device_to_handle(device),
362 state->clear[i].stencil_only_pipeline[j],
363 &state->alloc);
364 radv_DestroyPipeline(radv_device_to_handle(device),
365 state->clear[i].depthstencil_pipeline[j],
366 &state->alloc);
367
368 radv_DestroyPipeline(radv_device_to_handle(device),
369 state->clear[i].depth_only_unrestricted_pipeline[j],
370 &state->alloc);
371 radv_DestroyPipeline(radv_device_to_handle(device),
372 state->clear[i].stencil_only_unrestricted_pipeline[j],
373 &state->alloc);
374 radv_DestroyPipeline(radv_device_to_handle(device),
375 state->clear[i].depthstencil_unrestricted_pipeline[j],
376 &state->alloc);
377 }
378 radv_DestroyRenderPass(radv_device_to_handle(device),
379 state->clear[i].depthstencil_rp,
380 &state->alloc);
381 }
382 radv_DestroyPipelineLayout(radv_device_to_handle(device),
383 state->clear_color_p_layout,
384 &state->alloc);
385 radv_DestroyPipelineLayout(radv_device_to_handle(device),
386 state->clear_depth_p_layout,
387 &state->alloc);
388 radv_DestroyPipelineLayout(radv_device_to_handle(device),
389 state->clear_depth_unrestricted_p_layout,
390 &state->alloc);
391
392 finish_meta_clear_htile_mask_state(device);
393 }
394
395 static void
396 emit_color_clear(struct radv_cmd_buffer *cmd_buffer,
397 const VkClearAttachment *clear_att,
398 const VkClearRect *clear_rect,
399 uint32_t view_mask)
400 {
401 struct radv_device *device = cmd_buffer->device;
402 const struct radv_subpass *subpass = cmd_buffer->state.subpass;
403 const uint32_t subpass_att = clear_att->colorAttachment;
404 const uint32_t pass_att = subpass->color_attachments[subpass_att].attachment;
405 const struct radv_image_view *iview = cmd_buffer->state.attachments ?
406 cmd_buffer->state.attachments[pass_att].iview : NULL;
407 uint32_t samples, samples_log2;
408 VkFormat format;
409 unsigned fs_key;
410 VkClearColorValue clear_value = clear_att->clearValue.color;
411 VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer);
412 VkPipeline pipeline;
413
414 /* When a framebuffer is bound to the current command buffer, get the
415 * number of samples from it. Otherwise, get the number of samples from
416 * the render pass because it's likely a secondary command buffer.
417 */
418 if (iview) {
419 samples = iview->image->info.samples;
420 format = iview->vk_format;
421 } else {
422 samples = cmd_buffer->state.pass->attachments[pass_att].samples;
423 format = cmd_buffer->state.pass->attachments[pass_att].format;
424 }
425
426 samples_log2 = ffs(samples) - 1;
427 fs_key = radv_format_meta_fs_key(format);
428
429 if (fs_key == -1) {
430 radv_finishme("color clears incomplete");
431 return;
432 }
433
434 if (device->meta_state.clear[samples_log2].render_pass[fs_key] == VK_NULL_HANDLE) {
435 VkResult ret = create_color_renderpass(device, radv_fs_key_format_exemplars[fs_key],
436 samples,
437 &device->meta_state.clear[samples_log2].render_pass[fs_key]);
438 if (ret != VK_SUCCESS) {
439 cmd_buffer->record_result = ret;
440 return;
441 }
442 }
443
444 if (device->meta_state.clear[samples_log2].color_pipelines[fs_key] == VK_NULL_HANDLE) {
445 VkResult ret = create_color_pipeline(device, samples, 0,
446 &device->meta_state.clear[samples_log2].color_pipelines[fs_key],
447 device->meta_state.clear[samples_log2].render_pass[fs_key]);
448 if (ret != VK_SUCCESS) {
449 cmd_buffer->record_result = ret;
450 return;
451 }
452 }
453
454 pipeline = device->meta_state.clear[samples_log2].color_pipelines[fs_key];
455 if (!pipeline) {
456 radv_finishme("color clears incomplete");
457 return;
458 }
459 assert(samples_log2 < ARRAY_SIZE(device->meta_state.clear));
460 assert(pipeline);
461 assert(clear_att->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
462 assert(clear_att->colorAttachment < subpass->color_count);
463
464 radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
465 device->meta_state.clear_color_p_layout,
466 VK_SHADER_STAGE_FRAGMENT_BIT, 0, 16,
467 &clear_value);
468
469 struct radv_subpass clear_subpass = {
470 .color_count = 1,
471 .color_attachments = (struct radv_subpass_attachment[]) {
472 subpass->color_attachments[clear_att->colorAttachment]
473 },
474 .depth_stencil_attachment = NULL,
475 };
476
477 radv_cmd_buffer_set_subpass(cmd_buffer, &clear_subpass);
478
479 radv_CmdBindPipeline(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS,
480 pipeline);
481
482 radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &(VkViewport) {
483 .x = clear_rect->rect.offset.x,
484 .y = clear_rect->rect.offset.y,
485 .width = clear_rect->rect.extent.width,
486 .height = clear_rect->rect.extent.height,
487 .minDepth = 0.0f,
488 .maxDepth = 1.0f
489 });
490
491 radv_CmdSetScissor(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &clear_rect->rect);
492
493 if (view_mask) {
494 unsigned i;
495 for_each_bit(i, view_mask)
496 radv_CmdDraw(cmd_buffer_h, 3, 1, 0, i);
497 } else {
498 radv_CmdDraw(cmd_buffer_h, 3, clear_rect->layerCount, 0, clear_rect->baseArrayLayer);
499 }
500
501 radv_cmd_buffer_set_subpass(cmd_buffer, subpass);
502 }
503
504
505 static void
506 build_depthstencil_shader(struct nir_shader **out_vs,
507 struct nir_shader **out_fs,
508 bool unrestricted)
509 {
510 nir_builder vs_b, fs_b;
511
512 nir_builder_init_simple_shader(&vs_b, NULL, MESA_SHADER_VERTEX, NULL);
513 nir_builder_init_simple_shader(&fs_b, NULL, MESA_SHADER_FRAGMENT, NULL);
514
515 vs_b.shader->info.name = ralloc_strdup(vs_b.shader, "meta_clear_depthstencil_vs");
516 fs_b.shader->info.name = ralloc_strdup(fs_b.shader, "meta_clear_depthstencil_fs");
517 const struct glsl_type *position_out_type = glsl_vec4_type();
518
519 nir_variable *vs_out_pos =
520 nir_variable_create(vs_b.shader, nir_var_shader_out, position_out_type,
521 "gl_Position");
522 vs_out_pos->data.location = VARYING_SLOT_POS;
523
524 nir_ssa_def *z;
525 if (unrestricted) {
526 nir_intrinsic_instr *in_color_load = nir_intrinsic_instr_create(fs_b.shader, nir_intrinsic_load_push_constant);
527 nir_intrinsic_set_base(in_color_load, 0);
528 nir_intrinsic_set_range(in_color_load, 4);
529 in_color_load->src[0] = nir_src_for_ssa(nir_imm_int(&fs_b, 0));
530 in_color_load->num_components = 1;
531 nir_ssa_dest_init(&in_color_load->instr, &in_color_load->dest, 1, 32, "depth value");
532 nir_builder_instr_insert(&fs_b, &in_color_load->instr);
533
534 nir_variable *fs_out_depth =
535 nir_variable_create(fs_b.shader, nir_var_shader_out,
536 glsl_int_type(), "f_depth");
537 fs_out_depth->data.location = FRAG_RESULT_DEPTH;
538 nir_store_var(&fs_b, fs_out_depth, &in_color_load->dest.ssa, 0x1);
539
540 z = nir_imm_float(&vs_b, 0.0);
541 } else {
542 nir_intrinsic_instr *in_color_load = nir_intrinsic_instr_create(vs_b.shader, nir_intrinsic_load_push_constant);
543 nir_intrinsic_set_base(in_color_load, 0);
544 nir_intrinsic_set_range(in_color_load, 4);
545 in_color_load->src[0] = nir_src_for_ssa(nir_imm_int(&vs_b, 0));
546 in_color_load->num_components = 1;
547 nir_ssa_dest_init(&in_color_load->instr, &in_color_load->dest, 1, 32, "depth value");
548 nir_builder_instr_insert(&vs_b, &in_color_load->instr);
549
550 z = &in_color_load->dest.ssa;
551 }
552
553 nir_ssa_def *outvec = radv_meta_gen_rect_vertices_comp2(&vs_b, z);
554 nir_store_var(&vs_b, vs_out_pos, outvec, 0xf);
555
556 const struct glsl_type *layer_type = glsl_int_type();
557 nir_variable *vs_out_layer =
558 nir_variable_create(vs_b.shader, nir_var_shader_out, layer_type,
559 "v_layer");
560 vs_out_layer->data.location = VARYING_SLOT_LAYER;
561 vs_out_layer->data.interpolation = INTERP_MODE_FLAT;
562 nir_ssa_def *inst_id = nir_load_instance_id(&vs_b);
563 nir_ssa_def *base_instance = nir_load_base_instance(&vs_b);
564
565 nir_ssa_def *layer_id = nir_iadd(&vs_b, inst_id, base_instance);
566 nir_store_var(&vs_b, vs_out_layer, layer_id, 0x1);
567
568 *out_vs = vs_b.shader;
569 *out_fs = fs_b.shader;
570 }
571
572 static VkResult
573 create_depthstencil_renderpass(struct radv_device *device,
574 uint32_t samples,
575 VkRenderPass *render_pass)
576 {
577 mtx_lock(&device->meta_state.mtx);
578 if (*render_pass) {
579 mtx_unlock(&device->meta_state.mtx);
580 return VK_SUCCESS;
581 }
582
583 VkResult result = radv_CreateRenderPass(radv_device_to_handle(device),
584 &(VkRenderPassCreateInfo) {
585 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
586 .attachmentCount = 1,
587 .pAttachments = &(VkAttachmentDescription) {
588 .format = VK_FORMAT_D32_SFLOAT_S8_UINT,
589 .samples = samples,
590 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
591 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
592 .initialLayout = VK_IMAGE_LAYOUT_GENERAL,
593 .finalLayout = VK_IMAGE_LAYOUT_GENERAL,
594 },
595 .subpassCount = 1,
596 .pSubpasses = &(VkSubpassDescription) {
597 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
598 .inputAttachmentCount = 0,
599 .colorAttachmentCount = 0,
600 .pColorAttachments = NULL,
601 .pResolveAttachments = NULL,
602 .pDepthStencilAttachment = &(VkAttachmentReference) {
603 .attachment = 0,
604 .layout = VK_IMAGE_LAYOUT_GENERAL,
605 },
606 .preserveAttachmentCount = 0,
607 .pPreserveAttachments = NULL,
608 },
609 .dependencyCount = 2,
610 .pDependencies = (VkSubpassDependency[]) {
611 {
612 .srcSubpass = VK_SUBPASS_EXTERNAL,
613 .dstSubpass = 0,
614 .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
615 .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
616 .srcAccessMask = 0,
617 .dstAccessMask = 0,
618 .dependencyFlags = 0
619 },
620 {
621 .srcSubpass = 0,
622 .dstSubpass = VK_SUBPASS_EXTERNAL,
623 .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
624 .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
625 .srcAccessMask = 0,
626 .dstAccessMask = 0,
627 .dependencyFlags = 0
628 }
629 }
630 }, &device->meta_state.alloc, render_pass);
631 mtx_unlock(&device->meta_state.mtx);
632 return result;
633 }
634
635 static VkResult
636 create_depthstencil_pipeline(struct radv_device *device,
637 VkImageAspectFlags aspects,
638 uint32_t samples,
639 int index,
640 bool unrestricted,
641 VkPipeline *pipeline,
642 VkRenderPass render_pass)
643 {
644 struct nir_shader *vs_nir, *fs_nir;
645 VkResult result;
646
647 mtx_lock(&device->meta_state.mtx);
648 if (*pipeline) {
649 mtx_unlock(&device->meta_state.mtx);
650 return VK_SUCCESS;
651 }
652
653 build_depthstencil_shader(&vs_nir, &fs_nir, unrestricted);
654
655 const VkPipelineVertexInputStateCreateInfo vi_state = {
656 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
657 .vertexBindingDescriptionCount = 0,
658 .vertexAttributeDescriptionCount = 0,
659 };
660
661 const VkPipelineDepthStencilStateCreateInfo ds_state = {
662 .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
663 .depthTestEnable = (aspects & VK_IMAGE_ASPECT_DEPTH_BIT),
664 .depthCompareOp = VK_COMPARE_OP_ALWAYS,
665 .depthWriteEnable = (aspects & VK_IMAGE_ASPECT_DEPTH_BIT),
666 .depthBoundsTestEnable = false,
667 .stencilTestEnable = (aspects & VK_IMAGE_ASPECT_STENCIL_BIT),
668 .front = {
669 .passOp = VK_STENCIL_OP_REPLACE,
670 .compareOp = VK_COMPARE_OP_ALWAYS,
671 .writeMask = UINT32_MAX,
672 .reference = 0, /* dynamic */
673 },
674 .back = { 0 /* dont care */ },
675 };
676
677 const VkPipelineColorBlendStateCreateInfo cb_state = {
678 .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
679 .logicOpEnable = false,
680 .attachmentCount = 0,
681 .pAttachments = NULL,
682 };
683
684 struct radv_graphics_pipeline_create_info extra = {
685 .use_rectlist = true,
686 };
687
688 if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {
689 extra.db_depth_clear = index == DEPTH_CLEAR_SLOW ? false : true;
690 extra.db_depth_disable_expclear = index == DEPTH_CLEAR_FAST_NO_EXPCLEAR ? true : false;
691 }
692 if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
693 extra.db_stencil_clear = index == DEPTH_CLEAR_SLOW ? false : true;
694 extra.db_stencil_disable_expclear = index == DEPTH_CLEAR_FAST_NO_EXPCLEAR ? true : false;
695 }
696 result = create_pipeline(device, radv_render_pass_from_handle(render_pass),
697 samples, vs_nir, fs_nir, &vi_state, &ds_state, &cb_state,
698 device->meta_state.clear_depth_p_layout,
699 &extra, &device->meta_state.alloc, pipeline);
700
701 mtx_unlock(&device->meta_state.mtx);
702 return result;
703 }
704
705 static bool depth_view_can_fast_clear(struct radv_cmd_buffer *cmd_buffer,
706 const struct radv_image_view *iview,
707 VkImageAspectFlags aspects,
708 VkImageLayout layout,
709 bool in_render_loop,
710 const VkClearRect *clear_rect,
711 VkClearDepthStencilValue clear_value)
712 {
713 if (!iview)
714 return false;
715
716 uint32_t queue_mask = radv_image_queue_family_mask(iview->image,
717 cmd_buffer->queue_family_index,
718 cmd_buffer->queue_family_index);
719 if (clear_rect->rect.offset.x || clear_rect->rect.offset.y ||
720 clear_rect->rect.extent.width != iview->extent.width ||
721 clear_rect->rect.extent.height != iview->extent.height)
722 return false;
723 if (radv_image_is_tc_compat_htile(iview->image) &&
724 (((aspects & VK_IMAGE_ASPECT_DEPTH_BIT) && clear_value.depth != 0.0 &&
725 clear_value.depth != 1.0) ||
726 ((aspects & VK_IMAGE_ASPECT_STENCIL_BIT) && clear_value.stencil != 0)))
727 return false;
728 if (radv_image_has_htile(iview->image) &&
729 iview->base_mip == 0 &&
730 iview->base_layer == 0 &&
731 iview->layer_count == iview->image->info.array_size &&
732 radv_layout_is_htile_compressed(iview->image, layout, in_render_loop, queue_mask) &&
733 radv_image_extent_compare(iview->image, &iview->extent))
734 return true;
735 return false;
736 }
737
738 static VkPipeline
739 pick_depthstencil_pipeline(struct radv_cmd_buffer *cmd_buffer,
740 struct radv_meta_state *meta_state,
741 const struct radv_image_view *iview,
742 int samples_log2,
743 VkImageAspectFlags aspects,
744 VkImageLayout layout,
745 bool in_render_loop,
746 const VkClearRect *clear_rect,
747 VkClearDepthStencilValue clear_value)
748 {
749 bool fast = depth_view_can_fast_clear(cmd_buffer, iview, aspects, layout,
750 in_render_loop, clear_rect, clear_value);
751 bool unrestricted = cmd_buffer->device->enabled_extensions.EXT_depth_range_unrestricted;
752 int index = DEPTH_CLEAR_SLOW;
753 VkPipeline *pipeline;
754
755 if (fast) {
756 /* we don't know the previous clear values, so we always have
757 * the NO_EXPCLEAR path */
758 index = DEPTH_CLEAR_FAST_NO_EXPCLEAR;
759 }
760
761 switch (aspects) {
762 case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT:
763 pipeline = unrestricted ?
764 &meta_state->clear[samples_log2].depthstencil_unrestricted_pipeline[index] :
765 &meta_state->clear[samples_log2].depthstencil_pipeline[index];
766 break;
767 case VK_IMAGE_ASPECT_DEPTH_BIT:
768 pipeline = unrestricted ?
769 &meta_state->clear[samples_log2].depth_only_unrestricted_pipeline[index] :
770 &meta_state->clear[samples_log2].depth_only_pipeline[index];
771 break;
772 case VK_IMAGE_ASPECT_STENCIL_BIT:
773 pipeline = unrestricted ?
774 &meta_state->clear[samples_log2].stencil_only_unrestricted_pipeline[index] :
775 &meta_state->clear[samples_log2].stencil_only_pipeline[index];
776 break;
777 default:
778 unreachable("expected depth or stencil aspect");
779 }
780
781 if (cmd_buffer->device->meta_state.clear[samples_log2].depthstencil_rp == VK_NULL_HANDLE) {
782 VkResult ret = create_depthstencil_renderpass(cmd_buffer->device, 1u << samples_log2,
783 &cmd_buffer->device->meta_state.clear[samples_log2].depthstencil_rp);
784 if (ret != VK_SUCCESS) {
785 cmd_buffer->record_result = ret;
786 return VK_NULL_HANDLE;
787 }
788 }
789
790 if (*pipeline == VK_NULL_HANDLE) {
791 VkResult ret = create_depthstencil_pipeline(cmd_buffer->device, aspects, 1u << samples_log2, index, unrestricted,
792 pipeline, cmd_buffer->device->meta_state.clear[samples_log2].depthstencil_rp);
793 if (ret != VK_SUCCESS) {
794 cmd_buffer->record_result = ret;
795 return VK_NULL_HANDLE;
796 }
797 }
798 return *pipeline;
799 }
800
801 static void
802 emit_depthstencil_clear(struct radv_cmd_buffer *cmd_buffer,
803 const VkClearAttachment *clear_att,
804 const VkClearRect *clear_rect,
805 struct radv_subpass_attachment *ds_att,
806 uint32_t view_mask)
807 {
808 struct radv_device *device = cmd_buffer->device;
809 struct radv_meta_state *meta_state = &device->meta_state;
810 const struct radv_subpass *subpass = cmd_buffer->state.subpass;
811 const uint32_t pass_att = ds_att->attachment;
812 VkClearDepthStencilValue clear_value = clear_att->clearValue.depthStencil;
813 VkImageAspectFlags aspects = clear_att->aspectMask;
814 const struct radv_image_view *iview = cmd_buffer->state.attachments ?
815 cmd_buffer->state.attachments[pass_att].iview : NULL;
816 uint32_t samples, samples_log2;
817 VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer);
818
819 /* When a framebuffer is bound to the current command buffer, get the
820 * number of samples from it. Otherwise, get the number of samples from
821 * the render pass because it's likely a secondary command buffer.
822 */
823 if (iview) {
824 samples = iview->image->info.samples;
825 } else {
826 samples = cmd_buffer->state.pass->attachments[pass_att].samples;
827 }
828
829 samples_log2 = ffs(samples) - 1;
830
831 assert(pass_att != VK_ATTACHMENT_UNUSED);
832
833 if (!(aspects & VK_IMAGE_ASPECT_DEPTH_BIT))
834 clear_value.depth = 1.0f;
835
836 if (cmd_buffer->device->enabled_extensions.EXT_depth_range_unrestricted) {
837 radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
838 device->meta_state.clear_depth_unrestricted_p_layout,
839 VK_SHADER_STAGE_FRAGMENT_BIT, 0, 4,
840 &clear_value.depth);
841 } else {
842 radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
843 device->meta_state.clear_depth_p_layout,
844 VK_SHADER_STAGE_VERTEX_BIT, 0, 4,
845 &clear_value.depth);
846 }
847
848 uint32_t prev_reference = cmd_buffer->state.dynamic.stencil_reference.front;
849 if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
850 radv_CmdSetStencilReference(cmd_buffer_h, VK_STENCIL_FACE_FRONT_BIT,
851 clear_value.stencil);
852 }
853
854 VkPipeline pipeline = pick_depthstencil_pipeline(cmd_buffer,
855 meta_state,
856 iview,
857 samples_log2,
858 aspects,
859 ds_att->layout,
860 ds_att->in_render_loop,
861 clear_rect,
862 clear_value);
863 if (!pipeline)
864 return;
865
866 struct radv_subpass clear_subpass = {
867 .color_count = 0,
868 .color_attachments = NULL,
869 .depth_stencil_attachment = ds_att,
870 };
871
872 radv_cmd_buffer_set_subpass(cmd_buffer, &clear_subpass);
873
874 radv_CmdBindPipeline(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS,
875 pipeline);
876
877 if (depth_view_can_fast_clear(cmd_buffer, iview, aspects,
878 ds_att->layout, ds_att->in_render_loop,
879 clear_rect, clear_value))
880 radv_update_ds_clear_metadata(cmd_buffer, iview,
881 clear_value, aspects);
882
883 radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &(VkViewport) {
884 .x = clear_rect->rect.offset.x,
885 .y = clear_rect->rect.offset.y,
886 .width = clear_rect->rect.extent.width,
887 .height = clear_rect->rect.extent.height,
888 .minDepth = 0.0f,
889 .maxDepth = 1.0f
890 });
891
892 radv_CmdSetScissor(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &clear_rect->rect);
893
894 if (view_mask) {
895 unsigned i;
896 for_each_bit(i, view_mask)
897 radv_CmdDraw(cmd_buffer_h, 3, 1, 0, i);
898 } else {
899 radv_CmdDraw(cmd_buffer_h, 3, clear_rect->layerCount, 0, clear_rect->baseArrayLayer);
900 }
901
902 if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
903 radv_CmdSetStencilReference(cmd_buffer_h, VK_STENCIL_FACE_FRONT_BIT,
904 prev_reference);
905 }
906
907 radv_cmd_buffer_set_subpass(cmd_buffer, subpass);
908 }
909
910 static uint32_t
911 clear_htile_mask(struct radv_cmd_buffer *cmd_buffer,
912 struct radeon_winsys_bo *bo, uint64_t offset, uint64_t size,
913 uint32_t htile_value, uint32_t htile_mask)
914 {
915 struct radv_device *device = cmd_buffer->device;
916 struct radv_meta_state *state = &device->meta_state;
917 uint64_t block_count = round_up_u64(size, 1024);
918 struct radv_meta_saved_state saved_state;
919
920 radv_meta_save(&saved_state, cmd_buffer,
921 RADV_META_SAVE_COMPUTE_PIPELINE |
922 RADV_META_SAVE_CONSTANTS |
923 RADV_META_SAVE_DESCRIPTORS);
924
925 struct radv_buffer dst_buffer = {
926 .bo = bo,
927 .offset = offset,
928 .size = size
929 };
930
931 radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer),
932 VK_PIPELINE_BIND_POINT_COMPUTE,
933 state->clear_htile_mask_pipeline);
934
935 radv_meta_push_descriptor_set(cmd_buffer, VK_PIPELINE_BIND_POINT_COMPUTE,
936 state->clear_htile_mask_p_layout,
937 0, /* set */
938 1, /* descriptorWriteCount */
939 (VkWriteDescriptorSet[]) {
940 {
941 .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
942 .dstBinding = 0,
943 .dstArrayElement = 0,
944 .descriptorCount = 1,
945 .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
946 .pBufferInfo = &(VkDescriptorBufferInfo) {
947 .buffer = radv_buffer_to_handle(&dst_buffer),
948 .offset = 0,
949 .range = size
950 }
951 }
952 });
953
954 const unsigned constants[2] = {
955 htile_value & htile_mask,
956 ~htile_mask,
957 };
958
959 radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
960 state->clear_htile_mask_p_layout,
961 VK_SHADER_STAGE_COMPUTE_BIT, 0, 8,
962 constants);
963
964 radv_CmdDispatch(radv_cmd_buffer_to_handle(cmd_buffer), block_count, 1, 1);
965
966 radv_meta_restore(&saved_state, cmd_buffer);
967
968 return RADV_CMD_FLAG_CS_PARTIAL_FLUSH |
969 RADV_CMD_FLAG_INV_VCACHE |
970 RADV_CMD_FLAG_WB_L2;
971 }
972
973 static uint32_t
974 radv_get_htile_fast_clear_value(const struct radv_image *image,
975 VkClearDepthStencilValue value)
976 {
977 uint32_t clear_value;
978
979 if (!image->planes[0].surface.has_stencil) {
980 clear_value = value.depth ? 0xfffffff0 : 0;
981 } else {
982 clear_value = value.depth ? 0xfffc0000 : 0;
983 }
984
985 return clear_value;
986 }
987
988 static uint32_t
989 radv_get_htile_mask(const struct radv_image *image, VkImageAspectFlags aspects)
990 {
991 uint32_t mask = 0;
992
993 if (!image->planes[0].surface.has_stencil) {
994 /* All the HTILE buffer is used when there is no stencil. */
995 mask = UINT32_MAX;
996 } else {
997 if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT)
998 mask |= 0xfffffc0f;
999 if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT)
1000 mask |= 0x000003f0;
1001 }
1002
1003 return mask;
1004 }
1005
1006 static bool
1007 radv_is_fast_clear_depth_allowed(VkClearDepthStencilValue value)
1008 {
1009 return value.depth == 1.0f || value.depth == 0.0f;
1010 }
1011
1012 static bool
1013 radv_is_fast_clear_stencil_allowed(VkClearDepthStencilValue value)
1014 {
1015 return value.stencil == 0;
1016 }
1017
1018 /**
1019 * Determine if the given image can be fast cleared.
1020 */
1021 static bool
1022 radv_image_can_fast_clear(struct radv_device *device, struct radv_image *image)
1023 {
1024 if (device->instance->debug_flags & RADV_DEBUG_NO_FAST_CLEARS)
1025 return false;
1026
1027 if (vk_format_is_color(image->vk_format)) {
1028 if (!radv_image_has_cmask(image) && !radv_image_has_dcc(image))
1029 return false;
1030
1031 /* RB+ doesn't work with CMASK fast clear on Stoney. */
1032 if (!radv_image_has_dcc(image) &&
1033 device->physical_device->rad_info.family == CHIP_STONEY)
1034 return false;
1035 } else {
1036 if (!radv_image_has_htile(image))
1037 return false;
1038 }
1039
1040 /* Do not fast clears 3D images. */
1041 if (image->type == VK_IMAGE_TYPE_3D)
1042 return false;
1043
1044 return true;
1045 }
1046
1047 /**
1048 * Determine if the given image view can be fast cleared.
1049 */
1050 static bool
1051 radv_image_view_can_fast_clear(struct radv_device *device,
1052 const struct radv_image_view *iview)
1053 {
1054 struct radv_image *image;
1055
1056 if (!iview)
1057 return false;
1058 image = iview->image;
1059
1060 /* Only fast clear if the image itself can be fast cleared. */
1061 if (!radv_image_can_fast_clear(device, image))
1062 return false;
1063
1064 /* Only fast clear if all layers are bound. */
1065 if (iview->base_layer > 0 ||
1066 iview->layer_count != image->info.array_size)
1067 return false;
1068
1069 /* Only fast clear if the view covers the whole image. */
1070 if (!radv_image_extent_compare(image, &iview->extent))
1071 return false;
1072
1073 return true;
1074 }
1075
1076 static bool
1077 radv_can_fast_clear_depth(struct radv_cmd_buffer *cmd_buffer,
1078 const struct radv_image_view *iview,
1079 VkImageLayout image_layout,
1080 bool in_render_loop,
1081 VkImageAspectFlags aspects,
1082 const VkClearRect *clear_rect,
1083 const VkClearDepthStencilValue clear_value,
1084 uint32_t view_mask)
1085 {
1086 if (!radv_image_view_can_fast_clear(cmd_buffer->device, iview))
1087 return false;
1088
1089 if (!radv_layout_is_htile_compressed(iview->image, image_layout, in_render_loop,
1090 radv_image_queue_family_mask(iview->image,
1091 cmd_buffer->queue_family_index,
1092 cmd_buffer->queue_family_index)))
1093 return false;
1094
1095 if (clear_rect->rect.offset.x || clear_rect->rect.offset.y ||
1096 clear_rect->rect.extent.width != iview->image->info.width ||
1097 clear_rect->rect.extent.height != iview->image->info.height)
1098 return false;
1099
1100 if (view_mask && (iview->image->info.array_size >= 32 ||
1101 (1u << iview->image->info.array_size) - 1u != view_mask))
1102 return false;
1103 if (!view_mask && clear_rect->baseArrayLayer != 0)
1104 return false;
1105 if (!view_mask && clear_rect->layerCount != iview->image->info.array_size)
1106 return false;
1107
1108 if (((aspects & VK_IMAGE_ASPECT_DEPTH_BIT) &&
1109 !radv_is_fast_clear_depth_allowed(clear_value)) ||
1110 ((aspects & VK_IMAGE_ASPECT_STENCIL_BIT) &&
1111 !radv_is_fast_clear_stencil_allowed(clear_value)))
1112 return false;
1113
1114 return true;
1115 }
1116
1117 static void
1118 radv_fast_clear_depth(struct radv_cmd_buffer *cmd_buffer,
1119 const struct radv_image_view *iview,
1120 const VkClearAttachment *clear_att,
1121 enum radv_cmd_flush_bits *pre_flush,
1122 enum radv_cmd_flush_bits *post_flush)
1123 {
1124 VkClearDepthStencilValue clear_value = clear_att->clearValue.depthStencil;
1125 VkImageAspectFlags aspects = clear_att->aspectMask;
1126 uint32_t clear_word, flush_bits;
1127
1128 clear_word = radv_get_htile_fast_clear_value(iview->image, clear_value);
1129
1130 if (pre_flush) {
1131 cmd_buffer->state.flush_bits |= (RADV_CMD_FLAG_FLUSH_AND_INV_DB |
1132 RADV_CMD_FLAG_FLUSH_AND_INV_DB_META) & ~ *pre_flush;
1133 *pre_flush |= cmd_buffer->state.flush_bits;
1134 }
1135
1136 struct VkImageSubresourceRange range = {
1137 .aspectMask = aspects,
1138 .baseMipLevel = 0,
1139 .levelCount = VK_REMAINING_MIP_LEVELS,
1140 .baseArrayLayer = 0,
1141 .layerCount = VK_REMAINING_ARRAY_LAYERS,
1142 };
1143
1144 flush_bits = radv_clear_htile(cmd_buffer, iview->image, &range, clear_word);
1145
1146 if (iview->image->planes[0].surface.has_stencil &&
1147 !(aspects == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))) {
1148 /* Synchronize after performing a depth-only or a stencil-only
1149 * fast clear because the driver uses an optimized path which
1150 * performs a read-modify-write operation, and the two separate
1151 * aspects might use the same HTILE memory.
1152 */
1153 cmd_buffer->state.flush_bits |= flush_bits;
1154 }
1155
1156 radv_update_ds_clear_metadata(cmd_buffer, iview, clear_value, aspects);
1157 if (post_flush) {
1158 *post_flush |= flush_bits;
1159 }
1160 }
1161
1162 static nir_shader *
1163 build_clear_htile_mask_shader()
1164 {
1165 nir_builder b;
1166
1167 nir_builder_init_simple_shader(&b, NULL, MESA_SHADER_COMPUTE, NULL);
1168 b.shader->info.name = ralloc_strdup(b.shader, "meta_clear_htile_mask");
1169 b.shader->info.cs.local_size[0] = 64;
1170 b.shader->info.cs.local_size[1] = 1;
1171 b.shader->info.cs.local_size[2] = 1;
1172
1173 nir_ssa_def *invoc_id = nir_load_local_invocation_id(&b);
1174 nir_ssa_def *wg_id = nir_load_work_group_id(&b);
1175 nir_ssa_def *block_size = nir_imm_ivec4(&b,
1176 b.shader->info.cs.local_size[0],
1177 b.shader->info.cs.local_size[1],
1178 b.shader->info.cs.local_size[2], 0);
1179
1180 nir_ssa_def *global_id = nir_iadd(&b, nir_imul(&b, wg_id, block_size), invoc_id);
1181
1182 nir_ssa_def *offset = nir_imul(&b, global_id, nir_imm_int(&b, 16));
1183 offset = nir_channel(&b, offset, 0);
1184
1185 nir_intrinsic_instr *buf =
1186 nir_intrinsic_instr_create(b.shader,
1187 nir_intrinsic_vulkan_resource_index);
1188
1189 buf->src[0] = nir_src_for_ssa(nir_imm_int(&b, 0));
1190 buf->num_components = 1;
1191 nir_intrinsic_set_desc_set(buf, 0);
1192 nir_intrinsic_set_binding(buf, 0);
1193 nir_ssa_dest_init(&buf->instr, &buf->dest, buf->num_components, 32, NULL);
1194 nir_builder_instr_insert(&b, &buf->instr);
1195
1196 nir_intrinsic_instr *constants =
1197 nir_intrinsic_instr_create(b.shader,
1198 nir_intrinsic_load_push_constant);
1199 nir_intrinsic_set_base(constants, 0);
1200 nir_intrinsic_set_range(constants, 8);
1201 constants->src[0] = nir_src_for_ssa(nir_imm_int(&b, 0));
1202 constants->num_components = 2;
1203 nir_ssa_dest_init(&constants->instr, &constants->dest, 2, 32, "constants");
1204 nir_builder_instr_insert(&b, &constants->instr);
1205
1206 nir_intrinsic_instr *load =
1207 nir_intrinsic_instr_create(b.shader, nir_intrinsic_load_ssbo);
1208 load->src[0] = nir_src_for_ssa(&buf->dest.ssa);
1209 load->src[1] = nir_src_for_ssa(offset);
1210 nir_ssa_dest_init(&load->instr, &load->dest, 4, 32, NULL);
1211 load->num_components = 4;
1212 nir_intrinsic_set_align(load, 16, 0);
1213 nir_builder_instr_insert(&b, &load->instr);
1214
1215 /* data = (data & ~htile_mask) | (htile_value & htile_mask) */
1216 nir_ssa_def *data =
1217 nir_iand(&b, &load->dest.ssa,
1218 nir_channel(&b, &constants->dest.ssa, 1));
1219 data = nir_ior(&b, data, nir_channel(&b, &constants->dest.ssa, 0));
1220
1221 nir_intrinsic_instr *store =
1222 nir_intrinsic_instr_create(b.shader, nir_intrinsic_store_ssbo);
1223 store->src[0] = nir_src_for_ssa(data);
1224 store->src[1] = nir_src_for_ssa(&buf->dest.ssa);
1225 store->src[2] = nir_src_for_ssa(offset);
1226 nir_intrinsic_set_write_mask(store, 0xf);
1227 nir_intrinsic_set_access(store, ACCESS_NON_READABLE);
1228 nir_intrinsic_set_align(store, 16, 0);
1229 store->num_components = 4;
1230 nir_builder_instr_insert(&b, &store->instr);
1231
1232 return b.shader;
1233 }
1234
1235 static VkResult
1236 init_meta_clear_htile_mask_state(struct radv_device *device)
1237 {
1238 struct radv_meta_state *state = &device->meta_state;
1239 struct radv_shader_module cs = { .nir = NULL };
1240 VkResult result;
1241
1242 cs.nir = build_clear_htile_mask_shader();
1243
1244 VkDescriptorSetLayoutCreateInfo ds_layout_info = {
1245 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1246 .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,
1247 .bindingCount = 1,
1248 .pBindings = (VkDescriptorSetLayoutBinding[]) {
1249 {
1250 .binding = 0,
1251 .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1252 .descriptorCount = 1,
1253 .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
1254 .pImmutableSamplers = NULL
1255 },
1256 }
1257 };
1258
1259 result = radv_CreateDescriptorSetLayout(radv_device_to_handle(device),
1260 &ds_layout_info, &state->alloc,
1261 &state->clear_htile_mask_ds_layout);
1262 if (result != VK_SUCCESS)
1263 goto fail;
1264
1265 VkPipelineLayoutCreateInfo p_layout_info = {
1266 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1267 .setLayoutCount = 1,
1268 .pSetLayouts = &state->clear_htile_mask_ds_layout,
1269 .pushConstantRangeCount = 1,
1270 .pPushConstantRanges = &(VkPushConstantRange){
1271 VK_SHADER_STAGE_COMPUTE_BIT, 0, 8,
1272 },
1273 };
1274
1275 result = radv_CreatePipelineLayout(radv_device_to_handle(device),
1276 &p_layout_info, &state->alloc,
1277 &state->clear_htile_mask_p_layout);
1278 if (result != VK_SUCCESS)
1279 goto fail;
1280
1281 VkPipelineShaderStageCreateInfo shader_stage = {
1282 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1283 .stage = VK_SHADER_STAGE_COMPUTE_BIT,
1284 .module = radv_shader_module_to_handle(&cs),
1285 .pName = "main",
1286 .pSpecializationInfo = NULL,
1287 };
1288
1289 VkComputePipelineCreateInfo pipeline_info = {
1290 .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
1291 .stage = shader_stage,
1292 .flags = 0,
1293 .layout = state->clear_htile_mask_p_layout,
1294 };
1295
1296 result = radv_CreateComputePipelines(radv_device_to_handle(device),
1297 radv_pipeline_cache_to_handle(&state->cache),
1298 1, &pipeline_info, NULL,
1299 &state->clear_htile_mask_pipeline);
1300
1301 ralloc_free(cs.nir);
1302 return result;
1303 fail:
1304 ralloc_free(cs.nir);
1305 return result;
1306 }
1307
1308 VkResult
1309 radv_device_init_meta_clear_state(struct radv_device *device, bool on_demand)
1310 {
1311 VkResult res;
1312 struct radv_meta_state *state = &device->meta_state;
1313
1314 VkPipelineLayoutCreateInfo pl_color_create_info = {
1315 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1316 .setLayoutCount = 0,
1317 .pushConstantRangeCount = 1,
1318 .pPushConstantRanges = &(VkPushConstantRange){VK_SHADER_STAGE_FRAGMENT_BIT, 0, 16},
1319 };
1320
1321 res = radv_CreatePipelineLayout(radv_device_to_handle(device),
1322 &pl_color_create_info,
1323 &device->meta_state.alloc,
1324 &device->meta_state.clear_color_p_layout);
1325 if (res != VK_SUCCESS)
1326 goto fail;
1327
1328 VkPipelineLayoutCreateInfo pl_depth_create_info = {
1329 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1330 .setLayoutCount = 0,
1331 .pushConstantRangeCount = 1,
1332 .pPushConstantRanges = &(VkPushConstantRange){VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
1333 };
1334
1335 res = radv_CreatePipelineLayout(radv_device_to_handle(device),
1336 &pl_depth_create_info,
1337 &device->meta_state.alloc,
1338 &device->meta_state.clear_depth_p_layout);
1339 if (res != VK_SUCCESS)
1340 goto fail;
1341
1342 VkPipelineLayoutCreateInfo pl_depth_unrestricted_create_info = {
1343 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1344 .setLayoutCount = 0,
1345 .pushConstantRangeCount = 1,
1346 .pPushConstantRanges = &(VkPushConstantRange){VK_SHADER_STAGE_FRAGMENT_BIT, 0, 4},
1347 };
1348
1349 res = radv_CreatePipelineLayout(radv_device_to_handle(device),
1350 &pl_depth_unrestricted_create_info,
1351 &device->meta_state.alloc,
1352 &device->meta_state.clear_depth_unrestricted_p_layout);
1353 if (res != VK_SUCCESS)
1354 goto fail;
1355
1356 res = init_meta_clear_htile_mask_state(device);
1357 if (res != VK_SUCCESS)
1358 goto fail;
1359
1360 if (on_demand)
1361 return VK_SUCCESS;
1362
1363 for (uint32_t i = 0; i < ARRAY_SIZE(state->clear); ++i) {
1364 uint32_t samples = 1 << i;
1365 for (uint32_t j = 0; j < NUM_META_FS_KEYS; ++j) {
1366 VkFormat format = radv_fs_key_format_exemplars[j];
1367 unsigned fs_key = radv_format_meta_fs_key(format);
1368 assert(!state->clear[i].color_pipelines[fs_key]);
1369
1370 res = create_color_renderpass(device, format, samples,
1371 &state->clear[i].render_pass[fs_key]);
1372 if (res != VK_SUCCESS)
1373 goto fail;
1374
1375 res = create_color_pipeline(device, samples, 0, &state->clear[i].color_pipelines[fs_key],
1376 state->clear[i].render_pass[fs_key]);
1377 if (res != VK_SUCCESS)
1378 goto fail;
1379
1380 }
1381
1382 res = create_depthstencil_renderpass(device,
1383 samples,
1384 &state->clear[i].depthstencil_rp);
1385 if (res != VK_SUCCESS)
1386 goto fail;
1387
1388 for (uint32_t j = 0; j < NUM_DEPTH_CLEAR_PIPELINES; j++) {
1389 res = create_depthstencil_pipeline(device,
1390 VK_IMAGE_ASPECT_DEPTH_BIT,
1391 samples,
1392 j,
1393 false,
1394 &state->clear[i].depth_only_pipeline[j],
1395 state->clear[i].depthstencil_rp);
1396 if (res != VK_SUCCESS)
1397 goto fail;
1398
1399 res = create_depthstencil_pipeline(device,
1400 VK_IMAGE_ASPECT_STENCIL_BIT,
1401 samples,
1402 j,
1403 false,
1404 &state->clear[i].stencil_only_pipeline[j],
1405 state->clear[i].depthstencil_rp);
1406 if (res != VK_SUCCESS)
1407 goto fail;
1408
1409 res = create_depthstencil_pipeline(device,
1410 VK_IMAGE_ASPECT_DEPTH_BIT |
1411 VK_IMAGE_ASPECT_STENCIL_BIT,
1412 samples,
1413 j,
1414 false,
1415 &state->clear[i].depthstencil_pipeline[j],
1416 state->clear[i].depthstencil_rp);
1417 if (res != VK_SUCCESS)
1418 goto fail;
1419
1420 res = create_depthstencil_pipeline(device,
1421 VK_IMAGE_ASPECT_DEPTH_BIT,
1422 samples,
1423 j,
1424 true,
1425 &state->clear[i].depth_only_unrestricted_pipeline[j],
1426 state->clear[i].depthstencil_rp);
1427 if (res != VK_SUCCESS)
1428 goto fail;
1429
1430 res = create_depthstencil_pipeline(device,
1431 VK_IMAGE_ASPECT_STENCIL_BIT,
1432 samples,
1433 j,
1434 true,
1435 &state->clear[i].stencil_only_unrestricted_pipeline[j],
1436 state->clear[i].depthstencil_rp);
1437 if (res != VK_SUCCESS)
1438 goto fail;
1439
1440 res = create_depthstencil_pipeline(device,
1441 VK_IMAGE_ASPECT_DEPTH_BIT |
1442 VK_IMAGE_ASPECT_STENCIL_BIT,
1443 samples,
1444 j,
1445 true,
1446 &state->clear[i].depthstencil_unrestricted_pipeline[j],
1447 state->clear[i].depthstencil_rp);
1448 if (res != VK_SUCCESS)
1449 goto fail;
1450 }
1451 }
1452 return VK_SUCCESS;
1453
1454 fail:
1455 radv_device_finish_meta_clear_state(device);
1456 return res;
1457 }
1458
1459 static uint32_t
1460 radv_get_cmask_fast_clear_value(const struct radv_image *image)
1461 {
1462 uint32_t value = 0; /* Default value when no DCC. */
1463
1464 /* The fast-clear value is different for images that have both DCC and
1465 * CMASK metadata.
1466 */
1467 if (radv_image_has_dcc(image)) {
1468 /* DCC fast clear with MSAA should clear CMASK to 0xC. */
1469 return image->info.samples > 1 ? 0xcccccccc : 0xffffffff;
1470 }
1471
1472 return value;
1473 }
1474
1475 uint32_t
1476 radv_clear_cmask(struct radv_cmd_buffer *cmd_buffer,
1477 struct radv_image *image,
1478 const VkImageSubresourceRange *range, uint32_t value)
1479 {
1480 uint64_t offset = image->offset + image->cmask_offset;
1481 uint64_t size;
1482
1483 if (cmd_buffer->device->physical_device->rad_info.chip_class >= GFX9) {
1484 /* TODO: clear layers. */
1485 size = image->planes[0].surface.cmask_size;
1486 } else {
1487 unsigned cmask_slice_size =
1488 image->planes[0].surface.cmask_slice_size;
1489
1490 offset += cmask_slice_size * range->baseArrayLayer;
1491 size = cmask_slice_size * radv_get_layerCount(image, range);
1492 }
1493
1494 return radv_fill_buffer(cmd_buffer, image->bo, offset, size, value);
1495 }
1496
1497
1498 uint32_t
1499 radv_clear_fmask(struct radv_cmd_buffer *cmd_buffer,
1500 struct radv_image *image,
1501 const VkImageSubresourceRange *range, uint32_t value)
1502 {
1503 uint64_t offset = image->offset + image->fmask_offset;
1504 uint64_t size;
1505
1506 /* MSAA images do not support mipmap levels. */
1507 assert(range->baseMipLevel == 0 &&
1508 radv_get_levelCount(image, range) == 1);
1509
1510 if (cmd_buffer->device->physical_device->rad_info.chip_class >= GFX9) {
1511 /* TODO: clear layers. */
1512 size = image->planes[0].surface.fmask_size;
1513 } else {
1514 unsigned fmask_slice_size =
1515 image->planes[0].surface.u.legacy.fmask.slice_size;
1516
1517
1518 offset += fmask_slice_size * range->baseArrayLayer;
1519 size = fmask_slice_size * radv_get_layerCount(image, range);
1520 }
1521
1522 return radv_fill_buffer(cmd_buffer, image->bo, offset, size, value);
1523 }
1524
1525 uint32_t
1526 radv_clear_dcc(struct radv_cmd_buffer *cmd_buffer,
1527 struct radv_image *image,
1528 const VkImageSubresourceRange *range, uint32_t value)
1529 {
1530 uint32_t level_count = radv_get_levelCount(image, range);
1531 uint32_t flush_bits = 0;
1532
1533 /* Mark the image as being compressed. */
1534 radv_update_dcc_metadata(cmd_buffer, image, range, true);
1535
1536 for (uint32_t l = 0; l < level_count; l++) {
1537 uint64_t offset = image->offset + image->dcc_offset;
1538 uint32_t level = range->baseMipLevel + l;
1539 uint64_t size;
1540
1541 if (cmd_buffer->device->physical_device->rad_info.chip_class >= GFX9) {
1542 /* Mipmap levels aren't implemented. */
1543 assert(level == 0);
1544 size = image->planes[0].surface.dcc_size;
1545 } else {
1546 const struct legacy_surf_level *surf_level =
1547 &image->planes[0].surface.u.legacy.level[level];
1548
1549 /* If dcc_fast_clear_size is 0 (which might happens for
1550 * mipmaps) the fill buffer operation below is a no-op.
1551 * This can only happen during initialization as the
1552 * fast clear path fallbacks to slow clears if one
1553 * level can't be fast cleared.
1554 */
1555 offset += surf_level->dcc_offset +
1556 surf_level->dcc_slice_fast_clear_size * range->baseArrayLayer;
1557 size = surf_level->dcc_slice_fast_clear_size * radv_get_layerCount(image, range);
1558 }
1559
1560 flush_bits |= radv_fill_buffer(cmd_buffer, image->bo, offset,
1561 size, value);
1562 }
1563
1564 return flush_bits;
1565 }
1566
1567 uint32_t
1568 radv_clear_htile(struct radv_cmd_buffer *cmd_buffer,
1569 const struct radv_image *image,
1570 const VkImageSubresourceRange *range,
1571 uint32_t value)
1572 {
1573 unsigned layer_count = radv_get_layerCount(image, range);
1574 uint64_t size = image->planes[0].surface.htile_slice_size * layer_count;
1575 uint64_t offset = image->offset + image->htile_offset +
1576 image->planes[0].surface.htile_slice_size * range->baseArrayLayer;
1577 uint32_t htile_mask, flush_bits;
1578
1579 htile_mask = radv_get_htile_mask(image, range->aspectMask);
1580
1581 if (htile_mask == UINT_MAX) {
1582 /* Clear the whole HTILE buffer. */
1583 flush_bits = radv_fill_buffer(cmd_buffer, image->bo, offset,
1584 size, value);
1585 } else {
1586 /* Only clear depth or stencil bytes in the HTILE buffer. */
1587 flush_bits = clear_htile_mask(cmd_buffer, image->bo, offset,
1588 size, value, htile_mask);
1589 }
1590
1591 return flush_bits;
1592 }
1593
1594 enum {
1595 RADV_DCC_CLEAR_REG = 0x20202020U,
1596 RADV_DCC_CLEAR_MAIN_1 = 0x80808080U,
1597 RADV_DCC_CLEAR_SECONDARY_1 = 0x40404040U
1598 };
1599
1600 static void vi_get_fast_clear_parameters(struct radv_device *device,
1601 VkFormat image_format,
1602 VkFormat view_format,
1603 const VkClearColorValue *clear_value,
1604 uint32_t* reset_value,
1605 bool *can_avoid_fast_clear_elim)
1606 {
1607 bool values[4] = {};
1608 int extra_channel;
1609 bool main_value = false;
1610 bool extra_value = false;
1611 bool has_color = false;
1612 bool has_alpha = false;
1613 int i;
1614 *can_avoid_fast_clear_elim = false;
1615
1616 *reset_value = RADV_DCC_CLEAR_REG;
1617
1618 const struct vk_format_description *desc = vk_format_description(view_format);
1619 if (view_format == VK_FORMAT_B10G11R11_UFLOAT_PACK32 ||
1620 view_format == VK_FORMAT_R5G6B5_UNORM_PACK16 ||
1621 view_format == VK_FORMAT_B5G6R5_UNORM_PACK16)
1622 extra_channel = -1;
1623 else if (desc->layout == VK_FORMAT_LAYOUT_PLAIN) {
1624 if (vi_alpha_is_on_msb(device, view_format))
1625 extra_channel = desc->nr_channels - 1;
1626 else
1627 extra_channel = 0;
1628 } else
1629 return;
1630
1631 for (i = 0; i < 4; i++) {
1632 int index = desc->swizzle[i] - VK_SWIZZLE_X;
1633 if (desc->swizzle[i] < VK_SWIZZLE_X ||
1634 desc->swizzle[i] > VK_SWIZZLE_W)
1635 continue;
1636
1637 if (desc->channel[i].pure_integer &&
1638 desc->channel[i].type == VK_FORMAT_TYPE_SIGNED) {
1639 /* Use the maximum value for clamping the clear color. */
1640 int max = u_bit_consecutive(0, desc->channel[i].size - 1);
1641
1642 values[i] = clear_value->int32[i] != 0;
1643 if (clear_value->int32[i] != 0 && MIN2(clear_value->int32[i], max) != max)
1644 return;
1645 } else if (desc->channel[i].pure_integer &&
1646 desc->channel[i].type == VK_FORMAT_TYPE_UNSIGNED) {
1647 /* Use the maximum value for clamping the clear color. */
1648 unsigned max = u_bit_consecutive(0, desc->channel[i].size);
1649
1650 values[i] = clear_value->uint32[i] != 0U;
1651 if (clear_value->uint32[i] != 0U && MIN2(clear_value->uint32[i], max) != max)
1652 return;
1653 } else {
1654 values[i] = clear_value->float32[i] != 0.0F;
1655 if (clear_value->float32[i] != 0.0F && clear_value->float32[i] != 1.0F)
1656 return;
1657 }
1658
1659 if (index == extra_channel) {
1660 extra_value = values[i];
1661 has_alpha = true;
1662 } else {
1663 main_value = values[i];
1664 has_color = true;
1665 }
1666 }
1667
1668 /* If alpha isn't present, make it the same as color, and vice versa. */
1669 if (!has_alpha)
1670 extra_value = main_value;
1671 else if (!has_color)
1672 main_value = extra_value;
1673
1674 for (int i = 0; i < 4; ++i)
1675 if (values[i] != main_value &&
1676 desc->swizzle[i] - VK_SWIZZLE_X != extra_channel &&
1677 desc->swizzle[i] >= VK_SWIZZLE_X &&
1678 desc->swizzle[i] <= VK_SWIZZLE_W)
1679 return;
1680
1681 *can_avoid_fast_clear_elim = true;
1682 *reset_value = 0;
1683 if (main_value)
1684 *reset_value |= RADV_DCC_CLEAR_MAIN_1;
1685
1686 if (extra_value)
1687 *reset_value |= RADV_DCC_CLEAR_SECONDARY_1;
1688 return;
1689 }
1690
1691 static bool
1692 radv_can_fast_clear_color(struct radv_cmd_buffer *cmd_buffer,
1693 const struct radv_image_view *iview,
1694 VkImageLayout image_layout,
1695 bool in_render_loop,
1696 const VkClearRect *clear_rect,
1697 VkClearColorValue clear_value,
1698 uint32_t view_mask)
1699 {
1700 uint32_t clear_color[2];
1701
1702 if (!radv_image_view_can_fast_clear(cmd_buffer->device, iview))
1703 return false;
1704
1705 if (!radv_layout_can_fast_clear(iview->image, image_layout, in_render_loop,
1706 radv_image_queue_family_mask(iview->image,
1707 cmd_buffer->queue_family_index,
1708 cmd_buffer->queue_family_index)))
1709 return false;
1710
1711 if (clear_rect->rect.offset.x || clear_rect->rect.offset.y ||
1712 clear_rect->rect.extent.width != iview->image->info.width ||
1713 clear_rect->rect.extent.height != iview->image->info.height)
1714 return false;
1715
1716 if (view_mask && (iview->image->info.array_size >= 32 ||
1717 (1u << iview->image->info.array_size) - 1u != view_mask))
1718 return false;
1719 if (!view_mask && clear_rect->baseArrayLayer != 0)
1720 return false;
1721 if (!view_mask && clear_rect->layerCount != iview->image->info.array_size)
1722 return false;
1723
1724 /* DCC */
1725 if (!radv_format_pack_clear_color(iview->vk_format,
1726 clear_color, &clear_value))
1727 return false;
1728
1729 if (radv_dcc_enabled(iview->image, iview->base_mip)) {
1730 bool can_avoid_fast_clear_elim;
1731 uint32_t reset_value;
1732
1733 vi_get_fast_clear_parameters(cmd_buffer->device,
1734 iview->image->vk_format,
1735 iview->vk_format,
1736 &clear_value, &reset_value,
1737 &can_avoid_fast_clear_elim);
1738
1739 if (iview->image->info.samples > 1) {
1740 /* DCC fast clear with MSAA should clear CMASK. */
1741 /* FIXME: This doesn't work for now. There is a
1742 * hardware bug with fast clears and DCC for MSAA
1743 * textures. AMDVLK has a workaround but it doesn't
1744 * seem to work here. Note that we might emit useless
1745 * CB flushes but that shouldn't matter.
1746 */
1747 if (!can_avoid_fast_clear_elim)
1748 return false;
1749 }
1750
1751 if (iview->image->info.levels > 1 &&
1752 cmd_buffer->device->physical_device->rad_info.chip_class == GFX8) {
1753 for (uint32_t l = 0; l < iview->level_count; l++) {
1754 uint32_t level = iview->base_mip + l;
1755 struct legacy_surf_level *surf_level =
1756 &iview->image->planes[0].surface.u.legacy.level[level];
1757
1758 /* Do not fast clears if one level can't be
1759 * fast cleared.
1760 */
1761 if (!surf_level->dcc_fast_clear_size)
1762 return false;
1763 }
1764 }
1765 }
1766
1767 return true;
1768 }
1769
1770
1771 static void
1772 radv_fast_clear_color(struct radv_cmd_buffer *cmd_buffer,
1773 const struct radv_image_view *iview,
1774 const VkClearAttachment *clear_att,
1775 uint32_t subpass_att,
1776 enum radv_cmd_flush_bits *pre_flush,
1777 enum radv_cmd_flush_bits *post_flush)
1778 {
1779 VkClearColorValue clear_value = clear_att->clearValue.color;
1780 uint32_t clear_color[2], flush_bits = 0;
1781 uint32_t cmask_clear_value;
1782 VkImageSubresourceRange range = {
1783 .aspectMask = iview->aspect_mask,
1784 .baseMipLevel = iview->base_mip,
1785 .levelCount = iview->level_count,
1786 .baseArrayLayer = iview->base_layer,
1787 .layerCount = iview->layer_count,
1788 };
1789
1790 if (pre_flush) {
1791 cmd_buffer->state.flush_bits |= (RADV_CMD_FLAG_FLUSH_AND_INV_CB |
1792 RADV_CMD_FLAG_FLUSH_AND_INV_CB_META) & ~ *pre_flush;
1793 *pre_flush |= cmd_buffer->state.flush_bits;
1794 }
1795
1796 /* DCC */
1797 radv_format_pack_clear_color(iview->vk_format, clear_color, &clear_value);
1798
1799 cmask_clear_value = radv_get_cmask_fast_clear_value(iview->image);
1800
1801 /* clear cmask buffer */
1802 if (radv_dcc_enabled(iview->image, iview->base_mip)) {
1803 uint32_t reset_value;
1804 bool can_avoid_fast_clear_elim;
1805 bool need_decompress_pass = false;
1806
1807 vi_get_fast_clear_parameters(cmd_buffer->device,
1808 iview->image->vk_format,
1809 iview->vk_format,
1810 &clear_value, &reset_value,
1811 &can_avoid_fast_clear_elim);
1812
1813 if (radv_image_has_cmask(iview->image)) {
1814 flush_bits = radv_clear_cmask(cmd_buffer, iview->image,
1815 &range, cmask_clear_value);
1816
1817 need_decompress_pass = true;
1818 }
1819
1820 if (!can_avoid_fast_clear_elim)
1821 need_decompress_pass = true;
1822
1823 flush_bits |= radv_clear_dcc(cmd_buffer, iview->image, &range,
1824 reset_value);
1825
1826 radv_update_fce_metadata(cmd_buffer, iview->image, &range,
1827 need_decompress_pass);
1828 } else {
1829 flush_bits = radv_clear_cmask(cmd_buffer, iview->image,
1830 &range, cmask_clear_value);
1831 }
1832
1833 if (post_flush) {
1834 *post_flush |= flush_bits;
1835 }
1836
1837 radv_update_color_clear_metadata(cmd_buffer, iview, subpass_att,
1838 clear_color);
1839 }
1840
1841 /**
1842 * The parameters mean that same as those in vkCmdClearAttachments.
1843 */
1844 static void
1845 emit_clear(struct radv_cmd_buffer *cmd_buffer,
1846 const VkClearAttachment *clear_att,
1847 const VkClearRect *clear_rect,
1848 enum radv_cmd_flush_bits *pre_flush,
1849 enum radv_cmd_flush_bits *post_flush,
1850 uint32_t view_mask,
1851 bool ds_resolve_clear)
1852 {
1853 const struct radv_framebuffer *fb = cmd_buffer->state.framebuffer;
1854 const struct radv_subpass *subpass = cmd_buffer->state.subpass;
1855 VkImageAspectFlags aspects = clear_att->aspectMask;
1856
1857 if (aspects & VK_IMAGE_ASPECT_COLOR_BIT) {
1858 const uint32_t subpass_att = clear_att->colorAttachment;
1859 assert(subpass_att < subpass->color_count);
1860 const uint32_t pass_att = subpass->color_attachments[subpass_att].attachment;
1861 if (pass_att == VK_ATTACHMENT_UNUSED)
1862 return;
1863
1864 VkImageLayout image_layout = subpass->color_attachments[subpass_att].layout;
1865 bool in_render_loop = subpass->color_attachments[subpass_att].in_render_loop;
1866 const struct radv_image_view *iview = fb ? cmd_buffer->state.attachments[pass_att].iview : NULL;
1867 VkClearColorValue clear_value = clear_att->clearValue.color;
1868
1869 if (radv_can_fast_clear_color(cmd_buffer, iview, image_layout, in_render_loop,
1870 clear_rect, clear_value, view_mask)) {
1871 radv_fast_clear_color(cmd_buffer, iview, clear_att,
1872 subpass_att, pre_flush,
1873 post_flush);
1874 } else {
1875 emit_color_clear(cmd_buffer, clear_att, clear_rect, view_mask);
1876 }
1877 } else {
1878 struct radv_subpass_attachment *ds_att = subpass->depth_stencil_attachment;
1879
1880 if (ds_resolve_clear)
1881 ds_att = subpass->ds_resolve_attachment;
1882
1883 if (!ds_att || ds_att->attachment == VK_ATTACHMENT_UNUSED)
1884 return;
1885
1886 VkImageLayout image_layout = ds_att->layout;
1887 bool in_render_loop = ds_att->in_render_loop;
1888 const struct radv_image_view *iview = fb ? cmd_buffer->state.attachments[ds_att->attachment].iview : NULL;
1889 VkClearDepthStencilValue clear_value = clear_att->clearValue.depthStencil;
1890
1891 assert(aspects & (VK_IMAGE_ASPECT_DEPTH_BIT |
1892 VK_IMAGE_ASPECT_STENCIL_BIT));
1893
1894 if (radv_can_fast_clear_depth(cmd_buffer, iview, image_layout,
1895 in_render_loop, aspects, clear_rect,
1896 clear_value, view_mask)) {
1897 radv_fast_clear_depth(cmd_buffer, iview, clear_att,
1898 pre_flush, post_flush);
1899 } else {
1900 emit_depthstencil_clear(cmd_buffer, clear_att, clear_rect,
1901 ds_att, view_mask);
1902 }
1903 }
1904 }
1905
1906 static inline bool
1907 radv_attachment_needs_clear(struct radv_cmd_state *cmd_state, uint32_t a)
1908 {
1909 uint32_t view_mask = cmd_state->subpass->view_mask;
1910 return (a != VK_ATTACHMENT_UNUSED &&
1911 cmd_state->attachments[a].pending_clear_aspects &&
1912 (!view_mask || (view_mask & ~cmd_state->attachments[a].cleared_views)));
1913 }
1914
1915 static bool
1916 radv_subpass_needs_clear(struct radv_cmd_buffer *cmd_buffer)
1917 {
1918 struct radv_cmd_state *cmd_state = &cmd_buffer->state;
1919 uint32_t a;
1920
1921 if (!cmd_state->subpass)
1922 return false;
1923
1924 for (uint32_t i = 0; i < cmd_state->subpass->color_count; ++i) {
1925 a = cmd_state->subpass->color_attachments[i].attachment;
1926 if (radv_attachment_needs_clear(cmd_state, a))
1927 return true;
1928 }
1929
1930 if (cmd_state->subpass->depth_stencil_attachment) {
1931 a = cmd_state->subpass->depth_stencil_attachment->attachment;
1932 if (radv_attachment_needs_clear(cmd_state, a))
1933 return true;
1934 }
1935
1936 if (!cmd_state->subpass->ds_resolve_attachment)
1937 return false;
1938
1939 a = cmd_state->subpass->ds_resolve_attachment->attachment;
1940 return radv_attachment_needs_clear(cmd_state, a);
1941 }
1942
1943 static void
1944 radv_subpass_clear_attachment(struct radv_cmd_buffer *cmd_buffer,
1945 struct radv_attachment_state *attachment,
1946 const VkClearAttachment *clear_att,
1947 enum radv_cmd_flush_bits *pre_flush,
1948 enum radv_cmd_flush_bits *post_flush,
1949 bool ds_resolve_clear)
1950 {
1951 struct radv_cmd_state *cmd_state = &cmd_buffer->state;
1952 uint32_t view_mask = cmd_state->subpass->view_mask;
1953
1954 VkClearRect clear_rect = {
1955 .rect = cmd_state->render_area,
1956 .baseArrayLayer = 0,
1957 .layerCount = cmd_state->framebuffer->layers,
1958 };
1959
1960 radv_describe_begin_render_pass_clear(cmd_buffer, clear_att->aspectMask);
1961
1962 emit_clear(cmd_buffer, clear_att, &clear_rect, pre_flush, post_flush,
1963 view_mask & ~attachment->cleared_views, ds_resolve_clear);
1964 if (view_mask)
1965 attachment->cleared_views |= view_mask;
1966 else
1967 attachment->pending_clear_aspects = 0;
1968
1969 radv_describe_end_render_pass_clear(cmd_buffer);
1970 }
1971
1972 /**
1973 * Emit any pending attachment clears for the current subpass.
1974 *
1975 * @see radv_attachment_state::pending_clear_aspects
1976 */
1977 void
1978 radv_cmd_buffer_clear_subpass(struct radv_cmd_buffer *cmd_buffer)
1979 {
1980 struct radv_cmd_state *cmd_state = &cmd_buffer->state;
1981 struct radv_meta_saved_state saved_state;
1982 enum radv_cmd_flush_bits pre_flush = 0;
1983 enum radv_cmd_flush_bits post_flush = 0;
1984
1985 if (!radv_subpass_needs_clear(cmd_buffer))
1986 return;
1987
1988 radv_meta_save(&saved_state, cmd_buffer,
1989 RADV_META_SAVE_GRAPHICS_PIPELINE |
1990 RADV_META_SAVE_CONSTANTS);
1991
1992 for (uint32_t i = 0; i < cmd_state->subpass->color_count; ++i) {
1993 uint32_t a = cmd_state->subpass->color_attachments[i].attachment;
1994
1995 if (!radv_attachment_needs_clear(cmd_state, a))
1996 continue;
1997
1998 assert(cmd_state->attachments[a].pending_clear_aspects ==
1999 VK_IMAGE_ASPECT_COLOR_BIT);
2000
2001 VkClearAttachment clear_att = {
2002 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
2003 .colorAttachment = i, /* Use attachment index relative to subpass */
2004 .clearValue = cmd_state->attachments[a].clear_value,
2005 };
2006
2007 radv_subpass_clear_attachment(cmd_buffer,
2008 &cmd_state->attachments[a],
2009 &clear_att, &pre_flush,
2010 &post_flush, false);
2011 }
2012
2013 if (cmd_state->subpass->depth_stencil_attachment) {
2014 uint32_t ds = cmd_state->subpass->depth_stencil_attachment->attachment;
2015 if (radv_attachment_needs_clear(cmd_state, ds)) {
2016 VkClearAttachment clear_att = {
2017 .aspectMask = cmd_state->attachments[ds].pending_clear_aspects,
2018 .clearValue = cmd_state->attachments[ds].clear_value,
2019 };
2020
2021 radv_subpass_clear_attachment(cmd_buffer,
2022 &cmd_state->attachments[ds],
2023 &clear_att, &pre_flush,
2024 &post_flush, false);
2025 }
2026 }
2027
2028 if (cmd_state->subpass->ds_resolve_attachment) {
2029 uint32_t ds_resolve = cmd_state->subpass->ds_resolve_attachment->attachment;
2030 if (radv_attachment_needs_clear(cmd_state, ds_resolve)) {
2031 VkClearAttachment clear_att = {
2032 .aspectMask = cmd_state->attachments[ds_resolve].pending_clear_aspects,
2033 .clearValue = cmd_state->attachments[ds_resolve].clear_value,
2034 };
2035
2036 radv_subpass_clear_attachment(cmd_buffer,
2037 &cmd_state->attachments[ds_resolve],
2038 &clear_att, &pre_flush,
2039 &post_flush, true);
2040 }
2041 }
2042
2043 radv_meta_restore(&saved_state, cmd_buffer);
2044 cmd_buffer->state.flush_bits |= post_flush;
2045 }
2046
2047 static void
2048 radv_clear_image_layer(struct radv_cmd_buffer *cmd_buffer,
2049 struct radv_image *image,
2050 VkImageLayout image_layout,
2051 const VkImageSubresourceRange *range,
2052 VkFormat format, int level, int layer,
2053 const VkClearValue *clear_val)
2054 {
2055 VkDevice device_h = radv_device_to_handle(cmd_buffer->device);
2056 struct radv_image_view iview;
2057 uint32_t width = radv_minify(image->info.width, range->baseMipLevel + level);
2058 uint32_t height = radv_minify(image->info.height, range->baseMipLevel + level);
2059
2060 radv_image_view_init(&iview, cmd_buffer->device,
2061 &(VkImageViewCreateInfo) {
2062 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
2063 .image = radv_image_to_handle(image),
2064 .viewType = radv_meta_get_view_type(image),
2065 .format = format,
2066 .subresourceRange = {
2067 .aspectMask = range->aspectMask,
2068 .baseMipLevel = range->baseMipLevel + level,
2069 .levelCount = 1,
2070 .baseArrayLayer = range->baseArrayLayer + layer,
2071 .layerCount = 1
2072 },
2073 }, NULL);
2074
2075 VkFramebuffer fb;
2076 radv_CreateFramebuffer(device_h,
2077 &(VkFramebufferCreateInfo) {
2078 .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
2079 .attachmentCount = 1,
2080 .pAttachments = (VkImageView[]) {
2081 radv_image_view_to_handle(&iview),
2082 },
2083 .width = width,
2084 .height = height,
2085 .layers = 1
2086 },
2087 &cmd_buffer->pool->alloc,
2088 &fb);
2089
2090 VkAttachmentDescription att_desc = {
2091 .format = iview.vk_format,
2092 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
2093 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
2094 .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
2095 .stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE,
2096 .initialLayout = image_layout,
2097 .finalLayout = image_layout,
2098 };
2099
2100 VkSubpassDescription subpass_desc = {
2101 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
2102 .inputAttachmentCount = 0,
2103 .colorAttachmentCount = 0,
2104 .pColorAttachments = NULL,
2105 .pResolveAttachments = NULL,
2106 .pDepthStencilAttachment = NULL,
2107 .preserveAttachmentCount = 0,
2108 .pPreserveAttachments = NULL,
2109 };
2110
2111 const VkAttachmentReference att_ref = {
2112 .attachment = 0,
2113 .layout = image_layout,
2114 };
2115
2116 if (range->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
2117 subpass_desc.colorAttachmentCount = 1;
2118 subpass_desc.pColorAttachments = &att_ref;
2119 } else {
2120 subpass_desc.pDepthStencilAttachment = &att_ref;
2121 }
2122
2123 VkRenderPass pass;
2124 radv_CreateRenderPass(device_h,
2125 &(VkRenderPassCreateInfo) {
2126 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
2127 .attachmentCount = 1,
2128 .pAttachments = &att_desc,
2129 .subpassCount = 1,
2130 .pSubpasses = &subpass_desc,
2131 .dependencyCount = 2,
2132 .pDependencies = (VkSubpassDependency[]) {
2133 {
2134 .srcSubpass = VK_SUBPASS_EXTERNAL,
2135 .dstSubpass = 0,
2136 .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
2137 .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
2138 .srcAccessMask = 0,
2139 .dstAccessMask = 0,
2140 .dependencyFlags = 0
2141 },
2142 {
2143 .srcSubpass = 0,
2144 .dstSubpass = VK_SUBPASS_EXTERNAL,
2145 .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
2146 .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
2147 .srcAccessMask = 0,
2148 .dstAccessMask = 0,
2149 .dependencyFlags = 0
2150 }
2151 }
2152 },
2153 &cmd_buffer->pool->alloc,
2154 &pass);
2155
2156 radv_cmd_buffer_begin_render_pass(cmd_buffer,
2157 &(VkRenderPassBeginInfo) {
2158 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
2159 .renderArea = {
2160 .offset = { 0, 0, },
2161 .extent = {
2162 .width = width,
2163 .height = height,
2164 },
2165 },
2166 .renderPass = pass,
2167 .framebuffer = fb,
2168 .clearValueCount = 0,
2169 .pClearValues = NULL,
2170 });
2171
2172 radv_cmd_buffer_set_subpass(cmd_buffer,
2173 &cmd_buffer->state.pass->subpasses[0]);
2174
2175 VkClearAttachment clear_att = {
2176 .aspectMask = range->aspectMask,
2177 .colorAttachment = 0,
2178 .clearValue = *clear_val,
2179 };
2180
2181 VkClearRect clear_rect = {
2182 .rect = {
2183 .offset = { 0, 0 },
2184 .extent = { width, height },
2185 },
2186 .baseArrayLayer = range->baseArrayLayer,
2187 .layerCount = 1, /* FINISHME: clear multi-layer framebuffer */
2188 };
2189
2190 emit_clear(cmd_buffer, &clear_att, &clear_rect, NULL, NULL, 0, false);
2191
2192 radv_cmd_buffer_end_render_pass(cmd_buffer);
2193 radv_DestroyRenderPass(device_h, pass,
2194 &cmd_buffer->pool->alloc);
2195 radv_DestroyFramebuffer(device_h, fb,
2196 &cmd_buffer->pool->alloc);
2197 }
2198
2199 /**
2200 * Return TRUE if a fast color or depth clear has been performed.
2201 */
2202 static bool
2203 radv_fast_clear_range(struct radv_cmd_buffer *cmd_buffer,
2204 struct radv_image *image,
2205 VkFormat format,
2206 VkImageLayout image_layout,
2207 bool in_render_loop,
2208 const VkImageSubresourceRange *range,
2209 const VkClearValue *clear_val)
2210 {
2211 struct radv_image_view iview;
2212
2213 radv_image_view_init(&iview, cmd_buffer->device,
2214 &(VkImageViewCreateInfo) {
2215 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
2216 .image = radv_image_to_handle(image),
2217 .viewType = radv_meta_get_view_type(image),
2218 .format = image->vk_format,
2219 .subresourceRange = {
2220 .aspectMask = range->aspectMask,
2221 .baseMipLevel = range->baseMipLevel,
2222 .levelCount = range->levelCount,
2223 .baseArrayLayer = range->baseArrayLayer,
2224 .layerCount = range->layerCount,
2225 },
2226 }, NULL);
2227
2228 VkClearRect clear_rect = {
2229 .rect = {
2230 .offset = { 0, 0 },
2231 .extent = {
2232 radv_minify(image->info.width, range->baseMipLevel),
2233 radv_minify(image->info.height, range->baseMipLevel),
2234 },
2235 },
2236 .baseArrayLayer = range->baseArrayLayer,
2237 .layerCount = range->layerCount,
2238 };
2239
2240 VkClearAttachment clear_att = {
2241 .aspectMask = range->aspectMask,
2242 .colorAttachment = 0,
2243 .clearValue = *clear_val,
2244 };
2245
2246 if (vk_format_is_color(format)) {
2247 if (radv_can_fast_clear_color(cmd_buffer, &iview, image_layout,
2248 in_render_loop, &clear_rect,
2249 clear_att.clearValue.color, 0)) {
2250 radv_fast_clear_color(cmd_buffer, &iview, &clear_att,
2251 clear_att.colorAttachment,
2252 NULL, NULL);
2253 return true;
2254 }
2255 } else {
2256 if (radv_can_fast_clear_depth(cmd_buffer, &iview, image_layout,
2257 in_render_loop,range->aspectMask,
2258 &clear_rect, clear_att.clearValue.depthStencil,
2259 0)) {
2260 radv_fast_clear_depth(cmd_buffer, &iview, &clear_att,
2261 NULL, NULL);
2262 return true;
2263 }
2264 }
2265
2266 return false;
2267 }
2268
2269 static void
2270 radv_cmd_clear_image(struct radv_cmd_buffer *cmd_buffer,
2271 struct radv_image *image,
2272 VkImageLayout image_layout,
2273 const VkClearValue *clear_value,
2274 uint32_t range_count,
2275 const VkImageSubresourceRange *ranges,
2276 bool cs)
2277 {
2278 VkFormat format = image->vk_format;
2279 VkClearValue internal_clear_value = *clear_value;
2280
2281 if (format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) {
2282 uint32_t value;
2283 format = VK_FORMAT_R32_UINT;
2284 value = float3_to_rgb9e5(clear_value->color.float32);
2285 internal_clear_value.color.uint32[0] = value;
2286 }
2287
2288 if (format == VK_FORMAT_R4G4_UNORM_PACK8) {
2289 uint8_t r, g;
2290 format = VK_FORMAT_R8_UINT;
2291 r = float_to_ubyte(clear_value->color.float32[0]) >> 4;
2292 g = float_to_ubyte(clear_value->color.float32[1]) >> 4;
2293 internal_clear_value.color.uint32[0] = (r << 4) | (g & 0xf);
2294 }
2295
2296 if (format == VK_FORMAT_R32G32B32_UINT ||
2297 format == VK_FORMAT_R32G32B32_SINT ||
2298 format == VK_FORMAT_R32G32B32_SFLOAT)
2299 cs = true;
2300
2301 for (uint32_t r = 0; r < range_count; r++) {
2302 const VkImageSubresourceRange *range = &ranges[r];
2303
2304 /* Try to perform a fast clear first, otherwise fallback to
2305 * the legacy path.
2306 */
2307 if (!cs &&
2308 radv_fast_clear_range(cmd_buffer, image, format,
2309 image_layout, false, range,
2310 &internal_clear_value)) {
2311 continue;
2312 }
2313
2314 for (uint32_t l = 0; l < radv_get_levelCount(image, range); ++l) {
2315 const uint32_t layer_count = image->type == VK_IMAGE_TYPE_3D ?
2316 radv_minify(image->info.depth, range->baseMipLevel + l) :
2317 radv_get_layerCount(image, range);
2318 for (uint32_t s = 0; s < layer_count; ++s) {
2319
2320 if (cs) {
2321 struct radv_meta_blit2d_surf surf;
2322 surf.format = format;
2323 surf.image = image;
2324 surf.level = range->baseMipLevel + l;
2325 surf.layer = range->baseArrayLayer + s;
2326 surf.aspect_mask = range->aspectMask;
2327 radv_meta_clear_image_cs(cmd_buffer, &surf,
2328 &internal_clear_value.color);
2329 } else {
2330 radv_clear_image_layer(cmd_buffer, image, image_layout,
2331 range, format, l, s, &internal_clear_value);
2332 }
2333 }
2334 }
2335 }
2336 }
2337
2338 void radv_CmdClearColorImage(
2339 VkCommandBuffer commandBuffer,
2340 VkImage image_h,
2341 VkImageLayout imageLayout,
2342 const VkClearColorValue* pColor,
2343 uint32_t rangeCount,
2344 const VkImageSubresourceRange* pRanges)
2345 {
2346 RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
2347 RADV_FROM_HANDLE(radv_image, image, image_h);
2348 struct radv_meta_saved_state saved_state;
2349 bool cs = cmd_buffer->queue_family_index == RADV_QUEUE_COMPUTE;
2350
2351 if (cs) {
2352 radv_meta_save(&saved_state, cmd_buffer,
2353 RADV_META_SAVE_COMPUTE_PIPELINE |
2354 RADV_META_SAVE_CONSTANTS |
2355 RADV_META_SAVE_DESCRIPTORS);
2356 } else {
2357 radv_meta_save(&saved_state, cmd_buffer,
2358 RADV_META_SAVE_GRAPHICS_PIPELINE |
2359 RADV_META_SAVE_CONSTANTS);
2360 }
2361
2362 radv_cmd_clear_image(cmd_buffer, image, imageLayout,
2363 (const VkClearValue *) pColor,
2364 rangeCount, pRanges, cs);
2365
2366 radv_meta_restore(&saved_state, cmd_buffer);
2367 }
2368
2369 void radv_CmdClearDepthStencilImage(
2370 VkCommandBuffer commandBuffer,
2371 VkImage image_h,
2372 VkImageLayout imageLayout,
2373 const VkClearDepthStencilValue* pDepthStencil,
2374 uint32_t rangeCount,
2375 const VkImageSubresourceRange* pRanges)
2376 {
2377 RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
2378 RADV_FROM_HANDLE(radv_image, image, image_h);
2379 struct radv_meta_saved_state saved_state;
2380
2381 radv_meta_save(&saved_state, cmd_buffer,
2382 RADV_META_SAVE_GRAPHICS_PIPELINE |
2383 RADV_META_SAVE_CONSTANTS);
2384
2385 radv_cmd_clear_image(cmd_buffer, image, imageLayout,
2386 (const VkClearValue *) pDepthStencil,
2387 rangeCount, pRanges, false);
2388
2389 radv_meta_restore(&saved_state, cmd_buffer);
2390 }
2391
2392 void radv_CmdClearAttachments(
2393 VkCommandBuffer commandBuffer,
2394 uint32_t attachmentCount,
2395 const VkClearAttachment* pAttachments,
2396 uint32_t rectCount,
2397 const VkClearRect* pRects)
2398 {
2399 RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
2400 struct radv_meta_saved_state saved_state;
2401 enum radv_cmd_flush_bits pre_flush = 0;
2402 enum radv_cmd_flush_bits post_flush = 0;
2403
2404 if (!cmd_buffer->state.subpass)
2405 return;
2406
2407 radv_meta_save(&saved_state, cmd_buffer,
2408 RADV_META_SAVE_GRAPHICS_PIPELINE |
2409 RADV_META_SAVE_CONSTANTS);
2410
2411 /* FINISHME: We can do better than this dumb loop. It thrashes too much
2412 * state.
2413 */
2414 for (uint32_t a = 0; a < attachmentCount; ++a) {
2415 for (uint32_t r = 0; r < rectCount; ++r) {
2416 emit_clear(cmd_buffer, &pAttachments[a], &pRects[r], &pre_flush, &post_flush,
2417 cmd_buffer->state.subpass->view_mask, false);
2418 }
2419 }
2420
2421 radv_meta_restore(&saved_state, cmd_buffer);
2422 cmd_buffer->state.flush_bits |= post_flush;
2423 }