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