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