1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright © 2021 Collabora Ltd.
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
10bf215546Sopenharmony_ci *
11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
13bf215546Sopenharmony_ci * Software.
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE.
22bf215546Sopenharmony_ci */
23bf215546Sopenharmony_ci
24bf215546Sopenharmony_ci#include "gen_macros.h"
25bf215546Sopenharmony_ci
26bf215546Sopenharmony_ci#include "pan_blitter.h"
27bf215546Sopenharmony_ci
28bf215546Sopenharmony_ci#include "panvk_private.h"
29bf215546Sopenharmony_ci
30bf215546Sopenharmony_cistatic void
31bf215546Sopenharmony_cipanvk_meta_blit(struct panvk_cmd_buffer *cmdbuf,
32bf215546Sopenharmony_ci                const struct pan_blit_info *blitinfo)
33bf215546Sopenharmony_ci{
34bf215546Sopenharmony_ci   struct panfrost_device *pdev = &cmdbuf->device->physical_device->pdev;
35bf215546Sopenharmony_ci   struct pan_fb_info *fbinfo = &cmdbuf->state.fb.info;
36bf215546Sopenharmony_ci   struct pan_blit_context ctx;
37bf215546Sopenharmony_ci   struct pan_image_view views[2] = {
38bf215546Sopenharmony_ci      {
39bf215546Sopenharmony_ci         .format = blitinfo->dst.planes[0].format,
40bf215546Sopenharmony_ci         .dim = MALI_TEXTURE_DIMENSION_2D,
41bf215546Sopenharmony_ci         .image = blitinfo->dst.planes[0].image,
42bf215546Sopenharmony_ci         .nr_samples = blitinfo->dst.planes[0].image->layout.nr_samples,
43bf215546Sopenharmony_ci         .first_level = blitinfo->dst.level,
44bf215546Sopenharmony_ci         .last_level = blitinfo->dst.level,
45bf215546Sopenharmony_ci         .swizzle = { PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W },
46bf215546Sopenharmony_ci      },
47bf215546Sopenharmony_ci   };
48bf215546Sopenharmony_ci
49bf215546Sopenharmony_ci   *fbinfo = (struct pan_fb_info){
50bf215546Sopenharmony_ci      .width = u_minify(blitinfo->dst.planes[0].image->layout.width, blitinfo->dst.level),
51bf215546Sopenharmony_ci      .height = u_minify(blitinfo->dst.planes[0].image->layout.height, blitinfo->dst.level),
52bf215546Sopenharmony_ci      .extent = {
53bf215546Sopenharmony_ci         .minx = MAX2(MIN2(blitinfo->dst.start.x, blitinfo->dst.end.x), 0),
54bf215546Sopenharmony_ci         .miny = MAX2(MIN2(blitinfo->dst.start.y, blitinfo->dst.end.y), 0),
55bf215546Sopenharmony_ci         .maxx = MAX2(blitinfo->dst.start.x, blitinfo->dst.end.x),
56bf215546Sopenharmony_ci         .maxy = MAX2(blitinfo->dst.start.y, blitinfo->dst.end.y),
57bf215546Sopenharmony_ci      },
58bf215546Sopenharmony_ci      .nr_samples = blitinfo->dst.planes[0].image->layout.nr_samples,
59bf215546Sopenharmony_ci   };
60bf215546Sopenharmony_ci
61bf215546Sopenharmony_ci   fbinfo->extent.maxx = MIN2(fbinfo->extent.maxx, fbinfo->width - 1);
62bf215546Sopenharmony_ci   fbinfo->extent.maxy = MIN2(fbinfo->extent.maxy, fbinfo->height - 1);
63bf215546Sopenharmony_ci
64bf215546Sopenharmony_ci   /* TODO: don't force preloads of dst resources if unneeded */
65bf215546Sopenharmony_ci
66bf215546Sopenharmony_ci   const struct util_format_description *fdesc =
67bf215546Sopenharmony_ci      util_format_description(blitinfo->dst.planes[0].image->layout.format);
68bf215546Sopenharmony_ci
69bf215546Sopenharmony_ci   if (util_format_has_depth(fdesc)) {
70bf215546Sopenharmony_ci      /* We want the image format here, otherwise we might lose one of the
71bf215546Sopenharmony_ci       * component.
72bf215546Sopenharmony_ci       */
73bf215546Sopenharmony_ci      views[0].format = blitinfo->dst.planes[0].image->layout.format;
74bf215546Sopenharmony_ci      fbinfo->zs.view.zs = &views[0];
75bf215546Sopenharmony_ci      fbinfo->zs.preload.z = true;
76bf215546Sopenharmony_ci      fbinfo->zs.preload.s = util_format_has_stencil(fdesc);
77bf215546Sopenharmony_ci   } else if (util_format_has_stencil(fdesc)) {
78bf215546Sopenharmony_ci      fbinfo->zs.view.s = &views[0];
79bf215546Sopenharmony_ci      fbinfo->zs.preload.s = true;
80bf215546Sopenharmony_ci   } else {
81bf215546Sopenharmony_ci      fbinfo->rt_count = 1;
82bf215546Sopenharmony_ci      fbinfo->rts[0].view = &views[0];
83bf215546Sopenharmony_ci      fbinfo->rts[0].preload = true;
84bf215546Sopenharmony_ci      cmdbuf->state.fb.crc_valid[0] = false;
85bf215546Sopenharmony_ci      fbinfo->rts[0].crc_valid = &cmdbuf->state.fb.crc_valid[0];
86bf215546Sopenharmony_ci   }
87bf215546Sopenharmony_ci
88bf215546Sopenharmony_ci   if (blitinfo->dst.planes[1].format != PIPE_FORMAT_NONE) {
89bf215546Sopenharmony_ci      /* TODO: don't force preloads of dst resources if unneeded */
90bf215546Sopenharmony_ci      views[1].format = blitinfo->dst.planes[1].format;
91bf215546Sopenharmony_ci      views[1].dim = MALI_TEXTURE_DIMENSION_2D;
92bf215546Sopenharmony_ci      views[1].image = blitinfo->dst.planes[1].image;
93bf215546Sopenharmony_ci      views[1].nr_samples = blitinfo->dst.planes[1].image->layout.nr_samples;
94bf215546Sopenharmony_ci      views[1].first_level = blitinfo->dst.level;
95bf215546Sopenharmony_ci      views[1].last_level = blitinfo->dst.level;
96bf215546Sopenharmony_ci      views[1].swizzle[0] = PIPE_SWIZZLE_X;
97bf215546Sopenharmony_ci      views[1].swizzle[1] = PIPE_SWIZZLE_Y;
98bf215546Sopenharmony_ci      views[1].swizzle[2] = PIPE_SWIZZLE_Z;
99bf215546Sopenharmony_ci      views[1].swizzle[3] = PIPE_SWIZZLE_W;
100bf215546Sopenharmony_ci      fbinfo->zs.view.s = &views[1];
101bf215546Sopenharmony_ci   }
102bf215546Sopenharmony_ci
103bf215546Sopenharmony_ci   panvk_per_arch(cmd_close_batch)(cmdbuf);
104bf215546Sopenharmony_ci
105bf215546Sopenharmony_ci   GENX(pan_blit_ctx_init)(pdev, blitinfo, &cmdbuf->desc_pool.base, &ctx);
106bf215546Sopenharmony_ci   do {
107bf215546Sopenharmony_ci      if (ctx.dst.cur_layer < 0)
108bf215546Sopenharmony_ci         continue;
109bf215546Sopenharmony_ci
110bf215546Sopenharmony_ci      struct panvk_batch *batch = panvk_cmd_open_batch(cmdbuf);
111bf215546Sopenharmony_ci      mali_ptr tsd, tiler;
112bf215546Sopenharmony_ci
113bf215546Sopenharmony_ci      views[0].first_layer = views[0].last_layer = ctx.dst.cur_layer;
114bf215546Sopenharmony_ci      views[1].first_layer = views[1].last_layer = views[0].first_layer;
115bf215546Sopenharmony_ci      batch->blit.src = blitinfo->src.planes[0].image->data.bo;
116bf215546Sopenharmony_ci      batch->blit.dst = blitinfo->dst.planes[0].image->data.bo;
117bf215546Sopenharmony_ci      panvk_per_arch(cmd_alloc_tls_desc)(cmdbuf, true);
118bf215546Sopenharmony_ci      panvk_per_arch(cmd_alloc_fb_desc)(cmdbuf);
119bf215546Sopenharmony_ci      panvk_per_arch(cmd_prepare_tiler_context)(cmdbuf);
120bf215546Sopenharmony_ci
121bf215546Sopenharmony_ci      tsd = batch->tls.gpu;
122bf215546Sopenharmony_ci      tiler = batch->tiler.descs.gpu;
123bf215546Sopenharmony_ci
124bf215546Sopenharmony_ci      struct panfrost_ptr job =
125bf215546Sopenharmony_ci         GENX(pan_blit)(&ctx, &cmdbuf->desc_pool.base, &batch->scoreboard, tsd, tiler);
126bf215546Sopenharmony_ci      util_dynarray_append(&batch->jobs, void *, job.cpu);
127bf215546Sopenharmony_ci      panvk_per_arch(cmd_close_batch)(cmdbuf);
128bf215546Sopenharmony_ci   } while (pan_blit_next_surface(&ctx));
129bf215546Sopenharmony_ci}
130bf215546Sopenharmony_ci
131bf215546Sopenharmony_civoid
132bf215546Sopenharmony_cipanvk_per_arch(CmdBlitImage2)(VkCommandBuffer commandBuffer,
133bf215546Sopenharmony_ci                              const VkBlitImageInfo2 *pBlitImageInfo)
134bf215546Sopenharmony_ci{
135bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
136bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_image, src, pBlitImageInfo->srcImage);
137bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_image, dst, pBlitImageInfo->dstImage);
138bf215546Sopenharmony_ci
139bf215546Sopenharmony_ci   for (unsigned i = 0; i < pBlitImageInfo->regionCount; i++) {
140bf215546Sopenharmony_ci      const VkImageBlit2 *region = &pBlitImageInfo->pRegions[i];
141bf215546Sopenharmony_ci      struct pan_blit_info info = {
142bf215546Sopenharmony_ci         .src = {
143bf215546Sopenharmony_ci            .planes[0].image = &src->pimage,
144bf215546Sopenharmony_ci            .planes[0].format = src->pimage.layout.format,
145bf215546Sopenharmony_ci            .level = region->srcSubresource.mipLevel,
146bf215546Sopenharmony_ci            .start = {
147bf215546Sopenharmony_ci               region->srcOffsets[0].x,
148bf215546Sopenharmony_ci               region->srcOffsets[0].y,
149bf215546Sopenharmony_ci               region->srcOffsets[0].z,
150bf215546Sopenharmony_ci               region->srcSubresource.baseArrayLayer,
151bf215546Sopenharmony_ci            },
152bf215546Sopenharmony_ci            .end = {
153bf215546Sopenharmony_ci               region->srcOffsets[1].x,
154bf215546Sopenharmony_ci               region->srcOffsets[1].y,
155bf215546Sopenharmony_ci               region->srcOffsets[1].z,
156bf215546Sopenharmony_ci               region->srcSubresource.baseArrayLayer + region->srcSubresource.layerCount - 1,
157bf215546Sopenharmony_ci            },
158bf215546Sopenharmony_ci         },
159bf215546Sopenharmony_ci         .dst = {
160bf215546Sopenharmony_ci            .planes[0].image = &dst->pimage,
161bf215546Sopenharmony_ci            .planes[0].format = dst->pimage.layout.format,
162bf215546Sopenharmony_ci            .level = region->dstSubresource.mipLevel,
163bf215546Sopenharmony_ci            .start = {
164bf215546Sopenharmony_ci               region->dstOffsets[0].x,
165bf215546Sopenharmony_ci               region->dstOffsets[0].y,
166bf215546Sopenharmony_ci               region->dstOffsets[0].z,
167bf215546Sopenharmony_ci               region->dstSubresource.baseArrayLayer,
168bf215546Sopenharmony_ci            },
169bf215546Sopenharmony_ci            .end = {
170bf215546Sopenharmony_ci               region->dstOffsets[1].x,
171bf215546Sopenharmony_ci               region->dstOffsets[1].y,
172bf215546Sopenharmony_ci               region->dstOffsets[1].z,
173bf215546Sopenharmony_ci               region->dstSubresource.baseArrayLayer + region->dstSubresource.layerCount - 1,
174bf215546Sopenharmony_ci            },
175bf215546Sopenharmony_ci         },
176bf215546Sopenharmony_ci         .nearest = pBlitImageInfo->filter == VK_FILTER_NEAREST,
177bf215546Sopenharmony_ci      };
178bf215546Sopenharmony_ci
179bf215546Sopenharmony_ci      if (region->srcSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
180bf215546Sopenharmony_ci         info.src.planes[0].format = util_format_stencil_only(info.src.planes[0].format);
181bf215546Sopenharmony_ci      else if (region->srcSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)
182bf215546Sopenharmony_ci         info.src.planes[0].format = util_format_get_depth_only(info.src.planes[0].format);
183bf215546Sopenharmony_ci
184bf215546Sopenharmony_ci      if (region->dstSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
185bf215546Sopenharmony_ci         info.dst.planes[0].format = util_format_stencil_only(info.dst.planes[0].format);
186bf215546Sopenharmony_ci      else if (region->dstSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)
187bf215546Sopenharmony_ci         info.dst.planes[0].format = util_format_get_depth_only(info.dst.planes[0].format);
188bf215546Sopenharmony_ci
189bf215546Sopenharmony_ci      panvk_meta_blit(cmdbuf, &info);
190bf215546Sopenharmony_ci   }
191bf215546Sopenharmony_ci}
192bf215546Sopenharmony_ci
193bf215546Sopenharmony_civoid
194bf215546Sopenharmony_cipanvk_per_arch(CmdResolveImage2)(VkCommandBuffer commandBuffer,
195bf215546Sopenharmony_ci                                 const VkResolveImageInfo2* pResolveImageInfo)
196bf215546Sopenharmony_ci{
197bf215546Sopenharmony_ci   panvk_stub();
198bf215546Sopenharmony_ci}
199bf215546Sopenharmony_ci
200bf215546Sopenharmony_civoid
201bf215546Sopenharmony_cipanvk_per_arch(meta_blit_init)(struct panvk_physical_device *dev)
202bf215546Sopenharmony_ci{
203bf215546Sopenharmony_ci   panvk_pool_init(&dev->meta.blitter.bin_pool, &dev->pdev, NULL,
204bf215546Sopenharmony_ci                   PAN_BO_EXECUTE, 16 * 1024,
205bf215546Sopenharmony_ci                   "panvk_meta blitter binary pool", false);
206bf215546Sopenharmony_ci   panvk_pool_init(&dev->meta.blitter.desc_pool, &dev->pdev, NULL,
207bf215546Sopenharmony_ci                   0, 16 * 1024, "panvk_meta blitter descriptor pool",
208bf215546Sopenharmony_ci                   false);
209bf215546Sopenharmony_ci   pan_blend_shaders_init(&dev->pdev);
210bf215546Sopenharmony_ci   GENX(pan_blitter_init)(&dev->pdev, &dev->meta.blitter.bin_pool.base,
211bf215546Sopenharmony_ci                          &dev->meta.blitter.desc_pool.base);
212bf215546Sopenharmony_ci}
213bf215546Sopenharmony_ci
214bf215546Sopenharmony_civoid
215bf215546Sopenharmony_cipanvk_per_arch(meta_blit_cleanup)(struct panvk_physical_device *dev)
216bf215546Sopenharmony_ci{
217bf215546Sopenharmony_ci   GENX(pan_blitter_cleanup)(&dev->pdev);
218bf215546Sopenharmony_ci   pan_blend_shaders_cleanup(&dev->pdev);
219bf215546Sopenharmony_ci   panvk_pool_cleanup(&dev->meta.blitter.desc_pool);
220bf215546Sopenharmony_ci   panvk_pool_cleanup(&dev->meta.blitter.bin_pool);
221bf215546Sopenharmony_ci}
222