anv: Use isl_tiling_flags in anv_image_create_info
[mesa.git] / src / vulkan / anv_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 "anv_meta.h"
25 #include "anv_meta_clear.h"
26 #include "anv_nir_builder.h"
27 #include "anv_private.h"
28
29 /** Vertex attributes for color clears. */
30 struct color_clear_vattrs {
31 struct anv_vue_header vue_header;
32 float position[2]; /**< 3DPRIM_RECTLIST */
33 VkClearColorValue color;
34 };
35
36 /** Vertex attributes for depthstencil clears. */
37 struct depthstencil_clear_vattrs {
38 struct anv_vue_header vue_header;
39 float position[2]; /*<< 3DPRIM_RECTLIST */
40 };
41
42 static void
43 meta_clear_begin(struct anv_meta_saved_state *saved_state,
44 struct anv_cmd_buffer *cmd_buffer)
45 {
46 anv_meta_save(saved_state, cmd_buffer,
47 (1 << VK_DYNAMIC_STATE_VIEWPORT) |
48 (1 << VK_DYNAMIC_STATE_SCISSOR) |
49 (1 << VK_DYNAMIC_STATE_STENCIL_REFERENCE));
50
51 cmd_buffer->state.dynamic.viewport.count = 0;
52 cmd_buffer->state.dynamic.scissor.count = 0;
53 }
54
55 static void
56 meta_clear_end(struct anv_meta_saved_state *saved_state,
57 struct anv_cmd_buffer *cmd_buffer)
58 {
59 anv_meta_restore(saved_state, cmd_buffer);
60 }
61
62 static void
63 build_color_shaders(struct nir_shader **out_vs,
64 struct nir_shader **out_fs)
65 {
66 nir_builder vs_b;
67 nir_builder fs_b;
68
69 nir_builder_init_simple_shader(&vs_b, MESA_SHADER_VERTEX);
70 nir_builder_init_simple_shader(&fs_b, MESA_SHADER_FRAGMENT);
71
72 const struct glsl_type *position_type = glsl_vec4_type();
73 const struct glsl_type *color_type = glsl_vec4_type();
74
75 nir_variable *vs_in_pos =
76 nir_variable_create(vs_b.shader, nir_var_shader_in, position_type,
77 "a_position");
78 vs_in_pos->data.location = VERT_ATTRIB_GENERIC0;
79
80 nir_variable *vs_out_pos =
81 nir_variable_create(vs_b.shader, nir_var_shader_out, position_type,
82 "gl_Position");
83 vs_out_pos->data.location = VARYING_SLOT_POS;
84
85 nir_variable *vs_in_color =
86 nir_variable_create(vs_b.shader, nir_var_shader_in, color_type,
87 "a_color");
88 vs_in_color->data.location = VERT_ATTRIB_GENERIC1;
89
90 nir_variable *vs_out_color =
91 nir_variable_create(vs_b.shader, nir_var_shader_out, color_type,
92 "v_color");
93 vs_out_color->data.location = VARYING_SLOT_VAR0;
94 vs_out_color->data.interpolation = INTERP_QUALIFIER_FLAT;
95
96 nir_variable *fs_in_color =
97 nir_variable_create(fs_b.shader, nir_var_shader_in, color_type,
98 "v_color");
99 fs_in_color->data.location = vs_out_color->data.location;
100 fs_in_color->data.interpolation = vs_out_color->data.interpolation;
101
102 nir_variable *fs_out_color =
103 nir_variable_create(fs_b.shader, nir_var_shader_out, color_type,
104 "f_color");
105 fs_out_color->data.location = FRAG_RESULT_DATA0;
106
107 nir_copy_var(&vs_b, vs_out_pos, vs_in_pos);
108 nir_copy_var(&vs_b, vs_out_color, vs_in_color);
109 nir_copy_var(&fs_b, fs_out_color, fs_in_color);
110
111 *out_vs = vs_b.shader;
112 *out_fs = fs_b.shader;
113 }
114
115 static struct anv_pipeline *
116 create_pipeline(struct anv_device *device,
117 struct nir_shader *vs_nir,
118 struct nir_shader *fs_nir,
119 const VkPipelineVertexInputStateCreateInfo *vi_state,
120 const VkPipelineDepthStencilStateCreateInfo *ds_state,
121 const VkPipelineColorBlendStateCreateInfo *cb_state,
122 const VkAllocationCallbacks *alloc)
123 {
124 VkDevice device_h = anv_device_to_handle(device);
125
126 struct anv_shader_module vs_m = { .nir = vs_nir };
127 struct anv_shader_module fs_m = { .nir = fs_nir };
128
129 VkPipeline pipeline_h;
130 anv_graphics_pipeline_create(device_h,
131 &(VkGraphicsPipelineCreateInfo) {
132 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
133 .stageCount = 2,
134 .pStages = (VkPipelineShaderStageCreateInfo[]) {
135 {
136 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
137 .stage = VK_SHADER_STAGE_VERTEX_BIT,
138 .module = anv_shader_module_to_handle(&vs_m),
139 .pName = "main",
140 },
141 {
142 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
143 .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
144 .module = anv_shader_module_to_handle(&fs_m),
145 .pName = "main",
146 },
147 },
148 .pVertexInputState = vi_state,
149 .pInputAssemblyState = &(VkPipelineInputAssemblyStateCreateInfo) {
150 .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
151 .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
152 .primitiveRestartEnable = false,
153 },
154 .pViewportState = &(VkPipelineViewportStateCreateInfo) {
155 .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
156 .viewportCount = 1,
157 .pViewports = NULL, /* dynamic */
158 .scissorCount = 1,
159 .pScissors = NULL, /* dynamic */
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 = 1, /* FINISHME: Multisampling */
172 .sampleShadingEnable = false,
173 .pSampleMask = (VkSampleMask[]) { UINT32_MAX },
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 = 9,
187 .pDynamicStates = (VkDynamicState[]) {
188 VK_DYNAMIC_STATE_VIEWPORT,
189 VK_DYNAMIC_STATE_SCISSOR,
190 VK_DYNAMIC_STATE_LINE_WIDTH,
191 VK_DYNAMIC_STATE_DEPTH_BIAS,
192 VK_DYNAMIC_STATE_BLEND_CONSTANTS,
193 VK_DYNAMIC_STATE_DEPTH_BOUNDS,
194 VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
195 VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
196 VK_DYNAMIC_STATE_STENCIL_REFERENCE,
197 },
198 },
199 .flags = 0,
200 .renderPass = anv_render_pass_to_handle(&anv_meta_dummy_renderpass),
201 .subpass = 0,
202 },
203 &(struct anv_graphics_pipeline_create_info) {
204 .use_repclear = true,
205 .disable_viewport = true,
206 .disable_vs = true,
207 .use_rectlist = true
208 },
209 alloc,
210 &pipeline_h);
211
212 ralloc_free(vs_nir);
213 ralloc_free(fs_nir);
214
215 return anv_pipeline_from_handle(pipeline_h);
216 }
217
218 static void
219 init_color_pipeline(struct anv_device *device)
220 {
221 struct nir_shader *vs_nir;
222 struct nir_shader *fs_nir;
223 build_color_shaders(&vs_nir, &fs_nir);
224
225 const VkPipelineVertexInputStateCreateInfo vi_state = {
226 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
227 .vertexBindingDescriptionCount = 1,
228 .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) {
229 {
230 .binding = 0,
231 .stride = sizeof(struct color_clear_vattrs),
232 .inputRate = VK_VERTEX_INPUT_RATE_VERTEX
233 },
234 },
235 .vertexAttributeDescriptionCount = 3,
236 .pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[]) {
237 {
238 /* VUE Header */
239 .location = 0,
240 .binding = 0,
241 .format = VK_FORMAT_R32G32B32A32_UINT,
242 .offset = offsetof(struct color_clear_vattrs, vue_header),
243 },
244 {
245 /* Position */
246 .location = 1,
247 .binding = 0,
248 .format = VK_FORMAT_R32G32_SFLOAT,
249 .offset = offsetof(struct color_clear_vattrs, position),
250 },
251 {
252 /* Color */
253 .location = 2,
254 .binding = 0,
255 .format = VK_FORMAT_R32G32B32A32_SFLOAT,
256 .offset = offsetof(struct color_clear_vattrs, color),
257 },
258 },
259 };
260
261 const VkPipelineDepthStencilStateCreateInfo ds_state = {
262 .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
263 .depthTestEnable = false,
264 .depthWriteEnable = false,
265 .depthBoundsTestEnable = false,
266 .stencilTestEnable = false,
267 };
268
269 const VkPipelineColorBlendStateCreateInfo cb_state = {
270 .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
271 .logicOpEnable = false,
272 .attachmentCount = 1,
273 .pAttachments = (VkPipelineColorBlendAttachmentState []) {
274 {
275 .blendEnable = false,
276 .colorWriteMask = VK_COLOR_COMPONENT_A_BIT |
277 VK_COLOR_COMPONENT_R_BIT |
278 VK_COLOR_COMPONENT_G_BIT |
279 VK_COLOR_COMPONENT_B_BIT,
280 },
281 },
282 };
283
284 device->meta_state.clear.color_pipeline =
285 create_pipeline(device, vs_nir, fs_nir, &vi_state, &ds_state,
286 &cb_state, NULL);
287 }
288
289 static void
290 emit_load_color_clear(struct anv_cmd_buffer *cmd_buffer,
291 uint32_t attachment,
292 VkClearColorValue clear_value)
293 {
294 struct anv_device *device = cmd_buffer->device;
295 VkCommandBuffer cmd_buffer_h = anv_cmd_buffer_to_handle(cmd_buffer);
296 const struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
297 VkPipeline pipeline_h =
298 anv_pipeline_to_handle(device->meta_state.clear.color_pipeline);
299
300 const struct color_clear_vattrs vertex_data[3] = {
301 {
302 .vue_header = { 0 },
303 .position = { 0.0, 0.0 },
304 .color = clear_value,
305 },
306 {
307 .vue_header = { 0 },
308 .position = { fb->width, 0.0 },
309 .color = clear_value,
310 },
311 {
312 .vue_header = { 0 },
313 .position = { fb->width, fb->height },
314 .color = clear_value,
315 },
316 };
317
318 struct anv_state state =
319 anv_cmd_buffer_emit_dynamic(cmd_buffer, vertex_data, sizeof(vertex_data), 16);
320
321 struct anv_buffer vertex_buffer = {
322 .device = device,
323 .size = sizeof(vertex_data),
324 .bo = &device->dynamic_state_block_pool.bo,
325 .offset = state.offset,
326 };
327
328 anv_cmd_buffer_begin_subpass(cmd_buffer,
329 &(struct anv_subpass) {
330 .color_count = 1,
331 .color_attachments = (uint32_t[]) { attachment },
332 .depth_stencil_attachment = VK_ATTACHMENT_UNUSED,
333 });
334
335 ANV_CALL(CmdSetViewport)(cmd_buffer_h, 1,
336 (VkViewport[]) {
337 {
338 .x = 0,
339 .y = 0,
340 .width = fb->width,
341 .height = fb->height,
342 .minDepth = 0.0,
343 .maxDepth = 1.0,
344 },
345 });
346
347 ANV_CALL(CmdSetScissor)(cmd_buffer_h, 1,
348 (VkRect2D[]) {
349 {
350 .offset = { 0, 0 },
351 .extent = { fb->width, fb->height },
352 }
353 });
354
355 ANV_CALL(CmdBindVertexBuffers)(cmd_buffer_h, 0, 1,
356 (VkBuffer[]) { anv_buffer_to_handle(&vertex_buffer) },
357 (VkDeviceSize[]) { 0 });
358
359 if (cmd_buffer->state.pipeline != device->meta_state.clear.color_pipeline) {
360 ANV_CALL(CmdBindPipeline)(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS,
361 pipeline_h);
362 }
363
364 ANV_CALL(CmdDraw)(cmd_buffer_h, 3, 1, 0, 0);
365 }
366
367
368 static void
369 build_depthstencil_shaders(struct nir_shader **out_vs,
370 struct nir_shader **out_fs)
371 {
372 nir_builder vs_b;
373 nir_builder fs_b;
374
375 nir_builder_init_simple_shader(&vs_b, MESA_SHADER_VERTEX);
376 nir_builder_init_simple_shader(&fs_b, MESA_SHADER_FRAGMENT);
377
378 const struct glsl_type *position_type = glsl_vec4_type();
379
380 nir_variable *vs_in_pos =
381 nir_variable_create(vs_b.shader, nir_var_shader_in, position_type,
382 "a_position");
383 vs_in_pos->data.location = VERT_ATTRIB_GENERIC0;
384
385 nir_variable *vs_out_pos =
386 nir_variable_create(vs_b.shader, nir_var_shader_out, position_type,
387 "gl_Position");
388 vs_out_pos->data.location = VARYING_SLOT_POS;
389
390 nir_copy_var(&vs_b, vs_out_pos, vs_in_pos);
391
392 *out_vs = vs_b.shader;
393 *out_fs = fs_b.shader;
394 }
395
396 static struct anv_pipeline *
397 create_depthstencil_pipeline(struct anv_device *device,
398 VkImageAspectFlags aspects)
399 {
400 struct nir_shader *vs_nir;
401 struct nir_shader *fs_nir;
402
403 build_depthstencil_shaders(&vs_nir, &fs_nir);
404
405 const VkPipelineVertexInputStateCreateInfo vi_state = {
406 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
407 .vertexBindingDescriptionCount = 1,
408 .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) {
409 {
410 .binding = 0,
411 .stride = sizeof(struct depthstencil_clear_vattrs),
412 .inputRate = VK_VERTEX_INPUT_RATE_VERTEX
413 },
414 },
415 .vertexAttributeDescriptionCount = 2,
416 .pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[]) {
417 {
418 /* VUE Header */
419 .location = 0,
420 .binding = 0,
421 .format = VK_FORMAT_R32G32B32A32_UINT,
422 .offset = offsetof(struct depthstencil_clear_vattrs, vue_header),
423 },
424 {
425 /* Position */
426 .location = 1,
427 .binding = 0,
428 .format = VK_FORMAT_R32G32_SFLOAT,
429 .offset = offsetof(struct depthstencil_clear_vattrs, position),
430 },
431 },
432 };
433
434 const VkPipelineDepthStencilStateCreateInfo ds_state = {
435 .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
436 .depthTestEnable = (aspects & VK_IMAGE_ASPECT_DEPTH_BIT),
437 .depthCompareOp = VK_COMPARE_OP_ALWAYS,
438 .depthWriteEnable = (aspects & VK_IMAGE_ASPECT_DEPTH_BIT),
439 .depthBoundsTestEnable = false,
440 .stencilTestEnable = (aspects & VK_IMAGE_ASPECT_STENCIL_BIT),
441 .front = {
442 .passOp = VK_STENCIL_OP_REPLACE,
443 .compareOp = VK_COMPARE_OP_ALWAYS,
444 .writeMask = UINT32_MAX,
445 .reference = 0, /* dynamic */
446 },
447 .back = { 0 /* dont care */ },
448 };
449
450 const VkPipelineColorBlendStateCreateInfo cb_state = {
451 .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
452 .logicOpEnable = false,
453 .attachmentCount = 0,
454 .pAttachments = NULL,
455 };
456
457 return create_pipeline(device, vs_nir, fs_nir, &vi_state, &ds_state,
458 &cb_state, NULL);
459 }
460
461 static void
462 emit_load_depthstencil_clear(struct anv_cmd_buffer *cmd_buffer,
463 uint32_t attachment,
464 VkImageAspectFlags aspects,
465 VkClearDepthStencilValue clear_value)
466 {
467 struct anv_device *device = cmd_buffer->device;
468 VkCommandBuffer cmd_buffer_h = anv_cmd_buffer_to_handle(cmd_buffer);
469 const struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
470
471 const struct depthstencil_clear_vattrs vertex_data[3] = {
472 {
473 .vue_header = { 0 },
474 .position = { 0.0, 0.0 },
475 },
476 {
477 .vue_header = { 0 },
478 .position = { fb->width, 0.0 },
479 },
480 {
481 .vue_header = { 0 },
482 .position = { fb->width, fb->height },
483 },
484 };
485
486 struct anv_state state =
487 anv_cmd_buffer_emit_dynamic(cmd_buffer, vertex_data, sizeof(vertex_data), 16);
488
489 struct anv_buffer vertex_buffer = {
490 .device = device,
491 .size = sizeof(vertex_data),
492 .bo = &device->dynamic_state_block_pool.bo,
493 .offset = state.offset,
494 };
495
496 anv_cmd_buffer_begin_subpass(cmd_buffer,
497 &(struct anv_subpass) {
498 .color_count = 0,
499 .depth_stencil_attachment = attachment,
500 });
501
502 ANV_CALL(CmdSetViewport)(cmd_buffer_h, 1,
503 (VkViewport[]) {
504 {
505 .x = 0,
506 .y = 0,
507 .width = fb->width,
508 .height = fb->height,
509
510 /* Ignored when clearing only stencil. */
511 .minDepth = clear_value.depth,
512 .maxDepth = clear_value.depth,
513 },
514 });
515
516 ANV_CALL(CmdSetScissor)(cmd_buffer_h, 1,
517 (VkRect2D[]) {
518 {
519 .offset = { 0, 0 },
520 .extent = { fb->width, fb->height },
521 }
522 });
523
524 if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
525 ANV_CALL(CmdSetStencilReference)(cmd_buffer_h, VK_STENCIL_FACE_FRONT_BIT,
526 clear_value.stencil);
527 }
528
529 ANV_CALL(CmdBindVertexBuffers)(cmd_buffer_h, 0, 1,
530 (VkBuffer[]) { anv_buffer_to_handle(&vertex_buffer) },
531 (VkDeviceSize[]) { 0 });
532
533 struct anv_pipeline *pipeline;
534 switch (aspects) {
535 case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT:
536 pipeline = device->meta_state.clear.depthstencil_pipeline;
537 break;
538 case VK_IMAGE_ASPECT_DEPTH_BIT:
539 pipeline = device->meta_state.clear.depth_only_pipeline;
540 break;
541 case VK_IMAGE_ASPECT_STENCIL_BIT:
542 pipeline = device->meta_state.clear.stencil_only_pipeline;
543 break;
544 default:
545 unreachable("expected depth or stencil aspect");
546 }
547
548 if (cmd_buffer->state.pipeline != pipeline) {
549 ANV_CALL(CmdBindPipeline)(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS,
550 anv_pipeline_to_handle(pipeline));
551 }
552
553 ANV_CALL(CmdDraw)(cmd_buffer_h, 3, 1, 0, 0);
554 }
555
556 static void
557 init_depthstencil_pipelines(struct anv_device *device)
558 {
559 device->meta_state.clear.depth_only_pipeline =
560 create_depthstencil_pipeline(device, VK_IMAGE_ASPECT_DEPTH_BIT);
561
562 device->meta_state.clear.stencil_only_pipeline =
563 create_depthstencil_pipeline(device, VK_IMAGE_ASPECT_STENCIL_BIT);
564
565 device->meta_state.clear.depthstencil_pipeline =
566 create_depthstencil_pipeline(device, VK_IMAGE_ASPECT_DEPTH_BIT |
567 VK_IMAGE_ASPECT_STENCIL_BIT);
568 }
569
570 void
571 anv_device_init_meta_clear_state(struct anv_device *device)
572 {
573 init_color_pipeline(device);
574 init_depthstencil_pipelines(device);
575 }
576
577 void
578 anv_device_finish_meta_clear_state(struct anv_device *device)
579 {
580 VkDevice device_h = anv_device_to_handle(device);
581
582 ANV_CALL(DestroyPipeline)(device_h,
583 anv_pipeline_to_handle(device->meta_state.clear.color_pipeline),
584 NULL);
585 ANV_CALL(DestroyPipeline)(device_h,
586 anv_pipeline_to_handle(device->meta_state.clear.depth_only_pipeline),
587 NULL);
588 ANV_CALL(DestroyPipeline)(device_h,
589 anv_pipeline_to_handle(device->meta_state.clear.stencil_only_pipeline),
590 NULL);
591 ANV_CALL(DestroyPipeline)(device_h,
592 anv_pipeline_to_handle(device->meta_state.clear.depthstencil_pipeline),
593 NULL);
594 }
595
596 void
597 anv_cmd_buffer_clear_attachments(struct anv_cmd_buffer *cmd_buffer,
598 struct anv_render_pass *pass,
599 const VkClearValue *clear_values)
600 {
601 struct anv_meta_saved_state saved_state;
602
603 /* Figure out whether or not we actually need to clear anything to avoid
604 * trashing state when clearing is a no-op.
605 */
606 bool needs_clear = false;
607 for (uint32_t a = 0; a < pass->attachment_count; ++a) {
608 struct anv_render_pass_attachment *att = &pass->attachments[a];
609
610 if (anv_format_is_color(att->format)) {
611 if (att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
612 needs_clear = true;
613 break;
614 }
615 } else {
616 if ((att->format->depth_format &&
617 att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) ||
618 (att->format->has_stencil &&
619 att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)) {
620 needs_clear = true;
621 break;
622 }
623 }
624 }
625
626 if (!needs_clear)
627 return;
628
629 meta_clear_begin(&saved_state, cmd_buffer);
630
631 for (uint32_t a = 0; a < pass->attachment_count; ++a) {
632 struct anv_render_pass_attachment *att = &pass->attachments[a];
633
634 if (anv_format_is_color(att->format)) {
635 if (att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
636 emit_load_color_clear(cmd_buffer, a, clear_values[a].color);
637 }
638 } else {
639 VkImageAspectFlags clear_aspects = 0;
640
641 if (att->format->depth_format &&
642 att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
643 clear_aspects |= VK_IMAGE_ASPECT_DEPTH_BIT;
644 }
645
646 if (att->format->has_stencil &&
647 att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
648 clear_aspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
649 }
650
651 if (clear_aspects) {
652 emit_load_depthstencil_clear(cmd_buffer, a, clear_aspects,
653 clear_values[a].depthStencil);
654 }
655 }
656 }
657
658 meta_clear_end(&saved_state, cmd_buffer);
659 }
660
661 void anv_CmdClearColorImage(
662 VkCommandBuffer commandBuffer,
663 VkImage _image,
664 VkImageLayout imageLayout,
665 const VkClearColorValue* pColor,
666 uint32_t rangeCount,
667 const VkImageSubresourceRange* pRanges)
668 {
669 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
670 ANV_FROM_HANDLE(anv_image, image, _image);
671 struct anv_meta_saved_state saved_state;
672
673 meta_clear_begin(&saved_state, cmd_buffer);
674
675 for (uint32_t r = 0; r < rangeCount; r++) {
676 for (uint32_t l = 0; l < pRanges[r].levelCount; l++) {
677 for (uint32_t s = 0; s < pRanges[r].layerCount; s++) {
678 struct anv_image_view iview;
679 anv_image_view_init(&iview, cmd_buffer->device,
680 &(VkImageViewCreateInfo) {
681 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
682 .image = _image,
683 .viewType = VK_IMAGE_VIEW_TYPE_2D,
684 .format = image->format->vk_format,
685 .subresourceRange = {
686 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
687 .baseMipLevel = pRanges[r].baseMipLevel + l,
688 .levelCount = 1,
689 .baseArrayLayer = pRanges[r].baseArrayLayer + s,
690 .layerCount = 1
691 },
692 },
693 cmd_buffer);
694
695 VkFramebuffer fb;
696 anv_CreateFramebuffer(anv_device_to_handle(cmd_buffer->device),
697 &(VkFramebufferCreateInfo) {
698 .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
699 .attachmentCount = 1,
700 .pAttachments = (VkImageView[]) {
701 anv_image_view_to_handle(&iview),
702 },
703 .width = iview.extent.width,
704 .height = iview.extent.height,
705 .layers = 1
706 }, &cmd_buffer->pool->alloc, &fb);
707
708 VkRenderPass pass;
709 anv_CreateRenderPass(anv_device_to_handle(cmd_buffer->device),
710 &(VkRenderPassCreateInfo) {
711 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
712 .attachmentCount = 1,
713 .pAttachments = &(VkAttachmentDescription) {
714 .format = iview.format->vk_format,
715 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
716 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
717 .initialLayout = VK_IMAGE_LAYOUT_GENERAL,
718 .finalLayout = VK_IMAGE_LAYOUT_GENERAL,
719 },
720 .subpassCount = 1,
721 .pSubpasses = &(VkSubpassDescription) {
722 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
723 .inputAttachmentCount = 0,
724 .colorAttachmentCount = 1,
725 .pColorAttachments = &(VkAttachmentReference) {
726 .attachment = 0,
727 .layout = VK_IMAGE_LAYOUT_GENERAL,
728 },
729 .pResolveAttachments = NULL,
730 .pDepthStencilAttachment = &(VkAttachmentReference) {
731 .attachment = VK_ATTACHMENT_UNUSED,
732 .layout = VK_IMAGE_LAYOUT_GENERAL,
733 },
734 .preserveAttachmentCount = 1,
735 .pPreserveAttachments = &(VkAttachmentReference) {
736 .attachment = 0,
737 .layout = VK_IMAGE_LAYOUT_GENERAL,
738 },
739 },
740 .dependencyCount = 0,
741 }, &cmd_buffer->pool->alloc, &pass);
742
743 ANV_CALL(CmdBeginRenderPass)(anv_cmd_buffer_to_handle(cmd_buffer),
744 &(VkRenderPassBeginInfo) {
745 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
746 .renderArea = {
747 .offset = { 0, 0, },
748 .extent = {
749 .width = iview.extent.width,
750 .height = iview.extent.height,
751 },
752 },
753 .renderPass = pass,
754 .framebuffer = fb,
755 .clearValueCount = 1,
756 .pClearValues = (VkClearValue[]) {
757 { .color = *pColor },
758 },
759 }, VK_SUBPASS_CONTENTS_INLINE);
760
761 ANV_CALL(CmdEndRenderPass)(anv_cmd_buffer_to_handle(cmd_buffer));
762
763 /* XXX: We're leaking the render pass and framebuffer */
764 }
765 }
766 }
767
768 meta_clear_end(&saved_state, cmd_buffer);
769 }
770
771 void anv_CmdClearDepthStencilImage(
772 VkCommandBuffer commandBuffer,
773 VkImage image,
774 VkImageLayout imageLayout,
775 const VkClearDepthStencilValue* pDepthStencil,
776 uint32_t rangeCount,
777 const VkImageSubresourceRange* pRanges)
778 {
779 stub();
780 }
781
782 void anv_CmdClearAttachments(
783 VkCommandBuffer commandBuffer,
784 uint32_t attachmentCount,
785 const VkClearAttachment* pAttachments,
786 uint32_t rectCount,
787 const VkClearRect* pRects)
788 {
789 stub();
790 }