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