i915: Fix driver for the miptree x/y offset changes.
[mesa.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 #ifdef XFree86Server
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;
149 #else
150 xmesa_get_window_size(b->display, b, &width, &height);
151 x = y = 0;
152 #endif
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 */
158 }
159
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 */
169 }
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;
176 XDITHER_SETUP(y);
177
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,
182 0,
183 pixbuf );
184
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);
191 }
192 }
193 }
194 else {
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,
201 0,
202 pixbuf );
203
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,
211 0xff,
212 b->xm_visual->undithered_pf));
213 }
214 }
215 }
216 /* grLfbWriteColorFormat(GR_COLORFORMAT_ABGR); */
217 }
218
219
220 GLboolean FXswapBuffers( XMesaBuffer b )
221 {
222 if (b->FXctx) {
223 fxMesaSwapBuffers();
224
225 if (!b->FXwindowHack)
226 return GL_TRUE;
227
228 FXgetImage(b);
229 }
230 return GL_FALSE;
231 }
232
233
234 /*
235 * Switch 3Dfx support hack between window and full-screen mode.
236 */
237 GLboolean XMesaSetFXmode( GLint mode )
238 {
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");*/
245 return GL_FALSE;
246 }
247 if (hw.num_sst < 1) {
248 /*fprintf(stderr, "hw.num_sst < 1\n");*/
249 return GL_FALSE;
250 }
251 if (ctx) {
252 /* [dBorca] Hack alert:
253 * oh, this is sooo wrong: ctx above is
254 * really an fxMesaContext, not an XMesaContext
255 */
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;
261 return GL_TRUE;
262 }
263 }
264 else if (mode == XMESA_FX_FULLSCREEN) {
265 FX_grSstControl(GR_CONTROL_ACTIVATE);
266 xmbuf->FXwindowHack = GL_FALSE;
267 return GL_TRUE;
268 }
269 else {
270 /* Error: Bad mode value */
271 }
272 }
273 }
274 /*fprintf(stderr, "fallthrough\n");*/
275 return GL_FALSE;
276 }
277 #endif