vk: Split the dynamic state binding function into one per state
[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 VkShader 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 .pIaState = &(VkPipelineIaStateCreateInfo) {
115 .sType = VK_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO,
116 .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
117 .primitiveRestartEnable = false,
118 },
119 .pRsState = &(VkPipelineRsStateCreateInfo) {
120 .sType = VK_STRUCTURE_TYPE_PIPELINE_RS_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 .pCbState = &(VkPipelineCbStateCreateInfo) {
128 .sType = VK_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO,
129 .attachmentCount = 1,
130 .pAttachments = (VkPipelineCbAttachmentState []) {
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_DestroyObject(anv_device_to_handle(device), VK_OBJECT_TYPE_SHADER, 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->pipeline;
160 state->old_descriptor_set0 = cmd_buffer->descriptors[0].set;
161 memcpy(state->old_vertex_bindings, cmd_buffer->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->pipeline = state->old_pipeline;
170 cmd_buffer->descriptors[0].set = state->old_descriptor_set0;
171 memcpy(cmd_buffer->vertex_bindings, state->old_vertex_bindings,
172 sizeof(state->old_vertex_bindings));
173
174 cmd_buffer->vb_dirty |= (1 << NUM_VB_USED) - 1;
175 cmd_buffer->dirty |= ANV_CMD_BUFFER_PIPELINE_DIRTY;
176 cmd_buffer->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->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->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->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->vp_state == NULL)
247 anv_CmdBindDynamicViewportState(anv_cmd_buffer_to_handle(cmd_buffer),
248 cmd_buffer->framebuffer->vp_state);
249
250 if (cmd_buffer->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->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 .pIaState = &(VkPipelineIaStateCreateInfo) {
447 .sType = VK_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO,
448 .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
449 .primitiveRestartEnable = false,
450 },
451 .pRsState = &(VkPipelineRsStateCreateInfo) {
452 .sType = VK_STRUCTURE_TYPE_PIPELINE_RS_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 .pCbState = &(VkPipelineCbStateCreateInfo) {
460 .sType = VK_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO,
461 .attachmentCount = 1,
462 .pAttachments = (VkPipelineCbAttachmentState []) {
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_DestroyObject(anv_device_to_handle(device), VK_OBJECT_TYPE_SHADER, vs);
480 anv_DestroyObject(anv_device_to_handle(device), VK_OBJECT_TYPE_SHADER, 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->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->rs_state == NULL)
498 anv_CmdBindDynamicRasterState(anv_cmd_buffer_to_handle(cmd_buffer),
499 device->meta_state.shared.rs_state);
500 if (cmd_buffer->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->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_surface_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
527 struct blit_vb_data {
528 float pos[2];
529 float tex_coord[2];
530 } *vb_data;
531
532 unsigned vb_size = sizeof(struct vue_header) + 3 * sizeof(*vb_data);
533
534 struct anv_state vb_state =
535 anv_state_stream_alloc(&cmd_buffer->surface_state_stream, vb_size, 16);
536 memset(vb_state.map, 0, sizeof(struct vue_header));
537 vb_data = vb_state.map + sizeof(struct vue_header);
538
539 vb_data[0] = (struct blit_vb_data) {
540 .pos = {
541 dest_offset.x + dest_extent.width,
542 dest_offset.y + dest_extent.height,
543 },
544 .tex_coord = {
545 (float)(src_offset.x + src_extent.width) / (float)src->extent.width,
546 (float)(src_offset.y + src_extent.height) / (float)src->extent.height,
547 },
548 };
549
550 vb_data[1] = (struct blit_vb_data) {
551 .pos = {
552 dest_offset.x,
553 dest_offset.y + dest_extent.height,
554 },
555 .tex_coord = {
556 (float)src_offset.x / (float)src->extent.width,
557 (float)(src_offset.y + src_extent.height) / (float)src->extent.height,
558 },
559 };
560
561 vb_data[2] = (struct blit_vb_data) {
562 .pos = {
563 dest_offset.x,
564 dest_offset.y,
565 },
566 .tex_coord = {
567 (float)src_offset.x / (float)src->extent.width,
568 (float)src_offset.y / (float)src->extent.height,
569 },
570 };
571
572 struct anv_buffer vertex_buffer = {
573 .device = device,
574 .size = vb_size,
575 .bo = &device->surface_state_block_pool.bo,
576 .offset = vb_state.offset,
577 };
578
579 anv_CmdBindVertexBuffers(anv_cmd_buffer_to_handle(cmd_buffer), 0, 2,
580 (VkBuffer[]) {
581 anv_buffer_to_handle(&vertex_buffer),
582 anv_buffer_to_handle(&vertex_buffer)
583 },
584 (VkDeviceSize[]) {
585 0,
586 sizeof(struct vue_header),
587 });
588
589 uint32_t count;
590 VkDescriptorSet set;
591 anv_AllocDescriptorSets(anv_device_to_handle(device), 0 /* pool */,
592 VK_DESCRIPTOR_SET_USAGE_ONE_SHOT,
593 1, &device->meta_state.blit.ds_layout, &set, &count);
594 anv_UpdateDescriptorSets(anv_device_to_handle(device),
595 1, /* writeCount */
596 (VkWriteDescriptorSet[]) {
597 {
598 .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
599 .destSet = set,
600 .destBinding = 0,
601 .destArrayElement = 0,
602 .count = 1,
603 .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
604 .pDescriptors = (VkDescriptorInfo[]) {
605 {
606 .imageView = (VkImageView) src,
607 .imageLayout = VK_IMAGE_LAYOUT_GENERAL
608 },
609 }
610 }
611 }, 0, NULL);
612
613 VkFramebuffer fb;
614 anv_CreateFramebuffer(anv_device_to_handle(device),
615 &(VkFramebufferCreateInfo) {
616 .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
617 .attachmentCount = 1,
618 .pAttachments = (VkAttachmentBindInfo[]) {
619 {
620 .view = anv_attachment_view_to_handle(&dest->base),
621 .layout = VK_IMAGE_LAYOUT_GENERAL
622 }
623 },
624 .width = dest->view.extent.width,
625 .height = dest->view.extent.height,
626 .layers = 1
627 }, &fb);
628
629 VkRenderPass pass;
630 anv_CreateRenderPass(anv_device_to_handle(device),
631 &(VkRenderPassCreateInfo) {
632 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
633 .attachmentCount = 1,
634 .pAttachments = &(VkAttachmentDescription) {
635 .sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION,
636 .format = dest->view.format,
637 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
638 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
639 .initialLayout = VK_IMAGE_LAYOUT_GENERAL,
640 .finalLayout = VK_IMAGE_LAYOUT_GENERAL,
641 },
642 .subpassCount = 1,
643 .pSubpasses = &(VkSubpassDescription) {
644 .sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION,
645 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
646 .inputCount = 0,
647 .colorCount = 1,
648 .colorAttachments = &(VkAttachmentReference) {
649 .attachment = 0,
650 .layout = VK_IMAGE_LAYOUT_GENERAL,
651 },
652 .resolveAttachments = NULL,
653 .depthStencilAttachment = (VkAttachmentReference) {
654 .attachment = VK_ATTACHMENT_UNUSED,
655 .layout = VK_IMAGE_LAYOUT_GENERAL,
656 },
657 .preserveCount = 1,
658 .preserveAttachments = &(VkAttachmentReference) {
659 .attachment = 0,
660 .layout = VK_IMAGE_LAYOUT_GENERAL,
661 },
662 },
663 .dependencyCount = 0,
664 }, &pass);
665
666 anv_CmdBeginRenderPass(anv_cmd_buffer_to_handle(cmd_buffer),
667 &(VkRenderPassBeginInfo) {
668 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
669 .renderPass = pass,
670 .framebuffer = fb,
671 .renderArea = {
672 .offset = { dest_offset.x, dest_offset.y },
673 .extent = { dest_extent.width, dest_extent.height },
674 },
675 .attachmentCount = 1,
676 .pAttachmentClearValues = NULL,
677 }, VK_RENDER_PASS_CONTENTS_INLINE);
678
679 anv_CmdBindDynamicViewportState(anv_cmd_buffer_to_handle(cmd_buffer),
680 anv_framebuffer_from_handle(fb)->vp_state);
681
682 anv_CmdBindDescriptorSets(anv_cmd_buffer_to_handle(cmd_buffer),
683 VK_PIPELINE_BIND_POINT_GRAPHICS,
684 device->meta_state.blit.pipeline_layout, 0, 1,
685 &set, 0, NULL);
686
687 anv_CmdDraw(anv_cmd_buffer_to_handle(cmd_buffer), 0, 3, 0, 1);
688
689 anv_CmdEndRenderPass(anv_cmd_buffer_to_handle(cmd_buffer));
690
691 /* At the point where we emit the draw call, all data from the
692 * descriptor sets, etc. has been used. We are free to delete it.
693 */
694 anv_DestroyObject(anv_device_to_handle(device),
695 VK_OBJECT_TYPE_DESCRIPTOR_SET, set);
696 anv_DestroyObject(anv_device_to_handle(device),
697 VK_OBJECT_TYPE_FRAMEBUFFER, fb);
698 anv_DestroyObject(anv_device_to_handle(device),
699 VK_OBJECT_TYPE_RENDER_PASS, pass);
700 }
701
702 static void
703 meta_finish_blit(struct anv_cmd_buffer *cmd_buffer,
704 const struct anv_saved_state *saved_state)
705 {
706 anv_cmd_buffer_restore(cmd_buffer, saved_state);
707 anv_CmdBindDynamicColorBlendState(anv_cmd_buffer_to_handle(cmd_buffer),
708 saved_state->cb_state);
709 }
710
711 static VkFormat
712 vk_format_for_cpp(int cpp)
713 {
714 switch (cpp) {
715 case 1: return VK_FORMAT_R8_UINT;
716 case 2: return VK_FORMAT_R8G8_UINT;
717 case 3: return VK_FORMAT_R8G8B8_UINT;
718 case 4: return VK_FORMAT_R8G8B8A8_UINT;
719 case 6: return VK_FORMAT_R16G16B16_UINT;
720 case 8: return VK_FORMAT_R16G16B16A16_UINT;
721 case 12: return VK_FORMAT_R32G32B32_UINT;
722 case 16: return VK_FORMAT_R32G32B32A32_UINT;
723 default:
724 unreachable("Invalid format cpp");
725 }
726 }
727
728 static void
729 do_buffer_copy(struct anv_cmd_buffer *cmd_buffer,
730 struct anv_bo *src, uint64_t src_offset,
731 struct anv_bo *dest, uint64_t dest_offset,
732 int width, int height, VkFormat copy_format)
733 {
734 VkDevice vk_device = anv_device_to_handle(cmd_buffer->device);
735
736 VkImageCreateInfo image_info = {
737 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
738 .imageType = VK_IMAGE_TYPE_2D,
739 .format = copy_format,
740 .extent = {
741 .width = width,
742 .height = height,
743 .depth = 1,
744 },
745 .mipLevels = 1,
746 .arraySize = 1,
747 .samples = 1,
748 .tiling = VK_IMAGE_TILING_LINEAR,
749 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
750 .flags = 0,
751 };
752
753 VkImage src_image, dest_image;
754 anv_CreateImage(vk_device, &image_info, &src_image);
755 anv_CreateImage(vk_device, &image_info, &dest_image);
756
757 /* We could use a vk call to bind memory, but that would require
758 * creating a dummy memory object etc. so there's really no point.
759 */
760 anv_image_from_handle(src_image)->bo = src;
761 anv_image_from_handle(src_image)->offset = src_offset;
762 anv_image_from_handle(dest_image)->bo = dest;
763 anv_image_from_handle(dest_image)->offset = dest_offset;
764
765 struct anv_surface_view src_view;
766 anv_image_view_init(&src_view, cmd_buffer->device,
767 &(VkImageViewCreateInfo) {
768 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
769 .image = src_image,
770 .viewType = VK_IMAGE_VIEW_TYPE_2D,
771 .format = copy_format,
772 .channels = {
773 VK_CHANNEL_SWIZZLE_R,
774 VK_CHANNEL_SWIZZLE_G,
775 VK_CHANNEL_SWIZZLE_B,
776 VK_CHANNEL_SWIZZLE_A
777 },
778 .subresourceRange = {
779 .aspect = VK_IMAGE_ASPECT_COLOR,
780 .baseMipLevel = 0,
781 .mipLevels = 1,
782 .baseArraySlice = 0,
783 .arraySize = 1
784 },
785 },
786 cmd_buffer);
787
788 struct anv_color_attachment_view dest_view;
789 anv_color_attachment_view_init(&dest_view, cmd_buffer->device,
790 &(VkAttachmentViewCreateInfo) {
791 .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO,
792 .image = dest_image,
793 .format = copy_format,
794 .mipLevel = 0,
795 .baseArraySlice = 0,
796 .arraySize = 1,
797 },
798 cmd_buffer);
799
800 meta_emit_blit(cmd_buffer,
801 &src_view,
802 (VkOffset3D) { 0, 0, 0 },
803 (VkExtent3D) { width, height, 1 },
804 &dest_view,
805 (VkOffset3D) { 0, 0, 0 },
806 (VkExtent3D) { width, height, 1 });
807
808 anv_DestroyObject(vk_device, VK_OBJECT_TYPE_IMAGE, src_image);
809 anv_DestroyObject(vk_device, VK_OBJECT_TYPE_IMAGE, dest_image);
810 }
811
812 void anv_CmdCopyBuffer(
813 VkCmdBuffer cmdBuffer,
814 VkBuffer srcBuffer,
815 VkBuffer destBuffer,
816 uint32_t regionCount,
817 const VkBufferCopy* pRegions)
818 {
819 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *)cmdBuffer;
820 struct anv_buffer *src_buffer = (struct anv_buffer *)srcBuffer;
821 struct anv_buffer *dest_buffer = (struct anv_buffer *)destBuffer;
822 struct anv_saved_state saved_state;
823
824 meta_prepare_blit(cmd_buffer, &saved_state);
825
826 for (unsigned r = 0; r < regionCount; r++) {
827 uint64_t src_offset = src_buffer->offset + pRegions[r].srcOffset;
828 uint64_t dest_offset = dest_buffer->offset + pRegions[r].destOffset;
829 uint64_t copy_size = pRegions[r].copySize;
830
831 /* First, we compute the biggest format that can be used with the
832 * given offsets and size.
833 */
834 int cpp = 16;
835
836 int fs = ffs(src_offset) - 1;
837 if (fs != -1)
838 cpp = MIN2(cpp, 1 << fs);
839 assert(src_offset % cpp == 0);
840
841 fs = ffs(dest_offset) - 1;
842 if (fs != -1)
843 cpp = MIN2(cpp, 1 << fs);
844 assert(dest_offset % cpp == 0);
845
846 fs = ffs(pRegions[r].copySize) - 1;
847 if (fs != -1)
848 cpp = MIN2(cpp, 1 << fs);
849 assert(pRegions[r].copySize % cpp == 0);
850
851 VkFormat copy_format = vk_format_for_cpp(cpp);
852
853 /* This is maximum possible width/height our HW can handle */
854 uint64_t max_surface_dim = 1 << 14;
855
856 /* First, we make a bunch of max-sized copies */
857 uint64_t max_copy_size = max_surface_dim * max_surface_dim * cpp;
858 while (copy_size > max_copy_size) {
859 do_buffer_copy(cmd_buffer, src_buffer->bo, src_offset,
860 dest_buffer->bo, dest_offset,
861 max_surface_dim, max_surface_dim, copy_format);
862 copy_size -= max_copy_size;
863 src_offset += max_copy_size;
864 dest_offset += max_copy_size;
865 }
866
867 uint64_t height = copy_size / (max_surface_dim * cpp);
868 assert(height < max_surface_dim);
869 if (height != 0) {
870 uint64_t rect_copy_size = height * max_surface_dim * cpp;
871 do_buffer_copy(cmd_buffer, src_buffer->bo, src_offset,
872 dest_buffer->bo, dest_offset,
873 max_surface_dim, height, copy_format);
874 copy_size -= rect_copy_size;
875 src_offset += rect_copy_size;
876 dest_offset += rect_copy_size;
877 }
878
879 if (copy_size != 0) {
880 do_buffer_copy(cmd_buffer, src_buffer->bo, src_offset,
881 dest_buffer->bo, dest_offset,
882 copy_size / cpp, 1, copy_format);
883 }
884 }
885
886 meta_finish_blit(cmd_buffer, &saved_state);
887 }
888
889 void anv_CmdCopyImage(
890 VkCmdBuffer cmdBuffer,
891 VkImage srcImage,
892 VkImageLayout srcImageLayout,
893 VkImage destImage,
894 VkImageLayout destImageLayout,
895 uint32_t regionCount,
896 const VkImageCopy* pRegions)
897 {
898 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *)cmdBuffer;
899 struct anv_image *src_image = (struct anv_image *)srcImage;
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_surface_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 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *)cmdBuffer;
964 struct anv_image *src_image = (struct anv_image *)srcImage;
965 struct anv_image *dest_image = (struct anv_image *)destImage;
966 struct anv_saved_state saved_state;
967
968 anv_finishme("respect VkTexFilter");
969
970 meta_prepare_blit(cmd_buffer, &saved_state);
971
972 for (unsigned r = 0; r < regionCount; r++) {
973 struct anv_surface_view src_view;
974 anv_image_view_init(&src_view, cmd_buffer->device,
975 &(VkImageViewCreateInfo) {
976 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
977 .image = srcImage,
978 .viewType = VK_IMAGE_VIEW_TYPE_2D,
979 .format = src_image->format,
980 .channels = {
981 VK_CHANNEL_SWIZZLE_R,
982 VK_CHANNEL_SWIZZLE_G,
983 VK_CHANNEL_SWIZZLE_B,
984 VK_CHANNEL_SWIZZLE_A
985 },
986 .subresourceRange = {
987 .aspect = pRegions[r].srcSubresource.aspect,
988 .baseMipLevel = pRegions[r].srcSubresource.mipLevel,
989 .mipLevels = 1,
990 .baseArraySlice = pRegions[r].srcSubresource.arraySlice,
991 .arraySize = 1
992 },
993 },
994 cmd_buffer);
995
996 struct anv_color_attachment_view dest_view;
997 anv_color_attachment_view_init(&dest_view, cmd_buffer->device,
998 &(VkAttachmentViewCreateInfo) {
999 .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO,
1000 .image = destImage,
1001 .format = dest_image->format,
1002 .mipLevel = pRegions[r].destSubresource.mipLevel,
1003 .baseArraySlice = pRegions[r].destSubresource.arraySlice,
1004 .arraySize = 1,
1005 },
1006 cmd_buffer);
1007
1008 meta_emit_blit(cmd_buffer,
1009 &src_view,
1010 pRegions[r].srcOffset,
1011 pRegions[r].srcExtent,
1012 &dest_view,
1013 pRegions[r].destOffset,
1014 pRegions[r].destExtent);
1015 }
1016
1017 meta_finish_blit(cmd_buffer, &saved_state);
1018 }
1019
1020 void anv_CmdCopyBufferToImage(
1021 VkCmdBuffer cmdBuffer,
1022 VkBuffer srcBuffer,
1023 VkImage destImage,
1024 VkImageLayout destImageLayout,
1025 uint32_t regionCount,
1026 const VkBufferImageCopy* pRegions)
1027 {
1028 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
1029 ANV_FROM_HANDLE(anv_buffer, src_buffer, srcBuffer);
1030 ANV_FROM_HANDLE(anv_image, dest_image, destImage);
1031 VkDevice vk_device = anv_device_to_handle(cmd_buffer->device);
1032 struct anv_saved_state saved_state;
1033
1034 meta_prepare_blit(cmd_buffer, &saved_state);
1035
1036 for (unsigned r = 0; r < regionCount; r++) {
1037 if (pRegions[r].bufferRowLength != 0)
1038 anv_finishme("bufferRowLength not supported in CopyBufferToImage");
1039 if (pRegions[r].bufferImageHeight != 0)
1040 anv_finishme("bufferImageHeight not supported in CopyBufferToImage");
1041
1042 VkImage srcImage;
1043 anv_CreateImage(vk_device,
1044 &(VkImageCreateInfo) {
1045 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
1046 .imageType = VK_IMAGE_TYPE_2D,
1047 .format = dest_image->format,
1048 .extent = {
1049 .width = pRegions[r].imageExtent.width,
1050 .height = pRegions[r].imageExtent.height,
1051 .depth = 1,
1052 },
1053 .mipLevels = 1,
1054 .arraySize = 1,
1055 .samples = 1,
1056 .tiling = VK_IMAGE_TILING_LINEAR,
1057 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
1058 .flags = 0,
1059 }, &srcImage);
1060
1061 ANV_FROM_HANDLE(anv_image, src_image, srcImage);
1062
1063 /* We could use a vk call to bind memory, but that would require
1064 * creating a dummy memory object etc. so there's really no point.
1065 */
1066 src_image->bo = src_buffer->bo;
1067 src_image->offset = src_buffer->offset + pRegions[r].bufferOffset;
1068
1069 struct anv_surface_view src_view;
1070 anv_image_view_init(&src_view, cmd_buffer->device,
1071 &(VkImageViewCreateInfo) {
1072 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
1073 .image = anv_image_to_handle(src_image),
1074 .viewType = VK_IMAGE_VIEW_TYPE_2D,
1075 .format = dest_image->format,
1076 .channels = {
1077 VK_CHANNEL_SWIZZLE_R,
1078 VK_CHANNEL_SWIZZLE_G,
1079 VK_CHANNEL_SWIZZLE_B,
1080 VK_CHANNEL_SWIZZLE_A
1081 },
1082 .subresourceRange = {
1083 .aspect = pRegions[r].imageSubresource.aspect,
1084 .baseMipLevel = 0,
1085 .mipLevels = 1,
1086 .baseArraySlice = 0,
1087 .arraySize = 1
1088 },
1089 },
1090 cmd_buffer);
1091
1092 struct anv_color_attachment_view dest_view;
1093 anv_color_attachment_view_init(&dest_view, cmd_buffer->device,
1094 &(VkAttachmentViewCreateInfo) {
1095 .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO,
1096 .image = anv_image_to_handle(dest_image),
1097 .format = dest_image->format,
1098 .mipLevel = pRegions[r].imageSubresource.mipLevel,
1099 .baseArraySlice = pRegions[r].imageSubresource.arraySlice,
1100 .arraySize = 1,
1101 },
1102 cmd_buffer);
1103
1104 meta_emit_blit(cmd_buffer,
1105 &src_view,
1106 (VkOffset3D) { 0, 0, 0 },
1107 pRegions[r].imageExtent,
1108 &dest_view,
1109 pRegions[r].imageOffset,
1110 pRegions[r].imageExtent);
1111
1112 anv_DestroyObject(vk_device, VK_OBJECT_TYPE_IMAGE, srcImage);
1113 }
1114
1115 meta_finish_blit(cmd_buffer, &saved_state);
1116 }
1117
1118 void anv_CmdCopyImageToBuffer(
1119 VkCmdBuffer cmdBuffer,
1120 VkImage srcImage,
1121 VkImageLayout srcImageLayout,
1122 VkBuffer destBuffer,
1123 uint32_t regionCount,
1124 const VkBufferImageCopy* pRegions)
1125 {
1126 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
1127 ANV_FROM_HANDLE(anv_image, src_image, srcImage);
1128 ANV_FROM_HANDLE(anv_buffer, dest_buffer, destBuffer);
1129 VkDevice vk_device = anv_device_to_handle(cmd_buffer->device);
1130 struct anv_saved_state saved_state;
1131
1132 meta_prepare_blit(cmd_buffer, &saved_state);
1133
1134 for (unsigned r = 0; r < regionCount; r++) {
1135 if (pRegions[r].bufferRowLength != 0)
1136 anv_finishme("bufferRowLength not supported in CopyBufferToImage");
1137 if (pRegions[r].bufferImageHeight != 0)
1138 anv_finishme("bufferImageHeight not supported in CopyBufferToImage");
1139
1140 struct anv_surface_view src_view;
1141 anv_image_view_init(&src_view, cmd_buffer->device,
1142 &(VkImageViewCreateInfo) {
1143 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
1144 .image = srcImage,
1145 .viewType = VK_IMAGE_VIEW_TYPE_2D,
1146 .format = src_image->format,
1147 .channels = {
1148 VK_CHANNEL_SWIZZLE_R,
1149 VK_CHANNEL_SWIZZLE_G,
1150 VK_CHANNEL_SWIZZLE_B,
1151 VK_CHANNEL_SWIZZLE_A
1152 },
1153 .subresourceRange = {
1154 .aspect = pRegions[r].imageSubresource.aspect,
1155 .baseMipLevel = pRegions[r].imageSubresource.mipLevel,
1156 .mipLevels = 1,
1157 .baseArraySlice = pRegions[r].imageSubresource.arraySlice,
1158 .arraySize = 1
1159 },
1160 },
1161 cmd_buffer);
1162
1163 VkImage destImage;
1164 anv_CreateImage(vk_device,
1165 &(VkImageCreateInfo) {
1166 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
1167 .imageType = VK_IMAGE_TYPE_2D,
1168 .format = src_image->format,
1169 .extent = {
1170 .width = pRegions[r].imageExtent.width,
1171 .height = pRegions[r].imageExtent.height,
1172 .depth = 1,
1173 },
1174 .mipLevels = 1,
1175 .arraySize = 1,
1176 .samples = 1,
1177 .tiling = VK_IMAGE_TILING_LINEAR,
1178 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
1179 .flags = 0,
1180 }, &destImage);
1181
1182 ANV_FROM_HANDLE(anv_image, dest_image, destImage);
1183
1184 /* We could use a vk call to bind memory, but that would require
1185 * creating a dummy memory object etc. so there's really no point.
1186 */
1187 dest_image->bo = dest_buffer->bo;
1188 dest_image->offset = dest_buffer->offset + pRegions[r].bufferOffset;
1189
1190 struct anv_color_attachment_view dest_view;
1191 anv_color_attachment_view_init(&dest_view, cmd_buffer->device,
1192 &(VkAttachmentViewCreateInfo) {
1193 .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO,
1194 .image = destImage,
1195 .format = src_image->format,
1196 .mipLevel = 0,
1197 .baseArraySlice = 0,
1198 .arraySize = 1,
1199 },
1200 cmd_buffer);
1201
1202 meta_emit_blit(cmd_buffer,
1203 &src_view,
1204 pRegions[r].imageOffset,
1205 pRegions[r].imageExtent,
1206 &dest_view,
1207 (VkOffset3D) { 0, 0, 0 },
1208 pRegions[r].imageExtent);
1209
1210 anv_DestroyObject(vk_device, VK_OBJECT_TYPE_IMAGE, destImage);
1211 }
1212
1213 meta_finish_blit(cmd_buffer, &saved_state);
1214 }
1215
1216 void anv_CmdUpdateBuffer(
1217 VkCmdBuffer cmdBuffer,
1218 VkBuffer destBuffer,
1219 VkDeviceSize destOffset,
1220 VkDeviceSize dataSize,
1221 const uint32_t* pData)
1222 {
1223 stub();
1224 }
1225
1226 void anv_CmdFillBuffer(
1227 VkCmdBuffer cmdBuffer,
1228 VkBuffer destBuffer,
1229 VkDeviceSize destOffset,
1230 VkDeviceSize fillSize,
1231 uint32_t data)
1232 {
1233 stub();
1234 }
1235
1236 void anv_CmdClearColorImage(
1237 VkCmdBuffer cmdBuffer,
1238 VkImage _image,
1239 VkImageLayout imageLayout,
1240 const VkClearColorValue* pColor,
1241 uint32_t rangeCount,
1242 const VkImageSubresourceRange* pRanges)
1243 {
1244 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
1245 ANV_FROM_HANDLE(anv_image, image, _image);
1246 struct anv_saved_state saved_state;
1247
1248 anv_cmd_buffer_save(cmd_buffer, &saved_state);
1249
1250 for (uint32_t r = 0; r < rangeCount; r++) {
1251 for (uint32_t l = 0; l < pRanges[r].mipLevels; l++) {
1252 for (uint32_t s = 0; s < pRanges[r].arraySize; s++) {
1253 struct anv_color_attachment_view view;
1254 anv_color_attachment_view_init(&view, cmd_buffer->device,
1255 &(VkAttachmentViewCreateInfo) {
1256 .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO,
1257 .image = _image,
1258 .format = image->format,
1259 .mipLevel = pRanges[r].baseMipLevel + l,
1260 .baseArraySlice = pRanges[r].baseArraySlice + s,
1261 .arraySize = 1,
1262 },
1263 cmd_buffer);
1264
1265 VkFramebuffer fb;
1266 anv_CreateFramebuffer(anv_device_to_handle(cmd_buffer->device),
1267 &(VkFramebufferCreateInfo) {
1268 .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
1269 .attachmentCount = 1,
1270 .pAttachments = (VkAttachmentBindInfo[]) {
1271 {
1272 .view = anv_attachment_view_to_handle(&view.base),
1273 .layout = VK_IMAGE_LAYOUT_GENERAL
1274 }
1275 },
1276 .width = view.view.extent.width,
1277 .height = view.view.extent.height,
1278 .layers = 1
1279 }, &fb);
1280
1281 VkRenderPass pass;
1282 anv_CreateRenderPass(anv_device_to_handle(cmd_buffer->device),
1283 &(VkRenderPassCreateInfo) {
1284 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
1285 .attachmentCount = 1,
1286 .pAttachments = &(VkAttachmentDescription) {
1287 .sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION,
1288 .format = view.view.format,
1289 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
1290 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
1291 .initialLayout = VK_IMAGE_LAYOUT_GENERAL,
1292 .finalLayout = VK_IMAGE_LAYOUT_GENERAL,
1293 },
1294 .subpassCount = 1,
1295 .pSubpasses = &(VkSubpassDescription) {
1296 .sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION,
1297 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
1298 .inputCount = 0,
1299 .colorCount = 1,
1300 .colorAttachments = &(VkAttachmentReference) {
1301 .attachment = 0,
1302 .layout = VK_IMAGE_LAYOUT_GENERAL,
1303 },
1304 .resolveAttachments = NULL,
1305 .depthStencilAttachment = (VkAttachmentReference) {
1306 .attachment = VK_ATTACHMENT_UNUSED,
1307 .layout = VK_IMAGE_LAYOUT_GENERAL,
1308 },
1309 .preserveCount = 1,
1310 .preserveAttachments = &(VkAttachmentReference) {
1311 .attachment = 0,
1312 .layout = VK_IMAGE_LAYOUT_GENERAL,
1313 },
1314 },
1315 .dependencyCount = 0,
1316 }, &pass);
1317
1318 anv_CmdBeginRenderPass(anv_cmd_buffer_to_handle(cmd_buffer),
1319 &(VkRenderPassBeginInfo) {
1320 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
1321 .renderArea = {
1322 .offset = { 0, 0, },
1323 .extent = {
1324 .width = view.view.extent.width,
1325 .height = view.view.extent.height,
1326 },
1327 },
1328 .renderPass = pass,
1329 .framebuffer = fb,
1330 .attachmentCount = 1,
1331 .pAttachmentClearValues = NULL,
1332 }, VK_RENDER_PASS_CONTENTS_INLINE);
1333
1334 struct clear_instance_data instance_data = {
1335 .vue_header = {
1336 .RTAIndex = 0,
1337 .ViewportIndex = 0,
1338 .PointWidth = 0.0
1339 },
1340 .color = *pColor,
1341 };
1342
1343 meta_emit_clear(cmd_buffer, 1, &instance_data);
1344
1345 anv_CmdEndRenderPass(anv_cmd_buffer_to_handle(cmd_buffer));
1346 }
1347 }
1348 }
1349
1350 /* Restore API state */
1351 anv_cmd_buffer_restore(cmd_buffer, &saved_state);
1352 }
1353
1354 void anv_CmdClearDepthStencilImage(
1355 VkCmdBuffer cmdBuffer,
1356 VkImage image,
1357 VkImageLayout imageLayout,
1358 float depth,
1359 uint32_t stencil,
1360 uint32_t rangeCount,
1361 const VkImageSubresourceRange* pRanges)
1362 {
1363 stub();
1364 }
1365
1366 void anv_CmdClearColorAttachment(
1367 VkCmdBuffer cmdBuffer,
1368 uint32_t colorAttachment,
1369 VkImageLayout imageLayout,
1370 const VkClearColorValue* pColor,
1371 uint32_t rectCount,
1372 const VkRect3D* pRects)
1373 {
1374 stub();
1375 }
1376
1377 void anv_CmdClearDepthStencilAttachment(
1378 VkCmdBuffer cmdBuffer,
1379 VkImageAspectFlags imageAspectMask,
1380 VkImageLayout imageLayout,
1381 float depth,
1382 uint32_t stencil,
1383 uint32_t rectCount,
1384 const VkRect3D* pRects)
1385 {
1386 stub();
1387 }
1388
1389 void anv_CmdResolveImage(
1390 VkCmdBuffer cmdBuffer,
1391 VkImage srcImage,
1392 VkImageLayout srcImageLayout,
1393 VkImage destImage,
1394 VkImageLayout destImageLayout,
1395 uint32_t regionCount,
1396 const VkImageResolve* pRegions)
1397 {
1398 stub();
1399 }
1400
1401 void
1402 anv_device_init_meta(struct anv_device *device)
1403 {
1404 anv_device_init_meta_clear_state(device);
1405 anv_device_init_meta_blit_state(device);
1406
1407 anv_CreateDynamicRasterState(anv_device_to_handle(device),
1408 &(VkDynamicRasterStateCreateInfo) {
1409 .sType = VK_STRUCTURE_TYPE_DYNAMIC_RS_STATE_CREATE_INFO,
1410 },
1411 &device->meta_state.shared.rs_state);
1412
1413 anv_CreateDynamicColorBlendState(anv_device_to_handle(device),
1414 &(VkDynamicColorBlendStateCreateInfo) {
1415 .sType = VK_STRUCTURE_TYPE_DYNAMIC_CB_STATE_CREATE_INFO
1416 },
1417 &device->meta_state.shared.cb_state);
1418
1419 anv_CreateDynamicDepthStencilState(anv_device_to_handle(device),
1420 &(VkDynamicDepthStencilStateCreateInfo) {
1421 .sType = VK_STRUCTURE_TYPE_DYNAMIC_DS_STATE_CREATE_INFO
1422 },
1423 &device->meta_state.shared.ds_state);
1424 }
1425
1426 void
1427 anv_device_finish_meta(struct anv_device *device)
1428 {
1429 /* Clear */
1430 anv_DestroyObject(anv_device_to_handle(device), VK_OBJECT_TYPE_PIPELINE,
1431 device->meta_state.clear.pipeline);
1432
1433 /* Blit */
1434 anv_DestroyObject(anv_device_to_handle(device), VK_OBJECT_TYPE_PIPELINE,
1435 device->meta_state.blit.pipeline);
1436 anv_DestroyObject(anv_device_to_handle(device),
1437 VK_OBJECT_TYPE_PIPELINE_LAYOUT,
1438 device->meta_state.blit.pipeline_layout);
1439 anv_DestroyObject(anv_device_to_handle(device),
1440 VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT,
1441 device->meta_state.blit.ds_layout);
1442
1443 /* Shared */
1444 anv_DestroyObject(anv_device_to_handle(device),
1445 VK_OBJECT_TYPE_DYNAMIC_RS_STATE,
1446 device->meta_state.shared.rs_state);
1447 anv_DestroyObject(anv_device_to_handle(device),
1448 VK_OBJECT_TYPE_DYNAMIC_CB_STATE,
1449 device->meta_state.shared.cb_state);
1450 anv_DestroyObject(anv_device_to_handle(device),
1451 VK_OBJECT_TYPE_DYNAMIC_DS_STATE,
1452 device->meta_state.shared.ds_state);
1453 }