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