17ec681f3Smrg/* 27ec681f3Smrg * Copyright © 2021 Collabora Ltd. 37ec681f3Smrg * 47ec681f3Smrg * Derived from tu_image.c which is: 57ec681f3Smrg * Copyright © 2016 Red Hat. 67ec681f3Smrg * Copyright © 2016 Bas Nieuwenhuizen 77ec681f3Smrg * Copyright © 2015 Intel Corporation 87ec681f3Smrg * 97ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a 107ec681f3Smrg * copy of this software and associated documentation files (the "Software"), 117ec681f3Smrg * to deal in the Software without restriction, including without limitation 127ec681f3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 137ec681f3Smrg * and/or sell copies of the Software, and to permit persons to whom the 147ec681f3Smrg * Software is furnished to do so, subject to the following conditions: 157ec681f3Smrg * 167ec681f3Smrg * The above copyright notice and this permission notice (including the next 177ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the 187ec681f3Smrg * Software. 197ec681f3Smrg * 207ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 217ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 227ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 237ec681f3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 247ec681f3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 257ec681f3Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 267ec681f3Smrg * DEALINGS IN THE SOFTWARE. 277ec681f3Smrg */ 287ec681f3Smrg 297ec681f3Smrg#include "genxml/gen_macros.h" 307ec681f3Smrg#include "panvk_private.h" 317ec681f3Smrg#include "panfrost-quirks.h" 327ec681f3Smrg 337ec681f3Smrg#include "util/debug.h" 347ec681f3Smrg#include "util/u_atomic.h" 357ec681f3Smrg#include "vk_format.h" 367ec681f3Smrg#include "vk_object.h" 377ec681f3Smrg#include "vk_util.h" 387ec681f3Smrg#include "drm-uapi/drm_fourcc.h" 397ec681f3Smrg 407ec681f3Smrgstatic enum mali_texture_dimension 417ec681f3Smrgpanvk_view_type_to_mali_tex_dim(VkImageViewType type) 427ec681f3Smrg{ 437ec681f3Smrg switch (type) { 447ec681f3Smrg case VK_IMAGE_VIEW_TYPE_1D: 457ec681f3Smrg case VK_IMAGE_VIEW_TYPE_1D_ARRAY: 467ec681f3Smrg return MALI_TEXTURE_DIMENSION_1D; 477ec681f3Smrg case VK_IMAGE_VIEW_TYPE_2D: 487ec681f3Smrg case VK_IMAGE_VIEW_TYPE_2D_ARRAY: 497ec681f3Smrg return MALI_TEXTURE_DIMENSION_2D; 507ec681f3Smrg case VK_IMAGE_VIEW_TYPE_3D: 517ec681f3Smrg return MALI_TEXTURE_DIMENSION_3D; 527ec681f3Smrg case VK_IMAGE_VIEW_TYPE_CUBE: 537ec681f3Smrg case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: 547ec681f3Smrg return MALI_TEXTURE_DIMENSION_CUBE; 557ec681f3Smrg default: 567ec681f3Smrg unreachable("Invalid view type"); 577ec681f3Smrg } 587ec681f3Smrg} 597ec681f3Smrg 607ec681f3Smrgstatic void 617ec681f3Smrgpanvk_convert_swizzle(const VkComponentMapping *in, 627ec681f3Smrg unsigned char *out) 637ec681f3Smrg{ 647ec681f3Smrg const VkComponentSwizzle *comp = &in->r; 657ec681f3Smrg for (unsigned i = 0; i < 4; i++) { 667ec681f3Smrg switch (comp[i]) { 677ec681f3Smrg case VK_COMPONENT_SWIZZLE_IDENTITY: 687ec681f3Smrg out[i] = PIPE_SWIZZLE_X + i; 697ec681f3Smrg break; 707ec681f3Smrg case VK_COMPONENT_SWIZZLE_ZERO: 717ec681f3Smrg out[i] = PIPE_SWIZZLE_0; 727ec681f3Smrg break; 737ec681f3Smrg case VK_COMPONENT_SWIZZLE_ONE: 747ec681f3Smrg out[i] = PIPE_SWIZZLE_1; 757ec681f3Smrg break; 767ec681f3Smrg case VK_COMPONENT_SWIZZLE_R: 777ec681f3Smrg out[i] = PIPE_SWIZZLE_X; 787ec681f3Smrg break; 797ec681f3Smrg case VK_COMPONENT_SWIZZLE_G: 807ec681f3Smrg out[i] = PIPE_SWIZZLE_Y; 817ec681f3Smrg break; 827ec681f3Smrg case VK_COMPONENT_SWIZZLE_B: 837ec681f3Smrg out[i] = PIPE_SWIZZLE_Z; 847ec681f3Smrg break; 857ec681f3Smrg case VK_COMPONENT_SWIZZLE_A: 867ec681f3Smrg out[i] = PIPE_SWIZZLE_W; 877ec681f3Smrg break; 887ec681f3Smrg default: 897ec681f3Smrg unreachable("Invalid swizzle"); 907ec681f3Smrg } 917ec681f3Smrg } 927ec681f3Smrg} 937ec681f3Smrg 947ec681f3SmrgVkResult 957ec681f3Smrgpanvk_per_arch(CreateImageView)(VkDevice _device, 967ec681f3Smrg const VkImageViewCreateInfo *pCreateInfo, 977ec681f3Smrg const VkAllocationCallbacks *pAllocator, 987ec681f3Smrg VkImageView *pView) 997ec681f3Smrg{ 1007ec681f3Smrg VK_FROM_HANDLE(panvk_device, device, _device); 1017ec681f3Smrg VK_FROM_HANDLE(panvk_image, image, pCreateInfo->image); 1027ec681f3Smrg struct panvk_image_view *view; 1037ec681f3Smrg 1047ec681f3Smrg view = vk_object_zalloc(&device->vk, pAllocator, sizeof(*view), 1057ec681f3Smrg VK_OBJECT_TYPE_IMAGE_VIEW); 1067ec681f3Smrg if (view == NULL) 1077ec681f3Smrg return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 1087ec681f3Smrg 1097ec681f3Smrg view->pview.format = vk_format_to_pipe_format(pCreateInfo->format); 1107ec681f3Smrg 1117ec681f3Smrg if (pCreateInfo->subresourceRange.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) 1127ec681f3Smrg view->pview.format = util_format_get_depth_only(view->pview.format); 1137ec681f3Smrg else if (pCreateInfo->subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) 1147ec681f3Smrg view->pview.format = util_format_stencil_only(view->pview.format); 1157ec681f3Smrg 1167ec681f3Smrg unsigned level_count = 1177ec681f3Smrg pCreateInfo->subresourceRange.levelCount == VK_REMAINING_MIP_LEVELS ? 1187ec681f3Smrg image->pimage.layout.nr_slices - pCreateInfo->subresourceRange.baseMipLevel : 1197ec681f3Smrg pCreateInfo->subresourceRange.levelCount; 1207ec681f3Smrg unsigned layer_count = 1217ec681f3Smrg pCreateInfo->subresourceRange.layerCount == VK_REMAINING_ARRAY_LAYERS ? 1227ec681f3Smrg image->pimage.layout.array_size - pCreateInfo->subresourceRange.baseArrayLayer : 1237ec681f3Smrg pCreateInfo->subresourceRange.layerCount; 1247ec681f3Smrg 1257ec681f3Smrg view->pview.dim = panvk_view_type_to_mali_tex_dim(pCreateInfo->viewType); 1267ec681f3Smrg view->pview.first_level = pCreateInfo->subresourceRange.baseMipLevel; 1277ec681f3Smrg view->pview.last_level = pCreateInfo->subresourceRange.baseMipLevel + level_count - 1; 1287ec681f3Smrg view->pview.first_layer = pCreateInfo->subresourceRange.baseArrayLayer; 1297ec681f3Smrg view->pview.last_layer = pCreateInfo->subresourceRange.baseArrayLayer + layer_count - 1; 1307ec681f3Smrg panvk_convert_swizzle(&pCreateInfo->components, view->pview.swizzle); 1317ec681f3Smrg view->pview.image = &image->pimage; 1327ec681f3Smrg view->pview.nr_samples = image->pimage.layout.nr_samples; 1337ec681f3Smrg view->vk_format = pCreateInfo->format; 1347ec681f3Smrg 1357ec681f3Smrg struct panfrost_device *pdev = &device->physical_device->pdev; 1367ec681f3Smrg 1377ec681f3Smrg if (image->usage & 1387ec681f3Smrg (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) { 1397ec681f3Smrg unsigned bo_size = 1407ec681f3Smrg GENX(panfrost_estimate_texture_payload_size)(&view->pview) + 1417ec681f3Smrg pan_size(TEXTURE); 1427ec681f3Smrg 1437ec681f3Smrg unsigned surf_descs_offset = PAN_ARCH <= 5 ? pan_size(TEXTURE) : 0; 1447ec681f3Smrg 1457ec681f3Smrg view->bo = panfrost_bo_create(pdev, bo_size, 0, "Texture descriptor"); 1467ec681f3Smrg 1477ec681f3Smrg struct panfrost_ptr surf_descs = { 1487ec681f3Smrg .cpu = view->bo->ptr.cpu + surf_descs_offset, 1497ec681f3Smrg .gpu = view->bo->ptr.gpu + surf_descs_offset, 1507ec681f3Smrg }; 1517ec681f3Smrg void *tex_desc = PAN_ARCH >= 6 ? 1527ec681f3Smrg &view->descs.tex : view->bo->ptr.cpu; 1537ec681f3Smrg 1547ec681f3Smrg STATIC_ASSERT(sizeof(view->descs.tex) >= pan_size(TEXTURE)); 1557ec681f3Smrg GENX(panfrost_new_texture)(pdev, &view->pview, tex_desc, &surf_descs); 1567ec681f3Smrg } 1577ec681f3Smrg 1587ec681f3Smrg *pView = panvk_image_view_to_handle(view); 1597ec681f3Smrg return VK_SUCCESS; 1607ec681f3Smrg} 161