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