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