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