Path: blob/21.2-virgl/src/broadcom/vulkan/v3dvx_image.c
4560 views
/*1* Copyright © 2021 Raspberry Pi2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223#include "v3dv_private.h"24#include "broadcom/common/v3d_macros.h"25#include "broadcom/cle/v3dx_pack.h"26#include "broadcom/compiler/v3d_compiler.h"2728#include "vk_format_info.h"2930/*31* This method translates pipe_swizzle to the swizzle values used at the32* packet TEXTURE_SHADER_STATE33*34* FIXME: C&P from v3d, common place?35*/36static uint32_t37translate_swizzle(unsigned char pipe_swizzle)38{39switch (pipe_swizzle) {40case PIPE_SWIZZLE_0:41return 0;42case PIPE_SWIZZLE_1:43return 1;44case PIPE_SWIZZLE_X:45case PIPE_SWIZZLE_Y:46case PIPE_SWIZZLE_Z:47case PIPE_SWIZZLE_W:48return 2 + pipe_swizzle;49default:50unreachable("unknown swizzle");51}52}5354/*55* Packs and ensure bo for the shader state (the latter can be temporal).56*/57static void58pack_texture_shader_state_helper(struct v3dv_device *device,59struct v3dv_image_view *image_view,60bool for_cube_map_array_storage)61{62assert(!for_cube_map_array_storage ||63image_view->type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY);64const uint32_t index = for_cube_map_array_storage ? 1 : 0;6566assert(image_view->image);67const struct v3dv_image *image = image_view->image;6869assert(image->samples == VK_SAMPLE_COUNT_1_BIT ||70image->samples == VK_SAMPLE_COUNT_4_BIT);71const uint32_t msaa_scale = image->samples == VK_SAMPLE_COUNT_1_BIT ? 1 : 2;7273v3dvx_pack(image_view->texture_shader_state[index], TEXTURE_SHADER_STATE, tex) {7475tex.level_0_is_strictly_uif =76(image->slices[0].tiling == V3D_TILING_UIF_XOR ||77image->slices[0].tiling == V3D_TILING_UIF_NO_XOR);7879tex.level_0_xor_enable = (image->slices[0].tiling == V3D_TILING_UIF_XOR);8081if (tex.level_0_is_strictly_uif)82tex.level_0_ub_pad = image->slices[0].ub_pad;8384/* FIXME: v3d never sets uif_xor_disable, but uses it on the following85* check so let's set the default value86*/87tex.uif_xor_disable = false;88if (tex.uif_xor_disable ||89tex.level_0_is_strictly_uif) {90tex.extended = true;91}9293tex.base_level = image_view->base_level;94tex.max_level = image_view->max_level;9596tex.swizzle_r = translate_swizzle(image_view->swizzle[0]);97tex.swizzle_g = translate_swizzle(image_view->swizzle[1]);98tex.swizzle_b = translate_swizzle(image_view->swizzle[2]);99tex.swizzle_a = translate_swizzle(image_view->swizzle[3]);100101tex.texture_type = image_view->format->tex_type;102103if (image->type == VK_IMAGE_TYPE_3D) {104tex.image_depth = image->extent.depth;105} else {106tex.image_depth = (image_view->last_layer - image_view->first_layer) + 1;107}108109/* Empirical testing with CTS shows that when we are sampling from cube110* arrays we want to set image depth to layers / 6, but not when doing111* image load/store.112*/113if (image_view->type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY &&114!for_cube_map_array_storage) {115assert(tex.image_depth % 6 == 0);116tex.image_depth /= 6;117}118119tex.image_height = image->extent.height * msaa_scale;120tex.image_width = image->extent.width * msaa_scale;121122/* On 4.x, the height of a 1D texture is redefined to be the123* upper 14 bits of the width (which is only usable with txf).124*/125if (image->type == VK_IMAGE_TYPE_1D) {126tex.image_height = tex.image_width >> 14;127}128tex.image_width &= (1 << 14) - 1;129tex.image_height &= (1 << 14) - 1;130131tex.array_stride_64_byte_aligned = image->cube_map_stride / 64;132133tex.srgb = vk_format_is_srgb(image_view->vk_format);134135/* At this point we don't have the job. That's the reason the first136* parameter is NULL, to avoid a crash when cl_pack_emit_reloc tries to137* add the bo to the job. This also means that we need to add manually138* the image bo to the job using the texture.139*/140const uint32_t base_offset =141image->mem->bo->offset +142v3dv_layer_offset(image, 0, image_view->first_layer);143tex.texture_base_pointer = v3dv_cl_address(NULL, base_offset);144}145}146147void148v3dX(pack_texture_shader_state)(struct v3dv_device *device,149struct v3dv_image_view *iview)150{151pack_texture_shader_state_helper(device, iview, false);152if (iview->type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)153pack_texture_shader_state_helper(device, iview, true);154}155156void157v3dX(pack_texture_shader_state_from_buffer_view)(struct v3dv_device *device,158struct v3dv_buffer_view *buffer_view)159{160assert(buffer_view->buffer);161const struct v3dv_buffer *buffer = buffer_view->buffer;162163v3dvx_pack(buffer_view->texture_shader_state, TEXTURE_SHADER_STATE, tex) {164tex.swizzle_r = translate_swizzle(PIPE_SWIZZLE_X);165tex.swizzle_g = translate_swizzle(PIPE_SWIZZLE_Y);166tex.swizzle_b = translate_swizzle(PIPE_SWIZZLE_Z);167tex.swizzle_a = translate_swizzle(PIPE_SWIZZLE_W);168169tex.image_depth = 1;170171/* On 4.x, the height of a 1D texture is redefined to be the upper 14172* bits of the width (which is only usable with txf) (or in other words,173* we are providing a 28 bit field for size, but split on the usual174* 14bit height/width).175*/176tex.image_width = buffer_view->num_elements;177tex.image_height = tex.image_width >> 14;178tex.image_width &= (1 << 14) - 1;179tex.image_height &= (1 << 14) - 1;180181tex.texture_type = buffer_view->format->tex_type;182tex.srgb = vk_format_is_srgb(buffer_view->vk_format);183184/* At this point we don't have the job. That's the reason the first185* parameter is NULL, to avoid a crash when cl_pack_emit_reloc tries to186* add the bo to the job. This also means that we need to add manually187* the image bo to the job using the texture.188*/189const uint32_t base_offset =190buffer->mem->bo->offset +191buffer->mem_offset +192buffer_view->offset;193194tex.texture_base_pointer = v3dv_cl_address(NULL, base_offset);195}196}197198199