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