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