1 /**************************************************************************
3 Copyright 2000, 2001 VA Linux Systems Inc., Fremont, California.
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 "Software"), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sublicense, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
15 The above copyright notice and this permission notice (including the
16 next paragraph) shall be included in all copies or substantial
17 portions of the Software.
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
23 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 **************************************************************************/
31 * Gareth Hughes <gareth@valinux.com>
32 * Keith Whitwell <keith@tungstengraphics.com>
35 #include "main/glheader.h"
36 #include "main/imports.h"
37 #include "main/api_arrayelt.h"
38 #include "main/enums.h"
39 #include "main/light.h"
40 #include "main/state.h"
41 #include "main/context.h"
42 #include "main/framebuffer.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 "drirenderbuffer.h"
57 static void radeonUpdateSpecular( GLcontext
*ctx
);
59 /* =============================================================
63 static void radeonAlphaFunc( GLcontext
*ctx
, GLenum func
, GLfloat ref
)
65 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
66 int pp_misc
= rmesa
->hw
.ctx
.cmd
[CTX_PP_MISC
];
69 CLAMPED_FLOAT_TO_UBYTE(refByte
, ref
);
71 RADEON_STATECHANGE( rmesa
, ctx
);
73 pp_misc
&= ~(RADEON_ALPHA_TEST_OP_MASK
| RADEON_REF_ALPHA_MASK
);
74 pp_misc
|= (refByte
& RADEON_REF_ALPHA_MASK
);
78 pp_misc
|= RADEON_ALPHA_TEST_FAIL
;
81 pp_misc
|= RADEON_ALPHA_TEST_LESS
;
84 pp_misc
|= RADEON_ALPHA_TEST_EQUAL
;
87 pp_misc
|= RADEON_ALPHA_TEST_LEQUAL
;
90 pp_misc
|= RADEON_ALPHA_TEST_GREATER
;
93 pp_misc
|= RADEON_ALPHA_TEST_NEQUAL
;
96 pp_misc
|= RADEON_ALPHA_TEST_GEQUAL
;
99 pp_misc
|= RADEON_ALPHA_TEST_PASS
;
103 rmesa
->hw
.ctx
.cmd
[CTX_PP_MISC
] = pp_misc
;
106 static void radeonBlendEquationSeparate( GLcontext
*ctx
,
107 GLenum modeRGB
, GLenum modeA
)
109 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
110 GLuint b
= rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] & ~RADEON_COMB_FCN_MASK
;
111 GLboolean fallback
= GL_FALSE
;
113 assert( modeRGB
== modeA
);
118 b
|= RADEON_COMB_FCN_ADD_CLAMP
;
121 case GL_FUNC_SUBTRACT
:
122 b
|= RADEON_COMB_FCN_SUB_CLAMP
;
126 if (ctx
->Color
.BlendEnabled
)
129 b
|= RADEON_COMB_FCN_ADD_CLAMP
;
133 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_EQ
, fallback
);
135 RADEON_STATECHANGE( rmesa
, ctx
);
136 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = b
;
137 if ( (ctx
->Color
.ColorLogicOpEnabled
|| (ctx
->Color
.BlendEnabled
138 && ctx
->Color
.BlendEquationRGB
== GL_LOGIC_OP
)) ) {
139 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
141 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
146 static void radeonBlendFuncSeparate( GLcontext
*ctx
,
147 GLenum sfactorRGB
, GLenum dfactorRGB
,
148 GLenum sfactorA
, GLenum dfactorA
)
150 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
151 GLuint b
= rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] &
152 ~(RADEON_SRC_BLEND_MASK
| RADEON_DST_BLEND_MASK
);
153 GLboolean fallback
= GL_FALSE
;
155 switch ( ctx
->Color
.BlendSrcRGB
) {
157 b
|= RADEON_SRC_BLEND_GL_ZERO
;
160 b
|= RADEON_SRC_BLEND_GL_ONE
;
163 b
|= RADEON_SRC_BLEND_GL_DST_COLOR
;
165 case GL_ONE_MINUS_DST_COLOR
:
166 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_COLOR
;
169 b
|= RADEON_SRC_BLEND_GL_SRC_COLOR
;
171 case GL_ONE_MINUS_SRC_COLOR
:
172 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR
;
175 b
|= RADEON_SRC_BLEND_GL_SRC_ALPHA
;
177 case GL_ONE_MINUS_SRC_ALPHA
:
178 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
181 b
|= RADEON_SRC_BLEND_GL_DST_ALPHA
;
183 case GL_ONE_MINUS_DST_ALPHA
:
184 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA
;
186 case GL_SRC_ALPHA_SATURATE
:
187 b
|= RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE
;
189 case GL_CONSTANT_COLOR
:
190 case GL_ONE_MINUS_CONSTANT_COLOR
:
191 case GL_CONSTANT_ALPHA
:
192 case GL_ONE_MINUS_CONSTANT_ALPHA
:
193 if (ctx
->Color
.BlendEnabled
)
196 b
|= RADEON_SRC_BLEND_GL_ONE
;
202 switch ( ctx
->Color
.BlendDstRGB
) {
204 b
|= RADEON_DST_BLEND_GL_ZERO
;
207 b
|= RADEON_DST_BLEND_GL_ONE
;
210 b
|= RADEON_DST_BLEND_GL_SRC_COLOR
;
212 case GL_ONE_MINUS_SRC_COLOR
:
213 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_COLOR
;
216 b
|= RADEON_DST_BLEND_GL_SRC_ALPHA
;
218 case GL_ONE_MINUS_SRC_ALPHA
:
219 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
222 b
|= RADEON_DST_BLEND_GL_DST_COLOR
;
224 case GL_ONE_MINUS_DST_COLOR
:
225 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_DST_COLOR
;
228 b
|= RADEON_DST_BLEND_GL_DST_ALPHA
;
230 case GL_ONE_MINUS_DST_ALPHA
:
231 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_DST_ALPHA
;
233 case GL_CONSTANT_COLOR
:
234 case GL_ONE_MINUS_CONSTANT_COLOR
:
235 case GL_CONSTANT_ALPHA
:
236 case GL_ONE_MINUS_CONSTANT_ALPHA
:
237 if (ctx
->Color
.BlendEnabled
)
240 b
|= RADEON_DST_BLEND_GL_ZERO
;
246 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_FUNC
, fallback
);
248 RADEON_STATECHANGE( rmesa
, ctx
);
249 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = b
;
254 /* =============================================================
258 static void radeonDepthFunc( GLcontext
*ctx
, GLenum func
)
260 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
262 RADEON_STATECHANGE( rmesa
, ctx
);
263 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_Z_TEST_MASK
;
265 switch ( ctx
->Depth
.Func
) {
267 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_NEVER
;
270 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_LESS
;
273 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_EQUAL
;
276 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_LEQUAL
;
279 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_GREATER
;
282 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_NEQUAL
;
285 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_GEQUAL
;
288 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_ALWAYS
;
294 static void radeonDepthMask( GLcontext
*ctx
, GLboolean flag
)
296 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
297 RADEON_STATECHANGE( rmesa
, ctx
);
299 if ( ctx
->Depth
.Mask
) {
300 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_WRITE_ENABLE
;
302 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_Z_WRITE_ENABLE
;
306 static void radeonClearDepth( GLcontext
*ctx
, GLclampd d
)
308 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
309 GLuint format
= (rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &
310 RADEON_DEPTH_FORMAT_MASK
);
313 case RADEON_DEPTH_FORMAT_16BIT_INT_Z
:
314 rmesa
->state
.depth
.clear
= d
* 0x0000ffff;
316 case RADEON_DEPTH_FORMAT_24BIT_INT_Z
:
317 rmesa
->state
.depth
.clear
= d
* 0x00ffffff;
323 /* =============================================================
328 static void radeonFogfv( GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
330 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
331 union { int i
; float f
; } c
, d
;
336 if (!ctx
->Fog
.Enabled
)
338 RADEON_STATECHANGE(rmesa
, tcl
);
339 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_TCL_FOG_MASK
;
340 switch (ctx
->Fog
.Mode
) {
342 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_LINEAR
;
345 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_EXP
;
348 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_EXP2
;
357 if (!ctx
->Fog
.Enabled
)
359 c
.i
= rmesa
->hw
.fog
.cmd
[FOG_C
];
360 d
.i
= rmesa
->hw
.fog
.cmd
[FOG_D
];
361 switch (ctx
->Fog
.Mode
) {
364 /* While this is the opposite sign from the DDK, it makes the fog test
365 * pass, and matches r200.
367 d
.f
= -ctx
->Fog
.Density
;
371 d
.f
= -(ctx
->Fog
.Density
* ctx
->Fog
.Density
);
374 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
378 c
.f
= ctx
->Fog
.End
/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
379 /* While this is the opposite sign from the DDK, it makes the fog
380 * test pass, and matches r200.
382 d
.f
= -1.0/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
388 if (c
.i
!= rmesa
->hw
.fog
.cmd
[FOG_C
] || d
.i
!= rmesa
->hw
.fog
.cmd
[FOG_D
]) {
389 RADEON_STATECHANGE( rmesa
, fog
);
390 rmesa
->hw
.fog
.cmd
[FOG_C
] = c
.i
;
391 rmesa
->hw
.fog
.cmd
[FOG_D
] = d
.i
;
395 RADEON_STATECHANGE( rmesa
, ctx
);
396 UNCLAMPED_FLOAT_TO_RGB_CHAN( col
, ctx
->Fog
.Color
);
397 rmesa
->hw
.ctx
.cmd
[CTX_PP_FOG_COLOR
] &= ~RADEON_FOG_COLOR_MASK
;
398 rmesa
->hw
.ctx
.cmd
[CTX_PP_FOG_COLOR
] |=
399 radeonPackColor( 4, col
[0], col
[1], col
[2], 0 );
401 case GL_FOG_COORD_SRC
:
402 radeonUpdateSpecular( ctx
);
410 /* =============================================================
415 static GLboolean
intersect_rect( drm_clip_rect_t
*out
,
420 if ( b
->x1
> out
->x1
) out
->x1
= b
->x1
;
421 if ( b
->y1
> out
->y1
) out
->y1
= b
->y1
;
422 if ( b
->x2
< out
->x2
) out
->x2
= b
->x2
;
423 if ( b
->y2
< out
->y2
) out
->y2
= b
->y2
;
424 if ( out
->x1
>= out
->x2
) return GL_FALSE
;
425 if ( out
->y1
>= out
->y2
) return GL_FALSE
;
430 void radeonRecalcScissorRects( radeonContextPtr rmesa
)
432 drm_clip_rect_t
*out
;
435 /* Grow cliprect store?
437 if (rmesa
->state
.scissor
.numAllocedClipRects
< rmesa
->numClipRects
) {
438 while (rmesa
->state
.scissor
.numAllocedClipRects
< rmesa
->numClipRects
) {
439 rmesa
->state
.scissor
.numAllocedClipRects
+= 1; /* zero case */
440 rmesa
->state
.scissor
.numAllocedClipRects
*= 2;
443 if (rmesa
->state
.scissor
.pClipRects
)
444 FREE(rmesa
->state
.scissor
.pClipRects
);
446 rmesa
->state
.scissor
.pClipRects
=
447 MALLOC( rmesa
->state
.scissor
.numAllocedClipRects
*
448 sizeof(drm_clip_rect_t
) );
450 if ( rmesa
->state
.scissor
.pClipRects
== NULL
) {
451 rmesa
->state
.scissor
.numAllocedClipRects
= 0;
456 out
= rmesa
->state
.scissor
.pClipRects
;
457 rmesa
->state
.scissor
.numClipRects
= 0;
459 for ( i
= 0 ; i
< rmesa
->numClipRects
; i
++ ) {
460 if ( intersect_rect( out
,
461 &rmesa
->pClipRects
[i
],
462 &rmesa
->state
.scissor
.rect
) ) {
463 rmesa
->state
.scissor
.numClipRects
++;
470 static void radeonUpdateScissor( GLcontext
*ctx
)
472 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
474 if ( rmesa
->dri
.drawable
) {
475 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
477 int x
= ctx
->Scissor
.X
;
478 int y
= dPriv
->h
- ctx
->Scissor
.Y
- ctx
->Scissor
.Height
;
479 int w
= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
- 1;
480 int h
= dPriv
->h
- ctx
->Scissor
.Y
- 1;
482 rmesa
->state
.scissor
.rect
.x1
= x
+ dPriv
->x
;
483 rmesa
->state
.scissor
.rect
.y1
= y
+ dPriv
->y
;
484 rmesa
->state
.scissor
.rect
.x2
= w
+ dPriv
->x
+ 1;
485 rmesa
->state
.scissor
.rect
.y2
= h
+ dPriv
->y
+ 1;
487 radeonRecalcScissorRects( rmesa
);
492 static void radeonScissor( GLcontext
*ctx
,
493 GLint x
, GLint y
, GLsizei w
, GLsizei h
)
495 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
497 if ( ctx
->Scissor
.Enabled
) {
498 RADEON_FIREVERTICES( rmesa
); /* don't pipeline cliprect changes */
499 radeonUpdateScissor( ctx
);
505 /* =============================================================
509 static void radeonCullFace( GLcontext
*ctx
, GLenum unused
)
511 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
512 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
513 GLuint t
= rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
];
515 s
|= RADEON_FFACE_SOLID
| RADEON_BFACE_SOLID
;
516 t
&= ~(RADEON_CULL_FRONT
| RADEON_CULL_BACK
);
518 if ( ctx
->Polygon
.CullFlag
) {
519 switch ( ctx
->Polygon
.CullFaceMode
) {
521 s
&= ~RADEON_FFACE_SOLID
;
522 t
|= RADEON_CULL_FRONT
;
525 s
&= ~RADEON_BFACE_SOLID
;
526 t
|= RADEON_CULL_BACK
;
528 case GL_FRONT_AND_BACK
:
529 s
&= ~(RADEON_FFACE_SOLID
| RADEON_BFACE_SOLID
);
530 t
|= (RADEON_CULL_FRONT
| RADEON_CULL_BACK
);
535 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
536 RADEON_STATECHANGE(rmesa
, set
);
537 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
540 if ( rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] != t
) {
541 RADEON_STATECHANGE(rmesa
, tcl
);
542 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] = t
;
546 static void radeonFrontFace( GLcontext
*ctx
, GLenum mode
)
548 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
550 RADEON_STATECHANGE( rmesa
, set
);
551 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_FFACE_CULL_DIR_MASK
;
553 RADEON_STATECHANGE( rmesa
, tcl
);
554 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_CULL_FRONT_IS_CCW
;
558 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_FFACE_CULL_CW
;
561 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_FFACE_CULL_CCW
;
562 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_CULL_FRONT_IS_CCW
;
568 /* =============================================================
571 static void radeonLineWidth( GLcontext
*ctx
, GLfloat widthf
)
573 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
575 RADEON_STATECHANGE( rmesa
, lin
);
576 RADEON_STATECHANGE( rmesa
, set
);
578 /* Line width is stored in U6.4 format.
580 rmesa
->hw
.lin
.cmd
[LIN_SE_LINE_WIDTH
] = (GLuint
)(widthf
* 16.0);
581 if ( widthf
> 1.0 ) {
582 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_WIDELINE_ENABLE
;
584 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_WIDELINE_ENABLE
;
588 static void radeonLineStipple( GLcontext
*ctx
, GLint factor
, GLushort pattern
)
590 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
592 RADEON_STATECHANGE( rmesa
, lin
);
593 rmesa
->hw
.lin
.cmd
[LIN_RE_LINE_PATTERN
] =
594 ((((GLuint
)factor
& 0xff) << 16) | ((GLuint
)pattern
));
598 /* =============================================================
601 static void radeonColorMask( GLcontext
*ctx
,
602 GLboolean r
, GLboolean g
,
603 GLboolean b
, GLboolean a
)
605 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
606 GLuint mask
= radeonPackColor( rmesa
->radeonScreen
->cpp
,
607 ctx
->Color
.ColorMask
[RCOMP
],
608 ctx
->Color
.ColorMask
[GCOMP
],
609 ctx
->Color
.ColorMask
[BCOMP
],
610 ctx
->Color
.ColorMask
[ACOMP
] );
612 if ( rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] != mask
) {
613 RADEON_STATECHANGE( rmesa
, msk
);
614 rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] = mask
;
619 /* =============================================================
623 static void radeonPolygonOffset( GLcontext
*ctx
,
624 GLfloat factor
, GLfloat units
)
626 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
627 float_ui32_type constant
= { units
* rmesa
->state
.depth
.scale
};
628 float_ui32_type factoru
= { factor
};
630 RADEON_STATECHANGE( rmesa
, zbs
);
631 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_FACTOR
] = factoru
.ui32
;
632 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_CONSTANT
] = constant
.ui32
;
635 static void radeonPolygonStipple( GLcontext
*ctx
, const GLubyte
*mask
)
637 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
639 drm_radeon_stipple_t stipple
;
641 /* Must flip pattern upside down.
643 for ( i
= 0 ; i
< 32 ; i
++ ) {
644 rmesa
->state
.stipple
.mask
[31 - i
] = ((GLuint
*) mask
)[i
];
647 /* TODO: push this into cmd mechanism
649 RADEON_FIREVERTICES( rmesa
);
650 LOCK_HARDWARE( rmesa
);
652 /* FIXME: Use window x,y offsets into stipple RAM.
654 stipple
.mask
= rmesa
->state
.stipple
.mask
;
655 drmCommandWrite( rmesa
->dri
.fd
, DRM_RADEON_STIPPLE
,
656 &stipple
, sizeof(drm_radeon_stipple_t
) );
657 UNLOCK_HARDWARE( rmesa
);
660 static void radeonPolygonMode( GLcontext
*ctx
, GLenum face
, GLenum mode
)
662 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
663 GLboolean flag
= (ctx
->_TriangleCaps
& DD_TRI_UNFILLED
) != 0;
665 /* Can't generally do unfilled via tcl, but some good special
668 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_UNFILLED
, flag
);
669 if (rmesa
->TclFallback
) {
670 radeonChooseRenderState( ctx
);
671 radeonChooseVertexState( ctx
);
676 /* =============================================================
677 * Rendering attributes
679 * We really don't want to recalculate all this every time we bind a
680 * texture. These things shouldn't change all that often, so it makes
681 * sense to break them out of the core texture state update routines.
684 /* Examine lighting and texture state to determine if separate specular
687 static void radeonUpdateSpecular( GLcontext
*ctx
)
689 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
690 uint32_t p
= rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
];
693 RADEON_STATECHANGE( rmesa
, tcl
);
695 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &= ~RADEON_TCL_COMPUTE_SPECULAR
;
696 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &= ~RADEON_TCL_COMPUTE_DIFFUSE
;
697 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &= ~RADEON_TCL_VTX_PK_SPEC
;
698 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &= ~RADEON_TCL_VTX_PK_DIFFUSE
;
699 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_LIGHTING_ENABLE
;
701 p
&= ~RADEON_SPECULAR_ENABLE
;
703 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_DIFFUSE_SPECULAR_COMBINE
;
706 if (ctx
->Light
.Enabled
&&
707 ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
) {
708 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_SPECULAR
;
709 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_DIFFUSE
;
710 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
711 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
712 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
713 p
|= RADEON_SPECULAR_ENABLE
;
714 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &=
715 ~RADEON_DIFFUSE_SPECULAR_COMBINE
;
717 else if (ctx
->Light
.Enabled
) {
718 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_DIFFUSE
;
719 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
720 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
721 } else if (ctx
->Fog
.ColorSumEnabled
) {
722 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
723 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
724 p
|= RADEON_SPECULAR_ENABLE
;
726 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
729 if (ctx
->Fog
.Enabled
) {
730 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
731 if (ctx
->Fog
.FogCoordinateSource
== GL_FRAGMENT_DEPTH
) {
732 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_SPECULAR
;
733 /* Bizzare: have to leave lighting enabled to get fog. */
734 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
737 /* cannot do tcl fog factor calculation with fog coord source
738 * (send precomputed factors). Cannot use precomputed fog
739 * factors together with tcl spec light (need tcl fallback) */
740 flag
= (rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &
741 RADEON_TCL_COMPUTE_SPECULAR
) != 0;
745 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_FOGCOORDSPEC
, flag
);
747 if (NEED_SECONDARY_COLOR(ctx
)) {
748 assert( (p
& RADEON_SPECULAR_ENABLE
) != 0 );
750 assert( (p
& RADEON_SPECULAR_ENABLE
) == 0 );
753 if ( rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] != p
) {
754 RADEON_STATECHANGE( rmesa
, ctx
);
755 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] = p
;
758 /* Update vertex/render formats
760 if (rmesa
->TclFallback
) {
761 radeonChooseRenderState( ctx
);
762 radeonChooseVertexState( ctx
);
767 /* =============================================================
772 /* Update on colormaterial, material emmissive/ambient,
773 * lightmodel.globalambient
775 static void update_global_ambient( GLcontext
*ctx
)
777 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
778 float *fcmd
= (float *)RADEON_DB_STATE( glt
);
780 /* Need to do more if both emmissive & ambient are PREMULT:
781 * Hope this is not needed for MULT
783 if ((rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &
784 ((3 << RADEON_EMISSIVE_SOURCE_SHIFT
) |
785 (3 << RADEON_AMBIENT_SOURCE_SHIFT
))) == 0)
787 COPY_3V( &fcmd
[GLT_RED
],
788 ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_EMISSION
]);
789 ACC_SCALE_3V( &fcmd
[GLT_RED
],
790 ctx
->Light
.Model
.Ambient
,
791 ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_AMBIENT
]);
795 COPY_3V( &fcmd
[GLT_RED
], ctx
->Light
.Model
.Ambient
);
798 RADEON_DB_STATECHANGE(rmesa
, &rmesa
->hw
.glt
);
801 /* Update on change to
805 static void update_light_colors( GLcontext
*ctx
, GLuint p
)
807 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
809 /* fprintf(stderr, "%s\n", __FUNCTION__); */
812 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
813 float *fcmd
= (float *)RADEON_DB_STATE( lit
[p
] );
815 COPY_4V( &fcmd
[LIT_AMBIENT_RED
], l
->Ambient
);
816 COPY_4V( &fcmd
[LIT_DIFFUSE_RED
], l
->Diffuse
);
817 COPY_4V( &fcmd
[LIT_SPECULAR_RED
], l
->Specular
);
819 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
823 /* Also fallback for asym colormaterial mode in twoside lighting...
825 static void check_twoside_fallback( GLcontext
*ctx
)
827 GLboolean fallback
= GL_FALSE
;
830 if (ctx
->Light
.Enabled
&& ctx
->Light
.Model
.TwoSide
) {
831 if (ctx
->Light
.ColorMaterialEnabled
&&
832 (ctx
->Light
.ColorMaterialBitmask
& BACK_MATERIAL_BITS
) !=
833 ((ctx
->Light
.ColorMaterialBitmask
& FRONT_MATERIAL_BITS
)<<1))
836 for (i
= MAT_ATTRIB_FRONT_AMBIENT
; i
< MAT_ATTRIB_FRONT_INDEXES
; i
+=2)
837 if (memcmp( ctx
->Light
.Material
.Attrib
[i
],
838 ctx
->Light
.Material
.Attrib
[i
+1],
839 sizeof(GLfloat
)*4) != 0) {
846 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_LIGHT_TWOSIDE
, fallback
);
850 static void radeonColorMaterial( GLcontext
*ctx
, GLenum face
, GLenum mode
)
852 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
853 GLuint light_model_ctl1
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
];
855 light_model_ctl1
&= ~((3 << RADEON_EMISSIVE_SOURCE_SHIFT
) |
856 (3 << RADEON_AMBIENT_SOURCE_SHIFT
) |
857 (3 << RADEON_DIFFUSE_SOURCE_SHIFT
) |
858 (3 << RADEON_SPECULAR_SOURCE_SHIFT
));
860 if (ctx
->Light
.ColorMaterialEnabled
) {
861 GLuint mask
= ctx
->Light
.ColorMaterialBitmask
;
863 if (mask
& MAT_BIT_FRONT_EMISSION
) {
864 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
865 RADEON_EMISSIVE_SOURCE_SHIFT
);
868 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
869 RADEON_EMISSIVE_SOURCE_SHIFT
);
872 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
873 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
874 RADEON_AMBIENT_SOURCE_SHIFT
);
877 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
878 RADEON_AMBIENT_SOURCE_SHIFT
);
881 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
882 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
883 RADEON_DIFFUSE_SOURCE_SHIFT
);
886 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
887 RADEON_DIFFUSE_SOURCE_SHIFT
);
890 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
891 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
892 RADEON_SPECULAR_SOURCE_SHIFT
);
895 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
896 RADEON_SPECULAR_SOURCE_SHIFT
);
902 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_EMISSIVE_SOURCE_SHIFT
) |
903 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_AMBIENT_SOURCE_SHIFT
) |
904 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_DIFFUSE_SOURCE_SHIFT
) |
905 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_SPECULAR_SOURCE_SHIFT
);
908 if (light_model_ctl1
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]) {
909 RADEON_STATECHANGE( rmesa
, tcl
);
910 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] = light_model_ctl1
;
914 void radeonUpdateMaterial( GLcontext
*ctx
)
916 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
917 GLfloat (*mat
)[4] = ctx
->Light
.Material
.Attrib
;
918 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( mtl
);
921 if (ctx
->Light
.ColorMaterialEnabled
)
922 mask
&= ~ctx
->Light
.ColorMaterialBitmask
;
924 if (RADEON_DEBUG
& DEBUG_STATE
)
925 fprintf(stderr
, "%s\n", __FUNCTION__
);
928 if (mask
& MAT_BIT_FRONT_EMISSION
) {
929 fcmd
[MTL_EMMISSIVE_RED
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][0];
930 fcmd
[MTL_EMMISSIVE_GREEN
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][1];
931 fcmd
[MTL_EMMISSIVE_BLUE
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][2];
932 fcmd
[MTL_EMMISSIVE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][3];
934 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
935 fcmd
[MTL_AMBIENT_RED
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][0];
936 fcmd
[MTL_AMBIENT_GREEN
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][1];
937 fcmd
[MTL_AMBIENT_BLUE
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][2];
938 fcmd
[MTL_AMBIENT_ALPHA
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][3];
940 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
941 fcmd
[MTL_DIFFUSE_RED
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][0];
942 fcmd
[MTL_DIFFUSE_GREEN
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][1];
943 fcmd
[MTL_DIFFUSE_BLUE
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][2];
944 fcmd
[MTL_DIFFUSE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][3];
946 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
947 fcmd
[MTL_SPECULAR_RED
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][0];
948 fcmd
[MTL_SPECULAR_GREEN
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][1];
949 fcmd
[MTL_SPECULAR_BLUE
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][2];
950 fcmd
[MTL_SPECULAR_ALPHA
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][3];
952 if (mask
& MAT_BIT_FRONT_SHININESS
) {
953 fcmd
[MTL_SHININESS
] = mat
[MAT_ATTRIB_FRONT_SHININESS
][0];
956 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mtl
);
958 check_twoside_fallback( ctx
);
959 /* update_global_ambient( ctx );*/
964 * _MESA_NEW_NEED_EYE_COORDS
966 * Uses derived state from mesa:
975 * which are calculated in light.c and are correct for the current
976 * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW
977 * and _MESA_NEW_NEED_EYE_COORDS.
979 static void update_light( GLcontext
*ctx
)
981 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
983 /* Have to check these, or have an automatic shortcircuit mechanism
984 * to remove noop statechanges. (Or just do a better job on the
988 GLuint tmp
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
];
990 if (ctx
->_NeedEyeCoords
)
991 tmp
&= ~RADEON_LIGHT_IN_MODELSPACE
;
993 tmp
|= RADEON_LIGHT_IN_MODELSPACE
;
996 /* Leave this test disabled: (unexplained q3 lockup) (even with
999 if (tmp
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
])
1001 RADEON_STATECHANGE( rmesa
, tcl
);
1002 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] = tmp
;
1007 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( eye
);
1008 fcmd
[EYE_X
] = ctx
->_EyeZDir
[0];
1009 fcmd
[EYE_Y
] = ctx
->_EyeZDir
[1];
1010 fcmd
[EYE_Z
] = - ctx
->_EyeZDir
[2];
1011 fcmd
[EYE_RESCALE_FACTOR
] = ctx
->_ModelViewInvScale
;
1012 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.eye
);
1017 if (ctx
->Light
.Enabled
) {
1019 for (p
= 0 ; p
< MAX_LIGHTS
; p
++) {
1020 if (ctx
->Light
.Light
[p
].Enabled
) {
1021 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
1022 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( lit
[p
] );
1024 if (l
->EyePosition
[3] == 0.0) {
1025 COPY_3FV( &fcmd
[LIT_POSITION_X
], l
->_VP_inf_norm
);
1026 COPY_3FV( &fcmd
[LIT_DIRECTION_X
], l
->_h_inf_norm
);
1027 fcmd
[LIT_POSITION_W
] = 0;
1028 fcmd
[LIT_DIRECTION_W
] = 0;
1030 COPY_4V( &fcmd
[LIT_POSITION_X
], l
->_Position
);
1031 fcmd
[LIT_DIRECTION_X
] = -l
->_NormDirection
[0];
1032 fcmd
[LIT_DIRECTION_Y
] = -l
->_NormDirection
[1];
1033 fcmd
[LIT_DIRECTION_Z
] = -l
->_NormDirection
[2];
1034 fcmd
[LIT_DIRECTION_W
] = 0;
1037 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
1043 static void radeonLightfv( GLcontext
*ctx
, GLenum light
,
1044 GLenum pname
, const GLfloat
*params
)
1046 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1047 GLint p
= light
- GL_LIGHT0
;
1048 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
1049 GLfloat
*fcmd
= (GLfloat
*)rmesa
->hw
.lit
[p
].cmd
;
1056 update_light_colors( ctx
, p
);
1059 case GL_SPOT_DIRECTION
:
1060 /* picked up in update_light */
1064 /* positions picked up in update_light, but can do flag here */
1066 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1068 /* FIXME: Set RANGE_ATTEN only when needed */
1070 flag
= RADEON_LIGHT_1_IS_LOCAL
;
1072 flag
= RADEON_LIGHT_0_IS_LOCAL
;
1074 RADEON_STATECHANGE(rmesa
, tcl
);
1075 if (l
->EyePosition
[3] != 0.0F
)
1076 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
1078 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
1082 case GL_SPOT_EXPONENT
:
1083 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1084 fcmd
[LIT_SPOT_EXPONENT
] = params
[0];
1087 case GL_SPOT_CUTOFF
: {
1088 GLuint flag
= (p
&1) ? RADEON_LIGHT_1_IS_SPOT
: RADEON_LIGHT_0_IS_SPOT
;
1089 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1091 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1092 fcmd
[LIT_SPOT_CUTOFF
] = l
->_CosCutoff
;
1094 RADEON_STATECHANGE(rmesa
, tcl
);
1095 if (l
->SpotCutoff
!= 180.0F
)
1096 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
1098 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
1103 case GL_CONSTANT_ATTENUATION
:
1104 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1105 fcmd
[LIT_ATTEN_CONST
] = params
[0];
1106 if ( params
[0] == 0.0 )
1107 fcmd
[LIT_ATTEN_CONST_INV
] = FLT_MAX
;
1109 fcmd
[LIT_ATTEN_CONST_INV
] = 1.0 / params
[0];
1111 case GL_LINEAR_ATTENUATION
:
1112 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1113 fcmd
[LIT_ATTEN_LINEAR
] = params
[0];
1115 case GL_QUADRATIC_ATTENUATION
:
1116 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1117 fcmd
[LIT_ATTEN_QUADRATIC
] = params
[0];
1123 /* Set RANGE_ATTEN only when needed */
1126 case GL_CONSTANT_ATTENUATION
:
1127 case GL_LINEAR_ATTENUATION
:
1128 case GL_QUADRATIC_ATTENUATION
:
1130 GLuint
*icmd
= (GLuint
*)RADEON_DB_STATE( tcl
);
1131 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1132 GLuint atten_flag
= ( p
&1 ) ? RADEON_LIGHT_1_ENABLE_RANGE_ATTEN
1133 : RADEON_LIGHT_0_ENABLE_RANGE_ATTEN
;
1134 GLuint atten_const_flag
= ( p
&1 ) ? RADEON_LIGHT_1_CONSTANT_RANGE_ATTEN
1135 : RADEON_LIGHT_0_CONSTANT_RANGE_ATTEN
;
1137 if ( l
->EyePosition
[3] == 0.0F
||
1138 ( ( fcmd
[LIT_ATTEN_CONST
] == 0.0 || fcmd
[LIT_ATTEN_CONST
] == 1.0 ) &&
1139 fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) ) {
1140 /* Disable attenuation */
1141 icmd
[idx
] &= ~atten_flag
;
1143 if ( fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) {
1144 /* Enable only constant portion of attenuation calculation */
1145 icmd
[idx
] |= ( atten_flag
| atten_const_flag
);
1147 /* Enable full attenuation calculation */
1148 icmd
[idx
] &= ~atten_const_flag
;
1149 icmd
[idx
] |= atten_flag
;
1153 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.tcl
);
1164 static void radeonLightModelfv( GLcontext
*ctx
, GLenum pname
,
1165 const GLfloat
*param
)
1167 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1170 case GL_LIGHT_MODEL_AMBIENT
:
1171 update_global_ambient( ctx
);
1174 case GL_LIGHT_MODEL_LOCAL_VIEWER
:
1175 RADEON_STATECHANGE( rmesa
, tcl
);
1176 if (ctx
->Light
.Model
.LocalViewer
)
1177 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LOCAL_VIEWER
;
1179 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_LOCAL_VIEWER
;
1182 case GL_LIGHT_MODEL_TWO_SIDE
:
1183 RADEON_STATECHANGE( rmesa
, tcl
);
1184 if (ctx
->Light
.Model
.TwoSide
)
1185 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_LIGHT_TWOSIDE
;
1187 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_LIGHT_TWOSIDE
;
1189 check_twoside_fallback( ctx
);
1191 if (rmesa
->TclFallback
) {
1192 radeonChooseRenderState( ctx
);
1193 radeonChooseVertexState( ctx
);
1197 case GL_LIGHT_MODEL_COLOR_CONTROL
:
1198 radeonUpdateSpecular(ctx
);
1206 static void radeonShadeModel( GLcontext
*ctx
, GLenum mode
)
1208 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1209 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
1211 s
&= ~(RADEON_DIFFUSE_SHADE_MASK
|
1212 RADEON_ALPHA_SHADE_MASK
|
1213 RADEON_SPECULAR_SHADE_MASK
|
1214 RADEON_FOG_SHADE_MASK
);
1218 s
|= (RADEON_DIFFUSE_SHADE_FLAT
|
1219 RADEON_ALPHA_SHADE_FLAT
|
1220 RADEON_SPECULAR_SHADE_FLAT
|
1221 RADEON_FOG_SHADE_FLAT
);
1224 s
|= (RADEON_DIFFUSE_SHADE_GOURAUD
|
1225 RADEON_ALPHA_SHADE_GOURAUD
|
1226 RADEON_SPECULAR_SHADE_GOURAUD
|
1227 RADEON_FOG_SHADE_GOURAUD
);
1233 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
1234 RADEON_STATECHANGE( rmesa
, set
);
1235 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
1240 /* =============================================================
1244 static void radeonClipPlane( GLcontext
*ctx
, GLenum plane
, const GLfloat
*eq
)
1246 GLint p
= (GLint
) plane
- (GLint
) GL_CLIP_PLANE0
;
1247 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1248 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1250 RADEON_STATECHANGE( rmesa
, ucp
[p
] );
1251 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1252 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1253 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1254 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1257 static void radeonUpdateClipPlanes( GLcontext
*ctx
)
1259 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1262 for (p
= 0; p
< ctx
->Const
.MaxClipPlanes
; p
++) {
1263 if (ctx
->Transform
.ClipPlanesEnabled
& (1 << p
)) {
1264 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1266 RADEON_STATECHANGE( rmesa
, ucp
[p
] );
1267 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1268 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1269 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1270 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1276 /* =============================================================
1281 radeonStencilFuncSeparate( GLcontext
*ctx
, GLenum face
, GLenum func
,
1282 GLint ref
, GLuint mask
)
1284 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1285 GLuint refmask
= (((ctx
->Stencil
.Ref
[0] & 0xff) << RADEON_STENCIL_REF_SHIFT
) |
1286 ((ctx
->Stencil
.ValueMask
[0] & 0xff) << RADEON_STENCIL_MASK_SHIFT
));
1288 RADEON_STATECHANGE( rmesa
, ctx
);
1289 RADEON_STATECHANGE( rmesa
, msk
);
1291 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_STENCIL_TEST_MASK
;
1292 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~(RADEON_STENCIL_REF_MASK
|
1293 RADEON_STENCIL_VALUE_MASK
);
1295 switch ( ctx
->Stencil
.Function
[0] ) {
1297 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_NEVER
;
1300 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_LESS
;
1303 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_EQUAL
;
1306 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_LEQUAL
;
1309 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_GREATER
;
1312 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_NEQUAL
;
1315 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_GEQUAL
;
1318 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_ALWAYS
;
1322 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |= refmask
;
1326 radeonStencilMaskSeparate( GLcontext
*ctx
, GLenum face
, GLuint mask
)
1328 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1330 RADEON_STATECHANGE( rmesa
, msk
);
1331 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~RADEON_STENCIL_WRITE_MASK
;
1332 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |=
1333 ((ctx
->Stencil
.WriteMask
[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT
);
1336 static void radeonStencilOpSeparate( GLcontext
*ctx
, GLenum face
, GLenum fail
,
1337 GLenum zfail
, GLenum zpass
)
1339 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1341 /* radeon 7200 have stencil bug, DEC and INC_WRAP will actually both do DEC_WRAP,
1342 and DEC_WRAP (and INVERT) will do INVERT. No way to get correct INC_WRAP and DEC,
1343 but DEC_WRAP can be fixed by using DEC and INC_WRAP at least use INC. */
1345 GLuint tempRADEON_STENCIL_FAIL_DEC_WRAP
;
1346 GLuint tempRADEON_STENCIL_FAIL_INC_WRAP
;
1347 GLuint tempRADEON_STENCIL_ZFAIL_DEC_WRAP
;
1348 GLuint tempRADEON_STENCIL_ZFAIL_INC_WRAP
;
1349 GLuint tempRADEON_STENCIL_ZPASS_DEC_WRAP
;
1350 GLuint tempRADEON_STENCIL_ZPASS_INC_WRAP
;
1352 if (rmesa
->radeonScreen
->chip_flags
& RADEON_CHIPSET_BROKEN_STENCIL
) {
1353 tempRADEON_STENCIL_FAIL_DEC_WRAP
= RADEON_STENCIL_FAIL_DEC
;
1354 tempRADEON_STENCIL_FAIL_INC_WRAP
= RADEON_STENCIL_FAIL_INC
;
1355 tempRADEON_STENCIL_ZFAIL_DEC_WRAP
= RADEON_STENCIL_ZFAIL_DEC
;
1356 tempRADEON_STENCIL_ZFAIL_INC_WRAP
= RADEON_STENCIL_ZFAIL_INC
;
1357 tempRADEON_STENCIL_ZPASS_DEC_WRAP
= RADEON_STENCIL_ZPASS_DEC
;
1358 tempRADEON_STENCIL_ZPASS_INC_WRAP
= RADEON_STENCIL_ZPASS_INC
;
1361 tempRADEON_STENCIL_FAIL_DEC_WRAP
= RADEON_STENCIL_FAIL_DEC_WRAP
;
1362 tempRADEON_STENCIL_FAIL_INC_WRAP
= RADEON_STENCIL_FAIL_INC_WRAP
;
1363 tempRADEON_STENCIL_ZFAIL_DEC_WRAP
= RADEON_STENCIL_ZFAIL_DEC_WRAP
;
1364 tempRADEON_STENCIL_ZFAIL_INC_WRAP
= RADEON_STENCIL_ZFAIL_INC_WRAP
;
1365 tempRADEON_STENCIL_ZPASS_DEC_WRAP
= RADEON_STENCIL_ZPASS_DEC_WRAP
;
1366 tempRADEON_STENCIL_ZPASS_INC_WRAP
= RADEON_STENCIL_ZPASS_INC_WRAP
;
1369 RADEON_STATECHANGE( rmesa
, ctx
);
1370 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~(RADEON_STENCIL_FAIL_MASK
|
1371 RADEON_STENCIL_ZFAIL_MASK
|
1372 RADEON_STENCIL_ZPASS_MASK
);
1374 switch ( ctx
->Stencil
.FailFunc
[0] ) {
1376 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_KEEP
;
1379 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_ZERO
;
1382 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_REPLACE
;
1385 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_INC
;
1388 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_DEC
;
1391 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_FAIL_INC_WRAP
;
1394 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_FAIL_DEC_WRAP
;
1397 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_INVERT
;
1401 switch ( ctx
->Stencil
.ZFailFunc
[0] ) {
1403 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_KEEP
;
1406 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_ZERO
;
1409 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_REPLACE
;
1412 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_INC
;
1415 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_DEC
;
1418 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZFAIL_INC_WRAP
;
1421 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZFAIL_DEC_WRAP
;
1424 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_INVERT
;
1428 switch ( ctx
->Stencil
.ZPassFunc
[0] ) {
1430 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_KEEP
;
1433 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_ZERO
;
1436 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_REPLACE
;
1439 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_INC
;
1442 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_DEC
;
1445 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZPASS_INC_WRAP
;
1448 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZPASS_DEC_WRAP
;
1451 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_INVERT
;
1456 static void radeonClearStencil( GLcontext
*ctx
, GLint s
)
1458 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1460 rmesa
->state
.stencil
.clear
=
1461 ((GLuint
) (ctx
->Stencil
.Clear
& 0xff) |
1462 (0xff << RADEON_STENCIL_MASK_SHIFT
) |
1463 ((ctx
->Stencil
.WriteMask
[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT
));
1467 /* =============================================================
1468 * Window position and viewport transformation
1472 * To correctly position primitives:
1474 #define SUBPIXEL_X 0.125
1475 #define SUBPIXEL_Y 0.125
1479 * Called when window size or position changes or viewport or depth range
1480 * state is changed. We update the hardware viewport state here.
1482 void radeonUpdateWindow( GLcontext
*ctx
)
1484 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1485 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
1486 GLfloat xoffset
= (GLfloat
)dPriv
->x
;
1487 GLfloat yoffset
= (GLfloat
)dPriv
->y
+ dPriv
->h
;
1488 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1490 float_ui32_type sx
= { v
[MAT_SX
] };
1491 float_ui32_type tx
= { v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
};
1492 float_ui32_type sy
= { - v
[MAT_SY
] };
1493 float_ui32_type ty
= { (- v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
};
1494 float_ui32_type sz
= { v
[MAT_SZ
] * rmesa
->state
.depth
.scale
};
1495 float_ui32_type tz
= { v
[MAT_TZ
] * rmesa
->state
.depth
.scale
};
1497 RADEON_FIREVERTICES( rmesa
);
1498 RADEON_STATECHANGE( rmesa
, vpt
);
1500 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XSCALE
] = sx
.ui32
;
1501 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = tx
.ui32
;
1502 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YSCALE
] = sy
.ui32
;
1503 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = ty
.ui32
;
1504 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZSCALE
] = sz
.ui32
;
1505 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZOFFSET
] = tz
.ui32
;
1509 static void radeonViewport( GLcontext
*ctx
, GLint x
, GLint y
,
1510 GLsizei width
, GLsizei height
)
1512 /* Don't pipeline viewport changes, conflict with window offset
1513 * setting below. Could apply deltas to rescue pipelined viewport
1514 * values, or keep the originals hanging around.
1516 radeonUpdateWindow( ctx
);
1519 static void radeonDepthRange( GLcontext
*ctx
, GLclampd nearval
,
1522 radeonUpdateWindow( ctx
);
1525 void radeonUpdateViewportOffset( GLcontext
*ctx
)
1527 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1528 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
1529 GLfloat xoffset
= (GLfloat
)dPriv
->x
;
1530 GLfloat yoffset
= (GLfloat
)dPriv
->y
+ dPriv
->h
;
1531 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1536 tx
.f
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1537 ty
.f
= (- v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1539 if ( rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] != tx
.ui32
||
1540 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] != ty
.ui32
)
1542 /* Note: this should also modify whatever data the context reset
1545 RADEON_STATECHANGE( rmesa
, vpt
);
1546 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = tx
.ui32
;
1547 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = ty
.ui32
;
1549 /* update polygon stipple x/y screen offset */
1552 GLuint m
= rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
];
1554 m
&= ~(RADEON_STIPPLE_X_OFFSET_MASK
|
1555 RADEON_STIPPLE_Y_OFFSET_MASK
);
1557 /* add magic offsets, then invert */
1558 stx
= 31 - ((rmesa
->dri
.drawable
->x
- 1) & RADEON_STIPPLE_COORD_MASK
);
1559 sty
= 31 - ((rmesa
->dri
.drawable
->y
+ rmesa
->dri
.drawable
->h
- 1)
1560 & RADEON_STIPPLE_COORD_MASK
);
1562 m
|= ((stx
<< RADEON_STIPPLE_X_OFFSET_SHIFT
) |
1563 (sty
<< RADEON_STIPPLE_Y_OFFSET_SHIFT
));
1565 if ( rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
] != m
) {
1566 RADEON_STATECHANGE( rmesa
, msc
);
1567 rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
] = m
;
1572 radeonUpdateScissor( ctx
);
1577 /* =============================================================
1581 static void radeonClearColor( GLcontext
*ctx
, const GLfloat color
[4] )
1583 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1585 CLAMPED_FLOAT_TO_UBYTE(c
[0], color
[0]);
1586 CLAMPED_FLOAT_TO_UBYTE(c
[1], color
[1]);
1587 CLAMPED_FLOAT_TO_UBYTE(c
[2], color
[2]);
1588 CLAMPED_FLOAT_TO_UBYTE(c
[3], color
[3]);
1589 rmesa
->state
.color
.clear
= radeonPackColor( rmesa
->radeonScreen
->cpp
,
1590 c
[0], c
[1], c
[2], c
[3] );
1594 static void radeonRenderMode( GLcontext
*ctx
, GLenum mode
)
1596 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1597 FALLBACK( rmesa
, RADEON_FALLBACK_RENDER_MODE
, (mode
!= GL_RENDER
) );
1601 static GLuint radeon_rop_tab
[] = {
1604 RADEON_ROP_AND_REVERSE
,
1606 RADEON_ROP_AND_INVERTED
,
1613 RADEON_ROP_OR_REVERSE
,
1614 RADEON_ROP_COPY_INVERTED
,
1615 RADEON_ROP_OR_INVERTED
,
1620 static void radeonLogicOpCode( GLcontext
*ctx
, GLenum opcode
)
1622 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1623 GLuint rop
= (GLuint
)opcode
- GL_CLEAR
;
1627 RADEON_STATECHANGE( rmesa
, msk
);
1628 rmesa
->hw
.msk
.cmd
[MSK_RB3D_ROPCNTL
] = radeon_rop_tab
[rop
];
1633 * Set up the cliprects for either front or back-buffer drawing.
1635 void radeonSetCliprects( radeonContextPtr rmesa
)
1637 __DRIdrawablePrivate
*const drawable
= rmesa
->dri
.drawable
;
1638 __DRIdrawablePrivate
*const readable
= rmesa
->dri
.readable
;
1639 GLframebuffer
*const draw_fb
= (GLframebuffer
*) drawable
->driverPrivate
;
1640 GLframebuffer
*const read_fb
= (GLframebuffer
*) readable
->driverPrivate
;
1642 if (draw_fb
->_ColorDrawBufferIndexes
[0] == BUFFER_BACK_LEFT
) {
1643 /* Can't ignore 2d windows if we are page flipping.
1645 if ( drawable
->numBackClipRects
== 0 || rmesa
->doPageFlip
) {
1646 rmesa
->numClipRects
= drawable
->numClipRects
;
1647 rmesa
->pClipRects
= drawable
->pClipRects
;
1650 rmesa
->numClipRects
= drawable
->numBackClipRects
;
1651 rmesa
->pClipRects
= drawable
->pBackClipRects
;
1655 /* front buffer (or none, or multiple buffers */
1656 rmesa
->numClipRects
= drawable
->numClipRects
;
1657 rmesa
->pClipRects
= drawable
->pClipRects
;
1660 if ((draw_fb
->Width
!= drawable
->w
) || (draw_fb
->Height
!= drawable
->h
)) {
1661 _mesa_resize_framebuffer(rmesa
->glCtx
, draw_fb
,
1662 drawable
->w
, drawable
->h
);
1663 draw_fb
->Initialized
= GL_TRUE
;
1666 if (drawable
!= readable
) {
1667 if ((read_fb
->Width
!= readable
->w
) || (read_fb
->Height
!= readable
->h
)) {
1668 _mesa_resize_framebuffer(rmesa
->glCtx
, read_fb
,
1669 readable
->w
, readable
->h
);
1670 read_fb
->Initialized
= GL_TRUE
;
1674 if (rmesa
->state
.scissor
.enabled
)
1675 radeonRecalcScissorRects( rmesa
);
1677 rmesa
->lastStamp
= drawable
->lastStamp
;
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 */
1694 if (ctx
->DrawBuffer
->_NumColorDrawBuffers
!= 1) {
1695 /* 0 (GL_NONE) buffers or multiple color drawing buffers */
1696 FALLBACK( rmesa
, RADEON_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
1700 switch ( ctx
->DrawBuffer
->_ColorDrawBufferIndexes
[0] ) {
1701 case BUFFER_FRONT_LEFT
:
1702 case BUFFER_BACK_LEFT
:
1703 FALLBACK( rmesa
, RADEON_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
1706 FALLBACK( rmesa
, RADEON_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
1710 radeonSetCliprects( rmesa
);
1712 /* We'll set the drawing engine's offset/pitch parameters later
1713 * when we update other state.
1717 static void radeonReadBuffer( GLcontext
*ctx
, GLenum mode
)
1719 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
1723 /* =============================================================
1724 * State enable/disable
1727 static void radeonEnable( GLcontext
*ctx
, GLenum cap
, GLboolean state
)
1729 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1732 if ( RADEON_DEBUG
& DEBUG_STATE
)
1733 fprintf( stderr
, "%s( %s = %s )\n", __FUNCTION__
,
1734 _mesa_lookup_enum_by_nr( cap
),
1735 state
? "GL_TRUE" : "GL_FALSE" );
1738 /* Fast track this one...
1746 RADEON_STATECHANGE( rmesa
, ctx
);
1748 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ALPHA_TEST_ENABLE
;
1750 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ALPHA_TEST_ENABLE
;
1755 RADEON_STATECHANGE( rmesa
, ctx
);
1757 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ALPHA_BLEND_ENABLE
;
1759 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ALPHA_BLEND_ENABLE
;
1761 if ( (ctx
->Color
.ColorLogicOpEnabled
|| (ctx
->Color
.BlendEnabled
1762 && ctx
->Color
.BlendEquationRGB
== GL_LOGIC_OP
)) ) {
1763 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
1765 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
1768 /* Catch a possible fallback:
1771 ctx
->Driver
.BlendEquationSeparate( ctx
,
1772 ctx
->Color
.BlendEquationRGB
,
1773 ctx
->Color
.BlendEquationA
);
1774 ctx
->Driver
.BlendFuncSeparate( ctx
, ctx
->Color
.BlendSrcRGB
,
1775 ctx
->Color
.BlendDstRGB
,
1776 ctx
->Color
.BlendSrcA
,
1777 ctx
->Color
.BlendDstA
);
1780 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_FUNC
, GL_FALSE
);
1781 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_EQ
, GL_FALSE
);
1785 case GL_CLIP_PLANE0
:
1786 case GL_CLIP_PLANE1
:
1787 case GL_CLIP_PLANE2
:
1788 case GL_CLIP_PLANE3
:
1789 case GL_CLIP_PLANE4
:
1790 case GL_CLIP_PLANE5
:
1791 p
= cap
-GL_CLIP_PLANE0
;
1792 RADEON_STATECHANGE( rmesa
, tcl
);
1794 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= (RADEON_UCP_ENABLE_0
<<p
);
1795 radeonClipPlane( ctx
, cap
, NULL
);
1798 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~(RADEON_UCP_ENABLE_0
<<p
);
1802 case GL_COLOR_MATERIAL
:
1803 radeonColorMaterial( ctx
, 0, 0 );
1804 radeonUpdateMaterial( ctx
);
1808 radeonCullFace( ctx
, 0 );
1812 RADEON_STATECHANGE(rmesa
, ctx
);
1814 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_Z_ENABLE
;
1816 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_Z_ENABLE
;
1821 RADEON_STATECHANGE(rmesa
, ctx
);
1823 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_DITHER_ENABLE
;
1824 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~rmesa
->state
.color
.roundEnable
;
1826 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_DITHER_ENABLE
;
1827 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= rmesa
->state
.color
.roundEnable
;
1832 RADEON_STATECHANGE(rmesa
, ctx
);
1834 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_FOG_ENABLE
;
1835 radeonFogfv( ctx
, GL_FOG_MODE
, NULL
);
1837 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_FOG_ENABLE
;
1838 RADEON_STATECHANGE(rmesa
, tcl
);
1839 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_TCL_FOG_MASK
;
1841 radeonUpdateSpecular( ctx
); /* for PK_SPEC */
1842 _mesa_allow_light_in_model( ctx
, !state
);
1853 RADEON_STATECHANGE(rmesa
, tcl
);
1854 p
= cap
- GL_LIGHT0
;
1856 flag
= (RADEON_LIGHT_1_ENABLE
|
1857 RADEON_LIGHT_1_ENABLE_AMBIENT
|
1858 RADEON_LIGHT_1_ENABLE_SPECULAR
);
1860 flag
= (RADEON_LIGHT_0_ENABLE
|
1861 RADEON_LIGHT_0_ENABLE_AMBIENT
|
1862 RADEON_LIGHT_0_ENABLE_SPECULAR
);
1865 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] |= flag
;
1867 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] &= ~flag
;
1871 update_light_colors( ctx
, p
);
1875 RADEON_STATECHANGE(rmesa
, tcl
);
1876 radeonUpdateSpecular(ctx
);
1877 check_twoside_fallback( ctx
);
1880 case GL_LINE_SMOOTH
:
1881 RADEON_STATECHANGE( rmesa
, ctx
);
1883 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ANTI_ALIAS_LINE
;
1885 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ANTI_ALIAS_LINE
;
1889 case GL_LINE_STIPPLE
:
1890 RADEON_STATECHANGE( rmesa
, ctx
);
1892 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_PATTERN_ENABLE
;
1894 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_PATTERN_ENABLE
;
1898 case GL_COLOR_LOGIC_OP
:
1899 RADEON_STATECHANGE( rmesa
, ctx
);
1900 if ( (ctx
->Color
.ColorLogicOpEnabled
|| (ctx
->Color
.BlendEnabled
1901 && ctx
->Color
.BlendEquationRGB
== GL_LOGIC_OP
)) ) {
1902 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
1904 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
1909 RADEON_STATECHANGE( rmesa
, tcl
);
1911 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_NORMALIZE_NORMALS
;
1913 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_NORMALIZE_NORMALS
;
1917 case GL_POLYGON_OFFSET_POINT
:
1918 RADEON_STATECHANGE( rmesa
, set
);
1920 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_POINT
;
1922 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_POINT
;
1926 case GL_POLYGON_OFFSET_LINE
:
1927 RADEON_STATECHANGE( rmesa
, set
);
1929 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_LINE
;
1931 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_LINE
;
1935 case GL_POLYGON_OFFSET_FILL
:
1936 RADEON_STATECHANGE( rmesa
, set
);
1938 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_TRI
;
1940 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_TRI
;
1944 case GL_POLYGON_SMOOTH
:
1945 RADEON_STATECHANGE( rmesa
, ctx
);
1947 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ANTI_ALIAS_POLY
;
1949 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ANTI_ALIAS_POLY
;
1953 case GL_POLYGON_STIPPLE
:
1954 RADEON_STATECHANGE(rmesa
, ctx
);
1956 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_STIPPLE_ENABLE
;
1958 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_STIPPLE_ENABLE
;
1962 case GL_RESCALE_NORMAL_EXT
: {
1963 GLboolean tmp
= ctx
->_NeedEyeCoords
? state
: !state
;
1964 RADEON_STATECHANGE( rmesa
, tcl
);
1966 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_RESCALE_NORMALS
;
1968 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_RESCALE_NORMALS
;
1973 case GL_SCISSOR_TEST
:
1974 RADEON_FIREVERTICES( rmesa
);
1975 rmesa
->state
.scissor
.enabled
= state
;
1976 radeonUpdateScissor( ctx
);
1979 case GL_STENCIL_TEST
:
1980 if ( rmesa
->state
.stencil
.hwBuffer
) {
1981 RADEON_STATECHANGE( rmesa
, ctx
);
1983 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_STENCIL_ENABLE
;
1985 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_STENCIL_ENABLE
;
1988 FALLBACK( rmesa
, RADEON_FALLBACK_STENCIL
, state
);
1992 case GL_TEXTURE_GEN_Q
:
1993 case GL_TEXTURE_GEN_R
:
1994 case GL_TEXTURE_GEN_S
:
1995 case GL_TEXTURE_GEN_T
:
1996 /* Picked up in radeonUpdateTextureState.
1998 rmesa
->recheck_texgen
[ctx
->Texture
.CurrentUnit
] = GL_TRUE
;
2001 case GL_COLOR_SUM_EXT
:
2002 radeonUpdateSpecular ( ctx
);
2011 static void radeonLightingSpaceChange( GLcontext
*ctx
)
2013 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2015 RADEON_STATECHANGE( rmesa
, tcl
);
2017 if (RADEON_DEBUG
& DEBUG_STATE
)
2018 fprintf(stderr
, "%s %d BEFORE %x\n", __FUNCTION__
, ctx
->_NeedEyeCoords
,
2019 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]);
2021 if (ctx
->_NeedEyeCoords
)
2022 tmp
= ctx
->Transform
.RescaleNormals
;
2024 tmp
= !ctx
->Transform
.RescaleNormals
;
2027 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_RESCALE_NORMALS
;
2029 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_RESCALE_NORMALS
;
2032 if (RADEON_DEBUG
& DEBUG_STATE
)
2033 fprintf(stderr
, "%s %d AFTER %x\n", __FUNCTION__
, ctx
->_NeedEyeCoords
,
2034 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]);
2037 /* =============================================================
2038 * Deferred state management - matrices, textures, other?
2042 void radeonUploadTexMatrix( radeonContextPtr rmesa
,
2043 int unit
, GLboolean swapcols
)
2045 /* Here's how this works: on r100, only 3 tex coords can be submitted, so the
2046 vector looks like this probably: (s t r|q 0) (not sure if the last coord
2047 is hardwired to 0, could be 1 too). Interestingly, it actually looks like
2048 texgen generates all 4 coords, at least tests with projtex indicated that.
2049 So: if we need the q coord in the end (solely determined by the texture
2050 target, i.e. 2d / 1d / texrect targets) we swap the third and 4th row.
2051 Additionally, if we don't have texgen but 4 tex coords submitted, we swap
2052 column 3 and 4 (for the 2d / 1d / texrect targets) since the the q coord
2053 will get submitted in the "wrong", i.e. 3rd, slot.
2054 If an app submits 3 coords for 2d targets, we assume it is saving on vertex
2055 size and using the texture matrix to swap the r and q coords around (ut2k3
2056 does exactly that), so we don't need the 3rd / 4th column swap - still need
2057 the 3rd / 4th row swap of course. This will potentially break for apps which
2058 use TexCoord3x just for fun. Additionally, it will never work if an app uses
2059 an "advanced" texture matrix and relies on all 4 texcoord inputs to generate
2060 the maximum needed 3. This seems impossible to do with hw tcl on r100, and
2061 incredibly hard to detect so we can't just fallback in such a case. Assume
2062 it never happens... - rs
2065 int idx
= TEXMAT_0
+ unit
;
2066 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] )) + MAT_ELT_0
;
2068 struct gl_texture_unit tUnit
= rmesa
->glCtx
->Texture
.Unit
[unit
];
2069 GLfloat
*src
= rmesa
->tmpmat
[unit
].m
;
2071 rmesa
->TexMatColSwap
&= ~(1 << unit
);
2072 if ((tUnit
._ReallyEnabled
& (TEXTURE_3D_BIT
| TEXTURE_CUBE_BIT
)) == 0) {
2074 rmesa
->TexMatColSwap
|= 1 << unit
;
2075 /* attention some elems are swapped 2 times! */
2088 /* those last 4 are probably never used */
2095 for (i
= 0; i
< 2; i
++) {
2099 *dest
++ = src
[i
+12];
2101 for (i
= 3; i
>= 2; i
--) {
2105 *dest
++ = src
[i
+12];
2110 for (i
= 0 ; i
< 4 ; i
++) {
2114 *dest
++ = src
[i
+12];
2118 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
2122 static void upload_matrix( radeonContextPtr rmesa
, GLfloat
*src
, int idx
)
2124 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
2128 for (i
= 0 ; i
< 4 ; i
++) {
2132 *dest
++ = src
[i
+12];
2135 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
2138 static void upload_matrix_t( radeonContextPtr rmesa
, GLfloat
*src
, int idx
)
2140 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
2141 memcpy(dest
, src
, 16*sizeof(float));
2142 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
2146 static void update_texturematrix( GLcontext
*ctx
)
2148 radeonContextPtr rmesa
= RADEON_CONTEXT( ctx
);
2149 GLuint tpc
= rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
];
2150 GLuint vs
= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
];
2152 GLuint texMatEnabled
= 0;
2153 rmesa
->NeedTexMatrix
= 0;
2154 rmesa
->TexMatColSwap
= 0;
2156 for (unit
= 0 ; unit
< ctx
->Const
.MaxTextureUnits
; unit
++) {
2157 if (ctx
->Texture
.Unit
[unit
]._ReallyEnabled
) {
2158 GLboolean needMatrix
= GL_FALSE
;
2159 if (ctx
->TextureMatrixStack
[unit
].Top
->type
!= MATRIX_IDENTITY
) {
2160 needMatrix
= GL_TRUE
;
2161 texMatEnabled
|= (RADEON_TEXGEN_TEXMAT_0_ENABLE
|
2162 RADEON_TEXMAT_0_ENABLE
) << unit
;
2164 if (rmesa
->TexGenEnabled
& (RADEON_TEXMAT_0_ENABLE
<< unit
)) {
2165 /* Need to preconcatenate any active texgen
2166 * obj/eyeplane matrices:
2168 _math_matrix_mul_matrix( &rmesa
->tmpmat
[unit
],
2169 ctx
->TextureMatrixStack
[unit
].Top
,
2170 &rmesa
->TexGenMatrix
[unit
] );
2173 _math_matrix_copy( &rmesa
->tmpmat
[unit
],
2174 ctx
->TextureMatrixStack
[unit
].Top
);
2177 else if (rmesa
->TexGenEnabled
& (RADEON_TEXMAT_0_ENABLE
<< unit
)) {
2178 _math_matrix_copy( &rmesa
->tmpmat
[unit
], &rmesa
->TexGenMatrix
[unit
] );
2179 needMatrix
= GL_TRUE
;
2182 rmesa
->NeedTexMatrix
|= 1 << unit
;
2183 radeonUploadTexMatrix( rmesa
, unit
,
2184 !ctx
->Texture
.Unit
[unit
].TexGenEnabled
);
2189 tpc
= (texMatEnabled
| rmesa
->TexGenEnabled
);
2191 /* TCL_TEX_COMPUTED_x is TCL_TEX_INPUT_x | 0x8 */
2192 vs
&= ~((RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_0_OUTPUT_SHIFT
) |
2193 (RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_1_OUTPUT_SHIFT
) |
2194 (RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_2_OUTPUT_SHIFT
));
2196 vs
|= (((tpc
& RADEON_TEXGEN_TEXMAT_0_ENABLE
) <<
2197 (RADEON_TCL_TEX_0_OUTPUT_SHIFT
+ 3)) |
2198 ((tpc
& RADEON_TEXGEN_TEXMAT_1_ENABLE
) <<
2199 (RADEON_TCL_TEX_1_OUTPUT_SHIFT
+ 2)) |
2200 ((tpc
& RADEON_TEXGEN_TEXMAT_2_ENABLE
) <<
2201 (RADEON_TCL_TEX_2_OUTPUT_SHIFT
+ 1)));
2203 if (tpc
!= rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
] ||
2204 vs
!= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
]) {
2206 RADEON_STATECHANGE(rmesa
, tcl
);
2207 rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
] = tpc
;
2208 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] = vs
;
2214 * Tell the card where to render (offset, pitch).
2215 * Effected by glDrawBuffer, etc
2218 radeonUpdateDrawBuffer(GLcontext
*ctx
)
2220 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2221 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
2222 driRenderbuffer
*drb
;
2224 if (fb
->_ColorDrawBufferIndexes
[0] == BUFFER_FRONT_LEFT
) {
2226 drb
= (driRenderbuffer
*) fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
;
2228 else if (fb
->_ColorDrawBufferIndexes
[0] == BUFFER_BACK_LEFT
) {
2230 drb
= (driRenderbuffer
*) fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
;
2233 /* drawing to multiple buffers, or none */
2238 assert(drb
->flippedPitch
);
2240 RADEON_STATECHANGE( rmesa
, ctx
);
2242 /* Note: we used the (possibly) page-flipped values */
2243 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLOROFFSET
]
2244 = ((drb
->flippedOffset
+ rmesa
->radeonScreen
->fbLocation
)
2245 & RADEON_COLOROFFSET_MASK
);
2246 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] = drb
->flippedPitch
;
2247 if (rmesa
->sarea
->tiling_enabled
) {
2248 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] |= RADEON_COLOR_TILE_ENABLE
;
2253 void radeonValidateState( GLcontext
*ctx
)
2255 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2256 GLuint new_state
= rmesa
->NewGLState
;
2258 if (new_state
& (_NEW_BUFFERS
| _NEW_COLOR
| _NEW_PIXEL
)) {
2259 radeonUpdateDrawBuffer(ctx
);
2262 if (new_state
& _NEW_TEXTURE
) {
2263 radeonUpdateTextureState( ctx
);
2264 new_state
|= rmesa
->NewGLState
; /* may add TEXTURE_MATRIX */
2267 /* Need an event driven matrix update?
2269 if (new_state
& (_NEW_MODELVIEW
|_NEW_PROJECTION
))
2270 upload_matrix( rmesa
, ctx
->_ModelProjectMatrix
.m
, MODEL_PROJ
);
2272 /* Need these for lighting (shouldn't upload otherwise)
2274 if (new_state
& (_NEW_MODELVIEW
)) {
2275 upload_matrix( rmesa
, ctx
->ModelviewMatrixStack
.Top
->m
, MODEL
);
2276 upload_matrix_t( rmesa
, ctx
->ModelviewMatrixStack
.Top
->inv
, MODEL_IT
);
2279 /* Does this need to be triggered on eg. modelview for
2280 * texgen-derived objplane/eyeplane matrices?
2282 if (new_state
& _NEW_TEXTURE_MATRIX
) {
2283 update_texturematrix( ctx
);
2286 if (new_state
& (_NEW_LIGHT
|_NEW_MODELVIEW
|_MESA_NEW_NEED_EYE_COORDS
)) {
2287 update_light( ctx
);
2290 /* emit all active clip planes if projection matrix changes.
2292 if (new_state
& (_NEW_PROJECTION
)) {
2293 if (ctx
->Transform
.ClipPlanesEnabled
)
2294 radeonUpdateClipPlanes( ctx
);
2298 rmesa
->NewGLState
= 0;
2302 static void radeonInvalidateState( GLcontext
*ctx
, GLuint new_state
)
2304 _swrast_InvalidateState( ctx
, new_state
);
2305 _swsetup_InvalidateState( ctx
, new_state
);
2306 _vbo_InvalidateState( ctx
, new_state
);
2307 _tnl_InvalidateState( ctx
, new_state
);
2308 _ae_invalidate_state( ctx
, new_state
);
2309 RADEON_CONTEXT(ctx
)->NewGLState
|= new_state
;
2313 /* A hack. Need a faster way to find this out.
2315 static GLboolean
check_material( GLcontext
*ctx
)
2317 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
2320 for (i
= _TNL_ATTRIB_MAT_FRONT_AMBIENT
;
2321 i
< _TNL_ATTRIB_MAT_BACK_INDEXES
;
2323 if (tnl
->vb
.AttribPtr
[i
] &&
2324 tnl
->vb
.AttribPtr
[i
]->stride
)
2331 static void radeonWrapRunPipeline( GLcontext
*ctx
)
2333 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2334 GLboolean has_material
;
2337 fprintf(stderr
, "%s, newstate: %x\n", __FUNCTION__
, rmesa
->NewGLState
);
2341 if (rmesa
->NewGLState
)
2342 radeonValidateState( ctx
);
2344 has_material
= (ctx
->Light
.Enabled
&& check_material( ctx
));
2347 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_MATERIAL
, GL_TRUE
);
2350 /* Run the pipeline.
2352 _tnl_run_pipeline( ctx
);
2355 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_MATERIAL
, GL_FALSE
);
2360 /* Initialize the driver's state functions.
2361 * Many of the ctx->Driver functions might have been initialized to
2362 * software defaults in the earlier _mesa_init_driver_functions() call.
2364 void radeonInitStateFuncs( GLcontext
*ctx
)
2366 ctx
->Driver
.UpdateState
= radeonInvalidateState
;
2367 ctx
->Driver
.LightingSpaceChange
= radeonLightingSpaceChange
;
2369 ctx
->Driver
.DrawBuffer
= radeonDrawBuffer
;
2370 ctx
->Driver
.ReadBuffer
= radeonReadBuffer
;
2372 ctx
->Driver
.AlphaFunc
= radeonAlphaFunc
;
2373 ctx
->Driver
.BlendEquationSeparate
= radeonBlendEquationSeparate
;
2374 ctx
->Driver
.BlendFuncSeparate
= radeonBlendFuncSeparate
;
2375 ctx
->Driver
.ClearColor
= radeonClearColor
;
2376 ctx
->Driver
.ClearDepth
= radeonClearDepth
;
2377 ctx
->Driver
.ClearIndex
= NULL
;
2378 ctx
->Driver
.ClearStencil
= radeonClearStencil
;
2379 ctx
->Driver
.ClipPlane
= radeonClipPlane
;
2380 ctx
->Driver
.ColorMask
= radeonColorMask
;
2381 ctx
->Driver
.CullFace
= radeonCullFace
;
2382 ctx
->Driver
.DepthFunc
= radeonDepthFunc
;
2383 ctx
->Driver
.DepthMask
= radeonDepthMask
;
2384 ctx
->Driver
.DepthRange
= radeonDepthRange
;
2385 ctx
->Driver
.Enable
= radeonEnable
;
2386 ctx
->Driver
.Fogfv
= radeonFogfv
;
2387 ctx
->Driver
.FrontFace
= radeonFrontFace
;
2388 ctx
->Driver
.Hint
= NULL
;
2389 ctx
->Driver
.IndexMask
= NULL
;
2390 ctx
->Driver
.LightModelfv
= radeonLightModelfv
;
2391 ctx
->Driver
.Lightfv
= radeonLightfv
;
2392 ctx
->Driver
.LineStipple
= radeonLineStipple
;
2393 ctx
->Driver
.LineWidth
= radeonLineWidth
;
2394 ctx
->Driver
.LogicOpcode
= radeonLogicOpCode
;
2395 ctx
->Driver
.PolygonMode
= radeonPolygonMode
;
2396 ctx
->Driver
.PolygonOffset
= radeonPolygonOffset
;
2397 ctx
->Driver
.PolygonStipple
= radeonPolygonStipple
;
2398 ctx
->Driver
.RenderMode
= radeonRenderMode
;
2399 ctx
->Driver
.Scissor
= radeonScissor
;
2400 ctx
->Driver
.ShadeModel
= radeonShadeModel
;
2401 ctx
->Driver
.StencilFuncSeparate
= radeonStencilFuncSeparate
;
2402 ctx
->Driver
.StencilMaskSeparate
= radeonStencilMaskSeparate
;
2403 ctx
->Driver
.StencilOpSeparate
= radeonStencilOpSeparate
;
2404 ctx
->Driver
.Viewport
= radeonViewport
;
2406 TNL_CONTEXT(ctx
)->Driver
.NotifyMaterialChange
= radeonUpdateMaterial
;
2407 TNL_CONTEXT(ctx
)->Driver
.RunPipeline
= radeonWrapRunPipeline
;