i965: Fix compiler warning from unused var.
[mesa.git] / src / mesa / drivers / dri / trident / trident_context.c
1 /*
2 * Copyright 2002 by Alan Hourihane, Sychdyn, North Wales, UK.
3 *
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.
13 *
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.
21 *
22 * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
23 *
24 * Trident CyberBladeXP driver.
25 *
26 */
27 #include "trident_dri.h"
28 #include "trident_context.h"
29 #include "trident_lock.h"
30
31 #include "swrast/swrast.h"
32 #include "swrast_setup/swrast_setup.h"
33 #include "vbo/vbo.h"
34
35 #include "tnl/tnl.h"
36 #include "tnl/t_pipeline.h"
37
38 #include "main/context.h"
39 #include "main/simple_list.h"
40 #include "main/matrix.h"
41 #include "main/extensions.h"
42 #include "main/framebuffer.h"
43 #include "main/renderbuffer.h"
44 #if defined(USE_X86_ASM)
45 #include "x86/common_x86_asm.h"
46 #endif
47 #include "main/simple_list.h"
48 #include "main/mm.h"
49 #include "drirenderbuffer.h"
50
51 #include "drivers/common/driverfuncs.h"
52 #include "dri_util.h"
53 #include "utils.h"
54
55 static const struct tnl_pipeline_stage *trident_pipeline[] = {
56 &_tnl_vertex_transform_stage,
57 &_tnl_normal_transform_stage,
58 &_tnl_lighting_stage,
59 &_tnl_texgen_stage,
60 &_tnl_texture_transform_stage,
61 &_tnl_render_stage,
62 0,
63 };
64
65
66 static GLboolean
67 tridentCreateContext( const __GLcontextModes *glVisual,
68 __DRIcontextPrivate *driContextPriv,
69 void *sharedContextPrivate)
70 {
71 GLcontext *ctx, *shareCtx;
72 __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
73 tridentContextPtr tmesa;
74 tridentScreenPtr tridentscrn;
75 struct dd_function_table functions;
76 #if 0
77 drm_trident_sarea_t *saPriv=(drm_trident_sarea_t *)(((char*)sPriv->pSAREA)+
78 sizeof(XF86DRISAREARec));
79 #endif
80
81 tmesa = (tridentContextPtr) CALLOC( sizeof(*tmesa) );
82 if ( !tmesa ) return GL_FALSE;
83
84 /* Allocate the Mesa context */
85 if (sharedContextPrivate)
86 shareCtx = ((tridentContextPtr) sharedContextPrivate)->glCtx;
87 else
88 shareCtx = NULL;
89
90 _mesa_init_driver_functions(&functions);
91
92 tmesa->glCtx =
93 _mesa_create_context(glVisual, shareCtx, &functions, (void *)tmesa);
94
95 if (!tmesa->glCtx) {
96 FREE(tmesa);
97 return GL_FALSE;
98 }
99
100 tmesa->driContext = driContextPriv;
101 tmesa->driScreen = sPriv;
102 tmesa->driDrawable = NULL; /* Set by XMesaMakeCurrent */
103
104 tmesa->hHWContext = driContextPriv->hHWContext;
105 tmesa->driHwLock = (drmLock *)&sPriv->pSAREA->lock;
106 tmesa->driFd = sPriv->fd;
107 #if 0
108 tmesa->sarea = saPriv;
109 #endif
110
111 tridentscrn = tmesa->tridentScreen = (tridentScreenPtr)(sPriv->private);
112
113 ctx = tmesa->glCtx;
114
115 ctx->Const.MaxTextureLevels = 13; /* 4K by 4K? Is that right? */
116 ctx->Const.MaxTextureUnits = 1; /* Permedia 3 */
117
118 ctx->Const.MinLineWidth = 0.0;
119 ctx->Const.MaxLineWidth = 255.0;
120
121 ctx->Const.MinLineWidthAA = 0.0;
122 ctx->Const.MaxLineWidthAA = 65536.0;
123
124 ctx->Const.MinPointSize = 0.0;
125 ctx->Const.MaxPointSize = 255.0;
126
127 ctx->Const.MinPointSizeAA = 0.5; /* 4x4 quality mode */
128 ctx->Const.MaxPointSizeAA = 16.0;
129 ctx->Const.PointSizeGranularity = 0.25;
130
131 #if 0
132 tmesa->texHeap = mmInit( 0, tmesa->tridentScreen->textureSize );
133
134 make_empty_list(&tmesa->TexObjList);
135 make_empty_list(&tmesa->SwappedOut);
136
137 tmesa->CurrentTexObj[0] = 0;
138 tmesa->CurrentTexObj[1] = 0; /* Permedia 3, second texture */
139
140 tmesa->RenderIndex = ~0;
141 #endif
142
143 /* Initialize the software rasterizer and helper modules.
144 */
145 _swrast_CreateContext( ctx );
146 _vbo_CreateContext( ctx );
147 _tnl_CreateContext( ctx );
148 _swsetup_CreateContext( ctx );
149
150 /* Install the customized pipeline:
151 */
152 _tnl_destroy_pipeline( ctx );
153 _tnl_install_pipeline( ctx, trident_pipeline );
154
155 /* Configure swrast to match hardware characteristics:
156 */
157 _swrast_allow_pixel_fog( ctx, GL_FALSE );
158 _swrast_allow_vertex_fog( ctx, GL_TRUE );
159
160 tridentInitVB( ctx );
161 tridentDDInitExtensions( ctx );
162 tridentDDInitDriverFuncs( ctx );
163 tridentDDInitStateFuncs( ctx );
164 #if 0
165 tridentDDInitSpanFuncs( ctx );
166 tridentDDInitTextureFuncs( ctx );
167 #endif
168 tridentDDInitTriFuncs( ctx );
169 tridentDDInitState( tmesa );
170
171 driContextPriv->driverPrivate = (void *)tmesa;
172
173 UNLOCK_HARDWARE(tmesa);
174
175 return GL_TRUE;
176 }
177
178 static void
179 tridentDestroyContext(__DRIcontextPrivate *driContextPriv)
180 {
181 tridentContextPtr tmesa = (tridentContextPtr)driContextPriv->driverPrivate;
182
183 if (tmesa) {
184 _swsetup_DestroyContext( tmesa->glCtx );
185 _tnl_DestroyContext( tmesa->glCtx );
186 _vbo_DestroyContext( tmesa->glCtx );
187 _swrast_DestroyContext( tmesa->glCtx );
188
189 /* free the Mesa context */
190 tmesa->glCtx->DriverCtx = NULL;
191 _mesa_destroy_context(tmesa->glCtx);
192
193 _mesa_free(tmesa);
194 driContextPriv->driverPrivate = NULL;
195 }
196 }
197
198
199 static GLboolean
200 tridentCreateBuffer( __DRIscreenPrivate *driScrnPriv,
201 __DRIdrawablePrivate *driDrawPriv,
202 const __GLcontextModes *mesaVis,
203 GLboolean isPixmap )
204 {
205 tridentScreenPtr screen = (tridentScreenPtr) driScrnPriv->private;
206
207 if (isPixmap) {
208 return GL_FALSE; /* not implemented */
209 }
210 else {
211 struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis);
212
213 {
214 driRenderbuffer *frontRb
215 = driNewRenderbuffer(GL_RGBA, NULL, screen->cpp,
216 screen->frontOffset, screen->frontPitch,
217 driDrawPriv);
218 /*
219 tridentSetSpanFunctions(frontRb, mesaVis);
220 */
221 _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontRb->Base);
222 }
223
224 if (mesaVis->doubleBufferMode) {
225 driRenderbuffer *backRb
226 = driNewRenderbuffer(GL_RGBA, NULL, screen->cpp,
227 screen->backOffset, screen->backPitch,
228 driDrawPriv);
229 /*
230 tridentSetSpanFunctions(backRb, mesaVis);
231 */
232 _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base);
233 }
234
235 if (mesaVis->depthBits == 16) {
236 driRenderbuffer *depthRb
237 = driNewRenderbuffer(GL_DEPTH_COMPONENT16, NULL, screen->cpp,
238 screen->depthOffset, screen->depthPitch,
239 driDrawPriv);
240 /*
241 tridentSetSpanFunctions(depthRb, mesaVis);
242 */
243 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
244 }
245 else if (mesaVis->depthBits == 24) {
246 driRenderbuffer *depthRb
247 = driNewRenderbuffer(GL_DEPTH_COMPONENT24, NULL, screen->cpp,
248 screen->depthOffset, screen->depthPitch,
249 driDrawPriv);
250 /*
251 tridentSetSpanFunctions(depthRb, mesaVis);
252 */
253 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
254 }
255
256 /* no h/w stencil?
257 if (mesaVis->stencilBits > 0 && !swStencil) {
258 driRenderbuffer *stencilRb
259 = driNewRenderbuffer(GL_STENCIL_INDEX8_EXT);
260 tridentSetSpanFunctions(stencilRb, mesaVis);
261 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencilRb->Base);
262 }
263 */
264
265 _mesa_add_soft_renderbuffers(fb,
266 GL_FALSE, /* color */
267 GL_FALSE, /* depth */
268 mesaVis->stencilBits > 0,
269 mesaVis->accumRedBits > 0,
270 GL_FALSE, /* alpha */
271 GL_FALSE /* aux */);
272 driDrawPriv->driverPrivate = (void *) fb;
273
274 return (driDrawPriv->driverPrivate != NULL);
275 }
276 }
277
278
279 static void
280 tridentDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
281 {
282 _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)));
283 }
284
285 static void
286 tridentSwapBuffers(__DRIdrawablePrivate *drawablePrivate)
287 {
288 __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate;
289
290 if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
291 tridentContextPtr tmesa;
292 GLcontext *ctx;
293 tmesa = (tridentContextPtr) dPriv->driContextPriv->driverPrivate;
294 ctx = tmesa->glCtx;
295 if (ctx->Visual.doubleBufferMode) {
296 _mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */
297 tridentCopyBuffer( dPriv );
298 }
299 }
300 else {
301 /* XXX this shouldn't be an error but we can't handle it for now */
302 _mesa_problem(NULL, "tridentSwapBuffers: drawable has no context!\n");
303 }
304 }
305
306 static GLboolean
307 tridentMakeCurrent(__DRIcontextPrivate *driContextPriv,
308 __DRIdrawablePrivate *driDrawPriv,
309 __DRIdrawablePrivate *driReadPriv)
310 {
311 if (driContextPriv) {
312 GET_CURRENT_CONTEXT(ctx);
313 tridentContextPtr oldCtx = ctx ? TRIDENT_CONTEXT(ctx) : NULL;
314 tridentContextPtr newCtx = (tridentContextPtr) driContextPriv->driverPrivate;
315
316 if ( newCtx != oldCtx ) {
317 newCtx->dirty = ~0;
318 }
319
320 if (newCtx->driDrawable != driDrawPriv) {
321 newCtx->driDrawable = driDrawPriv;
322 #if 0
323 tridentUpdateWindow ( newCtx->glCtx );
324 tridentUpdateViewportOffset( newCtx->glCtx );
325 #endif
326 }
327
328 newCtx->drawOffset = newCtx->tridentScreen->backOffset;
329 newCtx->drawPitch = newCtx->tridentScreen->backPitch;
330
331 _mesa_make_current( newCtx->glCtx,
332 (GLframebuffer *) driDrawPriv->driverPrivate,
333 (GLframebuffer *) driReadPriv->driverPrivate );
334
335 if (!newCtx->glCtx->Viewport.Width) {
336 _mesa_set_viewport(newCtx->glCtx, 0, 0,
337 driDrawPriv->w, driDrawPriv->h);
338 }
339 } else {
340 _mesa_make_current( NULL, NULL, NULL );
341 }
342 return GL_TRUE;
343 }
344
345
346 static GLboolean
347 tridentUnbindContext( __DRIcontextPrivate *driContextPriv )
348 {
349 return GL_TRUE;
350 }
351
352
353 static tridentScreenPtr
354 tridentCreateScreen( __DRIscreenPrivate *sPriv )
355 {
356 TRIDENTDRIPtr tDRIPriv = (TRIDENTDRIPtr)sPriv->pDevPriv;
357 tridentScreenPtr tridentScreen;
358
359 if (sPriv->devPrivSize != sizeof(TRIDENTDRIRec)) {
360 fprintf(stderr,"\nERROR! sizeof(TRIDENTDRIRec) does not match passed size from device driver\n");
361 return GL_FALSE;
362 }
363
364 /* Allocate the private area */
365 tridentScreen = (tridentScreenPtr) CALLOC( sizeof(*tridentScreen) );
366 if ( !tridentScreen ) return NULL;
367
368 tridentScreen->driScreen = sPriv;
369
370 tridentScreen->frontOffset = tDRIPriv->frontOffset;
371 tridentScreen->backOffset = tDRIPriv->backOffset;
372 tridentScreen->depthOffset = tDRIPriv->depthOffset;
373 tridentScreen->frontPitch = tDRIPriv->frontPitch;
374 tridentScreen->backPitch = tDRIPriv->backPitch;
375 tridentScreen->depthPitch = tDRIPriv->depthPitch;
376 tridentScreen->width = tDRIPriv->width;
377 tridentScreen->height = tDRIPriv->height;
378
379 printf("%d %d\n",tridentScreen->width,tridentScreen->height);
380 printf("%d %d\n",tridentScreen->frontPitch,tridentScreen->backPitch);
381 printf("offset 0x%x 0x%x\n",tridentScreen->backOffset,tridentScreen->depthOffset);
382
383 tridentScreen->mmio.handle = tDRIPriv->regs;
384 tridentScreen->mmio.size = 0x20000;
385
386 if (drmMap(sPriv->fd,
387 tridentScreen->mmio.handle, tridentScreen->mmio.size,
388 (drmAddressPtr)&tridentScreen->mmio.map)) {
389 FREE(tridentScreen);
390 return GL_FALSE;
391 }
392 printf("MAPPED at %p\n", tridentScreen->mmio.map);
393
394 return tridentScreen;
395 }
396
397 /* Destroy the device specific screen private data struct.
398 */
399 static void
400 tridentDestroyScreen( __DRIscreenPrivate *sPriv )
401 {
402 tridentScreenPtr tridentScreen = (tridentScreenPtr)sPriv->private;
403
404 FREE(tridentScreen);
405 }
406
407 static GLboolean
408 tridentInitDriver(__DRIscreenPrivate *sPriv)
409 {
410 sPriv->private = (void *) tridentCreateScreen( sPriv );
411
412 if (!sPriv->private) {
413 tridentDestroyScreen( sPriv );
414 return GL_FALSE;
415 }
416
417 return GL_TRUE;
418 }
419
420 /**
421 * This is the driver specific part of the createNewScreen entry point.
422 *
423 * \todo maybe fold this into intelInitDriver
424 *
425 * \return the __GLcontextModes supported by this driver
426 */
427 const __DRIconfig **tridentInitScreen(__DRIscreenPrivate *psp)
428 {
429 static const __DRIversion ddx_expected = { 4, 0, 0 };
430 static const __DRIversion dri_expected = { 3, 1, 0 };
431 static const __DRIversion drm_expected = { 1, 0, 0 };
432
433 if ( ! driCheckDriDdxDrmVersions2( "Trident",
434 &psp->dri_version, & dri_expected,
435 &psp->ddx_version, & ddx_expected,
436 &psp->drm_version, & drm_expected ) )
437 return NULL;
438
439 if (!tridentInitDriver(psp))
440 return NULL;
441
442 /* Wait... what? This driver doesn't report any modes... */
443 #if 0
444 TRIDENTDRIPtr dri_priv = (TRIDENTDRIPtr) psp->pDevPriv;
445 *driver_modes = tridentFillInModes( dri_priv->bytesPerPixel * 8,
446 GL_TRUE );
447 #endif
448
449 return NULL;
450 }
451
452 const struct __DriverAPIRec driDriverAPI = {
453 tridentInitScreen,
454 tridentDestroyScreen,
455 tridentCreateContext,
456 tridentDestroyContext,
457 tridentCreateBuffer,
458 tridentDestroyBuffer,
459 tridentSwapBuffers,
460 tridentMakeCurrent,
461 tridentUnbindContext,
462 };