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