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