1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2021 Collabora Ltd. 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Derived from tu_image.c which is: 5bf215546Sopenharmony_ci * Copyright © 2016 Red Hat. 6bf215546Sopenharmony_ci * Copyright © 2016 Bas Nieuwenhuizen 7bf215546Sopenharmony_ci * Copyright © 2015 Intel Corporation 8bf215546Sopenharmony_ci * 9bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 10bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 11bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 12bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 13bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 14bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 15bf215546Sopenharmony_ci * 16bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 17bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 18bf215546Sopenharmony_ci * Software. 19bf215546Sopenharmony_ci * 20bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE. 27bf215546Sopenharmony_ci */ 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ci#include "genxml/gen_macros.h" 30bf215546Sopenharmony_ci#include "panvk_private.h" 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_ci#include "util/debug.h" 33bf215546Sopenharmony_ci#include "util/u_atomic.h" 34bf215546Sopenharmony_ci#include "vk_format.h" 35bf215546Sopenharmony_ci#include "vk_object.h" 36bf215546Sopenharmony_ci#include "vk_util.h" 37bf215546Sopenharmony_ci#include "drm-uapi/drm_fourcc.h" 38bf215546Sopenharmony_ci 39bf215546Sopenharmony_cistatic enum mali_texture_dimension 40bf215546Sopenharmony_cipanvk_view_type_to_mali_tex_dim(VkImageViewType type) 41bf215546Sopenharmony_ci{ 42bf215546Sopenharmony_ci switch (type) { 43bf215546Sopenharmony_ci case VK_IMAGE_VIEW_TYPE_1D: 44bf215546Sopenharmony_ci case VK_IMAGE_VIEW_TYPE_1D_ARRAY: 45bf215546Sopenharmony_ci return MALI_TEXTURE_DIMENSION_1D; 46bf215546Sopenharmony_ci case VK_IMAGE_VIEW_TYPE_2D: 47bf215546Sopenharmony_ci case VK_IMAGE_VIEW_TYPE_2D_ARRAY: 48bf215546Sopenharmony_ci return MALI_TEXTURE_DIMENSION_2D; 49bf215546Sopenharmony_ci case VK_IMAGE_VIEW_TYPE_3D: 50bf215546Sopenharmony_ci return MALI_TEXTURE_DIMENSION_3D; 51bf215546Sopenharmony_ci case VK_IMAGE_VIEW_TYPE_CUBE: 52bf215546Sopenharmony_ci case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: 53bf215546Sopenharmony_ci return MALI_TEXTURE_DIMENSION_CUBE; 54bf215546Sopenharmony_ci default: 55bf215546Sopenharmony_ci unreachable("Invalid view type"); 56bf215546Sopenharmony_ci } 57bf215546Sopenharmony_ci} 58bf215546Sopenharmony_ci 59bf215546Sopenharmony_cistatic void 60bf215546Sopenharmony_cipanvk_convert_swizzle(const VkComponentMapping *in, 61bf215546Sopenharmony_ci unsigned char *out) 62bf215546Sopenharmony_ci{ 63bf215546Sopenharmony_ci const VkComponentSwizzle *comp = &in->r; 64bf215546Sopenharmony_ci for (unsigned i = 0; i < 4; i++) { 65bf215546Sopenharmony_ci switch (comp[i]) { 66bf215546Sopenharmony_ci case VK_COMPONENT_SWIZZLE_ZERO: 67bf215546Sopenharmony_ci out[i] = PIPE_SWIZZLE_0; 68bf215546Sopenharmony_ci break; 69bf215546Sopenharmony_ci case VK_COMPONENT_SWIZZLE_ONE: 70bf215546Sopenharmony_ci out[i] = PIPE_SWIZZLE_1; 71bf215546Sopenharmony_ci break; 72bf215546Sopenharmony_ci case VK_COMPONENT_SWIZZLE_R: 73bf215546Sopenharmony_ci out[i] = PIPE_SWIZZLE_X; 74bf215546Sopenharmony_ci break; 75bf215546Sopenharmony_ci case VK_COMPONENT_SWIZZLE_G: 76bf215546Sopenharmony_ci out[i] = PIPE_SWIZZLE_Y; 77bf215546Sopenharmony_ci break; 78bf215546Sopenharmony_ci case VK_COMPONENT_SWIZZLE_B: 79bf215546Sopenharmony_ci out[i] = PIPE_SWIZZLE_Z; 80bf215546Sopenharmony_ci break; 81bf215546Sopenharmony_ci case VK_COMPONENT_SWIZZLE_A: 82bf215546Sopenharmony_ci out[i] = PIPE_SWIZZLE_W; 83bf215546Sopenharmony_ci break; 84bf215546Sopenharmony_ci default: 85bf215546Sopenharmony_ci unreachable("Invalid swizzle"); 86bf215546Sopenharmony_ci } 87bf215546Sopenharmony_ci } 88bf215546Sopenharmony_ci} 89bf215546Sopenharmony_ci 90bf215546Sopenharmony_ciVkResult 91bf215546Sopenharmony_cipanvk_per_arch(CreateImageView)(VkDevice _device, 92bf215546Sopenharmony_ci const VkImageViewCreateInfo *pCreateInfo, 93bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 94bf215546Sopenharmony_ci VkImageView *pView) 95bf215546Sopenharmony_ci{ 96bf215546Sopenharmony_ci VK_FROM_HANDLE(panvk_device, device, _device); 97bf215546Sopenharmony_ci VK_FROM_HANDLE(panvk_image, image, pCreateInfo->image); 98bf215546Sopenharmony_ci struct panvk_image_view *view; 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_ci view = vk_image_view_create(&device->vk, false, pCreateInfo, 101bf215546Sopenharmony_ci pAllocator, sizeof(*view)); 102bf215546Sopenharmony_ci if (view == NULL) 103bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 104bf215546Sopenharmony_ci 105bf215546Sopenharmony_ci view->pview = (struct pan_image_view) { 106bf215546Sopenharmony_ci .image = &image->pimage, 107bf215546Sopenharmony_ci .format = vk_format_to_pipe_format(view->vk.view_format), 108bf215546Sopenharmony_ci .dim = panvk_view_type_to_mali_tex_dim(view->vk.view_type), 109bf215546Sopenharmony_ci .nr_samples = image->pimage.layout.nr_samples, 110bf215546Sopenharmony_ci .first_level = view->vk.base_mip_level, 111bf215546Sopenharmony_ci .last_level = view->vk.base_mip_level + 112bf215546Sopenharmony_ci view->vk.level_count - 1, 113bf215546Sopenharmony_ci .first_layer = view->vk.base_array_layer, 114bf215546Sopenharmony_ci .last_layer = view->vk.base_array_layer + 115bf215546Sopenharmony_ci view->vk.layer_count - 1, 116bf215546Sopenharmony_ci }; 117bf215546Sopenharmony_ci panvk_convert_swizzle(&view->vk.swizzle, view->pview.swizzle); 118bf215546Sopenharmony_ci 119bf215546Sopenharmony_ci struct panfrost_device *pdev = &device->physical_device->pdev; 120bf215546Sopenharmony_ci 121bf215546Sopenharmony_ci if (view->vk.usage & 122bf215546Sopenharmony_ci (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) { 123bf215546Sopenharmony_ci unsigned bo_size = 124bf215546Sopenharmony_ci GENX(panfrost_estimate_texture_payload_size)(&view->pview) + 125bf215546Sopenharmony_ci pan_size(TEXTURE); 126bf215546Sopenharmony_ci 127bf215546Sopenharmony_ci view->bo = panfrost_bo_create(pdev, bo_size, 0, "Texture descriptor"); 128bf215546Sopenharmony_ci 129bf215546Sopenharmony_ci STATIC_ASSERT(sizeof(view->descs.tex) >= pan_size(TEXTURE)); 130bf215546Sopenharmony_ci GENX(panfrost_new_texture)(pdev, &view->pview, &view->descs.tex, &view->bo->ptr); 131bf215546Sopenharmony_ci } 132bf215546Sopenharmony_ci 133bf215546Sopenharmony_ci if (view->vk.usage & VK_IMAGE_USAGE_STORAGE_BIT) { 134bf215546Sopenharmony_ci uint8_t *attrib_buf = (uint8_t *)view->descs.img_attrib_buf; 135bf215546Sopenharmony_ci bool is_3d = image->pimage.layout.dim == MALI_TEXTURE_DIMENSION_3D; 136bf215546Sopenharmony_ci unsigned offset = image->pimage.data.offset; 137bf215546Sopenharmony_ci offset += panfrost_texture_offset(&image->pimage.layout, 138bf215546Sopenharmony_ci view->pview.first_level, 139bf215546Sopenharmony_ci is_3d ? 0 : view->pview.first_layer, 140bf215546Sopenharmony_ci is_3d ? view->pview.first_layer : 0); 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_ci pan_pack(attrib_buf, ATTRIBUTE_BUFFER, cfg) { 143bf215546Sopenharmony_ci cfg.type = image->pimage.layout.modifier == DRM_FORMAT_MOD_LINEAR ? 144bf215546Sopenharmony_ci MALI_ATTRIBUTE_TYPE_3D_LINEAR : MALI_ATTRIBUTE_TYPE_3D_INTERLEAVED; 145bf215546Sopenharmony_ci cfg.pointer = image->pimage.data.bo->ptr.gpu + offset; 146bf215546Sopenharmony_ci cfg.stride = util_format_get_blocksize(view->pview.format); 147bf215546Sopenharmony_ci cfg.size = image->pimage.data.bo->size - offset; 148bf215546Sopenharmony_ci } 149bf215546Sopenharmony_ci 150bf215546Sopenharmony_ci attrib_buf += pan_size(ATTRIBUTE_BUFFER); 151bf215546Sopenharmony_ci pan_pack(attrib_buf, ATTRIBUTE_BUFFER_CONTINUATION_3D, cfg) { 152bf215546Sopenharmony_ci unsigned level = view->pview.first_level; 153bf215546Sopenharmony_ci 154bf215546Sopenharmony_ci cfg.s_dimension = u_minify(image->pimage.layout.width, level); 155bf215546Sopenharmony_ci cfg.t_dimension = u_minify(image->pimage.layout.height, level); 156bf215546Sopenharmony_ci cfg.r_dimension = 157bf215546Sopenharmony_ci view->pview.dim == MALI_TEXTURE_DIMENSION_3D ? 158bf215546Sopenharmony_ci u_minify(image->pimage.layout.depth, level) : 159bf215546Sopenharmony_ci (view->pview.last_layer - view->pview.first_layer + 1); 160bf215546Sopenharmony_ci cfg.row_stride = image->pimage.layout.slices[level].row_stride; 161bf215546Sopenharmony_ci if (cfg.r_dimension > 1) { 162bf215546Sopenharmony_ci cfg.slice_stride = 163bf215546Sopenharmony_ci panfrost_get_layer_stride(&image->pimage.layout, level); 164bf215546Sopenharmony_ci } 165bf215546Sopenharmony_ci } 166bf215546Sopenharmony_ci } 167bf215546Sopenharmony_ci 168bf215546Sopenharmony_ci *pView = panvk_image_view_to_handle(view); 169bf215546Sopenharmony_ci return VK_SUCCESS; 170bf215546Sopenharmony_ci} 171bf215546Sopenharmony_ci 172bf215546Sopenharmony_ciVkResult 173bf215546Sopenharmony_cipanvk_per_arch(CreateBufferView)(VkDevice _device, 174bf215546Sopenharmony_ci const VkBufferViewCreateInfo *pCreateInfo, 175bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 176bf215546Sopenharmony_ci VkBufferView *pView) 177bf215546Sopenharmony_ci{ 178bf215546Sopenharmony_ci VK_FROM_HANDLE(panvk_device, device, _device); 179bf215546Sopenharmony_ci VK_FROM_HANDLE(panvk_buffer, buffer, pCreateInfo->buffer); 180bf215546Sopenharmony_ci 181bf215546Sopenharmony_ci struct panvk_buffer_view *view = 182bf215546Sopenharmony_ci vk_object_zalloc(&device->vk, pAllocator, sizeof(*view), 183bf215546Sopenharmony_ci VK_OBJECT_TYPE_BUFFER_VIEW); 184bf215546Sopenharmony_ci 185bf215546Sopenharmony_ci if (!view) 186bf215546Sopenharmony_ci return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY); 187bf215546Sopenharmony_ci 188bf215546Sopenharmony_ci view->fmt = vk_format_to_pipe_format(pCreateInfo->format); 189bf215546Sopenharmony_ci 190bf215546Sopenharmony_ci struct panfrost_device *pdev = &device->physical_device->pdev; 191bf215546Sopenharmony_ci mali_ptr address = panvk_buffer_gpu_ptr(buffer, pCreateInfo->offset); 192bf215546Sopenharmony_ci unsigned size = panvk_buffer_range(buffer, pCreateInfo->offset, 193bf215546Sopenharmony_ci pCreateInfo->range); 194bf215546Sopenharmony_ci unsigned blksz = util_format_get_blocksize(view->fmt); 195bf215546Sopenharmony_ci view->elems = size / blksz; 196bf215546Sopenharmony_ci 197bf215546Sopenharmony_ci assert(!(address & 63)); 198bf215546Sopenharmony_ci 199bf215546Sopenharmony_ci if (buffer->vk.usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) { 200bf215546Sopenharmony_ci unsigned bo_size = pan_size(SURFACE_WITH_STRIDE); 201bf215546Sopenharmony_ci view->bo = panfrost_bo_create(pdev, bo_size, 0, "Texture descriptor"); 202bf215546Sopenharmony_ci 203bf215546Sopenharmony_ci pan_pack(&view->bo->ptr.cpu, SURFACE_WITH_STRIDE, cfg) { 204bf215546Sopenharmony_ci cfg.pointer = address; 205bf215546Sopenharmony_ci } 206bf215546Sopenharmony_ci 207bf215546Sopenharmony_ci pan_pack(&view->descs.tex, TEXTURE, cfg) { 208bf215546Sopenharmony_ci cfg.dimension = MALI_TEXTURE_DIMENSION_1D; 209bf215546Sopenharmony_ci cfg.format = pdev->formats[view->fmt].hw; 210bf215546Sopenharmony_ci cfg.width = view->elems; 211bf215546Sopenharmony_ci cfg.depth = cfg.height = 1; 212bf215546Sopenharmony_ci cfg.swizzle = PAN_V6_SWIZZLE(R, G, B, A); 213bf215546Sopenharmony_ci cfg.texel_ordering = MALI_TEXTURE_LAYOUT_LINEAR; 214bf215546Sopenharmony_ci cfg.levels = 1; 215bf215546Sopenharmony_ci cfg.array_size = 1; 216bf215546Sopenharmony_ci cfg.surfaces = view->bo->ptr.gpu; 217bf215546Sopenharmony_ci cfg.maximum_lod = cfg.minimum_lod = FIXED_16(0, false); 218bf215546Sopenharmony_ci } 219bf215546Sopenharmony_ci } 220bf215546Sopenharmony_ci 221bf215546Sopenharmony_ci if (buffer->vk.usage & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) { 222bf215546Sopenharmony_ci uint8_t *attrib_buf = (uint8_t *)view->descs.img_attrib_buf; 223bf215546Sopenharmony_ci 224bf215546Sopenharmony_ci pan_pack(attrib_buf, ATTRIBUTE_BUFFER, cfg) { 225bf215546Sopenharmony_ci cfg.type = MALI_ATTRIBUTE_TYPE_3D_LINEAR; 226bf215546Sopenharmony_ci cfg.pointer = address; 227bf215546Sopenharmony_ci cfg.stride = blksz; 228bf215546Sopenharmony_ci cfg.size = view->elems * blksz; 229bf215546Sopenharmony_ci } 230bf215546Sopenharmony_ci 231bf215546Sopenharmony_ci attrib_buf += pan_size(ATTRIBUTE_BUFFER); 232bf215546Sopenharmony_ci pan_pack(attrib_buf, ATTRIBUTE_BUFFER_CONTINUATION_3D, cfg) { 233bf215546Sopenharmony_ci cfg.s_dimension = view->elems; 234bf215546Sopenharmony_ci cfg.t_dimension = 1; 235bf215546Sopenharmony_ci cfg.r_dimension = 1; 236bf215546Sopenharmony_ci cfg.row_stride = view->elems * blksz; 237bf215546Sopenharmony_ci } 238bf215546Sopenharmony_ci } 239bf215546Sopenharmony_ci 240bf215546Sopenharmony_ci *pView = panvk_buffer_view_to_handle(view); 241bf215546Sopenharmony_ci return VK_SUCCESS; 242bf215546Sopenharmony_ci} 243