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