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