1 #include "zink_context.h"
2 #include "zink_helpers.h"
3 #include "zink_resource.h"
4 #include "zink_screen.h"
6 #include "util/u_blitter.h"
7 #include "util/format/u_format.h"
10 blit_resolve(struct zink_context
*ctx
, const struct pipe_blit_info
*info
)
12 if (util_format_get_mask(info
->dst
.format
) != info
->mask
||
13 util_format_get_mask(info
->src
.format
) != info
->mask
||
14 info
->scissor_enable
||
16 info
->render_condition_enable
)
19 struct zink_resource
*src
= zink_resource(info
->src
.resource
);
20 struct zink_resource
*dst
= zink_resource(info
->dst
.resource
);
22 struct zink_screen
*screen
= zink_screen(ctx
->base
.screen
);
23 if (src
->format
!= zink_get_format(screen
, info
->src
.format
) ||
24 dst
->format
!= zink_get_format(screen
, info
->dst
.format
))
27 struct zink_batch
*batch
= zink_batch_no_rp(ctx
);
29 zink_batch_reference_resoure(batch
, src
);
30 zink_batch_reference_resoure(batch
, dst
);
32 if (src
->layout
!= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
)
33 zink_resource_barrier(batch
->cmdbuf
, src
, src
->aspect
,
34 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
);
36 if (dst
->layout
!= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
)
37 zink_resource_barrier(batch
->cmdbuf
, dst
, dst
->aspect
,
38 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
);
40 VkImageResolve region
= {};
42 region
.srcSubresource
.aspectMask
= src
->aspect
;
43 region
.srcSubresource
.mipLevel
= info
->src
.level
;
44 region
.srcSubresource
.baseArrayLayer
= 0; // no clue
45 region
.srcSubresource
.layerCount
= 1; // no clue
46 region
.srcOffset
.x
= info
->src
.box
.x
;
47 region
.srcOffset
.y
= info
->src
.box
.y
;
48 region
.srcOffset
.z
= info
->src
.box
.z
;
50 region
.dstSubresource
.aspectMask
= dst
->aspect
;
51 region
.dstSubresource
.mipLevel
= info
->dst
.level
;
52 region
.dstSubresource
.baseArrayLayer
= 0; // no clue
53 region
.dstSubresource
.layerCount
= 1; // no clue
54 region
.dstOffset
.x
= info
->dst
.box
.x
;
55 region
.dstOffset
.y
= info
->dst
.box
.y
;
56 region
.dstOffset
.z
= info
->dst
.box
.z
;
58 region
.extent
.width
= info
->dst
.box
.width
;
59 region
.extent
.height
= info
->dst
.box
.height
;
60 region
.extent
.depth
= info
->dst
.box
.depth
;
61 vkCmdResolveImage(batch
->cmdbuf
, src
->image
, src
->layout
,
62 dst
->image
, dst
->layout
,
69 blit_native(struct zink_context
*ctx
, const struct pipe_blit_info
*info
)
71 if (util_format_get_mask(info
->dst
.format
) != info
->mask
||
72 util_format_get_mask(info
->src
.format
) != info
->mask
||
73 info
->scissor_enable
||
75 info
->render_condition_enable
)
78 if (util_format_is_depth_or_stencil(info
->dst
.format
) &&
79 info
->dst
.format
!= info
->src
.format
)
82 struct zink_resource
*src
= zink_resource(info
->src
.resource
);
83 struct zink_resource
*dst
= zink_resource(info
->dst
.resource
);
85 struct zink_screen
*screen
= zink_screen(ctx
->base
.screen
);
86 if (src
->format
!= zink_get_format(screen
, info
->src
.format
) ||
87 dst
->format
!= zink_get_format(screen
, info
->dst
.format
))
90 struct zink_batch
*batch
= zink_batch_no_rp(ctx
);
91 zink_batch_reference_resoure(batch
, src
);
92 zink_batch_reference_resoure(batch
, dst
);
95 /* The Vulkan 1.1 specification says the following about valid usage
98 * "srcImageLayout must be VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR,
99 * VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL"
103 * "dstImageLayout must be VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR,
104 * VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL"
106 * Since we cant have the same image in two states at the same time,
107 * we're effectively left with VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR or
108 * VK_IMAGE_LAYOUT_GENERAL. And since this isn't a present-related
109 * operation, VK_IMAGE_LAYOUT_GENERAL seems most appropriate.
111 if (src
->layout
!= VK_IMAGE_LAYOUT_GENERAL
)
112 zink_resource_barrier(batch
->cmdbuf
, src
, src
->aspect
,
113 VK_IMAGE_LAYOUT_GENERAL
);
115 if (src
->layout
!= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
)
116 zink_resource_barrier(batch
->cmdbuf
, src
, src
->aspect
,
117 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
);
119 if (dst
->layout
!= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
)
120 zink_resource_barrier(batch
->cmdbuf
, dst
, dst
->aspect
,
121 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
);
124 VkImageBlit region
= {};
125 region
.srcSubresource
.aspectMask
= src
->aspect
;
126 region
.srcSubresource
.mipLevel
= info
->src
.level
;
127 region
.srcOffsets
[0].x
= info
->src
.box
.x
;
128 region
.srcOffsets
[0].y
= info
->src
.box
.y
;
129 region
.srcOffsets
[1].x
= info
->src
.box
.x
+ info
->src
.box
.width
;
130 region
.srcOffsets
[1].y
= info
->src
.box
.y
+ info
->src
.box
.height
;
132 if (src
->base
.array_size
> 1) {
133 region
.srcOffsets
[0].z
= 0;
134 region
.srcOffsets
[1].z
= 1;
135 region
.srcSubresource
.baseArrayLayer
= info
->src
.box
.z
;
136 region
.srcSubresource
.layerCount
= info
->src
.box
.depth
;
138 region
.srcOffsets
[0].z
= info
->src
.box
.z
;
139 region
.srcOffsets
[1].z
= info
->src
.box
.z
+ info
->src
.box
.depth
;
140 region
.srcSubresource
.baseArrayLayer
= 0;
141 region
.srcSubresource
.layerCount
= 1;
144 region
.dstSubresource
.aspectMask
= dst
->aspect
;
145 region
.dstSubresource
.mipLevel
= info
->dst
.level
;
146 region
.dstOffsets
[0].x
= info
->dst
.box
.x
;
147 region
.dstOffsets
[0].y
= info
->dst
.box
.y
;
148 region
.dstOffsets
[1].x
= info
->dst
.box
.x
+ info
->dst
.box
.width
;
149 region
.dstOffsets
[1].y
= info
->dst
.box
.y
+ info
->dst
.box
.height
;
151 if (dst
->base
.array_size
> 1) {
152 region
.dstOffsets
[0].z
= 0;
153 region
.dstOffsets
[1].z
= 1;
154 region
.dstSubresource
.baseArrayLayer
= info
->dst
.box
.z
;
155 region
.dstSubresource
.layerCount
= info
->dst
.box
.depth
;
157 region
.dstOffsets
[0].z
= info
->dst
.box
.z
;
158 region
.dstOffsets
[1].z
= info
->dst
.box
.z
+ info
->dst
.box
.depth
;
159 region
.dstSubresource
.baseArrayLayer
= 0;
160 region
.dstSubresource
.layerCount
= 1;
163 vkCmdBlitImage(batch
->cmdbuf
, src
->image
, src
->layout
,
164 dst
->image
, dst
->layout
,
166 zink_filter(info
->filter
));
172 zink_blit(struct pipe_context
*pctx
,
173 const struct pipe_blit_info
*info
)
175 struct zink_context
*ctx
= zink_context(pctx
);
176 if (info
->src
.resource
->nr_samples
> 1 &&
177 info
->dst
.resource
->nr_samples
<= 1) {
178 if (blit_resolve(ctx
, info
))
181 if (blit_native(ctx
, info
))
185 if (!util_blitter_is_blit_supported(ctx
->blitter
, info
)) {
186 debug_printf("blit unsupported %s -> %s\n",
187 util_format_short_name(info
->src
.resource
->format
),
188 util_format_short_name(info
->dst
.resource
->format
));
192 util_blitter_save_blend(ctx
->blitter
, ctx
->gfx_pipeline_state
.blend_state
);
193 util_blitter_save_depth_stencil_alpha(ctx
->blitter
, ctx
->gfx_pipeline_state
.depth_stencil_alpha_state
);
194 util_blitter_save_vertex_elements(ctx
->blitter
, ctx
->element_state
);
195 util_blitter_save_stencil_ref(ctx
->blitter
, &ctx
->stencil_ref
);
196 util_blitter_save_rasterizer(ctx
->blitter
, ctx
->rast_state
);
197 util_blitter_save_fragment_shader(ctx
->blitter
, ctx
->gfx_stages
[PIPE_SHADER_FRAGMENT
]);
198 util_blitter_save_vertex_shader(ctx
->blitter
, ctx
->gfx_stages
[PIPE_SHADER_VERTEX
]);
199 util_blitter_save_framebuffer(ctx
->blitter
, &ctx
->fb_state
);
200 util_blitter_save_viewport(ctx
->blitter
, ctx
->viewport_states
);
201 util_blitter_save_scissor(ctx
->blitter
, ctx
->scissor_states
);
202 util_blitter_save_fragment_sampler_states(ctx
->blitter
,
203 ctx
->num_samplers
[PIPE_SHADER_FRAGMENT
],
204 ctx
->sampler_states
[PIPE_SHADER_FRAGMENT
]);
205 util_blitter_save_fragment_sampler_views(ctx
->blitter
,
206 ctx
->num_image_views
[PIPE_SHADER_FRAGMENT
],
207 ctx
->image_views
[PIPE_SHADER_FRAGMENT
]);
208 util_blitter_save_fragment_constant_buffer_slot(ctx
->blitter
, ctx
->ubos
[PIPE_SHADER_FRAGMENT
]);
209 util_blitter_save_vertex_buffer_slot(ctx
->blitter
, ctx
->buffers
);
210 util_blitter_save_sample_mask(ctx
->blitter
, ctx
->gfx_pipeline_state
.sample_mask
);
212 util_blitter_blit(ctx
->blitter
, info
);