Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / drivers / x11 / xm_glide.c
1 /*
2  * Mesa 3-D graphics library
3  * Version:  6.5
4  *
5  * Copyright (C) 1999-2006  Brian Paul   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  * 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.
23  */
24
25
26 #include "glxheader.h"
27 #include "xmesaP.h"
28
29 #ifdef FX
30 #include "../glide/fxdrv.h"
31
32 void
33 FXcreateContext(XMesaVisual v, XMesaWindow w, XMesaContext c, XMesaBuffer b)
34 {
35    char *fxEnvVar = _mesa_getenv("MESA_GLX_FX");
36    if (fxEnvVar) {
37      if (fxEnvVar[0]!='d') {
38        int attribs[100];
39        int numAttribs = 0;
40        int hw;
41        if (v->mesa_visual.depthBits > 0) {
42          attribs[numAttribs++] = FXMESA_DEPTH_SIZE;
43          attribs[numAttribs++] = v->mesa_visual.depthBits;
44        }
45        if (v->mesa_visual.doubleBufferMode) {
46          attribs[numAttribs++] = FXMESA_DOUBLEBUFFER;
47        }
48        if (v->mesa_visual.accumRedBits > 0) {
49          attribs[numAttribs++] = FXMESA_ACCUM_SIZE;
50          attribs[numAttribs++] = v->mesa_visual.accumRedBits;
51        }
52        if (v->mesa_visual.stencilBits > 0) {
53          attribs[numAttribs++] = FXMESA_STENCIL_SIZE;
54          attribs[numAttribs++] = v->mesa_visual.stencilBits;
55        }
56        if (v->mesa_visual.alphaBits > 0) {
57          attribs[numAttribs++] = FXMESA_ALPHA_SIZE;
58          attribs[numAttribs++] = v->mesa_visual.alphaBits;
59        }
60        if (1) {
61          attribs[numAttribs++] = FXMESA_SHARE_CONTEXT;
62          attribs[numAttribs++] = (int) &(c->mesa);
63        }
64        attribs[numAttribs++] = FXMESA_NONE;
65
66        /* [dBorca] we should take an envvar for `fxMesaSelectCurrentBoard'!!! */
67 /*       hw = fxMesaSelectCurrentBoard(0); */
68        hw = GR_SSTTYPE_Voodoo2;
69
70        /* if these fail, there's a new bug somewhere */
71        ASSERT(b->mesa_buffer.Width > 0);
72        ASSERT(b->mesa_buffer.Height > 0);
73
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);
82            }
83            else {
84              b->FXwindowHack = GL_FALSE;
85            }
86          }
87        }
88        else {
89          if (fxEnvVar[0]=='w' || fxEnvVar[0]=='W')
90            b->FXctx = fxMesaCreateContext(w, GR_RESOLUTION_NONE,
91                                           GR_REFRESH_75Hz, attribs);
92          else
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;
97        }
98        /*
99        fprintf(stderr,
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);
103        */
104      }
105    }
106    else {
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");
111    }
112 }
113
114
115 void FXdestroyContext( XMesaBuffer b )
116 {
117    if (b && b->FXctx)
118       fxMesaDestroyContext(b->FXctx);
119 }
120
121
122 GLboolean FXmakeCurrent( XMesaBuffer b )
123 {
124    if (b->FXctx) {
125       fxMesaMakeCurrent(b->FXctx);
126
127       return GL_TRUE;
128    }
129    return GL_FALSE;
130 }
131
132
133 /*
134  * Read image from VooDoo frame buffer into X/Mesa's back XImage.
135  */
136 static void FXgetImage( XMesaBuffer b )
137 {
138    GET_CURRENT_CONTEXT(ctx);
139    static unsigned short pixbuf[MAX_WIDTH];
140    GLuint x, y;
141    GLuint width, height;
142
143    xmesa_get_window_size(b->display, b, &width, &height);
144    x = y = 0;
145    if (b->mesa_buffer.Width != width || b->mesa_buffer.Height != height) {
146       b->mesa_buffer.Width = MIN2((int)width, b->FXctx->width);
147       b->mesa_buffer.Height = MIN2((int)height, b->FXctx->height);
148       if (b->mesa_buffer.Width & 1)
149          b->mesa_buffer.Width--;  /* prevent odd width */
150    }
151
152    /* [dBorca] we're always in the right GR_COLORFORMAT... aren't we? */
153    /* grLfbWriteColorFormat(GR_COLORFORMAT_ARGB); */
154    if (b->xm_visual->undithered_pf==PF_5R6G5B) {
155       /* Special case: 16bpp RGB */
156       grLfbReadRegion( GR_BUFFER_FRONTBUFFER,       /* src buffer */
157                        0, b->FXctx->height - b->mesa_buffer.Height,  /*pos*/
158                        b->mesa_buffer.Width, b->mesa_buffer.Height,  /* size */
159                        b->mesa_buffer.Width * sizeof(GLushort), /* stride */
160                        b->backxrb->ximage->data);         /* dest buffer */
161    }
162    else if (b->xm_visual->dithered_pf==PF_Dither
163             && GET_VISUAL_DEPTH(b->xm_visual)==8) {
164       /* Special case: 8bpp RGB */
165       for (y=0;y<b->mesa_buffer.Height;y++) {
166          GLubyte *ptr = (GLubyte*) b->backxrb->ximage->data
167                         + b->backxrb->ximage->bytes_per_line * y;
168          XDITHER_SETUP(y);
169
170          /* read row from 3Dfx frame buffer */
171          grLfbReadRegion( GR_BUFFER_FRONTBUFFER,
172                           0, b->FXctx->height-(b->mesa_buffer.Height-y),
173                           b->mesa_buffer.Width, 1,
174                           0,
175                           pixbuf );
176
177          /* write to XImage back buffer */
178          for (x=0;x<b->mesa_buffer.Width;x++) {
179             GLubyte r = (pixbuf[x] & 0xf800) >> 8;
180             GLubyte g = (pixbuf[x] & 0x07e0) >> 3;
181             GLubyte b = (pixbuf[x] & 0x001f) << 3;
182             *ptr++ = XDITHER( x, r, g, b);
183          }
184       }
185    }
186    else {
187       /* General case: slow! */
188       for (y=0;y<b->mesa_buffer.Height;y++) {
189          /* read row from 3Dfx frame buffer */
190          grLfbReadRegion( GR_BUFFER_FRONTBUFFER,
191                           0, b->FXctx->height-(b->mesa_buffer.Height-y),
192                           b->mesa_buffer.Width, 1,
193                           0,
194                           pixbuf );
195
196          /* write to XImage back buffer */
197          for (x=0;x<b->mesa_buffer.Width;x++) {
198             XMesaPutPixel(b->backxrb->ximage,x,y,
199                           xmesa_color_to_pixel(ctx,
200                                                (pixbuf[x] & 0xf800) >> 8,
201                                                (pixbuf[x] & 0x07e0) >> 3,
202                                                (pixbuf[x] & 0x001f) << 3,
203                                                0xff,
204                                                b->xm_visual->undithered_pf));
205          }
206       }
207    }
208    /* grLfbWriteColorFormat(GR_COLORFORMAT_ABGR); */
209 }
210
211
212 GLboolean FXswapBuffers( XMesaBuffer b )
213 {
214    if (b->FXctx) {
215       fxMesaSwapBuffers();
216
217       if (!b->FXwindowHack)
218          return GL_TRUE;
219
220       FXgetImage(b);
221    }
222    return GL_FALSE;
223 }
224
225
226 /*
227  * Switch 3Dfx support hack between window and full-screen mode.
228  */
229 GLboolean XMesaSetFXmode( GLint mode )
230 {
231    const char *fx = _mesa_getenv("MESA_GLX_FX");
232    if (fx && fx[0] != 'd') {
233       GET_CURRENT_CONTEXT(ctx);
234       GrHwConfiguration hw;
235       if (!FX_grSstQueryHardware(&hw)) {
236          /*fprintf(stderr, "!grSstQueryHardware\n");*/
237          return GL_FALSE;
238       }
239       if (hw.num_sst < 1) {
240          /*fprintf(stderr, "hw.num_sst < 1\n");*/
241          return GL_FALSE;
242       }
243       if (ctx) {
244          /* [dBorca] Hack alert: 
245           * oh, this is sooo wrong: ctx above is
246           * really an fxMesaContext, not an XMesaContext
247           */
248          XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer);
249          if (mode == XMESA_FX_WINDOW) {
250             if (xmbuf->FXisHackUsable) {
251                FX_grSstControl(GR_CONTROL_DEACTIVATE);
252                xmbuf->FXwindowHack = GL_TRUE;
253                return GL_TRUE;
254             }
255          }
256          else if (mode == XMESA_FX_FULLSCREEN) {
257             FX_grSstControl(GR_CONTROL_ACTIVATE);
258             xmbuf->FXwindowHack = GL_FALSE;
259             return GL_TRUE;
260          }
261          else {
262             /* Error: Bad mode value */
263          }
264       }
265    }
266    /*fprintf(stderr, "fallthrough\n");*/
267    return GL_FALSE;
268 }
269 #endif