1 /* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_xmesa.c,v 1.14 2002/10/30 12:51:30 alanh Exp $ */
3 * Copyright 2001 by Alan Hourihane.
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.
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.
23 * Authors: Alan Hourihane, <alanh@tungstengraphics.com>
28 #include "gamma_context.h"
32 #include "glint_dri.h"
34 #include "swrast/swrast.h"
35 #include "swrast_setup/swrast_setup.h"
37 #include "array_cache/acache.h"
40 gammaInitDriver(__DRIscreenPrivate
*sPriv
)
42 sPriv
->private = (void *) gammaCreateScreen( sPriv
);
44 if (!sPriv
->private) {
45 gammaDestroyScreen( sPriv
);
53 gammaDestroyContext(__DRIcontextPrivate
*driContextPriv
)
55 gammaContextPtr gmesa
= (gammaContextPtr
)driContextPriv
->driverPrivate
;
58 _swsetup_DestroyContext( gmesa
->glCtx
);
59 _tnl_DestroyContext( gmesa
->glCtx
);
60 _ac_DestroyContext( gmesa
->glCtx
);
61 _swrast_DestroyContext( gmesa
->glCtx
);
63 gammaFreeVB( gmesa
->glCtx
);
65 /* free the Mesa context */
66 gmesa
->glCtx
->DriverCtx
= NULL
;
67 _mesa_destroy_context(gmesa
->glCtx
);
70 driContextPriv
->driverPrivate
= NULL
;
76 gammaCreateBuffer( __DRIscreenPrivate
*driScrnPriv
,
77 __DRIdrawablePrivate
*driDrawPriv
,
78 const __GLcontextModes
*mesaVis
,
82 return GL_FALSE
; /* not implemented */
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
92 return (driDrawPriv
->driverPrivate
!= NULL
);
98 gammaDestroyBuffer(__DRIdrawablePrivate
*driDrawPriv
)
100 _mesa_destroy_framebuffer((GLframebuffer
*) (driDrawPriv
->driverPrivate
));
104 gammaSwapBuffers( __DRIdrawablePrivate
*dPriv
)
106 if (dPriv
->driContextPriv
&& dPriv
->driContextPriv
->driverPrivate
) {
107 gammaContextPtr gmesa
;
108 __DRIscreenPrivate
*driScrnPriv
;
111 gmesa
= (gammaContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
113 driScrnPriv
= gmesa
->driScreen
;
115 _mesa_notifySwapBuffers(ctx
);
117 VALIDATE_DRAWABLE_INFO(gmesa
);
119 /* Flush any partially filled buffers */
120 FLUSH_DMA_BUFFER(gmesa
);
122 DRM_SPINLOCK(&driScrnPriv
->pSAREA
->drawable_lock
,
123 driScrnPriv
->drawLockID
);
124 VALIDATE_DRAWABLE_INFO_NO_LOCK(gmesa
);
126 if (gmesa
->EnabledFlags
& GAMMA_BACK_BUFFER
) {
127 int src
, dst
, x0
, y0
, x1
, h
;
129 int nRect
= dPriv
->numClipRects
;
130 drm_clip_rect_t
*pRect
= dPriv
->pClipRects
;
131 __DRIscreenPrivate
*driScrnPriv
= gmesa
->driScreen
;
132 GLINTDRIPtr gDRIPriv
= (GLINTDRIPtr
)driScrnPriv
->pDevPriv
;
134 CHECK_DMA_BUFFER(gmesa
, 2);
135 WRITE(gmesa
->buf
, FBReadMode
, (gmesa
->FBReadMode
|
137 WRITE(gmesa
->buf
, LBWriteMode
, LBWriteModeDisable
);
139 for (i
= 0; i
< nRect
; i
++, pRect
++) {
142 h
= pRect
->y2
- pRect
->y1
;
144 y0
= driScrnPriv
->fbHeight
- (pRect
->y1
+h
);
145 if (gDRIPriv
->numMultiDevices
== 2)
146 src
= (y0
/2)*driScrnPriv
->fbWidth
+x0
;
148 src
= y0
*driScrnPriv
->fbWidth
+x0
;
150 y0
+= driScrnPriv
->fbHeight
;
151 if (gDRIPriv
->numMultiDevices
== 2)
152 dst
= (y0
/2)*driScrnPriv
->fbWidth
+x0
;
154 dst
= y0
*driScrnPriv
->fbWidth
+x0
;
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 */
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.
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
);
182 if (gmesa
->EnabledFlags
& GAMMA_BACK_BUFFER
)
183 PROCESS_DMA_BUFFER_TOP_HALF(gmesa
);
185 DRM_SPINUNLOCK(&driScrnPriv
->pSAREA
->drawable_lock
,
186 driScrnPriv
->drawLockID
);
187 VALIDATE_DRAWABLE_INFO_NO_LOCK_POST(gmesa
);
189 if (gmesa
->EnabledFlags
& GAMMA_BACK_BUFFER
)
190 PROCESS_DMA_BUFFER_BOTTOM_HALF(gmesa
);
192 _mesa_problem(NULL
, "gammaSwapBuffers: drawable has no context!\n");
197 gammaMakeCurrent(__DRIcontextPrivate
*driContextPriv
,
198 __DRIdrawablePrivate
*driDrawPriv
,
199 __DRIdrawablePrivate
*driReadPriv
)
201 if (driContextPriv
) {
202 GET_CURRENT_CONTEXT(ctx
);
203 gammaContextPtr oldGammaCtx
= ctx
? GAMMA_CONTEXT(ctx
) : NULL
;
204 gammaContextPtr newGammaCtx
= (gammaContextPtr
) driContextPriv
->driverPrivate
;
206 if ( newGammaCtx
!= oldGammaCtx
) {
207 newGammaCtx
->dirty
= ~0;
210 if (newGammaCtx
->driDrawable
!= driDrawPriv
) {
211 newGammaCtx
->driDrawable
= driDrawPriv
;
212 gammaUpdateWindow ( newGammaCtx
->glCtx
);
213 gammaUpdateViewportOffset( newGammaCtx
->glCtx
);
217 newGammaCtx
->Window
&= ~W_GIDMask
;
218 newGammaCtx
->Window
|= (driDrawPriv
->index
<< 5);
219 CHECK_DMA_BUFFER(newGammaCtx
,1);
220 WRITE(newGammaCtx
->buf
, GLINTWindow
, newGammaCtx
->Window
);
223 newGammaCtx
->new_state
|= GAMMA_NEW_WINDOW
; /* FIXME */
225 _mesa_make_current2( newGammaCtx
->glCtx
,
226 (GLframebuffer
*) driDrawPriv
->driverPrivate
,
227 (GLframebuffer
*) driReadPriv
->driverPrivate
);
229 _mesa_make_current( 0, 0 );
236 gammaUnbindContext( __DRIcontextPrivate
*driContextPriv
)
241 static struct __DriverAPIRec gammaAPI
= {
256 * This is the bootstrap function for the driver.
257 * The __driCreateScreen name is the symbol that libGL.so fetches.
258 * Return: pointer to a __DRIscreenPrivate.
260 void *__driCreateScreen(Display
*dpy
, int scrn
, __DRIscreen
*psc
,
261 int numConfigs
, __GLXvisualConfig
*config
)
263 __DRIscreenPrivate
*psp
;
264 psp
= __driUtilCreateScreen(dpy
, scrn
, psc
, numConfigs
, config
, &gammaAPI
);