Remove Driver.ResizeBuffers = _mesa_resize_framebuffer lines.
[mesa.git] / src / mesa / drivers / dri / trident / trident_state.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_context.h"
28 #include "trident_lock.h"
29 #include "array_cache/acache.h"
30 #include "swrast/swrast.h"
31 #include "swrast_setup/swrast_setup.h"
32 #include "tnl/tnl.h"
33 #include "framebuffer.h"
34
35 #define TRIDENTPACKCOLOR332(r, g, b) \
36 (((r) & 0xe0) | (((g) & 0xe0) >> 3) | (((b) & 0xc0) >> 6))
37
38 #define TRIDENTPACKCOLOR1555(r, g, b, a) \
39 ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \
40 ((a) ? 0x8000 : 0))
41
42 #define TRIDENTPACKCOLOR565(r, g, b) \
43 ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3))
44
45 #define TRIDENTPACKCOLOR888(r, g, b) \
46 (((r) << 16) | ((g) << 8) | (b))
47
48 #define TRIDENTPACKCOLOR8888(r, g, b, a) \
49 (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
50
51 #define TRIDENTPACKCOLOR4444(r, g, b, a) \
52 ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4))
53
54 static __inline__ GLuint tridentPackColor( GLuint cpp,
55 GLubyte r, GLubyte g,
56 GLubyte b, GLubyte a )
57 {
58 switch ( cpp ) {
59 case 2:
60 return TRIDENTPACKCOLOR565( r, g, b );
61 case 4:
62 return TRIDENTPACKCOLOR8888( r, g, b, a );
63 default:
64 return 0;
65 }
66 }
67
68 void tridentUploadHwStateLocked( tridentContextPtr tmesa )
69 {
70 unsigned char *MMIO = tmesa->tridentScreen->mmio.map;
71 #if 0
72 ATISAREAPrivPtr sarea = tmesa->sarea;
73 trident_context_regs_t *regs = &(sarea->ContextState);
74 #endif
75
76 if ( tmesa->dirty & TRIDENT_UPLOAD_COMMAND_D ) {
77 MMIO_OUT32(MMIO, 0x00281C, tmesa->commandD );
78 tmesa->dirty &= ~TRIDENT_UPLOAD_COMMAND_D;
79 }
80
81 if ( tmesa->dirty & TRIDENT_UPLOAD_CLIPRECTS ) {
82 /* XXX FIX ME ! */
83 MMIO_OUT32(MMIO, 0x002C80 , 0x20008000 | tmesa->tridentScreen->height );
84 MMIO_OUT32(MMIO, 0x002C84 , 0x20000000 | tmesa->tridentScreen->width );
85 tmesa->dirty &= ~TRIDENT_UPLOAD_CLIPRECTS;
86 }
87
88 tmesa->dirty = 0;
89 }
90
91 /* Copy the back color buffer to the front color buffer.
92 */
93 void tridentCopyBuffer( const __DRIdrawablePrivate *dPriv )
94 {
95 unsigned char *MMIO;
96 tridentContextPtr tmesa;
97 GLint nbox, i;
98 int busy;
99 drm_clip_rect_t *pbox;
100
101 assert(dPriv);
102 assert(dPriv->driContextPriv);
103 assert(dPriv->driContextPriv->driverPrivate);
104
105 tmesa = (tridentContextPtr) dPriv->driContextPriv->driverPrivate;
106 MMIO = tmesa->tridentScreen->mmio.map;
107
108 LOCK_HARDWARE( tmesa );
109
110 /* use front buffer cliprects */
111 nbox = dPriv->numClipRects;
112 pbox = dPriv->pClipRects;
113
114 for ( i = 0 ; i < nbox ; i++ ) {
115 #if 0
116 GLint nr = MIN2( i + MACH64_NR_SAREA_CLIPRECTS , nbox );
117 drm_clip_rect_t *b = tmesa->sarea->boxes;
118 GLint n = 0;
119
120 for ( ; i < nr ; i++ ) {
121 *b++ = pbox[i];
122 n++;
123 }
124 tmesa->sarea->nbox = n;
125 #endif
126
127 MMIO_OUT32(MMIO, 0x2150, tmesa->tridentScreen->frontPitch << 20 | tmesa->tridentScreen->frontOffset>>4);
128 MMIO_OUT32(MMIO, 0x2154, tmesa->tridentScreen->backPitch << 20 | tmesa->tridentScreen->backOffset>>4);
129 MMIO_OUT8(MMIO, 0x2127, 0xCC); /* Copy Rop */
130 MMIO_OUT32(MMIO, 0x2128, 0x4); /* scr2scr */
131 MMIO_OUT32(MMIO, 0x2138, (pbox->x1 << 16) | pbox->y1);
132 MMIO_OUT32(MMIO, 0x213C, (pbox->x1 << 16) | pbox->y1);
133 MMIO_OUT32(MMIO, 0x2140, (pbox->x2 - pbox->x1) << 16 | (pbox->y2 - pbox->y1) );
134 MMIO_OUT8(MMIO, 0x2124, 0x01); /* BLT */
135 #define GE_BUSY 0x80
136 for (;;) {
137 busy = MMIO_IN8(MMIO, 0x2120);
138 if ( !(busy & GE_BUSY) )
139 break;
140 }
141 }
142
143 UNLOCK_HARDWARE( tmesa );
144
145 #if 0
146 tmesa->dirty |= (MACH64_UPLOAD_CONTEXT |
147 MACH64_UPLOAD_MISC |
148 MACH64_UPLOAD_CLIPRECTS);
149 #endif
150 }
151
152
153 static void tridentDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all,
154 GLint cx, GLint cy, GLint cw, GLint ch )
155 {
156 tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
157 unsigned char *MMIO = tmesa->tridentScreen->mmio.map;
158 int busy;
159 GLuint flags = 0;
160 GLint i;
161
162 #define DRM_TRIDENT_FRONT 0x01
163 #define DRM_TRIDENT_BACK 0x02
164 #define DRM_TRIDENT_DEPTH 0x04
165
166 if ( tmesa->new_state )
167 tridentDDUpdateHWState( ctx );
168
169 if ( mask & BUFFER_BIT_FRONT_LEFT ) {
170 flags |= DRM_TRIDENT_FRONT;
171 mask &= ~BUFFER_BIT_FRONT_LEFT;
172 }
173
174 if ( mask & BUFFER_BIT_BACK_LEFT ) {
175 flags |= DRM_TRIDENT_BACK;
176 mask &= ~BUFFER_BIT_BACK_LEFT;
177 }
178
179 if ( ( mask & BUFFER_BIT_DEPTH ) && ctx->Depth.Mask ) {
180 flags |= DRM_TRIDENT_DEPTH;
181 mask &= ~BUFFER_BIT_DEPTH;
182 }
183
184 LOCK_HARDWARE(tmesa);
185
186 if ( flags ) {
187
188 cx += tmesa->drawX;
189 cy += tmesa->drawY;
190
191 /* HACK!!!
192 */
193 if ( tmesa->dirty & ~TRIDENT_UPLOAD_CLIPRECTS ) {
194 tridentUploadHwStateLocked( tmesa );
195 }
196
197 for ( i = 0 ; i < tmesa->numClipRects ; i++ ) {
198 #if 0
199 int nr = MIN2( i + TRIDENT_NR_SAREA_CLIPRECTS, tmesa->numClipRects );
200 drm_clip_rect_t *box = tmesa->pClipRects;
201 drm_clip_rect_t *b = tmesa->sarea->boxes;
202 GLint n = 0;
203
204 if ( !all ) {
205 for ( ; i < nr ; i++ ) {
206 GLint x = box[i].x1;
207 GLint y = box[i].y1;
208 GLint w = box[i].x2 - x;
209 GLint h = box[i].y2 - y;
210
211 if ( x < cx ) w -= cx - x, x = cx;
212 if ( y < cy ) h -= cy - y, y = cy;
213 if ( x + w > cx + cw ) w = cx + cw - x;
214 if ( y + h > cy + ch ) h = cy + ch - y;
215 if ( w <= 0 ) continue;
216 if ( h <= 0 ) continue;
217
218 b->x1 = x;
219 b->y1 = y;
220 b->x2 = x + w;
221 b->y2 = y + h;
222 b++;
223 n++;
224 }
225 } else {
226 for ( ; i < nr ; i++ ) {
227 *b++ = box[i];
228 n++;
229 }
230 }
231
232 tmesa->sarea->nbox = n;
233 #endif
234
235 if (flags & DRM_TRIDENT_BACK) {
236 MMIO_OUT32(MMIO, 0x2150, tmesa->tridentScreen->backPitch << 20 | tmesa->tridentScreen->backOffset>>4);
237 MMIO_OUT8(MMIO, 0x2127, 0xF0); /* Pat Rop */
238 MMIO_OUT32(MMIO, 0x2158, tmesa->ClearColor);
239 MMIO_OUT32(MMIO, 0x2128, 0x4000); /* solidfill */
240 MMIO_OUT32(MMIO, 0x2138, cx << 16 | cy);
241 MMIO_OUT32(MMIO, 0x2140, cw << 16 | ch);
242 MMIO_OUT8(MMIO, 0x2124, 0x01); /* BLT */
243 #define GE_BUSY 0x80
244 for (;;) {
245 busy = MMIO_IN8(MMIO, 0x2120);
246 if ( !(busy & GE_BUSY) )
247 break;
248 }
249 }
250 if (flags & DRM_TRIDENT_DEPTH) {
251 MMIO_OUT32(MMIO, 0x2150, tmesa->tridentScreen->depthPitch << 20 | tmesa->tridentScreen->depthOffset>>4);
252 MMIO_OUT8(MMIO, 0x2127, 0xF0); /* Pat Rop */
253 MMIO_OUT32(MMIO, 0x2158, tmesa->ClearColor);
254 MMIO_OUT32(MMIO, 0x2128, 0x4000); /* solidfill */
255 MMIO_OUT32(MMIO, 0x2138, cx << 16 | cy);
256 MMIO_OUT32(MMIO, 0x2140, cw << 16 | ch);
257 MMIO_OUT8(MMIO, 0x2124, 0x01); /* BLT */
258 #define GE_BUSY 0x80
259 for (;;) {
260 busy = MMIO_IN8(MMIO, 0x2120);
261 if ( !(busy & GE_BUSY) )
262 break;
263 }
264 }
265 MMIO_OUT32(MMIO, 0x2150, tmesa->tridentScreen->frontPitch << 20 | tmesa->tridentScreen->frontOffset>>4);
266 if (flags & DRM_TRIDENT_FRONT) {
267 MMIO_OUT8(MMIO, 0x2127, 0xF0); /* Pat Rop */
268 MMIO_OUT32(MMIO, 0x2158, tmesa->ClearColor);
269 MMIO_OUT32(MMIO, 0x2128, 0x4000); /* solidfill */
270 MMIO_OUT32(MMIO, 0x2138, cx << 16 | cy);
271 MMIO_OUT32(MMIO, 0x2140, cw << 16 | ch);
272 MMIO_OUT8(MMIO, 0x2124, 0x01); /* BLT */
273 #define GE_BUSY 0x80
274 for (;;) {
275 busy = MMIO_IN8(MMIO, 0x2120);
276 if ( !(busy & GE_BUSY) )
277 break;
278 }
279 }
280
281 }
282
283 #if 0
284 tmesa->dirty |= (TRIDENT_UPLOAD_CONTEXT |
285 TRIDENT_UPLOAD_MISC |
286 TRIDENT_UPLOAD_CLIPRECTS);
287 #endif
288 }
289
290 UNLOCK_HARDWARE(tmesa);
291
292 if ( mask )
293 _swrast_Clear( ctx, mask, all, cx, cy, cw, ch );
294 }
295
296 static void tridentDDShadeModel( GLcontext *ctx, GLenum mode )
297 {
298 tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
299 GLuint s = tmesa->commandD;
300
301 #define TRIDENT_FLAT_SHADE 0x000000E0
302 #define TRIDENT_FLAT_SHADE_VERTEX_C 0x00000060
303 #define TRIDENT_FLAT_SHADE_GOURAUD 0x00000080
304
305 s &= ~TRIDENT_FLAT_SHADE;
306
307 switch ( mode ) {
308 case GL_FLAT:
309 s |= TRIDENT_FLAT_SHADE_VERTEX_C;
310 break;
311 case GL_SMOOTH:
312 s |= TRIDENT_FLAT_SHADE_GOURAUD;
313 break;
314 default:
315 return;
316 }
317
318 if ( tmesa->commandD != s ) {
319 tmesa->commandD = s;
320
321 tmesa->dirty |= TRIDENT_UPLOAD_COMMAND_D;
322 }
323 }
324
325 static void
326 tridentCalcViewport( GLcontext *ctx )
327 {
328 tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
329 const GLfloat *v = ctx->Viewport._WindowMap.m;
330 GLfloat *m = tmesa->hw_viewport;
331
332 /* See also trident_translate_vertex.
333 */
334 m[MAT_SX] = v[MAT_SX];
335 m[MAT_TX] = v[MAT_TX] + tmesa->drawX + SUBPIXEL_X;
336 m[MAT_SY] = - v[MAT_SY];
337 m[MAT_TY] = - v[MAT_TY] + tmesa->driDrawable->h + tmesa->drawY + SUBPIXEL_Y;
338 #if 0
339 m[MAT_SZ] = v[MAT_SZ] * tmesa->depth_scale;
340 m[MAT_TZ] = v[MAT_TZ] * tmesa->depth_scale;
341 #else
342 m[MAT_SZ] = v[MAT_SZ];
343 m[MAT_TZ] = v[MAT_TZ];
344 #endif
345
346 tmesa->SetupNewInputs = ~0;
347 }
348
349 static void tridentDDViewport( GLcontext *ctx,
350 GLint x, GLint y,
351 GLsizei width, GLsizei height )
352 {
353 tridentCalcViewport( ctx );
354 }
355
356 static void tridentDDDepthRange( GLcontext *ctx,
357 GLclampd nearval, GLclampd farval )
358 {
359 tridentCalcViewport( ctx );
360 }
361
362 static void
363 tridentSetCliprects( tridentContextPtr tmesa, GLenum mode )
364 {
365 __DRIdrawablePrivate *dPriv = tmesa->driDrawable;
366
367 switch ( mode ) {
368 case GL_FRONT_LEFT:
369 if (dPriv->numClipRects == 0) {
370 static drm_clip_rect_t zeroareacliprect = {0,0,0,0};
371 tmesa->numClipRects = 1;
372 tmesa->pClipRects = &zeroareacliprect;
373 } else {
374 tmesa->numClipRects = dPriv->numClipRects;
375 tmesa->pClipRects = (drm_clip_rect_t *)dPriv->pClipRects;
376 }
377 tmesa->drawX = dPriv->x;
378 tmesa->drawY = dPriv->y;
379 break;
380 case GL_BACK_LEFT:
381 if ( dPriv->numBackClipRects == 0 ) {
382 if (dPriv->numClipRects == 0) {
383 static drm_clip_rect_t zeroareacliprect = {0,0,0,0};
384 tmesa->numClipRects = 1;
385 tmesa->pClipRects = &zeroareacliprect;
386 } else {
387 tmesa->numClipRects = dPriv->numClipRects;
388 tmesa->pClipRects = (drm_clip_rect_t *)dPriv->pClipRects;
389 tmesa->drawX = dPriv->x;
390 tmesa->drawY = dPriv->y;
391 }
392 }
393 else {
394 tmesa->numClipRects = dPriv->numBackClipRects;
395 tmesa->pClipRects = (drm_clip_rect_t *)dPriv->pBackClipRects;
396 tmesa->drawX = dPriv->backX;
397 tmesa->drawY = dPriv->backY;
398 }
399 break;
400 default:
401 return;
402 }
403
404 #if 0
405 tmesa->dirty |= TRIDENT_UPLOAD_CLIPRECTS;
406 #endif
407 }
408
409 #if 0
410 static GLboolean tridentDDSetDrawBuffer( GLcontext *ctx, GLenum mode )
411 {
412 tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
413 int found = GL_TRUE;
414
415 if ( tmesa->DrawBuffer != mode ) {
416 tmesa->DrawBuffer = mode;
417
418 switch ( mode ) {
419 case GL_FRONT_LEFT:
420 tridentFallback( tmesa, TRIDENT_FALLBACK_DRAW_BUFFER, GL_FALSE );
421 tmesa->drawOffset = tmesa->tridentScreen->frontOffset;
422 tmesa->drawPitch = tmesa->tridentScreen->frontPitch;
423 tridentSetCliprects( tmesa, GL_FRONT_LEFT );
424 break;
425 case GL_BACK_LEFT:
426 tridentFallback( tmesa, TRIDENT_FALLBACK_DRAW_BUFFER, GL_FALSE );
427 tmesa->drawOffset = tmesa->tridentScreen->backOffset;
428 tmesa->drawPitch = tmesa->tridentScreen->backPitch;
429 tridentSetCliprects( tmesa, GL_BACK_LEFT );
430 break;
431 default:
432 tridentFallback( tmesa, TRIDENT_FALLBACK_DRAW_BUFFER, GL_TRUE );
433 found = GL_FALSE;
434 break;
435 }
436
437 #if 0
438 tmesa->setup.dst_off_pitch = (((tmesa->drawPitch/8) << 22) |
439 (tmesa->drawOffset >> 3));
440
441 tmesa->dirty |= MACH64_UPLOAD_DST_OFF_PITCH | MACH64_UPLOAD_CONTEXT;
442 #endif
443
444 }
445
446 return found;
447 }
448
449 static void tridentDDClearColor( GLcontext *ctx,
450 const GLchan color[4] )
451 {
452 tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
453
454 tmesa->ClearColor = tridentPackColor( tmesa->tridentScreen->cpp,
455 color[0], color[1],
456 color[2], color[3] );
457 }
458 #endif
459
460 static void
461 tridentDDUpdateState( GLcontext *ctx, GLuint new_state )
462 {
463 _swrast_InvalidateState( ctx, new_state );
464 _swsetup_InvalidateState( ctx, new_state );
465 _ac_InvalidateState( ctx, new_state );
466 _tnl_InvalidateState( ctx, new_state );
467 TRIDENT_CONTEXT(ctx)->new_gl_state |= new_state;
468 }
469
470
471 /* Initialize the context's hardware state.
472 */
473 void tridentDDInitState( tridentContextPtr tmesa )
474 {
475 tmesa->new_state = 0;
476
477 switch ( tmesa->glCtx->Visual.depthBits ) {
478 case 16:
479 tmesa->depth_scale = 1.0 / (GLfloat)0xffff;
480 break;
481 case 24:
482 tmesa->depth_scale = 1.0 / (GLfloat)0xffffff;
483 break;
484 }
485 }
486
487 void tridentDDUpdateHWState( GLcontext *ctx )
488 {
489 tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
490 int new_state = tmesa->new_state;
491
492 if ( new_state )
493 {
494 tmesa->new_state = 0;
495
496 #if 0
497 /* Update the various parts of the context's state.
498 */
499 if ( new_state & GAMMA_NEW_ALPHA )
500 tridentUpdateAlphaMode( ctx );
501
502 if ( new_state & GAMMA_NEW_DEPTH )
503 tridentUpdateZMode( ctx );
504
505 if ( new_state & GAMMA_NEW_FOG )
506 gammaUpdateFogAttrib( ctx );
507
508 if ( new_state & GAMMA_NEW_CLIP )
509 gammaUpdateClipping( ctx );
510
511 if ( new_state & GAMMA_NEW_POLYGON )
512 gammaUpdatePolygon( ctx );
513
514 if ( new_state & GAMMA_NEW_CULL )
515 gammaUpdateCull( ctx );
516
517 if ( new_state & GAMMA_NEW_MASKS )
518 gammaUpdateMasks( ctx );
519
520 if ( new_state & GAMMA_NEW_STIPPLE )
521 gammaUpdateStipple( ctx );
522 #endif
523 }
524
525 /* HACK ! */
526
527 #if 0
528 gammaEmitHwState( tmesa );
529 #endif
530 }
531
532 /* Initialize the driver's state functions.
533 */
534 void tridentDDInitStateFuncs( GLcontext *ctx )
535 {
536 ctx->Driver.UpdateState = tridentDDUpdateState;
537
538 ctx->Driver.Clear = tridentDDClear;
539 ctx->Driver.DepthRange = tridentDDDepthRange;
540 ctx->Driver.ShadeModel = tridentDDShadeModel;
541 ctx->Driver.Viewport = tridentDDViewport;
542
543 /* Pixel path fallbacks.
544 */
545 ctx->Driver.Accum = _swrast_Accum;
546 ctx->Driver.Bitmap = _swrast_Bitmap;
547 ctx->Driver.CopyPixels = _swrast_CopyPixels;
548 ctx->Driver.DrawPixels = _swrast_DrawPixels;
549 ctx->Driver.ReadPixels = _swrast_ReadPixels;
550
551 /* Swrast hooks for imaging extensions:
552 */
553 ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
554 ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
555 ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
556 ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
557 }