mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-24 14:58:10 +02:00
Provide a pan_cast_and_[un]pack() to help with the transition. Those helpers should only be used when the caller is sure the destination is big enough to emit the descriptor. Signed-off-by: Mary Guillemard <mary.guillemard@collabora.com> Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32962>
166 lines
5.1 KiB
C
166 lines
5.1 KiB
C
/*
|
|
* Copyright © 2021 Collabora Ltd.
|
|
*
|
|
* Derived from tu_image.c which is:
|
|
* Copyright © 2016 Red Hat.
|
|
* Copyright © 2016 Bas Nieuwenhuizen
|
|
* Copyright © 2015 Intel Corporation
|
|
*
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
|
|
#include "genxml/gen_macros.h"
|
|
|
|
#include "panvk_buffer.h"
|
|
#include "panvk_buffer_view.h"
|
|
#include "panvk_device.h"
|
|
#include "panvk_entrypoints.h"
|
|
#include "panvk_priv_bo.h"
|
|
|
|
#include "vk_format.h"
|
|
#include "vk_log.h"
|
|
|
|
VKAPI_ATTR VkResult VKAPI_CALL
|
|
panvk_per_arch(CreateBufferView)(VkDevice _device,
|
|
const VkBufferViewCreateInfo *pCreateInfo,
|
|
const VkAllocationCallbacks *pAllocator,
|
|
VkBufferView *pView)
|
|
{
|
|
VK_FROM_HANDLE(panvk_device, device, _device);
|
|
VK_FROM_HANDLE(panvk_buffer, buffer, pCreateInfo->buffer);
|
|
|
|
struct panvk_buffer_view *view = vk_object_zalloc(
|
|
&device->vk, pAllocator, sizeof(*view), VK_OBJECT_TYPE_BUFFER_VIEW);
|
|
|
|
if (!view)
|
|
return panvk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
|
|
|
vk_buffer_view_init(&device->vk, &view->vk, pCreateInfo);
|
|
|
|
enum pipe_format pfmt = vk_format_to_pipe_format(view->vk.format);
|
|
|
|
uint64_t address = panvk_buffer_gpu_ptr(buffer, pCreateInfo->offset);
|
|
VkBufferUsageFlags tex_usage_mask = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
|
|
|
|
#if PAN_ARCH >= 9
|
|
/* Valhall passes a texture descriptor to LEA_TEX. */
|
|
tex_usage_mask |= VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
|
|
#endif
|
|
|
|
assert(!(address & 63));
|
|
|
|
if (buffer->vk.usage & tex_usage_mask) {
|
|
struct panvk_physical_device *physical_device =
|
|
to_panvk_physical_device(device->vk.physical);
|
|
unsigned arch = pan_arch(physical_device->kmod.props.gpu_prod_id);
|
|
|
|
struct pan_image plane = {
|
|
.data = {
|
|
.base = address,
|
|
.offset = 0,
|
|
},
|
|
.layout = {
|
|
.modifier = DRM_FORMAT_MOD_LINEAR,
|
|
.format = pfmt,
|
|
.dim = MALI_TEXTURE_DIMENSION_1D,
|
|
.width = view->vk.elements,
|
|
.height = 1,
|
|
.depth = 1,
|
|
.array_size = 1,
|
|
.nr_samples = 1,
|
|
.nr_slices = 1,
|
|
},
|
|
};
|
|
|
|
struct pan_image_view pview = {
|
|
.planes[0] = &plane,
|
|
.format = pfmt,
|
|
.dim = MALI_TEXTURE_DIMENSION_1D,
|
|
.nr_samples = 1,
|
|
.first_level = 0,
|
|
.last_level = 0,
|
|
.first_layer = 0,
|
|
.last_layer = 0,
|
|
.swizzle =
|
|
{
|
|
PIPE_SWIZZLE_X,
|
|
PIPE_SWIZZLE_Y,
|
|
PIPE_SWIZZLE_Z,
|
|
PIPE_SWIZZLE_W,
|
|
},
|
|
};
|
|
|
|
#if PAN_ARCH == 7
|
|
/* v7 requires AFBC reswizzle. */
|
|
if (!util_format_is_depth_or_stencil(pfmt) &&
|
|
!panfrost_format_is_yuv(pfmt) &&
|
|
panfrost_format_supports_afbc(PAN_ARCH, pfmt))
|
|
GENX(panfrost_texture_afbc_reswizzle)(&pview);
|
|
#endif
|
|
|
|
pan_image_layout_init(arch, &plane.layout, NULL);
|
|
|
|
struct panvk_pool_alloc_info alloc_info = {
|
|
.alignment = pan_alignment(TEXTURE),
|
|
.size = GENX(panfrost_estimate_texture_payload_size)(&pview),
|
|
};
|
|
|
|
view->mem = panvk_pool_alloc_mem(&device->mempools.rw, alloc_info);
|
|
|
|
struct panfrost_ptr ptr = {
|
|
.gpu = panvk_priv_mem_dev_addr(view->mem),
|
|
.cpu = panvk_priv_mem_host_addr(view->mem),
|
|
};
|
|
|
|
GENX(panfrost_new_texture)(&pview, &view->descs.tex, &ptr);
|
|
}
|
|
|
|
#if PAN_ARCH <= 7
|
|
if (buffer->vk.usage & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) {
|
|
unsigned blksz = vk_format_get_blocksize(pCreateInfo->format);
|
|
|
|
pan_pack(&view->descs.img_attrib_buf[0], ATTRIBUTE_BUFFER, cfg) {
|
|
/* The format is the only thing we lack to emit attribute descriptors
|
|
* when copying from the set to the attribute tables. Instead of
|
|
* making the descriptor size to store an extra format, we pack
|
|
* the 22-bit format with the texel stride, which is expected to be
|
|
* fit in remaining 10 bits.
|
|
*/
|
|
uint32_t hw_fmt = GENX(panfrost_format_from_pipe_format)(pfmt)->hw;
|
|
|
|
assert(blksz < BITFIELD_MASK(10));
|
|
assert(hw_fmt < BITFIELD_MASK(22));
|
|
|
|
cfg.type = MALI_ATTRIBUTE_TYPE_3D_LINEAR;
|
|
cfg.pointer = address;
|
|
cfg.stride = blksz | (hw_fmt << 10);
|
|
cfg.size = view->vk.elements * blksz;
|
|
}
|
|
|
|
struct mali_attribute_buffer_packed *buf = &view->descs.img_attrib_buf[1];
|
|
pan_cast_and_pack(buf, ATTRIBUTE_BUFFER_CONTINUATION_3D, cfg) {
|
|
cfg.s_dimension = view->vk.elements;
|
|
cfg.t_dimension = 1;
|
|
cfg.r_dimension = 1;
|
|
cfg.row_stride = view->vk.elements * blksz;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
*pView = panvk_buffer_view_to_handle(view);
|
|
return VK_SUCCESS;
|
|
}
|
|
|
|
VKAPI_ATTR void VKAPI_CALL
|
|
panvk_per_arch(DestroyBufferView)(VkDevice _device, VkBufferView bufferView,
|
|
const VkAllocationCallbacks *pAllocator)
|
|
{
|
|
VK_FROM_HANDLE(panvk_device, device, _device);
|
|
VK_FROM_HANDLE(panvk_buffer_view, view, bufferView);
|
|
|
|
if (!view)
|
|
return;
|
|
|
|
panvk_pool_free_mem(&view->mem);
|
|
vk_buffer_view_destroy(&device->vk, pAllocator, &view->vk);
|
|
}
|