• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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