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