1/* 2 * Copyright © 2015 Intel Corporation 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 21 * DEALINGS IN THE SOFTWARE. 22 */ 23 24/** 25 * \name mesa_formats.cpp 26 * 27 * Verify that all mesa formats are handled in certain functions and that 28 * the format info table is sane. 29 * 30 */ 31 32#include <gtest/gtest.h> 33 34#include "main/formats.h" 35#include "main/glformats.h" 36#include "main/format_unpack.h" 37#include "main/format_pack.h" 38 39/** 40 * Debug/test: check that all uncompressed formats are handled in the 41 * _mesa_uncompressed_format_to_type_and_comps() function. When new pixel 42 * formats are added to Mesa, that function needs to be updated. 43 */ 44TEST(MesaFormatsTest, FormatTypeAndComps) 45{ 46 for (int fi = MESA_FORMAT_NONE + 1; fi < MESA_FORMAT_COUNT; ++fi) { 47 mesa_format f = (mesa_format) fi; 48 SCOPED_TRACE(_mesa_get_format_name(f)); 49 50 if (!_mesa_get_format_name(f)) 51 continue; 52 53 /* This function will emit a problem/warning if the format is 54 * not handled. 55 */ 56 if (!_mesa_is_format_compressed(f)) { 57 GLenum datatype = 0; 58 GLuint comps = 0; 59 60 /* If the datatype is zero, the format was not handled */ 61 _mesa_uncompressed_format_to_type_and_comps(f, &datatype, &comps); 62 EXPECT_NE(datatype, (GLenum)0); 63 } 64 65 } 66} 67 68/** 69 * Do sanity checking of the format info table. 70 */ 71TEST(MesaFormatsTest, FormatSanity) 72{ 73 for (int fi = 0; fi < MESA_FORMAT_COUNT; ++fi) { 74 mesa_format f = (mesa_format) fi; 75 SCOPED_TRACE(_mesa_get_format_name(f)); 76 if (!_mesa_get_format_name(f)) 77 continue; 78 79 GLenum datatype = _mesa_get_format_datatype(f); 80 GLint r = _mesa_get_format_bits(f, GL_RED_BITS); 81 GLint g = _mesa_get_format_bits(f, GL_GREEN_BITS); 82 GLint b = _mesa_get_format_bits(f, GL_BLUE_BITS); 83 GLint a = _mesa_get_format_bits(f, GL_ALPHA_BITS); 84 GLint l = _mesa_get_format_bits(f, GL_TEXTURE_LUMINANCE_SIZE); 85 GLint i = _mesa_get_format_bits(f, GL_TEXTURE_INTENSITY_SIZE); 86 87 /* Note: Z32_FLOAT_X24S8 has datatype of GL_NONE */ 88 EXPECT_TRUE(datatype == GL_NONE || 89 datatype == GL_UNSIGNED_NORMALIZED || 90 datatype == GL_SIGNED_NORMALIZED || 91 datatype == GL_UNSIGNED_INT || 92 datatype == GL_INT || 93 datatype == GL_FLOAT); 94 95 if (r > 0 && !_mesa_is_format_compressed(f)) { 96 GLint bytes = _mesa_get_format_bytes(f); 97 EXPECT_LE((r+g+b+a) / 8, bytes); 98 } 99 100 /* Determines if the base format has a channel [rgba] or property [li]. 101 * > indicates existance 102 * == indicates non-existance 103 */ 104 #define HAS_PROP(rop,gop,bop,aop,lop,iop) \ 105 do { \ 106 EXPECT_TRUE(r rop 0); \ 107 EXPECT_TRUE(g gop 0); \ 108 EXPECT_TRUE(b bop 0); \ 109 EXPECT_TRUE(a aop 0); \ 110 EXPECT_TRUE(l lop 0); \ 111 EXPECT_TRUE(i iop 0); \ 112 } while(0) 113 114 switch (_mesa_get_format_base_format(f)) { 115 case GL_RGBA: 116 HAS_PROP(>,>,>,>,==,==); 117 break; 118 case GL_RGB: 119 HAS_PROP(>,>,>,==,==,==); 120 break; 121 case GL_RG: 122 HAS_PROP(>,>,==,==,==,==); 123 break; 124 case GL_RED: 125 HAS_PROP(>,==,==,==,==,==); 126 break; 127 case GL_LUMINANCE: 128 HAS_PROP(==,==,==,==,>,==); 129 break; 130 case GL_INTENSITY: 131 HAS_PROP(==,==,==,==,==,>); 132 break; 133 default: 134 break; 135 } 136 137 #undef HAS_PROP 138 139 } 140} 141 142TEST(MesaFormatsTest, IntensityToRed) 143{ 144 EXPECT_EQ(_mesa_get_intensity_format_red(MESA_FORMAT_I_UNORM8), 145 MESA_FORMAT_R_UNORM8); 146 EXPECT_EQ(_mesa_get_intensity_format_red(MESA_FORMAT_I_SINT32), 147 MESA_FORMAT_R_SINT32); 148 EXPECT_EQ(_mesa_get_intensity_format_red(MESA_FORMAT_R8G8B8A8_UNORM), 149 MESA_FORMAT_R8G8B8A8_UNORM); 150} 151 152static mesa_format fffat_wrap(GLenum format, GLenum type) 153{ 154 uint32_t f = _mesa_format_from_format_and_type(format, type); 155 if (_mesa_format_is_mesa_array_format(f)) 156 f = _mesa_format_from_array_format((mesa_array_format)f); 157 return (mesa_format)f; 158} 159 160TEST(MesaFormatsTest, FormatFromFormatAndType) 161{ 162 EXPECT_EQ(fffat_wrap(GL_RGBA, GL_SHORT), 163 MESA_FORMAT_RGBA_SNORM16); 164 EXPECT_EQ(fffat_wrap(GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT), 165 MESA_FORMAT_Z_UNORM16); 166 EXPECT_EQ(fffat_wrap(GL_STENCIL_INDEX, GL_UNSIGNED_BYTE), 167 MESA_FORMAT_S_UINT8); 168 169 /* Should return an array format, but not a proper MESA_FORMAT. */ 170 EXPECT_TRUE(_mesa_format_is_mesa_array_format(_mesa_format_from_format_and_type(GL_DEPTH_COMPONENT, 171 GL_BYTE))); 172} 173 174TEST(MesaFormatsTest, FormatMatchesFormatAndType) 175{ 176 EXPECT_TRUE(_mesa_format_matches_format_and_type(MESA_FORMAT_RGBA_UNORM16, 177 GL_RGBA, 178 GL_UNSIGNED_SHORT, false, 179 NULL)); 180 EXPECT_TRUE(_mesa_format_matches_format_and_type(MESA_FORMAT_S_UINT8, 181 GL_STENCIL_INDEX, 182 GL_UNSIGNED_BYTE, false, 183 NULL)); 184 EXPECT_TRUE(_mesa_format_matches_format_and_type(MESA_FORMAT_Z_UNORM16, 185 GL_DEPTH_COMPONENT, 186 GL_UNSIGNED_SHORT, false, 187 NULL)); 188} 189 190static uint32_t 191test_unpack_r8i(int8_t val) 192{ 193 uint32_t result[4]; 194 _mesa_unpack_uint_rgba_row(MESA_FORMAT_R_SINT8, 1, &val, &result); 195 return result[0]; 196} 197 198static uint32_t 199test_unpack_r32ui(uint32_t val) 200{ 201 uint32_t result[4]; 202 _mesa_unpack_uint_rgba_row(MESA_FORMAT_R_UINT32, 1, &val, &result); 203 return result[0]; 204} 205 206TEST(MesaFormatsTest, UnpackRGBAUintRow) 207{ 208 EXPECT_EQ(test_unpack_r8i(0), 0); 209 EXPECT_EQ(test_unpack_r8i(1), 1); 210 EXPECT_EQ(test_unpack_r8i(0xff), 0xffffffff); 211 EXPECT_EQ(test_unpack_r32ui(0), 0); 212 EXPECT_EQ(test_unpack_r32ui(0xffffffff), 0xffffffff); 213} 214 215TEST(MesaFormatsTest, UnpackRGBAUbyteRowRGBA32F) 216{ 217 float val[4] = {0, 0.5, -1, 2}; 218 uint8_t result[4]; 219 _mesa_unpack_ubyte_rgba_row(MESA_FORMAT_RGBA_FLOAT32, 1, &val, &result); 220 EXPECT_EQ(result[0], 0); 221 EXPECT_EQ(result[1], 0x80); 222 EXPECT_EQ(result[2], 0); 223 EXPECT_EQ(result[3], 0xff); 224} 225 226TEST(MesaFormatsTest, UnpackRGBAUbyteRowRGBA4) 227{ 228 uint16_t val = (1 << 0) | (0x3f << 5) | (0x10 << 11); 229 uint8_t result[4]; 230 _mesa_unpack_ubyte_rgba_row(MESA_FORMAT_R5G6B5_UNORM, 1, &val, &result); 231 EXPECT_EQ(result[0], 0x08); 232 EXPECT_EQ(result[1], 0xff); 233 EXPECT_EQ(result[2], 0x84); 234 EXPECT_EQ(result[3], 0xff); 235} 236 237static float 238test_unpack_floatz_z32f(float val) 239{ 240 float result; 241 _mesa_unpack_float_z_row(MESA_FORMAT_Z_FLOAT32, 1, &val, &result); 242 return result; 243} 244 245TEST(MesaFormatsTest, UnpackFloatZRow) 246{ 247 EXPECT_EQ(test_unpack_floatz_z32f(0.5), 0.5); 248 EXPECT_EQ(test_unpack_floatz_z32f(-1.0), -1.0); 249 EXPECT_EQ(test_unpack_floatz_z32f(2.0), 2.0); 250} 251 252static uint32_t 253test_unpack_uintz_z32f(float val) 254{ 255 uint32_t result; 256 _mesa_unpack_uint_z_row(MESA_FORMAT_Z_FLOAT32, 1, &val, &result); 257 return result; 258} 259 260TEST(MesaFormatsTest, UnpackUintZRow) 261{ 262 EXPECT_EQ(test_unpack_uintz_z32f(0.5), 0x7fffffff); 263 EXPECT_EQ(test_unpack_uintz_z32f(-1.0), 0); 264 EXPECT_EQ(test_unpack_uintz_z32f(2.0), 0xffffffff); 265} 266 267/* It's easy to have precision issues packing 32-bit floats to unorm. */ 268TEST(MesaFormatsTest, PackFloatZ) 269{ 270 float val = 0.571428597f; 271 uint32_t result; 272 _mesa_pack_float_z_row(MESA_FORMAT_Z_UNORM32, 1, &val, &result); 273 EXPECT_EQ(result, 0x924924ff); 274} 275 276TEST(MesaFormatsTest, PackUbyteRGBARounding) 277{ 278 for (int i = 0; i <= 255; i++) { 279 uint8_t val[4] = {(uint8_t)i, 0, 0, 0}; 280 uint16_t result; 281 _mesa_pack_ubyte_rgba_row(MESA_FORMAT_R5G6B5_UNORM, 1, val, &result); 282 EXPECT_EQ(result, (i * 31 + 127) / 255); 283 } 284} 285