OSDN Git Service

anv/meta: Use blitter API for copies between Images and Buffers
[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    VkDevice vk_device = anv_device_to_handle(cmd_buffer->device);
567    VkFormat copy_format = vk_format_for_size(bs);
568
569    VkImageCreateInfo image_info = {
570       .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
571       .imageType = VK_IMAGE_TYPE_2D,
572       .format = copy_format,
573       .extent = {
574          .width = width,
575          .height = height,
576          .depth = 1,
577       },
578       .mipLevels = 1,
579       .arrayLayers = 1,
580       .samples = 1,
581       .tiling = VK_IMAGE_TILING_LINEAR,
582       .usage = 0,
583       .flags = 0,
584    };
585
586    VkImage src_image;
587    image_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
588    anv_CreateImage(vk_device, &image_info,
589                    &cmd_buffer->pool->alloc, &src_image);
590
591    VkImage dest_image;
592    image_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
593    anv_CreateImage(vk_device, &image_info,
594                    &cmd_buffer->pool->alloc, &dest_image);
595
596    /* We could use a vk call to bind memory, but that would require
597     * creating a dummy memory object etc. so there's really no point.
598     */
599    anv_image_from_handle(src_image)->bo = src;
600    anv_image_from_handle(src_image)->offset = src_offset;
601    anv_image_from_handle(dest_image)->bo = dest;
602    anv_image_from_handle(dest_image)->offset = dest_offset;
603
604    VkImageViewCreateInfo iview_info = {
605       .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
606       .image = 0, /* TEMPLATE */
607       .viewType = VK_IMAGE_VIEW_TYPE_2D,
608       .format = copy_format,
609       .subresourceRange = {
610          .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
611          .baseMipLevel = 0,
612          .levelCount = 1,
613          .baseArrayLayer = 0,
614          .layerCount = 1
615       },
616    };
617
618    struct anv_image_view src_iview;
619    iview_info.image = src_image;
620    anv_image_view_init(&src_iview, cmd_buffer->device,
621       &iview_info, cmd_buffer, 0, VK_IMAGE_USAGE_SAMPLED_BIT);
622
623    struct anv_image_view dest_iview;
624    iview_info.image = dest_image;
625    anv_image_view_init(&dest_iview, cmd_buffer->device,
626       &iview_info, cmd_buffer, 0, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
627
628    meta_emit_blit(cmd_buffer,
629                   anv_image_from_handle(src_image),
630                   &src_iview,
631                   (VkOffset3D) { 0, 0, 0 },
632                   (VkExtent3D) { width, height, 1 },
633                   anv_image_from_handle(dest_image),
634                   &dest_iview,
635                   (VkOffset3D) { 0, 0, 0 },
636                   (VkExtent3D) { width, height, 1 },
637                   VK_FILTER_NEAREST);
638
639    anv_DestroyImage(vk_device, src_image, &cmd_buffer->pool->alloc);
640    anv_DestroyImage(vk_device, dest_image, &cmd_buffer->pool->alloc);
641 }
642
643 void anv_CmdCopyBuffer(
644     VkCommandBuffer                             commandBuffer,
645     VkBuffer                                    srcBuffer,
646     VkBuffer                                    destBuffer,
647     uint32_t                                    regionCount,
648     const VkBufferCopy*                         pRegions)
649 {
650    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
651    ANV_FROM_HANDLE(anv_buffer, src_buffer, srcBuffer);
652    ANV_FROM_HANDLE(anv_buffer, dest_buffer, destBuffer);
653
654    struct anv_meta_saved_state saved_state;
655
656    meta_prepare_blit(cmd_buffer, &saved_state);
657
658    for (unsigned r = 0; r < regionCount; r++) {
659       uint64_t src_offset = src_buffer->offset + pRegions[r].srcOffset;
660       uint64_t dest_offset = dest_buffer->offset + pRegions[r].dstOffset;
661       uint64_t copy_size = pRegions[r].size;
662
663       /* First, we compute the biggest format that can be used with the
664        * given offsets and size.
665        */
666       int bs = 16;
667
668       int fs = ffs(src_offset) - 1;
669       if (fs != -1)
670          bs = MIN2(bs, 1 << fs);
671       assert(src_offset % bs == 0);
672
673       fs = ffs(dest_offset) - 1;
674       if (fs != -1)
675          bs = MIN2(bs, 1 << fs);
676       assert(dest_offset % bs == 0);
677
678       fs = ffs(pRegions[r].size) - 1;
679       if (fs != -1)
680          bs = MIN2(bs, 1 << fs);
681       assert(pRegions[r].size % bs == 0);
682
683       /* This is maximum possible width/height our HW can handle */
684       uint64_t max_surface_dim = 1 << 14;
685
686       /* First, we make a bunch of max-sized copies */
687       uint64_t max_copy_size = max_surface_dim * max_surface_dim * bs;
688       while (copy_size >= max_copy_size) {
689          do_buffer_copy(cmd_buffer, src_buffer->bo, src_offset,
690                         dest_buffer->bo, dest_offset,
691                         max_surface_dim, max_surface_dim, bs);
692          copy_size -= max_copy_size;
693          src_offset += max_copy_size;
694          dest_offset += max_copy_size;
695       }
696
697       uint64_t height = copy_size / (max_surface_dim * bs);
698       assert(height < max_surface_dim);
699       if (height != 0) {
700          uint64_t rect_copy_size = height * max_surface_dim * bs;
701          do_buffer_copy(cmd_buffer, src_buffer->bo, src_offset,
702                         dest_buffer->bo, dest_offset,
703                         max_surface_dim, height, bs);
704          copy_size -= rect_copy_size;
705          src_offset += rect_copy_size;
706          dest_offset += rect_copy_size;
707       }
708
709       if (copy_size != 0) {
710          do_buffer_copy(cmd_buffer, src_buffer->bo, src_offset,
711                         dest_buffer->bo, dest_offset,
712                         copy_size / bs, 1, bs);
713       }
714    }
715
716    meta_finish_blit(cmd_buffer, &saved_state);
717 }
718
719 void anv_CmdUpdateBuffer(
720     VkCommandBuffer                             commandBuffer,
721     VkBuffer                                    dstBuffer,
722     VkDeviceSize                                dstOffset,
723     VkDeviceSize                                dataSize,
724     const uint32_t*                             pData)
725 {
726    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
727    ANV_FROM_HANDLE(anv_buffer, dst_buffer, dstBuffer);
728    struct anv_meta_saved_state saved_state;
729
730    meta_prepare_blit(cmd_buffer, &saved_state);
731
732    /* We can't quite grab a full block because the state stream needs a
733     * little data at the top to build its linked list.
734     */
735    const uint32_t max_update_size =
736       cmd_buffer->device->dynamic_state_block_pool.block_size - 64;
737
738    assert(max_update_size < (1 << 14) * 4);
739
740    while (dataSize) {
741       const uint32_t copy_size = MIN2(dataSize, max_update_size);
742
743       struct anv_state tmp_data =
744          anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, copy_size, 64);
745
746       memcpy(tmp_data.map, pData, copy_size);
747
748       int bs;
749       if ((copy_size & 15) == 0 && (dstOffset & 15) == 0) {
750          bs = 16;
751       } else if ((copy_size & 7) == 0 && (dstOffset & 7) == 0) {
752          bs = 8;
753       } else {
754          assert((copy_size & 3) == 0 && (dstOffset & 3) == 0);
755          bs = 4;
756       }
757
758       do_buffer_copy(cmd_buffer,
759                      &cmd_buffer->device->dynamic_state_block_pool.bo,
760                      tmp_data.offset,
761                      dst_buffer->bo, dst_buffer->offset + dstOffset,
762                      copy_size / bs, 1, bs);
763
764       dataSize -= copy_size;
765       dstOffset += copy_size;
766       pData = (void *)pData + copy_size;
767    }
768
769    meta_finish_blit(cmd_buffer, &saved_state);
770 }
771
772 static VkFormat
773 choose_iview_format(struct anv_image *image, VkImageAspectFlagBits aspect)
774 {
775    assert(__builtin_popcount(aspect) == 1);
776
777    struct isl_surf *surf =
778       &anv_image_get_surface_for_aspect_mask(image, aspect)->isl;
779
780    /* vkCmdCopyImage behaves like memcpy. Therefore we choose identical UINT
781     * formats for the source and destination image views.
782     *
783     * From the Vulkan spec (2015-12-30):
784     *
785     *    vkCmdCopyImage performs image copies in a similar manner to a host
786     *    memcpy. It does not perform general-purpose conversions such as
787     *    scaling, resizing, blending, color-space conversion, or format
788     *    conversions.  Rather, it simply copies raw image data. vkCmdCopyImage
789     *    can copy between images with different formats, provided the formats
790     *    are compatible as defined below.
791     *
792     *    [The spec later defines compatibility as having the same number of
793     *    bytes per block].
794     */
795    return vk_format_for_size(isl_format_layouts[surf->format].bs);
796 }
797
798 static VkFormat
799 choose_buffer_format(VkFormat format, VkImageAspectFlagBits aspect)
800 {
801    assert(__builtin_popcount(aspect) == 1);
802
803    /* vkCmdCopy* commands behave like memcpy. Therefore we choose
804     * compatable UINT formats for the source and destination image views.
805     *
806     * For the buffer, we go back to the original image format and get a
807     * the format as if it were linear.  This way, for RGB formats, we get
808     * an RGB format here even if the tiled image is RGBA. XXX: This doesn't
809     * work if the buffer is the destination.
810     */
811    enum isl_format linear_format = anv_get_isl_format(format, aspect,
812                                                       VK_IMAGE_TILING_LINEAR,
813                                                       NULL);
814
815    return vk_format_for_size(isl_format_layouts[linear_format].bs);
816 }
817
818 void anv_CmdCopyImage(
819     VkCommandBuffer                             commandBuffer,
820     VkImage                                     srcImage,
821     VkImageLayout                               srcImageLayout,
822     VkImage                                     destImage,
823     VkImageLayout                               destImageLayout,
824     uint32_t                                    regionCount,
825     const VkImageCopy*                          pRegions)
826 {
827    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
828    ANV_FROM_HANDLE(anv_image, src_image, srcImage);
829    ANV_FROM_HANDLE(anv_image, dest_image, destImage);
830    struct anv_meta_saved_state saved_state;
831
832    /* From the Vulkan 1.0 spec:
833     *
834     *    vkCmdCopyImage can be used to copy image data between multisample
835     *    images, but both images must have the same number of samples.
836     */
837    assert(src_image->samples == dest_image->samples);
838
839    meta_prepare_blit(cmd_buffer, &saved_state);
840
841    for (unsigned r = 0; r < regionCount; r++) {
842       assert(pRegions[r].srcSubresource.aspectMask ==
843              pRegions[r].dstSubresource.aspectMask);
844
845       VkImageAspectFlags aspect = pRegions[r].srcSubresource.aspectMask;
846
847       VkFormat src_format = choose_iview_format(src_image, aspect);
848       VkFormat dst_format = choose_iview_format(dest_image, aspect);
849
850       struct anv_image_view src_iview;
851       anv_image_view_init(&src_iview, cmd_buffer->device,
852          &(VkImageViewCreateInfo) {
853             .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
854             .image = srcImage,
855             .viewType = anv_meta_get_view_type(src_image),
856             .format = src_format,
857             .subresourceRange = {
858                .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
859                .baseMipLevel = pRegions[r].srcSubresource.mipLevel,
860                .levelCount = 1,
861                .baseArrayLayer = pRegions[r].srcSubresource.baseArrayLayer,
862                .layerCount = pRegions[r].dstSubresource.layerCount,
863             },
864          },
865          cmd_buffer, 0, VK_IMAGE_USAGE_SAMPLED_BIT);
866
867       const uint32_t dest_base_array_slice =
868          anv_meta_get_iview_layer(dest_image, &pRegions[r].dstSubresource,
869                                   &pRegions[r].dstOffset);
870
871
872       unsigned num_slices_3d = pRegions[r].extent.depth;
873       unsigned num_slices_array = pRegions[r].dstSubresource.layerCount;
874       unsigned slice_3d = 0;
875       unsigned slice_array = 0;
876       while (slice_3d < num_slices_3d && slice_array < num_slices_array) {
877          VkOffset3D src_offset = pRegions[r].srcOffset;
878          src_offset.z += slice_3d + slice_array;
879
880          uint32_t img_x = 0;
881          uint32_t img_y = 0;
882          uint32_t img_o = 0;
883          if (isl_format_is_compressed(dest_image->format->isl_format))
884             isl_surf_get_image_intratile_offset_el(&cmd_buffer->device->isl_dev,
885                                                    &dest_image->color_surface.isl,
886                                                    pRegions[r].dstSubresource.mipLevel,
887                                                    pRegions[r].dstSubresource.baseArrayLayer + slice_array,
888                                                    pRegions[r].dstOffset.z + slice_3d,
889                                                    &img_o, &img_x, &img_y);
890
891          VkOffset3D dest_offset_el = meta_region_offset_el(dest_image, &pRegions[r].dstOffset);
892          dest_offset_el.x += img_x;
893          dest_offset_el.y += img_y;
894          dest_offset_el.z = 0;
895
896          struct anv_image_view dest_iview;
897          anv_image_view_init(&dest_iview, cmd_buffer->device,
898             &(VkImageViewCreateInfo) {
899                .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
900                .image = destImage,
901                .viewType = anv_meta_get_view_type(dest_image),
902                .format = dst_format,
903                .subresourceRange = {
904                   .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
905                   .baseMipLevel = pRegions[r].dstSubresource.mipLevel,
906                   .levelCount = 1,
907                   .baseArrayLayer = dest_base_array_slice +
908                                     slice_array + slice_3d,
909                   .layerCount = 1
910                },
911             },
912             cmd_buffer, img_o, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
913
914          const VkExtent3D img_extent_el = meta_region_extent_el(dest_image->vk_format,
915                                                                 &pRegions[r].extent);
916
917          meta_emit_blit(cmd_buffer,
918                         src_image, &src_iview,
919                         src_offset,
920                         img_extent_el,
921                         dest_image, &dest_iview,
922                         dest_offset_el,
923                         img_extent_el,
924                         VK_FILTER_NEAREST);
925
926          if (dest_image->type == VK_IMAGE_TYPE_3D)
927             slice_3d++;
928          else
929             slice_array++;
930       }
931    }
932
933    meta_finish_blit(cmd_buffer, &saved_state);
934 }
935
936 void anv_CmdBlitImage(
937     VkCommandBuffer                             commandBuffer,
938     VkImage                                     srcImage,
939     VkImageLayout                               srcImageLayout,
940     VkImage                                     destImage,
941     VkImageLayout                               destImageLayout,
942     uint32_t                                    regionCount,
943     const VkImageBlit*                          pRegions,
944     VkFilter                                    filter)
945
946 {
947    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
948    ANV_FROM_HANDLE(anv_image, src_image, srcImage);
949    ANV_FROM_HANDLE(anv_image, dest_image, destImage);
950    struct anv_meta_saved_state saved_state;
951
952    /* From the Vulkan 1.0 spec:
953     *
954     *    vkCmdBlitImage must not be used for multisampled source or
955     *    destination images. Use vkCmdResolveImage for this purpose.
956     */
957    assert(src_image->samples == 1);
958    assert(dest_image->samples == 1);
959
960    anv_finishme("respect VkFilter");
961
962    meta_prepare_blit(cmd_buffer, &saved_state);
963
964    for (unsigned r = 0; r < regionCount; r++) {
965       struct anv_image_view src_iview;
966       anv_image_view_init(&src_iview, cmd_buffer->device,
967          &(VkImageViewCreateInfo) {
968             .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
969             .image = srcImage,
970             .viewType = anv_meta_get_view_type(src_image),
971             .format = src_image->vk_format,
972             .subresourceRange = {
973                .aspectMask = pRegions[r].srcSubresource.aspectMask,
974                .baseMipLevel = pRegions[r].srcSubresource.mipLevel,
975                .levelCount = 1,
976                .baseArrayLayer = pRegions[r].srcSubresource.baseArrayLayer,
977                .layerCount = 1
978             },
979          },
980          cmd_buffer, 0, VK_IMAGE_USAGE_SAMPLED_BIT);
981
982       const VkOffset3D dest_offset = {
983          .x = pRegions[r].dstOffsets[0].x,
984          .y = pRegions[r].dstOffsets[0].y,
985          .z = 0,
986       };
987
988       if (pRegions[r].dstOffsets[1].x < pRegions[r].dstOffsets[0].x ||
989           pRegions[r].dstOffsets[1].y < pRegions[r].dstOffsets[0].y ||
990           pRegions[r].srcOffsets[1].x < pRegions[r].srcOffsets[0].x ||
991           pRegions[r].srcOffsets[1].y < pRegions[r].srcOffsets[0].y)
992          anv_finishme("FINISHME: Allow flipping in blits");
993
994       const VkExtent3D dest_extent = {
995          .width = pRegions[r].dstOffsets[1].x - pRegions[r].dstOffsets[0].x,
996          .height = pRegions[r].dstOffsets[1].y - pRegions[r].dstOffsets[0].y,
997       };
998
999       const VkExtent3D src_extent = {
1000          .width = pRegions[r].srcOffsets[1].x - pRegions[r].srcOffsets[0].x,
1001          .height = pRegions[r].srcOffsets[1].y - pRegions[r].srcOffsets[0].y,
1002       };
1003
1004       const uint32_t dest_array_slice =
1005          anv_meta_get_iview_layer(dest_image, &pRegions[r].dstSubresource,
1006                                   &pRegions[r].dstOffsets[0]);
1007
1008       if (pRegions[r].srcSubresource.layerCount > 1)
1009          anv_finishme("FINISHME: copy multiple array layers");
1010
1011       if (pRegions[r].srcOffsets[0].z + 1 != pRegions[r].srcOffsets[1].z ||
1012           pRegions[r].dstOffsets[0].z + 1 != pRegions[r].dstOffsets[1].z)
1013          anv_finishme("FINISHME: copy multiple depth layers");
1014
1015       struct anv_image_view dest_iview;
1016       anv_image_view_init(&dest_iview, cmd_buffer->device,
1017          &(VkImageViewCreateInfo) {
1018             .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
1019             .image = destImage,
1020             .viewType = anv_meta_get_view_type(dest_image),
1021             .format = dest_image->vk_format,
1022             .subresourceRange = {
1023                .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
1024                .baseMipLevel = pRegions[r].dstSubresource.mipLevel,
1025                .levelCount = 1,
1026                .baseArrayLayer = dest_array_slice,
1027                .layerCount = 1
1028             },
1029          },
1030          cmd_buffer, 0, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
1031
1032       meta_emit_blit(cmd_buffer,
1033                      src_image, &src_iview,
1034                      pRegions[r].srcOffsets[0], src_extent,
1035                      dest_image, &dest_iview,
1036                      dest_offset, dest_extent,
1037                      filter);
1038    }
1039
1040    meta_finish_blit(cmd_buffer, &saved_state);
1041 }
1042
1043 static void
1044 meta_copy_buffer_to_image(struct anv_cmd_buffer *cmd_buffer,
1045                           struct anv_buffer* buffer,
1046                           struct anv_image* image,
1047                           uint32_t regionCount,
1048                           const VkBufferImageCopy* pRegions,
1049                           bool forward)
1050 {
1051    struct anv_meta_saved_state saved_state;
1052
1053    /* The Vulkan 1.0 spec says "dstImage must have a sample count equal to
1054     * VK_SAMPLE_COUNT_1_BIT."
1055     */
1056    assert(image->samples == 1);
1057
1058    anv_meta_begin_blit2d(cmd_buffer, &saved_state);
1059
1060    for (unsigned r = 0; r < regionCount; r++) {
1061
1062       /* Start creating blit rect */
1063       const VkOffset3D img_offset_el = meta_region_offset_el(image, &pRegions[r].imageOffset);
1064       const VkExtent3D bufferExtent = {
1065          .width = pRegions[r].bufferRowLength,
1066          .height = pRegions[r].bufferImageHeight,
1067       };
1068       const VkExtent3D buf_extent_el = meta_region_extent_el(image->vk_format, &bufferExtent);
1069       const VkExtent3D img_extent_el = meta_region_extent_el(image->vk_format,
1070                                                                &pRegions[r].imageExtent);
1071       struct anv_meta_blit2d_rect rect = {
1072          .width = MAX2(buf_extent_el.width, img_extent_el.width),
1073          .height = MAX2(buf_extent_el.height, img_extent_el.height),
1074       };
1075
1076       /* Create blit surfaces */
1077       VkImageAspectFlags aspect = pRegions[r].imageSubresource.aspectMask;
1078       const struct isl_surf *img_isl_surf =
1079          &anv_image_get_surface_for_aspect_mask(image, aspect)->isl;
1080       struct anv_meta_blit2d_surf img_bsurf = blit_surf_for_image(image, img_isl_surf);
1081       struct anv_meta_blit2d_surf buf_bsurf = {
1082          .bo = buffer->bo,
1083          .tiling = ISL_TILING_LINEAR,
1084          .base_offset = buffer->offset + pRegions[r].bufferOffset,
1085          .bs = forward ? image->format->isl_layout->bs : img_bsurf.bs,
1086          .pitch = rect.width * buf_bsurf.bs,
1087       };
1088
1089       /* Set direction-dependent variables */
1090       struct anv_meta_blit2d_surf *dst_bsurf = forward ? &img_bsurf : &buf_bsurf;
1091       struct anv_meta_blit2d_surf *src_bsurf = forward ? &buf_bsurf : &img_bsurf;
1092       uint32_t *x_offset = forward ? &rect.dst_x : &rect.src_x;
1093       uint32_t *y_offset = forward ? &rect.dst_y : &rect.src_y;
1094
1095       /* Loop through each 3D or array slice */
1096       unsigned num_slices_3d = pRegions[r].imageExtent.depth;
1097       unsigned num_slices_array = pRegions[r].imageSubresource.layerCount;
1098       unsigned slice_3d = 0;
1099       unsigned slice_array = 0;
1100       while (slice_3d < num_slices_3d && slice_array < num_slices_array) {
1101
1102          /* Finish creating blit rect */
1103          isl_surf_get_image_offset_el(img_isl_surf,
1104                                     pRegions[r].imageSubresource.mipLevel,
1105                                     pRegions[r].imageSubresource.baseArrayLayer + slice_array,
1106                                     pRegions[r].imageOffset.z + slice_3d,
1107                                     x_offset,
1108                                     y_offset);
1109          *x_offset += img_offset_el.x;
1110          *y_offset += img_offset_el.y;
1111
1112          /* Perform Blit */
1113          anv_meta_blit2d(cmd_buffer,
1114                         src_bsurf,
1115                         dst_bsurf,
1116                         1,
1117                         &rect);
1118
1119          /* Once we've done the blit, all of the actual information about
1120           * the image is embedded in the command buffer so we can just
1121           * increment the offset directly in the image effectively
1122           * re-binding it to different backing memory.
1123           */
1124          buf_bsurf.base_offset += rect.width * rect.height * buf_bsurf.bs;
1125
1126          if (image->type == VK_IMAGE_TYPE_3D)
1127             slice_3d++;
1128          else
1129             slice_array++;
1130       }
1131    }
1132    anv_meta_end_blit2d(cmd_buffer, &saved_state);
1133 }
1134
1135 static struct anv_image *
1136 make_image_for_buffer(VkDevice vk_device, VkBuffer vk_buffer, VkFormat format,
1137                       VkImageUsageFlags usage,
1138                       VkImageType image_type,
1139                       const VkAllocationCallbacks *alloc,
1140                       const VkBufferImageCopy *copy)
1141 {
1142    ANV_FROM_HANDLE(anv_buffer, buffer, vk_buffer);
1143
1144    VkExtent3D extent = copy->imageExtent;
1145    if (copy->bufferRowLength)
1146       extent.width = copy->bufferRowLength;
1147    if (copy->bufferImageHeight)
1148       extent.height = copy->bufferImageHeight;
1149    extent.depth = 1;
1150    extent = meta_region_extent_el(format, &extent);
1151
1152    VkImageAspectFlags aspect = copy->imageSubresource.aspectMask;
1153    VkFormat buffer_format = choose_buffer_format(format, aspect);
1154
1155    VkImage vk_image;
1156    VkResult result = anv_CreateImage(vk_device,
1157       &(VkImageCreateInfo) {
1158          .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
1159          .imageType = VK_IMAGE_TYPE_2D,
1160          .format = buffer_format,
1161          .extent = extent,
1162          .mipLevels = 1,
1163          .arrayLayers = 1,
1164          .samples = 1,
1165          .tiling = VK_IMAGE_TILING_LINEAR,
1166          .usage = usage,
1167          .flags = 0,
1168       }, alloc, &vk_image);
1169    assert(result == VK_SUCCESS);
1170
1171    ANV_FROM_HANDLE(anv_image, image, vk_image);
1172
1173    /* We could use a vk call to bind memory, but that would require
1174     * creating a dummy memory object etc. so there's really no point.
1175     */
1176    image->bo = buffer->bo;
1177    image->offset = buffer->offset + copy->bufferOffset;
1178
1179    return image;
1180 }
1181
1182 void anv_CmdCopyBufferToImage(
1183     VkCommandBuffer                             commandBuffer,
1184     VkBuffer                                    srcBuffer,
1185     VkImage                                     destImage,
1186     VkImageLayout                               destImageLayout,
1187     uint32_t                                    regionCount,
1188     const VkBufferImageCopy*                    pRegions)
1189 {
1190    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1191    ANV_FROM_HANDLE(anv_image, dest_image, destImage);
1192    ANV_FROM_HANDLE(anv_buffer, src_buffer, srcBuffer);
1193
1194    meta_copy_buffer_to_image(cmd_buffer, src_buffer, dest_image,
1195                              regionCount, pRegions, true);
1196 }
1197
1198 void anv_CmdCopyImageToBuffer(
1199     VkCommandBuffer                             commandBuffer,
1200     VkImage                                     srcImage,
1201     VkImageLayout                               srcImageLayout,
1202     VkBuffer                                    destBuffer,
1203     uint32_t                                    regionCount,
1204     const VkBufferImageCopy*                    pRegions)
1205 {
1206    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1207    ANV_FROM_HANDLE(anv_image, src_image, srcImage);
1208    ANV_FROM_HANDLE(anv_buffer, dst_buffer, destBuffer);
1209
1210    meta_copy_buffer_to_image(cmd_buffer, dst_buffer, src_image,
1211                              regionCount, pRegions, false);
1212 }
1213
1214 void
1215 anv_device_finish_meta_blit_state(struct anv_device *device)
1216 {
1217    anv_DestroyRenderPass(anv_device_to_handle(device),
1218                          device->meta_state.blit.render_pass,
1219                          &device->meta_state.alloc);
1220    anv_DestroyPipeline(anv_device_to_handle(device),
1221                        device->meta_state.blit.pipeline_1d_src,
1222                        &device->meta_state.alloc);
1223    anv_DestroyPipeline(anv_device_to_handle(device),
1224                        device->meta_state.blit.pipeline_2d_src,
1225                        &device->meta_state.alloc);
1226    anv_DestroyPipeline(anv_device_to_handle(device),
1227                        device->meta_state.blit.pipeline_3d_src,
1228                        &device->meta_state.alloc);
1229    anv_DestroyPipelineLayout(anv_device_to_handle(device),
1230                              device->meta_state.blit.pipeline_layout,
1231                              &device->meta_state.alloc);
1232    anv_DestroyDescriptorSetLayout(anv_device_to_handle(device),
1233                                   device->meta_state.blit.ds_layout,
1234                                   &device->meta_state.alloc);
1235 }
1236
1237 VkResult
1238 anv_device_init_meta_blit_state(struct anv_device *device)
1239 {
1240    VkResult result;
1241
1242    result = anv_CreateRenderPass(anv_device_to_handle(device),
1243       &(VkRenderPassCreateInfo) {
1244          .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
1245          .attachmentCount = 1,
1246          .pAttachments = &(VkAttachmentDescription) {
1247             .format = VK_FORMAT_UNDEFINED, /* Our shaders don't care */
1248             .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
1249             .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
1250             .initialLayout = VK_IMAGE_LAYOUT_GENERAL,
1251             .finalLayout = VK_IMAGE_LAYOUT_GENERAL,
1252          },
1253          .subpassCount = 1,
1254          .pSubpasses = &(VkSubpassDescription) {
1255             .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
1256             .inputAttachmentCount = 0,
1257             .colorAttachmentCount = 1,
1258             .pColorAttachments = &(VkAttachmentReference) {
1259                .attachment = 0,
1260                .layout = VK_IMAGE_LAYOUT_GENERAL,
1261             },
1262             .pResolveAttachments = NULL,
1263             .pDepthStencilAttachment = &(VkAttachmentReference) {
1264                .attachment = VK_ATTACHMENT_UNUSED,
1265                .layout = VK_IMAGE_LAYOUT_GENERAL,
1266             },
1267             .preserveAttachmentCount = 1,
1268             .pPreserveAttachments = (uint32_t[]) { 0 },
1269          },
1270          .dependencyCount = 0,
1271       }, &device->meta_state.alloc, &device->meta_state.blit.render_pass);
1272    if (result != VK_SUCCESS)
1273       goto fail;
1274
1275    /* We don't use a vertex shader for blitting, but instead build and pass
1276     * the VUEs directly to the rasterization backend.  However, we do need
1277     * to provide GLSL source for the vertex shader so that the compiler
1278     * does not dead-code our inputs.
1279     */
1280    struct anv_shader_module vs = {
1281       .nir = build_nir_vertex_shader(),
1282    };
1283
1284    struct anv_shader_module fs_1d = {
1285       .nir = build_nir_copy_fragment_shader(GLSL_SAMPLER_DIM_1D),
1286    };
1287
1288    struct anv_shader_module fs_2d = {
1289       .nir = build_nir_copy_fragment_shader(GLSL_SAMPLER_DIM_2D),
1290    };
1291
1292    struct anv_shader_module fs_3d = {
1293       .nir = build_nir_copy_fragment_shader(GLSL_SAMPLER_DIM_3D),
1294    };
1295
1296    VkPipelineVertexInputStateCreateInfo vi_create_info = {
1297       .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
1298       .vertexBindingDescriptionCount = 2,
1299       .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) {
1300          {
1301             .binding = 0,
1302             .stride = 0,
1303             .inputRate = VK_VERTEX_INPUT_RATE_VERTEX
1304          },
1305          {
1306             .binding = 1,
1307             .stride = 5 * sizeof(float),
1308             .inputRate = VK_VERTEX_INPUT_RATE_VERTEX
1309          },
1310       },
1311       .vertexAttributeDescriptionCount = 3,
1312       .pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[]) {
1313          {
1314             /* VUE Header */
1315             .location = 0,
1316             .binding = 0,
1317             .format = VK_FORMAT_R32G32B32A32_UINT,
1318             .offset = 0
1319          },
1320          {
1321             /* Position */
1322             .location = 1,
1323             .binding = 1,
1324             .format = VK_FORMAT_R32G32_SFLOAT,
1325             .offset = 0
1326          },
1327          {
1328             /* Texture Coordinate */
1329             .location = 2,
1330             .binding = 1,
1331             .format = VK_FORMAT_R32G32B32_SFLOAT,
1332             .offset = 8
1333          }
1334       }
1335    };
1336
1337    VkDescriptorSetLayoutCreateInfo ds_layout_info = {
1338       .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1339       .bindingCount = 1,
1340       .pBindings = (VkDescriptorSetLayoutBinding[]) {
1341          {
1342             .binding = 0,
1343             .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
1344             .descriptorCount = 1,
1345             .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
1346             .pImmutableSamplers = NULL
1347          },
1348       }
1349    };
1350    result = anv_CreateDescriptorSetLayout(anv_device_to_handle(device),
1351                                           &ds_layout_info,
1352                                           &device->meta_state.alloc,
1353                                           &device->meta_state.blit.ds_layout);
1354    if (result != VK_SUCCESS)
1355       goto fail_render_pass;
1356
1357    result = anv_CreatePipelineLayout(anv_device_to_handle(device),
1358       &(VkPipelineLayoutCreateInfo) {
1359          .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1360          .setLayoutCount = 1,
1361          .pSetLayouts = &device->meta_state.blit.ds_layout,
1362       },
1363       &device->meta_state.alloc, &device->meta_state.blit.pipeline_layout);
1364    if (result != VK_SUCCESS)
1365       goto fail_descriptor_set_layout;
1366
1367    VkPipelineShaderStageCreateInfo pipeline_shader_stages[] = {
1368       {
1369          .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1370          .stage = VK_SHADER_STAGE_VERTEX_BIT,
1371          .module = anv_shader_module_to_handle(&vs),
1372          .pName = "main",
1373          .pSpecializationInfo = NULL
1374       }, {
1375          .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1376          .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
1377          .module = VK_NULL_HANDLE, /* TEMPLATE VALUE! FILL ME IN! */
1378          .pName = "main",
1379          .pSpecializationInfo = NULL
1380       },
1381    };
1382
1383    const VkGraphicsPipelineCreateInfo vk_pipeline_info = {
1384       .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1385       .stageCount = ARRAY_SIZE(pipeline_shader_stages),
1386       .pStages = pipeline_shader_stages,
1387       .pVertexInputState = &vi_create_info,
1388       .pInputAssemblyState = &(VkPipelineInputAssemblyStateCreateInfo) {
1389          .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
1390          .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
1391          .primitiveRestartEnable = false,
1392       },
1393       .pViewportState = &(VkPipelineViewportStateCreateInfo) {
1394          .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
1395          .viewportCount = 1,
1396          .scissorCount = 1,
1397       },
1398       .pRasterizationState = &(VkPipelineRasterizationStateCreateInfo) {
1399          .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
1400          .rasterizerDiscardEnable = false,
1401          .polygonMode = VK_POLYGON_MODE_FILL,
1402          .cullMode = VK_CULL_MODE_NONE,
1403          .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE
1404       },
1405       .pMultisampleState = &(VkPipelineMultisampleStateCreateInfo) {
1406          .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
1407          .rasterizationSamples = 1,
1408          .sampleShadingEnable = false,
1409          .pSampleMask = (VkSampleMask[]) { UINT32_MAX },
1410       },
1411       .pColorBlendState = &(VkPipelineColorBlendStateCreateInfo) {
1412          .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
1413          .attachmentCount = 1,
1414          .pAttachments = (VkPipelineColorBlendAttachmentState []) {
1415             { .colorWriteMask =
1416                  VK_COLOR_COMPONENT_A_BIT |
1417                  VK_COLOR_COMPONENT_R_BIT |
1418                  VK_COLOR_COMPONENT_G_BIT |
1419                  VK_COLOR_COMPONENT_B_BIT },
1420          }
1421       },
1422       .pDynamicState = &(VkPipelineDynamicStateCreateInfo) {
1423          .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
1424          .dynamicStateCount = 9,
1425          .pDynamicStates = (VkDynamicState[]) {
1426             VK_DYNAMIC_STATE_VIEWPORT,
1427             VK_DYNAMIC_STATE_SCISSOR,
1428             VK_DYNAMIC_STATE_LINE_WIDTH,
1429             VK_DYNAMIC_STATE_DEPTH_BIAS,
1430             VK_DYNAMIC_STATE_BLEND_CONSTANTS,
1431             VK_DYNAMIC_STATE_DEPTH_BOUNDS,
1432             VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
1433             VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
1434             VK_DYNAMIC_STATE_STENCIL_REFERENCE,
1435          },
1436       },
1437       .flags = 0,
1438       .layout = device->meta_state.blit.pipeline_layout,
1439       .renderPass = device->meta_state.blit.render_pass,
1440       .subpass = 0,
1441    };
1442
1443    const struct anv_graphics_pipeline_create_info anv_pipeline_info = {
1444       .color_attachment_count = -1,
1445       .use_repclear = false,
1446       .disable_viewport = true,
1447       .disable_scissor = true,
1448       .disable_vs = true,
1449       .use_rectlist = true
1450    };
1451
1452    pipeline_shader_stages[1].module = anv_shader_module_to_handle(&fs_1d);
1453    result = anv_graphics_pipeline_create(anv_device_to_handle(device),
1454       VK_NULL_HANDLE,
1455       &vk_pipeline_info, &anv_pipeline_info,
1456       &device->meta_state.alloc, &device->meta_state.blit.pipeline_1d_src);
1457    if (result != VK_SUCCESS)
1458       goto fail_pipeline_layout;
1459
1460    pipeline_shader_stages[1].module = anv_shader_module_to_handle(&fs_2d);
1461    result = anv_graphics_pipeline_create(anv_device_to_handle(device),
1462       VK_NULL_HANDLE,
1463       &vk_pipeline_info, &anv_pipeline_info,
1464       &device->meta_state.alloc, &device->meta_state.blit.pipeline_2d_src);
1465    if (result != VK_SUCCESS)
1466       goto fail_pipeline_1d;
1467
1468    pipeline_shader_stages[1].module = anv_shader_module_to_handle(&fs_3d);
1469    result = anv_graphics_pipeline_create(anv_device_to_handle(device),
1470       VK_NULL_HANDLE,
1471       &vk_pipeline_info, &anv_pipeline_info,
1472       &device->meta_state.alloc, &device->meta_state.blit.pipeline_3d_src);
1473    if (result != VK_SUCCESS)
1474       goto fail_pipeline_2d;
1475
1476    ralloc_free(vs.nir);
1477    ralloc_free(fs_1d.nir);
1478    ralloc_free(fs_2d.nir);
1479    ralloc_free(fs_3d.nir);
1480
1481    return VK_SUCCESS;
1482
1483  fail_pipeline_2d:
1484    anv_DestroyPipeline(anv_device_to_handle(device),
1485                        device->meta_state.blit.pipeline_2d_src,
1486                        &device->meta_state.alloc);
1487
1488  fail_pipeline_1d:
1489    anv_DestroyPipeline(anv_device_to_handle(device),
1490                        device->meta_state.blit.pipeline_1d_src,
1491                        &device->meta_state.alloc);
1492
1493  fail_pipeline_layout:
1494    anv_DestroyPipelineLayout(anv_device_to_handle(device),
1495                              device->meta_state.blit.pipeline_layout,
1496                              &device->meta_state.alloc);
1497  fail_descriptor_set_layout:
1498    anv_DestroyDescriptorSetLayout(anv_device_to_handle(device),
1499                                   device->meta_state.blit.ds_layout,
1500                                   &device->meta_state.alloc);
1501  fail_render_pass:
1502    anv_DestroyRenderPass(anv_device_to_handle(device),
1503                          device->meta_state.blit.render_pass,
1504                          &device->meta_state.alloc);
1505
1506    ralloc_free(vs.nir);
1507    ralloc_free(fs_1d.nir);
1508    ralloc_free(fs_2d.nir);
1509    ralloc_free(fs_3d.nir);
1510  fail:
1511    return result;
1512 }