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