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