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 d
.f
= ctx
->Fog
.Density
;
368 d
.f
= -(ctx
->Fog
.Density
* ctx
->Fog
.Density
);
371 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
375 c
.f
= ctx
->Fog
.End
/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
376 d
.f
= 1.0/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
382 if (c
.i
!= rmesa
->hw
.fog
.cmd
[FOG_C
] || d
.i
!= rmesa
->hw
.fog
.cmd
[FOG_D
]) {
383 RADEON_STATECHANGE( rmesa
, fog
);
384 rmesa
->hw
.fog
.cmd
[FOG_C
] = c
.i
;
385 rmesa
->hw
.fog
.cmd
[FOG_D
] = d
.i
;
389 RADEON_STATECHANGE( rmesa
, ctx
);
390 UNCLAMPED_FLOAT_TO_RGB_CHAN( col
, ctx
->Fog
.Color
);
391 rmesa
->hw
.ctx
.cmd
[CTX_PP_FOG_COLOR
] &= ~RADEON_FOG_COLOR_MASK
;
392 rmesa
->hw
.ctx
.cmd
[CTX_PP_FOG_COLOR
] |=
393 radeonPackColor( 4, col
[0], col
[1], col
[2], 0 );
395 case GL_FOG_COORD_SRC
:
396 radeonUpdateSpecular( ctx
);
404 /* =============================================================
409 static GLboolean
intersect_rect( drm_clip_rect_t
*out
,
414 if ( b
->x1
> out
->x1
) out
->x1
= b
->x1
;
415 if ( b
->y1
> out
->y1
) out
->y1
= b
->y1
;
416 if ( b
->x2
< out
->x2
) out
->x2
= b
->x2
;
417 if ( b
->y2
< out
->y2
) out
->y2
= b
->y2
;
418 if ( out
->x1
>= out
->x2
) return GL_FALSE
;
419 if ( out
->y1
>= out
->y2
) return GL_FALSE
;
424 void radeonRecalcScissorRects( radeonContextPtr rmesa
)
426 drm_clip_rect_t
*out
;
429 /* Grow cliprect store?
431 if (rmesa
->state
.scissor
.numAllocedClipRects
< rmesa
->numClipRects
) {
432 while (rmesa
->state
.scissor
.numAllocedClipRects
< rmesa
->numClipRects
) {
433 rmesa
->state
.scissor
.numAllocedClipRects
+= 1; /* zero case */
434 rmesa
->state
.scissor
.numAllocedClipRects
*= 2;
437 if (rmesa
->state
.scissor
.pClipRects
)
438 FREE(rmesa
->state
.scissor
.pClipRects
);
440 rmesa
->state
.scissor
.pClipRects
=
441 MALLOC( rmesa
->state
.scissor
.numAllocedClipRects
*
442 sizeof(drm_clip_rect_t
) );
444 if ( rmesa
->state
.scissor
.pClipRects
== NULL
) {
445 rmesa
->state
.scissor
.numAllocedClipRects
= 0;
450 out
= rmesa
->state
.scissor
.pClipRects
;
451 rmesa
->state
.scissor
.numClipRects
= 0;
453 for ( i
= 0 ; i
< rmesa
->numClipRects
; i
++ ) {
454 if ( intersect_rect( out
,
455 &rmesa
->pClipRects
[i
],
456 &rmesa
->state
.scissor
.rect
) ) {
457 rmesa
->state
.scissor
.numClipRects
++;
464 static void radeonUpdateScissor( GLcontext
*ctx
)
466 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
468 if ( rmesa
->dri
.drawable
) {
469 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
471 int x
= ctx
->Scissor
.X
;
472 int y
= dPriv
->h
- ctx
->Scissor
.Y
- ctx
->Scissor
.Height
;
473 int w
= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
- 1;
474 int h
= dPriv
->h
- ctx
->Scissor
.Y
- 1;
476 rmesa
->state
.scissor
.rect
.x1
= x
+ dPriv
->x
;
477 rmesa
->state
.scissor
.rect
.y1
= y
+ dPriv
->y
;
478 rmesa
->state
.scissor
.rect
.x2
= w
+ dPriv
->x
+ 1;
479 rmesa
->state
.scissor
.rect
.y2
= h
+ dPriv
->y
+ 1;
481 radeonRecalcScissorRects( rmesa
);
486 static void radeonScissor( GLcontext
*ctx
,
487 GLint x
, GLint y
, GLsizei w
, GLsizei h
)
489 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
491 if ( ctx
->Scissor
.Enabled
) {
492 RADEON_FIREVERTICES( rmesa
); /* don't pipeline cliprect changes */
493 radeonUpdateScissor( ctx
);
499 /* =============================================================
503 static void radeonCullFace( GLcontext
*ctx
, GLenum unused
)
505 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
506 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
507 GLuint t
= rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
];
509 s
|= RADEON_FFACE_SOLID
| RADEON_BFACE_SOLID
;
510 t
&= ~(RADEON_CULL_FRONT
| RADEON_CULL_BACK
);
512 if ( ctx
->Polygon
.CullFlag
) {
513 switch ( ctx
->Polygon
.CullFaceMode
) {
515 s
&= ~RADEON_FFACE_SOLID
;
516 t
|= RADEON_CULL_FRONT
;
519 s
&= ~RADEON_BFACE_SOLID
;
520 t
|= RADEON_CULL_BACK
;
522 case GL_FRONT_AND_BACK
:
523 s
&= ~(RADEON_FFACE_SOLID
| RADEON_BFACE_SOLID
);
524 t
|= (RADEON_CULL_FRONT
| RADEON_CULL_BACK
);
529 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
530 RADEON_STATECHANGE(rmesa
, set
);
531 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
534 if ( rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] != t
) {
535 RADEON_STATECHANGE(rmesa
, tcl
);
536 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] = t
;
540 static void radeonFrontFace( GLcontext
*ctx
, GLenum mode
)
542 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
544 RADEON_STATECHANGE( rmesa
, set
);
545 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_FFACE_CULL_DIR_MASK
;
547 RADEON_STATECHANGE( rmesa
, tcl
);
548 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_CULL_FRONT_IS_CCW
;
552 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_FFACE_CULL_CW
;
555 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_FFACE_CULL_CCW
;
556 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_CULL_FRONT_IS_CCW
;
562 /* =============================================================
565 static void radeonLineWidth( GLcontext
*ctx
, GLfloat widthf
)
567 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
569 RADEON_STATECHANGE( rmesa
, lin
);
570 RADEON_STATECHANGE( rmesa
, set
);
572 /* Line width is stored in U6.4 format.
574 rmesa
->hw
.lin
.cmd
[LIN_SE_LINE_WIDTH
] = (GLuint
)(widthf
* 16.0);
575 if ( widthf
> 1.0 ) {
576 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_WIDELINE_ENABLE
;
578 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_WIDELINE_ENABLE
;
582 static void radeonLineStipple( GLcontext
*ctx
, GLint factor
, GLushort pattern
)
584 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
586 RADEON_STATECHANGE( rmesa
, lin
);
587 rmesa
->hw
.lin
.cmd
[LIN_RE_LINE_PATTERN
] =
588 ((((GLuint
)factor
& 0xff) << 16) | ((GLuint
)pattern
));
592 /* =============================================================
595 static void radeonColorMask( GLcontext
*ctx
,
596 GLboolean r
, GLboolean g
,
597 GLboolean b
, GLboolean a
)
599 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
600 GLuint mask
= radeonPackColor( rmesa
->radeonScreen
->cpp
,
601 ctx
->Color
.ColorMask
[RCOMP
],
602 ctx
->Color
.ColorMask
[GCOMP
],
603 ctx
->Color
.ColorMask
[BCOMP
],
604 ctx
->Color
.ColorMask
[ACOMP
] );
606 if ( rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] != mask
) {
607 RADEON_STATECHANGE( rmesa
, msk
);
608 rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] = mask
;
613 /* =============================================================
617 static void radeonPolygonOffset( GLcontext
*ctx
,
618 GLfloat factor
, GLfloat units
)
620 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
621 GLfloat constant
= units
* rmesa
->state
.depth
.scale
;
623 RADEON_STATECHANGE( rmesa
, zbs
);
624 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_FACTOR
] = *(GLuint
*)&factor
;
625 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_CONSTANT
] = *(GLuint
*)&constant
;
628 static void radeonPolygonStipple( GLcontext
*ctx
, const GLubyte
*mask
)
630 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
632 drm_radeon_stipple_t stipple
;
634 /* Must flip pattern upside down.
636 for ( i
= 0 ; i
< 32 ; i
++ ) {
637 rmesa
->state
.stipple
.mask
[31 - i
] = ((GLuint
*) mask
)[i
];
640 /* TODO: push this into cmd mechanism
642 RADEON_FIREVERTICES( rmesa
);
643 LOCK_HARDWARE( rmesa
);
645 /* FIXME: Use window x,y offsets into stipple RAM.
647 stipple
.mask
= rmesa
->state
.stipple
.mask
;
648 drmCommandWrite( rmesa
->dri
.fd
, DRM_RADEON_STIPPLE
,
649 &stipple
, sizeof(drm_radeon_stipple_t
) );
650 UNLOCK_HARDWARE( rmesa
);
653 static void radeonPolygonMode( GLcontext
*ctx
, GLenum face
, GLenum mode
)
655 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
656 GLboolean flag
= (ctx
->_TriangleCaps
& DD_TRI_UNFILLED
) != 0;
658 /* Can't generally do unfilled via tcl, but some good special
661 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_UNFILLED
, flag
);
662 if (rmesa
->TclFallback
) {
663 radeonChooseRenderState( ctx
);
664 radeonChooseVertexState( ctx
);
669 /* =============================================================
670 * Rendering attributes
672 * We really don't want to recalculate all this every time we bind a
673 * texture. These things shouldn't change all that often, so it makes
674 * sense to break them out of the core texture state update routines.
677 /* Examine lighting and texture state to determine if separate specular
680 static void radeonUpdateSpecular( GLcontext
*ctx
)
682 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
683 u_int32_t p
= rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
];
686 RADEON_STATECHANGE( rmesa
, tcl
);
688 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &= ~RADEON_TCL_COMPUTE_SPECULAR
;
689 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &= ~RADEON_TCL_COMPUTE_DIFFUSE
;
690 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &= ~RADEON_TCL_VTX_PK_SPEC
;
691 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &= ~RADEON_TCL_VTX_PK_DIFFUSE
;
692 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_LIGHTING_ENABLE
;
694 p
&= ~RADEON_SPECULAR_ENABLE
;
696 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_DIFFUSE_SPECULAR_COMBINE
;
699 if (ctx
->Light
.Enabled
&&
700 ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
) {
701 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_SPECULAR
;
702 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_DIFFUSE
;
703 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
704 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
705 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
706 p
|= RADEON_SPECULAR_ENABLE
;
707 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &=
708 ~RADEON_DIFFUSE_SPECULAR_COMBINE
;
710 else if (ctx
->Light
.Enabled
) {
711 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_DIFFUSE
;
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 } else if (ctx
->Fog
.ColorSumEnabled
) {
715 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
716 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
717 p
|= RADEON_SPECULAR_ENABLE
;
719 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
722 if (ctx
->Fog
.Enabled
) {
723 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
724 if (ctx
->Fog
.FogCoordinateSource
== GL_FRAGMENT_DEPTH
) {
725 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_SPECULAR
;
726 /* Bizzare: have to leave lighting enabled to get fog. */
727 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
730 /* cannot do tcl fog factor calculation with fog coord source
731 * (send precomputed factors). Cannot use precomputed fog
732 * factors together with tcl spec light (need tcl fallback) */
733 flag
= (rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &
734 RADEON_TCL_COMPUTE_SPECULAR
) != 0;
738 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_FOGCOORDSPEC
, flag
);
740 if (NEED_SECONDARY_COLOR(ctx
)) {
741 assert( (p
& RADEON_SPECULAR_ENABLE
) != 0 );
743 assert( (p
& RADEON_SPECULAR_ENABLE
) == 0 );
746 if ( rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] != p
) {
747 RADEON_STATECHANGE( rmesa
, ctx
);
748 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] = p
;
751 /* Update vertex/render formats
753 if (rmesa
->TclFallback
) {
754 radeonChooseRenderState( ctx
);
755 radeonChooseVertexState( ctx
);
760 /* =============================================================
765 /* Update on colormaterial, material emmissive/ambient,
766 * lightmodel.globalambient
768 static void update_global_ambient( GLcontext
*ctx
)
770 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
771 float *fcmd
= (float *)RADEON_DB_STATE( glt
);
773 /* Need to do more if both emmissive & ambient are PREMULT:
774 * Hope this is not needed for MULT
776 if ((rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &
777 ((3 << RADEON_EMISSIVE_SOURCE_SHIFT
) |
778 (3 << RADEON_AMBIENT_SOURCE_SHIFT
))) == 0)
780 COPY_3V( &fcmd
[GLT_RED
],
781 ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_EMISSION
]);
782 ACC_SCALE_3V( &fcmd
[GLT_RED
],
783 ctx
->Light
.Model
.Ambient
,
784 ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_AMBIENT
]);
788 COPY_3V( &fcmd
[GLT_RED
], ctx
->Light
.Model
.Ambient
);
791 RADEON_DB_STATECHANGE(rmesa
, &rmesa
->hw
.glt
);
794 /* Update on change to
798 static void update_light_colors( GLcontext
*ctx
, GLuint p
)
800 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
802 /* fprintf(stderr, "%s\n", __FUNCTION__); */
805 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
806 float *fcmd
= (float *)RADEON_DB_STATE( lit
[p
] );
808 COPY_4V( &fcmd
[LIT_AMBIENT_RED
], l
->Ambient
);
809 COPY_4V( &fcmd
[LIT_DIFFUSE_RED
], l
->Diffuse
);
810 COPY_4V( &fcmd
[LIT_SPECULAR_RED
], l
->Specular
);
812 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
816 /* Also fallback for asym colormaterial mode in twoside lighting...
818 static void check_twoside_fallback( GLcontext
*ctx
)
820 GLboolean fallback
= GL_FALSE
;
823 if (ctx
->Light
.Enabled
&& ctx
->Light
.Model
.TwoSide
) {
824 if (ctx
->Light
.ColorMaterialEnabled
&&
825 (ctx
->Light
.ColorMaterialBitmask
& BACK_MATERIAL_BITS
) !=
826 ((ctx
->Light
.ColorMaterialBitmask
& FRONT_MATERIAL_BITS
)<<1))
829 for (i
= MAT_ATTRIB_FRONT_AMBIENT
; i
< MAT_ATTRIB_FRONT_INDEXES
; i
+=2)
830 if (memcmp( ctx
->Light
.Material
.Attrib
[i
],
831 ctx
->Light
.Material
.Attrib
[i
+1],
832 sizeof(GLfloat
)*4) != 0) {
839 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_LIGHT_TWOSIDE
, fallback
);
843 static void radeonColorMaterial( GLcontext
*ctx
, GLenum face
, GLenum mode
)
845 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
846 GLuint light_model_ctl1
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
];
848 light_model_ctl1
&= ~((3 << RADEON_EMISSIVE_SOURCE_SHIFT
) |
849 (3 << RADEON_AMBIENT_SOURCE_SHIFT
) |
850 (3 << RADEON_DIFFUSE_SOURCE_SHIFT
) |
851 (3 << RADEON_SPECULAR_SOURCE_SHIFT
));
853 if (ctx
->Light
.ColorMaterialEnabled
) {
854 GLuint mask
= ctx
->Light
.ColorMaterialBitmask
;
856 if (mask
& MAT_BIT_FRONT_EMISSION
) {
857 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
858 RADEON_EMISSIVE_SOURCE_SHIFT
);
861 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
862 RADEON_EMISSIVE_SOURCE_SHIFT
);
865 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
866 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
867 RADEON_AMBIENT_SOURCE_SHIFT
);
870 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
871 RADEON_AMBIENT_SOURCE_SHIFT
);
874 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
875 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
876 RADEON_DIFFUSE_SOURCE_SHIFT
);
879 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
880 RADEON_DIFFUSE_SOURCE_SHIFT
);
883 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
884 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
885 RADEON_SPECULAR_SOURCE_SHIFT
);
888 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
889 RADEON_SPECULAR_SOURCE_SHIFT
);
895 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_EMISSIVE_SOURCE_SHIFT
) |
896 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_AMBIENT_SOURCE_SHIFT
) |
897 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_DIFFUSE_SOURCE_SHIFT
) |
898 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_SPECULAR_SOURCE_SHIFT
);
901 if (light_model_ctl1
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]) {
902 RADEON_STATECHANGE( rmesa
, tcl
);
903 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] = light_model_ctl1
;
907 void radeonUpdateMaterial( GLcontext
*ctx
)
909 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
910 GLfloat (*mat
)[4] = ctx
->Light
.Material
.Attrib
;
911 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( mtl
);
914 if (ctx
->Light
.ColorMaterialEnabled
)
915 mask
&= ~ctx
->Light
.ColorMaterialBitmask
;
917 if (RADEON_DEBUG
& DEBUG_STATE
)
918 fprintf(stderr
, "%s\n", __FUNCTION__
);
921 if (mask
& MAT_BIT_FRONT_EMISSION
) {
922 fcmd
[MTL_EMMISSIVE_RED
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][0];
923 fcmd
[MTL_EMMISSIVE_GREEN
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][1];
924 fcmd
[MTL_EMMISSIVE_BLUE
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][2];
925 fcmd
[MTL_EMMISSIVE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][3];
927 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
928 fcmd
[MTL_AMBIENT_RED
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][0];
929 fcmd
[MTL_AMBIENT_GREEN
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][1];
930 fcmd
[MTL_AMBIENT_BLUE
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][2];
931 fcmd
[MTL_AMBIENT_ALPHA
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][3];
933 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
934 fcmd
[MTL_DIFFUSE_RED
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][0];
935 fcmd
[MTL_DIFFUSE_GREEN
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][1];
936 fcmd
[MTL_DIFFUSE_BLUE
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][2];
937 fcmd
[MTL_DIFFUSE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][3];
939 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
940 fcmd
[MTL_SPECULAR_RED
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][0];
941 fcmd
[MTL_SPECULAR_GREEN
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][1];
942 fcmd
[MTL_SPECULAR_BLUE
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][2];
943 fcmd
[MTL_SPECULAR_ALPHA
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][3];
945 if (mask
& MAT_BIT_FRONT_SHININESS
) {
946 fcmd
[MTL_SHININESS
] = mat
[MAT_ATTRIB_FRONT_SHININESS
][0];
949 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mtl
);
951 check_twoside_fallback( ctx
);
952 /* update_global_ambient( ctx );*/
957 * _MESA_NEW_NEED_EYE_COORDS
959 * Uses derived state from mesa:
968 * which are calculated in light.c and are correct for the current
969 * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW
970 * and _MESA_NEW_NEED_EYE_COORDS.
972 static void update_light( GLcontext
*ctx
)
974 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
976 /* Have to check these, or have an automatic shortcircuit mechanism
977 * to remove noop statechanges. (Or just do a better job on the
981 GLuint tmp
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
];
983 if (ctx
->_NeedEyeCoords
)
984 tmp
&= ~RADEON_LIGHT_IN_MODELSPACE
;
986 tmp
|= RADEON_LIGHT_IN_MODELSPACE
;
989 /* Leave this test disabled: (unexplained q3 lockup) (even with
992 if (tmp
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
])
994 RADEON_STATECHANGE( rmesa
, tcl
);
995 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] = tmp
;
1000 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( eye
);
1001 fcmd
[EYE_X
] = ctx
->_EyeZDir
[0];
1002 fcmd
[EYE_Y
] = ctx
->_EyeZDir
[1];
1003 fcmd
[EYE_Z
] = - ctx
->_EyeZDir
[2];
1004 fcmd
[EYE_RESCALE_FACTOR
] = ctx
->_ModelViewInvScale
;
1005 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.eye
);
1010 if (ctx
->Light
.Enabled
) {
1012 for (p
= 0 ; p
< MAX_LIGHTS
; p
++) {
1013 if (ctx
->Light
.Light
[p
].Enabled
) {
1014 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
1015 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( lit
[p
] );
1017 if (l
->EyePosition
[3] == 0.0) {
1018 COPY_3FV( &fcmd
[LIT_POSITION_X
], l
->_VP_inf_norm
);
1019 COPY_3FV( &fcmd
[LIT_DIRECTION_X
], l
->_h_inf_norm
);
1020 fcmd
[LIT_POSITION_W
] = 0;
1021 fcmd
[LIT_DIRECTION_W
] = 0;
1023 COPY_4V( &fcmd
[LIT_POSITION_X
], l
->_Position
);
1024 fcmd
[LIT_DIRECTION_X
] = -l
->_NormDirection
[0];
1025 fcmd
[LIT_DIRECTION_Y
] = -l
->_NormDirection
[1];
1026 fcmd
[LIT_DIRECTION_Z
] = -l
->_NormDirection
[2];
1027 fcmd
[LIT_DIRECTION_W
] = 0;
1030 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
1036 static void radeonLightfv( GLcontext
*ctx
, GLenum light
,
1037 GLenum pname
, const GLfloat
*params
)
1039 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1040 GLint p
= light
- GL_LIGHT0
;
1041 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
1042 GLfloat
*fcmd
= (GLfloat
*)rmesa
->hw
.lit
[p
].cmd
;
1049 update_light_colors( ctx
, p
);
1052 case GL_SPOT_DIRECTION
:
1053 /* picked up in update_light */
1057 /* positions picked up in update_light, but can do flag here */
1059 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1061 /* FIXME: Set RANGE_ATTEN only when needed */
1063 flag
= RADEON_LIGHT_1_IS_LOCAL
;
1065 flag
= RADEON_LIGHT_0_IS_LOCAL
;
1067 RADEON_STATECHANGE(rmesa
, tcl
);
1068 if (l
->EyePosition
[3] != 0.0F
)
1069 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
1071 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
1075 case GL_SPOT_EXPONENT
:
1076 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1077 fcmd
[LIT_SPOT_EXPONENT
] = params
[0];
1080 case GL_SPOT_CUTOFF
: {
1081 GLuint flag
= (p
&1) ? RADEON_LIGHT_1_IS_SPOT
: RADEON_LIGHT_0_IS_SPOT
;
1082 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1084 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1085 fcmd
[LIT_SPOT_CUTOFF
] = l
->_CosCutoff
;
1087 RADEON_STATECHANGE(rmesa
, tcl
);
1088 if (l
->SpotCutoff
!= 180.0F
)
1089 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
1091 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
1096 case GL_CONSTANT_ATTENUATION
:
1097 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1098 fcmd
[LIT_ATTEN_CONST
] = params
[0];
1099 if ( params
[0] == 0.0 )
1100 fcmd
[LIT_ATTEN_CONST_INV
] = FLT_MAX
;
1102 fcmd
[LIT_ATTEN_CONST_INV
] = 1.0 / params
[0];
1104 case GL_LINEAR_ATTENUATION
:
1105 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1106 fcmd
[LIT_ATTEN_LINEAR
] = params
[0];
1108 case GL_QUADRATIC_ATTENUATION
:
1109 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1110 fcmd
[LIT_ATTEN_QUADRATIC
] = params
[0];
1116 /* Set RANGE_ATTEN only when needed */
1119 case GL_CONSTANT_ATTENUATION
:
1120 case GL_LINEAR_ATTENUATION
:
1121 case GL_QUADRATIC_ATTENUATION
:
1123 GLuint
*icmd
= (GLuint
*)RADEON_DB_STATE( tcl
);
1124 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1125 GLuint atten_flag
= ( p
&1 ) ? RADEON_LIGHT_1_ENABLE_RANGE_ATTEN
1126 : RADEON_LIGHT_0_ENABLE_RANGE_ATTEN
;
1127 GLuint atten_const_flag
= ( p
&1 ) ? RADEON_LIGHT_1_CONSTANT_RANGE_ATTEN
1128 : RADEON_LIGHT_0_CONSTANT_RANGE_ATTEN
;
1130 if ( l
->EyePosition
[3] == 0.0F
||
1131 ( ( fcmd
[LIT_ATTEN_CONST
] == 0.0 || fcmd
[LIT_ATTEN_CONST
] == 1.0 ) &&
1132 fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) ) {
1133 /* Disable attenuation */
1134 icmd
[idx
] &= ~atten_flag
;
1136 if ( fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) {
1137 /* Enable only constant portion of attenuation calculation */
1138 icmd
[idx
] |= ( atten_flag
| atten_const_flag
);
1140 /* Enable full attenuation calculation */
1141 icmd
[idx
] &= ~atten_const_flag
;
1142 icmd
[idx
] |= atten_flag
;
1146 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.tcl
);
1157 static void radeonLightModelfv( GLcontext
*ctx
, GLenum pname
,
1158 const GLfloat
*param
)
1160 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1163 case GL_LIGHT_MODEL_AMBIENT
:
1164 update_global_ambient( ctx
);
1167 case GL_LIGHT_MODEL_LOCAL_VIEWER
:
1168 RADEON_STATECHANGE( rmesa
, tcl
);
1169 if (ctx
->Light
.Model
.LocalViewer
)
1170 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LOCAL_VIEWER
;
1172 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_LOCAL_VIEWER
;
1175 case GL_LIGHT_MODEL_TWO_SIDE
:
1176 RADEON_STATECHANGE( rmesa
, tcl
);
1177 if (ctx
->Light
.Model
.TwoSide
)
1178 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_LIGHT_TWOSIDE
;
1180 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_LIGHT_TWOSIDE
;
1182 check_twoside_fallback( ctx
);
1184 if (rmesa
->TclFallback
) {
1185 radeonChooseRenderState( ctx
);
1186 radeonChooseVertexState( ctx
);
1190 case GL_LIGHT_MODEL_COLOR_CONTROL
:
1191 radeonUpdateSpecular(ctx
);
1199 static void radeonShadeModel( GLcontext
*ctx
, GLenum mode
)
1201 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1202 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
1204 s
&= ~(RADEON_DIFFUSE_SHADE_MASK
|
1205 RADEON_ALPHA_SHADE_MASK
|
1206 RADEON_SPECULAR_SHADE_MASK
|
1207 RADEON_FOG_SHADE_MASK
);
1211 s
|= (RADEON_DIFFUSE_SHADE_FLAT
|
1212 RADEON_ALPHA_SHADE_FLAT
|
1213 RADEON_SPECULAR_SHADE_FLAT
|
1214 RADEON_FOG_SHADE_FLAT
);
1217 s
|= (RADEON_DIFFUSE_SHADE_GOURAUD
|
1218 RADEON_ALPHA_SHADE_GOURAUD
|
1219 RADEON_SPECULAR_SHADE_GOURAUD
|
1220 RADEON_FOG_SHADE_GOURAUD
);
1226 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
1227 RADEON_STATECHANGE( rmesa
, set
);
1228 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
1233 /* =============================================================
1237 static void radeonClipPlane( GLcontext
*ctx
, GLenum plane
, const GLfloat
*eq
)
1239 GLint p
= (GLint
) plane
- (GLint
) GL_CLIP_PLANE0
;
1240 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1241 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1243 RADEON_STATECHANGE( rmesa
, ucp
[p
] );
1244 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1245 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1246 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1247 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1250 static void radeonUpdateClipPlanes( GLcontext
*ctx
)
1252 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1255 for (p
= 0; p
< ctx
->Const
.MaxClipPlanes
; p
++) {
1256 if (ctx
->Transform
.ClipPlanesEnabled
& (1 << p
)) {
1257 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1259 RADEON_STATECHANGE( rmesa
, ucp
[p
] );
1260 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1261 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1262 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1263 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1269 /* =============================================================
1274 radeonStencilFuncSeparate( GLcontext
*ctx
, GLenum face
, GLenum func
,
1275 GLint ref
, GLuint mask
)
1277 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1278 GLuint refmask
= ((ctx
->Stencil
.Ref
[0] << RADEON_STENCIL_REF_SHIFT
) |
1279 (ctx
->Stencil
.ValueMask
[0] << RADEON_STENCIL_MASK_SHIFT
));
1281 RADEON_STATECHANGE( rmesa
, ctx
);
1282 RADEON_STATECHANGE( rmesa
, msk
);
1284 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_STENCIL_TEST_MASK
;
1285 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~(RADEON_STENCIL_REF_MASK
|
1286 RADEON_STENCIL_VALUE_MASK
);
1288 switch ( ctx
->Stencil
.Function
[0] ) {
1290 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_NEVER
;
1293 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_LESS
;
1296 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_EQUAL
;
1299 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_LEQUAL
;
1302 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_GREATER
;
1305 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_NEQUAL
;
1308 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_GEQUAL
;
1311 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_ALWAYS
;
1315 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |= refmask
;
1319 radeonStencilMaskSeparate( GLcontext
*ctx
, GLenum face
, GLuint mask
)
1321 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1323 RADEON_STATECHANGE( rmesa
, msk
);
1324 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~RADEON_STENCIL_WRITE_MASK
;
1325 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |=
1326 (ctx
->Stencil
.WriteMask
[0] << RADEON_STENCIL_WRITEMASK_SHIFT
);
1329 static void radeonStencilOpSeparate( GLcontext
*ctx
, GLenum face
, GLenum fail
,
1330 GLenum zfail
, GLenum zpass
)
1332 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1334 /* radeon 7200 have stencil bug, DEC and INC_WRAP will actually both do DEC_WRAP,
1335 and DEC_WRAP (and INVERT) will do INVERT. No way to get correct INC_WRAP and DEC,
1336 but DEC_WRAP can be fixed by using DEC and INC_WRAP at least use INC. */
1338 GLuint tempRADEON_STENCIL_FAIL_DEC_WRAP
;
1339 GLuint tempRADEON_STENCIL_FAIL_INC_WRAP
;
1340 GLuint tempRADEON_STENCIL_ZFAIL_DEC_WRAP
;
1341 GLuint tempRADEON_STENCIL_ZFAIL_INC_WRAP
;
1342 GLuint tempRADEON_STENCIL_ZPASS_DEC_WRAP
;
1343 GLuint tempRADEON_STENCIL_ZPASS_INC_WRAP
;
1345 if (rmesa
->radeonScreen
->chipset
& RADEON_CHIPSET_BROKEN_STENCIL
) {
1346 tempRADEON_STENCIL_FAIL_DEC_WRAP
= RADEON_STENCIL_FAIL_DEC
;
1347 tempRADEON_STENCIL_FAIL_INC_WRAP
= RADEON_STENCIL_FAIL_INC
;
1348 tempRADEON_STENCIL_ZFAIL_DEC_WRAP
= RADEON_STENCIL_ZFAIL_DEC
;
1349 tempRADEON_STENCIL_ZFAIL_INC_WRAP
= RADEON_STENCIL_ZFAIL_INC
;
1350 tempRADEON_STENCIL_ZPASS_DEC_WRAP
= RADEON_STENCIL_ZPASS_DEC
;
1351 tempRADEON_STENCIL_ZPASS_INC_WRAP
= RADEON_STENCIL_ZPASS_INC
;
1354 tempRADEON_STENCIL_FAIL_DEC_WRAP
= RADEON_STENCIL_FAIL_DEC_WRAP
;
1355 tempRADEON_STENCIL_FAIL_INC_WRAP
= RADEON_STENCIL_FAIL_INC_WRAP
;
1356 tempRADEON_STENCIL_ZFAIL_DEC_WRAP
= RADEON_STENCIL_ZFAIL_DEC_WRAP
;
1357 tempRADEON_STENCIL_ZFAIL_INC_WRAP
= RADEON_STENCIL_ZFAIL_INC_WRAP
;
1358 tempRADEON_STENCIL_ZPASS_DEC_WRAP
= RADEON_STENCIL_ZPASS_DEC_WRAP
;
1359 tempRADEON_STENCIL_ZPASS_INC_WRAP
= RADEON_STENCIL_ZPASS_INC_WRAP
;
1362 RADEON_STATECHANGE( rmesa
, ctx
);
1363 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~(RADEON_STENCIL_FAIL_MASK
|
1364 RADEON_STENCIL_ZFAIL_MASK
|
1365 RADEON_STENCIL_ZPASS_MASK
);
1367 switch ( ctx
->Stencil
.FailFunc
[0] ) {
1369 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_KEEP
;
1372 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_ZERO
;
1375 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_REPLACE
;
1378 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_INC
;
1381 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_DEC
;
1384 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_FAIL_INC_WRAP
;
1387 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_FAIL_DEC_WRAP
;
1390 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_INVERT
;
1394 switch ( ctx
->Stencil
.ZFailFunc
[0] ) {
1396 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_KEEP
;
1399 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_ZERO
;
1402 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_REPLACE
;
1405 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_INC
;
1408 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_DEC
;
1411 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZFAIL_INC_WRAP
;
1414 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZFAIL_DEC_WRAP
;
1417 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_INVERT
;
1421 switch ( ctx
->Stencil
.ZPassFunc
[0] ) {
1423 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_KEEP
;
1426 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_ZERO
;
1429 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_REPLACE
;
1432 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_INC
;
1435 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_DEC
;
1438 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZPASS_INC_WRAP
;
1441 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZPASS_DEC_WRAP
;
1444 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_INVERT
;
1449 static void radeonClearStencil( GLcontext
*ctx
, GLint s
)
1451 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1453 rmesa
->state
.stencil
.clear
=
1454 ((GLuint
) ctx
->Stencil
.Clear
|
1455 (0xff << RADEON_STENCIL_MASK_SHIFT
) |
1456 (ctx
->Stencil
.WriteMask
[0] << RADEON_STENCIL_WRITEMASK_SHIFT
));
1460 /* =============================================================
1461 * Window position and viewport transformation
1465 * To correctly position primitives:
1467 #define SUBPIXEL_X 0.125
1468 #define SUBPIXEL_Y 0.125
1472 * Called when window size or position changes or viewport or depth range
1473 * state is changed. We update the hardware viewport state here.
1475 void radeonUpdateWindow( GLcontext
*ctx
)
1477 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1478 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
1479 GLfloat xoffset
= (GLfloat
)dPriv
->x
;
1480 GLfloat yoffset
= (GLfloat
)dPriv
->y
+ dPriv
->h
;
1481 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1483 GLfloat sx
= v
[MAT_SX
];
1484 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1485 GLfloat sy
= - v
[MAT_SY
];
1486 GLfloat ty
= (- v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1487 GLfloat sz
= v
[MAT_SZ
] * rmesa
->state
.depth
.scale
;
1488 GLfloat tz
= v
[MAT_TZ
] * rmesa
->state
.depth
.scale
;
1489 RADEON_FIREVERTICES( rmesa
);
1490 RADEON_STATECHANGE( rmesa
, vpt
);
1492 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XSCALE
] = *(GLuint
*)&sx
;
1493 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = *(GLuint
*)&tx
;
1494 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YSCALE
] = *(GLuint
*)&sy
;
1495 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = *(GLuint
*)&ty
;
1496 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZSCALE
] = *(GLuint
*)&sz
;
1497 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZOFFSET
] = *(GLuint
*)&tz
;
1501 static void radeonViewport( GLcontext
*ctx
, GLint x
, GLint y
,
1502 GLsizei width
, GLsizei height
)
1504 /* Don't pipeline viewport changes, conflict with window offset
1505 * setting below. Could apply deltas to rescue pipelined viewport
1506 * values, or keep the originals hanging around.
1508 RADEON_FIREVERTICES( RADEON_CONTEXT(ctx
) );
1509 radeonUpdateWindow( ctx
);
1512 static void radeonDepthRange( GLcontext
*ctx
, GLclampd nearval
,
1515 radeonUpdateWindow( ctx
);
1518 void radeonUpdateViewportOffset( GLcontext
*ctx
)
1520 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1521 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
1522 GLfloat xoffset
= (GLfloat
)dPriv
->x
;
1523 GLfloat yoffset
= (GLfloat
)dPriv
->y
+ dPriv
->h
;
1524 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1526 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1527 GLfloat ty
= (- v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1529 if ( rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] != *(GLuint
*)&tx
||
1530 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] != *(GLuint
*)&ty
)
1532 /* Note: this should also modify whatever data the context reset
1535 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = *(GLuint
*)&tx
;
1536 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = *(GLuint
*)&ty
;
1538 /* update polygon stipple x/y screen offset */
1541 GLuint m
= rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
];
1543 m
&= ~(RADEON_STIPPLE_X_OFFSET_MASK
|
1544 RADEON_STIPPLE_Y_OFFSET_MASK
);
1546 /* add magic offsets, then invert */
1547 stx
= 31 - ((rmesa
->dri
.drawable
->x
- 1) & RADEON_STIPPLE_COORD_MASK
);
1548 sty
= 31 - ((rmesa
->dri
.drawable
->y
+ rmesa
->dri
.drawable
->h
- 1)
1549 & RADEON_STIPPLE_COORD_MASK
);
1551 m
|= ((stx
<< RADEON_STIPPLE_X_OFFSET_SHIFT
) |
1552 (sty
<< RADEON_STIPPLE_Y_OFFSET_SHIFT
));
1554 if ( rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
] != m
) {
1555 RADEON_STATECHANGE( rmesa
, msc
);
1556 rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
] = m
;
1561 radeonUpdateScissor( ctx
);
1566 /* =============================================================
1570 static void radeonClearColor( GLcontext
*ctx
, const GLfloat color
[4] )
1572 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1574 CLAMPED_FLOAT_TO_UBYTE(c
[0], color
[0]);
1575 CLAMPED_FLOAT_TO_UBYTE(c
[1], color
[1]);
1576 CLAMPED_FLOAT_TO_UBYTE(c
[2], color
[2]);
1577 CLAMPED_FLOAT_TO_UBYTE(c
[3], color
[3]);
1578 rmesa
->state
.color
.clear
= radeonPackColor( rmesa
->radeonScreen
->cpp
,
1579 c
[0], c
[1], c
[2], c
[3] );
1583 static void radeonRenderMode( GLcontext
*ctx
, GLenum mode
)
1585 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1586 FALLBACK( rmesa
, RADEON_FALLBACK_RENDER_MODE
, (mode
!= GL_RENDER
) );
1590 static GLuint radeon_rop_tab
[] = {
1593 RADEON_ROP_AND_REVERSE
,
1595 RADEON_ROP_AND_INVERTED
,
1602 RADEON_ROP_OR_REVERSE
,
1603 RADEON_ROP_COPY_INVERTED
,
1604 RADEON_ROP_OR_INVERTED
,
1609 static void radeonLogicOpCode( GLcontext
*ctx
, GLenum opcode
)
1611 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1612 GLuint rop
= (GLuint
)opcode
- GL_CLEAR
;
1616 RADEON_STATECHANGE( rmesa
, msk
);
1617 rmesa
->hw
.msk
.cmd
[MSK_RB3D_ROPCNTL
] = radeon_rop_tab
[rop
];
1622 * Set up the cliprects for either front or back-buffer drawing.
1624 void radeonSetCliprects( radeonContextPtr rmesa
)
1626 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
1628 if (rmesa
->glCtx
->DrawBuffer
->_ColorDrawBufferMask
[0]
1629 == BUFFER_BIT_BACK_LEFT
) {
1630 /* Can't ignore 2d windows if we are page flipping.
1632 if ( dPriv
->numBackClipRects
== 0 || rmesa
->doPageFlip
) {
1633 rmesa
->numClipRects
= dPriv
->numClipRects
;
1634 rmesa
->pClipRects
= dPriv
->pClipRects
;
1637 rmesa
->numClipRects
= dPriv
->numBackClipRects
;
1638 rmesa
->pClipRects
= dPriv
->pBackClipRects
;
1642 /* front buffer (or none, or multiple buffers */
1643 rmesa
->numClipRects
= dPriv
->numClipRects
;
1644 rmesa
->pClipRects
= dPriv
->pClipRects
;
1647 if (rmesa
->state
.scissor
.enabled
)
1648 radeonRecalcScissorRects( rmesa
);
1653 * Called via glDrawBuffer.
1655 static void radeonDrawBuffer( GLcontext
*ctx
, GLenum mode
)
1657 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1659 if (RADEON_DEBUG
& DEBUG_DRI
)
1660 fprintf(stderr
, "%s %s\n", __FUNCTION__
,
1661 _mesa_lookup_enum_by_nr( mode
));
1663 RADEON_FIREVERTICES(rmesa
); /* don't pipeline cliprect changes */
1666 * _ColorDrawBufferMask is easier to cope with than <mode>.
1667 * Check for software fallback, update cliprects.
1669 switch ( ctx
->DrawBuffer
->_ColorDrawBufferMask
[0] ) {
1670 case BUFFER_BIT_FRONT_LEFT
:
1671 case BUFFER_BIT_BACK_LEFT
:
1672 FALLBACK( rmesa
, RADEON_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
1675 /* 0 (GL_NONE) buffers or multiple color drawing buffers */
1676 FALLBACK( rmesa
, RADEON_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
1680 radeonSetCliprects( rmesa
);
1682 /* We'll set the drawing engine's offset/pitch parameters later
1683 * when we update other state.
1687 static void radeonReadBuffer( GLcontext
*ctx
, GLenum mode
)
1689 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
1693 /* =============================================================
1694 * State enable/disable
1697 static void radeonEnable( GLcontext
*ctx
, GLenum cap
, GLboolean state
)
1699 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1702 if ( RADEON_DEBUG
& DEBUG_STATE
)
1703 fprintf( stderr
, "%s( %s = %s )\n", __FUNCTION__
,
1704 _mesa_lookup_enum_by_nr( cap
),
1705 state
? "GL_TRUE" : "GL_FALSE" );
1708 /* Fast track this one...
1716 RADEON_STATECHANGE( rmesa
, ctx
);
1718 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ALPHA_TEST_ENABLE
;
1720 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ALPHA_TEST_ENABLE
;
1725 RADEON_STATECHANGE( rmesa
, ctx
);
1727 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ALPHA_BLEND_ENABLE
;
1729 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ALPHA_BLEND_ENABLE
;
1731 if ( ctx
->Color
._LogicOpEnabled
) {
1732 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
1734 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
1737 /* Catch a possible fallback:
1740 ctx
->Driver
.BlendEquationSeparate( ctx
,
1741 ctx
->Color
.BlendEquationRGB
,
1742 ctx
->Color
.BlendEquationA
);
1743 ctx
->Driver
.BlendFuncSeparate( ctx
, ctx
->Color
.BlendSrcRGB
,
1744 ctx
->Color
.BlendDstRGB
,
1745 ctx
->Color
.BlendSrcA
,
1746 ctx
->Color
.BlendDstA
);
1749 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_FUNC
, GL_FALSE
);
1750 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_EQ
, GL_FALSE
);
1754 case GL_CLIP_PLANE0
:
1755 case GL_CLIP_PLANE1
:
1756 case GL_CLIP_PLANE2
:
1757 case GL_CLIP_PLANE3
:
1758 case GL_CLIP_PLANE4
:
1759 case GL_CLIP_PLANE5
:
1760 p
= cap
-GL_CLIP_PLANE0
;
1761 RADEON_STATECHANGE( rmesa
, tcl
);
1763 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= (RADEON_UCP_ENABLE_0
<<p
);
1764 radeonClipPlane( ctx
, cap
, NULL
);
1767 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~(RADEON_UCP_ENABLE_0
<<p
);
1771 case GL_COLOR_MATERIAL
:
1772 radeonColorMaterial( ctx
, 0, 0 );
1773 radeonUpdateMaterial( ctx
);
1777 radeonCullFace( ctx
, 0 );
1781 RADEON_STATECHANGE(rmesa
, ctx
);
1783 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_Z_ENABLE
;
1785 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_Z_ENABLE
;
1790 RADEON_STATECHANGE(rmesa
, ctx
);
1792 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_DITHER_ENABLE
;
1793 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~rmesa
->state
.color
.roundEnable
;
1795 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_DITHER_ENABLE
;
1796 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= rmesa
->state
.color
.roundEnable
;
1801 RADEON_STATECHANGE(rmesa
, ctx
);
1803 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_FOG_ENABLE
;
1804 radeonFogfv( ctx
, GL_FOG_MODE
, NULL
);
1806 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_FOG_ENABLE
;
1807 RADEON_STATECHANGE(rmesa
, tcl
);
1808 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_TCL_FOG_MASK
;
1810 radeonUpdateSpecular( ctx
); /* for PK_SPEC */
1811 _mesa_allow_light_in_model( ctx
, !state
);
1822 RADEON_STATECHANGE(rmesa
, tcl
);
1823 p
= cap
- GL_LIGHT0
;
1825 flag
= (RADEON_LIGHT_1_ENABLE
|
1826 RADEON_LIGHT_1_ENABLE_AMBIENT
|
1827 RADEON_LIGHT_1_ENABLE_SPECULAR
);
1829 flag
= (RADEON_LIGHT_0_ENABLE
|
1830 RADEON_LIGHT_0_ENABLE_AMBIENT
|
1831 RADEON_LIGHT_0_ENABLE_SPECULAR
);
1834 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] |= flag
;
1836 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] &= ~flag
;
1840 update_light_colors( ctx
, p
);
1844 RADEON_STATECHANGE(rmesa
, tcl
);
1845 radeonUpdateSpecular(ctx
);
1846 check_twoside_fallback( ctx
);
1849 case GL_LINE_SMOOTH
:
1850 RADEON_STATECHANGE( rmesa
, ctx
);
1852 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ANTI_ALIAS_LINE
;
1854 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ANTI_ALIAS_LINE
;
1858 case GL_LINE_STIPPLE
:
1859 RADEON_STATECHANGE( rmesa
, ctx
);
1861 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_PATTERN_ENABLE
;
1863 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_PATTERN_ENABLE
;
1867 case GL_COLOR_LOGIC_OP
:
1868 RADEON_STATECHANGE( rmesa
, ctx
);
1869 if ( ctx
->Color
._LogicOpEnabled
) {
1870 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
1872 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
1877 RADEON_STATECHANGE( rmesa
, tcl
);
1879 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_NORMALIZE_NORMALS
;
1881 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_NORMALIZE_NORMALS
;
1885 case GL_POLYGON_OFFSET_POINT
:
1886 RADEON_STATECHANGE( rmesa
, set
);
1888 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_POINT
;
1890 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_POINT
;
1894 case GL_POLYGON_OFFSET_LINE
:
1895 RADEON_STATECHANGE( rmesa
, set
);
1897 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_LINE
;
1899 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_LINE
;
1903 case GL_POLYGON_OFFSET_FILL
:
1904 RADEON_STATECHANGE( rmesa
, set
);
1906 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_TRI
;
1908 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_TRI
;
1912 case GL_POLYGON_SMOOTH
:
1913 RADEON_STATECHANGE( rmesa
, ctx
);
1915 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ANTI_ALIAS_POLY
;
1917 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ANTI_ALIAS_POLY
;
1921 case GL_POLYGON_STIPPLE
:
1922 RADEON_STATECHANGE(rmesa
, ctx
);
1924 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_STIPPLE_ENABLE
;
1926 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_STIPPLE_ENABLE
;
1930 case GL_RESCALE_NORMAL_EXT
: {
1931 GLboolean tmp
= ctx
->_NeedEyeCoords
? state
: !state
;
1932 RADEON_STATECHANGE( rmesa
, tcl
);
1934 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_RESCALE_NORMALS
;
1936 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_RESCALE_NORMALS
;
1941 case GL_SCISSOR_TEST
:
1942 RADEON_FIREVERTICES( rmesa
);
1943 rmesa
->state
.scissor
.enabled
= state
;
1944 radeonUpdateScissor( ctx
);
1947 case GL_STENCIL_TEST
:
1948 if ( rmesa
->state
.stencil
.hwBuffer
) {
1949 RADEON_STATECHANGE( rmesa
, ctx
);
1951 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_STENCIL_ENABLE
;
1953 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_STENCIL_ENABLE
;
1956 FALLBACK( rmesa
, RADEON_FALLBACK_STENCIL
, state
);
1960 case GL_TEXTURE_GEN_Q
:
1961 case GL_TEXTURE_GEN_R
:
1962 case GL_TEXTURE_GEN_S
:
1963 case GL_TEXTURE_GEN_T
:
1964 /* Picked up in radeonUpdateTextureState.
1966 rmesa
->recheck_texgen
[ctx
->Texture
.CurrentUnit
] = GL_TRUE
;
1969 case GL_COLOR_SUM_EXT
:
1970 radeonUpdateSpecular ( ctx
);
1979 static void radeonLightingSpaceChange( GLcontext
*ctx
)
1981 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1983 RADEON_STATECHANGE( rmesa
, tcl
);
1985 if (RADEON_DEBUG
& DEBUG_STATE
)
1986 fprintf(stderr
, "%s %d BEFORE %x\n", __FUNCTION__
, ctx
->_NeedEyeCoords
,
1987 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]);
1989 if (ctx
->_NeedEyeCoords
)
1990 tmp
= ctx
->Transform
.RescaleNormals
;
1992 tmp
= !ctx
->Transform
.RescaleNormals
;
1995 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_RESCALE_NORMALS
;
1997 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_RESCALE_NORMALS
;
2000 if (RADEON_DEBUG
& DEBUG_STATE
)
2001 fprintf(stderr
, "%s %d AFTER %x\n", __FUNCTION__
, ctx
->_NeedEyeCoords
,
2002 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]);
2005 /* =============================================================
2006 * Deferred state management - matrices, textures, other?
2009 static void texmat_set_texrect( radeonContextPtr rmesa
,
2010 struct gl_texture_object
*tObj
, GLuint unit
)
2012 const struct gl_texture_image
*baseImage
= tObj
->Image
[0][tObj
->BaseLevel
];
2013 _math_matrix_set_identity( &rmesa
->tmpmat
[unit
] );
2014 rmesa
->tmpmat
[unit
].m
[0] = 1.0 / baseImage
->Width
;
2015 rmesa
->tmpmat
[unit
].m
[5] = 1.0 / baseImage
->Height
;
2019 static void texmat_fixup_texrect( radeonContextPtr rmesa
,
2020 struct gl_texture_object
*tObj
, GLuint unit
)
2022 const struct gl_texture_image
*baseImage
= tObj
->Image
[0][tObj
->BaseLevel
];
2024 for (i
= 0; i
< 4; i
++) {
2025 rmesa
->tmpmat
[unit
].m
[i
] = rmesa
->tmpmat
[unit
].m
[i
] / baseImage
->Width
;
2026 rmesa
->tmpmat
[unit
].m
[i
+4] = rmesa
->tmpmat
[unit
].m
[i
+4] / baseImage
->Height
;
2030 void radeonUploadTexMatrix( radeonContextPtr rmesa
,
2031 int unit
, GLboolean swapcols
)
2033 /* Here's how this works: on r100, only 3 tex coords can be submitted, so the
2034 vector looks like this probably: (s t r|q 0) (not sure if the last coord
2035 is hardwired to 0, could be 1 too). Interestingly, it actually looks like
2036 texgen generates all 4 coords, at least tests with projtex indicated that.
2037 So: if we need the q coord in the end (solely determined by the texture
2038 target, i.e. 2d / 1d / texrect targets) we swap the third and 4th row.
2039 Additionally, if we don't have texgen but 4 tex coords submitted, we swap
2040 column 3 and 4 (for the 2d / 1d / texrect targets) since the the q coord
2041 will get submitted in the "wrong", i.e. 3rd, slot.
2042 If an app submits 3 coords for 2d targets, we assume it is saving on vertex
2043 size and using the texture matrix to swap the r and q coords around (ut2k3
2044 does exactly that), so we don't need the 3rd / 4th column swap - still need
2045 the 3rd / 4th row swap of course. This will potentially break for apps which
2046 use TexCoord3x just for fun. Additionally, it will never work if an app uses
2047 an "advanced" texture matrix and relies on all 4 texcoord inputs to generate
2048 the maximum needed 3. This seems impossible to do with hw tcl on r100, and
2049 incredibly hard to detect so we can't just fallback in such a case. Assume
2050 it never happens... - rs
2053 int idx
= TEXMAT_0
+ unit
;
2054 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] )) + MAT_ELT_0
;
2056 struct gl_texture_unit tUnit
= rmesa
->glCtx
->Texture
.Unit
[unit
];
2057 GLfloat
*src
= rmesa
->tmpmat
[unit
].m
;
2059 rmesa
->TexMatColSwap
&= ~(1 << unit
);
2060 if ((tUnit
._ReallyEnabled
& (TEXTURE_3D_BIT
| TEXTURE_CUBE_BIT
)) == 0) {
2062 rmesa
->TexMatColSwap
|= 1 << unit
;
2063 /* attention some elems are swapped 2 times! */
2076 /* those last 4 are probably never used */
2083 for (i
= 0; i
< 2; i
++) {
2087 *dest
++ = src
[i
+12];
2089 for (i
= 3; i
>= 2; i
--) {
2093 *dest
++ = src
[i
+12];
2098 for (i
= 0 ; i
< 4 ; i
++) {
2102 *dest
++ = src
[i
+12];
2106 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
2110 static void upload_matrix( radeonContextPtr rmesa
, GLfloat
*src
, int idx
)
2112 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
2116 for (i
= 0 ; i
< 4 ; i
++) {
2120 *dest
++ = src
[i
+12];
2123 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
2126 static void upload_matrix_t( radeonContextPtr rmesa
, GLfloat
*src
, int idx
)
2128 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
2129 memcpy(dest
, src
, 16*sizeof(float));
2130 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
2134 static void update_texturematrix( GLcontext
*ctx
)
2136 radeonContextPtr rmesa
= RADEON_CONTEXT( ctx
);
2137 GLuint tpc
= rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
];
2138 GLuint vs
= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
];
2140 GLuint texMatEnabled
= 0;
2141 rmesa
->NeedTexMatrix
= 0;
2142 rmesa
->TexMatColSwap
= 0;
2144 for (unit
= 0 ; unit
< ctx
->Const
.MaxTextureUnits
; unit
++) {
2145 if (ctx
->Texture
.Unit
[unit
]._ReallyEnabled
) {
2146 GLboolean needMatrix
= GL_FALSE
;
2147 if (ctx
->TextureMatrixStack
[unit
].Top
->type
!= MATRIX_IDENTITY
) {
2148 needMatrix
= GL_TRUE
;
2149 texMatEnabled
|= (RADEON_TEXGEN_TEXMAT_0_ENABLE
|
2150 RADEON_TEXMAT_0_ENABLE
) << unit
;
2152 if (rmesa
->TexGenEnabled
& (RADEON_TEXMAT_0_ENABLE
<< unit
)) {
2153 /* Need to preconcatenate any active texgen
2154 * obj/eyeplane matrices:
2156 _math_matrix_mul_matrix( &rmesa
->tmpmat
[unit
],
2157 ctx
->TextureMatrixStack
[unit
].Top
,
2158 &rmesa
->TexGenMatrix
[unit
] );
2161 _math_matrix_copy( &rmesa
->tmpmat
[unit
],
2162 ctx
->TextureMatrixStack
[unit
].Top
);
2165 else if (rmesa
->TexGenEnabled
& (RADEON_TEXMAT_0_ENABLE
<< unit
)) {
2166 _math_matrix_copy( &rmesa
->tmpmat
[unit
], &rmesa
->TexGenMatrix
[unit
] );
2167 needMatrix
= GL_TRUE
;
2169 if (ctx
->Texture
.Unit
[unit
]._ReallyEnabled
== TEXTURE_RECT_BIT
) {
2170 texMatEnabled
|= (RADEON_TEXGEN_TEXMAT_0_ENABLE
|
2171 RADEON_TEXMAT_0_ENABLE
) << unit
;
2173 texmat_fixup_texrect( rmesa
, ctx
->Texture
.Unit
[unit
]._Current
, unit
);
2175 texmat_set_texrect( rmesa
, ctx
->Texture
.Unit
[unit
]._Current
, unit
);
2176 needMatrix
= GL_TRUE
;
2179 rmesa
->NeedTexMatrix
|= 1 << unit
;
2180 radeonUploadTexMatrix( rmesa
, unit
,
2181 !ctx
->Texture
.Unit
[unit
].TexGenEnabled
);
2186 tpc
= (texMatEnabled
| rmesa
->TexGenEnabled
);
2188 /* TCL_TEX_COMPUTED_x is TCL_TEX_INPUT_x | 0x8 */
2189 vs
&= ~((RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_0_OUTPUT_SHIFT
) |
2190 (RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_1_OUTPUT_SHIFT
) |
2191 (RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_2_OUTPUT_SHIFT
));
2193 vs
|= (((tpc
& RADEON_TEXGEN_TEXMAT_0_ENABLE
) <<
2194 (RADEON_TCL_TEX_0_OUTPUT_SHIFT
+ 3)) |
2195 ((tpc
& RADEON_TEXGEN_TEXMAT_1_ENABLE
) <<
2196 (RADEON_TCL_TEX_1_OUTPUT_SHIFT
+ 2)) |
2197 ((tpc
& RADEON_TEXGEN_TEXMAT_2_ENABLE
) <<
2198 (RADEON_TCL_TEX_2_OUTPUT_SHIFT
+ 1)));
2200 if (tpc
!= rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
] ||
2201 vs
!= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
]) {
2203 RADEON_STATECHANGE(rmesa
, tcl
);
2204 rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
] = tpc
;
2205 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] = vs
;
2211 * Tell the card where to render (offset, pitch).
2212 * Effected by glDrawBuffer, etc
2215 radeonUpdateDrawBuffer(GLcontext
*ctx
)
2217 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2218 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
2219 driRenderbuffer
*drb
;
2221 if (fb
->_ColorDrawBufferMask
[0] == BUFFER_BIT_FRONT_LEFT
) {
2223 drb
= (driRenderbuffer
*) fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
;
2225 else if (fb
->_ColorDrawBufferMask
[0] == BUFFER_BIT_BACK_LEFT
) {
2227 drb
= (driRenderbuffer
*) fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
;
2230 /* drawing to multiple buffers, or none */
2235 assert(drb
->flippedPitch
);
2237 RADEON_STATECHANGE( rmesa
, ctx
);
2239 /* Note: we used the (possibly) page-flipped values */
2240 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLOROFFSET
]
2241 = ((drb
->flippedOffset
+ rmesa
->radeonScreen
->fbLocation
)
2242 & RADEON_COLOROFFSET_MASK
);
2243 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] = drb
->flippedPitch
;
2244 if (rmesa
->sarea
->tiling_enabled
) {
2245 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] |= RADEON_COLOR_TILE_ENABLE
;
2250 void radeonValidateState( GLcontext
*ctx
)
2252 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2253 GLuint new_state
= rmesa
->NewGLState
;
2255 if (new_state
& (_NEW_BUFFERS
| _NEW_COLOR
| _NEW_PIXEL
)) {
2256 radeonUpdateDrawBuffer(ctx
);
2259 if (new_state
& _NEW_TEXTURE
) {
2260 radeonUpdateTextureState( ctx
);
2261 new_state
|= rmesa
->NewGLState
; /* may add TEXTURE_MATRIX */
2264 /* Need an event driven matrix update?
2266 if (new_state
& (_NEW_MODELVIEW
|_NEW_PROJECTION
))
2267 upload_matrix( rmesa
, ctx
->_ModelProjectMatrix
.m
, MODEL_PROJ
);
2269 /* Need these for lighting (shouldn't upload otherwise)
2271 if (new_state
& (_NEW_MODELVIEW
)) {
2272 upload_matrix( rmesa
, ctx
->ModelviewMatrixStack
.Top
->m
, MODEL
);
2273 upload_matrix_t( rmesa
, ctx
->ModelviewMatrixStack
.Top
->inv
, MODEL_IT
);
2276 /* Does this need to be triggered on eg. modelview for
2277 * texgen-derived objplane/eyeplane matrices?
2279 if (new_state
& _NEW_TEXTURE_MATRIX
) {
2280 update_texturematrix( ctx
);
2283 if (new_state
& (_NEW_LIGHT
|_NEW_MODELVIEW
|_MESA_NEW_NEED_EYE_COORDS
)) {
2284 update_light( ctx
);
2287 /* emit all active clip planes if projection matrix changes.
2289 if (new_state
& (_NEW_PROJECTION
)) {
2290 if (ctx
->Transform
.ClipPlanesEnabled
)
2291 radeonUpdateClipPlanes( ctx
);
2295 rmesa
->NewGLState
= 0;
2299 static void radeonInvalidateState( GLcontext
*ctx
, GLuint new_state
)
2301 _swrast_InvalidateState( ctx
, new_state
);
2302 _swsetup_InvalidateState( ctx
, new_state
);
2303 _ac_InvalidateState( ctx
, new_state
);
2304 _tnl_InvalidateState( ctx
, new_state
);
2305 _ae_invalidate_state( ctx
, new_state
);
2306 RADEON_CONTEXT(ctx
)->NewGLState
|= new_state
;
2307 radeonVtxfmtInvalidate( ctx
);
2311 /* A hack. Need a faster way to find this out.
2313 static GLboolean
check_material( GLcontext
*ctx
)
2315 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
2318 for (i
= _TNL_ATTRIB_MAT_FRONT_AMBIENT
;
2319 i
< _TNL_ATTRIB_MAT_BACK_INDEXES
;
2321 if (tnl
->vb
.AttribPtr
[i
] &&
2322 tnl
->vb
.AttribPtr
[i
]->stride
)
2329 static void radeonWrapRunPipeline( GLcontext
*ctx
)
2331 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2332 GLboolean has_material
;
2335 fprintf(stderr
, "%s, newstate: %x\n", __FUNCTION__
, rmesa
->NewGLState
);
2339 if (rmesa
->NewGLState
)
2340 radeonValidateState( ctx
);
2342 has_material
= (ctx
->Light
.Enabled
&& check_material( ctx
));
2345 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_MATERIAL
, GL_TRUE
);
2348 /* Run the pipeline.
2350 _tnl_run_pipeline( ctx
);
2353 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_MATERIAL
, GL_FALSE
);
2358 /* Initialize the driver's state functions.
2359 * Many of the ctx->Driver functions might have been initialized to
2360 * software defaults in the earlier _mesa_init_driver_functions() call.
2362 void radeonInitStateFuncs( GLcontext
*ctx
)
2364 ctx
->Driver
.UpdateState
= radeonInvalidateState
;
2365 ctx
->Driver
.LightingSpaceChange
= radeonLightingSpaceChange
;
2367 ctx
->Driver
.DrawBuffer
= radeonDrawBuffer
;
2368 ctx
->Driver
.ReadBuffer
= radeonReadBuffer
;
2370 ctx
->Driver
.AlphaFunc
= radeonAlphaFunc
;
2371 ctx
->Driver
.BlendEquationSeparate
= radeonBlendEquationSeparate
;
2372 ctx
->Driver
.BlendFuncSeparate
= radeonBlendFuncSeparate
;
2373 ctx
->Driver
.ClearColor
= radeonClearColor
;
2374 ctx
->Driver
.ClearDepth
= radeonClearDepth
;
2375 ctx
->Driver
.ClearIndex
= NULL
;
2376 ctx
->Driver
.ClearStencil
= radeonClearStencil
;
2377 ctx
->Driver
.ClipPlane
= radeonClipPlane
;
2378 ctx
->Driver
.ColorMask
= radeonColorMask
;
2379 ctx
->Driver
.CullFace
= radeonCullFace
;
2380 ctx
->Driver
.DepthFunc
= radeonDepthFunc
;
2381 ctx
->Driver
.DepthMask
= radeonDepthMask
;
2382 ctx
->Driver
.DepthRange
= radeonDepthRange
;
2383 ctx
->Driver
.Enable
= radeonEnable
;
2384 ctx
->Driver
.Fogfv
= radeonFogfv
;
2385 ctx
->Driver
.FrontFace
= radeonFrontFace
;
2386 ctx
->Driver
.Hint
= NULL
;
2387 ctx
->Driver
.IndexMask
= NULL
;
2388 ctx
->Driver
.LightModelfv
= radeonLightModelfv
;
2389 ctx
->Driver
.Lightfv
= radeonLightfv
;
2390 ctx
->Driver
.LineStipple
= radeonLineStipple
;
2391 ctx
->Driver
.LineWidth
= radeonLineWidth
;
2392 ctx
->Driver
.LogicOpcode
= radeonLogicOpCode
;
2393 ctx
->Driver
.PolygonMode
= radeonPolygonMode
;
2394 ctx
->Driver
.PolygonOffset
= radeonPolygonOffset
;
2395 ctx
->Driver
.PolygonStipple
= radeonPolygonStipple
;
2396 ctx
->Driver
.RenderMode
= radeonRenderMode
;
2397 ctx
->Driver
.Scissor
= radeonScissor
;
2398 ctx
->Driver
.ShadeModel
= radeonShadeModel
;
2399 ctx
->Driver
.StencilFuncSeparate
= radeonStencilFuncSeparate
;
2400 ctx
->Driver
.StencilMaskSeparate
= radeonStencilMaskSeparate
;
2401 ctx
->Driver
.StencilOpSeparate
= radeonStencilOpSeparate
;
2402 ctx
->Driver
.Viewport
= radeonViewport
;
2404 TNL_CONTEXT(ctx
)->Driver
.NotifyMaterialChange
= radeonUpdateMaterial
;
2405 TNL_CONTEXT(ctx
)->Driver
.RunPipeline
= radeonWrapRunPipeline
;