Module: Mesa Branch: main Commit: 4d9329ee90d0cdec5e7e4689b6cd6a81e3dd65a2 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=4d9329ee90d0cdec5e7e4689b6cd6a81e3dd65a2
Author: Boris Brezillon <[email protected]> Date: Wed Sep 8 09:56:04 2021 +0200 panvk: Implement vkCmdBlitImage() Signed-off-by: Boris Brezillon <[email protected]> Reviewed-by: Tomeu Vizoso <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12961> --- src/panfrost/vulkan/panvk_vX_meta_blit.c | 167 ++++++++++++++++++++++++++++++- 1 file changed, 165 insertions(+), 2 deletions(-) diff --git a/src/panfrost/vulkan/panvk_vX_meta_blit.c b/src/panfrost/vulkan/panvk_vX_meta_blit.c index c04ed4a9782..f1247e8c5ef 100644 --- a/src/panfrost/vulkan/panvk_vX_meta_blit.c +++ b/src/panfrost/vulkan/panvk_vX_meta_blit.c @@ -27,6 +27,115 @@ #include "panvk_private.h" +static void +panvk_meta_blit(struct panvk_cmd_buffer *cmdbuf, + const struct pan_blit_info *blitinfo) +{ + struct panfrost_device *pdev = &cmdbuf->device->physical_device->pdev; + struct pan_fb_info *fbinfo = &cmdbuf->state.fb.info; + struct pan_blit_context ctx; + struct pan_image_view views[2] = { + { + .format = blitinfo->dst.planes[0].format, + .dim = MALI_TEXTURE_DIMENSION_2D, + .image = blitinfo->dst.planes[0].image, + .nr_samples = blitinfo->dst.planes[0].image->layout.nr_samples, + .first_level = blitinfo->dst.level, + .last_level = blitinfo->dst.level, + .swizzle = { PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W }, + }, + }; + + *fbinfo = (struct pan_fb_info){ + .width = u_minify(blitinfo->dst.planes[0].image->layout.width, blitinfo->dst.level), + .height = u_minify(blitinfo->dst.planes[0].image->layout.height, blitinfo->dst.level), + .extent = { + .minx = MAX2(MIN2(blitinfo->dst.start.x, blitinfo->dst.end.x), 0), + .miny = MAX2(MIN2(blitinfo->dst.start.y, blitinfo->dst.end.y), 0), + .maxx = MAX2(blitinfo->dst.start.x, blitinfo->dst.end.x), + .maxy = MAX2(blitinfo->dst.start.y, blitinfo->dst.end.y), + }, + .nr_samples = blitinfo->dst.planes[0].image->layout.nr_samples, + }; + + fbinfo->extent.maxx = MIN2(fbinfo->extent.maxx, fbinfo->width - 1); + fbinfo->extent.maxy = MIN2(fbinfo->extent.maxy, fbinfo->height - 1); + + /* TODO: don't force preloads of dst resources if unneeded */ + + const struct util_format_description *fdesc = + util_format_description(blitinfo->dst.planes[0].image->layout.format); + + if (util_format_has_depth(fdesc)) { + /* We want the image format here, otherwise we might lose one of the + * component. + */ + views[0].format = blitinfo->dst.planes[0].image->layout.format; + fbinfo->zs.view.zs = &views[0]; + fbinfo->zs.preload.z = true; + fbinfo->zs.preload.s = util_format_has_stencil(fdesc); + } else if (util_format_has_stencil(fdesc)) { + fbinfo->zs.view.s = &views[0]; + fbinfo->zs.preload.s = true; + } else { + fbinfo->rt_count = 1; + fbinfo->rts[0].view = &views[0]; + fbinfo->rts[0].preload = true; + cmdbuf->state.fb.crc_valid[0] = false; + fbinfo->rts[0].crc_valid = &cmdbuf->state.fb.crc_valid[0]; + } + + if (blitinfo->dst.planes[1].format != PIPE_FORMAT_NONE) { + /* TODO: don't force preloads of dst resources if unneeded */ + views[1].format = blitinfo->dst.planes[1].format; + views[1].dim = MALI_TEXTURE_DIMENSION_2D; + views[1].image = blitinfo->dst.planes[1].image; + views[1].nr_samples = blitinfo->dst.planes[1].image->layout.nr_samples; + views[1].first_level = blitinfo->dst.level; + views[1].last_level = blitinfo->dst.level; + views[1].swizzle[0] = PIPE_SWIZZLE_X; + views[1].swizzle[1] = PIPE_SWIZZLE_Y; + views[1].swizzle[2] = PIPE_SWIZZLE_Z; + views[1].swizzle[3] = PIPE_SWIZZLE_W; + fbinfo->zs.view.s = &views[1]; + } + + if (cmdbuf->state.batch) + panvk_per_arch(cmd_close_batch)(cmdbuf); + + GENX(pan_blit_ctx_init)(pdev, blitinfo, &cmdbuf->desc_pool.base, &ctx); + do { + if (ctx.dst.cur_layer < 0) + continue; + + panvk_cmd_open_batch(cmdbuf); + + struct panvk_batch *batch = cmdbuf->state.batch; + mali_ptr tsd, tiler; + + views[0].first_layer = views[0].last_layer = ctx.dst.cur_layer; + views[1].first_layer = views[1].last_layer = views[0].first_layer; + batch->blit.src = blitinfo->src.planes[0].image->data.bo; + batch->blit.dst = blitinfo->dst.planes[0].image->data.bo; + panvk_per_arch(cmd_alloc_tls_desc)(cmdbuf, true); + panvk_per_arch(cmd_alloc_fb_desc)(cmdbuf); + panvk_per_arch(cmd_prepare_tiler_context)(cmdbuf); + +#if PAN_ARCH >= 6 + tsd = batch->tls.gpu; + tiler = batch->tiler.descs.gpu; +#else + tsd = batch->fb.desc.gpu; + tiler = 0; +#endif + + struct panfrost_ptr job = + GENX(pan_blit)(&ctx, &cmdbuf->desc_pool.base, &batch->scoreboard, tsd, tiler); + util_dynarray_append(&batch->jobs, void *, job.cpu); + panvk_per_arch(cmd_close_batch)(cmdbuf); + } while (pan_blit_next_surface(&ctx)); +} + void panvk_per_arch(CmdBlitImage)(VkCommandBuffer commandBuffer, VkImage srcImage, @@ -36,9 +145,63 @@ panvk_per_arch(CmdBlitImage)(VkCommandBuffer commandBuffer, uint32_t regionCount, const VkImageBlit *pRegions, VkFilter filter) - { - panvk_stub(); + VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer); + VK_FROM_HANDLE(panvk_image, src, srcImage); + VK_FROM_HANDLE(panvk_image, dst, destImage); + + for (unsigned i = 0; i < regionCount; i++) { + const VkImageBlit *region = &pRegions[i]; + struct pan_blit_info info = { + .src = { + .planes[0].image = &src->pimage, + .planes[0].format = src->pimage.layout.format, + .level = region->srcSubresource.mipLevel, + .start = { + region->srcOffsets[0].x, + region->srcOffsets[0].y, + region->srcOffsets[0].z, + region->srcSubresource.baseArrayLayer, + }, + .end = { + region->srcOffsets[1].x, + region->srcOffsets[1].y, + region->srcOffsets[1].z, + region->srcSubresource.baseArrayLayer + region->srcSubresource.layerCount - 1, + }, + }, + .dst = { + .planes[0].image = &dst->pimage, + .planes[0].format = dst->pimage.layout.format, + .level = region->dstSubresource.mipLevel, + .start = { + region->dstOffsets[0].x, + region->dstOffsets[0].y, + region->dstOffsets[0].z, + region->dstSubresource.baseArrayLayer, + }, + .end = { + region->dstOffsets[1].x, + region->dstOffsets[1].y, + region->dstOffsets[1].z, + region->dstSubresource.baseArrayLayer + region->dstSubresource.layerCount - 1, + }, + }, + .nearest = filter == VK_FILTER_NEAREST, + }; + + if (region->srcSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) + info.src.planes[0].format = util_format_stencil_only(info.src.planes[0].format); + else if (region->srcSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) + info.src.planes[0].format = util_format_get_depth_only(info.src.planes[0].format); + + if (region->dstSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) + info.dst.planes[0].format = util_format_stencil_only(info.dst.planes[0].format); + else if (region->dstSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) + info.dst.planes[0].format = util_format_get_depth_only(info.dst.planes[0].format); + + panvk_meta_blit(cmdbuf, &info); + } } void
