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"
33
#include "glint_dri.h"
35
#include "swrast/swrast.h"
36
#include "swrast_setup/swrast_setup.h"
38
#include "array_cache/acache.h"
41
gammaInitDriver(__DRIscreenPrivate *sPriv)
43
sPriv->private = (void *) gammaCreateScreen( sPriv );
45
if (!sPriv->private) {
46
gammaDestroyScreen( sPriv );
54
gammaDestroyContext(__DRIcontextPrivate *driContextPriv)
56
gammaContextPtr gmesa = (gammaContextPtr)driContextPriv->driverPrivate;
59
_swsetup_DestroyContext( gmesa->glCtx );
60
_tnl_DestroyContext( gmesa->glCtx );
61
_ac_DestroyContext( gmesa->glCtx );
62
_swrast_DestroyContext( gmesa->glCtx );
64
gammaFreeVB( gmesa->glCtx );
66
/* free the Mesa context */
67
gmesa->glCtx->DriverCtx = NULL;
68
_mesa_destroy_context(gmesa->glCtx);
71
driContextPriv->driverPrivate = NULL;
77
gammaCreateBuffer( Display *dpy,
78
__DRIscreenPrivate *driScrnPriv,
79
__DRIdrawablePrivate *driDrawPriv,
80
const __GLcontextModes *mesaVis,
84
return GL_FALSE; /* not implemented */
87
driDrawPriv->driverPrivate = (void *)
88
_mesa_create_framebuffer(mesaVis,
89
GL_FALSE, /* software depth buffer? */
90
mesaVis->stencilBits > 0,
91
mesaVis->accumRedBits > 0,
92
mesaVis->alphaBits > 0
94
return (driDrawPriv->driverPrivate != NULL);
100
gammaDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
102
_mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
106
gammaSwapBuffers(Display *dpy, void *drawablePrivate)
108
__DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate;
111
if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
112
gammaContextPtr gmesa;
113
__DRIscreenPrivate *driScrnPriv;
116
gmesa = (gammaContextPtr) dPriv->driContextPriv->driverPrivate;
118
driScrnPriv = gmesa->driScreen;
120
VALIDATE_DRAWABLE_INFO(gmesa);
122
/* Flush any partially filled buffers */
123
FLUSH_DMA_BUFFER(gmesa);
125
DRM_SPINLOCK(&driScrnPriv->pSAREA->drawable_lock,
126
driScrnPriv->drawLockID);
127
VALIDATE_DRAWABLE_INFO_NO_LOCK(gmesa);
129
if (gmesa->EnabledFlags & GAMMA_BACK_BUFFER) {
130
int src, dst, x0, y0, x1, h;
132
int nRect = dPriv->numClipRects;
133
XF86DRIClipRectPtr pRect = dPriv->pClipRects;
134
__DRIscreenPrivate *driScrnPriv = gmesa->driScreen;
135
GLINTDRIPtr gDRIPriv = (GLINTDRIPtr)driScrnPriv->pDevPriv;
137
CHECK_DMA_BUFFER(gmesa, 2);
138
WRITE(gmesa->buf, FBReadMode, (gmesa->FBReadMode |
140
WRITE(gmesa->buf, LBWriteMode, LBWriteModeDisable);
142
for (i = 0; i < nRect; i++, pRect++) {
145
h = pRect->y2 - pRect->y1;
147
y0 = driScrnPriv->fbHeight - (pRect->y1+h);
148
if (gDRIPriv->numMultiDevices == 2)
149
src = (y0/2)*driScrnPriv->fbWidth+x0;
151
src = y0*driScrnPriv->fbWidth+x0;
153
y0 += driScrnPriv->fbHeight;
154
if (gDRIPriv->numMultiDevices == 2)
155
dst = (y0/2)*driScrnPriv->fbWidth+x0;
157
dst = y0*driScrnPriv->fbWidth+x0;
159
CHECK_DMA_BUFFER(gmesa, 9);
160
WRITE(gmesa->buf, StartXDom, x0<<16); /* X0dest */
161
WRITE(gmesa->buf, StartY, y0<<16); /* Y0dest */
162
WRITE(gmesa->buf, StartXSub, x1<<16); /* X1dest */
163
WRITE(gmesa->buf, GLINTCount, h); /* H */
164
WRITE(gmesa->buf, dY, 1<<16); /* ydir */
165
WRITE(gmesa->buf, dXDom, 0<<16);
166
WRITE(gmesa->buf, dXSub, 0<<16);
167
WRITE(gmesa->buf, FBSourceOffset, (dst-src));
168
WRITE(gmesa->buf, Render, 0x00040048); /* NOT_DONE */
172
** NOTE: FBSourceOffset (above) is backwards from what is
173
** described in the manual (i.e., dst-src instead of src-dst)
174
** due to our using the bottom-left window origin instead of the
175
** top-left window origin.
178
/* Restore FBReadMode */
179
CHECK_DMA_BUFFER(gmesa, 2);
180
WRITE(gmesa->buf, FBReadMode, (gmesa->FBReadMode |
181
gmesa->AB_FBReadMode));
182
WRITE(gmesa->buf, LBWriteMode, LBWriteModeEnable);
185
if (gmesa->EnabledFlags & GAMMA_BACK_BUFFER)
186
PROCESS_DMA_BUFFER_TOP_HALF(gmesa);
188
DRM_SPINUNLOCK(&driScrnPriv->pSAREA->drawable_lock,
189
driScrnPriv->drawLockID);
190
VALIDATE_DRAWABLE_INFO_NO_LOCK_POST(gmesa);
192
if (gmesa->EnabledFlags & GAMMA_BACK_BUFFER)
193
PROCESS_DMA_BUFFER_BOTTOM_HALF(gmesa);
195
_mesa_problem(NULL, "gammaSwapBuffers: drawable has no context!\n");
200
gammaMakeCurrent(__DRIcontextPrivate *driContextPriv,
201
__DRIdrawablePrivate *driDrawPriv,
202
__DRIdrawablePrivate *driReadPriv)
204
if (driContextPriv) {
205
GET_CURRENT_CONTEXT(ctx);
206
gammaContextPtr oldGammaCtx = ctx ? GAMMA_CONTEXT(ctx) : NULL;
207
gammaContextPtr newGammaCtx = (gammaContextPtr) driContextPriv->driverPrivate;
209
if ( newGammaCtx != oldGammaCtx ) {
210
newGammaCtx->dirty = ~0;
213
if (newGammaCtx->driDrawable != driDrawPriv) {
214
newGammaCtx->driDrawable = driDrawPriv;
215
gammaUpdateWindow ( newGammaCtx->glCtx );
216
gammaUpdateViewportOffset( newGammaCtx->glCtx );
220
newGammaCtx->Window &= ~W_GIDMask;
221
newGammaCtx->Window |= (driDrawPriv->index << 5);
222
CHECK_DMA_BUFFER(newGammaCtx,1);
223
WRITE(newGammaCtx->buf, GLINTWindow, newGammaCtx->Window);
226
newGammaCtx->new_state |= GAMMA_NEW_WINDOW; /* FIXME */
228
_mesa_make_current2( newGammaCtx->glCtx,
229
(GLframebuffer *) driDrawPriv->driverPrivate,
230
(GLframebuffer *) driReadPriv->driverPrivate );
232
if (!newGammaCtx->glCtx->Viewport.Width) {
233
_mesa_set_viewport(newGammaCtx->glCtx, 0, 0,
234
driDrawPriv->w, driDrawPriv->h);
237
_mesa_make_current( 0, 0 );
244
gammaUnbindContext( __DRIcontextPrivate *driContextPriv )
250
gammaOpenFullScreen(__DRIcontextPrivate *driContextPriv)
256
gammaCloseFullScreen(__DRIcontextPrivate *driContextPriv)
262
static struct __DriverAPIRec gammaAPI = {
279
* This is the bootstrap function for the driver.
280
* The __driCreateScreen name is the symbol that libGL.so fetches.
281
* Return: pointer to a __DRIscreenPrivate.
283
void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
284
int numConfigs, __GLXvisualConfig *config)
286
__DRIscreenPrivate *psp;
287
psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &gammaAPI);
291
void __driRegisterExtensions(void)