2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
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:
14 * The above copyright notice and this permission notice shall be included
15 * 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 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 #include "glxheader.h"
30 #include "../glide/fxdrv.h"
33 FXcreateContext(XMesaVisual v
, XMesaWindow w
, XMesaContext c
, XMesaBuffer b
)
35 char *fxEnvVar
= _mesa_getenv("MESA_GLX_FX");
37 if (fxEnvVar
[0]!='d') {
41 if (v
->mesa_visual
.depthBits
> 0) {
42 attribs
[numAttribs
++] = FXMESA_DEPTH_SIZE
;
43 attribs
[numAttribs
++] = v
->mesa_visual
.depthBits
;
45 if (v
->mesa_visual
.doubleBufferMode
) {
46 attribs
[numAttribs
++] = FXMESA_DOUBLEBUFFER
;
48 if (v
->mesa_visual
.accumRedBits
> 0) {
49 attribs
[numAttribs
++] = FXMESA_ACCUM_SIZE
;
50 attribs
[numAttribs
++] = v
->mesa_visual
.accumRedBits
;
52 if (v
->mesa_visual
.stencilBits
> 0) {
53 attribs
[numAttribs
++] = FXMESA_STENCIL_SIZE
;
54 attribs
[numAttribs
++] = v
->mesa_visual
.stencilBits
;
56 if (v
->mesa_visual
.alphaBits
> 0) {
57 attribs
[numAttribs
++] = FXMESA_ALPHA_SIZE
;
58 attribs
[numAttribs
++] = v
->mesa_visual
.alphaBits
;
61 attribs
[numAttribs
++] = FXMESA_SHARE_CONTEXT
;
62 attribs
[numAttribs
++] = (int) &(c
->mesa
);
64 attribs
[numAttribs
++] = FXMESA_NONE
;
66 /* [dBorca] we should take an envvar for `fxMesaSelectCurrentBoard'!!! */
67 /* hw = fxMesaSelectCurrentBoard(0); */
68 hw
= GR_SSTTYPE_Voodoo2
;
70 /* if these fail, there's a new bug somewhere */
71 ASSERT(b
->mesa_buffer
.Width
> 0);
72 ASSERT(b
->mesa_buffer
.Height
> 0);
74 if ((hw
== GR_SSTTYPE_VOODOO
) || (hw
== GR_SSTTYPE_Voodoo2
)) {
75 b
->FXctx
= fxMesaCreateBestContext(0, b
->mesa_buffer
.Width
,
76 b
->mesa_buffer
.Height
, attribs
);
77 if ((v
->undithered_pf
!=PF_Index
) && (b
->backxrb
->ximage
)) {
78 b
->FXisHackUsable
= b
->FXctx
? GL_TRUE
: GL_FALSE
;
79 if (b
->FXctx
&& (fxEnvVar
[0]=='w' || fxEnvVar
[0]=='W')) {
80 b
->FXwindowHack
= GL_TRUE
;
81 FX_grSstControl(GR_CONTROL_DEACTIVATE
);
84 b
->FXwindowHack
= GL_FALSE
;
89 if (fxEnvVar
[0]=='w' || fxEnvVar
[0]=='W')
90 b
->FXctx
= fxMesaCreateContext(w
, GR_RESOLUTION_NONE
,
91 GR_REFRESH_75Hz
, attribs
);
93 b
->FXctx
= fxMesaCreateBestContext(0, b
->mesa_buffer
.Width
,
94 b
->mesa_buffer
.Height
, attribs
);
95 b
->FXisHackUsable
= GL_FALSE
;
96 b
->FXwindowHack
= GL_FALSE
;
100 "voodoo %d, wid %d height %d hack: usable %d active %d\n",
101 hw, b->mesa_buffer.Width, b->mesa_buffer.Height,
102 b->FXisHackUsable, b->FXwindowHack);
107 _mesa_warning(NULL
, "WARNING: This Mesa Library includes the Glide driver but\n");
108 _mesa_warning(NULL
, " you have not defined the MESA_GLX_FX env. var.\n");
109 _mesa_warning(NULL
, " (check the README.3DFX file for more information).\n\n");
110 _mesa_warning(NULL
, " you can disable this message with a 'export MESA_GLX_FX=disable'.\n");
115 void FXdestroyContext( XMesaBuffer b
)
118 fxMesaDestroyContext(b
->FXctx
);
122 GLboolean
FXmakeCurrent( XMesaBuffer b
)
125 fxMesaMakeCurrent(b
->FXctx
);
134 * Read image from VooDoo frame buffer into X/Mesa's back XImage.
136 static void FXgetImage( XMesaBuffer b
)
138 GET_CURRENT_CONTEXT(ctx
);
139 static unsigned short pixbuf
[MAX_WIDTH
];
141 GLuint width
, height
;
144 x
= b
->frontxrb
->pixmap
->x
;
145 y
= b
->frontxrb
->pixmap
->y
;
146 width
= b
->frontxrb
->pixmap
->width
;
147 height
= b
->frontxrb
->pixmap
->height
;
148 depth
= b
->frontxrb
->pixmap
->depth
;
150 xmesa_get_window_size(b
->display
, b
, &width
, &height
);
153 if (b
->mesa_buffer
.Width
!= width
|| b
->mesa_buffer
.Height
!= height
) {
154 b
->mesa_buffer
.Width
= MIN2((int)width
, b
->FXctx
->width
);
155 b
->mesa_buffer
.Height
= MIN2((int)height
, b
->FXctx
->height
);
156 if (b
->mesa_buffer
.Width
& 1)
157 b
->mesa_buffer
.Width
--; /* prevent odd width */
160 /* [dBorca] we're always in the right GR_COLORFORMAT... aren't we? */
161 /* grLfbWriteColorFormat(GR_COLORFORMAT_ARGB); */
162 if (b
->xm_visual
->undithered_pf
==PF_5R6G5B
) {
163 /* Special case: 16bpp RGB */
164 grLfbReadRegion( GR_BUFFER_FRONTBUFFER
, /* src buffer */
165 0, b
->FXctx
->height
- b
->mesa_buffer
.Height
, /*pos*/
166 b
->mesa_buffer
.Width
, b
->mesa_buffer
.Height
, /* size */
167 b
->mesa_buffer
.Width
* sizeof(GLushort
), /* stride */
168 b
->backxrb
->ximage
->data
); /* dest buffer */
170 else if (b
->xm_visual
->dithered_pf
==PF_Dither
171 && GET_VISUAL_DEPTH(b
->xm_visual
)==8) {
172 /* Special case: 8bpp RGB */
173 for (y
=0;y
<b
->mesa_buffer
.Height
;y
++) {
174 GLubyte
*ptr
= (GLubyte
*) b
->backxrb
->ximage
->data
175 + b
->backxrb
->ximage
->bytes_per_line
* y
;
178 /* read row from 3Dfx frame buffer */
179 grLfbReadRegion( GR_BUFFER_FRONTBUFFER
,
180 0, b
->FXctx
->height
-(b
->mesa_buffer
.Height
-y
),
181 b
->mesa_buffer
.Width
, 1,
185 /* write to XImage back buffer */
186 for (x
=0;x
<b
->mesa_buffer
.Width
;x
++) {
187 GLubyte r
= (pixbuf
[x
] & 0xf800) >> 8;
188 GLubyte g
= (pixbuf
[x
] & 0x07e0) >> 3;
189 GLubyte b
= (pixbuf
[x
] & 0x001f) << 3;
190 *ptr
++ = XDITHER( x
, r
, g
, b
);
195 /* General case: slow! */
196 for (y
=0;y
<b
->mesa_buffer
.Height
;y
++) {
197 /* read row from 3Dfx frame buffer */
198 grLfbReadRegion( GR_BUFFER_FRONTBUFFER
,
199 0, b
->FXctx
->height
-(b
->mesa_buffer
.Height
-y
),
200 b
->mesa_buffer
.Width
, 1,
204 /* write to XImage back buffer */
205 for (x
=0;x
<b
->mesa_buffer
.Width
;x
++) {
206 XMesaPutPixel(b
->backxrb
->ximage
,x
,y
,
207 xmesa_color_to_pixel(ctx
,
208 (pixbuf
[x
] & 0xf800) >> 8,
209 (pixbuf
[x
] & 0x07e0) >> 3,
210 (pixbuf
[x
] & 0x001f) << 3,
212 b
->xm_visual
->undithered_pf
));
216 /* grLfbWriteColorFormat(GR_COLORFORMAT_ABGR); */
220 GLboolean
FXswapBuffers( XMesaBuffer b
)
225 if (!b
->FXwindowHack
)
235 * Switch 3Dfx support hack between window and full-screen mode.
237 GLboolean
XMesaSetFXmode( GLint mode
)
239 const char *fx
= _mesa_getenv("MESA_GLX_FX");
240 if (fx
&& fx
[0] != 'd') {
241 GET_CURRENT_CONTEXT(ctx
);
242 GrHwConfiguration hw
;
243 if (!FX_grSstQueryHardware(&hw
)) {
244 /*fprintf(stderr, "!grSstQueryHardware\n");*/
247 if (hw
.num_sst
< 1) {
248 /*fprintf(stderr, "hw.num_sst < 1\n");*/
252 /* [dBorca] Hack alert:
253 * oh, this is sooo wrong: ctx above is
254 * really an fxMesaContext, not an XMesaContext
256 XMesaBuffer xmbuf
= XMESA_BUFFER(ctx
->DrawBuffer
);
257 if (mode
== XMESA_FX_WINDOW
) {
258 if (xmbuf
->FXisHackUsable
) {
259 FX_grSstControl(GR_CONTROL_DEACTIVATE
);
260 xmbuf
->FXwindowHack
= GL_TRUE
;
264 else if (mode
== XMESA_FX_FULLSCREEN
) {
265 FX_grSstControl(GR_CONTROL_ACTIVATE
);
266 xmbuf
->FXwindowHack
= GL_FALSE
;
270 /* Error: Bad mode value */
274 /*fprintf(stderr, "fallthrough\n");*/