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