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