Home | History | Annotate | Download | only in src
      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