1 /*
2 * Copyright © 2021 Collabora Ltd.
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
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 #include "gen_macros.h"
25
26 #include "pan_blitter.h"
27 #include "pan_props.h"
28
29 #include "panvk_private.h"
30
31 static void
panvk_meta_blit(struct panvk_cmd_buffer * cmdbuf,const struct pan_blit_info * blitinfo,const struct panvk_image * src_img,const struct panvk_image * dst_img)32 panvk_meta_blit(struct panvk_cmd_buffer *cmdbuf,
33 const struct pan_blit_info *blitinfo,
34 const struct panvk_image *src_img,
35 const struct panvk_image *dst_img)
36 {
37 struct panvk_device *dev = cmdbuf->device;
38 struct pan_fb_info *fbinfo = &cmdbuf->state.fb.info;
39 struct pan_blit_context ctx;
40 struct pan_image_view views[2] = {
41 {
42 .format = blitinfo->dst.planes[0].format,
43 .dim = MALI_TEXTURE_DIMENSION_2D,
44 .planes =
45 {
46 blitinfo->dst.planes[0].image,
47 blitinfo->dst.planes[1].image,
48 blitinfo->dst.planes[2].image,
49 },
50 .nr_samples = blitinfo->dst.planes[0].image->layout.nr_samples,
51 .first_level = blitinfo->dst.level,
52 .last_level = blitinfo->dst.level,
53 .swizzle = {PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, PIPE_SWIZZLE_Z,
54 PIPE_SWIZZLE_W},
55 },
56 };
57
58 *fbinfo = (struct pan_fb_info){
59 .tile_buf_budget = panfrost_query_optimal_tib_size(
60 cmdbuf->device->physical_device->model),
61 .width = u_minify(blitinfo->dst.planes[0].image->layout.width,
62 blitinfo->dst.level),
63 .height = u_minify(blitinfo->dst.planes[0].image->layout.height,
64 blitinfo->dst.level),
65 .extent =
66 {
67 .minx = MAX2(MIN2(blitinfo->dst.start.x, blitinfo->dst.end.x), 0),
68 .miny = MAX2(MIN2(blitinfo->dst.start.y, blitinfo->dst.end.y), 0),
69 .maxx = MAX2(blitinfo->dst.start.x, blitinfo->dst.end.x),
70 .maxy = MAX2(blitinfo->dst.start.y, blitinfo->dst.end.y),
71 },
72 .nr_samples = blitinfo->dst.planes[0].image->layout.nr_samples,
73 };
74
75 fbinfo->extent.maxx = MIN2(fbinfo->extent.maxx, fbinfo->width - 1);
76 fbinfo->extent.maxy = MIN2(fbinfo->extent.maxy, fbinfo->height - 1);
77
78 /* TODO: don't force preloads of dst resources if unneeded */
79
80 const struct util_format_description *fdesc =
81 util_format_description(blitinfo->dst.planes[0].image->layout.format);
82
83 if (util_format_has_depth(fdesc)) {
84 /* We want the image format here, otherwise we might lose one of the
85 * component.
86 */
87 views[0].format = blitinfo->dst.planes[0].image->layout.format;
88 fbinfo->zs.view.zs = &views[0];
89 fbinfo->zs.preload.z = true;
90 fbinfo->zs.preload.s = util_format_has_stencil(fdesc);
91 } else if (util_format_has_stencil(fdesc)) {
92 fbinfo->zs.view.s = &views[0];
93 fbinfo->zs.preload.s = true;
94 } else {
95 fbinfo->rt_count = 1;
96 fbinfo->rts[0].view = &views[0];
97 fbinfo->rts[0].preload = true;
98 cmdbuf->state.fb.crc_valid[0] = false;
99 fbinfo->rts[0].crc_valid = &cmdbuf->state.fb.crc_valid[0];
100 }
101
102 if (blitinfo->dst.planes[1].format != PIPE_FORMAT_NONE) {
103 /* TODO: don't force preloads of dst resources if unneeded */
104 views[1].format = blitinfo->dst.planes[1].format;
105 views[1].dim = MALI_TEXTURE_DIMENSION_2D;
106 views[1].planes[0] = blitinfo->dst.planes[1].image;
107 views[1].nr_samples = blitinfo->dst.planes[1].image->layout.nr_samples;
108 views[1].first_level = blitinfo->dst.level;
109 views[1].last_level = blitinfo->dst.level;
110 views[1].swizzle[0] = PIPE_SWIZZLE_X;
111 views[1].swizzle[1] = PIPE_SWIZZLE_Y;
112 views[1].swizzle[2] = PIPE_SWIZZLE_Z;
113 views[1].swizzle[3] = PIPE_SWIZZLE_W;
114 fbinfo->zs.view.s = &views[1];
115 }
116
117 panvk_per_arch(cmd_close_batch)(cmdbuf);
118
119 GENX(pan_blit_ctx_init)
120 (&dev->meta.blitter.cache, blitinfo, &cmdbuf->desc_pool.base, &ctx);
121 do {
122 if (ctx.dst.cur_layer < 0)
123 continue;
124
125 struct panvk_batch *batch = panvk_cmd_open_batch(cmdbuf);
126 mali_ptr tsd, tiler;
127
128 views[0].first_layer = views[0].last_layer = ctx.dst.cur_layer;
129 views[1].first_layer = views[1].last_layer = views[0].first_layer;
130 batch->blit.src = src_img->bo;
131 batch->blit.dst = dst_img->bo;
132 panvk_per_arch(cmd_alloc_tls_desc)(cmdbuf, true);
133 panvk_per_arch(cmd_alloc_fb_desc)(cmdbuf);
134 panvk_per_arch(cmd_prepare_tiler_context)(cmdbuf);
135
136 tsd = batch->tls.gpu;
137 tiler = batch->tiler.descs.gpu;
138
139 struct panfrost_ptr job =
140 GENX(pan_blit)(&ctx, &cmdbuf->desc_pool.base, &batch->jc, tsd, tiler);
141 util_dynarray_append(&batch->jobs, void *, job.cpu);
142 panvk_per_arch(cmd_close_batch)(cmdbuf);
143 } while (pan_blit_next_surface(&ctx));
144 }
145
146 void
panvk_per_arch(CmdBlitImage2)147 panvk_per_arch(CmdBlitImage2)(VkCommandBuffer commandBuffer,
148 const VkBlitImageInfo2 *pBlitImageInfo)
149 {
150 VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
151 VK_FROM_HANDLE(panvk_image, src, pBlitImageInfo->srcImage);
152 VK_FROM_HANDLE(panvk_image, dst, pBlitImageInfo->dstImage);
153
154 for (unsigned i = 0; i < pBlitImageInfo->regionCount; i++) {
155 const VkImageBlit2 *region = &pBlitImageInfo->pRegions[i];
156 struct pan_blit_info info = {
157 .src =
158 {
159 .planes[0].image = &src->pimage,
160 .planes[0].format = src->pimage.layout.format,
161 .level = region->srcSubresource.mipLevel,
162 .start =
163 {
164 region->srcOffsets[0].x,
165 region->srcOffsets[0].y,
166 region->srcOffsets[0].z,
167 region->srcSubresource.baseArrayLayer,
168 },
169 .end =
170 {
171 region->srcOffsets[1].x,
172 region->srcOffsets[1].y,
173 region->srcOffsets[1].z,
174 region->srcSubresource.baseArrayLayer +
175 region->srcSubresource.layerCount - 1,
176 },
177 },
178 .dst =
179 {
180 .planes[0].image = &dst->pimage,
181 .planes[0].format = dst->pimage.layout.format,
182 .level = region->dstSubresource.mipLevel,
183 .start =
184 {
185 region->dstOffsets[0].x,
186 region->dstOffsets[0].y,
187 region->dstOffsets[0].z,
188 region->dstSubresource.baseArrayLayer,
189 },
190 .end =
191 {
192 region->dstOffsets[1].x,
193 region->dstOffsets[1].y,
194 region->dstOffsets[1].z,
195 region->dstSubresource.baseArrayLayer +
196 region->dstSubresource.layerCount - 1,
197 },
198 },
199 .nearest = pBlitImageInfo->filter == VK_FILTER_NEAREST,
200 };
201
202 if (region->srcSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
203 info.src.planes[0].format =
204 util_format_stencil_only(info.src.planes[0].format);
205 else if (region->srcSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)
206 info.src.planes[0].format =
207 util_format_get_depth_only(info.src.planes[0].format);
208
209 if (region->dstSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
210 info.dst.planes[0].format =
211 util_format_stencil_only(info.dst.planes[0].format);
212 else if (region->dstSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)
213 info.dst.planes[0].format =
214 util_format_get_depth_only(info.dst.planes[0].format);
215
216 panvk_meta_blit(cmdbuf, &info, src, dst);
217 }
218 }
219
220 void
panvk_per_arch(CmdResolveImage2)221 panvk_per_arch(CmdResolveImage2)(VkCommandBuffer commandBuffer,
222 const VkResolveImageInfo2 *pResolveImageInfo)
223 {
224 panvk_stub();
225 }
226
227 void
panvk_per_arch(meta_blit_init)228 panvk_per_arch(meta_blit_init)(struct panvk_device *dev)
229 {
230 panvk_pool_init(&dev->meta.blitter.bin_pool, dev, NULL,
231 PAN_KMOD_BO_FLAG_EXECUTABLE, 16 * 1024,
232 "panvk_meta blitter binary pool", false);
233 panvk_pool_init(&dev->meta.blitter.desc_pool, dev, NULL, 0, 16 * 1024,
234 "panvk_meta blitter descriptor pool", false);
235 pan_blend_shader_cache_init(&dev->meta.blend_shader_cache,
236 dev->physical_device->kmod.props.gpu_prod_id);
237 GENX(pan_blitter_cache_init)
238 (&dev->meta.blitter.cache, dev->physical_device->kmod.props.gpu_prod_id,
239 &dev->meta.blend_shader_cache, &dev->meta.blitter.bin_pool.base,
240 &dev->meta.blitter.desc_pool.base);
241 }
242
243 void
panvk_per_arch(meta_blit_cleanup)244 panvk_per_arch(meta_blit_cleanup)(struct panvk_device *dev)
245 {
246 GENX(pan_blitter_cache_cleanup)(&dev->meta.blitter.cache);
247 pan_blend_shader_cache_cleanup(&dev->meta.blend_shader_cache);
248 panvk_pool_cleanup(&dev->meta.blitter.desc_pool);
249 panvk_pool_cleanup(&dev->meta.blitter.bin_pool);
250 }
251