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