1b8e80941Smrg/* 2b8e80941Smrg * Copyright 2015 Intel Corporation 3b8e80941Smrg * 4b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5b8e80941Smrg * copy of this software and associated documentation files (the "Software"), 6b8e80941Smrg * to deal in the Software without restriction, including without limitation 7b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the 9b8e80941Smrg * Software is furnished to do so, subject to the following conditions: 10b8e80941Smrg * 11b8e80941Smrg * The above copyright notice and this permission notice (including the next 12b8e80941Smrg * paragraph) shall be included in all copies or substantial portions of the 13b8e80941Smrg * Software. 14b8e80941Smrg * 15b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16b8e80941Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19b8e80941Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20b8e80941Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21b8e80941Smrg * IN THE SOFTWARE. 22b8e80941Smrg */ 23b8e80941Smrg 24b8e80941Smrg#include <assert.h> 25b8e80941Smrg 26b8e80941Smrg#include "isl.h" 27b8e80941Smrg#include "isl_priv.h" 28b8e80941Smrg#include "dev/gen_device_info.h" 29b8e80941Smrg 30b8e80941Smrg#include "main/macros.h" /* Needed for MAX3 and MAX2 for format_rgb9e5 */ 31b8e80941Smrg#include "util/format_srgb.h" 32b8e80941Smrg#include "util/format_rgb9e5.h" 33b8e80941Smrg#include "util/format_r11g11b10f.h" 34b8e80941Smrg 35b8e80941Smrg/* Header-only format conversion include */ 36b8e80941Smrg#include "main/format_utils.h" 37b8e80941Smrg 38b8e80941Smrgstruct surface_format_info { 39b8e80941Smrg bool exists; 40b8e80941Smrg uint8_t sampling; 41b8e80941Smrg uint8_t filtering; 42b8e80941Smrg uint8_t shadow_compare; 43b8e80941Smrg uint8_t chroma_key; 44b8e80941Smrg uint8_t render_target; 45b8e80941Smrg uint8_t alpha_blend; 46b8e80941Smrg uint8_t input_vb; 47b8e80941Smrg uint8_t streamed_output_vb; 48b8e80941Smrg uint8_t color_processing; 49b8e80941Smrg uint8_t typed_write; 50b8e80941Smrg uint8_t typed_read; 51b8e80941Smrg uint8_t ccs_e; 52b8e80941Smrg}; 53b8e80941Smrg 54b8e80941Smrg/* This macro allows us to write the table almost as it appears in the PRM, 55b8e80941Smrg * while restructuring it to turn it into the C code we want. 56b8e80941Smrg */ 57b8e80941Smrg#define SF(sampl, filt, shad, ck, rt, ab, vb, so, color, tw, tr, ccs_e, sf) \ 58b8e80941Smrg [ISL_FORMAT_##sf] = { true, sampl, filt, shad, ck, rt, ab, vb, so, color, tw, tr, ccs_e}, 59b8e80941Smrg 60b8e80941Smrg#define Y 0 61b8e80941Smrg#define x 255 62b8e80941Smrg/** 63b8e80941Smrg * This is the table of support for surface (texture, renderbuffer, and vertex 64b8e80941Smrg * buffer, but not depthbuffer) formats across the various hardware generations. 65b8e80941Smrg * 66b8e80941Smrg * The table is formatted to match the documentation, except that the docs have 67b8e80941Smrg * this ridiculous mapping of Y[*+~^#&] for "supported on DevWhatever". To put 68b8e80941Smrg * it in our table, here's the mapping: 69b8e80941Smrg * 70b8e80941Smrg * Y*: 45 71b8e80941Smrg * Y+: 45 (g45/gm45) 72b8e80941Smrg * Y~: 50 (gen5) 73b8e80941Smrg * Y^: 60 (gen6) 74b8e80941Smrg * Y#: 70 (gen7) 75b8e80941Smrg * 76b8e80941Smrg * The abbreviations in the header below are: 77b8e80941Smrg * smpl - Sampling Engine 78b8e80941Smrg * filt - Sampling Engine Filtering 79b8e80941Smrg * shad - Sampling Engine Shadow Map 80b8e80941Smrg * CK - Sampling Engine Chroma Key 81b8e80941Smrg * RT - Render Target 82b8e80941Smrg * AB - Alpha Blend Render Target 83b8e80941Smrg * VB - Input Vertex Buffer 84b8e80941Smrg * SO - Steamed Output Vertex Buffers (transform feedback) 85b8e80941Smrg * color - Color Processing 86b8e80941Smrg * ccs_e - Lossless Compression Support (gen9+ only) 87b8e80941Smrg * sf - Surface Format 88b8e80941Smrg * 89b8e80941Smrg * See page 88 of the Sandybridge PRM VOL4_Part1 PDF. 90b8e80941Smrg * 91b8e80941Smrg * As of Ivybridge, the columns are no longer in that table and the 92b8e80941Smrg * information can be found spread across: 93b8e80941Smrg * 94b8e80941Smrg * - VOL2_Part1 section 2.5.11 Format Conversion (vertex fetch). 95b8e80941Smrg * - VOL4_Part1 section 2.12.2.1.2 Sampler Output Channel Mapping. 96b8e80941Smrg * - VOL4_Part1 section 3.9.11 Render Target Write. 97b8e80941Smrg * - Render Target Surface Types [SKL+] 98b8e80941Smrg */ 99b8e80941Smrgstatic const struct surface_format_info format_info[] = { 100b8e80941Smrg/* smpl filt shad CK RT AB VB SO color TW TR ccs_e */ 101b8e80941Smrg SF( Y, 50, x, x, Y, Y, Y, Y, x, 70, 90, 90, R32G32B32A32_FLOAT) 102b8e80941Smrg SF( Y, x, x, x, Y, x, Y, Y, x, 70, 90, 90, R32G32B32A32_SINT) 103b8e80941Smrg SF( Y, x, x, x, Y, x, Y, Y, x, 70, 90, 90, R32G32B32A32_UINT) 104b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R32G32B32A32_UNORM) 105b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R32G32B32A32_SNORM) 106b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R64G64_FLOAT) 107b8e80941Smrg SF( Y, 50, x, x, 100, 100, x, x, x, x, x, 100, R32G32B32X32_FLOAT) 108b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R32G32B32A32_SSCALED) 109b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R32G32B32A32_USCALED) 110b8e80941Smrg SF( x, x, x, x, x, x, 75, x, x, x, x, x, R32G32B32A32_SFIXED) 111b8e80941Smrg SF( x, x, x, x, x, x, 80, x, x, x, x, x, R64G64_PASSTHRU) 112b8e80941Smrg SF( Y, 50, x, x, x, x, Y, Y, x, x, x, x, R32G32B32_FLOAT) 113b8e80941Smrg SF( Y, x, x, x, x, x, Y, Y, x, x, x, x, R32G32B32_SINT) 114b8e80941Smrg SF( Y, x, x, x, x, x, Y, Y, x, x, x, x, R32G32B32_UINT) 115b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R32G32B32_UNORM) 116b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R32G32B32_SNORM) 117b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R32G32B32_SSCALED) 118b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R32G32B32_USCALED) 119b8e80941Smrg SF( x, x, x, x, x, x, 75, x, x, x, x, x, R32G32B32_SFIXED) 120b8e80941Smrg SF( Y, Y, x, x, Y, 45, Y, x, 60, 70, 110, 90, R16G16B16A16_UNORM) 121b8e80941Smrg SF( Y, Y, x, x, Y, 60, Y, x, x, 70, 110, 90, R16G16B16A16_SNORM) 122b8e80941Smrg SF( Y, x, x, x, Y, x, Y, x, x, 70, 90, 90, R16G16B16A16_SINT) 123b8e80941Smrg SF( Y, x, x, x, Y, x, Y, x, x, 70, 75, 90, R16G16B16A16_UINT) 124b8e80941Smrg SF( Y, Y, x, x, Y, Y, Y, x, x, 70, 90, 90, R16G16B16A16_FLOAT) 125b8e80941Smrg SF( Y, 50, x, x, Y, Y, Y, Y, x, 70, 90, 90, R32G32_FLOAT) 126b8e80941Smrg SF( Y, 70, x, x, Y, Y, Y, Y, x, x, x, x, R32G32_FLOAT_LD) 127b8e80941Smrg SF( Y, x, x, x, Y, x, Y, Y, x, 70, 90, 90, R32G32_SINT) 128b8e80941Smrg SF( Y, x, x, x, Y, x, Y, Y, x, 70, 90, 90, R32G32_UINT) 129b8e80941Smrg SF( Y, 50, Y, x, x, x, x, x, x, x, x, x, R32_FLOAT_X8X24_TYPELESS) 130b8e80941Smrg SF( Y, x, x, x, x, x, x, x, x, x, x, x, X32_TYPELESS_G8X24_UINT) 131b8e80941Smrg SF( Y, 50, x, x, x, x, x, x, x, x, x, x, L32A32_FLOAT) 132b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R32G32_UNORM) 133b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R32G32_SNORM) 134b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R64_FLOAT) 135b8e80941Smrg SF( Y, Y, x, x, x, x, x, x, x, x, x, x, R16G16B16X16_UNORM) 136b8e80941Smrg SF( Y, Y, x, x, 90, 90, x, x, x, x, x, 90, R16G16B16X16_FLOAT) 137b8e80941Smrg SF( Y, 50, x, x, x, x, x, x, x, x, x, x, A32X32_FLOAT) 138b8e80941Smrg SF( Y, 50, x, x, x, x, x, x, x, x, x, x, L32X32_FLOAT) 139b8e80941Smrg SF( Y, 50, x, x, x, x, x, x, x, x, x, x, I32X32_FLOAT) 140b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R16G16B16A16_SSCALED) 141b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R16G16B16A16_USCALED) 142b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R32G32_SSCALED) 143b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R32G32_USCALED) 144b8e80941Smrg SF( x, x, x, x, x, x, 75, x, x, x, x, x, R32G32_SFIXED) 145b8e80941Smrg SF( x, x, x, x, x, x, 80, x, x, x, x, x, R64_PASSTHRU) 146b8e80941Smrg SF( Y, Y, x, Y, Y, Y, Y, x, 60, 70, x, 90, B8G8R8A8_UNORM) 147b8e80941Smrg SF( Y, Y, x, x, Y, Y, x, x, x, x, x, 100, B8G8R8A8_UNORM_SRGB) 148b8e80941Smrg/* smpl filt shad CK RT AB VB SO color TW TR ccs_e */ 149b8e80941Smrg SF( Y, Y, x, x, Y, Y, Y, x, 60, 70, x, 100, R10G10B10A2_UNORM) 150b8e80941Smrg SF( Y, Y, x, x, x, x, x, x, 60, x, x, x, R10G10B10A2_UNORM_SRGB) 151b8e80941Smrg SF( Y, x, x, x, Y, x, Y, x, x, 70, x, 100, R10G10B10A2_UINT) 152b8e80941Smrg SF( Y, Y, x, x, x, x, Y, x, x, x, x, x, R10G10B10_SNORM_A2_UNORM) 153b8e80941Smrg SF( Y, Y, x, x, Y, Y, Y, x, 60, 70, 110, 90, R8G8B8A8_UNORM) 154b8e80941Smrg SF( Y, Y, x, x, Y, Y, x, x, 60, x, x, 100, R8G8B8A8_UNORM_SRGB) 155b8e80941Smrg SF( Y, Y, x, x, Y, 60, Y, x, x, 70, 110, 90, R8G8B8A8_SNORM) 156b8e80941Smrg SF( Y, x, x, x, Y, x, Y, x, x, 70, 90, 90, R8G8B8A8_SINT) 157b8e80941Smrg SF( Y, x, x, x, Y, x, Y, x, x, 70, 75, 90, R8G8B8A8_UINT) 158b8e80941Smrg SF( Y, Y, x, x, Y, 45, Y, x, x, 70, 110, 90, R16G16_UNORM) 159b8e80941Smrg SF( Y, Y, x, x, Y, 60, Y, x, x, 70, 110, 90, R16G16_SNORM) 160b8e80941Smrg SF( Y, x, x, x, Y, x, Y, x, x, 70, 90, 90, R16G16_SINT) 161b8e80941Smrg SF( Y, x, x, x, Y, x, Y, x, x, 70, 75, 90, R16G16_UINT) 162b8e80941Smrg SF( Y, Y, x, x, Y, Y, Y, x, x, 70, 90, 90, R16G16_FLOAT) 163b8e80941Smrg SF( Y, Y, x, x, Y, Y, 75, x, 60, 70, x, 100, B10G10R10A2_UNORM) 164b8e80941Smrg SF( Y, Y, x, x, Y, Y, x, x, 60, x, x, 100, B10G10R10A2_UNORM_SRGB) 165b8e80941Smrg SF( Y, Y, x, x, Y, Y, Y, x, x, 70, x, 100, R11G11B10_FLOAT) 166b8e80941Smrg SF( Y, x, x, x, Y, x, Y, Y, x, 70, 70, 90, R32_SINT) 167b8e80941Smrg SF( Y, x, x, x, Y, x, Y, Y, x, 70, 70, 90, R32_UINT) 168b8e80941Smrg SF( Y, 50, Y, x, Y, Y, Y, Y, x, 70, 70, 90, R32_FLOAT) 169b8e80941Smrg SF( Y, 50, Y, x, x, x, x, x, x, x, x, x, R24_UNORM_X8_TYPELESS) 170b8e80941Smrg SF( Y, x, x, x, x, x, x, x, x, x, x, x, X24_TYPELESS_G8_UINT) 171b8e80941Smrg SF( Y, Y, x, x, x, x, x, x, x, x, x, x, L16A16_UNORM) 172b8e80941Smrg SF( Y, 50, Y, x, x, x, x, x, x, x, x, x, I24X8_UNORM) 173b8e80941Smrg SF( Y, 50, Y, x, x, x, x, x, x, x, x, x, L24X8_UNORM) 174b8e80941Smrg SF( Y, 50, Y, x, x, x, x, x, x, x, x, x, A24X8_UNORM) 175b8e80941Smrg SF( Y, 50, Y, x, x, x, x, x, x, x, x, x, I32_FLOAT) 176b8e80941Smrg SF( Y, 50, Y, x, x, x, x, x, x, x, x, x, L32_FLOAT) 177b8e80941Smrg SF( Y, 50, Y, x, x, x, x, x, x, x, x, x, A32_FLOAT) 178b8e80941Smrg SF( Y, Y, x, Y, 80, 80, x, x, 60, x, x, 90, B8G8R8X8_UNORM) 179b8e80941Smrg SF( Y, Y, x, x, 80, 80, x, x, x, x, x, 100, B8G8R8X8_UNORM_SRGB) 180b8e80941Smrg SF( Y, Y, x, x, x, x, x, x, x, x, x, x, R8G8B8X8_UNORM) 181b8e80941Smrg SF( Y, Y, x, x, x, x, x, x, x, x, x, x, R8G8B8X8_UNORM_SRGB) 182b8e80941Smrg SF( Y, Y, x, x, x, x, x, x, x, x, x, x, R9G9B9E5_SHAREDEXP) 183b8e80941Smrg SF( Y, Y, x, x, x, x, x, x, x, x, x, x, B10G10R10X2_UNORM) 184b8e80941Smrg SF( Y, Y, x, x, x, x, x, x, x, x, x, x, L16A16_FLOAT) 185b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R32_UNORM) 186b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R32_SNORM) 187b8e80941Smrg/* smpl filt shad CK RT AB VB SO color TW TR ccs_e */ 188b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R10G10B10X2_USCALED) 189b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R8G8B8A8_SSCALED) 190b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R8G8B8A8_USCALED) 191b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R16G16_SSCALED) 192b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R16G16_USCALED) 193b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R32_SSCALED) 194b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R32_USCALED) 195b8e80941Smrg SF( Y, Y, x, Y, Y, Y, x, x, x, 70, x, x, B5G6R5_UNORM) 196b8e80941Smrg SF( Y, Y, x, x, Y, Y, x, x, x, x, x, x, B5G6R5_UNORM_SRGB) 197b8e80941Smrg SF( Y, Y, x, Y, Y, Y, x, x, x, 70, x, x, B5G5R5A1_UNORM) 198b8e80941Smrg SF( Y, Y, x, x, Y, Y, x, x, x, x, x, x, B5G5R5A1_UNORM_SRGB) 199b8e80941Smrg SF( Y, Y, x, Y, Y, Y, x, x, x, 70, x, x, B4G4R4A4_UNORM) 200b8e80941Smrg SF( Y, Y, x, x, Y, Y, x, x, x, x, x, x, B4G4R4A4_UNORM_SRGB) 201b8e80941Smrg SF( Y, Y, x, x, Y, Y, Y, x, x, 70, 110, x, R8G8_UNORM) 202b8e80941Smrg SF( Y, Y, x, Y, Y, 60, Y, x, x, 70, 110, x, R8G8_SNORM) 203b8e80941Smrg SF( Y, x, x, x, Y, x, Y, x, x, 70, 90, x, R8G8_SINT) 204b8e80941Smrg SF( Y, x, x, x, Y, x, Y, x, x, 70, 75, x, R8G8_UINT) 205b8e80941Smrg SF( Y, Y, Y, x, Y, 45, Y, x, 70, 70, 110, x, R16_UNORM) 206b8e80941Smrg SF( Y, Y, x, x, Y, 60, Y, x, x, 70, 110, x, R16_SNORM) 207b8e80941Smrg SF( Y, x, x, x, Y, x, Y, x, x, 70, 90, x, R16_SINT) 208b8e80941Smrg SF( Y, x, x, x, Y, x, Y, x, x, 70, 75, x, R16_UINT) 209b8e80941Smrg SF( Y, Y, x, x, Y, Y, Y, x, x, 70, 90, x, R16_FLOAT) 210b8e80941Smrg SF( 50, 50, x, x, x, x, x, x, x, x, x, x, A8P8_UNORM_PALETTE0) 211b8e80941Smrg SF( 50, 50, x, x, x, x, x, x, x, x, x, x, A8P8_UNORM_PALETTE1) 212b8e80941Smrg SF( Y, Y, Y, x, x, x, x, x, x, x, x, x, I16_UNORM) 213b8e80941Smrg SF( Y, Y, Y, x, x, x, x, x, x, x, x, x, L16_UNORM) 214b8e80941Smrg SF( Y, Y, Y, x, x, x, x, x, x, x, x, x, A16_UNORM) 215b8e80941Smrg SF( Y, Y, x, Y, x, x, x, x, x, x, x, x, L8A8_UNORM) 216b8e80941Smrg SF( Y, Y, Y, x, x, x, x, x, x, x, x, x, I16_FLOAT) 217b8e80941Smrg SF( Y, Y, Y, x, x, x, x, x, x, x, x, x, L16_FLOAT) 218b8e80941Smrg SF( Y, Y, Y, x, x, x, x, x, x, x, x, x, A16_FLOAT) 219b8e80941Smrg SF( 45, 45, x, x, x, x, x, x, x, x, x, x, L8A8_UNORM_SRGB) 220b8e80941Smrg SF( Y, Y, x, Y, x, x, x, x, x, x, x, x, R5G5_SNORM_B6_UNORM) 221b8e80941Smrg SF( x, x, x, x, Y, Y, x, x, x, 70, x, x, B5G5R5X1_UNORM) 222b8e80941Smrg SF( x, x, x, x, Y, Y, x, x, x, x, x, x, B5G5R5X1_UNORM_SRGB) 223b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R8G8_SSCALED) 224b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R8G8_USCALED) 225b8e80941Smrg/* smpl filt shad CK RT AB VB SO color TW TR ccs_e */ 226b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R16_SSCALED) 227b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R16_USCALED) 228b8e80941Smrg SF( 50, 50, x, x, x, x, x, x, x, x, x, x, P8A8_UNORM_PALETTE0) 229b8e80941Smrg SF( 50, 50, x, x, x, x, x, x, x, x, x, x, P8A8_UNORM_PALETTE1) 230b8e80941Smrg SF( x, x, x, x, x, x, x, x, x, x, x, x, A1B5G5R5_UNORM) 231b8e80941Smrg /* According to the PRM, A4B4G4R4_UNORM isn't supported until Sky Lake 232b8e80941Smrg * but empirical testing indicates that at least sampling works just fine 233b8e80941Smrg * on Broadwell. 234b8e80941Smrg */ 235b8e80941Smrg SF( 80, 80, x, x, 90, x, x, x, x, x, x, x, A4B4G4R4_UNORM) 236b8e80941Smrg SF( 90, x, x, x, x, x, x, x, x, x, x, x, L8A8_UINT) 237b8e80941Smrg SF( 90, x, x, x, x, x, x, x, x, x, x, x, L8A8_SINT) 238b8e80941Smrg SF( Y, Y, x, 45, Y, Y, Y, x, x, 70, 110, x, R8_UNORM) 239b8e80941Smrg SF( Y, Y, x, x, Y, 60, Y, x, x, 70, 110, x, R8_SNORM) 240b8e80941Smrg SF( Y, x, x, x, Y, x, Y, x, x, 70, 90, x, R8_SINT) 241b8e80941Smrg SF( Y, x, x, x, Y, x, Y, x, x, 70, 75, x, R8_UINT) 242b8e80941Smrg SF( Y, Y, x, Y, Y, Y, x, x, x, 70, 110, x, A8_UNORM) 243b8e80941Smrg SF( Y, Y, x, x, x, x, x, x, x, x, x, x, I8_UNORM) 244b8e80941Smrg SF( Y, Y, x, Y, x, x, x, x, x, x, x, x, L8_UNORM) 245b8e80941Smrg SF( Y, Y, x, x, x, x, x, x, x, x, x, x, P4A4_UNORM_PALETTE0) 246b8e80941Smrg SF( Y, Y, x, x, x, x, x, x, x, x, x, x, A4P4_UNORM_PALETTE0) 247b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R8_SSCALED) 248b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R8_USCALED) 249b8e80941Smrg SF( 45, 45, x, x, x, x, x, x, x, x, x, x, P8_UNORM_PALETTE0) 250b8e80941Smrg SF( 45, 45, x, x, x, x, x, x, x, x, x, x, L8_UNORM_SRGB) 251b8e80941Smrg SF( 45, 45, x, x, x, x, x, x, x, x, x, x, P8_UNORM_PALETTE1) 252b8e80941Smrg SF( 45, 45, x, x, x, x, x, x, x, x, x, x, P4A4_UNORM_PALETTE1) 253b8e80941Smrg SF( 45, 45, x, x, x, x, x, x, x, x, x, x, A4P4_UNORM_PALETTE1) 254b8e80941Smrg SF( x, x, x, x, x, x, x, x, x, x, x, x, Y8_UNORM) 255b8e80941Smrg SF( 90, x, x, x, x, x, x, x, x, x, x, x, L8_UINT) 256b8e80941Smrg SF( 90, x, x, x, x, x, x, x, x, x, x, x, L8_SINT) 257b8e80941Smrg SF( 90, x, x, x, x, x, x, x, x, x, x, x, I8_UINT) 258b8e80941Smrg SF( 90, x, x, x, x, x, x, x, x, x, x, x, I8_SINT) 259b8e80941Smrg SF( 45, 45, x, x, x, x, x, x, x, x, x, x, DXT1_RGB_SRGB) 260b8e80941Smrg SF( Y, Y, x, x, x, x, x, x, x, x, x, x, R1_UNORM) 261b8e80941Smrg SF( Y, Y, x, Y, Y, x, x, x, 60, x, x, x, YCRCB_NORMAL) 262b8e80941Smrg SF( Y, Y, x, Y, Y, x, x, x, 60, x, x, x, YCRCB_SWAPUVY) 263b8e80941Smrg SF( 45, 45, x, x, x, x, x, x, x, x, x, x, P2_UNORM_PALETTE0) 264b8e80941Smrg SF( 45, 45, x, x, x, x, x, x, x, x, x, x, P2_UNORM_PALETTE1) 265b8e80941Smrg SF( Y, Y, x, Y, x, x, x, x, x, x, x, x, BC1_UNORM) 266b8e80941Smrg SF( Y, Y, x, Y, x, x, x, x, x, x, x, x, BC2_UNORM) 267b8e80941Smrg SF( Y, Y, x, Y, x, x, x, x, x, x, x, x, BC3_UNORM) 268b8e80941Smrg SF( Y, Y, x, x, x, x, x, x, x, x, x, x, BC4_UNORM) 269b8e80941Smrg SF( Y, Y, x, x, x, x, x, x, x, x, x, x, BC5_UNORM) 270b8e80941Smrg SF( Y, Y, x, x, x, x, x, x, x, x, x, x, BC1_UNORM_SRGB) 271b8e80941Smrg SF( Y, Y, x, x, x, x, x, x, x, x, x, x, BC2_UNORM_SRGB) 272b8e80941Smrg SF( Y, Y, x, x, x, x, x, x, x, x, x, x, BC3_UNORM_SRGB) 273b8e80941Smrg SF( Y, x, x, x, x, x, x, x, x, x, x, x, MONO8) 274b8e80941Smrg SF( Y, Y, x, x, Y, x, x, x, 60, x, x, x, YCRCB_SWAPUV) 275b8e80941Smrg SF( Y, Y, x, x, Y, x, x, x, 60, x, x, x, YCRCB_SWAPY) 276b8e80941Smrg SF( Y, Y, x, x, x, x, x, x, x, x, x, x, DXT1_RGB) 277b8e80941Smrg/* smpl filt shad CK RT AB VB SO color TW TR ccs_e */ 278b8e80941Smrg SF( Y, Y, x, x, x, x, x, x, x, x, x, x, FXT1) 279b8e80941Smrg SF( 75, 75, x, x, x, x, Y, x, x, x, x, x, R8G8B8_UNORM) 280b8e80941Smrg SF( 75, 75, x, x, x, x, Y, x, x, x, x, x, R8G8B8_SNORM) 281b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R8G8B8_SSCALED) 282b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R8G8B8_USCALED) 283b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R64G64B64A64_FLOAT) 284b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R64G64B64_FLOAT) 285b8e80941Smrg SF( Y, Y, x, x, x, x, x, x, x, x, x, x, BC4_SNORM) 286b8e80941Smrg SF( Y, Y, x, x, x, x, x, x, x, x, x, x, BC5_SNORM) 287b8e80941Smrg SF( 50, 50, x, x, x, x, 60, x, x, x, x, x, R16G16B16_FLOAT) 288b8e80941Smrg SF( 75, 75, x, x, x, x, Y, x, x, x, x, x, R16G16B16_UNORM) 289b8e80941Smrg SF( 75, 75, x, x, x, x, Y, x, x, x, x, x, R16G16B16_SNORM) 290b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R16G16B16_SSCALED) 291b8e80941Smrg SF( x, x, x, x, x, x, Y, x, x, x, x, x, R16G16B16_USCALED) 292b8e80941Smrg SF( 70, 70, x, x, x, x, x, x, x, x, x, x, BC6H_SF16) 293b8e80941Smrg SF( 70, 70, x, x, x, x, x, x, x, x, x, x, BC7_UNORM) 294b8e80941Smrg SF( 70, 70, x, x, x, x, x, x, x, x, x, x, BC7_UNORM_SRGB) 295b8e80941Smrg SF( 70, 70, x, x, x, x, x, x, x, x, x, x, BC6H_UF16) 296b8e80941Smrg SF( x, x, x, x, x, x, x, x, x, x, x, x, PLANAR_420_8) 297b8e80941Smrg /* The format enum for R8G8B8_UNORM_SRGB first shows up in the HSW PRM but 298b8e80941Smrg * empirical testing indicates that it doesn't actually sRGB decode and 299b8e80941Smrg * acts identical to R8G8B8_UNORM. It does work on gen8+. 300b8e80941Smrg */ 301b8e80941Smrg SF( 80, 80, x, x, x, x, x, x, x, x, x, x, R8G8B8_UNORM_SRGB) 302b8e80941Smrg SF( 80, 80, x, x, x, x, x, x, x, x, x, x, ETC1_RGB8) 303b8e80941Smrg SF( 80, 80, x, x, x, x, x, x, x, x, x, x, ETC2_RGB8) 304b8e80941Smrg SF( 80, 80, x, x, x, x, x, x, x, x, x, x, EAC_R11) 305b8e80941Smrg SF( 80, 80, x, x, x, x, x, x, x, x, x, x, EAC_RG11) 306b8e80941Smrg SF( 80, 80, x, x, x, x, x, x, x, x, x, x, EAC_SIGNED_R11) 307b8e80941Smrg SF( 80, 80, x, x, x, x, x, x, x, x, x, x, EAC_SIGNED_RG11) 308b8e80941Smrg SF( 80, 80, x, x, x, x, x, x, x, x, x, x, ETC2_SRGB8) 309b8e80941Smrg SF( 90, x, x, x, x, x, 75, x, x, x, x, x, R16G16B16_UINT) 310b8e80941Smrg SF( 90, x, x, x, x, x, 75, x, x, x, x, x, R16G16B16_SINT) 311b8e80941Smrg SF( x, x, x, x, x, x, 75, x, x, x, x, x, R32_SFIXED) 312b8e80941Smrg SF( x, x, x, x, x, x, 75, x, x, x, x, x, R10G10B10A2_SNORM) 313b8e80941Smrg SF( x, x, x, x, x, x, 75, x, x, x, x, x, R10G10B10A2_USCALED) 314b8e80941Smrg SF( x, x, x, x, x, x, 75, x, x, x, x, x, R10G10B10A2_SSCALED) 315b8e80941Smrg SF( x, x, x, x, x, x, 75, x, x, x, x, x, R10G10B10A2_SINT) 316b8e80941Smrg SF( x, x, x, x, x, x, 75, x, x, x, x, x, B10G10R10A2_SNORM) 317b8e80941Smrg SF( x, x, x, x, x, x, 75, x, x, x, x, x, B10G10R10A2_USCALED) 318b8e80941Smrg SF( x, x, x, x, x, x, 75, x, x, x, x, x, B10G10R10A2_SSCALED) 319b8e80941Smrg SF( x, x, x, x, x, x, 75, x, x, x, x, x, B10G10R10A2_UINT) 320b8e80941Smrg SF( x, x, x, x, x, x, 75, x, x, x, x, x, B10G10R10A2_SINT) 321b8e80941Smrg SF( x, x, x, x, x, x, 80, x, x, x, x, x, R64G64B64A64_PASSTHRU) 322b8e80941Smrg SF( x, x, x, x, x, x, 80, x, x, x, x, x, R64G64B64_PASSTHRU) 323b8e80941Smrg SF( 80, 80, x, x, x, x, x, x, x, x, x, x, ETC2_RGB8_PTA) 324b8e80941Smrg SF( 80, 80, x, x, x, x, x, x, x, x, x, x, ETC2_SRGB8_PTA) 325b8e80941Smrg SF( 80, 80, x, x, x, x, x, x, x, x, x, x, ETC2_EAC_RGBA8) 326b8e80941Smrg SF( 80, 80, x, x, x, x, x, x, x, x, x, x, ETC2_EAC_SRGB8_A8) 327b8e80941Smrg SF( 90, x, x, x, x, x, 75, x, x, x, x, x, R8G8B8_UINT) 328b8e80941Smrg SF( 90, x, x, x, x, x, 75, x, x, x, x, x, R8G8B8_SINT) 329b8e80941Smrg SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_4X4_FLT16) 330b8e80941Smrg SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_5X4_FLT16) 331b8e80941Smrg SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_5X5_FLT16) 332b8e80941Smrg SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_6X5_FLT16) 333b8e80941Smrg SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_6X6_FLT16) 334b8e80941Smrg SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_8X5_FLT16) 335b8e80941Smrg SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_8X6_FLT16) 336b8e80941Smrg SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_8X8_FLT16) 337b8e80941Smrg SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_10X5_FLT16) 338b8e80941Smrg SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_10X6_FLT16) 339b8e80941Smrg SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_10X8_FLT16) 340b8e80941Smrg SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_10X10_FLT16) 341b8e80941Smrg SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_12X10_FLT16) 342b8e80941Smrg SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_12X12_FLT16) 343b8e80941Smrg SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_4X4_U8SRGB) 344b8e80941Smrg SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_5X4_U8SRGB) 345b8e80941Smrg SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_5X5_U8SRGB) 346b8e80941Smrg SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_6X5_U8SRGB) 347b8e80941Smrg SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_6X6_U8SRGB) 348b8e80941Smrg SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_8X5_U8SRGB) 349b8e80941Smrg SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_8X6_U8SRGB) 350b8e80941Smrg SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_8X8_U8SRGB) 351b8e80941Smrg SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_10X5_U8SRGB) 352b8e80941Smrg SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_10X6_U8SRGB) 353b8e80941Smrg SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_10X8_U8SRGB) 354b8e80941Smrg SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_10X10_U8SRGB) 355b8e80941Smrg SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_12X10_U8SRGB) 356b8e80941Smrg SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_12X12_U8SRGB) 357b8e80941Smrg SF(100, 100, x, x, x, x, x, x, x, x, x, x, ASTC_HDR_2D_4X4_FLT16) 358b8e80941Smrg SF(100, 100, x, x, x, x, x, x, x, x, x, x, ASTC_HDR_2D_5X4_FLT16) 359b8e80941Smrg SF(100, 100, x, x, x, x, x, x, x, x, x, x, ASTC_HDR_2D_5X5_FLT16) 360b8e80941Smrg SF(100, 100, x, x, x, x, x, x, x, x, x, x, ASTC_HDR_2D_6X5_FLT16) 361b8e80941Smrg SF(100, 100, x, x, x, x, x, x, x, x, x, x, ASTC_HDR_2D_6X6_FLT16) 362b8e80941Smrg SF(100, 100, x, x, x, x, x, x, x, x, x, x, ASTC_HDR_2D_8X5_FLT16) 363b8e80941Smrg SF(100, 100, x, x, x, x, x, x, x, x, x, x, ASTC_HDR_2D_8X6_FLT16) 364b8e80941Smrg SF(100, 100, x, x, x, x, x, x, x, x, x, x, ASTC_HDR_2D_8X8_FLT16) 365b8e80941Smrg SF(100, 100, x, x, x, x, x, x, x, x, x, x, ASTC_HDR_2D_10X5_FLT16) 366b8e80941Smrg SF(100, 100, x, x, x, x, x, x, x, x, x, x, ASTC_HDR_2D_10X6_FLT16) 367b8e80941Smrg SF(100, 100, x, x, x, x, x, x, x, x, x, x, ASTC_HDR_2D_10X8_FLT16) 368b8e80941Smrg SF(100, 100, x, x, x, x, x, x, x, x, x, x, ASTC_HDR_2D_10X10_FLT16) 369b8e80941Smrg SF(100, 100, x, x, x, x, x, x, x, x, x, x, ASTC_HDR_2D_12X10_FLT16) 370b8e80941Smrg SF(100, 100, x, x, x, x, x, x, x, x, x, x, ASTC_HDR_2D_12X12_FLT16) 371b8e80941Smrg}; 372b8e80941Smrg#undef x 373b8e80941Smrg#undef Y 374b8e80941Smrg 375b8e80941Smrgstatic unsigned 376b8e80941Smrgformat_gen(const struct gen_device_info *devinfo) 377b8e80941Smrg{ 378b8e80941Smrg return devinfo->gen * 10 + (devinfo->is_g4x || devinfo->is_haswell) * 5; 379b8e80941Smrg} 380b8e80941Smrg 381b8e80941Smrgstatic bool 382b8e80941Smrgformat_info_exists(enum isl_format format) 383b8e80941Smrg{ 384b8e80941Smrg assert(format != ISL_FORMAT_UNSUPPORTED); 385b8e80941Smrg assert(format < ISL_NUM_FORMATS); 386b8e80941Smrg return format < ARRAY_SIZE(format_info) && format_info[format].exists; 387b8e80941Smrg} 388b8e80941Smrg 389b8e80941Smrgbool 390b8e80941Smrgisl_format_supports_rendering(const struct gen_device_info *devinfo, 391b8e80941Smrg enum isl_format format) 392b8e80941Smrg{ 393b8e80941Smrg if (!format_info_exists(format)) 394b8e80941Smrg return false; 395b8e80941Smrg 396b8e80941Smrg return format_gen(devinfo) >= format_info[format].render_target; 397b8e80941Smrg} 398b8e80941Smrg 399b8e80941Smrgbool 400b8e80941Smrgisl_format_supports_alpha_blending(const struct gen_device_info *devinfo, 401b8e80941Smrg enum isl_format format) 402b8e80941Smrg{ 403b8e80941Smrg if (!format_info_exists(format)) 404b8e80941Smrg return false; 405b8e80941Smrg 406b8e80941Smrg return format_gen(devinfo) >= format_info[format].alpha_blend; 407b8e80941Smrg} 408b8e80941Smrg 409b8e80941Smrgbool 410b8e80941Smrgisl_format_supports_sampling(const struct gen_device_info *devinfo, 411b8e80941Smrg enum isl_format format) 412b8e80941Smrg{ 413b8e80941Smrg if (!format_info_exists(format)) 414b8e80941Smrg return false; 415b8e80941Smrg 416b8e80941Smrg if (devinfo->is_baytrail) { 417b8e80941Smrg const struct isl_format_layout *fmtl = isl_format_get_layout(format); 418b8e80941Smrg /* Support for ETC1 and ETC2 exists on Bay Trail even though big-core 419b8e80941Smrg * GPUs didn't get it until Broadwell. 420b8e80941Smrg */ 421b8e80941Smrg if (fmtl->txc == ISL_TXC_ETC1 || fmtl->txc == ISL_TXC_ETC2) 422b8e80941Smrg return true; 423b8e80941Smrg } else if (devinfo->is_cherryview) { 424b8e80941Smrg const struct isl_format_layout *fmtl = isl_format_get_layout(format); 425b8e80941Smrg /* Support for ASTC LDR exists on Cherry View even though big-core 426b8e80941Smrg * GPUs didn't get it until Skylake. 427b8e80941Smrg */ 428b8e80941Smrg if (fmtl->txc == ISL_TXC_ASTC) 429b8e80941Smrg return format < ISL_FORMAT_ASTC_HDR_2D_4X4_FLT16; 430b8e80941Smrg } else if (gen_device_info_is_9lp(devinfo)) { 431b8e80941Smrg const struct isl_format_layout *fmtl = isl_format_get_layout(format); 432b8e80941Smrg /* Support for ASTC HDR exists on Broxton even though big-core 433b8e80941Smrg * GPUs didn't get it until Cannonlake. 434b8e80941Smrg */ 435b8e80941Smrg if (fmtl->txc == ISL_TXC_ASTC) 436b8e80941Smrg return true; 437b8e80941Smrg } 438b8e80941Smrg 439b8e80941Smrg return format_gen(devinfo) >= format_info[format].sampling; 440b8e80941Smrg} 441b8e80941Smrg 442b8e80941Smrgbool 443b8e80941Smrgisl_format_supports_filtering(const struct gen_device_info *devinfo, 444b8e80941Smrg enum isl_format format) 445b8e80941Smrg{ 446b8e80941Smrg if (!format_info_exists(format)) 447b8e80941Smrg return false; 448b8e80941Smrg 449b8e80941Smrg if (devinfo->is_baytrail) { 450b8e80941Smrg const struct isl_format_layout *fmtl = isl_format_get_layout(format); 451b8e80941Smrg /* Support for ETC1 and ETC2 exists on Bay Trail even though big-core 452b8e80941Smrg * GPUs didn't get it until Broadwell. 453b8e80941Smrg */ 454b8e80941Smrg if (fmtl->txc == ISL_TXC_ETC1 || fmtl->txc == ISL_TXC_ETC2) 455b8e80941Smrg return true; 456b8e80941Smrg } else if (devinfo->is_cherryview) { 457b8e80941Smrg const struct isl_format_layout *fmtl = isl_format_get_layout(format); 458b8e80941Smrg /* Support for ASTC LDR exists on Cherry View even though big-core 459b8e80941Smrg * GPUs didn't get it until Skylake. 460b8e80941Smrg */ 461b8e80941Smrg if (fmtl->txc == ISL_TXC_ASTC) 462b8e80941Smrg return format < ISL_FORMAT_ASTC_HDR_2D_4X4_FLT16; 463b8e80941Smrg } else if (gen_device_info_is_9lp(devinfo)) { 464b8e80941Smrg const struct isl_format_layout *fmtl = isl_format_get_layout(format); 465b8e80941Smrg /* Support for ASTC HDR exists on Broxton even though big-core 466b8e80941Smrg * GPUs didn't get it until Cannonlake. 467b8e80941Smrg */ 468b8e80941Smrg if (fmtl->txc == ISL_TXC_ASTC) 469b8e80941Smrg return true; 470b8e80941Smrg } 471b8e80941Smrg 472b8e80941Smrg return format_gen(devinfo) >= format_info[format].filtering; 473b8e80941Smrg} 474b8e80941Smrg 475b8e80941Smrgbool 476b8e80941Smrgisl_format_supports_vertex_fetch(const struct gen_device_info *devinfo, 477b8e80941Smrg enum isl_format format) 478b8e80941Smrg{ 479b8e80941Smrg if (!format_info_exists(format)) 480b8e80941Smrg return false; 481b8e80941Smrg 482b8e80941Smrg /* For vertex fetch, Bay Trail supports the same set of formats as Haswell 483b8e80941Smrg * but is a superset of Ivy Bridge. 484b8e80941Smrg */ 485b8e80941Smrg if (devinfo->is_baytrail) 486b8e80941Smrg return 75 >= format_info[format].input_vb; 487b8e80941Smrg 488b8e80941Smrg return format_gen(devinfo) >= format_info[format].input_vb; 489b8e80941Smrg} 490b8e80941Smrg 491b8e80941Smrg/** 492b8e80941Smrg * Returns true if the given format can support typed writes. 493b8e80941Smrg */ 494b8e80941Smrgbool 495b8e80941Smrgisl_format_supports_typed_writes(const struct gen_device_info *devinfo, 496b8e80941Smrg enum isl_format format) 497b8e80941Smrg{ 498b8e80941Smrg if (!format_info_exists(format)) 499b8e80941Smrg return false; 500b8e80941Smrg 501b8e80941Smrg return format_gen(devinfo) >= format_info[format].typed_write; 502b8e80941Smrg} 503b8e80941Smrg 504b8e80941Smrg 505b8e80941Smrg/** 506b8e80941Smrg * Returns true if the given format can support typed reads with format 507b8e80941Smrg * conversion fully handled by hardware. On Sky Lake, all formats which are 508b8e80941Smrg * supported for typed writes also support typed reads but some of them return 509b8e80941Smrg * the raw image data and don't provide format conversion. 510b8e80941Smrg * 511b8e80941Smrg * For anyone looking to find this data in the PRM, the easiest way to find 512b8e80941Smrg * format tables is to search for R11G11B10. There are only a few 513b8e80941Smrg * occurrences. 514b8e80941Smrg */ 515b8e80941Smrgbool 516b8e80941Smrgisl_format_supports_typed_reads(const struct gen_device_info *devinfo, 517b8e80941Smrg enum isl_format format) 518b8e80941Smrg{ 519b8e80941Smrg if (!format_info_exists(format)) 520b8e80941Smrg return false; 521b8e80941Smrg 522b8e80941Smrg return format_gen(devinfo) >= format_info[format].typed_read; 523b8e80941Smrg} 524b8e80941Smrg 525b8e80941Smrg/** 526b8e80941Smrg * Returns true if the given format can support single-sample fast clears. 527b8e80941Smrg * This function only checks the format. In order to determine if a surface 528b8e80941Smrg * supports CCS_E, several other factors need to be considered such as tiling 529b8e80941Smrg * and sample count. See isl_surf_get_ccs_surf for details. 530b8e80941Smrg */ 531b8e80941Smrgbool 532b8e80941Smrgisl_format_supports_ccs_d(const struct gen_device_info *devinfo, 533b8e80941Smrg enum isl_format format) 534b8e80941Smrg{ 535b8e80941Smrg /* Fast clears were first added on Ivy Bridge */ 536b8e80941Smrg if (devinfo->gen < 7) 537b8e80941Smrg return false; 538b8e80941Smrg 539b8e80941Smrg if (!isl_format_supports_rendering(devinfo, format)) 540b8e80941Smrg return false; 541b8e80941Smrg 542b8e80941Smrg const struct isl_format_layout *fmtl = isl_format_get_layout(format); 543b8e80941Smrg 544b8e80941Smrg return fmtl->bpb == 32 || fmtl->bpb == 64 || fmtl->bpb == 128; 545b8e80941Smrg} 546b8e80941Smrg 547b8e80941Smrg/** 548b8e80941Smrg * Returns true if the given format can support single-sample color 549b8e80941Smrg * compression. This function only checks the format. In order to determine 550b8e80941Smrg * if a surface supports CCS_E, several other factors need to be considered 551b8e80941Smrg * such as tiling and sample count. See isl_surf_get_ccs_surf for details. 552b8e80941Smrg */ 553b8e80941Smrgbool 554b8e80941Smrgisl_format_supports_ccs_e(const struct gen_device_info *devinfo, 555b8e80941Smrg enum isl_format format) 556b8e80941Smrg{ 557b8e80941Smrg if (!format_info_exists(format)) 558b8e80941Smrg return false; 559b8e80941Smrg 560b8e80941Smrg /* For simplicity, only report that a format supports CCS_E if blorp can 561b8e80941Smrg * perform bit-for-bit copies with an image of that format while compressed. 562b8e80941Smrg * This allows ISL users to avoid having to resolve the image before 563b8e80941Smrg * performing such a copy. We may want to change this behavior in the 564b8e80941Smrg * future. 565b8e80941Smrg * 566b8e80941Smrg * R11G11B10_FLOAT has no equivalent UINT format. Given how blorp_copy 567b8e80941Smrg * currently works, bit-for-bit copy operations are not possible without an 568b8e80941Smrg * intermediate resolve. 569b8e80941Smrg */ 570b8e80941Smrg if (format == ISL_FORMAT_R11G11B10_FLOAT) 571b8e80941Smrg return false; 572b8e80941Smrg 573b8e80941Smrg return format_gen(devinfo) >= format_info[format].ccs_e; 574b8e80941Smrg} 575b8e80941Smrg 576b8e80941Smrgbool 577b8e80941Smrgisl_format_supports_multisampling(const struct gen_device_info *devinfo, 578b8e80941Smrg enum isl_format format) 579b8e80941Smrg{ 580b8e80941Smrg /* From the Sandybridge PRM, Volume 4 Part 1 p72, SURFACE_STATE, Surface 581b8e80941Smrg * Format: 582b8e80941Smrg * 583b8e80941Smrg * If Number of Multisamples is set to a value other than 584b8e80941Smrg * MULTISAMPLECOUNT_1, this field cannot be set to the following 585b8e80941Smrg * formats: 586b8e80941Smrg * 587b8e80941Smrg * - any format with greater than 64 bits per element 588b8e80941Smrg * - any compressed texture format (BC*) 589b8e80941Smrg * - any YCRCB* format 590b8e80941Smrg * 591b8e80941Smrg * The restriction on the format's size is removed on Broadwell. Moreover, 592b8e80941Smrg * empirically it looks that even IvyBridge can handle multisampled surfaces 593b8e80941Smrg * with format sizes all the way to 128-bits (RGBA32F, RGBA32I, RGBA32UI). 594b8e80941Smrg * 595b8e80941Smrg * Also, there is an exception for HiZ which we treat as a compressed 596b8e80941Smrg * format and is allowed to be multisampled on Broadwell and earlier. 597b8e80941Smrg */ 598b8e80941Smrg if (format == ISL_FORMAT_HIZ) { 599b8e80941Smrg /* On SKL+, HiZ is always single-sampled even when the primary surface 600b8e80941Smrg * is multisampled. See also isl_surf_get_hiz_surf(). 601b8e80941Smrg */ 602b8e80941Smrg return devinfo->gen <= 8; 603b8e80941Smrg } else if (devinfo->gen < 7 && isl_format_get_layout(format)->bpb > 64) { 604b8e80941Smrg return false; 605b8e80941Smrg } else if (isl_format_is_compressed(format)) { 606b8e80941Smrg return false; 607b8e80941Smrg } else if (isl_format_is_yuv(format)) { 608b8e80941Smrg return false; 609b8e80941Smrg } else { 610b8e80941Smrg return true; 611b8e80941Smrg } 612b8e80941Smrg} 613b8e80941Smrg 614b8e80941Smrg/** 615b8e80941Smrg * Returns true if the two formats are "CCS_E compatible" meaning that you can 616b8e80941Smrg * render in one format with CCS_E enabled and then texture using the other 617b8e80941Smrg * format without needing a resolve. 618b8e80941Smrg * 619b8e80941Smrg * Note: Even if the formats are compatible, special care must be taken if a 620b8e80941Smrg * clear color is involved because the encoding of the clear color is heavily 621b8e80941Smrg * format-dependent. 622b8e80941Smrg */ 623b8e80941Smrgbool 624b8e80941Smrgisl_formats_are_ccs_e_compatible(const struct gen_device_info *devinfo, 625b8e80941Smrg enum isl_format format1, 626b8e80941Smrg enum isl_format format2) 627b8e80941Smrg{ 628b8e80941Smrg /* They must support CCS_E */ 629b8e80941Smrg if (!isl_format_supports_ccs_e(devinfo, format1) || 630b8e80941Smrg !isl_format_supports_ccs_e(devinfo, format2)) 631b8e80941Smrg return false; 632b8e80941Smrg 633b8e80941Smrg const struct isl_format_layout *fmtl1 = isl_format_get_layout(format1); 634b8e80941Smrg const struct isl_format_layout *fmtl2 = isl_format_get_layout(format2); 635b8e80941Smrg 636b8e80941Smrg /* The compression used by CCS is not dependent on the actual data encoding 637b8e80941Smrg * of the format but only depends on the bit-layout of the channels. 638b8e80941Smrg */ 639b8e80941Smrg return fmtl1->channels.r.bits == fmtl2->channels.r.bits && 640b8e80941Smrg fmtl1->channels.g.bits == fmtl2->channels.g.bits && 641b8e80941Smrg fmtl1->channels.b.bits == fmtl2->channels.b.bits && 642b8e80941Smrg fmtl1->channels.a.bits == fmtl2->channels.a.bits; 643b8e80941Smrg} 644b8e80941Smrg 645b8e80941Smrgstatic bool 646b8e80941Smrgisl_format_has_channel_type(enum isl_format fmt, enum isl_base_type type) 647b8e80941Smrg{ 648b8e80941Smrg const struct isl_format_layout *fmtl = isl_format_get_layout(fmt); 649b8e80941Smrg 650b8e80941Smrg return fmtl->channels.r.type == type || 651b8e80941Smrg fmtl->channels.g.type == type || 652b8e80941Smrg fmtl->channels.b.type == type || 653b8e80941Smrg fmtl->channels.a.type == type || 654b8e80941Smrg fmtl->channels.l.type == type || 655b8e80941Smrg fmtl->channels.i.type == type || 656b8e80941Smrg fmtl->channels.p.type == type; 657b8e80941Smrg} 658b8e80941Smrg 659b8e80941Smrgbool 660b8e80941Smrgisl_format_has_unorm_channel(enum isl_format fmt) 661b8e80941Smrg{ 662b8e80941Smrg return isl_format_has_channel_type(fmt, ISL_UNORM); 663b8e80941Smrg} 664b8e80941Smrg 665b8e80941Smrgbool 666b8e80941Smrgisl_format_has_snorm_channel(enum isl_format fmt) 667b8e80941Smrg{ 668b8e80941Smrg return isl_format_has_channel_type(fmt, ISL_SNORM); 669b8e80941Smrg} 670b8e80941Smrg 671b8e80941Smrgbool 672b8e80941Smrgisl_format_has_ufloat_channel(enum isl_format fmt) 673b8e80941Smrg{ 674b8e80941Smrg return isl_format_has_channel_type(fmt, ISL_UFLOAT); 675b8e80941Smrg} 676b8e80941Smrg 677b8e80941Smrgbool 678b8e80941Smrgisl_format_has_sfloat_channel(enum isl_format fmt) 679b8e80941Smrg{ 680b8e80941Smrg return isl_format_has_channel_type(fmt, ISL_SFLOAT); 681b8e80941Smrg} 682b8e80941Smrg 683b8e80941Smrgbool 684b8e80941Smrgisl_format_has_uint_channel(enum isl_format fmt) 685b8e80941Smrg{ 686b8e80941Smrg return isl_format_has_channel_type(fmt, ISL_UINT); 687b8e80941Smrg} 688b8e80941Smrg 689b8e80941Smrgbool 690b8e80941Smrgisl_format_has_sint_channel(enum isl_format fmt) 691b8e80941Smrg{ 692b8e80941Smrg return isl_format_has_channel_type(fmt, ISL_SINT); 693b8e80941Smrg} 694b8e80941Smrg 695b8e80941Smrgbool 696b8e80941Smrgisl_format_has_color_component(enum isl_format fmt, int component) 697b8e80941Smrg{ 698b8e80941Smrg const struct isl_format_layout *fmtl = isl_format_get_layout(fmt); 699b8e80941Smrg const uint8_t intensity = fmtl->channels.i.bits; 700b8e80941Smrg const uint8_t luminance = fmtl->channels.l.bits; 701b8e80941Smrg 702b8e80941Smrg switch (component) { 703b8e80941Smrg case 0: 704b8e80941Smrg return (fmtl->channels.r.bits + intensity + luminance) > 0; 705b8e80941Smrg case 1: 706b8e80941Smrg return (fmtl->channels.g.bits + intensity + luminance) > 0; 707b8e80941Smrg case 2: 708b8e80941Smrg return (fmtl->channels.b.bits + intensity + luminance) > 0; 709b8e80941Smrg case 3: 710b8e80941Smrg return (fmtl->channels.a.bits + intensity) > 0; 711b8e80941Smrg default: 712b8e80941Smrg assert(!"Invalid color component: must be 0..3"); 713b8e80941Smrg return false; 714b8e80941Smrg } 715b8e80941Smrg} 716b8e80941Smrg 717b8e80941Smrgunsigned 718b8e80941Smrgisl_format_get_num_channels(enum isl_format fmt) 719b8e80941Smrg{ 720b8e80941Smrg const struct isl_format_layout *fmtl = isl_format_get_layout(fmt); 721b8e80941Smrg 722b8e80941Smrg assert(fmtl->channels.p.bits == 0); 723b8e80941Smrg 724b8e80941Smrg return (fmtl->channels.r.bits > 0) + 725b8e80941Smrg (fmtl->channels.g.bits > 0) + 726b8e80941Smrg (fmtl->channels.b.bits > 0) + 727b8e80941Smrg (fmtl->channels.a.bits > 0) + 728b8e80941Smrg (fmtl->channels.l.bits > 0) + 729b8e80941Smrg (fmtl->channels.i.bits > 0); 730b8e80941Smrg} 731b8e80941Smrg 732b8e80941Smrguint32_t 733b8e80941Smrgisl_format_get_depth_format(enum isl_format fmt, bool has_stencil) 734b8e80941Smrg{ 735b8e80941Smrg switch (fmt) { 736b8e80941Smrg default: 737b8e80941Smrg unreachable("bad isl depth format"); 738b8e80941Smrg case ISL_FORMAT_R32_FLOAT_X8X24_TYPELESS: 739b8e80941Smrg assert(has_stencil); 740b8e80941Smrg return 0; /* D32_FLOAT_S8X24_UINT */ 741b8e80941Smrg case ISL_FORMAT_R32_FLOAT: 742b8e80941Smrg assert(!has_stencil); 743b8e80941Smrg return 1; /* D32_FLOAT */ 744b8e80941Smrg case ISL_FORMAT_R24_UNORM_X8_TYPELESS: 745b8e80941Smrg if (has_stencil) { 746b8e80941Smrg return 2; /* D24_UNORM_S8_UINT */ 747b8e80941Smrg } else { 748b8e80941Smrg return 3; /* D24_UNORM_X8_UINT */ 749b8e80941Smrg } 750b8e80941Smrg case ISL_FORMAT_R16_UNORM: 751b8e80941Smrg assert(!has_stencil); 752b8e80941Smrg return 5; /* D16_UNORM */ 753b8e80941Smrg } 754b8e80941Smrg} 755b8e80941Smrg 756b8e80941Smrgenum isl_format 757b8e80941Smrgisl_format_rgb_to_rgba(enum isl_format rgb) 758b8e80941Smrg{ 759b8e80941Smrg assert(isl_format_is_rgb(rgb)); 760b8e80941Smrg 761b8e80941Smrg switch (rgb) { 762b8e80941Smrg case ISL_FORMAT_R32G32B32_FLOAT: return ISL_FORMAT_R32G32B32A32_FLOAT; 763b8e80941Smrg case ISL_FORMAT_R32G32B32_SINT: return ISL_FORMAT_R32G32B32A32_SINT; 764b8e80941Smrg case ISL_FORMAT_R32G32B32_UINT: return ISL_FORMAT_R32G32B32A32_UINT; 765b8e80941Smrg case ISL_FORMAT_R32G32B32_UNORM: return ISL_FORMAT_R32G32B32A32_UNORM; 766b8e80941Smrg case ISL_FORMAT_R32G32B32_SNORM: return ISL_FORMAT_R32G32B32A32_SNORM; 767b8e80941Smrg case ISL_FORMAT_R32G32B32_SSCALED: return ISL_FORMAT_R32G32B32A32_SSCALED; 768b8e80941Smrg case ISL_FORMAT_R32G32B32_USCALED: return ISL_FORMAT_R32G32B32A32_USCALED; 769b8e80941Smrg case ISL_FORMAT_R32G32B32_SFIXED: return ISL_FORMAT_R32G32B32A32_SFIXED; 770b8e80941Smrg case ISL_FORMAT_R8G8B8_UNORM: return ISL_FORMAT_R8G8B8A8_UNORM; 771b8e80941Smrg case ISL_FORMAT_R8G8B8_SNORM: return ISL_FORMAT_R8G8B8A8_SNORM; 772b8e80941Smrg case ISL_FORMAT_R8G8B8_SSCALED: return ISL_FORMAT_R8G8B8A8_SSCALED; 773b8e80941Smrg case ISL_FORMAT_R8G8B8_USCALED: return ISL_FORMAT_R8G8B8A8_USCALED; 774b8e80941Smrg case ISL_FORMAT_R16G16B16_FLOAT: return ISL_FORMAT_R16G16B16A16_FLOAT; 775b8e80941Smrg case ISL_FORMAT_R16G16B16_UNORM: return ISL_FORMAT_R16G16B16A16_UNORM; 776b8e80941Smrg case ISL_FORMAT_R16G16B16_SNORM: return ISL_FORMAT_R16G16B16A16_SNORM; 777b8e80941Smrg case ISL_FORMAT_R16G16B16_SSCALED: return ISL_FORMAT_R16G16B16A16_SSCALED; 778b8e80941Smrg case ISL_FORMAT_R16G16B16_USCALED: return ISL_FORMAT_R16G16B16A16_USCALED; 779b8e80941Smrg case ISL_FORMAT_R8G8B8_UNORM_SRGB: return ISL_FORMAT_R8G8B8A8_UNORM_SRGB; 780b8e80941Smrg case ISL_FORMAT_R16G16B16_UINT: return ISL_FORMAT_R16G16B16A16_UINT; 781b8e80941Smrg case ISL_FORMAT_R16G16B16_SINT: return ISL_FORMAT_R16G16B16A16_SINT; 782b8e80941Smrg case ISL_FORMAT_R8G8B8_UINT: return ISL_FORMAT_R8G8B8A8_UINT; 783b8e80941Smrg case ISL_FORMAT_R8G8B8_SINT: return ISL_FORMAT_R8G8B8A8_SINT; 784b8e80941Smrg default: 785b8e80941Smrg return ISL_FORMAT_UNSUPPORTED; 786b8e80941Smrg } 787b8e80941Smrg} 788b8e80941Smrg 789b8e80941Smrgenum isl_format 790b8e80941Smrgisl_format_rgb_to_rgbx(enum isl_format rgb) 791b8e80941Smrg{ 792b8e80941Smrg assert(isl_format_is_rgb(rgb)); 793b8e80941Smrg 794b8e80941Smrg switch (rgb) { 795b8e80941Smrg case ISL_FORMAT_R32G32B32_FLOAT: 796b8e80941Smrg return ISL_FORMAT_R32G32B32X32_FLOAT; 797b8e80941Smrg case ISL_FORMAT_R16G16B16_UNORM: 798b8e80941Smrg return ISL_FORMAT_R16G16B16X16_UNORM; 799b8e80941Smrg case ISL_FORMAT_R16G16B16_FLOAT: 800b8e80941Smrg return ISL_FORMAT_R16G16B16X16_FLOAT; 801b8e80941Smrg case ISL_FORMAT_R8G8B8_UNORM: 802b8e80941Smrg return ISL_FORMAT_R8G8B8X8_UNORM; 803b8e80941Smrg case ISL_FORMAT_R8G8B8_UNORM_SRGB: 804b8e80941Smrg return ISL_FORMAT_R8G8B8X8_UNORM_SRGB; 805b8e80941Smrg default: 806b8e80941Smrg return ISL_FORMAT_UNSUPPORTED; 807b8e80941Smrg } 808b8e80941Smrg} 809b8e80941Smrg 810b8e80941Smrgenum isl_format 811b8e80941Smrgisl_format_rgbx_to_rgba(enum isl_format rgbx) 812b8e80941Smrg{ 813b8e80941Smrg assert(isl_format_is_rgbx(rgbx)); 814b8e80941Smrg 815b8e80941Smrg switch (rgbx) { 816b8e80941Smrg case ISL_FORMAT_R32G32B32X32_FLOAT: 817b8e80941Smrg return ISL_FORMAT_R32G32B32A32_FLOAT; 818b8e80941Smrg case ISL_FORMAT_R16G16B16X16_UNORM: 819b8e80941Smrg return ISL_FORMAT_R16G16B16A16_UNORM; 820b8e80941Smrg case ISL_FORMAT_R16G16B16X16_FLOAT: 821b8e80941Smrg return ISL_FORMAT_R16G16B16A16_FLOAT; 822b8e80941Smrg case ISL_FORMAT_B8G8R8X8_UNORM: 823b8e80941Smrg return ISL_FORMAT_B8G8R8A8_UNORM; 824b8e80941Smrg case ISL_FORMAT_B8G8R8X8_UNORM_SRGB: 825b8e80941Smrg return ISL_FORMAT_B8G8R8A8_UNORM_SRGB; 826b8e80941Smrg case ISL_FORMAT_R8G8B8X8_UNORM: 827b8e80941Smrg return ISL_FORMAT_R8G8B8A8_UNORM; 828b8e80941Smrg case ISL_FORMAT_R8G8B8X8_UNORM_SRGB: 829b8e80941Smrg return ISL_FORMAT_R8G8B8A8_UNORM_SRGB; 830b8e80941Smrg case ISL_FORMAT_B10G10R10X2_UNORM: 831b8e80941Smrg return ISL_FORMAT_B10G10R10A2_UNORM; 832b8e80941Smrg case ISL_FORMAT_B5G5R5X1_UNORM: 833b8e80941Smrg return ISL_FORMAT_B5G5R5A1_UNORM; 834b8e80941Smrg case ISL_FORMAT_B5G5R5X1_UNORM_SRGB: 835b8e80941Smrg return ISL_FORMAT_B5G5R5A1_UNORM_SRGB; 836b8e80941Smrg default: 837b8e80941Smrg assert(!"Invalid RGBX format"); 838b8e80941Smrg return rgbx; 839b8e80941Smrg } 840b8e80941Smrg} 841b8e80941Smrg 842b8e80941Smrgstatic inline void 843b8e80941Smrgpack_channel(const union isl_color_value *value, unsigned i, 844b8e80941Smrg const struct isl_channel_layout *layout, 845b8e80941Smrg enum isl_colorspace colorspace, 846b8e80941Smrg uint32_t data_out[4]) 847b8e80941Smrg{ 848b8e80941Smrg if (layout->type == ISL_VOID) 849b8e80941Smrg return; 850b8e80941Smrg 851b8e80941Smrg if (colorspace == ISL_COLORSPACE_SRGB) 852b8e80941Smrg assert(layout->type == ISL_UNORM); 853b8e80941Smrg 854b8e80941Smrg uint32_t packed; 855b8e80941Smrg switch (layout->type) { 856b8e80941Smrg case ISL_UNORM: 857b8e80941Smrg if (colorspace == ISL_COLORSPACE_SRGB) { 858b8e80941Smrg if (layout->bits == 8) { 859b8e80941Smrg packed = util_format_linear_float_to_srgb_8unorm(value->f32[i]); 860b8e80941Smrg } else { 861b8e80941Smrg float srgb = util_format_linear_to_srgb_float(value->f32[i]); 862b8e80941Smrg packed = _mesa_float_to_unorm(srgb, layout->bits); 863b8e80941Smrg } 864b8e80941Smrg } else { 865b8e80941Smrg packed = _mesa_float_to_unorm(value->f32[i], layout->bits); 866b8e80941Smrg } 867b8e80941Smrg break; 868b8e80941Smrg case ISL_SNORM: 869b8e80941Smrg packed = _mesa_float_to_snorm(value->f32[i], layout->bits); 870b8e80941Smrg break; 871b8e80941Smrg case ISL_SFLOAT: 872b8e80941Smrg assert(layout->bits == 16 || layout->bits == 32); 873b8e80941Smrg if (layout->bits == 16) { 874b8e80941Smrg packed = _mesa_float_to_half(value->f32[i]); 875b8e80941Smrg } else { 876b8e80941Smrg packed = value->u32[i]; 877b8e80941Smrg } 878b8e80941Smrg break; 879b8e80941Smrg case ISL_UINT: 880b8e80941Smrg packed = MIN(value->u32[i], MAX_UINT(layout->bits)); 881b8e80941Smrg break; 882b8e80941Smrg case ISL_SINT: 883b8e80941Smrg packed = MIN(MAX(value->u32[i], MIN_INT(layout->bits)), 884b8e80941Smrg MAX_INT(layout->bits)); 885b8e80941Smrg break; 886b8e80941Smrg 887b8e80941Smrg default: 888b8e80941Smrg unreachable("Invalid channel type"); 889b8e80941Smrg } 890b8e80941Smrg 891b8e80941Smrg unsigned dword = layout->start_bit / 32; 892b8e80941Smrg unsigned bit = layout->start_bit % 32; 893b8e80941Smrg assert(bit + layout->bits <= 32); 894b8e80941Smrg data_out[dword] |= (packed & MAX_UINT(layout->bits)) << bit; 895b8e80941Smrg} 896b8e80941Smrg 897b8e80941Smrg/** 898b8e80941Smrg * Take an isl_color_value and pack it into the actual bits as specified by 899b8e80941Smrg * the isl_format. This function is very slow for a format conversion 900b8e80941Smrg * function but should be fine for a single pixel worth of data. 901b8e80941Smrg */ 902b8e80941Smrgvoid 903b8e80941Smrgisl_color_value_pack(const union isl_color_value *value, 904b8e80941Smrg enum isl_format format, 905b8e80941Smrg uint32_t *data_out) 906b8e80941Smrg{ 907b8e80941Smrg const struct isl_format_layout *fmtl = isl_format_get_layout(format); 908b8e80941Smrg assert(fmtl->colorspace == ISL_COLORSPACE_LINEAR || 909b8e80941Smrg fmtl->colorspace == ISL_COLORSPACE_SRGB); 910b8e80941Smrg assert(!isl_format_is_compressed(format)); 911b8e80941Smrg 912b8e80941Smrg memset(data_out, 0, isl_align(fmtl->bpb, 32) / 8); 913b8e80941Smrg 914b8e80941Smrg if (format == ISL_FORMAT_R9G9B9E5_SHAREDEXP) { 915b8e80941Smrg data_out[0] = float3_to_rgb9e5(value->f32); 916b8e80941Smrg return; 917b8e80941Smrg } else if (format == ISL_FORMAT_R11G11B10_FLOAT) { 918b8e80941Smrg data_out[0] = float3_to_r11g11b10f(value->f32); 919b8e80941Smrg return; 920b8e80941Smrg } 921b8e80941Smrg 922b8e80941Smrg pack_channel(value, 0, &fmtl->channels.r, fmtl->colorspace, data_out); 923b8e80941Smrg pack_channel(value, 1, &fmtl->channels.g, fmtl->colorspace, data_out); 924b8e80941Smrg pack_channel(value, 2, &fmtl->channels.b, fmtl->colorspace, data_out); 925b8e80941Smrg pack_channel(value, 3, &fmtl->channels.a, ISL_COLORSPACE_LINEAR, data_out); 926b8e80941Smrg pack_channel(value, 0, &fmtl->channels.l, fmtl->colorspace, data_out); 927b8e80941Smrg pack_channel(value, 0, &fmtl->channels.i, ISL_COLORSPACE_LINEAR, data_out); 928b8e80941Smrg assert(fmtl->channels.p.bits == 0); 929b8e80941Smrg} 930b8e80941Smrg 931b8e80941Smrg/** Extend an N-bit signed integer to 32 bits */ 932b8e80941Smrgstatic inline int32_t 933b8e80941Smrgsign_extend(int32_t x, unsigned bits) 934b8e80941Smrg{ 935b8e80941Smrg if (bits < 32) { 936b8e80941Smrg unsigned shift = 32 - bits; 937b8e80941Smrg return (x << shift) >> shift; 938b8e80941Smrg } else { 939b8e80941Smrg return x; 940b8e80941Smrg } 941b8e80941Smrg} 942b8e80941Smrg 943b8e80941Smrgstatic inline void 944b8e80941Smrgunpack_channel(union isl_color_value *value, 945b8e80941Smrg unsigned start, unsigned count, 946b8e80941Smrg const struct isl_channel_layout *layout, 947b8e80941Smrg enum isl_colorspace colorspace, 948b8e80941Smrg const uint32_t *data_in) 949b8e80941Smrg{ 950b8e80941Smrg if (layout->type == ISL_VOID) 951b8e80941Smrg return; 952b8e80941Smrg 953b8e80941Smrg unsigned dword = layout->start_bit / 32; 954b8e80941Smrg unsigned bit = layout->start_bit % 32; 955b8e80941Smrg assert(bit + layout->bits <= 32); 956b8e80941Smrg uint32_t packed = (data_in[dword] >> bit) & MAX_UINT(layout->bits); 957b8e80941Smrg 958b8e80941Smrg union { 959b8e80941Smrg uint32_t u32; 960b8e80941Smrg float f32; 961b8e80941Smrg } unpacked; 962b8e80941Smrg 963b8e80941Smrg if (colorspace == ISL_COLORSPACE_SRGB) 964b8e80941Smrg assert(layout->type == ISL_UNORM); 965b8e80941Smrg 966b8e80941Smrg switch (layout->type) { 967b8e80941Smrg case ISL_UNORM: 968b8e80941Smrg unpacked.f32 = _mesa_unorm_to_float(packed, layout->bits); 969b8e80941Smrg if (colorspace == ISL_COLORSPACE_SRGB) { 970b8e80941Smrg if (layout->bits == 8) { 971b8e80941Smrg unpacked.f32 = util_format_srgb_8unorm_to_linear_float(packed); 972b8e80941Smrg } else { 973b8e80941Smrg float srgb = _mesa_unorm_to_float(packed, layout->bits); 974b8e80941Smrg unpacked.f32 = util_format_srgb_to_linear_float(srgb); 975b8e80941Smrg } 976b8e80941Smrg } else { 977b8e80941Smrg unpacked.f32 = _mesa_unorm_to_float(packed, layout->bits); 978b8e80941Smrg } 979b8e80941Smrg break; 980b8e80941Smrg case ISL_SNORM: 981b8e80941Smrg unpacked.f32 = _mesa_snorm_to_float(sign_extend(packed, layout->bits), 982b8e80941Smrg layout->bits); 983b8e80941Smrg break; 984b8e80941Smrg case ISL_SFLOAT: 985b8e80941Smrg assert(layout->bits == 16 || layout->bits == 32); 986b8e80941Smrg if (layout->bits == 16) { 987b8e80941Smrg unpacked.f32 = _mesa_half_to_float(packed); 988b8e80941Smrg } else { 989b8e80941Smrg unpacked.u32 = packed; 990b8e80941Smrg } 991b8e80941Smrg break; 992b8e80941Smrg case ISL_UINT: 993b8e80941Smrg unpacked.u32 = packed; 994b8e80941Smrg break; 995b8e80941Smrg case ISL_SINT: 996b8e80941Smrg unpacked.u32 = sign_extend(packed, layout->bits); 997b8e80941Smrg break; 998b8e80941Smrg 999b8e80941Smrg default: 1000b8e80941Smrg unreachable("Invalid channel type"); 1001b8e80941Smrg } 1002b8e80941Smrg 1003b8e80941Smrg for (unsigned i = 0; i < count; i++) 1004b8e80941Smrg value->u32[start + i] = unpacked.u32; 1005b8e80941Smrg} 1006b8e80941Smrg 1007b8e80941Smrg/** 1008b8e80941Smrg * Take unpack an isl_color_value from the actual bits as specified by 1009b8e80941Smrg * the isl_format. This function is very slow for a format conversion 1010b8e80941Smrg * function but should be fine for a single pixel worth of data. 1011b8e80941Smrg */ 1012b8e80941Smrgvoid 1013b8e80941Smrgisl_color_value_unpack(union isl_color_value *value, 1014b8e80941Smrg enum isl_format format, 1015b8e80941Smrg const uint32_t data_in[4]) 1016b8e80941Smrg{ 1017b8e80941Smrg const struct isl_format_layout *fmtl = isl_format_get_layout(format); 1018b8e80941Smrg assert(fmtl->colorspace == ISL_COLORSPACE_LINEAR || 1019b8e80941Smrg fmtl->colorspace == ISL_COLORSPACE_SRGB); 1020b8e80941Smrg assert(!isl_format_is_compressed(format)); 1021b8e80941Smrg 1022b8e80941Smrg /* Default to opaque black. */ 1023b8e80941Smrg memset(value, 0, sizeof(*value)); 1024b8e80941Smrg if (isl_format_has_int_channel(format)) { 1025b8e80941Smrg value->u32[3] = 1u; 1026b8e80941Smrg } else { 1027b8e80941Smrg value->f32[3] = 1.0f; 1028b8e80941Smrg } 1029b8e80941Smrg 1030b8e80941Smrg if (format == ISL_FORMAT_R9G9B9E5_SHAREDEXP) { 1031b8e80941Smrg rgb9e5_to_float3(data_in[0], value->f32); 1032b8e80941Smrg return; 1033b8e80941Smrg } else if (format == ISL_FORMAT_R11G11B10_FLOAT) { 1034b8e80941Smrg r11g11b10f_to_float3(data_in[0], value->f32); 1035b8e80941Smrg return; 1036b8e80941Smrg } 1037b8e80941Smrg 1038b8e80941Smrg unpack_channel(value, 0, 1, &fmtl->channels.r, fmtl->colorspace, data_in); 1039b8e80941Smrg unpack_channel(value, 1, 1, &fmtl->channels.g, fmtl->colorspace, data_in); 1040b8e80941Smrg unpack_channel(value, 2, 1, &fmtl->channels.b, fmtl->colorspace, data_in); 1041b8e80941Smrg unpack_channel(value, 3, 1, &fmtl->channels.a, ISL_COLORSPACE_LINEAR, data_in); 1042b8e80941Smrg unpack_channel(value, 0, 3, &fmtl->channels.l, fmtl->colorspace, data_in); 1043b8e80941Smrg unpack_channel(value, 0, 4, &fmtl->channels.i, ISL_COLORSPACE_LINEAR, data_in); 1044b8e80941Smrg assert(fmtl->channels.p.bits == 0); 1045b8e80941Smrg} 1046