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