Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/frontends/glx/xlib/glx_api.c
4561 views
1
/*
2
* Mesa 3-D graphics library
3
*
4
* Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
5
* Copyright (C) 2009 VMware, Inc. All Rights Reserved.
6
*
7
* Permission is hereby granted, free of charge, to any person obtaining a
8
* copy of this software and associated documentation files (the "Software"),
9
* to deal in the Software without restriction, including without limitation
10
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
11
* and/or sell copies of the Software, and to permit persons to whom the
12
* Software is furnished to do so, subject to the following conditions:
13
*
14
* The above copyright notice and this permission notice shall be included
15
* in all copies or substantial portions of the Software.
16
*
17
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
* OTHER DEALINGS IN THE SOFTWARE.
24
*/
25
26
27
/**
28
* "Fake" GLX API implemented in terms of the XMesa*() functions.
29
*/
30
31
32
33
#define GLX_GLXEXT_PROTOTYPES
34
#include "GL/glx.h"
35
36
#include <stdio.h>
37
#include <string.h>
38
#include <X11/Xmd.h>
39
#include <GL/glxproto.h>
40
41
#include "xm_api.h"
42
#include "main/errors.h"
43
#include "util/u_math.h"
44
#include "util/u_memory.h"
45
46
/* An "Atrribs/Attribs" typo was fixed in glxproto.h in Nov 2014.
47
* This is in case we don't have the updated header.
48
*/
49
#if !defined(X_GLXCreateContextAttribsARB) && \
50
defined(X_GLXCreateContextAtrribsARB)
51
#define X_GLXCreateContextAttribsARB X_GLXCreateContextAtrribsARB
52
#endif
53
54
/* This indicates the client-side GLX API and GLX encoder version. */
55
#define CLIENT_MAJOR_VERSION 1
56
#define CLIENT_MINOR_VERSION 4 /* but don't have 1.3's pbuffers, etc yet */
57
58
/* This indicates the server-side GLX decoder version.
59
* GLX 1.4 indicates OpenGL 1.3 support
60
*/
61
#define SERVER_MAJOR_VERSION 1
62
#define SERVER_MINOR_VERSION 4
63
64
/* Who implemented this GLX? */
65
#define VENDOR "Brian Paul"
66
67
#define EXTENSIONS \
68
"GLX_MESA_copy_sub_buffer " \
69
"GLX_MESA_pixmap_colormap " \
70
"GLX_MESA_release_buffers " \
71
"GLX_ARB_create_context " \
72
"GLX_ARB_create_context_profile " \
73
"GLX_ARB_get_proc_address " \
74
"GLX_EXT_create_context_es_profile " \
75
"GLX_EXT_create_context_es2_profile " \
76
"GLX_EXT_texture_from_pixmap " \
77
"GLX_EXT_visual_info " \
78
"GLX_EXT_visual_rating " \
79
/*"GLX_SGI_video_sync "*/ \
80
"GLX_SGIX_fbconfig " \
81
"GLX_SGIX_pbuffer "
82
83
#define DEFAULT_DIRECT GL_TRUE
84
85
86
/** XXX this could be based on gallium's max texture size */
87
#define PBUFFER_MAX_SIZE 16384
88
89
90
/**
91
* The GLXContext typedef is defined as a pointer to this structure.
92
*/
93
struct __GLXcontextRec
94
{
95
Display *currentDpy;
96
GLboolean isDirect;
97
GLXDrawable currentDrawable;
98
GLXDrawable currentReadable;
99
XID xid;
100
101
XMesaContext xmesaContext;
102
};
103
104
105
106
static pipe_tsd ContextTSD;
107
108
/** Set current context for calling thread */
109
static void
110
SetCurrentContext(GLXContext c)
111
{
112
pipe_tsd_set(&ContextTSD, c);
113
}
114
115
/** Get current context for calling thread */
116
static GLXContext
117
GetCurrentContext(void)
118
{
119
return pipe_tsd_get(&ContextTSD);
120
}
121
122
123
124
/**********************************************************************/
125
/*** GLX Visual Code ***/
126
/**********************************************************************/
127
128
#define DONT_CARE -1
129
130
131
static XMesaVisual *VisualTable = NULL;
132
static int NumVisuals = 0;
133
134
135
136
/* Macro to handle c_class vs class field name in XVisualInfo struct */
137
#if defined(__cplusplus) || defined(c_plusplus)
138
#define CLASS c_class
139
#else
140
#define CLASS class
141
#endif
142
143
144
145
/*
146
* Test if the given XVisualInfo is usable for Mesa rendering.
147
*/
148
static GLboolean
149
is_usable_visual( XVisualInfo *vinfo )
150
{
151
switch (vinfo->CLASS) {
152
case StaticGray:
153
case GrayScale:
154
/* Any StaticGray/GrayScale visual works in RGB or CI mode */
155
return GL_TRUE;
156
case StaticColor:
157
case PseudoColor:
158
/* Any StaticColor/PseudoColor visual of at least 4 bits */
159
if (vinfo->depth>=4) {
160
return GL_TRUE;
161
}
162
else {
163
return GL_FALSE;
164
}
165
case TrueColor:
166
case DirectColor:
167
/* Any depth of TrueColor or DirectColor works in RGB mode */
168
return GL_TRUE;
169
default:
170
/* This should never happen */
171
return GL_FALSE;
172
}
173
}
174
175
176
/*
177
* Given an XVisualInfo and RGB, Double, and Depth buffer flags, save the
178
* configuration in our list of GLX visuals.
179
*/
180
static XMesaVisual
181
save_glx_visual( Display *dpy, XVisualInfo *vinfo,
182
GLboolean rgbFlag, GLboolean alphaFlag, GLboolean dbFlag,
183
GLboolean stereoFlag,
184
GLint depth_size, GLint stencil_size,
185
GLint accumRedSize, GLint accumGreenSize,
186
GLint accumBlueSize, GLint accumAlphaSize,
187
GLint level, GLint numAuxBuffers, GLuint num_samples )
188
{
189
GLboolean ximageFlag = GL_TRUE;
190
XMesaVisual xmvis;
191
GLint i;
192
GLboolean comparePointers;
193
194
if (!rgbFlag)
195
return NULL;
196
197
if (dbFlag) {
198
/* Check if the MESA_BACK_BUFFER env var is set */
199
char *backbuffer = getenv("MESA_BACK_BUFFER");
200
if (backbuffer) {
201
if (backbuffer[0]=='p' || backbuffer[0]=='P') {
202
ximageFlag = GL_FALSE;
203
}
204
else if (backbuffer[0]=='x' || backbuffer[0]=='X') {
205
ximageFlag = GL_TRUE;
206
}
207
else {
208
_mesa_warning(NULL, "Mesa: invalid value for MESA_BACK_BUFFER environment variable, using an XImage.");
209
}
210
}
211
}
212
213
if (stereoFlag) {
214
/* stereo not supported */
215
return NULL;
216
}
217
218
if (stencil_size > 0 && depth_size > 0)
219
depth_size = 24;
220
221
/* Comparing IDs uses less memory but sometimes fails. */
222
/* XXX revisit this after 3.0 is finished. */
223
if (getenv("MESA_GLX_VISUAL_HACK"))
224
comparePointers = GL_TRUE;
225
else
226
comparePointers = GL_FALSE;
227
228
/* Force the visual to have an alpha channel */
229
if (rgbFlag && getenv("MESA_GLX_FORCE_ALPHA"))
230
alphaFlag = GL_TRUE;
231
232
/* First check if a matching visual is already in the list */
233
for (i=0; i<NumVisuals; i++) {
234
XMesaVisual v = VisualTable[i];
235
if (v->display == dpy
236
&& v->mesa_visual.samples == num_samples
237
&& v->ximage_flag == ximageFlag
238
&& v->mesa_visual.doubleBufferMode == dbFlag
239
&& v->mesa_visual.stereoMode == stereoFlag
240
&& (v->mesa_visual.alphaBits > 0) == alphaFlag
241
&& (v->mesa_visual.depthBits >= depth_size || depth_size == 0)
242
&& (v->mesa_visual.stencilBits >= stencil_size || stencil_size == 0)
243
&& (v->mesa_visual.accumRedBits >= accumRedSize || accumRedSize == 0)
244
&& (v->mesa_visual.accumGreenBits >= accumGreenSize || accumGreenSize == 0)
245
&& (v->mesa_visual.accumBlueBits >= accumBlueSize || accumBlueSize == 0)
246
&& (v->mesa_visual.accumAlphaBits >= accumAlphaSize || accumAlphaSize == 0)) {
247
/* now either compare XVisualInfo pointers or visual IDs */
248
if ((!comparePointers && v->visinfo->visualid == vinfo->visualid)
249
|| (comparePointers && v->vishandle == vinfo)) {
250
return v;
251
}
252
}
253
}
254
255
/* Create a new visual and add it to the list. */
256
257
xmvis = XMesaCreateVisual( dpy, vinfo, rgbFlag, alphaFlag, dbFlag,
258
stereoFlag, ximageFlag,
259
depth_size, stencil_size,
260
accumRedSize, accumBlueSize,
261
accumBlueSize, accumAlphaSize, num_samples, level,
262
GLX_NONE_EXT );
263
if (xmvis) {
264
/* Save a copy of the pointer now so we can find this visual again
265
* if we need to search for it in find_glx_visual().
266
*/
267
xmvis->vishandle = vinfo;
268
/* Allocate more space for additional visual */
269
VisualTable = realloc(VisualTable, sizeof(XMesaVisual) * (NumVisuals + 1));
270
/* add xmvis to the list */
271
VisualTable[NumVisuals] = xmvis;
272
NumVisuals++;
273
}
274
return xmvis;
275
}
276
277
278
/**
279
* Return the default number of bits for the Z buffer.
280
* If defined, use the MESA_GLX_DEPTH_BITS env var value.
281
* Otherwise, use the DEFAULT_SOFTWARE_DEPTH_BITS constant.
282
* XXX probably do the same thing for stencil, accum, etc.
283
*/
284
static GLint
285
default_depth_bits(void)
286
{
287
int zBits;
288
const char *zEnv = getenv("MESA_GLX_DEPTH_BITS");
289
if (zEnv)
290
zBits = atoi(zEnv);
291
else
292
zBits = 24;
293
return zBits;
294
}
295
296
static GLint
297
default_alpha_bits(void)
298
{
299
int aBits;
300
const char *aEnv = getenv("MESA_GLX_ALPHA_BITS");
301
if (aEnv)
302
aBits = atoi(aEnv);
303
else
304
aBits = 0;
305
return aBits;
306
}
307
308
static GLint
309
default_accum_bits(void)
310
{
311
return 16;
312
}
313
314
315
316
/*
317
* Create a GLX visual from a regular XVisualInfo.
318
* This is called when Fake GLX is given an XVisualInfo which wasn't
319
* returned by glXChooseVisual. Since this is the first time we're
320
* considering this visual we'll take a guess at reasonable values
321
* for depth buffer size, stencil size, accum size, etc.
322
* This is the best we can do with a client-side emulation of GLX.
323
*/
324
static XMesaVisual
325
create_glx_visual( Display *dpy, XVisualInfo *visinfo )
326
{
327
GLint zBits = default_depth_bits();
328
GLint accBits = default_accum_bits();
329
GLboolean alphaFlag = default_alpha_bits() > 0;
330
331
if (is_usable_visual( visinfo )) {
332
/* Configure this visual as RGB, double-buffered, depth-buffered. */
333
/* This is surely wrong for some people's needs but what else */
334
/* can be done? They should use glXChooseVisual(). */
335
return save_glx_visual( dpy, visinfo,
336
GL_TRUE, /* rgb */
337
alphaFlag, /* alpha */
338
GL_TRUE, /* double */
339
GL_FALSE, /* stereo */
340
zBits,
341
8, /* stencil bits */
342
accBits, /* r */
343
accBits, /* g */
344
accBits, /* b */
345
accBits, /* a */
346
0, /* level */
347
0, /* numAux */
348
0 /* numSamples */
349
);
350
}
351
else {
352
_mesa_warning(NULL, "Mesa: error in glXCreateContext: bad visual\n");
353
return NULL;
354
}
355
}
356
357
358
359
/*
360
* Find the GLX visual associated with an XVisualInfo.
361
*/
362
static XMesaVisual
363
find_glx_visual( Display *dpy, XVisualInfo *vinfo )
364
{
365
int i;
366
367
/* try to match visual id */
368
for (i=0;i<NumVisuals;i++) {
369
if (VisualTable[i]->display==dpy
370
&& VisualTable[i]->visinfo->visualid == vinfo->visualid) {
371
return VisualTable[i];
372
}
373
}
374
375
/* if that fails, try to match pointers */
376
for (i=0;i<NumVisuals;i++) {
377
if (VisualTable[i]->display==dpy && VisualTable[i]->vishandle==vinfo) {
378
return VisualTable[i];
379
}
380
}
381
382
return NULL;
383
}
384
385
386
/**
387
* Try to get an X visual which matches the given arguments.
388
*/
389
static XVisualInfo *
390
get_visual( Display *dpy, int scr, unsigned int depth, int xclass )
391
{
392
XVisualInfo temp, *vis;
393
long mask;
394
int n;
395
unsigned int default_depth;
396
int default_class;
397
398
mask = VisualScreenMask | VisualDepthMask | VisualClassMask;
399
temp.screen = scr;
400
temp.depth = depth;
401
temp.CLASS = xclass;
402
403
default_depth = DefaultDepth(dpy,scr);
404
default_class = DefaultVisual(dpy,scr)->CLASS;
405
406
if (depth==default_depth && xclass==default_class) {
407
/* try to get root window's visual */
408
temp.visualid = DefaultVisual(dpy,scr)->visualid;
409
mask |= VisualIDMask;
410
}
411
412
vis = XGetVisualInfo( dpy, mask, &temp, &n );
413
414
/* In case bits/pixel > 24, make sure color channels are still <=8 bits.
415
* An SGI Infinite Reality system, for example, can have 30bpp pixels:
416
* 10 bits per color channel. Mesa's limited to a max of 8 bits/channel.
417
*/
418
if (vis && depth > 24 && (xclass==TrueColor || xclass==DirectColor)) {
419
if (util_bitcount((GLuint) vis->red_mask ) <= 8 &&
420
util_bitcount((GLuint) vis->green_mask) <= 8 &&
421
util_bitcount((GLuint) vis->blue_mask ) <= 8) {
422
return vis;
423
}
424
else {
425
free((void *) vis);
426
return NULL;
427
}
428
}
429
430
return vis;
431
}
432
433
434
/*
435
* Retrieve the value of the given environment variable and find
436
* the X visual which matches it.
437
* Input: dpy - the display
438
* screen - the screen number
439
* varname - the name of the environment variable
440
* Return: an XVisualInfo pointer to NULL if error.
441
*/
442
static XVisualInfo *
443
get_env_visual(Display *dpy, int scr, const char *varname)
444
{
445
char value[100], type[100];
446
int depth, xclass = -1;
447
XVisualInfo *vis;
448
449
if (!getenv( varname )) {
450
return NULL;
451
}
452
453
strncpy( value, getenv(varname), 100 );
454
value[99] = 0;
455
456
sscanf( value, "%s %d", type, &depth );
457
458
if (strcmp(type,"TrueColor")==0) xclass = TrueColor;
459
else if (strcmp(type,"DirectColor")==0) xclass = DirectColor;
460
else if (strcmp(type,"PseudoColor")==0) xclass = PseudoColor;
461
else if (strcmp(type,"StaticColor")==0) xclass = StaticColor;
462
else if (strcmp(type,"GrayScale")==0) xclass = GrayScale;
463
else if (strcmp(type,"StaticGray")==0) xclass = StaticGray;
464
465
if (xclass>-1 && depth>0) {
466
vis = get_visual( dpy, scr, depth, xclass );
467
if (vis) {
468
return vis;
469
}
470
}
471
472
_mesa_warning(NULL, "GLX unable to find visual class=%s, depth=%d.",
473
type, depth);
474
475
return NULL;
476
}
477
478
479
480
/*
481
* Select an X visual which satisfies the RGBA flag and minimum depth.
482
* Input: dpy,
483
* screen - X display and screen number
484
* min_depth - minimum visual depth
485
* preferred_class - preferred GLX visual class or DONT_CARE
486
* Return: pointer to an XVisualInfo or NULL.
487
*/
488
static XVisualInfo *
489
choose_x_visual( Display *dpy, int screen, int min_depth,
490
int preferred_class )
491
{
492
XVisualInfo *vis;
493
int xclass, visclass = 0;
494
int depth;
495
496
/* First see if the MESA_RGB_VISUAL env var is defined */
497
vis = get_env_visual( dpy, screen, "MESA_RGB_VISUAL" );
498
if (vis) {
499
return vis;
500
}
501
/* Otherwise, search for a suitable visual */
502
if (preferred_class==DONT_CARE) {
503
for (xclass=0;xclass<6;xclass++) {
504
switch (xclass) {
505
case 0: visclass = TrueColor; break;
506
case 1: visclass = DirectColor; break;
507
case 2: visclass = PseudoColor; break;
508
case 3: visclass = StaticColor; break;
509
case 4: visclass = GrayScale; break;
510
case 5: visclass = StaticGray; break;
511
}
512
if (min_depth==0) {
513
/* start with shallowest */
514
for (depth=0;depth<=32;depth++) {
515
if (visclass==TrueColor && depth==8) {
516
/* Special case: try to get 8-bit PseudoColor before */
517
/* 8-bit TrueColor */
518
vis = get_visual( dpy, screen, 8, PseudoColor );
519
if (vis) {
520
return vis;
521
}
522
}
523
vis = get_visual( dpy, screen, depth, visclass );
524
if (vis) {
525
return vis;
526
}
527
}
528
}
529
else {
530
/* start with deepest */
531
for (depth=32;depth>=min_depth;depth--) {
532
if (visclass==TrueColor && depth==8) {
533
/* Special case: try to get 8-bit PseudoColor before */
534
/* 8-bit TrueColor */
535
vis = get_visual( dpy, screen, 8, PseudoColor );
536
if (vis) {
537
return vis;
538
}
539
}
540
vis = get_visual( dpy, screen, depth, visclass );
541
if (vis) {
542
return vis;
543
}
544
}
545
}
546
}
547
}
548
else {
549
/* search for a specific visual class */
550
switch (preferred_class) {
551
case GLX_TRUE_COLOR_EXT: visclass = TrueColor; break;
552
case GLX_DIRECT_COLOR_EXT: visclass = DirectColor; break;
553
case GLX_PSEUDO_COLOR_EXT: visclass = PseudoColor; break;
554
case GLX_STATIC_COLOR_EXT: visclass = StaticColor; break;
555
case GLX_GRAY_SCALE_EXT: visclass = GrayScale; break;
556
case GLX_STATIC_GRAY_EXT: visclass = StaticGray; break;
557
default: return NULL;
558
}
559
if (min_depth==0) {
560
/* start with shallowest */
561
for (depth=0;depth<=32;depth++) {
562
vis = get_visual( dpy, screen, depth, visclass );
563
if (vis) {
564
return vis;
565
}
566
}
567
}
568
else {
569
/* start with deepest */
570
for (depth=32;depth>=min_depth;depth--) {
571
vis = get_visual( dpy, screen, depth, visclass );
572
if (vis) {
573
return vis;
574
}
575
}
576
}
577
}
578
579
/* didn't find a visual */
580
return NULL;
581
}
582
583
584
585
586
/**********************************************************************/
587
/*** Display-related functions ***/
588
/**********************************************************************/
589
590
591
/**
592
* Free all XMesaVisuals which are associated with the given display.
593
*/
594
static void
595
destroy_visuals_on_display(Display *dpy)
596
{
597
int i;
598
for (i = 0; i < NumVisuals; i++) {
599
if (VisualTable[i]->display == dpy) {
600
/* remove this visual */
601
int j;
602
free(VisualTable[i]);
603
for (j = i; j < NumVisuals - 1; j++)
604
VisualTable[j] = VisualTable[j + 1];
605
NumVisuals--;
606
}
607
}
608
}
609
610
611
/**
612
* Called from XCloseDisplay() to let us free our display-related data.
613
*/
614
static int
615
close_display_callback(Display *dpy, XExtCodes *codes)
616
{
617
xmesa_destroy_buffers_on_display(dpy);
618
destroy_visuals_on_display(dpy);
619
xmesa_close_display(dpy);
620
return 0;
621
}
622
623
624
/**
625
* Look for the named extension on given display and return a pointer
626
* to the _XExtension data, or NULL if extension not found.
627
*/
628
static _XExtension *
629
lookup_extension(Display *dpy, const char *extName)
630
{
631
_XExtension *ext;
632
for (ext = dpy->ext_procs; ext; ext = ext->next) {
633
if (ext->name && strcmp(ext->name, extName) == 0) {
634
return ext;
635
}
636
}
637
return NULL;
638
}
639
640
641
/**
642
* Whenever we're given a new Display pointer, call this function to
643
* register our close_display_callback function.
644
*/
645
static void
646
register_with_display(Display *dpy)
647
{
648
const char *extName = "MesaGLX";
649
_XExtension *ext;
650
651
ext = lookup_extension(dpy, extName);
652
if (!ext) {
653
XExtCodes *c = XAddExtension(dpy);
654
ext = dpy->ext_procs; /* new extension is at head of list */
655
assert(c->extension == ext->codes.extension);
656
(void) c;
657
ext->name = strdup(extName);
658
ext->close_display = close_display_callback;
659
}
660
}
661
662
663
/**
664
* Fake an error.
665
*/
666
static int
667
generate_error(Display *dpy,
668
unsigned char error_code,
669
XID resourceid,
670
unsigned char minor_code,
671
Bool core)
672
{
673
XErrorHandler handler;
674
int major_opcode;
675
int first_event;
676
int first_error;
677
XEvent event;
678
679
handler = XSetErrorHandler(NULL);
680
XSetErrorHandler(handler);
681
if (!handler) {
682
return 0;
683
}
684
685
if (!XQueryExtension(dpy, GLX_EXTENSION_NAME, &major_opcode, &first_event, &first_error)) {
686
major_opcode = 0;
687
first_event = 0;
688
first_error = 0;
689
}
690
691
if (!core) {
692
error_code += first_error;
693
}
694
695
memset(&event, 0, sizeof event);
696
697
event.xerror.type = X_Error;
698
event.xerror.display = dpy;
699
event.xerror.resourceid = resourceid;
700
event.xerror.serial = NextRequest(dpy) - 1;
701
event.xerror.error_code = error_code;
702
event.xerror.request_code = major_opcode;
703
event.xerror.minor_code = minor_code;
704
705
return handler(dpy, &event.xerror);
706
}
707
708
709
/**********************************************************************/
710
/*** Begin Fake GLX API Functions ***/
711
/**********************************************************************/
712
713
714
/**
715
* Helper used by glXChooseVisual and glXChooseFBConfig.
716
* The fbConfig parameter must be GL_FALSE for the former and GL_TRUE for
717
* the later.
718
* In either case, the attribute list is terminated with the value 'None'.
719
*/
720
static XMesaVisual
721
choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
722
{
723
const GLboolean rgbModeDefault = fbConfig;
724
const int *parselist;
725
XVisualInfo *vis;
726
int min_red=0, min_green=0, min_blue=0;
727
GLboolean rgb_flag = rgbModeDefault;
728
GLboolean alpha_flag = GL_FALSE;
729
GLboolean double_flag = GL_FALSE;
730
GLboolean stereo_flag = GL_FALSE;
731
GLint depth_size = 0;
732
GLint stencil_size = 0;
733
GLint accumRedSize = 0;
734
GLint accumGreenSize = 0;
735
GLint accumBlueSize = 0;
736
GLint accumAlphaSize = 0;
737
int level = 0;
738
int visual_type = DONT_CARE;
739
GLint caveat = DONT_CARE;
740
XMesaVisual xmvis = NULL;
741
int desiredVisualID = -1;
742
int numAux = 0;
743
GLint num_samples = 0;
744
745
if (xmesa_init( dpy ) != 0) {
746
_mesa_warning(NULL, "Failed to initialize display");
747
return NULL;
748
}
749
750
parselist = list;
751
752
while (*parselist) {
753
754
if (fbConfig &&
755
parselist[1] == GLX_DONT_CARE &&
756
parselist[0] != GLX_LEVEL) {
757
/* For glXChooseFBConfig(), skip attributes whose value is
758
* GLX_DONT_CARE, unless it's GLX_LEVEL (which can legitimately be
759
* a negative value).
760
*
761
* From page 17 (23 of the pdf) of the GLX 1.4 spec:
762
* GLX DONT CARE may be specified for all attributes except GLX LEVEL.
763
*/
764
parselist += 2;
765
continue;
766
}
767
768
switch (*parselist) {
769
case GLX_USE_GL:
770
if (fbConfig) {
771
/* invalid token */
772
return NULL;
773
}
774
else {
775
/* skip */
776
parselist++;
777
}
778
break;
779
case GLX_BUFFER_SIZE:
780
parselist++;
781
parselist++;
782
break;
783
case GLX_LEVEL:
784
parselist++;
785
level = *parselist++;
786
break;
787
case GLX_RGBA:
788
if (fbConfig) {
789
/* invalid token */
790
return NULL;
791
}
792
else {
793
rgb_flag = GL_TRUE;
794
parselist++;
795
}
796
break;
797
case GLX_DOUBLEBUFFER:
798
parselist++;
799
if (fbConfig) {
800
double_flag = *parselist++;
801
}
802
else {
803
double_flag = GL_TRUE;
804
}
805
break;
806
case GLX_STEREO:
807
parselist++;
808
if (fbConfig) {
809
stereo_flag = *parselist++;
810
}
811
else {
812
stereo_flag = GL_TRUE;
813
}
814
break;
815
case GLX_AUX_BUFFERS:
816
parselist++;
817
numAux = *parselist++;
818
if (numAux > MAX_AUX_BUFFERS)
819
return NULL;
820
break;
821
case GLX_RED_SIZE:
822
parselist++;
823
min_red = *parselist++;
824
break;
825
case GLX_GREEN_SIZE:
826
parselist++;
827
min_green = *parselist++;
828
break;
829
case GLX_BLUE_SIZE:
830
parselist++;
831
min_blue = *parselist++;
832
break;
833
case GLX_ALPHA_SIZE:
834
parselist++;
835
{
836
GLint size = *parselist++;
837
alpha_flag = size ? GL_TRUE : GL_FALSE;
838
}
839
break;
840
case GLX_DEPTH_SIZE:
841
parselist++;
842
depth_size = *parselist++;
843
break;
844
case GLX_STENCIL_SIZE:
845
parselist++;
846
stencil_size = *parselist++;
847
break;
848
case GLX_ACCUM_RED_SIZE:
849
parselist++;
850
{
851
GLint size = *parselist++;
852
accumRedSize = MAX2( accumRedSize, size );
853
}
854
break;
855
case GLX_ACCUM_GREEN_SIZE:
856
parselist++;
857
{
858
GLint size = *parselist++;
859
accumGreenSize = MAX2( accumGreenSize, size );
860
}
861
break;
862
case GLX_ACCUM_BLUE_SIZE:
863
parselist++;
864
{
865
GLint size = *parselist++;
866
accumBlueSize = MAX2( accumBlueSize, size );
867
}
868
break;
869
case GLX_ACCUM_ALPHA_SIZE:
870
parselist++;
871
{
872
GLint size = *parselist++;
873
accumAlphaSize = MAX2( accumAlphaSize, size );
874
}
875
break;
876
877
/*
878
* GLX_EXT_visual_info extension
879
*/
880
case GLX_X_VISUAL_TYPE_EXT:
881
parselist++;
882
visual_type = *parselist++;
883
break;
884
case GLX_TRANSPARENT_TYPE_EXT:
885
parselist++;
886
parselist++;
887
break;
888
case GLX_TRANSPARENT_INDEX_VALUE_EXT:
889
parselist++;
890
parselist++;
891
break;
892
case GLX_TRANSPARENT_RED_VALUE_EXT:
893
case GLX_TRANSPARENT_GREEN_VALUE_EXT:
894
case GLX_TRANSPARENT_BLUE_VALUE_EXT:
895
case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
896
/* ignore */
897
parselist++;
898
parselist++;
899
break;
900
901
/*
902
* GLX_EXT_visual_info extension
903
*/
904
case GLX_VISUAL_CAVEAT_EXT:
905
parselist++;
906
caveat = *parselist++; /* ignored for now */
907
break;
908
909
/*
910
* GLX_ARB_multisample
911
*/
912
case GLX_SAMPLE_BUFFERS_ARB:
913
/* ignore */
914
parselist++;
915
parselist++;
916
break;
917
case GLX_SAMPLES_ARB:
918
parselist++;
919
num_samples = *parselist++;
920
break;
921
922
/*
923
* FBConfig attribs.
924
*/
925
case GLX_RENDER_TYPE:
926
if (!fbConfig)
927
return NULL;
928
parselist++;
929
if (*parselist & GLX_RGBA_BIT) {
930
rgb_flag = GL_TRUE;
931
}
932
else if (*parselist & GLX_COLOR_INDEX_BIT) {
933
rgb_flag = GL_FALSE;
934
}
935
else if (*parselist == 0) {
936
rgb_flag = GL_TRUE;
937
}
938
parselist++;
939
break;
940
case GLX_DRAWABLE_TYPE:
941
if (!fbConfig)
942
return NULL;
943
parselist++;
944
if (*parselist & ~(GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT)) {
945
return NULL; /* bad bit */
946
}
947
parselist++;
948
break;
949
case GLX_FBCONFIG_ID:
950
case GLX_VISUAL_ID:
951
if (!fbConfig)
952
return NULL;
953
parselist++;
954
desiredVisualID = *parselist++;
955
break;
956
case GLX_X_RENDERABLE:
957
case GLX_MAX_PBUFFER_WIDTH:
958
case GLX_MAX_PBUFFER_HEIGHT:
959
case GLX_MAX_PBUFFER_PIXELS:
960
if (!fbConfig)
961
return NULL; /* invalid config option */
962
parselist += 2; /* ignore the parameter */
963
break;
964
965
case GLX_BIND_TO_TEXTURE_RGB_EXT:
966
parselist++; /*skip*/
967
break;
968
case GLX_BIND_TO_TEXTURE_RGBA_EXT:
969
parselist++; /*skip*/
970
break;
971
case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
972
parselist++; /*skip*/
973
break;
974
case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
975
parselist++;
976
if (*parselist & ~(GLX_TEXTURE_1D_BIT_EXT |
977
GLX_TEXTURE_2D_BIT_EXT |
978
GLX_TEXTURE_RECTANGLE_BIT_EXT)) {
979
/* invalid bit */
980
return NULL;
981
}
982
break;
983
case GLX_Y_INVERTED_EXT:
984
parselist++; /*skip*/
985
break;
986
987
case None:
988
/* end of list */
989
break;
990
991
default:
992
/* undefined attribute */
993
_mesa_warning(NULL, "unexpected attrib 0x%x in choose_visual()",
994
*parselist);
995
return NULL;
996
}
997
}
998
999
(void) caveat;
1000
1001
if (num_samples < 0) {
1002
_mesa_warning(NULL, "GLX_SAMPLES_ARB: number of samples must not be negative");
1003
return NULL;
1004
}
1005
1006
/*
1007
* Since we're only simulating the GLX extension this function will never
1008
* find any real GL visuals. Instead, all we can do is try to find an RGB
1009
* or CI visual of appropriate depth. Other requested attributes such as
1010
* double buffering, depth buffer, etc. will be associated with the X
1011
* visual and stored in the VisualTable[].
1012
*/
1013
if (desiredVisualID != -1) {
1014
/* try to get a specific visual, by visualID */
1015
XVisualInfo temp;
1016
int n;
1017
temp.visualid = desiredVisualID;
1018
temp.screen = screen;
1019
vis = XGetVisualInfo(dpy, VisualIDMask | VisualScreenMask, &temp, &n);
1020
if (vis) {
1021
/* give the visual some useful GLX attributes */
1022
double_flag = GL_TRUE;
1023
rgb_flag = GL_TRUE;
1024
}
1025
}
1026
else if (level==0) {
1027
/* normal color planes */
1028
/* Get an RGB visual */
1029
int min_rgb = min_red + min_green + min_blue;
1030
if (min_rgb>1 && min_rgb<8) {
1031
/* a special case to be sure we can get a monochrome visual */
1032
min_rgb = 1;
1033
}
1034
vis = choose_x_visual( dpy, screen, min_rgb, visual_type );
1035
}
1036
else {
1037
_mesa_warning(NULL, "overlay not supported");
1038
return NULL;
1039
}
1040
1041
if (vis) {
1042
/* Note: we're not exactly obeying the glXChooseVisual rules here.
1043
* When GLX_DEPTH_SIZE = 1 is specified we're supposed to choose the
1044
* largest depth buffer size, which is 32bits/value. Instead, we
1045
* return 16 to maintain performance with earlier versions of Mesa.
1046
*/
1047
if (stencil_size > 0)
1048
depth_size = 24; /* if Z and stencil, always use 24+8 format */
1049
else if (depth_size > 24)
1050
depth_size = 32;
1051
else if (depth_size > 16)
1052
depth_size = 24;
1053
else if (depth_size > 0) {
1054
depth_size = default_depth_bits();
1055
}
1056
1057
if (!alpha_flag) {
1058
alpha_flag = default_alpha_bits() > 0;
1059
}
1060
1061
/* we only support one size of stencil and accum buffers. */
1062
if (stencil_size > 0)
1063
stencil_size = 8;
1064
1065
if (accumRedSize > 0 ||
1066
accumGreenSize > 0 ||
1067
accumBlueSize > 0 ||
1068
accumAlphaSize > 0) {
1069
1070
accumRedSize =
1071
accumGreenSize =
1072
accumBlueSize = default_accum_bits();
1073
1074
accumAlphaSize = alpha_flag ? accumRedSize : 0;
1075
}
1076
1077
xmvis = save_glx_visual( dpy, vis, rgb_flag, alpha_flag, double_flag,
1078
stereo_flag, depth_size, stencil_size,
1079
accumRedSize, accumGreenSize,
1080
accumBlueSize, accumAlphaSize, level, numAux,
1081
num_samples );
1082
}
1083
1084
return xmvis;
1085
}
1086
1087
1088
PUBLIC XVisualInfo *
1089
glXChooseVisual( Display *dpy, int screen, int *list )
1090
{
1091
XMesaVisual xmvis;
1092
1093
/* register ourselves as an extension on this display */
1094
register_with_display(dpy);
1095
1096
xmvis = choose_visual(dpy, screen, list, GL_FALSE);
1097
if (xmvis) {
1098
/* create a new vishandle - the cached one may be stale */
1099
xmvis->vishandle = malloc(sizeof(XVisualInfo));
1100
if (xmvis->vishandle) {
1101
memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo));
1102
}
1103
return xmvis->vishandle;
1104
}
1105
else
1106
return NULL;
1107
}
1108
1109
1110
/**
1111
* Helper function used by other glXCreateContext functions.
1112
*/
1113
static GLXContext
1114
create_context(Display *dpy, XMesaVisual xmvis,
1115
XMesaContext shareCtx, Bool direct,
1116
unsigned major, unsigned minor,
1117
unsigned profileMask, unsigned contextFlags)
1118
{
1119
GLXContext glxCtx;
1120
1121
if (!dpy || !xmvis)
1122
return 0;
1123
1124
glxCtx = CALLOC_STRUCT(__GLXcontextRec);
1125
if (!glxCtx)
1126
return 0;
1127
1128
/* deallocate unused windows/buffers */
1129
#if 0
1130
XMesaGarbageCollect();
1131
#endif
1132
1133
glxCtx->xmesaContext = XMesaCreateContext(xmvis, shareCtx, major, minor,
1134
profileMask, contextFlags);
1135
if (!glxCtx->xmesaContext) {
1136
free(glxCtx);
1137
return NULL;
1138
}
1139
1140
glxCtx->isDirect = DEFAULT_DIRECT;
1141
glxCtx->currentDpy = dpy;
1142
glxCtx->xid = (XID) glxCtx; /* self pointer */
1143
1144
return glxCtx;
1145
}
1146
1147
1148
PUBLIC GLXContext
1149
glXCreateContext( Display *dpy, XVisualInfo *visinfo,
1150
GLXContext shareCtx, Bool direct )
1151
{
1152
XMesaVisual xmvis;
1153
1154
xmvis = find_glx_visual( dpy, visinfo );
1155
if (!xmvis) {
1156
/* This visual wasn't found with glXChooseVisual() */
1157
xmvis = create_glx_visual( dpy, visinfo );
1158
if (!xmvis) {
1159
/* unusable visual */
1160
return NULL;
1161
}
1162
}
1163
1164
return create_context(dpy, xmvis,
1165
shareCtx ? shareCtx->xmesaContext : NULL,
1166
direct,
1167
1, 0, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0x0);
1168
}
1169
1170
1171
/* GLX 1.3 and later */
1172
PUBLIC Bool
1173
glXMakeContextCurrent( Display *dpy, GLXDrawable draw,
1174
GLXDrawable read, GLXContext ctx )
1175
{
1176
GLXContext glxCtx = ctx;
1177
GLXContext current = GetCurrentContext();
1178
static boolean firsttime = 1, no_rast = 0;
1179
1180
if (firsttime) {
1181
no_rast = getenv("SP_NO_RAST") != NULL;
1182
firsttime = 0;
1183
}
1184
1185
if (ctx) {
1186
XMesaBuffer drawBuffer = NULL, readBuffer = NULL;
1187
XMesaContext xmctx = glxCtx->xmesaContext;
1188
1189
/* either both must be null, or both must be non-null */
1190
if (!draw != !read)
1191
return False;
1192
1193
if (draw) {
1194
/* Find the XMesaBuffer which corresponds to 'draw' */
1195
drawBuffer = XMesaFindBuffer( dpy, draw );
1196
if (!drawBuffer) {
1197
/* drawable must be a new window! */
1198
drawBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, draw );
1199
if (!drawBuffer) {
1200
/* Out of memory, or context/drawable depth mismatch */
1201
return False;
1202
}
1203
}
1204
}
1205
1206
if (read) {
1207
/* Find the XMesaBuffer which corresponds to 'read' */
1208
readBuffer = XMesaFindBuffer( dpy, read );
1209
if (!readBuffer) {
1210
/* drawable must be a new window! */
1211
readBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, read );
1212
if (!readBuffer) {
1213
/* Out of memory, or context/drawable depth mismatch */
1214
return False;
1215
}
1216
}
1217
}
1218
1219
if (no_rast && current == ctx)
1220
return True;
1221
1222
/* Now make current! */
1223
if (XMesaMakeCurrent2(xmctx, drawBuffer, readBuffer)) {
1224
ctx->currentDpy = dpy;
1225
ctx->currentDrawable = draw;
1226
ctx->currentReadable = read;
1227
SetCurrentContext(ctx);
1228
return True;
1229
}
1230
else {
1231
return False;
1232
}
1233
}
1234
else if (!ctx && !draw && !read) {
1235
/* release current context w/out assigning new one. */
1236
XMesaMakeCurrent2( NULL, NULL, NULL );
1237
SetCurrentContext(NULL);
1238
return True;
1239
}
1240
else {
1241
/* We were given an invalid set of arguments */
1242
return False;
1243
}
1244
}
1245
1246
1247
PUBLIC Bool
1248
glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx )
1249
{
1250
return glXMakeContextCurrent( dpy, drawable, drawable, ctx );
1251
}
1252
1253
1254
PUBLIC GLXContext
1255
glXGetCurrentContext(void)
1256
{
1257
return GetCurrentContext();
1258
}
1259
1260
1261
PUBLIC Display *
1262
glXGetCurrentDisplay(void)
1263
{
1264
GLXContext glxCtx = glXGetCurrentContext();
1265
1266
return glxCtx ? glxCtx->currentDpy : NULL;
1267
}
1268
1269
1270
PUBLIC Display *
1271
glXGetCurrentDisplayEXT(void)
1272
{
1273
return glXGetCurrentDisplay();
1274
}
1275
1276
1277
PUBLIC GLXDrawable
1278
glXGetCurrentDrawable(void)
1279
{
1280
GLXContext gc = glXGetCurrentContext();
1281
return gc ? gc->currentDrawable : 0;
1282
}
1283
1284
1285
PUBLIC GLXDrawable
1286
glXGetCurrentReadDrawable(void)
1287
{
1288
GLXContext gc = glXGetCurrentContext();
1289
return gc ? gc->currentReadable : 0;
1290
}
1291
1292
1293
PUBLIC GLXDrawable
1294
glXGetCurrentReadDrawableSGI(void)
1295
{
1296
return glXGetCurrentReadDrawable();
1297
}
1298
1299
1300
PUBLIC GLXPixmap
1301
glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap )
1302
{
1303
XMesaVisual v;
1304
XMesaBuffer b;
1305
1306
v = find_glx_visual( dpy, visinfo );
1307
if (!v) {
1308
v = create_glx_visual( dpy, visinfo );
1309
if (!v) {
1310
/* unusable visual */
1311
return 0;
1312
}
1313
}
1314
1315
b = XMesaCreatePixmapBuffer( v, pixmap, 0 );
1316
if (!b) {
1317
return 0;
1318
}
1319
return b->ws.drawable;
1320
}
1321
1322
1323
/*** GLX_MESA_pixmap_colormap ***/
1324
1325
PUBLIC GLXPixmap
1326
glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo,
1327
Pixmap pixmap, Colormap cmap )
1328
{
1329
XMesaVisual v;
1330
XMesaBuffer b;
1331
1332
v = find_glx_visual( dpy, visinfo );
1333
if (!v) {
1334
v = create_glx_visual( dpy, visinfo );
1335
if (!v) {
1336
/* unusable visual */
1337
return 0;
1338
}
1339
}
1340
1341
b = XMesaCreatePixmapBuffer( v, pixmap, cmap );
1342
if (!b) {
1343
return 0;
1344
}
1345
return b->ws.drawable;
1346
}
1347
1348
1349
PUBLIC void
1350
glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap )
1351
{
1352
XMesaBuffer b = XMesaFindBuffer(dpy, pixmap);
1353
if (b) {
1354
XMesaDestroyBuffer(b);
1355
}
1356
else if (getenv("MESA_DEBUG")) {
1357
_mesa_warning(NULL, "Mesa: glXDestroyGLXPixmap: invalid pixmap\n");
1358
}
1359
}
1360
1361
1362
PUBLIC void
1363
glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
1364
unsigned long mask )
1365
{
1366
XMesaContext xm_src = src->xmesaContext;
1367
XMesaContext xm_dst = dst->xmesaContext;
1368
(void) dpy;
1369
if (GetCurrentContext() == src) {
1370
glFlush();
1371
}
1372
XMesaCopyContext(xm_src, xm_dst, mask);
1373
}
1374
1375
1376
PUBLIC Bool
1377
glXQueryExtension( Display *dpy, int *errorBase, int *eventBase )
1378
{
1379
int op, ev, err;
1380
/* Mesa's GLX isn't really an X extension but we try to act like one. */
1381
if (!XQueryExtension(dpy, GLX_EXTENSION_NAME, &op, &ev, &err))
1382
ev = err = 0;
1383
if (errorBase)
1384
*errorBase = err;
1385
if (eventBase)
1386
*eventBase = ev;
1387
return True; /* we're faking GLX so always return success */
1388
}
1389
1390
1391
PUBLIC void
1392
glXDestroyContext( Display *dpy, GLXContext ctx )
1393
{
1394
if (ctx) {
1395
GLXContext glxCtx = ctx;
1396
(void) dpy;
1397
XMesaDestroyContext( glxCtx->xmesaContext );
1398
XMesaGarbageCollect();
1399
free(glxCtx);
1400
}
1401
}
1402
1403
1404
PUBLIC Bool
1405
glXIsDirect( Display *dpy, GLXContext ctx )
1406
{
1407
return ctx ? ctx->isDirect : False;
1408
}
1409
1410
1411
1412
PUBLIC void
1413
glXSwapBuffers( Display *dpy, GLXDrawable drawable )
1414
{
1415
XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );
1416
static boolean firsttime = 1, no_rast = 0;
1417
1418
if (firsttime) {
1419
no_rast = getenv("SP_NO_RAST") != NULL;
1420
firsttime = 0;
1421
}
1422
1423
if (no_rast)
1424
return;
1425
1426
if (buffer) {
1427
XMesaSwapBuffers(buffer);
1428
}
1429
else if (getenv("MESA_DEBUG")) {
1430
_mesa_warning(NULL, "glXSwapBuffers: invalid drawable 0x%x\n",
1431
(int) drawable);
1432
}
1433
}
1434
1435
1436
1437
/*** GLX_MESA_copy_sub_buffer ***/
1438
1439
PUBLIC void
1440
glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable,
1441
int x, int y, int width, int height)
1442
{
1443
XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );
1444
if (buffer) {
1445
XMesaCopySubBuffer(buffer, x, y, width, height);
1446
}
1447
else if (getenv("MESA_DEBUG")) {
1448
_mesa_warning(NULL, "Mesa: glXCopySubBufferMESA: invalid drawable\n");
1449
}
1450
}
1451
1452
1453
PUBLIC Bool
1454
glXQueryVersion( Display *dpy, int *maj, int *min )
1455
{
1456
(void) dpy;
1457
/* Return GLX version, not Mesa version */
1458
assert(CLIENT_MAJOR_VERSION == SERVER_MAJOR_VERSION);
1459
*maj = CLIENT_MAJOR_VERSION;
1460
*min = MIN2( CLIENT_MINOR_VERSION, SERVER_MINOR_VERSION );
1461
return True;
1462
}
1463
1464
1465
/*
1466
* Query the GLX attributes of the given XVisualInfo.
1467
*/
1468
static int
1469
get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig )
1470
{
1471
assert(xmvis);
1472
switch(attrib) {
1473
case GLX_USE_GL:
1474
if (fbconfig)
1475
return GLX_BAD_ATTRIBUTE;
1476
*value = (int) True;
1477
return 0;
1478
case GLX_BUFFER_SIZE:
1479
*value = xmvis->visinfo->depth;
1480
return 0;
1481
case GLX_LEVEL:
1482
*value = 0;
1483
return 0;
1484
case GLX_RGBA:
1485
if (fbconfig)
1486
return GLX_BAD_ATTRIBUTE;
1487
*value = True;
1488
return 0;
1489
case GLX_DOUBLEBUFFER:
1490
*value = (int) xmvis->mesa_visual.doubleBufferMode;
1491
return 0;
1492
case GLX_STEREO:
1493
*value = (int) xmvis->mesa_visual.stereoMode;
1494
return 0;
1495
case GLX_AUX_BUFFERS:
1496
*value = 0;
1497
return 0;
1498
case GLX_RED_SIZE:
1499
*value = xmvis->mesa_visual.redBits;
1500
return 0;
1501
case GLX_GREEN_SIZE:
1502
*value = xmvis->mesa_visual.greenBits;
1503
return 0;
1504
case GLX_BLUE_SIZE:
1505
*value = xmvis->mesa_visual.blueBits;
1506
return 0;
1507
case GLX_ALPHA_SIZE:
1508
*value = xmvis->mesa_visual.alphaBits;
1509
return 0;
1510
case GLX_DEPTH_SIZE:
1511
*value = xmvis->mesa_visual.depthBits;
1512
return 0;
1513
case GLX_STENCIL_SIZE:
1514
*value = xmvis->mesa_visual.stencilBits;
1515
return 0;
1516
case GLX_ACCUM_RED_SIZE:
1517
*value = xmvis->mesa_visual.accumRedBits;
1518
return 0;
1519
case GLX_ACCUM_GREEN_SIZE:
1520
*value = xmvis->mesa_visual.accumGreenBits;
1521
return 0;
1522
case GLX_ACCUM_BLUE_SIZE:
1523
*value = xmvis->mesa_visual.accumBlueBits;
1524
return 0;
1525
case GLX_ACCUM_ALPHA_SIZE:
1526
*value = xmvis->mesa_visual.accumAlphaBits;
1527
return 0;
1528
1529
/*
1530
* GLX_EXT_visual_info extension
1531
*/
1532
case GLX_X_VISUAL_TYPE_EXT:
1533
switch (xmvis->visinfo->CLASS) {
1534
case StaticGray: *value = GLX_STATIC_GRAY_EXT; return 0;
1535
case GrayScale: *value = GLX_GRAY_SCALE_EXT; return 0;
1536
case StaticColor: *value = GLX_STATIC_GRAY_EXT; return 0;
1537
case PseudoColor: *value = GLX_PSEUDO_COLOR_EXT; return 0;
1538
case TrueColor: *value = GLX_TRUE_COLOR_EXT; return 0;
1539
case DirectColor: *value = GLX_DIRECT_COLOR_EXT; return 0;
1540
}
1541
return 0;
1542
case GLX_TRANSPARENT_TYPE_EXT:
1543
/* normal planes */
1544
*value = GLX_NONE_EXT;
1545
return 0;
1546
case GLX_TRANSPARENT_INDEX_VALUE_EXT:
1547
/* undefined */
1548
return 0;
1549
case GLX_TRANSPARENT_RED_VALUE_EXT:
1550
/* undefined */
1551
return 0;
1552
case GLX_TRANSPARENT_GREEN_VALUE_EXT:
1553
/* undefined */
1554
return 0;
1555
case GLX_TRANSPARENT_BLUE_VALUE_EXT:
1556
/* undefined */
1557
return 0;
1558
case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
1559
/* undefined */
1560
return 0;
1561
1562
/*
1563
* GLX_EXT_visual_info extension
1564
*/
1565
case GLX_VISUAL_CAVEAT_EXT:
1566
*value = GLX_NONE_EXT;
1567
return 0;
1568
1569
/*
1570
* GLX_ARB_multisample
1571
*/
1572
case GLX_SAMPLE_BUFFERS_ARB:
1573
*value = xmvis->mesa_visual.samples > 0;
1574
return 0;
1575
case GLX_SAMPLES_ARB:
1576
*value = xmvis->mesa_visual.samples;
1577
return 0;
1578
1579
/*
1580
* For FBConfigs:
1581
*/
1582
case GLX_SCREEN_EXT:
1583
if (!fbconfig)
1584
return GLX_BAD_ATTRIBUTE;
1585
*value = xmvis->visinfo->screen;
1586
break;
1587
case GLX_DRAWABLE_TYPE: /*SGIX too */
1588
if (!fbconfig)
1589
return GLX_BAD_ATTRIBUTE;
1590
*value = GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT;
1591
break;
1592
case GLX_RENDER_TYPE_SGIX:
1593
if (!fbconfig)
1594
return GLX_BAD_ATTRIBUTE;
1595
*value = GLX_RGBA_BIT;
1596
break;
1597
case GLX_X_RENDERABLE_SGIX:
1598
if (!fbconfig)
1599
return GLX_BAD_ATTRIBUTE;
1600
*value = True; /* XXX really? */
1601
break;
1602
case GLX_FBCONFIG_ID_SGIX:
1603
if (!fbconfig)
1604
return GLX_BAD_ATTRIBUTE;
1605
*value = xmvis->visinfo->visualid;
1606
break;
1607
case GLX_MAX_PBUFFER_WIDTH:
1608
if (!fbconfig)
1609
return GLX_BAD_ATTRIBUTE;
1610
/* XXX should be same as ctx->Const.MaxRenderbufferSize */
1611
*value = DisplayWidth(xmvis->display, xmvis->visinfo->screen);
1612
break;
1613
case GLX_MAX_PBUFFER_HEIGHT:
1614
if (!fbconfig)
1615
return GLX_BAD_ATTRIBUTE;
1616
*value = DisplayHeight(xmvis->display, xmvis->visinfo->screen);
1617
break;
1618
case GLX_MAX_PBUFFER_PIXELS:
1619
if (!fbconfig)
1620
return GLX_BAD_ATTRIBUTE;
1621
*value = DisplayWidth(xmvis->display, xmvis->visinfo->screen) *
1622
DisplayHeight(xmvis->display, xmvis->visinfo->screen);
1623
break;
1624
case GLX_VISUAL_ID:
1625
if (!fbconfig)
1626
return GLX_BAD_ATTRIBUTE;
1627
*value = xmvis->visinfo->visualid;
1628
break;
1629
1630
case GLX_BIND_TO_TEXTURE_RGB_EXT:
1631
*value = True; /*XXX*/
1632
break;
1633
case GLX_BIND_TO_TEXTURE_RGBA_EXT:
1634
/* XXX review */
1635
*value = xmvis->mesa_visual.alphaBits > 0 ? True : False;
1636
break;
1637
case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
1638
*value = True; /*XXX*/
1639
break;
1640
case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
1641
*value = (GLX_TEXTURE_1D_BIT_EXT |
1642
GLX_TEXTURE_2D_BIT_EXT |
1643
GLX_TEXTURE_RECTANGLE_BIT_EXT); /*XXX*/
1644
break;
1645
case GLX_Y_INVERTED_EXT:
1646
*value = True; /*XXX*/
1647
break;
1648
1649
default:
1650
return GLX_BAD_ATTRIBUTE;
1651
}
1652
return Success;
1653
}
1654
1655
1656
PUBLIC int
1657
glXGetConfig( Display *dpy, XVisualInfo *visinfo,
1658
int attrib, int *value )
1659
{
1660
XMesaVisual xmvis;
1661
int k;
1662
if (!dpy || !visinfo)
1663
return GLX_BAD_ATTRIBUTE;
1664
1665
xmvis = find_glx_visual( dpy, visinfo );
1666
if (!xmvis) {
1667
/* this visual wasn't obtained with glXChooseVisual */
1668
xmvis = create_glx_visual( dpy, visinfo );
1669
if (!xmvis) {
1670
/* this visual can't be used for GL rendering */
1671
if (attrib==GLX_USE_GL) {
1672
*value = (int) False;
1673
return 0;
1674
}
1675
else {
1676
return GLX_BAD_VISUAL;
1677
}
1678
}
1679
}
1680
1681
k = get_config(xmvis, attrib, value, GL_FALSE);
1682
return k;
1683
}
1684
1685
1686
PUBLIC void
1687
glXWaitGL( void )
1688
{
1689
XMesaContext xmesa = XMesaGetCurrentContext();
1690
XMesaFlush( xmesa );
1691
}
1692
1693
1694
1695
PUBLIC void
1696
glXWaitX( void )
1697
{
1698
XMesaContext xmesa = XMesaGetCurrentContext();
1699
XMesaFlush( xmesa );
1700
}
1701
1702
1703
static const char *
1704
get_extensions( void )
1705
{
1706
return EXTENSIONS;
1707
}
1708
1709
1710
1711
/* GLX 1.1 and later */
1712
PUBLIC const char *
1713
glXQueryExtensionsString( Display *dpy, int screen )
1714
{
1715
(void) dpy;
1716
(void) screen;
1717
return get_extensions();
1718
}
1719
1720
1721
1722
/* GLX 1.1 and later */
1723
PUBLIC const char *
1724
glXQueryServerString( Display *dpy, int screen, int name )
1725
{
1726
static char version[1000];
1727
sprintf(version, "%d.%d %s",
1728
SERVER_MAJOR_VERSION, SERVER_MINOR_VERSION, xmesa_get_name());
1729
1730
(void) dpy;
1731
(void) screen;
1732
1733
switch (name) {
1734
case GLX_EXTENSIONS:
1735
return get_extensions();
1736
case GLX_VENDOR:
1737
return VENDOR;
1738
case GLX_VERSION:
1739
return version;
1740
default:
1741
return NULL;
1742
}
1743
}
1744
1745
1746
1747
/* GLX 1.1 and later */
1748
PUBLIC const char *
1749
glXGetClientString( Display *dpy, int name )
1750
{
1751
static char version[1000];
1752
sprintf(version, "%d.%d %s", CLIENT_MAJOR_VERSION,
1753
CLIENT_MINOR_VERSION, xmesa_get_name());
1754
1755
(void) dpy;
1756
1757
switch (name) {
1758
case GLX_EXTENSIONS:
1759
return get_extensions();
1760
case GLX_VENDOR:
1761
return VENDOR;
1762
case GLX_VERSION:
1763
return version;
1764
default:
1765
return NULL;
1766
}
1767
}
1768
1769
1770
1771
/*
1772
* GLX 1.3 and later
1773
*/
1774
1775
1776
PUBLIC int
1777
glXGetFBConfigAttrib(Display *dpy, GLXFBConfig config,
1778
int attribute, int *value)
1779
{
1780
XMesaVisual v = (XMesaVisual) config;
1781
(void) dpy;
1782
(void) config;
1783
1784
if (!dpy || !config || !value)
1785
return -1;
1786
1787
return get_config(v, attribute, value, GL_TRUE);
1788
}
1789
1790
1791
PUBLIC GLXFBConfig *
1792
glXGetFBConfigs( Display *dpy, int screen, int *nelements )
1793
{
1794
XVisualInfo *visuals, visTemplate;
1795
const long visMask = VisualScreenMask;
1796
int i;
1797
1798
/* Get list of all X visuals */
1799
visTemplate.screen = screen;
1800
visuals = XGetVisualInfo(dpy, visMask, &visTemplate, nelements);
1801
if (*nelements > 0) {
1802
XMesaVisual *results = malloc(*nelements * sizeof(XMesaVisual));
1803
if (!results) {
1804
*nelements = 0;
1805
return NULL;
1806
}
1807
for (i = 0; i < *nelements; i++) {
1808
results[i] = create_glx_visual(dpy, visuals + i);
1809
if (!results[i]) {
1810
*nelements = i;
1811
break;
1812
}
1813
}
1814
return (GLXFBConfig *) results;
1815
}
1816
return NULL;
1817
}
1818
1819
1820
PUBLIC GLXFBConfig *
1821
glXChooseFBConfig(Display *dpy, int screen,
1822
const int *attribList, int *nitems)
1823
{
1824
XMesaVisual xmvis;
1825
1826
/* register ourselves as an extension on this display */
1827
register_with_display(dpy);
1828
1829
if (!attribList || !attribList[0]) {
1830
/* return list of all configs (per GLX_SGIX_fbconfig spec) */
1831
return glXGetFBConfigs(dpy, screen, nitems);
1832
}
1833
1834
xmvis = choose_visual(dpy, screen, attribList, GL_TRUE);
1835
if (xmvis) {
1836
GLXFBConfig *config = malloc(sizeof(XMesaVisual));
1837
if (!config) {
1838
*nitems = 0;
1839
return NULL;
1840
}
1841
*nitems = 1;
1842
config[0] = (GLXFBConfig) xmvis;
1843
return (GLXFBConfig *) config;
1844
}
1845
else {
1846
*nitems = 0;
1847
return NULL;
1848
}
1849
}
1850
1851
1852
PUBLIC XVisualInfo *
1853
glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config )
1854
{
1855
if (dpy && config) {
1856
XMesaVisual xmvis = (XMesaVisual) config;
1857
#if 0
1858
return xmvis->vishandle;
1859
#else
1860
/* create a new vishandle - the cached one may be stale */
1861
xmvis->vishandle = malloc(sizeof(XVisualInfo));
1862
if (xmvis->vishandle) {
1863
memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo));
1864
}
1865
return xmvis->vishandle;
1866
#endif
1867
}
1868
else {
1869
return NULL;
1870
}
1871
}
1872
1873
1874
PUBLIC GLXWindow
1875
glXCreateWindow(Display *dpy, GLXFBConfig config, Window win,
1876
const int *attribList)
1877
{
1878
XMesaVisual xmvis = (XMesaVisual) config;
1879
XMesaBuffer xmbuf;
1880
if (!xmvis)
1881
return 0;
1882
1883
xmbuf = XMesaCreateWindowBuffer(xmvis, win);
1884
if (!xmbuf)
1885
return 0;
1886
1887
(void) dpy;
1888
(void) attribList; /* Ignored in GLX 1.3 */
1889
1890
return win; /* A hack for now */
1891
}
1892
1893
1894
PUBLIC void
1895
glXDestroyWindow( Display *dpy, GLXWindow window )
1896
{
1897
XMesaBuffer b = XMesaFindBuffer(dpy, (Drawable) window);
1898
if (b)
1899
XMesaDestroyBuffer(b);
1900
/* don't destroy X window */
1901
}
1902
1903
1904
/* XXX untested */
1905
PUBLIC GLXPixmap
1906
glXCreatePixmap(Display *dpy, GLXFBConfig config, Pixmap pixmap,
1907
const int *attribList)
1908
{
1909
XMesaVisual v = (XMesaVisual) config;
1910
XMesaBuffer b;
1911
const int *attr;
1912
int target = 0, format = 0, mipmap = 0;
1913
int value;
1914
1915
if (!dpy || !config || !pixmap)
1916
return 0;
1917
1918
for (attr = attribList; attr && *attr; attr++) {
1919
switch (*attr) {
1920
case GLX_TEXTURE_FORMAT_EXT:
1921
attr++;
1922
switch (*attr) {
1923
case GLX_TEXTURE_FORMAT_NONE_EXT:
1924
case GLX_TEXTURE_FORMAT_RGB_EXT:
1925
case GLX_TEXTURE_FORMAT_RGBA_EXT:
1926
format = *attr;
1927
break;
1928
default:
1929
/* error */
1930
return 0;
1931
}
1932
break;
1933
case GLX_TEXTURE_TARGET_EXT:
1934
attr++;
1935
switch (*attr) {
1936
case GLX_TEXTURE_1D_EXT:
1937
case GLX_TEXTURE_2D_EXT:
1938
case GLX_TEXTURE_RECTANGLE_EXT:
1939
target = *attr;
1940
break;
1941
default:
1942
/* error */
1943
return 0;
1944
}
1945
break;
1946
case GLX_MIPMAP_TEXTURE_EXT:
1947
attr++;
1948
if (*attr)
1949
mipmap = 1;
1950
break;
1951
default:
1952
/* error */
1953
return 0;
1954
}
1955
}
1956
1957
if (format == GLX_TEXTURE_FORMAT_RGB_EXT) {
1958
if (get_config(v, GLX_BIND_TO_TEXTURE_RGB_EXT,
1959
&value, GL_TRUE) != Success
1960
|| !value) {
1961
return 0; /* error! */
1962
}
1963
}
1964
else if (format == GLX_TEXTURE_FORMAT_RGBA_EXT) {
1965
if (get_config(v, GLX_BIND_TO_TEXTURE_RGBA_EXT,
1966
&value, GL_TRUE) != Success
1967
|| !value) {
1968
return 0; /* error! */
1969
}
1970
}
1971
if (mipmap) {
1972
if (get_config(v, GLX_BIND_TO_MIPMAP_TEXTURE_EXT,
1973
&value, GL_TRUE) != Success
1974
|| !value) {
1975
return 0; /* error! */
1976
}
1977
}
1978
if (target == GLX_TEXTURE_1D_EXT) {
1979
if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT,
1980
&value, GL_TRUE) != Success
1981
|| (value & GLX_TEXTURE_1D_BIT_EXT) == 0) {
1982
return 0; /* error! */
1983
}
1984
}
1985
else if (target == GLX_TEXTURE_2D_EXT) {
1986
if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT,
1987
&value, GL_TRUE) != Success
1988
|| (value & GLX_TEXTURE_2D_BIT_EXT) == 0) {
1989
return 0; /* error! */
1990
}
1991
}
1992
if (target == GLX_TEXTURE_RECTANGLE_EXT) {
1993
if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT,
1994
&value, GL_TRUE) != Success
1995
|| (value & GLX_TEXTURE_RECTANGLE_BIT_EXT) == 0) {
1996
return 0; /* error! */
1997
}
1998
}
1999
2000
if (format || target || mipmap) {
2001
/* texture from pixmap */
2002
b = XMesaCreatePixmapTextureBuffer(v, pixmap, 0, format, target, mipmap);
2003
}
2004
else {
2005
b = XMesaCreatePixmapBuffer( v, pixmap, 0 );
2006
}
2007
if (!b) {
2008
return 0;
2009
}
2010
2011
return pixmap;
2012
}
2013
2014
2015
PUBLIC void
2016
glXDestroyPixmap( Display *dpy, GLXPixmap pixmap )
2017
{
2018
XMesaBuffer b = XMesaFindBuffer(dpy, (Drawable)pixmap);
2019
if (b)
2020
XMesaDestroyBuffer(b);
2021
/* don't destroy X pixmap */
2022
}
2023
2024
2025
PUBLIC GLXPbuffer
2026
glXCreatePbuffer(Display *dpy, GLXFBConfig config, const int *attribList)
2027
{
2028
XMesaVisual xmvis = (XMesaVisual) config;
2029
XMesaBuffer xmbuf;
2030
const int *attrib;
2031
int width = 0, height = 0;
2032
GLboolean useLargest = GL_FALSE, preserveContents = GL_FALSE;
2033
2034
(void) dpy;
2035
2036
for (attrib = attribList; *attrib; attrib++) {
2037
switch (*attrib) {
2038
case GLX_PBUFFER_WIDTH:
2039
attrib++;
2040
width = *attrib;
2041
break;
2042
case GLX_PBUFFER_HEIGHT:
2043
attrib++;
2044
height = *attrib;
2045
break;
2046
case GLX_PRESERVED_CONTENTS:
2047
attrib++;
2048
preserveContents = *attrib;
2049
break;
2050
case GLX_LARGEST_PBUFFER:
2051
attrib++;
2052
useLargest = *attrib;
2053
break;
2054
default:
2055
return 0;
2056
}
2057
}
2058
2059
if (width == 0 || height == 0)
2060
return 0;
2061
2062
if (width > PBUFFER_MAX_SIZE || height > PBUFFER_MAX_SIZE) {
2063
/* If allocation would have failed and GLX_LARGEST_PBUFFER is set,
2064
* allocate the largest possible buffer.
2065
*/
2066
if (useLargest) {
2067
width = PBUFFER_MAX_SIZE;
2068
height = PBUFFER_MAX_SIZE;
2069
}
2070
}
2071
2072
xmbuf = XMesaCreatePBuffer( xmvis, 0, width, height);
2073
/* A GLXPbuffer handle must be an X Drawable because that's what
2074
* glXMakeCurrent takes.
2075
*/
2076
if (xmbuf) {
2077
xmbuf->largestPbuffer = useLargest;
2078
xmbuf->preservedContents = preserveContents;
2079
return (GLXPbuffer) xmbuf->ws.drawable;
2080
}
2081
else {
2082
return 0;
2083
}
2084
}
2085
2086
2087
PUBLIC void
2088
glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf )
2089
{
2090
XMesaBuffer b = XMesaFindBuffer(dpy, pbuf);
2091
if (b) {
2092
XMesaDestroyBuffer(b);
2093
}
2094
}
2095
2096
2097
PUBLIC void
2098
glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute,
2099
unsigned int *value)
2100
{
2101
GLuint width, height;
2102
XMesaBuffer xmbuf = XMesaFindBuffer(dpy, draw);
2103
if (!xmbuf) {
2104
generate_error(dpy, GLXBadDrawable, draw, X_GLXGetDrawableAttributes, False);
2105
return;
2106
}
2107
2108
/* make sure buffer's dimensions are up to date */
2109
xmesa_get_window_size(dpy, xmbuf, &width, &height);
2110
2111
switch (attribute) {
2112
case GLX_WIDTH:
2113
*value = width;
2114
break;
2115
case GLX_HEIGHT:
2116
*value = height;
2117
break;
2118
case GLX_PRESERVED_CONTENTS:
2119
*value = xmbuf->preservedContents;
2120
break;
2121
case GLX_LARGEST_PBUFFER:
2122
*value = xmbuf->largestPbuffer;
2123
break;
2124
case GLX_FBCONFIG_ID:
2125
*value = xmbuf->xm_visual->visinfo->visualid;
2126
return;
2127
case GLX_TEXTURE_FORMAT_EXT:
2128
*value = xmbuf->TextureFormat;
2129
break;
2130
case GLX_TEXTURE_TARGET_EXT:
2131
*value = xmbuf->TextureTarget;
2132
break;
2133
case GLX_MIPMAP_TEXTURE_EXT:
2134
*value = xmbuf->TextureMipmap;
2135
break;
2136
2137
default:
2138
generate_error(dpy, BadValue, 0, X_GLXCreateContextAttribsARB, true);
2139
return;
2140
}
2141
}
2142
2143
2144
PUBLIC GLXContext
2145
glXCreateNewContext( Display *dpy, GLXFBConfig config,
2146
int renderType, GLXContext shareCtx, Bool direct )
2147
{
2148
XMesaVisual xmvis = (XMesaVisual) config;
2149
2150
if (!dpy || !config ||
2151
(renderType != GLX_RGBA_TYPE && renderType != GLX_COLOR_INDEX_TYPE))
2152
return 0;
2153
2154
return create_context(dpy, xmvis,
2155
shareCtx ? shareCtx->xmesaContext : NULL,
2156
direct,
2157
1, 0, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0x0);
2158
}
2159
2160
2161
PUBLIC int
2162
glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value )
2163
{
2164
GLXContext glxCtx = ctx;
2165
XMesaContext xmctx = glxCtx->xmesaContext;
2166
2167
(void) dpy;
2168
(void) ctx;
2169
2170
switch (attribute) {
2171
case GLX_FBCONFIG_ID:
2172
*value = xmctx->xm_visual->visinfo->visualid;
2173
break;
2174
case GLX_RENDER_TYPE:
2175
*value = GLX_RGBA_TYPE;
2176
break;
2177
case GLX_SCREEN:
2178
*value = 0;
2179
return Success;
2180
default:
2181
return GLX_BAD_ATTRIBUTE;
2182
}
2183
return 0;
2184
}
2185
2186
2187
PUBLIC void
2188
glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask )
2189
{
2190
XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
2191
if (xmbuf)
2192
xmbuf->selectedEvents = mask;
2193
}
2194
2195
2196
PUBLIC void
2197
glXGetSelectedEvent(Display *dpy, GLXDrawable drawable, unsigned long *mask)
2198
{
2199
XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
2200
if (xmbuf)
2201
*mask = xmbuf->selectedEvents;
2202
else
2203
*mask = 0;
2204
}
2205
2206
2207
2208
/*** GLX_SGI_swap_control ***/
2209
2210
PUBLIC int
2211
glXSwapIntervalSGI(int interval)
2212
{
2213
(void) interval;
2214
return 0;
2215
}
2216
2217
2218
2219
/*** GLX_SGI_video_sync ***/
2220
2221
static unsigned int FrameCounter = 0;
2222
2223
PUBLIC int
2224
glXGetVideoSyncSGI(unsigned int *count)
2225
{
2226
/* this is a bogus implementation */
2227
*count = FrameCounter++;
2228
return 0;
2229
}
2230
2231
PUBLIC int
2232
glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
2233
{
2234
if (divisor <= 0 || remainder < 0)
2235
return GLX_BAD_VALUE;
2236
/* this is a bogus implementation */
2237
FrameCounter++;
2238
while (FrameCounter % divisor != remainder)
2239
FrameCounter++;
2240
*count = FrameCounter;
2241
return 0;
2242
}
2243
2244
2245
2246
/*** GLX_SGI_make_current_read ***/
2247
2248
PUBLIC Bool
2249
glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read,
2250
GLXContext ctx)
2251
{
2252
return glXMakeContextCurrent( dpy, draw, read, ctx );
2253
}
2254
2255
/* not used
2256
static GLXDrawable
2257
glXGetCurrentReadDrawableSGI(void)
2258
{
2259
return 0;
2260
}
2261
*/
2262
2263
2264
/*** GLX_SGIX_video_source ***/
2265
#if defined(_VL_H)
2266
2267
PUBLIC GLXVideoSourceSGIX
2268
glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server,
2269
VLPath path, int nodeClass, VLNode drainNode)
2270
{
2271
(void) dpy;
2272
(void) screen;
2273
(void) server;
2274
(void) path;
2275
(void) nodeClass;
2276
(void) drainNode;
2277
return 0;
2278
}
2279
2280
PUBLIC void
2281
glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src)
2282
{
2283
(void) dpy;
2284
(void) src;
2285
}
2286
2287
#endif
2288
2289
2290
/*** GLX_EXT_import_context ***/
2291
2292
PUBLIC void
2293
glXFreeContextEXT(Display *dpy, GLXContext context)
2294
{
2295
(void) dpy;
2296
(void) context;
2297
}
2298
2299
PUBLIC GLXContextID
2300
glXGetContextIDEXT(const GLXContext context)
2301
{
2302
(void) context;
2303
return 0;
2304
}
2305
2306
PUBLIC GLXContext
2307
glXImportContextEXT(Display *dpy, GLXContextID contextID)
2308
{
2309
(void) dpy;
2310
(void) contextID;
2311
return 0;
2312
}
2313
2314
PUBLIC int
2315
glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute,
2316
int *value)
2317
{
2318
(void) dpy;
2319
(void) context;
2320
(void) attribute;
2321
(void) value;
2322
return 0;
2323
}
2324
2325
2326
2327
/*** GLX_SGIX_fbconfig ***/
2328
2329
PUBLIC int
2330
glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config,
2331
int attribute, int *value)
2332
{
2333
return glXGetFBConfigAttrib(dpy, config, attribute, value);
2334
}
2335
2336
PUBLIC GLXFBConfigSGIX *
2337
glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list,
2338
int *nelements)
2339
{
2340
return (GLXFBConfig *) glXChooseFBConfig(dpy, screen,
2341
attrib_list, nelements);
2342
}
2343
2344
2345
PUBLIC GLXPixmap
2346
glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config,
2347
Pixmap pixmap)
2348
{
2349
XMesaVisual xmvis = (XMesaVisual) config;
2350
XMesaBuffer xmbuf = XMesaCreatePixmapBuffer(xmvis, pixmap, 0);
2351
return xmbuf->ws.drawable; /* need to return an X ID */
2352
}
2353
2354
2355
PUBLIC GLXContext
2356
glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config,
2357
int renderType, GLXContext shareCtx,
2358
Bool direct)
2359
{
2360
XMesaVisual xmvis = (XMesaVisual) config;
2361
2362
if (!dpy || !config ||
2363
(renderType != GLX_RGBA_TYPE && renderType != GLX_COLOR_INDEX_TYPE))
2364
return 0;
2365
2366
return create_context(dpy, xmvis,
2367
shareCtx ? shareCtx->xmesaContext : NULL,
2368
direct,
2369
1, 0, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0x0);
2370
}
2371
2372
2373
PUBLIC XVisualInfo *
2374
glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config)
2375
{
2376
return glXGetVisualFromFBConfig(dpy, config);
2377
}
2378
2379
2380
PUBLIC GLXFBConfigSGIX
2381
glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis)
2382
{
2383
XMesaVisual xmvis = find_glx_visual(dpy, vis);
2384
if (!xmvis) {
2385
/* This visual wasn't found with glXChooseVisual() */
2386
xmvis = create_glx_visual(dpy, vis);
2387
}
2388
2389
return (GLXFBConfigSGIX) xmvis;
2390
}
2391
2392
2393
2394
/*** GLX_SGIX_pbuffer ***/
2395
2396
PUBLIC GLXPbufferSGIX
2397
glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config,
2398
unsigned int width, unsigned int height,
2399
int *attribList)
2400
{
2401
XMesaVisual xmvis = (XMesaVisual) config;
2402
XMesaBuffer xmbuf;
2403
const int *attrib;
2404
GLboolean useLargest = GL_FALSE, preserveContents = GL_FALSE;
2405
2406
(void) dpy;
2407
2408
for (attrib = attribList; attrib && *attrib; attrib++) {
2409
switch (*attrib) {
2410
case GLX_PRESERVED_CONTENTS_SGIX:
2411
attrib++;
2412
preserveContents = *attrib; /* ignored */
2413
break;
2414
case GLX_LARGEST_PBUFFER_SGIX:
2415
attrib++;
2416
useLargest = *attrib; /* ignored */
2417
break;
2418
default:
2419
return 0;
2420
}
2421
}
2422
2423
/* not used at this time */
2424
(void) useLargest;
2425
(void) preserveContents;
2426
2427
xmbuf = XMesaCreatePBuffer( xmvis, 0, width, height);
2428
/* A GLXPbuffer handle must be an X Drawable because that's what
2429
* glXMakeCurrent takes.
2430
*/
2431
return (GLXPbuffer) xmbuf->ws.drawable;
2432
}
2433
2434
2435
PUBLIC void
2436
glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf)
2437
{
2438
XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf);
2439
if (xmbuf) {
2440
XMesaDestroyBuffer(xmbuf);
2441
}
2442
}
2443
2444
2445
PUBLIC void
2446
glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute,
2447
unsigned int *value)
2448
{
2449
const XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf);
2450
2451
if (!xmbuf) {
2452
/* Generate GLXBadPbufferSGIX for bad pbuffer */
2453
return;
2454
}
2455
2456
switch (attribute) {
2457
case GLX_PRESERVED_CONTENTS_SGIX:
2458
*value = True;
2459
break;
2460
case GLX_LARGEST_PBUFFER_SGIX:
2461
*value = xmesa_buffer_width(xmbuf) * xmesa_buffer_height(xmbuf);
2462
break;
2463
case GLX_WIDTH_SGIX:
2464
*value = xmesa_buffer_width(xmbuf);
2465
break;
2466
case GLX_HEIGHT_SGIX:
2467
*value = xmesa_buffer_height(xmbuf);
2468
break;
2469
case GLX_EVENT_MASK_SGIX:
2470
*value = 0; /* XXX might be wrong */
2471
break;
2472
default:
2473
*value = 0;
2474
}
2475
}
2476
2477
2478
PUBLIC void
2479
glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask)
2480
{
2481
XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
2482
if (xmbuf) {
2483
/* Note: we'll never generate clobber events */
2484
xmbuf->selectedEvents = mask;
2485
}
2486
}
2487
2488
2489
PUBLIC void
2490
glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable,
2491
unsigned long *mask)
2492
{
2493
XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
2494
if (xmbuf) {
2495
*mask = xmbuf->selectedEvents;
2496
}
2497
else {
2498
*mask = 0;
2499
}
2500
}
2501
2502
2503
2504
/*** GLX_SGI_cushion ***/
2505
2506
PUBLIC void
2507
glXCushionSGI(Display *dpy, Window win, float cushion)
2508
{
2509
(void) dpy;
2510
(void) win;
2511
(void) cushion;
2512
}
2513
2514
2515
2516
/*** GLX_SGIX_video_resize ***/
2517
2518
PUBLIC int
2519
glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel,
2520
Window window)
2521
{
2522
(void) dpy;
2523
(void) screen;
2524
(void) channel;
2525
(void) window;
2526
return 0;
2527
}
2528
2529
PUBLIC int
2530
glXChannelRectSGIX(Display *dpy, int screen, int channel,
2531
int x, int y, int w, int h)
2532
{
2533
(void) dpy;
2534
(void) screen;
2535
(void) channel;
2536
(void) x;
2537
(void) y;
2538
(void) w;
2539
(void) h;
2540
return 0;
2541
}
2542
2543
PUBLIC int
2544
glXQueryChannelRectSGIX(Display *dpy, int screen, int channel,
2545
int *x, int *y, int *w, int *h)
2546
{
2547
(void) dpy;
2548
(void) screen;
2549
(void) channel;
2550
(void) x;
2551
(void) y;
2552
(void) w;
2553
(void) h;
2554
return 0;
2555
}
2556
2557
PUBLIC int
2558
glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel,
2559
int *dx, int *dy, int *dw, int *dh)
2560
{
2561
(void) dpy;
2562
(void) screen;
2563
(void) channel;
2564
(void) dx;
2565
(void) dy;
2566
(void) dw;
2567
(void) dh;
2568
return 0;
2569
}
2570
2571
PUBLIC int
2572
glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype)
2573
{
2574
(void) dpy;
2575
(void) screen;
2576
(void) channel;
2577
(void) synctype;
2578
return 0;
2579
}
2580
2581
2582
2583
/*** GLX_SGIX_dmbuffer **/
2584
2585
#if defined(_DM_BUFFER_H_)
2586
PUBLIC Bool
2587
glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer,
2588
DMparams *params, DMbuffer dmbuffer)
2589
{
2590
(void) dpy;
2591
(void) pbuffer;
2592
(void) params;
2593
(void) dmbuffer;
2594
return False;
2595
}
2596
#endif
2597
2598
2599
/*** GLX_SUN_get_transparent_index ***/
2600
2601
PUBLIC Status
2602
glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay,
2603
unsigned long *pTransparent)
2604
{
2605
(void) dpy;
2606
(void) overlay;
2607
(void) underlay;
2608
(void) pTransparent;
2609
return 0;
2610
}
2611
2612
2613
2614
/*** GLX_MESA_release_buffers ***/
2615
2616
/*
2617
* Release the depth, stencil, accum buffers attached to a GLXDrawable
2618
* (a window or pixmap) prior to destroying the GLXDrawable.
2619
*/
2620
PUBLIC Bool
2621
glXReleaseBuffersMESA( Display *dpy, GLXDrawable d )
2622
{
2623
XMesaBuffer b = XMesaFindBuffer(dpy, d);
2624
if (b) {
2625
XMesaDestroyBuffer(b);
2626
return True;
2627
}
2628
return False;
2629
}
2630
2631
/*** GLX_EXT_texture_from_pixmap ***/
2632
2633
PUBLIC void
2634
glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer,
2635
const int *attrib_list)
2636
{
2637
XMesaBuffer b = XMesaFindBuffer(dpy, drawable);
2638
if (b)
2639
XMesaBindTexImage(dpy, b, buffer, attrib_list);
2640
}
2641
2642
PUBLIC void
2643
glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer)
2644
{
2645
XMesaBuffer b = XMesaFindBuffer(dpy, drawable);
2646
if (b)
2647
XMesaReleaseTexImage(dpy, b, buffer);
2648
}
2649
2650
2651
2652
/*** GLX_ARB_create_context ***/
2653
2654
2655
GLXContext
2656
glXCreateContextAttribsARB(Display *dpy, GLXFBConfig config,
2657
GLXContext shareCtx, Bool direct,
2658
const int *attrib_list)
2659
{
2660
XMesaVisual xmvis = (XMesaVisual) config;
2661
int majorVersion = 1, minorVersion = 0;
2662
int contextFlags = 0x0;
2663
int profileMask = GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
2664
int renderType = GLX_RGBA_TYPE;
2665
unsigned i;
2666
Bool done = False;
2667
const int contextFlagsAll = (GLX_CONTEXT_DEBUG_BIT_ARB |
2668
GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB);
2669
GLXContext ctx;
2670
2671
/* parse attrib_list */
2672
for (i = 0; !done && attrib_list && attrib_list[i]; i++) {
2673
switch (attrib_list[i]) {
2674
case GLX_CONTEXT_MAJOR_VERSION_ARB:
2675
majorVersion = attrib_list[++i];
2676
break;
2677
case GLX_CONTEXT_MINOR_VERSION_ARB:
2678
minorVersion = attrib_list[++i];
2679
break;
2680
case GLX_CONTEXT_FLAGS_ARB:
2681
contextFlags = attrib_list[++i];
2682
break;
2683
case GLX_CONTEXT_PROFILE_MASK_ARB:
2684
profileMask = attrib_list[++i];
2685
break;
2686
case GLX_RENDER_TYPE:
2687
renderType = attrib_list[++i];
2688
break;
2689
case 0:
2690
/* end of list */
2691
done = True;
2692
break;
2693
default:
2694
/* bad attribute */
2695
generate_error(dpy, BadValue, 0, X_GLXCreateContextAttribsARB, True);
2696
return NULL;
2697
}
2698
}
2699
2700
/* check contextFlags */
2701
if (contextFlags & ~contextFlagsAll) {
2702
generate_error(dpy, BadValue, 0, X_GLXCreateContextAttribsARB, True);
2703
return NULL;
2704
}
2705
2706
/* check profileMask */
2707
if (profileMask != GLX_CONTEXT_CORE_PROFILE_BIT_ARB &&
2708
profileMask != GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB &&
2709
profileMask != GLX_CONTEXT_ES_PROFILE_BIT_EXT) {
2710
generate_error(dpy, GLXBadProfileARB, 0, X_GLXCreateContextAttribsARB, False);
2711
return NULL;
2712
}
2713
2714
/* check renderType */
2715
if (renderType != GLX_RGBA_TYPE &&
2716
renderType != GLX_COLOR_INDEX_TYPE) {
2717
generate_error(dpy, BadValue, 0, X_GLXCreateContextAttribsARB, True);
2718
return NULL;
2719
}
2720
2721
/* check version */
2722
if (majorVersion <= 0 ||
2723
minorVersion < 0 ||
2724
(profileMask != GLX_CONTEXT_ES_PROFILE_BIT_EXT &&
2725
((majorVersion == 1 && minorVersion > 5) ||
2726
(majorVersion == 2 && minorVersion > 1) ||
2727
(majorVersion == 3 && minorVersion > 3) ||
2728
(majorVersion == 4 && minorVersion > 5) ||
2729
majorVersion > 4))) {
2730
generate_error(dpy, BadMatch, 0, X_GLXCreateContextAttribsARB, True);
2731
return NULL;
2732
}
2733
if (profileMask == GLX_CONTEXT_ES_PROFILE_BIT_EXT &&
2734
((majorVersion == 1 && minorVersion > 1) ||
2735
(majorVersion == 2 && minorVersion > 0) ||
2736
(majorVersion == 3 && minorVersion > 1) ||
2737
majorVersion > 3)) {
2738
/* GLX_EXT_create_context_es2_profile says nothing to justifying a
2739
* different error code for invalid ES versions, but this is what NVIDIA
2740
* does and piglit expects.
2741
*/
2742
generate_error(dpy, GLXBadProfileARB, 0, X_GLXCreateContextAttribsARB, False);
2743
return NULL;
2744
}
2745
2746
if ((contextFlags & GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB) &&
2747
majorVersion < 3) {
2748
generate_error(dpy, BadMatch, 0, X_GLXCreateContextAttribsARB, True);
2749
return NULL;
2750
}
2751
2752
if (renderType == GLX_COLOR_INDEX_TYPE && majorVersion >= 3) {
2753
generate_error(dpy, BadMatch, 0, X_GLXCreateContextAttribsARB, True);
2754
return NULL;
2755
}
2756
2757
ctx = create_context(dpy, xmvis,
2758
shareCtx ? shareCtx->xmesaContext : NULL,
2759
direct,
2760
majorVersion, minorVersion,
2761
profileMask, contextFlags);
2762
if (!ctx) {
2763
generate_error(dpy, GLXBadFBConfig, 0, X_GLXCreateContextAttribsARB, False);
2764
}
2765
2766
return ctx;
2767
}
2768
2769