isl_format.c revision 01e04c3f
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 SF( 75, 75, x, x, x, x, x, x, x, x, x, x, R8G8B8_UNORM_SRGB) 298 SF( 80, 80, x, x, x, x, x, x, x, x, x, x, ETC1_RGB8) 299 SF( 80, 80, x, x, x, x, x, x, x, x, x, x, ETC2_RGB8) 300 SF( 80, 80, x, x, x, x, x, x, x, x, x, x, EAC_R11) 301 SF( 80, 80, x, x, x, x, x, x, x, x, x, x, EAC_RG11) 302 SF( 80, 80, x, x, x, x, x, x, x, x, x, x, EAC_SIGNED_R11) 303 SF( 80, 80, x, x, x, x, x, x, x, x, x, x, EAC_SIGNED_RG11) 304 SF( 80, 80, x, x, x, x, x, x, x, x, x, x, ETC2_SRGB8) 305 SF( 90, x, x, x, x, x, 75, x, x, x, x, x, R16G16B16_UINT) 306 SF( 90, x, x, x, x, x, 75, x, x, x, x, x, R16G16B16_SINT) 307 SF( x, x, x, x, x, x, 75, x, x, x, x, x, R32_SFIXED) 308 SF( x, x, x, x, x, x, 75, x, x, x, x, x, R10G10B10A2_SNORM) 309 SF( x, x, x, x, x, x, 75, x, x, x, x, x, R10G10B10A2_USCALED) 310 SF( x, x, x, x, x, x, 75, x, x, x, x, x, R10G10B10A2_SSCALED) 311 SF( x, x, x, x, x, x, 75, x, x, x, x, x, R10G10B10A2_SINT) 312 SF( x, x, x, x, x, x, 75, x, x, x, x, x, B10G10R10A2_SNORM) 313 SF( x, x, x, x, x, x, 75, x, x, x, x, x, B10G10R10A2_USCALED) 314 SF( x, x, x, x, x, x, 75, x, x, x, x, x, B10G10R10A2_SSCALED) 315 SF( x, x, x, x, x, x, 75, x, x, x, x, x, B10G10R10A2_UINT) 316 SF( x, x, x, x, x, x, 75, x, x, x, x, x, B10G10R10A2_SINT) 317 SF( x, x, x, x, x, x, 80, x, x, x, x, x, R64G64B64A64_PASSTHRU) 318 SF( x, x, x, x, x, x, 80, x, x, x, x, x, R64G64B64_PASSTHRU) 319 SF( 80, 80, x, x, x, x, x, x, x, x, x, x, ETC2_RGB8_PTA) 320 SF( 80, 80, x, x, x, x, x, x, x, x, x, x, ETC2_SRGB8_PTA) 321 SF( 80, 80, x, x, x, x, x, x, x, x, x, x, ETC2_EAC_RGBA8) 322 SF( 80, 80, x, x, x, x, x, x, x, x, x, x, ETC2_EAC_SRGB8_A8) 323 SF( 90, x, x, x, x, x, 75, x, x, x, x, x, R8G8B8_UINT) 324 SF( 90, x, x, x, x, x, 75, x, x, x, x, x, R8G8B8_SINT) 325 SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_4X4_FLT16) 326 SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_5X4_FLT16) 327 SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_5X5_FLT16) 328 SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_6X5_FLT16) 329 SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_6X6_FLT16) 330 SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_8X5_FLT16) 331 SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_8X6_FLT16) 332 SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_8X8_FLT16) 333 SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_10X5_FLT16) 334 SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_10X6_FLT16) 335 SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_10X8_FLT16) 336 SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_10X10_FLT16) 337 SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_12X10_FLT16) 338 SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_12X12_FLT16) 339 SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_4X4_U8SRGB) 340 SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_5X4_U8SRGB) 341 SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_5X5_U8SRGB) 342 SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_6X5_U8SRGB) 343 SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_6X6_U8SRGB) 344 SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_8X5_U8SRGB) 345 SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_8X6_U8SRGB) 346 SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_8X8_U8SRGB) 347 SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_10X5_U8SRGB) 348 SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_10X6_U8SRGB) 349 SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_10X8_U8SRGB) 350 SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_10X10_U8SRGB) 351 SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_12X10_U8SRGB) 352 SF( 90, 90, x, x, x, x, x, x, x, x, x, x, ASTC_LDR_2D_12X12_U8SRGB) 353 SF(100, 100, x, x, x, x, x, x, x, x, x, x, ASTC_HDR_2D_4X4_FLT16) 354 SF(100, 100, x, x, x, x, x, x, x, x, x, x, ASTC_HDR_2D_5X4_FLT16) 355 SF(100, 100, x, x, x, x, x, x, x, x, x, x, ASTC_HDR_2D_5X5_FLT16) 356 SF(100, 100, x, x, x, x, x, x, x, x, x, x, ASTC_HDR_2D_6X5_FLT16) 357 SF(100, 100, x, x, x, x, x, x, x, x, x, x, ASTC_HDR_2D_6X6_FLT16) 358 SF(100, 100, x, x, x, x, x, x, x, x, x, x, ASTC_HDR_2D_8X5_FLT16) 359 SF(100, 100, x, x, x, x, x, x, x, x, x, x, ASTC_HDR_2D_8X6_FLT16) 360 SF(100, 100, x, x, x, x, x, x, x, x, x, x, ASTC_HDR_2D_8X8_FLT16) 361 SF(100, 100, x, x, x, x, x, x, x, x, x, x, ASTC_HDR_2D_10X5_FLT16) 362 SF(100, 100, x, x, x, x, x, x, x, x, x, x, ASTC_HDR_2D_10X6_FLT16) 363 SF(100, 100, x, x, x, x, x, x, x, x, x, x, ASTC_HDR_2D_10X8_FLT16) 364 SF(100, 100, x, x, x, x, x, x, x, x, x, x, ASTC_HDR_2D_10X10_FLT16) 365 SF(100, 100, x, x, x, x, x, x, x, x, x, x, ASTC_HDR_2D_12X10_FLT16) 366 SF(100, 100, x, x, x, x, x, x, x, x, x, x, ASTC_HDR_2D_12X12_FLT16) 367}; 368#undef x 369#undef Y 370 371static unsigned 372format_gen(const struct gen_device_info *devinfo) 373{ 374 return devinfo->gen * 10 + (devinfo->is_g4x || devinfo->is_haswell) * 5; 375} 376 377static bool 378format_info_exists(enum isl_format format) 379{ 380 assert(format != ISL_FORMAT_UNSUPPORTED); 381 assert(format < ISL_NUM_FORMATS); 382 return format < ARRAY_SIZE(format_info) && format_info[format].exists; 383} 384 385bool 386isl_format_supports_rendering(const struct gen_device_info *devinfo, 387 enum isl_format format) 388{ 389 if (!format_info_exists(format)) 390 return false; 391 392 return format_gen(devinfo) >= format_info[format].render_target; 393} 394 395bool 396isl_format_supports_alpha_blending(const struct gen_device_info *devinfo, 397 enum isl_format format) 398{ 399 if (!format_info_exists(format)) 400 return false; 401 402 return format_gen(devinfo) >= format_info[format].alpha_blend; 403} 404 405bool 406isl_format_supports_sampling(const struct gen_device_info *devinfo, 407 enum isl_format format) 408{ 409 if (!format_info_exists(format)) 410 return false; 411 412 if (devinfo->is_baytrail) { 413 const struct isl_format_layout *fmtl = isl_format_get_layout(format); 414 /* Support for ETC1 and ETC2 exists on Bay Trail even though big-core 415 * GPUs didn't get it until Broadwell. 416 */ 417 if (fmtl->txc == ISL_TXC_ETC1 || fmtl->txc == ISL_TXC_ETC2) 418 return true; 419 } else if (devinfo->is_cherryview) { 420 const struct isl_format_layout *fmtl = isl_format_get_layout(format); 421 /* Support for ASTC LDR exists on Cherry View even though big-core 422 * GPUs didn't get it until Skylake. 423 */ 424 if (fmtl->txc == ISL_TXC_ASTC) 425 return format < ISL_FORMAT_ASTC_HDR_2D_4X4_FLT16; 426 } else if (gen_device_info_is_9lp(devinfo)) { 427 const struct isl_format_layout *fmtl = isl_format_get_layout(format); 428 /* Support for ASTC HDR exists on Broxton even though big-core 429 * GPUs didn't get it until Cannonlake. 430 */ 431 if (fmtl->txc == ISL_TXC_ASTC) 432 return true; 433 } 434 435 return format_gen(devinfo) >= format_info[format].sampling; 436} 437 438bool 439isl_format_supports_filtering(const struct gen_device_info *devinfo, 440 enum isl_format format) 441{ 442 if (!format_info_exists(format)) 443 return false; 444 445 if (devinfo->is_baytrail) { 446 const struct isl_format_layout *fmtl = isl_format_get_layout(format); 447 /* Support for ETC1 and ETC2 exists on Bay Trail even though big-core 448 * GPUs didn't get it until Broadwell. 449 */ 450 if (fmtl->txc == ISL_TXC_ETC1 || fmtl->txc == ISL_TXC_ETC2) 451 return true; 452 } else if (devinfo->is_cherryview) { 453 const struct isl_format_layout *fmtl = isl_format_get_layout(format); 454 /* Support for ASTC LDR exists on Cherry View even though big-core 455 * GPUs didn't get it until Skylake. 456 */ 457 if (fmtl->txc == ISL_TXC_ASTC) 458 return format < ISL_FORMAT_ASTC_HDR_2D_4X4_FLT16; 459 } else if (gen_device_info_is_9lp(devinfo)) { 460 const struct isl_format_layout *fmtl = isl_format_get_layout(format); 461 /* Support for ASTC HDR exists on Broxton even though big-core 462 * GPUs didn't get it until Cannonlake. 463 */ 464 if (fmtl->txc == ISL_TXC_ASTC) 465 return true; 466 } 467 468 return format_gen(devinfo) >= format_info[format].filtering; 469} 470 471bool 472isl_format_supports_vertex_fetch(const struct gen_device_info *devinfo, 473 enum isl_format format) 474{ 475 if (!format_info_exists(format)) 476 return false; 477 478 /* For vertex fetch, Bay Trail supports the same set of formats as Haswell 479 * but is a superset of Ivy Bridge. 480 */ 481 if (devinfo->is_baytrail) 482 return 75 >= format_info[format].input_vb; 483 484 return format_gen(devinfo) >= format_info[format].input_vb; 485} 486 487/** 488 * Returns true if the given format can support typed writes. 489 */ 490bool 491isl_format_supports_typed_writes(const struct gen_device_info *devinfo, 492 enum isl_format format) 493{ 494 if (!format_info_exists(format)) 495 return false; 496 497 return format_gen(devinfo) >= format_info[format].typed_write; 498} 499 500 501/** 502 * Returns true if the given format can support typed reads with format 503 * conversion fully handled by hardware. On Sky Lake, all formats which are 504 * supported for typed writes also support typed reads but some of them return 505 * the raw image data and don't provide format conversion. 506 * 507 * For anyone looking to find this data in the PRM, the easiest way to find 508 * format tables is to search for R11G11B10. There are only a few 509 * occurrences. 510 */ 511bool 512isl_format_supports_typed_reads(const struct gen_device_info *devinfo, 513 enum isl_format format) 514{ 515 if (!format_info_exists(format)) 516 return false; 517 518 return format_gen(devinfo) >= format_info[format].typed_read; 519} 520 521/** 522 * Returns true if the given format can support single-sample fast clears. 523 * This function only checks the format. In order to determine if a surface 524 * supports CCS_E, several other factors need to be considered such as tiling 525 * and sample count. See isl_surf_get_ccs_surf for details. 526 */ 527bool 528isl_format_supports_ccs_d(const struct gen_device_info *devinfo, 529 enum isl_format format) 530{ 531 /* Fast clears were first added on Ivy Bridge */ 532 if (devinfo->gen < 7) 533 return false; 534 535 if (!isl_format_supports_rendering(devinfo, format)) 536 return false; 537 538 const struct isl_format_layout *fmtl = isl_format_get_layout(format); 539 540 return fmtl->bpb == 32 || fmtl->bpb == 64 || fmtl->bpb == 128; 541} 542 543/** 544 * Returns true if the given format can support single-sample color 545 * compression. This function only checks the format. In order to determine 546 * if a surface supports CCS_E, several other factors need to be considered 547 * such as tiling and sample count. See isl_surf_get_ccs_surf for details. 548 */ 549bool 550isl_format_supports_ccs_e(const struct gen_device_info *devinfo, 551 enum isl_format format) 552{ 553 if (!format_info_exists(format)) 554 return false; 555 556 /* For simplicity, only report that a format supports CCS_E if blorp can 557 * perform bit-for-bit copies with an image of that format while compressed. 558 * This allows ISL users to avoid having to resolve the image before 559 * performing such a copy. We may want to change this behavior in the 560 * future. 561 * 562 * R11G11B10_FLOAT has no equivalent UINT format. Given how blorp_copy 563 * currently works, bit-for-bit copy operations are not possible without an 564 * intermediate resolve. 565 */ 566 if (format == ISL_FORMAT_R11G11B10_FLOAT) 567 return false; 568 569 return format_gen(devinfo) >= format_info[format].ccs_e; 570} 571 572bool 573isl_format_supports_multisampling(const struct gen_device_info *devinfo, 574 enum isl_format format) 575{ 576 /* From the Sandybridge PRM, Volume 4 Part 1 p72, SURFACE_STATE, Surface 577 * Format: 578 * 579 * If Number of Multisamples is set to a value other than 580 * MULTISAMPLECOUNT_1, this field cannot be set to the following 581 * formats: 582 * 583 * - any format with greater than 64 bits per element 584 * - any compressed texture format (BC*) 585 * - any YCRCB* format 586 * 587 * The restriction on the format's size is removed on Broadwell. Moreover, 588 * empirically it looks that even IvyBridge can handle multisampled surfaces 589 * with format sizes all the way to 128-bits (RGBA32F, RGBA32I, RGBA32UI). 590 * 591 * Also, there is an exception for HiZ which we treat as a compressed 592 * format and is allowed to be multisampled on Broadwell and earlier. 593 */ 594 if (format == ISL_FORMAT_HIZ) { 595 /* On SKL+, HiZ is always single-sampled even when the primary surface 596 * is multisampled. See also isl_surf_get_hiz_surf(). 597 */ 598 return devinfo->gen <= 8; 599 } else if (devinfo->gen < 7 && isl_format_get_layout(format)->bpb > 64) { 600 return false; 601 } else if (isl_format_is_compressed(format)) { 602 return false; 603 } else if (isl_format_is_yuv(format)) { 604 return false; 605 } else { 606 return true; 607 } 608} 609 610/** 611 * Returns true if the two formats are "CCS_E compatible" meaning that you can 612 * render in one format with CCS_E enabled and then texture using the other 613 * format without needing a resolve. 614 * 615 * Note: Even if the formats are compatible, special care must be taken if a 616 * clear color is involved because the encoding of the clear color is heavily 617 * format-dependent. 618 */ 619bool 620isl_formats_are_ccs_e_compatible(const struct gen_device_info *devinfo, 621 enum isl_format format1, 622 enum isl_format format2) 623{ 624 /* They must support CCS_E */ 625 if (!isl_format_supports_ccs_e(devinfo, format1) || 626 !isl_format_supports_ccs_e(devinfo, format2)) 627 return false; 628 629 const struct isl_format_layout *fmtl1 = isl_format_get_layout(format1); 630 const struct isl_format_layout *fmtl2 = isl_format_get_layout(format2); 631 632 /* The compression used by CCS is not dependent on the actual data encoding 633 * of the format but only depends on the bit-layout of the channels. 634 */ 635 return fmtl1->channels.r.bits == fmtl2->channels.r.bits && 636 fmtl1->channels.g.bits == fmtl2->channels.g.bits && 637 fmtl1->channels.b.bits == fmtl2->channels.b.bits && 638 fmtl1->channels.a.bits == fmtl2->channels.a.bits; 639} 640 641static bool 642isl_format_has_channel_type(enum isl_format fmt, enum isl_base_type type) 643{ 644 const struct isl_format_layout *fmtl = isl_format_get_layout(fmt); 645 646 return fmtl->channels.r.type == type || 647 fmtl->channels.g.type == type || 648 fmtl->channels.b.type == type || 649 fmtl->channels.a.type == type || 650 fmtl->channels.l.type == type || 651 fmtl->channels.i.type == type || 652 fmtl->channels.p.type == type; 653} 654 655bool 656isl_format_has_unorm_channel(enum isl_format fmt) 657{ 658 return isl_format_has_channel_type(fmt, ISL_UNORM); 659} 660 661bool 662isl_format_has_snorm_channel(enum isl_format fmt) 663{ 664 return isl_format_has_channel_type(fmt, ISL_SNORM); 665} 666 667bool 668isl_format_has_ufloat_channel(enum isl_format fmt) 669{ 670 return isl_format_has_channel_type(fmt, ISL_UFLOAT); 671} 672 673bool 674isl_format_has_sfloat_channel(enum isl_format fmt) 675{ 676 return isl_format_has_channel_type(fmt, ISL_SFLOAT); 677} 678 679bool 680isl_format_has_uint_channel(enum isl_format fmt) 681{ 682 return isl_format_has_channel_type(fmt, ISL_UINT); 683} 684 685bool 686isl_format_has_sint_channel(enum isl_format fmt) 687{ 688 return isl_format_has_channel_type(fmt, ISL_SINT); 689} 690 691unsigned 692isl_format_get_num_channels(enum isl_format fmt) 693{ 694 const struct isl_format_layout *fmtl = isl_format_get_layout(fmt); 695 696 assert(fmtl->channels.p.bits == 0); 697 698 return (fmtl->channels.r.bits > 0) + 699 (fmtl->channels.g.bits > 0) + 700 (fmtl->channels.b.bits > 0) + 701 (fmtl->channels.a.bits > 0) + 702 (fmtl->channels.l.bits > 0) + 703 (fmtl->channels.i.bits > 0); 704} 705 706uint32_t 707isl_format_get_depth_format(enum isl_format fmt, bool has_stencil) 708{ 709 switch (fmt) { 710 default: 711 unreachable("bad isl depth format"); 712 case ISL_FORMAT_R32_FLOAT_X8X24_TYPELESS: 713 assert(has_stencil); 714 return 0; /* D32_FLOAT_S8X24_UINT */ 715 case ISL_FORMAT_R32_FLOAT: 716 assert(!has_stencil); 717 return 1; /* D32_FLOAT */ 718 case ISL_FORMAT_R24_UNORM_X8_TYPELESS: 719 if (has_stencil) { 720 return 2; /* D24_UNORM_S8_UINT */ 721 } else { 722 return 3; /* D24_UNORM_X8_UINT */ 723 } 724 case ISL_FORMAT_R16_UNORM: 725 assert(!has_stencil); 726 return 5; /* D16_UNORM */ 727 } 728} 729 730enum isl_format 731isl_format_rgb_to_rgba(enum isl_format rgb) 732{ 733 assert(isl_format_is_rgb(rgb)); 734 735 switch (rgb) { 736 case ISL_FORMAT_R32G32B32_FLOAT: return ISL_FORMAT_R32G32B32A32_FLOAT; 737 case ISL_FORMAT_R32G32B32_SINT: return ISL_FORMAT_R32G32B32A32_SINT; 738 case ISL_FORMAT_R32G32B32_UINT: return ISL_FORMAT_R32G32B32A32_UINT; 739 case ISL_FORMAT_R32G32B32_UNORM: return ISL_FORMAT_R32G32B32A32_UNORM; 740 case ISL_FORMAT_R32G32B32_SNORM: return ISL_FORMAT_R32G32B32A32_SNORM; 741 case ISL_FORMAT_R32G32B32_SSCALED: return ISL_FORMAT_R32G32B32A32_SSCALED; 742 case ISL_FORMAT_R32G32B32_USCALED: return ISL_FORMAT_R32G32B32A32_USCALED; 743 case ISL_FORMAT_R32G32B32_SFIXED: return ISL_FORMAT_R32G32B32A32_SFIXED; 744 case ISL_FORMAT_R8G8B8_UNORM: return ISL_FORMAT_R8G8B8A8_UNORM; 745 case ISL_FORMAT_R8G8B8_SNORM: return ISL_FORMAT_R8G8B8A8_SNORM; 746 case ISL_FORMAT_R8G8B8_SSCALED: return ISL_FORMAT_R8G8B8A8_SSCALED; 747 case ISL_FORMAT_R8G8B8_USCALED: return ISL_FORMAT_R8G8B8A8_USCALED; 748 case ISL_FORMAT_R16G16B16_FLOAT: return ISL_FORMAT_R16G16B16A16_FLOAT; 749 case ISL_FORMAT_R16G16B16_UNORM: return ISL_FORMAT_R16G16B16A16_UNORM; 750 case ISL_FORMAT_R16G16B16_SNORM: return ISL_FORMAT_R16G16B16A16_SNORM; 751 case ISL_FORMAT_R16G16B16_SSCALED: return ISL_FORMAT_R16G16B16A16_SSCALED; 752 case ISL_FORMAT_R16G16B16_USCALED: return ISL_FORMAT_R16G16B16A16_USCALED; 753 case ISL_FORMAT_R8G8B8_UNORM_SRGB: return ISL_FORMAT_R8G8B8A8_UNORM_SRGB; 754 case ISL_FORMAT_R16G16B16_UINT: return ISL_FORMAT_R16G16B16A16_UINT; 755 case ISL_FORMAT_R16G16B16_SINT: return ISL_FORMAT_R16G16B16A16_SINT; 756 case ISL_FORMAT_R8G8B8_UINT: return ISL_FORMAT_R8G8B8A8_UINT; 757 case ISL_FORMAT_R8G8B8_SINT: return ISL_FORMAT_R8G8B8A8_SINT; 758 default: 759 return ISL_FORMAT_UNSUPPORTED; 760 } 761} 762 763enum isl_format 764isl_format_rgb_to_rgbx(enum isl_format rgb) 765{ 766 assert(isl_format_is_rgb(rgb)); 767 768 switch (rgb) { 769 case ISL_FORMAT_R32G32B32_FLOAT: 770 return ISL_FORMAT_R32G32B32X32_FLOAT; 771 case ISL_FORMAT_R16G16B16_UNORM: 772 return ISL_FORMAT_R16G16B16X16_UNORM; 773 case ISL_FORMAT_R16G16B16_FLOAT: 774 return ISL_FORMAT_R16G16B16X16_FLOAT; 775 case ISL_FORMAT_R8G8B8_UNORM: 776 return ISL_FORMAT_R8G8B8X8_UNORM; 777 case ISL_FORMAT_R8G8B8_UNORM_SRGB: 778 return ISL_FORMAT_R8G8B8X8_UNORM_SRGB; 779 default: 780 return ISL_FORMAT_UNSUPPORTED; 781 } 782} 783 784enum isl_format 785isl_format_rgbx_to_rgba(enum isl_format rgbx) 786{ 787 assert(isl_format_is_rgbx(rgbx)); 788 789 switch (rgbx) { 790 case ISL_FORMAT_R32G32B32X32_FLOAT: 791 return ISL_FORMAT_R32G32B32A32_FLOAT; 792 case ISL_FORMAT_R16G16B16X16_UNORM: 793 return ISL_FORMAT_R16G16B16A16_UNORM; 794 case ISL_FORMAT_R16G16B16X16_FLOAT: 795 return ISL_FORMAT_R16G16B16A16_FLOAT; 796 case ISL_FORMAT_B8G8R8X8_UNORM: 797 return ISL_FORMAT_B8G8R8A8_UNORM; 798 case ISL_FORMAT_B8G8R8X8_UNORM_SRGB: 799 return ISL_FORMAT_B8G8R8A8_UNORM_SRGB; 800 case ISL_FORMAT_R8G8B8X8_UNORM: 801 return ISL_FORMAT_R8G8B8A8_UNORM; 802 case ISL_FORMAT_R8G8B8X8_UNORM_SRGB: 803 return ISL_FORMAT_R8G8B8A8_UNORM_SRGB; 804 case ISL_FORMAT_B10G10R10X2_UNORM: 805 return ISL_FORMAT_B10G10R10A2_UNORM; 806 case ISL_FORMAT_B5G5R5X1_UNORM: 807 return ISL_FORMAT_B5G5R5A1_UNORM; 808 case ISL_FORMAT_B5G5R5X1_UNORM_SRGB: 809 return ISL_FORMAT_B5G5R5A1_UNORM_SRGB; 810 default: 811 assert(!"Invalid RGBX format"); 812 return rgbx; 813 } 814} 815 816static inline void 817pack_channel(const union isl_color_value *value, unsigned i, 818 const struct isl_channel_layout *layout, 819 enum isl_colorspace colorspace, 820 uint32_t data_out[4]) 821{ 822 if (layout->type == ISL_VOID) 823 return; 824 825 if (colorspace == ISL_COLORSPACE_SRGB) 826 assert(layout->type == ISL_UNORM); 827 828 uint32_t packed; 829 switch (layout->type) { 830 case ISL_UNORM: 831 if (colorspace == ISL_COLORSPACE_SRGB) { 832 if (layout->bits == 8) { 833 packed = util_format_linear_float_to_srgb_8unorm(value->f32[i]); 834 } else { 835 float srgb = util_format_linear_to_srgb_float(value->f32[i]); 836 packed = _mesa_float_to_unorm(srgb, layout->bits); 837 } 838 } else { 839 packed = _mesa_float_to_unorm(value->f32[i], layout->bits); 840 } 841 break; 842 case ISL_SNORM: 843 packed = _mesa_float_to_snorm(value->f32[i], layout->bits); 844 break; 845 case ISL_SFLOAT: 846 assert(layout->bits == 16 || layout->bits == 32); 847 if (layout->bits == 16) { 848 packed = _mesa_float_to_half(value->f32[i]); 849 } else { 850 packed = value->u32[i]; 851 } 852 break; 853 case ISL_UINT: 854 packed = MIN(value->u32[i], MAX_UINT(layout->bits)); 855 break; 856 case ISL_SINT: 857 packed = MIN(MAX(value->u32[i], MIN_INT(layout->bits)), 858 MAX_INT(layout->bits)); 859 break; 860 861 default: 862 unreachable("Invalid channel type"); 863 } 864 865 unsigned dword = layout->start_bit / 32; 866 unsigned bit = layout->start_bit % 32; 867 assert(bit + layout->bits <= 32); 868 data_out[dword] |= (packed & MAX_UINT(layout->bits)) << bit; 869} 870 871/** 872 * Take an isl_color_value and pack it into the actual bits as specified by 873 * the isl_format. This function is very slow for a format conversion 874 * function but should be fine for a single pixel worth of data. 875 */ 876void 877isl_color_value_pack(const union isl_color_value *value, 878 enum isl_format format, 879 uint32_t *data_out) 880{ 881 const struct isl_format_layout *fmtl = isl_format_get_layout(format); 882 assert(fmtl->colorspace == ISL_COLORSPACE_LINEAR || 883 fmtl->colorspace == ISL_COLORSPACE_SRGB); 884 assert(!isl_format_is_compressed(format)); 885 886 memset(data_out, 0, isl_align(fmtl->bpb, 32) / 8); 887 888 if (format == ISL_FORMAT_R9G9B9E5_SHAREDEXP) { 889 data_out[0] = float3_to_rgb9e5(value->f32); 890 return; 891 } else if (format == ISL_FORMAT_R11G11B10_FLOAT) { 892 data_out[0] = float3_to_r11g11b10f(value->f32); 893 return; 894 } 895 896 pack_channel(value, 0, &fmtl->channels.r, fmtl->colorspace, data_out); 897 pack_channel(value, 1, &fmtl->channels.g, fmtl->colorspace, data_out); 898 pack_channel(value, 2, &fmtl->channels.b, fmtl->colorspace, data_out); 899 pack_channel(value, 3, &fmtl->channels.a, ISL_COLORSPACE_LINEAR, data_out); 900 pack_channel(value, 0, &fmtl->channels.l, fmtl->colorspace, data_out); 901 pack_channel(value, 0, &fmtl->channels.i, ISL_COLORSPACE_LINEAR, data_out); 902 assert(fmtl->channels.p.bits == 0); 903} 904 905/** Extend an N-bit signed integer to 32 bits */ 906static inline int32_t 907sign_extend(int32_t x, unsigned bits) 908{ 909 if (bits < 32) { 910 unsigned shift = 32 - bits; 911 return (x << shift) >> shift; 912 } else { 913 return x; 914 } 915} 916 917static inline void 918unpack_channel(union isl_color_value *value, 919 unsigned start, unsigned count, 920 const struct isl_channel_layout *layout, 921 enum isl_colorspace colorspace, 922 const uint32_t *data_in) 923{ 924 if (layout->type == ISL_VOID) 925 return; 926 927 unsigned dword = layout->start_bit / 32; 928 unsigned bit = layout->start_bit % 32; 929 assert(bit + layout->bits <= 32); 930 uint32_t packed = (data_in[dword] >> bit) & MAX_UINT(layout->bits); 931 932 union { 933 uint32_t u32; 934 float f32; 935 } unpacked; 936 937 if (colorspace == ISL_COLORSPACE_SRGB) 938 assert(layout->type == ISL_UNORM); 939 940 switch (layout->type) { 941 case ISL_UNORM: 942 unpacked.f32 = _mesa_unorm_to_float(packed, layout->bits); 943 if (colorspace == ISL_COLORSPACE_SRGB) { 944 if (layout->bits == 8) { 945 unpacked.f32 = util_format_srgb_8unorm_to_linear_float(packed); 946 } else { 947 float srgb = _mesa_unorm_to_float(packed, layout->bits); 948 unpacked.f32 = util_format_srgb_to_linear_float(srgb); 949 } 950 } else { 951 unpacked.f32 = _mesa_unorm_to_float(packed, layout->bits); 952 } 953 break; 954 case ISL_SNORM: 955 unpacked.f32 = _mesa_snorm_to_float(sign_extend(packed, layout->bits), 956 layout->bits); 957 break; 958 case ISL_SFLOAT: 959 assert(layout->bits == 16 || layout->bits == 32); 960 if (layout->bits == 16) { 961 unpacked.f32 = _mesa_half_to_float(packed); 962 } else { 963 unpacked.u32 = packed; 964 } 965 break; 966 case ISL_UINT: 967 unpacked.u32 = packed; 968 break; 969 case ISL_SINT: 970 unpacked.u32 = sign_extend(packed, layout->bits); 971 break; 972 973 default: 974 unreachable("Invalid channel type"); 975 } 976 977 for (unsigned i = 0; i < count; i++) 978 value->u32[start + i] = unpacked.u32; 979} 980 981/** 982 * Take unpack an isl_color_value from the actual bits as specified by 983 * the isl_format. This function is very slow for a format conversion 984 * function but should be fine for a single pixel worth of data. 985 */ 986void 987isl_color_value_unpack(union isl_color_value *value, 988 enum isl_format format, 989 const uint32_t data_in[4]) 990{ 991 const struct isl_format_layout *fmtl = isl_format_get_layout(format); 992 assert(fmtl->colorspace == ISL_COLORSPACE_LINEAR || 993 fmtl->colorspace == ISL_COLORSPACE_SRGB); 994 assert(!isl_format_is_compressed(format)); 995 996 /* Default to opaque black. */ 997 memset(value, 0, sizeof(*value)); 998 if (isl_format_has_int_channel(format)) { 999 value->u32[3] = 1u; 1000 } else { 1001 value->f32[3] = 1.0f; 1002 } 1003 1004 if (format == ISL_FORMAT_R9G9B9E5_SHAREDEXP) { 1005 rgb9e5_to_float3(data_in[0], value->f32); 1006 return; 1007 } else if (format == ISL_FORMAT_R11G11B10_FLOAT) { 1008 r11g11b10f_to_float3(data_in[0], value->f32); 1009 return; 1010 } 1011 1012 unpack_channel(value, 0, 1, &fmtl->channels.r, fmtl->colorspace, data_in); 1013 unpack_channel(value, 1, 1, &fmtl->channels.g, fmtl->colorspace, data_in); 1014 unpack_channel(value, 2, 1, &fmtl->channels.b, fmtl->colorspace, data_in); 1015 unpack_channel(value, 3, 1, &fmtl->channels.a, ISL_COLORSPACE_LINEAR, data_in); 1016 unpack_channel(value, 0, 3, &fmtl->channels.l, fmtl->colorspace, data_in); 1017 unpack_channel(value, 0, 4, &fmtl->channels.i, ISL_COLORSPACE_LINEAR, data_in); 1018 assert(fmtl->channels.p.bits == 0); 1019} 1020