2 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice including the dates of first publication and
13 * either this permission notice or a reference to
14 * http://oss.sgi.com/projects/FreeB/
15 * shall be included in all copies or substantial portions of the Software.
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 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * Except as contained in this notice, the name of Silicon Graphics, Inc.
26 * shall not be used in advertising or otherwise to promote the sale, use or
27 * other dealings in this Software without prior written authorization from
28 * Silicon Graphics, Inc.
31 #ifdef HAVE_DIX_CONFIG_H
32 #include <dix-config.h>
35 #include <GL/glxtokens.h>
37 #include <windowstr.h>
39 #include <colormapst.h>
42 #include "glxserver.h"
45 #include "protocol-versions.h"
47 static DevPrivateKeyRec glxScreenPrivateKeyRec
;
49 #define glxScreenPrivateKey (&glxScreenPrivateKeyRec)
51 const char GLServerVersion
[] = "1.4";
52 static const char GLServerExtensions
[] =
53 "GL_ARB_depth_texture "
54 "GL_ARB_draw_buffers "
55 "GL_ARB_fragment_program "
56 "GL_ARB_fragment_program_shadow "
59 "GL_ARB_multitexture "
60 "GL_ARB_occlusion_query "
61 "GL_ARB_point_parameters "
62 "GL_ARB_point_sprite "
64 "GL_ARB_shadow_ambient "
65 "GL_ARB_texture_border_clamp "
66 "GL_ARB_texture_compression "
67 "GL_ARB_texture_cube_map "
68 "GL_ARB_texture_env_add "
69 "GL_ARB_texture_env_combine "
70 "GL_ARB_texture_env_crossbar "
71 "GL_ARB_texture_env_dot3 "
72 "GL_ARB_texture_mirrored_repeat "
73 "GL_ARB_texture_non_power_of_two "
74 "GL_ARB_transpose_matrix "
75 "GL_ARB_vertex_program "
80 "GL_EXT_blend_equation_separate "
81 "GL_EXT_blend_func_separate "
82 "GL_EXT_blend_logic_op "
83 "GL_EXT_blend_minmax "
84 "GL_EXT_blend_subtract "
85 "GL_EXT_clip_volume_hint "
86 "GL_EXT_copy_texture "
87 "GL_EXT_draw_range_elements "
89 "GL_EXT_framebuffer_object "
90 "GL_EXT_multi_draw_arrays "
91 "GL_EXT_packed_pixels "
92 "GL_EXT_paletted_texture "
93 "GL_EXT_point_parameters "
94 "GL_EXT_polygon_offset "
95 "GL_EXT_rescale_normal "
96 "GL_EXT_secondary_color "
97 "GL_EXT_separate_specular_color "
98 "GL_EXT_shadow_funcs "
99 "GL_EXT_shared_texture_palette "
100 "GL_EXT_stencil_two_side "
101 "GL_EXT_stencil_wrap "
105 "GL_EXT_texture_compression_dxt1 "
106 "GL_EXT_texture_compression_s3tc "
107 "GL_EXT_texture_edge_clamp "
108 "GL_EXT_texture_env_add "
109 "GL_EXT_texture_env_combine "
110 "GL_EXT_texture_env_dot3 "
111 "GL_EXT_texture_filter_anisotropic "
112 "GL_EXT_texture_lod "
113 "GL_EXT_texture_lod_bias "
114 "GL_EXT_texture_mirror_clamp "
115 "GL_EXT_texture_object "
116 "GL_EXT_texture_rectangle "
117 "GL_EXT_vertex_array "
118 "GL_3DFX_texture_compression_FXT1 "
119 "GL_APPLE_packed_pixels "
120 "GL_ATI_draw_buffers "
121 "GL_ATI_texture_env_combine3 "
122 "GL_ATI_texture_mirror_once "
123 "GL_HP_occlusion_test "
124 "GL_IBM_texture_mirrored_repeat "
125 "GL_INGR_blend_func_separate "
126 "GL_MESA_pack_invert "
127 "GL_MESA_ycbcr_texture "
128 "GL_NV_blend_square "
130 "GL_NV_fog_distance "
131 "GL_NV_fragment_program_option "
132 "GL_NV_fragment_program2 "
133 "GL_NV_light_max_exponent "
134 "GL_NV_multisample_filter_hint "
135 "GL_NV_point_sprite "
136 "GL_NV_texgen_reflection "
137 "GL_NV_texture_compression_vtc "
138 "GL_NV_texture_env_combine4 "
139 "GL_NV_texture_expand_normal "
140 "GL_NV_texture_rectangle "
141 "GL_NV_vertex_program2_option "
142 "GL_NV_vertex_program3 "
143 "GL_OES_compressed_paletted_texture "
144 "GL_SGI_color_matrix "
145 "GL_SGI_color_table "
146 "GL_SGIS_generate_mipmap "
147 "GL_SGIS_multisample "
148 "GL_SGIS_point_parameters "
149 "GL_SGIS_texture_border_clamp "
150 "GL_SGIS_texture_edge_clamp "
151 "GL_SGIS_texture_lod "
152 "GL_SGIX_depth_texture "
154 "GL_SGIX_shadow_ambient "
155 "GL_SUN_slice_accum ";
158 ** We have made the simplifying assuption that the same extensions are
159 ** supported across all screens in a multi-screen system.
161 unsigned glxMajorVersion
= SERVER_GLX_MAJOR_VERSION
;
162 unsigned glxMinorVersion
= SERVER_GLX_MINOR_VERSION
;
163 static char GLXServerExtensions
[] =
164 "GLX_ARB_multisample "
165 "GLX_EXT_visual_info "
166 "GLX_EXT_visual_rating "
167 "GLX_EXT_import_context "
168 "GLX_EXT_texture_from_pixmap "
169 "GLX_OML_swap_method "
170 "GLX_SGI_make_current_read "
172 "GLX_SGIS_multisample "
176 "GLX_MESA_copy_sub_buffer ";
179 glxCloseScreen(ScreenPtr pScreen
)
181 __GLXscreen
*pGlxScreen
= glxGetScreen(pScreen
);
183 pScreen
->CloseScreen
= pGlxScreen
->CloseScreen
;
185 pGlxScreen
->destroy(pGlxScreen
);
187 return pScreen
->CloseScreen(pScreen
);
191 glxGetScreen(ScreenPtr pScreen
)
193 return dixLookupPrivate(&pScreen
->devPrivates
, glxScreenPrivateKey
);
197 GlxSetVisualConfigs(int nconfigs
, void *configs
, void **privates
)
199 /* We keep this stub around for the DDX drivers that still
204 glxConvertToXVisualType(int visualType
)
206 static const int x_visual_types
[] = {
207 TrueColor
, DirectColor
,
208 PseudoColor
, StaticColor
,
209 GrayScale
, StaticGray
212 return ((unsigned) (visualType
- GLX_TRUE_COLOR
) < 6)
213 ? x_visual_types
[visualType
- GLX_TRUE_COLOR
] : -1;
216 /* This code inspired by composite/compinit.c. We could move this to
217 * mi/ and share it with composite.*/
220 AddScreenVisuals(ScreenPtr pScreen
, int count
, int d
)
226 for (i
= 0; i
< pScreen
->numDepths
; i
++) {
227 if (pScreen
->allowedDepths
[i
].depth
== d
) {
228 depth
= &pScreen
->allowedDepths
[i
];
235 if (ResizeVisualArray(pScreen
, count
, depth
) == FALSE
)
238 /* Return a pointer to the first of the added visuals. */
239 return pScreen
->visuals
+ pScreen
->numVisuals
- count
;
243 findFirstSet(unsigned int v
)
247 for (i
= 0; i
< 32; i
++)
255 initGlxVisual(VisualPtr visual
, __GLXconfig
* config
)
259 maxBits
= max(config
->redBits
, max(config
->greenBits
, config
->blueBits
));
261 config
->visualID
= visual
->vid
;
262 visual
->class = glxConvertToXVisualType(config
->visualType
);
263 visual
->bitsPerRGBValue
= maxBits
;
264 visual
->ColormapEntries
= 1 << maxBits
;
265 visual
->nplanes
= config
->redBits
+ config
->greenBits
+ config
->blueBits
;
267 visual
->redMask
= config
->redMask
;
268 visual
->greenMask
= config
->greenMask
;
269 visual
->blueMask
= config
->blueMask
;
270 visual
->offsetRed
= findFirstSet(config
->redMask
);
271 visual
->offsetGreen
= findFirstSet(config
->greenMask
);
272 visual
->offsetBlue
= findFirstSet(config
->blueMask
);
276 pickFBConfig(__GLXscreen
* pGlxScreen
, VisualPtr visual
)
278 __GLXconfig
*best
= NULL
, *config
;
281 for (config
= pGlxScreen
->fbconfigs
; config
!= NULL
; config
= config
->next
) {
284 if (config
->redMask
!= visual
->redMask
||
285 config
->greenMask
!= visual
->greenMask
||
286 config
->blueMask
!= visual
->blueMask
)
288 if (config
->visualRating
!= GLX_NONE
)
290 /* Ignore multisampled configs */
291 if (config
->sampleBuffers
)
293 if (glxConvertToXVisualType(config
->visualType
) != visual
->class)
295 /* If it's the 32-bit RGBA visual, demand a 32-bit fbconfig. */
296 if (visual
->nplanes
== 32 && config
->rgbBits
!= 32)
298 /* Can't use the same FBconfig for multiple X visuals. I think. */
299 if (config
->visualID
!= 0)
302 if (config
->doubleBufferMode
> 0)
304 if (config
->depthBits
> 0)
306 if (config
->stencilBits
> 0)
308 if (config
->alphaBits
> 0)
311 if (score
> best_score
) {
321 __glXScreenInit(__GLXscreen
* pGlxScreen
, ScreenPtr pScreen
)
327 if (!dixRegisterPrivateKey(&glxScreenPrivateKeyRec
, PRIVATE_SCREEN
, 0))
330 pGlxScreen
->pScreen
= pScreen
;
331 pGlxScreen
->GLextensions
= strdup(GLServerExtensions
);
332 pGlxScreen
->GLXextensions
= strdup(GLXServerExtensions
);
334 /* All GLX providers must support all of the functionality required for at
335 * least GLX 1.2. If the provider supports a higher version, the GLXminor
336 * version can be changed in the provider's screen-probe routine. For
337 * most providers, the screen-probe routine is the caller of this
340 pGlxScreen
->GLXmajor
= 1;
341 pGlxScreen
->GLXminor
= 2;
343 pGlxScreen
->CloseScreen
= pScreen
->CloseScreen
;
344 pScreen
->CloseScreen
= glxCloseScreen
;
347 for (m
= pGlxScreen
->fbconfigs
; m
!= NULL
; m
= m
->next
) {
348 m
->fbconfigID
= FakeClientID(0);
352 pGlxScreen
->numFBConfigs
= i
;
354 pGlxScreen
->visuals
=
355 calloc(pGlxScreen
->numFBConfigs
, sizeof(__GLXconfig
*));
357 /* First, try to choose featureful FBconfigs for the existing X visuals.
358 * Note that if multiple X visuals end up with the same FBconfig being
359 * chosen, the later X visuals don't get GLX visuals (because we want to
360 * prioritize the root visual being GLX).
362 for (i
= 0; i
< pScreen
->numVisuals
; i
++) {
363 VisualPtr visual
= &pScreen
->visuals
[i
];
365 config
= pickFBConfig(pGlxScreen
, visual
);
367 pGlxScreen
->visuals
[pGlxScreen
->numVisuals
++] = config
;
368 config
->visualID
= visual
->vid
;
372 /* Then, add new visuals corresponding to all FBconfigs that didn't have
373 * an existing, appropriate visual.
375 for (config
= pGlxScreen
->fbconfigs
; config
!= NULL
; config
= config
->next
) {
380 if (config
->visualID
!= 0)
383 /* Only count RGB bits and not alpha, as we're not trying to create
384 * visuals for compositing (that's what the 32-bit composite visual
385 * set up above is for.
387 depth
= config
->redBits
+ config
->greenBits
+ config
->blueBits
;
389 /* Make sure that our FBconfig's depth can actually be displayed
390 * (corresponds to an existing visual).
392 for (i
= 0; i
< pScreen
->numVisuals
; i
++) {
393 if (depth
== pScreen
->visuals
[i
].nplanes
)
396 /* if it can't, fix up the fbconfig to not advertise window support */
397 if (i
== pScreen
->numVisuals
)
398 config
->drawableType
&= ~(GLX_WINDOW_BIT
);
400 /* fbconfig must support window drawables */
401 if (!(config
->drawableType
& GLX_WINDOW_BIT
)) {
402 config
->visualID
= 0;
406 /* Create a new X visual for our FBconfig. */
407 visual
= AddScreenVisuals(pScreen
, 1, depth
);
411 pGlxScreen
->visuals
[pGlxScreen
->numVisuals
++] = config
;
412 initGlxVisual(visual
, config
);
415 dixSetPrivate(&pScreen
->devPrivates
, glxScreenPrivateKey
, pGlxScreen
);
419 __glXScreenDestroy(__GLXscreen
* screen
)
421 free(screen
->GLXextensions
);
422 free(screen
->GLextensions
);
423 free(screen
->visuals
);