vk: Make cmd_buffer->bindings a pointer
[mesa.git] / src / vulkan / 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 "private.h"
31 #include "glsl_helpers.h"
32
33 static void
34 anv_device_init_meta_clear_state(struct anv_device *device)
35 {
36 VkPipelineIaStateCreateInfo ia_create_info = {
37 .sType = VK_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO,
38 .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
39 .disableVertexReuse = false,
40 .primitiveRestartEnable = false,
41 .primitiveRestartIndex = 0
42 };
43
44 /* We don't use a vertex shader for clearing, but instead build and pass
45 * the VUEs directly to the rasterization backend.
46 */
47 VkShader fs = GLSL_VK_SHADER(device, FRAGMENT,
48 out vec4 f_color;
49 flat in vec4 v_color;
50 void main()
51 {
52 f_color = v_color;
53 }
54 );
55
56 VkPipelineShaderStageCreateInfo fs_create_info = {
57 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
58 .pNext = &ia_create_info,
59 .shader = {
60 .stage = VK_SHADER_STAGE_FRAGMENT,
61 .shader = fs,
62 .linkConstBufferCount = 0,
63 .pLinkConstBufferInfo = NULL,
64 .pSpecializationInfo = NULL
65 }
66 };
67
68 /* We use instanced rendering to clear multiple render targets. We have two
69 * vertex buffers: the first vertex buffer holds per-vertex data and
70 * provides the vertices for the clear rectangle. The second one holds
71 * per-instance data, which consists of the VUE header (which selects the
72 * layer) and the color (Vulkan supports per-RT clear colors).
73 */
74 VkPipelineVertexInputCreateInfo vi_create_info = {
75 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO,
76 .pNext = &fs_create_info,
77 .bindingCount = 2,
78 .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) {
79 {
80 .binding = 0,
81 .strideInBytes = 8,
82 .stepRate = VK_VERTEX_INPUT_STEP_RATE_VERTEX
83 },
84 {
85 .binding = 1,
86 .strideInBytes = 32,
87 .stepRate = VK_VERTEX_INPUT_STEP_RATE_INSTANCE
88 },
89 },
90 .attributeCount = 3,
91 .pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[]) {
92 {
93 /* VUE Header */
94 .location = 0,
95 .binding = 1,
96 .format = VK_FORMAT_R32G32B32A32_UINT,
97 .offsetInBytes = 0
98 },
99 {
100 /* Position */
101 .location = 1,
102 .binding = 0,
103 .format = VK_FORMAT_R32G32_SFLOAT,
104 .offsetInBytes = 0
105 },
106 {
107 /* Color */
108 .location = 2,
109 .binding = 1,
110 .format = VK_FORMAT_R32G32B32A32_SFLOAT,
111 .offsetInBytes = 16
112 }
113 }
114 };
115
116 VkPipelineRsStateCreateInfo rs_create_info = {
117 .sType = VK_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO,
118 .pNext = &vi_create_info,
119 .depthClipEnable = true,
120 .rasterizerDiscardEnable = false,
121 .fillMode = VK_FILL_MODE_SOLID,
122 .cullMode = VK_CULL_MODE_NONE,
123 .frontFace = VK_FRONT_FACE_CCW
124 };
125
126 anv_pipeline_create((VkDevice) device,
127 &(VkGraphicsPipelineCreateInfo) {
128 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
129 .pNext = &rs_create_info,
130 .flags = 0,
131 .layout = 0
132 },
133 &(struct anv_pipeline_create_info) {
134 .use_repclear = true,
135 .disable_viewport = true,
136 .use_rectlist = true
137 },
138 &device->clear_state.pipeline);
139
140 vkDestroyObject((VkDevice) device, VK_OBJECT_TYPE_SHADER, fs);
141
142 vkCreateDynamicRasterState((VkDevice) device,
143 &(VkDynamicRsStateCreateInfo) {
144 .sType = VK_STRUCTURE_TYPE_DYNAMIC_RS_STATE_CREATE_INFO,
145 },
146 &device->clear_state.rs_state);
147 }
148
149 #define NUM_VB_USED 2
150 struct anv_saved_state {
151 struct anv_bindings bindings;
152 struct anv_pipeline *pipeline;
153 };
154
155 static void
156 anv_cmd_buffer_save(struct anv_cmd_buffer *cmd_buffer,
157 struct anv_saved_state *state)
158 {
159 cmd_buffer->bindings = &state->bindings;
160 state->pipeline = cmd_buffer->pipeline;
161
162 /* Initialize render targets for the meta bindings. */
163 anv_cmd_buffer_fill_render_targets(cmd_buffer);
164 }
165
166 static void
167 anv_cmd_buffer_restore(struct anv_cmd_buffer *cmd_buffer,
168 const struct anv_saved_state *state)
169 {
170 cmd_buffer->bindings = &cmd_buffer->default_bindings;
171 cmd_buffer->pipeline = state->pipeline;
172
173 cmd_buffer->vb_dirty |= (1 << NUM_VB_USED) - 1;
174 cmd_buffer->dirty |= ANV_CMD_BUFFER_PIPELINE_DIRTY |
175 ANV_CMD_BUFFER_DESCRIPTOR_SET_DIRTY;
176 }
177
178 struct vue_header {
179 uint32_t Reserved;
180 uint32_t RTAIndex;
181 uint32_t ViewportIndex;
182 float PointWidth;
183 };
184
185 void
186 anv_cmd_buffer_clear(struct anv_cmd_buffer *cmd_buffer,
187 struct anv_render_pass *pass)
188 {
189 struct anv_device *device = cmd_buffer->device;
190 struct anv_framebuffer *fb = cmd_buffer->framebuffer;
191 struct anv_saved_state saved_state;
192 struct anv_state state;
193 uint32_t size;
194
195 struct instance_data {
196 struct vue_header vue_header;
197 float color[4];
198 } *instance_data;
199
200 const float vertex_data[] = {
201 /* Rect-list coordinates */
202 0.0, 0.0,
203 fb->width, 0.0,
204 fb->width, fb->height,
205
206 /* Align to 16 bytes */
207 0.0, 0.0,
208 };
209
210 size = sizeof(vertex_data) + pass->num_clear_layers * sizeof(instance_data[0]);
211 state = anv_state_stream_alloc(&cmd_buffer->surface_state_stream, size, 16);
212
213 memcpy(state.map, vertex_data, sizeof(vertex_data));
214 instance_data = state.map + sizeof(vertex_data);
215
216 for (uint32_t i = 0; i < pass->num_layers; i++) {
217 if (pass->layers[i].color_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
218 *instance_data++ = (struct instance_data) {
219 .vue_header = {
220 .RTAIndex = i,
221 .ViewportIndex = 0,
222 .PointWidth = 0.0
223 },
224 .color = {
225 pass->layers[i].clear_color.color.floatColor[0],
226 pass->layers[i].clear_color.color.floatColor[1],
227 pass->layers[i].clear_color.color.floatColor[2],
228 pass->layers[i].clear_color.color.floatColor[3],
229 }
230 };
231 }
232 }
233
234 struct anv_buffer vertex_buffer = {
235 .device = cmd_buffer->device,
236 .size = size,
237 .bo = &device->surface_state_block_pool.bo,
238 .offset = state.offset
239 };
240
241 anv_cmd_buffer_save(cmd_buffer, &saved_state);
242
243 vkCmdBindVertexBuffers((VkCmdBuffer) cmd_buffer, 0, 2,
244 (VkBuffer[]) {
245 (VkBuffer) &vertex_buffer,
246 (VkBuffer) &vertex_buffer
247 },
248 (VkDeviceSize[]) {
249 0,
250 sizeof(vertex_data)
251 });
252
253 if ((VkPipeline) cmd_buffer->pipeline != device->clear_state.pipeline)
254 vkCmdBindPipeline((VkCmdBuffer) cmd_buffer,
255 VK_PIPELINE_BIND_POINT_GRAPHICS, device->clear_state.pipeline);
256
257 /* We don't need anything here, only set if not already set. */
258 if (cmd_buffer->rs_state == NULL)
259 vkCmdBindDynamicStateObject((VkCmdBuffer) cmd_buffer,
260 VK_STATE_BIND_POINT_RASTER,
261 device->clear_state.rs_state);
262
263 if (cmd_buffer->vp_state == NULL)
264 vkCmdBindDynamicStateObject((VkCmdBuffer) cmd_buffer,
265 VK_STATE_BIND_POINT_VIEWPORT,
266 cmd_buffer->framebuffer->vp_state);
267
268 vkCmdDraw((VkCmdBuffer) cmd_buffer, 0, 3, 0, pass->num_clear_layers);
269
270 /* Restore API state */
271 anv_cmd_buffer_restore(cmd_buffer, &saved_state);
272
273 }
274
275 static void
276 anv_device_init_meta_blit_state(struct anv_device *device)
277 {
278 VkPipelineIaStateCreateInfo ia_create_info = {
279 .sType = VK_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO,
280 .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
281 .disableVertexReuse = false,
282 .primitiveRestartEnable = false,
283 .primitiveRestartIndex = 0
284 };
285
286 /* We don't use a vertex shader for clearing, but instead build and pass
287 * the VUEs directly to the rasterization backend. However, we do need
288 * to provide GLSL source for the vertex shader so that the compiler
289 * does not dead-code our inputs.
290 */
291 VkShader vs = GLSL_VK_SHADER(device, VERTEX,
292 in vec2 a_pos;
293 in vec2 a_tex_coord;
294 out vec4 v_tex_coord;
295 void main()
296 {
297 v_tex_coord = vec4(a_tex_coord, 0, 1);
298 gl_Position = vec4(a_pos, 0, 1);
299 }
300 );
301
302 VkShader fs = GLSL_VK_SHADER(device, FRAGMENT,
303 out vec4 f_color;
304 in vec4 v_tex_coord;
305 layout(set = 0, index = 0) uniform sampler2D u_tex;
306 void main()
307 {
308 f_color = texture2D(u_tex, v_tex_coord.xy);
309 }
310 );
311
312 VkPipelineShaderStageCreateInfo vs_create_info = {
313 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
314 .pNext = &ia_create_info,
315 .shader = {
316 .stage = VK_SHADER_STAGE_VERTEX,
317 .shader = vs,
318 .linkConstBufferCount = 0,
319 .pLinkConstBufferInfo = NULL,
320 .pSpecializationInfo = NULL
321 }
322 };
323
324 VkPipelineShaderStageCreateInfo fs_create_info = {
325 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
326 .pNext = &vs_create_info,
327 .shader = {
328 .stage = VK_SHADER_STAGE_FRAGMENT,
329 .shader = fs,
330 .linkConstBufferCount = 0,
331 .pLinkConstBufferInfo = NULL,
332 .pSpecializationInfo = NULL
333 }
334 };
335
336 VkPipelineVertexInputCreateInfo vi_create_info = {
337 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO,
338 .pNext = &fs_create_info,
339 .bindingCount = 2,
340 .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) {
341 {
342 .binding = 0,
343 .strideInBytes = 0,
344 .stepRate = VK_VERTEX_INPUT_STEP_RATE_VERTEX
345 },
346 {
347 .binding = 1,
348 .strideInBytes = 16,
349 .stepRate = VK_VERTEX_INPUT_STEP_RATE_VERTEX
350 },
351 },
352 .attributeCount = 3,
353 .pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[]) {
354 {
355 /* VUE Header */
356 .location = 0,
357 .binding = 0,
358 .format = VK_FORMAT_R32G32B32A32_UINT,
359 .offsetInBytes = 0
360 },
361 {
362 /* Position */
363 .location = 1,
364 .binding = 1,
365 .format = VK_FORMAT_R32G32_SFLOAT,
366 .offsetInBytes = 0
367 },
368 {
369 /* Texture Coordinate */
370 .location = 2,
371 .binding = 1,
372 .format = VK_FORMAT_R32G32_SFLOAT,
373 .offsetInBytes = 8
374 }
375 }
376 };
377
378 VkDescriptorSetLayoutCreateInfo ds_layout_info = {
379 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
380 .count = 1,
381 .pBinding = (VkDescriptorSetLayoutBinding[]) {
382 {
383 .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
384 .count = 1,
385 .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
386 .pImmutableSamplers = NULL
387 },
388 }
389 };
390 vkCreateDescriptorSetLayout((VkDevice) device, &ds_layout_info,
391 &device->blit_state.ds_layout);
392
393 VkPipelineLayoutCreateInfo pipeline_layout_info = {
394 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
395 .descriptorSetCount = 1,
396 .pSetLayouts = &device->blit_state.ds_layout,
397 };
398
399 VkPipelineLayout pipeline_layout;
400 vkCreatePipelineLayout((VkDevice) device, &pipeline_layout_info,
401 &pipeline_layout);
402
403 VkPipelineRsStateCreateInfo rs_create_info = {
404 .sType = VK_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO,
405 .pNext = &vi_create_info,
406 .depthClipEnable = true,
407 .rasterizerDiscardEnable = false,
408 .fillMode = VK_FILL_MODE_SOLID,
409 .cullMode = VK_CULL_MODE_NONE,
410 .frontFace = VK_FRONT_FACE_CCW
411 };
412
413 VkGraphicsPipelineCreateInfo pipeline_info = {
414 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
415 .pNext = &rs_create_info,
416 .flags = 0,
417 .layout = pipeline_layout,
418 };
419
420 anv_pipeline_create((VkDevice) device, &pipeline_info,
421 &(struct anv_pipeline_create_info) {
422 .use_repclear = false,
423 .disable_viewport = true,
424 .disable_scissor = true,
425 .disable_vs = true,
426 .use_rectlist = true
427 },
428 &device->blit_state.pipeline);
429
430 vkDestroyObject((VkDevice) device, VK_OBJECT_TYPE_SHADER, vs);
431 vkDestroyObject((VkDevice) device, VK_OBJECT_TYPE_SHADER, fs);
432
433 vkCreateDynamicRasterState((VkDevice) device,
434 &(VkDynamicRsStateCreateInfo) {
435 .sType = VK_STRUCTURE_TYPE_DYNAMIC_RS_STATE_CREATE_INFO,
436 },
437 &device->blit_state.rs_state);
438 }
439
440 static void
441 meta_prepare_blit(struct anv_cmd_buffer *cmd_buffer,
442 struct anv_saved_state *saved_state)
443 {
444 struct anv_device *device = cmd_buffer->device;
445
446 anv_cmd_buffer_save(cmd_buffer, saved_state);
447
448 if ((VkPipeline) cmd_buffer->pipeline != device->blit_state.pipeline)
449 vkCmdBindPipeline((VkCmdBuffer) cmd_buffer,
450 VK_PIPELINE_BIND_POINT_GRAPHICS,
451 device->blit_state.pipeline);
452
453 /* We don't need anything here, only set if not already set. */
454 if (cmd_buffer->rs_state == NULL)
455 vkCmdBindDynamicStateObject((VkCmdBuffer) cmd_buffer,
456 VK_STATE_BIND_POINT_RASTER,
457 device->blit_state.rs_state);
458 }
459
460 struct blit_region {
461 VkOffset3D src_offset;
462 VkExtent3D src_extent;
463 VkOffset3D dest_offset;
464 VkExtent3D dest_extent;
465 };
466
467 static void
468 meta_emit_blit(struct anv_cmd_buffer *cmd_buffer,
469 struct anv_surface_view *src,
470 VkOffset3D src_offset,
471 VkExtent3D src_extent,
472 struct anv_surface_view *dest,
473 VkOffset3D dest_offset,
474 VkExtent3D dest_extent)
475 {
476 struct anv_device *device = cmd_buffer->device;
477
478 struct blit_vb_data {
479 float pos[2];
480 float tex_coord[2];
481 } *vb_data;
482
483 unsigned vb_size = sizeof(struct vue_header) + 3 * sizeof(*vb_data);
484
485 struct anv_state vb_state =
486 anv_state_stream_alloc(&cmd_buffer->surface_state_stream, vb_size, 16);
487 memset(vb_state.map, 0, sizeof(struct vue_header));
488 vb_data = vb_state.map + sizeof(struct vue_header);
489
490 vb_data[0] = (struct blit_vb_data) {
491 .pos = {
492 dest_offset.x + dest_extent.width,
493 dest_offset.y + dest_extent.height,
494 },
495 .tex_coord = {
496 (float)(src_offset.x + src_extent.width) / (float)src->extent.width,
497 (float)(src_offset.y + src_extent.height) / (float)src->extent.height,
498 },
499 };
500
501 vb_data[1] = (struct blit_vb_data) {
502 .pos = {
503 dest_offset.x,
504 dest_offset.y + dest_extent.height,
505 },
506 .tex_coord = {
507 (float)src_offset.x / (float)src->extent.width,
508 (float)(src_offset.y + src_extent.height) / (float)src->extent.height,
509 },
510 };
511
512 vb_data[2] = (struct blit_vb_data) {
513 .pos = {
514 dest_offset.x,
515 dest_offset.y,
516 },
517 .tex_coord = {
518 (float)src_offset.x / (float)src->extent.width,
519 (float)src_offset.y / (float)src->extent.height,
520 },
521 };
522
523 struct anv_buffer vertex_buffer = {
524 .device = device,
525 .size = vb_size,
526 .bo = &device->surface_state_block_pool.bo,
527 .offset = vb_state.offset,
528 };
529
530 vkCmdBindVertexBuffers((VkCmdBuffer) cmd_buffer, 0, 2,
531 (VkBuffer[]) {
532 (VkBuffer) &vertex_buffer,
533 (VkBuffer) &vertex_buffer
534 },
535 (VkDeviceSize[]) {
536 0,
537 sizeof(struct vue_header),
538 });
539
540 uint32_t count;
541 VkDescriptorSet set;
542 vkAllocDescriptorSets((VkDevice) device, 0 /* pool */,
543 VK_DESCRIPTOR_SET_USAGE_ONE_SHOT,
544 1, &device->blit_state.ds_layout, &set, &count);
545 vkUpdateDescriptors((VkDevice) device, set, 1,
546 (const void * []) {
547 &(VkUpdateImages) {
548 .sType = VK_STRUCTURE_TYPE_UPDATE_IMAGES,
549 .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
550 .binding = 0,
551 .count = 1,
552 .pImageViews = (VkImageViewAttachInfo[]) {
553 {
554 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_ATTACH_INFO,
555 .view = (VkImageView) src,
556 .layout = VK_IMAGE_LAYOUT_GENERAL,
557 }
558 }
559 }
560 });
561
562 VkFramebufferCreateInfo fb_info = {
563 .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
564 .colorAttachmentCount = 1,
565 .pColorAttachments = (VkColorAttachmentBindInfo[]) {
566 {
567 .view = (VkColorAttachmentView) dest,
568 .layout = VK_IMAGE_LAYOUT_GENERAL
569 }
570 },
571 .pDepthStencilAttachment = NULL,
572 .sampleCount = 1,
573 .width = dest->extent.width,
574 .height = dest->extent.height,
575 .layers = 1
576 };
577
578 struct anv_framebuffer *fb;
579 vkCreateFramebuffer((VkDevice) device, &fb_info, (VkFramebuffer *)&fb);
580
581 VkRenderPassCreateInfo pass_info = {
582 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
583 .renderArea = { { 0, 0 }, { dest->extent.width, dest->extent.height } },
584 .colorAttachmentCount = 1,
585 .extent = { 0, },
586 .sampleCount = 1,
587 .layers = 1,
588 .pColorFormats = (VkFormat[]) { dest->format },
589 .pColorLayouts = (VkImageLayout[]) { VK_IMAGE_LAYOUT_GENERAL },
590 .pColorLoadOps = (VkAttachmentLoadOp[]) { VK_ATTACHMENT_LOAD_OP_LOAD },
591 .pColorStoreOps = (VkAttachmentStoreOp[]) { VK_ATTACHMENT_STORE_OP_STORE },
592 .pColorLoadClearValues = (VkClearColor[]) {
593 { .color = { .floatColor = { 1.0, 0.0, 0.0, 1.0 } }, .useRawValue = false }
594 },
595 .depthStencilFormat = VK_FORMAT_UNDEFINED,
596 };
597
598 VkRenderPass pass;
599 vkCreateRenderPass((VkDevice )device, &pass_info, &pass);
600
601 vkCmdBeginRenderPass((VkCmdBuffer) cmd_buffer,
602 &(VkRenderPassBegin) {
603 .renderPass = pass,
604 .framebuffer = (VkFramebuffer) fb,
605 });
606
607 vkCmdBindDynamicStateObject((VkCmdBuffer) cmd_buffer,
608 VK_STATE_BIND_POINT_VIEWPORT, fb->vp_state);
609
610 vkCmdBindDescriptorSets((VkCmdBuffer) cmd_buffer,
611 VK_PIPELINE_BIND_POINT_GRAPHICS, 0, 1,
612 &set, 0, NULL);
613
614 vkCmdDraw((VkCmdBuffer) cmd_buffer, 0, 3, 0, 1);
615
616 vkCmdEndRenderPass((VkCmdBuffer) cmd_buffer, pass);
617 }
618
619 static void
620 meta_finish_blit(struct anv_cmd_buffer *cmd_buffer,
621 const struct anv_saved_state *saved_state)
622 {
623 anv_cmd_buffer_restore(cmd_buffer, saved_state);
624 }
625
626 void VKAPI vkCmdCopyBuffer(
627 VkCmdBuffer cmdBuffer,
628 VkBuffer srcBuffer,
629 VkBuffer destBuffer,
630 uint32_t regionCount,
631 const VkBufferCopy* pRegions)
632 {
633 stub();
634 }
635
636 void VKAPI vkCmdCopyImage(
637 VkCmdBuffer cmdBuffer,
638 VkImage srcImage,
639 VkImageLayout srcImageLayout,
640 VkImage destImage,
641 VkImageLayout destImageLayout,
642 uint32_t regionCount,
643 const VkImageCopy* pRegions)
644 {
645 stub();
646 }
647
648 void VKAPI vkCmdBlitImage(
649 VkCmdBuffer cmdBuffer,
650 VkImage srcImage,
651 VkImageLayout srcImageLayout,
652 VkImage destImage,
653 VkImageLayout destImageLayout,
654 uint32_t regionCount,
655 const VkImageBlit* pRegions)
656 {
657 stub();
658 }
659
660 void VKAPI vkCmdCopyBufferToImage(
661 VkCmdBuffer cmdBuffer,
662 VkBuffer srcBuffer,
663 VkImage destImage,
664 VkImageLayout destImageLayout,
665 uint32_t regionCount,
666 const VkBufferImageCopy* pRegions)
667 {
668 stub();
669 }
670
671 void VKAPI vkCmdCopyImageToBuffer(
672 VkCmdBuffer cmdBuffer,
673 VkImage srcImage,
674 VkImageLayout srcImageLayout,
675 VkBuffer destBuffer,
676 uint32_t regionCount,
677 const VkBufferImageCopy* pRegions)
678 {
679 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *)cmdBuffer;
680 VkDevice vk_device = (VkDevice) cmd_buffer->device;
681 struct anv_image *src_image = (struct anv_image *)srcImage;
682 struct anv_buffer *dest_buffer = (struct anv_buffer *)destBuffer;
683 struct anv_saved_state saved_state;
684
685 meta_prepare_blit(cmd_buffer, &saved_state);
686
687 for (unsigned r = 0; r < regionCount; r++) {
688 VkImageViewCreateInfo src_view_info = {
689 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
690 .image = srcImage,
691 .viewType = VK_IMAGE_VIEW_TYPE_2D,
692 .format = src_image->format,
693 .channels = {
694 VK_CHANNEL_SWIZZLE_R,
695 VK_CHANNEL_SWIZZLE_G,
696 VK_CHANNEL_SWIZZLE_B,
697 VK_CHANNEL_SWIZZLE_A
698 },
699 .subresourceRange = {
700 .aspect = pRegions[r].imageSubresource.aspect,
701 .baseMipLevel = pRegions[r].imageSubresource.mipLevel,
702 .mipLevels = 1,
703 .baseArraySlice = pRegions[r].imageSubresource.arraySlice,
704 .arraySize = 1
705 },
706 .minLod = 0
707 };
708
709 VkImageView src_view;
710 vkCreateImageView(vk_device, &src_view_info, &src_view);
711
712 VkImageCreateInfo dest_image_info = {
713 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
714 .imageType = VK_IMAGE_TYPE_2D,
715 .format = src_image->format,
716 .extent = {
717 .width = pRegions[r].imageExtent.width,
718 .height = pRegions[r].imageExtent.height,
719 .depth = 1,
720 },
721 .mipLevels = 1,
722 .arraySize = 1,
723 .samples = 1,
724 .tiling = VK_IMAGE_TILING_LINEAR,
725 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
726 .flags = 0,
727 };
728
729 struct anv_image *dest_image;
730 vkCreateImage(vk_device, &dest_image_info, (VkImage *)&dest_image);
731
732 /* We could use a vk call to bind memory, but that would require
733 * creating a dummy memory object etc. so there's really no point.
734 */
735 dest_image->bo = dest_buffer->bo;
736 dest_image->offset = dest_buffer->offset + pRegions[r].bufferOffset;
737
738 VkColorAttachmentViewCreateInfo dest_view_info = {
739 .sType = VK_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO,
740 .image = (VkImage)dest_image,
741 .format = src_image->format,
742 .mipLevel = 0,
743 .baseArraySlice = 0,
744 .arraySize = 1,
745 };
746
747 VkColorAttachmentView dest_view;
748 vkCreateColorAttachmentView(vk_device, &dest_view_info, &dest_view);
749
750 meta_emit_blit(cmd_buffer,
751 (struct anv_surface_view *)src_view,
752 pRegions[r].imageOffset,
753 pRegions[r].imageExtent,
754 (struct anv_surface_view *)dest_view,
755 (VkOffset3D) { 0, 0, 0 },
756 pRegions[r].imageExtent);
757 }
758
759 meta_finish_blit(cmd_buffer, &saved_state);
760 }
761
762 void VKAPI vkCmdCloneImageData(
763 VkCmdBuffer cmdBuffer,
764 VkImage srcImage,
765 VkImageLayout srcImageLayout,
766 VkImage destImage,
767 VkImageLayout destImageLayout)
768 {
769 stub();
770 }
771
772 void VKAPI vkCmdUpdateBuffer(
773 VkCmdBuffer cmdBuffer,
774 VkBuffer destBuffer,
775 VkDeviceSize destOffset,
776 VkDeviceSize dataSize,
777 const uint32_t* pData)
778 {
779 stub();
780 }
781
782 void VKAPI vkCmdFillBuffer(
783 VkCmdBuffer cmdBuffer,
784 VkBuffer destBuffer,
785 VkDeviceSize destOffset,
786 VkDeviceSize fillSize,
787 uint32_t data)
788 {
789 stub();
790 }
791
792 void VKAPI vkCmdClearColorImage(
793 VkCmdBuffer cmdBuffer,
794 VkImage image,
795 VkImageLayout imageLayout,
796 const VkClearColor* color,
797 uint32_t rangeCount,
798 const VkImageSubresourceRange* pRanges)
799 {
800 stub();
801 }
802
803 void VKAPI vkCmdClearDepthStencil(
804 VkCmdBuffer cmdBuffer,
805 VkImage image,
806 VkImageLayout imageLayout,
807 float depth,
808 uint32_t stencil,
809 uint32_t rangeCount,
810 const VkImageSubresourceRange* pRanges)
811 {
812 stub();
813 }
814
815 void VKAPI vkCmdResolveImage(
816 VkCmdBuffer cmdBuffer,
817 VkImage srcImage,
818 VkImageLayout srcImageLayout,
819 VkImage destImage,
820 VkImageLayout destImageLayout,
821 uint32_t regionCount,
822 const VkImageResolve* pRegions)
823 {
824 stub();
825 }
826
827 void
828 anv_device_init_meta(struct anv_device *device)
829 {
830 anv_device_init_meta_clear_state(device);
831 anv_device_init_meta_blit_state(device);
832 }