1 /* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_state.c,v 1.8 2002/12/16 16:18:58 dawes Exp $ */
2 /**************************************************************************
4 Copyright 2000, 2001 VA Linux Systems Inc., Fremont, California.
8 Permission is hereby granted, free of charge, to any person obtaining
9 a copy of this software and associated documentation files (the
10 "Software"), to deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify, merge, publish,
12 distribute, sublicense, and/or sell copies of the Software, and to
13 permit persons to whom the Software is furnished to do so, subject to
14 the following conditions:
16 The above copyright notice and this permission notice (including the
17 next paragraph) shall be included in all copies or substantial
18 portions of the Software.
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
24 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 **************************************************************************/
32 * Gareth Hughes <gareth@valinux.com>
33 * Keith Whitwell <keith@tungstengraphics.com>
38 #include "api_arrayelt.h"
44 #include "array_cache/acache.h"
46 #include "tnl/t_pipeline.h"
47 #include "swrast_setup/swrast_setup.h"
49 #include "radeon_context.h"
50 #include "radeon_ioctl.h"
51 #include "radeon_state.h"
52 #include "radeon_tcl.h"
53 #include "radeon_tex.h"
54 #include "radeon_swtcl.h"
55 #include "radeon_vtxfmt.h"
56 #include "drirenderbuffer.h"
58 static void radeonUpdateSpecular( GLcontext
*ctx
);
60 /* =============================================================
64 static void radeonAlphaFunc( GLcontext
*ctx
, GLenum func
, GLfloat ref
)
66 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
67 int pp_misc
= rmesa
->hw
.ctx
.cmd
[CTX_PP_MISC
];
70 CLAMPED_FLOAT_TO_UBYTE(refByte
, ref
);
72 RADEON_STATECHANGE( rmesa
, ctx
);
74 pp_misc
&= ~(RADEON_ALPHA_TEST_OP_MASK
| RADEON_REF_ALPHA_MASK
);
75 pp_misc
|= (refByte
& RADEON_REF_ALPHA_MASK
);
79 pp_misc
|= RADEON_ALPHA_TEST_FAIL
;
82 pp_misc
|= RADEON_ALPHA_TEST_LESS
;
85 pp_misc
|= RADEON_ALPHA_TEST_EQUAL
;
88 pp_misc
|= RADEON_ALPHA_TEST_LEQUAL
;
91 pp_misc
|= RADEON_ALPHA_TEST_GREATER
;
94 pp_misc
|= RADEON_ALPHA_TEST_NEQUAL
;
97 pp_misc
|= RADEON_ALPHA_TEST_GEQUAL
;
100 pp_misc
|= RADEON_ALPHA_TEST_PASS
;
104 rmesa
->hw
.ctx
.cmd
[CTX_PP_MISC
] = pp_misc
;
107 static void radeonBlendEquationSeparate( GLcontext
*ctx
,
108 GLenum modeRGB
, GLenum modeA
)
110 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
111 GLuint b
= rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] & ~RADEON_COMB_FCN_MASK
;
112 GLboolean fallback
= GL_FALSE
;
114 assert( modeRGB
== modeA
);
119 b
|= RADEON_COMB_FCN_ADD_CLAMP
;
122 case GL_FUNC_SUBTRACT
:
123 b
|= RADEON_COMB_FCN_SUB_CLAMP
;
127 if (ctx
->Color
.BlendEnabled
)
130 b
|= RADEON_COMB_FCN_ADD_CLAMP
;
134 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_EQ
, fallback
);
136 RADEON_STATECHANGE( rmesa
, ctx
);
137 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = b
;
138 if ( ctx
->Color
._LogicOpEnabled
) {
139 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
141 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
146 static void radeonBlendFuncSeparate( GLcontext
*ctx
,
147 GLenum sfactorRGB
, GLenum dfactorRGB
,
148 GLenum sfactorA
, GLenum dfactorA
)
150 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
151 GLuint b
= rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] &
152 ~(RADEON_SRC_BLEND_MASK
| RADEON_DST_BLEND_MASK
);
153 GLboolean fallback
= GL_FALSE
;
155 switch ( ctx
->Color
.BlendSrcRGB
) {
157 b
|= RADEON_SRC_BLEND_GL_ZERO
;
160 b
|= RADEON_SRC_BLEND_GL_ONE
;
163 b
|= RADEON_SRC_BLEND_GL_DST_COLOR
;
165 case GL_ONE_MINUS_DST_COLOR
:
166 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_COLOR
;
169 b
|= RADEON_SRC_BLEND_GL_SRC_COLOR
;
171 case GL_ONE_MINUS_SRC_COLOR
:
172 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR
;
175 b
|= RADEON_SRC_BLEND_GL_SRC_ALPHA
;
177 case GL_ONE_MINUS_SRC_ALPHA
:
178 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
181 b
|= RADEON_SRC_BLEND_GL_DST_ALPHA
;
183 case GL_ONE_MINUS_DST_ALPHA
:
184 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA
;
186 case GL_SRC_ALPHA_SATURATE
:
187 b
|= RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE
;
189 case GL_CONSTANT_COLOR
:
190 case GL_ONE_MINUS_CONSTANT_COLOR
:
191 case GL_CONSTANT_ALPHA
:
192 case GL_ONE_MINUS_CONSTANT_ALPHA
:
193 if (ctx
->Color
.BlendEnabled
)
196 b
|= RADEON_SRC_BLEND_GL_ONE
;
202 switch ( ctx
->Color
.BlendDstRGB
) {
204 b
|= RADEON_DST_BLEND_GL_ZERO
;
207 b
|= RADEON_DST_BLEND_GL_ONE
;
210 b
|= RADEON_DST_BLEND_GL_SRC_COLOR
;
212 case GL_ONE_MINUS_SRC_COLOR
:
213 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_COLOR
;
216 b
|= RADEON_DST_BLEND_GL_SRC_ALPHA
;
218 case GL_ONE_MINUS_SRC_ALPHA
:
219 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
222 b
|= RADEON_DST_BLEND_GL_DST_COLOR
;
224 case GL_ONE_MINUS_DST_COLOR
:
225 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_DST_COLOR
;
228 b
|= RADEON_DST_BLEND_GL_DST_ALPHA
;
230 case GL_ONE_MINUS_DST_ALPHA
:
231 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_DST_ALPHA
;
233 case GL_CONSTANT_COLOR
:
234 case GL_ONE_MINUS_CONSTANT_COLOR
:
235 case GL_CONSTANT_ALPHA
:
236 case GL_ONE_MINUS_CONSTANT_ALPHA
:
237 if (ctx
->Color
.BlendEnabled
)
240 b
|= RADEON_DST_BLEND_GL_ZERO
;
246 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_FUNC
, fallback
);
248 RADEON_STATECHANGE( rmesa
, ctx
);
249 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = b
;
254 /* =============================================================
258 static void radeonDepthFunc( GLcontext
*ctx
, GLenum func
)
260 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
262 RADEON_STATECHANGE( rmesa
, ctx
);
263 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_Z_TEST_MASK
;
265 switch ( ctx
->Depth
.Func
) {
267 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_NEVER
;
270 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_LESS
;
273 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_EQUAL
;
276 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_LEQUAL
;
279 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_GREATER
;
282 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_NEQUAL
;
285 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_GEQUAL
;
288 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_ALWAYS
;
294 static void radeonDepthMask( GLcontext
*ctx
, GLboolean flag
)
296 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
297 RADEON_STATECHANGE( rmesa
, ctx
);
299 if ( ctx
->Depth
.Mask
) {
300 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_WRITE_ENABLE
;
302 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_Z_WRITE_ENABLE
;
306 static void radeonClearDepth( GLcontext
*ctx
, GLclampd d
)
308 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
309 GLuint format
= (rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &
310 RADEON_DEPTH_FORMAT_MASK
);
313 case RADEON_DEPTH_FORMAT_16BIT_INT_Z
:
314 rmesa
->state
.depth
.clear
= d
* 0x0000ffff;
316 case RADEON_DEPTH_FORMAT_24BIT_INT_Z
:
317 rmesa
->state
.depth
.clear
= d
* 0x00ffffff;
323 /* =============================================================
328 static void radeonFogfv( GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
330 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
331 union { int i
; float f
; } c
, d
;
336 if (!ctx
->Fog
.Enabled
)
338 RADEON_STATECHANGE(rmesa
, tcl
);
339 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_TCL_FOG_MASK
;
340 switch (ctx
->Fog
.Mode
) {
342 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_LINEAR
;
345 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_EXP
;
348 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_EXP2
;
357 if (!ctx
->Fog
.Enabled
)
359 c
.i
= rmesa
->hw
.fog
.cmd
[FOG_C
];
360 d
.i
= rmesa
->hw
.fog
.cmd
[FOG_D
];
361 switch (ctx
->Fog
.Mode
) {
364 /* While this is the opposite sign from the DDK, it makes the fog test
365 * pass, and matches r200.
367 d
.f
= -ctx
->Fog
.Density
;
371 d
.f
= -(ctx
->Fog
.Density
* ctx
->Fog
.Density
);
374 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
378 c
.f
= ctx
->Fog
.End
/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
379 /* While this is the opposite sign from the DDK, it makes the fog
380 * test pass, and matches r200.
382 d
.f
= -1.0/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
388 if (c
.i
!= rmesa
->hw
.fog
.cmd
[FOG_C
] || d
.i
!= rmesa
->hw
.fog
.cmd
[FOG_D
]) {
389 RADEON_STATECHANGE( rmesa
, fog
);
390 rmesa
->hw
.fog
.cmd
[FOG_C
] = c
.i
;
391 rmesa
->hw
.fog
.cmd
[FOG_D
] = d
.i
;
395 RADEON_STATECHANGE( rmesa
, ctx
);
396 UNCLAMPED_FLOAT_TO_RGB_CHAN( col
, ctx
->Fog
.Color
);
397 rmesa
->hw
.ctx
.cmd
[CTX_PP_FOG_COLOR
] &= ~RADEON_FOG_COLOR_MASK
;
398 rmesa
->hw
.ctx
.cmd
[CTX_PP_FOG_COLOR
] |=
399 radeonPackColor( 4, col
[0], col
[1], col
[2], 0 );
401 case GL_FOG_COORD_SRC
:
402 radeonUpdateSpecular( ctx
);
410 /* =============================================================
415 static GLboolean
intersect_rect( drm_clip_rect_t
*out
,
420 if ( b
->x1
> out
->x1
) out
->x1
= b
->x1
;
421 if ( b
->y1
> out
->y1
) out
->y1
= b
->y1
;
422 if ( b
->x2
< out
->x2
) out
->x2
= b
->x2
;
423 if ( b
->y2
< out
->y2
) out
->y2
= b
->y2
;
424 if ( out
->x1
>= out
->x2
) return GL_FALSE
;
425 if ( out
->y1
>= out
->y2
) return GL_FALSE
;
430 void radeonRecalcScissorRects( radeonContextPtr rmesa
)
432 drm_clip_rect_t
*out
;
435 /* Grow cliprect store?
437 if (rmesa
->state
.scissor
.numAllocedClipRects
< rmesa
->numClipRects
) {
438 while (rmesa
->state
.scissor
.numAllocedClipRects
< rmesa
->numClipRects
) {
439 rmesa
->state
.scissor
.numAllocedClipRects
+= 1; /* zero case */
440 rmesa
->state
.scissor
.numAllocedClipRects
*= 2;
443 if (rmesa
->state
.scissor
.pClipRects
)
444 FREE(rmesa
->state
.scissor
.pClipRects
);
446 rmesa
->state
.scissor
.pClipRects
=
447 MALLOC( rmesa
->state
.scissor
.numAllocedClipRects
*
448 sizeof(drm_clip_rect_t
) );
450 if ( rmesa
->state
.scissor
.pClipRects
== NULL
) {
451 rmesa
->state
.scissor
.numAllocedClipRects
= 0;
456 out
= rmesa
->state
.scissor
.pClipRects
;
457 rmesa
->state
.scissor
.numClipRects
= 0;
459 for ( i
= 0 ; i
< rmesa
->numClipRects
; i
++ ) {
460 if ( intersect_rect( out
,
461 &rmesa
->pClipRects
[i
],
462 &rmesa
->state
.scissor
.rect
) ) {
463 rmesa
->state
.scissor
.numClipRects
++;
470 static void radeonUpdateScissor( GLcontext
*ctx
)
472 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
474 if ( rmesa
->dri
.drawable
) {
475 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
477 int x
= ctx
->Scissor
.X
;
478 int y
= dPriv
->h
- ctx
->Scissor
.Y
- ctx
->Scissor
.Height
;
479 int w
= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
- 1;
480 int h
= dPriv
->h
- ctx
->Scissor
.Y
- 1;
482 rmesa
->state
.scissor
.rect
.x1
= x
+ dPriv
->x
;
483 rmesa
->state
.scissor
.rect
.y1
= y
+ dPriv
->y
;
484 rmesa
->state
.scissor
.rect
.x2
= w
+ dPriv
->x
+ 1;
485 rmesa
->state
.scissor
.rect
.y2
= h
+ dPriv
->y
+ 1;
487 radeonRecalcScissorRects( rmesa
);
492 static void radeonScissor( GLcontext
*ctx
,
493 GLint x
, GLint y
, GLsizei w
, GLsizei h
)
495 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
497 if ( ctx
->Scissor
.Enabled
) {
498 RADEON_FIREVERTICES( rmesa
); /* don't pipeline cliprect changes */
499 radeonUpdateScissor( ctx
);
505 /* =============================================================
509 static void radeonCullFace( GLcontext
*ctx
, GLenum unused
)
511 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
512 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
513 GLuint t
= rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
];
515 s
|= RADEON_FFACE_SOLID
| RADEON_BFACE_SOLID
;
516 t
&= ~(RADEON_CULL_FRONT
| RADEON_CULL_BACK
);
518 if ( ctx
->Polygon
.CullFlag
) {
519 switch ( ctx
->Polygon
.CullFaceMode
) {
521 s
&= ~RADEON_FFACE_SOLID
;
522 t
|= RADEON_CULL_FRONT
;
525 s
&= ~RADEON_BFACE_SOLID
;
526 t
|= RADEON_CULL_BACK
;
528 case GL_FRONT_AND_BACK
:
529 s
&= ~(RADEON_FFACE_SOLID
| RADEON_BFACE_SOLID
);
530 t
|= (RADEON_CULL_FRONT
| RADEON_CULL_BACK
);
535 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
536 RADEON_STATECHANGE(rmesa
, set
);
537 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
540 if ( rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] != t
) {
541 RADEON_STATECHANGE(rmesa
, tcl
);
542 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] = t
;
546 static void radeonFrontFace( GLcontext
*ctx
, GLenum mode
)
548 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
550 RADEON_STATECHANGE( rmesa
, set
);
551 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_FFACE_CULL_DIR_MASK
;
553 RADEON_STATECHANGE( rmesa
, tcl
);
554 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_CULL_FRONT_IS_CCW
;
558 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_FFACE_CULL_CW
;
561 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_FFACE_CULL_CCW
;
562 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_CULL_FRONT_IS_CCW
;
568 /* =============================================================
571 static void radeonLineWidth( GLcontext
*ctx
, GLfloat widthf
)
573 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
575 RADEON_STATECHANGE( rmesa
, lin
);
576 RADEON_STATECHANGE( rmesa
, set
);
578 /* Line width is stored in U6.4 format.
580 rmesa
->hw
.lin
.cmd
[LIN_SE_LINE_WIDTH
] = (GLuint
)(widthf
* 16.0);
581 if ( widthf
> 1.0 ) {
582 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_WIDELINE_ENABLE
;
584 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_WIDELINE_ENABLE
;
588 static void radeonLineStipple( GLcontext
*ctx
, GLint factor
, GLushort pattern
)
590 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
592 RADEON_STATECHANGE( rmesa
, lin
);
593 rmesa
->hw
.lin
.cmd
[LIN_RE_LINE_PATTERN
] =
594 ((((GLuint
)factor
& 0xff) << 16) | ((GLuint
)pattern
));
598 /* =============================================================
601 static void radeonColorMask( GLcontext
*ctx
,
602 GLboolean r
, GLboolean g
,
603 GLboolean b
, GLboolean a
)
605 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
606 GLuint mask
= radeonPackColor( rmesa
->radeonScreen
->cpp
,
607 ctx
->Color
.ColorMask
[RCOMP
],
608 ctx
->Color
.ColorMask
[GCOMP
],
609 ctx
->Color
.ColorMask
[BCOMP
],
610 ctx
->Color
.ColorMask
[ACOMP
] );
612 if ( rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] != mask
) {
613 RADEON_STATECHANGE( rmesa
, msk
);
614 rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] = mask
;
619 /* =============================================================
623 static void radeonPolygonOffset( GLcontext
*ctx
,
624 GLfloat factor
, GLfloat units
)
626 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
627 GLfloat constant
= units
* rmesa
->state
.depth
.scale
;
629 RADEON_STATECHANGE( rmesa
, zbs
);
630 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_FACTOR
] = *(GLuint
*)&factor
;
631 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_CONSTANT
] = *(GLuint
*)&constant
;
634 static void radeonPolygonStipple( GLcontext
*ctx
, const GLubyte
*mask
)
636 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
638 drm_radeon_stipple_t stipple
;
640 /* Must flip pattern upside down.
642 for ( i
= 0 ; i
< 32 ; i
++ ) {
643 rmesa
->state
.stipple
.mask
[31 - i
] = ((GLuint
*) mask
)[i
];
646 /* TODO: push this into cmd mechanism
648 RADEON_FIREVERTICES( rmesa
);
649 LOCK_HARDWARE( rmesa
);
651 /* FIXME: Use window x,y offsets into stipple RAM.
653 stipple
.mask
= rmesa
->state
.stipple
.mask
;
654 drmCommandWrite( rmesa
->dri
.fd
, DRM_RADEON_STIPPLE
,
655 &stipple
, sizeof(drm_radeon_stipple_t
) );
656 UNLOCK_HARDWARE( rmesa
);
659 static void radeonPolygonMode( GLcontext
*ctx
, GLenum face
, GLenum mode
)
661 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
662 GLboolean flag
= (ctx
->_TriangleCaps
& DD_TRI_UNFILLED
) != 0;
664 /* Can't generally do unfilled via tcl, but some good special
667 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_UNFILLED
, flag
);
668 if (rmesa
->TclFallback
) {
669 radeonChooseRenderState( ctx
);
670 radeonChooseVertexState( ctx
);
675 /* =============================================================
676 * Rendering attributes
678 * We really don't want to recalculate all this every time we bind a
679 * texture. These things shouldn't change all that often, so it makes
680 * sense to break them out of the core texture state update routines.
683 /* Examine lighting and texture state to determine if separate specular
686 static void radeonUpdateSpecular( GLcontext
*ctx
)
688 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
689 u_int32_t p
= rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
];
692 RADEON_STATECHANGE( rmesa
, tcl
);
694 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &= ~RADEON_TCL_COMPUTE_SPECULAR
;
695 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &= ~RADEON_TCL_COMPUTE_DIFFUSE
;
696 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &= ~RADEON_TCL_VTX_PK_SPEC
;
697 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &= ~RADEON_TCL_VTX_PK_DIFFUSE
;
698 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_LIGHTING_ENABLE
;
700 p
&= ~RADEON_SPECULAR_ENABLE
;
702 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_DIFFUSE_SPECULAR_COMBINE
;
705 if (ctx
->Light
.Enabled
&&
706 ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
) {
707 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_SPECULAR
;
708 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_DIFFUSE
;
709 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
710 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
711 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
712 p
|= RADEON_SPECULAR_ENABLE
;
713 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &=
714 ~RADEON_DIFFUSE_SPECULAR_COMBINE
;
716 else if (ctx
->Light
.Enabled
) {
717 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_DIFFUSE
;
718 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
719 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
720 } else if (ctx
->Fog
.ColorSumEnabled
) {
721 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
722 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
723 p
|= RADEON_SPECULAR_ENABLE
;
725 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
728 if (ctx
->Fog
.Enabled
) {
729 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
730 if (ctx
->Fog
.FogCoordinateSource
== GL_FRAGMENT_DEPTH
) {
731 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_SPECULAR
;
732 /* Bizzare: have to leave lighting enabled to get fog. */
733 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
736 /* cannot do tcl fog factor calculation with fog coord source
737 * (send precomputed factors). Cannot use precomputed fog
738 * factors together with tcl spec light (need tcl fallback) */
739 flag
= (rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &
740 RADEON_TCL_COMPUTE_SPECULAR
) != 0;
744 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_FOGCOORDSPEC
, flag
);
746 if (NEED_SECONDARY_COLOR(ctx
)) {
747 assert( (p
& RADEON_SPECULAR_ENABLE
) != 0 );
749 assert( (p
& RADEON_SPECULAR_ENABLE
) == 0 );
752 if ( rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] != p
) {
753 RADEON_STATECHANGE( rmesa
, ctx
);
754 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] = p
;
757 /* Update vertex/render formats
759 if (rmesa
->TclFallback
) {
760 radeonChooseRenderState( ctx
);
761 radeonChooseVertexState( ctx
);
766 /* =============================================================
771 /* Update on colormaterial, material emmissive/ambient,
772 * lightmodel.globalambient
774 static void update_global_ambient( GLcontext
*ctx
)
776 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
777 float *fcmd
= (float *)RADEON_DB_STATE( glt
);
779 /* Need to do more if both emmissive & ambient are PREMULT:
780 * Hope this is not needed for MULT
782 if ((rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &
783 ((3 << RADEON_EMISSIVE_SOURCE_SHIFT
) |
784 (3 << RADEON_AMBIENT_SOURCE_SHIFT
))) == 0)
786 COPY_3V( &fcmd
[GLT_RED
],
787 ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_EMISSION
]);
788 ACC_SCALE_3V( &fcmd
[GLT_RED
],
789 ctx
->Light
.Model
.Ambient
,
790 ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_AMBIENT
]);
794 COPY_3V( &fcmd
[GLT_RED
], ctx
->Light
.Model
.Ambient
);
797 RADEON_DB_STATECHANGE(rmesa
, &rmesa
->hw
.glt
);
800 /* Update on change to
804 static void update_light_colors( GLcontext
*ctx
, GLuint p
)
806 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
808 /* fprintf(stderr, "%s\n", __FUNCTION__); */
811 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
812 float *fcmd
= (float *)RADEON_DB_STATE( lit
[p
] );
814 COPY_4V( &fcmd
[LIT_AMBIENT_RED
], l
->Ambient
);
815 COPY_4V( &fcmd
[LIT_DIFFUSE_RED
], l
->Diffuse
);
816 COPY_4V( &fcmd
[LIT_SPECULAR_RED
], l
->Specular
);
818 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
822 /* Also fallback for asym colormaterial mode in twoside lighting...
824 static void check_twoside_fallback( GLcontext
*ctx
)
826 GLboolean fallback
= GL_FALSE
;
829 if (ctx
->Light
.Enabled
&& ctx
->Light
.Model
.TwoSide
) {
830 if (ctx
->Light
.ColorMaterialEnabled
&&
831 (ctx
->Light
.ColorMaterialBitmask
& BACK_MATERIAL_BITS
) !=
832 ((ctx
->Light
.ColorMaterialBitmask
& FRONT_MATERIAL_BITS
)<<1))
835 for (i
= MAT_ATTRIB_FRONT_AMBIENT
; i
< MAT_ATTRIB_FRONT_INDEXES
; i
+=2)
836 if (memcmp( ctx
->Light
.Material
.Attrib
[i
],
837 ctx
->Light
.Material
.Attrib
[i
+1],
838 sizeof(GLfloat
)*4) != 0) {
845 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_LIGHT_TWOSIDE
, fallback
);
849 static void radeonColorMaterial( GLcontext
*ctx
, GLenum face
, GLenum mode
)
851 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
852 GLuint light_model_ctl1
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
];
854 light_model_ctl1
&= ~((3 << RADEON_EMISSIVE_SOURCE_SHIFT
) |
855 (3 << RADEON_AMBIENT_SOURCE_SHIFT
) |
856 (3 << RADEON_DIFFUSE_SOURCE_SHIFT
) |
857 (3 << RADEON_SPECULAR_SOURCE_SHIFT
));
859 if (ctx
->Light
.ColorMaterialEnabled
) {
860 GLuint mask
= ctx
->Light
.ColorMaterialBitmask
;
862 if (mask
& MAT_BIT_FRONT_EMISSION
) {
863 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
864 RADEON_EMISSIVE_SOURCE_SHIFT
);
867 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
868 RADEON_EMISSIVE_SOURCE_SHIFT
);
871 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
872 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
873 RADEON_AMBIENT_SOURCE_SHIFT
);
876 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
877 RADEON_AMBIENT_SOURCE_SHIFT
);
880 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
881 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
882 RADEON_DIFFUSE_SOURCE_SHIFT
);
885 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
886 RADEON_DIFFUSE_SOURCE_SHIFT
);
889 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
890 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
891 RADEON_SPECULAR_SOURCE_SHIFT
);
894 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
895 RADEON_SPECULAR_SOURCE_SHIFT
);
901 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_EMISSIVE_SOURCE_SHIFT
) |
902 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_AMBIENT_SOURCE_SHIFT
) |
903 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_DIFFUSE_SOURCE_SHIFT
) |
904 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_SPECULAR_SOURCE_SHIFT
);
907 if (light_model_ctl1
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]) {
908 RADEON_STATECHANGE( rmesa
, tcl
);
909 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] = light_model_ctl1
;
913 void radeonUpdateMaterial( GLcontext
*ctx
)
915 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
916 GLfloat (*mat
)[4] = ctx
->Light
.Material
.Attrib
;
917 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( mtl
);
920 if (ctx
->Light
.ColorMaterialEnabled
)
921 mask
&= ~ctx
->Light
.ColorMaterialBitmask
;
923 if (RADEON_DEBUG
& DEBUG_STATE
)
924 fprintf(stderr
, "%s\n", __FUNCTION__
);
927 if (mask
& MAT_BIT_FRONT_EMISSION
) {
928 fcmd
[MTL_EMMISSIVE_RED
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][0];
929 fcmd
[MTL_EMMISSIVE_GREEN
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][1];
930 fcmd
[MTL_EMMISSIVE_BLUE
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][2];
931 fcmd
[MTL_EMMISSIVE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][3];
933 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
934 fcmd
[MTL_AMBIENT_RED
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][0];
935 fcmd
[MTL_AMBIENT_GREEN
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][1];
936 fcmd
[MTL_AMBIENT_BLUE
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][2];
937 fcmd
[MTL_AMBIENT_ALPHA
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][3];
939 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
940 fcmd
[MTL_DIFFUSE_RED
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][0];
941 fcmd
[MTL_DIFFUSE_GREEN
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][1];
942 fcmd
[MTL_DIFFUSE_BLUE
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][2];
943 fcmd
[MTL_DIFFUSE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][3];
945 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
946 fcmd
[MTL_SPECULAR_RED
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][0];
947 fcmd
[MTL_SPECULAR_GREEN
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][1];
948 fcmd
[MTL_SPECULAR_BLUE
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][2];
949 fcmd
[MTL_SPECULAR_ALPHA
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][3];
951 if (mask
& MAT_BIT_FRONT_SHININESS
) {
952 fcmd
[MTL_SHININESS
] = mat
[MAT_ATTRIB_FRONT_SHININESS
][0];
955 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mtl
);
957 check_twoside_fallback( ctx
);
958 /* update_global_ambient( ctx );*/
963 * _MESA_NEW_NEED_EYE_COORDS
965 * Uses derived state from mesa:
974 * which are calculated in light.c and are correct for the current
975 * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW
976 * and _MESA_NEW_NEED_EYE_COORDS.
978 static void update_light( GLcontext
*ctx
)
980 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
982 /* Have to check these, or have an automatic shortcircuit mechanism
983 * to remove noop statechanges. (Or just do a better job on the
987 GLuint tmp
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
];
989 if (ctx
->_NeedEyeCoords
)
990 tmp
&= ~RADEON_LIGHT_IN_MODELSPACE
;
992 tmp
|= RADEON_LIGHT_IN_MODELSPACE
;
995 /* Leave this test disabled: (unexplained q3 lockup) (even with
998 if (tmp
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
])
1000 RADEON_STATECHANGE( rmesa
, tcl
);
1001 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] = tmp
;
1006 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( eye
);
1007 fcmd
[EYE_X
] = ctx
->_EyeZDir
[0];
1008 fcmd
[EYE_Y
] = ctx
->_EyeZDir
[1];
1009 fcmd
[EYE_Z
] = - ctx
->_EyeZDir
[2];
1010 fcmd
[EYE_RESCALE_FACTOR
] = ctx
->_ModelViewInvScale
;
1011 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.eye
);
1016 if (ctx
->Light
.Enabled
) {
1018 for (p
= 0 ; p
< MAX_LIGHTS
; p
++) {
1019 if (ctx
->Light
.Light
[p
].Enabled
) {
1020 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
1021 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( lit
[p
] );
1023 if (l
->EyePosition
[3] == 0.0) {
1024 COPY_3FV( &fcmd
[LIT_POSITION_X
], l
->_VP_inf_norm
);
1025 COPY_3FV( &fcmd
[LIT_DIRECTION_X
], l
->_h_inf_norm
);
1026 fcmd
[LIT_POSITION_W
] = 0;
1027 fcmd
[LIT_DIRECTION_W
] = 0;
1029 COPY_4V( &fcmd
[LIT_POSITION_X
], l
->_Position
);
1030 fcmd
[LIT_DIRECTION_X
] = -l
->_NormDirection
[0];
1031 fcmd
[LIT_DIRECTION_Y
] = -l
->_NormDirection
[1];
1032 fcmd
[LIT_DIRECTION_Z
] = -l
->_NormDirection
[2];
1033 fcmd
[LIT_DIRECTION_W
] = 0;
1036 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
1042 static void radeonLightfv( GLcontext
*ctx
, GLenum light
,
1043 GLenum pname
, const GLfloat
*params
)
1045 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1046 GLint p
= light
- GL_LIGHT0
;
1047 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
1048 GLfloat
*fcmd
= (GLfloat
*)rmesa
->hw
.lit
[p
].cmd
;
1055 update_light_colors( ctx
, p
);
1058 case GL_SPOT_DIRECTION
:
1059 /* picked up in update_light */
1063 /* positions picked up in update_light, but can do flag here */
1065 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1067 /* FIXME: Set RANGE_ATTEN only when needed */
1069 flag
= RADEON_LIGHT_1_IS_LOCAL
;
1071 flag
= RADEON_LIGHT_0_IS_LOCAL
;
1073 RADEON_STATECHANGE(rmesa
, tcl
);
1074 if (l
->EyePosition
[3] != 0.0F
)
1075 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
1077 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
1081 case GL_SPOT_EXPONENT
:
1082 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1083 fcmd
[LIT_SPOT_EXPONENT
] = params
[0];
1086 case GL_SPOT_CUTOFF
: {
1087 GLuint flag
= (p
&1) ? RADEON_LIGHT_1_IS_SPOT
: RADEON_LIGHT_0_IS_SPOT
;
1088 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1090 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1091 fcmd
[LIT_SPOT_CUTOFF
] = l
->_CosCutoff
;
1093 RADEON_STATECHANGE(rmesa
, tcl
);
1094 if (l
->SpotCutoff
!= 180.0F
)
1095 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
1097 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
1102 case GL_CONSTANT_ATTENUATION
:
1103 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1104 fcmd
[LIT_ATTEN_CONST
] = params
[0];
1105 if ( params
[0] == 0.0 )
1106 fcmd
[LIT_ATTEN_CONST_INV
] = FLT_MAX
;
1108 fcmd
[LIT_ATTEN_CONST_INV
] = 1.0 / params
[0];
1110 case GL_LINEAR_ATTENUATION
:
1111 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1112 fcmd
[LIT_ATTEN_LINEAR
] = params
[0];
1114 case GL_QUADRATIC_ATTENUATION
:
1115 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1116 fcmd
[LIT_ATTEN_QUADRATIC
] = params
[0];
1122 /* Set RANGE_ATTEN only when needed */
1125 case GL_CONSTANT_ATTENUATION
:
1126 case GL_LINEAR_ATTENUATION
:
1127 case GL_QUADRATIC_ATTENUATION
:
1129 GLuint
*icmd
= (GLuint
*)RADEON_DB_STATE( tcl
);
1130 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1131 GLuint atten_flag
= ( p
&1 ) ? RADEON_LIGHT_1_ENABLE_RANGE_ATTEN
1132 : RADEON_LIGHT_0_ENABLE_RANGE_ATTEN
;
1133 GLuint atten_const_flag
= ( p
&1 ) ? RADEON_LIGHT_1_CONSTANT_RANGE_ATTEN
1134 : RADEON_LIGHT_0_CONSTANT_RANGE_ATTEN
;
1136 if ( l
->EyePosition
[3] == 0.0F
||
1137 ( ( fcmd
[LIT_ATTEN_CONST
] == 0.0 || fcmd
[LIT_ATTEN_CONST
] == 1.0 ) &&
1138 fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) ) {
1139 /* Disable attenuation */
1140 icmd
[idx
] &= ~atten_flag
;
1142 if ( fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) {
1143 /* Enable only constant portion of attenuation calculation */
1144 icmd
[idx
] |= ( atten_flag
| atten_const_flag
);
1146 /* Enable full attenuation calculation */
1147 icmd
[idx
] &= ~atten_const_flag
;
1148 icmd
[idx
] |= atten_flag
;
1152 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.tcl
);
1163 static void radeonLightModelfv( GLcontext
*ctx
, GLenum pname
,
1164 const GLfloat
*param
)
1166 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1169 case GL_LIGHT_MODEL_AMBIENT
:
1170 update_global_ambient( ctx
);
1173 case GL_LIGHT_MODEL_LOCAL_VIEWER
:
1174 RADEON_STATECHANGE( rmesa
, tcl
);
1175 if (ctx
->Light
.Model
.LocalViewer
)
1176 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LOCAL_VIEWER
;
1178 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_LOCAL_VIEWER
;
1181 case GL_LIGHT_MODEL_TWO_SIDE
:
1182 RADEON_STATECHANGE( rmesa
, tcl
);
1183 if (ctx
->Light
.Model
.TwoSide
)
1184 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_LIGHT_TWOSIDE
;
1186 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_LIGHT_TWOSIDE
;
1188 check_twoside_fallback( ctx
);
1190 if (rmesa
->TclFallback
) {
1191 radeonChooseRenderState( ctx
);
1192 radeonChooseVertexState( ctx
);
1196 case GL_LIGHT_MODEL_COLOR_CONTROL
:
1197 radeonUpdateSpecular(ctx
);
1205 static void radeonShadeModel( GLcontext
*ctx
, GLenum mode
)
1207 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1208 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
1210 s
&= ~(RADEON_DIFFUSE_SHADE_MASK
|
1211 RADEON_ALPHA_SHADE_MASK
|
1212 RADEON_SPECULAR_SHADE_MASK
|
1213 RADEON_FOG_SHADE_MASK
);
1217 s
|= (RADEON_DIFFUSE_SHADE_FLAT
|
1218 RADEON_ALPHA_SHADE_FLAT
|
1219 RADEON_SPECULAR_SHADE_FLAT
|
1220 RADEON_FOG_SHADE_FLAT
);
1223 s
|= (RADEON_DIFFUSE_SHADE_GOURAUD
|
1224 RADEON_ALPHA_SHADE_GOURAUD
|
1225 RADEON_SPECULAR_SHADE_GOURAUD
|
1226 RADEON_FOG_SHADE_GOURAUD
);
1232 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
1233 RADEON_STATECHANGE( rmesa
, set
);
1234 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
1239 /* =============================================================
1243 static void radeonClipPlane( GLcontext
*ctx
, GLenum plane
, const GLfloat
*eq
)
1245 GLint p
= (GLint
) plane
- (GLint
) GL_CLIP_PLANE0
;
1246 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1247 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1249 RADEON_STATECHANGE( rmesa
, ucp
[p
] );
1250 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1251 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1252 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1253 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1256 static void radeonUpdateClipPlanes( GLcontext
*ctx
)
1258 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1261 for (p
= 0; p
< ctx
->Const
.MaxClipPlanes
; p
++) {
1262 if (ctx
->Transform
.ClipPlanesEnabled
& (1 << p
)) {
1263 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1265 RADEON_STATECHANGE( rmesa
, ucp
[p
] );
1266 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1267 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1268 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1269 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1275 /* =============================================================
1280 radeonStencilFuncSeparate( GLcontext
*ctx
, GLenum face
, GLenum func
,
1281 GLint ref
, GLuint mask
)
1283 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1284 GLuint refmask
= ((ctx
->Stencil
.Ref
[0] << RADEON_STENCIL_REF_SHIFT
) |
1285 (ctx
->Stencil
.ValueMask
[0] << RADEON_STENCIL_MASK_SHIFT
));
1287 RADEON_STATECHANGE( rmesa
, ctx
);
1288 RADEON_STATECHANGE( rmesa
, msk
);
1290 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_STENCIL_TEST_MASK
;
1291 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~(RADEON_STENCIL_REF_MASK
|
1292 RADEON_STENCIL_VALUE_MASK
);
1294 switch ( ctx
->Stencil
.Function
[0] ) {
1296 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_NEVER
;
1299 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_LESS
;
1302 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_EQUAL
;
1305 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_LEQUAL
;
1308 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_GREATER
;
1311 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_NEQUAL
;
1314 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_GEQUAL
;
1317 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_ALWAYS
;
1321 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |= refmask
;
1325 radeonStencilMaskSeparate( GLcontext
*ctx
, GLenum face
, GLuint mask
)
1327 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1329 RADEON_STATECHANGE( rmesa
, msk
);
1330 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~RADEON_STENCIL_WRITE_MASK
;
1331 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |=
1332 (ctx
->Stencil
.WriteMask
[0] << RADEON_STENCIL_WRITEMASK_SHIFT
);
1335 static void radeonStencilOpSeparate( GLcontext
*ctx
, GLenum face
, GLenum fail
,
1336 GLenum zfail
, GLenum zpass
)
1338 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1340 /* radeon 7200 have stencil bug, DEC and INC_WRAP will actually both do DEC_WRAP,
1341 and DEC_WRAP (and INVERT) will do INVERT. No way to get correct INC_WRAP and DEC,
1342 but DEC_WRAP can be fixed by using DEC and INC_WRAP at least use INC. */
1344 GLuint tempRADEON_STENCIL_FAIL_DEC_WRAP
;
1345 GLuint tempRADEON_STENCIL_FAIL_INC_WRAP
;
1346 GLuint tempRADEON_STENCIL_ZFAIL_DEC_WRAP
;
1347 GLuint tempRADEON_STENCIL_ZFAIL_INC_WRAP
;
1348 GLuint tempRADEON_STENCIL_ZPASS_DEC_WRAP
;
1349 GLuint tempRADEON_STENCIL_ZPASS_INC_WRAP
;
1351 if (rmesa
->radeonScreen
->chipset
& RADEON_CHIPSET_BROKEN_STENCIL
) {
1352 tempRADEON_STENCIL_FAIL_DEC_WRAP
= RADEON_STENCIL_FAIL_DEC
;
1353 tempRADEON_STENCIL_FAIL_INC_WRAP
= RADEON_STENCIL_FAIL_INC
;
1354 tempRADEON_STENCIL_ZFAIL_DEC_WRAP
= RADEON_STENCIL_ZFAIL_DEC
;
1355 tempRADEON_STENCIL_ZFAIL_INC_WRAP
= RADEON_STENCIL_ZFAIL_INC
;
1356 tempRADEON_STENCIL_ZPASS_DEC_WRAP
= RADEON_STENCIL_ZPASS_DEC
;
1357 tempRADEON_STENCIL_ZPASS_INC_WRAP
= RADEON_STENCIL_ZPASS_INC
;
1360 tempRADEON_STENCIL_FAIL_DEC_WRAP
= RADEON_STENCIL_FAIL_DEC_WRAP
;
1361 tempRADEON_STENCIL_FAIL_INC_WRAP
= RADEON_STENCIL_FAIL_INC_WRAP
;
1362 tempRADEON_STENCIL_ZFAIL_DEC_WRAP
= RADEON_STENCIL_ZFAIL_DEC_WRAP
;
1363 tempRADEON_STENCIL_ZFAIL_INC_WRAP
= RADEON_STENCIL_ZFAIL_INC_WRAP
;
1364 tempRADEON_STENCIL_ZPASS_DEC_WRAP
= RADEON_STENCIL_ZPASS_DEC_WRAP
;
1365 tempRADEON_STENCIL_ZPASS_INC_WRAP
= RADEON_STENCIL_ZPASS_INC_WRAP
;
1368 RADEON_STATECHANGE( rmesa
, ctx
);
1369 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~(RADEON_STENCIL_FAIL_MASK
|
1370 RADEON_STENCIL_ZFAIL_MASK
|
1371 RADEON_STENCIL_ZPASS_MASK
);
1373 switch ( ctx
->Stencil
.FailFunc
[0] ) {
1375 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_KEEP
;
1378 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_ZERO
;
1381 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_REPLACE
;
1384 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_INC
;
1387 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_DEC
;
1390 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_FAIL_INC_WRAP
;
1393 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_FAIL_DEC_WRAP
;
1396 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_INVERT
;
1400 switch ( ctx
->Stencil
.ZFailFunc
[0] ) {
1402 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_KEEP
;
1405 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_ZERO
;
1408 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_REPLACE
;
1411 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_INC
;
1414 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_DEC
;
1417 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZFAIL_INC_WRAP
;
1420 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZFAIL_DEC_WRAP
;
1423 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_INVERT
;
1427 switch ( ctx
->Stencil
.ZPassFunc
[0] ) {
1429 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_KEEP
;
1432 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_ZERO
;
1435 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_REPLACE
;
1438 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_INC
;
1441 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_DEC
;
1444 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZPASS_INC_WRAP
;
1447 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZPASS_DEC_WRAP
;
1450 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_INVERT
;
1455 static void radeonClearStencil( GLcontext
*ctx
, GLint s
)
1457 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1459 rmesa
->state
.stencil
.clear
=
1460 ((GLuint
) ctx
->Stencil
.Clear
|
1461 (0xff << RADEON_STENCIL_MASK_SHIFT
) |
1462 (ctx
->Stencil
.WriteMask
[0] << RADEON_STENCIL_WRITEMASK_SHIFT
));
1466 /* =============================================================
1467 * Window position and viewport transformation
1471 * To correctly position primitives:
1473 #define SUBPIXEL_X 0.125
1474 #define SUBPIXEL_Y 0.125
1478 * Called when window size or position changes or viewport or depth range
1479 * state is changed. We update the hardware viewport state here.
1481 void radeonUpdateWindow( GLcontext
*ctx
)
1483 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1484 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
1485 GLfloat xoffset
= (GLfloat
)dPriv
->x
;
1486 GLfloat yoffset
= (GLfloat
)dPriv
->y
+ dPriv
->h
;
1487 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1489 GLfloat sx
= v
[MAT_SX
];
1490 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1491 GLfloat sy
= - v
[MAT_SY
];
1492 GLfloat ty
= (- v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1493 GLfloat sz
= v
[MAT_SZ
] * rmesa
->state
.depth
.scale
;
1494 GLfloat tz
= v
[MAT_TZ
] * rmesa
->state
.depth
.scale
;
1495 RADEON_FIREVERTICES( rmesa
);
1496 RADEON_STATECHANGE( rmesa
, vpt
);
1498 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XSCALE
] = *(GLuint
*)&sx
;
1499 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = *(GLuint
*)&tx
;
1500 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YSCALE
] = *(GLuint
*)&sy
;
1501 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = *(GLuint
*)&ty
;
1502 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZSCALE
] = *(GLuint
*)&sz
;
1503 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZOFFSET
] = *(GLuint
*)&tz
;
1507 static void radeonViewport( GLcontext
*ctx
, GLint x
, GLint y
,
1508 GLsizei width
, GLsizei height
)
1510 /* Don't pipeline viewport changes, conflict with window offset
1511 * setting below. Could apply deltas to rescue pipelined viewport
1512 * values, or keep the originals hanging around.
1514 RADEON_FIREVERTICES( RADEON_CONTEXT(ctx
) );
1515 radeonUpdateWindow( ctx
);
1518 static void radeonDepthRange( GLcontext
*ctx
, GLclampd nearval
,
1521 radeonUpdateWindow( ctx
);
1524 void radeonUpdateViewportOffset( GLcontext
*ctx
)
1526 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1527 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
1528 GLfloat xoffset
= (GLfloat
)dPriv
->x
;
1529 GLfloat yoffset
= (GLfloat
)dPriv
->y
+ dPriv
->h
;
1530 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1532 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1533 GLfloat ty
= (- v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1535 if ( rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] != *(GLuint
*)&tx
||
1536 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] != *(GLuint
*)&ty
)
1538 /* Note: this should also modify whatever data the context reset
1541 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = *(GLuint
*)&tx
;
1542 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = *(GLuint
*)&ty
;
1544 /* update polygon stipple x/y screen offset */
1547 GLuint m
= rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
];
1549 m
&= ~(RADEON_STIPPLE_X_OFFSET_MASK
|
1550 RADEON_STIPPLE_Y_OFFSET_MASK
);
1552 /* add magic offsets, then invert */
1553 stx
= 31 - ((rmesa
->dri
.drawable
->x
- 1) & RADEON_STIPPLE_COORD_MASK
);
1554 sty
= 31 - ((rmesa
->dri
.drawable
->y
+ rmesa
->dri
.drawable
->h
- 1)
1555 & RADEON_STIPPLE_COORD_MASK
);
1557 m
|= ((stx
<< RADEON_STIPPLE_X_OFFSET_SHIFT
) |
1558 (sty
<< RADEON_STIPPLE_Y_OFFSET_SHIFT
));
1560 if ( rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
] != m
) {
1561 RADEON_STATECHANGE( rmesa
, msc
);
1562 rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
] = m
;
1567 radeonUpdateScissor( ctx
);
1572 /* =============================================================
1576 static void radeonClearColor( GLcontext
*ctx
, const GLfloat color
[4] )
1578 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1580 CLAMPED_FLOAT_TO_UBYTE(c
[0], color
[0]);
1581 CLAMPED_FLOAT_TO_UBYTE(c
[1], color
[1]);
1582 CLAMPED_FLOAT_TO_UBYTE(c
[2], color
[2]);
1583 CLAMPED_FLOAT_TO_UBYTE(c
[3], color
[3]);
1584 rmesa
->state
.color
.clear
= radeonPackColor( rmesa
->radeonScreen
->cpp
,
1585 c
[0], c
[1], c
[2], c
[3] );
1589 static void radeonRenderMode( GLcontext
*ctx
, GLenum mode
)
1591 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1592 FALLBACK( rmesa
, RADEON_FALLBACK_RENDER_MODE
, (mode
!= GL_RENDER
) );
1596 static GLuint radeon_rop_tab
[] = {
1599 RADEON_ROP_AND_REVERSE
,
1601 RADEON_ROP_AND_INVERTED
,
1608 RADEON_ROP_OR_REVERSE
,
1609 RADEON_ROP_COPY_INVERTED
,
1610 RADEON_ROP_OR_INVERTED
,
1615 static void radeonLogicOpCode( GLcontext
*ctx
, GLenum opcode
)
1617 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1618 GLuint rop
= (GLuint
)opcode
- GL_CLEAR
;
1622 RADEON_STATECHANGE( rmesa
, msk
);
1623 rmesa
->hw
.msk
.cmd
[MSK_RB3D_ROPCNTL
] = radeon_rop_tab
[rop
];
1628 * Set up the cliprects for either front or back-buffer drawing.
1630 void radeonSetCliprects( radeonContextPtr rmesa
)
1632 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
1634 if (rmesa
->glCtx
->DrawBuffer
->_ColorDrawBufferMask
[0]
1635 == BUFFER_BIT_BACK_LEFT
) {
1636 /* Can't ignore 2d windows if we are page flipping.
1638 if ( dPriv
->numBackClipRects
== 0 || rmesa
->doPageFlip
) {
1639 rmesa
->numClipRects
= dPriv
->numClipRects
;
1640 rmesa
->pClipRects
= dPriv
->pClipRects
;
1643 rmesa
->numClipRects
= dPriv
->numBackClipRects
;
1644 rmesa
->pClipRects
= dPriv
->pBackClipRects
;
1648 /* front buffer (or none, or multiple buffers */
1649 rmesa
->numClipRects
= dPriv
->numClipRects
;
1650 rmesa
->pClipRects
= dPriv
->pClipRects
;
1653 if (rmesa
->state
.scissor
.enabled
)
1654 radeonRecalcScissorRects( rmesa
);
1659 * Called via glDrawBuffer.
1661 static void radeonDrawBuffer( GLcontext
*ctx
, GLenum mode
)
1663 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1665 if (RADEON_DEBUG
& DEBUG_DRI
)
1666 fprintf(stderr
, "%s %s\n", __FUNCTION__
,
1667 _mesa_lookup_enum_by_nr( mode
));
1669 RADEON_FIREVERTICES(rmesa
); /* don't pipeline cliprect changes */
1672 * _ColorDrawBufferMask is easier to cope with than <mode>.
1673 * Check for software fallback, update cliprects.
1675 switch ( ctx
->DrawBuffer
->_ColorDrawBufferMask
[0] ) {
1676 case BUFFER_BIT_FRONT_LEFT
:
1677 case BUFFER_BIT_BACK_LEFT
:
1678 FALLBACK( rmesa
, RADEON_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
1681 /* 0 (GL_NONE) buffers or multiple color drawing buffers */
1682 FALLBACK( rmesa
, RADEON_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
1686 radeonSetCliprects( rmesa
);
1688 /* We'll set the drawing engine's offset/pitch parameters later
1689 * when we update other state.
1693 static void radeonReadBuffer( GLcontext
*ctx
, GLenum mode
)
1695 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
1699 /* =============================================================
1700 * State enable/disable
1703 static void radeonEnable( GLcontext
*ctx
, GLenum cap
, GLboolean state
)
1705 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1708 if ( RADEON_DEBUG
& DEBUG_STATE
)
1709 fprintf( stderr
, "%s( %s = %s )\n", __FUNCTION__
,
1710 _mesa_lookup_enum_by_nr( cap
),
1711 state
? "GL_TRUE" : "GL_FALSE" );
1714 /* Fast track this one...
1722 RADEON_STATECHANGE( rmesa
, ctx
);
1724 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ALPHA_TEST_ENABLE
;
1726 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ALPHA_TEST_ENABLE
;
1731 RADEON_STATECHANGE( rmesa
, ctx
);
1733 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ALPHA_BLEND_ENABLE
;
1735 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ALPHA_BLEND_ENABLE
;
1737 if ( ctx
->Color
._LogicOpEnabled
) {
1738 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
1740 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
1743 /* Catch a possible fallback:
1746 ctx
->Driver
.BlendEquationSeparate( ctx
,
1747 ctx
->Color
.BlendEquationRGB
,
1748 ctx
->Color
.BlendEquationA
);
1749 ctx
->Driver
.BlendFuncSeparate( ctx
, ctx
->Color
.BlendSrcRGB
,
1750 ctx
->Color
.BlendDstRGB
,
1751 ctx
->Color
.BlendSrcA
,
1752 ctx
->Color
.BlendDstA
);
1755 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_FUNC
, GL_FALSE
);
1756 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_EQ
, GL_FALSE
);
1760 case GL_CLIP_PLANE0
:
1761 case GL_CLIP_PLANE1
:
1762 case GL_CLIP_PLANE2
:
1763 case GL_CLIP_PLANE3
:
1764 case GL_CLIP_PLANE4
:
1765 case GL_CLIP_PLANE5
:
1766 p
= cap
-GL_CLIP_PLANE0
;
1767 RADEON_STATECHANGE( rmesa
, tcl
);
1769 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= (RADEON_UCP_ENABLE_0
<<p
);
1770 radeonClipPlane( ctx
, cap
, NULL
);
1773 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~(RADEON_UCP_ENABLE_0
<<p
);
1777 case GL_COLOR_MATERIAL
:
1778 radeonColorMaterial( ctx
, 0, 0 );
1779 radeonUpdateMaterial( ctx
);
1783 radeonCullFace( ctx
, 0 );
1787 RADEON_STATECHANGE(rmesa
, ctx
);
1789 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_Z_ENABLE
;
1791 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_Z_ENABLE
;
1796 RADEON_STATECHANGE(rmesa
, ctx
);
1798 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_DITHER_ENABLE
;
1799 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~rmesa
->state
.color
.roundEnable
;
1801 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_DITHER_ENABLE
;
1802 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= rmesa
->state
.color
.roundEnable
;
1807 RADEON_STATECHANGE(rmesa
, ctx
);
1809 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_FOG_ENABLE
;
1810 radeonFogfv( ctx
, GL_FOG_MODE
, NULL
);
1812 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_FOG_ENABLE
;
1813 RADEON_STATECHANGE(rmesa
, tcl
);
1814 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_TCL_FOG_MASK
;
1816 radeonUpdateSpecular( ctx
); /* for PK_SPEC */
1817 _mesa_allow_light_in_model( ctx
, !state
);
1828 RADEON_STATECHANGE(rmesa
, tcl
);
1829 p
= cap
- GL_LIGHT0
;
1831 flag
= (RADEON_LIGHT_1_ENABLE
|
1832 RADEON_LIGHT_1_ENABLE_AMBIENT
|
1833 RADEON_LIGHT_1_ENABLE_SPECULAR
);
1835 flag
= (RADEON_LIGHT_0_ENABLE
|
1836 RADEON_LIGHT_0_ENABLE_AMBIENT
|
1837 RADEON_LIGHT_0_ENABLE_SPECULAR
);
1840 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] |= flag
;
1842 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] &= ~flag
;
1846 update_light_colors( ctx
, p
);
1850 RADEON_STATECHANGE(rmesa
, tcl
);
1851 radeonUpdateSpecular(ctx
);
1852 check_twoside_fallback( ctx
);
1855 case GL_LINE_SMOOTH
:
1856 RADEON_STATECHANGE( rmesa
, ctx
);
1858 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ANTI_ALIAS_LINE
;
1860 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ANTI_ALIAS_LINE
;
1864 case GL_LINE_STIPPLE
:
1865 RADEON_STATECHANGE( rmesa
, ctx
);
1867 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_PATTERN_ENABLE
;
1869 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_PATTERN_ENABLE
;
1873 case GL_COLOR_LOGIC_OP
:
1874 RADEON_STATECHANGE( rmesa
, ctx
);
1875 if ( ctx
->Color
._LogicOpEnabled
) {
1876 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
1878 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
1883 RADEON_STATECHANGE( rmesa
, tcl
);
1885 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_NORMALIZE_NORMALS
;
1887 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_NORMALIZE_NORMALS
;
1891 case GL_POLYGON_OFFSET_POINT
:
1892 RADEON_STATECHANGE( rmesa
, set
);
1894 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_POINT
;
1896 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_POINT
;
1900 case GL_POLYGON_OFFSET_LINE
:
1901 RADEON_STATECHANGE( rmesa
, set
);
1903 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_LINE
;
1905 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_LINE
;
1909 case GL_POLYGON_OFFSET_FILL
:
1910 RADEON_STATECHANGE( rmesa
, set
);
1912 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_TRI
;
1914 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_TRI
;
1918 case GL_POLYGON_SMOOTH
:
1919 RADEON_STATECHANGE( rmesa
, ctx
);
1921 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ANTI_ALIAS_POLY
;
1923 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ANTI_ALIAS_POLY
;
1927 case GL_POLYGON_STIPPLE
:
1928 RADEON_STATECHANGE(rmesa
, ctx
);
1930 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_STIPPLE_ENABLE
;
1932 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_STIPPLE_ENABLE
;
1936 case GL_RESCALE_NORMAL_EXT
: {
1937 GLboolean tmp
= ctx
->_NeedEyeCoords
? state
: !state
;
1938 RADEON_STATECHANGE( rmesa
, tcl
);
1940 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_RESCALE_NORMALS
;
1942 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_RESCALE_NORMALS
;
1947 case GL_SCISSOR_TEST
:
1948 RADEON_FIREVERTICES( rmesa
);
1949 rmesa
->state
.scissor
.enabled
= state
;
1950 radeonUpdateScissor( ctx
);
1953 case GL_STENCIL_TEST
:
1954 if ( rmesa
->state
.stencil
.hwBuffer
) {
1955 RADEON_STATECHANGE( rmesa
, ctx
);
1957 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_STENCIL_ENABLE
;
1959 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_STENCIL_ENABLE
;
1962 FALLBACK( rmesa
, RADEON_FALLBACK_STENCIL
, state
);
1966 case GL_TEXTURE_GEN_Q
:
1967 case GL_TEXTURE_GEN_R
:
1968 case GL_TEXTURE_GEN_S
:
1969 case GL_TEXTURE_GEN_T
:
1970 /* Picked up in radeonUpdateTextureState.
1972 rmesa
->recheck_texgen
[ctx
->Texture
.CurrentUnit
] = GL_TRUE
;
1975 case GL_COLOR_SUM_EXT
:
1976 radeonUpdateSpecular ( ctx
);
1985 static void radeonLightingSpaceChange( GLcontext
*ctx
)
1987 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1989 RADEON_STATECHANGE( rmesa
, tcl
);
1991 if (RADEON_DEBUG
& DEBUG_STATE
)
1992 fprintf(stderr
, "%s %d BEFORE %x\n", __FUNCTION__
, ctx
->_NeedEyeCoords
,
1993 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]);
1995 if (ctx
->_NeedEyeCoords
)
1996 tmp
= ctx
->Transform
.RescaleNormals
;
1998 tmp
= !ctx
->Transform
.RescaleNormals
;
2001 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_RESCALE_NORMALS
;
2003 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_RESCALE_NORMALS
;
2006 if (RADEON_DEBUG
& DEBUG_STATE
)
2007 fprintf(stderr
, "%s %d AFTER %x\n", __FUNCTION__
, ctx
->_NeedEyeCoords
,
2008 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]);
2011 /* =============================================================
2012 * Deferred state management - matrices, textures, other?
2015 static void texmat_set_texrect( radeonContextPtr rmesa
,
2016 struct gl_texture_object
*tObj
, GLuint unit
)
2018 const struct gl_texture_image
*baseImage
= tObj
->Image
[0][tObj
->BaseLevel
];
2019 _math_matrix_set_identity( &rmesa
->tmpmat
[unit
] );
2020 rmesa
->tmpmat
[unit
].m
[0] = 1.0 / baseImage
->Width
;
2021 rmesa
->tmpmat
[unit
].m
[5] = 1.0 / baseImage
->Height
;
2025 static void texmat_fixup_texrect( radeonContextPtr rmesa
,
2026 struct gl_texture_object
*tObj
, GLuint unit
)
2028 const struct gl_texture_image
*baseImage
= tObj
->Image
[0][tObj
->BaseLevel
];
2030 for (i
= 0; i
< 4; i
++) {
2031 rmesa
->tmpmat
[unit
].m
[i
] = rmesa
->tmpmat
[unit
].m
[i
] / baseImage
->Width
;
2032 rmesa
->tmpmat
[unit
].m
[i
+4] = rmesa
->tmpmat
[unit
].m
[i
+4] / baseImage
->Height
;
2036 void radeonUploadTexMatrix( radeonContextPtr rmesa
,
2037 int unit
, GLboolean swapcols
)
2039 /* Here's how this works: on r100, only 3 tex coords can be submitted, so the
2040 vector looks like this probably: (s t r|q 0) (not sure if the last coord
2041 is hardwired to 0, could be 1 too). Interestingly, it actually looks like
2042 texgen generates all 4 coords, at least tests with projtex indicated that.
2043 So: if we need the q coord in the end (solely determined by the texture
2044 target, i.e. 2d / 1d / texrect targets) we swap the third and 4th row.
2045 Additionally, if we don't have texgen but 4 tex coords submitted, we swap
2046 column 3 and 4 (for the 2d / 1d / texrect targets) since the the q coord
2047 will get submitted in the "wrong", i.e. 3rd, slot.
2048 If an app submits 3 coords for 2d targets, we assume it is saving on vertex
2049 size and using the texture matrix to swap the r and q coords around (ut2k3
2050 does exactly that), so we don't need the 3rd / 4th column swap - still need
2051 the 3rd / 4th row swap of course. This will potentially break for apps which
2052 use TexCoord3x just for fun. Additionally, it will never work if an app uses
2053 an "advanced" texture matrix and relies on all 4 texcoord inputs to generate
2054 the maximum needed 3. This seems impossible to do with hw tcl on r100, and
2055 incredibly hard to detect so we can't just fallback in such a case. Assume
2056 it never happens... - rs
2059 int idx
= TEXMAT_0
+ unit
;
2060 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] )) + MAT_ELT_0
;
2062 struct gl_texture_unit tUnit
= rmesa
->glCtx
->Texture
.Unit
[unit
];
2063 GLfloat
*src
= rmesa
->tmpmat
[unit
].m
;
2065 rmesa
->TexMatColSwap
&= ~(1 << unit
);
2066 if ((tUnit
._ReallyEnabled
& (TEXTURE_3D_BIT
| TEXTURE_CUBE_BIT
)) == 0) {
2068 rmesa
->TexMatColSwap
|= 1 << unit
;
2069 /* attention some elems are swapped 2 times! */
2082 /* those last 4 are probably never used */
2089 for (i
= 0; i
< 2; i
++) {
2093 *dest
++ = src
[i
+12];
2095 for (i
= 3; i
>= 2; i
--) {
2099 *dest
++ = src
[i
+12];
2104 for (i
= 0 ; i
< 4 ; i
++) {
2108 *dest
++ = src
[i
+12];
2112 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
2116 static void upload_matrix( radeonContextPtr rmesa
, GLfloat
*src
, int idx
)
2118 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
2122 for (i
= 0 ; i
< 4 ; i
++) {
2126 *dest
++ = src
[i
+12];
2129 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
2132 static void upload_matrix_t( radeonContextPtr rmesa
, GLfloat
*src
, int idx
)
2134 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
2135 memcpy(dest
, src
, 16*sizeof(float));
2136 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
2140 static void update_texturematrix( GLcontext
*ctx
)
2142 radeonContextPtr rmesa
= RADEON_CONTEXT( ctx
);
2143 GLuint tpc
= rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
];
2144 GLuint vs
= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
];
2146 GLuint texMatEnabled
= 0;
2147 rmesa
->NeedTexMatrix
= 0;
2148 rmesa
->TexMatColSwap
= 0;
2150 for (unit
= 0 ; unit
< ctx
->Const
.MaxTextureUnits
; unit
++) {
2151 if (ctx
->Texture
.Unit
[unit
]._ReallyEnabled
) {
2152 GLboolean needMatrix
= GL_FALSE
;
2153 if (ctx
->TextureMatrixStack
[unit
].Top
->type
!= MATRIX_IDENTITY
) {
2154 needMatrix
= GL_TRUE
;
2155 texMatEnabled
|= (RADEON_TEXGEN_TEXMAT_0_ENABLE
|
2156 RADEON_TEXMAT_0_ENABLE
) << unit
;
2158 if (rmesa
->TexGenEnabled
& (RADEON_TEXMAT_0_ENABLE
<< unit
)) {
2159 /* Need to preconcatenate any active texgen
2160 * obj/eyeplane matrices:
2162 _math_matrix_mul_matrix( &rmesa
->tmpmat
[unit
],
2163 ctx
->TextureMatrixStack
[unit
].Top
,
2164 &rmesa
->TexGenMatrix
[unit
] );
2167 _math_matrix_copy( &rmesa
->tmpmat
[unit
],
2168 ctx
->TextureMatrixStack
[unit
].Top
);
2171 else if (rmesa
->TexGenEnabled
& (RADEON_TEXMAT_0_ENABLE
<< unit
)) {
2172 _math_matrix_copy( &rmesa
->tmpmat
[unit
], &rmesa
->TexGenMatrix
[unit
] );
2173 needMatrix
= GL_TRUE
;
2175 if (ctx
->Texture
.Unit
[unit
]._ReallyEnabled
== TEXTURE_RECT_BIT
) {
2176 texMatEnabled
|= (RADEON_TEXGEN_TEXMAT_0_ENABLE
|
2177 RADEON_TEXMAT_0_ENABLE
) << unit
;
2179 texmat_fixup_texrect( rmesa
, ctx
->Texture
.Unit
[unit
]._Current
, unit
);
2181 texmat_set_texrect( rmesa
, ctx
->Texture
.Unit
[unit
]._Current
, unit
);
2182 needMatrix
= GL_TRUE
;
2185 rmesa
->NeedTexMatrix
|= 1 << unit
;
2186 radeonUploadTexMatrix( rmesa
, unit
,
2187 !ctx
->Texture
.Unit
[unit
].TexGenEnabled
);
2192 tpc
= (texMatEnabled
| rmesa
->TexGenEnabled
);
2194 /* TCL_TEX_COMPUTED_x is TCL_TEX_INPUT_x | 0x8 */
2195 vs
&= ~((RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_0_OUTPUT_SHIFT
) |
2196 (RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_1_OUTPUT_SHIFT
) |
2197 (RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_2_OUTPUT_SHIFT
));
2199 vs
|= (((tpc
& RADEON_TEXGEN_TEXMAT_0_ENABLE
) <<
2200 (RADEON_TCL_TEX_0_OUTPUT_SHIFT
+ 3)) |
2201 ((tpc
& RADEON_TEXGEN_TEXMAT_1_ENABLE
) <<
2202 (RADEON_TCL_TEX_1_OUTPUT_SHIFT
+ 2)) |
2203 ((tpc
& RADEON_TEXGEN_TEXMAT_2_ENABLE
) <<
2204 (RADEON_TCL_TEX_2_OUTPUT_SHIFT
+ 1)));
2206 if (tpc
!= rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
] ||
2207 vs
!= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
]) {
2209 RADEON_STATECHANGE(rmesa
, tcl
);
2210 rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
] = tpc
;
2211 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] = vs
;
2217 * Tell the card where to render (offset, pitch).
2218 * Effected by glDrawBuffer, etc
2221 radeonUpdateDrawBuffer(GLcontext
*ctx
)
2223 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2224 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
2225 driRenderbuffer
*drb
;
2227 if (fb
->_ColorDrawBufferMask
[0] == BUFFER_BIT_FRONT_LEFT
) {
2229 drb
= (driRenderbuffer
*) fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
;
2231 else if (fb
->_ColorDrawBufferMask
[0] == BUFFER_BIT_BACK_LEFT
) {
2233 drb
= (driRenderbuffer
*) fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
;
2236 /* drawing to multiple buffers, or none */
2241 assert(drb
->flippedPitch
);
2243 RADEON_STATECHANGE( rmesa
, ctx
);
2245 /* Note: we used the (possibly) page-flipped values */
2246 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLOROFFSET
]
2247 = ((drb
->flippedOffset
+ rmesa
->radeonScreen
->fbLocation
)
2248 & RADEON_COLOROFFSET_MASK
);
2249 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] = drb
->flippedPitch
;
2250 if (rmesa
->sarea
->tiling_enabled
) {
2251 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] |= RADEON_COLOR_TILE_ENABLE
;
2256 void radeonValidateState( GLcontext
*ctx
)
2258 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2259 GLuint new_state
= rmesa
->NewGLState
;
2261 if (new_state
& (_NEW_BUFFERS
| _NEW_COLOR
| _NEW_PIXEL
)) {
2262 radeonUpdateDrawBuffer(ctx
);
2265 if (new_state
& _NEW_TEXTURE
) {
2266 radeonUpdateTextureState( ctx
);
2267 new_state
|= rmesa
->NewGLState
; /* may add TEXTURE_MATRIX */
2270 /* Need an event driven matrix update?
2272 if (new_state
& (_NEW_MODELVIEW
|_NEW_PROJECTION
))
2273 upload_matrix( rmesa
, ctx
->_ModelProjectMatrix
.m
, MODEL_PROJ
);
2275 /* Need these for lighting (shouldn't upload otherwise)
2277 if (new_state
& (_NEW_MODELVIEW
)) {
2278 upload_matrix( rmesa
, ctx
->ModelviewMatrixStack
.Top
->m
, MODEL
);
2279 upload_matrix_t( rmesa
, ctx
->ModelviewMatrixStack
.Top
->inv
, MODEL_IT
);
2282 /* Does this need to be triggered on eg. modelview for
2283 * texgen-derived objplane/eyeplane matrices?
2285 if (new_state
& _NEW_TEXTURE_MATRIX
) {
2286 update_texturematrix( ctx
);
2289 if (new_state
& (_NEW_LIGHT
|_NEW_MODELVIEW
|_MESA_NEW_NEED_EYE_COORDS
)) {
2290 update_light( ctx
);
2293 /* emit all active clip planes if projection matrix changes.
2295 if (new_state
& (_NEW_PROJECTION
)) {
2296 if (ctx
->Transform
.ClipPlanesEnabled
)
2297 radeonUpdateClipPlanes( ctx
);
2301 rmesa
->NewGLState
= 0;
2305 static void radeonInvalidateState( GLcontext
*ctx
, GLuint new_state
)
2307 _swrast_InvalidateState( ctx
, new_state
);
2308 _swsetup_InvalidateState( ctx
, new_state
);
2309 _ac_InvalidateState( ctx
, new_state
);
2310 _tnl_InvalidateState( ctx
, new_state
);
2311 _ae_invalidate_state( ctx
, new_state
);
2312 RADEON_CONTEXT(ctx
)->NewGLState
|= new_state
;
2313 radeonVtxfmtInvalidate( ctx
);
2317 /* A hack. Need a faster way to find this out.
2319 static GLboolean
check_material( GLcontext
*ctx
)
2321 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
2324 for (i
= _TNL_ATTRIB_MAT_FRONT_AMBIENT
;
2325 i
< _TNL_ATTRIB_MAT_BACK_INDEXES
;
2327 if (tnl
->vb
.AttribPtr
[i
] &&
2328 tnl
->vb
.AttribPtr
[i
]->stride
)
2335 static void radeonWrapRunPipeline( GLcontext
*ctx
)
2337 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2338 GLboolean has_material
;
2341 fprintf(stderr
, "%s, newstate: %x\n", __FUNCTION__
, rmesa
->NewGLState
);
2345 if (rmesa
->NewGLState
)
2346 radeonValidateState( ctx
);
2348 has_material
= (ctx
->Light
.Enabled
&& check_material( ctx
));
2351 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_MATERIAL
, GL_TRUE
);
2354 /* Run the pipeline.
2356 _tnl_run_pipeline( ctx
);
2359 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_MATERIAL
, GL_FALSE
);
2364 /* Initialize the driver's state functions.
2365 * Many of the ctx->Driver functions might have been initialized to
2366 * software defaults in the earlier _mesa_init_driver_functions() call.
2368 void radeonInitStateFuncs( GLcontext
*ctx
)
2370 ctx
->Driver
.UpdateState
= radeonInvalidateState
;
2371 ctx
->Driver
.LightingSpaceChange
= radeonLightingSpaceChange
;
2373 ctx
->Driver
.DrawBuffer
= radeonDrawBuffer
;
2374 ctx
->Driver
.ReadBuffer
= radeonReadBuffer
;
2376 ctx
->Driver
.AlphaFunc
= radeonAlphaFunc
;
2377 ctx
->Driver
.BlendEquationSeparate
= radeonBlendEquationSeparate
;
2378 ctx
->Driver
.BlendFuncSeparate
= radeonBlendFuncSeparate
;
2379 ctx
->Driver
.ClearColor
= radeonClearColor
;
2380 ctx
->Driver
.ClearDepth
= radeonClearDepth
;
2381 ctx
->Driver
.ClearIndex
= NULL
;
2382 ctx
->Driver
.ClearStencil
= radeonClearStencil
;
2383 ctx
->Driver
.ClipPlane
= radeonClipPlane
;
2384 ctx
->Driver
.ColorMask
= radeonColorMask
;
2385 ctx
->Driver
.CullFace
= radeonCullFace
;
2386 ctx
->Driver
.DepthFunc
= radeonDepthFunc
;
2387 ctx
->Driver
.DepthMask
= radeonDepthMask
;
2388 ctx
->Driver
.DepthRange
= radeonDepthRange
;
2389 ctx
->Driver
.Enable
= radeonEnable
;
2390 ctx
->Driver
.Fogfv
= radeonFogfv
;
2391 ctx
->Driver
.FrontFace
= radeonFrontFace
;
2392 ctx
->Driver
.Hint
= NULL
;
2393 ctx
->Driver
.IndexMask
= NULL
;
2394 ctx
->Driver
.LightModelfv
= radeonLightModelfv
;
2395 ctx
->Driver
.Lightfv
= radeonLightfv
;
2396 ctx
->Driver
.LineStipple
= radeonLineStipple
;
2397 ctx
->Driver
.LineWidth
= radeonLineWidth
;
2398 ctx
->Driver
.LogicOpcode
= radeonLogicOpCode
;
2399 ctx
->Driver
.PolygonMode
= radeonPolygonMode
;
2400 ctx
->Driver
.PolygonOffset
= radeonPolygonOffset
;
2401 ctx
->Driver
.PolygonStipple
= radeonPolygonStipple
;
2402 ctx
->Driver
.RenderMode
= radeonRenderMode
;
2403 ctx
->Driver
.Scissor
= radeonScissor
;
2404 ctx
->Driver
.ShadeModel
= radeonShadeModel
;
2405 ctx
->Driver
.StencilFuncSeparate
= radeonStencilFuncSeparate
;
2406 ctx
->Driver
.StencilMaskSeparate
= radeonStencilMaskSeparate
;
2407 ctx
->Driver
.StencilOpSeparate
= radeonStencilOpSeparate
;
2408 ctx
->Driver
.Viewport
= radeonViewport
;
2410 TNL_CONTEXT(ctx
)->Driver
.NotifyMaterialChange
= radeonUpdateMaterial
;
2411 TNL_CONTEXT(ctx
)->Driver
.RunPipeline
= radeonWrapRunPipeline
;