2 * Copyright © 2015 Intel Corporation
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:
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
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
31 #include "glsl_helpers.h"
32 #include "meta-spirv.h"
35 anv_device_init_meta_clear_state(struct anv_device
*device
)
37 VkPipelineIaStateCreateInfo ia_create_info
= {
38 .sType
= VK_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO
,
39 .topology
= VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP
,
40 .disableVertexReuse
= false,
41 .primitiveRestartEnable
= false,
42 .primitiveRestartIndex
= 0
45 /* We don't use a vertex shader for clearing, but instead build and pass
46 * the VUEs directly to the rasterization backend.
48 VkShader fs
= GLSL_VK_SHADER(device
, FRAGMENT
,
57 VkPipelineShaderStageCreateInfo fs_create_info
= {
58 .sType
= VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO
,
59 .pNext
= &ia_create_info
,
61 .stage
= VK_SHADER_STAGE_FRAGMENT
,
63 .linkConstBufferCount
= 0,
64 .pLinkConstBufferInfo
= NULL
,
65 .pSpecializationInfo
= NULL
69 /* We use instanced rendering to clear multiple render targets. We have two
70 * vertex buffers: the first vertex buffer holds per-vertex data and
71 * provides the vertices for the clear rectangle. The second one holds
72 * per-instance data, which consists of the VUE header (which selects the
73 * layer) and the color (Vulkan supports per-RT clear colors).
75 VkPipelineVertexInputCreateInfo vi_create_info
= {
76 .sType
= VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO
,
77 .pNext
= &fs_create_info
,
79 .pVertexBindingDescriptions
= (VkVertexInputBindingDescription
[]) {
83 .stepRate
= VK_VERTEX_INPUT_STEP_RATE_VERTEX
88 .stepRate
= VK_VERTEX_INPUT_STEP_RATE_INSTANCE
92 .pVertexAttributeDescriptions
= (VkVertexInputAttributeDescription
[]) {
97 .format
= VK_FORMAT_R32G32B32A32_UINT
,
104 .format
= VK_FORMAT_R32G32_SFLOAT
,
111 .format
= VK_FORMAT_R32G32B32A32_SFLOAT
,
117 VkPipelineRsStateCreateInfo rs_create_info
= {
118 .sType
= VK_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO
,
119 .pNext
= &vi_create_info
,
120 .depthClipEnable
= true,
121 .rasterizerDiscardEnable
= false,
122 .fillMode
= VK_FILL_MODE_SOLID
,
123 .cullMode
= VK_CULL_MODE_NONE
,
124 .frontFace
= VK_FRONT_FACE_CCW
127 anv_pipeline_create((VkDevice
) device
,
128 &(VkGraphicsPipelineCreateInfo
) {
129 .sType
= VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO
,
130 .pNext
= &rs_create_info
,
134 &(struct anv_pipeline_create_info
) {
135 .use_repclear
= true,
136 .disable_viewport
= true,
139 &device
->clear_state
.pipeline
);
141 anv_DestroyObject((VkDevice
) device
, VK_OBJECT_TYPE_SHADER
, fs
);
143 anv_CreateDynamicRasterState((VkDevice
) device
,
144 &(VkDynamicRsStateCreateInfo
) {
145 .sType
= VK_STRUCTURE_TYPE_DYNAMIC_RS_STATE_CREATE_INFO
,
147 &device
->clear_state
.rs_state
);
150 #define NUM_VB_USED 2
151 struct anv_saved_state
{
152 struct anv_bindings bindings
;
153 struct anv_bindings
*old_bindings
;
154 struct anv_pipeline
*old_pipeline
;
158 anv_cmd_buffer_save(struct anv_cmd_buffer
*cmd_buffer
,
159 struct anv_saved_state
*state
)
161 state
->old_bindings
= cmd_buffer
->bindings
;
162 cmd_buffer
->bindings
= &state
->bindings
;
163 state
->old_pipeline
= cmd_buffer
->pipeline
;
167 anv_cmd_buffer_restore(struct anv_cmd_buffer
*cmd_buffer
,
168 const struct anv_saved_state
*state
)
170 cmd_buffer
->bindings
= state
->old_bindings
;
171 cmd_buffer
->pipeline
= state
->old_pipeline
;
173 cmd_buffer
->vb_dirty
|= (1 << NUM_VB_USED
) - 1;
174 cmd_buffer
->dirty
|= ANV_CMD_BUFFER_PIPELINE_DIRTY
|
175 ANV_CMD_BUFFER_DESCRIPTOR_SET_DIRTY
;
179 anv_cmd_buffer_copy_render_targets(struct anv_cmd_buffer
*cmd_buffer
,
180 struct anv_saved_state
*state
)
182 struct anv_framebuffer
*fb
= cmd_buffer
->framebuffer
;
183 struct anv_bindings
*old_bindings
= state
->old_bindings
;
184 struct anv_bindings
*bindings
= cmd_buffer
->bindings
;
186 for (uint32_t i
= 0; i
< fb
->color_attachment_count
; i
++) {
187 bindings
->descriptors
[VK_SHADER_STAGE_FRAGMENT
].surfaces
[i
] =
188 old_bindings
->descriptors
[VK_SHADER_STAGE_FRAGMENT
].surfaces
[i
];
190 bindings
->descriptors
[VK_SHADER_STAGE_FRAGMENT
].relocs
[i
].bo
=
191 old_bindings
->descriptors
[VK_SHADER_STAGE_FRAGMENT
].relocs
[i
].bo
;
192 bindings
->descriptors
[VK_SHADER_STAGE_FRAGMENT
].relocs
[i
].offset
=
193 old_bindings
->descriptors
[VK_SHADER_STAGE_FRAGMENT
].relocs
[i
].offset
;
196 cmd_buffer
->dirty
|= ANV_CMD_BUFFER_DESCRIPTOR_SET_DIRTY
;
202 uint32_t ViewportIndex
;
207 anv_cmd_buffer_clear(struct anv_cmd_buffer
*cmd_buffer
,
208 struct anv_render_pass
*pass
)
210 struct anv_device
*device
= cmd_buffer
->device
;
211 struct anv_framebuffer
*fb
= cmd_buffer
->framebuffer
;
212 struct anv_saved_state saved_state
;
213 struct anv_state state
;
216 struct instance_data
{
217 struct vue_header vue_header
;
221 if (pass
->num_clear_layers
== 0)
224 const float vertex_data
[] = {
225 /* Rect-list coordinates */
228 fb
->width
, fb
->height
,
230 /* Align to 16 bytes */
234 size
= sizeof(vertex_data
) + pass
->num_clear_layers
* sizeof(instance_data
[0]);
235 state
= anv_state_stream_alloc(&cmd_buffer
->surface_state_stream
, size
, 16);
237 memcpy(state
.map
, vertex_data
, sizeof(vertex_data
));
238 instance_data
= state
.map
+ sizeof(vertex_data
);
240 for (uint32_t i
= 0; i
< pass
->num_layers
; i
++) {
241 if (pass
->layers
[i
].color_load_op
== VK_ATTACHMENT_LOAD_OP_CLEAR
) {
242 *instance_data
++ = (struct instance_data
) {
249 pass
->layers
[i
].clear_color
.color
.floatColor
[0],
250 pass
->layers
[i
].clear_color
.color
.floatColor
[1],
251 pass
->layers
[i
].clear_color
.color
.floatColor
[2],
252 pass
->layers
[i
].clear_color
.color
.floatColor
[3],
258 struct anv_buffer vertex_buffer
= {
259 .device
= cmd_buffer
->device
,
261 .bo
= &device
->surface_state_block_pool
.bo
,
262 .offset
= state
.offset
265 anv_cmd_buffer_save(cmd_buffer
, &saved_state
);
266 anv_cmd_buffer_copy_render_targets(cmd_buffer
, &saved_state
);
268 anv_CmdBindVertexBuffers((VkCmdBuffer
) cmd_buffer
, 0, 2,
270 (VkBuffer
) &vertex_buffer
,
271 (VkBuffer
) &vertex_buffer
278 if ((VkPipeline
) cmd_buffer
->pipeline
!= device
->clear_state
.pipeline
)
279 anv_CmdBindPipeline((VkCmdBuffer
) cmd_buffer
,
280 VK_PIPELINE_BIND_POINT_GRAPHICS
, device
->clear_state
.pipeline
);
282 /* We don't need anything here, only set if not already set. */
283 if (cmd_buffer
->rs_state
== NULL
)
284 anv_CmdBindDynamicStateObject((VkCmdBuffer
) cmd_buffer
,
285 VK_STATE_BIND_POINT_RASTER
,
286 device
->clear_state
.rs_state
);
288 if (cmd_buffer
->vp_state
== NULL
)
289 anv_CmdBindDynamicStateObject((VkCmdBuffer
) cmd_buffer
,
290 VK_STATE_BIND_POINT_VIEWPORT
,
291 cmd_buffer
->framebuffer
->vp_state
);
293 anv_CmdDraw((VkCmdBuffer
) cmd_buffer
, 0, 3, 0, pass
->num_clear_layers
);
295 /* Restore API state */
296 anv_cmd_buffer_restore(cmd_buffer
, &saved_state
);
301 anv_device_init_meta_blit_state(struct anv_device
*device
)
303 VkPipelineIaStateCreateInfo ia_create_info
= {
304 .sType
= VK_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO
,
305 .topology
= VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP
,
306 .disableVertexReuse
= false,
307 .primitiveRestartEnable
= false,
308 .primitiveRestartIndex
= 0
311 /* We don't use a vertex shader for clearing, but instead build and pass
312 * the VUEs directly to the rasterization backend. However, we do need
313 * to provide GLSL source for the vertex shader so that the compiler
314 * does not dead-code our inputs.
316 VkShader vs
= GLSL_VK_SHADER(device
, VERTEX
,
319 out vec4 v_tex_coord
;
322 v_tex_coord
= vec4(a_tex_coord
, 0, 1);
323 gl_Position
= vec4(a_pos
, 0, 1);
327 VkShader fs
= GLSL_VK_SHADER(device
, FRAGMENT
,
330 layout(set
= 0, binding
= 0) uniform sampler2D u_tex
;
333 f_color
= texture(u_tex
, v_tex_coord
.xy
);
337 VkPipelineShaderStageCreateInfo vs_create_info
= {
338 .sType
= VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO
,
339 .pNext
= &ia_create_info
,
341 .stage
= VK_SHADER_STAGE_VERTEX
,
343 .linkConstBufferCount
= 0,
344 .pLinkConstBufferInfo
= NULL
,
345 .pSpecializationInfo
= NULL
349 VkPipelineShaderStageCreateInfo fs_create_info
= {
350 .sType
= VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO
,
351 .pNext
= &vs_create_info
,
353 .stage
= VK_SHADER_STAGE_FRAGMENT
,
355 .linkConstBufferCount
= 0,
356 .pLinkConstBufferInfo
= NULL
,
357 .pSpecializationInfo
= NULL
361 VkPipelineVertexInputCreateInfo vi_create_info
= {
362 .sType
= VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO
,
363 .pNext
= &fs_create_info
,
365 .pVertexBindingDescriptions
= (VkVertexInputBindingDescription
[]) {
369 .stepRate
= VK_VERTEX_INPUT_STEP_RATE_VERTEX
374 .stepRate
= VK_VERTEX_INPUT_STEP_RATE_VERTEX
378 .pVertexAttributeDescriptions
= (VkVertexInputAttributeDescription
[]) {
383 .format
= VK_FORMAT_R32G32B32A32_UINT
,
390 .format
= VK_FORMAT_R32G32_SFLOAT
,
394 /* Texture Coordinate */
397 .format
= VK_FORMAT_R32G32_SFLOAT
,
403 VkDescriptorSetLayoutCreateInfo ds_layout_info
= {
404 .sType
= VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO
,
406 .pBinding
= (VkDescriptorSetLayoutBinding
[]) {
408 .descriptorType
= VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
,
410 .stageFlags
= VK_SHADER_STAGE_FRAGMENT_BIT
,
411 .pImmutableSamplers
= NULL
415 anv_CreateDescriptorSetLayout((VkDevice
) device
, &ds_layout_info
,
416 &device
->blit_state
.ds_layout
);
418 VkPipelineLayoutCreateInfo pipeline_layout_info
= {
419 .sType
= VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO
,
420 .descriptorSetCount
= 1,
421 .pSetLayouts
= &device
->blit_state
.ds_layout
,
424 VkPipelineLayout pipeline_layout
;
425 anv_CreatePipelineLayout((VkDevice
) device
, &pipeline_layout_info
,
428 VkPipelineRsStateCreateInfo rs_create_info
= {
429 .sType
= VK_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO
,
430 .pNext
= &vi_create_info
,
431 .depthClipEnable
= true,
432 .rasterizerDiscardEnable
= false,
433 .fillMode
= VK_FILL_MODE_SOLID
,
434 .cullMode
= VK_CULL_MODE_NONE
,
435 .frontFace
= VK_FRONT_FACE_CCW
438 VkGraphicsPipelineCreateInfo pipeline_info
= {
439 .sType
= VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO
,
440 .pNext
= &rs_create_info
,
442 .layout
= pipeline_layout
,
445 anv_pipeline_create((VkDevice
) device
, &pipeline_info
,
446 &(struct anv_pipeline_create_info
) {
447 .use_repclear
= false,
448 .disable_viewport
= true,
449 .disable_scissor
= true,
453 &device
->blit_state
.pipeline
);
455 anv_DestroyObject((VkDevice
) device
, VK_OBJECT_TYPE_SHADER
, vs
);
456 anv_DestroyObject((VkDevice
) device
, VK_OBJECT_TYPE_SHADER
, fs
);
458 anv_CreateDynamicRasterState((VkDevice
) device
,
459 &(VkDynamicRsStateCreateInfo
) {
460 .sType
= VK_STRUCTURE_TYPE_DYNAMIC_RS_STATE_CREATE_INFO
,
462 &device
->blit_state
.rs_state
);
466 meta_prepare_blit(struct anv_cmd_buffer
*cmd_buffer
,
467 struct anv_saved_state
*saved_state
)
469 struct anv_device
*device
= cmd_buffer
->device
;
471 anv_cmd_buffer_save(cmd_buffer
, saved_state
);
473 if ((VkPipeline
) cmd_buffer
->pipeline
!= device
->blit_state
.pipeline
)
474 anv_CmdBindPipeline((VkCmdBuffer
) cmd_buffer
,
475 VK_PIPELINE_BIND_POINT_GRAPHICS
,
476 device
->blit_state
.pipeline
);
478 /* We don't need anything here, only set if not already set. */
479 if (cmd_buffer
->rs_state
== NULL
)
480 anv_CmdBindDynamicStateObject((VkCmdBuffer
) cmd_buffer
,
481 VK_STATE_BIND_POINT_RASTER
,
482 device
->blit_state
.rs_state
);
486 VkOffset3D src_offset
;
487 VkExtent3D src_extent
;
488 VkOffset3D dest_offset
;
489 VkExtent3D dest_extent
;
493 meta_emit_blit(struct anv_cmd_buffer
*cmd_buffer
,
494 struct anv_surface_view
*src
,
495 VkOffset3D src_offset
,
496 VkExtent3D src_extent
,
497 struct anv_surface_view
*dest
,
498 VkOffset3D dest_offset
,
499 VkExtent3D dest_extent
)
501 struct anv_device
*device
= cmd_buffer
->device
;
503 struct blit_vb_data
{
508 unsigned vb_size
= sizeof(struct vue_header
) + 3 * sizeof(*vb_data
);
510 struct anv_state vb_state
=
511 anv_state_stream_alloc(&cmd_buffer
->surface_state_stream
, vb_size
, 16);
512 memset(vb_state
.map
, 0, sizeof(struct vue_header
));
513 vb_data
= vb_state
.map
+ sizeof(struct vue_header
);
515 vb_data
[0] = (struct blit_vb_data
) {
517 dest_offset
.x
+ dest_extent
.width
,
518 dest_offset
.y
+ dest_extent
.height
,
521 (float)(src_offset
.x
+ src_extent
.width
) / (float)src
->extent
.width
,
522 (float)(src_offset
.y
+ src_extent
.height
) / (float)src
->extent
.height
,
526 vb_data
[1] = (struct blit_vb_data
) {
529 dest_offset
.y
+ dest_extent
.height
,
532 (float)src_offset
.x
/ (float)src
->extent
.width
,
533 (float)(src_offset
.y
+ src_extent
.height
) / (float)src
->extent
.height
,
537 vb_data
[2] = (struct blit_vb_data
) {
543 (float)src_offset
.x
/ (float)src
->extent
.width
,
544 (float)src_offset
.y
/ (float)src
->extent
.height
,
548 struct anv_buffer vertex_buffer
= {
551 .bo
= &device
->surface_state_block_pool
.bo
,
552 .offset
= vb_state
.offset
,
555 anv_CmdBindVertexBuffers((VkCmdBuffer
) cmd_buffer
, 0, 2,
557 (VkBuffer
) &vertex_buffer
,
558 (VkBuffer
) &vertex_buffer
562 sizeof(struct vue_header
),
567 anv_AllocDescriptorSets((VkDevice
) device
, 0 /* pool */,
568 VK_DESCRIPTOR_SET_USAGE_ONE_SHOT
,
569 1, &device
->blit_state
.ds_layout
, &set
, &count
);
570 anv_UpdateDescriptors((VkDevice
) device
, set
, 1,
573 .sType
= VK_STRUCTURE_TYPE_UPDATE_IMAGES
,
574 .descriptorType
= VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
,
577 .pImageViews
= (VkImageViewAttachInfo
[]) {
579 .sType
= VK_STRUCTURE_TYPE_IMAGE_VIEW_ATTACH_INFO
,
580 .view
= (VkImageView
) src
,
581 .layout
= VK_IMAGE_LAYOUT_GENERAL
,
587 struct anv_framebuffer
*fb
;
588 anv_CreateFramebuffer((VkDevice
) device
,
589 &(VkFramebufferCreateInfo
) {
590 .sType
= VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO
,
591 .colorAttachmentCount
= 1,
592 .pColorAttachments
= (VkColorAttachmentBindInfo
[]) {
594 .view
= (VkColorAttachmentView
) dest
,
595 .layout
= VK_IMAGE_LAYOUT_GENERAL
598 .pDepthStencilAttachment
= NULL
,
600 .width
= dest
->extent
.width
,
601 .height
= dest
->extent
.height
,
603 }, (VkFramebuffer
*)&fb
);
607 anv_CreateRenderPass((VkDevice
)device
,
608 &(VkRenderPassCreateInfo
) {
609 .sType
= VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO
,
610 .renderArea
= { { 0, 0 }, { dest
->extent
.width
, dest
->extent
.height
} },
611 .colorAttachmentCount
= 1,
615 .pColorFormats
= (VkFormat
[]) { dest
->format
},
616 .pColorLayouts
= (VkImageLayout
[]) { VK_IMAGE_LAYOUT_GENERAL
},
617 .pColorLoadOps
= (VkAttachmentLoadOp
[]) { VK_ATTACHMENT_LOAD_OP_LOAD
},
618 .pColorStoreOps
= (VkAttachmentStoreOp
[]) { VK_ATTACHMENT_STORE_OP_STORE
},
619 .pColorLoadClearValues
= (VkClearColor
[]) {
620 { .color
= { .floatColor
= { 1.0, 0.0, 0.0, 1.0 } }, .useRawValue
= false }
622 .depthStencilFormat
= VK_FORMAT_UNDEFINED
,
625 anv_CmdBeginRenderPass((VkCmdBuffer
) cmd_buffer
,
626 &(VkRenderPassBegin
) {
628 .framebuffer
= (VkFramebuffer
) fb
,
631 anv_CmdBindDynamicStateObject((VkCmdBuffer
) cmd_buffer
,
632 VK_STATE_BIND_POINT_VIEWPORT
, fb
->vp_state
);
634 anv_CmdBindDescriptorSets((VkCmdBuffer
) cmd_buffer
,
635 VK_PIPELINE_BIND_POINT_GRAPHICS
, 0, 1,
638 anv_CmdDraw((VkCmdBuffer
) cmd_buffer
, 0, 3, 0, 1);
640 anv_CmdEndRenderPass((VkCmdBuffer
) cmd_buffer
, pass
);
644 meta_finish_blit(struct anv_cmd_buffer
*cmd_buffer
,
645 const struct anv_saved_state
*saved_state
)
647 anv_cmd_buffer_restore(cmd_buffer
, saved_state
);
651 vk_format_for_cpp(int cpp
)
654 case 1: return VK_FORMAT_R8_UINT
;
655 case 2: return VK_FORMAT_R8G8_UINT
;
656 case 3: return VK_FORMAT_R8G8B8_UINT
;
657 case 4: return VK_FORMAT_R8G8B8A8_UINT
;
658 case 6: return VK_FORMAT_R16G16B16_UINT
;
659 case 8: return VK_FORMAT_R16G16B16A16_UINT
;
660 case 12: return VK_FORMAT_R32G32B32_UINT
;
661 case 16: return VK_FORMAT_R32G32B32A32_UINT
;
663 unreachable("Invalid format cpp");
668 do_buffer_copy(struct anv_cmd_buffer
*cmd_buffer
,
669 struct anv_bo
*src
, uint64_t src_offset
,
670 struct anv_bo
*dest
, uint64_t dest_offset
,
671 int width
, int height
, VkFormat copy_format
)
673 VkDevice vk_device
= (VkDevice
)cmd_buffer
->device
;
675 VkImageCreateInfo image_info
= {
676 .sType
= VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
,
677 .imageType
= VK_IMAGE_TYPE_2D
,
678 .format
= copy_format
,
687 .tiling
= VK_IMAGE_TILING_LINEAR
,
688 .usage
= VK_IMAGE_USAGE_SAMPLED_BIT
,
692 struct anv_image
*src_image
, *dest_image
;
693 anv_CreateImage(vk_device
, &image_info
, (VkImage
*)&src_image
);
694 anv_CreateImage(vk_device
, &image_info
, (VkImage
*)&dest_image
);
696 /* We could use a vk call to bind memory, but that would require
697 * creating a dummy memory object etc. so there's really no point.
700 src_image
->offset
= src_offset
;
701 dest_image
->bo
= dest
;
702 dest_image
->offset
= dest_offset
;
704 struct anv_surface_view src_view
;
705 anv_image_view_init(&src_view
, cmd_buffer
->device
,
706 &(VkImageViewCreateInfo
) {
707 .sType
= VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO
,
708 .image
= (VkImage
)src_image
,
709 .viewType
= VK_IMAGE_VIEW_TYPE_2D
,
710 .format
= copy_format
,
712 VK_CHANNEL_SWIZZLE_R
,
713 VK_CHANNEL_SWIZZLE_G
,
714 VK_CHANNEL_SWIZZLE_B
,
717 .subresourceRange
= {
718 .aspect
= VK_IMAGE_ASPECT_COLOR
,
728 struct anv_surface_view dest_view
;
729 anv_color_attachment_view_init(&dest_view
, cmd_buffer
->device
,
730 &(VkColorAttachmentViewCreateInfo
) {
731 .sType
= VK_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO
,
732 .image
= (VkImage
)dest_image
,
733 .format
= copy_format
,
740 meta_emit_blit(cmd_buffer
,
742 (VkOffset3D
) { 0, 0, 0 },
743 (VkExtent3D
) { width
, height
, 1 },
745 (VkOffset3D
) { 0, 0, 0 },
746 (VkExtent3D
) { width
, height
, 1 });
749 void anv_CmdCopyBuffer(
750 VkCmdBuffer cmdBuffer
,
753 uint32_t regionCount
,
754 const VkBufferCopy
* pRegions
)
756 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*)cmdBuffer
;
757 struct anv_buffer
*src_buffer
= (struct anv_buffer
*)srcBuffer
;
758 struct anv_buffer
*dest_buffer
= (struct anv_buffer
*)destBuffer
;
759 struct anv_saved_state saved_state
;
761 meta_prepare_blit(cmd_buffer
, &saved_state
);
763 for (unsigned r
= 0; r
< regionCount
; r
++) {
764 uint64_t src_offset
= src_buffer
->offset
+ pRegions
[r
].srcOffset
;
765 uint64_t dest_offset
= dest_buffer
->offset
+ pRegions
[r
].destOffset
;
766 uint64_t copy_size
= pRegions
[r
].copySize
;
768 /* First, we compute the biggest format that can be used with the
769 * given offsets and size.
773 int fs
= ffs(src_offset
) - 1;
775 cpp
= MIN2(cpp
, 1 << fs
);
776 assert(src_offset
% cpp
== 0);
778 fs
= ffs(dest_offset
) - 1;
780 cpp
= MIN2(cpp
, 1 << fs
);
781 assert(dest_offset
% cpp
== 0);
783 fs
= ffs(pRegions
[r
].copySize
) - 1;
785 cpp
= MIN2(cpp
, 1 << fs
);
786 assert(pRegions
[r
].copySize
% cpp
== 0);
788 VkFormat copy_format
= vk_format_for_cpp(cpp
);
790 /* This is maximum possible width/height our HW can handle */
791 uint64_t max_surface_dim
= 1 << 14;
793 /* First, we make a bunch of max-sized copies */
794 uint64_t max_copy_size
= max_surface_dim
* max_surface_dim
* cpp
;
795 while (copy_size
> max_copy_size
) {
796 do_buffer_copy(cmd_buffer
, src_buffer
->bo
, src_offset
,
797 dest_buffer
->bo
, dest_offset
,
798 max_surface_dim
, max_surface_dim
, copy_format
);
799 copy_size
-= max_copy_size
;
800 src_offset
+= max_copy_size
;
801 dest_offset
+= max_copy_size
;
804 uint64_t height
= copy_size
/ (max_surface_dim
* cpp
);
805 assert(height
< max_surface_dim
);
807 uint64_t rect_copy_size
= height
* max_surface_dim
* cpp
;
808 do_buffer_copy(cmd_buffer
, src_buffer
->bo
, src_offset
,
809 dest_buffer
->bo
, dest_offset
,
810 max_surface_dim
, height
, copy_format
);
811 copy_size
-= rect_copy_size
;
812 src_offset
+= rect_copy_size
;
813 dest_offset
+= rect_copy_size
;
816 if (copy_size
!= 0) {
817 do_buffer_copy(cmd_buffer
, src_buffer
->bo
, src_offset
,
818 dest_buffer
->bo
, dest_offset
,
819 copy_size
/ cpp
, 1, copy_format
);
823 meta_finish_blit(cmd_buffer
, &saved_state
);
826 void anv_CmdCopyImage(
827 VkCmdBuffer cmdBuffer
,
829 VkImageLayout srcImageLayout
,
831 VkImageLayout destImageLayout
,
832 uint32_t regionCount
,
833 const VkImageCopy
* pRegions
)
835 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*)cmdBuffer
;
836 struct anv_image
*src_image
= (struct anv_image
*)srcImage
;
837 struct anv_saved_state saved_state
;
839 meta_prepare_blit(cmd_buffer
, &saved_state
);
841 for (unsigned r
= 0; r
< regionCount
; r
++) {
842 struct anv_surface_view src_view
;
843 anv_image_view_init(&src_view
, cmd_buffer
->device
,
844 &(VkImageViewCreateInfo
) {
845 .sType
= VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO
,
847 .viewType
= VK_IMAGE_VIEW_TYPE_2D
,
848 .format
= src_image
->format
,
850 VK_CHANNEL_SWIZZLE_R
,
851 VK_CHANNEL_SWIZZLE_G
,
852 VK_CHANNEL_SWIZZLE_B
,
855 .subresourceRange
= {
856 .aspect
= pRegions
[r
].srcSubresource
.aspect
,
857 .baseMipLevel
= pRegions
[r
].srcSubresource
.mipLevel
,
859 .baseArraySlice
= pRegions
[r
].srcSubresource
.arraySlice
,
866 struct anv_surface_view dest_view
;
867 anv_color_attachment_view_init(&dest_view
, cmd_buffer
->device
,
868 &(VkColorAttachmentViewCreateInfo
) {
869 .sType
= VK_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO
,
871 .format
= src_image
->format
,
872 .mipLevel
= pRegions
[r
].destSubresource
.mipLevel
,
873 .baseArraySlice
= pRegions
[r
].destSubresource
.arraySlice
,
878 meta_emit_blit(cmd_buffer
,
880 pRegions
[r
].srcOffset
,
883 pRegions
[r
].destOffset
,
887 meta_finish_blit(cmd_buffer
, &saved_state
);
890 void anv_CmdBlitImage(
891 VkCmdBuffer cmdBuffer
,
893 VkImageLayout srcImageLayout
,
895 VkImageLayout destImageLayout
,
896 uint32_t regionCount
,
897 const VkImageBlit
* pRegions
)
899 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*)cmdBuffer
;
900 struct anv_image
*src_image
= (struct anv_image
*)srcImage
;
901 struct anv_image
*dest_image
= (struct anv_image
*)destImage
;
902 struct anv_saved_state saved_state
;
904 meta_prepare_blit(cmd_buffer
, &saved_state
);
906 for (unsigned r
= 0; r
< regionCount
; r
++) {
907 struct anv_surface_view src_view
;
908 anv_image_view_init(&src_view
, cmd_buffer
->device
,
909 &(VkImageViewCreateInfo
) {
910 .sType
= VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO
,
912 .viewType
= VK_IMAGE_VIEW_TYPE_2D
,
913 .format
= src_image
->format
,
915 VK_CHANNEL_SWIZZLE_R
,
916 VK_CHANNEL_SWIZZLE_G
,
917 VK_CHANNEL_SWIZZLE_B
,
920 .subresourceRange
= {
921 .aspect
= pRegions
[r
].srcSubresource
.aspect
,
922 .baseMipLevel
= pRegions
[r
].srcSubresource
.mipLevel
,
924 .baseArraySlice
= pRegions
[r
].srcSubresource
.arraySlice
,
931 struct anv_surface_view dest_view
;
932 anv_color_attachment_view_init(&dest_view
, cmd_buffer
->device
,
933 &(VkColorAttachmentViewCreateInfo
) {
934 .sType
= VK_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO
,
936 .format
= dest_image
->format
,
937 .mipLevel
= pRegions
[r
].destSubresource
.mipLevel
,
938 .baseArraySlice
= pRegions
[r
].destSubresource
.arraySlice
,
943 meta_emit_blit(cmd_buffer
,
945 pRegions
[r
].srcOffset
,
946 pRegions
[r
].srcExtent
,
948 pRegions
[r
].destOffset
,
949 pRegions
[r
].destExtent
);
952 meta_finish_blit(cmd_buffer
, &saved_state
);
955 void anv_CmdCopyBufferToImage(
956 VkCmdBuffer cmdBuffer
,
959 VkImageLayout destImageLayout
,
960 uint32_t regionCount
,
961 const VkBufferImageCopy
* pRegions
)
963 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*)cmdBuffer
;
964 VkDevice vk_device
= (VkDevice
) cmd_buffer
->device
;
965 struct anv_buffer
*src_buffer
= (struct anv_buffer
*)srcBuffer
;
966 struct anv_image
*dest_image
= (struct anv_image
*)destImage
;
967 struct anv_saved_state saved_state
;
969 meta_prepare_blit(cmd_buffer
, &saved_state
);
971 for (unsigned r
= 0; r
< regionCount
; r
++) {
972 struct anv_image
*src_image
;
973 anv_CreateImage(vk_device
,
974 &(VkImageCreateInfo
) {
975 .sType
= VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
,
976 .imageType
= VK_IMAGE_TYPE_2D
,
977 .format
= dest_image
->format
,
979 .width
= pRegions
[r
].imageExtent
.width
,
980 .height
= pRegions
[r
].imageExtent
.height
,
986 .tiling
= VK_IMAGE_TILING_LINEAR
,
987 .usage
= VK_IMAGE_USAGE_SAMPLED_BIT
,
989 }, (VkImage
*)&src_image
);
991 /* We could use a vk call to bind memory, but that would require
992 * creating a dummy memory object etc. so there's really no point.
994 src_image
->bo
= src_buffer
->bo
;
995 src_image
->offset
= src_buffer
->offset
+ pRegions
[r
].bufferOffset
;
997 struct anv_surface_view src_view
;
998 anv_image_view_init(&src_view
, cmd_buffer
->device
,
999 &(VkImageViewCreateInfo
) {
1000 .sType
= VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO
,
1001 .image
= (VkImage
)src_image
,
1002 .viewType
= VK_IMAGE_VIEW_TYPE_2D
,
1003 .format
= dest_image
->format
,
1005 VK_CHANNEL_SWIZZLE_R
,
1006 VK_CHANNEL_SWIZZLE_G
,
1007 VK_CHANNEL_SWIZZLE_B
,
1008 VK_CHANNEL_SWIZZLE_A
1010 .subresourceRange
= {
1011 .aspect
= pRegions
[r
].imageSubresource
.aspect
,
1014 .baseArraySlice
= 0,
1021 struct anv_surface_view dest_view
;
1022 anv_color_attachment_view_init(&dest_view
, cmd_buffer
->device
,
1023 &(VkColorAttachmentViewCreateInfo
) {
1024 .sType
= VK_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO
,
1025 .image
= (VkImage
)dest_image
,
1026 .format
= dest_image
->format
,
1027 .mipLevel
= pRegions
[r
].imageSubresource
.mipLevel
,
1028 .baseArraySlice
= pRegions
[r
].imageSubresource
.arraySlice
,
1033 meta_emit_blit(cmd_buffer
,
1035 (VkOffset3D
) { 0, 0, 0 },
1036 pRegions
[r
].imageExtent
,
1038 pRegions
[r
].imageOffset
,
1039 pRegions
[r
].imageExtent
);
1042 meta_finish_blit(cmd_buffer
, &saved_state
);
1045 void anv_CmdCopyImageToBuffer(
1046 VkCmdBuffer cmdBuffer
,
1048 VkImageLayout srcImageLayout
,
1049 VkBuffer destBuffer
,
1050 uint32_t regionCount
,
1051 const VkBufferImageCopy
* pRegions
)
1053 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*)cmdBuffer
;
1054 VkDevice vk_device
= (VkDevice
) cmd_buffer
->device
;
1055 struct anv_image
*src_image
= (struct anv_image
*)srcImage
;
1056 struct anv_buffer
*dest_buffer
= (struct anv_buffer
*)destBuffer
;
1057 struct anv_saved_state saved_state
;
1059 meta_prepare_blit(cmd_buffer
, &saved_state
);
1061 for (unsigned r
= 0; r
< regionCount
; r
++) {
1062 struct anv_surface_view src_view
;
1063 anv_image_view_init(&src_view
, cmd_buffer
->device
,
1064 &(VkImageViewCreateInfo
) {
1065 .sType
= VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO
,
1067 .viewType
= VK_IMAGE_VIEW_TYPE_2D
,
1068 .format
= src_image
->format
,
1070 VK_CHANNEL_SWIZZLE_R
,
1071 VK_CHANNEL_SWIZZLE_G
,
1072 VK_CHANNEL_SWIZZLE_B
,
1073 VK_CHANNEL_SWIZZLE_A
1075 .subresourceRange
= {
1076 .aspect
= pRegions
[r
].imageSubresource
.aspect
,
1077 .baseMipLevel
= pRegions
[r
].imageSubresource
.mipLevel
,
1079 .baseArraySlice
= pRegions
[r
].imageSubresource
.arraySlice
,
1086 struct anv_image
*dest_image
;
1087 anv_CreateImage(vk_device
,
1088 &(VkImageCreateInfo
) {
1089 .sType
= VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
,
1090 .imageType
= VK_IMAGE_TYPE_2D
,
1091 .format
= src_image
->format
,
1093 .width
= pRegions
[r
].imageExtent
.width
,
1094 .height
= pRegions
[r
].imageExtent
.height
,
1100 .tiling
= VK_IMAGE_TILING_LINEAR
,
1101 .usage
= VK_IMAGE_USAGE_SAMPLED_BIT
,
1103 }, (VkImage
*)&dest_image
);
1105 /* We could use a vk call to bind memory, but that would require
1106 * creating a dummy memory object etc. so there's really no point.
1108 dest_image
->bo
= dest_buffer
->bo
;
1109 dest_image
->offset
= dest_buffer
->offset
+ pRegions
[r
].bufferOffset
;
1111 struct anv_surface_view dest_view
;
1112 anv_color_attachment_view_init(&dest_view
, cmd_buffer
->device
,
1113 &(VkColorAttachmentViewCreateInfo
) {
1114 .sType
= VK_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO
,
1115 .image
= (VkImage
)dest_image
,
1116 .format
= src_image
->format
,
1118 .baseArraySlice
= 0,
1123 meta_emit_blit(cmd_buffer
,
1125 pRegions
[r
].imageOffset
,
1126 pRegions
[r
].imageExtent
,
1128 (VkOffset3D
) { 0, 0, 0 },
1129 pRegions
[r
].imageExtent
);
1132 meta_finish_blit(cmd_buffer
, &saved_state
);
1135 void anv_CmdCloneImageData(
1136 VkCmdBuffer cmdBuffer
,
1138 VkImageLayout srcImageLayout
,
1140 VkImageLayout destImageLayout
)
1145 void anv_CmdUpdateBuffer(
1146 VkCmdBuffer cmdBuffer
,
1147 VkBuffer destBuffer
,
1148 VkDeviceSize destOffset
,
1149 VkDeviceSize dataSize
,
1150 const uint32_t* pData
)
1155 void anv_CmdFillBuffer(
1156 VkCmdBuffer cmdBuffer
,
1157 VkBuffer destBuffer
,
1158 VkDeviceSize destOffset
,
1159 VkDeviceSize fillSize
,
1165 void anv_CmdClearColorImage(
1166 VkCmdBuffer cmdBuffer
,
1168 VkImageLayout imageLayout
,
1169 const VkClearColor
* color
,
1170 uint32_t rangeCount
,
1171 const VkImageSubresourceRange
* pRanges
)
1176 void anv_CmdClearDepthStencil(
1177 VkCmdBuffer cmdBuffer
,
1179 VkImageLayout imageLayout
,
1182 uint32_t rangeCount
,
1183 const VkImageSubresourceRange
* pRanges
)
1188 void anv_CmdResolveImage(
1189 VkCmdBuffer cmdBuffer
,
1191 VkImageLayout srcImageLayout
,
1193 VkImageLayout destImageLayout
,
1194 uint32_t regionCount
,
1195 const VkImageResolve
* pRegions
)
1201 anv_device_init_meta(struct anv_device
*device
)
1203 anv_device_init_meta_clear_state(device
);
1204 anv_device_init_meta_blit_state(device
);