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