panvk: Switch to vk_meta

Replace our custom panvk_meta stuff by something based on vk_meta.
That's less gen-specific code to maintain which will help with v10
support.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Mary Guillemard <mary.guillemard@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29451>
This commit is contained in:
Boris Brezillon
2024-04-29 10:21:28 +02:00
committed by Marge Bot
parent 38258138ad
commit 5067921349
15 changed files with 597 additions and 2959 deletions

View File

@@ -235,7 +235,7 @@ single_desc_copy(nir_builder *b, nir_def *desc_copy_idx)
nir_pop_if(b, NULL);
}
static mali_ptr
static struct panvk_priv_mem
panvk_meta_desc_copy_shader(struct panvk_device *dev,
struct pan_shader_info *shader_info)
{
@@ -270,8 +270,8 @@ panvk_meta_desc_copy_shader(struct panvk_device *dev,
shader_info->push.count =
DIV_ROUND_UP(sizeof(struct pan_nir_desc_copy_info), 4);
mali_ptr shader = pan_pool_upload_aligned(&dev->meta.bin_pool.base,
binary.data, binary.size, 128);
struct panvk_priv_mem shader = panvk_pool_upload_aligned(
&dev->mempools.exec, binary.data, binary.size, 128);
util_dynarray_fini(&binary);
return shader;
@@ -282,15 +282,24 @@ panvk_per_arch(meta_desc_copy_init)(struct panvk_device *dev)
{
struct pan_shader_info shader_info;
mali_ptr shader = panvk_meta_desc_copy_shader(dev, &shader_info);
struct panfrost_ptr rsd =
pan_pool_alloc_desc(&dev->meta.desc_pool.base, RENDERER_STATE);
dev->desc_copy.shader = panvk_meta_desc_copy_shader(dev, &shader_info);
pan_pack(rsd.cpu, RENDERER_STATE, cfg) {
mali_ptr shader = panvk_priv_mem_dev_addr(dev->desc_copy.shader);
struct panvk_priv_mem rsd =
panvk_pool_alloc_desc(&dev->mempools.rw, RENDERER_STATE);
pan_pack(panvk_priv_mem_host_addr(rsd), RENDERER_STATE, cfg) {
pan_shader_prepare_rsd(&shader_info, shader, &cfg);
}
dev->meta.desc_copy.rsd = rsd.gpu;
dev->desc_copy.rsd = rsd;
}
void
panvk_per_arch(meta_desc_copy_cleanup)(struct panvk_device *dev)
{
panvk_pool_free_mem(&dev->mempools.rw, dev->desc_copy.rsd);
panvk_pool_free_mem(&dev->mempools.exec, dev->desc_copy.shader);
}
struct panfrost_ptr
@@ -368,7 +377,7 @@ panvk_per_arch(meta_get_copy_desc_job)(
GENX(pan_emit_tls)(&tlsinfo, tls.cpu);
pan_section_pack(job.cpu, COMPUTE_JOB, DRAW, cfg) {
cfg.state = dev->meta.desc_copy.rsd;
cfg.state = panvk_priv_mem_dev_addr(dev->desc_copy.rsd);
cfg.push_uniforms = push_uniforms;
cfg.thread_storage = tls.gpu;
}

View File

@@ -154,7 +154,7 @@ panvk_per_arch(cmd_close_batch)(struct panvk_cmd_buffer *cmdbuf)
cmdbuf->state.gfx.render.fb.info.bifrost.pre_post.dcds.gpu = 0;
ASSERTED unsigned num_preload_jobs = GENX(pan_preload_fb)(
&dev->meta.blitter.cache, &cmdbuf->desc_pool.base,
&dev->blitter.cache, &cmdbuf->desc_pool.base,
&cmdbuf->state.gfx.render.fb.info, i, batch->tls.gpu, NULL);
/* Bifrost GPUs use pre frame DCDs to preload the FB content. We

View File

@@ -15,6 +15,7 @@
#include "panvk_cmd_desc_state.h"
#include "panvk_device.h"
#include "panvk_entrypoints.h"
#include "panvk_meta.h"
#include "panvk_physical_device.h"
#include "pan_desc.h"

View File

@@ -32,6 +32,7 @@
#include "pan_shader.h"
#include "vk_format.h"
#include "vk_meta.h"
#include "vk_pipeline_layout.h"
struct panvk_draw_info {
@@ -857,6 +858,12 @@ panvk_draw_prepare_vertex_job(struct panvk_cmd_buffer *cmdbuf,
static enum mali_draw_mode
translate_prim_topology(VkPrimitiveTopology in)
{
/* Test VK_PRIMITIVE_TOPOLOGY_META_RECT_LIST_MESA separately, as it's not
* part of the VkPrimitiveTopology enum.
*/
if (in == VK_PRIMITIVE_TOPOLOGY_META_RECT_LIST_MESA)
return MALI_DRAW_MODE_TRIANGLES;
switch (in) {
case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
return MALI_DRAW_MODE_POINTS;

View File

@@ -1,84 +0,0 @@
/*
* Copyright © 2021 Collabora Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "genxml/gen_macros.h"
#include "nir/nir_builder.h"
#include "pan_encoder.h"
#include "pan_shader.h"
#include "panvk_device.h"
#include "vk_format.h"
mali_ptr
panvk_per_arch(meta_emit_viewport)(struct pan_pool *pool, uint16_t minx,
uint16_t miny, uint16_t maxx, uint16_t maxy)
{
struct panfrost_ptr vp = pan_pool_alloc_desc(pool, VIEWPORT);
pan_pack(vp.cpu, VIEWPORT, cfg) {
cfg.scissor_minimum_x = minx;
cfg.scissor_minimum_y = miny;
cfg.scissor_maximum_x = maxx;
cfg.scissor_maximum_y = maxy;
}
return vp.gpu;
}
void
panvk_per_arch(meta_init)(struct panvk_device *dev)
{
struct panvk_pool_properties bin_pool_props = {
.create_flags = PAN_KMOD_BO_FLAG_EXECUTABLE,
.slab_size = 16 * 1024,
.label = "panvk_meta binary pool",
.prealloc = false,
.owns_bos = true,
.needs_locking = false,
};
struct panvk_pool_properties desc_pool_props = {
.create_flags = 0,
.slab_size = 16 * 1024,
.label = "panvk_meta descriptor pool",
.prealloc = false,
.owns_bos = true,
.needs_locking = false,
};
panvk_pool_init(&dev->meta.bin_pool, dev, NULL, &bin_pool_props);
panvk_pool_init(&dev->meta.desc_pool, dev, NULL, &desc_pool_props);
panvk_per_arch(meta_blit_init)(dev);
panvk_per_arch(meta_copy_init)(dev);
panvk_per_arch(meta_clear_init)(dev);
panvk_per_arch(meta_desc_copy_init)(dev);
}
void
panvk_per_arch(meta_cleanup)(struct panvk_device *dev)
{
panvk_per_arch(meta_blit_cleanup)(dev);
panvk_pool_cleanup(&dev->meta.desc_pool);
panvk_pool_cleanup(&dev->meta.bin_pool);
}

View File

@@ -1,272 +0,0 @@
/*
* Copyright © 2021 Collabora Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "gen_macros.h"
#include "pan_blitter.h"
#include "pan_props.h"
#include "panvk_cmd_buffer.h"
#include "panvk_device.h"
#include "panvk_entrypoints.h"
#include "panvk_image.h"
#include "panvk_physical_device.h"
static void
panvk_meta_blit(struct panvk_cmd_buffer *cmdbuf,
const struct pan_blit_info *blitinfo,
const struct panvk_image *src_img,
const struct panvk_image *dst_img)
{
struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
struct panvk_physical_device *phys_dev =
to_panvk_physical_device(dev->vk.physical);
struct pan_fb_info *fbinfo = &cmdbuf->state.gfx.render.fb.info;
struct pan_blit_context ctx;
struct pan_image_view views[2] = {
{
.format = blitinfo->dst.planes[0].format,
.dim = MALI_TEXTURE_DIMENSION_2D,
.planes =
{
blitinfo->dst.planes[0].image,
blitinfo->dst.planes[1].image,
blitinfo->dst.planes[2].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){
.tile_buf_budget = panfrost_query_optimal_tib_size(phys_dev->model),
.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.gfx.render.fb.crc_valid[0] = false;
fbinfo->rts[0].crc_valid = &cmdbuf->state.gfx.render.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].planes[0] = 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];
}
panvk_per_arch(cmd_close_batch)(cmdbuf);
cmdbuf->state.gfx.render.layer_count = 1;
GENX(pan_blit_ctx_init)
(&dev->meta.blitter.cache, blitinfo, &cmdbuf->desc_pool.base, &ctx);
do {
if (ctx.dst.cur_layer < 0)
continue;
struct panvk_batch *batch = panvk_per_arch(cmd_open_batch)(cmdbuf);
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 = src_img->bo;
batch->blit.dst = dst_img->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, 0);
tsd = batch->tls.gpu;
tiler = batch->tiler.ctx_descs.gpu;
struct panfrost_ptr job = GENX(pan_blit)(&ctx, &cmdbuf->desc_pool.base,
&batch->vtc_jc, tsd, tiler);
util_dynarray_append(&batch->jobs, void *, job.cpu);
panvk_per_arch(cmd_close_batch)(cmdbuf);
} while (pan_blit_next_surface(&ctx));
}
VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdBlitImage2)(VkCommandBuffer commandBuffer,
const VkBlitImageInfo2 *pBlitImageInfo)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
VK_FROM_HANDLE(panvk_image, src, pBlitImageInfo->srcImage);
VK_FROM_HANDLE(panvk_image, dst, pBlitImageInfo->dstImage);
for (unsigned i = 0; i < pBlitImageInfo->regionCount; i++) {
const VkImageBlit2 *region = &pBlitImageInfo->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 = pBlitImageInfo->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, src, dst);
}
}
VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdResolveImage2)(VkCommandBuffer commandBuffer,
const VkResolveImageInfo2 *pResolveImageInfo)
{
panvk_stub();
}
void
panvk_per_arch(meta_blit_init)(struct panvk_device *dev)
{
struct panvk_physical_device *phys_dev =
to_panvk_physical_device(dev->vk.physical);
struct panvk_pool_properties bin_pool_props = {
.create_flags = PAN_KMOD_BO_FLAG_EXECUTABLE,
.slab_size = 16 * 1024,
.label = "panvk_meta blitter binary pool",
.prealloc = false,
.owns_bos = true,
.needs_locking = false,
};
struct panvk_pool_properties desc_pool_props = {
.create_flags = 0,
.slab_size = 16 * 1024,
.label = "panvk_meta blitter descriptor pool",
.prealloc = false,
.owns_bos = true,
.needs_locking = false,
};
panvk_pool_init(&dev->meta.blitter.bin_pool, dev, NULL, &bin_pool_props);
panvk_pool_init(&dev->meta.blitter.desc_pool, dev, NULL, &desc_pool_props);
pan_blend_shader_cache_init(&dev->meta.blend_shader_cache,
phys_dev->kmod.props.gpu_prod_id);
GENX(pan_blitter_cache_init)
(&dev->meta.blitter.cache, phys_dev->kmod.props.gpu_prod_id,
&dev->meta.blend_shader_cache, &dev->meta.blitter.bin_pool.base,
&dev->meta.blitter.desc_pool.base);
}
void
panvk_per_arch(meta_blit_cleanup)(struct panvk_device *dev)
{
GENX(pan_blitter_cache_cleanup)(&dev->meta.blitter.cache);
pan_blend_shader_cache_cleanup(&dev->meta.blend_shader_cache);
panvk_pool_cleanup(&dev->meta.blitter.desc_pool);
panvk_pool_cleanup(&dev->meta.blitter.bin_pool);
}

View File

@@ -1,529 +0,0 @@
/*
* Copyright © 2021 Collabora Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "nir/nir_builder.h"
#include "pan_blitter.h"
#include "pan_encoder.h"
#include "pan_props.h"
#include "pan_shader.h"
#include "panvk_cmd_buffer.h"
#include "panvk_device.h"
#include "panvk_entrypoints.h"
#include "panvk_image.h"
#include "panvk_meta.h"
#include "panvk_physical_device.h"
#include "vk_format.h"
#include "vk_render_pass.h"
static mali_ptr
panvk_meta_clear_color_attachment_shader(struct panvk_device *dev,
enum glsl_base_type base_type,
struct pan_shader_info *shader_info)
{
struct panvk_physical_device *phys_dev =
to_panvk_physical_device(dev->vk.physical);
struct pan_pool *bin_pool = &dev->meta.bin_pool.base;
nir_builder b = nir_builder_init_simple_shader(
MESA_SHADER_FRAGMENT, GENX(pan_shader_get_compiler_options)(),
"panvk_meta_clear_attachment(base_type=%d)", base_type);
const struct glsl_type *out_type = glsl_vector_type(base_type, 4);
nir_variable *out =
nir_variable_create(b.shader, nir_var_shader_out, out_type, "out");
out->data.location = FRAG_RESULT_DATA0;
nir_def *clear_values =
nir_load_push_constant(&b, 4, 32, nir_imm_int(&b, 0), .range = ~0);
nir_store_var(&b, out, clear_values, 0xff);
struct panfrost_compile_inputs inputs = {
.gpu_id = phys_dev->kmod.props.gpu_prod_id,
.is_blit = true,
.no_ubo_to_push = true,
};
struct util_dynarray binary;
util_dynarray_init(&binary, NULL);
pan_shader_preprocess(b.shader, inputs.gpu_id);
GENX(pan_shader_compile)(b.shader, &inputs, &binary, shader_info);
shader_info->push.count = 4;
mali_ptr shader =
pan_pool_upload_aligned(bin_pool, binary.data, binary.size, 128);
util_dynarray_fini(&binary);
ralloc_free(b.shader);
return shader;
}
static mali_ptr
panvk_meta_clear_color_attachment_emit_rsd(struct pan_pool *desc_pool,
enum pipe_format format, unsigned rt,
struct pan_shader_info *shader_info,
mali_ptr shader)
{
struct panfrost_ptr rsd_ptr = pan_pool_alloc_desc_aggregate(
desc_pool, PAN_DESC(RENDERER_STATE), PAN_DESC_ARRAY(rt + 1, BLEND));
pan_pack(rsd_ptr.cpu, RENDERER_STATE, cfg) {
pan_shader_prepare_rsd(shader_info, shader, &cfg);
cfg.properties.depth_source = MALI_DEPTH_SOURCE_FIXED_FUNCTION;
cfg.multisample_misc.sample_mask = UINT16_MAX;
cfg.multisample_misc.depth_function = MALI_FUNC_ALWAYS;
cfg.properties.allow_forward_pixel_to_be_killed = true;
cfg.properties.allow_forward_pixel_to_kill = true;
cfg.properties.zs_update_operation = MALI_PIXEL_KILL_WEAK_EARLY;
cfg.properties.pixel_kill_operation = MALI_PIXEL_KILL_WEAK_EARLY;
}
void *bd = rsd_ptr.cpu + pan_size(RENDERER_STATE);
pan_pack(bd, BLEND, cfg) {
cfg.round_to_fb_precision = true;
cfg.load_destination = false;
cfg.equation.rgb.a = MALI_BLEND_OPERAND_A_SRC;
cfg.equation.rgb.b = MALI_BLEND_OPERAND_B_SRC;
cfg.equation.rgb.c = MALI_BLEND_OPERAND_C_ZERO;
cfg.equation.alpha.a = MALI_BLEND_OPERAND_A_SRC;
cfg.equation.alpha.b = MALI_BLEND_OPERAND_B_SRC;
cfg.equation.alpha.c = MALI_BLEND_OPERAND_C_ZERO;
cfg.internal.mode = MALI_BLEND_MODE_OPAQUE;
cfg.equation.color_mask = 0xf;
cfg.internal.fixed_function.num_comps = 4;
cfg.internal.fixed_function.rt = rt;
cfg.internal.fixed_function.conversion.memory_format =
GENX(panfrost_dithered_format_from_pipe_format)(format, false);
cfg.internal.fixed_function.conversion.register_format =
shader_info->bifrost.blend[0].format;
}
return rsd_ptr.gpu;
}
static mali_ptr
panvk_meta_clear_zs_attachment_emit_rsd(struct pan_pool *desc_pool,
VkImageAspectFlags mask,
VkClearDepthStencilValue value)
{
struct panfrost_ptr rsd_ptr = pan_pool_alloc_desc(desc_pool, RENDERER_STATE);
pan_pack(rsd_ptr.cpu, RENDERER_STATE, cfg) {
cfg.properties.depth_source = MALI_DEPTH_SOURCE_FIXED_FUNCTION;
cfg.multisample_misc.sample_mask = UINT16_MAX;
if (mask & VK_IMAGE_ASPECT_DEPTH_BIT) {
cfg.multisample_misc.depth_write_mask = true;
cfg.multisample_misc.depth_function = MALI_FUNC_NOT_EQUAL;
if (value.depth != 0.0) {
cfg.stencil_mask_misc.front_facing_depth_bias = true;
cfg.stencil_mask_misc.back_facing_depth_bias = true;
cfg.depth_units = INFINITY;
cfg.depth_bias_clamp = value.depth;
}
}
if (mask & VK_IMAGE_ASPECT_STENCIL_BIT) {
cfg.stencil_mask_misc.stencil_enable = true;
cfg.stencil_mask_misc.stencil_mask_front = 0xFF;
cfg.stencil_mask_misc.stencil_mask_back = 0xFF;
cfg.stencil_front.compare_function = (mask & VK_IMAGE_ASPECT_DEPTH_BIT)
? MALI_FUNC_ALWAYS
: MALI_FUNC_NOT_EQUAL;
cfg.stencil_front.stencil_fail = MALI_STENCIL_OP_KEEP;
cfg.stencil_front.depth_fail = MALI_STENCIL_OP_REPLACE;
cfg.stencil_front.depth_pass = MALI_STENCIL_OP_REPLACE;
cfg.stencil_front.reference_value = value.stencil;
cfg.stencil_front.mask = 0xFF;
cfg.stencil_back = cfg.stencil_front;
}
cfg.properties.allow_forward_pixel_to_be_killed = true;
cfg.properties.zs_update_operation = MALI_PIXEL_KILL_WEAK_EARLY;
cfg.properties.pixel_kill_operation = MALI_PIXEL_KILL_WEAK_EARLY;
}
return rsd_ptr.gpu;
}
static void
panvk_meta_clear_attachment_emit_dcd(struct pan_pool *pool, mali_ptr coords,
mali_ptr push_constants, mali_ptr vpd,
mali_ptr tsd, mali_ptr rsd, void *out)
{
pan_pack(out, DRAW, cfg) {
cfg.thread_storage = tsd;
cfg.state = rsd;
cfg.push_uniforms = push_constants;
cfg.position = coords;
cfg.viewport = vpd;
}
}
static struct panfrost_ptr
panvk_meta_clear_attachment_emit_tiler_job(struct pan_pool *desc_pool,
struct pan_jc *jc, mali_ptr coords,
mali_ptr push_constants,
mali_ptr vpd, mali_ptr rsd,
mali_ptr tsd, mali_ptr tiler)
{
struct panfrost_ptr job = pan_pool_alloc_desc(desc_pool, TILER_JOB);
panvk_meta_clear_attachment_emit_dcd(
desc_pool, coords, push_constants, vpd, tsd, rsd,
pan_section_ptr(job.cpu, TILER_JOB, DRAW));
pan_section_pack(job.cpu, TILER_JOB, PRIMITIVE, cfg) {
cfg.draw_mode = MALI_DRAW_MODE_TRIANGLE_STRIP;
cfg.index_count = 4;
cfg.job_task_split = 6;
}
pan_section_pack(job.cpu, TILER_JOB, PRIMITIVE_SIZE, cfg) {
cfg.constant = 1.0f;
}
void *invoc = pan_section_ptr(job.cpu, TILER_JOB, INVOCATION);
panfrost_pack_work_groups_compute(invoc, 1, 4, 1, 1, 1, 1, true, false);
pan_section_pack(job.cpu, TILER_JOB, PADDING, cfg)
;
pan_section_pack(job.cpu, TILER_JOB, TILER, cfg) {
cfg.address = tiler;
}
pan_jc_add_job(jc, MALI_JOB_TYPE_TILER, false, false, 0, 0, &job, false);
return job;
}
static enum glsl_base_type
panvk_meta_get_format_type(enum pipe_format format)
{
const struct util_format_description *desc = util_format_description(format);
int i;
i = util_format_get_first_non_void_channel(format);
assert(i >= 0);
if (desc->channel[i].normalized)
return GLSL_TYPE_FLOAT;
switch (desc->channel[i].type) {
case UTIL_FORMAT_TYPE_UNSIGNED:
return GLSL_TYPE_UINT;
case UTIL_FORMAT_TYPE_SIGNED:
return GLSL_TYPE_INT;
case UTIL_FORMAT_TYPE_FLOAT:
return GLSL_TYPE_FLOAT;
default:
unreachable("Unhandled format");
return GLSL_TYPE_FLOAT;
}
}
static void
panvk_meta_clear_attachment(struct panvk_cmd_buffer *cmdbuf, unsigned rt,
VkImageAspectFlags mask,
const VkClearValue *clear_value,
const VkClearRect *clear_rect)
{
struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
struct panvk_meta *meta = &dev->meta;
struct panvk_batch *batch = cmdbuf->cur_batch;
enum pipe_format pfmt =
cmdbuf->state.gfx.render.fb.info.rts[rt].view->format;
unsigned minx = MAX2(clear_rect->rect.offset.x, 0);
unsigned miny = MAX2(clear_rect->rect.offset.y, 0);
unsigned maxx =
MAX2(clear_rect->rect.offset.x + clear_rect->rect.extent.width - 1, 0);
unsigned maxy =
MAX2(clear_rect->rect.offset.y + clear_rect->rect.extent.height - 1, 0);
panvk_per_arch(cmd_alloc_fb_desc)(cmdbuf);
panvk_per_arch(cmd_alloc_tls_desc)(cmdbuf, true);
cmdbuf->state.gfx.render.layer_count = 1;
panvk_per_arch(cmd_prepare_tiler_context)(cmdbuf, 0);
mali_ptr vpd = panvk_per_arch(meta_emit_viewport)(&cmdbuf->desc_pool.base,
minx, miny, maxx, maxy);
float rect[] = {
minx, miny, 0.0, 1.0, maxx + 1, miny, 0.0, 1.0,
minx, maxy + 1, 0.0, 1.0, maxx + 1, maxy + 1, 0.0, 1.0,
};
mali_ptr coordinates =
pan_pool_upload_aligned(&cmdbuf->desc_pool.base, rect, sizeof(rect), 64);
enum glsl_base_type base_type = panvk_meta_get_format_type(pfmt);
mali_ptr tiler = batch->tiler.ctx_descs.gpu;
mali_ptr tsd = batch->tls.gpu;
mali_ptr pushconsts = 0, rsd = 0;
if (mask & VK_IMAGE_ASPECT_COLOR_BIT) {
mali_ptr shader = meta->clear_attachment.color[base_type].shader;
struct pan_shader_info *shader_info =
&meta->clear_attachment.color[base_type].shader_info;
pushconsts = pan_pool_upload_aligned(&cmdbuf->desc_pool.base, clear_value,
sizeof(*clear_value), 16);
rsd = panvk_meta_clear_color_attachment_emit_rsd(
&cmdbuf->desc_pool.base, pfmt, rt, shader_info, shader);
} else {
rsd = panvk_meta_clear_zs_attachment_emit_rsd(
&cmdbuf->desc_pool.base, mask, clear_value->depthStencil);
}
struct panfrost_ptr job;
job = panvk_meta_clear_attachment_emit_tiler_job(
&cmdbuf->desc_pool.base, &batch->vtc_jc, coordinates, pushconsts, vpd,
rsd, tsd, tiler);
util_dynarray_append(&batch->jobs, void *, job.cpu);
}
static void
panvk_meta_clear_color_img(struct panvk_cmd_buffer *cmdbuf,
struct panvk_image *img,
const VkClearColorValue *color,
const VkImageSubresourceRange *range)
{
struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
struct panvk_physical_device *phys_dev =
to_panvk_physical_device(dev->vk.physical);
struct pan_fb_info *fbinfo = &cmdbuf->state.gfx.render.fb.info;
struct pan_image_view view = {
.format = img->pimage.layout.format,
.dim = MALI_TEXTURE_DIMENSION_2D,
.planes[0] = &img->pimage,
.nr_samples = img->pimage.layout.nr_samples,
.swizzle = {PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, PIPE_SWIZZLE_Z,
PIPE_SWIZZLE_W},
};
cmdbuf->state.gfx.render.layer_count = 1;
cmdbuf->state.gfx.render.fb.crc_valid[0] = false;
*fbinfo = (struct pan_fb_info){
.tile_buf_budget = panfrost_query_optimal_tib_size(phys_dev->model),
.nr_samples = img->pimage.layout.nr_samples,
.rt_count = 1,
.rts[0].view = &view,
.rts[0].clear = true,
.rts[0].crc_valid = &cmdbuf->state.gfx.render.fb.crc_valid[0],
};
uint32_t clearval[4];
pan_pack_color(panfrost_blendable_formats_v7, clearval,
(union pipe_color_union *)color, img->pimage.layout.format,
false);
memcpy(fbinfo->rts[0].clear_value, clearval,
sizeof(fbinfo->rts[0].clear_value));
unsigned level_count = vk_image_subresource_level_count(&img->vk, range);
unsigned layer_count = vk_image_subresource_layer_count(&img->vk, range);
for (unsigned level = range->baseMipLevel;
level < range->baseMipLevel + level_count; level++) {
view.first_level = view.last_level = level;
fbinfo->width = u_minify(img->pimage.layout.width, level);
fbinfo->height = u_minify(img->pimage.layout.height, level);
fbinfo->extent.maxx = fbinfo->width - 1;
fbinfo->extent.maxy = fbinfo->height - 1;
for (unsigned layer = range->baseArrayLayer;
layer < range->baseArrayLayer + layer_count; layer++) {
view.first_layer = view.last_layer = layer;
panvk_per_arch(cmd_open_batch)(cmdbuf);
panvk_per_arch(cmd_alloc_fb_desc)(cmdbuf);
panvk_per_arch(cmd_close_batch)(cmdbuf);
}
}
}
VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdClearColorImage)(VkCommandBuffer commandBuffer, VkImage image,
VkImageLayout imageLayout,
const VkClearColorValue *pColor,
uint32_t rangeCount,
const VkImageSubresourceRange *pRanges)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
VK_FROM_HANDLE(panvk_image, img, image);
panvk_per_arch(cmd_close_batch)(cmdbuf);
for (unsigned i = 0; i < rangeCount; i++)
panvk_meta_clear_color_img(cmdbuf, img, pColor, &pRanges[i]);
}
static void
panvk_meta_clear_zs_img(struct panvk_cmd_buffer *cmdbuf,
struct panvk_image *img,
const VkClearDepthStencilValue *value,
const VkImageSubresourceRange *range)
{
struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
struct panvk_physical_device *phys_dev =
to_panvk_physical_device(dev->vk.physical);
struct pan_fb_info *fbinfo = &cmdbuf->state.gfx.render.fb.info;
struct pan_image_view view = {
.format = img->pimage.layout.format,
.dim = MALI_TEXTURE_DIMENSION_2D,
.planes[0] = &img->pimage,
.nr_samples = img->pimage.layout.nr_samples,
.swizzle = {PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, PIPE_SWIZZLE_Z,
PIPE_SWIZZLE_W},
};
cmdbuf->state.gfx.render.fb.crc_valid[0] = false;
*fbinfo = (struct pan_fb_info){
.tile_buf_budget = panfrost_query_optimal_tib_size(phys_dev->model),
.nr_samples = img->pimage.layout.nr_samples,
.rt_count = 1,
.zs.clear_value.depth = value->depth,
.zs.clear_value.stencil = value->stencil,
.zs.clear.z = range->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT,
.zs.clear.s = range->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT};
const struct util_format_description *fdesc =
util_format_description(view.format);
if (util_format_has_depth(fdesc)) {
fbinfo->zs.view.zs = &view;
if (util_format_has_stencil(fdesc)) {
fbinfo->zs.preload.z = !fbinfo->zs.clear.z;
fbinfo->zs.preload.s = !fbinfo->zs.clear.s;
}
} else {
fbinfo->zs.view.s = &view;
}
unsigned level_count = vk_image_subresource_level_count(&img->vk, range);
unsigned layer_count = vk_image_subresource_layer_count(&img->vk, range);
for (unsigned level = range->baseMipLevel;
level < range->baseMipLevel + level_count; level++) {
view.first_level = view.last_level = level;
fbinfo->width = u_minify(img->pimage.layout.width, level);
fbinfo->height = u_minify(img->pimage.layout.height, level);
fbinfo->extent.maxx = fbinfo->width - 1;
fbinfo->extent.maxy = fbinfo->height - 1;
for (unsigned layer = range->baseArrayLayer;
layer < range->baseArrayLayer + layer_count; layer++) {
view.first_layer = view.last_layer = layer;
panvk_per_arch(cmd_open_batch)(cmdbuf);
panvk_per_arch(cmd_alloc_fb_desc)(cmdbuf);
panvk_per_arch(cmd_close_batch)(cmdbuf);
}
}
memset(fbinfo, 0, sizeof(*fbinfo));
}
VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdClearDepthStencilImage)(
VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout,
const VkClearDepthStencilValue *pDepthStencil, uint32_t rangeCount,
const VkImageSubresourceRange *pRanges)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
VK_FROM_HANDLE(panvk_image, img, image);
panvk_per_arch(cmd_close_batch)(cmdbuf);
for (unsigned i = 0; i < rangeCount; i++)
panvk_meta_clear_zs_img(cmdbuf, img, pDepthStencil, &pRanges[i]);
}
VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdClearAttachments)(VkCommandBuffer commandBuffer,
uint32_t attachmentCount,
const VkClearAttachment *pAttachments,
uint32_t rectCount,
const VkClearRect *pRects)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
const struct vk_subpass *subpass =
&cmdbuf->vk.render_pass->subpasses[cmdbuf->vk.subpass_idx];
for (unsigned i = 0; i < attachmentCount; i++) {
for (unsigned j = 0; j < rectCount; j++) {
uint32_t attachment = VK_ATTACHMENT_UNUSED, rt = 0;
if (pAttachments[i].aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
rt = pAttachments[i].colorAttachment;
attachment = subpass->color_attachments[rt].attachment;
} else if (subpass->depth_stencil_attachment) {
attachment = subpass->depth_stencil_attachment->attachment;
}
if (attachment == VK_ATTACHMENT_UNUSED)
continue;
panvk_meta_clear_attachment(cmdbuf, rt, pAttachments[i].aspectMask,
&pAttachments[i].clearValue, &pRects[j]);
}
}
}
static void
panvk_meta_clear_attachment_init(struct panvk_device *dev)
{
dev->meta.clear_attachment.color[GLSL_TYPE_UINT].shader =
panvk_meta_clear_color_attachment_shader(
dev, GLSL_TYPE_UINT,
&dev->meta.clear_attachment.color[GLSL_TYPE_UINT].shader_info);
dev->meta.clear_attachment.color[GLSL_TYPE_INT].shader =
panvk_meta_clear_color_attachment_shader(
dev, GLSL_TYPE_INT,
&dev->meta.clear_attachment.color[GLSL_TYPE_INT].shader_info);
dev->meta.clear_attachment.color[GLSL_TYPE_FLOAT].shader =
panvk_meta_clear_color_attachment_shader(
dev, GLSL_TYPE_FLOAT,
&dev->meta.clear_attachment.color[GLSL_TYPE_FLOAT].shader_info);
}
void
panvk_per_arch(meta_clear_init)(struct panvk_device *dev)
{
panvk_meta_clear_attachment_init(dev);
}

File diff suppressed because it is too large Load Diff

View File

@@ -56,10 +56,6 @@ jm_files = [
'jm/panvk_vX_cmd_dispatch.c',
'jm/panvk_vX_cmd_draw.c',
'jm/panvk_vX_cmd_event.c',
'jm/panvk_vX_meta.c',
'jm/panvk_vX_meta_blit.c',
'jm/panvk_vX_meta_clear.c',
'jm/panvk_vX_meta_copy.c',
'jm/panvk_vX_queue.c',
]

View File

@@ -9,6 +9,7 @@
#include <stdint.h>
#include "vk_device.h"
#include "vk_meta.h"
#include "panvk_blend.h"
#include "panvk_instance.h"
@@ -36,13 +37,31 @@ struct panvk_device {
struct panvk_priv_bo *tiler_heap;
struct panvk_priv_bo *sample_positions;
struct panvk_blend_shader_cache blend_shader_cache;
struct panvk_meta meta;
/* Access to the blitter pools are protected by the blitter
* shader/rsd locks. They can't be merged with other binary/desc
* pools unless we patch pan_blitter.c to support external pool locks.
*
* FIXME: The blitter infrastructure is only needed for FB preload.
* We should probably consider getting rid of the dependency we have
* on pan_desc.c and implement preload ourselves so we don't have
* to duplicate caches.
*/
struct {
struct panvk_priv_bo *shader_bo;
struct panvk_priv_bo *rsd_bo;
struct panvk_pool bin_pool;
struct panvk_pool desc_pool;
struct pan_blitter_cache cache;
struct pan_blend_shader_cache blend_shader_cache;
} blitter;
struct panvk_blend_shader_cache blend_shader_cache;
struct vk_meta_device meta;
#if PAN_ARCH <= 7
struct {
struct panvk_priv_mem shader;
struct panvk_priv_mem rsd;
} desc_copy;
#endif
struct {
struct panvk_pool rw;

View File

@@ -197,6 +197,61 @@ panvk_image_select_mod(struct panvk_image *image,
panvk_image_select_mod_from_list(image, NULL, 0);
}
static void
panvk_image_pre_mod_select_meta_adjustments(struct panvk_image *image)
{
const VkImageAspectFlags aspects = vk_format_aspects(image->vk.format);
/* We do image blit/resolve with vk_meta, so when an image is flagged as
* being a potential transfer source, we also need to add the sampled usage.
*/
if (image->vk.usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
image->vk.usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT)
image->vk.stencil_usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
}
if (image->vk.usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
/* Similarly, image that can be a transfer destination can be attached
* as a color or depth-stencil attachment by vk_meta. */
if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT)
image->vk.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT)
image->vk.stencil_usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
if (aspects & VK_IMAGE_ASPECT_COLOR_BIT) {
image->vk.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
image->vk.usage |= VK_IMAGE_USAGE_STORAGE_BIT;
}
/* vk_meta creates 2D array views of 3D images. */
if (image->vk.image_type == VK_IMAGE_TYPE_3D)
image->vk.create_flags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT;
}
/* Needed for resolve operations. */
if (image->vk.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
image->vk.usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
if (image->vk.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT)
image->vk.usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT)
image->vk.stencil_usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
}
if ((image->vk.usage &
(VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT)) &&
util_format_is_compressed(image->pimage.layout.format)) {
/* We need to be able to create RGBA views of compressed formats for
* vk_meta copies. */
image->vk.create_flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT |
VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT;
}
}
static uint64_t
panvk_image_get_total_size(const struct panvk_image *image)
{
@@ -241,6 +296,13 @@ panvk_CreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo,
.nr_slices = image->vk.mip_levels,
};
/* Add any create/usage flags that might be needed for meta operations.
* This is run before the modifier selection because some
* usage/create_flags influence the modifier selection logic. */
panvk_image_pre_mod_select_meta_adjustments(image);
/* Now that we've patched the create/usage flags, we can proceed with the
* modifier selection. */
panvk_image_select_mod(image, pCreateInfo);
*pImage = panvk_image_to_handle(image);

View File

@@ -6,78 +6,140 @@
#ifndef PANVK_META_H
#define PANVK_META_H
#include "panvk_macros.h"
#include "panvk_image.h"
#include "panvk_mempool.h"
#include "pan_blend.h"
#include "pan_blitter.h"
#include "vk_format.h"
#include "vk_meta.h"
#define PANVK_META_COPY_BUF2IMG_NUM_FORMATS 12
#define PANVK_META_COPY_IMG2BUF_NUM_FORMATS 12
#define PANVK_META_COPY_IMG2IMG_NUM_FORMATS 14
#define PANVK_META_COPY_NUM_TEX_TYPES 5
#define PANVK_META_COPY_BUF2BUF_NUM_BLKSIZES 5
static inline unsigned
panvk_meta_copy_tex_type(unsigned dim, bool isarray)
static inline bool
panvk_meta_copy_to_image_use_gfx_pipeline(struct panvk_image *dst_img)
{
assert(dim > 0 && dim <= 3);
assert(dim < 3 || !isarray);
return (((dim - 1) << 1) | (isarray ? 1 : 0));
/* Writes to AFBC images must go through the graphics pipeline. */
if (drm_is_afbc(dst_img->pimage.layout.modifier))
return true;
return false;
}
struct panvk_meta {
struct panvk_pool bin_pool;
struct panvk_pool desc_pool;
static inline VkFormat
panvk_meta_get_uint_format_for_blk_size(unsigned blk_sz)
{
switch (blk_sz) {
case 1:
return VK_FORMAT_R8_UINT;
case 2:
return VK_FORMAT_R16_UINT;
case 3:
return VK_FORMAT_R8G8B8_UINT;
case 4:
return VK_FORMAT_R32_UINT;
case 6:
return VK_FORMAT_R16G16B16_UINT;
case 8:
return VK_FORMAT_R32G32_UINT;
case 12:
return VK_FORMAT_R32G32B32_UINT;
case 16:
return VK_FORMAT_R32G32B32A32_UINT;
default:
return VK_FORMAT_UNDEFINED;
}
}
/* Access to the blitter pools are protected by the blitter
* shader/rsd locks. They can't be merged with other binary/desc
* pools unless we patch pan_blitter.c to external pool locks.
*/
struct {
struct panvk_pool bin_pool;
struct panvk_pool desc_pool;
struct pan_blitter_cache cache;
} blitter;
static inline struct vk_meta_copy_image_properties
panvk_meta_copy_get_image_properties(struct panvk_image *img)
{
uint64_t mod = img->pimage.layout.modifier;
enum pipe_format pfmt = vk_format_to_pipe_format(img->vk.format);
unsigned blk_sz = util_format_get_blocksize(pfmt);
struct vk_meta_copy_image_properties props = {0};
struct pan_blend_shader_cache blend_shader_cache;
if (drm_is_afbc(mod)) {
if (!vk_format_is_depth_or_stencil(img->vk.format)) {
props.color.view_format = img->vk.format;
} else {
switch (img->vk.format) {
case VK_FORMAT_D24_UNORM_S8_UINT:
props.depth.view_format = VK_FORMAT_R8G8B8A8_UNORM;
props.depth.component_mask = BITFIELD_MASK(3);
props.stencil.view_format = VK_FORMAT_R8G8B8A8_UNORM;
props.stencil.component_mask = BITFIELD_BIT(3);
break;
case VK_FORMAT_X8_D24_UNORM_PACK32:
props.depth.view_format = VK_FORMAT_R8G8B8A8_UNORM;
props.depth.component_mask = BITFIELD_MASK(3);
break;
case VK_FORMAT_D16_UNORM:
props.depth.view_format = VK_FORMAT_R8G8_UNORM;
props.depth.component_mask = BITFIELD_MASK(2);
break;
default:
assert(!"Invalid ZS format");
break;
}
}
} else if (vk_format_is_depth_or_stencil(img->vk.format)) {
switch (img->vk.format) {
case VK_FORMAT_S8_UINT:
props.stencil.view_format = VK_FORMAT_R8_UINT;
props.stencil.component_mask = BITFIELD_MASK(1);
break;
case VK_FORMAT_D24_UNORM_S8_UINT:
props.depth.view_format = VK_FORMAT_R8G8B8A8_UINT;
props.depth.component_mask = BITFIELD_MASK(3);
props.stencil.view_format = VK_FORMAT_R8G8B8A8_UINT;
props.stencil.component_mask = BITFIELD_BIT(3);
break;
case VK_FORMAT_X8_D24_UNORM_PACK32:
props.depth.view_format = VK_FORMAT_R8G8B8A8_UINT;
props.depth.component_mask = BITFIELD_MASK(3);
break;
case VK_FORMAT_D32_SFLOAT_S8_UINT:
props.depth.view_format = VK_FORMAT_R32G32_UINT;
props.depth.component_mask = BITFIELD_BIT(0);
props.stencil.view_format = VK_FORMAT_R32G32_UINT;
props.stencil.component_mask = BITFIELD_BIT(1);
break;
case VK_FORMAT_D16_UNORM:
props.depth.view_format = VK_FORMAT_R16_UINT;
props.depth.component_mask = BITFIELD_BIT(0);
break;
case VK_FORMAT_D32_SFLOAT:
props.depth.view_format = VK_FORMAT_R32_UINT;
props.depth.component_mask = BITFIELD_BIT(0);
break;
default:
assert(!"Invalid ZS format");
break;
}
} else {
props.color.view_format = panvk_meta_get_uint_format_for_blk_size(blk_sz);
}
struct {
struct {
mali_ptr shader;
struct pan_shader_info shader_info;
} color[3]; /* 3 base types */
} clear_attachment;
if (mod == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED ||
drm_is_afbc(mod)) {
props.tile_size.width = 16;
props.tile_size.height = 16;
props.tile_size.depth = 1;
} else {
/* When linear, pretend we have a 1D-tile so we end up with a <64,1,1>
* workgroup. */
props.tile_size.width = 64;
props.tile_size.height = 1;
props.tile_size.depth = 1;
}
struct {
struct {
mali_ptr rsd;
} buf2img[PANVK_META_COPY_BUF2IMG_NUM_FORMATS];
struct {
mali_ptr rsd;
} img2buf[PANVK_META_COPY_NUM_TEX_TYPES]
[PANVK_META_COPY_IMG2BUF_NUM_FORMATS];
struct {
mali_ptr rsd;
} img2img[2][PANVK_META_COPY_NUM_TEX_TYPES]
[PANVK_META_COPY_IMG2IMG_NUM_FORMATS];
struct {
mali_ptr rsd;
} buf2buf[PANVK_META_COPY_BUF2BUF_NUM_BLKSIZES];
struct {
mali_ptr rsd;
} fillbuf;
} copy;
return props;
}
struct {
mali_ptr rsd;
} desc_copy;
};
#if defined(PAN_ARCH) && PAN_ARCH <= 7
void panvk_per_arch(meta_desc_copy_init)(struct panvk_device *dev);
#if PAN_ARCH
void panvk_per_arch(meta_desc_copy_cleanup)(struct panvk_device *dev);
#if PAN_ARCH <= 7
struct panvk_descriptor_state;
struct panvk_device;
struct panvk_shader;
struct panvk_shader_desc_state;
@@ -89,23 +151,4 @@ struct panfrost_ptr panvk_per_arch(meta_get_copy_desc_job)(
uint32_t attrib_buf_idx_offset);
#endif
void panvk_per_arch(meta_init)(struct panvk_device *dev);
void panvk_per_arch(meta_cleanup)(struct panvk_device *dev);
mali_ptr panvk_per_arch(meta_emit_viewport)(struct pan_pool *pool,
uint16_t minx, uint16_t miny,
uint16_t maxx, uint16_t maxy);
void panvk_per_arch(meta_clear_init)(struct panvk_device *dev);
void panvk_per_arch(meta_blit_init)(struct panvk_device *dev);
void panvk_per_arch(meta_blit_cleanup)(struct panvk_device *dev);
void panvk_per_arch(meta_copy_init)(struct panvk_device *dev);
void panvk_per_arch(meta_desc_copy_init)(struct panvk_device *dev);
#endif
#endif

View File

@@ -4,6 +4,7 @@
*/
#include "panvk_cmd_meta.h"
#include "panvk_entrypoints.h"
void
panvk_per_arch(cmd_meta_compute_start)(
@@ -122,3 +123,236 @@ panvk_per_arch(cmd_meta_gfx_end)(
vk_dynamic_graphics_state_copy(&cmdbuf->vk.dynamic_graphics_state,
&save_ctx->dyn_state.all);
}
VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdBlitImage2)(VkCommandBuffer commandBuffer,
const VkBlitImageInfo2 *pBlitImageInfo)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
struct panvk_cmd_meta_graphics_save_ctx save = {0};
panvk_per_arch(cmd_meta_gfx_start)(cmdbuf, &save);
vk_meta_blit_image2(&cmdbuf->vk, &dev->meta, pBlitImageInfo);
panvk_per_arch(cmd_meta_gfx_end)(cmdbuf, &save);
}
VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdResolveImage2)(VkCommandBuffer commandBuffer,
const VkResolveImageInfo2 *pResolveImageInfo)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
struct panvk_cmd_meta_graphics_save_ctx save = {0};
panvk_per_arch(cmd_meta_gfx_start)(cmdbuf, &save);
vk_meta_resolve_image2(&cmdbuf->vk, &dev->meta, pResolveImageInfo);
panvk_per_arch(cmd_meta_gfx_end)(cmdbuf, &save);
}
VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdClearAttachments)(VkCommandBuffer commandBuffer,
uint32_t attachmentCount,
const VkClearAttachment *pAttachments,
uint32_t rectCount,
const VkClearRect *pRects)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
const struct pan_fb_info *fbinfo = &cmdbuf->state.gfx.render.fb.info;
struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
struct panvk_cmd_meta_graphics_save_ctx save = {0};
struct vk_meta_rendering_info render = {
.view_mask = 0,
.samples = fbinfo->nr_samples,
.color_attachment_count = fbinfo->rt_count,
};
for (uint32_t i = 0; i < fbinfo->rt_count; i++) {
if (fbinfo->rts[i].view) {
render.color_attachment_formats[i] =
cmdbuf->state.gfx.render.color_attachments.fmts[i];
render.color_attachment_write_masks[i] =
VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
}
}
if (fbinfo->zs.view.zs) {
render.depth_attachment_format =
vk_format_from_pipe_format(fbinfo->zs.view.zs->format);
if (vk_format_has_stencil(render.depth_attachment_format))
render.stencil_attachment_format = render.depth_attachment_format;
}
if (fbinfo->zs.view.s) {
render.stencil_attachment_format =
vk_format_from_pipe_format(fbinfo->zs.view.s->format);
}
panvk_per_arch(cmd_meta_gfx_start)(cmdbuf, &save);
vk_meta_clear_attachments(&cmdbuf->vk, &dev->meta, &render, attachmentCount,
pAttachments, rectCount, pRects);
panvk_per_arch(cmd_meta_gfx_end)(cmdbuf, &save);
}
VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdClearDepthStencilImage)(
VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout,
const VkClearDepthStencilValue *pDepthStencil, uint32_t rangeCount,
const VkImageSubresourceRange *pRanges)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
VK_FROM_HANDLE(panvk_image, img, image);
struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
struct panvk_cmd_meta_graphics_save_ctx save = {0};
panvk_per_arch(cmd_meta_gfx_start)(cmdbuf, &save);
vk_meta_clear_depth_stencil_image(&cmdbuf->vk, &dev->meta, &img->vk,
imageLayout, pDepthStencil, rangeCount,
pRanges);
panvk_per_arch(cmd_meta_gfx_end)(cmdbuf, &save);
}
VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdClearColorImage)(VkCommandBuffer commandBuffer, VkImage image,
VkImageLayout imageLayout,
const VkClearColorValue *pColor,
uint32_t rangeCount,
const VkImageSubresourceRange *pRanges)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
VK_FROM_HANDLE(panvk_image, img, image);
struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
struct panvk_cmd_meta_graphics_save_ctx save = {0};
panvk_per_arch(cmd_meta_gfx_start)(cmdbuf, &save);
vk_meta_clear_color_image(&cmdbuf->vk, &dev->meta, &img->vk, imageLayout,
img->vk.format, pColor, rangeCount, pRanges);
panvk_per_arch(cmd_meta_gfx_end)(cmdbuf, &save);
}
VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdCopyBuffer2)(VkCommandBuffer commandBuffer,
const VkCopyBufferInfo2 *pCopyBufferInfo)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
struct panvk_cmd_meta_compute_save_ctx save = {0};
panvk_per_arch(cmd_meta_compute_start)(cmdbuf, &save);
vk_meta_copy_buffer(&cmdbuf->vk, &dev->meta, pCopyBufferInfo);
panvk_per_arch(cmd_meta_compute_end)(cmdbuf, &save);
}
VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdCopyBufferToImage2)(
VkCommandBuffer commandBuffer,
const VkCopyBufferToImageInfo2 *pCopyBufferToImageInfo)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
VK_FROM_HANDLE(panvk_image, img, pCopyBufferToImageInfo->dstImage);
struct vk_meta_copy_image_properties img_props =
panvk_meta_copy_get_image_properties(img);
bool use_gfx_pipeline = panvk_meta_copy_to_image_use_gfx_pipeline(img);
if (use_gfx_pipeline) {
struct panvk_cmd_meta_graphics_save_ctx save = {0};
panvk_per_arch(cmd_meta_gfx_start)(cmdbuf, &save);
vk_meta_copy_buffer_to_image(&cmdbuf->vk, &dev->meta,
pCopyBufferToImageInfo, &img_props,
VK_PIPELINE_BIND_POINT_GRAPHICS);
panvk_per_arch(cmd_meta_gfx_end)(cmdbuf, &save);
} else {
struct panvk_cmd_meta_compute_save_ctx save = {0};
panvk_per_arch(cmd_meta_compute_start)(cmdbuf, &save);
vk_meta_copy_buffer_to_image(&cmdbuf->vk, &dev->meta,
pCopyBufferToImageInfo, &img_props,
VK_PIPELINE_BIND_POINT_COMPUTE);
panvk_per_arch(cmd_meta_compute_end)(cmdbuf, &save);
}
}
VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdCopyImageToBuffer2)(
VkCommandBuffer commandBuffer,
const VkCopyImageToBufferInfo2 *pCopyImageToBufferInfo)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
VK_FROM_HANDLE(panvk_image, img, pCopyImageToBufferInfo->srcImage);
struct vk_meta_copy_image_properties img_props =
panvk_meta_copy_get_image_properties(img);
struct panvk_cmd_meta_compute_save_ctx save = {0};
panvk_per_arch(cmd_meta_compute_start)(cmdbuf, &save);
vk_meta_copy_image_to_buffer(&cmdbuf->vk, &dev->meta, pCopyImageToBufferInfo,
&img_props);
panvk_per_arch(cmd_meta_compute_end)(cmdbuf, &save);
}
VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdFillBuffer)(VkCommandBuffer commandBuffer, VkBuffer dstBuffer,
VkDeviceSize dstOffset, VkDeviceSize fillSize,
uint32_t data)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
struct panvk_cmd_meta_compute_save_ctx save = {0};
panvk_per_arch(cmd_meta_compute_start)(cmdbuf, &save);
vk_meta_fill_buffer(&cmdbuf->vk, &dev->meta, dstBuffer, dstOffset, fillSize,
data);
panvk_per_arch(cmd_meta_compute_end)(cmdbuf, &save);
}
VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdUpdateBuffer)(VkCommandBuffer commandBuffer,
VkBuffer dstBuffer, VkDeviceSize dstOffset,
VkDeviceSize dataSize, const void *pData)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
struct panvk_cmd_meta_compute_save_ctx save = {0};
panvk_per_arch(cmd_meta_compute_start)(cmdbuf, &save);
vk_meta_update_buffer(&cmdbuf->vk, &dev->meta, dstBuffer, dstOffset,
dataSize, pData);
panvk_per_arch(cmd_meta_compute_end)(cmdbuf, &save);
}
VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdCopyImage2)(VkCommandBuffer commandBuffer,
const VkCopyImageInfo2 *pCopyImageInfo)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
VK_FROM_HANDLE(panvk_image, src_img, pCopyImageInfo->srcImage);
VK_FROM_HANDLE(panvk_image, dst_img, pCopyImageInfo->dstImage);
struct vk_meta_copy_image_properties src_img_props =
panvk_meta_copy_get_image_properties(src_img);
struct vk_meta_copy_image_properties dst_img_props =
panvk_meta_copy_get_image_properties(dst_img);
bool use_gfx_pipeline = panvk_meta_copy_to_image_use_gfx_pipeline(dst_img);
if (use_gfx_pipeline) {
struct panvk_cmd_meta_graphics_save_ctx save = {0};
panvk_per_arch(cmd_meta_gfx_start)(cmdbuf, &save);
vk_meta_copy_image(&cmdbuf->vk, &dev->meta, pCopyImageInfo,
&src_img_props, &dst_img_props,
VK_PIPELINE_BIND_POINT_GRAPHICS);
panvk_per_arch(cmd_meta_gfx_end)(cmdbuf, &save);
} else {
struct panvk_cmd_meta_compute_save_ctx save = {0};
panvk_per_arch(cmd_meta_compute_start)(cmdbuf, &save);
vk_meta_copy_image(&cmdbuf->vk, &dev->meta, pCopyImageInfo,
&src_img_props, &dst_img_props,
VK_PIPELINE_BIND_POINT_COMPUTE);
panvk_per_arch(cmd_meta_compute_end)(cmdbuf, &save);
}
}

