OSDN Git Service

anv/meta: Implement multisample clears
[android-x86/external-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 "glsl/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 }