nir: replace nir_load_system_value calls with appropiate builder functions
[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 = 1,
236 .pPreserveAttachments = (uint32_t[]) { 0 },
237 },
238 .dependencyCount = 0,
239 }, &device->meta_state.alloc, pass);
240 mtx_unlock(&device->meta_state.mtx);
241 return result;
242 }
243
244 static VkResult
245 create_color_pipeline(struct radv_device *device,
246 uint32_t samples,
247 uint32_t frag_output,
248 VkPipeline *pipeline,
249 VkRenderPass pass)
250 {
251 struct nir_shader *vs_nir;
252 struct nir_shader *fs_nir;
253 VkResult result;
254
255 mtx_lock(&device->meta_state.mtx);
256 if (*pipeline) {
257 mtx_unlock(&device->meta_state.mtx);
258 return VK_SUCCESS;
259 }
260
261 build_color_shaders(&vs_nir, &fs_nir, frag_output);
262
263 const VkPipelineVertexInputStateCreateInfo vi_state = {
264 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
265 .vertexBindingDescriptionCount = 0,
266 .vertexAttributeDescriptionCount = 0,
267 };
268
269 const VkPipelineDepthStencilStateCreateInfo ds_state = {
270 .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
271 .depthTestEnable = false,
272 .depthWriteEnable = false,
273 .depthBoundsTestEnable = false,
274 .stencilTestEnable = false,
275 };
276
277 VkPipelineColorBlendAttachmentState blend_attachment_state[MAX_RTS] = { 0 };
278 blend_attachment_state[frag_output] = (VkPipelineColorBlendAttachmentState) {
279 .blendEnable = false,
280 .colorWriteMask = VK_COLOR_COMPONENT_A_BIT |
281 VK_COLOR_COMPONENT_R_BIT |
282 VK_COLOR_COMPONENT_G_BIT |
283 VK_COLOR_COMPONENT_B_BIT,
284 };
285
286 const VkPipelineColorBlendStateCreateInfo cb_state = {
287 .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
288 .logicOpEnable = false,
289 .attachmentCount = MAX_RTS,
290 .pAttachments = blend_attachment_state
291 };
292
293
294 struct radv_graphics_pipeline_create_info extra = {
295 .use_rectlist = true,
296 };
297 result = create_pipeline(device, radv_render_pass_from_handle(pass),
298 samples, vs_nir, fs_nir, &vi_state, &ds_state, &cb_state,
299 device->meta_state.clear_color_p_layout,
300 &extra, &device->meta_state.alloc, pipeline);
301
302 mtx_unlock(&device->meta_state.mtx);
303 return result;
304 }
305
306 void
307 radv_device_finish_meta_clear_state(struct radv_device *device)
308 {
309 struct radv_meta_state *state = &device->meta_state;
310
311 for (uint32_t i = 0; i < ARRAY_SIZE(state->clear); ++i) {
312 for (uint32_t j = 0; j < ARRAY_SIZE(state->clear[i].color_pipelines); ++j) {
313 radv_DestroyPipeline(radv_device_to_handle(device),
314 state->clear[i].color_pipelines[j],
315 &state->alloc);
316 radv_DestroyRenderPass(radv_device_to_handle(device),
317 state->clear[i].render_pass[j],
318 &state->alloc);
319 }
320
321 for (uint32_t j = 0; j < NUM_DEPTH_CLEAR_PIPELINES; j++) {
322 radv_DestroyPipeline(radv_device_to_handle(device),
323 state->clear[i].depth_only_pipeline[j],
324 &state->alloc);
325 radv_DestroyPipeline(radv_device_to_handle(device),
326 state->clear[i].stencil_only_pipeline[j],
327 &state->alloc);
328 radv_DestroyPipeline(radv_device_to_handle(device),
329 state->clear[i].depthstencil_pipeline[j],
330 &state->alloc);
331 }
332 radv_DestroyRenderPass(radv_device_to_handle(device),
333 state->clear[i].depthstencil_rp,
334 &state->alloc);
335 }
336 radv_DestroyPipelineLayout(radv_device_to_handle(device),
337 state->clear_color_p_layout,
338 &state->alloc);
339 radv_DestroyPipelineLayout(radv_device_to_handle(device),
340 state->clear_depth_p_layout,
341 &state->alloc);
342 }
343
344 static void
345 emit_color_clear(struct radv_cmd_buffer *cmd_buffer,
346 const VkClearAttachment *clear_att,
347 const VkClearRect *clear_rect,
348 uint32_t view_mask)
349 {
350 struct radv_device *device = cmd_buffer->device;
351 const struct radv_subpass *subpass = cmd_buffer->state.subpass;
352 const struct radv_framebuffer *fb = cmd_buffer->state.framebuffer;
353 const uint32_t subpass_att = clear_att->colorAttachment;
354 const uint32_t pass_att = subpass->color_attachments[subpass_att].attachment;
355 const struct radv_image_view *iview = fb->attachments[pass_att].attachment;
356 const uint32_t samples = iview->image->info.samples;
357 const uint32_t samples_log2 = ffs(samples) - 1;
358 unsigned fs_key = radv_format_meta_fs_key(iview->vk_format);
359 VkClearColorValue clear_value = clear_att->clearValue.color;
360 VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer);
361 VkPipeline pipeline;
362
363 if (fs_key == -1) {
364 radv_finishme("color clears incomplete");
365 return;
366 }
367
368 if (device->meta_state.clear[samples_log2].render_pass[fs_key] == VK_NULL_HANDLE) {
369 VkResult ret = create_color_renderpass(device, radv_fs_key_format_exemplars[fs_key],
370 samples,
371 &device->meta_state.clear[samples_log2].render_pass[fs_key]);
372 if (ret != VK_SUCCESS) {
373 cmd_buffer->record_result = ret;
374 return;
375 }
376 }
377
378 if (device->meta_state.clear[samples_log2].color_pipelines[fs_key] == VK_NULL_HANDLE) {
379 VkResult ret = create_color_pipeline(device, samples, 0,
380 &device->meta_state.clear[samples_log2].color_pipelines[fs_key],
381 device->meta_state.clear[samples_log2].render_pass[fs_key]);
382 if (ret != VK_SUCCESS) {
383 cmd_buffer->record_result = ret;
384 return;
385 }
386 }
387
388 pipeline = device->meta_state.clear[samples_log2].color_pipelines[fs_key];
389 if (!pipeline) {
390 radv_finishme("color clears incomplete");
391 return;
392 }
393 assert(samples_log2 < ARRAY_SIZE(device->meta_state.clear));
394 assert(pipeline);
395 assert(clear_att->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
396 assert(clear_att->colorAttachment < subpass->color_count);
397
398 radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
399 device->meta_state.clear_color_p_layout,
400 VK_SHADER_STAGE_FRAGMENT_BIT, 0, 16,
401 &clear_value);
402
403 struct radv_subpass clear_subpass = {
404 .color_count = 1,
405 .color_attachments = (struct radv_subpass_attachment[]) {
406 subpass->color_attachments[clear_att->colorAttachment]
407 },
408 .depth_stencil_attachment = (struct radv_subpass_attachment) { VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_UNDEFINED }
409 };
410
411 radv_cmd_buffer_set_subpass(cmd_buffer, &clear_subpass, false);
412
413 radv_CmdBindPipeline(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS,
414 pipeline);
415
416 radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &(VkViewport) {
417 .x = clear_rect->rect.offset.x,
418 .y = clear_rect->rect.offset.y,
419 .width = clear_rect->rect.extent.width,
420 .height = clear_rect->rect.extent.height,
421 .minDepth = 0.0f,
422 .maxDepth = 1.0f
423 });
424
425 radv_CmdSetScissor(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &clear_rect->rect);
426
427 if (view_mask) {
428 unsigned i;
429 for_each_bit(i, view_mask)
430 radv_CmdDraw(cmd_buffer_h, 3, 1, 0, i);
431 } else {
432 radv_CmdDraw(cmd_buffer_h, 3, clear_rect->layerCount, 0, clear_rect->baseArrayLayer);
433 }
434
435 radv_cmd_buffer_set_subpass(cmd_buffer, subpass, false);
436 }
437
438
439 static void
440 build_depthstencil_shader(struct nir_shader **out_vs, struct nir_shader **out_fs)
441 {
442 nir_builder vs_b, fs_b;
443
444 nir_builder_init_simple_shader(&vs_b, NULL, MESA_SHADER_VERTEX, NULL);
445 nir_builder_init_simple_shader(&fs_b, NULL, MESA_SHADER_FRAGMENT, NULL);
446
447 vs_b.shader->info.name = ralloc_strdup(vs_b.shader, "meta_clear_depthstencil_vs");
448 fs_b.shader->info.name = ralloc_strdup(fs_b.shader, "meta_clear_depthstencil_fs");
449 const struct glsl_type *position_out_type = glsl_vec4_type();
450
451 nir_variable *vs_out_pos =
452 nir_variable_create(vs_b.shader, nir_var_shader_out, position_out_type,
453 "gl_Position");
454 vs_out_pos->data.location = VARYING_SLOT_POS;
455
456 nir_intrinsic_instr *in_color_load = nir_intrinsic_instr_create(vs_b.shader, nir_intrinsic_load_push_constant);
457 nir_intrinsic_set_base(in_color_load, 0);
458 nir_intrinsic_set_range(in_color_load, 4);
459 in_color_load->src[0] = nir_src_for_ssa(nir_imm_int(&vs_b, 0));
460 in_color_load->num_components = 1;
461 nir_ssa_dest_init(&in_color_load->instr, &in_color_load->dest, 1, 32, "depth value");
462 nir_builder_instr_insert(&vs_b, &in_color_load->instr);
463
464 nir_ssa_def *outvec = radv_meta_gen_rect_vertices_comp2(&vs_b, &in_color_load->dest.ssa);
465 nir_store_var(&vs_b, vs_out_pos, outvec, 0xf);
466
467 const struct glsl_type *layer_type = glsl_int_type();
468 nir_variable *vs_out_layer =
469 nir_variable_create(vs_b.shader, nir_var_shader_out, layer_type,
470 "v_layer");
471 vs_out_layer->data.location = VARYING_SLOT_LAYER;
472 vs_out_layer->data.interpolation = INTERP_MODE_FLAT;
473 nir_ssa_def *inst_id = nir_load_instance_id(&vs_b);
474 nir_ssa_def *base_instance = nir_load_base_instance(&vs_b);
475
476 nir_ssa_def *layer_id = nir_iadd(&vs_b, inst_id, base_instance);
477 nir_store_var(&vs_b, vs_out_layer, layer_id, 0x1);
478
479 *out_vs = vs_b.shader;
480 *out_fs = fs_b.shader;
481 }
482
483 static VkResult
484 create_depthstencil_renderpass(struct radv_device *device,
485 uint32_t samples,
486 VkRenderPass *render_pass)
487 {
488 mtx_lock(&device->meta_state.mtx);
489 if (*render_pass) {
490 mtx_unlock(&device->meta_state.mtx);
491 return VK_SUCCESS;
492 }
493
494 VkResult result = radv_CreateRenderPass(radv_device_to_handle(device),
495 &(VkRenderPassCreateInfo) {
496 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
497 .attachmentCount = 1,
498 .pAttachments = &(VkAttachmentDescription) {
499 .format = VK_FORMAT_D32_SFLOAT_S8_UINT,
500 .samples = samples,
501 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
502 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
503 .initialLayout = VK_IMAGE_LAYOUT_GENERAL,
504 .finalLayout = VK_IMAGE_LAYOUT_GENERAL,
505 },
506 .subpassCount = 1,
507 .pSubpasses = &(VkSubpassDescription) {
508 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
509 .inputAttachmentCount = 0,
510 .colorAttachmentCount = 0,
511 .pColorAttachments = NULL,
512 .pResolveAttachments = NULL,
513 .pDepthStencilAttachment = &(VkAttachmentReference) {
514 .attachment = 0,
515 .layout = VK_IMAGE_LAYOUT_GENERAL,
516 },
517 .preserveAttachmentCount = 1,
518 .pPreserveAttachments = (uint32_t[]) { 0 },
519 },
520 .dependencyCount = 0,
521 }, &device->meta_state.alloc, render_pass);
522 mtx_unlock(&device->meta_state.mtx);
523 return result;
524 }
525
526 static VkResult
527 create_depthstencil_pipeline(struct radv_device *device,
528 VkImageAspectFlags aspects,
529 uint32_t samples,
530 int index,
531 VkPipeline *pipeline,
532 VkRenderPass render_pass)
533 {
534 struct nir_shader *vs_nir, *fs_nir;
535 VkResult result;
536
537 mtx_lock(&device->meta_state.mtx);
538 if (*pipeline) {
539 mtx_unlock(&device->meta_state.mtx);
540 return VK_SUCCESS;
541 }
542
543 build_depthstencil_shader(&vs_nir, &fs_nir);
544
545 const VkPipelineVertexInputStateCreateInfo vi_state = {
546 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
547 .vertexBindingDescriptionCount = 0,
548 .vertexAttributeDescriptionCount = 0,
549 };
550
551 const VkPipelineDepthStencilStateCreateInfo ds_state = {
552 .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
553 .depthTestEnable = (aspects & VK_IMAGE_ASPECT_DEPTH_BIT),
554 .depthCompareOp = VK_COMPARE_OP_ALWAYS,
555 .depthWriteEnable = (aspects & VK_IMAGE_ASPECT_DEPTH_BIT),
556 .depthBoundsTestEnable = false,
557 .stencilTestEnable = (aspects & VK_IMAGE_ASPECT_STENCIL_BIT),
558 .front = {
559 .passOp = VK_STENCIL_OP_REPLACE,
560 .compareOp = VK_COMPARE_OP_ALWAYS,
561 .writeMask = UINT32_MAX,
562 .reference = 0, /* dynamic */
563 },
564 .back = { 0 /* dont care */ },
565 };
566
567 const VkPipelineColorBlendStateCreateInfo cb_state = {
568 .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
569 .logicOpEnable = false,
570 .attachmentCount = 0,
571 .pAttachments = NULL,
572 };
573
574 struct radv_graphics_pipeline_create_info extra = {
575 .use_rectlist = true,
576 };
577
578 if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {
579 extra.db_depth_clear = index == DEPTH_CLEAR_SLOW ? false : true;
580 extra.db_depth_disable_expclear = index == DEPTH_CLEAR_FAST_NO_EXPCLEAR ? true : false;
581 }
582 if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
583 extra.db_stencil_clear = index == DEPTH_CLEAR_SLOW ? false : true;
584 extra.db_stencil_disable_expclear = index == DEPTH_CLEAR_FAST_NO_EXPCLEAR ? true : false;
585 }
586 result = create_pipeline(device, radv_render_pass_from_handle(render_pass),
587 samples, vs_nir, fs_nir, &vi_state, &ds_state, &cb_state,
588 device->meta_state.clear_depth_p_layout,
589 &extra, &device->meta_state.alloc, pipeline);
590
591 mtx_unlock(&device->meta_state.mtx);
592 return result;
593 }
594
595 static bool depth_view_can_fast_clear(struct radv_cmd_buffer *cmd_buffer,
596 const struct radv_image_view *iview,
597 VkImageAspectFlags aspects,
598 VkImageLayout layout,
599 const VkClearRect *clear_rect,
600 VkClearDepthStencilValue clear_value)
601 {
602 uint32_t queue_mask = radv_image_queue_family_mask(iview->image,
603 cmd_buffer->queue_family_index,
604 cmd_buffer->queue_family_index);
605 if (clear_rect->rect.offset.x || clear_rect->rect.offset.y ||
606 clear_rect->rect.extent.width != iview->extent.width ||
607 clear_rect->rect.extent.height != iview->extent.height)
608 return false;
609 if (radv_image_is_tc_compat_htile(iview->image) &&
610 (((aspects & VK_IMAGE_ASPECT_DEPTH_BIT) && clear_value.depth != 0.0 &&
611 clear_value.depth != 1.0) ||
612 ((aspects & VK_IMAGE_ASPECT_STENCIL_BIT) && clear_value.stencil != 0)))
613 return false;
614 if (radv_image_has_htile(iview->image) &&
615 iview->base_mip == 0 &&
616 iview->base_layer == 0 &&
617 radv_layout_is_htile_compressed(iview->image, layout, queue_mask) &&
618 !radv_image_extent_compare(iview->image, &iview->extent))
619 return true;
620 return false;
621 }
622
623 static VkPipeline
624 pick_depthstencil_pipeline(struct radv_cmd_buffer *cmd_buffer,
625 struct radv_meta_state *meta_state,
626 const struct radv_image_view *iview,
627 int samples_log2,
628 VkImageAspectFlags aspects,
629 VkImageLayout layout,
630 const VkClearRect *clear_rect,
631 VkClearDepthStencilValue clear_value)
632 {
633 bool fast = depth_view_can_fast_clear(cmd_buffer, iview, aspects, layout, clear_rect, clear_value);
634 int index = DEPTH_CLEAR_SLOW;
635 VkPipeline *pipeline;
636
637 if (fast) {
638 /* we don't know the previous clear values, so we always have
639 * the NO_EXPCLEAR path */
640 index = DEPTH_CLEAR_FAST_NO_EXPCLEAR;
641 }
642
643 switch (aspects) {
644 case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT:
645 pipeline = &meta_state->clear[samples_log2].depthstencil_pipeline[index];
646 break;
647 case VK_IMAGE_ASPECT_DEPTH_BIT:
648 pipeline = &meta_state->clear[samples_log2].depth_only_pipeline[index];
649 break;
650 case VK_IMAGE_ASPECT_STENCIL_BIT:
651 pipeline = &meta_state->clear[samples_log2].stencil_only_pipeline[index];
652 break;
653 default:
654 unreachable("expected depth or stencil aspect");
655 }
656
657 if (cmd_buffer->device->meta_state.clear[samples_log2].depthstencil_rp == VK_NULL_HANDLE) {
658 VkResult ret = create_depthstencil_renderpass(cmd_buffer->device, 1u << samples_log2,
659 &cmd_buffer->device->meta_state.clear[samples_log2].depthstencil_rp);
660 if (ret != VK_SUCCESS) {
661 cmd_buffer->record_result = ret;
662 return VK_NULL_HANDLE;
663 }
664 }
665
666 if (*pipeline == VK_NULL_HANDLE) {
667 VkResult ret = create_depthstencil_pipeline(cmd_buffer->device, aspects, 1u << samples_log2, index,
668 pipeline, cmd_buffer->device->meta_state.clear[samples_log2].depthstencil_rp);
669 if (ret != VK_SUCCESS) {
670 cmd_buffer->record_result = ret;
671 return VK_NULL_HANDLE;
672 }
673 }
674 return *pipeline;
675 }
676
677 static void
678 emit_depthstencil_clear(struct radv_cmd_buffer *cmd_buffer,
679 const VkClearAttachment *clear_att,
680 const VkClearRect *clear_rect)
681 {
682 struct radv_device *device = cmd_buffer->device;
683 struct radv_meta_state *meta_state = &device->meta_state;
684 const struct radv_subpass *subpass = cmd_buffer->state.subpass;
685 const struct radv_framebuffer *fb = cmd_buffer->state.framebuffer;
686 const uint32_t pass_att = subpass->depth_stencil_attachment.attachment;
687 VkClearDepthStencilValue clear_value = clear_att->clearValue.depthStencil;
688 VkImageAspectFlags aspects = clear_att->aspectMask;
689 const struct radv_image_view *iview = fb->attachments[pass_att].attachment;
690 const uint32_t samples = iview->image->info.samples;
691 const uint32_t samples_log2 = ffs(samples) - 1;
692 VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer);
693
694 assert(pass_att != VK_ATTACHMENT_UNUSED);
695
696 if (!(aspects & VK_IMAGE_ASPECT_DEPTH_BIT))
697 clear_value.depth = 1.0f;
698
699 radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
700 device->meta_state.clear_depth_p_layout,
701 VK_SHADER_STAGE_VERTEX_BIT, 0, 4,
702 &clear_value.depth);
703
704 uint32_t prev_reference = cmd_buffer->state.dynamic.stencil_reference.front;
705 if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
706 radv_CmdSetStencilReference(cmd_buffer_h, VK_STENCIL_FACE_FRONT_BIT,
707 clear_value.stencil);
708 }
709
710 VkPipeline pipeline = pick_depthstencil_pipeline(cmd_buffer,
711 meta_state,
712 iview,
713 samples_log2,
714 aspects,
715 subpass->depth_stencil_attachment.layout,
716 clear_rect,
717 clear_value);
718 if (!pipeline)
719 return;
720
721 radv_CmdBindPipeline(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS,
722 pipeline);
723
724 if (depth_view_can_fast_clear(cmd_buffer, iview, aspects,
725 subpass->depth_stencil_attachment.layout,
726 clear_rect, clear_value))
727 radv_update_ds_clear_metadata(cmd_buffer, iview->image,
728 clear_value, aspects);
729
730 radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &(VkViewport) {
731 .x = clear_rect->rect.offset.x,
732 .y = clear_rect->rect.offset.y,
733 .width = clear_rect->rect.extent.width,
734 .height = clear_rect->rect.extent.height,
735 .minDepth = 0.0f,
736 .maxDepth = 1.0f
737 });
738
739 radv_CmdSetScissor(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &clear_rect->rect);
740
741 radv_CmdDraw(cmd_buffer_h, 3, clear_rect->layerCount, 0, clear_rect->baseArrayLayer);
742
743 if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
744 radv_CmdSetStencilReference(cmd_buffer_h, VK_STENCIL_FACE_FRONT_BIT,
745 prev_reference);
746 }
747 }
748
749 static bool
750 emit_fast_htile_clear(struct radv_cmd_buffer *cmd_buffer,
751 const VkClearAttachment *clear_att,
752 const VkClearRect *clear_rect,
753 enum radv_cmd_flush_bits *pre_flush,
754 enum radv_cmd_flush_bits *post_flush)
755 {
756 const struct radv_subpass *subpass = cmd_buffer->state.subpass;
757 const uint32_t pass_att = subpass->depth_stencil_attachment.attachment;
758 VkImageLayout image_layout = subpass->depth_stencil_attachment.layout;
759 const struct radv_framebuffer *fb = cmd_buffer->state.framebuffer;
760 const struct radv_image_view *iview = fb->attachments[pass_att].attachment;
761 VkClearDepthStencilValue clear_value = clear_att->clearValue.depthStencil;
762 VkImageAspectFlags aspects = clear_att->aspectMask;
763 uint32_t clear_word, flush_bits;
764
765 if (!radv_image_has_htile(iview->image))
766 return false;
767
768 if (cmd_buffer->device->instance->debug_flags & RADV_DEBUG_NO_FAST_CLEARS)
769 return false;
770
771 if (!radv_layout_is_htile_compressed(iview->image, image_layout, radv_image_queue_family_mask(iview->image, cmd_buffer->queue_family_index, cmd_buffer->queue_family_index)))
772 goto fail;
773
774 /* don't fast clear 3D */
775 if (iview->image->type == VK_IMAGE_TYPE_3D)
776 goto fail;
777
778 /* all layers are bound */
779 if (iview->base_layer > 0)
780 goto fail;
781 if (iview->image->info.array_size != iview->layer_count)
782 goto fail;
783
784 if (!radv_image_extent_compare(iview->image, &iview->extent))
785 goto fail;
786
787 if (clear_rect->rect.offset.x || clear_rect->rect.offset.y ||
788 clear_rect->rect.extent.width != iview->image->info.width ||
789 clear_rect->rect.extent.height != iview->image->info.height)
790 goto fail;
791
792 if (clear_rect->baseArrayLayer != 0)
793 goto fail;
794 if (clear_rect->layerCount != iview->image->info.array_size)
795 goto fail;
796
797 if ((clear_value.depth != 0.0 && clear_value.depth != 1.0) || !(aspects & VK_IMAGE_ASPECT_DEPTH_BIT))
798 goto fail;
799
800 /* GFX8 only supports 32-bit depth surfaces but we can enable TC-compat
801 * HTILE for 16-bit surfaces if no Z planes are compressed. Though,
802 * fast HTILE clears don't seem to work.
803 */
804 if (cmd_buffer->device->physical_device->rad_info.chip_class == VI &&
805 iview->image->vk_format == VK_FORMAT_D16_UNORM)
806 goto fail;
807
808 if (vk_format_aspects(iview->image->vk_format) & VK_IMAGE_ASPECT_STENCIL_BIT) {
809 if (clear_value.stencil != 0 || !(aspects & VK_IMAGE_ASPECT_STENCIL_BIT))
810 goto fail;
811 clear_word = clear_value.depth ? 0xfffc0000 : 0;
812 } else
813 clear_word = clear_value.depth ? 0xfffffff0 : 0;
814
815 if (pre_flush) {
816 cmd_buffer->state.flush_bits |= (RADV_CMD_FLAG_FLUSH_AND_INV_DB |
817 RADV_CMD_FLAG_FLUSH_AND_INV_DB_META) & ~ *pre_flush;
818 *pre_flush |= cmd_buffer->state.flush_bits;
819 } else
820 cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_FLUSH_AND_INV_DB |
821 RADV_CMD_FLAG_FLUSH_AND_INV_DB_META;
822
823 flush_bits = radv_fill_buffer(cmd_buffer, iview->image->bo,
824 iview->image->offset + iview->image->htile_offset,
825 iview->image->surface.htile_size, clear_word);
826
827 radv_update_ds_clear_metadata(cmd_buffer, iview->image, clear_value, aspects);
828 if (post_flush) {
829 *post_flush |= flush_bits;
830 } else {
831 cmd_buffer->state.flush_bits |= flush_bits;
832 }
833
834 return true;
835 fail:
836 return false;
837 }
838
839 VkResult
840 radv_device_init_meta_clear_state(struct radv_device *device, bool on_demand)
841 {
842 VkResult res;
843 struct radv_meta_state *state = &device->meta_state;
844
845 VkPipelineLayoutCreateInfo pl_color_create_info = {
846 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
847 .setLayoutCount = 0,
848 .pushConstantRangeCount = 1,
849 .pPushConstantRanges = &(VkPushConstantRange){VK_SHADER_STAGE_FRAGMENT_BIT, 0, 16},
850 };
851
852 res = radv_CreatePipelineLayout(radv_device_to_handle(device),
853 &pl_color_create_info,
854 &device->meta_state.alloc,
855 &device->meta_state.clear_color_p_layout);
856 if (res != VK_SUCCESS)
857 goto fail;
858
859 VkPipelineLayoutCreateInfo pl_depth_create_info = {
860 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
861 .setLayoutCount = 0,
862 .pushConstantRangeCount = 1,
863 .pPushConstantRanges = &(VkPushConstantRange){VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
864 };
865
866 res = radv_CreatePipelineLayout(radv_device_to_handle(device),
867 &pl_depth_create_info,
868 &device->meta_state.alloc,
869 &device->meta_state.clear_depth_p_layout);
870 if (res != VK_SUCCESS)
871 goto fail;
872
873 if (on_demand)
874 return VK_SUCCESS;
875
876 for (uint32_t i = 0; i < ARRAY_SIZE(state->clear); ++i) {
877 uint32_t samples = 1 << i;
878 for (uint32_t j = 0; j < NUM_META_FS_KEYS; ++j) {
879 VkFormat format = radv_fs_key_format_exemplars[j];
880 unsigned fs_key = radv_format_meta_fs_key(format);
881 assert(!state->clear[i].color_pipelines[fs_key]);
882
883 res = create_color_renderpass(device, format, samples,
884 &state->clear[i].render_pass[fs_key]);
885 if (res != VK_SUCCESS)
886 goto fail;
887
888 res = create_color_pipeline(device, samples, 0, &state->clear[i].color_pipelines[fs_key],
889 state->clear[i].render_pass[fs_key]);
890 if (res != VK_SUCCESS)
891 goto fail;
892
893 }
894
895 res = create_depthstencil_renderpass(device,
896 samples,
897 &state->clear[i].depthstencil_rp);
898 if (res != VK_SUCCESS)
899 goto fail;
900
901 for (uint32_t j = 0; j < NUM_DEPTH_CLEAR_PIPELINES; j++) {
902 res = create_depthstencil_pipeline(device,
903 VK_IMAGE_ASPECT_DEPTH_BIT,
904 samples,
905 j,
906 &state->clear[i].depth_only_pipeline[j],
907 state->clear[i].depthstencil_rp);
908 if (res != VK_SUCCESS)
909 goto fail;
910
911 res = create_depthstencil_pipeline(device,
912 VK_IMAGE_ASPECT_STENCIL_BIT,
913 samples,
914 j,
915 &state->clear[i].stencil_only_pipeline[j],
916 state->clear[i].depthstencil_rp);
917 if (res != VK_SUCCESS)
918 goto fail;
919
920 res = create_depthstencil_pipeline(device,
921 VK_IMAGE_ASPECT_DEPTH_BIT |
922 VK_IMAGE_ASPECT_STENCIL_BIT,
923 samples,
924 j,
925 &state->clear[i].depthstencil_pipeline[j],
926 state->clear[i].depthstencil_rp);
927 if (res != VK_SUCCESS)
928 goto fail;
929 }
930 }
931 return VK_SUCCESS;
932
933 fail:
934 radv_device_finish_meta_clear_state(device);
935 return res;
936 }
937
938 static uint32_t
939 radv_get_cmask_fast_clear_value(const struct radv_image *image)
940 {
941 uint32_t value = 0; /* Default value when no DCC. */
942
943 /* The fast-clear value is different for images that have both DCC and
944 * CMASK metadata.
945 */
946 if (radv_image_has_dcc(image)) {
947 /* DCC fast clear with MSAA should clear CMASK to 0xC. */
948 return image->info.samples > 1 ? 0xcccccccc : 0xffffffff;
949 }
950
951 return value;
952 }
953
954 uint32_t
955 radv_clear_cmask(struct radv_cmd_buffer *cmd_buffer,
956 struct radv_image *image, uint32_t value)
957 {
958 return radv_fill_buffer(cmd_buffer, image->bo,
959 image->offset + image->cmask.offset,
960 image->cmask.size, value);
961 }
962
963 uint32_t
964 radv_clear_dcc(struct radv_cmd_buffer *cmd_buffer,
965 struct radv_image *image, uint32_t value)
966 {
967 return radv_fill_buffer(cmd_buffer, image->bo,
968 image->offset + image->dcc_offset,
969 image->surface.dcc_size, value);
970 }
971
972 static void vi_get_fast_clear_parameters(VkFormat format,
973 const VkClearColorValue *clear_value,
974 uint32_t* reset_value,
975 bool *can_avoid_fast_clear_elim)
976 {
977 bool values[4] = {};
978 int extra_channel;
979 bool main_value = false;
980 bool extra_value = false;
981 int i;
982 *can_avoid_fast_clear_elim = false;
983
984 *reset_value = 0x20202020U;
985
986 const struct vk_format_description *desc = vk_format_description(format);
987 if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32 ||
988 format == VK_FORMAT_R5G6B5_UNORM_PACK16 ||
989 format == VK_FORMAT_B5G6R5_UNORM_PACK16)
990 extra_channel = -1;
991 else if (desc->layout == VK_FORMAT_LAYOUT_PLAIN) {
992 if (radv_translate_colorswap(format, false) <= 1)
993 extra_channel = desc->nr_channels - 1;
994 else
995 extra_channel = 0;
996 } else
997 return;
998
999 for (i = 0; i < 4; i++) {
1000 int index = desc->swizzle[i] - VK_SWIZZLE_X;
1001 if (desc->swizzle[i] < VK_SWIZZLE_X ||
1002 desc->swizzle[i] > VK_SWIZZLE_W)
1003 continue;
1004
1005 if (desc->channel[i].pure_integer &&
1006 desc->channel[i].type == VK_FORMAT_TYPE_SIGNED) {
1007 /* Use the maximum value for clamping the clear color. */
1008 int max = u_bit_consecutive(0, desc->channel[i].size - 1);
1009
1010 values[i] = clear_value->int32[i] != 0;
1011 if (clear_value->int32[i] != 0 && MIN2(clear_value->int32[i], max) != max)
1012 return;
1013 } else if (desc->channel[i].pure_integer &&
1014 desc->channel[i].type == VK_FORMAT_TYPE_UNSIGNED) {
1015 /* Use the maximum value for clamping the clear color. */
1016 unsigned max = u_bit_consecutive(0, desc->channel[i].size);
1017
1018 values[i] = clear_value->uint32[i] != 0U;
1019 if (clear_value->uint32[i] != 0U && MIN2(clear_value->uint32[i], max) != max)
1020 return;
1021 } else {
1022 values[i] = clear_value->float32[i] != 0.0F;
1023 if (clear_value->float32[i] != 0.0F && clear_value->float32[i] != 1.0F)
1024 return;
1025 }
1026
1027 if (index == extra_channel)
1028 extra_value = values[i];
1029 else
1030 main_value = values[i];
1031 }
1032
1033 for (int i = 0; i < 4; ++i)
1034 if (values[i] != main_value &&
1035 desc->swizzle[i] - VK_SWIZZLE_X != extra_channel &&
1036 desc->swizzle[i] >= VK_SWIZZLE_X &&
1037 desc->swizzle[i] <= VK_SWIZZLE_W)
1038 return;
1039
1040 *can_avoid_fast_clear_elim = true;
1041 if (main_value)
1042 *reset_value |= 0x80808080U;
1043
1044 if (extra_value)
1045 *reset_value |= 0x40404040U;
1046 return;
1047 }
1048
1049 static bool
1050 emit_fast_color_clear(struct radv_cmd_buffer *cmd_buffer,
1051 const VkClearAttachment *clear_att,
1052 const VkClearRect *clear_rect,
1053 enum radv_cmd_flush_bits *pre_flush,
1054 enum radv_cmd_flush_bits *post_flush,
1055 uint32_t view_mask)
1056 {
1057 const struct radv_subpass *subpass = cmd_buffer->state.subpass;
1058 const uint32_t subpass_att = clear_att->colorAttachment;
1059 const uint32_t pass_att = subpass->color_attachments[subpass_att].attachment;
1060 VkImageLayout image_layout = subpass->color_attachments[subpass_att].layout;
1061 const struct radv_framebuffer *fb = cmd_buffer->state.framebuffer;
1062 const struct radv_image_view *iview = fb->attachments[pass_att].attachment;
1063 VkClearColorValue clear_value = clear_att->clearValue.color;
1064 uint32_t clear_color[2], flush_bits = 0;
1065 uint32_t cmask_clear_value;
1066 bool ret;
1067
1068 if (!radv_image_has_cmask(iview->image) && !radv_image_has_dcc(iview->image))
1069 return false;
1070
1071 if (cmd_buffer->device->instance->debug_flags & RADV_DEBUG_NO_FAST_CLEARS)
1072 return false;
1073
1074 if (!radv_layout_can_fast_clear(iview->image, image_layout, radv_image_queue_family_mask(iview->image, cmd_buffer->queue_family_index, cmd_buffer->queue_family_index)))
1075 goto fail;
1076
1077 /* don't fast clear 3D */
1078 if (iview->image->type == VK_IMAGE_TYPE_3D)
1079 goto fail;
1080
1081 /* all layers are bound */
1082 if (iview->base_layer > 0)
1083 goto fail;
1084 if (iview->image->info.array_size != iview->layer_count)
1085 goto fail;
1086
1087 if (iview->image->info.levels > 1)
1088 goto fail;
1089
1090 if (!radv_image_extent_compare(iview->image, &iview->extent))
1091 goto fail;
1092
1093 if (clear_rect->rect.offset.x || clear_rect->rect.offset.y ||
1094 clear_rect->rect.extent.width != iview->image->info.width ||
1095 clear_rect->rect.extent.height != iview->image->info.height)
1096 goto fail;
1097
1098 if (view_mask && (iview->image->info.array_size >= 32 ||
1099 (1u << iview->image->info.array_size) - 1u != view_mask))
1100 goto fail;
1101 if (!view_mask && clear_rect->baseArrayLayer != 0)
1102 goto fail;
1103 if (!view_mask && clear_rect->layerCount != iview->image->info.array_size)
1104 goto fail;
1105
1106 /* RB+ doesn't work with CMASK fast clear on Stoney. */
1107 if (!radv_image_has_dcc(iview->image) &&
1108 cmd_buffer->device->physical_device->rad_info.family == CHIP_STONEY)
1109 goto fail;
1110
1111 /* DCC */
1112 ret = radv_format_pack_clear_color(iview->vk_format,
1113 clear_color, &clear_value);
1114 if (ret == false)
1115 goto fail;
1116
1117 if (pre_flush) {
1118 cmd_buffer->state.flush_bits |= (RADV_CMD_FLAG_FLUSH_AND_INV_CB |
1119 RADV_CMD_FLAG_FLUSH_AND_INV_CB_META) & ~ *pre_flush;
1120 *pre_flush |= cmd_buffer->state.flush_bits;
1121 } else
1122 cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_FLUSH_AND_INV_CB |
1123 RADV_CMD_FLAG_FLUSH_AND_INV_CB_META;
1124
1125 cmask_clear_value = radv_get_cmask_fast_clear_value(iview->image);
1126
1127 /* clear cmask buffer */
1128 if (radv_image_has_dcc(iview->image)) {
1129 uint32_t reset_value;
1130 bool can_avoid_fast_clear_elim;
1131 bool need_decompress_pass = false;
1132
1133 vi_get_fast_clear_parameters(iview->vk_format,
1134 &clear_value, &reset_value,
1135 &can_avoid_fast_clear_elim);
1136
1137 if (iview->image->info.samples > 1) {
1138 /* DCC fast clear with MSAA should clear CMASK. */
1139 /* FIXME: This doesn't work for now. There is a
1140 * hardware bug with fast clears and DCC for MSAA
1141 * textures. AMDVLK has a workaround but it doesn't
1142 * seem to work here. Note that we might emit useless
1143 * CB flushes but that shouldn't matter.
1144 */
1145 if (!can_avoid_fast_clear_elim)
1146 goto fail;
1147
1148 assert(radv_image_has_cmask(iview->image));
1149
1150 flush_bits = radv_clear_cmask(cmd_buffer, iview->image,
1151 cmask_clear_value);
1152
1153 need_decompress_pass = true;
1154 }
1155
1156 if (!can_avoid_fast_clear_elim)
1157 need_decompress_pass = true;
1158
1159 flush_bits |= radv_clear_dcc(cmd_buffer, iview->image, reset_value);
1160
1161 radv_set_dcc_need_cmask_elim_pred(cmd_buffer, iview->image,
1162 need_decompress_pass);
1163 } else {
1164 flush_bits = radv_clear_cmask(cmd_buffer, iview->image,
1165 cmask_clear_value);
1166 }
1167
1168 if (post_flush) {
1169 *post_flush |= flush_bits;
1170 } else {
1171 cmd_buffer->state.flush_bits |= flush_bits;
1172 }
1173
1174 radv_update_color_clear_metadata(cmd_buffer, iview->image, subpass_att,
1175 clear_color);
1176
1177 return true;
1178 fail:
1179 return false;
1180 }
1181
1182 /**
1183 * The parameters mean that same as those in vkCmdClearAttachments.
1184 */
1185 static void
1186 emit_clear(struct radv_cmd_buffer *cmd_buffer,
1187 const VkClearAttachment *clear_att,
1188 const VkClearRect *clear_rect,
1189 enum radv_cmd_flush_bits *pre_flush,
1190 enum radv_cmd_flush_bits *post_flush,
1191 uint32_t view_mask)
1192 {
1193 if (clear_att->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
1194 if (!emit_fast_color_clear(cmd_buffer, clear_att, clear_rect,
1195 pre_flush, post_flush, view_mask))
1196 emit_color_clear(cmd_buffer, clear_att, clear_rect, view_mask);
1197 } else {
1198 assert(clear_att->aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT |
1199 VK_IMAGE_ASPECT_STENCIL_BIT));
1200 if (!emit_fast_htile_clear(cmd_buffer, clear_att, clear_rect,
1201 pre_flush, post_flush))
1202 emit_depthstencil_clear(cmd_buffer, clear_att, clear_rect);
1203 }
1204 }
1205
1206 static inline bool
1207 radv_attachment_needs_clear(struct radv_cmd_state *cmd_state, uint32_t a)
1208 {
1209 uint32_t view_mask = cmd_state->subpass->view_mask;
1210 return (a != VK_ATTACHMENT_UNUSED &&
1211 cmd_state->attachments[a].pending_clear_aspects &&
1212 (!view_mask || (view_mask & ~cmd_state->attachments[a].cleared_views)));
1213 }
1214
1215 static bool
1216 radv_subpass_needs_clear(struct radv_cmd_buffer *cmd_buffer)
1217 {
1218 struct radv_cmd_state *cmd_state = &cmd_buffer->state;
1219 uint32_t a;
1220
1221 if (!cmd_state->subpass)
1222 return false;
1223
1224 for (uint32_t i = 0; i < cmd_state->subpass->color_count; ++i) {
1225 a = cmd_state->subpass->color_attachments[i].attachment;
1226 if (radv_attachment_needs_clear(cmd_state, a))
1227 return true;
1228 }
1229
1230 a = cmd_state->subpass->depth_stencil_attachment.attachment;
1231 return radv_attachment_needs_clear(cmd_state, a);
1232 }
1233
1234 static void
1235 radv_subpass_clear_attachment(struct radv_cmd_buffer *cmd_buffer,
1236 struct radv_attachment_state *attachment,
1237 const VkClearAttachment *clear_att,
1238 enum radv_cmd_flush_bits *pre_flush,
1239 enum radv_cmd_flush_bits *post_flush)
1240 {
1241 struct radv_cmd_state *cmd_state = &cmd_buffer->state;
1242 uint32_t view_mask = cmd_state->subpass->view_mask;
1243
1244 VkClearRect clear_rect = {
1245 .rect = cmd_state->render_area,
1246 .baseArrayLayer = 0,
1247 .layerCount = cmd_state->framebuffer->layers,
1248 };
1249
1250 emit_clear(cmd_buffer, clear_att, &clear_rect, pre_flush, post_flush,
1251 view_mask & ~attachment->cleared_views);
1252 if (view_mask)
1253 attachment->cleared_views |= view_mask;
1254 else
1255 attachment->pending_clear_aspects = 0;
1256 }
1257
1258 /**
1259 * Emit any pending attachment clears for the current subpass.
1260 *
1261 * @see radv_attachment_state::pending_clear_aspects
1262 */
1263 void
1264 radv_cmd_buffer_clear_subpass(struct radv_cmd_buffer *cmd_buffer)
1265 {
1266 struct radv_cmd_state *cmd_state = &cmd_buffer->state;
1267 struct radv_meta_saved_state saved_state;
1268 enum radv_cmd_flush_bits pre_flush = 0;
1269 enum radv_cmd_flush_bits post_flush = 0;
1270
1271 if (!radv_subpass_needs_clear(cmd_buffer))
1272 return;
1273
1274 radv_meta_save(&saved_state, cmd_buffer,
1275 RADV_META_SAVE_GRAPHICS_PIPELINE |
1276 RADV_META_SAVE_CONSTANTS);
1277
1278 for (uint32_t i = 0; i < cmd_state->subpass->color_count; ++i) {
1279 uint32_t a = cmd_state->subpass->color_attachments[i].attachment;
1280
1281 if (!radv_attachment_needs_clear(cmd_state, a))
1282 continue;
1283
1284 assert(cmd_state->attachments[a].pending_clear_aspects ==
1285 VK_IMAGE_ASPECT_COLOR_BIT);
1286
1287 VkClearAttachment clear_att = {
1288 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
1289 .colorAttachment = i, /* Use attachment index relative to subpass */
1290 .clearValue = cmd_state->attachments[a].clear_value,
1291 };
1292
1293 radv_subpass_clear_attachment(cmd_buffer,
1294 &cmd_state->attachments[a],
1295 &clear_att, &pre_flush,
1296 &post_flush);
1297 }
1298
1299 uint32_t ds = cmd_state->subpass->depth_stencil_attachment.attachment;
1300 if (radv_attachment_needs_clear(cmd_state, ds)) {
1301 VkClearAttachment clear_att = {
1302 .aspectMask = cmd_state->attachments[ds].pending_clear_aspects,
1303 .clearValue = cmd_state->attachments[ds].clear_value,
1304 };
1305
1306 radv_subpass_clear_attachment(cmd_buffer,
1307 &cmd_state->attachments[ds],
1308 &clear_att, &pre_flush,
1309 &post_flush);
1310 }
1311
1312 radv_meta_restore(&saved_state, cmd_buffer);
1313 cmd_buffer->state.flush_bits |= post_flush;
1314 }
1315
1316 static void
1317 radv_clear_image_layer(struct radv_cmd_buffer *cmd_buffer,
1318 struct radv_image *image,
1319 VkImageLayout image_layout,
1320 const VkImageSubresourceRange *range,
1321 VkFormat format, int level, int layer,
1322 const VkClearValue *clear_val)
1323 {
1324 VkDevice device_h = radv_device_to_handle(cmd_buffer->device);
1325 struct radv_image_view iview;
1326 uint32_t width = radv_minify(image->info.width, range->baseMipLevel + level);
1327 uint32_t height = radv_minify(image->info.height, range->baseMipLevel + level);
1328
1329 radv_image_view_init(&iview, cmd_buffer->device,
1330 &(VkImageViewCreateInfo) {
1331 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
1332 .image = radv_image_to_handle(image),
1333 .viewType = radv_meta_get_view_type(image),
1334 .format = format,
1335 .subresourceRange = {
1336 .aspectMask = range->aspectMask,
1337 .baseMipLevel = range->baseMipLevel + level,
1338 .levelCount = 1,
1339 .baseArrayLayer = range->baseArrayLayer + layer,
1340 .layerCount = 1
1341 },
1342 });
1343
1344 VkFramebuffer fb;
1345 radv_CreateFramebuffer(device_h,
1346 &(VkFramebufferCreateInfo) {
1347 .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
1348 .attachmentCount = 1,
1349 .pAttachments = (VkImageView[]) {
1350 radv_image_view_to_handle(&iview),
1351 },
1352 .width = width,
1353 .height = height,
1354 .layers = 1
1355 },
1356 &cmd_buffer->pool->alloc,
1357 &fb);
1358
1359 VkAttachmentDescription att_desc = {
1360 .format = iview.vk_format,
1361 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
1362 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
1363 .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
1364 .stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE,
1365 .initialLayout = image_layout,
1366 .finalLayout = image_layout,
1367 };
1368
1369 VkSubpassDescription subpass_desc = {
1370 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
1371 .inputAttachmentCount = 0,
1372 .colorAttachmentCount = 0,
1373 .pColorAttachments = NULL,
1374 .pResolveAttachments = NULL,
1375 .pDepthStencilAttachment = NULL,
1376 .preserveAttachmentCount = 0,
1377 .pPreserveAttachments = NULL,
1378 };
1379
1380 const VkAttachmentReference att_ref = {
1381 .attachment = 0,
1382 .layout = image_layout,
1383 };
1384
1385 if (range->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
1386 subpass_desc.colorAttachmentCount = 1;
1387 subpass_desc.pColorAttachments = &att_ref;
1388 } else {
1389 subpass_desc.pDepthStencilAttachment = &att_ref;
1390 }
1391
1392 VkRenderPass pass;
1393 radv_CreateRenderPass(device_h,
1394 &(VkRenderPassCreateInfo) {
1395 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
1396 .attachmentCount = 1,
1397 .pAttachments = &att_desc,
1398 .subpassCount = 1,
1399 .pSubpasses = &subpass_desc,
1400 },
1401 &cmd_buffer->pool->alloc,
1402 &pass);
1403
1404 radv_CmdBeginRenderPass(radv_cmd_buffer_to_handle(cmd_buffer),
1405 &(VkRenderPassBeginInfo) {
1406 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
1407 .renderArea = {
1408 .offset = { 0, 0, },
1409 .extent = {
1410 .width = width,
1411 .height = height,
1412 },
1413 },
1414 .renderPass = pass,
1415 .framebuffer = fb,
1416 .clearValueCount = 0,
1417 .pClearValues = NULL,
1418 },
1419 VK_SUBPASS_CONTENTS_INLINE);
1420
1421 VkClearAttachment clear_att = {
1422 .aspectMask = range->aspectMask,
1423 .colorAttachment = 0,
1424 .clearValue = *clear_val,
1425 };
1426
1427 VkClearRect clear_rect = {
1428 .rect = {
1429 .offset = { 0, 0 },
1430 .extent = { width, height },
1431 },
1432 .baseArrayLayer = range->baseArrayLayer,
1433 .layerCount = 1, /* FINISHME: clear multi-layer framebuffer */
1434 };
1435
1436 emit_clear(cmd_buffer, &clear_att, &clear_rect, NULL, NULL, 0);
1437
1438 radv_CmdEndRenderPass(radv_cmd_buffer_to_handle(cmd_buffer));
1439 radv_DestroyRenderPass(device_h, pass,
1440 &cmd_buffer->pool->alloc);
1441 radv_DestroyFramebuffer(device_h, fb,
1442 &cmd_buffer->pool->alloc);
1443 }
1444 static void
1445 radv_cmd_clear_image(struct radv_cmd_buffer *cmd_buffer,
1446 struct radv_image *image,
1447 VkImageLayout image_layout,
1448 const VkClearValue *clear_value,
1449 uint32_t range_count,
1450 const VkImageSubresourceRange *ranges,
1451 bool cs)
1452 {
1453 VkFormat format = image->vk_format;
1454 VkClearValue internal_clear_value = *clear_value;
1455
1456 if (format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) {
1457 uint32_t value;
1458 format = VK_FORMAT_R32_UINT;
1459 value = float3_to_rgb9e5(clear_value->color.float32);
1460 internal_clear_value.color.uint32[0] = value;
1461 }
1462
1463 if (format == VK_FORMAT_R4G4_UNORM_PACK8) {
1464 uint8_t r, g;
1465 format = VK_FORMAT_R8_UINT;
1466 r = float_to_ubyte(clear_value->color.float32[0]) >> 4;
1467 g = float_to_ubyte(clear_value->color.float32[1]) >> 4;
1468 internal_clear_value.color.uint32[0] = (r << 4) | (g & 0xf);
1469 }
1470
1471 for (uint32_t r = 0; r < range_count; r++) {
1472 const VkImageSubresourceRange *range = &ranges[r];
1473 for (uint32_t l = 0; l < radv_get_levelCount(image, range); ++l) {
1474 const uint32_t layer_count = image->type == VK_IMAGE_TYPE_3D ?
1475 radv_minify(image->info.depth, range->baseMipLevel + l) :
1476 radv_get_layerCount(image, range);
1477 for (uint32_t s = 0; s < layer_count; ++s) {
1478
1479 if (cs ||
1480 (format == VK_FORMAT_R32G32B32_UINT ||
1481 format == VK_FORMAT_R32G32B32_SINT ||
1482 format == VK_FORMAT_R32G32B32_SFLOAT)) {
1483 struct radv_meta_blit2d_surf surf;
1484 surf.format = format;
1485 surf.image = image;
1486 surf.level = range->baseMipLevel + l;
1487 surf.layer = range->baseArrayLayer + s;
1488 surf.aspect_mask = range->aspectMask;
1489 radv_meta_clear_image_cs(cmd_buffer, &surf,
1490 &internal_clear_value.color);
1491 } else {
1492 radv_clear_image_layer(cmd_buffer, image, image_layout,
1493 range, format, l, s, &internal_clear_value);
1494 }
1495 }
1496 }
1497 }
1498 }
1499
1500 void radv_CmdClearColorImage(
1501 VkCommandBuffer commandBuffer,
1502 VkImage image_h,
1503 VkImageLayout imageLayout,
1504 const VkClearColorValue* pColor,
1505 uint32_t rangeCount,
1506 const VkImageSubresourceRange* pRanges)
1507 {
1508 RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
1509 RADV_FROM_HANDLE(radv_image, image, image_h);
1510 struct radv_meta_saved_state saved_state;
1511 bool cs = cmd_buffer->queue_family_index == RADV_QUEUE_COMPUTE;
1512
1513 if (cs) {
1514 radv_meta_save(&saved_state, cmd_buffer,
1515 RADV_META_SAVE_COMPUTE_PIPELINE |
1516 RADV_META_SAVE_CONSTANTS |
1517 RADV_META_SAVE_DESCRIPTORS);
1518 } else {
1519 radv_meta_save(&saved_state, cmd_buffer,
1520 RADV_META_SAVE_GRAPHICS_PIPELINE |
1521 RADV_META_SAVE_CONSTANTS);
1522 }
1523
1524 radv_cmd_clear_image(cmd_buffer, image, imageLayout,
1525 (const VkClearValue *) pColor,
1526 rangeCount, pRanges, cs);
1527
1528 radv_meta_restore(&saved_state, cmd_buffer);
1529 }
1530
1531 void radv_CmdClearDepthStencilImage(
1532 VkCommandBuffer commandBuffer,
1533 VkImage image_h,
1534 VkImageLayout imageLayout,
1535 const VkClearDepthStencilValue* pDepthStencil,
1536 uint32_t rangeCount,
1537 const VkImageSubresourceRange* pRanges)
1538 {
1539 RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
1540 RADV_FROM_HANDLE(radv_image, image, image_h);
1541 struct radv_meta_saved_state saved_state;
1542
1543 radv_meta_save(&saved_state, cmd_buffer,
1544 RADV_META_SAVE_GRAPHICS_PIPELINE |
1545 RADV_META_SAVE_CONSTANTS);
1546
1547 radv_cmd_clear_image(cmd_buffer, image, imageLayout,
1548 (const VkClearValue *) pDepthStencil,
1549 rangeCount, pRanges, false);
1550
1551 radv_meta_restore(&saved_state, cmd_buffer);
1552 }
1553
1554 void radv_CmdClearAttachments(
1555 VkCommandBuffer commandBuffer,
1556 uint32_t attachmentCount,
1557 const VkClearAttachment* pAttachments,
1558 uint32_t rectCount,
1559 const VkClearRect* pRects)
1560 {
1561 RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
1562 struct radv_meta_saved_state saved_state;
1563 enum radv_cmd_flush_bits pre_flush = 0;
1564 enum radv_cmd_flush_bits post_flush = 0;
1565
1566 if (!cmd_buffer->state.subpass)
1567 return;
1568
1569 radv_meta_save(&saved_state, cmd_buffer,
1570 RADV_META_SAVE_GRAPHICS_PIPELINE |
1571 RADV_META_SAVE_CONSTANTS);
1572
1573 /* FINISHME: We can do better than this dumb loop. It thrashes too much
1574 * state.
1575 */
1576 for (uint32_t a = 0; a < attachmentCount; ++a) {
1577 for (uint32_t r = 0; r < rectCount; ++r) {
1578 emit_clear(cmd_buffer, &pAttachments[a], &pRects[r], &pre_flush, &post_flush,
1579 cmd_buffer->state.subpass->view_mask);
1580 }
1581 }
1582
1583 radv_meta_restore(&saved_state, cmd_buffer);
1584 cmd_buffer->state.flush_bits |= post_flush;
1585 }