~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/glx/tests/query_renderer_unittest.cpp

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright © 2013 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
 
#include <gtest/gtest.h>
24
 
#include <signal.h>
25
 
#include <setjmp.h>
26
 
 
27
 
#include "glxclient.h"
28
 
#include "glx_error.h"
29
 
 
30
 
extern bool GetGLXScreenConfigs_called;
31
 
extern struct glx_screen *psc;
32
 
 
33
 
struct attribute_test_vector {
34
 
   const char *string;
35
 
   int value;
36
 
};
37
 
 
38
 
#define E(x) { # x, x }
39
 
 
40
 
 
41
 
 
42
 
static bool got_sigsegv;
43
 
static jmp_buf jmp;
44
 
 
45
 
static void
46
 
sigsegv_handler(int sig)
47
 
{
48
 
   (void) sig;
49
 
   got_sigsegv = true;
50
 
   longjmp(jmp, 1);
51
 
}
52
 
 
53
 
static bool query_renderer_string_called = false;
54
 
static bool query_renderer_integer_called = false;
55
 
 
56
 
static int
57
 
fake_query_renderer_integer(struct glx_screen *psc, int attribute,
58
 
                            unsigned int *value)
59
 
{
60
 
   (void) psc;
61
 
   (void) attribute;
62
 
   (void) value;
63
 
 
64
 
   query_renderer_integer_called = true;
65
 
 
66
 
   return -1;
67
 
}
68
 
 
69
 
static int
70
 
fake_query_renderer_string(struct glx_screen *psc, int attribute,
71
 
                           const char **value)
72
 
{
73
 
   (void) psc;
74
 
   (void) attribute;
75
 
   (void) value;
76
 
 
77
 
   query_renderer_string_called = true;
78
 
 
79
 
   return -1;
80
 
}
81
 
 
82
 
struct glx_screen_vtable fake_vtable = {
83
 
   NULL,
84
 
   NULL,
85
 
   fake_query_renderer_integer,
86
 
   fake_query_renderer_string
87
 
};
88
 
 
89
 
class query_renderer_string_test : public ::testing::Test {
90
 
public:
91
 
   virtual void SetUp();
92
 
   virtual void TearDown();
93
 
 
94
 
   struct glx_screen scr;
95
 
   struct sigaction sa;
96
 
   struct sigaction old_sa;
97
 
   Display dpy;
98
 
};
99
 
 
100
 
class query_renderer_integer_test : public query_renderer_string_test {
101
 
};
102
 
 
103
 
void query_renderer_string_test::SetUp()
104
 
{
105
 
   memset(&scr, 0, sizeof(scr));
106
 
   scr.vtable = &fake_vtable;
107
 
   psc = &scr;
108
 
 
109
 
   got_sigsegv = false;
110
 
 
111
 
   sa.sa_handler = sigsegv_handler;
112
 
   sigemptyset(&sa.sa_mask);
113
 
   sa.sa_flags = 0;
114
 
   sigaction(SIGSEGV, &sa, &old_sa);
115
 
}
116
 
 
117
 
void query_renderer_string_test::TearDown()
118
 
{
119
 
   sigaction(SIGSEGV, &old_sa, NULL);
120
 
}
121
 
 
122
 
/**
123
 
 * glXQueryRendererStringMESA will return \c NULL if the query_render_string
124
 
 * vtable entry is \c NULL.  It will also not segfault.
125
 
 */
126
 
TEST_F(query_renderer_string_test, null_query_render_string)
127
 
{
128
 
   struct glx_screen_vtable vtable = {
129
 
      NULL,
130
 
      NULL,
131
 
      NULL,
132
 
      NULL
133
 
   };
134
 
 
135
 
   scr.vtable = &vtable;
136
 
 
137
 
   if (setjmp(jmp) == 0) {
138
 
      const char *str =
139
 
         glXQueryRendererStringMESA(&dpy, 0, 0, GLX_RENDERER_VENDOR_ID_MESA);
140
 
      EXPECT_EQ((char *)0, str);
141
 
   } else {
142
 
      EXPECT_FALSE(got_sigsegv);
143
 
   }
144
 
}
145
 
 
146
 
/**
147
 
 * glXQueryRendererStringMESA will not call the screen query_render_string
148
 
 * function with an invalid GLX enum value, and it will return NULL.
149
 
 */
150
 
TEST_F(query_renderer_string_test, invalid_attribute)
151
 
