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