radv_meta_clear.c revision 01e04c3f
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
32enum {
33	DEPTH_CLEAR_SLOW,
34	DEPTH_CLEAR_FAST_EXPCLEAR,
35	DEPTH_CLEAR_FAST_NO_EXPCLEAR
36};
37
38static void
39build_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
94static VkResult
95create_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
197static VkResult
198create_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
244static VkResult
245create_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
306void
307radv_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
344static void
345emit_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
439static void
440build_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_system_value(&vs_b, nir_intrinsic_load_instance_id, 0);
474	nir_ssa_def *base_instance = nir_load_system_value(&vs_b, nir_intrinsic_load_base_instance, 0);
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
483static VkResult
484create_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
526static VkResult
527create_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
595static 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
623static VkPipeline
624pick_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
677static void
678emit_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
749static bool
750emit_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;
835fail:
836	return false;
837}
838
839VkResult
840radv_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
933fail:
934	radv_device_finish_meta_clear_state(device);
935	return res;
936}
937
938static uint32_t
939radv_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
954uint32_t
955radv_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
963uint32_t
964radv_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
972static 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
1049static bool
1050emit_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;
1178fail:
1179	return false;
1180}
1181
1182/**
1183 * The parameters mean that same as those in vkCmdClearAttachments.
1184 */
1185static void
1186emit_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
1206static inline bool
1207radv_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
1215static bool
1216radv_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
1234static void
1235radv_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 */
1263void
1264radv_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
1316static void
1317radv_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}
1444static void
1445radv_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
1500void 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
1531void 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
1554void 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}
1586