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