• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2015 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 #include "radv_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.  */
31 struct color_clear_vattrs {
32 	float position[2];
33 	VkClearColorValue color;
34 };
35 
36 /** Vertex attributes for depthstencil clears.  */
37 struct depthstencil_clear_vattrs {
38 	float position[2];
39 	float depth_clear;
40 };
41 
42 enum {
43 	DEPTH_CLEAR_SLOW,
44 	DEPTH_CLEAR_FAST_EXPCLEAR,
45 	DEPTH_CLEAR_FAST_NO_EXPCLEAR
46 };
47 
48 static void
build_color_shaders(struct nir_shader ** out_vs,struct nir_shader ** out_fs,uint32_t frag_output)49 build_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 
115 static VkResult
create_pipeline(struct radv_device * device,struct radv_render_pass * render_pass,uint32_t samples,struct nir_shader * vs_nir,struct nir_shader * fs_nir,const VkPipelineVertexInputStateCreateInfo * vi_state,const VkPipelineDepthStencilStateCreateInfo * ds_state,const VkPipelineColorBlendStateCreateInfo * cb_state,const struct radv_graphics_pipeline_create_info * extra,const VkAllocationCallbacks * alloc,struct radv_pipeline ** pipeline)116 create_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 
217 static VkResult
create_color_renderpass(struct radv_device * device,VkFormat vk_format,uint32_t samples,VkRenderPass * pass)218 create_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 
256 static VkResult
create_color_pipeline(struct radv_device * device,uint32_t samples,uint32_t frag_output,struct radv_pipeline ** pipeline,VkRenderPass pass)257 create_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 
332 static void
destroy_pipeline(struct radv_device * device,struct radv_pipeline * pipeline)333 destroy_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 
344 static void
destroy_render_pass(struct radv_device * device,VkRenderPass renderpass)345 destroy_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 
351 void
radv_device_finish_meta_clear_state(struct radv_device * device)352 radv_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 
372 static void
emit_color_clear(struct radv_cmd_buffer * cmd_buffer,const VkClearAttachment * clear_att,const VkClearRect * clear_rect)373 emit_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 
466 static void
build_depthstencil_shader(struct nir_shader ** out_vs,struct nir_shader ** out_fs)467 build_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 
503 static VkResult
create_depthstencil_renderpass(struct radv_device * device,uint32_t samples,VkRenderPass * render_pass)504 create_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 
538 static VkResult
create_depthstencil_pipeline(struct radv_device * device,VkImageAspectFlags aspects,uint32_t samples,int index,struct radv_pipeline ** pipeline,VkRenderPass render_pass)539 create_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 
depth_view_can_fast_clear(const struct radv_image_view * iview,VkImageLayout layout,const VkClearRect * clear_rect)613 static 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 
630 static struct radv_pipeline *
pick_depthstencil_pipeline(struct radv_meta_state * meta_state,const struct radv_image_view * iview,int samples_log2,VkImageAspectFlags aspects,VkImageLayout layout,const VkClearRect * clear_rect,VkClearDepthStencilValue clear_value)631 pick_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 
659 static void
emit_depthstencil_clear(struct radv_cmd_buffer * cmd_buffer,const VkClearAttachment * clear_att,const VkClearRect * clear_rect)660 emit_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 
743 static 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 
756 VkResult
radv_device_init_meta_clear_state(struct radv_device * device)757 radv_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 
821 fail:
822 	radv_device_finish_meta_clear_state(device);
823 	return res;
824 }
825 
826 static bool
emit_fast_color_clear(struct radv_cmd_buffer * cmd_buffer,const VkClearAttachment * clear_att,const VkClearRect * clear_rect)827 emit_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;
907 fail:
908 	return false;
909 }
910 
911 /**
912  * The parameters mean that same as those in vkCmdClearAttachments.
913  */
914 static void
emit_clear(struct radv_cmd_buffer * cmd_buffer,const VkClearAttachment * clear_att,const VkClearRect * clear_rect)915 emit_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 
930 static bool
subpass_needs_clear(const struct radv_cmd_buffer * cmd_buffer)931 subpass_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  */
959 void
radv_cmd_buffer_clear_subpass(struct radv_cmd_buffer * cmd_buffer)960 radv_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 
1014 static void
radv_clear_image_layer(struct radv_cmd_buffer * cmd_buffer,struct radv_image * image,VkImageLayout image_layout,const VkImageSubresourceRange * range,VkFormat format,int level,int layer,const VkClearValue * clear_val)1015 radv_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 }
1140 static void
radv_cmd_clear_image(struct radv_cmd_buffer * cmd_buffer,struct radv_image * image,VkImageLayout image_layout,const VkClearValue * clear_value,uint32_t range_count,const VkImageSubresourceRange * ranges,bool cs)1141 radv_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 
1185 union meta_saved_state {
1186 	struct radv_meta_saved_state gfx;
1187 	struct radv_meta_saved_compute_state compute;
1188 };
1189 
radv_CmdClearColorImage(VkCommandBuffer commandBuffer,VkImage image_h,VkImageLayout imageLayout,const VkClearColorValue * pColor,uint32_t rangeCount,const VkImageSubresourceRange * pRanges)1190 void 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 
radv_CmdClearDepthStencilImage(VkCommandBuffer commandBuffer,VkImage image_h,VkImageLayout imageLayout,const VkClearDepthStencilValue * pDepthStencil,uint32_t rangeCount,const VkImageSubresourceRange * pRanges)1218 void 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 
radv_CmdClearAttachments(VkCommandBuffer commandBuffer,uint32_t attachmentCount,const VkClearAttachment * pAttachments,uint32_t rectCount,const VkClearRect * pRects)1239 void 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