1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2022 Imagination Technologies Ltd. 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 5bf215546Sopenharmony_ci * of this software and associated documentation files (the "Software"), to deal 6bf215546Sopenharmony_ci * in the Software without restriction, including without limitation the rights 7bf215546Sopenharmony_ci * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8bf215546Sopenharmony_ci * copies of the Software, and to permit persons to whom the Software is 9bf215546Sopenharmony_ci * furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18bf215546Sopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20bf215546Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21bf215546Sopenharmony_ci * SOFTWARE. 22bf215546Sopenharmony_ci */ 23bf215546Sopenharmony_ci 24bf215546Sopenharmony_ci#include <stdint.h> 25bf215546Sopenharmony_ci#include <vulkan/vulkan.h> 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ci#include "hwdef/rogue_hw_defs.h" 28bf215546Sopenharmony_ci#include "pipe/p_defines.h" 29bf215546Sopenharmony_ci#include "pvr_csb.h" 30bf215546Sopenharmony_ci#include "pvr_device_info.h" 31bf215546Sopenharmony_ci#include "pvr_formats.h" 32bf215546Sopenharmony_ci#include "pvr_private.h" 33bf215546Sopenharmony_ci#include "pvr_tex_state.h" 34bf215546Sopenharmony_ci#include "util/macros.h" 35bf215546Sopenharmony_ci#include "util/u_math.h" 36bf215546Sopenharmony_ci#include "vk_format.h" 37bf215546Sopenharmony_ci#include "vk_log.h" 38bf215546Sopenharmony_ci 39bf215546Sopenharmony_cistatic enum ROGUE_TEXSTATE_SWIZ pvr_get_hw_swizzle(VkComponentSwizzle comp, 40bf215546Sopenharmony_ci enum pipe_swizzle swz) 41bf215546Sopenharmony_ci{ 42bf215546Sopenharmony_ci switch (swz) { 43bf215546Sopenharmony_ci case PIPE_SWIZZLE_0: 44bf215546Sopenharmony_ci return ROGUE_TEXSTATE_SWIZ_SRC_ZERO; 45bf215546Sopenharmony_ci case PIPE_SWIZZLE_1: 46bf215546Sopenharmony_ci return ROGUE_TEXSTATE_SWIZ_SRC_ONE; 47bf215546Sopenharmony_ci case PIPE_SWIZZLE_X: 48bf215546Sopenharmony_ci return ROGUE_TEXSTATE_SWIZ_SRCCHAN_0; 49bf215546Sopenharmony_ci case PIPE_SWIZZLE_Y: 50bf215546Sopenharmony_ci return ROGUE_TEXSTATE_SWIZ_SRCCHAN_1; 51bf215546Sopenharmony_ci case PIPE_SWIZZLE_Z: 52bf215546Sopenharmony_ci return ROGUE_TEXSTATE_SWIZ_SRCCHAN_2; 53bf215546Sopenharmony_ci case PIPE_SWIZZLE_W: 54bf215546Sopenharmony_ci return ROGUE_TEXSTATE_SWIZ_SRCCHAN_3; 55bf215546Sopenharmony_ci case PIPE_SWIZZLE_NONE: 56bf215546Sopenharmony_ci if (comp == VK_COMPONENT_SWIZZLE_A) 57bf215546Sopenharmony_ci return ROGUE_TEXSTATE_SWIZ_SRC_ONE; 58bf215546Sopenharmony_ci else 59bf215546Sopenharmony_ci return ROGUE_TEXSTATE_SWIZ_SRC_ZERO; 60bf215546Sopenharmony_ci default: 61bf215546Sopenharmony_ci unreachable("Unknown enum pipe_swizzle"); 62bf215546Sopenharmony_ci }; 63bf215546Sopenharmony_ci} 64bf215546Sopenharmony_ci 65bf215546Sopenharmony_ciVkResult 66bf215546Sopenharmony_cipvr_pack_tex_state(struct pvr_device *device, 67bf215546Sopenharmony_ci struct pvr_texture_state_info *info, 68bf215546Sopenharmony_ci uint64_t state[static const ROGUE_NUM_TEXSTATE_IMAGE_WORDS]) 69bf215546Sopenharmony_ci{ 70bf215546Sopenharmony_ci const struct pvr_device_info *dev_info = &device->pdevice->dev_info; 71bf215546Sopenharmony_ci uint32_t texture_type; 72bf215546Sopenharmony_ci 73bf215546Sopenharmony_ci pvr_csb_pack (&state[0], TEXSTATE_IMAGE_WORD0, word0) { 74bf215546Sopenharmony_ci /* Determine texture type */ 75bf215546Sopenharmony_ci if (info->is_cube && info->tex_state_type == PVR_TEXTURE_STATE_SAMPLE) { 76bf215546Sopenharmony_ci word0.textype = texture_type = PVRX(TEXSTATE_TEXTYPE_CUBE); 77bf215546Sopenharmony_ci } else if (info->mem_layout == PVR_MEMLAYOUT_TWIDDLED || 78bf215546Sopenharmony_ci info->mem_layout == PVR_MEMLAYOUT_3DTWIDDLED) { 79bf215546Sopenharmony_ci if (info->type == VK_IMAGE_VIEW_TYPE_3D) { 80bf215546Sopenharmony_ci word0.textype = texture_type = PVRX(TEXSTATE_TEXTYPE_3D); 81bf215546Sopenharmony_ci } else if (info->type == VK_IMAGE_VIEW_TYPE_1D || 82bf215546Sopenharmony_ci info->type == VK_IMAGE_VIEW_TYPE_1D_ARRAY) { 83bf215546Sopenharmony_ci word0.textype = texture_type = PVRX(TEXSTATE_TEXTYPE_1D); 84bf215546Sopenharmony_ci } else if (info->type == VK_IMAGE_VIEW_TYPE_2D || 85bf215546Sopenharmony_ci info->type == VK_IMAGE_VIEW_TYPE_2D_ARRAY) { 86bf215546Sopenharmony_ci word0.textype = texture_type = PVRX(TEXSTATE_TEXTYPE_2D); 87bf215546Sopenharmony_ci } else { 88bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_FORMAT_NOT_SUPPORTED); 89bf215546Sopenharmony_ci } 90bf215546Sopenharmony_ci } else if (info->mem_layout == PVR_MEMLAYOUT_LINEAR) { 91bf215546Sopenharmony_ci word0.textype = texture_type = PVRX(TEXSTATE_TEXTYPE_STRIDE); 92bf215546Sopenharmony_ci } else { 93bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_FORMAT_NOT_SUPPORTED); 94bf215546Sopenharmony_ci } 95bf215546Sopenharmony_ci 96bf215546Sopenharmony_ci word0.texformat = pvr_get_tex_format(info->format); 97bf215546Sopenharmony_ci word0.smpcnt = util_logbase2(info->sample_count); 98bf215546Sopenharmony_ci word0.swiz0 = 99bf215546Sopenharmony_ci pvr_get_hw_swizzle(VK_COMPONENT_SWIZZLE_R, info->swizzle[0]); 100bf215546Sopenharmony_ci word0.swiz1 = 101bf215546Sopenharmony_ci pvr_get_hw_swizzle(VK_COMPONENT_SWIZZLE_G, info->swizzle[1]); 102bf215546Sopenharmony_ci word0.swiz2 = 103bf215546Sopenharmony_ci pvr_get_hw_swizzle(VK_COMPONENT_SWIZZLE_B, info->swizzle[2]); 104bf215546Sopenharmony_ci word0.swiz3 = 105bf215546Sopenharmony_ci pvr_get_hw_swizzle(VK_COMPONENT_SWIZZLE_A, info->swizzle[3]); 106bf215546Sopenharmony_ci 107bf215546Sopenharmony_ci /* Gamma */ 108bf215546Sopenharmony_ci if (vk_format_is_srgb(info->format)) { 109bf215546Sopenharmony_ci /* Gamma for 2 Component Formats has to be handled differently. */ 110bf215546Sopenharmony_ci if (vk_format_get_nr_components(info->format) == 2) { 111bf215546Sopenharmony_ci /* Enable Gamma only for Channel 0 if Channel 1 is an Alpha 112bf215546Sopenharmony_ci * Channel. 113bf215546Sopenharmony_ci */ 114bf215546Sopenharmony_ci if (vk_format_has_alpha(info->format)) { 115bf215546Sopenharmony_ci word0.twocomp_gamma = PVRX(TEXSTATE_TWOCOMP_GAMMA_R); 116bf215546Sopenharmony_ci } else { 117bf215546Sopenharmony_ci /* Otherwise Enable Gamma for both the Channels. */ 118bf215546Sopenharmony_ci word0.twocomp_gamma = PVRX(TEXSTATE_TWOCOMP_GAMMA_RG); 119bf215546Sopenharmony_ci 120bf215546Sopenharmony_ci /* If Channel 0 happens to be the Alpha Channel, the 121bf215546Sopenharmony_ci * ALPHA_MSB bit would not be set thereby disabling Gamma 122bf215546Sopenharmony_ci * for Channel 0. 123bf215546Sopenharmony_ci */ 124bf215546Sopenharmony_ci } 125bf215546Sopenharmony_ci } else { 126bf215546Sopenharmony_ci word0.gamma = PVRX(TEXSTATE_GAMMA_ON); 127bf215546Sopenharmony_ci } 128bf215546Sopenharmony_ci } 129bf215546Sopenharmony_ci 130bf215546Sopenharmony_ci word0.width = info->extent.width - 1; 131bf215546Sopenharmony_ci if (info->type != VK_IMAGE_VIEW_TYPE_1D && 132bf215546Sopenharmony_ci info->type != VK_IMAGE_VIEW_TYPE_1D_ARRAY) 133bf215546Sopenharmony_ci word0.height = info->extent.height - 1; 134bf215546Sopenharmony_ci } 135bf215546Sopenharmony_ci 136bf215546Sopenharmony_ci /* Texture type specific stuff (word 1) */ 137bf215546Sopenharmony_ci if (texture_type == PVRX(TEXSTATE_TEXTYPE_STRIDE)) { 138bf215546Sopenharmony_ci pvr_csb_pack (&state[1], TEXSTATE_STRIDE_IMAGE_WORD1, word1) { 139bf215546Sopenharmony_ci assert(info->stride > 0U); 140bf215546Sopenharmony_ci word1.stride = info->stride - 1U; 141bf215546Sopenharmony_ci word1.num_mip_levels = info->mip_levels; 142bf215546Sopenharmony_ci word1.mipmaps_present = info->mipmaps_present; 143bf215546Sopenharmony_ci 144bf215546Sopenharmony_ci word1.texaddr = PVR_DEV_ADDR_OFFSET(info->addr, info->offset); 145bf215546Sopenharmony_ci 146bf215546Sopenharmony_ci if (vk_format_is_alpha_on_msb(info->format)) 147bf215546Sopenharmony_ci word1.alpha_msb = true; 148bf215546Sopenharmony_ci 149bf215546Sopenharmony_ci if (!PVR_HAS_FEATURE(dev_info, tpu_extended_integer_lookup) && 150bf215546Sopenharmony_ci !PVR_HAS_FEATURE(dev_info, tpu_image_state_v2)) { 151bf215546Sopenharmony_ci if (info->flags & PVR_TEXFLAGS_INDEX_LOOKUP || 152bf215546Sopenharmony_ci info->flags & PVR_TEXFLAGS_BUFFER) 153bf215546Sopenharmony_ci word1.index_lookup = true; 154bf215546Sopenharmony_ci } 155bf215546Sopenharmony_ci 156bf215546Sopenharmony_ci if (info->flags & PVR_TEXFLAGS_BUFFER) 157bf215546Sopenharmony_ci word1.mipmaps_present = false; 158bf215546Sopenharmony_ci 159bf215546Sopenharmony_ci if (PVR_HAS_FEATURE(dev_info, tpu_image_state_v2) && 160bf215546Sopenharmony_ci vk_format_is_compressed(info->format)) 161bf215546Sopenharmony_ci word1.tpu_image_state_v2_compression_mode = 162bf215546Sopenharmony_ci PVRX(TEXSTATE_COMPRESSION_MODE_TPU); 163bf215546Sopenharmony_ci } 164bf215546Sopenharmony_ci } else { 165bf215546Sopenharmony_ci pvr_csb_pack (&state[1], TEXSTATE_IMAGE_WORD1, word1) { 166bf215546Sopenharmony_ci word1.num_mip_levels = info->mip_levels; 167bf215546Sopenharmony_ci word1.mipmaps_present = info->mipmaps_present; 168bf215546Sopenharmony_ci word1.baselevel = info->base_level; 169bf215546Sopenharmony_ci 170bf215546Sopenharmony_ci if (info->extent.depth > 0) { 171bf215546Sopenharmony_ci word1.depth = info->extent.depth - 1; 172bf215546Sopenharmony_ci } else if (PVR_HAS_FEATURE(dev_info, tpu_array_textures)) { 173bf215546Sopenharmony_ci uint32_t array_layers = info->array_size; 174bf215546Sopenharmony_ci 175bf215546Sopenharmony_ci if (info->type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY && 176bf215546Sopenharmony_ci info->tex_state_type == PVR_TEXTURE_STATE_SAMPLE) 177bf215546Sopenharmony_ci array_layers /= 6; 178bf215546Sopenharmony_ci 179bf215546Sopenharmony_ci word1.depth = array_layers - 1; 180bf215546Sopenharmony_ci } 181bf215546Sopenharmony_ci 182bf215546Sopenharmony_ci word1.texaddr = PVR_DEV_ADDR_OFFSET(info->addr, info->offset); 183bf215546Sopenharmony_ci 184bf215546Sopenharmony_ci if (!PVR_HAS_FEATURE(dev_info, tpu_extended_integer_lookup) && 185bf215546Sopenharmony_ci !PVR_HAS_FEATURE(dev_info, tpu_image_state_v2)) { 186bf215546Sopenharmony_ci if (info->flags & PVR_TEXFLAGS_INDEX_LOOKUP || 187bf215546Sopenharmony_ci info->flags & PVR_TEXFLAGS_BUFFER) 188bf215546Sopenharmony_ci word1.index_lookup = true; 189bf215546Sopenharmony_ci } 190bf215546Sopenharmony_ci 191bf215546Sopenharmony_ci if (info->flags & PVR_TEXFLAGS_BUFFER) 192bf215546Sopenharmony_ci word1.mipmaps_present = false; 193bf215546Sopenharmony_ci 194bf215546Sopenharmony_ci if (info->flags & PVR_TEXFLAGS_BORDER) 195bf215546Sopenharmony_ci word1.border = true; 196bf215546Sopenharmony_ci 197bf215546Sopenharmony_ci if (vk_format_is_alpha_on_msb(info->format)) 198bf215546Sopenharmony_ci word1.alpha_msb = true; 199bf215546Sopenharmony_ci 200bf215546Sopenharmony_ci if (PVR_HAS_FEATURE(dev_info, tpu_image_state_v2) && 201bf215546Sopenharmony_ci vk_format_is_compressed(info->format)) 202bf215546Sopenharmony_ci word1.tpu_image_state_v2_compression_mode = 203bf215546Sopenharmony_ci PVRX(TEXSTATE_COMPRESSION_MODE_TPU); 204bf215546Sopenharmony_ci } 205bf215546Sopenharmony_ci } 206bf215546Sopenharmony_ci 207bf215546Sopenharmony_ci return VK_SUCCESS; 208bf215546Sopenharmony_ci} 209