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"
33 #include "framebuffer.h"
35 #define TRIDENTPACKCOLOR332(r, g, b) \
36 (((r) & 0xe0) | (((g) & 0xe0) >> 3) | (((b) & 0xc0) >> 6))
38 #define TRIDENTPACKCOLOR1555(r, g, b, a) \
39 ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \
42 #define TRIDENTPACKCOLOR565(r, g, b) \
43 ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3))
45 #define TRIDENTPACKCOLOR888(r, g, b) \
46 (((r) << 16) | ((g) << 8) | (b))
48 #define TRIDENTPACKCOLOR8888(r, g, b, a) \
49 (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
51 #define TRIDENTPACKCOLOR4444(r, g, b, a) \
52 ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4))
54 static __inline__ GLuint
tridentPackColor( GLuint cpp
,
56 GLubyte b
, GLubyte a
)
60 return TRIDENTPACKCOLOR565( r
, g
, b
);
62 return TRIDENTPACKCOLOR8888( r
, g
, b
, a
);
68 void tridentUploadHwStateLocked( tridentContextPtr tmesa
)
70 unsigned char *MMIO
= tmesa
->tridentScreen
->mmio
.map
;
72 ATISAREAPrivPtr sarea
= tmesa
->sarea
;
73 trident_context_regs_t
*regs
= &(sarea
->ContextState
);
76 if ( tmesa
->dirty
& TRIDENT_UPLOAD_COMMAND_D
) {
77 MMIO_OUT32(MMIO
, 0x00281C, tmesa
->commandD
);
78 tmesa
->dirty
&= ~TRIDENT_UPLOAD_COMMAND_D
;
81 if ( tmesa
->dirty
& TRIDENT_UPLOAD_CLIPRECTS
) {
83 MMIO_OUT32(MMIO
, 0x002C80 , 0x20008000 | tmesa
->tridentScreen
->height
);
84 MMIO_OUT32(MMIO
, 0x002C84 , 0x20000000 | tmesa
->tridentScreen
->width
);
85 tmesa
->dirty
&= ~TRIDENT_UPLOAD_CLIPRECTS
;
91 /* Copy the back color buffer to the front color buffer.
93 void tridentCopyBuffer( const __DRIdrawablePrivate
*dPriv
)
96 tridentContextPtr tmesa
;
99 drm_clip_rect_t
*pbox
;
102 assert(dPriv
->driContextPriv
);
103 assert(dPriv
->driContextPriv
->driverPrivate
);
105 tmesa
= (tridentContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
106 MMIO
= tmesa
->tridentScreen
->mmio
.map
;
108 LOCK_HARDWARE( tmesa
);
110 /* use front buffer cliprects */
111 nbox
= dPriv
->numClipRects
;
112 pbox
= dPriv
->pClipRects
;
114 for ( i
= 0 ; i
< nbox
; i
++ ) {
116 GLint nr
= MIN2( i
+ MACH64_NR_SAREA_CLIPRECTS
, nbox
);
117 drm_clip_rect_t
*b
= tmesa
->sarea
->boxes
;
120 for ( ; i
< nr
; i
++ ) {
124 tmesa
->sarea
->nbox
= n
;
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 */
137 busy
= MMIO_IN8(MMIO
, 0x2120);
138 if ( !(busy
& GE_BUSY
) )
143 UNLOCK_HARDWARE( tmesa
);
146 tmesa
->dirty
|= (MACH64_UPLOAD_CONTEXT
|
148 MACH64_UPLOAD_CLIPRECTS
);
153 static void tridentDDClear( GLcontext
*ctx
, GLbitfield mask
, GLboolean all
,
154 GLint cx
, GLint cy
, GLint cw
, GLint ch
)
156 tridentContextPtr tmesa
= TRIDENT_CONTEXT(ctx
);
157 unsigned char *MMIO
= tmesa
->tridentScreen
->mmio
.map
;
162 #define DRM_TRIDENT_FRONT 0x01
163 #define DRM_TRIDENT_BACK 0x02
164 #define DRM_TRIDENT_DEPTH 0x04
166 if ( tmesa
->new_state
)
167 tridentDDUpdateHWState( ctx
);
169 if ( mask
& BUFFER_BIT_FRONT_LEFT
) {
170 flags
|= DRM_TRIDENT_FRONT
;
171 mask
&= ~BUFFER_BIT_FRONT_LEFT
;
174 if ( mask
& BUFFER_BIT_BACK_LEFT
) {
175 flags
|= DRM_TRIDENT_BACK
;
176 mask
&= ~BUFFER_BIT_BACK_LEFT
;
179 if ( ( mask
& BUFFER_BIT_DEPTH
) && ctx
->Depth
.Mask
) {
180 flags
|= DRM_TRIDENT_DEPTH
;
181 mask
&= ~BUFFER_BIT_DEPTH
;
184 LOCK_HARDWARE(tmesa
);
193 if ( tmesa
->dirty
& ~TRIDENT_UPLOAD_CLIPRECTS
) {
194 tridentUploadHwStateLocked( tmesa
);
197 for ( i
= 0 ; i
< tmesa
->numClipRects
; i
++ ) {
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
;
205 for ( ; i
< nr
; i
++ ) {
208 GLint w
= box
[i
].x2
- x
;
209 GLint h
= box
[i
].y2
- y
;
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;
226 for ( ; i
< nr
; i
++ ) {
232 tmesa
->sarea
->nbox
= n
;
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 */
245 busy
= MMIO_IN8(MMIO
, 0x2120);
246 if ( !(busy
& GE_BUSY
) )
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 */
260 busy
= MMIO_IN8(MMIO
, 0x2120);
261 if ( !(busy
& GE_BUSY
) )
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 */
275 busy
= MMIO_IN8(MMIO
, 0x2120);
276 if ( !(busy
& GE_BUSY
) )
284 tmesa
->dirty
|= (TRIDENT_UPLOAD_CONTEXT
|
285 TRIDENT_UPLOAD_MISC
|
286 TRIDENT_UPLOAD_CLIPRECTS
);
290 UNLOCK_HARDWARE(tmesa
);
293 _swrast_Clear( ctx
, mask
, all
, cx
, cy
, cw
, ch
);
296 static void tridentDDShadeModel( GLcontext
*ctx
, GLenum mode
)
298 tridentContextPtr tmesa
= TRIDENT_CONTEXT(ctx
);
299 GLuint s
= tmesa
->commandD
;
301 #define TRIDENT_FLAT_SHADE 0x000000E0
302 #define TRIDENT_FLAT_SHADE_VERTEX_C 0x00000060
303 #define TRIDENT_FLAT_SHADE_GOURAUD 0x00000080
305 s
&= ~TRIDENT_FLAT_SHADE
;
309 s
|= TRIDENT_FLAT_SHADE_VERTEX_C
;
312 s
|= TRIDENT_FLAT_SHADE_GOURAUD
;
318 if ( tmesa
->commandD
!= s
) {
321 tmesa
->dirty
|= TRIDENT_UPLOAD_COMMAND_D
;
326 tridentCalcViewport( GLcontext
*ctx
)
328 tridentContextPtr tmesa
= TRIDENT_CONTEXT(ctx
);
329 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
330 GLfloat
*m
= tmesa
->hw_viewport
;
332 /* See also trident_translate_vertex.
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
;
339 m
[MAT_SZ
] = v
[MAT_SZ
] * tmesa
->depth_scale
;
340 m
[MAT_TZ
] = v
[MAT_TZ
] * tmesa
->depth_scale
;
342 m
[MAT_SZ
] = v
[MAT_SZ
];
343 m
[MAT_TZ
] = v
[MAT_TZ
];
346 tmesa
->SetupNewInputs
= ~0;
349 static void tridentDDViewport( GLcontext
*ctx
,
351 GLsizei width
, GLsizei height
)
353 tridentCalcViewport( ctx
);
356 static void tridentDDDepthRange( GLcontext
*ctx
,
357 GLclampd nearval
, GLclampd farval
)
359 tridentCalcViewport( ctx
);
363 tridentSetCliprects( tridentContextPtr tmesa
, GLenum mode
)
365 __DRIdrawablePrivate
*dPriv
= tmesa
->driDrawable
;
369 if (dPriv
->numClipRects
== 0) {
370 static drm_clip_rect_t zeroareacliprect
= {0,0,0,0};
371 tmesa
->numClipRects
= 1;
372 tmesa
->pClipRects
= &zeroareacliprect
;
374 tmesa
->numClipRects
= dPriv
->numClipRects
;
375 tmesa
->pClipRects
= (drm_clip_rect_t
*)dPriv
->pClipRects
;
377 tmesa
->drawX
= dPriv
->x
;
378 tmesa
->drawY
= dPriv
->y
;
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
;
387 tmesa
->numClipRects
= dPriv
->numClipRects
;
388 tmesa
->pClipRects
= (drm_clip_rect_t
*)dPriv
->pClipRects
;
389 tmesa
->drawX
= dPriv
->x
;
390 tmesa
->drawY
= dPriv
->y
;
394 tmesa
->numClipRects
= dPriv
->numBackClipRects
;
395 tmesa
->pClipRects
= (drm_clip_rect_t
*)dPriv
->pBackClipRects
;
396 tmesa
->drawX
= dPriv
->backX
;
397 tmesa
->drawY
= dPriv
->backY
;
405 tmesa
->dirty
|= TRIDENT_UPLOAD_CLIPRECTS
;
410 static GLboolean
tridentDDSetDrawBuffer( GLcontext
*ctx
, GLenum mode
)
412 tridentContextPtr tmesa
= TRIDENT_CONTEXT(ctx
);
415 if ( tmesa
->DrawBuffer
!= mode
) {
416 tmesa
->DrawBuffer
= mode
;
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
);
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
);
432 tridentFallback( tmesa
, TRIDENT_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
438 tmesa
->setup
.dst_off_pitch
= (((tmesa
->drawPitch
/8) << 22) |
439 (tmesa
->drawOffset
>> 3));
441 tmesa
->dirty
|= MACH64_UPLOAD_DST_OFF_PITCH
| MACH64_UPLOAD_CONTEXT
;
449 static void tridentDDClearColor( GLcontext
*ctx
,
450 const GLchan color
[4] )
452 tridentContextPtr tmesa
= TRIDENT_CONTEXT(ctx
);
454 tmesa
->ClearColor
= tridentPackColor( tmesa
->tridentScreen
->cpp
,
456 color
[2], color
[3] );
461 tridentDDUpdateState( GLcontext
*ctx
, GLuint new_state
)
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
;
471 /* Initialize the context's hardware state.
473 void tridentDDInitState( tridentContextPtr tmesa
)
475 tmesa
->new_state
= 0;
477 switch ( tmesa
->glCtx
->Visual
.depthBits
) {
479 tmesa
->depth_scale
= 1.0 / (GLfloat
)0xffff;
482 tmesa
->depth_scale
= 1.0 / (GLfloat
)0xffffff;
487 void tridentDDUpdateHWState( GLcontext
*ctx
)
489 tridentContextPtr tmesa
= TRIDENT_CONTEXT(ctx
);
490 int new_state
= tmesa
->new_state
;
494 tmesa
->new_state
= 0;
497 /* Update the various parts of the context's state.
499 if ( new_state
& GAMMA_NEW_ALPHA
)
500 tridentUpdateAlphaMode( ctx
);
502 if ( new_state
& GAMMA_NEW_DEPTH
)
503 tridentUpdateZMode( ctx
);
505 if ( new_state
& GAMMA_NEW_FOG
)
506 gammaUpdateFogAttrib( ctx
);
508 if ( new_state
& GAMMA_NEW_CLIP
)
509 gammaUpdateClipping( ctx
);
511 if ( new_state
& GAMMA_NEW_POLYGON
)
512 gammaUpdatePolygon( ctx
);
514 if ( new_state
& GAMMA_NEW_CULL
)
515 gammaUpdateCull( ctx
);
517 if ( new_state
& GAMMA_NEW_MASKS
)
518 gammaUpdateMasks( ctx
);
520 if ( new_state
& GAMMA_NEW_STIPPLE
)
521 gammaUpdateStipple( ctx
);
528 gammaEmitHwState( tmesa
);
532 /* Initialize the driver's state functions.
534 void tridentDDInitStateFuncs( GLcontext
*ctx
)
536 ctx
->Driver
.UpdateState
= tridentDDUpdateState
;
538 ctx
->Driver
.Clear
= tridentDDClear
;
539 ctx
->Driver
.DepthRange
= tridentDDDepthRange
;
540 ctx
->Driver
.ShadeModel
= tridentDDShadeModel
;
541 ctx
->Driver
.Viewport
= tridentDDViewport
;
543 /* Pixel path fallbacks.
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 ctx
->Driver
.ResizeBuffers
= _mesa_resize_framebuffer
;
552 /* Swrast hooks for imaging extensions:
554 ctx
->Driver
.CopyColorTable
= _swrast_CopyColorTable
;
555 ctx
->Driver
.CopyColorSubTable
= _swrast_CopyColorSubTable
;
556 ctx
->Driver
.CopyConvolutionFilter1D
= _swrast_CopyConvolutionFilter1D
;
557 ctx
->Driver
.CopyConvolutionFilter2D
= _swrast_CopyConvolutionFilter2D
;