Open/Close FullScreen die. unichrome and savage implemented, code is ifdef'd out
[mesa.git] / src / mesa / drivers / dri / gamma / gamma_xmesa.c
1 /* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_xmesa.c,v 1.14 2002/10/30 12:51:30 alanh Exp $ */
2 /*
3 * Copyright 2001 by Alan Hourihane.
4 *
5 * Permission to use, copy, modify, distribute, and sell this software and its
6 * documentation for any purpose is hereby granted without fee, provided that
7 * the above copyright notice appear in all copies and that both that
8 * copyright notice and this permission notice appear in supporting
9 * documentation, and that the name of Alan Hourihane not be used in
10 * advertising or publicity pertaining to distribution of the software without
11 * specific, written prior permission. Alan Hourihane makes no representations
12 * about the suitability of this software for any purpose. It is provided
13 * "as is" without express or implied warranty.
14 *
15 * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17 * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21 * PERFORMANCE OF THIS SOFTWARE.
22 *
23 * Authors: Alan Hourihane, <alanh@tungstengraphics.com>
24 *
25 * 3DLabs Gamma driver
26 */
27
28 #include "gamma_context.h"
29 #include "gamma_vb.h"
30 #include "context.h"
31 #include "matrix.h"
32 #include "glint_dri.h"
33
34 #include "swrast/swrast.h"
35 #include "swrast_setup/swrast_setup.h"
36 #include "tnl/tnl.h"
37 #include "array_cache/acache.h"
38
39 static GLboolean
40 gammaInitDriver(__DRIscreenPrivate *sPriv)
41 {
42 sPriv->private = (void *) gammaCreateScreen( sPriv );
43
44 if (!sPriv->private) {
45 gammaDestroyScreen( sPriv );
46 return GL_FALSE;
47 }
48
49 return GL_TRUE;
50 }
51
52 static void
53 gammaDestroyContext(__DRIcontextPrivate *driContextPriv)
54 {
55 gammaContextPtr gmesa = (gammaContextPtr)driContextPriv->driverPrivate;
56
57 if (gmesa) {
58 _swsetup_DestroyContext( gmesa->glCtx );
59 _tnl_DestroyContext( gmesa->glCtx );
60 _ac_DestroyContext( gmesa->glCtx );
61 _swrast_DestroyContext( gmesa->glCtx );
62
63 gammaFreeVB( gmesa->glCtx );
64
65 /* free the Mesa context */
66 gmesa->glCtx->DriverCtx = NULL;
67 _mesa_destroy_context(gmesa->glCtx);
68
69 FREE(gmesa);
70 driContextPriv->driverPrivate = NULL;
71 }
72 }
73
74
75 static GLboolean
76 gammaCreateBuffer( __DRIscreenPrivate *driScrnPriv,
77 __DRIdrawablePrivate *driDrawPriv,
78 const __GLcontextModes *mesaVis,
79 GLboolean isPixmap )
80 {
81 if (isPixmap) {
82 return GL_FALSE; /* not implemented */
83 }
84 else {
85 driDrawPriv->driverPrivate = (void *)
86 _mesa_create_framebuffer(mesaVis,
87 GL_FALSE, /* software depth buffer? */
88 mesaVis->stencilBits > 0,
89 mesaVis->accumRedBits > 0,
90 mesaVis->alphaBits > 0
91 );
92 return (driDrawPriv->driverPrivate != NULL);
93 }
94 }
95
96
97 static void
98 gammaDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
99 {
100 _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
101 }
102
103 static void
104 gammaSwapBuffers( __DRIdrawablePrivate *dPriv )
105 {
106 if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
107 gammaContextPtr gmesa;
108 __DRIscreenPrivate *driScrnPriv;
109 GLcontext *ctx;
110
111 gmesa = (gammaContextPtr) dPriv->driContextPriv->driverPrivate;
112 ctx = gmesa->glCtx;
113 driScrnPriv = gmesa->driScreen;
114
115 _mesa_notifySwapBuffers(ctx);
116
117 VALIDATE_DRAWABLE_INFO(gmesa);
118
119 /* Flush any partially filled buffers */
120 FLUSH_DMA_BUFFER(gmesa);
121
122 DRM_SPINLOCK(&driScrnPriv->pSAREA->drawable_lock,
123 driScrnPriv->drawLockID);
124 VALIDATE_DRAWABLE_INFO_NO_LOCK(gmesa);
125
126 if (gmesa->EnabledFlags & GAMMA_BACK_BUFFER) {
127 int src, dst, x0, y0, x1, h;
128 int i;
129 int nRect = dPriv->numClipRects;
130 drm_clip_rect_t *pRect = dPriv->pClipRects;
131 __DRIscreenPrivate *driScrnPriv = gmesa->driScreen;
132 GLINTDRIPtr gDRIPriv = (GLINTDRIPtr)driScrnPriv->pDevPriv;
133
134 CHECK_DMA_BUFFER(gmesa, 2);
135 WRITE(gmesa->buf, FBReadMode, (gmesa->FBReadMode |
136 FBReadSrcEnable));
137 WRITE(gmesa->buf, LBWriteMode, LBWriteModeDisable);
138
139 for (i = 0; i < nRect; i++, pRect++) {
140 x0 = pRect->x1;
141 x1 = pRect->x2;
142 h = pRect->y2 - pRect->y1;
143
144 y0 = driScrnPriv->fbHeight - (pRect->y1+h);
145 if (gDRIPriv->numMultiDevices == 2)
146 src = (y0/2)*driScrnPriv->fbWidth+x0;
147 else
148 src = y0*driScrnPriv->fbWidth+x0;
149
150 y0 += driScrnPriv->fbHeight;
151 if (gDRIPriv->numMultiDevices == 2)
152 dst = (y0/2)*driScrnPriv->fbWidth+x0;
153 else
154 dst = y0*driScrnPriv->fbWidth+x0;
155
156 CHECK_DMA_BUFFER(gmesa, 9);
157 WRITE(gmesa->buf, StartXDom, x0<<16); /* X0dest */
158 WRITE(gmesa->buf, StartY, y0<<16); /* Y0dest */
159 WRITE(gmesa->buf, StartXSub, x1<<16); /* X1dest */
160 WRITE(gmesa->buf, GLINTCount, h); /* H */
161 WRITE(gmesa->buf, dY, 1<<16); /* ydir */
162 WRITE(gmesa->buf, dXDom, 0<<16);
163 WRITE(gmesa->buf, dXSub, 0<<16);
164 WRITE(gmesa->buf, FBSourceOffset, (dst-src));
165 WRITE(gmesa->buf, Render, 0x00040048); /* NOT_DONE */
166 }
167
168 /*
169 ** NOTE: FBSourceOffset (above) is backwards from what is
170 ** described in the manual (i.e., dst-src instead of src-dst)
171 ** due to our using the bottom-left window origin instead of the
172 ** top-left window origin.
173 */
174
175 /* Restore FBReadMode */
176 CHECK_DMA_BUFFER(gmesa, 2);
177 WRITE(gmesa->buf, FBReadMode, (gmesa->FBReadMode |
178 gmesa->AB_FBReadMode));
179 WRITE(gmesa->buf, LBWriteMode, LBWriteModeEnable);
180 }
181
182 if (gmesa->EnabledFlags & GAMMA_BACK_BUFFER)
183 PROCESS_DMA_BUFFER_TOP_HALF(gmesa);
184
185 DRM_SPINUNLOCK(&driScrnPriv->pSAREA->drawable_lock,
186 driScrnPriv->drawLockID);
187 VALIDATE_DRAWABLE_INFO_NO_LOCK_POST(gmesa);
188
189 if (gmesa->EnabledFlags & GAMMA_BACK_BUFFER)
190 PROCESS_DMA_BUFFER_BOTTOM_HALF(gmesa);
191 } else {
192 _mesa_problem(NULL, "gammaSwapBuffers: drawable has no context!\n");
193 }
194 }
195
196 static GLboolean
197 gammaMakeCurrent(__DRIcontextPrivate *driContextPriv,
198 __DRIdrawablePrivate *driDrawPriv,
199 __DRIdrawablePrivate *driReadPriv)
200 {
201 if (driContextPriv) {
202 GET_CURRENT_CONTEXT(ctx);
203 gammaContextPtr oldGammaCtx = ctx ? GAMMA_CONTEXT(ctx) : NULL;
204 gammaContextPtr newGammaCtx = (gammaContextPtr) driContextPriv->driverPrivate;
205
206 if ( newGammaCtx != oldGammaCtx ) {
207 newGammaCtx->dirty = ~0;
208 }
209
210 if (newGammaCtx->driDrawable != driDrawPriv) {
211 newGammaCtx->driDrawable = driDrawPriv;
212 gammaUpdateWindow ( newGammaCtx->glCtx );
213 gammaUpdateViewportOffset( newGammaCtx->glCtx );
214 }
215
216 #if 0
217 newGammaCtx->Window &= ~W_GIDMask;
218 newGammaCtx->Window |= (driDrawPriv->index << 5);
219 CHECK_DMA_BUFFER(newGammaCtx,1);
220 WRITE(newGammaCtx->buf, GLINTWindow, newGammaCtx->Window);
221 #endif
222
223 newGammaCtx->new_state |= GAMMA_NEW_WINDOW; /* FIXME */
224
225 _mesa_make_current2( newGammaCtx->glCtx,
226 (GLframebuffer *) driDrawPriv->driverPrivate,
227 (GLframebuffer *) driReadPriv->driverPrivate );
228
229 if (!newGammaCtx->glCtx->Viewport.Width) {
230 _mesa_set_viewport(newGammaCtx->glCtx, 0, 0,
231 driDrawPriv->w, driDrawPriv->h);
232 }
233 } else {
234 _mesa_make_current( 0, 0 );
235 }
236 return GL_TRUE;
237 }
238
239
240 static GLboolean
241 gammaUnbindContext( __DRIcontextPrivate *driContextPriv )
242 {
243 return GL_TRUE;
244 }
245
246 static struct __DriverAPIRec gammaAPI = {
247 gammaInitDriver,
248 gammaDestroyScreen,
249 gammaCreateContext,
250 gammaDestroyContext,
251 gammaCreateBuffer,
252 gammaDestroyBuffer,
253 gammaSwapBuffers,
254 gammaMakeCurrent,
255 gammaUnbindContext
256 };
257
258
259
260 /*
261 * This is the bootstrap function for the driver.
262 * The __driCreateScreen name is the symbol that libGL.so fetches.
263 * Return: pointer to a __DRIscreenPrivate.
264 */
265 #ifndef _SOLO
266 void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
267 int numConfigs, __GLXvisualConfig *config)
268 {
269 __DRIscreenPrivate *psp;
270 psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &gammaAPI);
271 return (void *) psp;
272 }
273 #else
274 void *__driCreateScreen(struct DRIDriverRec *driver,
275 struct DRIDriverContextRec *driverContext)
276 {
277 __DRIscreenPrivate *psp;
278 psp = __driUtilCreateScreen(driver, driverContext, &gammaAPI);
279 return (void *) psp;
280 }
281 #endif