1/* 2 * Copyright © 2017 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 shall be included 12 * in all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 * DEALINGS IN THE SOFTWARE. 21 */ 22 23/** 24 * @file iris_formats.c 25 * 26 * Converts Gallium formats (PIPE_FORMAT_*) to hardware ones (ISL_FORMAT_*). 27 * Provides information about which formats support what features. 28 */ 29 30#include "util/bitscan.h" 31#include "util/macros.h" 32#include "util/format/u_format.h" 33 34#include "iris_resource.h" 35#include "iris_screen.h" 36 37struct iris_format_info 38iris_format_for_usage(const struct intel_device_info *devinfo, 39 enum pipe_format pformat, 40 isl_surf_usage_flags_t usage) 41{ 42 enum isl_format format = isl_format_for_pipe_format(pformat); 43 struct isl_swizzle swizzle = ISL_SWIZZLE_IDENTITY; 44 45 if (format == ISL_FORMAT_UNSUPPORTED) 46 return (struct iris_format_info) { .fmt = format, .swizzle = swizzle }; 47 48 const struct isl_format_layout *fmtl = isl_format_get_layout(format); 49 50 if (!util_format_is_srgb(pformat)) { 51 if (util_format_is_intensity(pformat)) { 52 swizzle = ISL_SWIZZLE(RED, RED, RED, RED); 53 } else if (util_format_is_luminance(pformat)) { 54 swizzle = ISL_SWIZZLE(RED, RED, RED, ONE); 55 } else if (util_format_is_luminance_alpha(pformat)) { 56 swizzle = ISL_SWIZZLE(RED, RED, RED, GREEN); 57 } else if (util_format_is_alpha(pformat)) { 58 swizzle = ISL_SWIZZLE(ZERO, ZERO, ZERO, RED); 59 } 60 } 61 62 /* When faking RGBX pipe formats with RGBA ISL formats, override alpha. */ 63 if (!util_format_has_alpha(pformat) && fmtl->channels.a.type != ISL_VOID) { 64 swizzle = ISL_SWIZZLE(RED, GREEN, BLUE, ONE); 65 } 66 67 if ((usage & ISL_SURF_USAGE_RENDER_TARGET_BIT) && 68 pformat == PIPE_FORMAT_A8_UNORM) { 69 /* Most of the hardware A/LA formats are not renderable, except 70 * for A8_UNORM. SURFACE_STATE's shader channel select fields 71 * cannot be used to swap RGB and A channels when rendering (as 72 * it could impact alpha blending), so we have to use the actual 73 * A8_UNORM format when rendering. 74 */ 75 format = ISL_FORMAT_A8_UNORM; 76 swizzle = ISL_SWIZZLE_IDENTITY; 77 } 78 79 /* We choose RGBA over RGBX for rendering the hardware doesn't support 80 * rendering to RGBX. However, when this internal override is used on Gfx9+, 81 * fast clears don't work correctly. 82 * 83 * i965 fixes this by pretending to not support RGBX formats, and the higher 84 * layers of Mesa pick the RGBA format instead. Gallium doesn't work that 85 * way, and might choose a different format, like BGRX instead of RGBX, 86 * which will also cause problems when sampling from a surface fast cleared 87 * as RGBX. So we always choose RGBA instead of RGBX explicitly 88 * here. 89 */ 90 if (isl_format_is_rgbx(format) && 91 !isl_format_supports_rendering(devinfo, format)) { 92 format = isl_format_rgbx_to_rgba(format); 93 swizzle = ISL_SWIZZLE(RED, GREEN, BLUE, ONE); 94 } 95 96 return (struct iris_format_info) { .fmt = format, .swizzle = swizzle }; 97} 98 99/** 100 * The pscreen->is_format_supported() driver hook. 101 * 102 * Returns true if the given format is supported for the given usage 103 * (PIPE_BIND_*) and sample count. 104 */ 105bool 106iris_is_format_supported(struct pipe_screen *pscreen, 107 enum pipe_format pformat, 108 enum pipe_texture_target target, 109 unsigned sample_count, 110 unsigned storage_sample_count, 111 unsigned usage) 112{ 113 struct iris_screen *screen = (struct iris_screen *) pscreen; 114 const struct intel_device_info *devinfo = &screen->devinfo; 115 uint32_t max_samples = devinfo->ver == 8 ? 8 : 16; 116 117 if (sample_count > max_samples || 118 !util_is_power_of_two_or_zero(sample_count)) 119 return false; 120 121 if (pformat == PIPE_FORMAT_NONE) 122 return true; 123 124 /* Rely on gallium fallbacks for better YUV format support. */ 125 if (util_format_is_yuv(pformat)) 126 return false; 127 128 enum isl_format format = isl_format_for_pipe_format(pformat); 129 130 if (format == ISL_FORMAT_UNSUPPORTED) 131 return false; 132 133 const struct isl_format_layout *fmtl = isl_format_get_layout(format); 134 const bool is_integer = isl_format_has_int_channel(format); 135 bool supported = true; 136 137 if (sample_count > 1) 138 supported &= isl_format_supports_multisampling(devinfo, format); 139 140 if (usage & PIPE_BIND_DEPTH_STENCIL) { 141 supported &= format == ISL_FORMAT_R32_FLOAT_X8X24_TYPELESS || 142 format == ISL_FORMAT_R32_FLOAT || 143 format == ISL_FORMAT_R24_UNORM_X8_TYPELESS || 144 format == ISL_FORMAT_R16_UNORM || 145 format == ISL_FORMAT_R8_UINT; 146 } 147 148 if (usage & PIPE_BIND_RENDER_TARGET) { 149 /* Alpha and luminance-alpha formats other than A8_UNORM are not 150 * renderable. For texturing, we can use R or RG formats with 151 * shader channel selects (SCS) to swizzle the data into the correct 152 * channels. But for render targets, the hardware prohibits using 153 * SCS to move shader outputs between the RGB and A channels, as it 154 * would alter what data is used for alpha blending. 155 * 156 * For BLORP, we can apply the swizzle in the shader. But for 157 * general rendering, this would mean recompiling the shader, which 158 * we'd like to avoid doing. So we mark these formats non-renderable. 159 * 160 * We do support A8_UNORM as it's required and is renderable. 161 */ 162 if (pformat != PIPE_FORMAT_A8_UNORM && 163 (util_format_is_alpha(pformat) || 164 util_format_is_luminance_alpha(pformat))) 165 supported = false; 166 167 enum isl_format rt_format = format; 168 169 if (isl_format_is_rgbx(format) && 170 !isl_format_supports_rendering(devinfo, format)) 171 rt_format = isl_format_rgbx_to_rgba(format); 172 173 supported &= isl_format_supports_rendering(devinfo, rt_format); 174 175 if (!is_integer) 176 supported &= isl_format_supports_alpha_blending(devinfo, rt_format); 177 } 178 179 if (usage & PIPE_BIND_SHADER_IMAGE) { 180 /* Dataport doesn't support compression, and we can't resolve an MCS 181 * compressed surface. (Buffer images may have sample count of 0.) 182 */ 183 supported &= sample_count == 0; 184 185 supported &= isl_format_supports_typed_writes(devinfo, format); 186 supported &= isl_has_matching_typed_storage_image_format(devinfo, format); 187 } 188 189 if (usage & PIPE_BIND_SAMPLER_VIEW) { 190 supported &= isl_format_supports_sampling(devinfo, format); 191 if (!is_integer) 192 supported &= isl_format_supports_filtering(devinfo, format); 193 194 /* Don't advertise 3-component RGB formats for non-buffer textures. 195 * This ensures that they are renderable from an API perspective since 196 * gallium frontends will fall back to RGBA or RGBX, which are 197 * renderable. We want to render internally for copies and blits, 198 * even if the application doesn't. 199 * 200 * Buffer textures don't need to be renderable, so we support real RGB. 201 * This is useful for PBO upload, and 32-bit RGB support is mandatory. 202 */ 203 if (target != PIPE_BUFFER) 204 supported &= fmtl->bpb != 24 && fmtl->bpb != 48 && fmtl->bpb != 96; 205 } 206 207 if (usage & PIPE_BIND_VERTEX_BUFFER) 208 supported &= isl_format_supports_vertex_fetch(devinfo, format); 209 210 if (usage & PIPE_BIND_INDEX_BUFFER) { 211 supported &= format == ISL_FORMAT_R8_UINT || 212 format == ISL_FORMAT_R16_UINT || 213 format == ISL_FORMAT_R32_UINT; 214 } 215 216 /* TODO: Support ASTC 5x5 on Gfx9 properly. This means implementing 217 * a complex sampler workaround (see i965's gfx9_apply_astc5x5_wa_flush). 218 * Without it, st/mesa will emulate ASTC 5x5 via uncompressed textures. 219 */ 220 if (devinfo->ver == 9 && (format == ISL_FORMAT_ASTC_LDR_2D_5X5_FLT16 || 221 format == ISL_FORMAT_ASTC_LDR_2D_5X5_U8SRGB)) 222 return false; 223 224 return supported; 225} 226 227