anv: Fix warning 3DSTATE_VERTEX_ELEMENTS setup
[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_private.h"
26 #include "nir/nir_builder.h"
27
28 /** Vertex attributes for color clears. */
29 struct color_clear_vattrs {
30 struct anv_vue_header vue_header;
31 float position[2]; /**< 3DPRIM_RECTLIST */
32 VkClearColorValue color;
33 };
34
35 /** Vertex attributes for depthstencil clears. */
36 struct depthstencil_clear_vattrs {
37 struct anv_vue_header vue_header;
38 float position[2]; /*<< 3DPRIM_RECTLIST */
39 };
40
41 static void
42 meta_clear_begin(struct anv_meta_saved_state *saved_state,
43 struct anv_cmd_buffer *cmd_buffer)
44 {
45 anv_meta_save(saved_state, cmd_buffer,
46 (1 << VK_DYNAMIC_STATE_VIEWPORT) |
47 (1 << VK_DYNAMIC_STATE_SCISSOR) |
48 (1 << VK_DYNAMIC_STATE_STENCIL_REFERENCE));
49
50 cmd_buffer->state.dynamic.viewport.count = 0;
51 cmd_buffer->state.dynamic.scissor.count = 0;
52 }
53
54 static void
55 meta_clear_end(struct anv_meta_saved_state *saved_state,
56 struct anv_cmd_buffer *cmd_buffer)
57 {
58 anv_meta_restore(saved_state, cmd_buffer);
59 }
60
61 static void
62 build_color_shaders(struct nir_shader **out_vs,
63 struct nir_shader **out_fs,
64 uint32_t frag_output)
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 + frag_output;
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 uint32_t samples,
121 struct nir_shader *vs_nir,
122 struct nir_shader *fs_nir,
123 const VkPipelineVertexInputStateCreateInfo *vi_state,
124 const VkPipelineDepthStencilStateCreateInfo *ds_state,
125 const VkPipelineColorBlendStateCreateInfo *cb_state,
126 const VkAllocationCallbacks *alloc,
127 bool use_repclear,
128 struct anv_pipeline **pipeline)
129 {
130 VkDevice device_h = anv_device_to_handle(device);
131 VkResult result;
132
133 struct anv_shader_module vs_m = { .nir = vs_nir };
134 struct anv_shader_module fs_m = { .nir = fs_nir };
135
136 VkPipeline pipeline_h = VK_NULL_HANDLE;
137 result = anv_graphics_pipeline_create(device_h,
138 VK_NULL_HANDLE,
139 &(VkGraphicsPipelineCreateInfo) {
140 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
141 .stageCount = fs_nir ? 2 : 1,
142 .pStages = (VkPipelineShaderStageCreateInfo[]) {
143 {
144 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
145 .stage = VK_SHADER_STAGE_VERTEX_BIT,
146 .module = anv_shader_module_to_handle(&vs_m),
147 .pName = "main",
148 },
149 {
150 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
151 .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
152 .module = anv_shader_module_to_handle(&fs_m),
153 .pName = "main",
154 },
155 },
156 .pVertexInputState = vi_state,
157 .pInputAssemblyState = &(VkPipelineInputAssemblyStateCreateInfo) {
158 .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
159 .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
160 .primitiveRestartEnable = false,
161 },
162 .pViewportState = &(VkPipelineViewportStateCreateInfo) {
163 .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
164 .viewportCount = 1,
165 .pViewports = NULL, /* dynamic */
166 .scissorCount = 1,
167 .pScissors = NULL, /* dynamic */
168 },
169 .pRasterizationState = &(VkPipelineRasterizationStateCreateInfo) {
170 .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
171 .rasterizerDiscardEnable = false,
172 .polygonMode = VK_POLYGON_MODE_FILL,
173 .cullMode = VK_CULL_MODE_NONE,
174 .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
175 .depthBiasEnable = false,
176 },
177 .pMultisampleState = &(VkPipelineMultisampleStateCreateInfo) {
178 .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
179 .rasterizationSamples = samples,
180 .sampleShadingEnable = false,
181 .pSampleMask = (VkSampleMask[]) { ~0 },
182 .alphaToCoverageEnable = false,
183 .alphaToOneEnable = false,
184 },
185 .pDepthStencilState = ds_state,
186 .pColorBlendState = cb_state,
187 .pDynamicState = &(VkPipelineDynamicStateCreateInfo) {
188 /* The meta clear pipeline declares all state as dynamic.
189 * As a consequence, vkCmdBindPipeline writes no dynamic state
190 * to the cmd buffer. Therefore, at the end of the meta clear,
191 * we need only restore dynamic state was vkCmdSet.
192 */
193 .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
194 .dynamicStateCount = 9,
195 .pDynamicStates = (VkDynamicState[]) {
196 VK_DYNAMIC_STATE_VIEWPORT,
197 VK_DYNAMIC_STATE_SCISSOR,
198 VK_DYNAMIC_STATE_LINE_WIDTH,
199 VK_DYNAMIC_STATE_DEPTH_BIAS,
200 VK_DYNAMIC_STATE_BLEND_CONSTANTS,
201 VK_DYNAMIC_STATE_DEPTH_BOUNDS,
202 VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
203 VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
204 VK_DYNAMIC_STATE_STENCIL_REFERENCE,
205 },
206 },
207 .flags = 0,
208 .renderPass = anv_render_pass_to_handle(&anv_meta_dummy_renderpass),
209 .subpass = 0,
210 },
211 &(struct anv_graphics_pipeline_create_info) {
212 .color_attachment_count = MAX_RTS,
213 .use_repclear = use_repclear,
214 .disable_viewport = true,
215 .disable_vs = true,
216 .use_rectlist = true
217 },
218 alloc,
219 &pipeline_h);
220
221 ralloc_free(vs_nir);
222 ralloc_free(fs_nir);
223
224 *pipeline = anv_pipeline_from_handle(pipeline_h);
225
226 return result;
227 }
228
229 static VkResult
230 create_color_pipeline(struct anv_device *device,
231 uint32_t samples,
232 uint32_t frag_output,
233 struct anv_pipeline **pipeline)
234 {
235 struct nir_shader *vs_nir;
236 struct nir_shader *fs_nir;
237 build_color_shaders(&vs_nir, &fs_nir, frag_output);
238
239 const VkPipelineVertexInputStateCreateInfo vi_state = {
240 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
241 .vertexBindingDescriptionCount = 1,
242 .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) {
243 {
244 .binding = 0,
245 .stride = sizeof(struct color_clear_vattrs),
246 .inputRate = VK_VERTEX_INPUT_RATE_VERTEX
247 },
248 },
249 .vertexAttributeDescriptionCount = 3,
250 .pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[]) {
251 {
252 /* VUE Header */
253 .location = 0,
254 .binding = 0,
255 .format = VK_FORMAT_R32G32B32A32_UINT,
256 .offset = offsetof(struct color_clear_vattrs, vue_header),
257 },
258 {
259 /* Position */
260 .location = 1,
261 .binding = 0,
262 .format = VK_FORMAT_R32G32_SFLOAT,
263 .offset = offsetof(struct color_clear_vattrs, position),
264 },
265 {
266 /* Color */
267 .location = 2,
268 .binding = 0,
269 .format = VK_FORMAT_R32G32B32A32_SFLOAT,
270 .offset = offsetof(struct color_clear_vattrs, color),
271 },
272 },
273 };
274
275 const VkPipelineDepthStencilStateCreateInfo ds_state = {
276 .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
277 .depthTestEnable = false,
278 .depthWriteEnable = false,
279 .depthBoundsTestEnable = false,
280 .stencilTestEnable = false,
281 };
282
283 const VkPipelineColorBlendStateCreateInfo cb_state = {
284 .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
285 .logicOpEnable = false,
286 .attachmentCount = 1,
287 .pAttachments = (VkPipelineColorBlendAttachmentState []) {
288 {
289 .blendEnable = false,
290 .colorWriteMask = VK_COLOR_COMPONENT_A_BIT |
291 VK_COLOR_COMPONENT_R_BIT |
292 VK_COLOR_COMPONENT_G_BIT |
293 VK_COLOR_COMPONENT_B_BIT,
294 },
295 },
296 };
297
298 /* Disable repclear because we do not want the compiler to replace the
299 * shader. We need the shader to write to the specified color attachment,
300 * but the repclear shader writes to all color attachments.
301 */
302 return
303 create_pipeline(device, samples, vs_nir, fs_nir, &vi_state, &ds_state,
304 &cb_state, &device->meta_state.alloc,
305 /*use_repclear*/ false, pipeline);
306 }
307
308 static void
309 destroy_pipeline(struct anv_device *device, struct anv_pipeline *pipeline)
310 {
311 if (!pipeline)
312 return;
313
314 ANV_CALL(DestroyPipeline)(anv_device_to_handle(device),
315 anv_pipeline_to_handle(pipeline),
316 &device->meta_state.alloc);
317 }
318
319 void
320 anv_device_finish_meta_clear_state(struct anv_device *device)
321 {
322 struct anv_meta_state *state = &device->meta_state;
323
324 for (uint32_t i = 0; i < ARRAY_SIZE(state->clear); ++i) {
325 for (uint32_t j = 0; j < ARRAY_SIZE(state->clear[i].color_pipelines); ++j) {
326 destroy_pipeline(device, state->clear[i].color_pipelines[j]);
327 }
328
329 destroy_pipeline(device, state->clear[i].depth_only_pipeline);
330 destroy_pipeline(device, state->clear[i].stencil_only_pipeline);
331 destroy_pipeline(device, state->clear[i].depthstencil_pipeline);
332 }
333 }
334
335 static void
336 emit_color_clear(struct anv_cmd_buffer *cmd_buffer,
337 const VkClearAttachment *clear_att,
338 const VkClearRect *clear_rect)
339 {
340 struct anv_device *device = cmd_buffer->device;
341 const struct anv_subpass *subpass = cmd_buffer->state.subpass;
342 const struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
343 const uint32_t subpass_att = clear_att->colorAttachment;
344 const uint32_t pass_att = subpass->color_attachments[subpass_att];
345 const struct anv_image_view *iview = fb->attachments[pass_att];
346 const uint32_t samples = iview->image->samples;
347 const uint32_t samples_log2 = ffs(samples) - 1;
348 struct anv_pipeline *pipeline =
349 device->meta_state.clear[samples_log2].color_pipelines[subpass_att];
350 VkClearColorValue clear_value = clear_att->clearValue.color;
351
352 VkCommandBuffer cmd_buffer_h = anv_cmd_buffer_to_handle(cmd_buffer);
353 VkPipeline pipeline_h = anv_pipeline_to_handle(pipeline);
354
355 assert(samples_log2 < ARRAY_SIZE(device->meta_state.clear));
356 assert(clear_att->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
357 assert(clear_att->colorAttachment < subpass->color_count);
358
359 const struct color_clear_vattrs vertex_data[3] = {
360 {
361 .vue_header = { 0 },
362 .position = {
363 clear_rect->rect.offset.x,
364 clear_rect->rect.offset.y,
365 },
366 .color = clear_value,
367 },
368 {
369 .vue_header = { 0 },
370 .position = {
371 clear_rect->rect.offset.x + clear_rect->rect.extent.width,
372 clear_rect->rect.offset.y,
373 },
374 .color = clear_value,
375 },
376 {
377 .vue_header = { 0 },
378 .position = {
379 clear_rect->rect.offset.x + clear_rect->rect.extent.width,
380 clear_rect->rect.offset.y + clear_rect->rect.extent.height,
381 },
382 .color = clear_value,
383 },
384 };
385
386 struct anv_state state =
387 anv_cmd_buffer_emit_dynamic(cmd_buffer, vertex_data, sizeof(vertex_data), 16);
388
389 struct anv_buffer vertex_buffer = {
390 .device = device,
391 .size = sizeof(vertex_data),
392 .bo = &device->dynamic_state_block_pool.bo,
393 .offset = state.offset,
394 };
395
396 ANV_CALL(CmdSetViewport)(cmd_buffer_h, 0, 1,
397 (VkViewport[]) {
398 {
399 .x = 0,
400 .y = 0,
401 .width = fb->width,
402 .height = fb->height,
403 .minDepth = 0.0,
404 .maxDepth = 1.0,
405 },
406 });
407
408 ANV_CALL(CmdSetScissor)(cmd_buffer_h, 0, 1,
409 (VkRect2D[]) {
410 {
411 .offset = { 0, 0 },
412 .extent = { fb->width, fb->height },
413 }
414 });
415
416 ANV_CALL(CmdBindVertexBuffers)(cmd_buffer_h, 0, 1,
417 (VkBuffer[]) { anv_buffer_to_handle(&vertex_buffer) },
418 (VkDeviceSize[]) { 0 });
419
420 if (cmd_buffer->state.pipeline != pipeline) {
421 ANV_CALL(CmdBindPipeline)(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS,
422 pipeline_h);
423 }
424
425 ANV_CALL(CmdDraw)(cmd_buffer_h, 3, 1, 0, 0);
426 }
427
428
429 static void
430 build_depthstencil_shader(struct nir_shader **out_vs)
431 {
432 nir_builder vs_b;
433
434 nir_builder_init_simple_shader(&vs_b, NULL, MESA_SHADER_VERTEX, NULL);
435
436 vs_b.shader->info.name = ralloc_strdup(vs_b.shader, "meta_clear_depthstencil_vs");
437
438 const struct glsl_type *position_type = glsl_vec4_type();
439
440 nir_variable *vs_in_pos =
441 nir_variable_create(vs_b.shader, nir_var_shader_in, position_type,
442 "a_position");
443 vs_in_pos->data.location = VERT_ATTRIB_GENERIC0;
444
445 nir_variable *vs_out_pos =
446 nir_variable_create(vs_b.shader, nir_var_shader_out, position_type,
447 "gl_Position");
448 vs_out_pos->data.location = VARYING_SLOT_POS;
449
450 nir_copy_var(&vs_b, vs_out_pos, vs_in_pos);
451
452 *out_vs = vs_b.shader;
453 }
454
455 static VkResult
456 create_depthstencil_pipeline(struct anv_device *device,
457 VkImageAspectFlags aspects,
458 uint32_t samples,
459 struct anv_pipeline **pipeline)
460 {
461 struct nir_shader *vs_nir;
462
463 build_depthstencil_shader(&vs_nir);
464
465 const VkPipelineVertexInputStateCreateInfo vi_state = {
466 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
467 .vertexBindingDescriptionCount = 1,
468 .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) {
469 {
470 .binding = 0,
471 .stride = sizeof(struct depthstencil_clear_vattrs),
472 .inputRate = VK_VERTEX_INPUT_RATE_VERTEX
473 },
474 },
475 .vertexAttributeDescriptionCount = 2,
476 .pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[]) {
477 {
478 /* VUE Header */
479 .location = 0,
480 .binding = 0,
481 .format = VK_FORMAT_R32G32B32A32_UINT,
482 .offset = offsetof(struct depthstencil_clear_vattrs, vue_header),
483 },
484 {
485 /* Position */
486 .location = 1,
487 .binding = 0,
488 .format = VK_FORMAT_R32G32_SFLOAT,
489 .offset = offsetof(struct depthstencil_clear_vattrs, position),
490 },
491 },
492 };
493
494 const VkPipelineDepthStencilStateCreateInfo ds_state = {
495 .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
496 .depthTestEnable = (aspects & VK_IMAGE_ASPECT_DEPTH_BIT),
497 .depthCompareOp = VK_COMPARE_OP_ALWAYS,
498 .depthWriteEnable = (aspects & VK_IMAGE_ASPECT_DEPTH_BIT),
499 .depthBoundsTestEnable = false,
500 .stencilTestEnable = (aspects & VK_IMAGE_ASPECT_STENCIL_BIT),
501 .front = {
502 .passOp = VK_STENCIL_OP_REPLACE,
503 .compareOp = VK_COMPARE_OP_ALWAYS,
504 .writeMask = UINT32_MAX,
505 .reference = 0, /* dynamic */
506 },
507 .back = { 0 /* dont care */ },
508 };
509
510 const VkPipelineColorBlendStateCreateInfo cb_state = {
511 .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
512 .logicOpEnable = false,
513 .attachmentCount = 0,
514 .pAttachments = NULL,
515 };
516
517 return create_pipeline(device, samples, vs_nir, NULL, &vi_state, &ds_state,
518 &cb_state, &device->meta_state.alloc,
519 /*use_repclear*/ true, pipeline);
520 }
521
522 static void
523 emit_depthstencil_clear(struct anv_cmd_buffer *cmd_buffer,
524 const VkClearAttachment *clear_att,
525 const VkClearRect *clear_rect)
526 {
527 struct anv_device *device = cmd_buffer->device;
528 struct anv_meta_state *meta_state = &device->meta_state;
529 const struct anv_subpass *subpass = cmd_buffer->state.subpass;
530 const struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
531 const uint32_t pass_att = subpass->depth_stencil_attachment;
532 const struct anv_image_view *iview = fb->attachments[pass_att];
533 const uint32_t samples = iview->image->samples;
534 const uint32_t samples_log2 = ffs(samples) - 1;
535 VkClearDepthStencilValue clear_value = clear_att->clearValue.depthStencil;
536 VkImageAspectFlags aspects = clear_att->aspectMask;
537
538 VkCommandBuffer cmd_buffer_h = anv_cmd_buffer_to_handle(cmd_buffer);
539
540 assert(samples_log2 < ARRAY_SIZE(meta_state->clear));
541 assert(aspects == VK_IMAGE_ASPECT_DEPTH_BIT ||
542 aspects == VK_IMAGE_ASPECT_STENCIL_BIT ||
543 aspects == (VK_IMAGE_ASPECT_DEPTH_BIT |
544 VK_IMAGE_ASPECT_STENCIL_BIT));
545 assert(pass_att != VK_ATTACHMENT_UNUSED);
546
547 const struct depthstencil_clear_vattrs vertex_data[3] = {
548 {
549 .vue_header = { 0 },
550 .position = {
551 clear_rect->rect.offset.x,
552 clear_rect->rect.offset.y,
553 },
554 },
555 {
556 .vue_header = { 0 },
557 .position = {
558 clear_rect->rect.offset.x + clear_rect->rect.extent.width,
559 clear_rect->rect.offset.y,
560 },
561 },
562 {
563 .vue_header = { 0 },
564 .position = {
565 clear_rect->rect.offset.x + clear_rect->rect.extent.width,
566 clear_rect->rect.offset.y + clear_rect->rect.extent.height,
567 },
568 },
569 };
570
571 struct anv_state state =
572 anv_cmd_buffer_emit_dynamic(cmd_buffer, vertex_data, sizeof(vertex_data), 16);
573
574 struct anv_buffer vertex_buffer = {
575 .device = device,
576 .size = sizeof(vertex_data),
577 .bo = &device->dynamic_state_block_pool.bo,
578 .offset = state.offset,
579 };
580
581 ANV_CALL(CmdSetViewport)(cmd_buffer_h, 0, 1,
582 (VkViewport[]) {
583 {
584 .x = 0,
585 .y = 0,
586 .width = fb->width,
587 .height = fb->height,
588
589 /* Ignored when clearing only stencil. */
590 .minDepth = clear_value.depth,
591 .maxDepth = clear_value.depth,
592 },
593 });
594
595 ANV_CALL(CmdSetScissor)(cmd_buffer_h, 0, 1,
596 (VkRect2D[]) {
597 {
598 .offset = { 0, 0 },
599 .extent = { fb->width, fb->height },
600 }
601 });
602
603 if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
604 ANV_CALL(CmdSetStencilReference)(cmd_buffer_h, VK_STENCIL_FACE_FRONT_BIT,
605 clear_value.stencil);
606 }
607
608 ANV_CALL(CmdBindVertexBuffers)(cmd_buffer_h, 0, 1,
609 (VkBuffer[]) { anv_buffer_to_handle(&vertex_buffer) },
610 (VkDeviceSize[]) { 0 });
611
612 struct anv_pipeline *pipeline;
613 switch (aspects) {
614 case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT:
615 pipeline = meta_state->clear[samples_log2].depthstencil_pipeline;
616 break;
617 case VK_IMAGE_ASPECT_DEPTH_BIT:
618 pipeline = meta_state->clear[samples_log2].depth_only_pipeline;
619 break;
620 case VK_IMAGE_ASPECT_STENCIL_BIT:
621 pipeline = meta_state->clear[samples_log2].stencil_only_pipeline;
622 break;
623 default:
624 unreachable("expected depth or stencil aspect");
625 }
626
627 if (cmd_buffer->state.pipeline != pipeline) {
628 ANV_CALL(CmdBindPipeline)(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS,
629 anv_pipeline_to_handle(pipeline));
630 }
631
632 ANV_CALL(CmdDraw)(cmd_buffer_h, 3, 1, 0, 0);
633 }
634
635 VkResult
636 anv_device_init_meta_clear_state(struct anv_device *device)
637 {
638 VkResult res;
639 struct anv_meta_state *state = &device->meta_state;
640
641 zero(device->meta_state.clear);
642
643 for (uint32_t i = 0; i < ARRAY_SIZE(state->clear); ++i) {
644 uint32_t samples = 1 << i;
645
646 for (uint32_t j = 0; j < ARRAY_SIZE(state->clear[i].color_pipelines); ++j) {
647 res = create_color_pipeline(device, samples, /* frag_output */ j,
648 &state->clear[i].color_pipelines[j]);
649 if (res != VK_SUCCESS)
650 goto fail;
651 }
652
653 res = create_depthstencil_pipeline(device,
654 VK_IMAGE_ASPECT_DEPTH_BIT, samples,
655 &state->clear[i].depth_only_pipeline);
656 if (res != VK_SUCCESS)
657 goto fail;
658
659 res = create_depthstencil_pipeline(device,
660 VK_IMAGE_ASPECT_STENCIL_BIT, samples,
661 &state->clear[i].stencil_only_pipeline);
662 if (res != VK_SUCCESS)
663 goto fail;
664
665 res = create_depthstencil_pipeline(device,
666 VK_IMAGE_ASPECT_DEPTH_BIT |
667 VK_IMAGE_ASPECT_STENCIL_BIT, samples,
668 &state->clear[i].depthstencil_pipeline);
669 if (res != VK_SUCCESS)
670 goto fail;
671 }
672
673 return VK_SUCCESS;
674
675 fail:
676 anv_device_finish_meta_clear_state(device);
677 return res;
678 }
679
680 /**
681 * The parameters mean that same as those in vkCmdClearAttachments.
682 */
683 static void
684 emit_clear(struct anv_cmd_buffer *cmd_buffer,
685 const VkClearAttachment *clear_att,
686 const VkClearRect *clear_rect)
687 {
688 if (clear_att->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
689 emit_color_clear(cmd_buffer, clear_att, clear_rect);
690 } else {
691 assert(clear_att->aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT |
692 VK_IMAGE_ASPECT_STENCIL_BIT));
693 emit_depthstencil_clear(cmd_buffer, clear_att, clear_rect);
694 }
695 }
696
697 static bool
698 subpass_needs_clear(const struct anv_cmd_buffer *cmd_buffer)
699 {
700 const struct anv_cmd_state *cmd_state = &cmd_buffer->state;
701 uint32_t ds = cmd_state->subpass->depth_stencil_attachment;
702
703 for (uint32_t i = 0; i < cmd_state->subpass->color_count; ++i) {
704 uint32_t a = cmd_state->subpass->color_attachments[i];
705 if (cmd_state->attachments[a].pending_clear_aspects) {
706 return true;
707 }
708 }
709
710 if (ds != VK_ATTACHMENT_UNUSED &&
711 cmd_state->attachments[ds].pending_clear_aspects) {
712 return true;
713 }
714
715 return false;
716 }
717
718 /**
719 * Emit any pending attachment clears for the current subpass.
720 *
721 * @see anv_attachment_state::pending_clear_aspects
722 */
723 void
724 anv_cmd_buffer_clear_subpass(struct anv_cmd_buffer *cmd_buffer)
725 {
726 struct anv_cmd_state *cmd_state = &cmd_buffer->state;
727 struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
728 struct anv_meta_saved_state saved_state;
729
730 if (!subpass_needs_clear(cmd_buffer))
731 return;
732
733 meta_clear_begin(&saved_state, cmd_buffer);
734
735 if (cmd_state->framebuffer->layers > 1)
736 anv_finishme("clearing multi-layer framebuffer");
737
738 VkClearRect clear_rect = {
739 .rect = {
740 .offset = { 0, 0 },
741 .extent = { fb->width, fb->height },
742 },
743 .baseArrayLayer = 0,
744 .layerCount = 1, /* FINISHME: clear multi-layer framebuffer */
745 };
746
747 for (uint32_t i = 0; i < cmd_state->subpass->color_count; ++i) {
748 uint32_t a = cmd_state->subpass->color_attachments[i];
749
750 if (!cmd_state->attachments[a].pending_clear_aspects)
751 continue;
752
753 assert(cmd_state->attachments[a].pending_clear_aspects ==
754 VK_IMAGE_ASPECT_COLOR_BIT);
755
756 VkClearAttachment clear_att = {
757 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
758 .colorAttachment = i, /* Use attachment index relative to subpass */
759 .clearValue = cmd_state->attachments[a].clear_value,
760 };
761
762 emit_clear(cmd_buffer, &clear_att, &clear_rect);
763 cmd_state->attachments[a].pending_clear_aspects = 0;
764 }
765
766 uint32_t ds = cmd_state->subpass->depth_stencil_attachment;
767
768 if (ds != VK_ATTACHMENT_UNUSED &&
769 cmd_state->attachments[ds].pending_clear_aspects) {
770
771 VkClearAttachment clear_att = {
772 .aspectMask = cmd_state->attachments[ds].pending_clear_aspects,
773 .clearValue = cmd_state->attachments[ds].clear_value,
774 };
775
776 emit_clear(cmd_buffer, &clear_att, &clear_rect);
777 cmd_state->attachments[ds].pending_clear_aspects = 0;
778 }
779
780 meta_clear_end(&saved_state, cmd_buffer);
781 }
782
783 static void
784 anv_cmd_clear_image(struct anv_cmd_buffer *cmd_buffer,
785 struct anv_image *image,
786 VkImageLayout image_layout,
787 const VkClearValue *clear_value,
788 uint32_t range_count,
789 const VkImageSubresourceRange *ranges)
790 {
791 VkDevice device_h = anv_device_to_handle(cmd_buffer->device);
792
793 for (uint32_t r = 0; r < range_count; r++) {
794 const VkImageSubresourceRange *range = &ranges[r];
795
796 for (uint32_t l = 0; l < range->levelCount; ++l) {
797 for (uint32_t s = 0; s < range->layerCount; ++s) {
798 struct anv_image_view iview;
799 anv_image_view_init(&iview, cmd_buffer->device,
800 &(VkImageViewCreateInfo) {
801 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
802 .image = anv_image_to_handle(image),
803 .viewType = anv_meta_get_view_type(image),
804 .format = image->vk_format,
805 .subresourceRange = {
806 .aspectMask = range->aspectMask,
807 .baseMipLevel = range->baseMipLevel + l,
808 .levelCount = 1,
809 .baseArrayLayer = range->baseArrayLayer + s,
810 .layerCount = 1
811 },
812 },
813 cmd_buffer, 0);
814
815 VkFramebuffer fb;
816 anv_CreateFramebuffer(device_h,
817 &(VkFramebufferCreateInfo) {
818 .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
819 .attachmentCount = 1,
820 .pAttachments = (VkImageView[]) {
821 anv_image_view_to_handle(&iview),
822 },
823 .width = iview.extent.width,
824 .height = iview.extent.height,
825 .layers = 1
826 },
827 &cmd_buffer->pool->alloc,
828 &fb);
829
830 VkAttachmentDescription att_desc = {
831 .format = iview.vk_format,
832 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
833 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
834 .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
835 .stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE,
836 .initialLayout = image_layout,
837 .finalLayout = image_layout,
838 };
839
840 VkSubpassDescription subpass_desc = {
841 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
842 .inputAttachmentCount = 0,
843 .colorAttachmentCount = 0,
844 .pColorAttachments = NULL,
845 .pResolveAttachments = NULL,
846 .pDepthStencilAttachment = NULL,
847 .preserveAttachmentCount = 0,
848 .pPreserveAttachments = NULL,
849 };
850
851 const VkAttachmentReference att_ref = {
852 .attachment = 0,
853 .layout = image_layout,
854 };
855
856 if (range->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
857 subpass_desc.colorAttachmentCount = 1;
858 subpass_desc.pColorAttachments = &att_ref;
859 } else {
860 subpass_desc.pDepthStencilAttachment = &att_ref;
861 }
862
863 VkRenderPass pass;
864 anv_CreateRenderPass(device_h,
865 &(VkRenderPassCreateInfo) {
866 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
867 .attachmentCount = 1,
868 .pAttachments = &att_desc,
869 .subpassCount = 1,
870 .pSubpasses = &subpass_desc,
871 },
872 &cmd_buffer->pool->alloc,
873 &pass);
874
875 ANV_CALL(CmdBeginRenderPass)(anv_cmd_buffer_to_handle(cmd_buffer),
876 &(VkRenderPassBeginInfo) {
877 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
878 .renderArea = {
879 .offset = { 0, 0, },
880 .extent = {
881 .width = iview.extent.width,
882 .height = iview.extent.height,
883 },
884 },
885 .renderPass = pass,
886 .framebuffer = fb,
887 .clearValueCount = 0,
888 .pClearValues = NULL,
889 },
890 VK_SUBPASS_CONTENTS_INLINE);
891
892 VkClearAttachment clear_att = {
893 .aspectMask = range->aspectMask,
894 .colorAttachment = 0,
895 .clearValue = *clear_value,
896 };
897
898 VkClearRect clear_rect = {
899 .rect = {
900 .offset = { 0, 0 },
901 .extent = { iview.extent.width, iview.extent.height },
902 },
903 .baseArrayLayer = range->baseArrayLayer,
904 .layerCount = 1, /* FINISHME: clear multi-layer framebuffer */
905 };
906
907 emit_clear(cmd_buffer, &clear_att, &clear_rect);
908
909 ANV_CALL(CmdEndRenderPass)(anv_cmd_buffer_to_handle(cmd_buffer));
910 ANV_CALL(DestroyRenderPass)(device_h, pass,
911 &cmd_buffer->pool->alloc);
912 ANV_CALL(DestroyFramebuffer)(device_h, fb,
913 &cmd_buffer->pool->alloc);
914 }
915 }
916 }
917 }
918
919 void anv_CmdClearColorImage(
920 VkCommandBuffer commandBuffer,
921 VkImage image_h,
922 VkImageLayout imageLayout,
923 const VkClearColorValue* pColor,
924 uint32_t rangeCount,
925 const VkImageSubresourceRange* pRanges)
926 {
927 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
928 ANV_FROM_HANDLE(anv_image, image, image_h);
929 struct anv_meta_saved_state saved_state;
930
931 meta_clear_begin(&saved_state, cmd_buffer);
932
933 anv_cmd_clear_image(cmd_buffer, image, imageLayout,
934 (const VkClearValue *) pColor,
935 rangeCount, pRanges);
936
937 meta_clear_end(&saved_state, cmd_buffer);
938 }
939
940 void anv_CmdClearDepthStencilImage(
941 VkCommandBuffer commandBuffer,
942 VkImage image_h,
943 VkImageLayout imageLayout,
944 const VkClearDepthStencilValue* pDepthStencil,
945 uint32_t rangeCount,
946 const VkImageSubresourceRange* pRanges)
947 {
948 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
949 ANV_FROM_HANDLE(anv_image, image, image_h);
950 struct anv_meta_saved_state saved_state;
951
952 meta_clear_begin(&saved_state, cmd_buffer);
953
954 anv_cmd_clear_image(cmd_buffer, image, imageLayout,
955 (const VkClearValue *) pDepthStencil,
956 rangeCount, pRanges);
957
958 meta_clear_end(&saved_state, cmd_buffer);
959 }
960
961 void anv_CmdClearAttachments(
962 VkCommandBuffer commandBuffer,
963 uint32_t attachmentCount,
964 const VkClearAttachment* pAttachments,
965 uint32_t rectCount,
966 const VkClearRect* pRects)
967 {
968 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
969 struct anv_meta_saved_state saved_state;
970
971 meta_clear_begin(&saved_state, cmd_buffer);
972
973 /* FINISHME: We can do better than this dumb loop. It thrashes too much
974 * state.
975 */
976 for (uint32_t a = 0; a < attachmentCount; ++a) {
977 for (uint32_t r = 0; r < rectCount; ++r) {
978 emit_clear(cmd_buffer, &pAttachments[a], &pRects[r]);
979 }
980 }
981
982 meta_clear_end(&saved_state, cmd_buffer);
983 }
984
985 static void
986 do_buffer_fill(struct anv_cmd_buffer *cmd_buffer,
987 struct anv_bo *dest, uint64_t dest_offset,
988 int width, int height, VkFormat fill_format, uint32_t data)
989 {
990 VkDevice vk_device = anv_device_to_handle(cmd_buffer->device);
991
992 VkImageCreateInfo image_info = {
993 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
994 .imageType = VK_IMAGE_TYPE_2D,
995 .format = fill_format,
996 .extent = {
997 .width = width,
998 .height = height,
999 .depth = 1,
1000 },
1001 .mipLevels = 1,
1002 .arrayLayers = 1,
1003 .samples = 1,
1004 .tiling = VK_IMAGE_TILING_LINEAR,
1005 .usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
1006 .flags = 0,
1007 };
1008
1009 VkImage dest_image;
1010 image_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1011 anv_CreateImage(vk_device, &image_info,
1012 &cmd_buffer->pool->alloc, &dest_image);
1013
1014 /* We could use a vk call to bind memory, but that would require
1015 * creating a dummy memory object etc. so there's really no point.
1016 */
1017 anv_image_from_handle(dest_image)->bo = dest;
1018 anv_image_from_handle(dest_image)->offset = dest_offset;
1019
1020 const VkClearValue clear_value = {
1021 .color = {
1022 .uint32 = { data, data, data, data }
1023 }
1024 };
1025
1026 const VkImageSubresourceRange range = {
1027 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
1028 .baseMipLevel = 0,
1029 .levelCount = 1,
1030 .baseArrayLayer = 0,
1031 .layerCount = 1,
1032 };
1033
1034 anv_cmd_clear_image(cmd_buffer, anv_image_from_handle(dest_image),
1035 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1036 &clear_value, 1, &range);
1037 }
1038
1039 void anv_CmdFillBuffer(
1040 VkCommandBuffer commandBuffer,
1041 VkBuffer dstBuffer,
1042 VkDeviceSize dstOffset,
1043 VkDeviceSize fillSize,
1044 uint32_t data)
1045 {
1046 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1047 ANV_FROM_HANDLE(anv_buffer, dst_buffer, dstBuffer);
1048 struct anv_meta_saved_state saved_state;
1049
1050 meta_clear_begin(&saved_state, cmd_buffer);
1051
1052 VkFormat format;
1053 int bs;
1054 if ((fillSize & 15) == 0 && (dstOffset & 15) == 0) {
1055 format = VK_FORMAT_R32G32B32A32_UINT;
1056 bs = 16;
1057 } else if ((fillSize & 7) == 0 && (dstOffset & 15) == 0) {
1058 format = VK_FORMAT_R32G32_UINT;
1059 bs = 8;
1060 } else {
1061 assert((fillSize & 3) == 0 && (dstOffset & 3) == 0);
1062 format = VK_FORMAT_R32_UINT;
1063 bs = 4;
1064 }
1065
1066 /* This is maximum possible width/height our HW can handle */
1067 const uint64_t max_surface_dim = 1 << 14;
1068
1069 /* First, we make a bunch of max-sized copies */
1070 const uint64_t max_fill_size = max_surface_dim * max_surface_dim * bs;
1071 while (fillSize > max_fill_size) {
1072 do_buffer_fill(cmd_buffer, dst_buffer->bo,
1073 dst_buffer->offset + dstOffset,
1074 max_surface_dim, max_surface_dim, format, data);
1075 fillSize -= max_fill_size;
1076 dstOffset += max_fill_size;
1077 }
1078
1079 uint64_t height = fillSize / (max_surface_dim * bs);
1080 assert(height < max_surface_dim);
1081 if (height != 0) {
1082 const uint64_t rect_fill_size = height * max_surface_dim * bs;
1083 do_buffer_fill(cmd_buffer, dst_buffer->bo,
1084 dst_buffer->offset + dstOffset,
1085 max_surface_dim, height, format, data);
1086 fillSize -= rect_fill_size;
1087 dstOffset += rect_fill_size;
1088 }
1089
1090 if (fillSize != 0) {
1091 do_buffer_fill(cmd_buffer, dst_buffer->bo,
1092 dst_buffer->offset + dstOffset,
1093 fillSize / bs, 1, format, data);
1094 }
1095
1096 meta_clear_end(&saved_state, cmd_buffer);
1097 }