• 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 #if PAN_ARCH >= 6
122       tsd = batch->tls.gpu;
123       tiler = batch->tiler.descs.gpu;
124 #else
125       tsd = batch->fb.desc.gpu;
126       tiler = 0;
127 #endif
128 
129       struct panfrost_ptr job =
130          GENX(pan_blit)(&ctx, &cmdbuf->desc_pool.base, &batch->scoreboard, tsd, tiler);
131       util_dynarray_append(&batch->jobs, void *, job.cpu);
132       panvk_per_arch(cmd_close_batch)(cmdbuf);
133    } while (pan_blit_next_surface(&ctx));
134 }
135 
136 void
panvk_per_arch(CmdBlitImage)137 panvk_per_arch(CmdBlitImage)(VkCommandBuffer commandBuffer,
138                              VkImage srcImage,
139                              VkImageLayout srcImageLayout,
140                              VkImage destImage,
141                              VkImageLayout destImageLayout,
142                              uint32_t regionCount,
143                              const VkImageBlit *pRegions,
144                              VkFilter filter)
145 {
146    VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
147    VK_FROM_HANDLE(panvk_image, src, srcImage);
148    VK_FROM_HANDLE(panvk_image, dst, destImage);
149 
150    for (unsigned i = 0; i < regionCount; i++) {
151       const VkImageBlit *region = &pRegions[i];
152       struct pan_blit_info info = {
153          .src = {
154             .planes[0].image = &src->pimage,
155             .planes[0].format = src->pimage.layout.format,
156             .level = region->srcSubresource.mipLevel,
157             .start = {
158                region->srcOffsets[0].x,
159                region->srcOffsets[0].y,
160                region->srcOffsets[0].z,
161                region->srcSubresource.baseArrayLayer,
162             },
163             .end = {
164                region->srcOffsets[1].x,
165                region->srcOffsets[1].y,
166                region->srcOffsets[1].z,
167                region->srcSubresource.baseArrayLayer + region->srcSubresource.layerCount - 1,
168             },
169          },
170          .dst = {
171             .planes[0].image = &dst->pimage,
172             .planes[0].format = dst->pimage.layout.format,
173             .level = region->dstSubresource.mipLevel,
174             .start = {
175                region->dstOffsets[0].x,
176                region->dstOffsets[0].y,
177                region->dstOffsets[0].z,
178                region->dstSubresource.baseArrayLayer,
179             },
180             .end = {
181                region->dstOffsets[1].x,
182                region->dstOffsets[1].y,
183                region->dstOffsets[1].z,
184                region->dstSubresource.baseArrayLayer + region->dstSubresource.layerCount - 1,
185             },
186          },
187          .nearest = filter == VK_FILTER_NEAREST,
188       };
189 
190       if (region->srcSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
191          info.src.planes[0].format = util_format_stencil_only(info.src.planes[0].format);
192       else if (region->srcSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)
193          info.src.planes[0].format = util_format_get_depth_only(info.src.planes[0].format);
194 
195       if (region->dstSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
196          info.dst.planes[0].format = util_format_stencil_only(info.dst.planes[0].format);
197       else if (region->dstSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)
198          info.dst.planes[0].format = util_format_get_depth_only(info.dst.planes[0].format);
199 
200       panvk_meta_blit(cmdbuf, &info);
201    }
202 }
203 
204 void
panvk_per_arch(CmdResolveImage)205 panvk_per_arch(CmdResolveImage)(VkCommandBuffer commandBuffer,
206                                 VkImage srcImage,
207                                 VkImageLayout srcImageLayout,
208                                 VkImage destImage,
209                                 VkImageLayout destImageLayout,
210                                 uint32_t regionCount,
211                                 const VkImageResolve *pRegions)
212 {
213    panvk_stub();
214 }
215 
216 void
panvk_per_arch(meta_blit_init)217 panvk_per_arch(meta_blit_init)(struct panvk_physical_device *dev)
218 {
219    panvk_pool_init(&dev->meta.blitter.bin_pool, &dev->pdev, NULL,
220                    PAN_BO_EXECUTE, 16 * 1024,
221                    "panvk_meta blitter binary pool", false);
222    panvk_pool_init(&dev->meta.blitter.desc_pool, &dev->pdev, NULL,
223                    0, 16 * 1024, "panvk_meta blitter descriptor pool",
224                    false);
225    pan_blend_shaders_init(&dev->pdev);
226    GENX(pan_blitter_init)(&dev->pdev, &dev->meta.blitter.bin_pool.base,
227                           &dev->meta.blitter.desc_pool.base);
228 }
229 
230 void
panvk_per_arch(meta_blit_cleanup)231 panvk_per_arch(meta_blit_cleanup)(struct panvk_physical_device *dev)
232 {
233    GENX(pan_blitter_cleanup)(&dev->pdev);
234    pan_blend_shaders_cleanup(&dev->pdev);
235    panvk_pool_cleanup(&dev->meta.blitter.desc_pool);
236    panvk_pool_cleanup(&dev->meta.blitter.bin_pool);
237 }
238