Merge ../mesa 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_private.h"
31 #include "anv_nir_builder.h"
32
33 static nir_shader *
34 build_nir_vertex_shader(bool attr_flat)
35 {
36 nir_builder b;
37
38 const struct glsl_type *vertex_type = glsl_vec4_type();
39
40 nir_builder_init_simple_shader(&b, MESA_SHADER_VERTEX);
41
42 nir_variable *pos_in = nir_variable_create(b.shader, "a_pos",
43 vertex_type,
44 nir_var_shader_in);
45 pos_in->data.location = VERT_ATTRIB_GENERIC0;
46 nir_variable *pos_out = nir_variable_create(b.shader, "gl_Position",
47 vertex_type,
48 nir_var_shader_out);
49 pos_in->data.location = VARYING_SLOT_POS;
50 nir_copy_var(&b, pos_out, pos_in);
51
52 /* Add one more pass-through attribute. For clear shaders, this is used
53 * to store the color and for blit shaders it's the texture coordinate.
54 */
55 const struct glsl_type *attr_type = glsl_vec4_type();
56 nir_variable *attr_in = nir_variable_create(b.shader, "a_attr", attr_type,
57 nir_var_shader_in);
58 attr_in->data.location = VERT_ATTRIB_GENERIC1;
59 nir_variable *attr_out = nir_variable_create(b.shader, "v_attr", attr_type,
60 nir_var_shader_out);
61 attr_out->data.location = VARYING_SLOT_VAR0;
62 attr_out->data.interpolation = attr_flat ? INTERP_QUALIFIER_FLAT :
63 INTERP_QUALIFIER_SMOOTH;
64 nir_copy_var(&b, attr_out, attr_in);
65
66 return b.shader;
67 }
68
69 static nir_shader *
70 build_nir_clear_fragment_shader(void)
71 {
72 nir_builder b;
73
74 const struct glsl_type *color_type = glsl_vec4_type();
75
76 nir_builder_init_simple_shader(&b, MESA_SHADER_FRAGMENT);
77
78 nir_variable *color_in = nir_variable_create(b.shader, "v_attr",
79 color_type,
80 nir_var_shader_in);
81 color_in->data.location = VARYING_SLOT_VAR0;
82 color_in->data.interpolation = INTERP_QUALIFIER_FLAT;
83 nir_variable *color_out = nir_variable_create(b.shader, "f_color",
84 color_type,
85 nir_var_shader_out);
86 color_out->data.location = FRAG_RESULT_DATA0;
87 nir_copy_var(&b, color_out, color_in);
88
89 return b.shader;
90 }
91
92 static nir_shader *
93 build_nir_copy_fragment_shader(enum glsl_sampler_dim tex_dim)
94 {
95 nir_builder b;
96
97 nir_builder_init_simple_shader(&b, MESA_SHADER_FRAGMENT);
98
99 const struct glsl_type *color_type = glsl_vec4_type();
100
101 nir_variable *tex_pos_in = nir_variable_create(b.shader, "v_attr",
102 glsl_vec4_type(),
103 nir_var_shader_in);
104 tex_pos_in->data.location = VARYING_SLOT_VAR0;
105
106 const struct glsl_type *sampler_type =
107 glsl_sampler_type(tex_dim, false, false, glsl_get_base_type(color_type));
108 nir_variable *sampler = nir_variable_create(b.shader, "s_tex", sampler_type,
109 nir_var_uniform);
110 sampler->data.descriptor_set = 0;
111 sampler->data.binding = 0;
112
113 nir_tex_instr *tex = nir_tex_instr_create(b.shader, 1);
114 tex->sampler_dim = tex_dim;
115 tex->op = nir_texop_tex;
116 tex->src[0].src_type = nir_tex_src_coord;
117 tex->src[0].src = nir_src_for_ssa(nir_load_var(&b, tex_pos_in));
118 tex->dest_type = nir_type_float; /* TODO */
119
120 switch (tex_dim) {
121 case GLSL_SAMPLER_DIM_2D:
122 tex->coord_components = 2;
123 break;
124 case GLSL_SAMPLER_DIM_3D:
125 tex->coord_components = 3;
126 break;
127 default:
128 assert(!"Unsupported texture dimension");
129 }
130
131 tex->sampler = nir_deref_var_create(tex, sampler);
132
133 nir_ssa_dest_init(&tex->instr, &tex->dest, 4, "tex");
134 nir_builder_instr_insert(&b, &tex->instr);
135
136 nir_variable *color_out = nir_variable_create(b.shader, "f_color",
137 color_type,
138 nir_var_shader_out);
139 color_out->data.location = FRAG_RESULT_DATA0;
140 nir_store_var(&b, color_out, &tex->dest.ssa);
141
142 return b.shader;
143 }
144
145 static void
146 anv_device_init_meta_clear_state(struct anv_device *device)
147 {
148 struct anv_shader_module vsm = {
149 .nir = build_nir_vertex_shader(true),
150 };
151
152 struct anv_shader_module fsm = {
153 .nir = build_nir_clear_fragment_shader(),
154 };
155
156 VkShader vs;
157 anv_CreateShader(anv_device_to_handle(device),
158 &(VkShaderCreateInfo) {
159 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
160 .module = anv_shader_module_to_handle(&vsm),
161 .pName = "main",
162 }, &vs);
163
164 VkShader fs;
165 anv_CreateShader(anv_device_to_handle(device),
166 &(VkShaderCreateInfo) {
167 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
168 .module = anv_shader_module_to_handle(&fsm),
169 .pName = "main",
170 }, &fs);
171
172 /* We use instanced rendering to clear multiple render targets. We have two
173 * vertex buffers: the first vertex buffer holds per-vertex data and
174 * provides the vertices for the clear rectangle. The second one holds
175 * per-instance data, which consists of the VUE header (which selects the
176 * layer) and the color (Vulkan supports per-RT clear colors).
177 */
178 VkPipelineVertexInputStateCreateInfo vi_create_info = {
179 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
180 .bindingCount = 2,
181 .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) {
182 {
183 .binding = 0,
184 .strideInBytes = 12,
185 .stepRate = VK_VERTEX_INPUT_STEP_RATE_VERTEX
186 },
187 {
188 .binding = 1,
189 .strideInBytes = 32,
190 .stepRate = VK_VERTEX_INPUT_STEP_RATE_INSTANCE
191 },
192 },
193 .attributeCount = 3,
194 .pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[]) {
195 {
196 /* VUE Header */
197 .location = 0,
198 .binding = 1,
199 .format = VK_FORMAT_R32G32B32A32_UINT,
200 .offsetInBytes = 0
201 },
202 {
203 /* Position */
204 .location = 1,
205 .binding = 0,
206 .format = VK_FORMAT_R32G32B32_SFLOAT,
207 .offsetInBytes = 0
208 },
209 {
210 /* Color */
211 .location = 2,
212 .binding = 1,
213 .format = VK_FORMAT_R32G32B32A32_SFLOAT,
214 .offsetInBytes = 16
215 }
216 }
217 };
218
219 anv_graphics_pipeline_create(anv_device_to_handle(device),
220 &(VkGraphicsPipelineCreateInfo) {
221 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
222
223 .stageCount = 2,
224 .pStages = (VkPipelineShaderStageCreateInfo[]) {
225 {
226 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
227 .stage = VK_SHADER_STAGE_VERTEX,
228 .shader = vs,
229 .pSpecializationInfo = NULL
230 }, {
231 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
232 .stage = VK_SHADER_STAGE_FRAGMENT,
233 .shader = fs,
234 .pSpecializationInfo = NULL,
235 }
236 },
237 .pVertexInputState = &vi_create_info,
238 .pInputAssemblyState = &(VkPipelineInputAssemblyStateCreateInfo) {
239 .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
240 .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
241 .primitiveRestartEnable = false,
242 },
243 .pRasterState = &(VkPipelineRasterStateCreateInfo) {
244 .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTER_STATE_CREATE_INFO,
245 .depthClipEnable = true,
246 .rasterizerDiscardEnable = false,
247 .fillMode = VK_FILL_MODE_SOLID,
248 .cullMode = VK_CULL_MODE_NONE,
249 .frontFace = VK_FRONT_FACE_CCW
250 },
251 .pDepthStencilState = &(VkPipelineDepthStencilStateCreateInfo) {
252 .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
253 .depthTestEnable = true,
254 .depthWriteEnable = true,
255 .depthCompareOp = VK_COMPARE_OP_ALWAYS,
256 .depthBoundsTestEnable = false,
257 .stencilTestEnable = true,
258 .front = (VkStencilOpState) {
259 .stencilPassOp = VK_STENCIL_OP_REPLACE,
260 .stencilCompareOp = VK_COMPARE_OP_ALWAYS,
261 },
262 .back = (VkStencilOpState) {
263 .stencilPassOp = VK_STENCIL_OP_REPLACE,
264 .stencilCompareOp = VK_COMPARE_OP_ALWAYS,
265 },
266 },
267 .pColorBlendState = &(VkPipelineColorBlendStateCreateInfo) {
268 .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
269 .attachmentCount = 1,
270 .pAttachments = (VkPipelineColorBlendAttachmentState []) {
271 { .channelWriteMask = VK_CHANNEL_A_BIT |
272 VK_CHANNEL_R_BIT | VK_CHANNEL_G_BIT | VK_CHANNEL_B_BIT },
273 }
274 },
275 .flags = 0,
276 },
277 &(struct anv_graphics_pipeline_create_info) {
278 .use_repclear = true,
279 .disable_viewport = true,
280 .disable_vs = true,
281 .use_rectlist = true
282 },
283 &device->meta_state.clear.pipeline);
284
285 anv_DestroyShader(anv_device_to_handle(device), vs);
286 anv_DestroyShader(anv_device_to_handle(device), fs);
287 ralloc_free(vsm.nir);
288 ralloc_free(fsm.nir);
289 }
290
291 #define NUM_VB_USED 2
292 struct anv_saved_state {
293 struct anv_vertex_binding old_vertex_bindings[NUM_VB_USED];
294 struct anv_descriptor_set *old_descriptor_set0;
295 struct anv_pipeline *old_pipeline;
296 uint32_t dynamic_flags;
297 struct anv_dynamic_state dynamic;
298 };
299
300 static void
301 anv_cmd_buffer_save(struct anv_cmd_buffer *cmd_buffer,
302 struct anv_saved_state *state,
303 uint32_t dynamic_state)
304 {
305 state->old_pipeline = cmd_buffer->state.pipeline;
306 state->old_descriptor_set0 = cmd_buffer->state.descriptors[0].set;
307 memcpy(state->old_vertex_bindings, cmd_buffer->state.vertex_bindings,
308 sizeof(state->old_vertex_bindings));
309 state->dynamic_flags = dynamic_state;
310 anv_dynamic_state_copy(&state->dynamic, &cmd_buffer->state.dynamic,
311 dynamic_state);
312 }
313
314 static void
315 anv_cmd_buffer_restore(struct anv_cmd_buffer *cmd_buffer,
316 const struct anv_saved_state *state)
317 {
318 cmd_buffer->state.pipeline = state->old_pipeline;
319 cmd_buffer->state.descriptors[0].set = state->old_descriptor_set0;
320 memcpy(cmd_buffer->state.vertex_bindings, state->old_vertex_bindings,
321 sizeof(state->old_vertex_bindings));
322
323 cmd_buffer->state.vb_dirty |= (1 << NUM_VB_USED) - 1;
324 cmd_buffer->state.dirty |= ANV_CMD_BUFFER_PIPELINE_DIRTY;
325 cmd_buffer->state.descriptors_dirty |= VK_SHADER_STAGE_VERTEX_BIT;
326
327 anv_dynamic_state_copy(&cmd_buffer->state.dynamic, &state->dynamic,
328 state->dynamic_flags);
329 cmd_buffer->state.dirty |= state->dynamic_flags;
330 }
331
332 struct vue_header {
333 uint32_t Reserved;
334 uint32_t RTAIndex;
335 uint32_t ViewportIndex;
336 float PointWidth;
337 };
338
339 struct clear_instance_data {
340 struct vue_header vue_header;
341 VkClearColorValue color;
342 };
343
344 static void
345 meta_emit_clear(struct anv_cmd_buffer *cmd_buffer,
346 int num_instances,
347 struct clear_instance_data *instance_data,
348 VkClearDepthStencilValue ds_clear_value)
349 {
350 struct anv_device *device = cmd_buffer->device;
351 struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
352 struct anv_state state;
353 uint32_t size;
354
355 const float vertex_data[] = {
356 /* Rect-list coordinates */
357 0.0, 0.0, ds_clear_value.depth,
358 fb->width, 0.0, ds_clear_value.depth,
359 fb->width, fb->height, ds_clear_value.depth,
360
361 /* Align to 16 bytes */
362 0.0, 0.0, 0.0,
363 };
364
365 size = sizeof(vertex_data) + num_instances * sizeof(*instance_data);
366 state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, size, 16);
367
368 /* Copy in the vertex and instance data */
369 memcpy(state.map, vertex_data, sizeof(vertex_data));
370 memcpy(state.map + sizeof(vertex_data), instance_data,
371 num_instances * sizeof(*instance_data));
372
373 struct anv_buffer vertex_buffer = {
374 .device = cmd_buffer->device,
375 .size = size,
376 .bo = &device->dynamic_state_block_pool.bo,
377 .offset = state.offset
378 };
379
380 anv_CmdBindVertexBuffers(anv_cmd_buffer_to_handle(cmd_buffer), 0, 2,
381 (VkBuffer[]) {
382 anv_buffer_to_handle(&vertex_buffer),
383 anv_buffer_to_handle(&vertex_buffer)
384 },
385 (VkDeviceSize[]) {
386 0,
387 sizeof(vertex_data)
388 });
389
390 if (cmd_buffer->state.pipeline != anv_pipeline_from_handle(device->meta_state.clear.pipeline))
391 anv_CmdBindPipeline(anv_cmd_buffer_to_handle(cmd_buffer),
392 VK_PIPELINE_BIND_POINT_GRAPHICS,
393 device->meta_state.clear.pipeline);
394
395 ANV_CALL(CmdDraw)(anv_cmd_buffer_to_handle(cmd_buffer),
396 3, num_instances, 0, 0);
397 }
398
399 void
400 anv_cmd_buffer_clear_attachments(struct anv_cmd_buffer *cmd_buffer,
401 struct anv_render_pass *pass,
402 const VkClearValue *clear_values)
403 {
404 struct anv_saved_state saved_state;
405
406 if (pass->has_stencil_clear_attachment)
407 anv_finishme("stencil clear");
408
409 /* FINISHME: Rethink how we count clear attachments in light of
410 * 0.138.2 -> 0.170.2 diff.
411 */
412 if (pass->num_color_clear_attachments == 0 &&
413 !pass->has_depth_clear_attachment)
414 return;
415
416 struct clear_instance_data instance_data[pass->num_color_clear_attachments];
417 uint32_t color_attachments[pass->num_color_clear_attachments];
418 uint32_t ds_attachment = VK_ATTACHMENT_UNUSED;
419 VkClearDepthStencilValue ds_clear_value = {0};
420
421 int layer = 0;
422 for (uint32_t i = 0; i < pass->attachment_count; i++) {
423 const struct anv_render_pass_attachment *att = &pass->attachments[i];
424
425 if (att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
426 if (anv_format_is_color(att->format)) {
427 instance_data[layer] = (struct clear_instance_data) {
428 .vue_header = {
429 .RTAIndex = i,
430 .ViewportIndex = 0,
431 .PointWidth = 0.0
432 },
433 .color = clear_values[i].color,
434 };
435 color_attachments[layer] = i;
436 layer++;
437 } else if (att->format->depth_format) {
438 assert(ds_attachment == VK_ATTACHMENT_UNUSED);
439 ds_attachment = i;
440 ds_clear_value = clear_values[ds_attachment].depthStencil;
441 }
442 } else if (att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
443 assert(att->format->has_stencil);
444 anv_finishme("stencil clear");
445 }
446 }
447
448 anv_cmd_buffer_save(cmd_buffer, &saved_state,
449 (1 << VK_DYNAMIC_STATE_VIEWPORT));
450 cmd_buffer->state.dynamic.viewport.count = 0;
451
452 struct anv_subpass subpass = {
453 .input_count = 0,
454 .color_count = pass->num_color_clear_attachments,
455 .color_attachments = color_attachments,
456 .depth_stencil_attachment = ds_attachment,
457 };
458
459 anv_cmd_buffer_begin_subpass(cmd_buffer, &subpass);
460
461 meta_emit_clear(cmd_buffer, pass->num_color_clear_attachments,
462 instance_data, ds_clear_value);
463
464 /* Restore API state */
465 anv_cmd_buffer_restore(cmd_buffer, &saved_state);
466 }
467
468 static VkImageViewType
469 meta_blit_get_src_image_view_type(const struct anv_image *src_image)
470 {
471 switch (src_image->type) {
472 case VK_IMAGE_TYPE_1D:
473 return VK_IMAGE_VIEW_TYPE_1D;
474 case VK_IMAGE_TYPE_2D:
475 return VK_IMAGE_VIEW_TYPE_2D;
476 case VK_IMAGE_TYPE_3D:
477 return VK_IMAGE_VIEW_TYPE_3D;
478 default:
479 assert(!"bad VkImageType");
480 return 0;
481 }
482 }
483
484 static uint32_t
485 meta_blit_get_dest_view_base_array_slice(const struct anv_image *dest_image,
486 const VkImageSubresourceCopy *dest_subresource,
487 const VkOffset3D *dest_offset)
488 {
489 switch (dest_image->type) {
490 case VK_IMAGE_TYPE_1D:
491 case VK_IMAGE_TYPE_2D:
492 return dest_subresource->arrayLayer;
493 case VK_IMAGE_TYPE_3D:
494 /* HACK: Vulkan does not allow attaching a 3D image to a framebuffer,
495 * but meta does it anyway. When doing so, we translate the
496 * destination's z offset into an array offset.
497 */
498 return dest_offset->z;
499 default:
500 assert(!"bad VkImageType");
501 return 0;
502 }
503 }
504
505 static void
506 anv_device_init_meta_blit_state(struct anv_device *device)
507 {
508 /* We don't use a vertex shader for clearing, but instead build and pass
509 * the VUEs directly to the rasterization backend. However, we do need
510 * to provide GLSL source for the vertex shader so that the compiler
511 * does not dead-code our inputs.
512 */
513 struct anv_shader_module vsm = {
514 .nir = build_nir_vertex_shader(false),
515 };
516
517 struct anv_shader_module fsm_2d = {
518 .nir = build_nir_copy_fragment_shader(GLSL_SAMPLER_DIM_2D),
519 };
520
521 struct anv_shader_module fsm_3d = {
522 .nir = build_nir_copy_fragment_shader(GLSL_SAMPLER_DIM_3D),
523 };
524
525 VkShader vs;
526 anv_CreateShader(anv_device_to_handle(device),
527 &(VkShaderCreateInfo) {
528 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
529 .module = anv_shader_module_to_handle(&vsm),
530 .pName = "main",
531 }, &vs);
532
533 VkShader fs_2d;
534 anv_CreateShader(anv_device_to_handle(device),
535 &(VkShaderCreateInfo) {
536 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
537 .module = anv_shader_module_to_handle(&fsm_2d),
538 .pName = "main",
539 }, &fs_2d);
540
541 VkShader fs_3d;
542 anv_CreateShader(anv_device_to_handle(device),
543 &(VkShaderCreateInfo) {
544 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
545 .module = anv_shader_module_to_handle(&fsm_3d),
546 .pName = "main",
547 }, &fs_3d);
548
549 VkPipelineVertexInputStateCreateInfo vi_create_info = {
550 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
551 .bindingCount = 2,
552 .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) {
553 {
554 .binding = 0,
555 .strideInBytes = 0,
556 .stepRate = VK_VERTEX_INPUT_STEP_RATE_VERTEX
557 },
558 {
559 .binding = 1,
560 .strideInBytes = 5 * sizeof(float),
561 .stepRate = VK_VERTEX_INPUT_STEP_RATE_VERTEX
562 },
563 },
564 .attributeCount = 3,
565 .pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[]) {
566 {
567 /* VUE Header */
568 .location = 0,
569 .binding = 0,
570 .format = VK_FORMAT_R32G32B32A32_UINT,
571 .offsetInBytes = 0
572 },
573 {
574 /* Position */
575 .location = 1,
576 .binding = 1,
577 .format = VK_FORMAT_R32G32_SFLOAT,
578 .offsetInBytes = 0
579 },
580 {
581 /* Texture Coordinate */
582 .location = 2,
583 .binding = 1,
584 .format = VK_FORMAT_R32G32B32_SFLOAT,
585 .offsetInBytes = 8
586 }
587 }
588 };
589
590 VkDescriptorSetLayoutCreateInfo ds_layout_info = {
591 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
592 .count = 1,
593 .pBinding = (VkDescriptorSetLayoutBinding[]) {
594 {
595 .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
596 .arraySize = 1,
597 .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
598 .pImmutableSamplers = NULL
599 },
600 }
601 };
602 anv_CreateDescriptorSetLayout(anv_device_to_handle(device), &ds_layout_info,
603 &device->meta_state.blit.ds_layout);
604
605 anv_CreatePipelineLayout(anv_device_to_handle(device),
606 &(VkPipelineLayoutCreateInfo) {
607 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
608 .descriptorSetCount = 1,
609 .pSetLayouts = &device->meta_state.blit.ds_layout,
610 },
611 &device->meta_state.blit.pipeline_layout);
612
613 VkPipelineShaderStageCreateInfo pipeline_shader_stages[] = {
614 {
615 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
616 .stage = VK_SHADER_STAGE_VERTEX,
617 .shader = vs,
618 .pSpecializationInfo = NULL
619 }, {
620 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
621 .stage = VK_SHADER_STAGE_FRAGMENT,
622 .shader = {0}, /* TEMPLATE VALUE! FILL ME IN! */
623 .pSpecializationInfo = NULL
624 },
625 };
626
627 const VkGraphicsPipelineCreateInfo vk_pipeline_info = {
628 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
629 .stageCount = ARRAY_SIZE(pipeline_shader_stages),
630 .pStages = pipeline_shader_stages,
631 .pVertexInputState = &vi_create_info,
632 .pInputAssemblyState = &(VkPipelineInputAssemblyStateCreateInfo) {
633 .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
634 .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
635 .primitiveRestartEnable = false,
636 },
637 .pRasterState = &(VkPipelineRasterStateCreateInfo) {
638 .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTER_STATE_CREATE_INFO,
639 .depthClipEnable = true,
640 .rasterizerDiscardEnable = false,
641 .fillMode = VK_FILL_MODE_SOLID,
642 .cullMode = VK_CULL_MODE_NONE,
643 .frontFace = VK_FRONT_FACE_CCW
644 },
645 .pColorBlendState = &(VkPipelineColorBlendStateCreateInfo) {
646 .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
647 .attachmentCount = 1,
648 .pAttachments = (VkPipelineColorBlendAttachmentState []) {
649 { .channelWriteMask = VK_CHANNEL_A_BIT |
650 VK_CHANNEL_R_BIT | VK_CHANNEL_G_BIT | VK_CHANNEL_B_BIT },
651 }
652 },
653 .flags = 0,
654 .layout = device->meta_state.blit.pipeline_layout,
655 };
656
657 const struct anv_graphics_pipeline_create_info anv_pipeline_info = {
658 .use_repclear = false,
659 .disable_viewport = true,
660 .disable_scissor = true,
661 .disable_vs = true,
662 .use_rectlist = true
663 };
664
665 pipeline_shader_stages[1].shader = fs_2d;
666 anv_graphics_pipeline_create(anv_device_to_handle(device),
667 &vk_pipeline_info, &anv_pipeline_info,
668 &device->meta_state.blit.pipeline_2d_src);
669
670 pipeline_shader_stages[1].shader = fs_3d;
671 anv_graphics_pipeline_create(anv_device_to_handle(device),
672 &vk_pipeline_info, &anv_pipeline_info,
673 &device->meta_state.blit.pipeline_3d_src);
674
675 anv_DestroyShader(anv_device_to_handle(device), vs);
676 anv_DestroyShader(anv_device_to_handle(device), fs_2d);
677 anv_DestroyShader(anv_device_to_handle(device), fs_3d);
678 ralloc_free(vsm.nir);
679 ralloc_free(fsm_2d.nir);
680 ralloc_free(fsm_3d.nir);
681 }
682
683 static void
684 meta_prepare_blit(struct anv_cmd_buffer *cmd_buffer,
685 struct anv_saved_state *saved_state)
686 {
687 anv_cmd_buffer_save(cmd_buffer, saved_state,
688 (1 << VK_DYNAMIC_STATE_VIEWPORT));
689 }
690
691 struct blit_region {
692 VkOffset3D src_offset;
693 VkExtent3D src_extent;
694 VkOffset3D dest_offset;
695 VkExtent3D dest_extent;
696 };
697
698 static void
699 meta_emit_blit(struct anv_cmd_buffer *cmd_buffer,
700 struct anv_image *src_image,
701 struct anv_image_view *src_iview,
702 VkOffset3D src_offset,
703 VkExtent3D src_extent,
704 struct anv_image *dest_image,
705 struct anv_image_view *dest_iview,
706 VkOffset3D dest_offset,
707 VkExtent3D dest_extent)
708 {
709 struct anv_device *device = cmd_buffer->device;
710 VkDescriptorPool dummy_desc_pool = { .handle = 1 };
711
712 struct blit_vb_data {
713 float pos[2];
714 float tex_coord[3];
715 } *vb_data;
716
717 unsigned vb_size = sizeof(struct vue_header) + 3 * sizeof(*vb_data);
718
719 struct anv_state vb_state =
720 anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, vb_size, 16);
721 memset(vb_state.map, 0, sizeof(struct vue_header));
722 vb_data = vb_state.map + sizeof(struct vue_header);
723
724 vb_data[0] = (struct blit_vb_data) {
725 .pos = {
726 dest_offset.x + dest_extent.width,
727 dest_offset.y + dest_extent.height,
728 },
729 .tex_coord = {
730 (float)(src_offset.x + src_extent.width) / (float)src_iview->extent.width,
731 (float)(src_offset.y + src_extent.height) / (float)src_iview->extent.height,
732 (float)(src_offset.z + src_extent.depth) / (float)src_iview->extent.depth,
733 },
734 };
735
736 vb_data[1] = (struct blit_vb_data) {
737 .pos = {
738 dest_offset.x,
739 dest_offset.y + dest_extent.height,
740 },
741 .tex_coord = {
742 (float)src_offset.x / (float)src_iview->extent.width,
743 (float)(src_offset.y + src_extent.height) / (float)src_iview->extent.height,
744 (float)(src_offset.z + src_extent.depth) / (float)src_iview->extent.depth,
745 },
746 };
747
748 vb_data[2] = (struct blit_vb_data) {
749 .pos = {
750 dest_offset.x,
751 dest_offset.y,
752 },
753 .tex_coord = {
754 (float)src_offset.x / (float)src_iview->extent.width,
755 (float)src_offset.y / (float)src_iview->extent.height,
756 (float)src_offset.z / (float)src_iview->extent.depth,
757 },
758 };
759
760 struct anv_buffer vertex_buffer = {
761 .device = device,
762 .size = vb_size,
763 .bo = &device->dynamic_state_block_pool.bo,
764 .offset = vb_state.offset,
765 };
766
767 anv_CmdBindVertexBuffers(anv_cmd_buffer_to_handle(cmd_buffer), 0, 2,
768 (VkBuffer[]) {
769 anv_buffer_to_handle(&vertex_buffer),
770 anv_buffer_to_handle(&vertex_buffer)
771 },
772 (VkDeviceSize[]) {
773 0,
774 sizeof(struct vue_header),
775 });
776
777 VkDescriptorSet set;
778 anv_AllocDescriptorSets(anv_device_to_handle(device), dummy_desc_pool,
779 VK_DESCRIPTOR_SET_USAGE_ONE_SHOT,
780 1, &device->meta_state.blit.ds_layout, &set);
781 anv_UpdateDescriptorSets(anv_device_to_handle(device),
782 1, /* writeCount */
783 (VkWriteDescriptorSet[]) {
784 {
785 .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
786 .destSet = set,
787 .destBinding = 0,
788 .destArrayElement = 0,
789 .count = 1,
790 .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
791 .pDescriptors = (VkDescriptorInfo[]) {
792 {
793 .imageView = anv_image_view_to_handle(src_iview),
794 .imageLayout = VK_IMAGE_LAYOUT_GENERAL
795 },
796 }
797 }
798 }, 0, NULL);
799
800 VkFramebuffer fb;
801 anv_CreateFramebuffer(anv_device_to_handle(device),
802 &(VkFramebufferCreateInfo) {
803 .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
804 .attachmentCount = 1,
805 .pAttachments = (VkImageView[]) {
806 anv_image_view_to_handle(dest_iview),
807 },
808 .width = dest_iview->extent.width,
809 .height = dest_iview->extent.height,
810 .layers = 1
811 }, &fb);
812
813 VkRenderPass pass;
814 anv_CreateRenderPass(anv_device_to_handle(device),
815 &(VkRenderPassCreateInfo) {
816 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
817 .attachmentCount = 1,
818 .pAttachments = &(VkAttachmentDescription) {
819 .sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION,
820 .format = dest_iview->format->vk_format,
821 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
822 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
823 .initialLayout = VK_IMAGE_LAYOUT_GENERAL,
824 .finalLayout = VK_IMAGE_LAYOUT_GENERAL,
825 },
826 .subpassCount = 1,
827 .pSubpasses = &(VkSubpassDescription) {
828 .sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION,
829 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
830 .inputCount = 0,
831 .colorCount = 1,
832 .pColorAttachments = &(VkAttachmentReference) {
833 .attachment = 0,
834 .layout = VK_IMAGE_LAYOUT_GENERAL,
835 },
836 .pResolveAttachments = NULL,
837 .depthStencilAttachment = (VkAttachmentReference) {
838 .attachment = VK_ATTACHMENT_UNUSED,
839 .layout = VK_IMAGE_LAYOUT_GENERAL,
840 },
841 .preserveCount = 1,
842 .pPreserveAttachments = &(VkAttachmentReference) {
843 .attachment = 0,
844 .layout = VK_IMAGE_LAYOUT_GENERAL,
845 },
846 },
847 .dependencyCount = 0,
848 }, &pass);
849
850 ANV_CALL(CmdBeginRenderPass)(anv_cmd_buffer_to_handle(cmd_buffer),
851 &(VkRenderPassBeginInfo) {
852 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
853 .renderPass = pass,
854 .framebuffer = fb,
855 .renderArea = {
856 .offset = { dest_offset.x, dest_offset.y },
857 .extent = { dest_extent.width, dest_extent.height },
858 },
859 .clearValueCount = 0,
860 .pClearValues = NULL,
861 }, VK_RENDER_PASS_CONTENTS_INLINE);
862
863 VkPipeline pipeline;
864
865 switch (src_image->type) {
866 case VK_IMAGE_TYPE_1D:
867 anv_finishme("VK_IMAGE_TYPE_1D");
868 pipeline = device->meta_state.blit.pipeline_2d_src;
869 break;
870 case VK_IMAGE_TYPE_2D:
871 pipeline = device->meta_state.blit.pipeline_2d_src;
872 break;
873 case VK_IMAGE_TYPE_3D:
874 pipeline = device->meta_state.blit.pipeline_3d_src;
875 break;
876 default:
877 unreachable(!"bad VkImageType");
878 }
879
880 if (cmd_buffer->state.pipeline != anv_pipeline_from_handle(pipeline)) {
881 anv_CmdBindPipeline(anv_cmd_buffer_to_handle(cmd_buffer),
882 VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
883 }
884
885 anv_CmdSetViewport(anv_cmd_buffer_to_handle(cmd_buffer), 1,
886 &(VkViewport) {
887 .originX = 0.0f,
888 .originY = 0.0f,
889 .width = dest_iview->extent.width,
890 .height = dest_iview->extent.height,
891 .minDepth = 0.0f,
892 .maxDepth = 1.0f,
893 });
894
895 anv_CmdBindDescriptorSets(anv_cmd_buffer_to_handle(cmd_buffer),
896 VK_PIPELINE_BIND_POINT_GRAPHICS,
897 device->meta_state.blit.pipeline_layout, 0, 1,
898 &set, 0, NULL);
899
900 ANV_CALL(CmdDraw)(anv_cmd_buffer_to_handle(cmd_buffer), 3, 1, 0, 0);
901
902 ANV_CALL(CmdEndRenderPass)(anv_cmd_buffer_to_handle(cmd_buffer));
903
904 /* At the point where we emit the draw call, all data from the
905 * descriptor sets, etc. has been used. We are free to delete it.
906 */
907 anv_descriptor_set_destroy(device, anv_descriptor_set_from_handle(set));
908 anv_DestroyFramebuffer(anv_device_to_handle(device), fb);
909 anv_DestroyRenderPass(anv_device_to_handle(device), pass);
910 }
911
912 static void
913 meta_finish_blit(struct anv_cmd_buffer *cmd_buffer,
914 const struct anv_saved_state *saved_state)
915 {
916 anv_cmd_buffer_restore(cmd_buffer, saved_state);
917 }
918
919 static VkFormat
920 vk_format_for_cpp(int cpp)
921 {
922 switch (cpp) {
923 case 1: return VK_FORMAT_R8_UINT;
924 case 2: return VK_FORMAT_R8G8_UINT;
925 case 3: return VK_FORMAT_R8G8B8_UINT;
926 case 4: return VK_FORMAT_R8G8B8A8_UINT;
927 case 6: return VK_FORMAT_R16G16B16_UINT;
928 case 8: return VK_FORMAT_R16G16B16A16_UINT;
929 case 12: return VK_FORMAT_R32G32B32_UINT;
930 case 16: return VK_FORMAT_R32G32B32A32_UINT;
931 default:
932 unreachable("Invalid format cpp");
933 }
934 }
935
936 static void
937 do_buffer_copy(struct anv_cmd_buffer *cmd_buffer,
938 struct anv_bo *src, uint64_t src_offset,
939 struct anv_bo *dest, uint64_t dest_offset,
940 int width, int height, VkFormat copy_format)
941 {
942 VkDevice vk_device = anv_device_to_handle(cmd_buffer->device);
943
944 VkImageCreateInfo image_info = {
945 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
946 .imageType = VK_IMAGE_TYPE_2D,
947 .format = copy_format,
948 .extent = {
949 .width = width,
950 .height = height,
951 .depth = 1,
952 },
953 .mipLevels = 1,
954 .arraySize = 1,
955 .samples = 1,
956 .tiling = VK_IMAGE_TILING_LINEAR,
957 .usage = 0,
958 .flags = 0,
959 };
960
961 VkImage src_image;
962 image_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
963 anv_CreateImage(vk_device, &image_info, &src_image);
964
965 VkImage dest_image;
966 image_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
967 anv_CreateImage(vk_device, &image_info, &dest_image);
968
969 /* We could use a vk call to bind memory, but that would require
970 * creating a dummy memory object etc. so there's really no point.
971 */
972 anv_image_from_handle(src_image)->bo = src;
973 anv_image_from_handle(src_image)->offset = src_offset;
974 anv_image_from_handle(dest_image)->bo = dest;
975 anv_image_from_handle(dest_image)->offset = dest_offset;
976
977 struct anv_image_view src_iview;
978 anv_image_view_init(&src_iview, cmd_buffer->device,
979 &(VkImageViewCreateInfo) {
980 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
981 .image = src_image,
982 .viewType = VK_IMAGE_VIEW_TYPE_2D,
983 .format = copy_format,
984 .channels = {
985 VK_CHANNEL_SWIZZLE_R,
986 VK_CHANNEL_SWIZZLE_G,
987 VK_CHANNEL_SWIZZLE_B,
988 VK_CHANNEL_SWIZZLE_A
989 },
990 .subresourceRange = {
991 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
992 .baseMipLevel = 0,
993 .mipLevels = 1,
994 .baseArrayLayer = 0,
995 .arraySize = 1
996 },
997 },
998 cmd_buffer);
999
1000 struct anv_image_view dest_iview;
1001 anv_image_view_init(&dest_iview, cmd_buffer->device,
1002 &(VkImageViewCreateInfo) {
1003 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
1004 .image = dest_image,
1005 .viewType = VK_IMAGE_VIEW_TYPE_2D,
1006 .format = copy_format,
1007 .channels = {
1008 .r = VK_CHANNEL_SWIZZLE_R,
1009 .g = VK_CHANNEL_SWIZZLE_G,
1010 .b = VK_CHANNEL_SWIZZLE_B,
1011 .a = VK_CHANNEL_SWIZZLE_A,
1012 },
1013 .subresourceRange = {
1014 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
1015 .baseMipLevel = 0,
1016 .mipLevels = 1,
1017 .baseArrayLayer = 0,
1018 .arraySize = 1,
1019 },
1020 },
1021 cmd_buffer);
1022
1023 meta_emit_blit(cmd_buffer,
1024 anv_image_from_handle(src_image),
1025 &src_iview,
1026 (VkOffset3D) { 0, 0, 0 },
1027 (VkExtent3D) { width, height, 1 },
1028 anv_image_from_handle(dest_image),
1029 &dest_iview,
1030 (VkOffset3D) { 0, 0, 0 },
1031 (VkExtent3D) { width, height, 1 });
1032
1033 anv_DestroyImage(vk_device, src_image);
1034 anv_DestroyImage(vk_device, dest_image);
1035 }
1036
1037 void anv_CmdCopyBuffer(
1038 VkCmdBuffer cmdBuffer,
1039 VkBuffer srcBuffer,
1040 VkBuffer destBuffer,
1041 uint32_t regionCount,
1042 const VkBufferCopy* pRegions)
1043 {
1044 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
1045 ANV_FROM_HANDLE(anv_buffer, src_buffer, srcBuffer);
1046 ANV_FROM_HANDLE(anv_buffer, dest_buffer, destBuffer);
1047
1048 struct anv_saved_state saved_state;
1049
1050 meta_prepare_blit(cmd_buffer, &saved_state);
1051
1052 for (unsigned r = 0; r < regionCount; r++) {
1053 uint64_t src_offset = src_buffer->offset + pRegions[r].srcOffset;
1054 uint64_t dest_offset = dest_buffer->offset + pRegions[r].destOffset;
1055 uint64_t copy_size = pRegions[r].copySize;
1056
1057 /* First, we compute the biggest format that can be used with the
1058 * given offsets and size.
1059 */
1060 int cpp = 16;
1061
1062 int fs = ffs(src_offset) - 1;
1063 if (fs != -1)
1064 cpp = MIN2(cpp, 1 << fs);
1065 assert(src_offset % cpp == 0);
1066
1067 fs = ffs(dest_offset) - 1;
1068 if (fs != -1)
1069 cpp = MIN2(cpp, 1 << fs);
1070 assert(dest_offset % cpp == 0);
1071
1072 fs = ffs(pRegions[r].copySize) - 1;
1073 if (fs != -1)
1074 cpp = MIN2(cpp, 1 << fs);
1075 assert(pRegions[r].copySize % cpp == 0);
1076
1077 VkFormat copy_format = vk_format_for_cpp(cpp);
1078
1079 /* This is maximum possible width/height our HW can handle */
1080 uint64_t max_surface_dim = 1 << 14;
1081
1082 /* First, we make a bunch of max-sized copies */
1083 uint64_t max_copy_size = max_surface_dim * max_surface_dim * cpp;
1084 while (copy_size > max_copy_size) {
1085 do_buffer_copy(cmd_buffer, src_buffer->bo, src_offset,
1086 dest_buffer->bo, dest_offset,
1087 max_surface_dim, max_surface_dim, copy_format);
1088 copy_size -= max_copy_size;
1089 src_offset += max_copy_size;
1090 dest_offset += max_copy_size;
1091 }
1092
1093 uint64_t height = copy_size / (max_surface_dim * cpp);
1094 assert(height < max_surface_dim);
1095 if (height != 0) {
1096 uint64_t rect_copy_size = height * max_surface_dim * cpp;
1097 do_buffer_copy(cmd_buffer, src_buffer->bo, src_offset,
1098 dest_buffer->bo, dest_offset,
1099 max_surface_dim, height, copy_format);
1100 copy_size -= rect_copy_size;
1101 src_offset += rect_copy_size;
1102 dest_offset += rect_copy_size;
1103 }
1104
1105 if (copy_size != 0) {
1106 do_buffer_copy(cmd_buffer, src_buffer->bo, src_offset,
1107 dest_buffer->bo, dest_offset,
1108 copy_size / cpp, 1, copy_format);
1109 }
1110 }
1111
1112 meta_finish_blit(cmd_buffer, &saved_state);
1113 }
1114
1115 void anv_CmdCopyImage(
1116 VkCmdBuffer cmdBuffer,
1117 VkImage srcImage,
1118 VkImageLayout srcImageLayout,
1119 VkImage destImage,
1120 VkImageLayout destImageLayout,
1121 uint32_t regionCount,
1122 const VkImageCopy* pRegions)
1123 {
1124 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
1125 ANV_FROM_HANDLE(anv_image, src_image, srcImage);
1126 ANV_FROM_HANDLE(anv_image, dest_image, destImage);
1127
1128 const VkImageViewType src_iview_type =
1129 meta_blit_get_src_image_view_type(src_image);
1130
1131 struct anv_saved_state saved_state;
1132
1133 meta_prepare_blit(cmd_buffer, &saved_state);
1134
1135 for (unsigned r = 0; r < regionCount; r++) {
1136 struct anv_image_view src_iview;
1137 anv_image_view_init(&src_iview, cmd_buffer->device,
1138 &(VkImageViewCreateInfo) {
1139 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
1140 .image = srcImage,
1141 .viewType = src_iview_type,
1142 .format = src_image->format->vk_format,
1143 .channels = {
1144 VK_CHANNEL_SWIZZLE_R,
1145 VK_CHANNEL_SWIZZLE_G,
1146 VK_CHANNEL_SWIZZLE_B,
1147 VK_CHANNEL_SWIZZLE_A
1148 },
1149 .subresourceRange = {
1150 .aspectMask = 1 << pRegions[r].srcSubresource.aspect,
1151 .baseMipLevel = pRegions[r].srcSubresource.mipLevel,
1152 .mipLevels = 1,
1153 .baseArrayLayer = pRegions[r].srcSubresource.arrayLayer,
1154 .arraySize = 1
1155 },
1156 },
1157 cmd_buffer);
1158
1159 const VkOffset3D dest_offset = {
1160 .x = pRegions[r].destOffset.x,
1161 .y = pRegions[r].destOffset.y,
1162 .z = 0,
1163 };
1164
1165 const uint32_t dest_array_slice =
1166 meta_blit_get_dest_view_base_array_slice(dest_image,
1167 &pRegions[r].destSubresource,
1168 &pRegions[r].destOffset);
1169
1170 if (pRegions[r].srcSubresource.arraySize > 1)
1171 anv_finishme("FINISHME: copy multiple array layers");
1172
1173 if (pRegions[r].extent.depth > 1)
1174 anv_finishme("FINISHME: copy multiple depth layers");
1175
1176 struct anv_image_view dest_iview;
1177 anv_image_view_init(&dest_iview, cmd_buffer->device,
1178 &(VkImageViewCreateInfo) {
1179 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
1180 .image = destImage,
1181 .viewType = VK_IMAGE_VIEW_TYPE_2D,
1182 .format = dest_image->format->vk_format,
1183 .channels = {
1184 VK_CHANNEL_SWIZZLE_R,
1185 VK_CHANNEL_SWIZZLE_G,
1186 VK_CHANNEL_SWIZZLE_B,
1187 VK_CHANNEL_SWIZZLE_A
1188 },
1189 .subresourceRange = {
1190 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
1191 .baseMipLevel = pRegions[r].destSubresource.mipLevel,
1192 .mipLevels = 1,
1193 .baseArrayLayer = dest_array_slice,
1194 .arraySize = 1
1195 },
1196 },
1197 cmd_buffer);
1198
1199 meta_emit_blit(cmd_buffer,
1200 src_image, &src_iview,
1201 pRegions[r].srcOffset,
1202 pRegions[r].extent,
1203 dest_image, &dest_iview,
1204 dest_offset,
1205 pRegions[r].extent);
1206 }
1207
1208 meta_finish_blit(cmd_buffer, &saved_state);
1209 }
1210
1211 void anv_CmdBlitImage(
1212 VkCmdBuffer cmdBuffer,
1213 VkImage srcImage,
1214 VkImageLayout srcImageLayout,
1215 VkImage destImage,
1216 VkImageLayout destImageLayout,
1217 uint32_t regionCount,
1218 const VkImageBlit* pRegions,
1219 VkTexFilter filter)
1220
1221 {
1222 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
1223 ANV_FROM_HANDLE(anv_image, src_image, srcImage);
1224 ANV_FROM_HANDLE(anv_image, dest_image, destImage);
1225
1226 const VkImageViewType src_iview_type =
1227 meta_blit_get_src_image_view_type(src_image);
1228
1229 struct anv_saved_state saved_state;
1230
1231 anv_finishme("respect VkTexFilter");
1232
1233 meta_prepare_blit(cmd_buffer, &saved_state);
1234
1235 for (unsigned r = 0; r < regionCount; r++) {
1236 struct anv_image_view src_iview;
1237 anv_image_view_init(&src_iview, cmd_buffer->device,
1238 &(VkImageViewCreateInfo) {
1239 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
1240 .image = srcImage,
1241 .viewType = src_iview_type,
1242 .format = src_image->format->vk_format,
1243 .channels = {
1244 VK_CHANNEL_SWIZZLE_R,
1245 VK_CHANNEL_SWIZZLE_G,
1246 VK_CHANNEL_SWIZZLE_B,
1247 VK_CHANNEL_SWIZZLE_A
1248 },
1249 .subresourceRange = {
1250 .aspectMask = 1 << pRegions[r].srcSubresource.aspect,
1251 .baseMipLevel = pRegions[r].srcSubresource.mipLevel,
1252 .mipLevels = 1,
1253 .baseArrayLayer = pRegions[r].srcSubresource.arrayLayer,
1254 .arraySize = 1
1255 },
1256 },
1257 cmd_buffer);
1258
1259 const VkOffset3D dest_offset = {
1260 .x = pRegions[r].destOffset.x,
1261 .y = pRegions[r].destOffset.y,
1262 .z = 0,
1263 };
1264
1265 const uint32_t dest_array_slice =
1266 meta_blit_get_dest_view_base_array_slice(dest_image,
1267 &pRegions[r].destSubresource,
1268 &pRegions[r].destOffset);
1269
1270 if (pRegions[r].srcSubresource.arraySize > 1)
1271 anv_finishme("FINISHME: copy multiple array layers");
1272
1273 if (pRegions[r].destExtent.depth > 1)
1274 anv_finishme("FINISHME: copy multiple depth layers");
1275
1276 struct anv_image_view dest_iview;
1277 anv_image_view_init(&dest_iview, cmd_buffer->device,
1278 &(VkImageViewCreateInfo) {
1279 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
1280 .image = destImage,
1281 .viewType = VK_IMAGE_VIEW_TYPE_2D,
1282 .format = dest_image->format->vk_format,
1283 .channels = {
1284 VK_CHANNEL_SWIZZLE_R,
1285 VK_CHANNEL_SWIZZLE_G,
1286 VK_CHANNEL_SWIZZLE_B,
1287 VK_CHANNEL_SWIZZLE_A
1288 },
1289 .subresourceRange = {
1290 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
1291 .baseMipLevel = pRegions[r].destSubresource.mipLevel,
1292 .mipLevels = 1,
1293 .baseArrayLayer = dest_array_slice,
1294 .arraySize = 1
1295 },
1296 },
1297 cmd_buffer);
1298
1299 meta_emit_blit(cmd_buffer,
1300 src_image, &src_iview,
1301 pRegions[r].srcOffset,
1302 pRegions[r].srcExtent,
1303 dest_image, &dest_iview,
1304 dest_offset,
1305 pRegions[r].destExtent);
1306 }
1307
1308 meta_finish_blit(cmd_buffer, &saved_state);
1309 }
1310
1311 static VkImage
1312 make_image_for_buffer(VkDevice vk_device, VkBuffer vk_buffer, VkFormat format,
1313 VkImageUsageFlags usage,
1314 const VkBufferImageCopy *copy)
1315 {
1316 ANV_FROM_HANDLE(anv_buffer, buffer, vk_buffer);
1317
1318 VkExtent3D extent = copy->imageExtent;
1319 if (copy->bufferRowLength)
1320 extent.width = copy->bufferRowLength;
1321 if (copy->bufferImageHeight)
1322 extent.height = copy->bufferImageHeight;
1323 extent.depth = 1;
1324
1325 VkImage vk_image;
1326 VkResult result = anv_CreateImage(vk_device,
1327 &(VkImageCreateInfo) {
1328 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
1329 .imageType = VK_IMAGE_TYPE_2D,
1330 .format = format,
1331 .extent = extent,
1332 .mipLevels = 1,
1333 .arraySize = 1,
1334 .samples = 1,
1335 .tiling = VK_IMAGE_TILING_LINEAR,
1336 .usage = usage,
1337 .flags = 0,
1338 }, &vk_image);
1339 assert(result == VK_SUCCESS);
1340
1341 ANV_FROM_HANDLE(anv_image, image, vk_image);
1342
1343 /* We could use a vk call to bind memory, but that would require
1344 * creating a dummy memory object etc. so there's really no point.
1345 */
1346 image->bo = buffer->bo;
1347 image->offset = buffer->offset + copy->bufferOffset;
1348
1349 return anv_image_to_handle(image);
1350 }
1351
1352 void anv_CmdCopyBufferToImage(
1353 VkCmdBuffer cmdBuffer,
1354 VkBuffer srcBuffer,
1355 VkImage destImage,
1356 VkImageLayout destImageLayout,
1357 uint32_t regionCount,
1358 const VkBufferImageCopy* pRegions)
1359 {
1360 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
1361 ANV_FROM_HANDLE(anv_image, dest_image, destImage);
1362 VkDevice vk_device = anv_device_to_handle(cmd_buffer->device);
1363 const VkFormat orig_format = dest_image->format->vk_format;
1364 struct anv_saved_state saved_state;
1365
1366 meta_prepare_blit(cmd_buffer, &saved_state);
1367
1368 for (unsigned r = 0; r < regionCount; r++) {
1369 VkFormat proxy_format = orig_format;
1370 VkImageAspect proxy_aspect = pRegions[r].imageSubresource.aspect;
1371
1372 if (orig_format == VK_FORMAT_S8_UINT) {
1373 proxy_format = VK_FORMAT_R8_UINT;
1374 proxy_aspect = VK_IMAGE_ASPECT_COLOR;
1375 }
1376
1377 VkImage srcImage = make_image_for_buffer(vk_device, srcBuffer,
1378 proxy_format, VK_IMAGE_USAGE_SAMPLED_BIT, &pRegions[r]);
1379
1380 struct anv_image_view src_iview;
1381 anv_image_view_init(&src_iview, cmd_buffer->device,
1382 &(VkImageViewCreateInfo) {
1383 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
1384 .image = srcImage,
1385 .viewType = VK_IMAGE_VIEW_TYPE_2D,
1386 .format = proxy_format,
1387 .channels = {
1388 VK_CHANNEL_SWIZZLE_R,
1389 VK_CHANNEL_SWIZZLE_G,
1390 VK_CHANNEL_SWIZZLE_B,
1391 VK_CHANNEL_SWIZZLE_A
1392 },
1393 .subresourceRange = {
1394 .aspectMask = 1 << proxy_aspect,
1395 .baseMipLevel = 0,
1396 .mipLevels = 1,
1397 .baseArrayLayer = 0,
1398 .arraySize = 1
1399 },
1400 },
1401 cmd_buffer);
1402
1403 const VkOffset3D dest_offset = {
1404 .x = pRegions[r].imageOffset.x,
1405 .y = pRegions[r].imageOffset.y,
1406 .z = 0,
1407 };
1408
1409 const uint32_t dest_array_slice =
1410 meta_blit_get_dest_view_base_array_slice(dest_image,
1411 &pRegions[r].imageSubresource,
1412 &pRegions[r].imageOffset);
1413
1414 if (pRegions[r].imageExtent.depth > 1)
1415 anv_finishme("FINISHME: copy multiple depth layers");
1416
1417 struct anv_image_view dest_iview;
1418 anv_image_view_init(&dest_iview, cmd_buffer->device,
1419 &(VkImageViewCreateInfo) {
1420 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
1421 .image = anv_image_to_handle(dest_image),
1422 .viewType = VK_IMAGE_VIEW_TYPE_2D,
1423 .format = proxy_format,
1424 .channels = {
1425 VK_CHANNEL_SWIZZLE_R,
1426 VK_CHANNEL_SWIZZLE_G,
1427 VK_CHANNEL_SWIZZLE_B,
1428 VK_CHANNEL_SWIZZLE_A
1429 },
1430 .subresourceRange = {
1431 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
1432 .baseMipLevel = pRegions[r].imageSubresource.mipLevel,
1433 .mipLevels = 1,
1434 .baseArrayLayer = dest_array_slice,
1435 .arraySize = 1
1436 },
1437 },
1438 cmd_buffer);
1439
1440 meta_emit_blit(cmd_buffer,
1441 anv_image_from_handle(srcImage),
1442 &src_iview,
1443 (VkOffset3D) { 0, 0, 0 },
1444 pRegions[r].imageExtent,
1445 dest_image,
1446 &dest_iview,
1447 dest_offset,
1448 pRegions[r].imageExtent);
1449
1450 anv_DestroyImage(vk_device, srcImage);
1451 }
1452
1453 meta_finish_blit(cmd_buffer, &saved_state);
1454 }
1455
1456 void anv_CmdCopyImageToBuffer(
1457 VkCmdBuffer cmdBuffer,
1458 VkImage srcImage,
1459 VkImageLayout srcImageLayout,
1460 VkBuffer destBuffer,
1461 uint32_t regionCount,
1462 const VkBufferImageCopy* pRegions)
1463 {
1464 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
1465 ANV_FROM_HANDLE(anv_image, src_image, srcImage);
1466 VkDevice vk_device = anv_device_to_handle(cmd_buffer->device);
1467 struct anv_saved_state saved_state;
1468
1469 const VkImageViewType src_iview_type =
1470 meta_blit_get_src_image_view_type(src_image);
1471
1472 meta_prepare_blit(cmd_buffer, &saved_state);
1473
1474 for (unsigned r = 0; r < regionCount; r++) {
1475 if (pRegions[r].imageSubresource.arraySize > 1)
1476 anv_finishme("FINISHME: copy multiple array layers");
1477
1478 if (pRegions[r].imageExtent.depth > 1)
1479 anv_finishme("FINISHME: copy multiple depth layers");
1480
1481 struct anv_image_view src_iview;
1482 anv_image_view_init(&src_iview, cmd_buffer->device,
1483 &(VkImageViewCreateInfo) {
1484 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
1485 .image = srcImage,
1486 .viewType = src_iview_type,
1487 .format = src_image->format->vk_format,
1488 .channels = {
1489 VK_CHANNEL_SWIZZLE_R,
1490 VK_CHANNEL_SWIZZLE_G,
1491 VK_CHANNEL_SWIZZLE_B,
1492 VK_CHANNEL_SWIZZLE_A
1493 },
1494 .subresourceRange = {
1495 .aspectMask = 1 << pRegions[r].imageSubresource.aspect,
1496 .baseMipLevel = pRegions[r].imageSubresource.mipLevel,
1497 .mipLevels = 1,
1498 .baseArrayLayer = pRegions[r].imageSubresource.arrayLayer,
1499 .arraySize = 1
1500 },
1501 },
1502 cmd_buffer);
1503
1504 VkFormat dest_format = src_image->format->vk_format;
1505 if (dest_format == VK_FORMAT_S8_UINT) {
1506 dest_format = VK_FORMAT_R8_UINT;
1507 }
1508
1509 VkImage destImage = make_image_for_buffer(vk_device, destBuffer,
1510 dest_format, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, &pRegions[r]);
1511
1512 struct anv_image_view dest_iview;
1513 anv_image_view_init(&dest_iview, cmd_buffer->device,
1514 &(VkImageViewCreateInfo) {
1515 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
1516 .image = destImage,
1517 .viewType = VK_IMAGE_VIEW_TYPE_2D,
1518 .format = dest_format,
1519 .channels = {
1520 VK_CHANNEL_SWIZZLE_R,
1521 VK_CHANNEL_SWIZZLE_G,
1522 VK_CHANNEL_SWIZZLE_B,
1523 VK_CHANNEL_SWIZZLE_A
1524 },
1525 .subresourceRange = {
1526 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
1527 .baseMipLevel = 0,
1528 .mipLevels = 1,
1529 .baseArrayLayer = 0,
1530 .arraySize = 1
1531 },
1532 },
1533 cmd_buffer);
1534
1535 meta_emit_blit(cmd_buffer,
1536 anv_image_from_handle(srcImage),
1537 &src_iview,
1538 pRegions[r].imageOffset,
1539 pRegions[r].imageExtent,
1540 anv_image_from_handle(destImage),
1541 &dest_iview,
1542 (VkOffset3D) { 0, 0, 0 },
1543 pRegions[r].imageExtent);
1544
1545 anv_DestroyImage(vk_device, destImage);
1546 }
1547
1548 meta_finish_blit(cmd_buffer, &saved_state);
1549 }
1550
1551 void anv_CmdUpdateBuffer(
1552 VkCmdBuffer cmdBuffer,
1553 VkBuffer destBuffer,
1554 VkDeviceSize destOffset,
1555 VkDeviceSize dataSize,
1556 const uint32_t* pData)
1557 {
1558 stub();
1559 }
1560
1561 void anv_CmdFillBuffer(
1562 VkCmdBuffer cmdBuffer,
1563 VkBuffer destBuffer,
1564 VkDeviceSize destOffset,
1565 VkDeviceSize fillSize,
1566 uint32_t data)
1567 {
1568 stub();
1569 }
1570
1571 void anv_CmdClearColorImage(
1572 VkCmdBuffer cmdBuffer,
1573 VkImage _image,
1574 VkImageLayout imageLayout,
1575 const VkClearColorValue* pColor,
1576 uint32_t rangeCount,
1577 const VkImageSubresourceRange* pRanges)
1578 {
1579 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
1580 ANV_FROM_HANDLE(anv_image, image, _image);
1581 struct anv_saved_state saved_state;
1582
1583 anv_cmd_buffer_save(cmd_buffer, &saved_state,
1584 (1 << VK_DYNAMIC_STATE_VIEWPORT));
1585 cmd_buffer->state.dynamic.viewport.count = 0;
1586
1587 for (uint32_t r = 0; r < rangeCount; r++) {
1588 for (uint32_t l = 0; l < pRanges[r].mipLevels; l++) {
1589 for (uint32_t s = 0; s < pRanges[r].arraySize; s++) {
1590 struct anv_image_view iview;
1591 anv_image_view_init(&iview, cmd_buffer->device,
1592 &(VkImageViewCreateInfo) {
1593 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
1594 .image = _image,
1595 .viewType = VK_IMAGE_VIEW_TYPE_2D,
1596 .format = image->format->vk_format,
1597 .channels = {
1598 VK_CHANNEL_SWIZZLE_R,
1599 VK_CHANNEL_SWIZZLE_G,
1600 VK_CHANNEL_SWIZZLE_B,
1601 VK_CHANNEL_SWIZZLE_A
1602 },
1603 .subresourceRange = {
1604 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
1605 .baseMipLevel = pRanges[r].baseMipLevel + l,
1606 .mipLevels = 1,
1607 .baseArrayLayer = pRanges[r].baseArrayLayer + s,
1608 .arraySize = 1
1609 },
1610 },
1611 cmd_buffer);
1612
1613 VkFramebuffer fb;
1614 anv_CreateFramebuffer(anv_device_to_handle(cmd_buffer->device),
1615 &(VkFramebufferCreateInfo) {
1616 .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
1617 .attachmentCount = 1,
1618 .pAttachments = (VkImageView[]) {
1619 anv_image_view_to_handle(&iview),
1620 },
1621 .width = iview.extent.width,
1622 .height = iview.extent.height,
1623 .layers = 1
1624 }, &fb);
1625
1626 VkRenderPass pass;
1627 anv_CreateRenderPass(anv_device_to_handle(cmd_buffer->device),
1628 &(VkRenderPassCreateInfo) {
1629 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
1630 .attachmentCount = 1,
1631 .pAttachments = &(VkAttachmentDescription) {
1632 .sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION,
1633 .format = iview.format->vk_format,
1634 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
1635 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
1636 .initialLayout = VK_IMAGE_LAYOUT_GENERAL,
1637 .finalLayout = VK_IMAGE_LAYOUT_GENERAL,
1638 },
1639 .subpassCount = 1,
1640 .pSubpasses = &(VkSubpassDescription) {
1641 .sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION,
1642 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
1643 .inputCount = 0,
1644 .colorCount = 1,
1645 .pColorAttachments = &(VkAttachmentReference) {
1646 .attachment = 0,
1647 .layout = VK_IMAGE_LAYOUT_GENERAL,
1648 },
1649 .pResolveAttachments = NULL,
1650 .depthStencilAttachment = (VkAttachmentReference) {
1651 .attachment = VK_ATTACHMENT_UNUSED,
1652 .layout = VK_IMAGE_LAYOUT_GENERAL,
1653 },
1654 .preserveCount = 1,
1655 .pPreserveAttachments = &(VkAttachmentReference) {
1656 .attachment = 0,
1657 .layout = VK_IMAGE_LAYOUT_GENERAL,
1658 },
1659 },
1660 .dependencyCount = 0,
1661 }, &pass);
1662
1663 ANV_CALL(CmdBeginRenderPass)(anv_cmd_buffer_to_handle(cmd_buffer),
1664 &(VkRenderPassBeginInfo) {
1665 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
1666 .renderArea = {
1667 .offset = { 0, 0, },
1668 .extent = {
1669 .width = iview.extent.width,
1670 .height = iview.extent.height,
1671 },
1672 },
1673 .renderPass = pass,
1674 .framebuffer = fb,
1675 .clearValueCount = 1,
1676 .pClearValues = NULL,
1677 }, VK_RENDER_PASS_CONTENTS_INLINE);
1678
1679 struct clear_instance_data instance_data = {
1680 .vue_header = {
1681 .RTAIndex = 0,
1682 .ViewportIndex = 0,
1683 .PointWidth = 0.0
1684 },
1685 .color = *pColor,
1686 };
1687
1688 meta_emit_clear(cmd_buffer, 1, &instance_data,
1689 (VkClearDepthStencilValue) {0});
1690
1691 ANV_CALL(CmdEndRenderPass)(anv_cmd_buffer_to_handle(cmd_buffer));
1692 }
1693 }
1694 }
1695
1696 /* Restore API state */
1697 anv_cmd_buffer_restore(cmd_buffer, &saved_state);
1698 }
1699
1700 void anv_CmdClearDepthStencilImage(
1701 VkCmdBuffer cmdBuffer,
1702 VkImage image,
1703 VkImageLayout imageLayout,
1704 const VkClearDepthStencilValue* pDepthStencil,
1705 uint32_t rangeCount,
1706 const VkImageSubresourceRange* pRanges)
1707 {
1708 stub();
1709 }
1710
1711 void anv_CmdClearColorAttachment(
1712 VkCmdBuffer cmdBuffer,
1713 uint32_t colorAttachment,
1714 VkImageLayout imageLayout,
1715 const VkClearColorValue* pColor,
1716 uint32_t rectCount,
1717 const VkRect3D* pRects)
1718 {
1719 stub();
1720 }
1721
1722 void anv_CmdClearDepthStencilAttachment(
1723 VkCmdBuffer cmdBuffer,
1724 VkImageAspectFlags aspectMask,
1725 VkImageLayout imageLayout,
1726 const VkClearDepthStencilValue* pDepthStencil,
1727 uint32_t rectCount,
1728 const VkRect3D* pRects)
1729 {
1730 stub();
1731 }
1732
1733 void anv_CmdResolveImage(
1734 VkCmdBuffer cmdBuffer,
1735 VkImage srcImage,
1736 VkImageLayout srcImageLayout,
1737 VkImage destImage,
1738 VkImageLayout destImageLayout,
1739 uint32_t regionCount,
1740 const VkImageResolve* pRegions)
1741 {
1742 stub();
1743 }
1744
1745 void
1746 anv_device_init_meta(struct anv_device *device)
1747 {
1748 anv_device_init_meta_clear_state(device);
1749 anv_device_init_meta_blit_state(device);
1750 }
1751
1752 void
1753 anv_device_finish_meta(struct anv_device *device)
1754 {
1755 /* Clear */
1756 anv_DestroyPipeline(anv_device_to_handle(device),
1757 device->meta_state.clear.pipeline);
1758
1759 /* Blit */
1760 anv_DestroyPipeline(anv_device_to_handle(device),
1761 device->meta_state.blit.pipeline_2d_src);
1762 anv_DestroyPipeline(anv_device_to_handle(device),
1763 device->meta_state.blit.pipeline_3d_src);
1764 anv_DestroyPipelineLayout(anv_device_to_handle(device),
1765 device->meta_state.blit.pipeline_layout);
1766 anv_DestroyDescriptorSetLayout(anv_device_to_handle(device),
1767 device->meta_state.blit.ds_layout);
1768 }