{
152
 
   static const attribute_test_vector invalid_attributes[] = {
153
 
      /* These values are just plain invalid for use with this extension.
154
 
       */
155
 
      E(0),
156
 
      E(GLX_VENDOR),
157
 
      E(GLX_VERSION),
158
 
      E(GLX_EXTENSIONS),
159
 
      E(GLX_RENDERER_VENDOR_ID_MESA + 0x10000),
160
 
      E(GLX_RENDERER_DEVICE_ID_MESA + 0x10000),
161
 
 
162
 
      /* These enums are part of the extension, but they are not allowed for
163
 
       * the string query.
164
 
       */
165
 
      E(GLX_RENDERER_VERSION_MESA),
166
 
      E(GLX_RENDERER_ACCELERATED_MESA),
167
 
      E(GLX_RENDERER_VIDEO_MEMORY_MESA),
168
 
      E(GLX_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_MESA),
169
 
      E(GLX_RENDERER_PREFERRED_PROFILE_MESA),
170
 
      E(GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA),
171
 
      E(GLX_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_MESA),
172
 
      E(GLX_RENDERER_OPENGL_ES_PROFILE_VERSION_MESA),
173
 
      E(GLX_RENDERER_OPENGL_ES2_PROFILE_VERSION_MESA),
174
 
   };
175
 
 
176
 
   for (unsigned i = 0; i < ARRAY_SIZE(invalid_attributes); i++) {
177
 
      query_renderer_integer_called = false;
178
 
      query_renderer_string_called = false;
179
 
 
180
 
      const char *str =
181
 
         glXQueryRendererStringMESA(&dpy, 0, 0, invalid_attributes[i].value);
182
 
      EXPECT_EQ((char *)0, str) << invalid_attributes[i].string;
183
 
      EXPECT_FALSE(query_renderer_integer_called)
184
 
         << invalid_attributes[i].string;
185
 
      EXPECT_FALSE(query_renderer_string_called)
186
 
         << invalid_attributes[i].string;
187
 
   }
188
 
}
189
 
 
190
 
/**
191
 
 * glXQueryRendererStringMESA will not call GetGLXScreenConfigs if the display
192
 
 * pointer is \c NULL.  It will also not segfault.
193
 
 */
194
 
TEST_F(query_renderer_string_test, null_display_pointer)
195
 
{
196
 
   if (setjmp(jmp) == 0) {
197
 
      GetGLXScreenConfigs_called = false;
198
 
 
199
 
      const char *str =
200
 
         glXQueryRendererStringMESA(NULL, 0, 0, GLX_RENDERER_VENDOR_ID_MESA);
201
 
      EXPECT_EQ((char *)0, str);
202
 
      EXPECT_FALSE(GetGLXScreenConfigs_called);
203
 
   } else {
204
 
      EXPECT_FALSE(got_sigsegv);
205
 
   }
206
 
}
207
 
 
208
 
/**
209
 
 * glXQueryRendererStringMESA will return error if GetGLXScreenConfigs returns
210
 
 * NULL.  It will also not segfault.
211
 
 */
212
 
TEST_F(query_renderer_string_test, null_screen_pointer)
213
 
{
214
 
   psc = NULL;
215
 
 
216
 
   if (setjmp(jmp) == 0) {
217
 
      GetGLXScreenConfigs_called = false;
218
 
 
219
 
      const char *str =
220
 
         glXQueryRendererStringMESA(&dpy, 0, 0, GLX_RENDERER_VENDOR_ID_MESA);
221
 
      EXPECT_EQ((char *)0, str);
222
 
      EXPECT_TRUE(GetGLXScreenConfigs_called);
223
 
   } else {
224
 
      EXPECT_FALSE(got_sigsegv);
225
 
   }
226
 
}
227
 
 
228
 
/**
229
 
 * glXQueryRendererStringMESA will not call the screen query_render_string
230
 
 * function if the renderer is invalid, and it will return NULL.
231
 
 */
232
 
TEST_F(query_renderer_string_test, invalid_renderer_index)
233
 
{
234
 
   static const int invalid_renderer_indices[] = {
235
 
      -1,
236
 
      1,
237
 
      999,
238
 
   };
239
 
 
240
 
   if (setjmp(jmp) == 0) {
241
 
      for (unsigned i = 0; i < ARRAY_SIZE(invalid_renderer_indices); i++) {
242
 
         const char *str =
243
 
            glXQueryRendererStringMESA(&dpy, 0,
244
 
                                       invalid_renderer_indices[i],
245
 
                                       GLX_RENDERER_VENDOR_ID_MESA);
246
 
         EXPECT_EQ((char *)0, str) << invalid_renderer_indices[i];
247
 
         EXPECT_FALSE(query_renderer_integer_called)
248
 
            << invalid_renderer_indices[i];
249
 
         EXPECT_FALSE(query_renderer_string_called)
250
 
            << invalid_renderer_indices[i];
251
 
      }
252
 
   } else {
253
 
      EXPECT_FALSE(got_sigsegv);
254
 
   }
255
 
}
256
 
 
257
 
