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"
43 #include "framebuffer.h"
47 #include "tnl/t_pipeline.h"
48 #include "swrast_setup/swrast_setup.h"
50 #include "radeon_context.h"
51 #include "radeon_ioctl.h"
52 #include "radeon_state.h"
53 #include "radeon_tcl.h"
54 #include "radeon_tex.h"
55 #include "radeon_swtcl.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
.ColorLogicOpEnabled
|| (ctx
->Color
.BlendEnabled
139 && ctx
->Color
.BlendEquationRGB
== GL_LOGIC_OP
)) ) {
140 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
142 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
147 static void radeonBlendFuncSeparate( GLcontext
*ctx
,
148 GLenum sfactorRGB
, GLenum dfactorRGB
,
149 GLenum sfactorA
, GLenum dfactorA
)
151 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
152 GLuint b
= rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] &
153 ~(RADEON_SRC_BLEND_MASK
| RADEON_DST_BLEND_MASK
);
154 GLboolean fallback
= GL_FALSE
;
156 switch ( ctx
->Color
.BlendSrcRGB
) {
158 b
|= RADEON_SRC_BLEND_GL_ZERO
;
161 b
|= RADEON_SRC_BLEND_GL_ONE
;
164 b
|= RADEON_SRC_BLEND_GL_DST_COLOR
;
166 case GL_ONE_MINUS_DST_COLOR
:
167 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_COLOR
;
170 b
|= RADEON_SRC_BLEND_GL_SRC_COLOR
;
172 case GL_ONE_MINUS_SRC_COLOR
:
173 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR
;
176 b
|= RADEON_SRC_BLEND_GL_SRC_ALPHA
;
178 case GL_ONE_MINUS_SRC_ALPHA
:
179 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
182 b
|= RADEON_SRC_BLEND_GL_DST_ALPHA
;
184 case GL_ONE_MINUS_DST_ALPHA
:
185 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA
;
187 case GL_SRC_ALPHA_SATURATE
:
188 b
|= RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE
;
190 case GL_CONSTANT_COLOR
:
191 case GL_ONE_MINUS_CONSTANT_COLOR
:
192 case GL_CONSTANT_ALPHA
:
193 case GL_ONE_MINUS_CONSTANT_ALPHA
:
194 if (ctx
->Color
.BlendEnabled
)
197 b
|= RADEON_SRC_BLEND_GL_ONE
;
203 switch ( ctx
->Color
.BlendDstRGB
) {
205 b
|= RADEON_DST_BLEND_GL_ZERO
;
208 b
|= RADEON_DST_BLEND_GL_ONE
;
211 b
|= RADEON_DST_BLEND_GL_SRC_COLOR
;
213 case GL_ONE_MINUS_SRC_COLOR
:
214 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_COLOR
;
217 b
|= RADEON_DST_BLEND_GL_SRC_ALPHA
;
219 case GL_ONE_MINUS_SRC_ALPHA
:
220 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
223 b
|= RADEON_DST_BLEND_GL_DST_COLOR
;
225 case GL_ONE_MINUS_DST_COLOR
:
226 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_DST_COLOR
;
229 b
|= RADEON_DST_BLEND_GL_DST_ALPHA
;
231 case GL_ONE_MINUS_DST_ALPHA
:
232 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_DST_ALPHA
;
234 case GL_CONSTANT_COLOR
:
235 case GL_ONE_MINUS_CONSTANT_COLOR
:
236 case GL_CONSTANT_ALPHA
:
237 case GL_ONE_MINUS_CONSTANT_ALPHA
:
238 if (ctx
->Color
.BlendEnabled
)
241 b
|= RADEON_DST_BLEND_GL_ZERO
;
247 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_FUNC
, fallback
);
249 RADEON_STATECHANGE( rmesa
, ctx
);
250 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = b
;
255 /* =============================================================
259 static void radeonDepthFunc( GLcontext
*ctx
, GLenum func
)
261 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
263 RADEON_STATECHANGE( rmesa
, ctx
);
264 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_Z_TEST_MASK
;
266 switch ( ctx
->Depth
.Func
) {
268 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_NEVER
;
271 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_LESS
;
274 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_EQUAL
;
277 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_LEQUAL
;
280 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_GREATER
;
283 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_NEQUAL
;
286 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_GEQUAL
;
289 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_ALWAYS
;
295 static void radeonDepthMask( GLcontext
*ctx
, GLboolean flag
)
297 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
298 RADEON_STATECHANGE( rmesa
, ctx
);
300 if ( ctx
->Depth
.Mask
) {
301 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_WRITE_ENABLE
;
303 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_Z_WRITE_ENABLE
;
307 static void radeonClearDepth( GLcontext
*ctx
, GLclampd d
)
309 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
310 GLuint format
= (rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &
311 RADEON_DEPTH_FORMAT_MASK
);
314 case RADEON_DEPTH_FORMAT_16BIT_INT_Z
:
315 rmesa
->state
.depth
.clear
= d
* 0x0000ffff;
317 case RADEON_DEPTH_FORMAT_24BIT_INT_Z
:
318 rmesa
->state
.depth
.clear
= d
* 0x00ffffff;
324 /* =============================================================
329 static void radeonFogfv( GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
331 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
332 union { int i
; float f
; } c
, d
;
337 if (!ctx
->Fog
.Enabled
)
339 RADEON_STATECHANGE(rmesa
, tcl
);
340 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_TCL_FOG_MASK
;
341 switch (ctx
->Fog
.Mode
) {
343 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_LINEAR
;
346 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_EXP
;
349 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_EXP2
;
358 if (!ctx
->Fog
.Enabled
)
360 c
.i
= rmesa
->hw
.fog
.cmd
[FOG_C
];
361 d
.i
= rmesa
->hw
.fog
.cmd
[FOG_D
];
362 switch (ctx
->Fog
.Mode
) {
365 /* While this is the opposite sign from the DDK, it makes the fog test
366 * pass, and matches r200.
368 d
.f
= -ctx
->Fog
.Density
;
372 d
.f
= -(ctx
->Fog
.Density
* ctx
->Fog
.Density
);
375 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
379 c
.f
= ctx
->Fog
.End
/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
380 /* While this is the opposite sign from the DDK, it makes the fog
381 * test pass, and matches r200.
383 d
.f
= -1.0/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
389 if (c
.i
!= rmesa
->hw
.fog
.cmd
[FOG_C
] || d
.i
!= rmesa
->hw
.fog
.cmd
[FOG_D
]) {
390 RADEON_STATECHANGE( rmesa
, fog
);
391 rmesa
->hw
.fog
.cmd
[FOG_C
] = c
.i
;
392 rmesa
->hw
.fog
.cmd
[FOG_D
] = d
.i
;
396 RADEON_STATECHANGE( rmesa
, ctx
);
397 UNCLAMPED_FLOAT_TO_RGB_CHAN( col
, ctx
->Fog
.Color
);
398 rmesa
->hw
.ctx
.cmd
[CTX_PP_FOG_COLOR
] &= ~RADEON_FOG_COLOR_MASK
;
399 rmesa
->hw
.ctx
.cmd
[CTX_PP_FOG_COLOR
] |=
400 radeonPackColor( 4, col
[0], col
[1], col
[2], 0 );
402 case GL_FOG_COORD_SRC
:
403 radeonUpdateSpecular( ctx
);
411 /* =============================================================
416 static GLboolean
intersect_rect( drm_clip_rect_t
*out
,
421 if ( b
->x1
> out
->x1
) out
->x1
= b
->x1
;
422 if ( b
->y1
> out
->y1
) out
->y1
= b
->y1
;
423 if ( b
->x2
< out
->x2
) out
->x2
= b
->x2
;
424 if ( b
->y2
< out
->y2
) out
->y2
= b
->y2
;
425 if ( out
->x1
>= out
->x2
) return GL_FALSE
;
426 if ( out
->y1
>= out
->y2
) return GL_FALSE
;
431 void radeonRecalcScissorRects( radeonContextPtr rmesa
)
433 drm_clip_rect_t
*out
;
436 /* Grow cliprect store?
438 if (rmesa
->state
.scissor
.numAllocedClipRects
< rmesa
->numClipRects
) {
439 while (rmesa
->state
.scissor
.numAllocedClipRects
< rmesa
->numClipRects
) {
440 rmesa
->state
.scissor
.numAllocedClipRects
+= 1; /* zero case */
441 rmesa
->state
.scissor
.numAllocedClipRects
*= 2;
444 if (rmesa
->state
.scissor
.pClipRects
)
445 FREE(rmesa
->state
.scissor
.pClipRects
);
447 rmesa
->state
.scissor
.pClipRects
=
448 MALLOC( rmesa
->state
.scissor
.numAllocedClipRects
*
449 sizeof(drm_clip_rect_t
) );
451 if ( rmesa
->state
.scissor
.pClipRects
== NULL
) {
452 rmesa
->state
.scissor
.numAllocedClipRects
= 0;
457 out
= rmesa
->state
.scissor
.pClipRects
;
458 rmesa
->state
.scissor
.numClipRects
= 0;
460 for ( i
= 0 ; i
< rmesa
->numClipRects
; i
++ ) {
461 if ( intersect_rect( out
,
462 &rmesa
->pClipRects
[i
],
463 &rmesa
->state
.scissor
.rect
) ) {
464 rmesa
->state
.scissor
.numClipRects
++;
471 static void radeonUpdateScissor( GLcontext
*ctx
)
473 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
475 if ( rmesa
->dri
.drawable
) {
476 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
478 int x
= ctx
->Scissor
.X
;
479 int y
= dPriv
->h
- ctx
->Scissor
.Y
- ctx
->Scissor
.Height
;
480 int w
= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
- 1;
481 int h
= dPriv
->h
- ctx
->Scissor
.Y
- 1;
483 rmesa
->state
.scissor
.rect
.x1
= x
+ dPriv
->x
;
484 rmesa
->state
.scissor
.rect
.y1
= y
+ dPriv
->y
;
485 rmesa
->state
.scissor
.rect
.x2
= w
+ dPriv
->x
+ 1;
486 rmesa
->state
.scissor
.rect
.y2
= h
+ dPriv
->y
+ 1;
488 radeonRecalcScissorRects( rmesa
);
493 static void radeonScissor( GLcontext
*ctx
,
494 GLint x
, GLint y
, GLsizei w
, GLsizei h
)
496 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
498 if ( ctx
->Scissor
.Enabled
) {
499 RADEON_FIREVERTICES( rmesa
); /* don't pipeline cliprect changes */
500 radeonUpdateScissor( ctx
);
506 /* =============================================================
510 static void radeonCullFace( GLcontext
*ctx
, GLenum unused
)
512 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
513 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
514 GLuint t
= rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
];
516 s
|= RADEON_FFACE_SOLID
| RADEON_BFACE_SOLID
;
517 t
&= ~(RADEON_CULL_FRONT
| RADEON_CULL_BACK
);
519 if ( ctx
->Polygon
.CullFlag
) {
520 switch ( ctx
->Polygon
.CullFaceMode
) {
522 s
&= ~RADEON_FFACE_SOLID
;
523 t
|= RADEON_CULL_FRONT
;
526 s
&= ~RADEON_BFACE_SOLID
;
527 t
|= RADEON_CULL_BACK
;
529 case GL_FRONT_AND_BACK
:
530 s
&= ~(RADEON_FFACE_SOLID
| RADEON_BFACE_SOLID
);
531 t
|= (RADEON_CULL_FRONT
| RADEON_CULL_BACK
);
536 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
537 RADEON_STATECHANGE(rmesa
, set
);
538 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
541 if ( rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] != t
) {
542 RADEON_STATECHANGE(rmesa
, tcl
);
543 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] = t
;
547 static void radeonFrontFace( GLcontext
*ctx
, GLenum mode
)
549 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
551 RADEON_STATECHANGE( rmesa
, set
);
552 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_FFACE_CULL_DIR_MASK
;
554 RADEON_STATECHANGE( rmesa
, tcl
);
555 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_CULL_FRONT_IS_CCW
;
559 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_FFACE_CULL_CW
;
562 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_FFACE_CULL_CCW
;
563 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_CULL_FRONT_IS_CCW
;
569 /* =============================================================
572 static void radeonLineWidth( GLcontext
*ctx
, GLfloat widthf
)
574 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
576 RADEON_STATECHANGE( rmesa
, lin
);
577 RADEON_STATECHANGE( rmesa
, set
);
579 /* Line width is stored in U6.4 format.
581 rmesa
->hw
.lin
.cmd
[LIN_SE_LINE_WIDTH
] = (GLuint
)(widthf
* 16.0);
582 if ( widthf
> 1.0 ) {
583 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_WIDELINE_ENABLE
;
585 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_WIDELINE_ENABLE
;
589 static void radeonLineStipple( GLcontext
*ctx
, GLint factor
, GLushort pattern
)
591 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
593 RADEON_STATECHANGE( rmesa
, lin
);
594 rmesa
->hw
.lin
.cmd
[LIN_RE_LINE_PATTERN
] =
595 ((((GLuint
)factor
& 0xff) << 16) | ((GLuint
)pattern
));
599 /* =============================================================
602 static void radeonColorMask( GLcontext
*ctx
,
603 GLboolean r
, GLboolean g
,
604 GLboolean b
, GLboolean a
)
606 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
607 GLuint mask
= radeonPackColor( rmesa
->radeonScreen
->cpp
,
608 ctx
->Color
.ColorMask
[RCOMP
],
609 ctx
->Color
.ColorMask
[GCOMP
],
610 ctx
->Color
.ColorMask
[BCOMP
],
611 ctx
->Color
.ColorMask
[ACOMP
] );
613 if ( rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] != mask
) {
614 RADEON_STATECHANGE( rmesa
, msk
);
615 rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] = mask
;
620 /* =============================================================
624 static void radeonPolygonOffset( GLcontext
*ctx
,
625 GLfloat factor
, GLfloat units
)
627 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
628 float_ui32_type constant
= { units
* rmesa
->state
.depth
.scale
};
629 float_ui32_type factoru
= { factor
};
631 RADEON_STATECHANGE( rmesa
, zbs
);
632 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_FACTOR
] = factoru
.ui32
;
633 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_CONSTANT
] = constant
.ui32
;
636 static void radeonPolygonStipple( GLcontext
*ctx
, const GLubyte
*mask
)
638 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
640 drm_radeon_stipple_t stipple
;
642 /* Must flip pattern upside down.
644 for ( i
= 0 ; i
< 32 ; i
++ ) {
645 rmesa
->state
.stipple
.mask
[31 - i
] = ((GLuint
*) mask
)[i
];
648 /* TODO: push this into cmd mechanism
650 RADEON_FIREVERTICES( rmesa
);
651 LOCK_HARDWARE( rmesa
);
653 /* FIXME: Use window x,y offsets into stipple RAM.
655 stipple
.mask
= rmesa
->state
.stipple
.mask
;
656 drmCommandWrite( rmesa
->dri
.fd
, DRM_RADEON_STIPPLE
,
657 &stipple
, sizeof(drm_radeon_stipple_t
) );
658 UNLOCK_HARDWARE( rmesa
);
661 static void radeonPolygonMode( GLcontext
*ctx
, GLenum face
, GLenum mode
)
663 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
664 GLboolean flag
= (ctx
->_TriangleCaps
& DD_TRI_UNFILLED
) != 0;
666 /* Can't generally do unfilled via tcl, but some good special
669 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_UNFILLED
, flag
);
670 if (rmesa
->TclFallback
) {
671 radeonChooseRenderState( ctx
);
672 radeonChooseVertexState( ctx
);
677 /* =============================================================
678 * Rendering attributes
680 * We really don't want to recalculate all this every time we bind a
681 * texture. These things shouldn't change all that often, so it makes
682 * sense to break them out of the core texture state update routines.
685 /* Examine lighting and texture state to determine if separate specular
688 static void radeonUpdateSpecular( GLcontext
*ctx
)
690 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
691 u_int32_t p
= rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
];
694 RADEON_STATECHANGE( rmesa
, tcl
);
696 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &= ~RADEON_TCL_COMPUTE_SPECULAR
;
697 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &= ~RADEON_TCL_COMPUTE_DIFFUSE
;
698 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &= ~RADEON_TCL_VTX_PK_SPEC
;
699 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &= ~RADEON_TCL_VTX_PK_DIFFUSE
;
700 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_LIGHTING_ENABLE
;
702 p
&= ~RADEON_SPECULAR_ENABLE
;
704 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_DIFFUSE_SPECULAR_COMBINE
;
707 if (ctx
->Light
.Enabled
&&
708 ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
) {
709 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_SPECULAR
;
710 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_DIFFUSE
;
711 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
712 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
713 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
714 p
|= RADEON_SPECULAR_ENABLE
;
715 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &=
716 ~RADEON_DIFFUSE_SPECULAR_COMBINE
;
718 else if (ctx
->Light
.Enabled
) {
719 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_DIFFUSE
;
720 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
721 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
722 } else if (ctx
->Fog
.ColorSumEnabled
) {
723 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
724 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
725 p
|= RADEON_SPECULAR_ENABLE
;
727 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
730 if (ctx
->Fog
.Enabled
) {
731 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
732 if (ctx
->Fog
.FogCoordinateSource
== GL_FRAGMENT_DEPTH
) {
733 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_SPECULAR
;
734 /* Bizzare: have to leave lighting enabled to get fog. */
735 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
738 /* cannot do tcl fog factor calculation with fog coord source
739 * (send precomputed factors). Cannot use precomputed fog
740 * factors together with tcl spec light (need tcl fallback) */
741 flag
= (rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &
742 RADEON_TCL_COMPUTE_SPECULAR
) != 0;
746 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_FOGCOORDSPEC
, flag
);
748 if (NEED_SECONDARY_COLOR(ctx
)) {
749 assert( (p
& RADEON_SPECULAR_ENABLE
) != 0 );
751 assert( (p
& RADEON_SPECULAR_ENABLE
) == 0 );
754 if ( rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] != p
) {
755 RADEON_STATECHANGE( rmesa
, ctx
);
756 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] = p
;
759 /* Update vertex/render formats
761 if (rmesa
->TclFallback
) {
762 radeonChooseRenderState( ctx
);
763 radeonChooseVertexState( ctx
);
768 /* =============================================================
773 /* Update on colormaterial, material emmissive/ambient,
774 * lightmodel.globalambient
776 static void update_global_ambient( GLcontext
*ctx
)
778 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
779 float *fcmd
= (float *)RADEON_DB_STATE( glt
);
781 /* Need to do more if both emmissive & ambient are PREMULT:
782 * Hope this is not needed for MULT
784 if ((rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &
785 ((3 << RADEON_EMISSIVE_SOURCE_SHIFT
) |
786 (3 << RADEON_AMBIENT_SOURCE_SHIFT
))) == 0)
788 COPY_3V( &fcmd
[GLT_RED
],
789 ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_EMISSION
]);
790 ACC_SCALE_3V( &fcmd
[GLT_RED
],
791 ctx
->Light
.Model
.Ambient
,
792 ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_AMBIENT
]);
796 COPY_3V( &fcmd
[GLT_RED
], ctx
->Light
.Model
.Ambient
);
799 RADEON_DB_STATECHANGE(rmesa
, &rmesa
->hw
.glt
);
802 /* Update on change to
806 static void update_light_colors( GLcontext
*ctx
, GLuint p
)
808 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
810 /* fprintf(stderr, "%s\n", __FUNCTION__); */
813 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
814 float *fcmd
= (float *)RADEON_DB_STATE( lit
[p
] );
816 COPY_4V( &fcmd
[LIT_AMBIENT_RED
], l
->Ambient
);
817 COPY_4V( &fcmd
[LIT_DIFFUSE_RED
], l
->Diffuse
);
818 COPY_4V( &fcmd
[LIT_SPECULAR_RED
], l
->Specular
);
820 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
824 /* Also fallback for asym colormaterial mode in twoside lighting...
826 static void check_twoside_fallback( GLcontext
*ctx
)
828 GLboolean fallback
= GL_FALSE
;
831 if (ctx
->Light
.Enabled
&& ctx
->Light
.Model
.TwoSide
) {
832 if (ctx
->Light
.ColorMaterialEnabled
&&
833 (ctx
->Light
.ColorMaterialBitmask
& BACK_MATERIAL_BITS
) !=
834 ((ctx
->Light
.ColorMaterialBitmask
& FRONT_MATERIAL_BITS
)<<1))
837 for (i
= MAT_ATTRIB_FRONT_AMBIENT
; i
< MAT_ATTRIB_FRONT_INDEXES
; i
+=2)
838 if (memcmp( ctx
->Light
.Material
.Attrib
[i
],
839 ctx
->Light
.Material
.Attrib
[i
+1],
840 sizeof(GLfloat
)*4) != 0) {
847 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_LIGHT_TWOSIDE
, fallback
);
851 static void radeonColorMaterial( GLcontext
*ctx
, GLenum face
, GLenum mode
)
853 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
854 GLuint light_model_ctl1
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
];
856 light_model_ctl1
&= ~((3 << RADEON_EMISSIVE_SOURCE_SHIFT
) |
857 (3 << RADEON_AMBIENT_SOURCE_SHIFT
) |
858 (3 << RADEON_DIFFUSE_SOURCE_SHIFT
) |
859 (3 << RADEON_SPECULAR_SOURCE_SHIFT
));
861 if (ctx
->Light
.ColorMaterialEnabled
) {
862 GLuint mask
= ctx
->Light
.ColorMaterialBitmask
;
864 if (mask
& MAT_BIT_FRONT_EMISSION
) {
865 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
866 RADEON_EMISSIVE_SOURCE_SHIFT
);
869 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
870 RADEON_EMISSIVE_SOURCE_SHIFT
);
873 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
874 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
875 RADEON_AMBIENT_SOURCE_SHIFT
);
878 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
879 RADEON_AMBIENT_SOURCE_SHIFT
);
882 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
883 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
884 RADEON_DIFFUSE_SOURCE_SHIFT
);
887 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
888 RADEON_DIFFUSE_SOURCE_SHIFT
);
891 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
892 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
893 RADEON_SPECULAR_SOURCE_SHIFT
);
896 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
897 RADEON_SPECULAR_SOURCE_SHIFT
);
903 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_EMISSIVE_SOURCE_SHIFT
) |
904 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_AMBIENT_SOURCE_SHIFT
) |
905 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_DIFFUSE_SOURCE_SHIFT
) |
906 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_SPECULAR_SOURCE_SHIFT
);
909 if (light_model_ctl1
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]) {
910 RADEON_STATECHANGE( rmesa
, tcl
);
911 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] = light_model_ctl1
;
915 void radeonUpdateMaterial( GLcontext
*ctx
)
917 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
918 GLfloat (*mat
)[4] = ctx
->Light
.Material
.Attrib
;
919 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( mtl
);
922 if (ctx
->Light
.ColorMaterialEnabled
)
923 mask
&= ~ctx
->Light
.ColorMaterialBitmask
;
925 if (RADEON_DEBUG
& DEBUG_STATE
)
926 fprintf(stderr
, "%s\n", __FUNCTION__
);
929 if (mask
& MAT_BIT_FRONT_EMISSION
) {
930 fcmd
[MTL_EMMISSIVE_RED
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][0];
931 fcmd
[MTL_EMMISSIVE_GREEN
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][1];
932 fcmd
[MTL_EMMISSIVE_BLUE
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][2];
933 fcmd
[MTL_EMMISSIVE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][3];
935 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
936 fcmd
[MTL_AMBIENT_RED
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][0];
937 fcmd
[MTL_AMBIENT_GREEN
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][1];
938 fcmd
[MTL_AMBIENT_BLUE
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][2];
939 fcmd
[MTL_AMBIENT_ALPHA
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][3];
941 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
942 fcmd
[MTL_DIFFUSE_RED
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][0];
943 fcmd
[MTL_DIFFUSE_GREEN
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][1];
944 fcmd
[MTL_DIFFUSE_BLUE
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][2];
945 fcmd
[MTL_DIFFUSE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][3];
947 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
948 fcmd
[MTL_SPECULAR_RED
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][0];
949 fcmd
[MTL_SPECULAR_GREEN
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][1];
950 fcmd
[MTL_SPECULAR_BLUE
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][2];
951 fcmd
[MTL_SPECULAR_ALPHA
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][3];
953 if (mask
& MAT_BIT_FRONT_SHININESS
) {
954 fcmd
[MTL_SHININESS
] = mat
[MAT_ATTRIB_FRONT_SHININESS
][0];
957 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mtl
);
959 check_twoside_fallback( ctx
);
960 /* update_global_ambient( ctx );*/
965 * _MESA_NEW_NEED_EYE_COORDS
967 * Uses derived state from mesa:
976 * which are calculated in light.c and are correct for the current
977 * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW
978 * and _MESA_NEW_NEED_EYE_COORDS.
980 static void update_light( GLcontext
*ctx
)
982 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
984 /* Have to check these, or have an automatic shortcircuit mechanism
985 * to remove noop statechanges. (Or just do a better job on the
989 GLuint tmp
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
];
991 if (ctx
->_NeedEyeCoords
)
992 tmp
&= ~RADEON_LIGHT_IN_MODELSPACE
;
994 tmp
|= RADEON_LIGHT_IN_MODELSPACE
;
997 /* Leave this test disabled: (unexplained q3 lockup) (even with
1000 if (tmp
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
])
1002 RADEON_STATECHANGE( rmesa
, tcl
);
1003 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] = tmp
;
1008 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( eye
);
1009 fcmd
[EYE_X
] = ctx
->_EyeZDir
[0];
1010 fcmd
[EYE_Y
] = ctx
->_EyeZDir
[1];
1011 fcmd
[EYE_Z
] = - ctx
->_EyeZDir
[2];
1012 fcmd
[EYE_RESCALE_FACTOR
] = ctx
->_ModelViewInvScale
;
1013 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.eye
);
1018 if (ctx
->Light
.Enabled
) {
1020 for (p
= 0 ; p
< MAX_LIGHTS
; p
++) {
1021 if (ctx
->Light
.Light
[p
].Enabled
) {
1022 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
1023 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( lit
[p
] );
1025 if (l
->EyePosition
[3] == 0.0) {
1026 COPY_3FV( &fcmd
[LIT_POSITION_X
], l
->_VP_inf_norm
);
1027 COPY_3FV( &fcmd
[LIT_DIRECTION_X
], l
->_h_inf_norm
);
1028 fcmd
[LIT_POSITION_W
] = 0;
1029 fcmd
[LIT_DIRECTION_W
] = 0;
1031 COPY_4V( &fcmd
[LIT_POSITION_X
], l
->_Position
);
1032 fcmd
[LIT_DIRECTION_X
] = -l
->_NormDirection
[0];
1033 fcmd
[LIT_DIRECTION_Y
] = -l
->_NormDirection
[1];
1034 fcmd
[LIT_DIRECTION_Z
] = -l
->_NormDirection
[2];
1035 fcmd
[LIT_DIRECTION_W
] = 0;
1038 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
1044 static void radeonLightfv( GLcontext
*ctx
, GLenum light
,
1045 GLenum pname
, const GLfloat
*params
)
1047 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1048 GLint p
= light
- GL_LIGHT0
;
1049 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
1050 GLfloat
*fcmd
= (GLfloat
*)rmesa
->hw
.lit
[p
].cmd
;
1057 update_light_colors( ctx
, p
);
1060 case GL_SPOT_DIRECTION
:
1061 /* picked up in update_light */
1065 /* positions picked up in update_light, but can do flag here */
1067 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1069 /* FIXME: Set RANGE_ATTEN only when needed */
1071 flag
= RADEON_LIGHT_1_IS_LOCAL
;
1073 flag
= RADEON_LIGHT_0_IS_LOCAL
;
1075 RADEON_STATECHANGE(rmesa
, tcl
);
1076 if (l
->EyePosition
[3] != 0.0F
)
1077 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
1079 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
1083 case GL_SPOT_EXPONENT
:
1084 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1085 fcmd
[LIT_SPOT_EXPONENT
] = params
[0];
1088 case GL_SPOT_CUTOFF
: {
1089 GLuint flag
= (p
&1) ? RADEON_LIGHT_1_IS_SPOT
: RADEON_LIGHT_0_IS_SPOT
;
1090 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1092 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1093 fcmd
[LIT_SPOT_CUTOFF
] = l
->_CosCutoff
;
1095 RADEON_STATECHANGE(rmesa
, tcl
);
1096 if (l
->SpotCutoff
!= 180.0F
)
1097 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
1099 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
1104 case GL_CONSTANT_ATTENUATION
:
1105 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1106 fcmd
[LIT_ATTEN_CONST
] = params
[0];
1107 if ( params
[0] == 0.0 )
1108 fcmd
[LIT_ATTEN_CONST_INV
] = FLT_MAX
;
1110 fcmd
[LIT_ATTEN_CONST_INV
] = 1.0 / params
[0];
1112 case GL_LINEAR_ATTENUATION
:
1113 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1114 fcmd
[LIT_ATTEN_LINEAR
] = params
[0];
1116 case GL_QUADRATIC_ATTENUATION
:
1117 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1118 fcmd
[LIT_ATTEN_QUADRATIC
] = params
[0];
1124 /* Set RANGE_ATTEN only when needed */
1127 case GL_CONSTANT_ATTENUATION
:
1128 case GL_LINEAR_ATTENUATION
:
1129 case GL_QUADRATIC_ATTENUATION
:
1131 GLuint
*icmd
= (GLuint
*)RADEON_DB_STATE( tcl
);
1132 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1133 GLuint atten_flag
= ( p
&1 ) ? RADEON_LIGHT_1_ENABLE_RANGE_ATTEN
1134 : RADEON_LIGHT_0_ENABLE_RANGE_ATTEN
;
1135 GLuint atten_const_flag
= ( p
&1 ) ? RADEON_LIGHT_1_CONSTANT_RANGE_ATTEN
1136 : RADEON_LIGHT_0_CONSTANT_RANGE_ATTEN
;
1138 if ( l
->EyePosition
[3] == 0.0F
||
1139 ( ( fcmd
[LIT_ATTEN_CONST
] == 0.0 || fcmd
[LIT_ATTEN_CONST
] == 1.0 ) &&
1140 fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) ) {
1141 /* Disable attenuation */
1142 icmd
[idx
] &= ~atten_flag
;
1144 if ( fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) {
1145 /* Enable only constant portion of attenuation calculation */
1146 icmd
[idx
] |= ( atten_flag
| atten_const_flag
);
1148 /* Enable full attenuation calculation */
1149 icmd
[idx
] &= ~atten_const_flag
;
1150 icmd
[idx
] |= atten_flag
;
1154 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.tcl
);
1165 static void radeonLightModelfv( GLcontext
*ctx
, GLenum pname
,
1166 const GLfloat
*param
)
1168 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1171 case GL_LIGHT_MODEL_AMBIENT
:
1172 update_global_ambient( ctx
);
1175 case GL_LIGHT_MODEL_LOCAL_VIEWER
:
1176 RADEON_STATECHANGE( rmesa
, tcl
);
1177 if (ctx
->Light
.Model
.LocalViewer
)
1178 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LOCAL_VIEWER
;
1180 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_LOCAL_VIEWER
;
1183 case GL_LIGHT_MODEL_TWO_SIDE
:
1184 RADEON_STATECHANGE( rmesa
, tcl
);
1185 if (ctx
->Light
.Model
.TwoSide
)
1186 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_LIGHT_TWOSIDE
;
1188 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_LIGHT_TWOSIDE
;
1190 check_twoside_fallback( ctx
);
1192 if (rmesa
->TclFallback
) {
1193 radeonChooseRenderState( ctx
);
1194 radeonChooseVertexState( ctx
);
1198 case GL_LIGHT_MODEL_COLOR_CONTROL
:
1199 radeonUpdateSpecular(ctx
);
1207 static void radeonShadeModel( GLcontext
*ctx
, GLenum mode
)
1209 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1210 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
1212 s
&= ~(RADEON_DIFFUSE_SHADE_MASK
|
1213 RADEON_ALPHA_SHADE_MASK
|
1214 RADEON_SPECULAR_SHADE_MASK
|
1215 RADEON_FOG_SHADE_MASK
);
1219 s
|= (RADEON_DIFFUSE_SHADE_FLAT
|
1220 RADEON_ALPHA_SHADE_FLAT
|
1221 RADEON_SPECULAR_SHADE_FLAT
|
1222 RADEON_FOG_SHADE_FLAT
);
1225 s
|= (RADEON_DIFFUSE_SHADE_GOURAUD
|
1226 RADEON_ALPHA_SHADE_GOURAUD
|
1227 RADEON_SPECULAR_SHADE_GOURAUD
|
1228 RADEON_FOG_SHADE_GOURAUD
);
1234 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
1235 RADEON_STATECHANGE( rmesa
, set
);
1236 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
1241 /* =============================================================
1245 static void radeonClipPlane( GLcontext
*ctx
, GLenum plane
, const GLfloat
*eq
)
1247 GLint p
= (GLint
) plane
- (GLint
) GL_CLIP_PLANE0
;
1248 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1249 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1251 RADEON_STATECHANGE( rmesa
, ucp
[p
] );
1252 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1253 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1254 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1255 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1258 static void radeonUpdateClipPlanes( GLcontext
*ctx
)
1260 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1263 for (p
= 0; p
< ctx
->Const
.MaxClipPlanes
; p
++) {
1264 if (ctx
->Transform
.ClipPlanesEnabled
& (1 << p
)) {
1265 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1267 RADEON_STATECHANGE( rmesa
, ucp
[p
] );
1268 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1269 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1270 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1271 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1277 /* =============================================================
1282 radeonStencilFuncSeparate( GLcontext
*ctx
, GLenum face
, GLenum func
,
1283 GLint ref
, GLuint mask
)
1285 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1286 GLuint refmask
= (((ctx
->Stencil
.Ref
[0] & 0xff) << RADEON_STENCIL_REF_SHIFT
) |
1287 ((ctx
->Stencil
.ValueMask
[0] & 0xff) << RADEON_STENCIL_MASK_SHIFT
));
1289 RADEON_STATECHANGE( rmesa
, ctx
);
1290 RADEON_STATECHANGE( rmesa
, msk
);
1292 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_STENCIL_TEST_MASK
;
1293 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~(RADEON_STENCIL_REF_MASK
|
1294 RADEON_STENCIL_VALUE_MASK
);
1296 switch ( ctx
->Stencil
.Function
[0] ) {
1298 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_NEVER
;
1301 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_LESS
;
1304 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_EQUAL
;
1307 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_LEQUAL
;
1310 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_GREATER
;
1313 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_NEQUAL
;
1316 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_GEQUAL
;
1319 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_ALWAYS
;
1323 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |= refmask
;
1327 radeonStencilMaskSeparate( GLcontext
*ctx
, GLenum face
, GLuint mask
)
1329 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1331 RADEON_STATECHANGE( rmesa
, msk
);
1332 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~RADEON_STENCIL_WRITE_MASK
;
1333 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |=
1334 ((ctx
->Stencil
.WriteMask
[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT
);
1337 static void radeonStencilOpSeparate( GLcontext
*ctx
, GLenum face
, GLenum fail
,
1338 GLenum zfail
, GLenum zpass
)
1340 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1342 /* radeon 7200 have stencil bug, DEC and INC_WRAP will actually both do DEC_WRAP,
1343 and DEC_WRAP (and INVERT) will do INVERT. No way to get correct INC_WRAP and DEC,
1344 but DEC_WRAP can be fixed by using DEC and INC_WRAP at least use INC. */
1346 GLuint tempRADEON_STENCIL_FAIL_DEC_WRAP
;
1347 GLuint tempRADEON_STENCIL_FAIL_INC_WRAP
;
1348 GLuint tempRADEON_STENCIL_ZFAIL_DEC_WRAP
;
1349 GLuint tempRADEON_STENCIL_ZFAIL_INC_WRAP
;
1350 GLuint tempRADEON_STENCIL_ZPASS_DEC_WRAP
;
1351 GLuint tempRADEON_STENCIL_ZPASS_INC_WRAP
;
1353 if (rmesa
->radeonScreen
->chip_flags
& RADEON_CHIPSET_BROKEN_STENCIL
) {
1354 tempRADEON_STENCIL_FAIL_DEC_WRAP
= RADEON_STENCIL_FAIL_DEC
;
1355 tempRADEON_STENCIL_FAIL_INC_WRAP
= RADEON_STENCIL_FAIL_INC
;
1356 tempRADEON_STENCIL_ZFAIL_DEC_WRAP
= RADEON_STENCIL_ZFAIL_DEC
;
1357 tempRADEON_STENCIL_ZFAIL_INC_WRAP
= RADEON_STENCIL_ZFAIL_INC
;
1358 tempRADEON_STENCIL_ZPASS_DEC_WRAP
= RADEON_STENCIL_ZPASS_DEC
;
1359 tempRADEON_STENCIL_ZPASS_INC_WRAP
= RADEON_STENCIL_ZPASS_INC
;
1362 tempRADEON_STENCIL_FAIL_DEC_WRAP
= RADEON_STENCIL_FAIL_DEC_WRAP
;
1363 tempRADEON_STENCIL_FAIL_INC_WRAP
= RADEON_STENCIL_FAIL_INC_WRAP
;
1364 tempRADEON_STENCIL_ZFAIL_DEC_WRAP
= RADEON_STENCIL_ZFAIL_DEC_WRAP
;
1365 tempRADEON_STENCIL_ZFAIL_INC_WRAP
= RADEON_STENCIL_ZFAIL_INC_WRAP
;
1366 tempRADEON_STENCIL_ZPASS_DEC_WRAP
= RADEON_STENCIL_ZPASS_DEC_WRAP
;
1367 tempRADEON_STENCIL_ZPASS_INC_WRAP
= RADEON_STENCIL_ZPASS_INC_WRAP
;
1370 RADEON_STATECHANGE( rmesa
, ctx
);
1371 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~(RADEON_STENCIL_FAIL_MASK
|
1372 RADEON_STENCIL_ZFAIL_MASK
|
1373 RADEON_STENCIL_ZPASS_MASK
);
1375 switch ( ctx
->Stencil
.FailFunc
[0] ) {
1377 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_KEEP
;
1380 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_ZERO
;
1383 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_REPLACE
;
1386 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_INC
;
1389 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_DEC
;
1392 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_FAIL_INC_WRAP
;
1395 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_FAIL_DEC_WRAP
;
1398 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_INVERT
;
1402 switch ( ctx
->Stencil
.ZFailFunc
[0] ) {
1404 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_KEEP
;
1407 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_ZERO
;
1410 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_REPLACE
;
1413 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_INC
;
1416 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_DEC
;
1419 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZFAIL_INC_WRAP
;
1422 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZFAIL_DEC_WRAP
;
1425 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_INVERT
;
1429 switch ( ctx
->Stencil
.ZPassFunc
[0] ) {
1431 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_KEEP
;
1434 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_ZERO
;
1437 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_REPLACE
;
1440 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_INC
;
1443 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_DEC
;
1446 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZPASS_INC_WRAP
;
1449 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZPASS_DEC_WRAP
;
1452 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_INVERT
;
1457 static void radeonClearStencil( GLcontext
*ctx
, GLint s
)
1459 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1461 rmesa
->state
.stencil
.clear
=
1462 ((GLuint
) (ctx
->Stencil
.Clear
& 0xff) |
1463 (0xff << RADEON_STENCIL_MASK_SHIFT
) |
1464 ((ctx
->Stencil
.WriteMask
[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT
));
1468 /* =============================================================
1469 * Window position and viewport transformation
1473 * To correctly position primitives:
1475 #define SUBPIXEL_X 0.125
1476 #define SUBPIXEL_Y 0.125
1480 * Called when window size or position changes or viewport or depth range
1481 * state is changed. We update the hardware viewport state here.
1483 void radeonUpdateWindow( GLcontext
*ctx
)
1485 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1486 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
1487 GLfloat xoffset
= (GLfloat
)dPriv
->x
;
1488 GLfloat yoffset
= (GLfloat
)dPriv
->y
+ dPriv
->h
;
1489 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1491 float_ui32_type sx
= { v
[MAT_SX
] };
1492 float_ui32_type tx
= { v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
};
1493 float_ui32_type sy
= { - v
[MAT_SY
] };
1494 float_ui32_type ty
= { (- v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
};
1495 float_ui32_type sz
= { v
[MAT_SZ
] * rmesa
->state
.depth
.scale
};
1496 float_ui32_type tz
= { v
[MAT_TZ
] * rmesa
->state
.depth
.scale
};
1498 RADEON_FIREVERTICES( rmesa
);
1499 RADEON_STATECHANGE( rmesa
, vpt
);
1501 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XSCALE
] = sx
.ui32
;
1502 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = tx
.ui32
;
1503 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YSCALE
] = sy
.ui32
;
1504 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = ty
.ui32
;
1505 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZSCALE
] = sz
.ui32
;
1506 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZOFFSET
] = tz
.ui32
;
1510 static void radeonViewport( GLcontext
*ctx
, GLint x
, GLint y
,
1511 GLsizei width
, GLsizei height
)
1513 /* Don't pipeline viewport changes, conflict with window offset
1514 * setting below. Could apply deltas to rescue pipelined viewport
1515 * values, or keep the originals hanging around.
1517 radeonUpdateWindow( ctx
);
1520 static void radeonDepthRange( GLcontext
*ctx
, GLclampd nearval
,
1523 radeonUpdateWindow( ctx
);
1526 void radeonUpdateViewportOffset( GLcontext
*ctx
)
1528 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1529 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
1530 GLfloat xoffset
= (GLfloat
)dPriv
->x
;
1531 GLfloat yoffset
= (GLfloat
)dPriv
->y
+ dPriv
->h
;
1532 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1537 tx
.f
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1538 ty
.f
= (- v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1540 if ( rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] != tx
.ui32
||
1541 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] != ty
.ui32
)
1543 /* Note: this should also modify whatever data the context reset
1546 RADEON_STATECHANGE( rmesa
, vpt
);
1547 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = tx
.ui32
;
1548 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = ty
.ui32
;
1550 /* update polygon stipple x/y screen offset */
1553 GLuint m
= rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
];
1555 m
&= ~(RADEON_STIPPLE_X_OFFSET_MASK
|
1556 RADEON_STIPPLE_Y_OFFSET_MASK
);
1558 /* add magic offsets, then invert */
1559 stx
= 31 - ((rmesa
->dri
.drawable
->x
- 1) & RADEON_STIPPLE_COORD_MASK
);
1560 sty
= 31 - ((rmesa
->dri
.drawable
->y
+ rmesa
->dri
.drawable
->h
- 1)
1561 & RADEON_STIPPLE_COORD_MASK
);
1563 m
|= ((stx
<< RADEON_STIPPLE_X_OFFSET_SHIFT
) |
1564 (sty
<< RADEON_STIPPLE_Y_OFFSET_SHIFT
));
1566 if ( rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
] != m
) {
1567 RADEON_STATECHANGE( rmesa
, msc
);
1568 rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
] = m
;
1573 radeonUpdateScissor( ctx
);
1578 /* =============================================================
1582 static void radeonClearColor( GLcontext
*ctx
, const GLfloat color
[4] )
1584 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1586 CLAMPED_FLOAT_TO_UBYTE(c
[0], color
[0]);
1587 CLAMPED_FLOAT_TO_UBYTE(c
[1], color
[1]);
1588 CLAMPED_FLOAT_TO_UBYTE(c
[2], color
[2]);
1589 CLAMPED_FLOAT_TO_UBYTE(c
[3], color
[3]);
1590 rmesa
->state
.color
.clear
= radeonPackColor( rmesa
->radeonScreen
->cpp
,
1591 c
[0], c
[1], c
[2], c
[3] );
1595 static void radeonRenderMode( GLcontext
*ctx
, GLenum mode
)
1597 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1598 FALLBACK( rmesa
, RADEON_FALLBACK_RENDER_MODE
, (mode
!= GL_RENDER
) );
1602 static GLuint radeon_rop_tab
[] = {
1605 RADEON_ROP_AND_REVERSE
,
1607 RADEON_ROP_AND_INVERTED
,
1614 RADEON_ROP_OR_REVERSE
,
1615 RADEON_ROP_COPY_INVERTED
,
1616 RADEON_ROP_OR_INVERTED
,
1621 static void radeonLogicOpCode( GLcontext
*ctx
, GLenum opcode
)
1623 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1624 GLuint rop
= (GLuint
)opcode
- GL_CLEAR
;
1628 RADEON_STATECHANGE( rmesa
, msk
);
1629 rmesa
->hw
.msk
.cmd
[MSK_RB3D_ROPCNTL
] = radeon_rop_tab
[rop
];
1634 * Set up the cliprects for either front or back-buffer drawing.
1636 void radeonSetCliprects( radeonContextPtr rmesa
)
1638 __DRIdrawablePrivate
*const drawable
= rmesa
->dri
.drawable
;
1639 __DRIdrawablePrivate
*const readable
= rmesa
->dri
.readable
;
1640 GLframebuffer
*const draw_fb
= (GLframebuffer
*) drawable
->driverPrivate
;
1641 GLframebuffer
*const read_fb
= (GLframebuffer
*) readable
->driverPrivate
;
1643 if (draw_fb
->_ColorDrawBufferMask
[0]
1644 == BUFFER_BIT_BACK_LEFT
) {
1645 /* Can't ignore 2d windows if we are page flipping.
1647 if ( drawable
->numBackClipRects
== 0 || rmesa
->doPageFlip
) {
1648 rmesa
->numClipRects
= drawable
->numClipRects
;
1649 rmesa
->pClipRects
= drawable
->pClipRects
;
1652 rmesa
->numClipRects
= drawable
->numBackClipRects
;
1653 rmesa
->pClipRects
= drawable
->pBackClipRects
;
1657 /* front buffer (or none, or multiple buffers */
1658 rmesa
->numClipRects
= drawable
->numClipRects
;
1659 rmesa
->pClipRects
= drawable
->pClipRects
;
1662 if ((draw_fb
->Width
!= drawable
->w
) || (draw_fb
->Height
!= drawable
->h
)) {
1663 _mesa_resize_framebuffer(rmesa
->glCtx
, draw_fb
,
1664 drawable
->w
, drawable
->h
);
1665 draw_fb
->Initialized
= GL_TRUE
;
1668 if (drawable
!= readable
) {
1669 if ((read_fb
->Width
!= readable
->w
) || (read_fb
->Height
!= readable
->h
)) {
1670 _mesa_resize_framebuffer(rmesa
->glCtx
, read_fb
,
1671 readable
->w
, readable
->h
);
1672 read_fb
->Initialized
= GL_TRUE
;
1676 if (rmesa
->state
.scissor
.enabled
)
1677 radeonRecalcScissorRects( rmesa
);
1682 * Called via glDrawBuffer.
1684 static void radeonDrawBuffer( GLcontext
*ctx
, GLenum mode
)
1686 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1688 if (RADEON_DEBUG
& DEBUG_DRI
)
1689 fprintf(stderr
, "%s %s\n", __FUNCTION__
,
1690 _mesa_lookup_enum_by_nr( mode
));
1692 RADEON_FIREVERTICES(rmesa
); /* don't pipeline cliprect changes */
1695 * _ColorDrawBufferMask is easier to cope with than <mode>.
1696 * Check for software fallback, update cliprects.
1698 switch ( ctx
->DrawBuffer
->_ColorDrawBufferMask
[0] ) {
1699 case BUFFER_BIT_FRONT_LEFT
:
1700 case BUFFER_BIT_BACK_LEFT
:
1701 FALLBACK( rmesa
, RADEON_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
1704 /* 0 (GL_NONE) buffers or multiple color drawing buffers */
1705 FALLBACK( rmesa
, RADEON_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
1709 radeonSetCliprects( rmesa
);
1711 /* We'll set the drawing engine's offset/pitch parameters later
1712 * when we update other state.
1716 static void radeonReadBuffer( GLcontext
*ctx
, GLenum mode
)
1718 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
1722 /* =============================================================
1723 * State enable/disable
1726 static void radeonEnable( GLcontext
*ctx
, GLenum cap
, GLboolean state
)
1728 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1731 if ( RADEON_DEBUG
& DEBUG_STATE
)
1732 fprintf( stderr
, "%s( %s = %s )\n", __FUNCTION__
,
1733 _mesa_lookup_enum_by_nr( cap
),
1734 state
? "GL_TRUE" : "GL_FALSE" );
1737 /* Fast track this one...
1745 RADEON_STATECHANGE( rmesa
, ctx
);
1747 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ALPHA_TEST_ENABLE
;
1749 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ALPHA_TEST_ENABLE
;
1754 RADEON_STATECHANGE( rmesa
, ctx
);
1756 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ALPHA_BLEND_ENABLE
;
1758 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ALPHA_BLEND_ENABLE
;
1760 if ( (ctx
->Color
.ColorLogicOpEnabled
|| (ctx
->Color
.BlendEnabled
1761 && ctx
->Color
.BlendEquationRGB
== GL_LOGIC_OP
)) ) {
1762 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
1764 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
1767 /* Catch a possible fallback:
1770 ctx
->Driver
.BlendEquationSeparate( ctx
,
1771 ctx
->Color
.BlendEquationRGB
,
1772 ctx
->Color
.BlendEquationA
);
1773 ctx
->Driver
.BlendFuncSeparate( ctx
, ctx
->Color
.BlendSrcRGB
,
1774 ctx
->Color
.BlendDstRGB
,
1775 ctx
->Color
.BlendSrcA
,
1776 ctx
->Color
.BlendDstA
);
1779 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_FUNC
, GL_FALSE
);
1780 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_EQ
, GL_FALSE
);
1784 case GL_CLIP_PLANE0
:
1785 case GL_CLIP_PLANE1
:
1786 case GL_CLIP_PLANE2
:
1787 case GL_CLIP_PLANE3
:
1788 case GL_CLIP_PLANE4
:
1789 case GL_CLIP_PLANE5
:
1790 p
= cap
-GL_CLIP_PLANE0
;
1791 RADEON_STATECHANGE( rmesa
, tcl
);
1793 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= (RADEON_UCP_ENABLE_0
<<p
);
1794 radeonClipPlane( ctx
, cap
, NULL
);
1797 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~(RADEON_UCP_ENABLE_0
<<p
);
1801 case GL_COLOR_MATERIAL
:
1802 radeonColorMaterial( ctx
, 0, 0 );
1803 radeonUpdateMaterial( ctx
);
1807 radeonCullFace( ctx
, 0 );
1811 RADEON_STATECHANGE(rmesa
, ctx
);
1813 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_Z_ENABLE
;
1815 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_Z_ENABLE
;
1820 RADEON_STATECHANGE(rmesa
, ctx
);
1822 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_DITHER_ENABLE
;
1823 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~rmesa
->state
.color
.roundEnable
;
1825 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_DITHER_ENABLE
;
1826 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= rmesa
->state
.color
.roundEnable
;
1831 RADEON_STATECHANGE(rmesa
, ctx
);
1833 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_FOG_ENABLE
;
1834 radeonFogfv( ctx
, GL_FOG_MODE
, NULL
);
1836 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_FOG_ENABLE
;
1837 RADEON_STATECHANGE(rmesa
, tcl
);
1838 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_TCL_FOG_MASK
;
1840 radeonUpdateSpecular( ctx
); /* for PK_SPEC */
1841 _mesa_allow_light_in_model( ctx
, !state
);
1852 RADEON_STATECHANGE(rmesa
, tcl
);
1853 p
= cap
- GL_LIGHT0
;
1855 flag
= (RADEON_LIGHT_1_ENABLE
|
1856 RADEON_LIGHT_1_ENABLE_AMBIENT
|
1857 RADEON_LIGHT_1_ENABLE_SPECULAR
);
1859 flag
= (RADEON_LIGHT_0_ENABLE
|
1860 RADEON_LIGHT_0_ENABLE_AMBIENT
|
1861 RADEON_LIGHT_0_ENABLE_SPECULAR
);
1864 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] |= flag
;
1866 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] &= ~flag
;
1870 update_light_colors( ctx
, p
);
1874 RADEON_STATECHANGE(rmesa
, tcl
);
1875 radeonUpdateSpecular(ctx
);
1876 check_twoside_fallback( ctx
);
1879 case GL_LINE_SMOOTH
:
1880 RADEON_STATECHANGE( rmesa
, ctx
);
1882 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ANTI_ALIAS_LINE
;
1884 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ANTI_ALIAS_LINE
;
1888 case GL_LINE_STIPPLE
:
1889 RADEON_STATECHANGE( rmesa
, ctx
);
1891 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_PATTERN_ENABLE
;
1893 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_PATTERN_ENABLE
;
1897 case GL_COLOR_LOGIC_OP
:
1898 RADEON_STATECHANGE( rmesa
, ctx
);
1899 if ( (ctx
->Color
.ColorLogicOpEnabled
|| (ctx
->Color
.BlendEnabled
1900 && ctx
->Color
.BlendEquationRGB
== GL_LOGIC_OP
)) ) {
1901 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
1903 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
1908 RADEON_STATECHANGE( rmesa
, tcl
);
1910 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_NORMALIZE_NORMALS
;
1912 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_NORMALIZE_NORMALS
;
1916 case GL_POLYGON_OFFSET_POINT
:
1917 RADEON_STATECHANGE( rmesa
, set
);
1919 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_POINT
;
1921 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_POINT
;
1925 case GL_POLYGON_OFFSET_LINE
:
1926 RADEON_STATECHANGE( rmesa
, set
);
1928 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_LINE
;
1930 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_LINE
;
1934 case GL_POLYGON_OFFSET_FILL
:
1935 RADEON_STATECHANGE( rmesa
, set
);
1937 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_TRI
;
1939 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_TRI
;
1943 case GL_POLYGON_SMOOTH
:
1944 RADEON_STATECHANGE( rmesa
, ctx
);
1946 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ANTI_ALIAS_POLY
;
1948 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ANTI_ALIAS_POLY
;
1952 case GL_POLYGON_STIPPLE
:
1953 RADEON_STATECHANGE(rmesa
, ctx
);
1955 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_STIPPLE_ENABLE
;
1957 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_STIPPLE_ENABLE
;
1961 case GL_RESCALE_NORMAL_EXT
: {
1962 GLboolean tmp
= ctx
->_NeedEyeCoords
? state
: !state
;
1963 RADEON_STATECHANGE( rmesa
, tcl
);
1965 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_RESCALE_NORMALS
;
1967 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_RESCALE_NORMALS
;
1972 case GL_SCISSOR_TEST
:
1973 RADEON_FIREVERTICES( rmesa
);
1974 rmesa
->state
.scissor
.enabled
= state
;
1975 radeonUpdateScissor( ctx
);
1978 case GL_STENCIL_TEST
:
1979 if ( rmesa
->state
.stencil
.hwBuffer
) {
1980 RADEON_STATECHANGE( rmesa
, ctx
);
1982 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_STENCIL_ENABLE
;
1984 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_STENCIL_ENABLE
;
1987 FALLBACK( rmesa
, RADEON_FALLBACK_STENCIL
, state
);
1991 case GL_TEXTURE_GEN_Q
:
1992 case GL_TEXTURE_GEN_R
:
1993 case GL_TEXTURE_GEN_S
:
1994 case GL_TEXTURE_GEN_T
:
1995 /* Picked up in radeonUpdateTextureState.
1997 rmesa
->recheck_texgen
[ctx
->Texture
.CurrentUnit
] = GL_TRUE
;
2000 case GL_COLOR_SUM_EXT
:
2001 radeonUpdateSpecular ( ctx
);
2010 static void radeonLightingSpaceChange( GLcontext
*ctx
)
2012 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2014 RADEON_STATECHANGE( rmesa
, tcl
);
2016 if (RADEON_DEBUG
& DEBUG_STATE
)
2017 fprintf(stderr
, "%s %d BEFORE %x\n", __FUNCTION__
, ctx
->_NeedEyeCoords
,
2018 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]);
2020 if (ctx
->_NeedEyeCoords
)
2021 tmp
= ctx
->Transform
.RescaleNormals
;
2023 tmp
= !ctx
->Transform
.RescaleNormals
;
2026 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_RESCALE_NORMALS
;
2028 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_RESCALE_NORMALS
;
2031 if (RADEON_DEBUG
& DEBUG_STATE
)
2032 fprintf(stderr
, "%s %d AFTER %x\n", __FUNCTION__
, ctx
->_NeedEyeCoords
,
2033 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]);
2036 /* =============================================================
2037 * Deferred state management - matrices, textures, other?
2041 void radeonUploadTexMatrix( radeonContextPtr rmesa
,
2042 int unit
, GLboolean swapcols
)
2044 /* Here's how this works: on r100, only 3 tex coords can be submitted, so the
2045 vector looks like this probably: (s t r|q 0) (not sure if the last coord
2046 is hardwired to 0, could be 1 too). Interestingly, it actually looks like
2047 texgen generates all 4 coords, at least tests with projtex indicated that.
2048 So: if we need the q coord in the end (solely determined by the texture
2049 target, i.e. 2d / 1d / texrect targets) we swap the third and 4th row.
2050 Additionally, if we don't have texgen but 4 tex coords submitted, we swap
2051 column 3 and 4 (for the 2d / 1d / texrect targets) since the the q coord
2052 will get submitted in the "wrong", i.e. 3rd, slot.
2053 If an app submits 3 coords for 2d targets, we assume it is saving on vertex
2054 size and using the texture matrix to swap the r and q coords around (ut2k3
2055 does exactly that), so we don't need the 3rd / 4th column swap - still need
2056 the 3rd / 4th row swap of course. This will potentially break for apps which
2057 use TexCoord3x just for fun. Additionally, it will never work if an app uses
2058 an "advanced" texture matrix and relies on all 4 texcoord inputs to generate
2059 the maximum needed 3. This seems impossible to do with hw tcl on r100, and
2060 incredibly hard to detect so we can't just fallback in such a case. Assume
2061 it never happens... - rs
2064 int idx
= TEXMAT_0
+ unit
;
2065 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] )) + MAT_ELT_0
;
2067 struct gl_texture_unit tUnit
= rmesa
->glCtx
->Texture
.Unit
[unit
];
2068 GLfloat
*src
= rmesa
->tmpmat
[unit
].m
;
2070 rmesa
->TexMatColSwap
&= ~(1 << unit
);
2071 if ((tUnit
._ReallyEnabled
& (TEXTURE_3D_BIT
| TEXTURE_CUBE_BIT
)) == 0) {
2073 rmesa
->TexMatColSwap
|= 1 << unit
;
2074 /* attention some elems are swapped 2 times! */
2087 /* those last 4 are probably never used */
2094 for (i
= 0; i
< 2; i
++) {
2098 *dest
++ = src
[i
+12];
2100 for (i
= 3; i
>= 2; i
--) {
2104 *dest
++ = src
[i
+12];
2109 for (i
= 0 ; i
< 4 ; i
++) {
2113 *dest
++ = src
[i
+12];
2117 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
2121 static void upload_matrix( radeonContextPtr rmesa
, GLfloat
*src
, int idx
)
2123 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
2127 for (i
= 0 ; i
< 4 ; i
++) {
2131 *dest
++ = src
[i
+12];
2134 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
2137 static void upload_matrix_t( radeonContextPtr rmesa
, GLfloat
*src
, int idx
)
2139 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
2140 memcpy(dest
, src
, 16*sizeof(float));
2141 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
2145 static void update_texturematrix( GLcontext
*ctx
)
2147 radeonContextPtr rmesa
= RADEON_CONTEXT( ctx
);
2148 GLuint tpc
= rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
];
2149 GLuint vs
= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
];
2151 GLuint texMatEnabled
= 0;
2152 rmesa
->NeedTexMatrix
= 0;
2153 rmesa
->TexMatColSwap
= 0;
2155 for (unit
= 0 ; unit
< ctx
->Const
.MaxTextureUnits
; unit
++) {
2156 if (ctx
->Texture
.Unit
[unit
]._ReallyEnabled
) {
2157 GLboolean needMatrix
= GL_FALSE
;
2158 if (ctx
->TextureMatrixStack
[unit
].Top
->type
!= MATRIX_IDENTITY
) {
2159 needMatrix
= GL_TRUE
;
2160 texMatEnabled
|= (RADEON_TEXGEN_TEXMAT_0_ENABLE
|
2161 RADEON_TEXMAT_0_ENABLE
) << unit
;
2163 if (rmesa
->TexGenEnabled
& (RADEON_TEXMAT_0_ENABLE
<< unit
)) {
2164 /* Need to preconcatenate any active texgen
2165 * obj/eyeplane matrices:
2167 _math_matrix_mul_matrix( &rmesa
->tmpmat
[unit
],
2168 ctx
->TextureMatrixStack
[unit
].Top
,
2169 &rmesa
->TexGenMatrix
[unit
] );
2172 _math_matrix_copy( &rmesa
->tmpmat
[unit
],
2173 ctx
->TextureMatrixStack
[unit
].Top
);
2176 else if (rmesa
->TexGenEnabled
& (RADEON_TEXMAT_0_ENABLE
<< unit
)) {
2177 _math_matrix_copy( &rmesa
->tmpmat
[unit
], &rmesa
->TexGenMatrix
[unit
] );
2178 needMatrix
= GL_TRUE
;
2181 rmesa
->NeedTexMatrix
|= 1 << unit
;
2182 radeonUploadTexMatrix( rmesa
, unit
,
2183 !ctx
->Texture
.Unit
[unit
].TexGenEnabled
);
2188 tpc
= (texMatEnabled
| rmesa
->TexGenEnabled
);
2190 /* TCL_TEX_COMPUTED_x is TCL_TEX_INPUT_x | 0x8 */
2191 vs
&= ~((RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_0_OUTPUT_SHIFT
) |
2192 (RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_1_OUTPUT_SHIFT
) |
2193 (RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_2_OUTPUT_SHIFT
));
2195 vs
|= (((tpc
& RADEON_TEXGEN_TEXMAT_0_ENABLE
) <<
2196 (RADEON_TCL_TEX_0_OUTPUT_SHIFT
+ 3)) |
2197 ((tpc
& RADEON_TEXGEN_TEXMAT_1_ENABLE
) <<
2198 (RADEON_TCL_TEX_1_OUTPUT_SHIFT
+ 2)) |
2199 ((tpc
& RADEON_TEXGEN_TEXMAT_2_ENABLE
) <<
2200 (RADEON_TCL_TEX_2_OUTPUT_SHIFT
+ 1)));
2202 if (tpc
!= rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
] ||
2203 vs
!= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
]) {
2205 RADEON_STATECHANGE(rmesa
, tcl
);
2206 rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
] = tpc
;
2207 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] = vs
;
2213 * Tell the card where to render (offset, pitch).
2214 * Effected by glDrawBuffer, etc
2217 radeonUpdateDrawBuffer(GLcontext
*ctx
)
2219 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2220 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
2221 driRenderbuffer
*drb
;
2223 if (fb
->_ColorDrawBufferMask
[0] == BUFFER_BIT_FRONT_LEFT
) {
2225 drb
= (driRenderbuffer
*) fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
;
2227 else if (fb
->_ColorDrawBufferMask
[0] == BUFFER_BIT_BACK_LEFT
) {
2229 drb
= (driRenderbuffer
*) fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
;
2232 /* drawing to multiple buffers, or none */
2237 assert(drb
->flippedPitch
);
2239 RADEON_STATECHANGE( rmesa
, ctx
);
2241 /* Note: we used the (possibly) page-flipped values */
2242 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLOROFFSET
]
2243 = ((drb
->flippedOffset
+ rmesa
->radeonScreen
->fbLocation
)
2244 & RADEON_COLOROFFSET_MASK
);
2245 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] = drb
->flippedPitch
;
2246 if (rmesa
->sarea
->tiling_enabled
) {
2247 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] |= RADEON_COLOR_TILE_ENABLE
;
2252 void radeonValidateState( GLcontext
*ctx
)
2254 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2255 GLuint new_state
= rmesa
->NewGLState
;
2257 if (new_state
& (_NEW_BUFFERS
| _NEW_COLOR
| _NEW_PIXEL
)) {
2258 radeonUpdateDrawBuffer(ctx
);
2261 if (new_state
& _NEW_TEXTURE
) {
2262 radeonUpdateTextureState( ctx
);
2263 new_state
|= rmesa
->NewGLState
; /* may add TEXTURE_MATRIX */
2266 /* Need an event driven matrix update?
2268 if (new_state
& (_NEW_MODELVIEW
|_NEW_PROJECTION
))
2269 upload_matrix( rmesa
, ctx
->_ModelProjectMatrix
.m
, MODEL_PROJ
);
2271 /* Need these for lighting (shouldn't upload otherwise)
2273 if (new_state
& (_NEW_MODELVIEW
)) {
2274 upload_matrix( rmesa
, ctx
->ModelviewMatrixStack
.Top
->m
, MODEL
);
2275 upload_matrix_t( rmesa
, ctx
->ModelviewMatrixStack
.Top
->inv
, MODEL_IT
);
2278 /* Does this need to be triggered on eg. modelview for
2279 * texgen-derived objplane/eyeplane matrices?
2281 if (new_state
& _NEW_TEXTURE_MATRIX
) {
2282 update_texturematrix( ctx
);
2285 if (new_state
& (_NEW_LIGHT
|_NEW_MODELVIEW
|_MESA_NEW_NEED_EYE_COORDS
)) {
2286 update_light( ctx
);
2289 /* emit all active clip planes if projection matrix changes.
2291 if (new_state
& (_NEW_PROJECTION
)) {
2292 if (ctx
->Transform
.ClipPlanesEnabled
)
2293 radeonUpdateClipPlanes( ctx
);
2297 rmesa
->NewGLState
= 0;
2301 static void radeonInvalidateState( GLcontext
*ctx
, GLuint new_state
)
2303 _swrast_InvalidateState( ctx
, new_state
);
2304 _swsetup_InvalidateState( ctx
, new_state
);
2305 _vbo_InvalidateState( ctx
, new_state
);
2306 _tnl_InvalidateState( ctx
, new_state
);
2307 _ae_invalidate_state( ctx
, new_state
);
2308 RADEON_CONTEXT(ctx
)->NewGLState
|= new_state
;
2312 /* A hack. Need a faster way to find this out.
2314 static GLboolean
check_material( GLcontext
*ctx
)
2316 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
2319 for (i
= _TNL_ATTRIB_MAT_FRONT_AMBIENT
;
2320 i
< _TNL_ATTRIB_MAT_BACK_INDEXES
;
2322 if (tnl
->vb
.AttribPtr
[i
] &&
2323 tnl
->vb
.AttribPtr
[i
]->stride
)
2330 static void radeonWrapRunPipeline( GLcontext
*ctx
)
2332 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2333 GLboolean has_material
;
2336 fprintf(stderr
, "%s, newstate: %x\n", __FUNCTION__
, rmesa
->NewGLState
);
2340 if (rmesa
->NewGLState
)
2341 radeonValidateState( ctx
);
2343 has_material
= (ctx
->Light
.Enabled
&& check_material( ctx
));
2346 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_MATERIAL
, GL_TRUE
);
2349 /* Run the pipeline.
2351 _tnl_run_pipeline( ctx
);
2354 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_MATERIAL
, GL_FALSE
);
2359 /* Initialize the driver's state functions.
2360 * Many of the ctx->Driver functions might have been initialized to
2361 * software defaults in the earlier _mesa_init_driver_functions() call.
2363 void radeonInitStateFuncs( GLcontext
*ctx
)
2365 ctx
->Driver
.UpdateState
= radeonInvalidateState
;
2366 ctx
->Driver
.LightingSpaceChange
= radeonLightingSpaceChange
;
2368 ctx
->Driver
.DrawBuffer
= radeonDrawBuffer
;
2369 ctx
->Driver
.ReadBuffer
= radeonReadBuffer
;
2371 ctx
->Driver
.AlphaFunc
= radeonAlphaFunc
;
2372 ctx
->Driver
.BlendEquationSeparate
= radeonBlendEquationSeparate
;
2373 ctx
->Driver
.BlendFuncSeparate
= radeonBlendFuncSeparate
;
2374 ctx
->Driver
.ClearColor
= radeonClearColor
;
2375 ctx
->Driver
.ClearDepth
= radeonClearDepth
;
2376 ctx
->Driver
.ClearIndex
= NULL
;
2377 ctx
->Driver
.ClearStencil
= radeonClearStencil
;
2378 ctx
->Driver
.ClipPlane
= radeonClipPlane
;
2379 ctx
->Driver
.ColorMask
= radeonColorMask
;
2380 ctx
->Driver
.CullFace
= radeonCullFace
;
2381 ctx
->Driver
.DepthFunc
= radeonDepthFunc
;
2382 ctx
->Driver
.DepthMask
= radeonDepthMask
;
2383 ctx
->Driver
.DepthRange
= radeonDepthRange
;
2384 ctx
->Driver
.Enable
= radeonEnable
;
2385 ctx
->Driver
.Fogfv
= radeonFogfv
;
2386 ctx
->Driver
.FrontFace
= radeonFrontFace
;
2387 ctx
->Driver
.Hint
= NULL
;
2388 ctx
->Driver
.IndexMask
= NULL
;
2389 ctx
->Driver
.LightModelfv
= radeonLightModelfv
;
2390 ctx
->Driver
.Lightfv
= radeonLightfv
;
2391 ctx
->Driver
.LineStipple
= radeonLineStipple
;
2392 ctx
->Driver
.LineWidth
= radeonLineWidth
;
2393 ctx
->Driver
.LogicOpcode
= radeonLogicOpCode
;
2394 ctx
->Driver
.PolygonMode
= radeonPolygonMode
;
2395 ctx
->Driver
.PolygonOffset
= radeonPolygonOffset
;
2396 ctx
->Driver
.PolygonStipple
= radeonPolygonStipple
;
2397 ctx
->Driver
.RenderMode
= radeonRenderMode
;
2398 ctx
->Driver
.Scissor
= radeonScissor
;
2399 ctx
->Driver
.ShadeModel
= radeonShadeModel
;
2400 ctx
->Driver
.StencilFuncSeparate
= radeonStencilFuncSeparate
;
2401 ctx
->Driver
.StencilMaskSeparate
= radeonStencilMaskSeparate
;
2402 ctx
->Driver
.StencilOpSeparate
= radeonStencilOpSeparate
;
2403 ctx
->Driver
.Viewport
= radeonViewport
;
2405 TNL_CONTEXT(ctx
)->Driver
.NotifyMaterialChange
= radeonUpdateMaterial
;
2406 TNL_CONTEXT(ctx
)->Driver
.RunPipeline
= radeonWrapRunPipeline
;