include texobj.h to silence warnings
[mesa.git] / src / mesa / drivers / dri / tdfx / tdfx_screen.c
1 /* -*- mode: c; c-basic-offset: 3 -*-
2 *
3 * Copyright 2000 VA Linux Systems Inc., Fremont, California.
4 *
5 * All Rights Reserved.
6 *
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:
13 *
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
16 * Software.
17 *
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
24 * SOFTWARE.
25 */
26 /* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_screen.c,v 1.3 2002/02/22 21:45:03 dawes Exp $ */
27
28 /*
29 * Original rewrite:
30 * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000
31 *
32 * Authors:
33 * Gareth Hughes <gareth@valinux.com>
34 *
35 */
36
37 #include "tdfx_dri.h"
38 #include "tdfx_context.h"
39 #include "tdfx_lock.h"
40 #include "tdfx_vb.h"
41 #include "tdfx_tris.h"
42
43
44 #ifdef DEBUG_LOCKING
45 char *prevLockFile = 0;
46 int prevLockLine = 0;
47 #endif
48
49 #ifndef TDFX_DEBUG
50 int TDFX_DEBUG = (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 */
58 );
59 #endif
60
61
62
63 static GLboolean
64 tdfxCreateScreen( __DRIscreenPrivate *sPriv )
65 {
66 tdfxScreenPrivate *fxScreen;
67 TDFXDRIPtr fxDRIPriv = (TDFXDRIPtr) sPriv->pDevPriv;
68
69 /* Allocate the private area */
70 fxScreen = (tdfxScreenPrivate *) CALLOC( sizeof(tdfxScreenPrivate) );
71 if ( !fxScreen )
72 return GL_FALSE;
73
74 fxScreen->driScrnPriv = sPriv;
75 sPriv->private = (void *) fxScreen;
76
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;
93
94 if ( drmMap( sPriv->fd, fxScreen->regs.handle,
95 fxScreen->regs.size, &fxScreen->regs.map ) ) {
96 return GL_FALSE;
97 }
98
99 return GL_TRUE;
100 }
101
102
103 static void
104 tdfxDestroyScreen( __DRIscreenPrivate *sPriv )
105 {
106 tdfxScreenPrivate *fxScreen = (tdfxScreenPrivate *) sPriv->private;
107
108 if ( fxScreen ) {
109 drmUnmap( fxScreen->regs.map, fxScreen->regs.size );
110
111 FREE( fxScreen );
112 sPriv->private = NULL;
113 }
114 }
115
116
117 static GLboolean
118 tdfxInitDriver( __DRIscreenPrivate *sPriv )
119 {
120 if ( TDFX_DEBUG & DEBUG_VERBOSE_DRI ) {
121 fprintf( stderr, "%s( %p )\n", __FUNCTION__, sPriv );
122 }
123
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 );
129 return GL_FALSE;
130 }
131
132 /* Check that the DDX driver version is compatible */
133 if ( sPriv->ddxMajor != 1 ||
134 sPriv->ddxMinor < 0 ) {
135 __driUtilMessage(
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 );
139 return GL_FALSE;
140 }
141
142 /* Check that the DRM driver version is compatible */
143 if ( sPriv->drmMajor != 1 ||
144 sPriv->drmMinor < 0 ) {
145 __driUtilMessage(
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 );
149 return GL_FALSE;
150 }
151
152 if ( !tdfxCreateScreen( sPriv ) ) {
153 tdfxDestroyScreen( sPriv );
154 return GL_FALSE;
155 }
156
157 return GL_TRUE;
158 }
159
160
161 static GLboolean
162 tdfxCreateBuffer( __DRIscreenPrivate *driScrnPriv,
163 __DRIdrawablePrivate *driDrawPriv,
164 const __GLcontextModes *mesaVis,
165 GLboolean isPixmap )
166 {
167 if (isPixmap) {
168 return GL_FALSE; /* not implemented */
169 }
170 else {
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);
178 }
179 }
180
181
182 static void
183 tdfxDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
184 {
185 _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
186 }
187
188
189 static void
190 tdfxSwapBuffers( __DRIdrawablePrivate *driDrawPriv )
191
192 {
193 GET_CURRENT_CONTEXT(ctx);
194 tdfxContextPtr fxMesa = 0;
195 GLframebuffer *mesaBuffer;
196
197 if ( TDFX_DEBUG & DEBUG_VERBOSE_DRI ) {
198 fprintf( stderr, "%s( %p )\n", __FUNCTION__, driDrawPriv );
199 }
200
201 mesaBuffer = (GLframebuffer *) driDrawPriv->driverPrivate;
202 if ( !mesaBuffer->Visual.doubleBufferMode )
203 return; /* can't swap a single-buffered window */
204
205 /* If the current context's drawable matches the given drawable
206 * we have to do a glFinish (per the GLX spec).
207 */
208 if ( ctx ) {
209 __DRIdrawablePrivate *curDrawPriv;
210 fxMesa = TDFX_CONTEXT(ctx);
211 curDrawPriv = fxMesa->driContext->driDrawablePriv;
212
213 if ( curDrawPriv == driDrawPriv ) {
214 /* swapping window bound to current context, flush first */
215 _mesa_notifySwapBuffers( ctx );
216 LOCK_HARDWARE( fxMesa );
217 }
218 else {
219 /* find the fxMesa context previously bound to the window */
220 fxMesa = (tdfxContextPtr) driDrawPriv->driContextPriv->driverPrivate;
221 if (!fxMesa)
222 return;
223 LOCK_HARDWARE( fxMesa );
224 fxMesa->Glide.grSstSelect( fxMesa->Glide.Board );
225 printf("SwapBuf SetState 1\n");
226 fxMesa->Glide.grGlideSetState(fxMesa->Glide.State );
227 }
228 }
229
230 #ifdef STATS
231 {
232 int stalls;
233 static int prevStalls = 0;
234
235 stalls = fxMesa->Glide.grFifoGetStalls();
236
237 fprintf( stderr, "%s:\n", __FUNCTION__ );
238 if ( stalls != prevStalls ) {
239 fprintf( stderr, " %d stalls occurred\n",
240 stalls - prevStalls );
241 prevStalls = stalls;
242 }
243 if ( fxMesa && fxMesa->texSwaps ) {
244 fprintf( stderr, " %d texture swaps occurred\n",
245 fxMesa->texSwaps );
246 fxMesa->texSwaps = 0;
247 }
248 }
249 #endif
250
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 );
257 }
258
259 fxMesa->Glide.grDRIBufferSwap( fxMesa->Glide.SwapInterval );
260
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 );
266 }
267
268
269 #if 0
270 {
271 FxI32 result;
272 do {
273 FxI32 result;
274 fxMesa->Glide.grGet(GR_PENDING_BUFFERSWAPS, 4, &result);
275 } while ( result > fxMesa->maxPendingSwapBuffers );
276 }
277 #endif
278
279 fxMesa->stats.swapBuffer++;
280
281 if (ctx) {
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 );
287 }
288 UNLOCK_HARDWARE( fxMesa );
289 }
290 }
291
292
293 static GLboolean
294 tdfxOpenCloseFullScreen(__DRIcontextPrivate *driContextPriv)
295 {
296 return GL_TRUE;
297 }
298
299
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,
312 .GetSwapInfo = NULL,
313 .GetMSC = NULL,
314 .WaitForMSC = NULL,
315 .WaitForSBC = NULL,
316 .SwapBuffersMSC = NULL
317 };
318
319
320 /*
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.
324 */
325 #ifndef _SOLO
326 void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
327 int numConfigs, __GLXvisualConfig *config)
328 {
329 __DRIscreenPrivate *psp;
330 psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &tdfxAPI);
331 return (void *) psp;
332 }
333 #else
334 void *__driCreateScreen(struct DRIDriverRec *driver,
335 struct DRIDriverContextRec *driverContext)
336 {
337 __DRIscreenPrivate *psp;
338 psp = __driUtilCreateScreen(driver, driverContext, &tdfxAPI);
339 return (void *) psp;
340 }
341 #endif