1 /* -*- mode: c; c-basic-offset: 3 -*-
3 * Copyright 2000 VA Linux Systems Inc., Fremont, California.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * VA LINUX SYSTEMS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
23 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 /* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_screen.c,v 1.3 2002/02/22 21:45:03 dawes Exp $ */
30 * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000
33 * Gareth Hughes <gareth@valinux.com>
38 #include "tdfx_context.h"
39 #include "tdfx_lock.h"
41 #include "tdfx_tris.h"
45 char *prevLockFile
= 0;
51 /* | DEBUG_ALWAYS_SYNC */
52 /* | DEBUG_VERBOSE_API */
53 /* | DEBUG_VERBOSE_MSG */
54 /* | DEBUG_VERBOSE_LRU */
55 /* | DEBUG_VERBOSE_DRI */
56 /* | DEBUG_VERBOSE_IOCTL */
57 /* | DEBUG_VERBOSE_2D */
64 tdfxCreateScreen( __DRIscreenPrivate
*sPriv
)
66 tdfxScreenPrivate
*fxScreen
;
67 TDFXDRIPtr fxDRIPriv
= (TDFXDRIPtr
) sPriv
->pDevPriv
;
69 /* Allocate the private area */
70 fxScreen
= (tdfxScreenPrivate
*) CALLOC( sizeof(tdfxScreenPrivate
) );
74 fxScreen
->driScrnPriv
= sPriv
;
75 sPriv
->private = (void *) fxScreen
;
77 fxScreen
->regs
.handle
= fxDRIPriv
->regs
;
78 fxScreen
->regs
.size
= fxDRIPriv
->regsSize
;
79 fxScreen
->deviceID
= fxDRIPriv
->deviceID
;
80 fxScreen
->width
= fxDRIPriv
->width
;
81 fxScreen
->height
= fxDRIPriv
->height
;
82 fxScreen
->mem
= fxDRIPriv
->mem
;
83 fxScreen
->cpp
= fxDRIPriv
->cpp
;
84 fxScreen
->stride
= fxDRIPriv
->stride
;
85 fxScreen
->fifoOffset
= fxDRIPriv
->fifoOffset
;
86 fxScreen
->fifoSize
= fxDRIPriv
->fifoSize
;
87 fxScreen
->fbOffset
= fxDRIPriv
->fbOffset
;
88 fxScreen
->backOffset
= fxDRIPriv
->backOffset
;
89 fxScreen
->depthOffset
= fxDRIPriv
->depthOffset
;
90 fxScreen
->textureOffset
= fxDRIPriv
->textureOffset
;
91 fxScreen
->textureSize
= fxDRIPriv
->textureSize
;
92 fxScreen
->sarea_priv_offset
= fxDRIPriv
->sarea_priv_offset
;
94 if ( drmMap( sPriv
->fd
, fxScreen
->regs
.handle
,
95 fxScreen
->regs
.size
, &fxScreen
->regs
.map
) ) {
104 tdfxDestroyScreen( __DRIscreenPrivate
*sPriv
)
106 tdfxScreenPrivate
*fxScreen
= (tdfxScreenPrivate
*) sPriv
->private;
109 drmUnmap( fxScreen
->regs
.map
, fxScreen
->regs
.size
);
112 sPriv
->private = NULL
;
118 tdfxInitDriver( __DRIscreenPrivate
*sPriv
)
120 if ( TDFX_DEBUG
& DEBUG_VERBOSE_DRI
) {
121 fprintf( stderr
, "%s( %p )\n", __FUNCTION__
, sPriv
);
124 /* Check the DRI externsion version */
125 if ( sPriv
->driMajor
!= 4 || sPriv
->driMinor
< 0 ) {
126 __driUtilMessage( "tdfx DRI driver expected DRI version 4.0.x "
127 "but got version %d.%d.%d",
128 sPriv
->driMajor
, sPriv
->driMinor
, sPriv
->driPatch
);
132 /* Check that the DDX driver version is compatible */
133 if ( sPriv
->ddxMajor
!= 1 ||
134 sPriv
->ddxMinor
< 0 ) {
136 "3dfx DRI driver expected DDX driver version 1.0.x "
137 "but got version %d.%d.%d",
138 sPriv
->ddxMajor
, sPriv
->ddxMinor
, sPriv
->ddxPatch
);
142 /* Check that the DRM driver version is compatible */
143 if ( sPriv
->drmMajor
!= 1 ||
144 sPriv
->drmMinor
< 0 ) {
146 "3dfx DRI driver expected DRM driver version 1.0.x "
147 "but got version %d.%d.%d",
148 sPriv
->drmMajor
, sPriv
->drmMinor
, sPriv
->drmPatch
);
152 if ( !tdfxCreateScreen( sPriv
) ) {
153 tdfxDestroyScreen( sPriv
);
162 tdfxCreateBuffer( __DRIscreenPrivate
*driScrnPriv
,
163 __DRIdrawablePrivate
*driDrawPriv
,
164 const __GLcontextModes
*mesaVis
,
168 return GL_FALSE
; /* not implemented */
171 driDrawPriv
->driverPrivate
= (void *)
172 _mesa_create_framebuffer( mesaVis
,
173 GL_FALSE
, /* software depth buffer? */
174 mesaVis
->stencilBits
> 0,
175 mesaVis
->accumRedBits
> 0,
176 GL_FALSE
/* software alpha channel? */ );
177 return (driDrawPriv
->driverPrivate
!= NULL
);
183 tdfxDestroyBuffer(__DRIdrawablePrivate
*driDrawPriv
)
185 _mesa_destroy_framebuffer((GLframebuffer
*) (driDrawPriv
->driverPrivate
));
190 tdfxSwapBuffers( __DRIdrawablePrivate
*driDrawPriv
)
193 GET_CURRENT_CONTEXT(ctx
);
194 tdfxContextPtr fxMesa
= 0;
195 GLframebuffer
*mesaBuffer
;
197 if ( TDFX_DEBUG
& DEBUG_VERBOSE_DRI
) {
198 fprintf( stderr
, "%s( %p )\n", __FUNCTION__
, driDrawPriv
);
201 mesaBuffer
= (GLframebuffer
*) driDrawPriv
->driverPrivate
;
202 if ( !mesaBuffer
->Visual
.doubleBufferMode
)
203 return; /* can't swap a single-buffered window */
205 /* If the current context's drawable matches the given drawable
206 * we have to do a glFinish (per the GLX spec).
209 __DRIdrawablePrivate
*curDrawPriv
;
210 fxMesa
= TDFX_CONTEXT(ctx
);
211 curDrawPriv
= fxMesa
->driContext
->driDrawablePriv
;
213 if ( curDrawPriv
== driDrawPriv
) {
214 /* swapping window bound to current context, flush first */
215 _mesa_notifySwapBuffers( ctx
);
216 LOCK_HARDWARE( fxMesa
);
219 /* find the fxMesa context previously bound to the window */
220 fxMesa
= (tdfxContextPtr
) driDrawPriv
->driContextPriv
->driverPrivate
;
223 LOCK_HARDWARE( fxMesa
);
224 fxMesa
->Glide
.grSstSelect( fxMesa
->Glide
.Board
);
225 printf("SwapBuf SetState 1\n");
226 fxMesa
->Glide
.grGlideSetState(fxMesa
->Glide
.State
);
233 static int prevStalls
= 0;
235 stalls
= fxMesa
->Glide
.grFifoGetStalls();
237 fprintf( stderr
, "%s:\n", __FUNCTION__
);
238 if ( stalls
!= prevStalls
) {
239 fprintf( stderr
, " %d stalls occurred\n",
240 stalls
- prevStalls
);
243 if ( fxMesa
&& fxMesa
->texSwaps
) {
244 fprintf( stderr
, " %d texture swaps occurred\n",
246 fxMesa
->texSwaps
= 0;
251 if (fxMesa
->scissoredClipRects
) {
252 /* restore clip rects without scissor box */
253 fxMesa
->Glide
.grDRIPosition( driDrawPriv
->x
, driDrawPriv
->y
,
254 driDrawPriv
->w
, driDrawPriv
->h
,
255 driDrawPriv
->numClipRects
,
256 driDrawPriv
->pClipRects
);
259 fxMesa
->Glide
.grDRIBufferSwap( fxMesa
->Glide
.SwapInterval
);
261 if (fxMesa
->scissoredClipRects
) {
262 /* restore clip rects WITH scissor box */
263 fxMesa
->Glide
.grDRIPosition( driDrawPriv
->x
, driDrawPriv
->y
,
264 driDrawPriv
->w
, driDrawPriv
->h
,
265 fxMesa
->numClipRects
, fxMesa
->pClipRects
);
274 fxMesa
->Glide
.grGet(GR_PENDING_BUFFERSWAPS
, 4, &result
);
275 } while ( result
> fxMesa
->maxPendingSwapBuffers
);
279 fxMesa
->stats
.swapBuffer
++;
282 if (ctx
->DriverCtx
!= fxMesa
) {
283 fxMesa
= TDFX_CONTEXT(ctx
);
284 fxMesa
->Glide
.grSstSelect( fxMesa
->Glide
.Board
);
285 printf("SwapBuf SetState 2\n");
286 fxMesa
->Glide
.grGlideSetState(fxMesa
->Glide
.State
);
288 UNLOCK_HARDWARE( fxMesa
);
294 tdfxOpenCloseFullScreen(__DRIcontextPrivate
*driContextPriv
)
300 static const struct __DriverAPIRec tdfxAPI
= {
301 .InitDriver
= tdfxInitDriver
,
302 .DestroyScreen
= tdfxDestroyScreen
,
303 .CreateContext
= tdfxCreateContext
,
304 .DestroyContext
= tdfxDestroyContext
,
305 .CreateBuffer
= tdfxCreateBuffer
,
306 .DestroyBuffer
= tdfxDestroyBuffer
,
307 .SwapBuffers
= tdfxSwapBuffers
,
308 .MakeCurrent
= tdfxMakeCurrent
,
309 .UnbindContext
= tdfxUnbindContext
,
310 .OpenFullScreen
= tdfxOpenCloseFullScreen
,
311 .CloseFullScreen
= tdfxOpenCloseFullScreen
,
316 .SwapBuffersMSC
= NULL
321 * This is the bootstrap function for the driver.
322 * The __driCreateScreen name is the symbol that libGL.so fetches.
323 * Return: pointer to a __DRIscreenPrivate.
326 void *__driCreateScreen(Display
*dpy
, int scrn
, __DRIscreen
*psc
,
327 int numConfigs
, __GLXvisualConfig
*config
)
329 __DRIscreenPrivate
*psp
;
330 psp
= __driUtilCreateScreen(dpy
, scrn
, psc
, numConfigs
, config
, &tdfxAPI
);
334 void *__driCreateScreen(struct DRIDriverRec
*driver
,
335 struct DRIDriverContextRec
*driverContext
)
337 __DRIscreenPrivate
*psp
;
338 psp
= __driUtilCreateScreen(driver
, driverContext
, &tdfxAPI
);