OSDN Git Service

anv/meta: Use blitter API in do_buffer_copy()
[android-x86/external-mesa.git] / src / intel / vulkan / anv_meta_blit.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 "nir/nir_builder.h"
26
27 struct blit_region {
28    VkOffset3D src_offset;
29    VkExtent3D src_extent;
30    VkOffset3D dest_offset;
31    VkExtent3D dest_extent;
32 };
33
34 static nir_shader *
35 build_nir_vertex_shader(void)
36 {
37    const struct glsl_type *vec4 = glsl_vec4_type();
38    nir_builder b;
39
40    nir_builder_init_simple_shader(&b, NULL, MESA_SHADER_VERTEX, NULL);
41    b.shader->info.name = ralloc_strdup(b.shader, "meta_blit_vs");
42
43    nir_variable *pos_in = nir_variable_create(b.shader, nir_var_shader_in,
44                                               vec4, "a_pos");
45    pos_in->data.location = VERT_ATTRIB_GENERIC0;
46    nir_variable *pos_out = nir_variable_create(b.shader, nir_var_shader_out,
47                                                vec4, "gl_Position");
48    pos_out->data.location = VARYING_SLOT_POS;
49    nir_copy_var(&b, pos_out, pos_in);
50
51    nir_variable *tex_pos_in = nir_variable_create(b.shader, nir_var_shader_in,
52                                                   vec4, "a_tex_pos");
53    tex_pos_in->data.location = VERT_ATTRIB_GENERIC1;
54    nir_variable *tex_pos_out = nir_variable_create(b.shader, nir_var_shader_out,
55                                                    vec4, "v_tex_pos");
56    tex_pos_out->data.location = VARYING_SLOT_VAR0;
57    tex_pos_out->data.interpolation = INTERP_QUALIFIER_SMOOTH;
58    nir_copy_var(&b, tex_pos_out, tex_pos_in);
59
60    return b.shader;
61 }
62
63 static nir_shader *
64 build_nir_copy_fragment_shader(enum glsl_sampler_dim tex_dim)
65 {
66    const struct glsl_type *vec4 = glsl_vec4_type();
67    nir_builder b;
68
69    nir_builder_init_simple_shader(&b, NULL, MESA_SHADER_FRAGMENT, NULL);
70    b.shader->info.name = ralloc_strdup(b.shader, "meta_blit_fs");
71
72    nir_variable *tex_pos_in = nir_variable_create(b.shader, nir_var_shader_in,
73                                                   vec4, "v_tex_pos");
74    tex_pos_in->data.location = VARYING_SLOT_VAR0;
75
76    /* Swizzle the array index which comes in as Z coordinate into the right
77     * position.
78     */
79    unsigned swz[] = { 0, (tex_dim == GLSL_SAMPLER_DIM_1D ? 2 : 1), 2 };
80    nir_ssa_def *const tex_pos =
81       nir_swizzle(&b, nir_load_var(&b, tex_pos_in), swz,
82                   (tex_dim == GLSL_SAMPLER_DIM_1D ? 2 : 3), false);
83
84    const struct glsl_type *sampler_type =
85       glsl_sampler_type(tex_dim, false, tex_dim != GLSL_SAMPLER_DIM_3D,
86                         glsl_get_base_type(vec4));
87    nir_variable *sampler = nir_variable_create(b.shader, nir_var_uniform,
88                                                sampler_type, "s_tex");
89    sampler->data.descriptor_set = 0;
90    sampler->data.binding = 0;
91
92    nir_tex_instr *tex = nir_tex_instr_create(b.shader, 1);
93    tex->sampler_dim = tex_dim;
94    tex->op = nir_texop_tex;
95    tex->src[0].src_type = nir_tex_src_coord;
96    tex->src[0].src = nir_src_for_ssa(tex_pos);
97    tex->dest_type = nir_type_float; /* TODO */
98    tex->is_array = glsl_sampler_type_is_array(sampler_type);
99    tex->coord_components = tex_pos->num_components;
100    tex->texture = nir_deref_var_create(tex, sampler);
101    tex->sampler = nir_deref_var_create(tex, sampler);
102
103    nir_ssa_dest_init(&tex->instr, &tex->dest, 4, "tex");
104    nir_builder_instr_insert(&b, &tex->instr);
105
106    nir_variable *color_out = nir_variable_create(b.shader, nir_var_shader_out,
107                                                  vec4, "f_color");
108    color_out->data.location = FRAG_RESULT_DATA0;
109    nir_store_var(&b, color_out, &tex->dest.ssa, 4);
110
111    return b.shader;
112 }
113
114 static void
115 meta_prepare_blit(struct anv_cmd_buffer *cmd_buffer,
116                   struct anv_meta_saved_state *saved_state)
117 {
118    anv_meta_save(saved_state, cmd_buffer,
119                  (1 << VK_DYNAMIC_STATE_VIEWPORT));
120 }
121
122 void
123 anv_meta_begin_blit2d(struct anv_cmd_buffer *cmd_buffer,
124                       struct anv_meta_saved_state *save)
125 {
126    meta_prepare_blit(cmd_buffer, save);
127 }
128
129
130 /* Returns the user-provided VkBufferImageCopy::imageOffset in units of
131  * elements rather than texels. One element equals one texel or one block
132  * if Image is uncompressed or compressed, respectively.
133  */
134 static struct VkOffset3D
135 meta_region_offset_el(const struct anv_image * image,
136                       const struct VkOffset3D * offset)
137 {
138    const struct isl_format_layout * isl_layout = image->format->isl_layout;
139    return (VkOffset3D) {
140       .x = offset->x / isl_layout->bw,
141       .y = offset->y / isl_layout->bh,
142       .z = offset->z / isl_layout->bd,
143    };
144 }
145
146 /* Returns the user-provided VkBufferImageCopy::imageExtent in units of
147  * elements rather than texels. One element equals one texel or one block
148  * if Image is uncompressed or compressed, respectively.
149  */
150 static struct VkExtent3D
151 meta_region_extent_el(const VkFormat format,
152                       const struct VkExtent3D * extent)
153 {
154    const struct isl_format_layout * isl_layout =
155       anv_format_for_vk_format(format)->isl_layout;
156    return (VkExtent3D) {
157       .width  = DIV_ROUND_UP(extent->width , isl_layout->bw),
158       .height = DIV_ROUND_UP(extent->height, isl_layout->bh),
159       .depth  = DIV_ROUND_UP(extent->depth , isl_layout->bd),
160    };
161 }
162
163 static void
164 meta_emit_blit(struct anv_cmd_buffer *cmd_buffer,
165                struct anv_image *src_image,
166                struct anv_image_view *src_iview,
167                VkOffset3D src_offset,
168                VkExtent3D src_extent,
169                struct anv_image *dest_image,
170                struct anv_image_view *dest_iview,
171                VkOffset3D dest_offset,
172                VkExtent3D dest_extent,
173                VkFilter blit_filter)
174 {
175    struct anv_device *device = cmd_buffer->device;
176
177    struct blit_vb_data {
178       float pos[2];
179       float tex_coord[3];
180    } *vb_data;
181
182    assert(src_image->samples == dest_image->samples);
183
184    unsigned vb_size = sizeof(struct anv_vue_header) + 3 * sizeof(*vb_data);
185
186    struct anv_state vb_state =
187       anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, vb_size, 16);
188    memset(vb_state.map, 0, sizeof(struct anv_vue_header));
189    vb_data = vb_state.map + sizeof(struct anv_vue_header);
190
191    vb_data[0] = (struct blit_vb_data) {
192       .pos = {
193          dest_offset.x + dest_extent.width,
194          dest_offset.y + dest_extent.height,
195       },
196       .tex_coord = {
197          (float)(src_offset.x + src_extent.width) / (float)src_iview->extent.width,
198          (float)(src_offset.y + src_extent.height) / (float)src_iview->extent.height,
199          (float)src_offset.z / (float)src_iview->extent.depth,
200       },
201    };
202
203    vb_data[1] = (struct blit_vb_data) {
204       .pos = {
205          dest_offset.x,
206          dest_offset.y + dest_extent.height,
207       },
208       .tex_coord = {
209          (float)src_offset.x / (float)src_iview->extent.width,
210          (float)(src_offset.y + src_extent.height) / (float)src_iview->extent.height,
211          (float)src_offset.z / (float)src_iview->extent.depth,
212       },
213    };
214
215    vb_data[2] = (struct blit_vb_data) {
216       .pos = {
217          dest_offset.x,
218          dest_offset.y,
219       },
220       .tex_coord = {
221          (float)src_offset.x / (float)src_iview->extent.width,
222          (float)src_offset.y / (float)src_iview->extent.height,
223          (float)src_offset.z / (float)src_iview->extent.depth,
224       },
225    };
226
227    anv_state_clflush(vb_state);
228
229    struct anv_buffer vertex_buffer = {
230       .device = device,
231       .size = vb_size,
232       .bo = &device->dynamic_state_block_pool.bo,
233       .offset = vb_state.offset,
234    };
235
236    anv_CmdBindVertexBuffers(anv_cmd_buffer_to_handle(cmd_buffer), 0, 2,
237       (VkBuffer[]) {
238          anv_buffer_to_handle(&vertex_buffer),
239          anv_buffer_to_handle(&vertex_buffer)
240       },
241       (VkDeviceSize[]) {
242          0,
243          sizeof(struct anv_vue_header),
244       });
245
246    VkSampler sampler;
247    ANV_CALL(CreateSampler)(anv_device_to_handle(device),
248       &(VkSamplerCreateInfo) {
249          .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
250          .magFilter = blit_filter,
251          .minFilter = blit_filter,
252       }, &cmd_buffer->pool->alloc, &sampler);
253
254    VkDescriptorPool desc_pool;
255    anv_CreateDescriptorPool(anv_device_to_handle(device),
256       &(const VkDescriptorPoolCreateInfo) {
257          .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
258          .pNext = NULL,
259          .flags = 0,
260          .maxSets = 1,
261          .poolSizeCount = 1,
262          .pPoolSizes = (VkDescriptorPoolSize[]) {
263             {
264                .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
265                .descriptorCount = 1
266             },
267          }
268       }, &cmd_buffer->pool->alloc, &desc_pool);
269
270    VkDescriptorSet set;
271    anv_AllocateDescriptorSets(anv_device_to_handle(device),
272       &(VkDescriptorSetAllocateInfo) {
273          .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
274          .descriptorPool = desc_pool,
275          .descriptorSetCount = 1,
276          .pSetLayouts = &device->meta_state.blit.ds_layout
277       }, &set);
278
279    anv_UpdateDescriptorSets(anv_device_to_handle(device),
280       1, /* writeCount */
281       (VkWriteDescriptorSet[]) {
282          {
283             .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
284             .dstSet = set,
285             .dstBinding = 0,
286             .dstArrayElement = 0,
287             .descriptorCount = 1,
288             .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
289             .pImageInfo = (VkDescriptorImageInfo[]) {
290                {
291                   .sampler = sampler,
292                   .imageView = anv_image_view_to_handle(src_iview),
293                   .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
294                },
295             }
296          }
297       }, 0, NULL);
298
299    VkFramebuffer fb;
300    anv_CreateFramebuffer(anv_device_to_handle(device),
301       &(VkFramebufferCreateInfo) {
302          .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
303          .attachmentCount = 1,
304          .pAttachments = (VkImageView[]) {
305             anv_image_view_to_handle(dest_iview),
306          },
307          .width = dest_iview->extent.width,
308          .height = dest_iview->extent.height,
309          .layers = 1
310       }, &cmd_buffer->pool->alloc, &fb);
311
312    ANV_CALL(CmdBeginRenderPass)(anv_cmd_buffer_to_handle(cmd_buffer),
313       &(VkRenderPassBeginInfo) {
314          .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
315          .renderPass = device->meta_state.blit.render_pass,
316          .framebuffer = fb,
317          .renderArea = {
318             .offset = { dest_offset.x, dest_offset.y },
319             .extent = { dest_extent.width, dest_extent.height },
320          },
321          .clearValueCount = 0,
322          .pClearValues = NULL,
323       }, VK_SUBPASS_CONTENTS_INLINE);
324
325    VkPipeline pipeline;
326
327    switch (src_image->type) {
328    case VK_IMAGE_TYPE_1D:
329       pipeline = device->meta_state.blit.pipeline_1d_src;
330       break;
331    case VK_IMAGE_TYPE_2D:
332       pipeline = device->meta_state.blit.pipeline_2d_src;
333       break;
334    case VK_IMAGE_TYPE_3D:
335       pipeline = device->meta_state.blit.pipeline_3d_src;
336       break;
337    default:
338       unreachable(!"bad VkImageType");
339    }
340
341    if (cmd_buffer->state.pipeline != anv_pipeline_from_handle(pipeline)) {
342       anv_CmdBindPipeline(anv_cmd_buffer_to_handle(cmd_buffer),
343                           VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
344    }
345
346    anv_CmdSetViewport(anv_cmd_buffer_to_handle(cmd_buffer), 0, 1,
347                       &(VkViewport) {
348                         .x = 0.0f,
349                         .y = 0.0f,
350                         .width = dest_iview->extent.width,
351                         .height = dest_iview->extent.height,
352                         .minDepth = 0.0f,
353                         .maxDepth = 1.0f,
354                       });
355
356    anv_CmdBindDescriptorSets(anv_cmd_buffer_to_handle(cmd_buffer),
357                              VK_PIPELINE_BIND_POINT_GRAPHICS,
358                              device->meta_state.blit.pipeline_layout, 0, 1,
359                              &set, 0, NULL);
360
361    ANV_CALL(CmdDraw)(anv_cmd_buffer_to_handle(cmd_buffer), 3, 1, 0, 0);
362
363    ANV_CALL(CmdEndRenderPass)(anv_cmd_buffer_to_handle(cmd_buffer));
364
365    /* At the point where we emit the draw call, all data from the
366     * descriptor sets, etc. has been used.  We are free to delete it.
367     */
368    anv_DestroyDescriptorPool(anv_device_to_handle(device),
369                              desc_pool, &cmd_buffer->pool->alloc);
370    anv_DestroySampler(anv_device_to_handle(device), sampler,
371                       &cmd_buffer->pool->alloc);
372    anv_DestroyFramebuffer(anv_device_to_handle(device), fb,
373                           &cmd_buffer->pool->alloc);
374 }
375
376 static void
377 meta_finish_blit(struct anv_cmd_buffer *cmd_buffer,
378                  const struct anv_meta_saved_state *saved_state)
379 {
380    anv_meta_restore(saved_state, cmd_buffer);
381 }
382
383 void
384 anv_meta_end_blit2d(struct anv_cmd_buffer *cmd_buffer,
385                     struct anv_meta_saved_state *save)
386 {
387    meta_finish_blit(cmd_buffer, save);
388 }
389
390 static VkFormat
391 vk_format_for_size(int bs)
392 {
393    /* The choice of UNORM and UINT formats is very intentional here.  Most of
394     * the time, we want to use a UINT format to avoid any rounding error in
395     * the blit.  For stencil blits, R8_UINT is required by the hardware.
396     * (It's the only format allowed in conjunction with W-tiling.)  Also we
397     * intentionally use the 4-channel formats whenever we can.  This is so
398     * that, when we do a RGB <-> RGBX copy, the two formats will line up even
399     * though one of them is 3/4 the size of the other.  The choice of UNORM
400     * vs. UINT is also very intentional because Haswell doesn't handle 8 or
401     * 16-bit RGB UINT formats at all so we have to use UNORM there.
402     * Fortunately, the only time we should ever use two different formats in
403     * the table below is for RGB -> RGBA blits and so we will never have any
404     * UNORM/UINT mismatch.
405     */
406    switch (bs) {
407    case 1: return VK_FORMAT_R8_UINT;
408    case 2: return VK_FORMAT_R8G8_UINT;
409    case 3: return VK_FORMAT_R8G8B8_UNORM;
410    case 4: return VK_FORMAT_R8G8B8A8_UNORM;
411    case 6: return VK_FORMAT_R16G16B16_UNORM;
412    case 8: return VK_FORMAT_R16G16B16A16_UNORM;
413    case 12: return VK_FORMAT_R32G32B32_UINT;
414    case 16: return VK_FORMAT_R32G32B32A32_UINT;
415    default:
416       unreachable("Invalid format block size");
417    }
418 }
419
420 static struct anv_meta_blit2d_surf
421 blit_surf_for_image(const struct anv_image* image,
422                     const struct isl_surf *img_isl_surf)
423 {
424    return (struct anv_meta_blit2d_surf) {
425             .bo = image->bo,
426             .tiling = img_isl_surf->tiling,
427             .base_offset = image->offset,
428             .bs = isl_format_get_layout(img_isl_surf->format)->bs,
429             .pitch = isl_surf_get_row_pitch(img_isl_surf),
430    };
431 }
432
433 void
434 anv_meta_blit2d(struct anv_cmd_buffer *cmd_buffer,
435                 struct anv_meta_blit2d_surf *src,
436                 struct anv_meta_blit2d_surf *dst,
437                 unsigned num_rects,
438                 struct anv_meta_blit2d_rect *rects)
439 {
440    VkDevice vk_device = anv_device_to_handle(cmd_buffer->device);
441    VkFormat src_format = vk_format_for_size(src->bs);
442    VkFormat dst_format = vk_format_for_size(dst->bs);
443
444    for (unsigned r = 0; r < num_rects; ++r) {
445
446       /* Create VkImages */
447       VkImageCreateInfo image_info = {
448          .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
449          .imageType = VK_IMAGE_TYPE_2D,
450          .format = 0, /* TEMPLATE */
451          .extent = {
452             .width = 0, /* TEMPLATE */
453             /* Pad to highest tile height to compensate for a vertical intratile offset */
454             .height = MIN(rects[r].height + 64, 1 << 14),
455             .depth = 1,
456          },
457          .mipLevels = 1,
458          .arrayLayers = 1,
459          .samples = 1,
460          .tiling = 0, /* TEMPLATE */
461          .usage = 0, /* TEMPLATE */
462       };
463       struct anv_image_create_info anv_image_info = {
464          .vk_info = &image_info,
465          .isl_tiling_flags = 0, /* TEMPLATE */
466       };
467
468       anv_image_info.isl_tiling_flags = 1 << src->tiling;
469       image_info.tiling = anv_image_info.isl_tiling_flags == ISL_TILING_LINEAR_BIT ?
470                         VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL;
471       image_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
472       image_info.format = src_format,
473       image_info.extent.width = src->pitch / src->bs;
474       VkImage src_image;
475       anv_image_create(vk_device, &anv_image_info,
476                      &cmd_buffer->pool->alloc, &src_image);
477
478       anv_image_info.isl_tiling_flags = 1 << dst->tiling;
479       image_info.tiling = anv_image_info.isl_tiling_flags == ISL_TILING_LINEAR_BIT ?
480                         VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL;
481       image_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
482       image_info.format = dst_format,
483       image_info.extent.width = dst->pitch / dst->bs;
484       VkImage dst_image;
485       anv_image_create(vk_device, &anv_image_info,
486                      &cmd_buffer->pool->alloc, &dst_image);
487
488       /* We could use a vk call to bind memory, but that would require
489       * creating a dummy memory object etc. so there's really no point.
490       */
491       anv_image_from_handle(src_image)->bo = src->bo;
492       anv_image_from_handle(src_image)->offset = src->base_offset;
493       anv_image_from_handle(dst_image)->bo = dst->bo;
494       anv_image_from_handle(dst_image)->offset = dst->base_offset;
495
496       /* Create VkImageViews */
497       VkImageViewCreateInfo iview_info = {
498          .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
499          .image = 0, /* TEMPLATE */
500          .viewType = VK_IMAGE_VIEW_TYPE_2D,
501          .format = 0, /* TEMPLATE */
502          .subresourceRange = {
503             .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
504             .baseMipLevel = 0,
505             .levelCount = 1,
506             .baseArrayLayer = 0,
507             .layerCount = 1
508          },
509       };
510       uint32_t img_o = 0;
511
512       iview_info.image = src_image;
513       iview_info.format = src_format;
514       VkOffset3D src_offset_el = {0};
515       isl_surf_get_image_intratile_offset_el_xy(&cmd_buffer->device->isl_dev,
516                                                 &anv_image_from_handle(src_image)->
517                                                    color_surface.isl,
518                                                 rects[r].src_x,
519                                                 rects[r].src_y,
520                                                 &img_o,
521                                                 (uint32_t*)&src_offset_el.x,
522                                                 (uint32_t*)&src_offset_el.y);
523
524       struct anv_image_view src_iview;
525       anv_image_view_init(&src_iview, cmd_buffer->device,
526          &iview_info, cmd_buffer, img_o, VK_IMAGE_USAGE_SAMPLED_BIT);
527
528       iview_info.image = dst_image;
529       iview_info.format = dst_format;
530       VkOffset3D dst_offset_el = {0};
531       isl_surf_get_image_intratile_offset_el_xy(&cmd_buffer->device->isl_dev,
532                                                 &anv_image_from_handle(dst_image)->
533                                                    color_surface.isl,
534                                                 rects[r].dst_x,
535                                                 rects[r].dst_y,
536                                                 &img_o,
537                                                 (uint32_t*)&dst_offset_el.x,
538                                                 (uint32_t*)&dst_offset_el.y);
539       struct anv_image_view dst_iview;
540       anv_image_view_init(&dst_iview, cmd_buffer->device,
541          &iview_info, cmd_buffer, img_o, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
542
543       /* Perform blit */
544       meta_emit_blit(cmd_buffer,
545                      anv_image_from_handle(src_image),
546                      &src_iview,
547                      src_offset_el,
548                      (VkExtent3D){rects[r].width, rects[r].height, 1},
549                      anv_image_from_handle(dst_image),
550                      &dst_iview,
551                      dst_offset_el,
552                      (VkExtent3D){rects[r].width, rects[r].height, 1},
553                      VK_FILTER_NEAREST);
554
555       anv_DestroyImage(vk_device, src_image, &cmd_buffer->pool->alloc);
556       anv_DestroyImage(vk_device, dst_image, &cmd_buffer->pool->alloc);
557    }
558 }
559
560 static void
561 do_buffer_copy(struct anv_cmd_buffer *cmd_buffer,
562                struct anv_bo *src, uint64_t src_offset,
563                struct anv_bo *dest, uint64_t dest_offset,
564                int width, int height, int bs)
565 {
566    struct anv_meta_blit2d_surf b_src = {
567             .bo = src,
568             .tiling = ISL_TILING_LINEAR,
569             .base_offset = src_offset,
570             .bs = bs,
571             .pitch = width * bs,
572    };
573    struct anv_meta_blit2d_surf b_dst = {
574             .bo = dest,
575             .tiling = ISL_TILING_LINEAR,
576             .base_offset = dest_offset,
577             .bs = bs,
578             .pitch = width * bs,
579    };
580    struct anv_meta_blit2d_rect rect = {
581       .width = width,
582       .height = height,
583    };
584    anv_meta_blit2d(cmd_buffer,
585                   &b_src,
586                   &b_dst,
587                   1,
588                   &rect);
589 }
590
591 void anv_CmdCopyBuffer(
592     VkCommandBuffer                             commandBuffer,
593     VkBuffer                                    srcBuffer,
594     VkBuffer                                    destBuffer,
595     uint32_t                                    regionCount,
596     const VkBufferCopy*                         pRegions)
597 {
598    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
599    ANV_FROM_HANDLE(anv_buffer, src_buffer, srcBuffer);
600    ANV_FROM_HANDLE(anv_buffer, dest_buffer, destBuffer);
601
602    struct anv_meta_saved_state saved_state;
603
604    meta_prepare_blit(cmd_buffer, &saved_state);
605
606    for (unsigned r = 0; r < regionCount; r++) {
607       uint64_t src_offset = src_buffer->offset + pRegions[r].srcOffset;
608       uint64_t dest_offset = dest_buffer->offset + pRegions[r].dstOffset;
609       uint64_t copy_size = pRegions[r].size;
610
611       /* First, we compute the biggest format that can be used with the
612        * given offsets and size.
613        */
614       int bs = 16;
615
616       int fs = ffs(src_offset) - 1;
617       if (fs != -1)
618          bs = MIN2(bs, 1 << fs);
619       assert(src_offset % bs == 0);
620
621       fs = ffs(dest_offset) - 1;
622       if (fs != -1)
623          bs = MIN2(bs, 1 << fs);
624       assert(dest_offset % bs == 0);
625
626       fs = ffs(pRegions[r].size) - 1;
627       if (fs != -1)
628          bs = MIN2(bs, 1 << fs);
629       assert(pRegions[r].size % bs == 0);
630
631       /* This is maximum possible width/height our HW can handle */
632       uint64_t max_surface_dim = 1 << 14;
633
634       /* First, we make a bunch of max-sized copies */
635       uint64_t max_copy_size = max_surface_dim * max_surface_dim * bs;
636       while (copy_size >= max_copy_size) {
637          do_buffer_copy(cmd_buffer, src_buffer->bo, src_offset,
638                         dest_buffer->bo, dest_offset,
639                         max_surface_dim, max_surface_dim, bs);
640          copy_size -= max_copy_size;
641          src_offset += max_copy_size;
642          dest_offset += max_copy_size;
643       }
644
645       uint64_t height = copy_size / (max_surface_dim * bs);
646       assert(height < max_surface_dim);
647       if (height != 0) {
648          uint64_t rect_copy_size = height * max_surface_dim * bs;
649          do_buffer_copy(cmd_buffer, src_buffer->bo, src_offset,
650                         dest_buffer->bo, dest_offset,
651                         max_surface_dim, height, bs);
652          copy_size -= rect_copy_size;
653          src_offset += rect_copy_size;
654          dest_offset += rect_copy_size;
655       }
656
657       if (copy_size != 0) {
658          do_buffer_copy(cmd_buffer, src_buffer->bo, src_offset,
659                         dest_buffer->bo, dest_offset,
660                         copy_size / bs, 1, bs);
661       }
662    }
663
664    meta_finish_blit(cmd_buffer, &saved_state);
665 }
666
667 void anv_CmdUpdateBuffer(
668     VkCommandBuffer                             commandBuffer,
669     VkBuffer                                    dstBuffer,
670     VkDeviceSize                                dstOffset,
671     VkDeviceSize                                dataSize,
672     const uint32_t*                             pData)
673 {
674    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
675    ANV_FROM_HANDLE(anv_buffer, dst_buffer, dstBuffer);
676    struct anv_meta_saved_state saved_state;
677
678    meta_prepare_blit(cmd_buffer, &saved_state);
679
680    /* We can't quite grab a full block because the state stream needs a
681     * little data at the top to build its linked list.
682     */
683    const uint32_t max_update_size =
684       cmd_buffer->device->dynamic_state_block_pool.block_size - 64;
685
686    assert(max_update_size < (1 << 14) * 4);
687
688    while (dataSize) {
689       const uint32_t copy_size = MIN2(dataSize, max_update_size);
690
691       struct anv_state tmp_data =
692          anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, copy_size, 64);
693
694       memcpy(tmp_data.map, pData, copy_size);
695
696       int bs;
697       if ((copy_size & 15) == 0 && (dstOffset & 15) == 0) {
698          bs = 16;
699       } else if ((copy_size & 7) == 0 && (dstOffset & 7) == 0) {
700          bs = 8;
701       } else {
702          assert((copy_size & 3) == 0 && (dstOffset & 3) == 0);
703          bs = 4;
704       }
705
706       do_buffer_copy(cmd_buffer,
707                      &cmd_buffer->device->dynamic_state_block_pool.bo,
708                      tmp_data.offset,
709                      dst_buffer->bo, dst_buffer->offset + dstOffset,
710                      copy_size / bs, 1, bs);
711
712       dataSize -= copy_size;
713       dstOffset += copy_size;
714       pData = (void *)pData + copy_size;
715    }
716
717    meta_finish_blit(cmd_buffer, &saved_state);
718 }
719
720 static VkFormat
721 choose_iview_format(struct anv_image *image, VkImageAspectFlagBits aspect)
722 {
723    assert(__builtin_popcount(aspect) == 1);
724
725    struct isl_surf *surf =
726       &anv_image_get_surface_for_aspect_mask(image, aspect)->isl;
727
728    /* vkCmdCopyImage behaves like memcpy. Therefore we choose identical UINT
729     * formats for the source and destination image views.
730     *
731     * From the Vulkan spec (2015-12-30):
732     *
733     *    vkCmdCopyImage performs image copies in a similar manner to a host
734     *    memcpy. It does not perform general-purpose conversions such as
735     *    scaling, resizing, blending, color-space conversion, or format
736     *    conversions.  Rather, it simply copies raw image data. vkCmdCopyImage
737     *    can copy between images with different formats, provided the formats
738     *    are compatible as defined below.
739     *
740     *    [The spec later defines compatibility as having the same number of
741     *    bytes per block].
742     */
743    return vk_format_for_size(isl_format_layouts[surf->format].bs);
744 }
745
746 static VkFormat
747 choose_buffer_format(VkFormat format, VkImageAspectFlagBits aspect)
748 {
749    assert(__builtin_popcount(aspect) == 1);
750
751    /* vkCmdCopy* commands behave like memcpy. Therefore we choose
752     * compatable UINT formats for the source and destination image views.
753     *
754     * For the buffer, we go back to the original image format and get a
755     * the format as if it were linear.  This way, for RGB formats, we get
756     * an RGB format here even if the tiled image is RGBA. XXX: This doesn't
757     * work if the buffer is the destination.
758     */
759    enum isl_format linear_format = anv_get_isl_format(format, aspect,
760                                                       VK_IMAGE_TILING_LINEAR,
761                                                       NULL);
762
763    return vk_format_for_size(isl_format_layouts[linear_format].bs);
764 }
765
766 void anv_CmdCopyImage(
767     VkCommandBuffer                             commandBuffer,
768     VkImage                                     srcImage,
769     VkImageLayout                               srcImageLayout,
770     VkImage                                     destImage,
771     VkImageLayout                               destImageLayout,
772     uint32_t                                    regionCount,
773     const VkImageCopy*                          pRegions)
774 {
775    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
776    ANV_FROM_HANDLE(anv_image, src_image, srcImage);
777    ANV_FROM_HANDLE(anv_image, dest_image, destImage);
778    struct anv_meta_saved_state saved_state;
779
780    /* From the Vulkan 1.0 spec:
781     *
782     *    vkCmdCopyImage can be used to copy image data between multisample
783     *    images, but both images must have the same number of samples.
784     */
785    assert(src_image->samples == dest_image->samples);
786
787    anv_meta_begin_blit2d(cmd_buffer, &saved_state);
788
789    for (unsigned r = 0; r < regionCount; r++) {
790       assert(pRegions[r].srcSubresource.aspectMask ==
791              pRegions[r].dstSubresource.aspectMask);
792
793       VkImageAspectFlags aspect = pRegions[r].srcSubresource.aspectMask;
794
795       /* Create blit surfaces */
796       struct isl_surf *src_isl_surf =
797          &anv_image_get_surface_for_aspect_mask(src_image, aspect)->isl;
798       struct isl_surf *dst_isl_surf =
799          &anv_image_get_surface_for_aspect_mask(dest_image, aspect)->isl;
800       struct anv_meta_blit2d_surf b_src = blit_surf_for_image(src_image, src_isl_surf);
801       struct anv_meta_blit2d_surf b_dst = blit_surf_for_image(dest_image, dst_isl_surf);
802
803       /* Start creating blit rect */
804       const VkOffset3D dst_offset_el = meta_region_offset_el(dest_image, &pRegions[r].dstOffset);
805       const VkOffset3D src_offset_el = meta_region_offset_el(src_image, &pRegions[r].srcOffset);
806       const VkExtent3D img_extent_el = meta_region_extent_el(src_image->vk_format,
807                                                                 &pRegions[r].extent);
808       struct anv_meta_blit2d_rect rect = {
809          .width = img_extent_el.width,
810          .height = img_extent_el.height,
811       };
812
813       /* Loop through each 3D or array slice */
814       unsigned num_slices_3d = pRegions[r].extent.depth;
815       unsigned num_slices_array = pRegions[r].dstSubresource.layerCount;
816       unsigned slice_3d = 0;
817       unsigned slice_array = 0;
818       while (slice_3d < num_slices_3d && slice_array < num_slices_array) {
819
820          /* Finish creating blit rect */
821          isl_surf_get_image_offset_el(dst_isl_surf,
822                                     pRegions[r].dstSubresource.mipLevel,
823                                     pRegions[r].dstSubresource.baseArrayLayer + slice_array,
824                                     pRegions[r].dstOffset.z + slice_3d,
825                                     &rect.dst_x,
826                                     &rect.dst_y);
827          isl_surf_get_image_offset_el(src_isl_surf,
828                                     pRegions[r].srcSubresource.mipLevel,
829                                     pRegions[r].srcSubresource.baseArrayLayer + slice_array,
830                                     pRegions[r].srcOffset.z + slice_3d,
831                                     &rect.src_x,
832                                     &rect.src_y);
833          rect.dst_x += dst_offset_el.x;
834          rect.dst_y += dst_offset_el.y;
835          rect.src_x += src_offset_el.x;
836          rect.src_y += src_offset_el.y;
837
838          /* Perform Blit */
839          anv_meta_blit2d(cmd_buffer,
840                         &b_src,
841                         &b_dst,
842                         1,
843                         &rect);
844
845          if (dest_image->type == VK_IMAGE_TYPE_3D)
846             slice_3d++;
847          else
848             slice_array++;
849       }
850    }
851
852    anv_meta_end_blit2d(cmd_buffer, &saved_state);
853 }
854
855 void anv_CmdBlitImage(
856     VkCommandBuffer                             commandBuffer,
857     VkImage                                     srcImage,
858     VkImageLayout                               srcImageLayout,
859     VkImage                                     destImage,
860     VkImageLayout                               destImageLayout,
861     uint32_t                                    regionCount,
862     const VkImageBlit*                          pRegions,
863     VkFilter                                    filter)
864
865 {
866    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
867    ANV_FROM_HANDLE(anv_image, src_image, srcImage);
868    ANV_FROM_HANDLE(anv_image, dest_image, destImage);
869    struct anv_meta_saved_state saved_state;
870
871    /* From the Vulkan 1.0 spec:
872     *
873     *    vkCmdBlitImage must not be used for multisampled source or
874     *    destination images. Use vkCmdResolveImage for this purpose.
875     */
876    assert(src_image->samples == 1);
877    assert(dest_image->samples == 1);
878
879    anv_finishme("respect VkFilter");
880
881    meta_prepare_blit(cmd_buffer, &saved_state);
882
883    for (unsigned r = 0; r < regionCount; r++) {
884       struct anv_image_view src_iview;
885       anv_image_view_init(&src_iview, cmd_buffer->device,
886          &(VkImageViewCreateInfo) {
887             .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
888             .image = srcImage,
889             .viewType = anv_meta_get_view_type(src_image),
890             .format = src_image->vk_format,
891             .subresourceRange = {
892                .aspectMask = pRegions[r].srcSubresource.aspectMask,
893                .baseMipLevel = pRegions[r].srcSubresource.mipLevel,
894                .levelCount = 1,
895                .baseArrayLayer = pRegions[r].srcSubresource.baseArrayLayer,
896                .layerCount = 1
897             },
898          },
899          cmd_buffer, 0, VK_IMAGE_USAGE_SAMPLED_BIT);
900
901       const VkOffset3D dest_offset = {
902          .x = pRegions[r].dstOffsets[0].x,
903          .y = pRegions[r].dstOffsets[0].y,
904          .z = 0,
905       };
906
907       if (pRegions[r].dstOffsets[1].x < pRegions[r].dstOffsets[0].x ||
908           pRegions[r].dstOffsets[1].y < pRegions[r].dstOffsets[0].y ||
909           pRegions[r].srcOffsets[1].x < pRegions[r].srcOffsets[0].x ||
910           pRegions[r].srcOffsets[1].y < pRegions[r].srcOffsets[0].y)
911          anv_finishme("FINISHME: Allow flipping in blits");
912
913       const VkExtent3D dest_extent = {
914          .width = pRegions[r].dstOffsets[1].x - pRegions[r].dstOffsets[0].x,
915          .height = pRegions[r].dstOffsets[1].y - pRegions[r].dstOffsets[0].y,
916       };
917
918       const VkExtent3D src_extent = {
919          .width = pRegions[r].srcOffsets[1].x - pRegions[r].srcOffsets[0].x,
920          .height = pRegions[r].srcOffsets[1].y - pRegions[r].srcOffsets[0].y,
921       };
922
923       const uint32_t dest_array_slice =
924          anv_meta_get_iview_layer(dest_image, &pRegions[r].dstSubresource,
925                                   &pRegions[r].dstOffsets[0]);
926
927       if (pRegions[r].srcSubresource.layerCount > 1)
928          anv_finishme("FINISHME: copy multiple array layers");
929
930       if (pRegions[r].srcOffsets[0].z + 1 != pRegions[r].srcOffsets[1].z ||
931           pRegions[r].dstOffsets[0].z + 1 != pRegions[r].dstOffsets[1].z)
932          anv_finishme("FINISHME: copy multiple depth layers");
933
934       struct anv_image_view dest_iview;
935       anv_image_view_init(&dest_iview, cmd_buffer->device,
936          &(VkImageViewCreateInfo) {
937             .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
938             .image = destImage,
939             .viewType = anv_meta_get_view_type(dest_image),
940             .format = dest_image->vk_format,
941             .subresourceRange = {
942                .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
943                .baseMipLevel = pRegions[r].dstSubresource.mipLevel,
944                .levelCount = 1,
945                .baseArrayLayer = dest_array_slice,
946                .layerCount = 1
947             },
948          },
949          cmd_buffer, 0, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
950
951       meta_emit_blit(cmd_buffer,
952                      src_image, &src_iview,
953                      pRegions[r].srcOffsets[0], src_extent,
954                      dest_image, &dest_iview,
955                      dest_offset, dest_extent,
956                      filter);
957    }
958
959    meta_finish_blit(cmd_buffer, &saved_state);
960 }
961
962 static void
963 meta_copy_buffer_to_image(struct anv_cmd_buffer *cmd_buffer,
964                           struct anv_buffer* buffer,
965                           struct anv_image* image,
966                           uint32_t regionCount,
967                           const VkBufferImageCopy* pRegions,
968                           bool forward)
969 {
970    struct anv_meta_saved_state saved_state;
971
972    /* The Vulkan 1.0 spec says "dstImage must have a sample count equal to
973     * VK_SAMPLE_COUNT_1_BIT."
974     */
975    assert(image->samples == 1);
976
977    anv_meta_begin_blit2d(cmd_buffer, &saved_state);
978
979    for (unsigned r = 0; r < regionCount; r++) {
980
981       /* Start creating blit rect */
982       const VkOffset3D img_offset_el = meta_region_offset_el(image, &pRegions[r].imageOffset);
983       const VkExtent3D bufferExtent = {
984          .width = pRegions[r].bufferRowLength,
985          .height = pRegions[r].bufferImageHeight,
986       };
987       const VkExtent3D buf_extent_el = meta_region_extent_el(image->vk_format, &bufferExtent);
988       const VkExtent3D img_extent_el = meta_region_extent_el(image->vk_format,
989                                                                &pRegions[r].imageExtent);
990       struct anv_meta_blit2d_rect rect = {
991          .width = MAX2(buf_extent_el.width, img_extent_el.width),
992          .height = MAX2(buf_extent_el.height, img_extent_el.height),
993       };
994
995       /* Create blit surfaces */
996       VkImageAspectFlags aspect = pRegions[r].imageSubresource.aspectMask;
997       const struct isl_surf *img_isl_surf =
998          &anv_image_get_surface_for_aspect_mask(image, aspect)->isl;
999       struct anv_meta_blit2d_surf img_bsurf = blit_surf_for_image(image, img_isl_surf);
1000       struct anv_meta_blit2d_surf buf_bsurf = {
1001          .bo = buffer->bo,
1002          .tiling = ISL_TILING_LINEAR,
1003          .base_offset = buffer->offset + pRegions[r].bufferOffset,
1004          .bs = forward ? image->format->isl_layout->bs : img_bsurf.bs,
1005          .pitch = rect.width * buf_bsurf.bs,
1006       };
1007
1008       /* Set direction-dependent variables */
1009       struct anv_meta_blit2d_surf *dst_bsurf = forward ? &img_bsurf : &buf_bsurf;
1010       struct anv_meta_blit2d_surf *src_bsurf = forward ? &buf_bsurf : &img_bsurf;
1011       uint32_t *x_offset = forward ? &rect.dst_x : &rect.src_x;
1012       uint32_t *y_offset = forward ? &rect.dst_y : &rect.src_y;
1013
1014       /* Loop through each 3D or array slice */
1015       unsigned num_slices_3d = pRegions[r].imageExtent.depth;
1016       unsigned num_slices_array = pRegions[r].imageSubresource.layerCount;
1017       unsigned slice_3d = 0;
1018       unsigned slice_array = 0;
1019       while (slice_3d < num_slices_3d && slice_array < num_slices_array) {
1020
1021          /* Finish creating blit rect */
1022          isl_surf_get_image_offset_el(img_isl_surf,
1023                                     pRegions[r].imageSubresource.mipLevel,
1024                                     pRegions[r].imageSubresource.baseArrayLayer + slice_array,
1025                                     pRegions[r].imageOffset.z + slice_3d,
1026                                     x_offset,
1027                                     y_offset);
1028          *x_offset += img_offset_el.x;
1029          *y_offset += img_offset_el.y;
1030
1031          /* Perform Blit */
1032          anv_meta_blit2d(cmd_buffer,
1033                         src_bsurf,
1034                         dst_bsurf,
1035                         1,
1036                         &rect);
1037
1038          /* Once we've done the blit, all of the actual information about
1039           * the image is embedded in the command buffer so we can just
1040           * increment the offset directly in the image effectively
1041           * re-binding it to different backing memory.
1042           */
1043          buf_bsurf.base_offset += rect.width * rect.height * buf_bsurf.bs;
1044
1045          if (image->type == VK_IMAGE_TYPE_3D)
1046             slice_3d++;
1047          else
1048             slice_array++;
1049       }
1050    }
1051    anv_meta_end_blit2d(cmd_buffer, &saved_state);
1052 }
1053
1054 static struct anv_image *
1055 make_image_for_buffer(VkDevice vk_device, VkBuffer vk_buffer, VkFormat format,
1056                       VkImageUsageFlags usage,
1057                       VkImageType image_type,
1058                       const VkAllocationCallbacks *alloc,
1059                       const VkBufferImageCopy *copy)
1060 {
1061    ANV_FROM_HANDLE(anv_buffer, buffer, vk_buffer);
1062
1063    VkExtent3D extent = copy->imageExtent;
1064    if (copy->bufferRowLength)
1065       extent.width = copy->bufferRowLength;
1066    if (copy->bufferImageHeight)
1067       extent.height = copy->bufferImageHeight;
1068    extent.depth = 1;
1069    extent = meta_region_extent_el(format, &extent);
1070
1071    VkImageAspectFlags aspect = copy->imageSubresource.aspectMask;
1072    VkFormat buffer_format = choose_buffer_format(format, aspect);
1073
1074    VkImage vk_image;
1075    VkResult result = anv_CreateImage(vk_device,
1076       &(VkImageCreateInfo) {
1077          .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
1078          .imageType = VK_IMAGE_TYPE_2D,
1079          .format = buffer_format,
1080          .extent = extent,
1081          .mipLevels = 1,
1082          .arrayLayers = 1,
1083          .samples = 1,
1084          .tiling = VK_IMAGE_TILING_LINEAR,
1085          .usage = usage,
1086          .flags = 0,
1087       }, alloc, &vk_image);
1088    assert(result == VK_SUCCESS);
1089
1090    ANV_FROM_HANDLE(anv_image, image, vk_image);
1091
1092    /* We could use a vk call to bind memory, but that would require
1093     * creating a dummy memory object etc. so there's really no point.
1094     */
1095    image->bo = buffer->bo;
1096    image->offset = buffer->offset + copy->bufferOffset;
1097
1098    return image;
1099 }
1100
1101 void anv_CmdCopyBufferToImage(
1102     VkCommandBuffer                             commandBuffer,
1103     VkBuffer                                    srcBuffer,
1104     VkImage                                     destImage,
1105     VkImageLayout                               destImageLayout,
1106     uint32_t                                    regionCount,
1107     const VkBufferImageCopy*                    pRegions)
1108 {
1109    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1110    ANV_FROM_HANDLE(anv_image, dest_image, destImage);
1111    ANV_FROM_HANDLE(anv_buffer, src_buffer, srcBuffer);
1112
1113    meta_copy_buffer_to_image(cmd_buffer, src_buffer, dest_image,
1114                              regionCount, pRegions, true);
1115 }
1116
1117 void anv_CmdCopyImageToBuffer(
1118     VkCommandBuffer                             commandBuffer,
1119     VkImage                                     srcImage,
1120     VkImageLayout                               srcImageLayout,
1121     VkBuffer                                    destBuffer,
1122     uint32_t                                    regionCount,
1123     const VkBufferImageCopy*                    pRegions)
1124 {
1125    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1126    ANV_FROM_HANDLE(anv_image, src_image, srcImage);
1127    ANV_FROM_HANDLE(anv_buffer, dst_buffer, destBuffer);
1128
1129    meta_copy_buffer_to_image(cmd_buffer, dst_buffer, src_image,
1130                              regionCount, pRegions, false);
1131 }
1132
1133 void
1134 anv_device_finish_meta_blit_state(struct anv_device *device)
1135 {
1136    anv_DestroyRenderPass(anv_device_to_handle(device),
1137                          device->meta_state.blit.render_pass,
1138                          &device->meta_state.alloc);
1139    anv_DestroyPipeline(anv_device_to_handle(device),
1140                        device->meta_state.blit.pipeline_1d_src,
1141                        &device->meta_state.alloc);
1142    anv_DestroyPipeline(anv_device_to_handle(device),
1143                        device->meta_state.blit.pipeline_2d_src,
1144                        &device->meta_state.alloc);
1145    anv_DestroyPipeline(anv_device_to_handle(device),
1146                        device->meta_state.blit.pipeline_3d_src,
1147                        &device->meta_state.alloc);
1148    anv_DestroyPipelineLayout(anv_device_to_handle(device),
1149                              device->meta_state.blit.pipeline_layout,
1150                              &device->meta_state.alloc);
1151    anv_DestroyDescriptorSetLayout(anv_device_to_handle(device),
1152                                   device->meta_state.blit.ds_layout,
1153                                   &device->meta_state.alloc);
1154 }
1155
1156 VkResult
1157 anv_device_init_meta_blit_state(struct anv_device *device)
1158 {
1159    VkResult result;
1160
1161    result = anv_CreateRenderPass(anv_device_to_handle(device),
1162       &(VkRenderPassCreateInfo) {
1163          .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
1164          .attachmentCount = 1,
1165          .pAttachments = &(VkAttachmentDescription) {
1166             .format = VK_FORMAT_UNDEFINED, /* Our shaders don't care */
1167             .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
1168             .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
1169             .initialLayout = VK_IMAGE_LAYOUT_GENERAL,
1170             .finalLayout = VK_IMAGE_LAYOUT_GENERAL,
1171          },
1172          .subpassCount = 1,
1173          .pSubpasses = &(VkSubpassDescription) {
1174             .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
1175             .inputAttachmentCount = 0,
1176             .colorAttachmentCount = 1,
1177             .pColorAttachments = &(VkAttachmentReference) {
1178                .attachment = 0,
1179                .layout = VK_IMAGE_LAYOUT_GENERAL,
1180             },
1181             .pResolveAttachments = NULL,
1182             .pDepthStencilAttachment = &(VkAttachmentReference) {
1183                .attachment = VK_ATTACHMENT_UNUSED,
1184                .layout = VK_IMAGE_LAYOUT_GENERAL,
1185             },
1186             .preserveAttachmentCount = 1,
1187             .pPreserveAttachments = (uint32_t[]) { 0 },
1188          },
1189          .dependencyCount = 0,
1190       }, &device->meta_state.alloc, &device->meta_state.blit.render_pass);
1191    if (result != VK_SUCCESS)
1192       goto fail;
1193
1194    /* We don't use a vertex shader for blitting, but instead build and pass
1195     * the VUEs directly to the rasterization backend.  However, we do need
1196     * to provide GLSL source for the vertex shader so that the compiler
1197     * does not dead-code our inputs.
1198     */
1199    struct anv_shader_module vs = {
1200       .nir = build_nir_vertex_shader(),
1201    };
1202
1203    struct anv_shader_module fs_1d = {
1204       .nir = build_nir_copy_fragment_shader(GLSL_SAMPLER_DIM_1D),
1205    };
1206
1207    struct anv_shader_module fs_2d = {
1208       .nir = build_nir_copy_fragment_shader(GLSL_SAMPLER_DIM_2D),
1209    };
1210
1211    struct anv_shader_module fs_3d = {
1212       .nir = build_nir_copy_fragment_shader(GLSL_SAMPLER_DIM_3D),
1213    };
1214
1215    VkPipelineVertexInputStateCreateInfo vi_create_info = {
1216       .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
1217       .vertexBindingDescriptionCount = 2,
1218       .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) {
1219          {
1220             .binding = 0,
1221             .stride = 0,
1222             .inputRate = VK_VERTEX_INPUT_RATE_VERTEX
1223          },
1224          {
1225             .binding = 1,
1226             .stride = 5 * sizeof(float),
1227             .inputRate = VK_VERTEX_INPUT_RATE_VERTEX
1228          },
1229       },
1230       .vertexAttributeDescriptionCount = 3,
1231       .pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[]) {
1232          {
1233             /* VUE Header */
1234             .location = 0,
1235             .binding = 0,
1236             .format = VK_FORMAT_R32G32B32A32_UINT,
1237             .offset = 0
1238          },
1239          {
1240             /* Position */
1241             .location = 1,
1242             .binding = 1,
1243             .format = VK_FORMAT_R32G32_SFLOAT,
1244             .offset = 0
1245          },
1246          {
1247             /* Texture Coordinate */
1248             .location = 2,
1249             .binding = 1,
1250             .format = VK_FORMAT_R32G32B32_SFLOAT,
1251             .offset = 8
1252          }
1253       }
1254    };
1255
1256    VkDescriptorSetLayoutCreateInfo ds_layout_info = {
1257       .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1258       .bindingCount = 1,
1259       .pBindings = (VkDescriptorSetLayoutBinding[]) {
1260          {
1261             .binding = 0,
1262             .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
1263             .descriptorCount = 1,
1264             .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
1265             .pImmutableSamplers = NULL
1266          },
1267       }
1268    };
1269    result = anv_CreateDescriptorSetLayout(anv_device_to_handle(device),
1270                                           &ds_layout_info,
1271                                           &device->meta_state.alloc,
1272                                           &device->meta_state.blit.ds_layout);
1273    if (result != VK_SUCCESS)
1274       goto fail_render_pass;
1275
1276    result = anv_CreatePipelineLayout(anv_device_to_handle(device),
1277       &(VkPipelineLayoutCreateInfo) {
1278          .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1279          .setLayoutCount = 1,
1280          .pSetLayouts = &device->meta_state.blit.ds_layout,
1281       },
1282       &device->meta_state.alloc, &device->meta_state.blit.pipeline_layout);
1283    if (result != VK_SUCCESS)
1284       goto fail_descriptor_set_layout;
1285
1286    VkPipelineShaderStageCreateInfo pipeline_shader_stages[] = {
1287       {
1288          .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1289          .stage = VK_SHADER_STAGE_VERTEX_BIT,
1290          .module = anv_shader_module_to_handle(&vs),
1291          .pName = "main",
1292          .pSpecializationInfo = NULL
1293       }, {
1294          .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1295          .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
1296          .module = VK_NULL_HANDLE, /* TEMPLATE VALUE! FILL ME IN! */
1297          .pName = "main",
1298          .pSpecializationInfo = NULL
1299       },
1300    };
1301
1302    const VkGraphicsPipelineCreateInfo vk_pipeline_info = {
1303       .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1304       .stageCount = ARRAY_SIZE(pipeline_shader_stages),
1305       .pStages = pipeline_shader_stages,
1306       .pVertexInputState = &vi_create_info,
1307       .pInputAssemblyState = &(VkPipelineInputAssemblyStateCreateInfo) {
1308          .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
1309          .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
1310          .primitiveRestartEnable = false,
1311       },
1312       .pViewportState = &(VkPipelineViewportStateCreateInfo) {
1313          .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
1314          .viewportCount = 1,
1315          .scissorCount = 1,
1316       },
1317       .pRasterizationState = &(VkPipelineRasterizationStateCreateInfo) {
1318          .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
1319          .rasterizerDiscardEnable = false,
1320          .polygonMode = VK_POLYGON_MODE_FILL,
1321          .cullMode = VK_CULL_MODE_NONE,
1322          .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE
1323       },
1324       .pMultisampleState = &(VkPipelineMultisampleStateCreateInfo) {
1325          .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
1326          .rasterizationSamples = 1,
1327          .sampleShadingEnable = false,
1328          .pSampleMask = (VkSampleMask[]) { UINT32_MAX },
1329       },
1330       .pColorBlendState = &(VkPipelineColorBlendStateCreateInfo) {
1331          .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
1332          .attachmentCount = 1,
1333          .pAttachments = (VkPipelineColorBlendAttachmentState []) {
1334             { .colorWriteMask =
1335                  VK_COLOR_COMPONENT_A_BIT |
1336                  VK_COLOR_COMPONENT_R_BIT |
1337                  VK_COLOR_COMPONENT_G_BIT |
1338                  VK_COLOR_COMPONENT_B_BIT },
1339          }
1340       },
1341       .pDynamicState = &(VkPipelineDynamicStateCreateInfo) {
1342          .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
1343          .dynamicStateCount = 9,
1344          .pDynamicStates = (VkDynamicState[]) {
1345             VK_DYNAMIC_STATE_VIEWPORT,
1346             VK_DYNAMIC_STATE_SCISSOR,
1347             VK_DYNAMIC_STATE_LINE_WIDTH,
1348             VK_DYNAMIC_STATE_DEPTH_BIAS,
1349             VK_DYNAMIC_STATE_BLEND_CONSTANTS,
1350             VK_DYNAMIC_STATE_DEPTH_BOUNDS,
1351             VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
1352             VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
1353             VK_DYNAMIC_STATE_STENCIL_REFERENCE,
1354          },
1355       },
1356       .flags = 0,
1357       .layout = device->meta_state.blit.pipeline_layout,
1358       .renderPass = device->meta_state.blit.render_pass,
1359       .subpass = 0,
1360    };
1361
1362    const struct anv_graphics_pipeline_create_info anv_pipeline_info = {
1363       .color_attachment_count = -1,
1364       .use_repclear = false,
1365       .disable_viewport = true,
1366       .disable_scissor = true,
1367       .disable_vs = true,
1368       .use_rectlist = true
1369    };
1370
1371    pipeline_shader_stages[1].module = anv_shader_module_to_handle(&fs_1d);
1372    result = anv_graphics_pipeline_create(anv_device_to_handle(device),
1373       VK_NULL_HANDLE,
1374       &vk_pipeline_info, &anv_pipeline_info,
1375       &device->meta_state.alloc, &device->meta_state.blit.pipeline_1d_src);
1376    if (result != VK_SUCCESS)
1377       goto fail_pipeline_layout;
1378
1379    pipeline_shader_stages[1].module = anv_shader_module_to_handle(&fs_2d);
1380    result = anv_graphics_pipeline_create(anv_device_to_handle(device),
1381       VK_NULL_HANDLE,
1382       &vk_pipeline_info, &anv_pipeline_info,
1383       &device->meta_state.alloc, &device->meta_state.blit.pipeline_2d_src);
1384    if (result != VK_SUCCESS)
1385       goto fail_pipeline_1d;
1386
1387    pipeline_shader_stages[1].module = anv_shader_module_to_handle(&fs_3d);
1388    result = anv_graphics_pipeline_create(anv_device_to_handle(device),
1389       VK_NULL_HANDLE,
1390       &vk_pipeline_info, &anv_pipeline_info,
1391       &device->meta_state.alloc, &device->meta_state.blit.pipeline_3d_src);
1392    if (result != VK_SUCCESS)
1393       goto fail_pipeline_2d;
1394
1395    ralloc_free(vs.nir);
1396    ralloc_free(fs_1d.nir);
1397    ralloc_free(fs_2d.nir);
1398    ralloc_free(fs_3d.nir);
1399
1400    return VK_SUCCESS;
1401
1402  fail_pipeline_2d:
1403    anv_DestroyPipeline(anv_device_to_handle(device),
1404                        device->meta_state.blit.pipeline_2d_src,
1405                        &device->meta_state.alloc);
1406
1407  fail_pipeline_1d:
1408    anv_DestroyPipeline(anv_device_to_handle(device),
1409                        device->meta_state.blit.pipeline_1d_src,
1410                        &device->meta_state.alloc);
1411
1412  fail_pipeline_layout:
1413    anv_DestroyPipelineLayout(anv_device_to_handle(device),
1414                              device->meta_state.blit.pipeline_layout,
1415                              &device->meta_state.alloc);
1416  fail_descriptor_set_layout:
1417    anv_DestroyDescriptorSetLayout(anv_device_to_handle(device),
1418                                   device->meta_state.blit.ds_layout,
1419                                   &device->meta_state.alloc);
1420  fail_render_pass:
1421    anv_DestroyRenderPass(anv_device_to_handle(device),
1422                          device->meta_state.blit.render_pass,
1423                          &device->meta_state.alloc);
1424
1425    ralloc_free(vs.nir);
1426    ralloc_free(fs_1d.nir);
1427    ralloc_free(fs_2d.nir);
1428    ralloc_free(fs_3d.nir);
1429  fail:
1430    return result;
1431 }