2 Copyright (C) The Weather Channel, Inc. 2002.
3 Copyright (C) 2004 Nicolai Haehnle.
6 The Weather Channel (TM) funded Tungsten Graphics to develop the
7 initial release of the Radeon 8500 driver under the XFree86 license.
8 This notice must be preserved.
10 Permission is hereby granted, free of charge, to any person obtaining
11 a copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sublicense, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial
20 portions of the Software.
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
26 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 **************************************************************************/
35 * \author Nicolai Haehnle <prefect_@gmx.net>
45 #include "simple_list.h"
47 #include "api_arrayelt.h"
48 #include "swrast/swrast.h"
49 #include "swrast_setup/swrast_setup.h"
50 #include "shader/prog_parameter.h"
51 #include "shader/prog_statevars.h"
54 #include "texformat.h"
56 #include "radeon_ioctl.h"
57 #include "radeon_state.h"
58 #include "r300_context.h"
59 #include "r300_ioctl.h"
60 #include "r300_state.h"
62 #include "r300_emit.h"
63 #include "r300_fragprog.h"
66 #include "drirenderbuffer.h"
68 extern int future_hw_tcl_on
;
69 extern void _tnl_UpdateFixedFunctionProgram(GLcontext
* ctx
);
71 static void r300BlendColor(GLcontext
* ctx
, const GLfloat cf
[4])
74 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
76 R300_STATECHANGE(rmesa
, blend_color
);
78 CLAMPED_FLOAT_TO_UBYTE(color
[0], cf
[0]);
79 CLAMPED_FLOAT_TO_UBYTE(color
[1], cf
[1]);
80 CLAMPED_FLOAT_TO_UBYTE(color
[2], cf
[2]);
81 CLAMPED_FLOAT_TO_UBYTE(color
[3], cf
[3]);
83 rmesa
->hw
.blend_color
.cmd
[1] = PACK_COLOR_8888(color
[3], color
[0],
85 rmesa
->hw
.blend_color
.cmd
[2] = 0;
86 rmesa
->hw
.blend_color
.cmd
[3] = 0;
90 * Calculate the hardware blend factor setting. This same function is used
91 * for source and destination of both alpha and RGB.
94 * The hardware register value for the specified blend factor. This value
95 * will need to be shifted into the correct position for either source or
99 * Since the two cases where source and destination are handled differently
100 * are essentially error cases, they should never happen. Determine if these
101 * cases can be removed.
103 static int blend_factor(GLenum factor
, GLboolean is_src
)
107 return R300_BLEND_GL_ZERO
;
110 return R300_BLEND_GL_ONE
;
113 return R300_BLEND_GL_DST_COLOR
;
115 case GL_ONE_MINUS_DST_COLOR
:
116 return R300_BLEND_GL_ONE_MINUS_DST_COLOR
;
119 return R300_BLEND_GL_SRC_COLOR
;
121 case GL_ONE_MINUS_SRC_COLOR
:
122 return R300_BLEND_GL_ONE_MINUS_SRC_COLOR
;
125 return R300_BLEND_GL_SRC_ALPHA
;
127 case GL_ONE_MINUS_SRC_ALPHA
:
128 return R300_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
131 return R300_BLEND_GL_DST_ALPHA
;
133 case GL_ONE_MINUS_DST_ALPHA
:
134 return R300_BLEND_GL_ONE_MINUS_DST_ALPHA
;
136 case GL_SRC_ALPHA_SATURATE
:
137 return (is_src
) ? R300_BLEND_GL_SRC_ALPHA_SATURATE
:
140 case GL_CONSTANT_COLOR
:
141 return R300_BLEND_GL_CONST_COLOR
;
143 case GL_ONE_MINUS_CONSTANT_COLOR
:
144 return R300_BLEND_GL_ONE_MINUS_CONST_COLOR
;
146 case GL_CONSTANT_ALPHA
:
147 return R300_BLEND_GL_CONST_ALPHA
;
149 case GL_ONE_MINUS_CONSTANT_ALPHA
:
150 return R300_BLEND_GL_ONE_MINUS_CONST_ALPHA
;
153 fprintf(stderr
, "unknown blend factor %x\n", factor
);
154 return (is_src
) ? R300_BLEND_GL_ONE
: R300_BLEND_GL_ZERO
;
160 * Sets both the blend equation and the blend function.
161 * This is done in a single
162 * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX)
163 * change the interpretation of the blend function.
164 * Also, make sure that blend function and blend equation are set to their
165 * default value if color blending is not enabled, since at least blend
166 * equations GL_MIN and GL_FUNC_REVERSE_SUBTRACT will cause wrong results
167 * otherwise for unknown reasons.
170 /* helper function */
171 static void r300SetBlendCntl(r300ContextPtr r300
, int func
, int eqn
,
172 int cbits
, int funcA
, int eqnA
)
174 GLuint new_ablend
, new_cblend
;
178 "eqnA=%08x funcA=%08x eqn=%08x func=%08x cbits=%08x\n",
179 eqnA
, funcA
, eqn
, func
, cbits
);
181 new_ablend
= eqnA
| funcA
;
182 new_cblend
= eqn
| func
;
184 /* Some blend factor combinations don't seem to work when the
185 * BLEND_NO_SEPARATE bit is set.
187 * Especially problematic candidates are the ONE_MINUS_* flags,
188 * but I can't see a real pattern.
191 if (new_ablend
== new_cblend
) {
192 new_cblend
|= R300_DISCARD_SRC_PIXELS_SRC_ALPHA_0
;
197 if ((new_ablend
!= r300
->hw
.bld
.cmd
[R300_BLD_ABLEND
]) ||
198 (new_cblend
!= r300
->hw
.bld
.cmd
[R300_BLD_CBLEND
])) {
199 R300_STATECHANGE(r300
, bld
);
200 r300
->hw
.bld
.cmd
[R300_BLD_ABLEND
] = new_ablend
;
201 r300
->hw
.bld
.cmd
[R300_BLD_CBLEND
] = new_cblend
;
205 static void r300SetBlendState(GLcontext
* ctx
)
207 r300ContextPtr r300
= R300_CONTEXT(ctx
);
208 int func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
209 (R300_BLEND_GL_ZERO
<< R300_DST_BLEND_SHIFT
);
210 int eqn
= R300_COMB_FCN_ADD_CLAMP
;
211 int funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
212 (R300_BLEND_GL_ZERO
<< R300_DST_BLEND_SHIFT
);
213 int eqnA
= R300_COMB_FCN_ADD_CLAMP
;
215 if (RGBA_LOGICOP_ENABLED(ctx
) || !ctx
->Color
.BlendEnabled
) {
216 r300SetBlendCntl(r300
, func
, eqn
, 0, func
, eqn
);
221 (blend_factor(ctx
->Color
.BlendSrcRGB
, GL_TRUE
) <<
222 R300_SRC_BLEND_SHIFT
) | (blend_factor(ctx
->Color
.BlendDstRGB
,
224 R300_DST_BLEND_SHIFT
);
226 switch (ctx
->Color
.BlendEquationRGB
) {
228 eqn
= R300_COMB_FCN_ADD_CLAMP
;
231 case GL_FUNC_SUBTRACT
:
232 eqn
= R300_COMB_FCN_SUB_CLAMP
;
235 case GL_FUNC_REVERSE_SUBTRACT
:
236 eqn
= R300_COMB_FCN_RSUB_CLAMP
;
240 eqn
= R300_COMB_FCN_MIN
;
241 func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
242 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
246 eqn
= R300_COMB_FCN_MAX
;
247 func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
248 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
253 "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
254 __FUNCTION__
, __LINE__
, ctx
->Color
.BlendEquationRGB
);
259 (blend_factor(ctx
->Color
.BlendSrcA
, GL_TRUE
) <<
260 R300_SRC_BLEND_SHIFT
) | (blend_factor(ctx
->Color
.BlendDstA
,
262 R300_DST_BLEND_SHIFT
);
264 switch (ctx
->Color
.BlendEquationA
) {
266 eqnA
= R300_COMB_FCN_ADD_CLAMP
;
269 case GL_FUNC_SUBTRACT
:
270 eqnA
= R300_COMB_FCN_SUB_CLAMP
;
273 case GL_FUNC_REVERSE_SUBTRACT
:
274 eqnA
= R300_COMB_FCN_RSUB_CLAMP
;
278 eqnA
= R300_COMB_FCN_MIN
;
279 funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
280 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
284 eqnA
= R300_COMB_FCN_MAX
;
285 funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
286 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
291 "[%s:%u] Invalid A blend equation (0x%04x).\n",
292 __FUNCTION__
, __LINE__
, ctx
->Color
.BlendEquationA
);
296 r300SetBlendCntl(r300
,
298 (R300_SEPARATE_ALPHA_ENABLE
|
300 R300_ALPHA_BLEND_ENABLE
), funcA
, eqnA
);
303 static void r300BlendEquationSeparate(GLcontext
* ctx
,
304 GLenum modeRGB
, GLenum modeA
)
306 r300SetBlendState(ctx
);
309 static void r300BlendFuncSeparate(GLcontext
* ctx
,
310 GLenum sfactorRGB
, GLenum dfactorRGB
,
311 GLenum sfactorA
, GLenum dfactorA
)
313 r300SetBlendState(ctx
);
316 static void r300ClipPlane( GLcontext
*ctx
, GLenum plane
, const GLfloat
*eq
)
318 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
322 /* no VAP UCP on non-TCL chipsets */
323 if (!(rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
326 p
= (GLint
) plane
- (GLint
) GL_CLIP_PLANE0
;
327 ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
329 R300_STATECHANGE( rmesa
, vpucp
[p
] );
330 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_X
] = ip
[0];
331 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_Y
] = ip
[1];
332 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_Z
] = ip
[2];
333 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_W
] = ip
[3];
336 static void r300SetClipPlaneState(GLcontext
* ctx
, GLenum cap
, GLboolean state
)
338 r300ContextPtr r300
= R300_CONTEXT(ctx
);
341 /* no VAP UCP on non-TCL chipsets */
342 if (!(r300
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
345 p
= cap
- GL_CLIP_PLANE0
;
346 R300_STATECHANGE(r300
, vap_clip_cntl
);
348 r300
->hw
.vap_clip_cntl
.cmd
[1] |= (R300_VAP_UCP_ENABLE_0
<< p
);
349 r300ClipPlane(ctx
, cap
, NULL
);
351 r300
->hw
.vap_clip_cntl
.cmd
[1] &= ~(R300_VAP_UCP_ENABLE_0
<< p
);
356 * Update our tracked culling state based on Mesa's state.
358 static void r300UpdateCulling(GLcontext
* ctx
)
360 r300ContextPtr r300
= R300_CONTEXT(ctx
);
363 if (ctx
->Polygon
.CullFlag
) {
364 switch (ctx
->Polygon
.CullFaceMode
) {
366 val
= R300_CULL_FRONT
;
369 val
= R300_CULL_BACK
;
371 case GL_FRONT_AND_BACK
:
372 val
= R300_CULL_FRONT
| R300_CULL_BACK
;
379 switch (ctx
->Polygon
.FrontFace
) {
381 val
|= R300_FRONT_FACE_CW
;
384 val
|= R300_FRONT_FACE_CCW
;
390 R300_STATECHANGE(r300
, cul
);
391 r300
->hw
.cul
.cmd
[R300_CUL_CULL
] = val
;
394 static void r300SetPolygonOffsetState(GLcontext
* ctx
, GLboolean state
)
396 r300ContextPtr r300
= R300_CONTEXT(ctx
);
398 R300_STATECHANGE(r300
, occlusion_cntl
);
400 r300
->hw
.occlusion_cntl
.cmd
[1] |= (3 << 0);
402 r300
->hw
.occlusion_cntl
.cmd
[1] &= ~(3 << 0);
406 static GLboolean
current_fragment_program_writes_depth(GLcontext
* ctx
)
408 r300ContextPtr r300
= R300_CONTEXT(ctx
);
410 if (r300
->radeon
.radeonScreen
->chip_family
< CHIP_FAMILY_RV515
) {
411 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
412 (char *)ctx
->FragmentProgram
._Current
;
413 return (fp
&& fp
->WritesDepth
);
415 struct r500_fragment_program
* fp
=
416 (struct r500_fragment_program
*)(char*)
417 ctx
->FragmentProgram
._Current
;
418 return (fp
&& fp
->writes_depth
);
422 static void r300SetEarlyZState(GLcontext
* ctx
)
424 r300ContextPtr r300
= R300_CONTEXT(ctx
);
425 GLuint topZ
= R300_ZTOP_ENABLE
;
427 if (ctx
->Color
.AlphaEnabled
&& ctx
->Color
.AlphaFunc
!= GL_ALWAYS
)
428 topZ
= R300_ZTOP_DISABLE
;
429 if (current_fragment_program_writes_depth(ctx
))
430 topZ
= R300_ZTOP_DISABLE
;
432 if (topZ
!= r300
->hw
.zstencil_format
.cmd
[2]) {
433 /* Note: This completely reemits the stencil format.
434 * I have not tested whether this is strictly necessary,
435 * or if emitting a write to ZB_ZTOP is enough.
437 R300_STATECHANGE(r300
, zstencil_format
);
438 r300
->hw
.zstencil_format
.cmd
[2] = topZ
;
442 static void r300SetAlphaState(GLcontext
* ctx
)
444 r300ContextPtr r300
= R300_CONTEXT(ctx
);
446 uint32_t pp_misc
= 0x0;
447 GLboolean really_enabled
= ctx
->Color
.AlphaEnabled
;
449 CLAMPED_FLOAT_TO_UBYTE(refByte
, ctx
->Color
.AlphaRef
);
451 switch (ctx
->Color
.AlphaFunc
) {
453 pp_misc
|= R300_FG_ALPHA_FUNC_NEVER
;
456 pp_misc
|= R300_FG_ALPHA_FUNC_LESS
;
459 pp_misc
|= R300_FG_ALPHA_FUNC_EQUAL
;
462 pp_misc
|= R300_FG_ALPHA_FUNC_LE
;
465 pp_misc
|= R300_FG_ALPHA_FUNC_GREATER
;
468 pp_misc
|= R300_FG_ALPHA_FUNC_NOTEQUAL
;
471 pp_misc
|= R300_FG_ALPHA_FUNC_GE
;
474 /*pp_misc |= FG_ALPHA_FUNC_ALWAYS; */
475 really_enabled
= GL_FALSE
;
479 if (really_enabled
) {
480 pp_misc
|= R300_FG_ALPHA_FUNC_ENABLE
;
481 pp_misc
|= R500_FG_ALPHA_FUNC_8BIT
;
482 pp_misc
|= (refByte
& R300_FG_ALPHA_FUNC_VAL_MASK
);
487 R300_STATECHANGE(r300
, at
);
488 r300
->hw
.at
.cmd
[R300_AT_ALPHA_TEST
] = pp_misc
;
489 r300
->hw
.at
.cmd
[R300_AT_UNKNOWN
] = 0;
491 r300SetEarlyZState(ctx
);
494 static void r300AlphaFunc(GLcontext
* ctx
, GLenum func
, GLfloat ref
)
498 r300SetAlphaState(ctx
);
501 static int translate_func(int func
)
505 return R300_ZS_NEVER
;
509 return R300_ZS_EQUAL
;
511 return R300_ZS_LEQUAL
;
513 return R300_ZS_GREATER
;
515 return R300_ZS_NOTEQUAL
;
517 return R300_ZS_GEQUAL
;
519 return R300_ZS_ALWAYS
;
524 static void r300SetDepthState(GLcontext
* ctx
)
526 r300ContextPtr r300
= R300_CONTEXT(ctx
);
528 R300_STATECHANGE(r300
, zs
);
529 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &= R300_STENCIL_ENABLE
|R300_STENCIL_FRONT_BACK
;
530 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= ~(R300_ZS_MASK
<< R300_Z_FUNC_SHIFT
);
532 if (ctx
->Depth
.Test
) {
533 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_Z_ENABLE
;
535 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_Z_WRITE_ENABLE
;
536 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
537 translate_func(ctx
->Depth
.Func
) << R300_Z_FUNC_SHIFT
;
540 r300SetEarlyZState(ctx
);
543 static void r300SetStencilState(GLcontext
* ctx
, GLboolean state
)
545 r300ContextPtr r300
= R300_CONTEXT(ctx
);
547 if (r300
->state
.stencil
.hw_stencil
) {
548 R300_STATECHANGE(r300
, zs
);
550 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |=
553 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &=
554 ~R300_STENCIL_ENABLE
;
558 FALLBACK(&r300
->radeon
, RADEON_FALLBACK_STENCIL
, state
);
563 static void r300UpdatePolygonMode(GLcontext
* ctx
)
565 r300ContextPtr r300
= R300_CONTEXT(ctx
);
566 uint32_t hw_mode
= R300_GA_POLY_MODE_DISABLE
;
568 /* Only do something if a polygon mode is wanted, default is GL_FILL */
569 if (ctx
->Polygon
.FrontMode
!= GL_FILL
||
570 ctx
->Polygon
.BackMode
!= GL_FILL
) {
573 /* Handle GL_CW (clock wise and GL_CCW (counter clock wise)
574 * correctly by selecting the correct front and back face
576 if (ctx
->Polygon
.FrontFace
== GL_CCW
) {
577 f
= ctx
->Polygon
.FrontMode
;
578 b
= ctx
->Polygon
.BackMode
;
580 f
= ctx
->Polygon
.BackMode
;
581 b
= ctx
->Polygon
.FrontMode
;
584 /* Enable polygon mode */
585 hw_mode
|= R300_GA_POLY_MODE_DUAL
;
589 hw_mode
|= R300_GA_POLY_MODE_FRONT_PTYPE_LINE
;
592 hw_mode
|= R300_GA_POLY_MODE_FRONT_PTYPE_POINT
;
595 hw_mode
|= R300_GA_POLY_MODE_FRONT_PTYPE_TRI
;
601 hw_mode
|= R300_GA_POLY_MODE_BACK_PTYPE_LINE
;
604 hw_mode
|= R300_GA_POLY_MODE_BACK_PTYPE_POINT
;
607 hw_mode
|= R300_GA_POLY_MODE_BACK_PTYPE_TRI
;
612 if (r300
->hw
.polygon_mode
.cmd
[1] != hw_mode
) {
613 R300_STATECHANGE(r300
, polygon_mode
);
614 r300
->hw
.polygon_mode
.cmd
[1] = hw_mode
;
617 r300
->hw
.polygon_mode
.cmd
[2] = 0x00000001;
618 r300
->hw
.polygon_mode
.cmd
[3] = 0x00000000;
622 * Change the culling mode.
624 * \note Mesa already filters redundant calls to this function.
626 static void r300CullFace(GLcontext
* ctx
, GLenum mode
)
630 r300UpdateCulling(ctx
);
634 * Change the polygon orientation.
636 * \note Mesa already filters redundant calls to this function.
638 static void r300FrontFace(GLcontext
* ctx
, GLenum mode
)
642 r300UpdateCulling(ctx
);
643 r300UpdatePolygonMode(ctx
);
647 * Change the depth testing function.
649 * \note Mesa already filters redundant calls to this function.
651 static void r300DepthFunc(GLcontext
* ctx
, GLenum func
)
654 r300SetDepthState(ctx
);
658 * Enable/Disable depth writing.
660 * \note Mesa already filters redundant calls to this function.
662 static void r300DepthMask(GLcontext
* ctx
, GLboolean mask
)
665 r300SetDepthState(ctx
);
669 * Handle glColorMask()
671 static void r300ColorMask(GLcontext
* ctx
,
672 GLboolean r
, GLboolean g
, GLboolean b
, GLboolean a
)
674 r300ContextPtr r300
= R300_CONTEXT(ctx
);
675 int mask
= (r
? RB3D_COLOR_CHANNEL_MASK_RED_MASK0
: 0) |
676 (g
? RB3D_COLOR_CHANNEL_MASK_GREEN_MASK0
: 0) |
677 (b
? RB3D_COLOR_CHANNEL_MASK_BLUE_MASK0
: 0) |
678 (a
? RB3D_COLOR_CHANNEL_MASK_ALPHA_MASK0
: 0);
680 if (mask
!= r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
]) {
681 R300_STATECHANGE(r300
, cmk
);
682 r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
] = mask
;
686 /* =============================================================
689 static void r300Fogfv(GLcontext
* ctx
, GLenum pname
, const GLfloat
* param
)
691 r300ContextPtr r300
= R300_CONTEXT(ctx
);
695 } fogScale
, fogStart
;
699 fogScale
.i
= r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
];
700 fogStart
.i
= r300
->hw
.fogp
.cmd
[R300_FOGP_START
];
704 if (!ctx
->Fog
.Enabled
)
706 switch (ctx
->Fog
.Mode
) {
708 R300_STATECHANGE(r300
, fogs
);
709 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
711 cmd
[R300_FOGS_STATE
] & ~R300_FG_FOG_BLEND_FN_MASK
) |
712 R300_FG_FOG_BLEND_FN_LINEAR
;
714 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
719 1.0 / (ctx
->Fog
.End
- ctx
->Fog
.Start
);
721 -ctx
->Fog
.Start
/ (ctx
->Fog
.End
-
726 R300_STATECHANGE(r300
, fogs
);
727 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
729 cmd
[R300_FOGS_STATE
] & ~R300_FG_FOG_BLEND_FN_MASK
) |
730 R300_FG_FOG_BLEND_FN_EXP
;
731 fogScale
.f
= 0.0933 * ctx
->Fog
.Density
;
735 R300_STATECHANGE(r300
, fogs
);
736 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
738 cmd
[R300_FOGS_STATE
] & ~R300_FG_FOG_BLEND_FN_MASK
) |
739 R300_FG_FOG_BLEND_FN_EXP2
;
740 fogScale
.f
= 0.3 * ctx
->Fog
.Density
;
747 switch (ctx
->Fog
.Mode
) {
749 fogScale
.f
= 0.0933 * ctx
->Fog
.Density
;
753 fogScale
.f
= 0.3 * ctx
->Fog
.Density
;
761 if (ctx
->Fog
.Mode
== GL_LINEAR
) {
762 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
767 1.0 / (ctx
->Fog
.End
- ctx
->Fog
.Start
);
769 -ctx
->Fog
.Start
/ (ctx
->Fog
.End
-
775 R300_STATECHANGE(r300
, fogc
);
776 r300
->hw
.fogc
.cmd
[R300_FOGC_R
] =
777 (GLuint
) (ctx
->Fog
.Color
[0] * 1023.0F
) & 0x3FF;
778 r300
->hw
.fogc
.cmd
[R300_FOGC_G
] =
779 (GLuint
) (ctx
->Fog
.Color
[1] * 1023.0F
) & 0x3FF;
780 r300
->hw
.fogc
.cmd
[R300_FOGC_B
] =
781 (GLuint
) (ctx
->Fog
.Color
[2] * 1023.0F
) & 0x3FF;
783 case GL_FOG_COORD_SRC
:
789 if (fogScale
.i
!= r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
] ||
790 fogStart
.i
!= r300
->hw
.fogp
.cmd
[R300_FOGP_START
]) {
791 R300_STATECHANGE(r300
, fogp
);
792 r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
] = fogScale
.i
;
793 r300
->hw
.fogp
.cmd
[R300_FOGP_START
] = fogStart
.i
;
797 static void r300SetFogState(GLcontext
* ctx
, GLboolean state
)
799 r300ContextPtr r300
= R300_CONTEXT(ctx
);
801 R300_STATECHANGE(r300
, fogs
);
803 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] |= R300_FG_FOG_BLEND_ENABLE
;
805 r300Fogfv(ctx
, GL_FOG_MODE
, NULL
);
806 r300Fogfv(ctx
, GL_FOG_DENSITY
, &ctx
->Fog
.Density
);
807 r300Fogfv(ctx
, GL_FOG_START
, &ctx
->Fog
.Start
);
808 r300Fogfv(ctx
, GL_FOG_END
, &ctx
->Fog
.End
);
809 r300Fogfv(ctx
, GL_FOG_COLOR
, ctx
->Fog
.Color
);
811 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] &= ~R300_FG_FOG_BLEND_ENABLE
;
815 /* =============================================================
818 static void r300PointSize(GLcontext
* ctx
, GLfloat size
)
820 r300ContextPtr r300
= R300_CONTEXT(ctx
);
821 /* same size limits for AA, non-AA points */
822 size
= CLAMP(size
, ctx
->Const
.MinPointSize
, ctx
->Const
.MaxPointSize
);
824 R300_STATECHANGE(r300
, ps
);
825 r300
->hw
.ps
.cmd
[R300_PS_POINTSIZE
] =
826 ((int)(size
* 6) << R300_POINTSIZE_X_SHIFT
) |
827 ((int)(size
* 6) << R300_POINTSIZE_Y_SHIFT
);
830 static void r300PointParameter(GLcontext
* ctx
, GLenum pname
, const GLfloat
* param
)
832 r300ContextPtr r300
= R300_CONTEXT(ctx
);
835 case GL_POINT_SIZE_MIN
:
836 R300_STATECHANGE(r300
, ga_point_minmax
);
837 r300
->hw
.ga_point_minmax
.cmd
[1] &= ~R300_GA_POINT_MINMAX_MIN_MASK
;
838 r300
->hw
.ga_point_minmax
.cmd
[1] |= (GLuint
)(ctx
->Point
.MinSize
* 16.0);
840 case GL_POINT_SIZE_MAX
:
841 R300_STATECHANGE(r300
, ga_point_minmax
);
842 r300
->hw
.ga_point_minmax
.cmd
[1] &= ~R300_GA_POINT_MINMAX_MAX_MASK
;
843 r300
->hw
.ga_point_minmax
.cmd
[1] |= (GLuint
)(ctx
->Point
.MaxSize
* 16.0)
844 << R300_GA_POINT_MINMAX_MAX_SHIFT
;
846 case GL_POINT_DISTANCE_ATTENUATION
:
848 case GL_POINT_FADE_THRESHOLD_SIZE
:
855 /* =============================================================
858 static void r300LineWidth(GLcontext
* ctx
, GLfloat widthf
)
860 r300ContextPtr r300
= R300_CONTEXT(ctx
);
862 widthf
= CLAMP(widthf
,
863 ctx
->Const
.MinPointSize
,
864 ctx
->Const
.MaxPointSize
);
865 R300_STATECHANGE(r300
, lcntl
);
866 r300
->hw
.lcntl
.cmd
[1] =
867 R300_LINE_CNT_HO
| R300_LINE_CNT_VE
| (int)(widthf
* 6.0);
870 static void r300PolygonMode(GLcontext
* ctx
, GLenum face
, GLenum mode
)
875 r300UpdatePolygonMode(ctx
);
878 /* =============================================================
882 static int translate_stencil_op(int op
)
890 return R300_ZS_REPLACE
;
895 case GL_INCR_WRAP_EXT
:
896 return R300_ZS_INCR_WRAP
;
897 case GL_DECR_WRAP_EXT
:
898 return R300_ZS_DECR_WRAP
;
900 return R300_ZS_INVERT
;
902 WARN_ONCE("Do not know how to translate stencil op");
908 static void r300ShadeModel(GLcontext
* ctx
, GLenum mode
)
910 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
912 R300_STATECHANGE(rmesa
, shade
);
913 rmesa
->hw
.shade
.cmd
[1] = 0x00000002;
916 rmesa
->hw
.shade
.cmd
[2] = R300_RE_SHADE_MODEL_FLAT
;
919 rmesa
->hw
.shade
.cmd
[2] = R300_RE_SHADE_MODEL_SMOOTH
;
924 rmesa
->hw
.shade
.cmd
[3] = 0x00000000;
925 rmesa
->hw
.shade
.cmd
[4] = 0x00000000;
928 static void r300StencilFuncSeparate(GLcontext
* ctx
, GLenum face
,
929 GLenum func
, GLint ref
, GLuint mask
)
931 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
934 Ref
[0] & 0xff) << R300_STENCILREF_SHIFT
) | ((ctx
->
940 R300_STENCILMASK_SHIFT
));
944 R300_STATECHANGE(rmesa
, zs
);
945 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_STENCIL_FRONT_BACK
;
946 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= ~((R300_ZS_MASK
<<
947 R300_S_FRONT_FUNC_SHIFT
)
949 R300_S_BACK_FUNC_SHIFT
));
951 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &=
952 ~((R300_STENCILREF_MASK
<< R300_STENCILREF_SHIFT
) |
953 (R300_STENCILREF_MASK
<< R300_STENCILMASK_SHIFT
));
955 flag
= translate_func(ctx
->Stencil
.Function
[0]);
956 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
957 (flag
<< R300_S_FRONT_FUNC_SHIFT
);
959 if (ctx
->Stencil
._TestTwoSide
)
960 flag
= translate_func(ctx
->Stencil
.Function
[1]);
962 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
963 (flag
<< R300_S_BACK_FUNC_SHIFT
);
964 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |= refmask
;
967 static void r300StencilMaskSeparate(GLcontext
* ctx
, GLenum face
, GLuint mask
)
969 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
971 R300_STATECHANGE(rmesa
, zs
);
972 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &=
973 ~(R300_STENCILREF_MASK
<<
974 R300_STENCILWRITEMASK_SHIFT
);
975 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |=
977 WriteMask
[0] & R300_STENCILREF_MASK
) <<
978 R300_STENCILWRITEMASK_SHIFT
;
981 static void r300StencilOpSeparate(GLcontext
* ctx
, GLenum face
,
982 GLenum fail
, GLenum zfail
, GLenum zpass
)
984 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
986 R300_STATECHANGE(rmesa
, zs
);
987 /* It is easier to mask what's left.. */
988 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &=
989 (R300_ZS_MASK
<< R300_Z_FUNC_SHIFT
) |
990 (R300_ZS_MASK
<< R300_S_FRONT_FUNC_SHIFT
) |
991 (R300_ZS_MASK
<< R300_S_BACK_FUNC_SHIFT
);
993 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
994 (translate_stencil_op(ctx
->Stencil
.FailFunc
[0]) <<
995 R300_S_FRONT_SFAIL_OP_SHIFT
)
996 | (translate_stencil_op(ctx
->Stencil
.ZFailFunc
[0]) <<
997 R300_S_FRONT_ZFAIL_OP_SHIFT
)
998 | (translate_stencil_op(ctx
->Stencil
.ZPassFunc
[0]) <<
999 R300_S_FRONT_ZPASS_OP_SHIFT
);
1001 if (ctx
->Stencil
._TestTwoSide
) {
1002 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
1003 (translate_stencil_op(ctx
->Stencil
.FailFunc
[1]) <<
1004 R300_S_BACK_SFAIL_OP_SHIFT
)
1005 | (translate_stencil_op(ctx
->Stencil
.ZFailFunc
[1]) <<
1006 R300_S_BACK_ZFAIL_OP_SHIFT
)
1007 | (translate_stencil_op(ctx
->Stencil
.ZPassFunc
[1]) <<
1008 R300_S_BACK_ZPASS_OP_SHIFT
);
1010 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
1011 (translate_stencil_op(ctx
->Stencil
.FailFunc
[0]) <<
1012 R300_S_BACK_SFAIL_OP_SHIFT
)
1013 | (translate_stencil_op(ctx
->Stencil
.ZFailFunc
[0]) <<
1014 R300_S_BACK_ZFAIL_OP_SHIFT
)
1015 | (translate_stencil_op(ctx
->Stencil
.ZPassFunc
[0]) <<
1016 R300_S_BACK_ZPASS_OP_SHIFT
);
1020 /* =============================================================
1021 * Window position and viewport transformation
1025 * To correctly position primitives:
1027 #define SUBPIXEL_X 0.125
1028 #define SUBPIXEL_Y 0.125
1030 static void r300UpdateWindow(GLcontext
* ctx
)
1032 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1033 __DRIdrawablePrivate
*dPriv
= rmesa
->radeon
.dri
.drawable
;
1034 GLfloat xoffset
= dPriv
? (GLfloat
) dPriv
->x
: 0;
1035 GLfloat yoffset
= dPriv
? (GLfloat
) dPriv
->y
+ dPriv
->h
: 0;
1036 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1038 GLfloat sx
= v
[MAT_SX
];
1039 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1040 GLfloat sy
= -v
[MAT_SY
];
1041 GLfloat ty
= (-v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1042 GLfloat sz
= v
[MAT_SZ
] * rmesa
->state
.depth
.scale
;
1043 GLfloat tz
= v
[MAT_TZ
] * rmesa
->state
.depth
.scale
;
1045 R300_FIREVERTICES(rmesa
);
1046 R300_STATECHANGE(rmesa
, vpt
);
1048 rmesa
->hw
.vpt
.cmd
[R300_VPT_XSCALE
] = r300PackFloat32(sx
);
1049 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
1050 rmesa
->hw
.vpt
.cmd
[R300_VPT_YSCALE
] = r300PackFloat32(sy
);
1051 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
1052 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZSCALE
] = r300PackFloat32(sz
);
1053 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZOFFSET
] = r300PackFloat32(tz
);
1056 static void r300Viewport(GLcontext
* ctx
, GLint x
, GLint y
,
1057 GLsizei width
, GLsizei height
)
1059 /* Don't pipeline viewport changes, conflict with window offset
1060 * setting below. Could apply deltas to rescue pipelined viewport
1061 * values, or keep the originals hanging around.
1063 r300UpdateWindow(ctx
);
1066 static void r300DepthRange(GLcontext
* ctx
, GLclampd nearval
, GLclampd farval
)
1068 r300UpdateWindow(ctx
);
1071 void r300UpdateViewportOffset(GLcontext
* ctx
)
1073 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1074 __DRIdrawablePrivate
*dPriv
= ((radeonContextPtr
) rmesa
)->dri
.drawable
;
1075 GLfloat xoffset
= (GLfloat
) dPriv
->x
;
1076 GLfloat yoffset
= (GLfloat
) dPriv
->y
+ dPriv
->h
;
1077 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1079 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1080 GLfloat ty
= (-v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1082 if (rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] != r300PackFloat32(tx
) ||
1083 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] != r300PackFloat32(ty
)) {
1084 /* Note: this should also modify whatever data the context reset
1087 R300_STATECHANGE(rmesa
, vpt
);
1088 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
1089 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
1093 radeonUpdateScissor(ctx
);
1097 * Tell the card where to render (offset, pitch).
1098 * Effected by glDrawBuffer, etc
1100 void r300UpdateDrawBuffer(GLcontext
* ctx
)
1102 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1103 r300ContextPtr r300
= rmesa
;
1104 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
1105 driRenderbuffer
*drb
;
1107 if (fb
->_ColorDrawBufferIndexes
[0] == BUFFER_FRONT_LEFT
) {
1110 (driRenderbuffer
*) fb
->Attachment
[BUFFER_FRONT_LEFT
].
1112 } else if (fb
->_ColorDrawBufferIndexes
[0] == BUFFER_BACK_LEFT
) {
1115 (driRenderbuffer
*) fb
->Attachment
[BUFFER_BACK_LEFT
].
1118 /* drawing to multiple buffers, or none */
1123 assert(drb
->flippedPitch
);
1125 R300_STATECHANGE(rmesa
, cb
);
1127 r300
->hw
.cb
.cmd
[R300_CB_OFFSET
] = drb
->flippedOffset
+ //r300->radeon.state.color.drawOffset +
1128 r300
->radeon
.radeonScreen
->fbLocation
;
1129 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] = drb
->flippedPitch
; //r300->radeon.state.color.drawPitch;
1131 if (r300
->radeon
.radeonScreen
->cpp
== 4)
1132 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_ARGB8888
;
1134 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_RGB565
;
1136 if (r300
->radeon
.sarea
->tiling_enabled
)
1137 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_TILE_ENABLE
;
1139 R200_STATECHANGE(rmesa
, ctx
);
1141 /* Note: we used the (possibly) page-flipped values */
1142 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLOROFFSET
]
1143 = ((drb
->flippedOffset
+ rmesa
->r200Screen
->fbLocation
)
1144 & R200_COLOROFFSET_MASK
);
1145 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] = drb
->flippedPitch
;
1147 if (rmesa
->sarea
->tiling_enabled
) {
1148 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] |=
1149 R200_COLOR_TILE_ENABLE
;
1155 r300FetchStateParameter(GLcontext
* ctx
,
1156 const gl_state_index state
[STATE_LENGTH
],
1159 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1162 case STATE_INTERNAL
:
1164 case STATE_R300_WINDOW_DIMENSION
:
1165 value
[0] = r300
->radeon
.dri
.drawable
->w
* 0.5f
; /* width*0.5 */
1166 value
[1] = r300
->radeon
.dri
.drawable
->h
* 0.5f
; /* height*0.5 */
1167 value
[2] = 0.5F
; /* for moving range [-1 1] -> [0 1] */
1168 value
[3] = 1.0F
; /* not used */
1171 case STATE_R300_TEXRECT_FACTOR
:{
1172 struct gl_texture_object
*t
=
1173 ctx
->Texture
.Unit
[state
[2]].CurrentRect
;
1175 if (t
&& t
->Image
[0][t
->BaseLevel
]) {
1176 struct gl_texture_image
*image
=
1177 t
->Image
[0][t
->BaseLevel
];
1178 value
[0] = 1.0 / image
->Width2
;
1179 value
[1] = 1.0 / image
->Height2
;
1200 * Update R300's own internal state parameters.
1201 * For now just STATE_R300_WINDOW_DIMENSION
1203 void r300UpdateStateParameters(GLcontext
* ctx
, GLuint new_state
)
1205 struct r300_fragment_program
*fp
;
1206 struct gl_program_parameter_list
*paramList
;
1209 if (!(new_state
& (_NEW_BUFFERS
| _NEW_PROGRAM
)))
1212 fp
= (struct r300_fragment_program
*)ctx
->FragmentProgram
._Current
;
1216 paramList
= fp
->mesa_program
.Base
.Parameters
;
1221 for (i
= 0; i
< paramList
->NumParameters
; i
++) {
1222 if (paramList
->Parameters
[i
].Type
== PROGRAM_STATE_VAR
) {
1223 r300FetchStateParameter(ctx
,
1224 paramList
->Parameters
[i
].
1226 paramList
->ParameterValues
[i
]);
1231 /* =============================================================
1234 static void r300PolygonOffset(GLcontext
* ctx
, GLfloat factor
, GLfloat units
)
1236 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1237 GLfloat constant
= units
;
1239 switch (ctx
->Visual
.depthBits
) {
1250 /* fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */
1252 R300_STATECHANGE(rmesa
, zbs
);
1253 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_FACTOR
] = r300PackFloat32(factor
);
1254 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_CONSTANT
] = r300PackFloat32(constant
);
1255 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_FACTOR
] = r300PackFloat32(factor
);
1256 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_CONSTANT
] = r300PackFloat32(constant
);
1259 /* Routing and texture-related */
1261 /* r300 doesnt handle GL_CLAMP and GL_MIRROR_CLAMP_EXT correctly when filter is NEAREST.
1262 * Since texwrap produces same results for GL_CLAMP and GL_CLAMP_TO_EDGE we use them instead.
1263 * We need to recalculate wrap modes whenever filter mode is changed because someone might do:
1264 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1265 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1266 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1267 * Since r300 completely ignores R300_TX_CLAMP when either min or mag is nearest it cant handle
1268 * combinations where only one of them is nearest.
1270 static unsigned long gen_fixed_filter(unsigned long f
)
1272 unsigned long mag
, min
, needs_fixing
= 0;
1275 /* We ignore MIRROR bit so we dont have to do everything twice */
1276 if ((f
& ((7 - 1) << R300_TX_WRAP_S_SHIFT
)) ==
1277 (R300_TX_CLAMP
<< R300_TX_WRAP_S_SHIFT
)) {
1280 if ((f
& ((7 - 1) << R300_TX_WRAP_T_SHIFT
)) ==
1281 (R300_TX_CLAMP
<< R300_TX_WRAP_T_SHIFT
)) {
1284 if ((f
& ((7 - 1) << R300_TX_WRAP_R_SHIFT
)) ==
1285 (R300_TX_CLAMP
<< R300_TX_WRAP_R_SHIFT
)) {
1292 mag
= f
& R300_TX_MAG_FILTER_MASK
;
1293 min
= f
& (R300_TX_MIN_FILTER_MASK
|R300_TX_MIN_FILTER_MIP_MASK
);
1295 /* TODO: Check for anisto filters too */
1296 if ((mag
!= R300_TX_MAG_FILTER_NEAREST
)
1297 && (min
!= R300_TX_MIN_FILTER_NEAREST
))
1300 /* r300 cant handle these modes hence we force nearest to linear */
1301 if ((mag
== R300_TX_MAG_FILTER_NEAREST
)
1302 && (min
!= R300_TX_MIN_FILTER_NEAREST
)) {
1303 f
&= ~R300_TX_MAG_FILTER_NEAREST
;
1304 f
|= R300_TX_MAG_FILTER_LINEAR
;
1308 if ((min
== R300_TX_MIN_FILTER_NEAREST
)
1309 && (mag
!= R300_TX_MAG_FILTER_NEAREST
)) {
1310 f
&= ~R300_TX_MIN_FILTER_NEAREST
;
1311 f
|= R300_TX_MIN_FILTER_LINEAR
;
1315 /* Both are nearest */
1316 if (needs_fixing
& 1) {
1317 f
&= ~((7 - 1) << R300_TX_WRAP_S_SHIFT
);
1318 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_S_SHIFT
;
1320 if (needs_fixing
& 2) {
1321 f
&= ~((7 - 1) << R300_TX_WRAP_T_SHIFT
);
1322 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_T_SHIFT
;
1324 if (needs_fixing
& 4) {
1325 f
&= ~((7 - 1) << R300_TX_WRAP_R_SHIFT
);
1326 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_R_SHIFT
;
1331 static void r300SetupFragmentShaderTextures(GLcontext
*ctx
, int *tmu_mappings
)
1333 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1335 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
1336 (char *)ctx
->FragmentProgram
._Current
;
1337 struct r300_fragment_program_code
*code
= &fp
->code
;
1339 R300_STATECHANGE(r300
, fpt
);
1341 for (i
= 0; i
< code
->tex
.length
; i
++) {
1346 unit
= code
->tex
.inst
[i
] >> R300_TEX_ID_SHIFT
;
1349 val
= code
->tex
.inst
[i
];
1350 val
&= ~R300_TEX_ID_MASK
;
1353 (val
& R300_TEX_INST_MASK
) >> R300_TEX_INST_SHIFT
;
1354 if (opcode
== R300_TEX_OP_KIL
) {
1355 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1357 if (tmu_mappings
[unit
] >= 0) {
1359 tmu_mappings
[unit
] <<
1361 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1363 // We get here when the corresponding texture image is incomplete
1364 // (e.g. incomplete mipmaps etc.)
1365 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1370 r300
->hw
.fpt
.cmd
[R300_FPT_CMD_0
] =
1371 cmdpacket0(R300_US_TEX_INST_0
, code
->tex
.length
);
1374 static void r500SetupFragmentShaderTextures(GLcontext
*ctx
, int *tmu_mappings
)
1377 struct r500_fragment_program
*fp
= (struct r500_fragment_program
*)
1378 (char *)ctx
->FragmentProgram
._Current
;
1379 struct r500_fragment_program_code
*code
= &fp
->code
;
1381 /* find all the texture instructions and relocate the texture units */
1382 for (i
= 0; i
< code
->inst_end
+ 1; i
++) {
1383 if ((code
->inst
[i
].inst0
& 0x3) == R500_INST_TYPE_TEX
) {
1385 int unit
, opcode
, new_unit
;
1387 val
= code
->inst
[i
].inst1
;
1389 unit
= (val
>> 16) & 0xf;
1391 val
&= ~(0xf << 16);
1393 opcode
= val
& (0x7 << 22);
1394 if (opcode
== R500_TEX_INST_TEXKILL
) {
1397 if (tmu_mappings
[unit
] >= 0) {
1398 new_unit
= tmu_mappings
[unit
];
1403 val
|= R500_TEX_ID(new_unit
);
1404 code
->inst
[i
].inst1
= val
;
1409 static GLuint
translate_lod_bias(GLfloat bias
)
1411 GLint b
= (int)(bias
*32);
1414 else if (b
< -(1 << 9))
1416 return (((GLuint
)b
) << R300_LOD_BIAS_SHIFT
) & R300_LOD_BIAS_MASK
;
1419 static void r300SetupTextures(GLcontext
* ctx
)
1422 struct r300_tex_obj
*t
;
1423 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1425 int last_hw_tmu
= -1; /* -1 translates into no setup costs for fields */
1426 int tmu_mappings
[R300_MAX_TEXTURE_UNITS
] = { -1, };
1427 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
1428 (char *)ctx
->FragmentProgram
._Current
;
1430 R300_STATECHANGE(r300
, txe
);
1431 R300_STATECHANGE(r300
, tex
.filter
);
1432 R300_STATECHANGE(r300
, tex
.filter_1
);
1433 R300_STATECHANGE(r300
, tex
.size
);
1434 R300_STATECHANGE(r300
, tex
.format
);
1435 R300_STATECHANGE(r300
, tex
.pitch
);
1436 R300_STATECHANGE(r300
, tex
.offset
);
1437 R300_STATECHANGE(r300
, tex
.chroma_key
);
1438 R300_STATECHANGE(r300
, tex
.border_color
);
1440 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] = 0x0;
1442 mtu
= r300
->radeon
.glCtx
->Const
.MaxTextureUnits
;
1443 if (RADEON_DEBUG
& DEBUG_STATE
)
1444 fprintf(stderr
, "mtu=%d\n", mtu
);
1446 if (mtu
> R300_MAX_TEXTURE_UNITS
) {
1448 "Aiiee ! mtu=%d is greater than R300_MAX_TEXTURE_UNITS=%d\n",
1449 mtu
, R300_MAX_TEXTURE_UNITS
);
1453 /* We cannot let disabled tmu offsets pass DRM */
1454 for (i
= 0; i
< mtu
; i
++) {
1455 if (ctx
->Texture
.Unit
[i
]._ReallyEnabled
) {
1457 #if 0 /* Enables old behaviour */
1460 tmu_mappings
[i
] = hw_tmu
;
1462 t
= r300
->state
.texture
.unit
[i
].texobj
;
1463 /* XXX questionable fix for bug 9170: */
1467 if ((t
->format
& 0xffffff00) == 0xffffff00) {
1469 ("unknown texture format (entry %x) encountered. Help me !\n",
1473 if (RADEON_DEBUG
& DEBUG_STATE
)
1475 "Activating texture unit %d\n", i
);
1477 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] |= (1 << hw_tmu
);
1479 r300
->hw
.tex
.filter
.cmd
[R300_TEX_VALUE_0
+
1481 gen_fixed_filter(t
->filter
) | (hw_tmu
<< 28);
1482 /* Note: There is a LOD bias per texture unit and a LOD bias
1483 * per texture object. We add them here to get the correct behaviour.
1484 * (The per-texture object LOD bias was introduced in OpenGL 1.4
1485 * and is not present in the EXT_texture_object extension).
1487 r300
->hw
.tex
.filter_1
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] =
1489 translate_lod_bias(ctx
->Texture
.Unit
[i
].LodBias
+ t
->base
.tObj
->LodBias
);
1490 r300
->hw
.tex
.size
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] =
1492 r300
->hw
.tex
.format
.cmd
[R300_TEX_VALUE_0
+
1493 hw_tmu
] = t
->format
;
1494 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] =
1496 r300
->hw
.tex
.offset
.cmd
[R300_TEX_VALUE_0
+
1497 hw_tmu
] = t
->offset
;
1499 if (t
->offset
& R300_TXO_MACRO_TILE
) {
1500 WARN_ONCE("macro tiling enabled!\n");
1503 if (t
->offset
& R300_TXO_MICRO_TILE
) {
1504 WARN_ONCE("micro tiling enabled!\n");
1507 r300
->hw
.tex
.chroma_key
.cmd
[R300_TEX_VALUE_0
+
1509 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_VALUE_0
+
1513 last_hw_tmu
= hw_tmu
;
1519 r300
->hw
.tex
.filter
.cmd
[R300_TEX_CMD_0
] =
1520 cmdpacket0(R300_TX_FILTER0_0
, last_hw_tmu
+ 1);
1521 r300
->hw
.tex
.filter_1
.cmd
[R300_TEX_CMD_0
] =
1522 cmdpacket0(R300_TX_FILTER1_0
, last_hw_tmu
+ 1);
1523 r300
->hw
.tex
.size
.cmd
[R300_TEX_CMD_0
] =
1524 cmdpacket0(R300_TX_SIZE_0
, last_hw_tmu
+ 1);
1525 r300
->hw
.tex
.format
.cmd
[R300_TEX_CMD_0
] =
1526 cmdpacket0(R300_TX_FORMAT_0
, last_hw_tmu
+ 1);
1527 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_CMD_0
] =
1528 cmdpacket0(R300_TX_FORMAT2_0
, last_hw_tmu
+ 1);
1529 r300
->hw
.tex
.offset
.cmd
[R300_TEX_CMD_0
] =
1530 cmdpacket0(R300_TX_OFFSET_0
, last_hw_tmu
+ 1);
1531 r300
->hw
.tex
.chroma_key
.cmd
[R300_TEX_CMD_0
] =
1532 cmdpacket0(R300_TX_CHROMA_KEY_0
, last_hw_tmu
+ 1);
1533 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_CMD_0
] =
1534 cmdpacket0(R300_TX_BORDER_COLOR_0
, last_hw_tmu
+ 1);
1536 if (!fp
) /* should only happenen once, just after context is created */
1539 if (r300
->radeon
.radeonScreen
->chip_family
< CHIP_FAMILY_RV515
) {
1540 if (fp
->mesa_program
.UsesKill
&& last_hw_tmu
< 0) {
1541 // The KILL operation requires the first texture unit
1543 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] |= 1;
1544 r300
->hw
.tex
.filter
.cmd
[R300_TEX_VALUE_0
] = 0;
1545 r300
->hw
.tex
.filter
.cmd
[R300_TEX_CMD_0
] =
1546 cmdpacket0(R300_TX_FILTER0_0
, 1);
1548 r300SetupFragmentShaderTextures(ctx
, tmu_mappings
);
1550 r500SetupFragmentShaderTextures(ctx
, tmu_mappings
);
1552 if (RADEON_DEBUG
& DEBUG_STATE
)
1553 fprintf(stderr
, "TX_ENABLE: %08x last_hw_tmu=%d\n",
1554 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
], last_hw_tmu
);
1557 union r300_outputs_written
{
1558 GLuint vp_outputs
; /* hw_tcl_on */
1559 DECLARE_RENDERINPUTS(index_bitset
); /* !hw_tcl_on */
1562 #define R300_OUTPUTS_WRITTEN_TEST(ow, vp_result, tnl_attrib) \
1563 ((hw_tcl_on) ? (ow).vp_outputs & (1 << (vp_result)) : \
1564 RENDERINPUTS_TEST( (ow.index_bitset), (tnl_attrib) ))
1566 static void r300SetupRSUnit(GLcontext
* ctx
)
1568 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1569 /* I'm still unsure if these are needed */
1570 GLuint interp_col
[8];
1571 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1572 struct vertex_buffer
*VB
= &tnl
->vb
;
1573 union r300_outputs_written OutputsWritten
;
1575 int fp_reg
, high_rr
;
1577 int rs_tex_count
= 0, rs_col_count
= 0;
1580 memset(interp_col
, 0, sizeof(interp_col
));
1583 OutputsWritten
.vp_outputs
= CURRENT_VERTEX_SHADER(ctx
)->key
.OutputsWritten
;
1585 RENDERINPUTS_COPY(OutputsWritten
.index_bitset
, r300
->state
.render_inputs_bitset
);
1587 if (ctx
->FragmentProgram
._Current
)
1588 InputsRead
= ctx
->FragmentProgram
._Current
->Base
.InputsRead
;
1590 fprintf(stderr
, "No ctx->FragmentProgram._Current!!\n");
1591 return; /* This should only ever happen once.. */
1594 R300_STATECHANGE(r300
, ri
);
1595 R300_STATECHANGE(r300
, rc
);
1596 R300_STATECHANGE(r300
, rr
);
1598 fp_reg
= col_interp_nr
= high_rr
= 0;
1600 r300
->hw
.rr
.cmd
[R300_RR_INST_1
] = 0;
1602 if (InputsRead
& FRAG_BIT_WPOS
) {
1603 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++)
1604 if (!(InputsRead
& (FRAG_BIT_TEX0
<< i
)))
1607 if (i
== ctx
->Const
.MaxTextureUnits
) {
1608 fprintf(stderr
, "\tno free texcoord found...\n");
1612 InputsRead
|= (FRAG_BIT_TEX0
<< i
);
1613 InputsRead
&= ~FRAG_BIT_WPOS
;
1616 if (InputsRead
& FRAG_BIT_COL0
) {
1617 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR0
]->size
;
1618 interp_col
[0] |= R300_RS_COL_PTR(rs_col_count
);
1620 interp_col
[0] |= R300_RS_COL_FMT(R300_RS_COL_FMT_RGB1
);
1621 rs_col_count
+= count
;
1624 interp_col
[0] = R300_RS_COL_FMT(R300_RS_COL_FMT_0001
);
1626 if (InputsRead
& FRAG_BIT_COL1
) {
1627 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR1
]->size
;
1629 interp_col
[1] |= R300_RS_COL_FMT(R300_RS_COL_FMT_RGB0
);
1630 interp_col
[1] |= R300_RS_COL_PTR(1);
1631 rs_col_count
+= count
;
1635 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
1638 /* with TCL we always seem to route 4 components */
1642 count
= VB
->AttribPtr
[_TNL_ATTRIB_TEX(i
)]->size
;
1644 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ i
] = interp_col
[i
] | rs_tex_count
;
1646 case 4: swiz
= R300_RS_SEL_S(0) | R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(3); break;
1647 case 3: swiz
= R300_RS_SEL_S(0) | R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(R300_RS_SEL_K1
); break;
1650 case 2: swiz
= R300_RS_SEL_S(0) | R300_RS_SEL_T(1) | R300_RS_SEL_R(R300_RS_SEL_K0
) | R300_RS_SEL_Q(R300_RS_SEL_K1
); break;
1653 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ i
] |= swiz
;
1655 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ fp_reg
] = 0;
1656 if (InputsRead
& (FRAG_BIT_TEX0
<< i
)) {
1658 rs_tex_count
+= count
;
1660 //assert(r300->state.texture.tc_count != 0);
1661 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ fp_reg
] |= R300_RS_INST_TEX_CN_WRITE
| i
/* source INTERP */
1662 | (fp_reg
<< R300_RS_INST_TEX_ADDR_SHIFT
);
1665 /* Passing invalid data here can lock the GPU. */
1666 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_TEX0
+ i
, _TNL_ATTRIB_TEX(i
))) {
1667 InputsRead
&= ~(FRAG_BIT_TEX0
<< i
);
1670 WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i
);
1675 if (InputsRead
& FRAG_BIT_COL0
) {
1676 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL0
, _TNL_ATTRIB_COLOR0
)) {
1677 r300
->hw
.rr
.cmd
[R300_RR_INST_0
] |= R300_RS_INST_COL_ID(0) | R300_RS_INST_COL_CN_WRITE
| (fp_reg
++ << R300_RS_INST_COL_ADDR_SHIFT
);
1678 InputsRead
&= ~FRAG_BIT_COL0
;
1681 WARN_ONCE("fragprog wants col0, vp doesn't provide it\n");
1685 if (InputsRead
& FRAG_BIT_COL1
) {
1686 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL1
, _TNL_ATTRIB_COLOR1
)) {
1687 r300
->hw
.rr
.cmd
[R300_RR_INST_1
] |= R300_RS_INST_COL_ID(1) | R300_RS_INST_COL_CN_WRITE
| (fp_reg
++ << R300_RS_INST_COL_ADDR_SHIFT
);
1688 InputsRead
&= ~FRAG_BIT_COL1
;
1693 WARN_ONCE("fragprog wants col1, vp doesn't provide it\n");
1697 /* Need at least one. This might still lock as the values are undefined... */
1698 if (rs_tex_count
== 0 && col_interp_nr
== 0) {
1699 r300
->hw
.rr
.cmd
[R300_RR_INST_0
] |= R300_RS_INST_COL_ID(0) | R300_RS_INST_COL_CN_WRITE
| (fp_reg
++ << R300_RS_INST_COL_ADDR_SHIFT
);
1703 r300
->hw
.rc
.cmd
[1] = 0 | (rs_tex_count
<< R300_IT_COUNT_SHIFT
)
1704 | (col_interp_nr
<< R300_IC_COUNT_SHIFT
)
1707 assert(high_rr
>= 0);
1708 r300
->hw
.rr
.cmd
[R300_RR_CMD_0
] = cmdpacket0(R300_RS_INST_0
, high_rr
+ 1);
1709 r300
->hw
.rc
.cmd
[2] = high_rr
;
1712 WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead
);
1715 static void r500SetupRSUnit(GLcontext
* ctx
)
1717 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1718 /* I'm still unsure if these are needed */
1719 GLuint interp_col
[8];
1720 union r300_outputs_written OutputsWritten
;
1721 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1722 struct vertex_buffer
*VB
= &tnl
->vb
;
1724 int fp_reg
, high_rr
;
1725 int rs_col_count
= 0;
1726 int in_texcoords
, col_interp_nr
;
1729 memset(interp_col
, 0, sizeof(interp_col
));
1731 OutputsWritten
.vp_outputs
= CURRENT_VERTEX_SHADER(ctx
)->key
.OutputsWritten
;
1733 RENDERINPUTS_COPY(OutputsWritten
.index_bitset
, r300
->state
.render_inputs_bitset
);
1735 if (ctx
->FragmentProgram
._Current
)
1736 InputsRead
= ctx
->FragmentProgram
._Current
->Base
.InputsRead
;
1738 fprintf(stderr
, "No ctx->FragmentProgram._Current!!\n");
1739 return; /* This should only ever happen once.. */
1742 R300_STATECHANGE(r300
, ri
);
1743 R300_STATECHANGE(r300
, rc
);
1744 R300_STATECHANGE(r300
, rr
);
1746 fp_reg
= col_interp_nr
= high_rr
= in_texcoords
= 0;
1748 r300
->hw
.rr
.cmd
[R300_RR_INST_1
] = 0;
1750 if (InputsRead
& FRAG_BIT_WPOS
) {
1751 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++)
1752 if (!(InputsRead
& (FRAG_BIT_TEX0
<< i
)))
1755 if (i
== ctx
->Const
.MaxTextureUnits
) {
1756 fprintf(stderr
, "\tno free texcoord found...\n");
1760 InputsRead
|= (FRAG_BIT_TEX0
<< i
);
1761 InputsRead
&= ~FRAG_BIT_WPOS
;
1764 if (InputsRead
& FRAG_BIT_COL0
) {
1765 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR0
]->size
;
1766 interp_col
[0] |= R500_RS_COL_PTR(rs_col_count
);
1768 interp_col
[0] |= R500_RS_COL_FMT(R300_RS_COL_FMT_RGB1
);
1769 rs_col_count
+= count
;
1772 interp_col
[0] = R500_RS_COL_FMT(R300_RS_COL_FMT_0001
);
1774 if (InputsRead
& FRAG_BIT_COL1
) {
1775 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR1
]->size
;
1776 interp_col
[1] |= R500_RS_COL_PTR(1);
1778 interp_col
[1] |= R500_RS_COL_FMT(R300_RS_COL_FMT_RGB0
);
1779 rs_col_count
+= count
;
1782 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
1785 /* with TCL we always seem to route 4 components */
1786 if (InputsRead
& (FRAG_BIT_TEX0
<< i
)) {
1791 count
= VB
->AttribPtr
[_TNL_ATTRIB_TEX(i
)]->size
;
1793 /* always have on texcoord */
1794 swiz
|= in_texcoords
++ << R500_RS_IP_TEX_PTR_S_SHIFT
;
1796 swiz
|= in_texcoords
++ << R500_RS_IP_TEX_PTR_T_SHIFT
;
1798 swiz
|= R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_T_SHIFT
;
1801 swiz
|= in_texcoords
++ << R500_RS_IP_TEX_PTR_R_SHIFT
;
1803 swiz
|= R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_R_SHIFT
;
1806 swiz
|= in_texcoords
++ << R500_RS_IP_TEX_PTR_Q_SHIFT
;
1808 swiz
|= R500_RS_IP_PTR_K1
<< R500_RS_IP_TEX_PTR_Q_SHIFT
;
1811 swiz
= (R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_S_SHIFT
) |
1812 (R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_T_SHIFT
) |
1813 (R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_R_SHIFT
) |
1814 (R500_RS_IP_PTR_K1
<< R500_RS_IP_TEX_PTR_Q_SHIFT
);
1816 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ i
] = interp_col
[i
] | swiz
;
1818 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ fp_reg
] = 0;
1819 if (InputsRead
& (FRAG_BIT_TEX0
<< i
)) {
1820 //assert(r300->state.texture.tc_count != 0);
1821 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ fp_reg
] |= R500_RS_INST_TEX_CN_WRITE
| i
/* source INTERP */
1822 | (fp_reg
<< R500_RS_INST_TEX_ADDR_SHIFT
);
1825 /* Passing invalid data here can lock the GPU. */
1826 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_TEX0
+ i
, _TNL_ATTRIB_TEX(i
))) {
1827 InputsRead
&= ~(FRAG_BIT_TEX0
<< i
);
1830 WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i
);
1835 if (InputsRead
& FRAG_BIT_COL0
) {
1836 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL0
, _TNL_ATTRIB_COLOR0
)) {
1837 r300
->hw
.rr
.cmd
[R300_RR_INST_0
] |= R500_RS_INST_COL_CN_WRITE
| (fp_reg
++ << R500_RS_INST_COL_ADDR_SHIFT
);
1838 InputsRead
&= ~FRAG_BIT_COL0
;
1841 WARN_ONCE("fragprog wants col0, vp doesn't provide it\n");
1845 if (InputsRead
& FRAG_BIT_COL1
) {
1846 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL1
, _TNL_ATTRIB_COLOR1
)) {
1847 r300
->hw
.rr
.cmd
[R300_RR_INST_1
] |= (1 << 12) | R500_RS_INST_COL_CN_WRITE
| (fp_reg
++ << R500_RS_INST_COL_ADDR_SHIFT
);
1848 InputsRead
&= ~FRAG_BIT_COL1
;
1853 WARN_ONCE("fragprog wants col1, vp doesn't provide it\n");
1857 /* Need at least one. This might still lock as the values are undefined... */
1858 if (in_texcoords
== 0 && col_interp_nr
== 0) {
1859 r300
->hw
.rr
.cmd
[R300_RR_INST_0
] |= 0 | R500_RS_INST_COL_CN_WRITE
| (fp_reg
++ << R500_RS_INST_COL_ADDR_SHIFT
);
1863 r300
->hw
.rc
.cmd
[1] = 0 | (in_texcoords
<< R300_IT_COUNT_SHIFT
)
1864 | (col_interp_nr
<< R300_IC_COUNT_SHIFT
)
1867 assert(high_rr
>= 0);
1868 r300
->hw
.rr
.cmd
[R300_RR_CMD_0
] = cmdpacket0(R500_RS_INST_0
, high_rr
+ 1);
1869 r300
->hw
.rc
.cmd
[2] = 0xC0 | high_rr
;
1872 WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead
);
1878 #define bump_vpu_count(ptr, new_count) do{\
1879 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
1880 int _nc=(new_count)/4; \
1881 assert(_nc < 256); \
1882 if(_nc>_p->vpu.count)_p->vpu.count=_nc;\
1885 static INLINE
void r300SetupVertexProgramFragment(r300ContextPtr r300
, int dest
, struct r300_vertex_shader_fragment
*vsf
)
1889 if (vsf
->length
== 0)
1892 if (vsf
->length
& 0x3) {
1893 fprintf(stderr
, "VERTEX_SHADER_FRAGMENT must have length divisible by 4\n");
1897 switch ((dest
>> 8) & 0xf) {
1899 R300_STATECHANGE(r300
, vpi
);
1900 for (i
= 0; i
< vsf
->length
; i
++)
1901 r300
->hw
.vpi
.cmd
[R300_VPI_INSTR_0
+ i
+ 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1902 bump_vpu_count(r300
->hw
.vpi
.cmd
, vsf
->length
+ 4 * (dest
& 0xff));
1906 R300_STATECHANGE(r300
, vpp
);
1907 for (i
= 0; i
< vsf
->length
; i
++)
1908 r300
->hw
.vpp
.cmd
[R300_VPP_PARAM_0
+ i
+ 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1909 bump_vpu_count(r300
->hw
.vpp
.cmd
, vsf
->length
+ 4 * (dest
& 0xff));
1912 R300_STATECHANGE(r300
, vps
);
1913 for (i
= 0; i
< vsf
->length
; i
++)
1914 r300
->hw
.vps
.cmd
[1 + i
+ 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1915 bump_vpu_count(r300
->hw
.vps
.cmd
, vsf
->length
+ 4 * (dest
& 0xff));
1918 fprintf(stderr
, "%s:%s don't know how to handle dest %04x\n", __FILE__
, __FUNCTION__
, dest
);
1923 #define MIN3(a, b, c) ((a) < (b) ? MIN2(a, c) : MIN2(b, c))
1926 static void r300VapCntl(r300ContextPtr rmesa
, GLuint input_count
,
1927 GLuint output_count
, GLuint temp_count
)
1933 /* Flush PVS engine before changing PVS_NUM_SLOTS, PVS_NUM_CNTRLS.
1934 * See r500 docs 6.5.2 - done in emit */
1936 /* avoid division by zero */
1937 if (input_count
== 0) input_count
= 1;
1938 if (output_count
== 0) output_count
= 1;
1939 if (temp_count
== 0) temp_count
= 1;
1941 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
1946 pvs_num_slots
= MIN3(10, vtx_mem_size
/input_count
, vtx_mem_size
/output_count
);
1947 pvs_num_cntrls
= MIN2(6, vtx_mem_size
/temp_count
);
1949 R300_STATECHANGE(rmesa
, vap_cntl
);
1950 if (rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
) {
1951 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] =
1952 (pvs_num_slots
<< R300_PVS_NUM_SLOTS_SHIFT
) |
1953 (pvs_num_cntrls
<< R300_PVS_NUM_CNTLRS_SHIFT
) |
1954 (12 << R300_VF_MAX_VTX_NUM_SHIFT
);
1955 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
1956 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= R500_TCL_STATE_OPTIMIZATION
;
1958 /* not sure about non-tcl */
1959 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] = ((10 << R300_PVS_NUM_SLOTS_SHIFT
) |
1960 (5 << R300_PVS_NUM_CNTLRS_SHIFT
) |
1961 (5 << R300_VF_MAX_VTX_NUM_SHIFT
));
1963 if (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV515
)
1964 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (2 << R300_PVS_NUM_FPUS_SHIFT
);
1965 else if ((rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV530
) ||
1966 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV560
))
1967 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (5 << R300_PVS_NUM_FPUS_SHIFT
);
1968 else if (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R420
)
1969 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (6 << R300_PVS_NUM_FPUS_SHIFT
);
1970 else if ((rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R520
) ||
1971 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R580
) ||
1972 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV570
))
1973 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (8 << R300_PVS_NUM_FPUS_SHIFT
);
1975 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (4 << R300_PVS_NUM_FPUS_SHIFT
);
1979 static void r300SetupDefaultVertexProgram(r300ContextPtr rmesa
)
1981 struct r300_vertex_shader_state
*prog
= &(rmesa
->state
.vertex_shader
);
1986 int param_count
= 0;
1987 int program_end
= 0;
1989 for (i
= VERT_ATTRIB_POS
; i
< VERT_ATTRIB_MAX
; i
++) {
1990 if (rmesa
->state
.sw_tcl_inputs
[i
] != -1) {
1991 prog
->program
.body
.i
[program_end
+ 0] = PVS_OP_DST_OPERAND(VE_MULTIPLY
, GL_FALSE
, GL_FALSE
, o_reg
++, VSF_FLAG_ALL
, PVS_DST_REG_OUT
);
1992 prog
->program
.body
.i
[program_end
+ 1] = PVS_SRC_OPERAND(rmesa
->state
.sw_tcl_inputs
[i
], PVS_SRC_SELECT_X
, PVS_SRC_SELECT_Y
, PVS_SRC_SELECT_Z
, PVS_SRC_SELECT_W
, PVS_SRC_REG_INPUT
, VSF_FLAG_NONE
);
1993 prog
->program
.body
.i
[program_end
+ 2] = PVS_SRC_OPERAND(rmesa
->state
.sw_tcl_inputs
[i
], PVS_SRC_SELECT_FORCE_1
, PVS_SRC_SELECT_FORCE_1
, PVS_SRC_SELECT_FORCE_1
, PVS_SRC_SELECT_FORCE_1
, PVS_SRC_REG_INPUT
, VSF_FLAG_NONE
);
1994 prog
->program
.body
.i
[program_end
+ 3] = PVS_SRC_OPERAND(rmesa
->state
.sw_tcl_inputs
[i
], PVS_SRC_SELECT_FORCE_1
, PVS_SRC_SELECT_FORCE_1
, PVS_SRC_SELECT_FORCE_1
, PVS_SRC_SELECT_FORCE_1
, PVS_SRC_REG_INPUT
, VSF_FLAG_NONE
);
2000 prog
->program
.length
= program_end
;
2002 r300SetupVertexProgramFragment(rmesa
, R300_PVS_CODE_START
,
2004 inst_count
= (prog
->program
.length
/ 4) - 1;
2006 r300VapCntl(rmesa
, i_reg
, o_reg
, 0);
2008 R300_STATECHANGE(rmesa
, pvs
);
2009 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] =
2010 (0 << R300_PVS_FIRST_INST_SHIFT
) |
2011 (inst_count
<< R300_PVS_XYZW_VALID_INST_SHIFT
) |
2012 (inst_count
<< R300_PVS_LAST_INST_SHIFT
);
2013 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] =
2014 (0 << R300_PVS_CONST_BASE_OFFSET_SHIFT
) |
2015 (param_count
<< R300_PVS_MAX_CONST_ADDR_SHIFT
);
2016 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] =
2017 (inst_count
<< R300_PVS_LAST_VTX_SRC_INST_SHIFT
);
2020 static int bit_count (int x
)
2022 x
= ((x
& 0xaaaaaaaaU
) >> 1) + (x
& 0x55555555U
);
2023 x
= ((x
& 0xccccccccU
) >> 2) + (x
& 0x33333333U
);
2024 x
= (x
>> 16) + (x
& 0xffff);
2025 x
= ((x
& 0xf0f0) >> 4) + (x
& 0x0f0f);
2026 return (x
>> 8) + (x
& 0x00ff);
2029 static void r300SetupRealVertexProgram(r300ContextPtr rmesa
)
2031 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
2032 struct r300_vertex_program
*prog
= (struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
);
2034 int param_count
= 0;
2036 /* FIXME: r300SetupVertexProgramFragment */
2037 R300_STATECHANGE(rmesa
, vpp
);
2039 r300VertexProgUpdateParams(ctx
,
2040 (struct r300_vertex_program_cont
*)
2041 ctx
->VertexProgram
._Current
,
2042 (float *)&rmesa
->hw
.vpp
.
2043 cmd
[R300_VPP_PARAM_0
]);
2044 bump_vpu_count(rmesa
->hw
.vpp
.cmd
, param_count
);
2047 r300SetupVertexProgramFragment(rmesa
, R300_PVS_CODE_START
, &(prog
->program
));
2048 inst_count
= (prog
->program
.length
/ 4) - 1;
2050 r300VapCntl(rmesa
, bit_count(prog
->key
.InputsRead
),
2051 bit_count(prog
->key
.OutputsWritten
), prog
->num_temporaries
);
2053 R300_STATECHANGE(rmesa
, pvs
);
2054 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] =
2055 (0 << R300_PVS_FIRST_INST_SHIFT
) |
2056 (inst_count
<< R300_PVS_XYZW_VALID_INST_SHIFT
) |
2057 (inst_count
<< R300_PVS_LAST_INST_SHIFT
);
2058 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] =
2059 (0 << R300_PVS_CONST_BASE_OFFSET_SHIFT
) |
2060 (param_count
<< R300_PVS_MAX_CONST_ADDR_SHIFT
);
2061 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] =
2062 (inst_count
<< R300_PVS_LAST_VTX_SRC_INST_SHIFT
);
2065 static void r300SetupVertexProgram(r300ContextPtr rmesa
)
2067 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
2069 /* Reset state, in case we don't use something */
2070 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vpp
.cmd
)->vpu
.count
= 0;
2071 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vpi
.cmd
)->vpu
.count
= 0;
2072 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vps
.cmd
)->vpu
.count
= 0;
2074 /* Not sure why this doesnt work...
2075 0x400 area might have something to do with pixel shaders as it appears right after pfs programming.
2076 0x406 is set to { 0.0, 0.0, 1.0, 0.0 } most of the time but should change with smooth points and in other rare cases. */
2077 //setup_vertex_shader_fragment(rmesa, 0x406, &unk4);
2078 if (hw_tcl_on
&& ((struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
))->translated
) {
2079 r300SetupRealVertexProgram(rmesa
);
2081 /* FIXME: This needs to be replaced by vertex shader generation code. */
2082 r300SetupDefaultVertexProgram(rmesa
);
2088 * Enable/Disable states.
2090 * \note Mesa already filters redundant calls to this function.
2092 static void r300Enable(GLcontext
* ctx
, GLenum cap
, GLboolean state
)
2094 if (RADEON_DEBUG
& DEBUG_STATE
)
2095 fprintf(stderr
, "%s( %s = %s )\n", __FUNCTION__
,
2096 _mesa_lookup_enum_by_nr(cap
),
2097 state
? "GL_TRUE" : "GL_FALSE");
2106 r300SetFogState(ctx
, state
);
2109 r300SetAlphaState(ctx
);
2112 case GL_COLOR_LOGIC_OP
:
2113 r300SetBlendState(ctx
);
2115 case GL_CLIP_PLANE0
:
2116 case GL_CLIP_PLANE1
:
2117 case GL_CLIP_PLANE2
:
2118 case GL_CLIP_PLANE3
:
2119 case GL_CLIP_PLANE4
:
2120 case GL_CLIP_PLANE5
:
2121 r300SetClipPlaneState(ctx
, cap
, state
);
2124 r300SetDepthState(ctx
);
2126 case GL_STENCIL_TEST
:
2127 r300SetStencilState(ctx
, state
);
2130 r300UpdateCulling(ctx
);
2132 case GL_POLYGON_OFFSET_POINT
:
2133 case GL_POLYGON_OFFSET_LINE
:
2134 case GL_POLYGON_OFFSET_FILL
:
2135 r300SetPolygonOffsetState(ctx
, state
);
2138 radeonEnable(ctx
, cap
, state
);
2144 * Completely recalculates hardware state based on the Mesa state.
2146 static void r300ResetHwState(r300ContextPtr r300
)
2148 GLcontext
*ctx
= r300
->radeon
.glCtx
;
2151 if (!(r300
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
2154 if (RADEON_DEBUG
& DEBUG_STATE
)
2155 fprintf(stderr
, "%s\n", __FUNCTION__
);
2157 r300UpdateWindow(ctx
);
2160 ctx
->Color
.ColorMask
[RCOMP
],
2161 ctx
->Color
.ColorMask
[GCOMP
],
2162 ctx
->Color
.ColorMask
[BCOMP
], ctx
->Color
.ColorMask
[ACOMP
]);
2164 r300Enable(ctx
, GL_DEPTH_TEST
, ctx
->Depth
.Test
);
2165 r300DepthMask(ctx
, ctx
->Depth
.Mask
);
2166 r300DepthFunc(ctx
, ctx
->Depth
.Func
);
2169 r300Enable(ctx
, GL_STENCIL_TEST
, ctx
->Stencil
.Enabled
);
2170 r300StencilMaskSeparate(ctx
, 0, ctx
->Stencil
.WriteMask
[0]);
2171 r300StencilFuncSeparate(ctx
, 0, ctx
->Stencil
.Function
[0],
2172 ctx
->Stencil
.Ref
[0], ctx
->Stencil
.ValueMask
[0]);
2173 r300StencilOpSeparate(ctx
, 0, ctx
->Stencil
.FailFunc
[0],
2174 ctx
->Stencil
.ZFailFunc
[0],
2175 ctx
->Stencil
.ZPassFunc
[0]);
2177 r300UpdateCulling(ctx
);
2179 r300UpdateTextureState(ctx
);
2181 r300SetBlendState(ctx
);
2183 r300AlphaFunc(ctx
, ctx
->Color
.AlphaFunc
, ctx
->Color
.AlphaRef
);
2184 r300Enable(ctx
, GL_ALPHA_TEST
, ctx
->Color
.AlphaEnabled
);
2186 r300
->hw
.vte
.cmd
[1] = R300_VPORT_X_SCALE_ENA
2187 | R300_VPORT_X_OFFSET_ENA
2188 | R300_VPORT_Y_SCALE_ENA
2189 | R300_VPORT_Y_OFFSET_ENA
2190 | R300_VPORT_Z_SCALE_ENA
2191 | R300_VPORT_Z_OFFSET_ENA
| R300_VTX_W0_FMT
;
2192 r300
->hw
.vte
.cmd
[2] = 0x00000008;
2194 r300
->hw
.vap_vf_max_vtx_indx
.cmd
[1] = 0x00FFFFFF;
2195 r300
->hw
.vap_vf_max_vtx_indx
.cmd
[2] = 0x00000000;
2197 #ifdef MESA_LITTLE_ENDIAN
2198 r300
->hw
.vap_cntl_status
.cmd
[1] = R300_VC_NO_SWAP
;
2200 r300
->hw
.vap_cntl_status
.cmd
[1] = R300_VC_32BIT_SWAP
;
2203 /* disable VAP/TCL on non-TCL capable chips */
2205 r300
->hw
.vap_cntl_status
.cmd
[1] |= R300_VAP_TCL_BYPASS
;
2207 r300
->hw
.vap_psc_sgn_norm_cntl
.cmd
[1] = 0xAAAAAAAA;
2209 /* XXX: Other families? */
2211 r300
->hw
.vap_clip_cntl
.cmd
[1] = R300_PS_UCP_MODE_DIST_COP
;
2213 r300
->hw
.vap_clip
.cmd
[1] = r300PackFloat32(1.0); /* X */
2214 r300
->hw
.vap_clip
.cmd
[2] = r300PackFloat32(1.0); /* X */
2215 r300
->hw
.vap_clip
.cmd
[3] = r300PackFloat32(1.0); /* Y */
2216 r300
->hw
.vap_clip
.cmd
[4] = r300PackFloat32(1.0); /* Y */
2218 switch (r300
->radeon
.radeonScreen
->chip_family
) {
2219 case CHIP_FAMILY_R300
:
2220 r300
->hw
.vap_pvs_vtx_timeout_reg
.cmd
[1] = R300_2288_R300
;
2223 r300
->hw
.vap_pvs_vtx_timeout_reg
.cmd
[1] = R300_2288_RV350
;
2228 r300
->hw
.gb_enable
.cmd
[1] = R300_GB_POINT_STUFF_ENABLE
2229 | R300_GB_LINE_STUFF_ENABLE
2230 | R300_GB_TRIANGLE_STUFF_ENABLE
;
2232 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_0
] = 0x66666666;
2233 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_1
] = 0x06666666;
2235 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] =
2236 R300_GB_TILE_ENABLE
| R300_GB_TILE_SIZE_16
/*| R300_GB_SUBPIXEL_1_16*/;
2237 switch (r300
->radeon
.radeonScreen
->num_gb_pipes
) {
2240 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2241 R300_GB_TILE_PIPE_COUNT_RV300
;
2244 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2245 R300_GB_TILE_PIPE_COUNT_R300
;
2248 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2249 R300_GB_TILE_PIPE_COUNT_R420_3P
;
2252 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2253 R300_GB_TILE_PIPE_COUNT_R420
;
2257 /* XXX: set to 0 when fog is disabled? */
2258 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_SELECT
] = R300_GB_FOG_SELECT_1_1_W
;
2260 /* XXX: Enable anti-aliasing? */
2261 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_AA_CONFIG
] = GB_AA_CONFIG_AA_DISABLE
;
2263 r300
->hw
.ga_point_s0
.cmd
[1] = r300PackFloat32(0.0);
2264 r300
->hw
.ga_point_s0
.cmd
[2] = r300PackFloat32(0.0);
2265 r300
->hw
.ga_point_s0
.cmd
[3] = r300PackFloat32(1.0);
2266 r300
->hw
.ga_point_s0
.cmd
[4] = r300PackFloat32(1.0);
2268 r300
->hw
.ga_triangle_stipple
.cmd
[1] = 0x00050005;
2270 r300PointSize(ctx
, 1.0);
2272 r300
->hw
.ga_point_minmax
.cmd
[1] = 0x18000006;
2273 r300
->hw
.ga_point_minmax
.cmd
[2] = 0x00020006;
2274 r300
->hw
.ga_point_minmax
.cmd
[3] = r300PackFloat32(1.0 / 192.0);
2276 r300LineWidth(ctx
, 1.0);
2278 r300
->hw
.ga_line_stipple
.cmd
[1] = 0;
2279 r300
->hw
.ga_line_stipple
.cmd
[2] = r300PackFloat32(0.0);
2280 r300
->hw
.ga_line_stipple
.cmd
[3] = r300PackFloat32(1.0);
2282 r300ShadeModel(ctx
, ctx
->Light
.ShadeModel
);
2284 r300PolygonMode(ctx
, GL_FRONT
, ctx
->Polygon
.FrontMode
);
2285 r300PolygonMode(ctx
, GL_BACK
, ctx
->Polygon
.BackMode
);
2286 r300
->hw
.zbias_cntl
.cmd
[1] = 0x00000000;
2288 r300PolygonOffset(ctx
, ctx
->Polygon
.OffsetFactor
,
2289 ctx
->Polygon
.OffsetUnits
);
2290 r300Enable(ctx
, GL_POLYGON_OFFSET_POINT
, ctx
->Polygon
.OffsetPoint
);
2291 r300Enable(ctx
, GL_POLYGON_OFFSET_LINE
, ctx
->Polygon
.OffsetLine
);
2292 r300Enable(ctx
, GL_POLYGON_OFFSET_FILL
, ctx
->Polygon
.OffsetFill
);
2294 r300
->hw
.su_depth_scale
.cmd
[1] = 0x4B7FFFFF;
2295 r300
->hw
.su_depth_scale
.cmd
[2] = 0x00000000;
2297 r300
->hw
.sc_hyperz
.cmd
[1] = 0x0000001C;
2298 r300
->hw
.sc_hyperz
.cmd
[2] = 0x2DA49525;
2300 r300
->hw
.sc_screendoor
.cmd
[1] = 0x00FFFFFF;
2302 r300
->hw
.us_out_fmt
.cmd
[1] = R500_OUT_FMT_C4_8
|
2303 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2304 r300
->hw
.us_out_fmt
.cmd
[2] = R500_OUT_FMT_UNUSED
|
2305 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2306 r300
->hw
.us_out_fmt
.cmd
[3] = R500_OUT_FMT_UNUSED
|
2307 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2308 r300
->hw
.us_out_fmt
.cmd
[4] = R500_OUT_FMT_UNUSED
|
2309 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2310 r300
->hw
.us_out_fmt
.cmd
[5] = R300_W_FMT_W24
;
2312 r300Enable(ctx
, GL_FOG
, ctx
->Fog
.Enabled
);
2313 r300Fogfv(ctx
, GL_FOG_MODE
, NULL
);
2314 r300Fogfv(ctx
, GL_FOG_DENSITY
, &ctx
->Fog
.Density
);
2315 r300Fogfv(ctx
, GL_FOG_START
, &ctx
->Fog
.Start
);
2316 r300Fogfv(ctx
, GL_FOG_END
, &ctx
->Fog
.End
);
2317 r300Fogfv(ctx
, GL_FOG_COLOR
, ctx
->Fog
.Color
);
2318 r300Fogfv(ctx
, GL_FOG_COORDINATE_SOURCE_EXT
, NULL
);
2320 r300
->hw
.fg_depth_src
.cmd
[1] = 0;
2322 r300
->hw
.rb3d_cctl
.cmd
[1] = 0;
2324 r300BlendColor(ctx
, ctx
->Color
.BlendColor
);
2326 /* Again, r300ClearBuffer uses this */
2327 r300
->hw
.cb
.cmd
[R300_CB_OFFSET
] =
2328 r300
->radeon
.state
.color
.drawOffset
+
2329 r300
->radeon
.radeonScreen
->fbLocation
;
2330 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] = r300
->radeon
.state
.color
.drawPitch
;
2332 if (r300
->radeon
.radeonScreen
->cpp
== 4)
2333 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_ARGB8888
;
2335 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_RGB565
;
2337 if (r300
->radeon
.sarea
->tiling_enabled
)
2338 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_TILE_ENABLE
;
2340 r300
->hw
.rb3d_dither_ctl
.cmd
[1] = 0;
2341 r300
->hw
.rb3d_dither_ctl
.cmd
[2] = 0;
2342 r300
->hw
.rb3d_dither_ctl
.cmd
[3] = 0;
2343 r300
->hw
.rb3d_dither_ctl
.cmd
[4] = 0;
2344 r300
->hw
.rb3d_dither_ctl
.cmd
[5] = 0;
2345 r300
->hw
.rb3d_dither_ctl
.cmd
[6] = 0;
2346 r300
->hw
.rb3d_dither_ctl
.cmd
[7] = 0;
2347 r300
->hw
.rb3d_dither_ctl
.cmd
[8] = 0;
2348 r300
->hw
.rb3d_dither_ctl
.cmd
[9] = 0;
2350 r300
->hw
.rb3d_aaresolve_ctl
.cmd
[1] = 0;
2352 r300
->hw
.rb3d_discard_src_pixel_lte_threshold
.cmd
[1] = 0x00000000;
2353 r300
->hw
.rb3d_discard_src_pixel_lte_threshold
.cmd
[2] = 0xffffffff;
2355 r300
->hw
.zb
.cmd
[R300_ZB_OFFSET
] =
2356 r300
->radeon
.radeonScreen
->depthOffset
+
2357 r300
->radeon
.radeonScreen
->fbLocation
;
2358 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] = r300
->radeon
.radeonScreen
->depthPitch
;
2360 if (r300
->radeon
.sarea
->tiling_enabled
) {
2361 /* XXX: Turn off when clearing buffers ? */
2362 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] |= R300_DEPTHMACROTILE_ENABLE
;
2364 if (ctx
->Visual
.depthBits
== 24)
2365 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] |=
2366 R300_DEPTHMICROTILE_TILED
;
2369 r300
->hw
.zb_depthclearvalue
.cmd
[1] = 0;
2371 switch (ctx
->Visual
.depthBits
) {
2373 r300
->hw
.zstencil_format
.cmd
[1] = R300_DEPTHFORMAT_16BIT_INT_Z
;
2376 r300
->hw
.zstencil_format
.cmd
[1] = R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL
;
2379 fprintf(stderr
, "Error: Unsupported depth %d... exiting\n", ctx
->Visual
.depthBits
);
2383 r300
->hw
.zstencil_format
.cmd
[2] = R300_ZTOP_DISABLE
;
2384 r300
->hw
.zstencil_format
.cmd
[3] = 0x00000003;
2385 r300
->hw
.zstencil_format
.cmd
[4] = 0x00000000;
2386 r300SetEarlyZState(ctx
);
2388 r300
->hw
.unk4F30
.cmd
[1] = 0;
2389 r300
->hw
.unk4F30
.cmd
[2] = 0;
2391 r300
->hw
.zb_hiz_offset
.cmd
[1] = 0;
2393 r300
->hw
.zb_hiz_pitch
.cmd
[1] = 0;
2395 r300VapCntl(r300
, 0, 0, 0);
2397 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_0
] = 0;
2398 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_1
] = 0;
2399 r300
->hw
.vps
.cmd
[R300_VPS_POINTSIZE
] = r300PackFloat32(1.0);
2400 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_3
] = 0;
2403 r300
->hw
.all_dirty
= GL_TRUE
;
2406 void r300UpdateShaders(r300ContextPtr rmesa
)
2409 struct r300_vertex_program
*vp
;
2412 ctx
= rmesa
->radeon
.glCtx
;
2414 if (rmesa
->NewGLState
&& hw_tcl_on
) {
2415 rmesa
->NewGLState
= 0;
2417 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
2418 rmesa
->temp_attrib
[i
] =
2419 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
];
2420 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] =
2421 &rmesa
->dummy_attrib
[i
];
2424 _tnl_UpdateFixedFunctionProgram(ctx
);
2426 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
2427 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] =
2428 rmesa
->temp_attrib
[i
];
2431 r300SelectVertexShader(rmesa
);
2432 vp
= (struct r300_vertex_program
*)
2433 CURRENT_VERTEX_SHADER(ctx
);
2434 /*if (vp->translated == GL_FALSE)
2435 r300TranslateVertexShader(vp); */
2436 if (vp
->translated
== GL_FALSE
) {
2437 fprintf(stderr
, "Failing back to sw-tcl\n");
2438 hw_tcl_on
= future_hw_tcl_on
= 0;
2439 r300ResetHwState(rmesa
);
2441 r300UpdateStateParameters(ctx
, _NEW_PROGRAM
);
2445 r300UpdateStateParameters(ctx
, _NEW_PROGRAM
);
2448 static void r300SetupPixelShader(r300ContextPtr rmesa
)
2450 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
2451 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
2452 (char *)ctx
->FragmentProgram
._Current
;
2453 struct r300_fragment_program_code
*code
;
2456 if (!fp
) /* should only happenen once, just after context is created */
2459 r300TranslateFragmentShader(rmesa
, fp
);
2460 if (!fp
->translated
) {
2461 fprintf(stderr
, "%s: No valid fragment shader, exiting\n",
2467 r300SetupTextures(ctx
);
2469 R300_STATECHANGE(rmesa
, fpi
[0]);
2470 rmesa
->hw
.fpi
[0].cmd
[R300_FPI_CMD_0
] = cmdpacket0(R300_US_ALU_RGB_INST_0
, code
->alu_end
+ 1);
2471 for (i
= 0; i
<= code
->alu_end
; i
++) {
2472 rmesa
->hw
.fpi
[0].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst0
;
2475 R300_STATECHANGE(rmesa
, fpi
[1]);
2476 rmesa
->hw
.fpi
[1].cmd
[R300_FPI_CMD_0
] = cmdpacket0(R300_US_ALU_RGB_ADDR_0
, code
->alu_end
+ 1);
2477 for (i
= 0; i
<= code
->alu_end
; i
++) {
2478 rmesa
->hw
.fpi
[1].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst1
;
2481 R300_STATECHANGE(rmesa
, fpi
[2]);
2482 rmesa
->hw
.fpi
[2].cmd
[R300_FPI_CMD_0
] = cmdpacket0(R300_US_ALU_ALPHA_INST_0
, code
->alu_end
+ 1);
2483 for (i
= 0; i
<= code
->alu_end
; i
++) {
2484 rmesa
->hw
.fpi
[2].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst2
;
2487 R300_STATECHANGE(rmesa
, fpi
[3]);
2488 rmesa
->hw
.fpi
[3].cmd
[R300_FPI_CMD_0
] = cmdpacket0(R300_US_ALU_ALPHA_ADDR_0
, code
->alu_end
+ 1);
2489 for (i
= 0; i
<= code
->alu_end
; i
++) {
2490 rmesa
->hw
.fpi
[3].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst3
;
2493 R300_STATECHANGE(rmesa
, fp
);
2494 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL0
] = code
->cur_node
| (code
->first_node_has_tex
<< 3);
2495 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL1
] = code
->max_temp_idx
;
2496 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL2
] =
2497 (code
->alu_offset
<< R300_PFS_CNTL_ALU_OFFSET_SHIFT
) |
2498 (code
->alu_end
<< R300_PFS_CNTL_ALU_END_SHIFT
) |
2499 (code
->tex_offset
<< R300_PFS_CNTL_TEX_OFFSET_SHIFT
) |
2500 (code
->tex_end
<< R300_PFS_CNTL_TEX_END_SHIFT
);
2501 /* I just want to say, the way these nodes are stored.. weird.. */
2502 for (i
= 0, k
= (4 - (code
->cur_node
+ 1)); i
< 4; i
++, k
++) {
2503 if (i
< (code
->cur_node
+ 1)) {
2504 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+ k
] =
2505 (code
->node
[i
].alu_offset
<< R300_ALU_START_SHIFT
) |
2506 (code
->node
[i
].alu_end
<< R300_ALU_SIZE_SHIFT
) |
2507 (code
->node
[i
].tex_offset
<< R300_TEX_START_SHIFT
) |
2508 (code
->node
[i
].tex_end
<< R300_TEX_SIZE_SHIFT
) |
2509 code
->node
[i
].flags
;
2511 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+ (3 - i
)] = 0;
2515 R300_STATECHANGE(rmesa
, fpp
);
2516 rmesa
->hw
.fpp
.cmd
[R300_FPP_CMD_0
] = cmdpacket0(R300_PFS_PARAM_0_X
, code
->const_nr
* 4);
2517 for (i
= 0; i
< code
->const_nr
; i
++) {
2518 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 0] = r300PackFloat24(code
->constant
[i
][0]);
2519 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 1] = r300PackFloat24(code
->constant
[i
][1]);
2520 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 2] = r300PackFloat24(code
->constant
[i
][2]);
2521 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 3] = r300PackFloat24(code
->constant
[i
][3]);
2525 #define bump_r500fp_count(ptr, new_count) do{\
2526 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
2527 int _nc=(new_count)/6; \
2528 assert(_nc < 256); \
2529 if(_nc>_p->r500fp.count)_p->r500fp.count=_nc;\
2532 #define bump_r500fp_const_count(ptr, new_count) do{\
2533 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
2534 int _nc=(new_count)/4; \
2535 assert(_nc < 256); \
2536 if(_nc>_p->r500fp.count)_p->r500fp.count=_nc;\
2539 static void r500SetupPixelShader(r300ContextPtr rmesa
)
2541 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
2542 struct r500_fragment_program
*fp
= (struct r500_fragment_program
*)
2543 (char *)ctx
->FragmentProgram
._Current
;
2545 struct r500_fragment_program_code
*code
;
2547 if (!fp
) /* should only happenen once, just after context is created */
2550 ((drm_r300_cmd_header_t
*) rmesa
->hw
.r500fp
.cmd
)->r500fp
.count
= 0;
2551 ((drm_r300_cmd_header_t
*) rmesa
->hw
.r500fp_const
.cmd
)->r500fp
.count
= 0;
2553 r500TranslateFragmentShader(rmesa
, fp
);
2554 if (!fp
->translated
) {
2555 fprintf(stderr
, "%s: No valid fragment shader, exiting\n",
2561 r300SetupTextures(ctx
);
2563 R300_STATECHANGE(rmesa
, fp
);
2564 rmesa
->hw
.fp
.cmd
[R500_FP_PIXSIZE
] = code
->max_temp_idx
;
2566 rmesa
->hw
.fp
.cmd
[R500_FP_CODE_ADDR
] =
2567 R500_US_CODE_START_ADDR(code
->inst_offset
) |
2568 R500_US_CODE_END_ADDR(code
->inst_end
);
2569 rmesa
->hw
.fp
.cmd
[R500_FP_CODE_RANGE
] =
2570 R500_US_CODE_RANGE_ADDR(code
->inst_offset
) |
2571 R500_US_CODE_RANGE_SIZE(code
->inst_end
);
2572 rmesa
->hw
.fp
.cmd
[R500_FP_CODE_OFFSET
] =
2573 R500_US_CODE_OFFSET_ADDR(0); /* FIXME when we add flow control */
2575 R300_STATECHANGE(rmesa
, r500fp
);
2576 /* Emit our shader... */
2577 for (i
= 0; i
< code
->inst_end
+1; i
++) {
2578 rmesa
->hw
.r500fp
.cmd
[i
*6+1] = code
->inst
[i
].inst0
;
2579 rmesa
->hw
.r500fp
.cmd
[i
*6+2] = code
->inst
[i
].inst1
;
2580 rmesa
->hw
.r500fp
.cmd
[i
*6+3] = code
->inst
[i
].inst2
;
2581 rmesa
->hw
.r500fp
.cmd
[i
*6+4] = code
->inst
[i
].inst3
;
2582 rmesa
->hw
.r500fp
.cmd
[i
*6+5] = code
->inst
[i
].inst4
;
2583 rmesa
->hw
.r500fp
.cmd
[i
*6+6] = code
->inst
[i
].inst5
;
2586 bump_r500fp_count(rmesa
->hw
.r500fp
.cmd
, (code
->inst_end
+ 1) * 6);
2588 R300_STATECHANGE(rmesa
, r500fp_const
);
2589 for (i
= 0; i
< code
->const_nr
; i
++) {
2590 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 0] = r300PackFloat32(code
->constant
[i
][0]);
2591 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 1] = r300PackFloat32(code
->constant
[i
][1]);
2592 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 2] = r300PackFloat32(code
->constant
[i
][2]);
2593 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 3] = r300PackFloat32(code
->constant
[i
][3]);
2595 bump_r500fp_const_count(rmesa
->hw
.r500fp_const
.cmd
, code
->const_nr
* 4);
2599 void r300UpdateShaderStates(r300ContextPtr rmesa
)
2602 ctx
= rmesa
->radeon
.glCtx
;
2604 r300UpdateTextureState(ctx
);
2605 r300SetEarlyZState(ctx
);
2607 GLuint fgdepthsrc
= R300_FG_DEPTH_SRC_SCAN
;
2608 if (current_fragment_program_writes_depth(ctx
))
2609 fgdepthsrc
= R300_FG_DEPTH_SRC_SHADER
;
2610 if (fgdepthsrc
!= rmesa
->hw
.fg_depth_src
.cmd
[1]) {
2611 R300_STATECHANGE(rmesa
, fg_depth_src
);
2612 rmesa
->hw
.fg_depth_src
.cmd
[1] = fgdepthsrc
;
2615 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
2616 r500SetupPixelShader(rmesa
);
2618 r300SetupPixelShader(rmesa
);
2620 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
2621 r500SetupRSUnit(ctx
);
2623 r300SetupRSUnit(ctx
);
2625 if ((rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
2626 r300SetupVertexProgram(rmesa
);
2631 * Called by Mesa after an internal state update.
2633 static void r300InvalidateState(GLcontext
* ctx
, GLuint new_state
)
2635 r300ContextPtr r300
= R300_CONTEXT(ctx
);
2637 _swrast_InvalidateState(ctx
, new_state
);
2638 _swsetup_InvalidateState(ctx
, new_state
);
2639 _vbo_InvalidateState(ctx
, new_state
);
2640 _tnl_InvalidateState(ctx
, new_state
);
2641 _ae_invalidate_state(ctx
, new_state
);
2643 if (new_state
& (_NEW_BUFFERS
| _NEW_COLOR
| _NEW_PIXEL
)) {
2644 r300UpdateDrawBuffer(ctx
);
2647 r300UpdateStateParameters(ctx
, new_state
);
2649 r300
->NewGLState
|= new_state
;
2653 * Calculate initial hardware state and register state functions.
2654 * Assumes that the command buffer and state atoms have been
2655 * initialized already.
2657 void r300InitState(r300ContextPtr r300
)
2659 GLcontext
*ctx
= r300
->radeon
.glCtx
;
2662 radeonInitState(&r300
->radeon
);
2664 switch (ctx
->Visual
.depthBits
) {
2666 r300
->state
.depth
.scale
= 1.0 / (GLfloat
) 0xffff;
2667 depth_fmt
= R300_DEPTHFORMAT_16BIT_INT_Z
;
2670 r300
->state
.depth
.scale
= 1.0 / (GLfloat
) 0xffffff;
2671 depth_fmt
= R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL
;
2674 fprintf(stderr
, "Error: Unsupported depth %d... exiting\n",
2675 ctx
->Visual
.depthBits
);
2679 /* Only have hw stencil when depth buffer is 24 bits deep */
2680 r300
->state
.stencil
.hw_stencil
= (ctx
->Visual
.stencilBits
> 0 &&
2681 ctx
->Visual
.depthBits
== 24);
2683 memset(&(r300
->state
.texture
), 0, sizeof(r300
->state
.texture
));
2685 r300ResetHwState(r300
);
2688 static void r300RenderMode(GLcontext
* ctx
, GLenum mode
)
2690 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
2695 void r300UpdateClipPlanes( GLcontext
*ctx
)
2697 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
2700 for (p
= 0; p
< ctx
->Const
.MaxClipPlanes
; p
++) {
2701 if (ctx
->Transform
.ClipPlanesEnabled
& (1 << p
)) {
2702 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
2704 R300_STATECHANGE( rmesa
, vpucp
[p
] );
2705 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_X
] = ip
[0];
2706 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_Y
] = ip
[1];
2707 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_Z
] = ip
[2];
2708 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_W
] = ip
[3];
2714 * Initialize driver's state callback functions
2716 void r300InitStateFuncs(struct dd_function_table
*functions
)
2718 radeonInitStateFuncs(functions
);
2720 functions
->UpdateState
= r300InvalidateState
;
2721 functions
->AlphaFunc
= r300AlphaFunc
;
2722 functions
->BlendColor
= r300BlendColor
;
2723 functions
->BlendEquationSeparate
= r300BlendEquationSeparate
;
2724 functions
->BlendFuncSeparate
= r300BlendFuncSeparate
;
2725 functions
->Enable
= r300Enable
;
2726 functions
->ColorMask
= r300ColorMask
;
2727 functions
->DepthFunc
= r300DepthFunc
;
2728 functions
->DepthMask
= r300DepthMask
;
2729 functions
->CullFace
= r300CullFace
;
2730 functions
->Fogfv
= r300Fogfv
;
2731 functions
->FrontFace
= r300FrontFace
;
2732 functions
->ShadeModel
= r300ShadeModel
;
2734 /* ARB_point_parameters */
2735 functions
->PointParameterfv
= r300PointParameter
;
2737 /* Stencil related */
2738 functions
->StencilFuncSeparate
= r300StencilFuncSeparate
;
2739 functions
->StencilMaskSeparate
= r300StencilMaskSeparate
;
2740 functions
->StencilOpSeparate
= r300StencilOpSeparate
;
2742 /* Viewport related */
2743 functions
->Viewport
= r300Viewport
;
2744 functions
->DepthRange
= r300DepthRange
;
2745 functions
->PointSize
= r300PointSize
;
2746 functions
->LineWidth
= r300LineWidth
;
2748 functions
->PolygonOffset
= r300PolygonOffset
;
2749 functions
->PolygonMode
= r300PolygonMode
;
2751 functions
->RenderMode
= r300RenderMode
;
2753 functions
->ClipPlane
= r300ClipPlane
;