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