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 * Permission is hereby granted, free of charge, to any person obtaining a 10 * copy of this software and associated documentation files (the "Software"), 11 * to deal in the Software without restriction, including without limitation 12 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 13 * and/or sell copies of the Software, and to permit persons to whom the 14 * Software is furnished to do so, subject to the following conditions: 15 * 16 * The above copyright notice and this permission notice (including the next 17 * paragraph) shall be included in all copies or substantial portions of the 18 * Software. 19 * 20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 * DEALINGS IN THE SOFTWARE. 27 */ 28 29#include "genxml/gen_macros.h" 30#include "panvk_private.h" 31#include "panfrost-quirks.h" 32 33#include "util/debug.h" 34#include "util/u_atomic.h" 35#include "vk_format.h" 36#include "vk_object.h" 37#include "vk_util.h" 38#include "drm-uapi/drm_fourcc.h" 39 40static enum mali_texture_dimension 41panvk_view_type_to_mali_tex_dim(VkImageViewType type) 42{ 43 switch (type) { 44 case VK_IMAGE_VIEW_TYPE_1D: 45 case VK_IMAGE_VIEW_TYPE_1D_ARRAY: 46 return MALI_TEXTURE_DIMENSION_1D; 47 case VK_IMAGE_VIEW_TYPE_2D: 48 case VK_IMAGE_VIEW_TYPE_2D_ARRAY: 49 return MALI_TEXTURE_DIMENSION_2D; 50 case VK_IMAGE_VIEW_TYPE_3D: 51 return MALI_TEXTURE_DIMENSION_3D; 52 case VK_IMAGE_VIEW_TYPE_CUBE: 53 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: 54 return MALI_TEXTURE_DIMENSION_CUBE; 55 default: 56 unreachable("Invalid view type"); 57 } 58} 59 60static void 61panvk_convert_swizzle(const VkComponentMapping *in, 62 unsigned char *out) 63{ 64 const VkComponentSwizzle *comp = &in->r; 65 for (unsigned i = 0; i < 4; i++) { 66 switch (comp[i]) { 67 case VK_COMPONENT_SWIZZLE_IDENTITY: 68 out[i] = PIPE_SWIZZLE_X + i; 69 break; 70 case VK_COMPONENT_SWIZZLE_ZERO: 71 out[i] = PIPE_SWIZZLE_0; 72 break; 73 case VK_COMPONENT_SWIZZLE_ONE: 74 out[i] = PIPE_SWIZZLE_1; 75 break; 76 case VK_COMPONENT_SWIZZLE_R: 77 out[i] = PIPE_SWIZZLE_X; 78 break; 79 case VK_COMPONENT_SWIZZLE_G: 80 out[i] = PIPE_SWIZZLE_Y; 81 break; 82 case VK_COMPONENT_SWIZZLE_B: 83 out[i] = PIPE_SWIZZLE_Z; 84 break; 85 case VK_COMPONENT_SWIZZLE_A: 86 out[i] = PIPE_SWIZZLE_W; 87 break; 88 default: 89 unreachable("Invalid swizzle"); 90 } 91 } 92} 93 94VkResult 95panvk_per_arch(CreateImageView)(VkDevice _device, 96 const VkImageViewCreateInfo *pCreateInfo, 97 const VkAllocationCallbacks *pAllocator, 98 VkImageView *pView) 99{ 100 VK_FROM_HANDLE(panvk_device, device, _device); 101 VK_FROM_HANDLE(panvk_image, image, pCreateInfo->image); 102 struct panvk_image_view *view; 103 104 view = vk_object_zalloc(&device->vk, pAllocator, sizeof(*view), 105 VK_OBJECT_TYPE_IMAGE_VIEW); 106 if (view == NULL) 107 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 108 109 view->pview.format = vk_format_to_pipe_format(pCreateInfo->format); 110 111 if (pCreateInfo->subresourceRange.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) 112 view->pview.format = util_format_get_depth_only(view->pview.format); 113 else if (pCreateInfo->subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) 114 view->pview.format = util_format_stencil_only(view->pview.format); 115 116 unsigned level_count = 117 pCreateInfo->subresourceRange.levelCount == VK_REMAINING_MIP_LEVELS ? 118 image->pimage.layout.nr_slices - pCreateInfo->subresourceRange.baseMipLevel : 119 pCreateInfo->subresourceRange.levelCount; 120 unsigned layer_count = 121 pCreateInfo->subresourceRange.layerCount == VK_REMAINING_ARRAY_LAYERS ? 122 image->pimage.layout.array_size - pCreateInfo->subresourceRange.baseArrayLayer : 123 pCreateInfo->subresourceRange.layerCount; 124 125 view->pview.dim = panvk_view_type_to_mali_tex_dim(pCreateInfo->viewType); 126 view->pview.first_level = pCreateInfo->subresourceRange.baseMipLevel; 127 view->pview.last_level = pCreateInfo->subresourceRange.baseMipLevel + level_count - 1; 128 view->pview.first_layer = pCreateInfo->subresourceRange.baseArrayLayer; 129 view->pview.last_layer = pCreateInfo->subresourceRange.baseArrayLayer + layer_count - 1; 130 panvk_convert_swizzle(&pCreateInfo->components, view->pview.swizzle); 131 view->pview.image = &image->pimage; 132 view->pview.nr_samples = image->pimage.layout.nr_samples; 133 view->vk_format = pCreateInfo->format; 134 135 struct panfrost_device *pdev = &device->physical_device->pdev; 136 137 if (image->usage & 138 (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) { 139 unsigned bo_size = 140 GENX(panfrost_estimate_texture_payload_size)(&view->pview) + 141 pan_size(TEXTURE); 142 143 unsigned surf_descs_offset = PAN_ARCH <= 5 ? pan_size(TEXTURE) : 0; 144 145 view->bo = panfrost_bo_create(pdev, bo_size, 0, "Texture descriptor"); 146 147 struct panfrost_ptr surf_descs = { 148 .cpu = view->bo->ptr.cpu + surf_descs_offset, 149 .gpu = view->bo->ptr.gpu + surf_descs_offset, 150 }; 151 void *tex_desc = PAN_ARCH >= 6 ? 152 &view->descs.tex : view->bo->ptr.cpu; 153 154 STATIC_ASSERT(sizeof(view->descs.tex) >= pan_size(TEXTURE)); 155 GENX(panfrost_new_texture)(pdev, &view->pview, tex_desc, &surf_descs); 156 } 157 158 *pView = panvk_image_view_to_handle(view); 159 return VK_SUCCESS; 160} 161