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;
48 #define glxScreenPrivateKey (&glxScreenPrivateKeyRec)
50 const char GLServerVersion[] = "1.4";
51 static const char GLServerExtensions[] =
52 "GL_ARB_depth_texture "
53 "GL_ARB_draw_buffers "
54 "GL_ARB_fragment_program "
55 "GL_ARB_fragment_program_shadow "
58 "GL_ARB_multitexture "
59 "GL_ARB_occlusion_query "
60 "GL_ARB_point_parameters "
61 "GL_ARB_point_sprite "
63 "GL_ARB_shadow_ambient "
64 "GL_ARB_texture_border_clamp "
65 "GL_ARB_texture_compression "
66 "GL_ARB_texture_cube_map "
67 "GL_ARB_texture_env_add "
68 "GL_ARB_texture_env_combine "
69 "GL_ARB_texture_env_crossbar "
70 "GL_ARB_texture_env_dot3 "
71 "GL_ARB_texture_mirrored_repeat "
72 "GL_ARB_texture_non_power_of_two "
73 "GL_ARB_transpose_matrix "
74 "GL_ARB_vertex_program "
79 "GL_EXT_blend_equation_separate "
80 "GL_EXT_blend_func_separate "
81 "GL_EXT_blend_logic_op "
82 "GL_EXT_blend_minmax "
83 "GL_EXT_blend_subtract "
84 "GL_EXT_clip_volume_hint "
85 "GL_EXT_copy_texture "
86 "GL_EXT_draw_range_elements "
88 "GL_EXT_framebuffer_object "
89 "GL_EXT_multi_draw_arrays "
90 "GL_EXT_packed_pixels "
91 "GL_EXT_paletted_texture "
92 "GL_EXT_point_parameters "
93 "GL_EXT_polygon_offset "
94 "GL_EXT_rescale_normal "
95 "GL_EXT_secondary_color "
96 "GL_EXT_separate_specular_color "
97 "GL_EXT_shadow_funcs "
98 "GL_EXT_shared_texture_palette "
99 "GL_EXT_stencil_two_side "
100 "GL_EXT_stencil_wrap "
104 "GL_EXT_texture_compression_dxt1 "
105 "GL_EXT_texture_compression_s3tc "
106 "GL_EXT_texture_edge_clamp "
107 "GL_EXT_texture_env_add "
108 "GL_EXT_texture_env_combine "
109 "GL_EXT_texture_env_dot3 "
110 "GL_EXT_texture_filter_anisotropic "
111 "GL_EXT_texture_lod "
112 "GL_EXT_texture_lod_bias "
113 "GL_EXT_texture_mirror_clamp "
114 "GL_EXT_texture_object "
115 "GL_EXT_texture_rectangle "
116 "GL_EXT_vertex_array "
117 "GL_3DFX_texture_compression_FXT1 "
118 "GL_APPLE_packed_pixels "
119 "GL_ATI_draw_buffers "
120 "GL_ATI_texture_env_combine3 "
121 "GL_ATI_texture_mirror_once "
122 "GL_HP_occlusion_test "
123 "GL_IBM_texture_mirrored_repeat "
124 "GL_INGR_blend_func_separate "
125 "GL_MESA_pack_invert "
126 "GL_MESA_ycbcr_texture "
127 "GL_NV_blend_square "
129 "GL_NV_fog_distance "
130 "GL_NV_fragment_program "
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_program "
142 "GL_NV_vertex_program1_1 "
143 "GL_NV_vertex_program2 "
144 "GL_NV_vertex_program2_option "
145 "GL_NV_vertex_program3 "
146 "GL_OES_compressed_paletted_texture "
147 "GL_SGI_color_matrix "
148 "GL_SGI_color_table "
149 "GL_SGIS_generate_mipmap "
150 "GL_SGIS_multisample "
151 "GL_SGIS_point_parameters "
152 "GL_SGIS_texture_border_clamp "
153 "GL_SGIS_texture_edge_clamp "
154 "GL_SGIS_texture_lod "
155 "GL_SGIX_depth_texture "
157 "GL_SGIX_shadow_ambient "
158 "GL_SUN_slice_accum "
162 ** We have made the simplifying assuption that the same extensions are
163 ** supported across all screens in a multi-screen system.
165 static char GLXServerVendorName[] = "SGI";
166 unsigned glxMajorVersion = SERVER_GLX_MAJOR_VERSION;
167 unsigned glxMinorVersion = SERVER_GLX_MINOR_VERSION;
168 static char GLXServerExtensions[] =
169 "GLX_ARB_multisample "
170 "GLX_EXT_visual_info "
171 "GLX_EXT_visual_rating "
172 "GLX_EXT_import_context "
173 "GLX_EXT_texture_from_pixmap "
174 "GLX_OML_swap_method "
175 "GLX_SGI_make_current_read "
177 "GLX_SGIS_multisample "
178 "GLX_SGIX_hyperpipe "
179 "GLX_SGIX_swap_barrier "
183 "GLX_MESA_copy_sub_buffer "
184 "GLX_INTEL_swap_event"
188 * If your DDX driver wants to register support for swap barriers or hyperpipe
189 * topology, it should call __glXHyperpipeInit() or __glXSwapBarrierInit()
190 * with a dispatch table of functions to handle the requests. In the XFree86
191 * DDX, for example, you would call these near the bottom of the driver's
192 * ScreenInit method, after DRI has been initialized.
194 * This should be replaced with a better method when we teach the server how
195 * to load DRI drivers.
198 void __glXHyperpipeInit(int screen, __GLXHyperpipeExtensionFuncs *funcs)
200 __GLXscreen *pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
202 pGlxScreen->hyperpipeFuncs = funcs;
205 void __glXSwapBarrierInit(int screen, __GLXSwapBarrierExtensionFuncs *funcs)
207 __GLXscreen *pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
209 pGlxScreen->swapBarrierFuncs = funcs;
213 glxCloseScreen (int index, ScreenPtr pScreen)
215 __GLXscreen *pGlxScreen = glxGetScreen(pScreen);
217 pScreen->CloseScreen = pGlxScreen->CloseScreen;
219 pGlxScreen->destroy(pGlxScreen);
221 return pScreen->CloseScreen(index, pScreen);
225 glxGetScreen(ScreenPtr pScreen)
227 return dixLookupPrivate(&pScreen->devPrivates, glxScreenPrivateKey);
230 _X_EXPORT void GlxSetVisualConfigs(int nconfigs,
231 void *configs, void **privates)
233 /* We keep this stub around for the DDX drivers that still
237 GLint glxConvertToXVisualType(int visualType)
239 static const int x_visual_types[] = {
240 TrueColor, DirectColor,
241 PseudoColor, StaticColor,
242 GrayScale, StaticGray
245 return ( (unsigned) (visualType - GLX_TRUE_COLOR) < 6 )
246 ? x_visual_types[ visualType - GLX_TRUE_COLOR ] : -1;
249 /* This code inspired by composite/compinit.c. We could move this to
250 * mi/ and share it with composite.*/
253 AddScreenVisuals(ScreenPtr pScreen, int count, int d)
259 for (i = 0; i < pScreen->numDepths; i++) {
260 if (pScreen->allowedDepths[i].depth == d) {
261 depth = &pScreen->allowedDepths[i];
268 if (ResizeVisualArray(pScreen, count, depth) == FALSE)
271 /* Return a pointer to the first of the added visuals. */
272 return pScreen->visuals + pScreen->numVisuals - count;
276 findFirstSet(unsigned int v)
280 for (i = 0; i < 32; i++)
288 initGlxVisual(VisualPtr visual, __GLXconfig *config)
291 maxBits = max(config->redBits, max(config->greenBits, config->blueBits));
293 config->visualID = visual->vid;
294 visual->class = glxConvertToXVisualType(config->visualType);
295 visual->bitsPerRGBValue = maxBits;
296 visual->ColormapEntries = 1 << maxBits;
297 visual->nplanes = config->redBits + config->greenBits + config->blueBits;
299 visual->redMask = config->redMask;
300 visual->greenMask = config->greenMask;
301 visual->blueMask = config->blueMask;
302 visual->offsetRed = findFirstSet(config->redMask);
303 visual->offsetGreen = findFirstSet(config->greenMask);
304 visual->offsetBlue = findFirstSet(config->blueMask);
308 pickFBConfig(__GLXscreen *pGlxScreen, VisualPtr visual)
310 __GLXconfig *best = NULL, *config;
313 for (config = pGlxScreen->fbconfigs; config != NULL; config = config->next) {
316 if (config->redMask != visual->redMask ||
317 config->greenMask != visual->greenMask ||
318 config->blueMask != visual->blueMask)
320 if (config->visualRating != GLX_NONE)
322 if (glxConvertToXVisualType(config->visualType) != visual->class)
324 /* If it's the 32-bit RGBA visual, demand a 32-bit fbconfig. */
325 if (visual->nplanes == 32 && config->rgbBits != 32)
327 /* Can't use the same FBconfig for multiple X visuals. I think. */
328 if (config->visualID != 0)
331 if (config->doubleBufferMode > 0)
333 if (config->depthBits > 0)
335 if (config->stencilBits > 0)
337 if (config->alphaBits > 0)
340 if (score > best_score) {
349 void __glXScreenInit(__GLXscreen *pGlxScreen, ScreenPtr pScreen)
355 if (!dixRegisterPrivateKey(&glxScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
358 pGlxScreen->pScreen = pScreen;
359 pGlxScreen->GLextensions = strdup(GLServerExtensions);
360 pGlxScreen->GLXvendor = strdup(GLXServerVendorName);
361 pGlxScreen->GLXextensions = strdup(GLXServerExtensions);
363 /* All GLX providers must support all of the functionality required for at
364 * least GLX 1.2. If the provider supports a higher version, the GLXminor
365 * version can be changed in the provider's screen-probe routine. For
366 * most providers, the screen-probe routine is the caller of this
369 pGlxScreen->GLXmajor = 1;
370 pGlxScreen->GLXminor = 2;
372 pGlxScreen->CloseScreen = pScreen->CloseScreen;
373 pScreen->CloseScreen = glxCloseScreen;
376 for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next) {
377 m->fbconfigID = FakeClientID(0);
381 pGlxScreen->numFBConfigs = i;
383 pGlxScreen->visuals =
384 calloc(pGlxScreen->numFBConfigs, sizeof (__GLXconfig *));
386 /* First, try to choose featureful FBconfigs for the existing X visuals.
387 * Note that if multiple X visuals end up with the same FBconfig being
388 * chosen, the later X visuals don't get GLX visuals (because we want to
389 * prioritize the root visual being GLX).
391 for (i = 0; i < pScreen->numVisuals; i++) {
392 VisualPtr visual = &pScreen->visuals[i];
394 config = pickFBConfig(pGlxScreen, visual);
396 pGlxScreen->visuals[pGlxScreen->numVisuals++] = config;
397 config->visualID = visual->vid;
401 /* Then, add new visuals corresponding to all FBconfigs that didn't have
402 * an existing, appropriate visual.
404 for (config = pGlxScreen->fbconfigs; config != NULL; config = config->next) {
409 if (config->visualID != 0)
412 /* Only count RGB bits and not alpha, as we're not trying to create
413 * visuals for compositing (that's what the 32-bit composite visual
414 * set up above is for.
416 depth = config->redBits + config->greenBits + config->blueBits;
418 /* Make sure that our FBconfig's depth can actually be displayed
419 * (corresponds to an existing visual).
421 for (i = 0; i < pScreen->numVisuals; i++) {
422 if (depth == pScreen->visuals[i].nplanes)
425 if (i == pScreen->numVisuals)
428 /* Create a new X visual for our FBconfig. */
429 visual = AddScreenVisuals(pScreen, 1, depth);
433 pGlxScreen->visuals[pGlxScreen->numVisuals++] = config;
434 initGlxVisual(visual, config);
437 dixSetPrivate(&pScreen->devPrivates, glxScreenPrivateKey, pGlxScreen);
440 void __glXScreenDestroy(__GLXscreen *screen)
442 free(screen->GLXvendor);
443 free(screen->GLXextensions);
444 free(screen->GLextensions);