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_meta.h"
25#include "radv_private.h"
26#include "nir/nir_builder.h"
27
28#include "util/format_rgb9e5.h"
29#include "vk_format.h"
30/** Vertex attributes for color clears.  */
31struct color_clear_vattrs {
32	float position[2];
33	VkClearColorValue color;
34};
35
36/** Vertex attributes for depthstencil clears.  */
37struct depthstencil_clear_vattrs {
38	float position[2];
39	float depth_clear;
40};
41
42enum {
43	DEPTH_CLEAR_SLOW,
44	DEPTH_CLEAR_FAST_EXPCLEAR,
45	DEPTH_CLEAR_FAST_NO_EXPCLEAR
46};
47
48static void
49build_color_shaders(struct nir_shader **out_vs,
50                    struct nir_shader **out_fs,
51                    uint32_t frag_output)
52{
53	nir_builder vs_b;
54	nir_builder fs_b;
55
56	nir_builder_init_simple_shader(&vs_b, NULL, MESA_SHADER_VERTEX, NULL);
57	nir_builder_init_simple_shader(&fs_b, NULL, MESA_SHADER_FRAGMENT, NULL);
58
59	vs_b.shader->info->name = ralloc_strdup(vs_b.shader, "meta_clear_color_vs");
60	fs_b.shader->info->name = ralloc_strdup(fs_b.shader, "meta_clear_color_fs");
61
62	const struct glsl_type *position_type = glsl_vec4_type();
63	const struct glsl_type *color_type = glsl_vec4_type();
64
65	nir_variable *vs_in_pos =
66		nir_variable_create(vs_b.shader, nir_var_shader_in, position_type,
67				    "a_position");
68	vs_in_pos->data.location = VERT_ATTRIB_GENERIC0;
69
70	nir_variable *vs_out_pos =
71		nir_variable_create(vs_b.shader, nir_var_shader_out, position_type,
72				    "gl_Position");
73	vs_out_pos->data.location = VARYING_SLOT_POS;
74
75	nir_variable *vs_in_color =
76		nir_variable_create(vs_b.shader, nir_var_shader_in, color_type,
77				    "a_color");
78	vs_in_color->data.location = VERT_ATTRIB_GENERIC1;
79
80	nir_variable *vs_out_color =
81		nir_variable_create(vs_b.shader, nir_var_shader_out, color_type,
82				    "v_color");
83	vs_out_color->data.location = VARYING_SLOT_VAR0;
84	vs_out_color->data.interpolation = INTERP_MODE_FLAT;
85
86	nir_variable *fs_in_color =
87		nir_variable_create(fs_b.shader, nir_var_shader_in, color_type,
88				    "v_color");
89	fs_in_color->data.location = vs_out_color->data.location;
90	fs_in_color->data.interpolation = vs_out_color->data.interpolation;
91
92	nir_variable *fs_out_color =
93		nir_variable_create(fs_b.shader, nir_var_shader_out, color_type,
94				    "f_color");
95	fs_out_color->data.location = FRAG_RESULT_DATA0 + frag_output;
96
97	nir_copy_var(&vs_b, vs_out_pos, vs_in_pos);
98	nir_copy_var(&vs_b, vs_out_color, vs_in_color);
99	nir_copy_var(&fs_b, fs_out_color, fs_in_color);
100
101	const struct glsl_type *layer_type = glsl_int_type();
102	nir_variable *vs_out_layer =
103		nir_variable_create(vs_b.shader, nir_var_shader_out, layer_type,
104				    "v_layer");
105	vs_out_layer->data.location = VARYING_SLOT_LAYER;
106	vs_out_layer->data.interpolation = INTERP_MODE_FLAT;
107	nir_ssa_def *inst_id = nir_load_system_value(&vs_b, nir_intrinsic_load_instance_id, 0);
108
109	nir_store_var(&vs_b, vs_out_layer, inst_id, 0x1);
110
111	*out_vs = vs_b.shader;
112	*out_fs = fs_b.shader;
113}
114
115static VkResult
116create_pipeline(struct radv_device *device,
117		struct radv_render_pass *render_pass,
118		uint32_t samples,
119                struct nir_shader *vs_nir,
120                struct nir_shader *fs_nir,
121                const VkPipelineVertexInputStateCreateInfo *vi_state,
122                const VkPipelineDepthStencilStateCreateInfo *ds_state,
123                const VkPipelineColorBlendStateCreateInfo *cb_state,
124		const struct radv_graphics_pipeline_create_info *extra,
125                const VkAllocationCallbacks *alloc,
126                struct radv_pipeline **pipeline)
127{
128	VkDevice device_h = radv_device_to_handle(device);
129	VkResult result;
130
131	struct radv_shader_module vs_m = { .nir = vs_nir };
132	struct radv_shader_module fs_m = { .nir = fs_nir };
133
134	VkPipeline pipeline_h = VK_NULL_HANDLE;
135	result = radv_graphics_pipeline_create(device_h,
136					       radv_pipeline_cache_to_handle(&device->meta_state.cache),
137					       &(VkGraphicsPipelineCreateInfo) {
138						       .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
139							       .stageCount = fs_nir ? 2 : 1,
140							       .pStages = (VkPipelineShaderStageCreateInfo[]) {
141							       {
142								       .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
143								       .stage = VK_SHADER_STAGE_VERTEX_BIT,
144								       .module = radv_shader_module_to_handle(&vs_m),
145								       .pName = "main",
146							       },
147							       {
148								       .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
149								       .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
150								       .module = radv_shader_module_to_handle(&fs_m),
151								       .pName = "main",
152							       },
153						       },
154							       .pVertexInputState = vi_state,
155									.pInputAssemblyState = &(VkPipelineInputAssemblyStateCreateInfo) {
156							       .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
157							       .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
158							       .primitiveRestartEnable = false,
159						       },
160									.pViewportState = &(VkPipelineViewportStateCreateInfo) {
161							       .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
162							       .viewportCount = 0,
163							       .scissorCount = 0,
164						       },
165										 .pRasterizationState = &(VkPipelineRasterizationStateCreateInfo) {
166							       .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
167							       .rasterizerDiscardEnable = false,
168							       .polygonMode = VK_POLYGON_MODE_FILL,
169							       .cullMode = VK_CULL_MODE_NONE,
170							       .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
171							       .depthBiasEnable = false,
172						       },
173											  .pMultisampleState = &(VkPipelineMultisampleStateCreateInfo) {
174							       .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
175							       .rasterizationSamples = samples,
176							       .sampleShadingEnable = false,
177							       .pSampleMask = NULL,
178							       .alphaToCoverageEnable = false,
179							       .alphaToOneEnable = false,
180						       },
181												   .pDepthStencilState = ds_state,
182													    .pColorBlendState = cb_state,
183													    .pDynamicState = &(VkPipelineDynamicStateCreateInfo) {
184							       /* The meta clear pipeline declares all state as dynamic.
185								* As a consequence, vkCmdBindPipeline writes no dynamic state
186								* to the cmd buffer. Therefore, at the end of the meta clear,
187								* we need only restore dynamic state was vkCmdSet.
188								*/
189							       .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
190							       .dynamicStateCount = 6,
191							       .pDynamicStates = (VkDynamicState[]) {
192								       /* Everything except stencil write mask */
193								       VK_DYNAMIC_STATE_LINE_WIDTH,
194								       VK_DYNAMIC_STATE_DEPTH_BIAS,
195								       VK_DYNAMIC_STATE_BLEND_CONSTANTS,
196								       VK_DYNAMIC_STATE_DEPTH_BOUNDS,
197								       VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
198								       VK_DYNAMIC_STATE_STENCIL_REFERENCE,
199							       },
200						       },
201													    .flags = 0,
202														     .renderPass = radv_render_pass_to_handle(render_pass),
203														     .subpass = 0,
204														     },
205					       extra,
206					       alloc,
207					       &pipeline_h);
208
209	ralloc_free(vs_nir);
210	ralloc_free(fs_nir);
211
212	*pipeline = radv_pipeline_from_handle(pipeline_h);
213
214	return result;
215}
216
217static VkResult
218create_color_renderpass(struct radv_device *device,
219			VkFormat vk_format,
220			uint32_t samples,
221			VkRenderPass *pass)
222{
223	return radv_CreateRenderPass(radv_device_to_handle(device),
224				       &(VkRenderPassCreateInfo) {
225					       .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
226						       .attachmentCount = 1,
227						       .pAttachments = &(VkAttachmentDescription) {
228						       .format = vk_format,
229						       .samples = samples,
230						       .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
231						       .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
232						       .initialLayout = VK_IMAGE_LAYOUT_GENERAL,
233						       .finalLayout = VK_IMAGE_LAYOUT_GENERAL,
234					       },
235						       .subpassCount = 1,
236								.pSubpasses = &(VkSubpassDescription) {
237						       .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
238						       .inputAttachmentCount = 0,
239						       .colorAttachmentCount = 1,
240						       .pColorAttachments = &(VkAttachmentReference) {
241							       .attachment = 0,
242							       .layout = VK_IMAGE_LAYOUT_GENERAL,
243						       },
244						       .pResolveAttachments = NULL,
245						       .pDepthStencilAttachment = &(VkAttachmentReference) {
246							       .attachment = VK_ATTACHMENT_UNUSED,
247							       .layout = VK_IMAGE_LAYOUT_GENERAL,
248						       },
249						       .preserveAttachmentCount = 1,
250						       .pPreserveAttachments = (uint32_t[]) { 0 },
251					       },
252								.dependencyCount = 0,
253									 }, &device->meta_state.alloc, pass);
254}
255
256static VkResult
257create_color_pipeline(struct radv_device *device,
258		      uint32_t samples,
259                      uint32_t frag_output,
260                      struct radv_pipeline **pipeline,
261		      VkRenderPass pass)
262{
263	struct nir_shader *vs_nir;
264	struct nir_shader *fs_nir;
265	VkResult result;
266	build_color_shaders(&vs_nir, &fs_nir, frag_output);
267
268	const VkPipelineVertexInputStateCreateInfo vi_state = {
269		.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
270		.vertexBindingDescriptionCount = 1,
271		.pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) {
272			{
273				.binding = 0,
274				.stride = sizeof(struct color_clear_vattrs),
275				.inputRate = VK_VERTEX_INPUT_RATE_VERTEX
276			},
277		},
278		.vertexAttributeDescriptionCount = 2,
279		.pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[]) {
280			{
281				/* Position */
282				.location = 0,
283				.binding = 0,
284				.format = VK_FORMAT_R32G32_SFLOAT,
285				.offset = offsetof(struct color_clear_vattrs, position),
286			},
287			{
288				/* Color */
289				.location = 1,
290				.binding = 0,
291				.format = VK_FORMAT_R32G32B32A32_SFLOAT,
292				.offset = offsetof(struct color_clear_vattrs, color),
293			},
294		},
295	};
296
297	const VkPipelineDepthStencilStateCreateInfo ds_state = {
298		.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
299		.depthTestEnable = false,
300		.depthWriteEnable = false,
301		.depthBoundsTestEnable = false,
302		.stencilTestEnable = false,
303	};
304
305	VkPipelineColorBlendAttachmentState blend_attachment_state[MAX_RTS] = { 0 };
306	blend_attachment_state[frag_output] = (VkPipelineColorBlendAttachmentState) {
307		.blendEnable = false,
308		.colorWriteMask = VK_COLOR_COMPONENT_A_BIT |
309		VK_COLOR_COMPONENT_R_BIT |
310		VK_COLOR_COMPONENT_G_BIT |
311		VK_COLOR_COMPONENT_B_BIT,
312	};
313
314	const VkPipelineColorBlendStateCreateInfo cb_state = {
315		.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
316		.logicOpEnable = false,
317		.attachmentCount = MAX_RTS,
318		.pAttachments = blend_attachment_state
319	};
320
321
322	struct radv_graphics_pipeline_create_info extra = {
323		.use_rectlist = true,
324	};
325	result = create_pipeline(device, radv_render_pass_from_handle(pass),
326				 samples, vs_nir, fs_nir, &vi_state, &ds_state, &cb_state,
327				 &extra, &device->meta_state.alloc, pipeline);
328
329	return result;
330}
331
332static void
333destroy_pipeline(struct radv_device *device, struct radv_pipeline *pipeline)
334{
335	if (!pipeline)
336		return;
337
338	radv_DestroyPipeline(radv_device_to_handle(device),
339				   radv_pipeline_to_handle(pipeline),
340				   &device->meta_state.alloc);
341
342}
343
344static void
345destroy_render_pass(struct radv_device *device, VkRenderPass renderpass)
346{
347	radv_DestroyRenderPass(radv_device_to_handle(device), renderpass,
348				     &device->meta_state.alloc);
349}
350
351void
352radv_device_finish_meta_clear_state(struct radv_device *device)
353{
354	struct radv_meta_state *state = &device->meta_state;
355
356	for (uint32_t i = 0; i < ARRAY_SIZE(state->clear); ++i) {
357		for (uint32_t j = 0; j < ARRAY_SIZE(state->clear[i].color_pipelines); ++j) {
358			destroy_pipeline(device, state->clear[i].color_pipelines[j]);
359			destroy_render_pass(device, state->clear[i].render_pass[j]);
360		}
361
362		for (uint32_t j = 0; j < NUM_DEPTH_CLEAR_PIPELINES; j++) {
363			destroy_pipeline(device, state->clear[i].depth_only_pipeline[j]);
364			destroy_pipeline(device, state->clear[i].stencil_only_pipeline[j]);
365			destroy_pipeline(device, state->clear[i].depthstencil_pipeline[j]);
366		}
367		destroy_render_pass(device, state->clear[i].depthstencil_rp);
368	}
369
370}
371
372static void
373emit_color_clear(struct radv_cmd_buffer *cmd_buffer,
374                 const VkClearAttachment *clear_att,
375                 const VkClearRect *clear_rect)
376{
377	struct radv_device *device = cmd_buffer->device;
378	const struct radv_subpass *subpass = cmd_buffer->state.subpass;
379	const struct radv_framebuffer *fb = cmd_buffer->state.framebuffer;
380	const uint32_t subpass_att = clear_att->colorAttachment;
381	const uint32_t pass_att = subpass->color_attachments[subpass_att].attachment;
382	const struct radv_image_view *iview = fb->attachments[pass_att].attachment;
383	const uint32_t samples = iview->image->samples;
384	const uint32_t samples_log2 = ffs(samples) - 1;
385	unsigned fs_key = radv_format_meta_fs_key(iview->vk_format);
386	struct radv_pipeline *pipeline;
387	VkClearColorValue clear_value = clear_att->clearValue.color;
388	VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer);
389	VkPipeline pipeline_h;
390	uint32_t offset;
391
392	if (fs_key == -1) {
393		radv_finishme("color clears incomplete");
394		return;
395	}
396	pipeline = device->meta_state.clear[samples_log2].color_pipelines[fs_key];
397	pipeline_h = radv_pipeline_to_handle(pipeline);
398
399	if (!pipeline) {
400		radv_finishme("color clears incomplete");
401		return;
402	}
403	assert(samples_log2 < ARRAY_SIZE(device->meta_state.clear));
404	assert(pipeline);
405	assert(clear_att->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
406	assert(clear_att->colorAttachment < subpass->color_count);
407
408	const struct color_clear_vattrs vertex_data[3] = {
409		{
410			.position = {
411				clear_rect->rect.offset.x,
412				clear_rect->rect.offset.y,
413			},
414			.color = clear_value,
415		},
416		{
417			.position = {
418				clear_rect->rect.offset.x,
419				clear_rect->rect.offset.y + clear_rect->rect.extent.height,
420			},
421			.color = clear_value,
422		},
423		{
424			.position = {
425				clear_rect->rect.offset.x + clear_rect->rect.extent.width,
426				clear_rect->rect.offset.y,
427			},
428			.color = clear_value,
429		},
430	};
431
432	struct radv_subpass clear_subpass = {
433		.color_count = 1,
434		.color_attachments = (VkAttachmentReference[]) {
435			subpass->color_attachments[clear_att->colorAttachment]
436		},
437		.depth_stencil_attachment = (VkAttachmentReference) { VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_UNDEFINED }
438	};
439
440	radv_cmd_buffer_set_subpass(cmd_buffer, &clear_subpass, false);
441
442	radv_cmd_buffer_upload_data(cmd_buffer, sizeof(vertex_data), 16, vertex_data, &offset);
443	struct radv_buffer vertex_buffer = {
444		.device = device,
445		.size = sizeof(vertex_data),
446		.bo = cmd_buffer->upload.upload_bo,
447		.offset = offset,
448	};
449
450
451	radv_CmdBindVertexBuffers(cmd_buffer_h, 0, 1,
452					(VkBuffer[]) { radv_buffer_to_handle(&vertex_buffer) },
453					(VkDeviceSize[]) { 0 });
454
455	if (cmd_buffer->state.pipeline != pipeline) {
456		radv_CmdBindPipeline(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS,
457					   pipeline_h);
458	}
459
460	radv_CmdDraw(cmd_buffer_h, 3, clear_rect->layerCount, 0, 0);
461
462	radv_cmd_buffer_set_subpass(cmd_buffer, subpass, false);
463}
464
465
466static void
467build_depthstencil_shader(struct nir_shader **out_vs, struct nir_shader **out_fs)
468{
469	nir_builder vs_b, fs_b;
470
471	nir_builder_init_simple_shader(&vs_b, NULL, MESA_SHADER_VERTEX, NULL);
472	nir_builder_init_simple_shader(&fs_b, NULL, MESA_SHADER_FRAGMENT, NULL);
473
474	vs_b.shader->info->name = ralloc_strdup(vs_b.shader, "meta_clear_depthstencil_vs");
475	fs_b.shader->info->name = ralloc_strdup(fs_b.shader, "meta_clear_depthstencil_fs");
476	const struct glsl_type *position_type = glsl_vec4_type();
477
478	nir_variable *vs_in_pos =
479		nir_variable_create(vs_b.shader, nir_var_shader_in, position_type,
480				    "a_position");
481	vs_in_pos->data.location = VERT_ATTRIB_GENERIC0;
482
483	nir_variable *vs_out_pos =
484		nir_variable_create(vs_b.shader, nir_var_shader_out, position_type,
485				    "gl_Position");
486	vs_out_pos->data.location = VARYING_SLOT_POS;
487
488	nir_copy_var(&vs_b, vs_out_pos, vs_in_pos);
489
490	const struct glsl_type *layer_type = glsl_int_type();
491	nir_variable *vs_out_layer =
492		nir_variable_create(vs_b.shader, nir_var_shader_out, layer_type,
493				    "v_layer");
494	vs_out_layer->data.location = VARYING_SLOT_LAYER;
495	vs_out_layer->data.interpolation = INTERP_MODE_FLAT;
496	nir_ssa_def *inst_id = nir_load_system_value(&vs_b, nir_intrinsic_load_instance_id, 0);
497	nir_store_var(&vs_b, vs_out_layer, inst_id, 0x1);
498
499	*out_vs = vs_b.shader;
500	*out_fs = fs_b.shader;
501}
502
503static VkResult
504create_depthstencil_renderpass(struct radv_device *device,
505			       uint32_t samples,
506			       VkRenderPass *render_pass)
507{
508	return radv_CreateRenderPass(radv_device_to_handle(device),
509				       &(VkRenderPassCreateInfo) {
510					       .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
511						       .attachmentCount = 1,
512						       .pAttachments = &(VkAttachmentDescription) {
513						       .format = VK_FORMAT_UNDEFINED,
514						       .samples = samples,
515						       .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
516						       .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
517						       .initialLayout = VK_IMAGE_LAYOUT_GENERAL,
518						       .finalLayout = VK_IMAGE_LAYOUT_GENERAL,
519					       },
520						       .subpassCount = 1,
521								.pSubpasses = &(VkSubpassDescription) {
522						       .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
523						       .inputAttachmentCount = 0,
524						       .colorAttachmentCount = 0,
525						       .pColorAttachments = NULL,
526						       .pResolveAttachments = NULL,
527						       .pDepthStencilAttachment = &(VkAttachmentReference) {
528							       .attachment = 0,
529							       .layout = VK_IMAGE_LAYOUT_GENERAL,
530						       },
531						       .preserveAttachmentCount = 1,
532						       .pPreserveAttachments = (uint32_t[]) { 0 },
533					       },
534								.dependencyCount = 0,
535									 }, &device->meta_state.alloc, render_pass);
536}
537
538static VkResult
539create_depthstencil_pipeline(struct radv_device *device,
540                             VkImageAspectFlags aspects,
541			     uint32_t samples,
542			     int index,
543                             struct radv_pipeline **pipeline,
544			     VkRenderPass render_pass)
545{
546	struct nir_shader *vs_nir, *fs_nir;
547	VkResult result;
548	build_depthstencil_shader(&vs_nir, &fs_nir);
549
550	const VkPipelineVertexInputStateCreateInfo vi_state = {
551		.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
552		.vertexBindingDescriptionCount = 1,
553		.pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) {
554			{
555				.binding = 0,
556				.stride = sizeof(struct depthstencil_clear_vattrs),
557				.inputRate = VK_VERTEX_INPUT_RATE_VERTEX
558			},
559		},
560		.vertexAttributeDescriptionCount = 1,
561		.pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[]) {
562			{
563				/* Position */
564				.location = 0,
565				.binding = 0,
566				.format = VK_FORMAT_R32G32B32_SFLOAT,
567				.offset = offsetof(struct depthstencil_clear_vattrs, position),
568			},
569		},
570	};
571
572	const VkPipelineDepthStencilStateCreateInfo ds_state = {
573		.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
574		.depthTestEnable = (aspects & VK_IMAGE_ASPECT_DEPTH_BIT),
575		.depthCompareOp = VK_COMPARE_OP_ALWAYS,
576		.depthWriteEnable = (aspects & VK_IMAGE_ASPECT_DEPTH_BIT),
577		.depthBoundsTestEnable = false,
578		.stencilTestEnable = (aspects & VK_IMAGE_ASPECT_STENCIL_BIT),
579		.front = {
580			.passOp = VK_STENCIL_OP_REPLACE,
581			.compareOp = VK_COMPARE_OP_ALWAYS,
582			.writeMask = UINT32_MAX,
583			.reference = 0, /* dynamic */
584		},
585		.back = { 0 /* dont care */ },
586	};
587
588	const VkPipelineColorBlendStateCreateInfo cb_state = {
589		.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
590		.logicOpEnable = false,
591		.attachmentCount = 0,
592		.pAttachments = NULL,
593	};
594
595	struct radv_graphics_pipeline_create_info extra = {
596		.use_rectlist = true,
597	};
598
599	if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {
600		extra.db_depth_clear = index == DEPTH_CLEAR_SLOW ? false : true;
601		extra.db_depth_disable_expclear = index == DEPTH_CLEAR_FAST_NO_EXPCLEAR ? true : false;
602	}
603	if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
604		extra.db_stencil_clear = index == DEPTH_CLEAR_SLOW ? false : true;
605		extra.db_stencil_disable_expclear = index == DEPTH_CLEAR_FAST_NO_EXPCLEAR ? true : false;
606	}
607	result = create_pipeline(device, radv_render_pass_from_handle(render_pass),
608				 samples, vs_nir, fs_nir, &vi_state, &ds_state, &cb_state,
609				 &extra, &device->meta_state.alloc, pipeline);
610	return result;
611}
612
613static bool depth_view_can_fast_clear(const struct radv_image_view *iview,
614				      VkImageLayout layout,
615				      const VkClearRect *clear_rect)
616{
617	if (clear_rect->rect.offset.x || clear_rect->rect.offset.y ||
618	    clear_rect->rect.extent.width != iview->extent.width ||
619	    clear_rect->rect.extent.height != iview->extent.height)
620		return false;
621	if (iview->image->htile.size &&
622	    iview->base_mip == 0 &&
623	    iview->base_layer == 0 &&
624	    radv_layout_can_expclear(iview->image, layout) &&
625	    memcmp(&iview->extent, &iview->image->extent, sizeof(iview->extent)) == 0)
626		return true;
627	return false;
628}
629
630static struct radv_pipeline *
631pick_depthstencil_pipeline(struct radv_meta_state *meta_state,
632			   const struct radv_image_view *iview,
633			   int samples_log2,
634			   VkImageAspectFlags aspects,
635			   VkImageLayout layout,
636			   const VkClearRect *clear_rect,
637			   VkClearDepthStencilValue clear_value)
638{
639	bool fast = depth_view_can_fast_clear(iview, layout, clear_rect);
640	int index = DEPTH_CLEAR_SLOW;
641
642	if (fast) {
643		/* we don't know the previous clear values, so we always have
644		 * the NO_EXPCLEAR path */
645		index = DEPTH_CLEAR_FAST_NO_EXPCLEAR;
646	}
647
648	switch (aspects) {
649	case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT:
650		return meta_state->clear[samples_log2].depthstencil_pipeline[index];
651	case VK_IMAGE_ASPECT_DEPTH_BIT:
652		return meta_state->clear[samples_log2].depth_only_pipeline[index];
653	case VK_IMAGE_ASPECT_STENCIL_BIT:
654		return meta_state->clear[samples_log2].stencil_only_pipeline[index];
655	}
656	unreachable("expected depth or stencil aspect");
657}
658
659static void
660emit_depthstencil_clear(struct radv_cmd_buffer *cmd_buffer,
661                        const VkClearAttachment *clear_att,
662                        const VkClearRect *clear_rect)
663{
664	struct radv_device *device = cmd_buffer->device;
665	struct radv_meta_state *meta_state = &device->meta_state;
666	const struct radv_subpass *subpass = cmd_buffer->state.subpass;
667	const struct radv_framebuffer *fb = cmd_buffer->state.framebuffer;
668	const uint32_t pass_att = subpass->depth_stencil_attachment.attachment;
669	VkClearDepthStencilValue clear_value = clear_att->clearValue.depthStencil;
670	VkImageAspectFlags aspects = clear_att->aspectMask;
671	const struct radv_image_view *iview = fb->attachments[pass_att].attachment;
672	const uint32_t samples = iview->image->samples;
673	const uint32_t samples_log2 = ffs(samples) - 1;
674	VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer);
675	uint32_t offset;
676
677	assert(aspects == VK_IMAGE_ASPECT_DEPTH_BIT ||
678	       aspects == VK_IMAGE_ASPECT_STENCIL_BIT ||
679	       aspects == (VK_IMAGE_ASPECT_DEPTH_BIT |
680			   VK_IMAGE_ASPECT_STENCIL_BIT));
681	assert(pass_att != VK_ATTACHMENT_UNUSED);
682
683	const struct depthstencil_clear_vattrs vertex_data[3] = {
684		{
685			.position = {
686				clear_rect->rect.offset.x,
687				clear_rect->rect.offset.y,
688			},
689			.depth_clear = clear_value.depth,
690		},
691		{
692			.position = {
693				clear_rect->rect.offset.x,
694				clear_rect->rect.offset.y + clear_rect->rect.extent.height,
695			},
696			.depth_clear = clear_value.depth,
697		},
698		{
699			.position = {
700				clear_rect->rect.offset.x + clear_rect->rect.extent.width,
701				clear_rect->rect.offset.y,
702			},
703			.depth_clear = clear_value.depth,
704		},
705	};
706
707	radv_cmd_buffer_upload_data(cmd_buffer, sizeof(vertex_data), 16, vertex_data, &offset);
708	struct radv_buffer vertex_buffer = {
709		.device = device,
710		.size = sizeof(vertex_data),
711		.bo = cmd_buffer->upload.upload_bo,
712		.offset = offset,
713	};
714
715	if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
716		radv_CmdSetStencilReference(cmd_buffer_h, VK_STENCIL_FACE_FRONT_BIT,
717						  clear_value.stencil);
718	}
719
720	radv_CmdBindVertexBuffers(cmd_buffer_h, 0, 1,
721					(VkBuffer[]) { radv_buffer_to_handle(&vertex_buffer) },
722					(VkDeviceSize[]) { 0 });
723
724	struct radv_pipeline *pipeline = pick_depthstencil_pipeline(meta_state,
725								    iview,
726								    samples_log2,
727								    aspects,
728								    subpass->depth_stencil_attachment.layout,
729								    clear_rect,
730								    clear_value);
731	if (cmd_buffer->state.pipeline != pipeline) {
732		radv_CmdBindPipeline(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS,
733					   radv_pipeline_to_handle(pipeline));
734	}
735
736	if (depth_view_can_fast_clear(iview, subpass->depth_stencil_attachment.layout, clear_rect))
737		radv_set_depth_clear_regs(cmd_buffer, iview->image, clear_value, aspects);
738
739	radv_CmdDraw(cmd_buffer_h, 3, clear_rect->layerCount, 0, 0);
740}
741
742
743static VkFormat pipeline_formats[] = {
744	VK_FORMAT_R8G8B8A8_UNORM,
745	VK_FORMAT_R8G8B8A8_UINT,
746	VK_FORMAT_R8G8B8A8_SINT,
747	VK_FORMAT_R16G16B16A16_UNORM,
748	VK_FORMAT_R16G16B16A16_SNORM,
749	VK_FORMAT_R16G16B16A16_UINT,
750	VK_FORMAT_R16G16B16A16_SINT,
751	VK_FORMAT_R32_SFLOAT,
752	VK_FORMAT_R32G32_SFLOAT,
753	VK_FORMAT_R32G32B32A32_SFLOAT
754};
755
756VkResult
757radv_device_init_meta_clear_state(struct radv_device *device)
758{
759	VkResult res;
760	struct radv_meta_state *state = &device->meta_state;
761
762	memset(&device->meta_state.clear, 0, sizeof(device->meta_state.clear));
763
764	for (uint32_t i = 0; i < ARRAY_SIZE(state->clear); ++i) {
765		uint32_t samples = 1 << i;
766		for (uint32_t j = 0; j < ARRAY_SIZE(pipeline_formats); ++j) {
767			VkFormat format = pipeline_formats[j];
768			unsigned fs_key = radv_format_meta_fs_key(format);
769			assert(!state->clear[i].color_pipelines[fs_key]);
770
771			res = create_color_renderpass(device, format, samples,
772						      &state->clear[i].render_pass[fs_key]);
773			if (res != VK_SUCCESS)
774				goto fail;
775
776			res = create_color_pipeline(device, samples, 0, &state->clear[i].color_pipelines[fs_key],
777						    state->clear[i].render_pass[fs_key]);
778			if (res != VK_SUCCESS)
779				goto fail;
780
781		}
782
783		res = create_depthstencil_renderpass(device,
784						     samples,
785						     &state->clear[i].depthstencil_rp);
786		if (res != VK_SUCCESS)
787			goto fail;
788
789		for (uint32_t j = 0; j < NUM_DEPTH_CLEAR_PIPELINES; j++) {
790			res = create_depthstencil_pipeline(device,
791							   VK_IMAGE_ASPECT_DEPTH_BIT,
792							   samples,
793							   j,
794							   &state->clear[i].depth_only_pipeline[j],
795							   state->clear[i].depthstencil_rp);
796			if (res != VK_SUCCESS)
797				goto fail;
798
799			res = create_depthstencil_pipeline(device,
800							   VK_IMAGE_ASPECT_STENCIL_BIT,
801							   samples,
802							   j,
803							   &state->clear[i].stencil_only_pipeline[j],
804							   state->clear[i].depthstencil_rp);
805			if (res != VK_SUCCESS)
806				goto fail;
807
808			res = create_depthstencil_pipeline(device,
809							   VK_IMAGE_ASPECT_DEPTH_BIT |
810							   VK_IMAGE_ASPECT_STENCIL_BIT,
811							   samples,
812							   j,
813							   &state->clear[i].depthstencil_pipeline[j],
814							   state->clear[i].depthstencil_rp);
815			if (res != VK_SUCCESS)
816				goto fail;
817		}
818	}
819	return VK_SUCCESS;
820
821fail:
822	radv_device_finish_meta_clear_state(device);
823	return res;
824}
825
826static bool
827emit_fast_color_clear(struct radv_cmd_buffer *cmd_buffer,
828		      const VkClearAttachment *clear_att,
829		      const VkClearRect *clear_rect)
830{
831	const struct radv_subpass *subpass = cmd_buffer->state.subpass;
832	const uint32_t subpass_att = clear_att->colorAttachment;
833	const uint32_t pass_att = subpass->color_attachments[subpass_att].attachment;
834	VkImageLayout image_layout = subpass->color_attachments[subpass_att].layout;
835	const struct radv_framebuffer *fb = cmd_buffer->state.framebuffer;
836	const struct radv_image_view *iview = fb->attachments[pass_att].attachment;
837	VkClearColorValue clear_value = clear_att->clearValue.color;
838	uint32_t clear_color[2];
839	bool ret;
840
841	if (!iview->image->cmask.size && !iview->image->surface.dcc_size)
842		return false;
843
844	if (!(cmd_buffer->device->debug_flags & RADV_DEBUG_FAST_CLEARS))
845		return false;
846
847	if (!radv_layout_can_fast_clear(iview->image, image_layout, radv_image_queue_family_mask(iview->image, cmd_buffer->queue_family_index)))
848		goto fail;
849	if (vk_format_get_blocksizebits(iview->image->vk_format) > 64)
850		goto fail;
851
852	/* don't fast clear 3D */
853	if (iview->image->type == VK_IMAGE_TYPE_3D)
854		goto fail;
855
856	/* all layers are bound */
857	if (iview->base_layer > 0)
858		goto fail;
859	if (iview->image->array_size != iview->layer_count)
860		goto fail;
861
862	if (iview->image->levels > 1)
863		goto fail;
864
865	if (iview->image->surface.level[0].mode < RADEON_SURF_MODE_1D)
866		goto fail;
867
868	if (memcmp(&iview->extent, &iview->image->extent, sizeof(iview->extent)))
869		goto fail;
870
871	if (clear_rect->rect.offset.x || clear_rect->rect.offset.y ||
872	    clear_rect->rect.extent.width != iview->image->extent.width ||
873	    clear_rect->rect.extent.height != iview->image->extent.height)
874		goto fail;
875
876	if (clear_rect->baseArrayLayer != 0)
877		goto fail;
878	if (clear_rect->layerCount != iview->image->array_size)
879		goto fail;
880
881	/* DCC */
882	ret = radv_format_pack_clear_color(iview->image->vk_format,
883					   clear_color, &clear_value);
884	if (ret == false)
885		goto fail;
886
887	cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_FLUSH_AND_INV_CB |
888	                                RADV_CMD_FLAG_FLUSH_AND_INV_CB_META;
889	si_emit_cache_flush(cmd_buffer);
890	/* clear cmask buffer */
891	if (iview->image->surface.dcc_size) {
892		radv_fill_buffer(cmd_buffer, iview->image->bo,
893				 iview->image->offset + iview->image->dcc_offset,
894				 iview->image->surface.dcc_size, 0x20202020);
895	} else {
896		radv_fill_buffer(cmd_buffer, iview->image->bo,
897				 iview->image->offset + iview->image->cmask.offset,
898				 iview->image->cmask.size, 0);
899	}
900	cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_CS_PARTIAL_FLUSH |
901	                                RADV_CMD_FLAG_INV_VMEM_L1 |
902	                                RADV_CMD_FLAG_INV_GLOBAL_L2;
903
904	radv_set_color_clear_regs(cmd_buffer, iview->image, subpass_att, clear_color);
905
906	return true;
907fail:
908	return false;
909}
910
911/**
912 * The parameters mean that same as those in vkCmdClearAttachments.
913 */
914static void
915emit_clear(struct radv_cmd_buffer *cmd_buffer,
916           const VkClearAttachment *clear_att,
917           const VkClearRect *clear_rect)
918{
919	if (clear_att->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
920
921		if (!emit_fast_color_clear(cmd_buffer, clear_att, clear_rect))
922			emit_color_clear(cmd_buffer, clear_att, clear_rect);
923	} else {
924		assert(clear_att->aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT |
925						VK_IMAGE_ASPECT_STENCIL_BIT));
926		emit_depthstencil_clear(cmd_buffer, clear_att, clear_rect);
927	}
928}
929
930static bool
931subpass_needs_clear(const struct radv_cmd_buffer *cmd_buffer)
932{
933	const struct radv_cmd_state *cmd_state = &cmd_buffer->state;
934	uint32_t ds;
935
936	if (!cmd_state->subpass)
937		return false;
938	ds = cmd_state->subpass->depth_stencil_attachment.attachment;
939	for (uint32_t i = 0; i < cmd_state->subpass->color_count; ++i) {
940		uint32_t a = cmd_state->subpass->color_attachments[i].attachment;
941		if (cmd_state->attachments[a].pending_clear_aspects) {
942			return true;
943		}
944	}
945
946	if (ds != VK_ATTACHMENT_UNUSED &&
947	    cmd_state->attachments[ds].pending_clear_aspects) {
948		return true;
949	}
950
951	return false;
952}
953
954/**
955 * Emit any pending attachment clears for the current subpass.
956 *
957 * @see radv_attachment_state::pending_clear_aspects
958 */
959void
960radv_cmd_buffer_clear_subpass(struct radv_cmd_buffer *cmd_buffer)
961{
962	struct radv_cmd_state *cmd_state = &cmd_buffer->state;
963	struct radv_meta_saved_state saved_state;
964
965	if (!subpass_needs_clear(cmd_buffer))
966		return;
967
968	radv_meta_save_graphics_reset_vport_scissor(&saved_state, cmd_buffer);
969
970	VkClearRect clear_rect = {
971		.rect = cmd_state->render_area,
972		.baseArrayLayer = 0,
973		.layerCount = cmd_state->framebuffer->layers,
974	};
975
976	for (uint32_t i = 0; i < cmd_state->subpass->color_count; ++i) {
977		uint32_t a = cmd_state->subpass->color_attachments[i].attachment;
978
979		if (!cmd_state->attachments[a].pending_clear_aspects)
980			continue;
981
982		assert(cmd_state->attachments[a].pending_clear_aspects ==
983		       VK_IMAGE_ASPECT_COLOR_BIT);
984
985		VkClearAttachment clear_att = {
986			.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
987			.colorAttachment = i, /* Use attachment index relative to subpass */
988			.clearValue = cmd_state->attachments[a].clear_value,
989		};
990
991		emit_clear(cmd_buffer, &clear_att, &clear_rect);
992		cmd_state->attachments[a].pending_clear_aspects = 0;
993	}
994
995	uint32_t ds = cmd_state->subpass->depth_stencil_attachment.attachment;
996
997	if (ds != VK_ATTACHMENT_UNUSED) {
998
999		if (cmd_state->attachments[ds].pending_clear_aspects) {
1000
1001			VkClearAttachment clear_att = {
1002				.aspectMask = cmd_state->attachments[ds].pending_clear_aspects,
1003				.clearValue = cmd_state->attachments[ds].clear_value,
1004			};
1005
1006			emit_clear(cmd_buffer, &clear_att, &clear_rect);
1007			cmd_state->attachments[ds].pending_clear_aspects = 0;
1008		}
1009	}
1010
1011	radv_meta_restore(&saved_state, cmd_buffer);
1012}
1013
1014static void
1015radv_clear_image_layer(struct radv_cmd_buffer *cmd_buffer,
1016		       struct radv_image *image,
1017		       VkImageLayout image_layout,
1018		       const VkImageSubresourceRange *range,
1019		       VkFormat format, int level, int layer,
1020		       const VkClearValue *clear_val)
1021{
1022	VkDevice device_h = radv_device_to_handle(cmd_buffer->device);
1023	struct radv_image_view iview;
1024	radv_image_view_init(&iview, cmd_buffer->device,
1025			     &(VkImageViewCreateInfo) {
1026				     .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
1027					     .image = radv_image_to_handle(image),
1028					     .viewType = radv_meta_get_view_type(image),
1029					     .format = format,
1030					     .subresourceRange = {
1031					     .aspectMask = range->aspectMask,
1032					     .baseMipLevel = range->baseMipLevel + level,
1033					     .levelCount = 1,
1034					     .baseArrayLayer = range->baseArrayLayer + layer,
1035					     .layerCount = 1
1036				     },
1037			     },
1038			     cmd_buffer, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
1039
1040	VkFramebuffer fb;
1041	radv_CreateFramebuffer(device_h,
1042			       &(VkFramebufferCreateInfo) {
1043				       .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
1044					       .attachmentCount = 1,
1045					       .pAttachments = (VkImageView[]) {
1046					       radv_image_view_to_handle(&iview),
1047				       },
1048					       .width = iview.extent.width,
1049							.height = iview.extent.height,
1050							.layers = 1
1051			       },
1052			       &cmd_buffer->pool->alloc,
1053			       &fb);
1054
1055	VkAttachmentDescription att_desc = {
1056		.format = iview.vk_format,
1057		.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
1058		.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
1059		.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
1060		.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE,
1061		.initialLayout = image_layout,
1062		.finalLayout = image_layout,
1063	};
1064
1065	VkSubpassDescription subpass_desc = {
1066		.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
1067		.inputAttachmentCount = 0,
1068		.colorAttachmentCount = 0,
1069		.pColorAttachments = NULL,
1070		.pResolveAttachments = NULL,
1071		.pDepthStencilAttachment = NULL,
1072		.preserveAttachmentCount = 0,
1073		.pPreserveAttachments = NULL,
1074	};
1075
1076	const VkAttachmentReference att_ref = {
1077		.attachment = 0,
1078		.layout = image_layout,
1079	};
1080
1081	if (range->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
1082		subpass_desc.colorAttachmentCount = 1;
1083		subpass_desc.pColorAttachments = &att_ref;
1084	} else {
1085		subpass_desc.pDepthStencilAttachment = &att_ref;
1086	}
1087
1088	VkRenderPass pass;
1089	radv_CreateRenderPass(device_h,
1090			      &(VkRenderPassCreateInfo) {
1091				      .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
1092					      .attachmentCount = 1,
1093					      .pAttachments = &att_desc,
1094					      .subpassCount = 1,
1095					      .pSubpasses = &subpass_desc,
1096					      },
1097			      &cmd_buffer->pool->alloc,
1098			      &pass);
1099
1100	radv_CmdBeginRenderPass(radv_cmd_buffer_to_handle(cmd_buffer),
1101				&(VkRenderPassBeginInfo) {
1102					.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
1103						.renderArea = {
1104						.offset = { 0, 0, },
1105						.extent = {
1106							.width = iview.extent.width,
1107							.height = iview.extent.height,
1108						},
1109					},
1110						.renderPass = pass,
1111						.framebuffer = fb,
1112						.clearValueCount = 0,
1113						.pClearValues = NULL,
1114						},
1115				VK_SUBPASS_CONTENTS_INLINE);
1116
1117	VkClearAttachment clear_att = {
1118		.aspectMask = range->aspectMask,
1119		.colorAttachment = 0,
1120		.clearValue = *clear_val,
1121	};
1122
1123	VkClearRect clear_rect = {
1124		.rect = {
1125			.offset = { 0, 0 },
1126			.extent = { iview.extent.width, iview.extent.height },
1127		},
1128		.baseArrayLayer = range->baseArrayLayer,
1129		.layerCount = 1, /* FINISHME: clear multi-layer framebuffer */
1130	};
1131
1132	emit_clear(cmd_buffer, &clear_att, &clear_rect);
1133
1134	radv_CmdEndRenderPass(radv_cmd_buffer_to_handle(cmd_buffer));
1135	radv_DestroyRenderPass(device_h, pass,
1136			       &cmd_buffer->pool->alloc);
1137	radv_DestroyFramebuffer(device_h, fb,
1138				&cmd_buffer->pool->alloc);
1139}
1140static void
1141radv_cmd_clear_image(struct radv_cmd_buffer *cmd_buffer,
1142		     struct radv_image *image,
1143		     VkImageLayout image_layout,
1144		     const VkClearValue *clear_value,
1145		     uint32_t range_count,
1146		     const VkImageSubresourceRange *ranges,
1147		     bool cs)
1148{
1149	VkFormat format = image->vk_format;
1150	VkClearValue internal_clear_value = *clear_value;
1151
1152	if (format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) {
1153		uint32_t value;
1154		format = VK_FORMAT_R32_UINT;
1155		value = float3_to_rgb9e5(clear_value->color.float32);
1156		internal_clear_value.color.uint32[0] = value;
1157	}
1158
1159	for (uint32_t r = 0; r < range_count; r++) {
1160		const VkImageSubresourceRange *range = &ranges[r];
1161		for (uint32_t l = 0; l < radv_get_levelCount(image, range); ++l) {
1162			const uint32_t layer_count = image->type == VK_IMAGE_TYPE_3D ?
1163				radv_minify(image->extent.depth, range->baseMipLevel + l) :
1164				radv_get_layerCount(image, range);
1165			for (uint32_t s = 0; s < layer_count; ++s) {
1166
1167				if (cs) {
1168					struct radv_meta_blit2d_surf surf;
1169					surf.format = format;
1170					surf.image = image;
1171					surf.level = range->baseMipLevel + l;
1172					surf.layer = range->baseArrayLayer + s;
1173					surf.aspect_mask = range->aspectMask;
1174					radv_meta_clear_image_cs(cmd_buffer, &surf,
1175								 &internal_clear_value.color);
1176				} else {
1177					radv_clear_image_layer(cmd_buffer, image, image_layout,
1178							       range, format, l, s, &internal_clear_value);
1179				}
1180			}
1181		}
1182	}
1183}
1184
1185union meta_saved_state {
1186	struct radv_meta_saved_state gfx;
1187	struct radv_meta_saved_compute_state compute;
1188};
1189
1190void radv_CmdClearColorImage(
1191	VkCommandBuffer                             commandBuffer,
1192	VkImage                                     image_h,
1193	VkImageLayout                               imageLayout,
1194	const VkClearColorValue*                    pColor,
1195	uint32_t                                    rangeCount,
1196	const VkImageSubresourceRange*              pRanges)
1197{
1198	RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
1199	RADV_FROM_HANDLE(radv_image, image, image_h);
1200	union meta_saved_state saved_state;
1201	bool cs = cmd_buffer->queue_family_index == RADV_QUEUE_COMPUTE;
1202
1203	if (cs)
1204		radv_meta_begin_cleari(cmd_buffer, &saved_state.compute);
1205	else
1206		radv_meta_save_graphics_reset_vport_scissor(&saved_state.gfx, cmd_buffer);
1207
1208	radv_cmd_clear_image(cmd_buffer, image, imageLayout,
1209			     (const VkClearValue *) pColor,
1210			     rangeCount, pRanges, cs);
1211
1212	if (cs)
1213		radv_meta_end_cleari(cmd_buffer, &saved_state.compute);
1214	else
1215		radv_meta_restore(&saved_state.gfx, cmd_buffer);
1216}
1217
1218void radv_CmdClearDepthStencilImage(
1219	VkCommandBuffer                             commandBuffer,
1220	VkImage                                     image_h,
1221	VkImageLayout                               imageLayout,
1222	const VkClearDepthStencilValue*             pDepthStencil,
1223	uint32_t                                    rangeCount,
1224	const VkImageSubresourceRange*              pRanges)
1225{
1226	RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
1227	RADV_FROM_HANDLE(radv_image, image, image_h);
1228	struct radv_meta_saved_state saved_state;
1229
1230	radv_meta_save_graphics_reset_vport_scissor(&saved_state, cmd_buffer);
1231
1232	radv_cmd_clear_image(cmd_buffer, image, imageLayout,
1233			     (const VkClearValue *) pDepthStencil,
1234			     rangeCount, pRanges, false);
1235
1236	radv_meta_restore(&saved_state, cmd_buffer);
1237}
1238
1239void radv_CmdClearAttachments(
1240	VkCommandBuffer                             commandBuffer,
1241	uint32_t                                    attachmentCount,
1242	const VkClearAttachment*                    pAttachments,
1243	uint32_t                                    rectCount,
1244	const VkClearRect*                          pRects)
1245{
1246	RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
1247	struct radv_meta_saved_state saved_state;
1248
1249	if (!cmd_buffer->state.subpass)
1250		return;
1251
1252	radv_meta_save_graphics_reset_vport_scissor(&saved_state, cmd_buffer);
1253
1254	/* FINISHME: We can do better than this dumb loop. It thrashes too much
1255	 * state.
1256	 */
1257	for (uint32_t a = 0; a < attachmentCount; ++a) {
1258		for (uint32_t r = 0; r < rectCount; ++r) {
1259			emit_clear(cmd_buffer, &pAttachments[a], &pRects[r]);
1260		}
1261	}
1262
1263	radv_meta_restore(&saved_state, cmd_buffer);
1264}
1265