Path: blob/21.2-virgl/src/intel/isl/isl_storage_image.c
4547 views
/*1* Copyright 2015 Intel Corporation2*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 "isl_priv.h"24#include "compiler/brw_compiler.h"2526bool27isl_is_storage_image_format(enum isl_format format)28{29/* XXX: Maybe we should put this in the CSV? */3031switch (format) {32case ISL_FORMAT_R32G32B32A32_UINT:33case ISL_FORMAT_R32G32B32A32_SINT:34case ISL_FORMAT_R32G32B32A32_FLOAT:35case ISL_FORMAT_R32_UINT:36case ISL_FORMAT_R32_SINT:37case ISL_FORMAT_R32_FLOAT:38case ISL_FORMAT_R16G16B16A16_UINT:39case ISL_FORMAT_R16G16B16A16_SINT:40case ISL_FORMAT_R16G16B16A16_FLOAT:41case ISL_FORMAT_R32G32_UINT:42case ISL_FORMAT_R32G32_SINT:43case ISL_FORMAT_R32G32_FLOAT:44case ISL_FORMAT_R8G8B8A8_UINT:45case ISL_FORMAT_R8G8B8A8_SINT:46case ISL_FORMAT_R16G16_UINT:47case ISL_FORMAT_R16G16_SINT:48case ISL_FORMAT_R16G16_FLOAT:49case ISL_FORMAT_R8G8_UINT:50case ISL_FORMAT_R8G8_SINT:51case ISL_FORMAT_R16_UINT:52case ISL_FORMAT_R16_FLOAT:53case ISL_FORMAT_R16_SINT:54case ISL_FORMAT_R8_UINT:55case ISL_FORMAT_R8_SINT:56case ISL_FORMAT_R10G10B10A2_UINT:57case ISL_FORMAT_R10G10B10A2_UNORM:58case ISL_FORMAT_R11G11B10_FLOAT:59case ISL_FORMAT_R16G16B16A16_UNORM:60case ISL_FORMAT_R16G16B16A16_SNORM:61case ISL_FORMAT_R8G8B8A8_UNORM:62case ISL_FORMAT_R8G8B8A8_SNORM:63case ISL_FORMAT_R16G16_UNORM:64case ISL_FORMAT_R16G16_SNORM:65case ISL_FORMAT_R8G8_UNORM:66case ISL_FORMAT_R8G8_SNORM:67case ISL_FORMAT_R16_UNORM:68case ISL_FORMAT_R16_SNORM:69case ISL_FORMAT_R8_UNORM:70case ISL_FORMAT_R8_SNORM:71return true;72default:73return false;74}75}7677enum isl_format78isl_lower_storage_image_format(const struct intel_device_info *devinfo,79enum isl_format format)80{81switch (format) {82/* These are never lowered. Up to BDW we'll have to fall back to untyped83* surface access for 128bpp formats.84*/85case ISL_FORMAT_R32G32B32A32_UINT:86case ISL_FORMAT_R32G32B32A32_SINT:87case ISL_FORMAT_R32G32B32A32_FLOAT:88case ISL_FORMAT_R32_UINT:89case ISL_FORMAT_R32_SINT:90return format;9192/* The Skylake PRM's "Surface Formats" section says:93*94* "The surface format for the typed atomic integer operations must95* be R32_UINT or R32_SINT."96*/97case ISL_FORMAT_R32_FLOAT:98return ISL_FORMAT_R32_UINT;99100/* From HSW to BDW the only 64bpp format supported for typed access is101* RGBA_UINT16. IVB falls back to untyped.102*/103case ISL_FORMAT_R16G16B16A16_UINT:104case ISL_FORMAT_R16G16B16A16_SINT:105case ISL_FORMAT_R16G16B16A16_FLOAT:106case ISL_FORMAT_R32G32_UINT:107case ISL_FORMAT_R32G32_SINT:108case ISL_FORMAT_R32G32_FLOAT:109return (devinfo->ver >= 9 ? format :110devinfo->verx10 >= 75 ?111ISL_FORMAT_R16G16B16A16_UINT :112ISL_FORMAT_R32G32_UINT);113114/* Up to BDW no SINT or FLOAT formats of less than 32 bits per component115* are supported. IVB doesn't support formats with more than one component116* for typed access. For 8 and 16 bpp formats IVB relies on the117* undocumented behavior that typed reads from R_UINT8 and R_UINT16118* surfaces actually do a 32-bit misaligned read. The alternative would be119* to use two surface state entries with different formats for each image,120* one for reading (using R_UINT32) and another one for writing (using121* R_UINT8 or R_UINT16), but that would complicate the shaders we generate122* even more.123*/124case ISL_FORMAT_R8G8B8A8_UINT:125case ISL_FORMAT_R8G8B8A8_SINT:126return (devinfo->ver >= 9 ? format :127devinfo->verx10 >= 75 ?128ISL_FORMAT_R8G8B8A8_UINT : ISL_FORMAT_R32_UINT);129130case ISL_FORMAT_R16G16_UINT:131case ISL_FORMAT_R16G16_SINT:132case ISL_FORMAT_R16G16_FLOAT:133return (devinfo->ver >= 9 ? format :134devinfo->verx10 >= 75 ?135ISL_FORMAT_R16G16_UINT : ISL_FORMAT_R32_UINT);136137case ISL_FORMAT_R8G8_UINT:138case ISL_FORMAT_R8G8_SINT:139return (devinfo->ver >= 9 ? format :140devinfo->verx10 >= 75 ?141ISL_FORMAT_R8G8_UINT : ISL_FORMAT_R16_UINT);142143case ISL_FORMAT_R16_UINT:144case ISL_FORMAT_R16_FLOAT:145case ISL_FORMAT_R16_SINT:146return (devinfo->ver >= 9 ? format : ISL_FORMAT_R16_UINT);147148case ISL_FORMAT_R8_UINT:149case ISL_FORMAT_R8_SINT:150return (devinfo->ver >= 9 ? format : ISL_FORMAT_R8_UINT);151152/* Neither the 2/10/10/10 nor the 11/11/10 packed formats are supported153* by the hardware.154*/155case ISL_FORMAT_R10G10B10A2_UINT:156case ISL_FORMAT_R10G10B10A2_UNORM:157case ISL_FORMAT_R11G11B10_FLOAT:158return ISL_FORMAT_R32_UINT;159160/* No normalized fixed-point formats are supported by the hardware. */161case ISL_FORMAT_R16G16B16A16_UNORM:162case ISL_FORMAT_R16G16B16A16_SNORM:163return (devinfo->ver >= 11 ? format :164devinfo->verx10 >= 75 ?165ISL_FORMAT_R16G16B16A16_UINT :166ISL_FORMAT_R32G32_UINT);167168case ISL_FORMAT_R8G8B8A8_UNORM:169case ISL_FORMAT_R8G8B8A8_SNORM:170return (devinfo->ver >= 11 ? format :171devinfo->verx10 >= 75 ?172ISL_FORMAT_R8G8B8A8_UINT : ISL_FORMAT_R32_UINT);173174case ISL_FORMAT_R16G16_UNORM:175case ISL_FORMAT_R16G16_SNORM:176return (devinfo->ver >= 11 ? format :177devinfo->verx10 >= 75 ?178ISL_FORMAT_R16G16_UINT : ISL_FORMAT_R32_UINT);179180case ISL_FORMAT_R8G8_UNORM:181case ISL_FORMAT_R8G8_SNORM:182return (devinfo->ver >= 11 ? format :183devinfo->verx10 >= 75 ?184ISL_FORMAT_R8G8_UINT : ISL_FORMAT_R16_UINT);185186case ISL_FORMAT_R16_UNORM:187case ISL_FORMAT_R16_SNORM:188return (devinfo->ver >= 11 ? format : ISL_FORMAT_R16_UINT);189190case ISL_FORMAT_R8_UNORM:191case ISL_FORMAT_R8_SNORM:192return (devinfo->ver >= 11 ? format : ISL_FORMAT_R8_UINT);193194default:195assert(!"Unknown image format");196return ISL_FORMAT_UNSUPPORTED;197}198}199200bool201isl_has_matching_typed_storage_image_format(const struct intel_device_info *devinfo,202enum isl_format fmt)203{204if (devinfo->ver >= 9) {205return true;206} else if (devinfo->verx10 >= 75) {207return isl_format_get_layout(fmt)->bpb <= 64;208} else {209return isl_format_get_layout(fmt)->bpb <= 32;210}211}212213static const struct brw_image_param image_param_defaults = {214/* Set the swizzling shifts to all-ones to effectively disable215* swizzling -- See emit_address_calculation() in216* brw_fs_surface_builder.cpp for a more detailed explanation of217* these parameters.218*/219.swizzling = { 0xff, 0xff },220};221222void223isl_surf_fill_image_param(const struct isl_device *dev,224struct brw_image_param *param,225const struct isl_surf *surf,226const struct isl_view *view)227{228*param = image_param_defaults;229230if (surf->dim != ISL_SURF_DIM_3D) {231assert(view->base_array_layer + view->array_len <=232surf->logical_level0_px.array_len);233}234param->size[0] = isl_minify(surf->logical_level0_px.w, view->base_level);235param->size[1] = surf->dim == ISL_SURF_DIM_1D ?236view->array_len :237isl_minify(surf->logical_level0_px.h, view->base_level);238param->size[2] = surf->dim == ISL_SURF_DIM_2D ?239view->array_len :240isl_minify(surf->logical_level0_px.d, view->base_level);241242uint32_t tile_z_el, phys_array_layer;243isl_surf_get_image_offset_el(surf, view->base_level,244surf->dim == ISL_SURF_DIM_3D ?2450 : view->base_array_layer,246surf->dim == ISL_SURF_DIM_3D ?247view->base_array_layer : 0,248¶m->offset[0], ¶m->offset[1],249&tile_z_el, &phys_array_layer);250assert(tile_z_el == 0);251assert(phys_array_layer == 0);252253const int cpp = isl_format_get_layout(surf->format)->bpb / 8;254param->stride[0] = cpp;255param->stride[1] = surf->row_pitch_B / cpp;256257const struct isl_extent3d image_align_sa =258isl_surf_get_image_alignment_sa(surf);259if (ISL_GFX_VER(dev) < 9 && surf->dim == ISL_SURF_DIM_3D) {260param->stride[2] = isl_align_npot(param->size[0], image_align_sa.w);261param->stride[3] = isl_align_npot(param->size[1], image_align_sa.h);262} else {263param->stride[2] = 0;264param->stride[3] = isl_surf_get_array_pitch_el_rows(surf);265}266267switch (surf->tiling) {268case ISL_TILING_LINEAR:269/* image_param_defaults is good enough */270break;271272case ISL_TILING_X:273/* An X tile is a rectangular block of 512x8 bytes. */274param->tiling[0] = isl_log2u(512 / cpp);275param->tiling[1] = isl_log2u(8);276277if (dev->has_bit6_swizzling) {278/* Right shifts required to swizzle bits 9 and 10 of the memory279* address with bit 6.280*/281param->swizzling[0] = 3;282param->swizzling[1] = 4;283}284break;285286case ISL_TILING_Y0:287/* The layout of a Y-tiled surface in memory isn't really fundamentally288* different to the layout of an X-tiled surface, we simply pretend that289* the surface is broken up in a number of smaller 16Bx32 tiles, each290* one arranged in X-major order just like is the case for X-tiling.291*/292param->tiling[0] = isl_log2u(16 / cpp);293param->tiling[1] = isl_log2u(32);294295if (dev->has_bit6_swizzling) {296/* Right shift required to swizzle bit 9 of the memory address with297* bit 6.298*/299param->swizzling[0] = 3;300param->swizzling[1] = 0xff;301}302break;303304default:305assert(!"Unhandled storage image tiling");306}307308/* 3D textures are arranged in 2D in memory with 2^lod slices per row. The309* address calculation algorithm (emit_address_calculation() in310* brw_fs_surface_builder.cpp) handles this as a sort of tiling with311* modulus equal to the LOD.312*/313param->tiling[2] = (ISL_GFX_VER(dev) < 9 && surf->dim == ISL_SURF_DIM_3D ?314view->base_level : 0);315}316317void318isl_buffer_fill_image_param(const struct isl_device *dev,319struct brw_image_param *param,320enum isl_format format,321uint64_t size)322{323*param = image_param_defaults;324325param->stride[0] = isl_format_get_layout(format)->bpb / 8;326param->size[0] = size / param->stride[0];327}328329330