Home | History | Annotate | Download | only in vc4
      1 /*
      2  * Copyright  2014 Broadcom
      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 /**
     25  * @file vc4_formats.c
     26  *
     27  * Contains the table and accessors for VC4 texture and render target format
     28  * support.
     29  *
     30  * The hardware has limited support for texture formats, and extremely limited
     31  * support for render target formats.  As a result, we emulate other formats
     32  * in our shader code, and this stores the table for doing so.
     33  */
     34 
     35 #include "util/u_format.h"
     36 #include "util/macros.h"
     37 
     38 #include "vc4_context.h"
     39 
     40 #define RT_NO        0
     41 #define RT_RGBA8888  1
     42 #define RT_RGB565    2
     43 
     44 struct vc4_format {
     45         /** Set if the pipe format is defined in the table. */
     46         bool present;
     47 
     48         /** Set to 0 if unsupported, 1 if RGBA8888, 2 if rgb565. */
     49         uint8_t rt_type;
     50 
     51         /** One of VC4_TEXTURE_TYPE_*. */
     52         uint8_t tex_type;
     53 
     54         /**
     55          * Swizzle to apply to the RGBA shader output for storing to the tile
     56          * buffer, to the RGBA tile buffer to produce shader input (for
     57          * blending), and for turning the rgba8888 texture sampler return
     58          * value into shader rgba values.
     59          */
     60         uint8_t swizzle[4];
     61 };
     62 
     63 #define SWIZ(x,y,z,w) {          \
     64         PIPE_SWIZZLE_##x, \
     65         PIPE_SWIZZLE_##y, \
     66         PIPE_SWIZZLE_##z, \
     67         PIPE_SWIZZLE_##w  \
     68 }
     69 
     70 #define FORMAT(pipe, rt, tex, swiz)                                     \
     71         [PIPE_FORMAT_##pipe] = { true, RT_##rt, VC4_TEXTURE_TYPE_##tex, swiz }
     72 
     73 static const struct vc4_format vc4_format_table[] = {
     74         FORMAT(R8G8B8A8_UNORM, RGBA8888, RGBA8888, SWIZ(X, Y, Z, W)),
     75         FORMAT(R8G8B8X8_UNORM, RGBA8888, RGBA8888, SWIZ(X, Y, Z, 1)),
     76         FORMAT(R8G8B8A8_SRGB,  RGBA8888, RGBA8888, SWIZ(X, Y, Z, W)),
     77         FORMAT(R8G8B8X8_SRGB,  RGBA8888, RGBA8888, SWIZ(X, Y, Z, 1)),
     78 
     79         FORMAT(B8G8R8A8_UNORM, RGBA8888, RGBA8888, SWIZ(Z, Y, X, W)),
     80         FORMAT(B8G8R8X8_UNORM, RGBA8888, RGBA8888, SWIZ(Z, Y, X, 1)),
     81         FORMAT(B8G8R8A8_SRGB, RGBA8888, RGBA8888, SWIZ(Z, Y, X, W)),
     82         FORMAT(B8G8R8X8_SRGB, RGBA8888, RGBA8888, SWIZ(Z, Y, X, 1)),
     83 
     84         FORMAT(B5G6R5_UNORM, RGB565, RGB565, SWIZ(X, Y, Z, 1)),
     85 
     86         FORMAT(ETC1_RGB8, NO, ETC1, SWIZ(X, Y, Z, 1)),
     87 
     88         /* Depth sampling will be handled by doing nearest filtering and not
     89          * unpacking the RGBA value.
     90          */
     91         FORMAT(S8_UINT_Z24_UNORM, NO, RGBA8888, SWIZ(X, Y, Z, W)),
     92         FORMAT(X8Z24_UNORM,       NO, RGBA8888, SWIZ(X, Y, Z, W)),
     93 
     94         FORMAT(B4G4R4A4_UNORM, NO, RGBA4444, SWIZ(Y, Z, W, X)),
     95         FORMAT(B4G4R4X4_UNORM, NO, RGBA4444, SWIZ(Y, Z, W, 1)),
     96 
     97         /* It looks like 5551 in the hardware is the other way around from
     98          * gallium.
     99          */
    100 
    101         FORMAT(A8_UNORM, NO, ALPHA, SWIZ(0, 0, 0, W)),
    102         FORMAT(L8_UNORM, NO, ALPHA, SWIZ(W, W, W, 1)),
    103         FORMAT(I8_UNORM, NO, ALPHA, SWIZ(W, W, W, W)),
    104         FORMAT(R8_UNORM, NO, ALPHA, SWIZ(W, 0, 0, 1)),
    105 
    106         FORMAT(L8A8_UNORM, NO, LUMALPHA, SWIZ(X, X, X, W)),
    107         FORMAT(R8G8_UNORM, NO, LUMALPHA, SWIZ(X, W, 0, 1)),
    108 };
    109 
    110 static const struct vc4_format *
    111 get_format(enum pipe_format f)
    112 {
    113         if (f >= ARRAY_SIZE(vc4_format_table) ||
    114             !vc4_format_table[f].present)
    115                 return NULL;
    116         else
    117                 return &vc4_format_table[f];
    118 }
    119 
    120 bool
    121 vc4_rt_format_supported(enum pipe_format f)
    122 {
    123         const struct vc4_format *vf = get_format(f);
    124 
    125         if (!vf)
    126                 return false;
    127 
    128         return vf->rt_type != RT_NO;
    129 }
    130 
    131 bool
    132 vc4_rt_format_is_565(enum pipe_format f)
    133 {
    134         const struct vc4_format *vf = get_format(f);
    135 
    136         if (!vf)
    137                 return false;
    138 
    139         return vf->rt_type == RT_RGB565;
    140 }
    141 
    142 bool
    143 vc4_tex_format_supported(enum pipe_format f)
    144 {
    145         const struct vc4_format *vf = get_format(f);
    146 
    147         return vf != NULL;
    148 }
    149 
    150 uint8_t
    151 vc4_get_tex_format(enum pipe_format f)
    152 {
    153         const struct vc4_format *vf = get_format(f);
    154 
    155         if (!vf)
    156                 return 0;
    157 
    158         return vf->tex_type;
    159 }
    160 
    161 const uint8_t *
    162 vc4_get_format_swizzle(enum pipe_format f)
    163 {
    164         const struct vc4_format *vf = get_format(f);
    165         static const uint8_t fallback[] = {0, 1, 2, 3};
    166 
    167         if (!vf)
    168                 return fallback;
    169 
    170         return vf->swizzle;
    171 }
    172