/**
258
 
 * glXQueryCurrentRendererStringMESA will return error if there is no context
259
 
 * current.  It will also not segfault.
260
 
 */
261
 
TEST_F(query_renderer_string_test, no_current_context)
262
 
{
263
 
   if (setjmp(jmp) == 0) {
264
 
      const char *str =
265
 
         glXQueryCurrentRendererStringMESA(GLX_RENDERER_VENDOR_ID_MESA);
266
 
      EXPECT_EQ((char *)0, str);
267
 
   } else {
268
 
      EXPECT_FALSE(got_sigsegv);
269
 
   }
270
 
}
271
 
 
272
 
/**
273
 
 * glXQueryCurrentRendererIntegerMESA will return \c NULL if the
274
 
 * query_render_string vtable entry is \c NULL.  It will also not segfault.
275
 
 */
276
 
TEST_F(query_renderer_integer_test, null_query_render_string)
277
 
{
278
 
   struct glx_screen_vtable vtable = {
279
 
      NULL,
280
 
      NULL,
281
 
      NULL,
282
 
      NULL
283
 
   };
284
 
 
285
 
   scr.vtable = &vtable;
286
 
 
287
 
   if (setjmp(jmp) == 0) {
288
 
      unsigned value = 0xDEADBEEF;
289
 
      Bool success = glXQueryRendererIntegerMESA(&dpy, 0, 0,
290
 
                                                 GLX_RENDERER_VENDOR_ID_MESA,
291
 
                                                 &value);
292
 
      EXPECT_FALSE(success);
293
 
      EXPECT_EQ(0xDEADBEEF, value);
294
 
   } else {
295
 
      EXPECT_FALSE(got_sigsegv);
296
 
   }
297
 
}
298
 
 
299
 
/**
300
 
 * glXQueryCurrentRendererIntegerMESA will not call the screen
301
 
 * query_render_string function with an invalid GLX enum value, and it will
302
 
 * return NULL.
303
 
 */
304
 
TEST_F(query_renderer_integer_test, invalid_attribute)
305
 
{
306
 
   static const attribute_test_vector invalid_attributes[] = {
307
 
      /* These values are just plain invalid for use with this extension.
308
 
       */
309
 
      E(0),
310
 
      E(GLX_VENDOR),
311
 
      E(GLX_VERSION),
312
 
      E(GLX_EXTENSIONS),
313
 
      E(GLX_RENDERER_VENDOR_ID_MESA + 0x10000),
314
 
      E(GLX_RENDERER_DEVICE_ID_MESA + 0x10000),
315
 
      E(GLX_RENDERER_VERSION_MESA + 0x10000),
316
 
      E(GLX_RENDERER_ACCELERATED_MESA + 0x10000),
317
 
      E(GLX_RENDERER_VIDEO_MEMORY_MESA + 0x10000),
318
 
      E(GLX_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_MESA + 0x10000),
319
 
      E(GLX_RENDERER_PREFERRED_PROFILE_MESA + 0x10000),
320
 
      E(GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA + 0x10000),
321
 
      E(GLX_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_MESA + 0x10000),
322
 
      E(GLX_RENDERER_OPENGL_ES_PROFILE_VERSION_MESA + 0x10000),
323
 
      E(GLX_RENDERER_OPENGL_ES2_PROFILE_VERSION_MESA + 0x10000),
324
 
   };
325
 
 
326
 
   for (unsigned i = 0; i < ARRAY_SIZE(invalid_attributes); i++) {
327
 
      query_renderer_integer_called = false;
328
 
      query_renderer_string_called = false;
329
 
 
330
 
      unsigned value = 0xDEADBEEF;
331
 
      Bool success =
332
 
         glXQueryRendererIntegerMESA(&dpy, 0, 0,
333
 
                                     invalid_attributes[i].value,
334
 
                                     &value);
335
 
      EXPECT_FALSE(success) << invalid_attributes[i].string;
336
 
      EXPECT_EQ(0xDEADBEEF, value) << invalid_attributes[i].string;
337
 
      EXPECT_FALSE(query_renderer_integer_called)
338
 
         << invalid_attributes[i].string;
339
 
      EXPECT_FALSE(query_renderer_string_called)
340
 
         << invalid_attributes[i].string;
341
 
   }
342
 
}
343
 
 
344
 
