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