anv/meta: Add FINISHME for clearing multi-layer framebuffers
[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_private.h"
27 #include "glsl/nir/nir_builder.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, NULL, MESA_SHADER_VERTEX, NULL);
70 nir_builder_init_simple_shader(&fs_b, NULL, MESA_SHADER_FRAGMENT, NULL);
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 VkResult
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 struct anv_pipeline **pipeline)
124 {
125 VkDevice device_h = anv_device_to_handle(device);
126 VkResult result;
127
128 struct anv_shader_module vs_m = { .nir = vs_nir };
129 struct anv_shader_module fs_m = { .nir = fs_nir };
130
131 VkPipeline pipeline_h;
132 result = anv_graphics_pipeline_create(device_h,
133 VK_NULL_HANDLE,
134 &(VkGraphicsPipelineCreateInfo) {
135 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
136 .stageCount = 2,
137 .pStages = (VkPipelineShaderStageCreateInfo[]) {
138 {
139 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
140 .stage = VK_SHADER_STAGE_VERTEX_BIT,
141 .module = anv_shader_module_to_handle(&vs_m),
142 .pName = "main",
143 },
144 {
145 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
146 .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
147 .module = anv_shader_module_to_handle(&fs_m),
148 .pName = "main",
149 },
150 },
151 .pVertexInputState = vi_state,
152 .pInputAssemblyState = &(VkPipelineInputAssemblyStateCreateInfo) {
153 .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
154 .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
155 .primitiveRestartEnable = false,
156 },
157 .pViewportState = &(VkPipelineViewportStateCreateInfo) {
158 .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
159 .viewportCount = 1,
160 .pViewports = NULL, /* dynamic */
161 .scissorCount = 1,
162 .pScissors = NULL, /* dynamic */
163 },
164 .pRasterizationState = &(VkPipelineRasterizationStateCreateInfo) {
165 .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
166 .rasterizerDiscardEnable = false,
167 .polygonMode = VK_POLYGON_MODE_FILL,
168 .cullMode = VK_CULL_MODE_NONE,
169 .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
170 .depthBiasEnable = false,
171 },
172 .pMultisampleState = &(VkPipelineMultisampleStateCreateInfo) {
173 .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
174 .rasterizationSamples = 1, /* FINISHME: Multisampling */
175 .sampleShadingEnable = false,
176 .pSampleMask = (VkSampleMask[]) { UINT32_MAX },
177 .alphaToCoverageEnable = false,
178 .alphaToOneEnable = false,
179 },
180 .pDepthStencilState = ds_state,
181 .pColorBlendState = cb_state,
182 .pDynamicState = &(VkPipelineDynamicStateCreateInfo) {
183 /* The meta clear pipeline declares all state as dynamic.
184 * As a consequence, vkCmdBindPipeline writes no dynamic state
185 * to the cmd buffer. Therefore, at the end of the meta clear,
186 * we need only restore dynamic state was vkCmdSet.
187 */
188 .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
189 .dynamicStateCount = 9,
190 .pDynamicStates = (VkDynamicState[]) {
191 VK_DYNAMIC_STATE_VIEWPORT,
192 VK_DYNAMIC_STATE_SCISSOR,
193 VK_DYNAMIC_STATE_LINE_WIDTH,
194 VK_DYNAMIC_STATE_DEPTH_BIAS,
195 VK_DYNAMIC_STATE_BLEND_CONSTANTS,
196 VK_DYNAMIC_STATE_DEPTH_BOUNDS,
197 VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
198 VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
199 VK_DYNAMIC_STATE_STENCIL_REFERENCE,
200 },
201 },
202 .flags = 0,
203 .renderPass = anv_render_pass_to_handle(&anv_meta_dummy_renderpass),
204 .subpass = 0,
205 },
206 &(struct anv_graphics_pipeline_create_info) {
207 .use_repclear = true,
208 .disable_viewport = true,
209 .disable_vs = true,
210 .use_rectlist = true
211 },
212 alloc,
213 &pipeline_h);
214
215 ralloc_free(vs_nir);
216 ralloc_free(fs_nir);
217
218 *pipeline = anv_pipeline_from_handle(pipeline_h);
219
220 return result;
221 }
222
223 static VkResult
224 init_color_pipeline(struct anv_device *device)
225 {
226 struct nir_shader *vs_nir;
227 struct nir_shader *fs_nir;
228 build_color_shaders(&vs_nir, &fs_nir);
229
230 const VkPipelineVertexInputStateCreateInfo vi_state = {
231 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
232 .vertexBindingDescriptionCount = 1,
233 .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) {
234 {
235 .binding = 0,
236 .stride = sizeof(struct color_clear_vattrs),
237 .inputRate = VK_VERTEX_INPUT_RATE_VERTEX
238 },
239 },
240 .vertexAttributeDescriptionCount = 3,
241 .pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[]) {
242 {
243 /* VUE Header */
244 .location = 0,
245 .binding = 0,
246 .format = VK_FORMAT_R32G32B32A32_UINT,
247 .offset = offsetof(struct color_clear_vattrs, vue_header),
248 },
249 {
250 /* Position */
251 .location = 1,
252 .binding = 0,
253 .format = VK_FORMAT_R32G32_SFLOAT,
254 .offset = offsetof(struct color_clear_vattrs, position),
255 },
256 {
257 /* Color */
258 .location = 2,
259 .binding = 0,
260 .format = VK_FORMAT_R32G32B32A32_SFLOAT,
261 .offset = offsetof(struct color_clear_vattrs, color),
262 },
263 },
264 };
265
266 const VkPipelineDepthStencilStateCreateInfo ds_state = {
267 .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
268 .depthTestEnable = false,
269 .depthWriteEnable = false,
270 .depthBoundsTestEnable = false,
271 .stencilTestEnable = false,
272 };
273
274 const VkPipelineColorBlendStateCreateInfo cb_state = {
275 .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
276 .logicOpEnable = false,
277 .attachmentCount = 1,
278 .pAttachments = (VkPipelineColorBlendAttachmentState []) {
279 {
280 .blendEnable = false,
281 .colorWriteMask = VK_COLOR_COMPONENT_A_BIT |
282 VK_COLOR_COMPONENT_R_BIT |
283 VK_COLOR_COMPONENT_G_BIT |
284 VK_COLOR_COMPONENT_B_BIT,
285 },
286 },
287 };
288
289 return
290 create_pipeline(device, vs_nir, fs_nir, &vi_state, &ds_state,
291 &cb_state, NULL,
292 &device->meta_state.clear.color_pipeline);
293 }
294
295 static void
296 emit_load_color_clear(struct anv_cmd_buffer *cmd_buffer,
297 uint32_t attachment,
298 VkClearColorValue clear_value)
299 {
300 struct anv_device *device = cmd_buffer->device;
301 VkCommandBuffer cmd_buffer_h = anv_cmd_buffer_to_handle(cmd_buffer);
302 const struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
303 VkPipeline pipeline_h =
304 anv_pipeline_to_handle(device->meta_state.clear.color_pipeline);
305
306 const struct color_clear_vattrs vertex_data[3] = {
307 {
308 .vue_header = { 0 },
309 .position = { 0.0, 0.0 },
310 .color = clear_value,
311 },
312 {
313 .vue_header = { 0 },
314 .position = { fb->width, 0.0 },
315 .color = clear_value,
316 },
317 {
318 .vue_header = { 0 },
319 .position = { fb->width, fb->height },
320 .color = clear_value,
321 },
322 };
323
324 struct anv_state state =
325 anv_cmd_buffer_emit_dynamic(cmd_buffer, vertex_data, sizeof(vertex_data), 16);
326
327 struct anv_buffer vertex_buffer = {
328 .device = device,
329 .size = sizeof(vertex_data),
330 .bo = &device->dynamic_state_block_pool.bo,
331 .offset = state.offset,
332 };
333
334 anv_cmd_buffer_begin_subpass(cmd_buffer,
335 &(struct anv_subpass) {
336 .color_count = 1,
337 .color_attachments = (uint32_t[]) { attachment },
338 .depth_stencil_attachment = VK_ATTACHMENT_UNUSED,
339 });
340
341 ANV_CALL(CmdSetViewport)(cmd_buffer_h, 0, 1,
342 (VkViewport[]) {
343 {
344 .x = 0,
345 .y = 0,
346 .width = fb->width,
347 .height = fb->height,
348 .minDepth = 0.0,
349 .maxDepth = 1.0,
350 },
351 });
352
353 ANV_CALL(CmdSetScissor)(cmd_buffer_h, 0, 1,
354 (VkRect2D[]) {
355 {
356 .offset = { 0, 0 },
357 .extent = { fb->width, fb->height },
358 }
359 });
360
361 ANV_CALL(CmdBindVertexBuffers)(cmd_buffer_h, 0, 1,
362 (VkBuffer[]) { anv_buffer_to_handle(&vertex_buffer) },
363 (VkDeviceSize[]) { 0 });
364
365 if (cmd_buffer->state.pipeline != device->meta_state.clear.color_pipeline) {
366 ANV_CALL(CmdBindPipeline)(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS,
367 pipeline_h);
368 }
369
370 ANV_CALL(CmdDraw)(cmd_buffer_h, 3, 1, 0, 0);
371 }
372
373
374 static void
375 build_depthstencil_shaders(struct nir_shader **out_vs,
376 struct nir_shader **out_fs)
377 {
378 nir_builder vs_b;
379 nir_builder fs_b;
380
381 nir_builder_init_simple_shader(&vs_b, NULL, MESA_SHADER_VERTEX, NULL);
382 nir_builder_init_simple_shader(&fs_b, NULL, MESA_SHADER_FRAGMENT, NULL);
383
384 const struct glsl_type *position_type = glsl_vec4_type();
385
386 nir_variable *vs_in_pos =
387 nir_variable_create(vs_b.shader, nir_var_shader_in, position_type,
388 "a_position");
389 vs_in_pos->data.location = VERT_ATTRIB_GENERIC0;
390
391 nir_variable *vs_out_pos =
392 nir_variable_create(vs_b.shader, nir_var_shader_out, position_type,
393 "gl_Position");
394 vs_out_pos->data.location = VARYING_SLOT_POS;
395
396 nir_copy_var(&vs_b, vs_out_pos, vs_in_pos);
397
398 *out_vs = vs_b.shader;
399 *out_fs = fs_b.shader;
400 }
401
402 static VkResult
403 create_depthstencil_pipeline(struct anv_device *device,
404 VkImageAspectFlags aspects,
405 struct anv_pipeline **pipeline)
406 {
407 struct nir_shader *vs_nir;
408 struct nir_shader *fs_nir;
409
410 build_depthstencil_shaders(&vs_nir, &fs_nir);
411
412 const VkPipelineVertexInputStateCreateInfo vi_state = {
413 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
414 .vertexBindingDescriptionCount = 1,
415 .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) {
416 {
417 .binding = 0,
418 .stride = sizeof(struct depthstencil_clear_vattrs),
419 .inputRate = VK_VERTEX_INPUT_RATE_VERTEX
420 },
421 },
422 .vertexAttributeDescriptionCount = 2,
423 .pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[]) {
424 {
425 /* VUE Header */
426 .location = 0,
427 .binding = 0,
428 .format = VK_FORMAT_R32G32B32A32_UINT,
429 .offset = offsetof(struct depthstencil_clear_vattrs, vue_header),
430 },
431 {
432 /* Position */
433 .location = 1,
434 .binding = 0,
435 .format = VK_FORMAT_R32G32_SFLOAT,
436 .offset = offsetof(struct depthstencil_clear_vattrs, position),
437 },
438 },
439 };
440
441 const VkPipelineDepthStencilStateCreateInfo ds_state = {
442 .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
443 .depthTestEnable = (aspects & VK_IMAGE_ASPECT_DEPTH_BIT),
444 .depthCompareOp = VK_COMPARE_OP_ALWAYS,
445 .depthWriteEnable = (aspects & VK_IMAGE_ASPECT_DEPTH_BIT),
446 .depthBoundsTestEnable = false,
447 .stencilTestEnable = (aspects & VK_IMAGE_ASPECT_STENCIL_BIT),
448 .front = {
449 .passOp = VK_STENCIL_OP_REPLACE,
450 .compareOp = VK_COMPARE_OP_ALWAYS,
451 .writeMask = UINT32_MAX,
452 .reference = 0, /* dynamic */
453 },
454 .back = { 0 /* dont care */ },
455 };
456
457 const VkPipelineColorBlendStateCreateInfo cb_state = {
458 .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
459 .logicOpEnable = false,
460 .attachmentCount = 0,
461 .pAttachments = NULL,
462 };
463
464 return create_pipeline(device, vs_nir, fs_nir, &vi_state, &ds_state,
465 &cb_state, NULL, pipeline);
466 }
467
468 static void
469 emit_load_depthstencil_clear(struct anv_cmd_buffer *cmd_buffer,
470 uint32_t attachment,
471 VkImageAspectFlags aspects,
472 VkClearDepthStencilValue clear_value)
473 {
474 struct anv_device *device = cmd_buffer->device;
475 VkCommandBuffer cmd_buffer_h = anv_cmd_buffer_to_handle(cmd_buffer);
476 const struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
477
478 const struct depthstencil_clear_vattrs vertex_data[3] = {
479 {
480 .vue_header = { 0 },
481 .position = { 0.0, 0.0 },
482 },
483 {
484 .vue_header = { 0 },
485 .position = { fb->width, 0.0 },
486 },
487 {
488 .vue_header = { 0 },
489 .position = { fb->width, fb->height },
490 },
491 };
492
493 struct anv_state state =
494 anv_cmd_buffer_emit_dynamic(cmd_buffer, vertex_data, sizeof(vertex_data), 16);
495
496 struct anv_buffer vertex_buffer = {
497 .device = device,
498 .size = sizeof(vertex_data),
499 .bo = &device->dynamic_state_block_pool.bo,
500 .offset = state.offset,
501 };
502
503 anv_cmd_buffer_begin_subpass(cmd_buffer,
504 &(struct anv_subpass) {
505 .color_count = 0,
506 .depth_stencil_attachment = attachment,
507 });
508
509 ANV_CALL(CmdSetViewport)(cmd_buffer_h, 0, 1,
510 (VkViewport[]) {
511 {
512 .x = 0,
513 .y = 0,
514 .width = fb->width,
515 .height = fb->height,
516
517 /* Ignored when clearing only stencil. */
518 .minDepth = clear_value.depth,
519 .maxDepth = clear_value.depth,
520 },
521 });
522
523 ANV_CALL(CmdSetScissor)(cmd_buffer_h, 0, 1,
524 (VkRect2D[]) {
525 {
526 .offset = { 0, 0 },
527 .extent = { fb->width, fb->height },
528 }
529 });
530
531 if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
532 ANV_CALL(CmdSetStencilReference)(cmd_buffer_h, VK_STENCIL_FACE_FRONT_BIT,
533 clear_value.stencil);
534 }
535
536 ANV_CALL(CmdBindVertexBuffers)(cmd_buffer_h, 0, 1,
537 (VkBuffer[]) { anv_buffer_to_handle(&vertex_buffer) },
538 (VkDeviceSize[]) { 0 });
539
540 struct anv_pipeline *pipeline;
541 switch (aspects) {
542 case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT:
543 pipeline = device->meta_state.clear.depthstencil_pipeline;
544 break;
545 case VK_IMAGE_ASPECT_DEPTH_BIT:
546 pipeline = device->meta_state.clear.depth_only_pipeline;
547 break;
548 case VK_IMAGE_ASPECT_STENCIL_BIT:
549 pipeline = device->meta_state.clear.stencil_only_pipeline;
550 break;
551 default:
552 unreachable("expected depth or stencil aspect");
553 }
554
555 if (cmd_buffer->state.pipeline != pipeline) {
556 ANV_CALL(CmdBindPipeline)(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS,
557 anv_pipeline_to_handle(pipeline));
558 }
559
560 ANV_CALL(CmdDraw)(cmd_buffer_h, 3, 1, 0, 0);
561 }
562
563 static VkResult
564 init_depthstencil_pipelines(struct anv_device *device)
565 {
566 VkResult result;
567 struct anv_meta_state *state = &device->meta_state;
568
569 result =
570 create_depthstencil_pipeline(device, VK_IMAGE_ASPECT_DEPTH_BIT,
571 &state->clear.depth_only_pipeline);
572 if (result != VK_SUCCESS)
573 goto fail;
574
575 result =
576 create_depthstencil_pipeline(device, VK_IMAGE_ASPECT_STENCIL_BIT,
577 &state->clear.stencil_only_pipeline);
578 if (result != VK_SUCCESS)
579 goto fail_depth_only;
580
581 result =
582 create_depthstencil_pipeline(device,
583 VK_IMAGE_ASPECT_DEPTH_BIT |
584 VK_IMAGE_ASPECT_STENCIL_BIT,
585 &state->clear.depthstencil_pipeline);
586 if (result != VK_SUCCESS)
587 goto fail_stencil_only;
588
589 return result;
590
591 fail_stencil_only:
592 anv_DestroyPipeline(anv_device_to_handle(device),
593 anv_pipeline_to_handle(state->clear.stencil_only_pipeline),
594 NULL);
595 fail_depth_only:
596 anv_DestroyPipeline(anv_device_to_handle(device),
597 anv_pipeline_to_handle(state->clear.depth_only_pipeline),
598 NULL);
599 fail:
600 return result;
601 }
602
603 VkResult
604 anv_device_init_meta_clear_state(struct anv_device *device)
605 {
606 VkResult result;
607
608 result = init_color_pipeline(device);
609 if (result != VK_SUCCESS)
610 goto fail;
611
612 result = init_depthstencil_pipelines(device);
613 if (result != VK_SUCCESS)
614 goto fail_color_pipeline;
615
616 return VK_SUCCESS;
617
618 fail_color_pipeline:
619 anv_DestroyPipeline(anv_device_to_handle(device),
620 anv_pipeline_to_handle(device->meta_state.clear.color_pipeline),
621 NULL);
622 fail:
623 return result;
624 }
625
626 void
627 anv_device_finish_meta_clear_state(struct anv_device *device)
628 {
629 VkDevice device_h = anv_device_to_handle(device);
630
631 ANV_CALL(DestroyPipeline)(device_h,
632 anv_pipeline_to_handle(device->meta_state.clear.color_pipeline),
633 NULL);
634 ANV_CALL(DestroyPipeline)(device_h,
635 anv_pipeline_to_handle(device->meta_state.clear.depth_only_pipeline),
636 NULL);
637 ANV_CALL(DestroyPipeline)(device_h,
638 anv_pipeline_to_handle(device->meta_state.clear.stencil_only_pipeline),
639 NULL);
640 ANV_CALL(DestroyPipeline)(device_h,
641 anv_pipeline_to_handle(device->meta_state.clear.depthstencil_pipeline),
642 NULL);
643 }
644
645 void
646 anv_cmd_buffer_clear_attachments(struct anv_cmd_buffer *cmd_buffer,
647 struct anv_render_pass *pass,
648 const VkClearValue *clear_values)
649 {
650 struct anv_meta_saved_state saved_state;
651
652 /* Figure out whether or not we actually need to clear anything to avoid
653 * trashing state when clearing is a no-op.
654 */
655 bool needs_clear = false;
656 for (uint32_t a = 0; a < pass->attachment_count; ++a) {
657 struct anv_render_pass_attachment *att = &pass->attachments[a];
658
659 if (anv_format_is_color(att->format)) {
660 if (att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
661 needs_clear = true;
662 break;
663 }
664 } else {
665 if ((att->format->depth_format &&
666 att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) ||
667 (att->format->has_stencil &&
668 att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)) {
669 needs_clear = true;
670 break;
671 }
672 }
673 }
674
675 if (!needs_clear)
676 return;
677
678 meta_clear_begin(&saved_state, cmd_buffer);
679
680 if (cmd_buffer->state.framebuffer->layers > 1)
681 anv_finishme("clearing multi-layer framebuffer");
682
683 for (uint32_t a = 0; a < pass->attachment_count; ++a) {
684 struct anv_render_pass_attachment *att = &pass->attachments[a];
685
686 if (anv_format_is_color(att->format)) {
687 if (att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
688 emit_load_color_clear(cmd_buffer, a, clear_values[a].color);
689 }
690 } else {
691 VkImageAspectFlags clear_aspects = 0;
692
693 if (att->format->depth_format &&
694 att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
695 clear_aspects |= VK_IMAGE_ASPECT_DEPTH_BIT;
696 }
697
698 if (att->format->has_stencil &&
699 att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
700 clear_aspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
701 }
702
703 if (clear_aspects) {
704 emit_load_depthstencil_clear(cmd_buffer, a, clear_aspects,
705 clear_values[a].depthStencil);
706 }
707 }
708 }
709
710 meta_clear_end(&saved_state, cmd_buffer);
711 }
712
713 void anv_CmdClearColorImage(
714 VkCommandBuffer commandBuffer,
715 VkImage _image,
716 VkImageLayout imageLayout,
717 const VkClearColorValue* pColor,
718 uint32_t rangeCount,
719 const VkImageSubresourceRange* pRanges)
720 {
721 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
722 ANV_FROM_HANDLE(anv_image, image, _image);
723 struct anv_meta_saved_state saved_state;
724
725 meta_clear_begin(&saved_state, cmd_buffer);
726
727 for (uint32_t r = 0; r < rangeCount; r++) {
728 for (uint32_t l = 0; l < pRanges[r].levelCount; l++) {
729 for (uint32_t s = 0; s < pRanges[r].layerCount; s++) {
730 struct anv_image_view iview;
731 anv_image_view_init(&iview, cmd_buffer->device,
732 &(VkImageViewCreateInfo) {
733 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
734 .image = _image,
735 .viewType = anv_meta_get_view_type(image),
736 .format = image->vk_format,
737 .subresourceRange = {
738 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
739 .baseMipLevel = pRanges[r].baseMipLevel + l,
740 .levelCount = 1,
741 .baseArrayLayer = pRanges[r].baseArrayLayer + s,
742 .layerCount = 1
743 },
744 },
745 cmd_buffer);
746
747 VkFramebuffer fb;
748 anv_CreateFramebuffer(anv_device_to_handle(cmd_buffer->device),
749 &(VkFramebufferCreateInfo) {
750 .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
751 .attachmentCount = 1,
752 .pAttachments = (VkImageView[]) {
753 anv_image_view_to_handle(&iview),
754 },
755 .width = iview.extent.width,
756 .height = iview.extent.height,
757 .layers = 1
758 }, &cmd_buffer->pool->alloc, &fb);
759
760 VkRenderPass pass;
761 anv_CreateRenderPass(anv_device_to_handle(cmd_buffer->device),
762 &(VkRenderPassCreateInfo) {
763 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
764 .attachmentCount = 1,
765 .pAttachments = &(VkAttachmentDescription) {
766 .format = iview.vk_format,
767 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
768 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
769 .initialLayout = VK_IMAGE_LAYOUT_GENERAL,
770 .finalLayout = VK_IMAGE_LAYOUT_GENERAL,
771 },
772 .subpassCount = 1,
773 .pSubpasses = &(VkSubpassDescription) {
774 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
775 .inputAttachmentCount = 0,
776 .colorAttachmentCount = 1,
777 .pColorAttachments = &(VkAttachmentReference) {
778 .attachment = 0,
779 .layout = VK_IMAGE_LAYOUT_GENERAL,
780 },
781 .pResolveAttachments = NULL,
782 .pDepthStencilAttachment = &(VkAttachmentReference) {
783 .attachment = VK_ATTACHMENT_UNUSED,
784 .layout = VK_IMAGE_LAYOUT_GENERAL,
785 },
786 .preserveAttachmentCount = 1,
787 .pPreserveAttachments = (uint32_t[]) { 0 },
788 },
789 .dependencyCount = 0,
790 }, &cmd_buffer->pool->alloc, &pass);
791
792 ANV_CALL(CmdBeginRenderPass)(anv_cmd_buffer_to_handle(cmd_buffer),
793 &(VkRenderPassBeginInfo) {
794 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
795 .renderArea = {
796 .offset = { 0, 0, },
797 .extent = {
798 .width = iview.extent.width,
799 .height = iview.extent.height,
800 },
801 },
802 .renderPass = pass,
803 .framebuffer = fb,
804 .clearValueCount = 1,
805 .pClearValues = (VkClearValue[]) {
806 { .color = *pColor },
807 },
808 }, VK_SUBPASS_CONTENTS_INLINE);
809
810 ANV_CALL(CmdEndRenderPass)(anv_cmd_buffer_to_handle(cmd_buffer));
811
812 /* XXX: We're leaking the render pass and framebuffer */
813 }
814 }
815 }
816
817 meta_clear_end(&saved_state, cmd_buffer);
818 }
819
820 void anv_CmdClearDepthStencilImage(
821 VkCommandBuffer commandBuffer,
822 VkImage image,
823 VkImageLayout imageLayout,
824 const VkClearDepthStencilValue* pDepthStencil,
825 uint32_t rangeCount,
826 const VkImageSubresourceRange* pRanges)
827 {
828 stub();
829 }
830
831 void anv_CmdClearAttachments(
832 VkCommandBuffer commandBuffer,
833 uint32_t attachmentCount,
834 const VkClearAttachment* pAttachments,
835 uint32_t rectCount,
836 const VkClearRect* pRects)
837 {
838 stub();
839 }