vk/meta: Use glsl_scraper for our GLSL source
[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 #include "meta-spirv.h"
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 VkShader fs = GLSL_VK_SHADER(device, FRAGMENT,
49 out vec4 f_color;
50 flat in vec4 v_color;
51 void main()
52 {
53 f_color = v_color;
54 }
55 );
56
57 VkPipelineShaderStageCreateInfo fs_create_info = {
58 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
59 .pNext = &ia_create_info,
60 .shader = {
61 .stage = VK_SHADER_STAGE_FRAGMENT,
62 .shader = fs,
63 .linkConstBufferCount = 0,
64 .pLinkConstBufferInfo = NULL,
65 .pSpecializationInfo = NULL
66 }
67 };
68
69 /* We use instanced rendering to clear multiple render targets. We have two
70 * vertex buffers: the first vertex buffer holds per-vertex data and
71 * provides the vertices for the clear rectangle. The second one holds
72 * per-instance data, which consists of the VUE header (which selects the
73 * layer) and the color (Vulkan supports per-RT clear colors).
74 */
75 VkPipelineVertexInputCreateInfo vi_create_info = {
76 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO,
77 .pNext = &fs_create_info,
78 .bindingCount = 2,
79 .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) {
80 {
81 .binding = 0,
82 .strideInBytes = 8,
83 .stepRate = VK_VERTEX_INPUT_STEP_RATE_VERTEX
84 },
85 {
86 .binding = 1,
87 .strideInBytes = 32,
88 .stepRate = VK_VERTEX_INPUT_STEP_RATE_INSTANCE
89 },
90 },
91 .attributeCount = 3,
92 .pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[]) {
93 {
94 /* VUE Header */
95 .location = 0,
96 .binding = 1,
97 .format = VK_FORMAT_R32G32B32A32_UINT,
98 .offsetInBytes = 0
99 },
100 {
101 /* Position */
102 .location = 1,
103 .binding = 0,
104 .format = VK_FORMAT_R32G32_SFLOAT,
105 .offsetInBytes = 0
106 },
107 {
108 /* Color */
109 .location = 2,
110 .binding = 1,
111 .format = VK_FORMAT_R32G32B32A32_SFLOAT,
112 .offsetInBytes = 16
113 }
114 }
115 };
116
117 VkPipelineRsStateCreateInfo rs_create_info = {
118 .sType = VK_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO,
119 .pNext = &vi_create_info,
120 .depthClipEnable = true,
121 .rasterizerDiscardEnable = false,
122 .fillMode = VK_FILL_MODE_SOLID,
123 .cullMode = VK_CULL_MODE_NONE,
124 .frontFace = VK_FRONT_FACE_CCW
125 };
126
127 anv_pipeline_create((VkDevice) device,
128 &(VkGraphicsPipelineCreateInfo) {
129 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
130 .pNext = &rs_create_info,
131 .flags = 0,
132 .layout = 0
133 },
134 &(struct anv_pipeline_create_info) {
135 .use_repclear = true,
136 .disable_viewport = true,
137 .use_rectlist = true
138 },
139 &device->clear_state.pipeline);
140
141 anv_DestroyObject((VkDevice) device, VK_OBJECT_TYPE_SHADER, fs);
142
143 anv_CreateDynamicRasterState((VkDevice) device,
144 &(VkDynamicRsStateCreateInfo) {
145 .sType = VK_STRUCTURE_TYPE_DYNAMIC_RS_STATE_CREATE_INFO,
146 },
147 &device->clear_state.rs_state);
148 }
149
150 #define NUM_VB_USED 2
151 struct anv_saved_state {
152 struct anv_bindings bindings;
153 struct anv_bindings *old_bindings;
154 struct anv_pipeline *old_pipeline;
155 };
156
157 static void
158 anv_cmd_buffer_save(struct anv_cmd_buffer *cmd_buffer,
159 struct anv_saved_state *state)
160 {
161 state->old_bindings = cmd_buffer->bindings;
162 cmd_buffer->bindings = &state->bindings;
163 state->old_pipeline = cmd_buffer->pipeline;
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 = state->old_bindings;
171 cmd_buffer->pipeline = state->old_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 static void
179 anv_cmd_buffer_copy_render_targets(struct anv_cmd_buffer *cmd_buffer,
180 struct anv_saved_state *state)
181 {
182 struct anv_framebuffer *fb = cmd_buffer->framebuffer;
183 struct anv_bindings *old_bindings = state->old_bindings;
184 struct anv_bindings *bindings = cmd_buffer->bindings;
185
186 for (uint32_t i = 0; i < fb->color_attachment_count; i++) {
187 bindings->descriptors[VK_SHADER_STAGE_FRAGMENT].surfaces[i] =
188 old_bindings->descriptors[VK_SHADER_STAGE_FRAGMENT].surfaces[i];
189
190 bindings->descriptors[VK_SHADER_STAGE_FRAGMENT].relocs[i].bo =
191 old_bindings->descriptors[VK_SHADER_STAGE_FRAGMENT].relocs[i].bo;
192 bindings->descriptors[VK_SHADER_STAGE_FRAGMENT].relocs[i].offset =
193 old_bindings->descriptors[VK_SHADER_STAGE_FRAGMENT].relocs[i].offset;
194 }
195
196 cmd_buffer->dirty |= ANV_CMD_BUFFER_DESCRIPTOR_SET_DIRTY;
197 }
198
199 struct vue_header {
200 uint32_t Reserved;
201 uint32_t RTAIndex;
202 uint32_t ViewportIndex;
203 float PointWidth;
204 };
205
206 void
207 anv_cmd_buffer_clear(struct anv_cmd_buffer *cmd_buffer,
208 struct anv_render_pass *pass)
209 {
210 struct anv_device *device = cmd_buffer->device;
211 struct anv_framebuffer *fb = cmd_buffer->framebuffer;
212 struct anv_saved_state saved_state;
213 struct anv_state state;
214 uint32_t size;
215
216 struct instance_data {
217 struct vue_header vue_header;
218 float color[4];
219 } *instance_data;
220
221 if (pass->num_clear_layers == 0)
222 return;
223
224 const float vertex_data[] = {
225 /* Rect-list coordinates */
226 0.0, 0.0,
227 fb->width, 0.0,
228 fb->width, fb->height,
229
230 /* Align to 16 bytes */
231 0.0, 0.0,
232 };
233
234 size = sizeof(vertex_data) + pass->num_clear_layers * sizeof(instance_data[0]);
235 state = anv_state_stream_alloc(&cmd_buffer->surface_state_stream, size, 16);
236
237 memcpy(state.map, vertex_data, sizeof(vertex_data));
238 instance_data = state.map + sizeof(vertex_data);
239
240 for (uint32_t i = 0; i < pass->num_layers; i++) {
241 if (pass->layers[i].color_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
242 *instance_data++ = (struct instance_data) {
243 .vue_header = {
244 .RTAIndex = i,
245 .ViewportIndex = 0,
246 .PointWidth = 0.0
247 },
248 .color = {
249 pass->layers[i].clear_color.color.floatColor[0],
250 pass->layers[i].clear_color.color.floatColor[1],
251 pass->layers[i].clear_color.color.floatColor[2],
252 pass->layers[i].clear_color.color.floatColor[3],
253 }
254 };
255 }
256 }
257
258 struct anv_buffer vertex_buffer = {
259 .device = cmd_buffer->device,
260 .size = size,
261 .bo = &device->surface_state_block_pool.bo,
262 .offset = state.offset
263 };
264
265 anv_cmd_buffer_save(cmd_buffer, &saved_state);
266 anv_cmd_buffer_copy_render_targets(cmd_buffer, &saved_state);
267
268 anv_CmdBindVertexBuffers((VkCmdBuffer) cmd_buffer, 0, 2,
269 (VkBuffer[]) {
270 (VkBuffer) &vertex_buffer,
271 (VkBuffer) &vertex_buffer
272 },
273 (VkDeviceSize[]) {
274 0,
275 sizeof(vertex_data)
276 });
277
278 if ((VkPipeline) cmd_buffer->pipeline != device->clear_state.pipeline)
279 anv_CmdBindPipeline((VkCmdBuffer) cmd_buffer,
280 VK_PIPELINE_BIND_POINT_GRAPHICS, device->clear_state.pipeline);
281
282 /* We don't need anything here, only set if not already set. */
283 if (cmd_buffer->rs_state == NULL)
284 anv_CmdBindDynamicStateObject((VkCmdBuffer) cmd_buffer,
285 VK_STATE_BIND_POINT_RASTER,
286 device->clear_state.rs_state);
287
288 if (cmd_buffer->vp_state == NULL)
289 anv_CmdBindDynamicStateObject((VkCmdBuffer) cmd_buffer,
290 VK_STATE_BIND_POINT_VIEWPORT,
291 cmd_buffer->framebuffer->vp_state);
292
293 anv_CmdDraw((VkCmdBuffer) cmd_buffer, 0, 3, 0, pass->num_clear_layers);
294
295 /* Restore API state */
296 anv_cmd_buffer_restore(cmd_buffer, &saved_state);
297
298 }
299
300 static void
301 anv_device_init_meta_blit_state(struct anv_device *device)
302 {
303 VkPipelineIaStateCreateInfo ia_create_info = {
304 .sType = VK_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO,
305 .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
306 .disableVertexReuse = false,
307 .primitiveRestartEnable = false,
308 .primitiveRestartIndex = 0
309 };
310
311 /* We don't use a vertex shader for clearing, but instead build and pass
312 * the VUEs directly to the rasterization backend. However, we do need
313 * to provide GLSL source for the vertex shader so that the compiler
314 * does not dead-code our inputs.
315 */
316 VkShader vs = GLSL_VK_SHADER(device, VERTEX,
317 in vec2 a_pos;
318 in vec2 a_tex_coord;
319 out vec4 v_tex_coord;
320 void main()
321 {
322 v_tex_coord = vec4(a_tex_coord, 0, 1);
323 gl_Position = vec4(a_pos, 0, 1);
324 }
325 );
326
327 VkShader fs = GLSL_VK_SHADER(device, FRAGMENT,
328 out vec4 f_color;
329 in vec4 v_tex_coord;
330 layout(set = 0, binding = 0) uniform sampler2D u_tex;
331 void main()
332 {
333 f_color = texture(u_tex, v_tex_coord.xy);
334 }
335 );
336
337 VkPipelineShaderStageCreateInfo vs_create_info = {
338 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
339 .pNext = &ia_create_info,
340 .shader = {
341 .stage = VK_SHADER_STAGE_VERTEX,
342 .shader = vs,
343 .linkConstBufferCount = 0,
344 .pLinkConstBufferInfo = NULL,
345 .pSpecializationInfo = NULL
346 }
347 };
348
349 VkPipelineShaderStageCreateInfo fs_create_info = {
350 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
351 .pNext = &vs_create_info,
352 .shader = {
353 .stage = VK_SHADER_STAGE_FRAGMENT,
354 .shader = fs,
355 .linkConstBufferCount = 0,
356 .pLinkConstBufferInfo = NULL,
357 .pSpecializationInfo = NULL
358 }
359 };
360
361 VkPipelineVertexInputCreateInfo vi_create_info = {
362 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO,
363 .pNext = &fs_create_info,
364 .bindingCount = 2,
365 .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) {
366 {
367 .binding = 0,
368 .strideInBytes = 0,
369 .stepRate = VK_VERTEX_INPUT_STEP_RATE_VERTEX
370 },
371 {
372 .binding = 1,
373 .strideInBytes = 16,
374 .stepRate = VK_VERTEX_INPUT_STEP_RATE_VERTEX
375 },
376 },
377 .attributeCount = 3,
378 .pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[]) {
379 {
380 /* VUE Header */
381 .location = 0,
382 .binding = 0,
383 .format = VK_FORMAT_R32G32B32A32_UINT,
384 .offsetInBytes = 0
385 },
386 {
387 /* Position */
388 .location = 1,
389 .binding = 1,
390 .format = VK_FORMAT_R32G32_SFLOAT,
391 .offsetInBytes = 0
392 },
393 {
394 /* Texture Coordinate */
395 .location = 2,
396 .binding = 1,
397 .format = VK_FORMAT_R32G32_SFLOAT,
398 .offsetInBytes = 8
399 }
400 }
401 };
402
403 VkDescriptorSetLayoutCreateInfo ds_layout_info = {
404 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
405 .count = 1,
406 .pBinding = (VkDescriptorSetLayoutBinding[]) {
407 {
408 .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
409 .count = 1,
410 .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
411 .pImmutableSamplers = NULL
412 },
413 }
414 };
415 anv_CreateDescriptorSetLayout((VkDevice) device, &ds_layout_info,
416 &device->blit_state.ds_layout);
417
418 VkPipelineLayoutCreateInfo pipeline_layout_info = {
419 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
420 .descriptorSetCount = 1,
421 .pSetLayouts = &device->blit_state.ds_layout,
422 };
423
424 VkPipelineLayout pipeline_layout;
425 anv_CreatePipelineLayout((VkDevice) device, &pipeline_layout_info,
426 &pipeline_layout);
427
428 VkPipelineRsStateCreateInfo rs_create_info = {
429 .sType = VK_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO,
430 .pNext = &vi_create_info,
431 .depthClipEnable = true,
432 .rasterizerDiscardEnable = false,
433 .fillMode = VK_FILL_MODE_SOLID,
434 .cullMode = VK_CULL_MODE_NONE,
435 .frontFace = VK_FRONT_FACE_CCW
436 };
437
438 VkGraphicsPipelineCreateInfo pipeline_info = {
439 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
440 .pNext = &rs_create_info,
441 .flags = 0,
442 .layout = pipeline_layout,
443 };
444
445 anv_pipeline_create((VkDevice) device, &pipeline_info,
446 &(struct anv_pipeline_create_info) {
447 .use_repclear = false,
448 .disable_viewport = true,
449 .disable_scissor = true,
450 .disable_vs = true,
451 .use_rectlist = true
452 },
453 &device->blit_state.pipeline);
454
455 anv_DestroyObject((VkDevice) device, VK_OBJECT_TYPE_SHADER, vs);
456 anv_DestroyObject((VkDevice) device, VK_OBJECT_TYPE_SHADER, fs);
457
458 anv_CreateDynamicRasterState((VkDevice) device,
459 &(VkDynamicRsStateCreateInfo) {
460 .sType = VK_STRUCTURE_TYPE_DYNAMIC_RS_STATE_CREATE_INFO,
461 },
462 &device->blit_state.rs_state);
463 }
464
465 static void
466 meta_prepare_blit(struct anv_cmd_buffer *cmd_buffer,
467 struct anv_saved_state *saved_state)
468 {
469 struct anv_device *device = cmd_buffer->device;
470
471 anv_cmd_buffer_save(cmd_buffer, saved_state);
472
473 if ((VkPipeline) cmd_buffer->pipeline != device->blit_state.pipeline)
474 anv_CmdBindPipeline((VkCmdBuffer) cmd_buffer,
475 VK_PIPELINE_BIND_POINT_GRAPHICS,
476 device->blit_state.pipeline);
477
478 /* We don't need anything here, only set if not already set. */
479 if (cmd_buffer->rs_state == NULL)
480 anv_CmdBindDynamicStateObject((VkCmdBuffer) cmd_buffer,
481 VK_STATE_BIND_POINT_RASTER,
482 device->blit_state.rs_state);
483 }
484
485 struct blit_region {
486 VkOffset3D src_offset;
487 VkExtent3D src_extent;
488 VkOffset3D dest_offset;
489 VkExtent3D dest_extent;
490 };
491
492 static void
493 meta_emit_blit(struct anv_cmd_buffer *cmd_buffer,
494 struct anv_surface_view *src,
495 VkOffset3D src_offset,
496 VkExtent3D src_extent,
497 struct anv_surface_view *dest,
498 VkOffset3D dest_offset,
499 VkExtent3D dest_extent)
500 {
501 struct anv_device *device = cmd_buffer->device;
502
503 struct blit_vb_data {
504 float pos[2];
505 float tex_coord[2];
506 } *vb_data;
507
508 unsigned vb_size = sizeof(struct vue_header) + 3 * sizeof(*vb_data);
509
510 struct anv_state vb_state =
511 anv_state_stream_alloc(&cmd_buffer->surface_state_stream, vb_size, 16);
512 memset(vb_state.map, 0, sizeof(struct vue_header));
513 vb_data = vb_state.map + sizeof(struct vue_header);
514
515 vb_data[0] = (struct blit_vb_data) {
516 .pos = {
517 dest_offset.x + dest_extent.width,
518 dest_offset.y + dest_extent.height,
519 },
520 .tex_coord = {
521 (float)(src_offset.x + src_extent.width) / (float)src->extent.width,
522 (float)(src_offset.y + src_extent.height) / (float)src->extent.height,
523 },
524 };
525
526 vb_data[1] = (struct blit_vb_data) {
527 .pos = {
528 dest_offset.x,
529 dest_offset.y + dest_extent.height,
530 },
531 .tex_coord = {
532 (float)src_offset.x / (float)src->extent.width,
533 (float)(src_offset.y + src_extent.height) / (float)src->extent.height,
534 },
535 };
536
537 vb_data[2] = (struct blit_vb_data) {
538 .pos = {
539 dest_offset.x,
540 dest_offset.y,
541 },
542 .tex_coord = {
543 (float)src_offset.x / (float)src->extent.width,
544 (float)src_offset.y / (float)src->extent.height,
545 },
546 };
547
548 struct anv_buffer vertex_buffer = {
549 .device = device,
550 .size = vb_size,
551 .bo = &device->surface_state_block_pool.bo,
552 .offset = vb_state.offset,
553 };
554
555 anv_CmdBindVertexBuffers((VkCmdBuffer) cmd_buffer, 0, 2,
556 (VkBuffer[]) {
557 (VkBuffer) &vertex_buffer,
558 (VkBuffer) &vertex_buffer
559 },
560 (VkDeviceSize[]) {
561 0,
562 sizeof(struct vue_header),
563 });
564
565 uint32_t count;
566 VkDescriptorSet set;
567 anv_AllocDescriptorSets((VkDevice) device, 0 /* pool */,
568 VK_DESCRIPTOR_SET_USAGE_ONE_SHOT,
569 1, &device->blit_state.ds_layout, &set, &count);
570 anv_UpdateDescriptors((VkDevice) device, set, 1,
571 (const void * []) {
572 &(VkUpdateImages) {
573 .sType = VK_STRUCTURE_TYPE_UPDATE_IMAGES,
574 .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
575 .binding = 0,
576 .count = 1,
577 .pImageViews = (VkImageViewAttachInfo[]) {
578 {
579 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_ATTACH_INFO,
580 .view = (VkImageView) src,
581 .layout = VK_IMAGE_LAYOUT_GENERAL,
582 }
583 }
584 }
585 });
586
587 struct anv_framebuffer *fb;
588 anv_CreateFramebuffer((VkDevice) device,
589 &(VkFramebufferCreateInfo) {
590 .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
591 .colorAttachmentCount = 1,
592 .pColorAttachments = (VkColorAttachmentBindInfo[]) {
593 {
594 .view = (VkColorAttachmentView) dest,
595 .layout = VK_IMAGE_LAYOUT_GENERAL
596 }
597 },
598 .pDepthStencilAttachment = NULL,
599 .sampleCount = 1,
600 .width = dest->extent.width,
601 .height = dest->extent.height,
602 .layers = 1
603 }, (VkFramebuffer *)&fb);
604
605
606 VkRenderPass pass;
607 anv_CreateRenderPass((VkDevice )device,
608 &(VkRenderPassCreateInfo) {
609 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
610 .renderArea = { { 0, 0 }, { dest->extent.width, dest->extent.height } },
611 .colorAttachmentCount = 1,
612 .extent = { 0, },
613 .sampleCount = 1,
614 .layers = 1,
615 .pColorFormats = (VkFormat[]) { dest->format },
616 .pColorLayouts = (VkImageLayout[]) { VK_IMAGE_LAYOUT_GENERAL },
617 .pColorLoadOps = (VkAttachmentLoadOp[]) { VK_ATTACHMENT_LOAD_OP_LOAD },
618 .pColorStoreOps = (VkAttachmentStoreOp[]) { VK_ATTACHMENT_STORE_OP_STORE },
619 .pColorLoadClearValues = (VkClearColor[]) {
620 { .color = { .floatColor = { 1.0, 0.0, 0.0, 1.0 } }, .useRawValue = false }
621 },
622 .depthStencilFormat = VK_FORMAT_UNDEFINED,
623 }, &pass);
624
625 anv_CmdBeginRenderPass((VkCmdBuffer) cmd_buffer,
626 &(VkRenderPassBegin) {
627 .renderPass = pass,
628 .framebuffer = (VkFramebuffer) fb,
629 });
630
631 anv_CmdBindDynamicStateObject((VkCmdBuffer) cmd_buffer,
632 VK_STATE_BIND_POINT_VIEWPORT, fb->vp_state);
633
634 anv_CmdBindDescriptorSets((VkCmdBuffer) cmd_buffer,
635 VK_PIPELINE_BIND_POINT_GRAPHICS, 0, 1,
636 &set, 0, NULL);
637
638 anv_CmdDraw((VkCmdBuffer) cmd_buffer, 0, 3, 0, 1);
639
640 anv_CmdEndRenderPass((VkCmdBuffer) cmd_buffer, pass);
641 }
642
643 static void
644 meta_finish_blit(struct anv_cmd_buffer *cmd_buffer,
645 const struct anv_saved_state *saved_state)
646 {
647 anv_cmd_buffer_restore(cmd_buffer, saved_state);
648 }
649
650 static VkFormat
651 vk_format_for_cpp(int cpp)
652 {
653 switch (cpp) {
654 case 1: return VK_FORMAT_R8_UINT;
655 case 2: return VK_FORMAT_R8G8_UINT;
656 case 3: return VK_FORMAT_R8G8B8_UINT;
657 case 4: return VK_FORMAT_R8G8B8A8_UINT;
658 case 6: return VK_FORMAT_R16G16B16_UINT;
659 case 8: return VK_FORMAT_R16G16B16A16_UINT;
660 case 12: return VK_FORMAT_R32G32B32_UINT;
661 case 16: return VK_FORMAT_R32G32B32A32_UINT;
662 default:
663 unreachable("Invalid format cpp");
664 }
665 }
666
667 static void
668 do_buffer_copy(struct anv_cmd_buffer *cmd_buffer,
669 struct anv_bo *src, uint64_t src_offset,
670 struct anv_bo *dest, uint64_t dest_offset,
671 int width, int height, VkFormat copy_format)
672 {
673 VkDevice vk_device = (VkDevice)cmd_buffer->device;
674
675 VkImageCreateInfo image_info = {
676 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
677 .imageType = VK_IMAGE_TYPE_2D,
678 .format = copy_format,
679 .extent = {
680 .width = width,
681 .height = height,
682 .depth = 1,
683 },
684 .mipLevels = 1,
685 .arraySize = 1,
686 .samples = 1,
687 .tiling = VK_IMAGE_TILING_LINEAR,
688 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
689 .flags = 0,
690 };
691
692 struct anv_image *src_image, *dest_image;
693 anv_CreateImage(vk_device, &image_info, (VkImage *)&src_image);
694 anv_CreateImage(vk_device, &image_info, (VkImage *)&dest_image);
695
696 /* We could use a vk call to bind memory, but that would require
697 * creating a dummy memory object etc. so there's really no point.
698 */
699 src_image->bo = src;
700 src_image->offset = src_offset;
701 dest_image->bo = dest;
702 dest_image->offset = dest_offset;
703
704 struct anv_surface_view src_view;
705 anv_image_view_init(&src_view, cmd_buffer->device,
706 &(VkImageViewCreateInfo) {
707 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
708 .image = (VkImage)src_image,
709 .viewType = VK_IMAGE_VIEW_TYPE_2D,
710 .format = copy_format,
711 .channels = {
712 VK_CHANNEL_SWIZZLE_R,
713 VK_CHANNEL_SWIZZLE_G,
714 VK_CHANNEL_SWIZZLE_B,
715 VK_CHANNEL_SWIZZLE_A
716 },
717 .subresourceRange = {
718 .aspect = VK_IMAGE_ASPECT_COLOR,
719 .baseMipLevel = 0,
720 .mipLevels = 1,
721 .baseArraySlice = 0,
722 .arraySize = 1
723 },
724 .minLod = 0
725 },
726 cmd_buffer);
727
728 struct anv_surface_view dest_view;
729 anv_color_attachment_view_init(&dest_view, cmd_buffer->device,
730 &(VkColorAttachmentViewCreateInfo) {
731 .sType = VK_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO,
732 .image = (VkImage)dest_image,
733 .format = copy_format,
734 .mipLevel = 0,
735 .baseArraySlice = 0,
736 .arraySize = 1,
737 },
738 cmd_buffer);
739
740 meta_emit_blit(cmd_buffer,
741 &src_view,
742 (VkOffset3D) { 0, 0, 0 },
743 (VkExtent3D) { width, height, 1 },
744 &dest_view,
745 (VkOffset3D) { 0, 0, 0 },
746 (VkExtent3D) { width, height, 1 });
747 }
748
749 void anv_CmdCopyBuffer(
750 VkCmdBuffer cmdBuffer,
751 VkBuffer srcBuffer,
752 VkBuffer destBuffer,
753 uint32_t regionCount,
754 const VkBufferCopy* pRegions)
755 {
756 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *)cmdBuffer;
757 struct anv_buffer *src_buffer = (struct anv_buffer *)srcBuffer;
758 struct anv_buffer *dest_buffer = (struct anv_buffer *)destBuffer;
759 struct anv_saved_state saved_state;
760
761 meta_prepare_blit(cmd_buffer, &saved_state);
762
763 for (unsigned r = 0; r < regionCount; r++) {
764 uint64_t src_offset = src_buffer->offset + pRegions[r].srcOffset;
765 uint64_t dest_offset = dest_buffer->offset + pRegions[r].destOffset;
766 uint64_t copy_size = pRegions[r].copySize;
767
768 /* First, we compute the biggest format that can be used with the
769 * given offsets and size.
770 */
771 int cpp = 16;
772
773 int fs = ffs(src_offset) - 1;
774 if (fs != -1)
775 cpp = MIN2(cpp, 1 << fs);
776 assert(src_offset % cpp == 0);
777
778 fs = ffs(dest_offset) - 1;
779 if (fs != -1)
780 cpp = MIN2(cpp, 1 << fs);
781 assert(dest_offset % cpp == 0);
782
783 fs = ffs(pRegions[r].copySize) - 1;
784 if (fs != -1)
785 cpp = MIN2(cpp, 1 << fs);
786 assert(pRegions[r].copySize % cpp == 0);
787
788 VkFormat copy_format = vk_format_for_cpp(cpp);
789
790 /* This is maximum possible width/height our HW can handle */
791 uint64_t max_surface_dim = 1 << 14;
792
793 /* First, we make a bunch of max-sized copies */
794 uint64_t max_copy_size = max_surface_dim * max_surface_dim * cpp;
795 while (copy_size > max_copy_size) {
796 do_buffer_copy(cmd_buffer, src_buffer->bo, src_offset,
797 dest_buffer->bo, dest_offset,
798 max_surface_dim, max_surface_dim, copy_format);
799 copy_size -= max_copy_size;
800 src_offset += max_copy_size;
801 dest_offset += max_copy_size;
802 }
803
804 uint64_t height = copy_size / (max_surface_dim * cpp);
805 assert(height < max_surface_dim);
806 if (height != 0) {
807 uint64_t rect_copy_size = height * max_surface_dim * cpp;
808 do_buffer_copy(cmd_buffer, src_buffer->bo, src_offset,
809 dest_buffer->bo, dest_offset,
810 max_surface_dim, height, copy_format);
811 copy_size -= rect_copy_size;
812 src_offset += rect_copy_size;
813 dest_offset += rect_copy_size;
814 }
815
816 if (copy_size != 0) {
817 do_buffer_copy(cmd_buffer, src_buffer->bo, src_offset,
818 dest_buffer->bo, dest_offset,
819 copy_size / cpp, 1, copy_format);
820 }
821 }
822
823 meta_finish_blit(cmd_buffer, &saved_state);
824 }
825
826 void anv_CmdCopyImage(
827 VkCmdBuffer cmdBuffer,
828 VkImage srcImage,
829 VkImageLayout srcImageLayout,
830 VkImage destImage,
831 VkImageLayout destImageLayout,
832 uint32_t regionCount,
833 const VkImageCopy* pRegions)
834 {
835 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *)cmdBuffer;
836 struct anv_image *src_image = (struct anv_image *)srcImage;
837 struct anv_saved_state saved_state;
838
839 meta_prepare_blit(cmd_buffer, &saved_state);
840
841 for (unsigned r = 0; r < regionCount; r++) {
842 struct anv_surface_view src_view;
843 anv_image_view_init(&src_view, cmd_buffer->device,
844 &(VkImageViewCreateInfo) {
845 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
846 .image = srcImage,
847 .viewType = VK_IMAGE_VIEW_TYPE_2D,
848 .format = src_image->format,
849 .channels = {
850 VK_CHANNEL_SWIZZLE_R,
851 VK_CHANNEL_SWIZZLE_G,
852 VK_CHANNEL_SWIZZLE_B,
853 VK_CHANNEL_SWIZZLE_A
854 },
855 .subresourceRange = {
856 .aspect = pRegions[r].srcSubresource.aspect,
857 .baseMipLevel = pRegions[r].srcSubresource.mipLevel,
858 .mipLevels = 1,
859 .baseArraySlice = pRegions[r].srcSubresource.arraySlice,
860 .arraySize = 1
861 },
862 .minLod = 0
863 },
864 cmd_buffer);
865
866 struct anv_surface_view dest_view;
867 anv_color_attachment_view_init(&dest_view, cmd_buffer->device,
868 &(VkColorAttachmentViewCreateInfo) {
869 .sType = VK_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO,
870 .image = destImage,
871 .format = src_image->format,
872 .mipLevel = pRegions[r].destSubresource.mipLevel,
873 .baseArraySlice = pRegions[r].destSubresource.arraySlice,
874 .arraySize = 1,
875 },
876 cmd_buffer);
877
878 meta_emit_blit(cmd_buffer,
879 &src_view,
880 pRegions[r].srcOffset,
881 pRegions[r].extent,
882 &dest_view,
883 pRegions[r].destOffset,
884 pRegions[r].extent);
885 }
886
887 meta_finish_blit(cmd_buffer, &saved_state);
888 }
889
890 void anv_CmdBlitImage(
891 VkCmdBuffer cmdBuffer,
892 VkImage srcImage,
893 VkImageLayout srcImageLayout,
894 VkImage destImage,
895 VkImageLayout destImageLayout,
896 uint32_t regionCount,
897 const VkImageBlit* pRegions)
898 {
899 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *)cmdBuffer;
900 struct anv_image *src_image = (struct anv_image *)srcImage;
901 struct anv_image *dest_image = (struct anv_image *)destImage;
902 struct anv_saved_state saved_state;
903
904 meta_prepare_blit(cmd_buffer, &saved_state);
905
906 for (unsigned r = 0; r < regionCount; r++) {
907 struct anv_surface_view src_view;
908 anv_image_view_init(&src_view, cmd_buffer->device,
909 &(VkImageViewCreateInfo) {
910 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
911 .image = srcImage,
912 .viewType = VK_IMAGE_VIEW_TYPE_2D,
913 .format = src_image->format,
914 .channels = {
915 VK_CHANNEL_SWIZZLE_R,
916 VK_CHANNEL_SWIZZLE_G,
917 VK_CHANNEL_SWIZZLE_B,
918 VK_CHANNEL_SWIZZLE_A
919 },
920 .subresourceRange = {
921 .aspect = pRegions[r].srcSubresource.aspect,
922 .baseMipLevel = pRegions[r].srcSubresource.mipLevel,
923 .mipLevels = 1,
924 .baseArraySlice = pRegions[r].srcSubresource.arraySlice,
925 .arraySize = 1
926 },
927 .minLod = 0
928 },
929 cmd_buffer);
930
931 struct anv_surface_view dest_view;
932 anv_color_attachment_view_init(&dest_view, cmd_buffer->device,
933 &(VkColorAttachmentViewCreateInfo) {
934 .sType = VK_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO,
935 .image = destImage,
936 .format = dest_image->format,
937 .mipLevel = pRegions[r].destSubresource.mipLevel,
938 .baseArraySlice = pRegions[r].destSubresource.arraySlice,
939 .arraySize = 1,
940 },
941 cmd_buffer);
942
943 meta_emit_blit(cmd_buffer,
944 &src_view,
945 pRegions[r].srcOffset,
946 pRegions[r].srcExtent,
947 &dest_view,
948 pRegions[r].destOffset,
949 pRegions[r].destExtent);
950 }
951
952 meta_finish_blit(cmd_buffer, &saved_state);
953 }
954
955 void anv_CmdCopyBufferToImage(
956 VkCmdBuffer cmdBuffer,
957 VkBuffer srcBuffer,
958 VkImage destImage,
959 VkImageLayout destImageLayout,
960 uint32_t regionCount,
961 const VkBufferImageCopy* pRegions)
962 {
963 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *)cmdBuffer;
964 VkDevice vk_device = (VkDevice) cmd_buffer->device;
965 struct anv_buffer *src_buffer = (struct anv_buffer *)srcBuffer;
966 struct anv_image *dest_image = (struct anv_image *)destImage;
967 struct anv_saved_state saved_state;
968
969 meta_prepare_blit(cmd_buffer, &saved_state);
970
971 for (unsigned r = 0; r < regionCount; r++) {
972 struct anv_image *src_image;
973 anv_CreateImage(vk_device,
974 &(VkImageCreateInfo) {
975 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
976 .imageType = VK_IMAGE_TYPE_2D,
977 .format = dest_image->format,
978 .extent = {
979 .width = pRegions[r].imageExtent.width,
980 .height = pRegions[r].imageExtent.height,
981 .depth = 1,
982 },
983 .mipLevels = 1,
984 .arraySize = 1,
985 .samples = 1,
986 .tiling = VK_IMAGE_TILING_LINEAR,
987 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
988 .flags = 0,
989 }, (VkImage *)&src_image);
990
991 /* We could use a vk call to bind memory, but that would require
992 * creating a dummy memory object etc. so there's really no point.
993 */
994 src_image->bo = src_buffer->bo;
995 src_image->offset = src_buffer->offset + pRegions[r].bufferOffset;
996
997 struct anv_surface_view src_view;
998 anv_image_view_init(&src_view, cmd_buffer->device,
999 &(VkImageViewCreateInfo) {
1000 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
1001 .image = (VkImage)src_image,
1002 .viewType = VK_IMAGE_VIEW_TYPE_2D,
1003 .format = dest_image->format,
1004 .channels = {
1005 VK_CHANNEL_SWIZZLE_R,
1006 VK_CHANNEL_SWIZZLE_G,
1007 VK_CHANNEL_SWIZZLE_B,
1008 VK_CHANNEL_SWIZZLE_A
1009 },
1010 .subresourceRange = {
1011 .aspect = pRegions[r].imageSubresource.aspect,
1012 .baseMipLevel = 0,
1013 .mipLevels = 1,
1014 .baseArraySlice = 0,
1015 .arraySize = 1
1016 },
1017 .minLod = 0
1018 },
1019 cmd_buffer);
1020
1021 struct anv_surface_view dest_view;
1022 anv_color_attachment_view_init(&dest_view, cmd_buffer->device,
1023 &(VkColorAttachmentViewCreateInfo) {
1024 .sType = VK_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO,
1025 .image = (VkImage)dest_image,
1026 .format = dest_image->format,
1027 .mipLevel = pRegions[r].imageSubresource.mipLevel,
1028 .baseArraySlice = pRegions[r].imageSubresource.arraySlice,
1029 .arraySize = 1,
1030 },
1031 cmd_buffer);
1032
1033 meta_emit_blit(cmd_buffer,
1034 &src_view,
1035 (VkOffset3D) { 0, 0, 0 },
1036 pRegions[r].imageExtent,
1037 &dest_view,
1038 pRegions[r].imageOffset,
1039 pRegions[r].imageExtent);
1040 }
1041
1042 meta_finish_blit(cmd_buffer, &saved_state);
1043 }
1044
1045 void anv_CmdCopyImageToBuffer(
1046 VkCmdBuffer cmdBuffer,
1047 VkImage srcImage,
1048 VkImageLayout srcImageLayout,
1049 VkBuffer destBuffer,
1050 uint32_t regionCount,
1051 const VkBufferImageCopy* pRegions)
1052 {
1053 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *)cmdBuffer;
1054 VkDevice vk_device = (VkDevice) cmd_buffer->device;
1055 struct anv_image *src_image = (struct anv_image *)srcImage;
1056 struct anv_buffer *dest_buffer = (struct anv_buffer *)destBuffer;
1057 struct anv_saved_state saved_state;
1058
1059 meta_prepare_blit(cmd_buffer, &saved_state);
1060
1061 for (unsigned r = 0; r < regionCount; r++) {
1062 struct anv_surface_view src_view;
1063 anv_image_view_init(&src_view, cmd_buffer->device,
1064 &(VkImageViewCreateInfo) {
1065 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
1066 .image = srcImage,
1067 .viewType = VK_IMAGE_VIEW_TYPE_2D,
1068 .format = src_image->format,
1069 .channels = {
1070 VK_CHANNEL_SWIZZLE_R,
1071 VK_CHANNEL_SWIZZLE_G,
1072 VK_CHANNEL_SWIZZLE_B,
1073 VK_CHANNEL_SWIZZLE_A
1074 },
1075 .subresourceRange = {
1076 .aspect = pRegions[r].imageSubresource.aspect,
1077 .baseMipLevel = pRegions[r].imageSubresource.mipLevel,
1078 .mipLevels = 1,
1079 .baseArraySlice = pRegions[r].imageSubresource.arraySlice,
1080 .arraySize = 1
1081 },
1082 .minLod = 0
1083 },
1084 cmd_buffer);
1085
1086 struct anv_image *dest_image;
1087 anv_CreateImage(vk_device,
1088 &(VkImageCreateInfo) {
1089 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
1090 .imageType = VK_IMAGE_TYPE_2D,
1091 .format = src_image->format,
1092 .extent = {
1093 .width = pRegions[r].imageExtent.width,
1094 .height = pRegions[r].imageExtent.height,
1095 .depth = 1,
1096 },
1097 .mipLevels = 1,
1098 .arraySize = 1,
1099 .samples = 1,
1100 .tiling = VK_IMAGE_TILING_LINEAR,
1101 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
1102 .flags = 0,
1103 }, (VkImage *)&dest_image);
1104
1105 /* We could use a vk call to bind memory, but that would require
1106 * creating a dummy memory object etc. so there's really no point.
1107 */
1108 dest_image->bo = dest_buffer->bo;
1109 dest_image->offset = dest_buffer->offset + pRegions[r].bufferOffset;
1110
1111 struct anv_surface_view dest_view;
1112 anv_color_attachment_view_init(&dest_view, cmd_buffer->device,
1113 &(VkColorAttachmentViewCreateInfo) {
1114 .sType = VK_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO,
1115 .image = (VkImage)dest_image,
1116 .format = src_image->format,
1117 .mipLevel = 0,
1118 .baseArraySlice = 0,
1119 .arraySize = 1,
1120 },
1121 cmd_buffer);
1122
1123 meta_emit_blit(cmd_buffer,
1124 &src_view,
1125 pRegions[r].imageOffset,
1126 pRegions[r].imageExtent,
1127 &dest_view,
1128 (VkOffset3D) { 0, 0, 0 },
1129 pRegions[r].imageExtent);
1130 }
1131
1132 meta_finish_blit(cmd_buffer, &saved_state);
1133 }
1134
1135 void anv_CmdCloneImageData(
1136 VkCmdBuffer cmdBuffer,
1137 VkImage srcImage,
1138 VkImageLayout srcImageLayout,
1139 VkImage destImage,
1140 VkImageLayout destImageLayout)
1141 {
1142 stub();
1143 }
1144
1145 void anv_CmdUpdateBuffer(
1146 VkCmdBuffer cmdBuffer,
1147 VkBuffer destBuffer,
1148 VkDeviceSize destOffset,
1149 VkDeviceSize dataSize,
1150 const uint32_t* pData)
1151 {
1152 stub();
1153 }
1154
1155 void anv_CmdFillBuffer(
1156 VkCmdBuffer cmdBuffer,
1157 VkBuffer destBuffer,
1158 VkDeviceSize destOffset,
1159 VkDeviceSize fillSize,
1160 uint32_t data)
1161 {
1162 stub();
1163 }
1164
1165 void anv_CmdClearColorImage(
1166 VkCmdBuffer cmdBuffer,
1167 VkImage image,
1168 VkImageLayout imageLayout,
1169 const VkClearColor* color,
1170 uint32_t rangeCount,
1171 const VkImageSubresourceRange* pRanges)
1172 {
1173 stub();
1174 }
1175
1176 void anv_CmdClearDepthStencil(
1177 VkCmdBuffer cmdBuffer,
1178 VkImage image,
1179 VkImageLayout imageLayout,
1180 float depth,
1181 uint32_t stencil,
1182 uint32_t rangeCount,
1183 const VkImageSubresourceRange* pRanges)
1184 {
1185 stub();
1186 }
1187
1188 void anv_CmdResolveImage(
1189 VkCmdBuffer cmdBuffer,
1190 VkImage srcImage,
1191 VkImageLayout srcImageLayout,
1192 VkImage destImage,
1193 VkImageLayout destImageLayout,
1194 uint32_t regionCount,
1195 const VkImageResolve* pRegions)
1196 {
1197 stub();
1198 }
1199
1200 void
1201 anv_device_init_meta(struct anv_device *device)
1202 {
1203 anv_device_init_meta_clear_state(device);
1204 anv_device_init_meta_blit_state(device);
1205 }