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