View File

@@ -12,6 +12,7 @@
#include "vk_cmd_enqueue_entrypoints.h"
#include "vk_common_entrypoints.h"
#include "panvk_buffer.h"
#include "panvk_cmd_buffer.h"
#include "panvk_device.h"
#include "panvk_entrypoints.h"
@@ -86,6 +87,103 @@ panvk_device_cleanup_mempools(struct panvk_device *dev)
panvk_pool_cleanup(&dev->mempools.exec);
}
static VkResult
panvk_meta_cmd_bind_map_buffer(struct vk_command_buffer *cmd,
struct vk_meta_device *meta, VkBuffer buf,
void **map_out)
{
VK_FROM_HANDLE(panvk_buffer, buffer, buf);
struct panvk_cmd_buffer *cmdbuf =
container_of(cmd, struct panvk_cmd_buffer, vk);
struct panfrost_ptr mem =
pan_pool_alloc_aligned(&cmdbuf->desc_pool.base, buffer->vk.size, 64);
buffer->dev_addr = mem.gpu;
*map_out = mem.cpu;
return VK_SUCCESS;
}
static VkResult
panvk_meta_init(struct panvk_device *device)
{
const struct vk_physical_device *pdev = device->vk.physical;
VkResult result = vk_meta_device_init(&device->vk, &device->meta);
if (result != VK_SUCCESS)
return result;
device->meta.use_stencil_export = true;
device->meta.max_bind_map_buffer_size_B = 64 * 1024;
device->meta.cmd_bind_map_buffer = panvk_meta_cmd_bind_map_buffer;
/* Assume a maximum of 1024 bytes per worgroup and choose the workgroup size
* accordingly. */
for (uint32_t i = 0;
i < ARRAY_SIZE(device->meta.buffer_access.optimal_wg_size); i++) {
device->meta.buffer_access.optimal_wg_size[i] =
MIN2(1024 >> i, pdev->properties.maxComputeWorkGroupSize[0]);
}
#if PAN_ARCH <= 7
panvk_per_arch(meta_desc_copy_init)(device);
#endif
return VK_SUCCESS;
}
static void
panvk_meta_cleanup(struct panvk_device *device)
{
#if PAN_ARCH <= 7
panvk_per_arch(meta_desc_copy_cleanup)(device);
#endif
vk_meta_device_finish(&device->vk, &device->meta);
}
static void
panvk_preload_blitter_init(struct panvk_device *device)
{
const struct panvk_physical_device *physical_device =
to_panvk_physical_device(device->vk.physical);
struct panvk_pool_properties bin_pool_props = {
.create_flags = PAN_KMOD_BO_FLAG_EXECUTABLE,
.slab_size = 16 * 1024,
.label = "panvk_meta blitter binary pool",
.owns_bos = true,
.needs_locking = false,
.prealloc = false,
};
panvk_pool_init(&device->blitter.bin_pool, device, NULL, &bin_pool_props);
struct panvk_pool_properties desc_pool_props = {
.create_flags = 0,
.slab_size = 16 * 1024,
.label = "panvk_meta blitter descriptor pool",
.owns_bos = true,
.needs_locking = false,
.prealloc = false,
};
panvk_pool_init(&device->blitter.desc_pool, device, NULL, &desc_pool_props);
pan_blend_shader_cache_init(&device->blitter.blend_shader_cache,
physical_device->kmod.props.gpu_prod_id);
GENX(pan_blitter_cache_init)
(&device->blitter.cache, physical_device->kmod.props.gpu_prod_id,
&device->blitter.blend_shader_cache, &device->blitter.bin_pool.base,
&device->blitter.desc_pool.base);
}
static void
panvk_preload_blitter_cleanup(struct panvk_device *device)
{
GENX(pan_blitter_cache_cleanup)(&device->blitter.cache);
pan_blend_shader_cache_cleanup(&device->blitter.blend_shader_cache);
panvk_pool_cleanup(&device->blitter.desc_pool);
panvk_pool_cleanup(&device->blitter.bin_pool);
}
/* Always reserve the lower 32MB. */
#define PANVK_VA_RESERVE_BOTTOM 0x2000000ull
@@ -206,7 +304,11 @@ panvk_per_arch(create_device)(struct panvk_physical_device *physical_device,
if (result != VK_SUCCESS)
goto err_free_priv_bos;
panvk_per_arch(meta_init)(device);
panvk_preload_blitter_init(device);
result = panvk_meta_init(device);
if (result != VK_SUCCESS)
goto err_cleanup_blitter;
for (unsigned i = 0; i < pCreateInfo->queueCreateInfoCount; i++) {
const VkDeviceQueueCreateInfo *queue_create =
@@ -245,7 +347,10 @@ err_finish_queues:
vk_object_free(&device->vk, NULL, device->queues[i]);
}
panvk_per_arch(meta_cleanup)(device);
panvk_meta_cleanup(device);
err_cleanup_blitter:
panvk_preload_blitter_cleanup(device);
panvk_per_arch(blend_shader_cache_cleanup)(device);
err_free_priv_bos:
@@ -279,7 +384,8 @@ panvk_per_arch(destroy_device)(struct panvk_device *device,
vk_object_free(&device->vk, NULL, device->queues[i]);
}
panvk_per_arch(meta_cleanup)(device);
panvk_meta_cleanup(device);
panvk_preload_blitter_cleanup(device);
panvk_per_arch(blend_shader_cache_cleanup)(device);
panvk_priv_bo_unref(device->tiler_heap);
panvk_priv_bo_unref(device->sample_positions);

View File

@@ -78,10 +78,12 @@ panvk_per_arch(CreateImageView)(VkDevice _device,
{
VK_FROM_HANDLE(panvk_device, device, _device);
VK_FROM_HANDLE(panvk_image, image, pCreateInfo->image);
bool driver_internal =
(pCreateInfo->flags & VK_IMAGE_VIEW_CREATE_DRIVER_INTERNAL_BIT_MESA) != 0;
struct panvk_image_view *view;
view = vk_image_view_create(&device->vk, false, pCreateInfo, pAllocator,
sizeof(*view));
view = vk_image_view_create(&device->vk, driver_internal, pCreateInfo,
pAllocator, sizeof(*view));
if (view == NULL)
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
@@ -101,19 +103,21 @@ panvk_per_arch(CreateImageView)(VkDevice _device,
* depth and stencil but the view only contains one of these components, so
* we can ignore the component we don't use.
*/
if (image->vk.format == VK_FORMAT_D32_SFLOAT_S8_UINT &&
view->vk.view_format != VK_FORMAT_D32_SFLOAT_S8_UINT)
view->pview.format = view->vk.view_format == VK_FORMAT_D32_SFLOAT
? PIPE_FORMAT_Z32_FLOAT_S8X24_UINT
: PIPE_FORMAT_X32_S8X24_UINT;
if (vk_format_is_depth_or_stencil(view->vk.view_format)) {
if (image->vk.format == VK_FORMAT_D32_SFLOAT_S8_UINT &&
view->vk.view_format != VK_FORMAT_D32_SFLOAT_S8_UINT)
view->pview.format = view->vk.view_format == VK_FORMAT_D32_SFLOAT
? PIPE_FORMAT_Z32_FLOAT_S8X24_UINT
: PIPE_FORMAT_X32_S8X24_UINT;
if (image->vk.format == VK_FORMAT_D24_UNORM_S8_UINT &&
view->vk.view_format == VK_FORMAT_S8_UINT)
view->pview.format = PIPE_FORMAT_X24S8_UINT;
if (image->vk.format == VK_FORMAT_D24_UNORM_S8_UINT &&
view->vk.view_format == VK_FORMAT_S8_UINT)
view->pview.format = PIPE_FORMAT_X24S8_UINT;
if (image->vk.format == VK_FORMAT_D32_SFLOAT_S8_UINT &&
view->vk.view_format == VK_FORMAT_S8_UINT)
view->pview.format = PIPE_FORMAT_X32_S8X24_UINT;
if (image->vk.format == VK_FORMAT_D32_SFLOAT_S8_UINT &&
view->vk.view_format == VK_FORMAT_S8_UINT)
view->pview.format = PIPE_FORMAT_X32_S8X24_UINT;
}
VkImageUsageFlags tex_usage_mask =
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
@@ -193,12 +197,13 @@ panvk_per_arch(CreateImageView)(VkDevice _device,
pan_pack(view->descs.img_attrib_buf[1].opaque,
ATTRIBUTE_BUFFER_CONTINUATION_3D, cfg) {
unsigned level = view->pview.first_level;
VkExtent3D extent = view->vk.extent;
cfg.s_dimension = u_minify(image->pimage.layout.width, level);
cfg.t_dimension = u_minify(image->pimage.layout.height, level);
cfg.s_dimension = extent.width;
cfg.t_dimension = extent.height;
cfg.r_dimension =
view->pview.dim == MALI_TEXTURE_DIMENSION_3D
? u_minify(image->pimage.layout.depth, level)
? extent.depth
: (view->pview.last_layer - view->pview.first_layer + 1);
cfg.row_stride = image->pimage.layout.slices[level].row_stride;
if (cfg.r_dimension > 1) {