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