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