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