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