2 * Copyright 2001 by Alan Hourihane.
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.
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.
22 * Authors: Alan Hourihane, <alanh@tungstengraphics.com>
27 #include "gammacontext.h"
29 #include "main/context.h"
30 #include "main/matrix.h"
31 #include "glint_dri.h"
33 #include "swrast/swrast.h"
34 #include "swrast_setup/swrast_setup.h"
39 gammaInitDriver(__DRIscreen
*sPriv
)
41 sPriv
->private = (void *) gammaCreateScreen( sPriv
);
43 if (!sPriv
->private) {
44 gammaDestroyScreen( sPriv
);
52 gammaDestroyContext(__DRIcontext
*driContextPriv
)
54 gammaContextPtr gmesa
= (gammaContextPtr
)driContextPriv
->driverPrivate
;
57 _swsetup_DestroyContext( gmesa
->glCtx
);
58 _tnl_DestroyContext( gmesa
->glCtx
);
59 _vbo_DestroyContext( gmesa
->glCtx
);
60 _swrast_DestroyContext( gmesa
->glCtx
);
62 gammaFreeVB( gmesa
->glCtx
);
64 /* free the Mesa context */
65 gmesa
->glCtx
->DriverCtx
= NULL
;
66 _mesa_destroy_context(gmesa
->glCtx
);
69 driContextPriv
->driverPrivate
= NULL
;
75 gammaCreateBuffer( __DRIscreen
*driScrnPriv
,
76 __DRIdrawable
*driDrawPriv
,
77 const __GLcontextModes
*mesaVis
,
81 return GL_FALSE
; /* not implemented */
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
91 return (driDrawPriv
->driverPrivate
!= NULL
);
97 gammaDestroyBuffer(__DRIdrawable
*driDrawPriv
)
99 _mesa_reference_framebuffer((GLframebuffer
**)(&(driDrawPriv
->driverPrivate
)), NULL
);
103 gammaSwapBuffers( __DRIdrawable
*dPriv
)
105 if (dPriv
->driContextPriv
&& dPriv
->driContextPriv
->driverPrivate
) {
106 gammaContextPtr gmesa
;
107 __DRIscreen
*driScrnPriv
;
110 gmesa
= (gammaContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
112 driScrnPriv
= gmesa
->driScreen
;
114 _mesa_notifySwapBuffers(ctx
);
116 VALIDATE_DRAWABLE_INFO(gmesa
);
118 /* Flush any partially filled buffers */
119 FLUSH_DMA_BUFFER(gmesa
);
121 DRM_SPINLOCK(&driScrnPriv
->pSAREA
->drawable_lock
,
122 driScrnPriv
->drawLockID
);
123 VALIDATE_DRAWABLE_INFO_NO_LOCK(gmesa
);
125 if (gmesa
->EnabledFlags
& GAMMA_BACK_BUFFER
) {
126 int src
, dst
, x0
, y0
, x1
, h
;
128 int nRect
= dPriv
->numClipRects
;
129 drm_clip_rect_t
*pRect
= dPriv
->pClipRects
;
130 __DRIscreen
*driScrnPriv
= gmesa
->driScreen
;
131 GLINTDRIPtr gDRIPriv
= (GLINTDRIPtr
)driScrnPriv
->pDevPriv
;
133 CHECK_DMA_BUFFER(gmesa
, 2);
134 WRITE(gmesa
->buf
, FBReadMode
, (gmesa
->FBReadMode
|
136 WRITE(gmesa
->buf
, LBWriteMode
, LBWriteModeDisable
);
138 for (i
= 0; i
< nRect
; i
++, pRect
++) {
141 h
= pRect
->y2
- pRect
->y1
;
143 y0
= driScrnPriv
->fbHeight
- (pRect
->y1
+h
);
144 if (gDRIPriv
->numMultiDevices
== 2)
145 src
= (y0
/2)*driScrnPriv
->fbWidth
+x0
;
147 src
= y0
*driScrnPriv
->fbWidth
+x0
;
149 y0
+= driScrnPriv
->fbHeight
;
150 if (gDRIPriv
->numMultiDevices
== 2)
151 dst
= (y0
/2)*driScrnPriv
->fbWidth
+x0
;
153 dst
= y0
*driScrnPriv
->fbWidth
+x0
;
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 */
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.
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
);
181 if (gmesa
->EnabledFlags
& GAMMA_BACK_BUFFER
)
182 PROCESS_DMA_BUFFER_TOP_HALF(gmesa
);
184 DRM_SPINUNLOCK(&driScrnPriv
->pSAREA
->drawable_lock
,
185 driScrnPriv
->drawLockID
);
186 VALIDATE_DRAWABLE_INFO_NO_LOCK_POST(gmesa
);
188 if (gmesa
->EnabledFlags
& GAMMA_BACK_BUFFER
)
189 PROCESS_DMA_BUFFER_BOTTOM_HALF(gmesa
);
191 _mesa_problem(NULL
, "gammaSwapBuffers: drawable has no context!\n");
196 gammaMakeCurrent(__DRIcontext
*driContextPriv
,
197 __DRIdrawable
*driDrawPriv
,
198 __DRIdrawable
*driReadPriv
)
200 if (driContextPriv
) {
201 GET_CURRENT_CONTEXT(ctx
);
202 gammaContextPtr oldGammaCtx
= ctx
? GAMMA_CONTEXT(ctx
) : NULL
;
203 gammaContextPtr newGammaCtx
= (gammaContextPtr
) driContextPriv
->driverPrivate
;
205 if ( newGammaCtx
!= oldGammaCtx
) {
206 newGammaCtx
->dirty
= ~0;
209 if (newGammaCtx
->driDrawable
!= driDrawPriv
) {
210 newGammaCtx
->driDrawable
= driDrawPriv
;
211 gammaUpdateWindow ( newGammaCtx
->glCtx
);
212 gammaUpdateViewportOffset( newGammaCtx
->glCtx
);
216 newGammaCtx
->Window
&= ~W_GIDMask
;
217 newGammaCtx
->Window
|= (driDrawPriv
->index
<< 5);
218 CHECK_DMA_BUFFER(newGammaCtx
,1);
219 WRITE(newGammaCtx
->buf
, GLINTWindow
, newGammaCtx
->Window
);
222 newGammaCtx
->new_state
|= GAMMA_NEW_WINDOW
; /* FIXME */
224 _mesa_make_current2( newGammaCtx
->glCtx
,
225 (GLframebuffer
*) driDrawPriv
->driverPrivate
,
226 (GLframebuffer
*) driReadPriv
->driverPrivate
);
228 _mesa_make_current( 0, 0 );
235 gammaUnbindContext( __DRIcontext
*driContextPriv
)
240 const struct __DriverAPIRec driDriverAPI
= {
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 __DRIscreen.
259 void *__driCreateScreen(Display
*dpy
, int scrn
, __DRIscreen
*psc
,
260 int numConfigs
, __GLXvisualConfig
*config
)
263 psp
= __driUtilCreateScreen(dpy
, scrn
, psc
, numConfigs
, config
, &gammaAPI
);
267 /* This is the table of extensions that the loader will dlsym() for. */
268 PUBLIC
const __DRIextension
*__driDriverExtensions
[] = {
269 &driCoreExtension
.base
,
270 &driLegacyExtension
.base
,