vk/meta: Add required renderpass to pipeline
[mesa.git] / src / vulkan / anv_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 "anv_private.h"
31 #include "anv_nir_builder.h"
32
33 struct anv_render_pass anv_meta_dummy_renderpass = {0};
34
35 static nir_shader *
36 build_nir_vertex_shader(bool attr_flat)
37 {
38 nir_builder b;
39
40 const struct glsl_type *vertex_type = glsl_vec4_type();
41
42 nir_builder_init_simple_shader(&b, MESA_SHADER_VERTEX);
43
44 nir_variable *pos_in = nir_variable_create(b.shader, nir_var_shader_in,
45 vertex_type, "a_pos");
46 pos_in->data.location = VERT_ATTRIB_GENERIC0;
47 nir_variable *pos_out = nir_variable_create(b.shader, nir_var_shader_out,
48 vertex_type, "gl_Position");
49 pos_in->data.location = VARYING_SLOT_POS;
50 nir_copy_var(&b, pos_out, pos_in);
51
52 /* Add one more pass-through attribute. For clear shaders, this is used
53 * to store the color and for blit shaders it's the texture coordinate.
54 */
55 const struct glsl_type *attr_type = glsl_vec4_type();
56 nir_variable *attr_in = nir_variable_create(b.shader, nir_var_shader_in,
57 attr_type, "a_attr");
58 attr_in->data.location = VERT_ATTRIB_GENERIC1;
59 nir_variable *attr_out = nir_variable_create(b.shader, nir_var_shader_out,
60 attr_type, "v_attr");
61 attr_out->data.location = VARYING_SLOT_VAR0;
62 attr_out->data.interpolation = attr_flat ? INTERP_QUALIFIER_FLAT :
63 INTERP_QUALIFIER_SMOOTH;
64 nir_copy_var(&b, attr_out, attr_in);
65
66 return b.shader;
67 }
68
69 static nir_shader *
70 build_nir_clear_fragment_shader(void)
71 {
72 nir_builder b;
73
74 const struct glsl_type *color_type = glsl_vec4_type();
75
76 nir_builder_init_simple_shader(&b, MESA_SHADER_FRAGMENT);
77
78 nir_variable *color_in = nir_variable_create(b.shader, nir_var_shader_in,
79 color_type, "v_attr");
80 color_in->data.location = VARYING_SLOT_VAR0;
81 color_in->data.interpolation = INTERP_QUALIFIER_FLAT;
82 nir_variable *color_out = nir_variable_create(b.shader, nir_var_shader_out,
83 color_type, "f_color");
84 color_out->data.location = FRAG_RESULT_DATA0;
85 nir_copy_var(&b, color_out, color_in);
86
87 return b.shader;
88 }
89
90 static nir_shader *
91 build_nir_copy_fragment_shader(enum glsl_sampler_dim tex_dim)
92 {
93 nir_builder b;
94
95 nir_builder_init_simple_shader(&b, MESA_SHADER_FRAGMENT);
96
97 const struct glsl_type *color_type = glsl_vec4_type();
98
99 nir_variable *tex_pos_in = nir_variable_create(b.shader, nir_var_shader_in,
100 glsl_vec4_type(), "v_attr");
101 tex_pos_in->data.location = VARYING_SLOT_VAR0;
102
103 const struct glsl_type *sampler_type =
104 glsl_sampler_type(tex_dim, false, false, glsl_get_base_type(color_type));
105 nir_variable *sampler = nir_variable_create(b.shader, nir_var_uniform,
106 sampler_type, "s_tex");
107 sampler->data.descriptor_set = 0;
108 sampler->data.binding = 0;
109
110 nir_tex_instr *tex = nir_tex_instr_create(b.shader, 1);
111 tex->sampler_dim = tex_dim;
112 tex->op = nir_texop_tex;
113 tex->src[0].src_type = nir_tex_src_coord;
114 tex->src[0].src = nir_src_for_ssa(nir_load_var(&b, tex_pos_in));
115 tex->dest_type = nir_type_float; /* TODO */
116
117 switch (tex_dim) {
118 case GLSL_SAMPLER_DIM_2D:
119 tex->coord_components = 2;
120 break;
121 case GLSL_SAMPLER_DIM_3D:
122 tex->coord_components = 3;
123 break;
124 default:
125 assert(!"Unsupported texture dimension");
126 }
127
128 tex->sampler = nir_deref_var_create(tex, sampler);
129
130 nir_ssa_dest_init(&tex->instr, &tex->dest, 4, "tex");
131 nir_builder_instr_insert(&b, &tex->instr);
132
133 nir_variable *color_out = nir_variable_create(b.shader, nir_var_shader_out,
134 color_type, "f_color");
135 color_out->data.location = FRAG_RESULT_DATA0;
136 nir_store_var(&b, color_out, &tex->dest.ssa);
137
138 return b.shader;
139 }
140
141 static void
142 anv_device_init_meta_clear_state(struct anv_device *device)
143 {
144 struct anv_shader_module vsm = {
145 .nir = build_nir_vertex_shader(true),
146 };
147
148 struct anv_shader_module fsm = {
149 .nir = build_nir_clear_fragment_shader(),
150 };
151
152 VkShader vs;
153 anv_CreateShader(anv_device_to_handle(device),
154 &(VkShaderCreateInfo) {
155 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
156 .module = anv_shader_module_to_handle(&vsm),
157 .pName = "main",
158 }, &vs);
159
160 VkShader fs;
161 anv_CreateShader(anv_device_to_handle(device),
162 &(VkShaderCreateInfo) {
163 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
164 .module = anv_shader_module_to_handle(&fsm),
165 .pName = "main",
166 }, &fs);
167
168 /* We use instanced rendering to clear multiple render targets. We have two
169 * vertex buffers: the first vertex buffer holds per-vertex data and
170 * provides the vertices for the clear rectangle. The second one holds
171 * per-instance data, which consists of the VUE header (which selects the
172 * layer) and the color (Vulkan supports per-RT clear colors).
173 */
174 VkPipelineVertexInputStateCreateInfo vi_create_info = {
175 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
176 .bindingCount = 2,
177 .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) {
178 {
179 .binding = 0,
180 .strideInBytes = 12,
181 .stepRate = VK_VERTEX_INPUT_STEP_RATE_VERTEX
182 },
183 {
184 .binding = 1,
185 .strideInBytes = 32,
186 .stepRate = VK_VERTEX_INPUT_STEP_RATE_INSTANCE
187 },
188 },
189 .attributeCount = 3,
190 .pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[]) {
191 {
192 /* VUE Header */
193 .location = 0,
194 .binding = 1,
195 .format = VK_FORMAT_R32G32B32A32_UINT,
196 .offsetInBytes = 0
197 },
198 {
199 /* Position */
200 .location = 1,
201 .binding = 0,
202 .format = VK_FORMAT_R32G32B32_SFLOAT,
203 .offsetInBytes = 0
204 },
205 {
206 /* Color */
207 .location = 2,
208 .binding = 1,
209 .format = VK_FORMAT_R32G32B32A32_SFLOAT,
210 .offsetInBytes = 16
211 }
212 }
213 };
214
215 anv_graphics_pipeline_create(anv_device_to_handle(device),
216 &(VkGraphicsPipelineCreateInfo) {
217 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
218
219 .stageCount = 2,
220 .pStages = (VkPipelineShaderStageCreateInfo[]) {
221 {
222 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
223 .stage = VK_SHADER_STAGE_VERTEX,
224 .shader = vs,
225 .pSpecializationInfo = NULL
226 }, {
227 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
228 .stage = VK_SHADER_STAGE_FRAGMENT,
229 .shader = fs,
230 .pSpecializationInfo = NULL,
231 }
232 },
233 .pVertexInputState = &vi_create_info,
234 .pInputAssemblyState = &(VkPipelineInputAssemblyStateCreateInfo) {
235 .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
236 .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
237 .primitiveRestartEnable = false,
238 },
239 .pViewportState = &(VkPipelineViewportStateCreateInfo) {
240 .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
241 .viewportCount = 1,
242 .scissorCount = 1,
243 },
244 .pRasterState = &(VkPipelineRasterStateCreateInfo) {
245 .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTER_STATE_CREATE_INFO,
246 .depthClipEnable = true,
247 .rasterizerDiscardEnable = false,
248 .fillMode = VK_FILL_MODE_SOLID,
249 .cullMode = VK_CULL_MODE_NONE,
250 .frontFace = VK_FRONT_FACE_CCW
251 },
252 .pMultisampleState = &(VkPipelineMultisampleStateCreateInfo) {
253 .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
254 .rasterSamples = 1,
255 .sampleShadingEnable = false,
256 .pSampleMask = (VkSampleMask[]) { UINT32_MAX },
257 },
258 .pDepthStencilState = &(VkPipelineDepthStencilStateCreateInfo) {
259 .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
260 .depthTestEnable = true,
261 .depthWriteEnable = true,
262 .depthCompareOp = VK_COMPARE_OP_ALWAYS,
263 .depthBoundsTestEnable = false,
264 .stencilTestEnable = true,
265 .front = (VkStencilOpState) {
266 .stencilPassOp = VK_STENCIL_OP_REPLACE,
267 .stencilCompareOp = VK_COMPARE_OP_ALWAYS,
268 },
269 .back = (VkStencilOpState) {
270 .stencilPassOp = VK_STENCIL_OP_REPLACE,
271 .stencilCompareOp = VK_COMPARE_OP_ALWAYS,
272 },
273 },
274 .pColorBlendState = &(VkPipelineColorBlendStateCreateInfo) {
275 .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
276 .attachmentCount = 1,
277 .pAttachments = (VkPipelineColorBlendAttachmentState []) {
278 { .channelWriteMask = VK_CHANNEL_A_BIT |
279 VK_CHANNEL_R_BIT | VK_CHANNEL_G_BIT | VK_CHANNEL_B_BIT },
280 }
281 },
282 .pDynamicState = &(VkPipelineDynamicStateCreateInfo) {
283 .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
284 .dynamicStateCount = 9,
285 .pDynamicStates = (VkDynamicState[]) {
286 VK_DYNAMIC_STATE_VIEWPORT,
287 VK_DYNAMIC_STATE_SCISSOR,
288 VK_DYNAMIC_STATE_LINE_WIDTH,
289 VK_DYNAMIC_STATE_DEPTH_BIAS,
290 VK_DYNAMIC_STATE_BLEND_CONSTANTS,
291 VK_DYNAMIC_STATE_DEPTH_BOUNDS,
292 VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
293 VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
294 VK_DYNAMIC_STATE_STENCIL_REFERENCE,
295 },
296 },
297 .flags = 0,
298 .renderPass = anv_render_pass_to_handle(&anv_meta_dummy_renderpass),
299 .subpass = 0,
300 },
301 &(struct anv_graphics_pipeline_create_info) {
302 .use_repclear = true,
303 .disable_viewport = true,
304 .disable_vs = true,
305 .use_rectlist = true
306 },
307 &device->meta_state.clear.pipeline);
308
309 anv_DestroyShader(anv_device_to_handle(device), vs);
310 anv_DestroyShader(anv_device_to_handle(device), fs);
311 ralloc_free(vsm.nir);
312 ralloc_free(fsm.nir);
313 }
314
315 #define NUM_VB_USED 2
316 struct anv_saved_state {
317 struct anv_vertex_binding old_vertex_bindings[NUM_VB_USED];
318 struct anv_descriptor_set *old_descriptor_set0;
319 struct anv_pipeline *old_pipeline;
320 uint32_t dynamic_flags;
321 struct anv_dynamic_state dynamic;
322 };
323
324 static void
325 anv_cmd_buffer_save(struct anv_cmd_buffer *cmd_buffer,
326 struct anv_saved_state *state,
327 uint32_t dynamic_state)
328 {
329 state->old_pipeline = cmd_buffer->state.pipeline;
330 state->old_descriptor_set0 = cmd_buffer->state.descriptors[0];
331 memcpy(state->old_vertex_bindings, cmd_buffer->state.vertex_bindings,
332 sizeof(state->old_vertex_bindings));
333 state->dynamic_flags = dynamic_state;
334 anv_dynamic_state_copy(&state->dynamic, &cmd_buffer->state.dynamic,
335 dynamic_state);
336 }
337
338 static void
339 anv_cmd_buffer_restore(struct anv_cmd_buffer *cmd_buffer,
340 const struct anv_saved_state *state)
341 {
342 cmd_buffer->state.pipeline = state->old_pipeline;
343 cmd_buffer->state.descriptors[0] = state->old_descriptor_set0;
344 memcpy(cmd_buffer->state.vertex_bindings, state->old_vertex_bindings,
345 sizeof(state->old_vertex_bindings));
346
347 cmd_buffer->state.vb_dirty |= (1 << NUM_VB_USED) - 1;
348 cmd_buffer->state.dirty |= ANV_CMD_BUFFER_PIPELINE_DIRTY;
349 cmd_buffer->state.descriptors_dirty |= VK_SHADER_STAGE_VERTEX_BIT;
350
351 anv_dynamic_state_copy(&cmd_buffer->state.dynamic, &state->dynamic,
352 state->dynamic_flags);
353 cmd_buffer->state.dirty |= state->dynamic_flags;
354 }
355
356 struct vue_header {
357 uint32_t Reserved;
358 uint32_t RTAIndex;
359 uint32_t ViewportIndex;
360 float PointWidth;
361 };
362
363 struct clear_instance_data {
364 struct vue_header vue_header;
365 VkClearColorValue color;
366 };
367
368 static void
369 meta_emit_clear(struct anv_cmd_buffer *cmd_buffer,
370 int num_instances,
371 struct clear_instance_data *instance_data,
372 VkClearDepthStencilValue ds_clear_value)
373 {
374 struct anv_device *device = cmd_buffer->device;
375 struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
376 struct anv_state state;
377 uint32_t size;
378
379 const float vertex_data[] = {
380 /* Rect-list coordinates */
381 0.0, 0.0, ds_clear_value.depth,
382 fb->width, 0.0, ds_clear_value.depth,
383 fb->width, fb->height, ds_clear_value.depth,
384
385 /* Align to 16 bytes */
386 0.0, 0.0, 0.0,
387 };
388
389 size = sizeof(vertex_data) + num_instances * sizeof(*instance_data);
390 state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, size, 16);
391
392 /* Copy in the vertex and instance data */
393 memcpy(state.map, vertex_data, sizeof(vertex_data));
394 memcpy(state.map + sizeof(vertex_data), instance_data,
395 num_instances * sizeof(*instance_data));
396
397 struct anv_buffer vertex_buffer = {
398 .device = cmd_buffer->device,
399 .size = size,
400 .bo = &device->dynamic_state_block_pool.bo,
401 .offset = state.offset
402 };
403
404 anv_CmdBindVertexBuffers(anv_cmd_buffer_to_handle(cmd_buffer), 0, 2,
405 (VkBuffer[]) {
406 anv_buffer_to_handle(&vertex_buffer),
407 anv_buffer_to_handle(&vertex_buffer)
408 },
409 (VkDeviceSize[]) {
410 0,
411 sizeof(vertex_data)
412 });
413
414 if (cmd_buffer->state.pipeline != anv_pipeline_from_handle(device->meta_state.clear.pipeline))
415 anv_CmdBindPipeline(anv_cmd_buffer_to_handle(cmd_buffer),
416 VK_PIPELINE_BIND_POINT_GRAPHICS,
417 device->meta_state.clear.pipeline);
418
419 ANV_CALL(CmdDraw)(anv_cmd_buffer_to_handle(cmd_buffer),
420 3, num_instances, 0, 0);
421 }
422
423 void
424 anv_cmd_buffer_clear_attachments(struct anv_cmd_buffer *cmd_buffer,
425 struct anv_render_pass *pass,
426 const VkClearValue *clear_values)
427 {
428 struct anv_saved_state saved_state;
429
430 if (pass->has_stencil_clear_attachment)
431 anv_finishme("stencil clear");
432
433 /* FINISHME: Rethink how we count clear attachments in light of
434 * 0.138.2 -> 0.170.2 diff.
435 */
436 if (pass->num_color_clear_attachments == 0 &&
437 !pass->has_depth_clear_attachment)
438 return;
439
440 struct clear_instance_data instance_data[pass->num_color_clear_attachments];
441 uint32_t color_attachments[pass->num_color_clear_attachments];
442 uint32_t ds_attachment = VK_ATTACHMENT_UNUSED;
443 VkClearDepthStencilValue ds_clear_value = {0};
444
445 int layer = 0;
446 for (uint32_t i = 0; i < pass->attachment_count; i++) {
447 const struct anv_render_pass_attachment *att = &pass->attachments[i];
448
449 if (att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
450 if (anv_format_is_color(att->format)) {
451 instance_data[layer] = (struct clear_instance_data) {
452 .vue_header = {
453 .RTAIndex = i,
454 .ViewportIndex = 0,
455 .PointWidth = 0.0
456 },
457 .color = clear_values[i].color,
458 };
459 color_attachments[layer] = i;
460 layer++;
461 } else if (att->format->depth_format) {
462 assert(ds_attachment == VK_ATTACHMENT_UNUSED);
463 ds_attachment = i;
464 ds_clear_value = clear_values[ds_attachment].depthStencil;
465 }
466 } else if (att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
467 assert(att->format->has_stencil);
468 anv_finishme("stencil clear");
469 }
470 }
471
472 anv_cmd_buffer_save(cmd_buffer, &saved_state,
473 (1 << VK_DYNAMIC_STATE_VIEWPORT));
474 cmd_buffer->state.dynamic.viewport.count = 0;
475
476 struct anv_subpass subpass = {
477 .input_count = 0,
478 .color_count = pass->num_color_clear_attachments,
479 .color_attachments = color_attachments,
480 .depth_stencil_attachment = ds_attachment,
481 };
482
483 anv_cmd_buffer_begin_subpass(cmd_buffer, &subpass);
484
485 meta_emit_clear(cmd_buffer, pass->num_color_clear_attachments,
486 instance_data, ds_clear_value);
487
488 /* Restore API state */
489 anv_cmd_buffer_restore(cmd_buffer, &saved_state);
490 }
491
492 static VkImageViewType
493 meta_blit_get_src_image_view_type(const struct anv_image *src_image)
494 {
495 switch (src_image->type) {
496 case VK_IMAGE_TYPE_1D:
497 return VK_IMAGE_VIEW_TYPE_1D;
498 case VK_IMAGE_TYPE_2D:
499 return VK_IMAGE_VIEW_TYPE_2D;
500 case VK_IMAGE_TYPE_3D:
501 return VK_IMAGE_VIEW_TYPE_3D;
502 default:
503 assert(!"bad VkImageType");
504 return 0;
505 }
506 }
507
508 static uint32_t
509 meta_blit_get_dest_view_base_array_slice(const struct anv_image *dest_image,
510 const VkImageSubresourceCopy *dest_subresource,
511 const VkOffset3D *dest_offset)
512 {
513 switch (dest_image->type) {
514 case VK_IMAGE_TYPE_1D:
515 case VK_IMAGE_TYPE_2D:
516 return dest_subresource->arrayLayer;
517 case VK_IMAGE_TYPE_3D:
518 /* HACK: Vulkan does not allow attaching a 3D image to a framebuffer,
519 * but meta does it anyway. When doing so, we translate the
520 * destination's z offset into an array offset.
521 */
522 return dest_offset->z;
523 default:
524 assert(!"bad VkImageType");
525 return 0;
526 }
527 }
528
529 static void
530 anv_device_init_meta_blit_state(struct anv_device *device)
531 {
532 /* We don't use a vertex shader for clearing, but instead build and pass
533 * the VUEs directly to the rasterization backend. However, we do need
534 * to provide GLSL source for the vertex shader so that the compiler
535 * does not dead-code our inputs.
536 */
537 struct anv_shader_module vsm = {
538 .nir = build_nir_vertex_shader(false),
539 };
540
541 struct anv_shader_module fsm_2d = {
542 .nir = build_nir_copy_fragment_shader(GLSL_SAMPLER_DIM_2D),
543 };
544
545 struct anv_shader_module fsm_3d = {
546 .nir = build_nir_copy_fragment_shader(GLSL_SAMPLER_DIM_3D),
547 };
548
549 VkShader vs;
550 anv_CreateShader(anv_device_to_handle(device),
551 &(VkShaderCreateInfo) {
552 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
553 .module = anv_shader_module_to_handle(&vsm),
554 .pName = "main",
555 }, &vs);
556
557 VkShader fs_2d;
558 anv_CreateShader(anv_device_to_handle(device),
559 &(VkShaderCreateInfo) {
560 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
561 .module = anv_shader_module_to_handle(&fsm_2d),
562 .pName = "main",
563 }, &fs_2d);
564
565 VkShader fs_3d;
566 anv_CreateShader(anv_device_to_handle(device),
567 &(VkShaderCreateInfo) {
568 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
569 .module = anv_shader_module_to_handle(&fsm_3d),
570 .pName = "main",
571 }, &fs_3d);
572
573 VkPipelineVertexInputStateCreateInfo vi_create_info = {
574 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
575 .bindingCount = 2,
576 .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) {
577 {
578 .binding = 0,
579 .strideInBytes = 0,
580 .stepRate = VK_VERTEX_INPUT_STEP_RATE_VERTEX
581 },
582 {
583 .binding = 1,
584 .strideInBytes = 5 * sizeof(float),
585 .stepRate = VK_VERTEX_INPUT_STEP_RATE_VERTEX
586 },
587 },
588 .attributeCount = 3,
589 .pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[]) {
590 {
591 /* VUE Header */
592 .location = 0,
593 .binding = 0,
594 .format = VK_FORMAT_R32G32B32A32_UINT,
595 .offsetInBytes = 0
596 },
597 {
598 /* Position */
599 .location = 1,
600 .binding = 1,
601 .format = VK_FORMAT_R32G32_SFLOAT,
602 .offsetInBytes = 0
603 },
604 {
605 /* Texture Coordinate */
606 .location = 2,
607 .binding = 1,
608 .format = VK_FORMAT_R32G32B32_SFLOAT,
609 .offsetInBytes = 8
610 }
611 }
612 };
613
614 VkDescriptorSetLayoutCreateInfo ds_layout_info = {
615 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
616 .count = 1,
617 .pBinding = (VkDescriptorSetLayoutBinding[]) {
618 {
619 .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
620 .arraySize = 1,
621 .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
622 .pImmutableSamplers = NULL
623 },
624 }
625 };
626 anv_CreateDescriptorSetLayout(anv_device_to_handle(device), &ds_layout_info,
627 &device->meta_state.blit.ds_layout);
628
629 anv_CreatePipelineLayout(anv_device_to_handle(device),
630 &(VkPipelineLayoutCreateInfo) {
631 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
632 .descriptorSetCount = 1,
633 .pSetLayouts = &device->meta_state.blit.ds_layout,
634 },
635 &device->meta_state.blit.pipeline_layout);
636
637 VkPipelineShaderStageCreateInfo pipeline_shader_stages[] = {
638 {
639 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
640 .stage = VK_SHADER_STAGE_VERTEX,
641 .shader = vs,
642 .pSpecializationInfo = NULL
643 }, {
644 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
645 .stage = VK_SHADER_STAGE_FRAGMENT,
646 .shader = {0}, /* TEMPLATE VALUE! FILL ME IN! */
647 .pSpecializationInfo = NULL
648 },
649 };
650
651 const VkGraphicsPipelineCreateInfo vk_pipeline_info = {
652 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
653 .stageCount = ARRAY_SIZE(pipeline_shader_stages),
654 .pStages = pipeline_shader_stages,
655 .pVertexInputState = &vi_create_info,
656 .pInputAssemblyState = &(VkPipelineInputAssemblyStateCreateInfo) {
657 .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
658 .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
659 .primitiveRestartEnable = false,
660 },
661 .pViewportState = &(VkPipelineViewportStateCreateInfo) {
662 .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
663 .viewportCount = 1,
664 .scissorCount = 1,
665 },
666 .pRasterState = &(VkPipelineRasterStateCreateInfo) {
667 .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTER_STATE_CREATE_INFO,
668 .depthClipEnable = true,
669 .rasterizerDiscardEnable = false,
670 .fillMode = VK_FILL_MODE_SOLID,
671 .cullMode = VK_CULL_MODE_NONE,
672 .frontFace = VK_FRONT_FACE_CCW
673 },
674 .pMultisampleState = &(VkPipelineMultisampleStateCreateInfo) {
675 .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
676 .rasterSamples = 1,
677 .sampleShadingEnable = false,
678 .pSampleMask = (VkSampleMask[]) { UINT32_MAX },
679 },
680 .pColorBlendState = &(VkPipelineColorBlendStateCreateInfo) {
681 .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
682 .attachmentCount = 1,
683 .pAttachments = (VkPipelineColorBlendAttachmentState []) {
684 { .channelWriteMask = VK_CHANNEL_A_BIT |
685 VK_CHANNEL_R_BIT | VK_CHANNEL_G_BIT | VK_CHANNEL_B_BIT },
686 }
687 },
688 .pDynamicState = &(VkPipelineDynamicStateCreateInfo) {
689 .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
690 .dynamicStateCount = 9,
691 .pDynamicStates = (VkDynamicState[]) {
692 VK_DYNAMIC_STATE_VIEWPORT,
693 VK_DYNAMIC_STATE_SCISSOR,
694 VK_DYNAMIC_STATE_LINE_WIDTH,
695 VK_DYNAMIC_STATE_DEPTH_BIAS,
696 VK_DYNAMIC_STATE_BLEND_CONSTANTS,
697 VK_DYNAMIC_STATE_DEPTH_BOUNDS,
698 VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
699 VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
700 VK_DYNAMIC_STATE_STENCIL_REFERENCE,
701 },
702 },
703 .flags = 0,
704 .layout = device->meta_state.blit.pipeline_layout,
705 .renderPass = anv_render_pass_to_handle(&anv_meta_dummy_renderpass),
706 .subpass = 0,
707 };
708
709 const struct anv_graphics_pipeline_create_info anv_pipeline_info = {
710 .use_repclear = false,
711 .disable_viewport = true,
712 .disable_scissor = true,
713 .disable_vs = true,
714 .use_rectlist = true
715 };
716
717 pipeline_shader_stages[1].shader = fs_2d;
718 anv_graphics_pipeline_create(anv_device_to_handle(device),
719 &vk_pipeline_info, &anv_pipeline_info,
720 &device->meta_state.blit.pipeline_2d_src);
721
722 pipeline_shader_stages[1].shader = fs_3d;
723 anv_graphics_pipeline_create(anv_device_to_handle(device),
724 &vk_pipeline_info, &anv_pipeline_info,
725 &device->meta_state.blit.pipeline_3d_src);
726
727 anv_DestroyShader(anv_device_to_handle(device), vs);
728 anv_DestroyShader(anv_device_to_handle(device), fs_2d);
729 anv_DestroyShader(anv_device_to_handle(device), fs_3d);
730 ralloc_free(vsm.nir);
731 ralloc_free(fsm_2d.nir);
732 ralloc_free(fsm_3d.nir);
733 }
734
735 static void
736 meta_prepare_blit(struct anv_cmd_buffer *cmd_buffer,
737 struct anv_saved_state *saved_state)
738 {
739 anv_cmd_buffer_save(cmd_buffer, saved_state,
740 (1 << VK_DYNAMIC_STATE_VIEWPORT));
741 }
742
743 struct blit_region {
744 VkOffset3D src_offset;
745 VkExtent3D src_extent;
746 VkOffset3D dest_offset;
747 VkExtent3D dest_extent;
748 };
749
750 static void
751 meta_emit_blit(struct anv_cmd_buffer *cmd_buffer,
752 struct anv_image *src_image,
753 struct anv_image_view *src_iview,
754 VkOffset3D src_offset,
755 VkExtent3D src_extent,
756 struct anv_image *dest_image,
757 struct anv_image_view *dest_iview,
758 VkOffset3D dest_offset,
759 VkExtent3D dest_extent)
760 {
761 struct anv_device *device = cmd_buffer->device;
762 VkDescriptorPool dummy_desc_pool = { .handle = 1 };
763
764 struct blit_vb_data {
765 float pos[2];
766 float tex_coord[3];
767 } *vb_data;
768
769 unsigned vb_size = sizeof(struct vue_header) + 3 * sizeof(*vb_data);
770
771 struct anv_state vb_state =
772 anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, vb_size, 16);
773 memset(vb_state.map, 0, sizeof(struct vue_header));
774 vb_data = vb_state.map + sizeof(struct vue_header);
775
776 vb_data[0] = (struct blit_vb_data) {
777 .pos = {
778 dest_offset.x + dest_extent.width,
779 dest_offset.y + dest_extent.height,
780 },
781 .tex_coord = {
782 (float)(src_offset.x + src_extent.width) / (float)src_iview->extent.width,
783 (float)(src_offset.y + src_extent.height) / (float)src_iview->extent.height,
784 (float)(src_offset.z + src_extent.depth) / (float)src_iview->extent.depth,
785 },
786 };
787
788 vb_data[1] = (struct blit_vb_data) {
789 .pos = {
790 dest_offset.x,
791 dest_offset.y + dest_extent.height,
792 },
793 .tex_coord = {
794 (float)src_offset.x / (float)src_iview->extent.width,
795 (float)(src_offset.y + src_extent.height) / (float)src_iview->extent.height,
796 (float)(src_offset.z + src_extent.depth) / (float)src_iview->extent.depth,
797 },
798 };
799
800 vb_data[2] = (struct blit_vb_data) {
801 .pos = {
802 dest_offset.x,
803 dest_offset.y,
804 },
805 .tex_coord = {
806 (float)src_offset.x / (float)src_iview->extent.width,
807 (float)src_offset.y / (float)src_iview->extent.height,
808 (float)src_offset.z / (float)src_iview->extent.depth,
809 },
810 };
811
812 struct anv_buffer vertex_buffer = {
813 .device = device,
814 .size = vb_size,
815 .bo = &device->dynamic_state_block_pool.bo,
816 .offset = vb_state.offset,
817 };
818
819 anv_CmdBindVertexBuffers(anv_cmd_buffer_to_handle(cmd_buffer), 0, 2,
820 (VkBuffer[]) {
821 anv_buffer_to_handle(&vertex_buffer),
822 anv_buffer_to_handle(&vertex_buffer)
823 },
824 (VkDeviceSize[]) {
825 0,
826 sizeof(struct vue_header),
827 });
828
829 VkDescriptorSet set;
830 anv_AllocDescriptorSets(anv_device_to_handle(device), dummy_desc_pool,
831 VK_DESCRIPTOR_SET_USAGE_ONE_SHOT,
832 1, &device->meta_state.blit.ds_layout, &set);
833 anv_UpdateDescriptorSets(anv_device_to_handle(device),
834 1, /* writeCount */
835 (VkWriteDescriptorSet[]) {
836 {
837 .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
838 .destSet = set,
839 .destBinding = 0,
840 .destArrayElement = 0,
841 .count = 1,
842 .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
843 .pDescriptors = (VkDescriptorInfo[]) {
844 {
845 .imageView = anv_image_view_to_handle(src_iview),
846 .imageLayout = VK_IMAGE_LAYOUT_GENERAL
847 },
848 }
849 }
850 }, 0, NULL);
851
852 VkFramebuffer fb;
853 anv_CreateFramebuffer(anv_device_to_handle(device),
854 &(VkFramebufferCreateInfo) {
855 .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
856 .attachmentCount = 1,
857 .pAttachments = (VkImageView[]) {
858 anv_image_view_to_handle(dest_iview),
859 },
860 .width = dest_iview->extent.width,
861 .height = dest_iview->extent.height,
862 .layers = 1
863 }, &fb);
864
865 VkRenderPass pass;
866 anv_CreateRenderPass(anv_device_to_handle(device),
867 &(VkRenderPassCreateInfo) {
868 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
869 .attachmentCount = 1,
870 .pAttachments = &(VkAttachmentDescription) {
871 .sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION,
872 .format = dest_iview->format->vk_format,
873 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
874 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
875 .initialLayout = VK_IMAGE_LAYOUT_GENERAL,
876 .finalLayout = VK_IMAGE_LAYOUT_GENERAL,
877 },
878 .subpassCount = 1,
879 .pSubpasses = &(VkSubpassDescription) {
880 .sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION,
881 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
882 .inputCount = 0,
883 .colorCount = 1,
884 .pColorAttachments = &(VkAttachmentReference) {
885 .attachment = 0,
886 .layout = VK_IMAGE_LAYOUT_GENERAL,
887 },
888 .pResolveAttachments = NULL,
889 .depthStencilAttachment = (VkAttachmentReference) {
890 .attachment = VK_ATTACHMENT_UNUSED,
891 .layout = VK_IMAGE_LAYOUT_GENERAL,
892 },
893 .preserveCount = 1,
894 .pPreserveAttachments = &(VkAttachmentReference) {
895 .attachment = 0,
896 .layout = VK_IMAGE_LAYOUT_GENERAL,
897 },
898 },
899 .dependencyCount = 0,
900 }, &pass);
901
902 ANV_CALL(CmdBeginRenderPass)(anv_cmd_buffer_to_handle(cmd_buffer),
903 &(VkRenderPassBeginInfo) {
904 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
905 .renderPass = pass,
906 .framebuffer = fb,
907 .renderArea = {
908 .offset = { dest_offset.x, dest_offset.y },
909 .extent = { dest_extent.width, dest_extent.height },
910 },
911 .clearValueCount = 0,
912 .pClearValues = NULL,
913 }, VK_RENDER_PASS_CONTENTS_INLINE);
914
915 VkPipeline pipeline;
916
917 switch (src_image->type) {
918 case VK_IMAGE_TYPE_1D:
919 anv_finishme("VK_IMAGE_TYPE_1D");
920 pipeline = device->meta_state.blit.pipeline_2d_src;
921 break;
922 case VK_IMAGE_TYPE_2D:
923 pipeline = device->meta_state.blit.pipeline_2d_src;
924 break;
925 case VK_IMAGE_TYPE_3D:
926 pipeline = device->meta_state.blit.pipeline_3d_src;
927 break;
928 default:
929 unreachable(!"bad VkImageType");
930 }
931
932 if (cmd_buffer->state.pipeline != anv_pipeline_from_handle(pipeline)) {
933 anv_CmdBindPipeline(anv_cmd_buffer_to_handle(cmd_buffer),
934 VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
935 }
936
937 anv_CmdSetViewport(anv_cmd_buffer_to_handle(cmd_buffer), 1,
938 &(VkViewport) {
939 .originX = 0.0f,
940 .originY = 0.0f,
941 .width = dest_iview->extent.width,
942 .height = dest_iview->extent.height,
943 .minDepth = 0.0f,
944 .maxDepth = 1.0f,
945 });
946
947 anv_CmdBindDescriptorSets(anv_cmd_buffer_to_handle(cmd_buffer),
948 VK_PIPELINE_BIND_POINT_GRAPHICS,
949 device->meta_state.blit.pipeline_layout, 0, 1,
950 &set, 0, NULL);
951
952 ANV_CALL(CmdDraw)(anv_cmd_buffer_to_handle(cmd_buffer), 3, 1, 0, 0);
953
954 ANV_CALL(CmdEndRenderPass)(anv_cmd_buffer_to_handle(cmd_buffer));
955
956 /* At the point where we emit the draw call, all data from the
957 * descriptor sets, etc. has been used. We are free to delete it.
958 */
959 anv_descriptor_set_destroy(device, anv_descriptor_set_from_handle(set));
960 anv_DestroyFramebuffer(anv_device_to_handle(device), fb);
961 anv_DestroyRenderPass(anv_device_to_handle(device), pass);
962 }
963
964 static void
965 meta_finish_blit(struct anv_cmd_buffer *cmd_buffer,
966 const struct anv_saved_state *saved_state)
967 {
968 anv_cmd_buffer_restore(cmd_buffer, saved_state);
969 }
970
971 static VkFormat
972 vk_format_for_cpp(int cpp)
973 {
974 switch (cpp) {
975 case 1: return VK_FORMAT_R8_UINT;
976 case 2: return VK_FORMAT_R8G8_UINT;
977 case 3: return VK_FORMAT_R8G8B8_UINT;
978 case 4: return VK_FORMAT_R8G8B8A8_UINT;
979 case 6: return VK_FORMAT_R16G16B16_UINT;
980 case 8: return VK_FORMAT_R16G16B16A16_UINT;
981 case 12: return VK_FORMAT_R32G32B32_UINT;
982 case 16: return VK_FORMAT_R32G32B32A32_UINT;
983 default:
984 unreachable("Invalid format cpp");
985 }
986 }
987
988 static void
989 do_buffer_copy(struct anv_cmd_buffer *cmd_buffer,
990 struct anv_bo *src, uint64_t src_offset,
991 struct anv_bo *dest, uint64_t dest_offset,
992 int width, int height, VkFormat copy_format)
993 {
994 VkDevice vk_device = anv_device_to_handle(cmd_buffer->device);
995
996 VkImageCreateInfo image_info = {
997 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
998 .imageType = VK_IMAGE_TYPE_2D,
999 .format = copy_format,
1000 .extent = {
1001 .width = width,
1002 .height = height,
1003 .depth = 1,
1004 },
1005 .mipLevels = 1,
1006 .arraySize = 1,
1007 .samples = 1,
1008 .tiling = VK_IMAGE_TILING_LINEAR,
1009 .usage = 0,
1010 .flags = 0,
1011 };
1012
1013 VkImage src_image;
1014 image_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
1015 anv_CreateImage(vk_device, &image_info, &src_image);
1016
1017 VkImage dest_image;
1018 image_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1019 anv_CreateImage(vk_device, &image_info, &dest_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 anv_image_from_handle(src_image)->bo = src;
1025 anv_image_from_handle(src_image)->offset = src_offset;
1026 anv_image_from_handle(dest_image)->bo = dest;
1027 anv_image_from_handle(dest_image)->offset = dest_offset;
1028
1029 struct anv_image_view src_iview;
1030 anv_image_view_init(&src_iview, cmd_buffer->device,
1031 &(VkImageViewCreateInfo) {
1032 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
1033 .image = src_image,
1034 .viewType = VK_IMAGE_VIEW_TYPE_2D,
1035 .format = copy_format,
1036 .channels = {
1037 VK_CHANNEL_SWIZZLE_R,
1038 VK_CHANNEL_SWIZZLE_G,
1039 VK_CHANNEL_SWIZZLE_B,
1040 VK_CHANNEL_SWIZZLE_A
1041 },
1042 .subresourceRange = {
1043 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
1044 .baseMipLevel = 0,
1045 .mipLevels = 1,
1046 .baseArrayLayer = 0,
1047 .arraySize = 1
1048 },
1049 },
1050 cmd_buffer);
1051
1052 struct anv_image_view dest_iview;
1053 anv_image_view_init(&dest_iview, cmd_buffer->device,
1054 &(VkImageViewCreateInfo) {
1055 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
1056 .image = dest_image,
1057 .viewType = VK_IMAGE_VIEW_TYPE_2D,
1058 .format = copy_format,
1059 .channels = {
1060 .r = VK_CHANNEL_SWIZZLE_R,
1061 .g = VK_CHANNEL_SWIZZLE_G,
1062 .b = VK_CHANNEL_SWIZZLE_B,
1063 .a = VK_CHANNEL_SWIZZLE_A,
1064 },
1065 .subresourceRange = {
1066 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
1067 .baseMipLevel = 0,
1068 .mipLevels = 1,
1069 .baseArrayLayer = 0,
1070 .arraySize = 1,
1071 },
1072 },
1073 cmd_buffer);
1074
1075 meta_emit_blit(cmd_buffer,
1076 anv_image_from_handle(src_image),
1077 &src_iview,
1078 (VkOffset3D) { 0, 0, 0 },
1079 (VkExtent3D) { width, height, 1 },
1080 anv_image_from_handle(dest_image),
1081 &dest_iview,
1082 (VkOffset3D) { 0, 0, 0 },
1083 (VkExtent3D) { width, height, 1 });
1084
1085 anv_DestroyImage(vk_device, src_image);
1086 anv_DestroyImage(vk_device, dest_image);
1087 }
1088
1089 void anv_CmdCopyBuffer(
1090 VkCmdBuffer cmdBuffer,
1091 VkBuffer srcBuffer,
1092 VkBuffer destBuffer,
1093 uint32_t regionCount,
1094 const VkBufferCopy* pRegions)
1095 {
1096 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
1097 ANV_FROM_HANDLE(anv_buffer, src_buffer, srcBuffer);
1098 ANV_FROM_HANDLE(anv_buffer, dest_buffer, destBuffer);
1099
1100 struct anv_saved_state saved_state;
1101
1102 meta_prepare_blit(cmd_buffer, &saved_state);
1103
1104 for (unsigned r = 0; r < regionCount; r++) {
1105 uint64_t src_offset = src_buffer->offset + pRegions[r].srcOffset;
1106 uint64_t dest_offset = dest_buffer->offset + pRegions[r].destOffset;
1107 uint64_t copy_size = pRegions[r].copySize;
1108
1109 /* First, we compute the biggest format that can be used with the
1110 * given offsets and size.
1111 */
1112 int cpp = 16;
1113
1114 int fs = ffs(src_offset) - 1;
1115 if (fs != -1)
1116 cpp = MIN2(cpp, 1 << fs);
1117 assert(src_offset % cpp == 0);
1118
1119 fs = ffs(dest_offset) - 1;
1120 if (fs != -1)
1121 cpp = MIN2(cpp, 1 << fs);
1122 assert(dest_offset % cpp == 0);
1123
1124 fs = ffs(pRegions[r].copySize) - 1;
1125 if (fs != -1)
1126 cpp = MIN2(cpp, 1 << fs);
1127 assert(pRegions[r].copySize % cpp == 0);
1128
1129 VkFormat copy_format = vk_format_for_cpp(cpp);
1130
1131 /* This is maximum possible width/height our HW can handle */
1132 uint64_t max_surface_dim = 1 << 14;
1133
1134 /* First, we make a bunch of max-sized copies */
1135 uint64_t max_copy_size = max_surface_dim * max_surface_dim * cpp;
1136 while (copy_size > max_copy_size) {
1137 do_buffer_copy(cmd_buffer, src_buffer->bo, src_offset,
1138 dest_buffer->bo, dest_offset,
1139 max_surface_dim, max_surface_dim, copy_format);
1140 copy_size -= max_copy_size;
1141 src_offset += max_copy_size;
1142 dest_offset += max_copy_size;
1143 }
1144
1145 uint64_t height = copy_size / (max_surface_dim * cpp);
1146 assert(height < max_surface_dim);
1147 if (height != 0) {
1148 uint64_t rect_copy_size = height * max_surface_dim * cpp;
1149 do_buffer_copy(cmd_buffer, src_buffer->bo, src_offset,
1150 dest_buffer->bo, dest_offset,
1151 max_surface_dim, height, copy_format);
1152 copy_size -= rect_copy_size;
1153 src_offset += rect_copy_size;
1154 dest_offset += rect_copy_size;
1155 }
1156
1157 if (copy_size != 0) {
1158 do_buffer_copy(cmd_buffer, src_buffer->bo, src_offset,
1159 dest_buffer->bo, dest_offset,
1160 copy_size / cpp, 1, copy_format);
1161 }
1162 }
1163
1164 meta_finish_blit(cmd_buffer, &saved_state);
1165 }
1166
1167 void anv_CmdCopyImage(
1168 VkCmdBuffer cmdBuffer,
1169 VkImage srcImage,
1170 VkImageLayout srcImageLayout,
1171 VkImage destImage,
1172 VkImageLayout destImageLayout,
1173 uint32_t regionCount,
1174 const VkImageCopy* pRegions)
1175 {
1176 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
1177 ANV_FROM_HANDLE(anv_image, src_image, srcImage);
1178 ANV_FROM_HANDLE(anv_image, dest_image, destImage);
1179
1180 const VkImageViewType src_iview_type =
1181 meta_blit_get_src_image_view_type(src_image);
1182
1183 struct anv_saved_state saved_state;
1184
1185 meta_prepare_blit(cmd_buffer, &saved_state);
1186
1187 for (unsigned r = 0; r < regionCount; r++) {
1188 struct anv_image_view src_iview;
1189 anv_image_view_init(&src_iview, cmd_buffer->device,
1190 &(VkImageViewCreateInfo) {
1191 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
1192 .image = srcImage,
1193 .viewType = src_iview_type,
1194 .format = src_image->format->vk_format,
1195 .channels = {
1196 VK_CHANNEL_SWIZZLE_R,
1197 VK_CHANNEL_SWIZZLE_G,
1198 VK_CHANNEL_SWIZZLE_B,
1199 VK_CHANNEL_SWIZZLE_A
1200 },
1201 .subresourceRange = {
1202 .aspectMask = 1 << pRegions[r].srcSubresource.aspect,
1203 .baseMipLevel = pRegions[r].srcSubresource.mipLevel,
1204 .mipLevels = 1,
1205 .baseArrayLayer = pRegions[r].srcSubresource.arrayLayer,
1206 .arraySize = 1
1207 },
1208 },
1209 cmd_buffer);
1210
1211 const VkOffset3D dest_offset = {
1212 .x = pRegions[r].destOffset.x,
1213 .y = pRegions[r].destOffset.y,
1214 .z = 0,
1215 };
1216
1217 const uint32_t dest_array_slice =
1218 meta_blit_get_dest_view_base_array_slice(dest_image,
1219 &pRegions[r].destSubresource,
1220 &pRegions[r].destOffset);
1221
1222 if (pRegions[r].srcSubresource.arraySize > 1)
1223 anv_finishme("FINISHME: copy multiple array layers");
1224
1225 if (pRegions[r].extent.depth > 1)
1226 anv_finishme("FINISHME: copy multiple depth layers");
1227
1228 struct anv_image_view dest_iview;
1229 anv_image_view_init(&dest_iview, cmd_buffer->device,
1230 &(VkImageViewCreateInfo) {
1231 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
1232 .image = destImage,
1233 .viewType = VK_IMAGE_VIEW_TYPE_2D,
1234 .format = dest_image->format->vk_format,
1235 .channels = {
1236 VK_CHANNEL_SWIZZLE_R,
1237 VK_CHANNEL_SWIZZLE_G,
1238 VK_CHANNEL_SWIZZLE_B,
1239 VK_CHANNEL_SWIZZLE_A
1240 },
1241 .subresourceRange = {
1242 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
1243 .baseMipLevel = pRegions[r].destSubresource.mipLevel,
1244 .mipLevels = 1,
1245 .baseArrayLayer = dest_array_slice,
1246 .arraySize = 1
1247 },
1248 },
1249 cmd_buffer);
1250
1251 meta_emit_blit(cmd_buffer,
1252 src_image, &src_iview,
1253 pRegions[r].srcOffset,
1254 pRegions[r].extent,
1255 dest_image, &dest_iview,
1256 dest_offset,
1257 pRegions[r].extent);
1258 }
1259
1260 meta_finish_blit(cmd_buffer, &saved_state);
1261 }
1262
1263 void anv_CmdBlitImage(
1264 VkCmdBuffer cmdBuffer,
1265 VkImage srcImage,
1266 VkImageLayout srcImageLayout,
1267 VkImage destImage,
1268 VkImageLayout destImageLayout,
1269 uint32_t regionCount,
1270 const VkImageBlit* pRegions,
1271 VkTexFilter filter)
1272
1273 {
1274 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
1275 ANV_FROM_HANDLE(anv_image, src_image, srcImage);
1276 ANV_FROM_HANDLE(anv_image, dest_image, destImage);
1277
1278 const VkImageViewType src_iview_type =
1279 meta_blit_get_src_image_view_type(src_image);
1280
1281 struct anv_saved_state saved_state;
1282
1283 anv_finishme("respect VkTexFilter");
1284
1285 meta_prepare_blit(cmd_buffer, &saved_state);
1286
1287 for (unsigned r = 0; r < regionCount; r++) {
1288 struct anv_image_view src_iview;
1289 anv_image_view_init(&src_iview, cmd_buffer->device,
1290 &(VkImageViewCreateInfo) {
1291 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
1292 .image = srcImage,
1293 .viewType = src_iview_type,
1294 .format = src_image->format->vk_format,
1295 .channels = {
1296 VK_CHANNEL_SWIZZLE_R,
1297 VK_CHANNEL_SWIZZLE_G,
1298 VK_CHANNEL_SWIZZLE_B,
1299 VK_CHANNEL_SWIZZLE_A
1300 },
1301 .subresourceRange = {
1302 .aspectMask = 1 << pRegions[r].srcSubresource.aspect,
1303 .baseMipLevel = pRegions[r].srcSubresource.mipLevel,
1304 .mipLevels = 1,
1305 .baseArrayLayer = pRegions[r].srcSubresource.arrayLayer,
1306 .arraySize = 1
1307 },
1308 },
1309 cmd_buffer);
1310
1311 const VkOffset3D dest_offset = {
1312 .x = pRegions[r].destOffset.x,
1313 .y = pRegions[r].destOffset.y,
1314 .z = 0,
1315 };
1316
1317 const uint32_t dest_array_slice =
1318 meta_blit_get_dest_view_base_array_slice(dest_image,
1319 &pRegions[r].destSubresource,
1320 &pRegions[r].destOffset);
1321
1322 if (pRegions[r].srcSubresource.arraySize > 1)
1323 anv_finishme("FINISHME: copy multiple array layers");
1324
1325 if (pRegions[r].destExtent.depth > 1)
1326 anv_finishme("FINISHME: copy multiple depth layers");
1327
1328 struct anv_image_view dest_iview;
1329 anv_image_view_init(&dest_iview, cmd_buffer->device,
1330 &(VkImageViewCreateInfo) {
1331 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
1332 .image = destImage,
1333 .viewType = VK_IMAGE_VIEW_TYPE_2D,
1334 .format = dest_image->format->vk_format,
1335 .channels = {
1336 VK_CHANNEL_SWIZZLE_R,
1337 VK_CHANNEL_SWIZZLE_G,
1338 VK_CHANNEL_SWIZZLE_B,
1339 VK_CHANNEL_SWIZZLE_A
1340 },
1341 .subresourceRange = {
1342 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
1343 .baseMipLevel = pRegions[r].destSubresource.mipLevel,
1344 .mipLevels = 1,
1345 .baseArrayLayer = dest_array_slice,
1346 .arraySize = 1
1347 },
1348 },
1349 cmd_buffer);
1350
1351 meta_emit_blit(cmd_buffer,
1352 src_image, &src_iview,
1353 pRegions[r].srcOffset,
1354 pRegions[r].srcExtent,
1355 dest_image, &dest_iview,
1356 dest_offset,
1357 pRegions[r].destExtent);
1358 }
1359
1360 meta_finish_blit(cmd_buffer, &saved_state);
1361 }
1362
1363 static VkImage
1364 make_image_for_buffer(VkDevice vk_device, VkBuffer vk_buffer, VkFormat format,
1365 VkImageUsageFlags usage,
1366 const VkBufferImageCopy *copy)
1367 {
1368 ANV_FROM_HANDLE(anv_buffer, buffer, vk_buffer);
1369
1370 VkExtent3D extent = copy->imageExtent;
1371 if (copy->bufferRowLength)
1372 extent.width = copy->bufferRowLength;
1373 if (copy->bufferImageHeight)
1374 extent.height = copy->bufferImageHeight;
1375 extent.depth = 1;
1376
1377 VkImage vk_image;
1378 VkResult result = anv_CreateImage(vk_device,
1379 &(VkImageCreateInfo) {
1380 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
1381 .imageType = VK_IMAGE_TYPE_2D,
1382 .format = format,
1383 .extent = extent,
1384 .mipLevels = 1,
1385 .arraySize = 1,
1386 .samples = 1,
1387 .tiling = VK_IMAGE_TILING_LINEAR,
1388 .usage = usage,
1389 .flags = 0,
1390 }, &vk_image);
1391 assert(result == VK_SUCCESS);
1392
1393 ANV_FROM_HANDLE(anv_image, image, vk_image);
1394
1395 /* We could use a vk call to bind memory, but that would require
1396 * creating a dummy memory object etc. so there's really no point.
1397 */
1398 image->bo = buffer->bo;
1399 image->offset = buffer->offset + copy->bufferOffset;
1400
1401 return anv_image_to_handle(image);
1402 }
1403
1404 void anv_CmdCopyBufferToImage(
1405 VkCmdBuffer cmdBuffer,
1406 VkBuffer srcBuffer,
1407 VkImage destImage,
1408 VkImageLayout destImageLayout,
1409 uint32_t regionCount,
1410 const VkBufferImageCopy* pRegions)
1411 {
1412 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
1413 ANV_FROM_HANDLE(anv_image, dest_image, destImage);
1414 VkDevice vk_device = anv_device_to_handle(cmd_buffer->device);
1415 const VkFormat orig_format = dest_image->format->vk_format;
1416 struct anv_saved_state saved_state;
1417
1418 meta_prepare_blit(cmd_buffer, &saved_state);
1419
1420 for (unsigned r = 0; r < regionCount; r++) {
1421 VkFormat proxy_format = orig_format;
1422 VkImageAspect proxy_aspect = pRegions[r].imageSubresource.aspect;
1423
1424 if (orig_format == VK_FORMAT_S8_UINT) {
1425 proxy_format = VK_FORMAT_R8_UINT;
1426 proxy_aspect = VK_IMAGE_ASPECT_COLOR;
1427 }
1428
1429 VkImage srcImage = make_image_for_buffer(vk_device, srcBuffer,
1430 proxy_format, VK_IMAGE_USAGE_SAMPLED_BIT, &pRegions[r]);
1431
1432 struct anv_image_view src_iview;
1433 anv_image_view_init(&src_iview, cmd_buffer->device,
1434 &(VkImageViewCreateInfo) {
1435 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
1436 .image = srcImage,
1437 .viewType = VK_IMAGE_VIEW_TYPE_2D,
1438 .format = proxy_format,
1439 .channels = {
1440 VK_CHANNEL_SWIZZLE_R,
1441 VK_CHANNEL_SWIZZLE_G,
1442 VK_CHANNEL_SWIZZLE_B,
1443 VK_CHANNEL_SWIZZLE_A
1444 },
1445 .subresourceRange = {
1446 .aspectMask = 1 << proxy_aspect,
1447 .baseMipLevel = 0,
1448 .mipLevels = 1,
1449 .baseArrayLayer = 0,
1450 .arraySize = 1
1451 },
1452 },
1453 cmd_buffer);
1454
1455 const VkOffset3D dest_offset = {
1456 .x = pRegions[r].imageOffset.x,
1457 .y = pRegions[r].imageOffset.y,
1458 .z = 0,
1459 };
1460
1461 const uint32_t dest_array_slice =
1462 meta_blit_get_dest_view_base_array_slice(dest_image,
1463 &pRegions[r].imageSubresource,
1464 &pRegions[r].imageOffset);
1465
1466 if (pRegions[r].imageExtent.depth > 1)
1467 anv_finishme("FINISHME: copy multiple depth layers");
1468
1469 struct anv_image_view dest_iview;
1470 anv_image_view_init(&dest_iview, cmd_buffer->device,
1471 &(VkImageViewCreateInfo) {
1472 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
1473 .image = anv_image_to_handle(dest_image),
1474 .viewType = VK_IMAGE_VIEW_TYPE_2D,
1475 .format = proxy_format,
1476 .channels = {
1477 VK_CHANNEL_SWIZZLE_R,
1478 VK_CHANNEL_SWIZZLE_G,
1479 VK_CHANNEL_SWIZZLE_B,
1480 VK_CHANNEL_SWIZZLE_A
1481 },
1482 .subresourceRange = {
1483 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
1484 .baseMipLevel = pRegions[r].imageSubresource.mipLevel,
1485 .mipLevels = 1,
1486 .baseArrayLayer = dest_array_slice,
1487 .arraySize = 1
1488 },
1489 },
1490 cmd_buffer);
1491
1492 meta_emit_blit(cmd_buffer,
1493 anv_image_from_handle(srcImage),
1494 &src_iview,
1495 (VkOffset3D) { 0, 0, 0 },
1496 pRegions[r].imageExtent,
1497 dest_image,
1498 &dest_iview,
1499 dest_offset,
1500 pRegions[r].imageExtent);
1501
1502 anv_DestroyImage(vk_device, srcImage);
1503 }
1504
1505 meta_finish_blit(cmd_buffer, &saved_state);
1506 }
1507
1508 void anv_CmdCopyImageToBuffer(
1509 VkCmdBuffer cmdBuffer,
1510 VkImage srcImage,
1511 VkImageLayout srcImageLayout,
1512 VkBuffer destBuffer,
1513 uint32_t regionCount,
1514 const VkBufferImageCopy* pRegions)
1515 {
1516 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
1517 ANV_FROM_HANDLE(anv_image, src_image, srcImage);
1518 VkDevice vk_device = anv_device_to_handle(cmd_buffer->device);
1519 struct anv_saved_state saved_state;
1520
1521 const VkImageViewType src_iview_type =
1522 meta_blit_get_src_image_view_type(src_image);
1523
1524 meta_prepare_blit(cmd_buffer, &saved_state);
1525
1526 for (unsigned r = 0; r < regionCount; r++) {
1527 if (pRegions[r].imageSubresource.arraySize > 1)
1528 anv_finishme("FINISHME: copy multiple array layers");
1529
1530 if (pRegions[r].imageExtent.depth > 1)
1531 anv_finishme("FINISHME: copy multiple depth layers");
1532
1533 struct anv_image_view src_iview;
1534 anv_image_view_init(&src_iview, cmd_buffer->device,
1535 &(VkImageViewCreateInfo) {
1536 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
1537 .image = srcImage,
1538 .viewType = src_iview_type,
1539 .format = src_image->format->vk_format,
1540 .channels = {
1541 VK_CHANNEL_SWIZZLE_R,
1542 VK_CHANNEL_SWIZZLE_G,
1543 VK_CHANNEL_SWIZZLE_B,
1544 VK_CHANNEL_SWIZZLE_A
1545 },
1546 .subresourceRange = {
1547 .aspectMask = 1 << pRegions[r].imageSubresource.aspect,
1548 .baseMipLevel = pRegions[r].imageSubresource.mipLevel,
1549 .mipLevels = 1,
1550 .baseArrayLayer = pRegions[r].imageSubresource.arrayLayer,
1551 .arraySize = 1
1552 },
1553 },
1554 cmd_buffer);
1555
1556 VkFormat dest_format = src_image->format->vk_format;
1557 if (dest_format == VK_FORMAT_S8_UINT) {
1558 dest_format = VK_FORMAT_R8_UINT;
1559 }
1560
1561 VkImage destImage = make_image_for_buffer(vk_device, destBuffer,
1562 dest_format, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, &pRegions[r]);
1563
1564 struct anv_image_view dest_iview;
1565 anv_image_view_init(&dest_iview, cmd_buffer->device,
1566 &(VkImageViewCreateInfo) {
1567 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
1568 .image = destImage,
1569 .viewType = VK_IMAGE_VIEW_TYPE_2D,
1570 .format = dest_format,
1571 .channels = {
1572 VK_CHANNEL_SWIZZLE_R,
1573 VK_CHANNEL_SWIZZLE_G,
1574 VK_CHANNEL_SWIZZLE_B,
1575 VK_CHANNEL_SWIZZLE_A
1576 },
1577 .subresourceRange = {
1578 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
1579 .baseMipLevel = 0,
1580 .mipLevels = 1,
1581 .baseArrayLayer = 0,
1582 .arraySize = 1
1583 },
1584 },
1585 cmd_buffer);
1586
1587 meta_emit_blit(cmd_buffer,
1588 anv_image_from_handle(srcImage),
1589 &src_iview,
1590 pRegions[r].imageOffset,
1591 pRegions[r].imageExtent,
1592 anv_image_from_handle(destImage),
1593 &dest_iview,
1594 (VkOffset3D) { 0, 0, 0 },
1595 pRegions[r].imageExtent);
1596
1597 anv_DestroyImage(vk_device, destImage);
1598 }
1599
1600 meta_finish_blit(cmd_buffer, &saved_state);
1601 }
1602
1603 void anv_CmdUpdateBuffer(
1604 VkCmdBuffer cmdBuffer,
1605 VkBuffer destBuffer,
1606 VkDeviceSize destOffset,
1607 VkDeviceSize dataSize,
1608 const uint32_t* pData)
1609 {
1610 stub();
1611 }
1612
1613 void anv_CmdFillBuffer(
1614 VkCmdBuffer cmdBuffer,
1615 VkBuffer destBuffer,
1616 VkDeviceSize destOffset,
1617 VkDeviceSize fillSize,
1618 uint32_t data)
1619 {
1620 stub();
1621 }
1622
1623 void anv_CmdClearColorImage(
1624 VkCmdBuffer cmdBuffer,
1625 VkImage _image,
1626 VkImageLayout imageLayout,
1627 const VkClearColorValue* pColor,
1628 uint32_t rangeCount,
1629 const VkImageSubresourceRange* pRanges)
1630 {
1631 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
1632 ANV_FROM_HANDLE(anv_image, image, _image);
1633 struct anv_saved_state saved_state;
1634
1635 anv_cmd_buffer_save(cmd_buffer, &saved_state,
1636 (1 << VK_DYNAMIC_STATE_VIEWPORT));
1637 cmd_buffer->state.dynamic.viewport.count = 0;
1638
1639 for (uint32_t r = 0; r < rangeCount; r++) {
1640 for (uint32_t l = 0; l < pRanges[r].mipLevels; l++) {
1641 for (uint32_t s = 0; s < pRanges[r].arraySize; s++) {
1642 struct anv_image_view iview;
1643 anv_image_view_init(&iview, cmd_buffer->device,
1644 &(VkImageViewCreateInfo) {
1645 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
1646 .image = _image,
1647 .viewType = VK_IMAGE_VIEW_TYPE_2D,
1648 .format = image->format->vk_format,
1649 .channels = {
1650 VK_CHANNEL_SWIZZLE_R,
1651 VK_CHANNEL_SWIZZLE_G,
1652 VK_CHANNEL_SWIZZLE_B,
1653 VK_CHANNEL_SWIZZLE_A
1654 },
1655 .subresourceRange = {
1656 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
1657 .baseMipLevel = pRanges[r].baseMipLevel + l,
1658 .mipLevels = 1,
1659 .baseArrayLayer = pRanges[r].baseArrayLayer + s,
1660 .arraySize = 1
1661 },
1662 },
1663 cmd_buffer);
1664
1665 VkFramebuffer fb;
1666 anv_CreateFramebuffer(anv_device_to_handle(cmd_buffer->device),
1667 &(VkFramebufferCreateInfo) {
1668 .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
1669 .attachmentCount = 1,
1670 .pAttachments = (VkImageView[]) {
1671 anv_image_view_to_handle(&iview),
1672 },
1673 .width = iview.extent.width,
1674 .height = iview.extent.height,
1675 .layers = 1
1676 }, &fb);
1677
1678 VkRenderPass pass;
1679 anv_CreateRenderPass(anv_device_to_handle(cmd_buffer->device),
1680 &(VkRenderPassCreateInfo) {
1681 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
1682 .attachmentCount = 1,
1683 .pAttachments = &(VkAttachmentDescription) {
1684 .sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION,
1685 .format = iview.format->vk_format,
1686 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
1687 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
1688 .initialLayout = VK_IMAGE_LAYOUT_GENERAL,
1689 .finalLayout = VK_IMAGE_LAYOUT_GENERAL,
1690 },
1691 .subpassCount = 1,
1692 .pSubpasses = &(VkSubpassDescription) {
1693 .sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION,
1694 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
1695 .inputCount = 0,
1696 .colorCount = 1,
1697 .pColorAttachments = &(VkAttachmentReference) {
1698 .attachment = 0,
1699 .layout = VK_IMAGE_LAYOUT_GENERAL,
1700 },
1701 .pResolveAttachments = NULL,
1702 .depthStencilAttachment = (VkAttachmentReference) {
1703 .attachment = VK_ATTACHMENT_UNUSED,
1704 .layout = VK_IMAGE_LAYOUT_GENERAL,
1705 },
1706 .preserveCount = 1,
1707 .pPreserveAttachments = &(VkAttachmentReference) {
1708 .attachment = 0,
1709 .layout = VK_IMAGE_LAYOUT_GENERAL,
1710 },
1711 },
1712 .dependencyCount = 0,
1713 }, &pass);
1714
1715 ANV_CALL(CmdBeginRenderPass)(anv_cmd_buffer_to_handle(cmd_buffer),
1716 &(VkRenderPassBeginInfo) {
1717 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
1718 .renderArea = {
1719 .offset = { 0, 0, },
1720 .extent = {
1721 .width = iview.extent.width,
1722 .height = iview.extent.height,
1723 },
1724 },
1725 .renderPass = pass,
1726 .framebuffer = fb,
1727 .clearValueCount = 1,
1728 .pClearValues = NULL,
1729 }, VK_RENDER_PASS_CONTENTS_INLINE);
1730
1731 struct clear_instance_data instance_data = {
1732 .vue_header = {
1733 .RTAIndex = 0,
1734 .ViewportIndex = 0,
1735 .PointWidth = 0.0
1736 },
1737 .color = *pColor,
1738 };
1739
1740 meta_emit_clear(cmd_buffer, 1, &instance_data,
1741 (VkClearDepthStencilValue) {0});
1742
1743 ANV_CALL(CmdEndRenderPass)(anv_cmd_buffer_to_handle(cmd_buffer));
1744 }
1745 }
1746 }
1747
1748 /* Restore API state */
1749 anv_cmd_buffer_restore(cmd_buffer, &saved_state);
1750 }
1751
1752 void anv_CmdClearDepthStencilImage(
1753 VkCmdBuffer cmdBuffer,
1754 VkImage image,
1755 VkImageLayout imageLayout,
1756 const VkClearDepthStencilValue* pDepthStencil,
1757 uint32_t rangeCount,
1758 const VkImageSubresourceRange* pRanges)
1759 {
1760 stub();
1761 }
1762
1763 void anv_CmdClearColorAttachment(
1764 VkCmdBuffer cmdBuffer,
1765 uint32_t colorAttachment,
1766 VkImageLayout imageLayout,
1767 const VkClearColorValue* pColor,
1768 uint32_t rectCount,
1769 const VkRect3D* pRects)
1770 {
1771 stub();
1772 }
1773
1774 void anv_CmdClearDepthStencilAttachment(
1775 VkCmdBuffer cmdBuffer,
1776 VkImageAspectFlags aspectMask,
1777 VkImageLayout imageLayout,
1778 const VkClearDepthStencilValue* pDepthStencil,
1779 uint32_t rectCount,
1780 const VkRect3D* pRects)
1781 {
1782 stub();
1783 }
1784
1785 void anv_CmdResolveImage(
1786 VkCmdBuffer cmdBuffer,
1787 VkImage srcImage,
1788 VkImageLayout srcImageLayout,
1789 VkImage destImage,
1790 VkImageLayout destImageLayout,
1791 uint32_t regionCount,
1792 const VkImageResolve* pRegions)
1793 {
1794 stub();
1795 }
1796
1797 void
1798 anv_device_init_meta(struct anv_device *device)
1799 {
1800 anv_device_init_meta_clear_state(device);
1801 anv_device_init_meta_blit_state(device);
1802 }
1803
1804 void
1805 anv_device_finish_meta(struct anv_device *device)
1806 {
1807 /* Clear */
1808 anv_DestroyPipeline(anv_device_to_handle(device),
1809 device->meta_state.clear.pipeline);
1810
1811 /* Blit */
1812 anv_DestroyPipeline(anv_device_to_handle(device),
1813 device->meta_state.blit.pipeline_2d_src);
1814 anv_DestroyPipeline(anv_device_to_handle(device),
1815 device->meta_state.blit.pipeline_3d_src);
1816 anv_DestroyPipelineLayout(anv_device_to_handle(device),
1817 device->meta_state.blit.pipeline_layout);
1818 anv_DestroyDescriptorSetLayout(anv_device_to_handle(device),
1819 device->meta_state.blit.ds_layout);
1820 }