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