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