• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <cstdint>
2 #include <cstdio>
3 #include <cstdlib>
4 #include <array>
5 #include <memory>
6 
7 #include <gtest/gtest.h>
8 
9 #include "GL/osmesa.h"
10 #include "util/macros.h"
11 #include "util/u_endian.h"
12 #include "util/u_math.h"
13 
14 typedef struct {
15    unsigned format;
16    GLenum type;
17    int bpp;
18    uint64_t expected;
19 } Params;
20 
21 class OSMesaRenderTestFixture : public testing::TestWithParam<Params> {};
22 
23 std::string
name_params(const testing::TestParamInfo<Params> params)24 name_params(const testing::TestParamInfo<Params> params) {
25    auto p = params.param;
26    std::string first, second;
27    switch (p.format) {
28    case OSMESA_RGBA:
29       first = "rgba";
30       break;
31    case OSMESA_BGRA:
32       first = "bgra";
33       break;
34    case OSMESA_RGB:
35       first = "rgb";
36       break;
37    case OSMESA_RGB_565:
38       first = "rgb_565";
39       break;
40    case OSMESA_ARGB:
41       first = "argb";
42       break;
43    }
44 
45    switch (p.type) {
46    case GL_UNSIGNED_SHORT:
47       second = "unsigned_short";
48       break;
49    case GL_UNSIGNED_BYTE:
50       second = "unsigned_byte";
51       break;
52    case GL_FLOAT:
53       second = "float";
54       break;
55    case GL_UNSIGNED_SHORT_5_6_5:
56       second = "unsigned_short_565";
57       break;
58    }
59 
60    return first + "_" + second;
61 };
62 
TEST_P(OSMesaRenderTestFixture,Render)63 TEST_P(OSMesaRenderTestFixture, Render)
64 {
65    auto p = GetParam();
66    const int w = 2, h = 2;
67    uint8_t pixels[w * h * 8] = { 0 };
68 
69    std::unique_ptr<osmesa_context, decltype(&OSMesaDestroyContext)> ctx{
70       OSMesaCreateContext(p.format, NULL), &OSMesaDestroyContext};
71    ASSERT_TRUE(ctx);
72 
73    auto ret = OSMesaMakeCurrent(ctx.get(), &pixels, p.type, w, h);
74    ASSERT_EQ(ret, GL_TRUE);
75 
76    glClearColor(0.25, 1.0, 0.5, 0.75);
77 
78    uint64_t expected = p.expected;
79 
80    /* All the formats other than 565 and RGB/byte are array formats, but our
81     * expected values are packed, so byte swap appropriately.
82     */
83    if (UTIL_ARCH_BIG_ENDIAN) {
84       switch (p.bpp) {
85       case 8:
86          expected = util_bswap64(expected);
87          break;
88 
89       case 4:
90          expected = util_bswap32(expected);
91          break;
92 
93       case 3:
94       case 2:
95          break;
96       }
97    }
98 
99    glClear(GL_COLOR_BUFFER_BIT);
100    glFinish();
101 
102 #if 0 /* XXX */
103    for (unsigned i = 0; i < ARRAY_SIZE(pixels); i += 4) {
104       fprintf(stderr, "pixel %d: %02x %02x %02x %02x\n",
105               i / 4,
106               pixels[i + 0],
107               pixels[i + 1],
108               pixels[i + 2],
109               pixels[i + 3]);
110    }
111 #endif
112 
113    for (unsigned i = 0; i < w * h; i++) {
114       switch (p.bpp) {
115       case 2: {
116          uint16_t color = 0;
117          memcpy(&color, &pixels[i * p.bpp], p.bpp);
118          ASSERT_EQ(expected, color);
119          break;
120       }
121 
122       case 3: {
123          uint32_t color = ((pixels[i * p.bpp + 0] << 0) |
124                            (pixels[i * p.bpp + 1] << 8) |
125                            (pixels[i * p.bpp + 2] << 16));
126          ASSERT_EQ(expected, color);
127          break;
128       }
129 
130       case 4: {
131          uint32_t color = 0;
132          memcpy(&color, &pixels[i * p.bpp], p.bpp);
133          ASSERT_EQ(expected, color);
134          break;
135       }
136 
137       case 8: {
138          uint64_t color = 0;
139          memcpy(&color, &pixels[i * p.bpp], p.bpp);
140          ASSERT_EQ(expected, color);
141          break;
142       }
143 
144       default:
145          unreachable("bad bpp");
146       }
147    }
148 }
149 
150 INSTANTIATE_TEST_CASE_P(
151    OSMesaRenderTest,
152    OSMesaRenderTestFixture,
153    testing::Values(
154       Params{ OSMESA_RGBA, GL_UNSIGNED_BYTE,  4, 0xbf80ff40 },
155       Params{ OSMESA_BGRA, GL_UNSIGNED_BYTE,  4, 0xbf40ff80 },
156       Params{ OSMESA_ARGB, GL_UNSIGNED_BYTE,  4, 0x80ff40bf},
157       Params{ OSMESA_RGB,  GL_UNSIGNED_BYTE,  3, 0x80ff40 },
158       Params{ OSMESA_RGBA, GL_UNSIGNED_SHORT, 8, 0xbfff8000ffff4000ull },
159       Params{ OSMESA_RGB_565, GL_UNSIGNED_SHORT_5_6_5, 2, ((0x10 << 0) |
160                                                            (0x3f << 5) |
161                                                            (0x8 << 11)) }
162    ),
163    name_params
164 );
165