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