/**
345
 
 * glXQueryCurrentRendererIntegerMESA will not call GetGLXScreenConfigs if the
346
 
 * display pointer is \c NULL.  It will also not segfault.
347
 
 */
348
 
TEST_F(query_renderer_integer_test, null_display_pointer)
349
 
{
350
 
   if (setjmp(jmp) == 0) {
351
 
      GetGLXScreenConfigs_called = false;
352
 
 
353
 
      unsigned value = 0xDEADBEEF;
354
 
      Bool success =
355
 
         glXQueryRendererIntegerMESA(NULL, 0, 0, GLX_RENDERER_VENDOR_ID_MESA,
356
 
                                     &value);
357
 
      EXPECT_FALSE(success);
358
 
      EXPECT_EQ(0xDEADBEEF, value);
359
 
      EXPECT_FALSE(GetGLXScreenConfigs_called);
360
 
   } else {
361
 
      EXPECT_FALSE(got_sigsegv);
362
 
   }
363
 
}
364
 
 
365
 
/**
366
 
 * glXQueryCurrentRendererIntegerMESA will return error if GetGLXScreenConfigs
367
 
 * returns NULL.  It will also not segfault.
368
 
 */
369
 
TEST_F(query_renderer_integer_test, null_screen_pointer)
370
 
{
371
 
   psc = NULL;
372
 
 
373
 
   if (setjmp(jmp) == 0) {
374
 
      GetGLXScreenConfigs_called = false;
375
 
 
376
 
      unsigned value = 0xDEADBEEF;
377
 
      Bool success =
378
 
         glXQueryRendererIntegerMESA(&dpy, 0, 0, GLX_RENDERER_VENDOR_ID_MESA,
379
 
            &value);
380
 
      EXPECT_FALSE(success);
381
 
      EXPECT_EQ(0xDEADBEEF, value);
382
 
      EXPECT_TRUE(GetGLXScreenConfigs_called);
383
 
   } else {
384
 
      EXPECT_FALSE(got_sigsegv);
385
 
   }
386
 
}
387
 
 
388
 
/**
389
 
 * glXQueryRendererIntegerMESA will not call the screen query_render_integer
390
 
 * function if the renderer is invalid, and it will return NULL.
391
 
 */
392
 
TEST_F(query_renderer_integer_test, invalid_renderer_index)
393
 
{
394
 
   static const int invalid_renderer_indices[] = {
395
 
      -1,
396
 
      1,
397
 
      999,
398
 
   };
399
 
 
400
 
   if (setjmp(jmp) == 0) {
401
 
      for (unsigned i = 0; i < ARRAY_SIZE(invalid_renderer_indices); i++) {
402
 
         unsigned value = 0xDEADBEEF;
403
 
         Bool success =
404
 
            glXQueryRendererIntegerMESA(&dpy, 0,
405
 
                                        invalid_renderer_indices[i],
406
 
                                        GLX_RENDERER_VENDOR_ID_MESA,
407
 
                                        &value);
408
 
         EXPECT_FALSE(success) << invalid_renderer_indices[i];
409
 
         EXPECT_EQ(0xDEADBEEF, value) << invalid_renderer_indices[i];
410
 
         EXPECT_FALSE(query_renderer_integer_called)
411
 
            << invalid_renderer_indices[i];
412
 
         EXPECT_FALSE(query_renderer_string_called)
413
 
            << invalid_renderer_indices[i];
414
 
      }
415
 
   } else {
416
 
      EXPECT_FALSE(got_sigsegv);
417
 
   }
418
 
}
419
 
 
420
 
/**
421
 
 * glXQueryCurrentRendererIntegerMESA will return error if there is no context
422
 
 * current.  It will also not segfault.
423
 
 */
424
 
TEST_F(query_renderer_integer_test, no_current_context)
425
 
{
426
 
   if (setjmp(jmp) == 0) {
427
 
      unsigned value = 0xDEADBEEF;
428
 
      Bool success =
429
 
         glXQueryCurrentRendererIntegerMESA(GLX_RENDERER_VENDOR_ID_MESA,
430
 
                                            &value);
431
 
      EXPECT_FALSE(success);
432
 
      EXPECT_EQ(0xDEADBEEF, value);
433
 
   } else {
434
 
      EXPECT_FALSE(got_sigsegv);
435
 
   }
436
 
}