1/* 2 * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org> 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 FROM, 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 * SOFTWARE. 22 * 23 * Authors: 24 * Rob Clark <robclark@freedesktop.org> 25 */ 26 27#include "pipe/p_defines.h" 28#include "util/format/u_format.h" 29 30#include "fd2_util.h" 31 32static enum a2xx_sq_surfaceformat 33pipe2surface(enum pipe_format format, struct surface_format *fmt) 34{ 35 const struct util_format_description *desc = util_format_description(format); 36 37 if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) { 38 switch (format) { 39 /* Compressed textures. */ 40 case PIPE_FORMAT_ETC1_RGB8: 41 return FMT_ETC1_RGB; 42 case PIPE_FORMAT_DXT1_RGB: 43 case PIPE_FORMAT_DXT1_RGBA: 44 return FMT_DXT1; 45 case PIPE_FORMAT_DXT3_RGBA: 46 return FMT_DXT2_3; 47 case PIPE_FORMAT_DXT5_RGBA: 48 return FMT_DXT4_5; 49 case PIPE_FORMAT_ATC_RGB: 50 return FMT_ATI_TC_555_565_RGB; 51 case PIPE_FORMAT_ATC_RGBA_EXPLICIT: 52 return FMT_ATI_TC_555_565_RGBA; 53 case PIPE_FORMAT_ATC_RGBA_INTERPOLATED: 54 return FMT_ATI_TC_555_565_RGBA_INTERP; 55 /* YUV buffers. */ 56 case PIPE_FORMAT_UYVY: 57 return FMT_Y1_Cr_Y0_Cb; 58 case PIPE_FORMAT_YUYV: 59 return FMT_Cr_Y1_Cb_Y0; 60 default: 61 return ~0; 62 } 63 } 64 65 uint32_t channel_size = 0; 66 for (unsigned i = 0; i < 4; i++) 67 channel_size |= desc->channel[i].size << i * 8; 68 69 unsigned i = util_format_get_first_non_void_channel(format); 70 if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED || 71 desc->channel[i].type == UTIL_FORMAT_TYPE_FIXED) 72 fmt->sign = SQ_TEX_SIGN_SIGNED; 73 if (!desc->channel[i].normalized) 74 fmt->num_format = SQ_TEX_NUM_FORMAT_INT; 75 if (desc->channel[i].type == UTIL_FORMAT_TYPE_FIXED) 76 fmt->exp_adjust = -16; 77 78 /* Note: the 3 channel 24bpp/48bpp/96bpp formats are only for vertex fetch 79 * we can use the 4 channel format and ignore the 4th component just isn't 80 * used 81 * XXX: is it possible for the extra loaded component to cause a MMU fault? 82 */ 83 84#define CASE(r, g, b, a) case (r | g << 8 | b << 16 | a << 24) 85 86 /* clang-format off */ 87 if (desc->channel[0].type == UTIL_FORMAT_TYPE_FLOAT) { 88 switch (channel_size) { 89 CASE(16, 0, 0, 0): return FMT_16_FLOAT; 90 CASE(16, 16, 0, 0): return FMT_16_16_FLOAT; 91 CASE(16, 16, 16, 0): return FMT_16_16_16_16_FLOAT; /* Note: only for vertex */ 92 CASE(16, 16, 16, 16): return FMT_16_16_16_16_FLOAT; 93 CASE(32, 0, 0, 0): return FMT_32_FLOAT; 94 CASE(32, 32, 0, 0): return FMT_32_32_FLOAT; 95 CASE(32, 32, 32, 0): return FMT_32_32_32_FLOAT; 96 CASE(32, 32, 32, 32): return FMT_32_32_32_32_FLOAT; 97 } 98 } else { 99 switch (channel_size) { 100 CASE( 8, 0, 0, 0): return FMT_8; 101 CASE( 8, 8, 0, 0): return FMT_8_8; 102 CASE( 8, 8, 8, 0): return FMT_8_8_8_8; /* Note: only for vertex */ 103 CASE( 8, 8, 8, 8): return FMT_8_8_8_8; 104 CASE(16, 0, 0, 0): return FMT_16; 105 CASE(16, 16, 0, 0): return FMT_16_16; 106 CASE(16, 16, 16, 0): return FMT_16_16_16_16; /* Note: only for vertex */ 107 CASE(16, 16, 16, 16): return FMT_16_16_16_16; 108 CASE(32, 0, 0, 0): return FMT_32; 109 CASE(32, 32, 0, 0): return FMT_32_32; 110 CASE(32, 32, 32, 0): return FMT_32_32_32_32; /* Note: only for vertex */ 111 CASE(32, 32, 32, 32): return FMT_32_32_32_32; 112 CASE( 4, 4, 4, 4): return FMT_4_4_4_4; 113 CASE( 5, 5, 5, 1): return FMT_1_5_5_5; 114 CASE( 5, 6, 5, 0): return FMT_5_6_5; 115 CASE(10, 10, 10, 2): return FMT_2_10_10_10; 116 CASE( 8, 24, 0, 0): return FMT_24_8; 117 CASE( 2, 3, 3, 0): return FMT_2_3_3; /* Note: R/B swapped */ 118 } 119 } 120 /* clang-format on */ 121#undef CASE 122 123 return ~0; 124} 125 126struct surface_format 127fd2_pipe2surface(enum pipe_format format) 128{ 129 struct surface_format fmt = { 130 .sign = SQ_TEX_SIGN_UNSIGNED, 131 .num_format = SQ_TEX_NUM_FORMAT_FRAC, 132 .exp_adjust = 0, 133 }; 134 fmt.format = pipe2surface(format, &fmt); 135 return fmt; 136} 137 138enum a2xx_colorformatx 139fd2_pipe2color(enum pipe_format format) 140{ 141 switch (format) { 142 /* 8-bit buffers. */ 143 case PIPE_FORMAT_R8_UNORM: 144 return COLORX_8; 145 case PIPE_FORMAT_B2G3R3_UNORM: 146 return COLORX_2_3_3; /* note: untested */ 147 148 /* 16-bit buffers. */ 149 case PIPE_FORMAT_B5G6R5_UNORM: 150 return COLORX_5_6_5; 151 case PIPE_FORMAT_B5G5R5A1_UNORM: 152 case PIPE_FORMAT_B5G5R5X1_UNORM: 153 return COLORX_1_5_5_5; 154 case PIPE_FORMAT_B4G4R4A4_UNORM: 155 case PIPE_FORMAT_B4G4R4X4_UNORM: 156 return COLORX_4_4_4_4; 157 case PIPE_FORMAT_R8G8_UNORM: 158 return COLORX_8_8; 159 160 /* 32-bit buffers. */ 161 case PIPE_FORMAT_B8G8R8A8_UNORM: 162 case PIPE_FORMAT_B8G8R8X8_UNORM: 163 case PIPE_FORMAT_R8G8B8A8_UNORM: 164 case PIPE_FORMAT_R8G8B8X8_UNORM: 165 return COLORX_8_8_8_8; 166 /* Note: snorm untested */ 167 case PIPE_FORMAT_R8G8B8A8_SNORM: 168 case PIPE_FORMAT_R8G8B8X8_SNORM: 169 return COLORX_S8_8_8_8; 170 171 /* float buffers */ 172 case PIPE_FORMAT_R16_FLOAT: 173 return COLORX_16_FLOAT; 174 case PIPE_FORMAT_R16G16_FLOAT: 175 return COLORX_16_16_FLOAT; 176 case PIPE_FORMAT_R16G16B16A16_FLOAT: 177 return COLORX_16_16_16_16_FLOAT; 178 case PIPE_FORMAT_R32_FLOAT: 179 return COLORX_32_FLOAT; 180 case PIPE_FORMAT_R32G32_FLOAT: 181 return COLORX_32_32_FLOAT; 182 case PIPE_FORMAT_R32G32B32A32_FLOAT: 183 return COLORX_32_32_32_32_FLOAT; 184 185 default: 186 return ~0; 187 } 188} 189 190static inline enum sq_tex_swiz 191tex_swiz(unsigned swiz) 192{ 193 switch (swiz) { 194 default: 195 case PIPE_SWIZZLE_X: 196 return SQ_TEX_X; 197 case PIPE_SWIZZLE_Y: 198 return SQ_TEX_Y; 199 case PIPE_SWIZZLE_Z: 200 return SQ_TEX_Z; 201 case PIPE_SWIZZLE_W: 202 return SQ_TEX_W; 203 case PIPE_SWIZZLE_0: 204 return SQ_TEX_ZERO; 205 case PIPE_SWIZZLE_1: 206 return SQ_TEX_ONE; 207 } 208} 209 210uint32_t 211fd2_tex_swiz(enum pipe_format format, unsigned swizzle_r, unsigned swizzle_g, 212 unsigned swizzle_b, unsigned swizzle_a) 213{ 214 const struct util_format_description *desc = util_format_description(format); 215 unsigned char swiz[4] = { 216 swizzle_r, 217 swizzle_g, 218 swizzle_b, 219 swizzle_a, 220 }, rswiz[4]; 221 222 util_format_compose_swizzles(desc->swizzle, swiz, rswiz); 223 224 return A2XX_SQ_TEX_3_SWIZ_X(tex_swiz(rswiz[0])) | 225 A2XX_SQ_TEX_3_SWIZ_Y(tex_swiz(rswiz[1])) | 226 A2XX_SQ_TEX_3_SWIZ_Z(tex_swiz(rswiz[2])) | 227 A2XX_SQ_TEX_3_SWIZ_W(tex_swiz(rswiz[3])); 228} 229 230uint32_t 231fd2_vtx_swiz(enum pipe_format format, unsigned swizzle) 232{ 233 const struct util_format_description *desc = util_format_description(format); 234 unsigned char swiz[4], rswiz[4]; 235 236 for (unsigned i = 0; i < 4; i++) 237 swiz[i] = (swizzle >> i * 3) & 7; 238 239 util_format_compose_swizzles(desc->swizzle, swiz, rswiz); 240 241 return rswiz[0] | rswiz[1] << 3 | rswiz[2] << 6 | rswiz[3] << 9; 242} 243