2 * Copyright 2002 by Alan Hourihane, Sychdyn, North Wales, UK.
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.
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.
22 * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
24 * Trident CyberBladeXP driver.
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"
34 #define TRIDENTPACKCOLOR332(r, g, b) \
35 (((r) & 0xe0) | (((g) & 0xe0) >> 3) | (((b) & 0xc0) >> 6))
37 #define TRIDENTPACKCOLOR1555(r, g, b, a) \
38 ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \
41 #define TRIDENTPACKCOLOR565(r, g, b) \
42 ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3))
44 #define TRIDENTPACKCOLOR888(r, g, b) \
45 (((r) << 16) | ((g) << 8) | (b))
47 #define TRIDENTPACKCOLOR8888(r, g, b, a) \
48 (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
50 #define TRIDENTPACKCOLOR4444(r, g, b, a) \
51 ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4))
53 static __inline__ GLuint
tridentPackColor( GLuint cpp
,
55 GLubyte b
, GLubyte a
)
59 return TRIDENTPACKCOLOR565( r
, g
, b
);
61 return TRIDENTPACKCOLOR8888( r
, g
, b
, a
);
67 void tridentUploadHwStateLocked( tridentContextPtr tmesa
)
69 unsigned char *MMIO
= tmesa
->tridentScreen
->mmio
.map
;
71 ATISAREAPrivPtr sarea
= tmesa
->sarea
;
72 trident_context_regs_t
*regs
= &(sarea
->ContextState
);
75 if ( tmesa
->dirty
& TRIDENT_UPLOAD_COMMAND_D
) {
76 MMIO_OUT32(MMIO
, 0x00281C, tmesa
->commandD
);
77 tmesa
->dirty
&= ~TRIDENT_UPLOAD_COMMAND_D
;
80 if ( tmesa
->dirty
& TRIDENT_UPLOAD_CLIPRECTS
) {
82 MMIO_OUT32(MMIO
, 0x002C80 , 0x20008000 | tmesa
->tridentScreen
->height
);
83 MMIO_OUT32(MMIO
, 0x002C84 , 0x20000000 | tmesa
->tridentScreen
->width
);
84 tmesa
->dirty
&= ~TRIDENT_UPLOAD_CLIPRECTS
;
90 /* Copy the back color buffer to the front color buffer.
92 void tridentCopyBuffer( const __DRIdrawablePrivate
*dPriv
)
95 tridentContextPtr tmesa
;
98 drm_clip_rect_t
*pbox
;
101 assert(dPriv
->driContextPriv
);
102 assert(dPriv
->driContextPriv
->driverPrivate
);
104 tmesa
= (tridentContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
105 MMIO
= tmesa
->tridentScreen
->mmio
.map
;
107 LOCK_HARDWARE( tmesa
);
109 /* use front buffer cliprects */
110 nbox
= dPriv
->numClipRects
;
111 pbox
= dPriv
->pClipRects
;
113 for ( i
= 0 ; i
< nbox
; i
++ ) {
115 GLint nr
= MIN2( i
+ MACH64_NR_SAREA_CLIPRECTS
, nbox
);
116 drm_clip_rect_t
*b
= tmesa
->sarea
->boxes
;
119 for ( ; i
< nr
; i
++ ) {
123 tmesa
->sarea
->nbox
= n
;
126 MMIO_OUT32(MMIO
, 0x2150, tmesa
->tridentScreen
->frontPitch
<< 20 | tmesa
->tridentScreen
->frontOffset
>>4);
127 MMIO_OUT32(MMIO
, 0x2154, tmesa
->tridentScreen
->backPitch
<< 20 | tmesa
->tridentScreen
->backOffset
>>4);
128 MMIO_OUT8(MMIO
, 0x2127, 0xCC); /* Copy Rop */
129 MMIO_OUT32(MMIO
, 0x2128, 0x4); /* scr2scr */
130 MMIO_OUT32(MMIO
, 0x2138, (pbox
->x1
<< 16) | pbox
->y1
);
131 MMIO_OUT32(MMIO
, 0x213C, (pbox
->x1
<< 16) | pbox
->y1
);
132 MMIO_OUT32(MMIO
, 0x2140, (pbox
->x2
- pbox
->x1
) << 16 | (pbox
->y2
- pbox
->y1
) );
133 MMIO_OUT8(MMIO
, 0x2124, 0x01); /* BLT */
136 busy
= MMIO_IN8(MMIO
, 0x2120);
137 if ( !(busy
& GE_BUSY
) )
142 UNLOCK_HARDWARE( tmesa
);
145 tmesa
->dirty
|= (MACH64_UPLOAD_CONTEXT
|
147 MACH64_UPLOAD_CLIPRECTS
);
152 static void tridentDDClear( GLcontext
*ctx
, GLbitfield mask
, GLboolean all
,
153 GLint cx
, GLint cy
, GLint cw
, GLint ch
)
155 tridentContextPtr tmesa
= TRIDENT_CONTEXT(ctx
);
156 unsigned char *MMIO
= tmesa
->tridentScreen
->mmio
.map
;
161 #define DRM_TRIDENT_FRONT 0x01
162 #define DRM_TRIDENT_BACK 0x02
163 #define DRM_TRIDENT_DEPTH 0x04
165 if ( tmesa
->new_state
)
166 tridentDDUpdateHWState( ctx
);
168 if ( mask
& DD_FRONT_LEFT_BIT
) {
169 flags
|= DRM_TRIDENT_FRONT
;
170 mask
&= ~DD_FRONT_LEFT_BIT
;
173 if ( mask
& DD_BACK_LEFT_BIT
) {
174 flags
|= DRM_TRIDENT_BACK
;
175 mask
&= ~DD_BACK_LEFT_BIT
;
178 if ( ( mask
& DD_DEPTH_BIT
) && ctx
->Depth
.Mask
) {
179 flags
|= DRM_TRIDENT_DEPTH
;
180 mask
&= ~DD_DEPTH_BIT
;
183 LOCK_HARDWARE(tmesa
);
192 if ( tmesa
->dirty
& ~TRIDENT_UPLOAD_CLIPRECTS
) {
193 tridentUploadHwStateLocked( tmesa
);
196 for ( i
= 0 ; i
< tmesa
->numClipRects
; i
++ ) {
198 int nr
= MIN2( i
+ TRIDENT_NR_SAREA_CLIPRECTS
, tmesa
->numClipRects
);
199 drm_clip_rect_t
*box
= tmesa
->pClipRects
;
200 drm_clip_rect_t
*b
= tmesa
->sarea
->boxes
;
204 for ( ; i
< nr
; i
++ ) {
207 GLint w
= box
[i
].x2
- x
;
208 GLint h
= box
[i
].y2
- y
;
210 if ( x
< cx
) w
-= cx
- x
, x
= cx
;
211 if ( y
< cy
) h
-= cy
- y
, y
= cy
;
212 if ( x
+ w
> cx
+ cw
) w
= cx
+ cw
- x
;
213 if ( y
+ h
> cy
+ ch
) h
= cy
+ ch
- y
;
214 if ( w
<= 0 ) continue;
215 if ( h
<= 0 ) continue;
225 for ( ; i
< nr
; i
++ ) {
231 tmesa
->sarea
->nbox
= n
;
234 if (flags
& DRM_TRIDENT_BACK
) {
235 MMIO_OUT32(MMIO
, 0x2150, tmesa
->tridentScreen
->backPitch
<< 20 | tmesa
->tridentScreen
->backOffset
>>4);
236 MMIO_OUT8(MMIO
, 0x2127, 0xF0); /* Pat Rop */
237 MMIO_OUT32(MMIO
, 0x2158, tmesa
->ClearColor
);
238 MMIO_OUT32(MMIO
, 0x2128, 0x4000); /* solidfill */
239 MMIO_OUT32(MMIO
, 0x2138, cx
<< 16 | cy
);
240 MMIO_OUT32(MMIO
, 0x2140, cw
<< 16 | ch
);
241 MMIO_OUT8(MMIO
, 0x2124, 0x01); /* BLT */
244 busy
= MMIO_IN8(MMIO
, 0x2120);
245 if ( !(busy
& GE_BUSY
) )
249 if (flags
& DRM_TRIDENT_DEPTH
) {
250 MMIO_OUT32(MMIO
, 0x2150, tmesa
->tridentScreen
->depthPitch
<< 20 | tmesa
->tridentScreen
->depthOffset
>>4);
251 MMIO_OUT8(MMIO
, 0x2127, 0xF0); /* Pat Rop */
252 MMIO_OUT32(MMIO
, 0x2158, tmesa
->ClearColor
);
253 MMIO_OUT32(MMIO
, 0x2128, 0x4000); /* solidfill */
254 MMIO_OUT32(MMIO
, 0x2138, cx
<< 16 | cy
);
255 MMIO_OUT32(MMIO
, 0x2140, cw
<< 16 | ch
);
256 MMIO_OUT8(MMIO
, 0x2124, 0x01); /* BLT */
259 busy
= MMIO_IN8(MMIO
, 0x2120);
260 if ( !(busy
& GE_BUSY
) )
264 MMIO_OUT32(MMIO
, 0x2150, tmesa
->tridentScreen
->frontPitch
<< 20 | tmesa
->tridentScreen
->frontOffset
>>4);
265 if (flags
& DRM_TRIDENT_FRONT
) {
266 MMIO_OUT8(MMIO
, 0x2127, 0xF0); /* Pat Rop */
267 MMIO_OUT32(MMIO
, 0x2158, tmesa
->ClearColor
);
268 MMIO_OUT32(MMIO
, 0x2128, 0x4000); /* solidfill */
269 MMIO_OUT32(MMIO
, 0x2138, cx
<< 16 | cy
);
270 MMIO_OUT32(MMIO
, 0x2140, cw
<< 16 | ch
);
271 MMIO_OUT8(MMIO
, 0x2124, 0x01); /* BLT */
274 busy
= MMIO_IN8(MMIO
, 0x2120);
275 if ( !(busy
& GE_BUSY
) )
283 tmesa
->dirty
|= (TRIDENT_UPLOAD_CONTEXT
|
284 TRIDENT_UPLOAD_MISC
|
285 TRIDENT_UPLOAD_CLIPRECTS
);
289 UNLOCK_HARDWARE(tmesa
);
292 _swrast_Clear( ctx
, mask
, all
, cx
, cy
, cw
, ch
);
295 static void tridentDDShadeModel( GLcontext
*ctx
, GLenum mode
)
297 tridentContextPtr tmesa
= TRIDENT_CONTEXT(ctx
);
298 GLuint s
= tmesa
->commandD
;
300 #define TRIDENT_FLAT_SHADE 0x000000E0
301 #define TRIDENT_FLAT_SHADE_VERTEX_C 0x00000060
302 #define TRIDENT_FLAT_SHADE_GOURAUD 0x00000080
304 s
&= ~TRIDENT_FLAT_SHADE
;
308 s
|= TRIDENT_FLAT_SHADE_VERTEX_C
;
311 s
|= TRIDENT_FLAT_SHADE_GOURAUD
;
317 if ( tmesa
->commandD
!= s
) {
320 tmesa
->dirty
|= TRIDENT_UPLOAD_COMMAND_D
;
324 void tridentCalcViewport( GLcontext
*ctx
)
326 tridentContextPtr tmesa
= TRIDENT_CONTEXT(ctx
);
327 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
328 GLfloat
*m
= tmesa
->hw_viewport
;
330 /* See also trident_translate_vertex.
332 m
[MAT_SX
] = v
[MAT_SX
];
333 m
[MAT_TX
] = v
[MAT_TX
] + tmesa
->drawX
+ SUBPIXEL_X
;
334 m
[MAT_SY
] = - v
[MAT_SY
];
335 m
[MAT_TY
] = - v
[MAT_TY
] + tmesa
->driDrawable
->h
+ tmesa
->drawY
+ SUBPIXEL_Y
;
337 m
[MAT_SZ
] = v
[MAT_SZ
] * tmesa
->depth_scale
;
338 m
[MAT_TZ
] = v
[MAT_TZ
] * tmesa
->depth_scale
;
340 m
[MAT_SZ
] = v
[MAT_SZ
];
341 m
[MAT_TZ
] = v
[MAT_TZ
];
344 tmesa
->SetupNewInputs
= ~0;
347 static void tridentDDViewport( GLcontext
*ctx
,
349 GLsizei width
, GLsizei height
)
351 tridentCalcViewport( ctx
);
354 static void tridentDDDepthRange( GLcontext
*ctx
,
355 GLclampd nearval
, GLclampd farval
)
357 tridentCalcViewport( ctx
);
360 void tridentSetCliprects( tridentContextPtr tmesa
, GLenum mode
)
362 __DRIdrawablePrivate
*dPriv
= tmesa
->driDrawable
;
366 if (dPriv
->numClipRects
== 0) {
367 static drm_clip_rect_t zeroareacliprect
= {0,0,0,0};
368 tmesa
->numClipRects
= 1;
369 tmesa
->pClipRects
= &zeroareacliprect
;
371 tmesa
->numClipRects
= dPriv
->numClipRects
;
372 tmesa
->pClipRects
= (drm_clip_rect_t
*)dPriv
->pClipRects
;
374 tmesa
->drawX
= dPriv
->x
;
375 tmesa
->drawY
= dPriv
->y
;
378 if ( dPriv
->numBackClipRects
== 0 ) {
379 if (dPriv
->numClipRects
== 0) {
380 static drm_clip_rect_t zeroareacliprect
= {0,0,0,0};
381 tmesa
->numClipRects
= 1;
382 tmesa
->pClipRects
= &zeroareacliprect
;
384 tmesa
->numClipRects
= dPriv
->numClipRects
;
385 tmesa
->pClipRects
= (drm_clip_rect_t
*)dPriv
->pClipRects
;
386 tmesa
->drawX
= dPriv
->x
;
387 tmesa
->drawY
= dPriv
->y
;
391 tmesa
->numClipRects
= dPriv
->numBackClipRects
;
392 tmesa
->pClipRects
= (drm_clip_rect_t
*)dPriv
->pBackClipRects
;
393 tmesa
->drawX
= dPriv
->backX
;
394 tmesa
->drawY
= dPriv
->backY
;
402 tmesa
->dirty
|= TRIDENT_UPLOAD_CLIPRECTS
;
407 static GLboolean
tridentDDSetDrawBuffer( GLcontext
*ctx
, GLenum mode
)
409 tridentContextPtr tmesa
= TRIDENT_CONTEXT(ctx
);
412 if ( tmesa
->DrawBuffer
!= mode
) {
413 tmesa
->DrawBuffer
= mode
;
417 tridentFallback( tmesa
, TRIDENT_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
418 tmesa
->drawOffset
= tmesa
->tridentScreen
->frontOffset
;
419 tmesa
->drawPitch
= tmesa
->tridentScreen
->frontPitch
;
420 tridentSetCliprects( tmesa
, GL_FRONT_LEFT
);
423 tridentFallback( tmesa
, TRIDENT_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
424 tmesa
->drawOffset
= tmesa
->tridentScreen
->backOffset
;
425 tmesa
->drawPitch
= tmesa
->tridentScreen
->backPitch
;
426 tridentSetCliprects( tmesa
, GL_BACK_LEFT
);
429 tridentFallback( tmesa
, TRIDENT_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
435 tmesa
->setup
.dst_off_pitch
= (((tmesa
->drawPitch
/8) << 22) |
436 (tmesa
->drawOffset
>> 3));
438 tmesa
->dirty
|= MACH64_UPLOAD_DST_OFF_PITCH
| MACH64_UPLOAD_CONTEXT
;
446 static void tridentDDClearColor( GLcontext
*ctx
,
447 const GLchan color
[4] )
449 tridentContextPtr tmesa
= TRIDENT_CONTEXT(ctx
);
451 tmesa
->ClearColor
= tridentPackColor( tmesa
->tridentScreen
->cpp
,
453 color
[2], color
[3] );
457 void tridentDDUpdateState( GLcontext
*ctx
, GLuint new_state
)
459 _swrast_InvalidateState( ctx
, new_state
);
460 _swsetup_InvalidateState( ctx
, new_state
);
461 _ac_InvalidateState( ctx
, new_state
);
462 _tnl_InvalidateState( ctx
, new_state
);
463 TRIDENT_CONTEXT(ctx
)->new_gl_state
|= new_state
;
467 /* Initialize the context's hardware state.
469 void tridentDDInitState( tridentContextPtr tmesa
)
471 tmesa
->new_state
= 0;
473 switch ( tmesa
->glCtx
->Visual
.depthBits
) {
475 tmesa
->depth_scale
= 1.0 / (GLfloat
)0xffff;
478 tmesa
->depth_scale
= 1.0 / (GLfloat
)0xffffff;
483 void tridentDDUpdateHWState( GLcontext
*ctx
)
485 tridentContextPtr tmesa
= TRIDENT_CONTEXT(ctx
);
486 int new_state
= tmesa
->new_state
;
490 tmesa
->new_state
= 0;
493 /* Update the various parts of the context's state.
495 if ( new_state
& GAMMA_NEW_ALPHA
)
496 tridentUpdateAlphaMode( ctx
);
498 if ( new_state
& GAMMA_NEW_DEPTH
)
499 tridentUpdateZMode( ctx
);
501 if ( new_state
& GAMMA_NEW_FOG
)
502 gammaUpdateFogAttrib( ctx
);
504 if ( new_state
& GAMMA_NEW_CLIP
)
505 gammaUpdateClipping( ctx
);
507 if ( new_state
& GAMMA_NEW_POLYGON
)
508 gammaUpdatePolygon( ctx
);
510 if ( new_state
& GAMMA_NEW_CULL
)
511 gammaUpdateCull( ctx
);
513 if ( new_state
& GAMMA_NEW_MASKS
)
514 gammaUpdateMasks( ctx
);
516 if ( new_state
& GAMMA_NEW_STIPPLE
)
517 gammaUpdateStipple( ctx
);
524 gammaEmitHwState( tmesa
);
528 /* Initialize the driver's state functions.
530 void tridentDDInitStateFuncs( GLcontext
*ctx
)
532 ctx
->Driver
.UpdateState
= tridentDDUpdateState
;
534 ctx
->Driver
.Clear
= tridentDDClear
;
535 ctx
->Driver
.DepthRange
= tridentDDDepthRange
;
536 ctx
->Driver
.ShadeModel
= tridentDDShadeModel
;
537 ctx
->Driver
.Viewport
= tridentDDViewport
;
539 /* Pixel path fallbacks.
541 ctx
->Driver
.Accum
= _swrast_Accum
;
542 ctx
->Driver
.Bitmap
= _swrast_Bitmap
;
543 ctx
->Driver
.CopyPixels
= _swrast_CopyPixels
;
544 ctx
->Driver
.DrawPixels
= _swrast_DrawPixels
;
545 ctx
->Driver
.ReadPixels
= _swrast_ReadPixels
;
546 ctx
->Driver
.ResizeBuffers
= _swrast_alloc_buffers
;
548 /* Swrast hooks for imaging extensions:
550 ctx
->Driver
.CopyColorTable
= _swrast_CopyColorTable
;
551 ctx
->Driver
.CopyColorSubTable
= _swrast_CopyColorSubTable
;
552 ctx
->Driver
.CopyConvolutionFilter1D
= _swrast_CopyConvolutionFilter1D
;
553 ctx
->Driver
.CopyConvolutionFilter2D
= _swrast_CopyConvolutionFilter2D
;