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