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 30static void 31panvk_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 131void 132panvk_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 193void 194panvk_per_arch(CmdResolveImage2)(VkCommandBuffer commandBuffer, 195 const VkResolveImageInfo2* pResolveImageInfo) 196{ 197 panvk_stub(); 198} 199 200void 201panvk_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 214void 215panvk_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