Path: blob/21.2-virgl/src/broadcom/vulkan/v3dvx_device.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"2425#include "broadcom/common/v3d_macros.h"26#include "broadcom/cle/v3dx_pack.h"27#include "broadcom/compiler/v3d_compiler.h"28#include "vk_format_info.h"29#include "util/u_pack_color.h"3031static const enum V3DX(Wrap_Mode) vk_to_v3d_wrap_mode[] = {32[VK_SAMPLER_ADDRESS_MODE_REPEAT] = V3D_WRAP_MODE_REPEAT,33[VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT] = V3D_WRAP_MODE_MIRROR,34[VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE] = V3D_WRAP_MODE_CLAMP,35[VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE] = V3D_WRAP_MODE_MIRROR_ONCE,36[VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER] = V3D_WRAP_MODE_BORDER,37};3839static const enum V3DX(Compare_Function)40vk_to_v3d_compare_func[] = {41[VK_COMPARE_OP_NEVER] = V3D_COMPARE_FUNC_NEVER,42[VK_COMPARE_OP_LESS] = V3D_COMPARE_FUNC_LESS,43[VK_COMPARE_OP_EQUAL] = V3D_COMPARE_FUNC_EQUAL,44[VK_COMPARE_OP_LESS_OR_EQUAL] = V3D_COMPARE_FUNC_LEQUAL,45[VK_COMPARE_OP_GREATER] = V3D_COMPARE_FUNC_GREATER,46[VK_COMPARE_OP_NOT_EQUAL] = V3D_COMPARE_FUNC_NOTEQUAL,47[VK_COMPARE_OP_GREATER_OR_EQUAL] = V3D_COMPARE_FUNC_GEQUAL,48[VK_COMPARE_OP_ALWAYS] = V3D_COMPARE_FUNC_ALWAYS,49};5051void52v3dX(pack_sampler_state)(struct v3dv_sampler *sampler,53const VkSamplerCreateInfo *pCreateInfo)54{55enum V3DX(Border_Color_Mode) border_color_mode;5657/* For now we only support the preset Vulkan border color modes. If we58* want to implement VK_EXT_custom_border_color in the future we would have59* to use V3D_BORDER_COLOR_FOLLOWS, and fill up border_color_word_[0/1/2/3]60* SAMPLER_STATE.61*/62switch (pCreateInfo->borderColor) {63case VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK:64case VK_BORDER_COLOR_INT_TRANSPARENT_BLACK:65border_color_mode = V3D_BORDER_COLOR_0000;66break;67case VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK:68case VK_BORDER_COLOR_INT_OPAQUE_BLACK:69border_color_mode = V3D_BORDER_COLOR_0001;70break;71case VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE:72case VK_BORDER_COLOR_INT_OPAQUE_WHITE:73border_color_mode = V3D_BORDER_COLOR_1111;74break;75default:76unreachable("Unknown border color");77break;78}7980/* For some texture formats, when clamping to transparent black border the81* CTS expects alpha to be set to 1 instead of 0, but the border color mode82* will take priority over the texture state swizzle, so the only way to83* fix that is to apply a swizzle in the shader. Here we keep track of84* whether we are activating that mode and we will decide if we need to85* activate the texture swizzle lowering in the shader key at compile time86* depending on the actual texture format.87*/88if ((pCreateInfo->addressModeU == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER ||89pCreateInfo->addressModeV == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER ||90pCreateInfo->addressModeW == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER) &&91border_color_mode == V3D_BORDER_COLOR_0000) {92sampler->clamp_to_transparent_black_border = true;93}9495v3dvx_pack(sampler->sampler_state, SAMPLER_STATE, s) {96if (pCreateInfo->anisotropyEnable) {97s.anisotropy_enable = true;98if (pCreateInfo->maxAnisotropy > 8)99s.maximum_anisotropy = 3;100else if (pCreateInfo->maxAnisotropy > 4)101s.maximum_anisotropy = 2;102else if (pCreateInfo->maxAnisotropy > 2)103s.maximum_anisotropy = 1;104}105106s.border_color_mode = border_color_mode;107108s.wrap_i_border = false; /* Also hardcoded on v3d */109s.wrap_s = vk_to_v3d_wrap_mode[pCreateInfo->addressModeU];110s.wrap_t = vk_to_v3d_wrap_mode[pCreateInfo->addressModeV];111s.wrap_r = vk_to_v3d_wrap_mode[pCreateInfo->addressModeW];112s.fixed_bias = pCreateInfo->mipLodBias;113s.max_level_of_detail = MIN2(MAX2(0, pCreateInfo->maxLod), 15);114s.min_level_of_detail = MIN2(MAX2(0, pCreateInfo->minLod), 15);115s.srgb_disable = 0; /* Not even set by v3d */116s.depth_compare_function =117vk_to_v3d_compare_func[pCreateInfo->compareEnable ?118pCreateInfo->compareOp : VK_COMPARE_OP_NEVER];119s.mip_filter_nearest = pCreateInfo->mipmapMode == VK_SAMPLER_MIPMAP_MODE_NEAREST;120s.min_filter_nearest = pCreateInfo->minFilter == VK_FILTER_NEAREST;121s.mag_filter_nearest = pCreateInfo->magFilter == VK_FILTER_NEAREST;122}123}124125/**126* This computes the maximum bpp used by any of the render targets used by127* a particular subpass and checks if any of those render targets are128* multisampled. If we don't have a subpass (when we are not inside a129* render pass), then we assume that all framebuffer attachments are used.130*/131void132v3dX(framebuffer_compute_internal_bpp_msaa)(133const struct v3dv_framebuffer *framebuffer,134const struct v3dv_subpass *subpass,135uint8_t *max_bpp,136bool *msaa)137{138STATIC_ASSERT(RENDER_TARGET_MAXIMUM_32BPP == 0);139*max_bpp = RENDER_TARGET_MAXIMUM_32BPP;140*msaa = false;141142if (subpass) {143for (uint32_t i = 0; i < subpass->color_count; i++) {144uint32_t att_idx = subpass->color_attachments[i].attachment;145if (att_idx == VK_ATTACHMENT_UNUSED)146continue;147148const struct v3dv_image_view *att = framebuffer->attachments[att_idx];149assert(att);150151if (att->aspects & VK_IMAGE_ASPECT_COLOR_BIT)152*max_bpp = MAX2(*max_bpp, att->internal_bpp);153154if (att->image->samples > VK_SAMPLE_COUNT_1_BIT)155*msaa = true;156}157158if (!*msaa && subpass->ds_attachment.attachment != VK_ATTACHMENT_UNUSED) {159const struct v3dv_image_view *att =160framebuffer->attachments[subpass->ds_attachment.attachment];161assert(att);162163if (att->image->samples > VK_SAMPLE_COUNT_1_BIT)164*msaa = true;165}166167return;168}169170assert(framebuffer->attachment_count <= 4);171for (uint32_t i = 0; i < framebuffer->attachment_count; i++) {172const struct v3dv_image_view *att = framebuffer->attachments[i];173assert(att);174175if (att->aspects & VK_IMAGE_ASPECT_COLOR_BIT)176*max_bpp = MAX2(*max_bpp, att->internal_bpp);177178if (att->image->samples > VK_SAMPLE_COUNT_1_BIT)179*msaa = true;180}181182return;183}184185uint32_t186v3dX(zs_buffer_from_aspect_bits)(VkImageAspectFlags aspects)187{188const VkImageAspectFlags zs_aspects =189VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;190const VkImageAspectFlags filtered_aspects = aspects & zs_aspects;191192if (filtered_aspects == zs_aspects)193return ZSTENCIL;194else if (filtered_aspects == VK_IMAGE_ASPECT_DEPTH_BIT)195return Z;196else if (filtered_aspects == VK_IMAGE_ASPECT_STENCIL_BIT)197return STENCIL;198else199return NONE;200}201202void203v3dX(get_hw_clear_color)(const VkClearColorValue *color,204uint32_t internal_type,205uint32_t internal_size,206uint32_t *hw_color)207{208union util_color uc;209switch (internal_type) {210case V3D_INTERNAL_TYPE_8:211util_pack_color(color->float32, PIPE_FORMAT_R8G8B8A8_UNORM, &uc);212memcpy(hw_color, uc.ui, internal_size);213break;214case V3D_INTERNAL_TYPE_8I:215case V3D_INTERNAL_TYPE_8UI:216hw_color[0] = ((color->uint32[0] & 0xff) |217(color->uint32[1] & 0xff) << 8 |218(color->uint32[2] & 0xff) << 16 |219(color->uint32[3] & 0xff) << 24);220break;221case V3D_INTERNAL_TYPE_16F:222util_pack_color(color->float32, PIPE_FORMAT_R16G16B16A16_FLOAT, &uc);223memcpy(hw_color, uc.ui, internal_size);224break;225case V3D_INTERNAL_TYPE_16I:226case V3D_INTERNAL_TYPE_16UI:227hw_color[0] = ((color->uint32[0] & 0xffff) | color->uint32[1] << 16);228hw_color[1] = ((color->uint32[2] & 0xffff) | color->uint32[3] << 16);229break;230case V3D_INTERNAL_TYPE_32F:231case V3D_INTERNAL_TYPE_32I:232case V3D_INTERNAL_TYPE_32UI:233memcpy(hw_color, color->uint32, internal_size);234break;235}236}237238#ifdef DEBUG239void240v3dX(device_check_prepacked_sizes)(void)241{242STATIC_ASSERT(V3DV_SAMPLER_STATE_LENGTH >=243cl_packet_length(SAMPLER_STATE));244STATIC_ASSERT(V3DV_TEXTURE_SHADER_STATE_LENGTH >=245cl_packet_length(TEXTURE_SHADER_STATE));246STATIC_ASSERT(V3DV_SAMPLER_STATE_LENGTH >=247cl_packet_length(SAMPLER_STATE));248STATIC_ASSERT(V3DV_BLEND_CFG_LENGTH>=249cl_packet_length(BLEND_CFG));250STATIC_ASSERT(V3DV_CFG_BITS_LENGTH>=251cl_packet_length(CFG_BITS));252STATIC_ASSERT(V3DV_GL_SHADER_STATE_RECORD_LENGTH >=253cl_packet_length(GL_SHADER_STATE_RECORD));254STATIC_ASSERT(V3DV_VCM_CACHE_SIZE_LENGTH>=255cl_packet_length(VCM_CACHE_SIZE));256STATIC_ASSERT(V3DV_GL_SHADER_STATE_ATTRIBUTE_RECORD_LENGTH >=257cl_packet_length(GL_SHADER_STATE_ATTRIBUTE_RECORD));258STATIC_ASSERT(V3DV_STENCIL_CFG_LENGTH >=259cl_packet_length(STENCIL_CFG));260}261#endif262263264