glx/tests: Add GetGLXScreenConfigs_called flag
[mesa.git] / src / glx / tests / create_context_unittest.cpp
1 /*
2 * Copyright © 2011 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 <string.h>
25
26 extern "C" {
27 #include "glxclient.h"
28 #include "glx_error.h"
29 }
30
31 #include <xcb/glx.h>
32 #include "mock_xdisplay.h"
33 #include "fake_glx_screen.h"
34
35 static bool CreateContextAttribsARB_was_sent;
36 static xcb_glx_create_context_attribs_arb_request_t req;
37 static uint32_t sent_attribs[1024];
38 static uint32_t next_id;
39
40
41 struct glx_screen *psc;
42
43 extern "C" Bool
44 glx_context_init(struct glx_context *gc,
45 struct glx_screen *psc, struct glx_config *config)
46 {
47 gc->majorOpcode = 123;
48 gc->screen = psc->scr;
49 gc->psc = psc;
50 gc->config = config;
51 gc->isDirect = GL_TRUE;
52 gc->currentContextTag = -1;
53
54 return GL_TRUE;
55 }
56
57 bool GetGLXScreenConfigs_called = false;
58
59 extern "C" struct glx_screen *
60 GetGLXScreenConfigs(Display * dpy, int scrn)
61 {
62 (void) dpy;
63 (void) scrn;
64
65 GetGLXScreenConfigs_called = true;
66 return psc;
67 }
68
69 extern "C" uint32_t
70 xcb_generate_id(xcb_connection_t *c)
71 {
72 (void) c;
73
74 return next_id++;
75 }
76
77 extern "C" xcb_void_cookie_t
78 xcb_glx_create_context_attribs_arb_checked(xcb_connection_t *c,
79 xcb_glx_context_t context,
80 uint32_t fbconfig,
81 uint32_t screen,
82 uint32_t share_list,
83 uint8_t is_direct,
84 uint32_t num_attribs,
85 const uint32_t *attribs)
86 {
87 (void) c;
88
89 CreateContextAttribsARB_was_sent = true;
90 req.context = context;
91 req.fbconfig = fbconfig;
92 req.screen = screen;
93 req.share_list = share_list;
94 req.is_direct = is_direct;
95 req.num_attribs = num_attribs;
96
97 if (num_attribs != 0 && attribs != NULL)
98 memcpy(sent_attribs, attribs, num_attribs * 2 * sizeof(uint32_t));
99
100 xcb_void_cookie_t cookie;
101 cookie.sequence = 0xbadc0de;
102
103 return cookie;
104 }
105
106 extern "C" xcb_generic_error_t *
107 xcb_request_check(xcb_connection_t *c, xcb_void_cookie_t cookie)
108 {
109 return NULL;
110 }
111
112 extern "C" void
113 __glXSendErrorForXcb(Display * dpy, const xcb_generic_error_t *err)
114 {
115 }
116
117 extern "C" void
118 __glXSendError(Display * dpy, int_fast8_t errorCode, uint_fast32_t resourceID,
119 uint_fast16_t minorCode, bool coreX11error)
120 {
121 }
122
123 class glXCreateContextAttribARB_test : public ::testing::Test {
124 public:
125 virtual void SetUp();
126
127 /**
128 * Replace the existing screen with a direct-rendering screen
129 */
130 void use_direct_rendering_screen();
131
132 mock_XDisplay *dpy;
133 struct glx_config fbc;
134 };
135
136 void
137 glXCreateContextAttribARB_test::SetUp()
138 {
139 CreateContextAttribsARB_was_sent = false;
140 memset(&req, 0, sizeof(req));
141 next_id = 99;
142 fake_glx_context::contexts_allocated = 0;
143 psc = new fake_glx_screen(NULL, 0, "");
144
145 this->dpy = new mock_XDisplay(1);
146
147 memset(&this->fbc, 0, sizeof(this->fbc));
148 this->fbc.fbconfigID = 0xbeefcafe;
149 }
150
151 void
152 glXCreateContextAttribARB_test::use_direct_rendering_screen()
153 {
154 struct glx_screen *direct_psc =
155 new fake_glx_screen_direct(psc->display,
156 psc->scr,
157 psc->serverGLXexts);
158
159 delete psc;
160 psc = direct_psc;
161 }
162
163 /**
164 * \name Verify detection of client-side errors
165 */
166 /*@{*/
167 TEST_F(glXCreateContextAttribARB_test, NULL_display_returns_None)
168 {
169 GLXContext ctx =
170 glXCreateContextAttribsARB(NULL, (GLXFBConfig) &this->fbc, 0,
171 False, NULL);
172
173 EXPECT_EQ(None, ctx);
174 EXPECT_EQ(0, fake_glx_context::contexts_allocated);
175 }
176
177 TEST_F(glXCreateContextAttribARB_test, NULL_fbconfig_returns_None)
178 {
179 GLXContext ctx =
180 glXCreateContextAttribsARB(this->dpy, NULL, 0, False, NULL);
181
182 EXPECT_EQ(None, ctx);
183 EXPECT_EQ(0, fake_glx_context::contexts_allocated);
184 }
185
186 TEST_F(glXCreateContextAttribARB_test, NULL_screen_returns_None)
187 {
188 delete psc;
189 psc = NULL;
190
191 GLXContext ctx =
192 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
193 False, NULL);
194
195 EXPECT_EQ(None, ctx);
196 EXPECT_EQ(0, fake_glx_context::contexts_allocated);
197 }
198 /*@}*/
199
200 /**
201 * \name Verify that correct protocol bits are sent to the server.
202 */
203 /*@{*/
204 TEST_F(glXCreateContextAttribARB_test, does_send_protocol)
205 {
206 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
207 False, NULL);
208
209 EXPECT_TRUE(CreateContextAttribsARB_was_sent);
210 }
211
212 TEST_F(glXCreateContextAttribARB_test, sent_correct_context)
213 {
214 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
215 False, NULL);
216
217 EXPECT_EQ(99u, req.context);
218 }
219
220 TEST_F(glXCreateContextAttribARB_test, sent_correct_fbconfig)
221 {
222 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
223 False, NULL);
224
225 EXPECT_EQ(0xbeefcafe, req.fbconfig);
226 }
227
228 TEST_F(glXCreateContextAttribARB_test, sent_correct_share_list)
229 {
230 GLXContext share =
231 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
232 False, NULL);
233
234 ASSERT_NE((GLXContext) 0, share);
235
236 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, share,
237 False, NULL);
238
239 struct glx_context *glx_ctx = (struct glx_context *) share;
240 EXPECT_EQ(glx_ctx->xid, req.share_list);
241 }
242
243 TEST_F(glXCreateContextAttribARB_test, sent_correct_is_direct_for_indirect_screen_and_direct_set_to_true)
244 {
245 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
246 True, NULL);
247
248 EXPECT_FALSE(req.is_direct);
249 }
250
251 TEST_F(glXCreateContextAttribARB_test, sent_correct_is_direct_for_indirect_screen_and_direct_set_to_false)
252 {
253 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
254 False, NULL);
255
256 EXPECT_FALSE(req.is_direct);
257 }
258
259 TEST_F(glXCreateContextAttribARB_test, sent_correct_is_direct_for_direct_screen_and_direct_set_to_true)
260 {
261 this->use_direct_rendering_screen();
262
263 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
264 True, NULL);
265
266 EXPECT_TRUE(req.is_direct);
267 }
268
269 TEST_F(glXCreateContextAttribARB_test, sent_correct_is_direct_for_direct_screen_and_direct_set_to_false)
270 {
271 this->use_direct_rendering_screen();
272
273 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
274 False, NULL);
275
276 EXPECT_FALSE(req.is_direct);
277 }
278
279 TEST_F(glXCreateContextAttribARB_test, sent_correct_screen)
280 {
281 this->fbc.screen = 7;
282 psc->scr = 7;
283
284 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
285 False, NULL);
286
287 EXPECT_EQ(7u, req.screen);
288 }
289
290 TEST_F(glXCreateContextAttribARB_test, sent_correct_num_attribs)
291 {
292 /* Use zeros in the second half of each attribute pair to try and trick the
293 * implementation into termiating the list early.
294 *
295 * Use non-zero in the second half of the last attribute pair to try and
296 * trick the implementation into not terminating the list early enough.
297 */
298 static const int attribs[] = {
299 1, 0,
300 2, 0,
301 3, 0,
302 4, 0,
303 0, 6,
304 0, 0
305 };
306
307 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
308 False, attribs);
309
310 EXPECT_EQ(4u, req.num_attribs);
311 }
312
313 TEST_F(glXCreateContextAttribARB_test, sent_correct_num_attribs_empty_list)
314 {
315 static const int attribs[] = {
316 0,
317 };
318
319 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
320 False, attribs);
321
322 EXPECT_EQ(0u, req.num_attribs);
323 }
324
325 TEST_F(glXCreateContextAttribARB_test, sent_correct_num_attribs_NULL_list_pointer)
326 {
327 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
328 False, NULL);
329
330 EXPECT_EQ(0u, req.num_attribs);
331 }
332
333 TEST_F(glXCreateContextAttribARB_test, sent_correct_attrib_list)
334 {
335 int attribs[] = {
336 GLX_RENDER_TYPE, GLX_RGBA_TYPE,
337 GLX_CONTEXT_MAJOR_VERSION_ARB, 1,
338 GLX_CONTEXT_MINOR_VERSION_ARB, 2,
339 0
340 };
341
342 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
343 False, attribs);
344
345 for (unsigned i = 0; i < 6; i++) {
346 EXPECT_EQ((uint32_t) attribs[i], sent_attribs[i]);
347 }
348 }
349 /*@}*/
350
351 /**
352 * \name Verify details of the returned GLXContext
353 */
354 /*@{*/
355 TEST_F(glXCreateContextAttribARB_test, correct_context)
356 {
357 GLXContext ctx =
358 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
359 False, NULL);
360
361 /* Since the server did not return an error, the GLXContext should not be
362 * NULL.
363 */
364 EXPECT_NE((GLXContext)0, ctx);
365
366 /* It shouldn't be the XID of the context either.
367 */
368 EXPECT_NE((GLXContext)99, ctx);
369 }
370
371 TEST_F(glXCreateContextAttribARB_test, correct_context_xid)
372 {
373 GLXContext ctx =
374 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
375 False, NULL);
376
377 /* Since the server did not return an error, the GLXContext should not be
378 * NULL.
379 */
380 ASSERT_NE((GLXContext)0, ctx);
381
382 struct glx_context *glx_ctx = (struct glx_context *) ctx;
383 EXPECT_EQ(99u, glx_ctx->xid);
384 }
385
386 TEST_F(glXCreateContextAttribARB_test, correct_context_share_xid)
387 {
388 GLXContext first =
389 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
390 False, NULL);
391
392 ASSERT_NE((GLXContext) 0, first);
393
394 GLXContext second =
395 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, first,
396 False, NULL);
397
398 ASSERT_NE((GLXContext) 0, second);
399
400 struct glx_context *share = (struct glx_context *) first;
401 struct glx_context *ctx = (struct glx_context *) second;
402 EXPECT_EQ(share->xid, ctx->share_xid);
403 }
404
405 TEST_F(glXCreateContextAttribARB_test, correct_context_isDirect_for_indirect_screen_and_direct_set_to_true)
406 {
407 GLXContext ctx =
408 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
409 True, NULL);
410
411 ASSERT_NE((GLXContext) 0, ctx);
412
413 struct glx_context *gc = (struct glx_context *) ctx;
414
415 EXPECT_FALSE(gc->isDirect);
416 }
417
418 TEST_F(glXCreateContextAttribARB_test, correct_context_isDirect_for_indirect_screen_and_direct_set_to_false)
419 {
420 GLXContext ctx =
421 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
422 False, NULL);
423
424 ASSERT_NE((GLXContext) 0, ctx);
425
426 struct glx_context *gc = (struct glx_context *) ctx;
427
428 EXPECT_FALSE(gc->isDirect);
429 }
430
431 TEST_F(glXCreateContextAttribARB_test, correct_context_isDirect_for_direct_screen_and_direct_set_to_true)
432 {
433 this->use_direct_rendering_screen();
434
435 GLXContext ctx =
436 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
437 True, NULL);
438
439 ASSERT_NE((GLXContext) 0, ctx);
440
441 struct glx_context *gc = (struct glx_context *) ctx;
442
443 EXPECT_TRUE(gc->isDirect);
444 }
445
446 TEST_F(glXCreateContextAttribARB_test, correct_context_isDirect_for_direct_screen_and_direct_set_to_false)
447 {
448 this->use_direct_rendering_screen();
449
450 GLXContext ctx =
451 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
452 False, NULL);
453
454 ASSERT_NE((GLXContext) 0, ctx);
455
456 struct glx_context *gc = (struct glx_context *) ctx;
457
458 EXPECT_FALSE(gc->isDirect);
459 }
460
461 TEST_F(glXCreateContextAttribARB_test, correct_indirect_context_client_state_private)
462 {
463 GLXContext ctx =
464 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
465 False, NULL);
466
467 ASSERT_NE((GLXContext) 0, ctx);
468
469 struct glx_context *gc = (struct glx_context *) ctx;
470
471 ASSERT_FALSE(gc->isDirect);
472 EXPECT_EQ((struct __GLXattributeRec *) 0xcafebabe,
473 gc->client_state_private);
474 }
475
476 TEST_F(glXCreateContextAttribARB_test, correct_indirect_context_config)
477 {
478 GLXContext ctx =
479 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
480 False, NULL);
481
482 ASSERT_NE((GLXContext) 0, ctx);
483
484 struct glx_context *gc = (struct glx_context *) ctx;
485
486 EXPECT_EQ(&this->fbc, gc->config);
487 }
488
489 TEST_F(glXCreateContextAttribARB_test, correct_context_screen_number)
490 {
491 this->fbc.screen = 7;
492 psc->scr = 7;
493
494 GLXContext ctx =
495 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
496 False, NULL);
497
498 ASSERT_NE((GLXContext) 0, ctx);
499
500 struct glx_context *gc = (struct glx_context *) ctx;
501
502 EXPECT_EQ(7, gc->screen);
503 }
504
505 TEST_F(glXCreateContextAttribARB_test, correct_context_screen_pointer)
506 {
507 GLXContext ctx =
508 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
509 False, NULL);
510
511 ASSERT_NE((GLXContext) 0, ctx);
512
513 struct glx_context *gc = (struct glx_context *) ctx;
514
515 EXPECT_EQ(psc, gc->psc);
516 }
517 /*@}*/