• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2021 Collabora Ltd.
3  *
4  * Derived from tu_image.c which is:
5  * Copyright © 2016 Red Hat.
6  * Copyright © 2016 Bas Nieuwenhuizen
7  * Copyright © 2015 Intel Corporation
8  *
9  * SPDX-License-Identifier: MIT
10  */
11 
12 #include "genxml/gen_macros.h"
13 
14 #include "panvk_buffer.h"
15 #include "panvk_buffer_view.h"
16 #include "panvk_device.h"
17 #include "panvk_entrypoints.h"
18 #include "panvk_priv_bo.h"
19 
20 #include "vk_format.h"
21 #include "vk_log.h"
22 
23 VKAPI_ATTR VkResult VKAPI_CALL
panvk_per_arch(CreateBufferView)24 panvk_per_arch(CreateBufferView)(VkDevice _device,
25                                  const VkBufferViewCreateInfo *pCreateInfo,
26                                  const VkAllocationCallbacks *pAllocator,
27                                  VkBufferView *pView)
28 {
29    VK_FROM_HANDLE(panvk_device, device, _device);
30    VK_FROM_HANDLE(panvk_buffer, buffer, pCreateInfo->buffer);
31 
32    struct panvk_buffer_view *view = vk_object_zalloc(
33       &device->vk, pAllocator, sizeof(*view), VK_OBJECT_TYPE_BUFFER_VIEW);
34 
35    if (!view)
36       return panvk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
37 
38    vk_buffer_view_init(&device->vk, &view->vk, pCreateInfo);
39 
40    enum pipe_format pfmt = vk_format_to_pipe_format(view->vk.format);
41 
42    uint64_t address = panvk_buffer_gpu_ptr(buffer, pCreateInfo->offset);
43    VkBufferUsageFlags tex_usage_mask = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
44 
45 #if PAN_ARCH >= 9
46    /* Valhall passes a texture descriptor to LEA_TEX. */
47    tex_usage_mask |= VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
48 #endif
49 
50    assert(!(address & 63));
51 
52    if (buffer->vk.usage & tex_usage_mask) {
53       struct panvk_physical_device *physical_device =
54          to_panvk_physical_device(device->vk.physical);
55       unsigned arch = pan_arch(physical_device->kmod.props.gpu_prod_id);
56 
57       struct pan_image plane = {
58          .data = {
59             .base = address,
60             .offset = 0,
61 	 },
62          .layout = {
63             .modifier = DRM_FORMAT_MOD_LINEAR,
64             .format = pfmt,
65             .dim = MALI_TEXTURE_DIMENSION_1D,
66             .width = view->vk.elements,
67             .height = 1,
68             .depth = 1,
69             .array_size = 1,
70             .nr_samples = 1,
71             .nr_slices = 1,
72          },
73       };
74 
75       struct pan_image_view pview = {
76          .planes[0] = &plane,
77          .format = pfmt,
78          .dim = MALI_TEXTURE_DIMENSION_1D,
79          .nr_samples = 1,
80          .first_level = 0,
81          .last_level = 0,
82          .first_layer = 0,
83          .last_layer = 0,
84          .swizzle =
85             {
86                PIPE_SWIZZLE_X,
87                PIPE_SWIZZLE_Y,
88                PIPE_SWIZZLE_Z,
89                PIPE_SWIZZLE_W,
90             },
91       };
92 
93 #if PAN_ARCH == 7
94       /* v7 requires AFBC reswizzle. */
95       if (!util_format_is_depth_or_stencil(pfmt) &&
96           !panfrost_format_is_yuv(pfmt) &&
97           panfrost_format_supports_afbc(PAN_ARCH, pfmt))
98          GENX(panfrost_texture_afbc_reswizzle)(&pview);
99 #endif
100 
101       pan_image_layout_init(arch, &plane.layout, NULL);
102 
103       struct panvk_pool_alloc_info alloc_info = {
104          .alignment = pan_alignment(TEXTURE),
105          .size = GENX(panfrost_estimate_texture_payload_size)(&pview),
106       };
107 
108       view->mem = panvk_pool_alloc_mem(&device->mempools.rw, alloc_info);
109 
110       struct panfrost_ptr ptr = {
111          .gpu = panvk_priv_mem_dev_addr(view->mem),
112          .cpu = panvk_priv_mem_host_addr(view->mem),
113       };
114 
115       GENX(panfrost_new_texture)(&pview, &view->descs.tex, &ptr);
116    }
117 
118 #if PAN_ARCH <= 7
119    if (buffer->vk.usage & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) {
120       unsigned blksz = vk_format_get_blocksize(pCreateInfo->format);
121 
122       pan_pack(&view->descs.img_attrib_buf[0], ATTRIBUTE_BUFFER, cfg) {
123          /* The format is the only thing we lack to emit attribute descriptors
124           * when copying from the set to the attribute tables. Instead of
125           * making the descriptor size to store an extra format, we pack
126           * the 22-bit format with the texel stride, which is expected to be
127           * fit in remaining 10 bits.
128           */
129          uint32_t hw_fmt = GENX(panfrost_format_from_pipe_format)(pfmt)->hw;
130 
131          assert(blksz < BITFIELD_MASK(10));
132          assert(hw_fmt < BITFIELD_MASK(22));
133 
134          cfg.type = MALI_ATTRIBUTE_TYPE_3D_LINEAR;
135          cfg.pointer = address;
136          cfg.stride = blksz | (hw_fmt << 10);
137          cfg.size = view->vk.elements * blksz;
138       }
139 
140       struct mali_attribute_buffer_packed *buf = &view->descs.img_attrib_buf[1];
141       pan_cast_and_pack(buf, ATTRIBUTE_BUFFER_CONTINUATION_3D, cfg) {
142          cfg.s_dimension = view->vk.elements;
143          cfg.t_dimension = 1;
144          cfg.r_dimension = 1;
145          cfg.row_stride = view->vk.elements * blksz;
146       }
147    }
148 #endif
149 
150    *pView = panvk_buffer_view_to_handle(view);
151    return VK_SUCCESS;
152 }
153 
154 VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(DestroyBufferView)155 panvk_per_arch(DestroyBufferView)(VkDevice _device, VkBufferView bufferView,
156                                   const VkAllocationCallbacks *pAllocator)
157 {
158    VK_FROM_HANDLE(panvk_device, device, _device);
159    VK_FROM_HANDLE(panvk_buffer_view, view, bufferView);
160 
161    if (!view)
162       return;
163 
164    panvk_pool_free_mem(&view->mem);
165    vk_buffer_view_destroy(&device->vk, pAllocator, &view->vk);
166 }
167