vk/image: Remove unneeded data from anv_buffer_view
[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 /* We don't use a vertex shader for clearing, but instead build and pass
37 * the VUEs directly to the rasterization backend.
38 */
39 VkShaderModule fsm = GLSL_VK_SHADER_MODULE(device, FRAGMENT,
40 out vec4 f_color;
41 flat in vec4 v_color;
42 void main()
43 {
44 f_color = v_color;
45 }
46 );
47
48 VkShader fs;
49 anv_CreateShader(anv_device_to_handle(device),
50 &(VkShaderCreateInfo) {
51 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
52 .module = fsm,
53 .pName = "main",
54 }, &fs);
55
56 /* We use instanced rendering to clear multiple render targets. We have two
57 * vertex buffers: the first vertex buffer holds per-vertex data and
58 * provides the vertices for the clear rectangle. The second one holds
59 * per-instance data, which consists of the VUE header (which selects the
60 * layer) and the color (Vulkan supports per-RT clear colors).
61 */
62 VkPipelineVertexInputStateCreateInfo vi_create_info = {
63 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
64 .bindingCount = 2,
65 .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) {
66 {
67 .binding = 0,
68 .strideInBytes = 8,
69 .stepRate = VK_VERTEX_INPUT_STEP_RATE_VERTEX
70 },
71 {
72 .binding = 1,
73 .strideInBytes = 32,
74 .stepRate = VK_VERTEX_INPUT_STEP_RATE_INSTANCE
75 },
76 },
77 .attributeCount = 3,
78 .pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[]) {
79 {
80 /* VUE Header */
81 .location = 0,
82 .binding = 1,
83 .format = VK_FORMAT_R32G32B32A32_UINT,
84 .offsetInBytes = 0
85 },
86 {
87 /* Position */
88 .location = 1,
89 .binding = 0,
90 .format = VK_FORMAT_R32G32_SFLOAT,
91 .offsetInBytes = 0
92 },
93 {
94 /* Color */
95 .location = 2,
96 .binding = 1,
97 .format = VK_FORMAT_R32G32B32A32_SFLOAT,
98 .offsetInBytes = 16
99 }
100 }
101 };
102
103 anv_pipeline_create(anv_device_to_handle(device),
104 &(VkGraphicsPipelineCreateInfo) {
105 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
106 .stageCount = 1,
107 .pStages = &(VkPipelineShaderStageCreateInfo) {
108 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
109 .stage = VK_SHADER_STAGE_FRAGMENT,
110 .shader = fs,
111 .pSpecializationInfo = NULL,
112 },
113 .pVertexInputState = &vi_create_info,
114 .pInputAssemblyState = &(VkPipelineInputAssemblyStateCreateInfo) {
115 .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
116 .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
117 .primitiveRestartEnable = false,
118 },
119 .pRasterState = &(VkPipelineRasterStateCreateInfo) {
120 .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTER_STATE_CREATE_INFO,
121 .depthClipEnable = true,
122 .rasterizerDiscardEnable = false,
123 .fillMode = VK_FILL_MODE_SOLID,
124 .cullMode = VK_CULL_MODE_NONE,
125 .frontFace = VK_FRONT_FACE_CCW
126 },
127 .pColorBlendState = &(VkPipelineColorBlendStateCreateInfo) {
128 .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
129 .attachmentCount = 1,
130 .pAttachments = (VkPipelineColorBlendAttachmentState []) {
131 { .channelWriteMask = VK_CHANNEL_A_BIT |
132 VK_CHANNEL_R_BIT | VK_CHANNEL_G_BIT | VK_CHANNEL_B_BIT },
133 }
134 },
135 .flags = 0,
136 },
137 &(struct anv_pipeline_create_info) {
138 .use_repclear = true,
139 .disable_viewport = true,
140 .use_rectlist = true
141 },
142 &device->meta_state.clear.pipeline);
143
144 anv_DestroyShader(anv_device_to_handle(device), fs);
145 }
146
147 #define NUM_VB_USED 2
148 struct anv_saved_state {
149 struct anv_vertex_binding old_vertex_bindings[NUM_VB_USED];
150 struct anv_descriptor_set *old_descriptor_set0;
151 struct anv_pipeline *old_pipeline;
152 VkDynamicColorBlendState cb_state;
153 };
154
155 static void
156 anv_cmd_buffer_save(struct anv_cmd_buffer *cmd_buffer,
157 struct anv_saved_state *state)
158 {
159 state->old_pipeline = cmd_buffer->state.pipeline;
160 state->old_descriptor_set0 = cmd_buffer->state.descriptors[0].set;
161 memcpy(state->old_vertex_bindings, cmd_buffer->state.vertex_bindings,
162 sizeof(state->old_vertex_bindings));
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->state.pipeline = state->old_pipeline;
170 cmd_buffer->state.descriptors[0].set = state->old_descriptor_set0;
171 memcpy(cmd_buffer->state.vertex_bindings, state->old_vertex_bindings,
172 sizeof(state->old_vertex_bindings));
173
174 cmd_buffer->state.vb_dirty |= (1 << NUM_VB_USED) - 1;
175 cmd_buffer->state.dirty |= ANV_CMD_BUFFER_PIPELINE_DIRTY;
176 cmd_buffer->state.descriptors_dirty |= VK_SHADER_STAGE_VERTEX_BIT;
177 }
178
179 struct vue_header {
180 uint32_t Reserved;
181 uint32_t RTAIndex;
182 uint32_t ViewportIndex;
183 float PointWidth;
184 };
185
186 struct clear_instance_data {
187 struct vue_header vue_header;
188 VkClearColorValue color;
189 };
190
191 static void
192 meta_emit_clear(struct anv_cmd_buffer *cmd_buffer,
193 int num_instances,
194 struct clear_instance_data *instance_data)
195 {
196 struct anv_device *device = cmd_buffer->device;
197 struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
198 struct anv_state state;
199 uint32_t size;
200
201 const float vertex_data[] = {
202 /* Rect-list coordinates */
203 0.0, 0.0,
204 fb->width, 0.0,
205 fb->width, fb->height,
206
207 /* Align to 16 bytes */
208 0.0, 0.0,
209 };
210
211 size = sizeof(vertex_data) + num_instances * sizeof(*instance_data);
212 state = anv_state_stream_alloc(&cmd_buffer->surface_state_stream, size, 16);
213
214 /* Copy in the vertex and instance data */
215 memcpy(state.map, vertex_data, sizeof(vertex_data));
216 memcpy(state.map + sizeof(vertex_data), instance_data,
217 num_instances * sizeof(*instance_data));
218
219 struct anv_buffer vertex_buffer = {
220 .device = cmd_buffer->device,
221 .size = size,
222 .bo = &device->surface_state_block_pool.bo,
223 .offset = state.offset
224 };
225
226 anv_CmdBindVertexBuffers(anv_cmd_buffer_to_handle(cmd_buffer), 0, 2,
227 (VkBuffer[]) {
228 anv_buffer_to_handle(&vertex_buffer),
229 anv_buffer_to_handle(&vertex_buffer)
230 },
231 (VkDeviceSize[]) {
232 0,
233 sizeof(vertex_data)
234 });
235
236 if (cmd_buffer->state.pipeline != anv_pipeline_from_handle(device->meta_state.clear.pipeline))
237 anv_CmdBindPipeline(anv_cmd_buffer_to_handle(cmd_buffer),
238 VK_PIPELINE_BIND_POINT_GRAPHICS,
239 device->meta_state.clear.pipeline);
240
241 /* We don't need anything here, only set if not already set. */
242 if (cmd_buffer->state.rs_state == NULL)
243 anv_CmdBindDynamicRasterState(anv_cmd_buffer_to_handle(cmd_buffer),
244 device->meta_state.shared.rs_state);
245
246 if (cmd_buffer->state.vp_state == NULL)
247 anv_CmdBindDynamicViewportState(anv_cmd_buffer_to_handle(cmd_buffer),
248 cmd_buffer->state.framebuffer->vp_state);
249
250 if (cmd_buffer->state.ds_state == NULL)
251 anv_CmdBindDynamicDepthStencilState(anv_cmd_buffer_to_handle(cmd_buffer),
252 device->meta_state.shared.ds_state);
253
254 if (cmd_buffer->state.cb_state == NULL)
255 anv_CmdBindDynamicColorBlendState(anv_cmd_buffer_to_handle(cmd_buffer),
256 device->meta_state.shared.cb_state);
257
258 anv_CmdDraw(anv_cmd_buffer_to_handle(cmd_buffer), 0, 3, 0, num_instances);
259 }
260
261 void
262 anv_cmd_buffer_clear_attachments(struct anv_cmd_buffer *cmd_buffer,
263 struct anv_render_pass *pass,
264 const VkClearValue *clear_values)
265 {
266 struct anv_saved_state saved_state;
267
268 int num_clear_layers = 0;
269 for (uint32_t i = 0; i < pass->attachment_count; i++) {
270 if (pass->attachments[i].load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
271 if (anv_is_vk_format_depth_or_stencil(pass->attachments[i].format)) {
272 anv_finishme("Can't clear depth-stencil yet");
273 continue;
274 }
275 num_clear_layers++;
276 }
277 }
278
279 if (num_clear_layers == 0)
280 return;
281
282 struct clear_instance_data instance_data[num_clear_layers];
283 uint32_t color_attachments[num_clear_layers];
284
285 int layer = 0;
286 for (uint32_t i = 0; i < pass->attachment_count; i++) {
287 if (pass->attachments[i].load_op == VK_ATTACHMENT_LOAD_OP_CLEAR &&
288 !anv_is_vk_format_depth_or_stencil(pass->attachments[i].format)) {
289 instance_data[layer] = (struct clear_instance_data) {
290 .vue_header = {
291 .RTAIndex = i,
292 .ViewportIndex = 0,
293 .PointWidth = 0.0
294 },
295 .color = clear_values[i].color,
296 };
297 color_attachments[layer] = i;
298 layer++;
299 }
300 }
301
302 anv_cmd_buffer_save(cmd_buffer, &saved_state);
303
304 struct anv_subpass subpass = {
305 .input_count = 0,
306 .color_count = num_clear_layers,
307 .color_attachments = color_attachments,
308 .depth_stencil_attachment = VK_ATTACHMENT_UNUSED,
309 };
310
311 anv_cmd_buffer_begin_subpass(cmd_buffer, &subpass);
312
313 meta_emit_clear(cmd_buffer, num_clear_layers, instance_data);
314
315 /* Restore API state */
316 anv_cmd_buffer_restore(cmd_buffer, &saved_state);
317 }
318
319 static void
320 anv_device_init_meta_blit_state(struct anv_device *device)
321 {
322 /* We don't use a vertex shader for clearing, but instead build and pass
323 * the VUEs directly to the rasterization backend. However, we do need
324 * to provide GLSL source for the vertex shader so that the compiler
325 * does not dead-code our inputs.
326 */
327 VkShaderModule vsm = GLSL_VK_SHADER_MODULE(device, VERTEX,
328 in vec2 a_pos;
329 in vec2 a_tex_coord;
330 out vec4 v_tex_coord;
331 void main()
332 {
333 v_tex_coord = vec4(a_tex_coord, 0, 1);
334 gl_Position = vec4(a_pos, 0, 1);
335 }
336 );
337
338 VkShaderModule fsm = GLSL_VK_SHADER_MODULE(device, FRAGMENT,
339 out vec4 f_color;
340 in vec4 v_tex_coord;
341 layout(set = 0, binding = 0) uniform sampler2D u_tex;
342 void main()
343 {
344 f_color = texture(u_tex, v_tex_coord.xy);
345 }
346 );
347
348 VkShader vs;
349 anv_CreateShader(anv_device_to_handle(device),
350 &(VkShaderCreateInfo) {
351 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
352 .module = vsm,
353 .pName = "main",
354 }, &vs);
355
356 VkShader fs;
357 anv_CreateShader(anv_device_to_handle(device),
358 &(VkShaderCreateInfo) {
359 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
360 .module = fsm,
361 .pName = "main",
362 }, &fs);
363
364 VkPipelineVertexInputStateCreateInfo vi_create_info = {
365 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
366 .bindingCount = 2,
367 .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) {
368 {
369 .binding = 0,
370 .strideInBytes = 0,
371 .stepRate = VK_VERTEX_INPUT_STEP_RATE_VERTEX
372 },
373 {
374 .binding = 1,
375 .strideInBytes = 16,
376 .stepRate = VK_VERTEX_INPUT_STEP_RATE_VERTEX
377 },
378 },
379 .attributeCount = 3,
380 .pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[]) {
381 {
382 /* VUE Header */
383 .location = 0,
384 .binding = 0,
385 .format = VK_FORMAT_R32G32B32A32_UINT,
386 .offsetInBytes = 0
387 },
388 {
389 /* Position */
390 .location = 1,
391 .binding = 1,
392 .format = VK_FORMAT_R32G32_SFLOAT,
393 .offsetInBytes = 0
394 },
395 {
396 /* Texture Coordinate */
397 .location = 2,
398 .binding = 1,
399 .format = VK_FORMAT_R32G32_SFLOAT,
400 .offsetInBytes = 8
401 }
402 }
403 };
404
405 VkDescriptorSetLayoutCreateInfo ds_layout_info = {
406 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
407 .count = 1,
408 .pBinding = (VkDescriptorSetLayoutBinding[]) {
409 {
410 .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
411 .arraySize = 1,
412 .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
413 .pImmutableSamplers = NULL
414 },
415 }
416 };
417 anv_CreateDescriptorSetLayout(anv_device_to_handle(device), &ds_layout_info,
418 &device->meta_state.blit.ds_layout);
419
420 anv_CreatePipelineLayout(anv_device_to_handle(device),
421 &(VkPipelineLayoutCreateInfo) {
422 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
423 .descriptorSetCount = 1,
424 .pSetLayouts = &device->meta_state.blit.ds_layout,
425 },
426 &device->meta_state.blit.pipeline_layout);
427
428 anv_pipeline_create(anv_device_to_handle(device),
429 &(VkGraphicsPipelineCreateInfo) {
430 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
431 .stageCount = 2,
432 .pStages = (VkPipelineShaderStageCreateInfo[]) {
433 {
434 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
435 .stage = VK_SHADER_STAGE_VERTEX,
436 .shader = vs,
437 .pSpecializationInfo = NULL
438 }, {
439 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
440 .stage = VK_SHADER_STAGE_FRAGMENT,
441 .shader = fs,
442 .pSpecializationInfo = NULL
443 },
444 },
445 .pVertexInputState = &vi_create_info,
446 .pInputAssemblyState = &(VkPipelineInputAssemblyStateCreateInfo) {
447 .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
448 .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
449 .primitiveRestartEnable = false,
450 },
451 .pRasterState = &(VkPipelineRasterStateCreateInfo) {
452 .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTER_STATE_CREATE_INFO,
453 .depthClipEnable = true,
454 .rasterizerDiscardEnable = false,
455 .fillMode = VK_FILL_MODE_SOLID,
456 .cullMode = VK_CULL_MODE_NONE,
457 .frontFace = VK_FRONT_FACE_CCW
458 },
459 .pColorBlendState = &(VkPipelineColorBlendStateCreateInfo) {
460 .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
461 .attachmentCount = 1,
462 .pAttachments = (VkPipelineColorBlendAttachmentState []) {
463 { .channelWriteMask = VK_CHANNEL_A_BIT |
464 VK_CHANNEL_R_BIT | VK_CHANNEL_G_BIT | VK_CHANNEL_B_BIT },
465 }
466 },
467 .flags = 0,
468 .layout = device->meta_state.blit.pipeline_layout,
469 },
470 &(struct anv_pipeline_create_info) {
471 .use_repclear = false,
472 .disable_viewport = true,
473 .disable_scissor = true,
474 .disable_vs = true,
475 .use_rectlist = true
476 },
477 &device->meta_state.blit.pipeline);
478
479 anv_DestroyShader(anv_device_to_handle(device), vs);
480 anv_DestroyShader(anv_device_to_handle(device), fs);
481 }
482
483 static void
484 meta_prepare_blit(struct anv_cmd_buffer *cmd_buffer,
485 struct anv_saved_state *saved_state)
486 {
487 struct anv_device *device = cmd_buffer->device;
488
489 anv_cmd_buffer_save(cmd_buffer, saved_state);
490
491 if (cmd_buffer->state.pipeline != anv_pipeline_from_handle(device->meta_state.blit.pipeline))
492 anv_CmdBindPipeline(anv_cmd_buffer_to_handle(cmd_buffer),
493 VK_PIPELINE_BIND_POINT_GRAPHICS,
494 device->meta_state.blit.pipeline);
495
496 /* We don't need anything here, only set if not already set. */
497 if (cmd_buffer->state.rs_state == NULL)
498 anv_CmdBindDynamicRasterState(anv_cmd_buffer_to_handle(cmd_buffer),
499 device->meta_state.shared.rs_state);
500 if (cmd_buffer->state.ds_state == NULL)
501 anv_CmdBindDynamicDepthStencilState(anv_cmd_buffer_to_handle(cmd_buffer),
502 device->meta_state.shared.ds_state);
503
504 saved_state->cb_state = anv_dynamic_cb_state_to_handle(cmd_buffer->state.cb_state);
505 anv_CmdBindDynamicColorBlendState(anv_cmd_buffer_to_handle(cmd_buffer),
506 device->meta_state.shared.cb_state);
507 }
508
509 struct blit_region {
510 VkOffset3D src_offset;
511 VkExtent3D src_extent;
512 VkOffset3D dest_offset;
513 VkExtent3D dest_extent;
514 };
515
516 static void
517 meta_emit_blit(struct anv_cmd_buffer *cmd_buffer,
518 struct anv_image_view *src,
519 VkOffset3D src_offset,
520 VkExtent3D src_extent,
521 struct anv_color_attachment_view *dest,
522 VkOffset3D dest_offset,
523 VkExtent3D dest_extent)
524 {
525 struct anv_device *device = cmd_buffer->device;
526 VkDescriptorPool dummy_desc_pool = { .handle = 1 };
527
528 struct blit_vb_data {
529 float pos[2];
530 float tex_coord[2];
531 } *vb_data;
532
533 unsigned vb_size = sizeof(struct vue_header) + 3 * sizeof(*vb_data);
534
535 struct anv_state vb_state =
536 anv_state_stream_alloc(&cmd_buffer->surface_state_stream, vb_size, 16);
537 memset(vb_state.map, 0, sizeof(struct vue_header));
538 vb_data = vb_state.map + sizeof(struct vue_header);
539
540 vb_data[0] = (struct blit_vb_data) {
541 .pos = {
542 dest_offset.x + dest_extent.width,
543 dest_offset.y + dest_extent.height,
544 },
545 .tex_coord = {
546 (float)(src_offset.x + src_extent.width) / (float)src->extent.width,
547 (float)(src_offset.y + src_extent.height) / (float)src->extent.height,
548 },
549 };
550
551 vb_data[1] = (struct blit_vb_data) {
552 .pos = {
553 dest_offset.x,
554 dest_offset.y + dest_extent.height,
555 },
556 .tex_coord = {
557 (float)src_offset.x / (float)src->extent.width,
558 (float)(src_offset.y + src_extent.height) / (float)src->extent.height,
559 },
560 };
561
562 vb_data[2] = (struct blit_vb_data) {
563 .pos = {
564 dest_offset.x,
565 dest_offset.y,
566 },
567 .tex_coord = {
568 (float)src_offset.x / (float)src->extent.width,
569 (float)src_offset.y / (float)src->extent.height,
570 },
571 };
572
573 struct anv_buffer vertex_buffer = {
574 .device = device,
575 .size = vb_size,
576 .bo = &device->surface_state_block_pool.bo,
577 .offset = vb_state.offset,
578 };
579
580 anv_CmdBindVertexBuffers(anv_cmd_buffer_to_handle(cmd_buffer), 0, 2,
581 (VkBuffer[]) {
582 anv_buffer_to_handle(&vertex_buffer),
583 anv_buffer_to_handle(&vertex_buffer)
584 },
585 (VkDeviceSize[]) {
586 0,
587 sizeof(struct vue_header),
588 });
589
590 uint32_t count;
591 VkDescriptorSet set;
592 anv_AllocDescriptorSets(anv_device_to_handle(device), dummy_desc_pool,
593 VK_DESCRIPTOR_SET_USAGE_ONE_SHOT,
594 1, &device->meta_state.blit.ds_layout, &set, &count);
595 anv_UpdateDescriptorSets(anv_device_to_handle(device),
596 1, /* writeCount */
597 (VkWriteDescriptorSet[]) {
598 {
599 .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
600 .destSet = set,
601 .destBinding = 0,
602 .destArrayElement = 0,
603 .count = 1,
604 .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
605 .pDescriptors = (VkDescriptorInfo[]) {
606 {
607 .imageView = anv_image_view_to_handle(src),
608 .imageLayout = VK_IMAGE_LAYOUT_GENERAL
609 },
610 }
611 }
612 }, 0, NULL);
613
614 VkFramebuffer fb;
615 anv_CreateFramebuffer(anv_device_to_handle(device),
616 &(VkFramebufferCreateInfo) {
617 .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
618 .attachmentCount = 1,
619 .pAttachments = (VkAttachmentBindInfo[]) {
620 {
621 .view = anv_attachment_view_to_handle(&dest->base),
622 .layout = VK_IMAGE_LAYOUT_GENERAL
623 }
624 },
625 .width = dest->base.extent.width,
626 .height = dest->base.extent.height,
627 .layers = 1
628 }, &fb);
629
630 VkRenderPass pass;
631 anv_CreateRenderPass(anv_device_to_handle(device),
632 &(VkRenderPassCreateInfo) {
633 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
634 .attachmentCount = 1,
635 .pAttachments = &(VkAttachmentDescription) {
636 .sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION,
637 .format = dest->view.format,
638 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
639 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
640 .initialLayout = VK_IMAGE_LAYOUT_GENERAL,
641 .finalLayout = VK_IMAGE_LAYOUT_GENERAL,
642 },
643 .subpassCount = 1,
644 .pSubpasses = &(VkSubpassDescription) {
645 .sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION,
646 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
647 .inputCount = 0,
648 .colorCount = 1,
649 .colorAttachments = &(VkAttachmentReference) {
650 .attachment = 0,
651 .layout = VK_IMAGE_LAYOUT_GENERAL,
652 },
653 .resolveAttachments = NULL,
654 .depthStencilAttachment = (VkAttachmentReference) {
655 .attachment = VK_ATTACHMENT_UNUSED,
656 .layout = VK_IMAGE_LAYOUT_GENERAL,
657 },
658 .preserveCount = 1,
659 .preserveAttachments = &(VkAttachmentReference) {
660 .attachment = 0,
661 .layout = VK_IMAGE_LAYOUT_GENERAL,
662 },
663 },
664 .dependencyCount = 0,
665 }, &pass);
666
667 anv_CmdBeginRenderPass(anv_cmd_buffer_to_handle(cmd_buffer),
668 &(VkRenderPassBeginInfo) {
669 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
670 .renderPass = pass,
671 .framebuffer = fb,
672 .renderArea = {
673 .offset = { dest_offset.x, dest_offset.y },
674 .extent = { dest_extent.width, dest_extent.height },
675 },
676 .attachmentCount = 1,
677 .pAttachmentClearValues = NULL,
678 }, VK_RENDER_PASS_CONTENTS_INLINE);
679
680 anv_CmdBindDynamicViewportState(anv_cmd_buffer_to_handle(cmd_buffer),
681 anv_framebuffer_from_handle(fb)->vp_state);
682
683 anv_CmdBindDescriptorSets(anv_cmd_buffer_to_handle(cmd_buffer),
684 VK_PIPELINE_BIND_POINT_GRAPHICS,
685 device->meta_state.blit.pipeline_layout, 0, 1,
686 &set, 0, NULL);
687
688 anv_CmdDraw(anv_cmd_buffer_to_handle(cmd_buffer), 0, 3, 0, 1);
689
690 anv_CmdEndRenderPass(anv_cmd_buffer_to_handle(cmd_buffer));
691
692 /* At the point where we emit the draw call, all data from the
693 * descriptor sets, etc. has been used. We are free to delete it.
694 */
695 anv_descriptor_set_destroy(device, anv_descriptor_set_from_handle(set));
696 anv_DestroyFramebuffer(anv_device_to_handle(device), fb);
697 anv_DestroyRenderPass(anv_device_to_handle(device), pass);
698 }
699
700 static void
701 meta_finish_blit(struct anv_cmd_buffer *cmd_buffer,
702 const struct anv_saved_state *saved_state)
703 {
704 anv_cmd_buffer_restore(cmd_buffer, saved_state);
705 anv_CmdBindDynamicColorBlendState(anv_cmd_buffer_to_handle(cmd_buffer),
706 saved_state->cb_state);
707 }
708
709 static VkFormat
710 vk_format_for_cpp(int cpp)
711 {
712 switch (cpp) {
713 case 1: return VK_FORMAT_R8_UINT;
714 case 2: return VK_FORMAT_R8G8_UINT;
715 case 3: return VK_FORMAT_R8G8B8_UINT;
716 case 4: return VK_FORMAT_R8G8B8A8_UINT;
717 case 6: return VK_FORMAT_R16G16B16_UINT;
718 case 8: return VK_FORMAT_R16G16B16A16_UINT;
719 case 12: return VK_FORMAT_R32G32B32_UINT;
720 case 16: return VK_FORMAT_R32G32B32A32_UINT;
721 default:
722 unreachable("Invalid format cpp");
723 }
724 }
725
726 static void
727 do_buffer_copy(struct anv_cmd_buffer *cmd_buffer,
728 struct anv_bo *src, uint64_t src_offset,
729 struct anv_bo *dest, uint64_t dest_offset,
730 int width, int height, VkFormat copy_format)
731 {
732 VkDevice vk_device = anv_device_to_handle(cmd_buffer->device);
733
734 VkImageCreateInfo image_info = {
735 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
736 .imageType = VK_IMAGE_TYPE_2D,
737 .format = copy_format,
738 .extent = {
739 .width = width,
740 .height = height,
741 .depth = 1,
742 },
743 .mipLevels = 1,
744 .arraySize = 1,
745 .samples = 1,
746 .tiling = VK_IMAGE_TILING_LINEAR,
747 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
748 .flags = 0,
749 };
750
751 VkImage src_image, dest_image;
752 anv_CreateImage(vk_device, &image_info, &src_image);
753 anv_CreateImage(vk_device, &image_info, &dest_image);
754
755 /* We could use a vk call to bind memory, but that would require
756 * creating a dummy memory object etc. so there's really no point.
757 */
758 anv_image_from_handle(src_image)->bo = src;
759 anv_image_from_handle(src_image)->offset = src_offset;
760 anv_image_from_handle(dest_image)->bo = dest;
761 anv_image_from_handle(dest_image)->offset = dest_offset;
762
763 struct anv_image_view src_view;
764 anv_image_view_init(&src_view, cmd_buffer->device,
765 &(VkImageViewCreateInfo) {
766 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
767 .image = src_image,
768 .viewType = VK_IMAGE_VIEW_TYPE_2D,
769 .format = copy_format,
770 .channels = {
771 VK_CHANNEL_SWIZZLE_R,
772 VK_CHANNEL_SWIZZLE_G,
773 VK_CHANNEL_SWIZZLE_B,
774 VK_CHANNEL_SWIZZLE_A
775 },
776 .subresourceRange = {
777 .aspect = VK_IMAGE_ASPECT_COLOR,
778 .baseMipLevel = 0,
779 .mipLevels = 1,
780 .baseArraySlice = 0,
781 .arraySize = 1
782 },
783 },
784 cmd_buffer);
785
786 struct anv_color_attachment_view dest_view;
787 anv_color_attachment_view_init(&dest_view, cmd_buffer->device,
788 &(VkAttachmentViewCreateInfo) {
789 .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO,
790 .image = dest_image,
791 .format = copy_format,
792 .mipLevel = 0,
793 .baseArraySlice = 0,
794 .arraySize = 1,
795 },
796 cmd_buffer);
797
798 meta_emit_blit(cmd_buffer,
799 &src_view,
800 (VkOffset3D) { 0, 0, 0 },
801 (VkExtent3D) { width, height, 1 },
802 &dest_view,
803 (VkOffset3D) { 0, 0, 0 },
804 (VkExtent3D) { width, height, 1 });
805
806 anv_DestroyImage(vk_device, src_image);
807 anv_DestroyImage(vk_device, dest_image);
808 }
809
810 void anv_CmdCopyBuffer(
811 VkCmdBuffer cmdBuffer,
812 VkBuffer srcBuffer,
813 VkBuffer destBuffer,
814 uint32_t regionCount,
815 const VkBufferCopy* pRegions)
816 {
817 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
818 ANV_FROM_HANDLE(anv_buffer, src_buffer, srcBuffer);
819 ANV_FROM_HANDLE(anv_buffer, dest_buffer, destBuffer);
820
821 struct anv_saved_state saved_state;
822
823 meta_prepare_blit(cmd_buffer, &saved_state);
824
825 for (unsigned r = 0; r < regionCount; r++) {
826 uint64_t src_offset = src_buffer->offset + pRegions[r].srcOffset;
827 uint64_t dest_offset = dest_buffer->offset + pRegions[r].destOffset;
828 uint64_t copy_size = pRegions[r].copySize;
829
830 /* First, we compute the biggest format that can be used with the
831 * given offsets and size.
832 */
833 int cpp = 16;
834
835 int fs = ffs(src_offset) - 1;
836 if (fs != -1)
837 cpp = MIN2(cpp, 1 << fs);
838 assert(src_offset % cpp == 0);
839
840 fs = ffs(dest_offset) - 1;
841 if (fs != -1)
842 cpp = MIN2(cpp, 1 << fs);
843 assert(dest_offset % cpp == 0);
844
845 fs = ffs(pRegions[r].copySize) - 1;
846 if (fs != -1)
847 cpp = MIN2(cpp, 1 << fs);
848 assert(pRegions[r].copySize % cpp == 0);
849
850 VkFormat copy_format = vk_format_for_cpp(cpp);
851
852 /* This is maximum possible width/height our HW can handle */
853 uint64_t max_surface_dim = 1 << 14;
854
855 /* First, we make a bunch of max-sized copies */
856 uint64_t max_copy_size = max_surface_dim * max_surface_dim * cpp;
857 while (copy_size > max_copy_size) {
858 do_buffer_copy(cmd_buffer, src_buffer->bo, src_offset,
859 dest_buffer->bo, dest_offset,
860 max_surface_dim, max_surface_dim, copy_format);
861 copy_size -= max_copy_size;
862 src_offset += max_copy_size;
863 dest_offset += max_copy_size;
864 }
865
866 uint64_t height = copy_size / (max_surface_dim * cpp);
867 assert(height < max_surface_dim);
868 if (height != 0) {
869 uint64_t rect_copy_size = height * max_surface_dim * cpp;
870 do_buffer_copy(cmd_buffer, src_buffer->bo, src_offset,
871 dest_buffer->bo, dest_offset,
872 max_surface_dim, height, copy_format);
873 copy_size -= rect_copy_size;
874 src_offset += rect_copy_size;
875 dest_offset += rect_copy_size;
876 }
877
878 if (copy_size != 0) {
879 do_buffer_copy(cmd_buffer, src_buffer->bo, src_offset,
880 dest_buffer->bo, dest_offset,
881 copy_size / cpp, 1, copy_format);
882 }
883 }
884
885 meta_finish_blit(cmd_buffer, &saved_state);
886 }
887
888 void anv_CmdCopyImage(
889 VkCmdBuffer cmdBuffer,
890 VkImage srcImage,
891 VkImageLayout srcImageLayout,
892 VkImage destImage,
893 VkImageLayout destImageLayout,
894 uint32_t regionCount,
895 const VkImageCopy* pRegions)
896 {
897 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
898 ANV_FROM_HANDLE(anv_image, src_image, srcImage);
899
900 struct anv_saved_state saved_state;
901
902 meta_prepare_blit(cmd_buffer, &saved_state);
903
904 for (unsigned r = 0; r < regionCount; r++) {
905 struct anv_image_view src_view;
906 anv_image_view_init(&src_view, cmd_buffer->device,
907 &(VkImageViewCreateInfo) {
908 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
909 .image = srcImage,
910 .viewType = VK_IMAGE_VIEW_TYPE_2D,
911 .format = src_image->format,
912 .channels = {
913 VK_CHANNEL_SWIZZLE_R,
914 VK_CHANNEL_SWIZZLE_G,
915 VK_CHANNEL_SWIZZLE_B,
916 VK_CHANNEL_SWIZZLE_A
917 },
918 .subresourceRange = {
919 .aspect = pRegions[r].srcSubresource.aspect,
920 .baseMipLevel = pRegions[r].srcSubresource.mipLevel,
921 .mipLevels = 1,
922 .baseArraySlice = pRegions[r].srcSubresource.arraySlice,
923 .arraySize = 1
924 },
925 },
926 cmd_buffer);
927
928 struct anv_color_attachment_view dest_view;
929 anv_color_attachment_view_init(&dest_view, cmd_buffer->device,
930 &(VkAttachmentViewCreateInfo) {
931 .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO,
932 .image = destImage,
933 .format = src_image->format,
934 .mipLevel = pRegions[r].destSubresource.mipLevel,
935 .baseArraySlice = pRegions[r].destSubresource.arraySlice,
936 .arraySize = 1,
937 },
938 cmd_buffer);
939
940 meta_emit_blit(cmd_buffer,
941 &src_view,
942 pRegions[r].srcOffset,
943 pRegions[r].extent,
944 &dest_view,
945 pRegions[r].destOffset,
946 pRegions[r].extent);
947 }
948
949 meta_finish_blit(cmd_buffer, &saved_state);
950 }
951
952 void anv_CmdBlitImage(
953 VkCmdBuffer cmdBuffer,
954 VkImage srcImage,
955 VkImageLayout srcImageLayout,
956 VkImage destImage,
957 VkImageLayout destImageLayout,
958 uint32_t regionCount,
959 const VkImageBlit* pRegions,
960 VkTexFilter filter)
961
962 {
963 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
964 ANV_FROM_HANDLE(anv_image, src_image, srcImage);
965 ANV_FROM_HANDLE(anv_image, dest_image, destImage);
966
967 struct anv_saved_state saved_state;
968
969 anv_finishme("respect VkTexFilter");
970
971 meta_prepare_blit(cmd_buffer, &saved_state);
972
973 for (unsigned r = 0; r < regionCount; r++) {
974 struct anv_image_view src_view;
975 anv_image_view_init(&src_view, cmd_buffer->device,
976 &(VkImageViewCreateInfo) {
977 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
978 .image = srcImage,
979 .viewType = VK_IMAGE_VIEW_TYPE_2D,
980 .format = src_image->format,
981 .channels = {
982 VK_CHANNEL_SWIZZLE_R,
983 VK_CHANNEL_SWIZZLE_G,
984 VK_CHANNEL_SWIZZLE_B,
985 VK_CHANNEL_SWIZZLE_A
986 },
987 .subresourceRange = {
988 .aspect = pRegions[r].srcSubresource.aspect,
989 .baseMipLevel = pRegions[r].srcSubresource.mipLevel,
990 .mipLevels = 1,
991 .baseArraySlice = pRegions[r].srcSubresource.arraySlice,
992 .arraySize = 1
993 },
994 },
995 cmd_buffer);
996
997 struct anv_color_attachment_view dest_view;
998 anv_color_attachment_view_init(&dest_view, cmd_buffer->device,
999 &(VkAttachmentViewCreateInfo) {
1000 .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO,
1001 .image = destImage,
1002 .format = dest_image->format,
1003 .mipLevel = pRegions[r].destSubresource.mipLevel,
1004 .baseArraySlice = pRegions[r].destSubresource.arraySlice,
1005 .arraySize = 1,
1006 },
1007 cmd_buffer);
1008
1009 meta_emit_blit(cmd_buffer,
1010 &src_view,
1011 pRegions[r].srcOffset,
1012 pRegions[r].srcExtent,
1013 &dest_view,
1014 pRegions[r].destOffset,
1015 pRegions[r].destExtent);
1016 }
1017
1018 meta_finish_blit(cmd_buffer, &saved_state);
1019 }
1020
1021 void anv_CmdCopyBufferToImage(
1022 VkCmdBuffer cmdBuffer,
1023 VkBuffer srcBuffer,
1024 VkImage destImage,
1025 VkImageLayout destImageLayout,
1026 uint32_t regionCount,
1027 const VkBufferImageCopy* pRegions)
1028 {
1029 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
1030 ANV_FROM_HANDLE(anv_buffer, src_buffer, srcBuffer);
1031 ANV_FROM_HANDLE(anv_image, dest_image, destImage);
1032 VkDevice vk_device = anv_device_to_handle(cmd_buffer->device);
1033 struct anv_saved_state saved_state;
1034
1035 meta_prepare_blit(cmd_buffer, &saved_state);
1036
1037 for (unsigned r = 0; r < regionCount; r++) {
1038 if (pRegions[r].bufferRowLength != 0)
1039 anv_finishme("bufferRowLength not supported in CopyBufferToImage");
1040 if (pRegions[r].bufferImageHeight != 0)
1041 anv_finishme("bufferImageHeight not supported in CopyBufferToImage");
1042
1043 VkImage srcImage;
1044 anv_CreateImage(vk_device,
1045 &(VkImageCreateInfo) {
1046 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
1047 .imageType = VK_IMAGE_TYPE_2D,
1048 .format = dest_image->format,
1049 .extent = {
1050 .width = pRegions[r].imageExtent.width,
1051 .height = pRegions[r].imageExtent.height,
1052 .depth = 1,
1053 },
1054 .mipLevels = 1,
1055 .arraySize = 1,
1056 .samples = 1,
1057 .tiling = VK_IMAGE_TILING_LINEAR,
1058 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
1059 .flags = 0,
1060 }, &srcImage);
1061
1062 ANV_FROM_HANDLE(anv_image, src_image, srcImage);
1063
1064 /* We could use a vk call to bind memory, but that would require
1065 * creating a dummy memory object etc. so there's really no point.
1066 */
1067 src_image->bo = src_buffer->bo;
1068 src_image->offset = src_buffer->offset + pRegions[r].bufferOffset;
1069
1070 struct anv_image_view src_view;
1071 anv_image_view_init(&src_view, cmd_buffer->device,
1072 &(VkImageViewCreateInfo) {
1073 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
1074 .image = anv_image_to_handle(src_image),
1075 .viewType = VK_IMAGE_VIEW_TYPE_2D,
1076 .format = dest_image->format,
1077 .channels = {
1078 VK_CHANNEL_SWIZZLE_R,
1079 VK_CHANNEL_SWIZZLE_G,
1080 VK_CHANNEL_SWIZZLE_B,
1081 VK_CHANNEL_SWIZZLE_A
1082 },
1083 .subresourceRange = {
1084 .aspect = pRegions[r].imageSubresource.aspect,
1085 .baseMipLevel = 0,
1086 .mipLevels = 1,
1087 .baseArraySlice = 0,
1088 .arraySize = 1
1089 },
1090 },
1091 cmd_buffer);
1092
1093 struct anv_color_attachment_view dest_view;
1094 anv_color_attachment_view_init(&dest_view, cmd_buffer->device,
1095 &(VkAttachmentViewCreateInfo) {
1096 .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO,
1097 .image = anv_image_to_handle(dest_image),
1098 .format = dest_image->format,
1099 .mipLevel = pRegions[r].imageSubresource.mipLevel,
1100 .baseArraySlice = pRegions[r].imageSubresource.arraySlice,
1101 .arraySize = 1,
1102 },
1103 cmd_buffer);
1104
1105 meta_emit_blit(cmd_buffer,
1106 &src_view,
1107 (VkOffset3D) { 0, 0, 0 },
1108 pRegions[r].imageExtent,
1109 &dest_view,
1110 pRegions[r].imageOffset,
1111 pRegions[r].imageExtent);
1112
1113 anv_DestroyImage(vk_device, srcImage);
1114 }
1115
1116 meta_finish_blit(cmd_buffer, &saved_state);
1117 }
1118
1119 void anv_CmdCopyImageToBuffer(
1120 VkCmdBuffer cmdBuffer,
1121 VkImage srcImage,
1122 VkImageLayout srcImageLayout,
1123 VkBuffer destBuffer,
1124 uint32_t regionCount,
1125 const VkBufferImageCopy* pRegions)
1126 {
1127 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
1128 ANV_FROM_HANDLE(anv_image, src_image, srcImage);
1129 ANV_FROM_HANDLE(anv_buffer, dest_buffer, destBuffer);
1130 VkDevice vk_device = anv_device_to_handle(cmd_buffer->device);
1131 struct anv_saved_state saved_state;
1132
1133 meta_prepare_blit(cmd_buffer, &saved_state);
1134
1135 for (unsigned r = 0; r < regionCount; r++) {
1136 if (pRegions[r].bufferRowLength != 0)
1137 anv_finishme("bufferRowLength not supported in CopyBufferToImage");
1138 if (pRegions[r].bufferImageHeight != 0)
1139 anv_finishme("bufferImageHeight not supported in CopyBufferToImage");
1140
1141 struct anv_image_view src_view;
1142 anv_image_view_init(&src_view, cmd_buffer->device,
1143 &(VkImageViewCreateInfo) {
1144 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
1145 .image = srcImage,
1146 .viewType = VK_IMAGE_VIEW_TYPE_2D,
1147 .format = src_image->format,
1148 .channels = {
1149 VK_CHANNEL_SWIZZLE_R,
1150 VK_CHANNEL_SWIZZLE_G,
1151 VK_CHANNEL_SWIZZLE_B,
1152 VK_CHANNEL_SWIZZLE_A
1153 },
1154 .subresourceRange = {
1155 .aspect = pRegions[r].imageSubresource.aspect,
1156 .baseMipLevel = pRegions[r].imageSubresource.mipLevel,
1157 .mipLevels = 1,
1158 .baseArraySlice = pRegions[r].imageSubresource.arraySlice,
1159 .arraySize = 1
1160 },
1161 },
1162 cmd_buffer);
1163
1164 VkImage destImage;
1165 anv_CreateImage(vk_device,
1166 &(VkImageCreateInfo) {
1167 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
1168 .imageType = VK_IMAGE_TYPE_2D,
1169 .format = src_image->format,
1170 .extent = {
1171 .width = pRegions[r].imageExtent.width,
1172 .height = pRegions[r].imageExtent.height,
1173 .depth = 1,
1174 },
1175 .mipLevels = 1,
1176 .arraySize = 1,
1177 .samples = 1,
1178 .tiling = VK_IMAGE_TILING_LINEAR,
1179 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
1180 .flags = 0,
1181 }, &destImage);
1182
1183 ANV_FROM_HANDLE(anv_image, dest_image, destImage);
1184
1185 /* We could use a vk call to bind memory, but that would require
1186 * creating a dummy memory object etc. so there's really no point.
1187 */
1188 dest_image->bo = dest_buffer->bo;
1189 dest_image->offset = dest_buffer->offset + pRegions[r].bufferOffset;
1190
1191 struct anv_color_attachment_view dest_view;
1192 anv_color_attachment_view_init(&dest_view, cmd_buffer->device,
1193 &(VkAttachmentViewCreateInfo) {
1194 .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO,
1195 .image = destImage,
1196 .format = src_image->format,
1197 .mipLevel = 0,
1198 .baseArraySlice = 0,
1199 .arraySize = 1,
1200 },
1201 cmd_buffer);
1202
1203 meta_emit_blit(cmd_buffer,
1204 &src_view,
1205 pRegions[r].imageOffset,
1206 pRegions[r].imageExtent,
1207 &dest_view,
1208 (VkOffset3D) { 0, 0, 0 },
1209 pRegions[r].imageExtent);
1210
1211 anv_DestroyImage(vk_device, destImage);
1212 }
1213
1214 meta_finish_blit(cmd_buffer, &saved_state);
1215 }
1216
1217 void anv_CmdUpdateBuffer(
1218 VkCmdBuffer cmdBuffer,
1219 VkBuffer destBuffer,
1220 VkDeviceSize destOffset,
1221 VkDeviceSize dataSize,
1222 const uint32_t* pData)
1223 {
1224 stub();
1225 }
1226
1227 void anv_CmdFillBuffer(
1228 VkCmdBuffer cmdBuffer,
1229 VkBuffer destBuffer,
1230 VkDeviceSize destOffset,
1231 VkDeviceSize fillSize,
1232 uint32_t data)
1233 {
1234 stub();
1235 }
1236
1237 void anv_CmdClearColorImage(
1238 VkCmdBuffer cmdBuffer,
1239 VkImage _image,
1240 VkImageLayout imageLayout,
1241 const VkClearColorValue* pColor,
1242 uint32_t rangeCount,
1243 const VkImageSubresourceRange* pRanges)
1244 {
1245 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
1246 ANV_FROM_HANDLE(anv_image, image, _image);
1247 struct anv_saved_state saved_state;
1248
1249 anv_cmd_buffer_save(cmd_buffer, &saved_state);
1250
1251 for (uint32_t r = 0; r < rangeCount; r++) {
1252 for (uint32_t l = 0; l < pRanges[r].mipLevels; l++) {
1253 for (uint32_t s = 0; s < pRanges[r].arraySize; s++) {
1254 struct anv_color_attachment_view view;
1255 anv_color_attachment_view_init(&view, cmd_buffer->device,
1256 &(VkAttachmentViewCreateInfo) {
1257 .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO,
1258 .image = _image,
1259 .format = image->format,
1260 .mipLevel = pRanges[r].baseMipLevel + l,
1261 .baseArraySlice = pRanges[r].baseArraySlice + s,
1262 .arraySize = 1,
1263 },
1264 cmd_buffer);
1265
1266 VkFramebuffer fb;
1267 anv_CreateFramebuffer(anv_device_to_handle(cmd_buffer->device),
1268 &(VkFramebufferCreateInfo) {
1269 .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
1270 .attachmentCount = 1,
1271 .pAttachments = (VkAttachmentBindInfo[]) {
1272 {
1273 .view = anv_attachment_view_to_handle(&view.base),
1274 .layout = VK_IMAGE_LAYOUT_GENERAL
1275 }
1276 },
1277 .width = view.base.extent.width,
1278 .height = view.base.extent.height,
1279 .layers = 1
1280 }, &fb);
1281
1282 VkRenderPass pass;
1283 anv_CreateRenderPass(anv_device_to_handle(cmd_buffer->device),
1284 &(VkRenderPassCreateInfo) {
1285 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
1286 .attachmentCount = 1,
1287 .pAttachments = &(VkAttachmentDescription) {
1288 .sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION,
1289 .format = view.view.format,
1290 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
1291 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
1292 .initialLayout = VK_IMAGE_LAYOUT_GENERAL,
1293 .finalLayout = VK_IMAGE_LAYOUT_GENERAL,
1294 },
1295 .subpassCount = 1,
1296 .pSubpasses = &(VkSubpassDescription) {
1297 .sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION,
1298 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
1299 .inputCount = 0,
1300 .colorCount = 1,
1301 .colorAttachments = &(VkAttachmentReference) {
1302 .attachment = 0,
1303 .layout = VK_IMAGE_LAYOUT_GENERAL,
1304 },
1305 .resolveAttachments = NULL,
1306 .depthStencilAttachment = (VkAttachmentReference) {
1307 .attachment = VK_ATTACHMENT_UNUSED,
1308 .layout = VK_IMAGE_LAYOUT_GENERAL,
1309 },
1310 .preserveCount = 1,
1311 .preserveAttachments = &(VkAttachmentReference) {
1312 .attachment = 0,
1313 .layout = VK_IMAGE_LAYOUT_GENERAL,
1314 },
1315 },
1316 .dependencyCount = 0,
1317 }, &pass);
1318
1319 anv_CmdBeginRenderPass(anv_cmd_buffer_to_handle(cmd_buffer),
1320 &(VkRenderPassBeginInfo) {
1321 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
1322 .renderArea = {
1323 .offset = { 0, 0, },
1324 .extent = {
1325 .width = view.base.extent.width,
1326 .height = view.base.extent.height,
1327 },
1328 },
1329 .renderPass = pass,
1330 .framebuffer = fb,
1331 .attachmentCount = 1,
1332 .pAttachmentClearValues = NULL,
1333 }, VK_RENDER_PASS_CONTENTS_INLINE);
1334
1335 struct clear_instance_data instance_data = {
1336 .vue_header = {
1337 .RTAIndex = 0,
1338 .ViewportIndex = 0,
1339 .PointWidth = 0.0
1340 },
1341 .color = *pColor,
1342 };
1343
1344 meta_emit_clear(cmd_buffer, 1, &instance_data);
1345
1346 anv_CmdEndRenderPass(anv_cmd_buffer_to_handle(cmd_buffer));
1347 }
1348 }
1349 }
1350
1351 /* Restore API state */
1352 anv_cmd_buffer_restore(cmd_buffer, &saved_state);
1353 }
1354
1355 void anv_CmdClearDepthStencilImage(
1356 VkCmdBuffer cmdBuffer,
1357 VkImage image,
1358 VkImageLayout imageLayout,
1359 float depth,
1360 uint32_t stencil,
1361 uint32_t rangeCount,
1362 const VkImageSubresourceRange* pRanges)
1363 {
1364 stub();
1365 }
1366
1367 void anv_CmdClearColorAttachment(
1368 VkCmdBuffer cmdBuffer,
1369 uint32_t colorAttachment,
1370 VkImageLayout imageLayout,
1371 const VkClearColorValue* pColor,
1372 uint32_t rectCount,
1373 const VkRect3D* pRects)
1374 {
1375 stub();
1376 }
1377
1378 void anv_CmdClearDepthStencilAttachment(
1379 VkCmdBuffer cmdBuffer,
1380 VkImageAspectFlags imageAspectMask,
1381 VkImageLayout imageLayout,
1382 float depth,
1383 uint32_t stencil,
1384 uint32_t rectCount,
1385 const VkRect3D* pRects)
1386 {
1387 stub();
1388 }
1389
1390 void anv_CmdResolveImage(
1391 VkCmdBuffer cmdBuffer,
1392 VkImage srcImage,
1393 VkImageLayout srcImageLayout,
1394 VkImage destImage,
1395 VkImageLayout destImageLayout,
1396 uint32_t regionCount,
1397 const VkImageResolve* pRegions)
1398 {
1399 stub();
1400 }
1401
1402 void
1403 anv_device_init_meta(struct anv_device *device)
1404 {
1405 anv_device_init_meta_clear_state(device);
1406 anv_device_init_meta_blit_state(device);
1407
1408 anv_CreateDynamicRasterState(anv_device_to_handle(device),
1409 &(VkDynamicRasterStateCreateInfo) {
1410 .sType = VK_STRUCTURE_TYPE_DYNAMIC_RASTER_STATE_CREATE_INFO,
1411 },
1412 &device->meta_state.shared.rs_state);
1413
1414 anv_CreateDynamicColorBlendState(anv_device_to_handle(device),
1415 &(VkDynamicColorBlendStateCreateInfo) {
1416 .sType = VK_STRUCTURE_TYPE_DYNAMIC_COLOR_BLEND_STATE_CREATE_INFO
1417 },
1418 &device->meta_state.shared.cb_state);
1419
1420 anv_CreateDynamicDepthStencilState(anv_device_to_handle(device),
1421 &(VkDynamicDepthStencilStateCreateInfo) {
1422 .sType = VK_STRUCTURE_TYPE_DYNAMIC_DEPTH_STENCIL_STATE_CREATE_INFO
1423 },
1424 &device->meta_state.shared.ds_state);
1425 }
1426
1427 void
1428 anv_device_finish_meta(struct anv_device *device)
1429 {
1430 /* Clear */
1431 anv_DestroyPipeline(anv_device_to_handle(device),
1432 device->meta_state.clear.pipeline);
1433
1434 /* Blit */
1435 anv_DestroyPipeline(anv_device_to_handle(device),
1436 device->meta_state.blit.pipeline);
1437 anv_DestroyPipelineLayout(anv_device_to_handle(device),
1438 device->meta_state.blit.pipeline_layout);
1439 anv_DestroyDescriptorSetLayout(anv_device_to_handle(device),
1440 device->meta_state.blit.ds_layout);
1441
1442 /* Shared */
1443 anv_DestroyDynamicRasterState(anv_device_to_handle(device),
1444 device->meta_state.shared.rs_state);
1445 anv_DestroyDynamicColorBlendState(anv_device_to_handle(device),
1446 device->meta_state.shared.cb_state);
1447 anv_DestroyDynamicDepthStencilState(anv_device_to_handle(device),
1448 device->meta_state.shared.ds_state);
1449 }