1 /************************************************************************** 2 * 3 * Copyright (C) 2014 Red Hat Inc. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be included 13 * in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 16 * OR 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 19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 21 * OTHER DEALINGS IN THE SOFTWARE. 22 * 23 **************************************************************************/ 24 #include <epoxy/gl.h> 25 26 #include "vrend_renderer.h" 27 #include "util/u_memory.h" 28 #include "util/u_format.h" 29 30 #define SWIZZLE_INVALID 0xff 31 #define NO_SWIZZLE { SWIZZLE_INVALID, SWIZZLE_INVALID, SWIZZLE_INVALID, SWIZZLE_INVALID } 32 #define RRR1_SWIZZLE { PIPE_SWIZZLE_RED, PIPE_SWIZZLE_RED, PIPE_SWIZZLE_RED, PIPE_SWIZZLE_ONE } 33 #define RGB1_SWIZZLE { PIPE_SWIZZLE_RED, PIPE_SWIZZLE_GREEN, PIPE_SWIZZLE_BLUE, PIPE_SWIZZLE_ONE } 34 35 #ifdef __GNUC__ 36 /* The warning missing-field-initializers is misleading: If at least one field 37 * is initialized, then the un-initialized fields will be filled with zero. 38 * Silencing the warning by manually adding the zeros that the compiler will add 39 * anyway doesn't improve the code, and initializing the files by using a named 40 * notation will make it worse, because then he remaining fields truely be 41 * un-initialized. 42 */ 43 #ifdef __clang__ 44 #pragma clang diagnostic ignored "-Wmissing-field-initializers" 45 #else 46 #pragma GCC diagnostic ignored "-Wmissing-field-initializers" 47 #endif 48 #endif 49 50 /* fill the format table */ 51 static struct vrend_format_table base_rgba_formats[] = 52 { 53 { VIRGL_FORMAT_B8G8R8X8_UNORM, GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE, RGB1_SWIZZLE }, 54 { VIRGL_FORMAT_B8G8R8A8_UNORM, GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE, NO_SWIZZLE }, 55 56 { VIRGL_FORMAT_R8G8B8X8_UNORM, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, RGB1_SWIZZLE }, 57 { VIRGL_FORMAT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE }, 58 59 { VIRGL_FORMAT_A8R8G8B8_UNORM, GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, NO_SWIZZLE }, 60 { VIRGL_FORMAT_X8R8G8B8_UNORM, GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, NO_SWIZZLE }, 61 62 { VIRGL_FORMAT_A8B8G8R8_UNORM, GL_RGBA8, GL_ABGR_EXT, GL_UNSIGNED_BYTE, NO_SWIZZLE }, 63 64 { VIRGL_FORMAT_B4G4R4X4_UNORM, GL_RGBA4, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, RGB1_SWIZZLE }, 65 { VIRGL_FORMAT_A4B4G4R4_UNORM, GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, NO_SWIZZLE }, 66 { VIRGL_FORMAT_B5G5R5X1_UNORM, GL_RGB5_A1, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, RGB1_SWIZZLE }, 67 68 { VIRGL_FORMAT_B5G6R5_UNORM, GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NO_SWIZZLE }, 69 { VIRGL_FORMAT_B2G3R3_UNORM, GL_R3_G3_B2, GL_RGB, GL_UNSIGNED_BYTE_3_3_2, NO_SWIZZLE }, 70 71 { VIRGL_FORMAT_R16G16B16X16_UNORM, GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT, RGB1_SWIZZLE }, 72 73 { VIRGL_FORMAT_R16G16B16A16_UNORM, GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT, NO_SWIZZLE }, 74 }; 75 76 static struct vrend_format_table gl_base_rgba_formats[] = 77 { 78 { VIRGL_FORMAT_B4G4R4A4_UNORM, GL_RGBA4, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, NO_SWIZZLE }, 79 { VIRGL_FORMAT_B5G5R5A1_UNORM, GL_RGB5_A1, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, NO_SWIZZLE }, 80 }; 81 82 static struct vrend_format_table base_depth_formats[] = 83 { 84 { VIRGL_FORMAT_Z16_UNORM, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, NO_SWIZZLE }, 85 { VIRGL_FORMAT_Z32_UNORM, GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NO_SWIZZLE }, 86 { VIRGL_FORMAT_S8_UINT_Z24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NO_SWIZZLE }, 87 { VIRGL_FORMAT_Z24X8_UNORM, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NO_SWIZZLE }, 88 { VIRGL_FORMAT_Z32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, NO_SWIZZLE }, 89 /* this is probably a separate format */ 90 { VIRGL_FORMAT_Z32_FLOAT_S8X24_UINT, GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, NO_SWIZZLE }, 91 { VIRGL_FORMAT_X24S8_UINT, GL_STENCIL_INDEX8, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, NO_SWIZZLE }, 92 }; 93 94 static struct vrend_format_table base_la_formats[] = { 95 { VIRGL_FORMAT_A8_UNORM, GL_ALPHA8, GL_ALPHA, GL_UNSIGNED_BYTE, NO_SWIZZLE }, 96 { VIRGL_FORMAT_L8_UNORM, GL_R8, GL_RED, GL_UNSIGNED_BYTE, RRR1_SWIZZLE }, 97 { VIRGL_FORMAT_L8A8_UNORM, GL_LUMINANCE8_ALPHA8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NO_SWIZZLE }, 98 { VIRGL_FORMAT_A16_UNORM, GL_ALPHA16, GL_ALPHA, GL_UNSIGNED_SHORT, NO_SWIZZLE }, 99 { VIRGL_FORMAT_L16_UNORM, GL_R16, GL_RED, GL_UNSIGNED_SHORT, RRR1_SWIZZLE }, 100 { VIRGL_FORMAT_L16A16_UNORM, GL_LUMINANCE16_ALPHA16, GL_LUMINANCE_ALPHA, GL_UNSIGNED_SHORT, NO_SWIZZLE }, 101 }; 102 103 static struct vrend_format_table rg_base_formats[] = { 104 { VIRGL_FORMAT_R8_UNORM, GL_R8, GL_RED, GL_UNSIGNED_BYTE, NO_SWIZZLE }, 105 { VIRGL_FORMAT_R8G8_UNORM, GL_RG8, GL_RG, GL_UNSIGNED_BYTE, NO_SWIZZLE }, 106 { VIRGL_FORMAT_R16_UNORM, GL_R16, GL_RED, GL_UNSIGNED_SHORT, NO_SWIZZLE }, 107 { VIRGL_FORMAT_R16G16_UNORM, GL_RG16, GL_RG, GL_UNSIGNED_SHORT, NO_SWIZZLE }, 108 }; 109 110 static struct vrend_format_table integer_base_formats[] = { 111 { VIRGL_FORMAT_R8G8B8A8_UINT, GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, NO_SWIZZLE }, 112 { VIRGL_FORMAT_R8G8B8A8_SINT, GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE, NO_SWIZZLE }, 113 114 { VIRGL_FORMAT_R16G16B16A16_UINT, GL_RGBA16UI, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, NO_SWIZZLE }, 115 { VIRGL_FORMAT_R16G16B16A16_SINT, GL_RGBA16I, GL_RGBA_INTEGER, GL_SHORT, NO_SWIZZLE }, 116 117 { VIRGL_FORMAT_R32G32B32A32_UINT, GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT, NO_SWIZZLE }, 118 { VIRGL_FORMAT_R32G32B32A32_SINT, GL_RGBA32I, GL_RGBA_INTEGER, GL_INT, NO_SWIZZLE }, 119 }; 120 121 static struct vrend_format_table integer_3comp_formats[] = { 122 { VIRGL_FORMAT_R8G8B8X8_UINT, GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, RGB1_SWIZZLE }, 123 { VIRGL_FORMAT_R8G8B8X8_SINT, GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE, RGB1_SWIZZLE }, 124 { VIRGL_FORMAT_R16G16B16X16_UINT, GL_RGBA16UI, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, RGB1_SWIZZLE }, 125 { VIRGL_FORMAT_R16G16B16X16_SINT, GL_RGBA16I, GL_RGBA_INTEGER, GL_SHORT, RGB1_SWIZZLE }, 126 { VIRGL_FORMAT_R32G32B32_UINT, GL_RGB32UI, GL_RGB_INTEGER, GL_UNSIGNED_INT, NO_SWIZZLE }, 127 { VIRGL_FORMAT_R32G32B32_SINT, GL_RGB32I, GL_RGB_INTEGER, GL_INT, NO_SWIZZLE }, 128 }; 129 130 static struct vrend_format_table float_base_formats[] = { 131 { VIRGL_FORMAT_R16G16B16A16_FLOAT, GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT, NO_SWIZZLE }, 132 { VIRGL_FORMAT_R32G32B32A32_FLOAT, GL_RGBA32F, GL_RGBA, GL_FLOAT, NO_SWIZZLE }, 133 }; 134 135 static struct vrend_format_table float_la_formats[] = { 136 { VIRGL_FORMAT_A16_FLOAT, GL_ALPHA16F_ARB, GL_ALPHA, GL_HALF_FLOAT, NO_SWIZZLE }, 137 { VIRGL_FORMAT_L16_FLOAT, GL_R16F, GL_RED, GL_HALF_FLOAT, RRR1_SWIZZLE }, 138 { VIRGL_FORMAT_L16A16_FLOAT, GL_LUMINANCE_ALPHA16F_ARB, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, NO_SWIZZLE }, 139 140 { VIRGL_FORMAT_A32_FLOAT, GL_ALPHA32F_ARB, GL_ALPHA, GL_FLOAT, NO_SWIZZLE }, 141 { VIRGL_FORMAT_L32_FLOAT, GL_R32F, GL_RED, GL_FLOAT, RRR1_SWIZZLE }, 142 { VIRGL_FORMAT_L32A32_FLOAT, GL_LUMINANCE_ALPHA32F_ARB, GL_LUMINANCE_ALPHA, GL_FLOAT, NO_SWIZZLE }, 143 }; 144 145 static struct vrend_format_table integer_rg_formats[] = { 146 { VIRGL_FORMAT_R8_UINT, GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE, NO_SWIZZLE }, 147 { VIRGL_FORMAT_R8G8_UINT, GL_RG8UI, GL_RG_INTEGER, GL_UNSIGNED_BYTE, NO_SWIZZLE }, 148 { VIRGL_FORMAT_R8_SINT, GL_R8I, GL_RED_INTEGER, GL_BYTE, NO_SWIZZLE }, 149 { VIRGL_FORMAT_R8G8_SINT, GL_RG8I, GL_RG_INTEGER, GL_BYTE, NO_SWIZZLE }, 150 151 { VIRGL_FORMAT_R16_UINT, GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT, NO_SWIZZLE }, 152 { VIRGL_FORMAT_R16G16_UINT, GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT, NO_SWIZZLE }, 153 { VIRGL_FORMAT_R16_SINT, GL_R16I, GL_RED_INTEGER, GL_SHORT, NO_SWIZZLE }, 154 { VIRGL_FORMAT_R16G16_SINT, GL_RG16I, GL_RG_INTEGER, GL_SHORT, NO_SWIZZLE }, 155 156 { VIRGL_FORMAT_R32_UINT, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT, NO_SWIZZLE }, 157 { VIRGL_FORMAT_R32G32_UINT, GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT, NO_SWIZZLE }, 158 { VIRGL_FORMAT_R32_SINT, GL_R32I, GL_RED_INTEGER, GL_INT, NO_SWIZZLE }, 159 { VIRGL_FORMAT_R32G32_SINT, GL_RG32I, GL_RG_INTEGER, GL_INT, NO_SWIZZLE }, 160 }; 161 162 static struct vrend_format_table float_rg_formats[] = { 163 { VIRGL_FORMAT_R16_FLOAT, GL_R16F, GL_RED, GL_HALF_FLOAT, NO_SWIZZLE }, 164 { VIRGL_FORMAT_R16G16_FLOAT, GL_RG16F, GL_RG, GL_HALF_FLOAT, NO_SWIZZLE }, 165 { VIRGL_FORMAT_R32_FLOAT, GL_R32F, GL_RED, GL_FLOAT, NO_SWIZZLE }, 166 { VIRGL_FORMAT_R32G32_FLOAT, GL_RG32F, GL_RG, GL_FLOAT, NO_SWIZZLE }, 167 }; 168 169 static struct vrend_format_table float_3comp_formats[] = { 170 { VIRGL_FORMAT_R16G16B16X16_FLOAT, GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT, RGB1_SWIZZLE }, 171 { VIRGL_FORMAT_R32G32B32_FLOAT, GL_RGB32F, GL_RGB, GL_FLOAT, NO_SWIZZLE }, 172 }; 173 174 175 static struct vrend_format_table integer_la_formats[] = { 176 { VIRGL_FORMAT_A8_UINT, GL_ALPHA8UI_EXT, GL_ALPHA_INTEGER, GL_UNSIGNED_BYTE, NO_SWIZZLE }, 177 { VIRGL_FORMAT_L8_UINT, GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE, RRR1_SWIZZLE }, 178 { VIRGL_FORMAT_L8A8_UINT, GL_LUMINANCE_ALPHA8UI_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT, GL_UNSIGNED_BYTE, NO_SWIZZLE }, 179 { VIRGL_FORMAT_A8_SINT, GL_ALPHA8I_EXT, GL_ALPHA_INTEGER, GL_BYTE, NO_SWIZZLE }, 180 { VIRGL_FORMAT_L8_SINT, GL_R8I, GL_RED_INTEGER, GL_BYTE, RRR1_SWIZZLE }, 181 { VIRGL_FORMAT_L8A8_SINT, GL_LUMINANCE_ALPHA8I_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT, GL_BYTE, NO_SWIZZLE }, 182 183 { VIRGL_FORMAT_A16_UINT, GL_ALPHA16UI_EXT, GL_ALPHA_INTEGER, GL_UNSIGNED_SHORT, NO_SWIZZLE }, 184 { VIRGL_FORMAT_L16_UINT, GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT, RRR1_SWIZZLE }, 185 { VIRGL_FORMAT_L16A16_UINT, GL_LUMINANCE_ALPHA16UI_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT, GL_UNSIGNED_SHORT, NO_SWIZZLE }, 186 187 { VIRGL_FORMAT_A16_SINT, GL_ALPHA16I_EXT, GL_ALPHA_INTEGER, GL_SHORT, NO_SWIZZLE }, 188 { VIRGL_FORMAT_L16_SINT, GL_R16I, GL_RED_INTEGER, GL_SHORT, RRR1_SWIZZLE }, 189 { VIRGL_FORMAT_L16A16_SINT, GL_LUMINANCE_ALPHA16I_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT, GL_SHORT, NO_SWIZZLE }, 190 191 { VIRGL_FORMAT_A32_UINT, GL_ALPHA32UI_EXT, GL_ALPHA_INTEGER, GL_UNSIGNED_INT, NO_SWIZZLE }, 192 { VIRGL_FORMAT_L32_UINT, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT, RRR1_SWIZZLE }, 193 { VIRGL_FORMAT_L32A32_UINT, GL_LUMINANCE_ALPHA32UI_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT, GL_UNSIGNED_INT, NO_SWIZZLE }, 194 195 { VIRGL_FORMAT_A32_SINT, GL_ALPHA32I_EXT, GL_ALPHA_INTEGER, GL_INT, NO_SWIZZLE }, 196 { VIRGL_FORMAT_L32_SINT, GL_R32I, GL_RED_INTEGER, GL_INT, RRR1_SWIZZLE }, 197 { VIRGL_FORMAT_L32A32_SINT, GL_LUMINANCE_ALPHA32I_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT, GL_INT, NO_SWIZZLE }, 198 199 200 }; 201 202 static struct vrend_format_table snorm_formats[] = { 203 { VIRGL_FORMAT_R8_SNORM, GL_R8_SNORM, GL_RED, GL_BYTE, NO_SWIZZLE }, 204 { VIRGL_FORMAT_R8G8_SNORM, GL_RG8_SNORM, GL_RG, GL_BYTE, NO_SWIZZLE }, 205 206 { VIRGL_FORMAT_R8G8B8A8_SNORM, GL_RGBA8_SNORM, GL_RGBA, GL_BYTE, NO_SWIZZLE }, 207 { VIRGL_FORMAT_R8G8B8X8_SNORM, GL_RGBA8_SNORM, GL_RGBA, GL_BYTE, RGB1_SWIZZLE }, 208 209 { VIRGL_FORMAT_R16_SNORM, GL_R16_SNORM, GL_RED, GL_SHORT, NO_SWIZZLE }, 210 { VIRGL_FORMAT_R16G16_SNORM, GL_RG16_SNORM, GL_RG, GL_SHORT, NO_SWIZZLE }, 211 { VIRGL_FORMAT_R16G16B16A16_SNORM, GL_RGBA16_SNORM, GL_RGBA, GL_SHORT, NO_SWIZZLE }, 212 213 { VIRGL_FORMAT_R16G16B16X16_SNORM, GL_RGBA16_SNORM, GL_RGBA, GL_SHORT, RGB1_SWIZZLE }, 214 }; 215 216 static struct vrend_format_table snorm_la_formats[] = { 217 { VIRGL_FORMAT_A8_SNORM, GL_ALPHA8_SNORM, GL_ALPHA, GL_BYTE, NO_SWIZZLE }, 218 { VIRGL_FORMAT_L8_SNORM, GL_R8_SNORM, GL_RED, GL_BYTE, RRR1_SWIZZLE }, 219 { VIRGL_FORMAT_L8A8_SNORM, GL_LUMINANCE8_ALPHA8_SNORM, GL_LUMINANCE_ALPHA, GL_BYTE, NO_SWIZZLE }, 220 { VIRGL_FORMAT_A16_SNORM, GL_ALPHA16_SNORM, GL_ALPHA, GL_SHORT, NO_SWIZZLE }, 221 { VIRGL_FORMAT_L16_SNORM, GL_R16_SNORM, GL_RED, GL_SHORT, RRR1_SWIZZLE }, 222 { VIRGL_FORMAT_L16A16_SNORM, GL_LUMINANCE16_ALPHA16_SNORM, GL_LUMINANCE_ALPHA, GL_SHORT, NO_SWIZZLE }, 223 }; 224 225 static struct vrend_format_table dxtn_formats[] = { 226 { VIRGL_FORMAT_DXT1_RGB, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_RGB, GL_UNSIGNED_BYTE, NO_SWIZZLE }, 227 { VIRGL_FORMAT_DXT1_RGBA, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE }, 228 { VIRGL_FORMAT_DXT3_RGBA, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE }, 229 { VIRGL_FORMAT_DXT5_RGBA, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE }, 230 }; 231 232 static struct vrend_format_table dxtn_srgb_formats[] = { 233 { VIRGL_FORMAT_DXT1_SRGB, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, GL_RGB, GL_UNSIGNED_BYTE, NO_SWIZZLE }, 234 { VIRGL_FORMAT_DXT1_SRGBA, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE }, 235 { VIRGL_FORMAT_DXT3_SRGBA, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE }, 236 { VIRGL_FORMAT_DXT5_SRGBA, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE }, 237 }; 238 239 static struct vrend_format_table rgtc_formats[] = { 240 { VIRGL_FORMAT_RGTC1_UNORM, GL_COMPRESSED_RED_RGTC1, GL_RED, GL_UNSIGNED_BYTE, NO_SWIZZLE }, 241 { VIRGL_FORMAT_RGTC1_SNORM, GL_COMPRESSED_SIGNED_RED_RGTC1, GL_RED, GL_BYTE, NO_SWIZZLE }, 242 243 { VIRGL_FORMAT_RGTC2_UNORM, GL_COMPRESSED_RG_RGTC2, GL_RG, GL_UNSIGNED_BYTE, NO_SWIZZLE }, 244 { VIRGL_FORMAT_RGTC2_SNORM, GL_COMPRESSED_SIGNED_RG_RGTC2, GL_RG, GL_BYTE, NO_SWIZZLE }, 245 }; 246 247 static struct vrend_format_table srgb_formats[] = { 248 { VIRGL_FORMAT_R8G8B8X8_SRGB, GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, RGB1_SWIZZLE }, 249 { VIRGL_FORMAT_R8G8B8A8_SRGB, GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE }, 250 251 { VIRGL_FORMAT_L8_SRGB, GL_SR8_EXT, GL_RED, GL_UNSIGNED_BYTE, RRR1_SWIZZLE }, 252 { VIRGL_FORMAT_L8A8_SRGB, GL_SLUMINANCE8_ALPHA8_EXT, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NO_SWIZZLE }, 253 }; 254 255 static struct vrend_format_table gl_srgb_formats[] = 256 { 257 { VIRGL_FORMAT_B8G8R8X8_SRGB, GL_SRGB8_ALPHA8, GL_BGRA, GL_UNSIGNED_BYTE, RGB1_SWIZZLE }, 258 { VIRGL_FORMAT_B8G8R8A8_SRGB, GL_SRGB8_ALPHA8, GL_BGRA, GL_UNSIGNED_BYTE, NO_SWIZZLE }, 259 }; 260 261 static struct vrend_format_table bit10_formats[] = { 262 { VIRGL_FORMAT_B10G10R10X2_UNORM, GL_RGB10_A2, GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, RGB1_SWIZZLE }, 263 { VIRGL_FORMAT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, NO_SWIZZLE }, 264 { VIRGL_FORMAT_B10G10R10A2_UINT, GL_RGB10_A2UI, GL_BGRA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, NO_SWIZZLE }, 265 { VIRGL_FORMAT_R10G10B10X2_UNORM, GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, RGB1_SWIZZLE }, 266 { VIRGL_FORMAT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, NO_SWIZZLE }, 267 { VIRGL_FORMAT_R10G10B10A2_UINT, GL_RGB10_A2UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, NO_SWIZZLE }, 268 }; 269 270 static struct vrend_format_table packed_float_formats[] = { 271 { VIRGL_FORMAT_R11G11B10_FLOAT, GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, NO_SWIZZLE }, 272 }; 273 274 static struct vrend_format_table exponent_float_formats[] = { 275 { VIRGL_FORMAT_R9G9B9E5_FLOAT, GL_RGB9_E5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, NO_SWIZZLE }, 276 }; 277 278 static struct vrend_format_table bptc_formats[] = { 279 { VIRGL_FORMAT_BPTC_RGBA_UNORM, GL_COMPRESSED_RGBA_BPTC_UNORM, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE }, 280 { VIRGL_FORMAT_BPTC_SRGBA, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE }, 281 { VIRGL_FORMAT_BPTC_RGB_FLOAT, GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, GL_RGB, GL_UNSIGNED_BYTE, NO_SWIZZLE }, 282 { VIRGL_FORMAT_BPTC_RGB_UFLOAT, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, GL_RGB, GL_UNSIGNED_BYTE, NO_SWIZZLE }, 283 }; 284 285 static struct vrend_format_table gles_bgra_formats[] = { 286 { VIRGL_FORMAT_B8G8R8X8_UNORM, GL_BGRA_EXT, GL_BGRA_EXT, GL_UNSIGNED_BYTE, RGB1_SWIZZLE }, 287 { VIRGL_FORMAT_B8G8R8A8_UNORM, GL_BGRA_EXT, GL_BGRA_EXT, GL_UNSIGNED_BYTE, NO_SWIZZLE }, 288 }; 289 290 static struct vrend_format_table gles_z32_format[] = { 291 { VIRGL_FORMAT_Z32_UNORM, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NO_SWIZZLE }, 292 }; 293 294 static void vrend_add_formats(struct vrend_format_table *table, int num_entries) 295 { 296 int i; 297 uint32_t binding = 0; 298 GLuint buffers; 299 GLuint tex_id, fb_id; 300 301 for (i = 0; i < num_entries; i++) { 302 GLenum status; 303 bool is_depth = false; 304 /**/ 305 glGenTextures(1, &tex_id); 306 glGenFramebuffers(1, &fb_id); 307 308 glBindTexture(GL_TEXTURE_2D, tex_id); 309 glBindFramebuffer(GL_FRAMEBUFFER, fb_id); 310 311 glTexImage2D(GL_TEXTURE_2D, 0, table[i].internalformat, 32, 32, 0, table[i].glformat, table[i].gltype, NULL); 312 status = glGetError(); 313 if (status == GL_INVALID_VALUE || status == GL_INVALID_ENUM || status == GL_INVALID_OPERATION) { 314 struct vrend_format_table *entry = NULL; 315 uint8_t swizzle[4]; 316 binding = VIRGL_BIND_SAMPLER_VIEW | VIRGL_BIND_RENDER_TARGET | VIRGL_BIND_NEED_SWIZZLE; 317 318 switch (table[i].format) { 319 case PIPE_FORMAT_A8_UNORM: 320 entry = &rg_base_formats[0]; 321 swizzle[0] = swizzle[1] = swizzle[2] = PIPE_SWIZZLE_ZERO; 322 swizzle[3] = PIPE_SWIZZLE_RED; 323 break; 324 case PIPE_FORMAT_A16_UNORM: 325 entry = &rg_base_formats[2]; 326 swizzle[0] = swizzle[1] = swizzle[2] = PIPE_SWIZZLE_ZERO; 327 swizzle[3] = PIPE_SWIZZLE_RED; 328 break; 329 default: 330 break; 331 } 332 333 if (entry) { 334 vrend_insert_format_swizzle(table[i].format, entry, binding, swizzle); 335 } 336 glDeleteTextures(1, &tex_id); 337 glDeleteFramebuffers(1, &fb_id); 338 continue; 339 } 340 341 if (util_format_is_depth_or_stencil(table[i].format)) { 342 GLenum attachment; 343 344 if (table[i].format == VIRGL_FORMAT_Z24X8_UNORM || table[i].format == VIRGL_FORMAT_Z32_UNORM || table[i].format == VIRGL_FORMAT_Z16_UNORM || table[i].format == VIRGL_FORMAT_Z32_FLOAT) 345 attachment = GL_DEPTH_ATTACHMENT; 346 else 347 attachment = GL_DEPTH_STENCIL_ATTACHMENT; 348 glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, attachment, GL_TEXTURE_2D, tex_id, 0); 349 350 is_depth = true; 351 352 buffers = GL_NONE; 353 glDrawBuffers(1, &buffers); 354 } else { 355 glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex_id, 0); 356 357 buffers = GL_COLOR_ATTACHMENT0_EXT; 358 glDrawBuffers(1, &buffers); 359 } 360 361 status = glCheckFramebufferStatus(GL_FRAMEBUFFER); 362 binding = VIRGL_BIND_SAMPLER_VIEW; 363 if (status == GL_FRAMEBUFFER_COMPLETE) 364 binding |= (is_depth ? VIRGL_BIND_DEPTH_STENCIL : VIRGL_BIND_RENDER_TARGET); 365 366 glDeleteTextures(1, &tex_id); 367 glDeleteFramebuffers(1, &fb_id); 368 369 if (table[i].swizzle[0] != SWIZZLE_INVALID) 370 vrend_insert_format_swizzle(table[i].format, &table[i], binding, table[i].swizzle); 371 else 372 vrend_insert_format(&table[i], binding); 373 } 374 } 375 376 #define add_formats(x) vrend_add_formats((x), ARRAY_SIZE((x))) 377 378 void vrend_build_format_list_common(void) 379 { 380 add_formats(base_rgba_formats); 381 add_formats(base_depth_formats); 382 add_formats(base_la_formats); 383 384 /* float support */ 385 add_formats(float_base_formats); 386 add_formats(float_la_formats); 387 add_formats(float_3comp_formats); 388 389 /* texture integer support ? */ 390 add_formats(integer_base_formats); 391 add_formats(integer_la_formats); 392 add_formats(integer_3comp_formats); 393 394 /* RG support? */ 395 add_formats(rg_base_formats); 396 /* integer + rg */ 397 add_formats(integer_rg_formats); 398 /* float + rg */ 399 add_formats(float_rg_formats); 400 401 /* snorm */ 402 add_formats(snorm_formats); 403 add_formats(snorm_la_formats); 404 405 /* compressed */ 406 add_formats(rgtc_formats); 407 add_formats(dxtn_formats); 408 add_formats(dxtn_srgb_formats); 409 410 add_formats(srgb_formats); 411 412 add_formats(bit10_formats); 413 414 add_formats(packed_float_formats); 415 add_formats(exponent_float_formats); 416 417 add_formats(bptc_formats); 418 } 419 420 421 void vrend_build_format_list_gl(void) 422 { 423 /* GL_BGRA formats aren't as well supported in GLES as in GL, specially in 424 * transfer operations. So we only register support for it in GL. 425 */ 426 add_formats(gl_base_rgba_formats); 427 add_formats(gl_srgb_formats); 428 } 429 430 void vrend_build_format_list_gles(void) 431 { 432 /* The BGR[A|X] formats is required but OpenGL ES does not 433 * support rendering to it. Try to use GL_BGRA_EXT from the 434 * GL_EXT_texture_format_BGRA8888 extension. But the 435 * GL_BGRA_EXT format is not supported by OpenGL Desktop. 436 */ 437 add_formats(gles_bgra_formats); 438 439 440 /* The Z32 format is required, but OpenGL ES does not support 441 * using it as a depth buffer. We just fake support with Z24 442 * and hope nobody notices. 443 */ 444 add_formats(gles_z32_format); 445 } 446 447 /* glTexStorage may not support all that is supported by glTexImage, 448 * so add a flag to indicate when it can be used. 449 */ 450 void vrend_check_texture_storage(struct vrend_format_table *table) 451 { 452 int i; 453 GLuint tex_id; 454 for (i = 0; i < VIRGL_FORMAT_MAX; i++) { 455 456 if (table[i].internalformat != 0) { 457 glGenTextures(1, &tex_id); 458 glBindTexture(GL_TEXTURE_2D, tex_id); 459 glTexStorage2D(GL_TEXTURE_2D, 1, table[i].internalformat, 32, 32); 460 if (glGetError() == GL_NO_ERROR) 461 table[i].bindings |= VIRGL_BIND_CAN_TEXTURE_STORAGE; 462 glDeleteTextures(1, &tex_id); 463 } 464 } 465 } 466 467 unsigned vrend_renderer_query_multisample_caps(unsigned max_samples, struct virgl_caps_v2 *caps) 468 { 469 GLuint tex; 470 GLuint fbo; 471 GLenum status; 472 473 uint max_samples_confirmed = 1; 474 uint test_num_samples[4] = {2,4,8,16}; 475 int out_buf_offsets[4] = {0,1,2,4}; 476 int lowest_working_ms_count_idx = -1; 477 478 glGenFramebuffers( 1, &fbo ); 479 memset(caps->sample_locations, 0, 8 * sizeof(uint32_t)); 480 481 for (int i = 3; i >= 0; i--) { 482 if (test_num_samples[i] > max_samples) 483 continue; 484 glGenTextures(1, &tex); 485 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex); 486 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, test_num_samples[i], GL_RGBA32F, 64, 64, GL_TRUE); 487 status = glGetError(); 488 if (status == GL_NO_ERROR) { 489 glBindFramebuffer(GL_FRAMEBUFFER, fbo); 490 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, tex, 0); 491 status = glCheckFramebufferStatus(GL_FRAMEBUFFER); 492 if (status == GL_FRAMEBUFFER_COMPLETE) { 493 if (max_samples_confirmed < test_num_samples[i]) 494 max_samples_confirmed = test_num_samples[i]; 495 496 for (uint k = 0; k < test_num_samples[i]; ++k) { 497 float msp[2]; 498 uint32_t compressed; 499 glGetMultisamplefv(GL_SAMPLE_POSITION, k, msp); 500 compressed = ((unsigned)(floor(msp[0] * 16.0f)) & 0xf) << 4; 501 compressed |= ((unsigned)(floor(msp[1] * 16.0f)) & 0xf); 502 caps->sample_locations[out_buf_offsets[i] + (k >> 2)] |= compressed << (8 * (k & 3)); 503 } 504 lowest_working_ms_count_idx = i; 505 } else { 506 /* If a framebuffer doesn't support low sample counts, 507 * use the sample position from the last working larger count. */ 508 if (lowest_working_ms_count_idx > 0) { 509 for (uint k = 0; k < test_num_samples[i]; ++k) { 510 caps->sample_locations[out_buf_offsets[i] + (k >> 2)] = 511 caps->sample_locations[out_buf_offsets[lowest_working_ms_count_idx] + (k >> 2)]; 512 } 513 } 514 } 515 glBindFramebuffer(GL_FRAMEBUFFER, 0); 516 } 517 glDeleteTextures(1, &tex); 518 } 519 glDeleteFramebuffers(1, &fbo); 520 return max_samples_confirmed; 521 } 522 523 /* returns: 1 = compatible, -1 = not compatible, 0 = undecided */ 524 static int format_uncompressed_compressed_copy_compatible(enum pipe_format src, 525 enum pipe_format dst) 526 { 527 switch (src) { 528 case PIPE_FORMAT_R32G32B32A32_UINT: 529 case PIPE_FORMAT_R32G32B32A32_SINT: 530 case PIPE_FORMAT_R32G32B32A32_FLOAT: 531 case PIPE_FORMAT_R32G32B32A32_SNORM: 532 case PIPE_FORMAT_R32G32B32A32_UNORM: 533 switch (dst) { 534 case PIPE_FORMAT_DXT3_RGBA: 535 case PIPE_FORMAT_DXT3_SRGBA: 536 case PIPE_FORMAT_DXT5_RGBA: 537 case PIPE_FORMAT_DXT5_SRGBA: 538 case PIPE_FORMAT_RGTC2_UNORM: 539 case PIPE_FORMAT_RGTC2_SNORM: 540 case PIPE_FORMAT_BPTC_RGBA_UNORM: 541 case PIPE_FORMAT_BPTC_SRGBA: 542 case PIPE_FORMAT_BPTC_RGB_FLOAT: 543 case PIPE_FORMAT_BPTC_RGB_UFLOAT: 544 return 1; 545 default: 546 return -1; 547 } 548 case PIPE_FORMAT_R16G16B16A16_UINT: 549 case PIPE_FORMAT_R16G16B16A16_SINT: 550 case PIPE_FORMAT_R16G16B16A16_FLOAT: 551 case PIPE_FORMAT_R16G16B16A16_SNORM: 552 case PIPE_FORMAT_R16G16B16A16_UNORM: 553 case PIPE_FORMAT_R32G32_UINT: 554 case PIPE_FORMAT_R32G32_SINT: 555 case PIPE_FORMAT_R32G32_FLOAT: 556 case PIPE_FORMAT_R32G32_UNORM: 557 case PIPE_FORMAT_R32G32_SNORM: 558 switch (dst) { 559 case PIPE_FORMAT_DXT1_RGBA: 560 case PIPE_FORMAT_DXT1_SRGBA: 561 case PIPE_FORMAT_DXT1_RGB: 562 case PIPE_FORMAT_DXT1_SRGB: 563 case PIPE_FORMAT_RGTC1_UNORM: 564 case PIPE_FORMAT_RGTC1_SNORM: 565 return 1; 566 default: 567 return -1; 568 } 569 default: 570 return 0; 571 } 572 } 573 574 static boolean format_compressed_compressed_copy_compatible(enum pipe_format src, enum pipe_format dst) 575 { 576 if ((src == PIPE_FORMAT_RGTC1_UNORM && dst == PIPE_FORMAT_RGTC1_SNORM) || 577 (src == PIPE_FORMAT_RGTC2_UNORM && dst == PIPE_FORMAT_RGTC2_SNORM) || 578 (src == PIPE_FORMAT_BPTC_RGBA_UNORM && dst == PIPE_FORMAT_BPTC_SRGBA) || 579 (src == PIPE_FORMAT_BPTC_RGB_FLOAT && dst == PIPE_FORMAT_BPTC_RGB_UFLOAT)) 580 return true; 581 return false; 582 } 583 584 boolean format_is_copy_compatible(enum pipe_format src, enum pipe_format dst, 585 boolean allow_compressed) 586 { 587 int r; 588 589 if (src == dst) 590 return true; 591 592 if (util_format_is_plain(src) && util_format_is_plain(dst)) { 593 const struct util_format_description *src_desc = util_format_description(src); 594 const struct util_format_description *dst_desc = util_format_description(dst); 595 return util_is_format_compatible(src_desc, dst_desc); 596 } 597 598 if (!allow_compressed) 599 return false; 600 601 /* compressed-uncompressed */ 602 r = format_uncompressed_compressed_copy_compatible(src, dst); 603 if (r) 604 return r > 0; 605 606 r = format_uncompressed_compressed_copy_compatible(dst, src); 607 if (r) 608 return r > 0; 609 610 return format_compressed_compressed_copy_compatible(dst, src); 611 } 612