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>
38 #include "main/glheader.h"
39 #include "main/state.h"
40 #include "main/imports.h"
41 #include "main/enums.h"
42 #include "main/macros.h"
43 #include "main/context.h"
45 #include "main/simple_list.h"
46 #include "main/api_arrayelt.h"
47 #include "main/texformat.h"
49 #include "swrast/swrast.h"
50 #include "swrast_setup/swrast_setup.h"
51 #include "shader/prog_parameter.h"
52 #include "shader/prog_statevars.h"
56 #include "radeon_ioctl.h"
57 #include "radeon_state.h"
58 #include "radeon_buffer.h"
59 #include "r300_context.h"
60 #include "r300_ioctl.h"
61 #include "r300_state.h"
63 #include "r300_emit.h"
64 #include "r300_fragprog.h"
67 #include "drirenderbuffer.h"
69 extern int future_hw_tcl_on
;
70 extern void _tnl_UpdateFixedFunctionProgram(GLcontext
* ctx
);
72 static void r300BlendColor(GLcontext
* ctx
, const GLfloat cf
[4])
74 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
76 R300_STATECHANGE(rmesa
, blend_color
);
78 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
) {
79 GLuint r
= IROUND(cf
[0]*1023.0f
);
80 GLuint g
= IROUND(cf
[1]*1023.0f
);
81 GLuint b
= IROUND(cf
[2]*1023.0f
);
82 GLuint a
= IROUND(cf
[3]*1023.0f
);
84 rmesa
->hw
.blend_color
.cmd
[1] = r
| (a
<< 16);
85 rmesa
->hw
.blend_color
.cmd
[2] = b
| (g
<< 16);
88 CLAMPED_FLOAT_TO_UBYTE(color
[0], cf
[0]);
89 CLAMPED_FLOAT_TO_UBYTE(color
[1], cf
[1]);
90 CLAMPED_FLOAT_TO_UBYTE(color
[2], cf
[2]);
91 CLAMPED_FLOAT_TO_UBYTE(color
[3], cf
[3]);
93 rmesa
->hw
.blend_color
.cmd
[1] = PACK_COLOR_8888(color
[3], color
[0],
99 * Calculate the hardware blend factor setting. This same function is used
100 * for source and destination of both alpha and RGB.
103 * The hardware register value for the specified blend factor. This value
104 * will need to be shifted into the correct position for either source or
105 * destination factor.
108 * Since the two cases where source and destination are handled differently
109 * are essentially error cases, they should never happen. Determine if these
110 * cases can be removed.
112 static int blend_factor(GLenum factor
, GLboolean is_src
)
116 return R300_BLEND_GL_ZERO
;
119 return R300_BLEND_GL_ONE
;
122 return R300_BLEND_GL_DST_COLOR
;
124 case GL_ONE_MINUS_DST_COLOR
:
125 return R300_BLEND_GL_ONE_MINUS_DST_COLOR
;
128 return R300_BLEND_GL_SRC_COLOR
;
130 case GL_ONE_MINUS_SRC_COLOR
:
131 return R300_BLEND_GL_ONE_MINUS_SRC_COLOR
;
134 return R300_BLEND_GL_SRC_ALPHA
;
136 case GL_ONE_MINUS_SRC_ALPHA
:
137 return R300_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
140 return R300_BLEND_GL_DST_ALPHA
;
142 case GL_ONE_MINUS_DST_ALPHA
:
143 return R300_BLEND_GL_ONE_MINUS_DST_ALPHA
;
145 case GL_SRC_ALPHA_SATURATE
:
146 return (is_src
) ? R300_BLEND_GL_SRC_ALPHA_SATURATE
:
149 case GL_CONSTANT_COLOR
:
150 return R300_BLEND_GL_CONST_COLOR
;
152 case GL_ONE_MINUS_CONSTANT_COLOR
:
153 return R300_BLEND_GL_ONE_MINUS_CONST_COLOR
;
155 case GL_CONSTANT_ALPHA
:
156 return R300_BLEND_GL_CONST_ALPHA
;
158 case GL_ONE_MINUS_CONSTANT_ALPHA
:
159 return R300_BLEND_GL_ONE_MINUS_CONST_ALPHA
;
162 fprintf(stderr
, "unknown blend factor %x\n", factor
);
163 return (is_src
) ? R300_BLEND_GL_ONE
: R300_BLEND_GL_ZERO
;
169 * Sets both the blend equation and the blend function.
170 * This is done in a single
171 * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX)
172 * change the interpretation of the blend function.
173 * Also, make sure that blend function and blend equation are set to their
174 * default value if color blending is not enabled, since at least blend
175 * equations GL_MIN and GL_FUNC_REVERSE_SUBTRACT will cause wrong results
176 * otherwise for unknown reasons.
179 /* helper function */
180 static void r300SetBlendCntl(r300ContextPtr r300
, int func
, int eqn
,
181 int cbits
, int funcA
, int eqnA
)
183 GLuint new_ablend
, new_cblend
;
187 "eqnA=%08x funcA=%08x eqn=%08x func=%08x cbits=%08x\n",
188 eqnA
, funcA
, eqn
, func
, cbits
);
190 new_ablend
= eqnA
| funcA
;
191 new_cblend
= eqn
| func
;
193 /* Some blend factor combinations don't seem to work when the
194 * BLEND_NO_SEPARATE bit is set.
196 * Especially problematic candidates are the ONE_MINUS_* flags,
197 * but I can't see a real pattern.
200 if (new_ablend
== new_cblend
) {
201 new_cblend
|= R300_DISCARD_SRC_PIXELS_SRC_ALPHA_0
;
206 if ((new_ablend
!= r300
->hw
.bld
.cmd
[R300_BLD_ABLEND
]) ||
207 (new_cblend
!= r300
->hw
.bld
.cmd
[R300_BLD_CBLEND
])) {
208 R300_STATECHANGE(r300
, bld
);
209 r300
->hw
.bld
.cmd
[R300_BLD_ABLEND
] = new_ablend
;
210 r300
->hw
.bld
.cmd
[R300_BLD_CBLEND
] = new_cblend
;
214 static void r300SetBlendState(GLcontext
* ctx
)
216 r300ContextPtr r300
= R300_CONTEXT(ctx
);
217 int func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
218 (R300_BLEND_GL_ZERO
<< R300_DST_BLEND_SHIFT
);
219 int eqn
= R300_COMB_FCN_ADD_CLAMP
;
220 int funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
221 (R300_BLEND_GL_ZERO
<< R300_DST_BLEND_SHIFT
);
222 int eqnA
= R300_COMB_FCN_ADD_CLAMP
;
224 if (RGBA_LOGICOP_ENABLED(ctx
) || !ctx
->Color
.BlendEnabled
) {
225 r300SetBlendCntl(r300
, func
, eqn
, 0, func
, eqn
);
230 (blend_factor(ctx
->Color
.BlendSrcRGB
, GL_TRUE
) <<
231 R300_SRC_BLEND_SHIFT
) | (blend_factor(ctx
->Color
.BlendDstRGB
,
233 R300_DST_BLEND_SHIFT
);
235 switch (ctx
->Color
.BlendEquationRGB
) {
237 eqn
= R300_COMB_FCN_ADD_CLAMP
;
240 case GL_FUNC_SUBTRACT
:
241 eqn
= R300_COMB_FCN_SUB_CLAMP
;
244 case GL_FUNC_REVERSE_SUBTRACT
:
245 eqn
= R300_COMB_FCN_RSUB_CLAMP
;
249 eqn
= R300_COMB_FCN_MIN
;
250 func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
251 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
255 eqn
= R300_COMB_FCN_MAX
;
256 func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
257 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
262 "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
263 __FUNCTION__
, __LINE__
, ctx
->Color
.BlendEquationRGB
);
268 (blend_factor(ctx
->Color
.BlendSrcA
, GL_TRUE
) <<
269 R300_SRC_BLEND_SHIFT
) | (blend_factor(ctx
->Color
.BlendDstA
,
271 R300_DST_BLEND_SHIFT
);
273 switch (ctx
->Color
.BlendEquationA
) {
275 eqnA
= R300_COMB_FCN_ADD_CLAMP
;
278 case GL_FUNC_SUBTRACT
:
279 eqnA
= R300_COMB_FCN_SUB_CLAMP
;
282 case GL_FUNC_REVERSE_SUBTRACT
:
283 eqnA
= R300_COMB_FCN_RSUB_CLAMP
;
287 eqnA
= R300_COMB_FCN_MIN
;
288 funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
289 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
293 eqnA
= R300_COMB_FCN_MAX
;
294 funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
295 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
300 "[%s:%u] Invalid A blend equation (0x%04x).\n",
301 __FUNCTION__
, __LINE__
, ctx
->Color
.BlendEquationA
);
305 r300SetBlendCntl(r300
,
307 (R300_SEPARATE_ALPHA_ENABLE
|
309 R300_ALPHA_BLEND_ENABLE
), funcA
, eqnA
);
312 static void r300BlendEquationSeparate(GLcontext
* ctx
,
313 GLenum modeRGB
, GLenum modeA
)
315 r300SetBlendState(ctx
);
318 static void r300BlendFuncSeparate(GLcontext
* ctx
,
319 GLenum sfactorRGB
, GLenum dfactorRGB
,
320 GLenum sfactorA
, GLenum dfactorA
)
322 r300SetBlendState(ctx
);
326 * Translate LogicOp enums into hardware representation.
327 * Both use a very logical bit-wise layout, but unfortunately the order
328 * of bits is reversed.
330 static GLuint
translate_logicop(GLenum logicop
)
332 GLuint bits
= logicop
- GL_CLEAR
;
333 bits
= ((bits
& 1) << 3) | ((bits
& 2) << 1) | ((bits
& 4) >> 1) | ((bits
& 8) >> 3);
334 return bits
<< R300_RB3D_ROPCNTL_ROP_SHIFT
;
338 * Used internally to update the r300->hw hardware state to match the
339 * current OpenGL state.
341 static void r300SetLogicOpState(GLcontext
*ctx
)
343 r300ContextPtr r300
= R300_CONTEXT(ctx
);
344 R300_STATECHANGE(r300
, rop
);
345 if (RGBA_LOGICOP_ENABLED(ctx
)) {
346 r300
->hw
.rop
.cmd
[1] = R300_RB3D_ROPCNTL_ROP_ENABLE
|
347 translate_logicop(ctx
->Color
.LogicOp
);
349 r300
->hw
.rop
.cmd
[1] = 0;
354 * Called by Mesa when an application program changes the LogicOp state
357 static void r300LogicOpcode(GLcontext
*ctx
, GLenum logicop
)
359 if (RGBA_LOGICOP_ENABLED(ctx
))
360 r300SetLogicOpState(ctx
);
363 static void r300ClipPlane( GLcontext
*ctx
, GLenum plane
, const GLfloat
*eq
)
365 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
369 /* no VAP UCP on non-TCL chipsets */
370 if (!(rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
373 p
= (GLint
) plane
- (GLint
) GL_CLIP_PLANE0
;
374 ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
376 R300_STATECHANGE( rmesa
, vpucp
[p
] );
377 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_X
] = ip
[0];
378 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_Y
] = ip
[1];
379 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_Z
] = ip
[2];
380 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_W
] = ip
[3];
383 static void r300SetClipPlaneState(GLcontext
* ctx
, GLenum cap
, GLboolean state
)
385 r300ContextPtr r300
= R300_CONTEXT(ctx
);
388 /* no VAP UCP on non-TCL chipsets */
389 if (!(r300
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
392 p
= cap
- GL_CLIP_PLANE0
;
393 R300_STATECHANGE(r300
, vap_clip_cntl
);
395 r300
->hw
.vap_clip_cntl
.cmd
[1] |= (R300_VAP_UCP_ENABLE_0
<< p
);
396 r300ClipPlane(ctx
, cap
, NULL
);
398 r300
->hw
.vap_clip_cntl
.cmd
[1] &= ~(R300_VAP_UCP_ENABLE_0
<< p
);
403 * Update our tracked culling state based on Mesa's state.
405 static void r300UpdateCulling(GLcontext
* ctx
)
407 r300ContextPtr r300
= R300_CONTEXT(ctx
);
410 if (ctx
->Polygon
.CullFlag
) {
411 switch (ctx
->Polygon
.CullFaceMode
) {
413 val
= R300_CULL_FRONT
;
416 val
= R300_CULL_BACK
;
418 case GL_FRONT_AND_BACK
:
419 val
= R300_CULL_FRONT
| R300_CULL_BACK
;
426 switch (ctx
->Polygon
.FrontFace
) {
428 val
|= R300_FRONT_FACE_CW
;
431 val
|= R300_FRONT_FACE_CCW
;
437 R300_STATECHANGE(r300
, cul
);
438 r300
->hw
.cul
.cmd
[R300_CUL_CULL
] = val
;
441 static void r300SetPolygonOffsetState(GLcontext
* ctx
, GLboolean state
)
443 r300ContextPtr r300
= R300_CONTEXT(ctx
);
445 R300_STATECHANGE(r300
, occlusion_cntl
);
447 r300
->hw
.occlusion_cntl
.cmd
[1] |= (3 << 0);
449 r300
->hw
.occlusion_cntl
.cmd
[1] &= ~(3 << 0);
453 static GLboolean
current_fragment_program_writes_depth(GLcontext
* ctx
)
455 r300ContextPtr r300
= R300_CONTEXT(ctx
);
457 if (r300
->radeon
.radeonScreen
->chip_family
< CHIP_FAMILY_RV515
) {
458 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
459 (char *)ctx
->FragmentProgram
._Current
;
460 return (fp
&& fp
->WritesDepth
);
462 struct r500_fragment_program
* fp
=
463 (struct r500_fragment_program
*)(char*)
464 ctx
->FragmentProgram
._Current
;
465 return (fp
&& fp
->writes_depth
);
469 static void r300SetEarlyZState(GLcontext
* ctx
)
471 r300ContextPtr r300
= R300_CONTEXT(ctx
);
472 GLuint topZ
= R300_ZTOP_ENABLE
;
474 if (ctx
->Color
.AlphaEnabled
&& ctx
->Color
.AlphaFunc
!= GL_ALWAYS
)
475 topZ
= R300_ZTOP_DISABLE
;
476 if (current_fragment_program_writes_depth(ctx
))
477 topZ
= R300_ZTOP_DISABLE
;
479 if (topZ
!= r300
->hw
.zstencil_format
.cmd
[2]) {
480 /* Note: This completely reemits the stencil format.
481 * I have not tested whether this is strictly necessary,
482 * or if emitting a write to ZB_ZTOP is enough.
484 R300_STATECHANGE(r300
, zstencil_format
);
485 r300
->hw
.zstencil_format
.cmd
[2] = topZ
;
489 static void r300SetAlphaState(GLcontext
* ctx
)
491 r300ContextPtr r300
= R300_CONTEXT(ctx
);
493 uint32_t pp_misc
= 0x0;
494 GLboolean really_enabled
= ctx
->Color
.AlphaEnabled
;
496 CLAMPED_FLOAT_TO_UBYTE(refByte
, ctx
->Color
.AlphaRef
);
498 switch (ctx
->Color
.AlphaFunc
) {
500 pp_misc
|= R300_FG_ALPHA_FUNC_NEVER
;
503 pp_misc
|= R300_FG_ALPHA_FUNC_LESS
;
506 pp_misc
|= R300_FG_ALPHA_FUNC_EQUAL
;
509 pp_misc
|= R300_FG_ALPHA_FUNC_LE
;
512 pp_misc
|= R300_FG_ALPHA_FUNC_GREATER
;
515 pp_misc
|= R300_FG_ALPHA_FUNC_NOTEQUAL
;
518 pp_misc
|= R300_FG_ALPHA_FUNC_GE
;
521 /*pp_misc |= FG_ALPHA_FUNC_ALWAYS; */
522 really_enabled
= GL_FALSE
;
526 if (really_enabled
) {
527 pp_misc
|= R300_FG_ALPHA_FUNC_ENABLE
;
528 pp_misc
|= R500_FG_ALPHA_FUNC_8BIT
;
529 pp_misc
|= (refByte
& R300_FG_ALPHA_FUNC_VAL_MASK
);
534 R300_STATECHANGE(r300
, at
);
535 r300
->hw
.at
.cmd
[R300_AT_ALPHA_TEST
] = pp_misc
;
536 r300
->hw
.at
.cmd
[R300_AT_UNKNOWN
] = 0;
538 r300SetEarlyZState(ctx
);
541 static void r300AlphaFunc(GLcontext
* ctx
, GLenum func
, GLfloat ref
)
545 r300SetAlphaState(ctx
);
548 static int translate_func(int func
)
552 return R300_ZS_NEVER
;
556 return R300_ZS_EQUAL
;
558 return R300_ZS_LEQUAL
;
560 return R300_ZS_GREATER
;
562 return R300_ZS_NOTEQUAL
;
564 return R300_ZS_GEQUAL
;
566 return R300_ZS_ALWAYS
;
571 static void r300SetDepthState(GLcontext
* ctx
)
573 r300ContextPtr r300
= R300_CONTEXT(ctx
);
575 R300_STATECHANGE(r300
, zs
);
576 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &= R300_STENCIL_ENABLE
|R300_STENCIL_FRONT_BACK
;
577 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= ~(R300_ZS_MASK
<< R300_Z_FUNC_SHIFT
);
579 if (ctx
->Depth
.Test
) {
580 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_Z_ENABLE
;
582 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_Z_WRITE_ENABLE
;
583 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
584 translate_func(ctx
->Depth
.Func
) << R300_Z_FUNC_SHIFT
;
587 r300SetEarlyZState(ctx
);
590 static void r300SetStencilState(GLcontext
* ctx
, GLboolean state
)
592 r300ContextPtr r300
= R300_CONTEXT(ctx
);
594 if (r300
->radeon
.state
.stencil
.hwBuffer
) {
595 R300_STATECHANGE(r300
, zs
);
597 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |=
600 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &=
601 ~R300_STENCIL_ENABLE
;
605 FALLBACK(&r300
->radeon
, RADEON_FALLBACK_STENCIL
, state
);
610 static void r300UpdatePolygonMode(GLcontext
* ctx
)
612 r300ContextPtr r300
= R300_CONTEXT(ctx
);
613 uint32_t hw_mode
= R300_GA_POLY_MODE_DISABLE
;
615 /* Only do something if a polygon mode is wanted, default is GL_FILL */
616 if (ctx
->Polygon
.FrontMode
!= GL_FILL
||
617 ctx
->Polygon
.BackMode
!= GL_FILL
) {
620 /* Handle GL_CW (clock wise and GL_CCW (counter clock wise)
621 * correctly by selecting the correct front and back face
623 if (ctx
->Polygon
.FrontFace
== GL_CCW
) {
624 f
= ctx
->Polygon
.FrontMode
;
625 b
= ctx
->Polygon
.BackMode
;
627 f
= ctx
->Polygon
.BackMode
;
628 b
= ctx
->Polygon
.FrontMode
;
631 /* Enable polygon mode */
632 hw_mode
|= R300_GA_POLY_MODE_DUAL
;
636 hw_mode
|= R300_GA_POLY_MODE_FRONT_PTYPE_LINE
;
639 hw_mode
|= R300_GA_POLY_MODE_FRONT_PTYPE_POINT
;
642 hw_mode
|= R300_GA_POLY_MODE_FRONT_PTYPE_TRI
;
648 hw_mode
|= R300_GA_POLY_MODE_BACK_PTYPE_LINE
;
651 hw_mode
|= R300_GA_POLY_MODE_BACK_PTYPE_POINT
;
654 hw_mode
|= R300_GA_POLY_MODE_BACK_PTYPE_TRI
;
659 if (r300
->hw
.polygon_mode
.cmd
[1] != hw_mode
) {
660 R300_STATECHANGE(r300
, polygon_mode
);
661 r300
->hw
.polygon_mode
.cmd
[1] = hw_mode
;
664 r300
->hw
.polygon_mode
.cmd
[2] = 0x00000001;
665 r300
->hw
.polygon_mode
.cmd
[3] = 0x00000000;
669 * Change the culling mode.
671 * \note Mesa already filters redundant calls to this function.
673 static void r300CullFace(GLcontext
* ctx
, GLenum mode
)
677 r300UpdateCulling(ctx
);
681 * Change the polygon orientation.
683 * \note Mesa already filters redundant calls to this function.
685 static void r300FrontFace(GLcontext
* ctx
, GLenum mode
)
689 r300UpdateCulling(ctx
);
690 r300UpdatePolygonMode(ctx
);
694 * Change the depth testing function.
696 * \note Mesa already filters redundant calls to this function.
698 static void r300DepthFunc(GLcontext
* ctx
, GLenum func
)
701 r300SetDepthState(ctx
);
705 * Enable/Disable depth writing.
707 * \note Mesa already filters redundant calls to this function.
709 static void r300DepthMask(GLcontext
* ctx
, GLboolean mask
)
712 r300SetDepthState(ctx
);
716 * Handle glColorMask()
718 static void r300ColorMask(GLcontext
* ctx
,
719 GLboolean r
, GLboolean g
, GLboolean b
, GLboolean a
)
721 r300ContextPtr r300
= R300_CONTEXT(ctx
);
722 int mask
= (r
? RB3D_COLOR_CHANNEL_MASK_RED_MASK0
: 0) |
723 (g
? RB3D_COLOR_CHANNEL_MASK_GREEN_MASK0
: 0) |
724 (b
? RB3D_COLOR_CHANNEL_MASK_BLUE_MASK0
: 0) |
725 (a
? RB3D_COLOR_CHANNEL_MASK_ALPHA_MASK0
: 0);
727 if (mask
!= r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
]) {
728 R300_STATECHANGE(r300
, cmk
);
729 r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
] = mask
;
733 /* =============================================================
736 static void r300Fogfv(GLcontext
* ctx
, GLenum pname
, const GLfloat
* param
)
738 r300ContextPtr r300
= R300_CONTEXT(ctx
);
742 } fogScale
, fogStart
;
746 fogScale
.i
= r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
];
747 fogStart
.i
= r300
->hw
.fogp
.cmd
[R300_FOGP_START
];
751 switch (ctx
->Fog
.Mode
) {
753 R300_STATECHANGE(r300
, fogs
);
754 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
756 cmd
[R300_FOGS_STATE
] & ~R300_FG_FOG_BLEND_FN_MASK
) |
757 R300_FG_FOG_BLEND_FN_LINEAR
;
759 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
764 1.0 / (ctx
->Fog
.End
- ctx
->Fog
.Start
);
766 -ctx
->Fog
.Start
/ (ctx
->Fog
.End
-
771 R300_STATECHANGE(r300
, fogs
);
772 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
774 cmd
[R300_FOGS_STATE
] & ~R300_FG_FOG_BLEND_FN_MASK
) |
775 R300_FG_FOG_BLEND_FN_EXP
;
776 fogScale
.f
= 0.0933 * ctx
->Fog
.Density
;
780 R300_STATECHANGE(r300
, fogs
);
781 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
783 cmd
[R300_FOGS_STATE
] & ~R300_FG_FOG_BLEND_FN_MASK
) |
784 R300_FG_FOG_BLEND_FN_EXP2
;
785 fogScale
.f
= 0.3 * ctx
->Fog
.Density
;
792 switch (ctx
->Fog
.Mode
) {
794 fogScale
.f
= 0.0933 * ctx
->Fog
.Density
;
798 fogScale
.f
= 0.3 * ctx
->Fog
.Density
;
806 if (ctx
->Fog
.Mode
== GL_LINEAR
) {
807 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
812 1.0 / (ctx
->Fog
.End
- ctx
->Fog
.Start
);
814 -ctx
->Fog
.Start
/ (ctx
->Fog
.End
-
820 R300_STATECHANGE(r300
, fogc
);
821 r300
->hw
.fogc
.cmd
[R300_FOGC_R
] =
822 (GLuint
) (ctx
->Fog
.Color
[0] * 1023.0F
) & 0x3FF;
823 r300
->hw
.fogc
.cmd
[R300_FOGC_G
] =
824 (GLuint
) (ctx
->Fog
.Color
[1] * 1023.0F
) & 0x3FF;
825 r300
->hw
.fogc
.cmd
[R300_FOGC_B
] =
826 (GLuint
) (ctx
->Fog
.Color
[2] * 1023.0F
) & 0x3FF;
828 case GL_FOG_COORD_SRC
:
834 if (fogScale
.i
!= r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
] ||
835 fogStart
.i
!= r300
->hw
.fogp
.cmd
[R300_FOGP_START
]) {
836 R300_STATECHANGE(r300
, fogp
);
837 r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
] = fogScale
.i
;
838 r300
->hw
.fogp
.cmd
[R300_FOGP_START
] = fogStart
.i
;
842 static void r300SetFogState(GLcontext
* ctx
, GLboolean state
)
844 r300ContextPtr r300
= R300_CONTEXT(ctx
);
846 R300_STATECHANGE(r300
, fogs
);
848 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] |= R300_FG_FOG_BLEND_ENABLE
;
850 r300Fogfv(ctx
, GL_FOG_MODE
, NULL
);
851 r300Fogfv(ctx
, GL_FOG_DENSITY
, &ctx
->Fog
.Density
);
852 r300Fogfv(ctx
, GL_FOG_START
, &ctx
->Fog
.Start
);
853 r300Fogfv(ctx
, GL_FOG_END
, &ctx
->Fog
.End
);
854 r300Fogfv(ctx
, GL_FOG_COLOR
, ctx
->Fog
.Color
);
856 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] &= ~R300_FG_FOG_BLEND_ENABLE
;
860 /* =============================================================
863 static void r300PointSize(GLcontext
* ctx
, GLfloat size
)
865 r300ContextPtr r300
= R300_CONTEXT(ctx
);
866 /* same size limits for AA, non-AA points */
867 size
= CLAMP(size
, ctx
->Const
.MinPointSize
, ctx
->Const
.MaxPointSize
);
869 R300_STATECHANGE(r300
, ps
);
870 r300
->hw
.ps
.cmd
[R300_PS_POINTSIZE
] =
871 ((int)(size
* 6) << R300_POINTSIZE_X_SHIFT
) |
872 ((int)(size
* 6) << R300_POINTSIZE_Y_SHIFT
);
875 static void r300PointParameter(GLcontext
* ctx
, GLenum pname
, const GLfloat
* param
)
877 r300ContextPtr r300
= R300_CONTEXT(ctx
);
880 case GL_POINT_SIZE_MIN
:
881 R300_STATECHANGE(r300
, ga_point_minmax
);
882 r300
->hw
.ga_point_minmax
.cmd
[1] &= ~R300_GA_POINT_MINMAX_MIN_MASK
;
883 r300
->hw
.ga_point_minmax
.cmd
[1] |= (GLuint
)(ctx
->Point
.MinSize
* 6.0);
885 case GL_POINT_SIZE_MAX
:
886 R300_STATECHANGE(r300
, ga_point_minmax
);
887 r300
->hw
.ga_point_minmax
.cmd
[1] &= ~R300_GA_POINT_MINMAX_MAX_MASK
;
888 r300
->hw
.ga_point_minmax
.cmd
[1] |= (GLuint
)(ctx
->Point
.MaxSize
* 6.0)
889 << R300_GA_POINT_MINMAX_MAX_SHIFT
;
891 case GL_POINT_DISTANCE_ATTENUATION
:
893 case GL_POINT_FADE_THRESHOLD_SIZE
:
900 /* =============================================================
903 static void r300LineWidth(GLcontext
* ctx
, GLfloat widthf
)
905 r300ContextPtr r300
= R300_CONTEXT(ctx
);
907 widthf
= CLAMP(widthf
,
908 ctx
->Const
.MinPointSize
,
909 ctx
->Const
.MaxPointSize
);
910 R300_STATECHANGE(r300
, lcntl
);
911 r300
->hw
.lcntl
.cmd
[1] =
912 R300_LINE_CNT_HO
| R300_LINE_CNT_VE
| (int)(widthf
* 6.0);
915 static void r300PolygonMode(GLcontext
* ctx
, GLenum face
, GLenum mode
)
920 r300UpdatePolygonMode(ctx
);
923 /* =============================================================
927 static int translate_stencil_op(int op
)
935 return R300_ZS_REPLACE
;
940 case GL_INCR_WRAP_EXT
:
941 return R300_ZS_INCR_WRAP
;
942 case GL_DECR_WRAP_EXT
:
943 return R300_ZS_DECR_WRAP
;
945 return R300_ZS_INVERT
;
947 WARN_ONCE("Do not know how to translate stencil op");
953 static void r300ShadeModel(GLcontext
* ctx
, GLenum mode
)
955 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
957 R300_STATECHANGE(rmesa
, shade
);
958 rmesa
->hw
.shade
.cmd
[1] = 0x00000002;
961 rmesa
->hw
.shade
.cmd
[2] = R300_RE_SHADE_MODEL_FLAT
;
964 rmesa
->hw
.shade
.cmd
[2] = R300_RE_SHADE_MODEL_SMOOTH
;
969 rmesa
->hw
.shade
.cmd
[3] = 0x00000000;
970 rmesa
->hw
.shade
.cmd
[4] = 0x00000000;
973 static void r300StencilFuncSeparate(GLcontext
* ctx
, GLenum face
,
974 GLenum func
, GLint ref
, GLuint mask
)
976 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
979 Ref
[0] & 0xff) << R300_STENCILREF_SHIFT
) | ((ctx
->
985 R300_STENCILMASK_SHIFT
));
989 R300_STATECHANGE(rmesa
, zs
);
990 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_STENCIL_FRONT_BACK
;
991 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= ~((R300_ZS_MASK
<<
992 R300_S_FRONT_FUNC_SHIFT
)
994 R300_S_BACK_FUNC_SHIFT
));
996 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &=
997 ~((R300_STENCILREF_MASK
<< R300_STENCILREF_SHIFT
) |
998 (R300_STENCILREF_MASK
<< R300_STENCILMASK_SHIFT
));
1000 flag
= translate_func(ctx
->Stencil
.Function
[0]);
1001 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
1002 (flag
<< R300_S_FRONT_FUNC_SHIFT
);
1004 if (ctx
->Stencil
._TestTwoSide
)
1005 flag
= translate_func(ctx
->Stencil
.Function
[1]);
1007 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
1008 (flag
<< R300_S_BACK_FUNC_SHIFT
);
1009 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |= refmask
;
1012 static void r300StencilMaskSeparate(GLcontext
* ctx
, GLenum face
, GLuint mask
)
1014 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1016 R300_STATECHANGE(rmesa
, zs
);
1017 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &=
1018 ~(R300_STENCILREF_MASK
<<
1019 R300_STENCILWRITEMASK_SHIFT
);
1020 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |=
1022 WriteMask
[0] & R300_STENCILREF_MASK
) <<
1023 R300_STENCILWRITEMASK_SHIFT
;
1026 static void r300StencilOpSeparate(GLcontext
* ctx
, GLenum face
,
1027 GLenum fail
, GLenum zfail
, GLenum zpass
)
1029 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1031 R300_STATECHANGE(rmesa
, zs
);
1032 /* It is easier to mask what's left.. */
1033 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &=
1034 (R300_ZS_MASK
<< R300_Z_FUNC_SHIFT
) |
1035 (R300_ZS_MASK
<< R300_S_FRONT_FUNC_SHIFT
) |
1036 (R300_ZS_MASK
<< R300_S_BACK_FUNC_SHIFT
);
1038 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
1039 (translate_stencil_op(ctx
->Stencil
.FailFunc
[0]) <<
1040 R300_S_FRONT_SFAIL_OP_SHIFT
)
1041 | (translate_stencil_op(ctx
->Stencil
.ZFailFunc
[0]) <<
1042 R300_S_FRONT_ZFAIL_OP_SHIFT
)
1043 | (translate_stencil_op(ctx
->Stencil
.ZPassFunc
[0]) <<
1044 R300_S_FRONT_ZPASS_OP_SHIFT
);
1046 if (ctx
->Stencil
._TestTwoSide
) {
1047 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
1048 (translate_stencil_op(ctx
->Stencil
.FailFunc
[1]) <<
1049 R300_S_BACK_SFAIL_OP_SHIFT
)
1050 | (translate_stencil_op(ctx
->Stencil
.ZFailFunc
[1]) <<
1051 R300_S_BACK_ZFAIL_OP_SHIFT
)
1052 | (translate_stencil_op(ctx
->Stencil
.ZPassFunc
[1]) <<
1053 R300_S_BACK_ZPASS_OP_SHIFT
);
1055 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
1056 (translate_stencil_op(ctx
->Stencil
.FailFunc
[0]) <<
1057 R300_S_BACK_SFAIL_OP_SHIFT
)
1058 | (translate_stencil_op(ctx
->Stencil
.ZFailFunc
[0]) <<
1059 R300_S_BACK_ZFAIL_OP_SHIFT
)
1060 | (translate_stencil_op(ctx
->Stencil
.ZPassFunc
[0]) <<
1061 R300_S_BACK_ZPASS_OP_SHIFT
);
1065 /* =============================================================
1066 * Window position and viewport transformation
1070 * To correctly position primitives:
1072 #define SUBPIXEL_X 0.125
1073 #define SUBPIXEL_Y 0.125
1075 static void r300UpdateWindow(GLcontext
* ctx
)
1077 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1078 __DRIdrawablePrivate
*dPriv
= rmesa
->radeon
.dri
.drawable
;
1079 GLfloat xoffset
= dPriv
? (GLfloat
) dPriv
->x
: 0;
1080 GLfloat yoffset
= dPriv
? (GLfloat
) dPriv
->y
+ dPriv
->h
: 0;
1081 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1083 GLfloat sx
= v
[MAT_SX
];
1084 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1085 GLfloat sy
= -v
[MAT_SY
];
1086 GLfloat ty
= (-v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1087 GLfloat sz
= v
[MAT_SZ
] * rmesa
->radeon
.state
.depth
.scale
;
1088 GLfloat tz
= v
[MAT_TZ
] * rmesa
->radeon
.state
.depth
.scale
;
1090 R300_FIREVERTICES(rmesa
);
1091 R300_STATECHANGE(rmesa
, vpt
);
1093 rmesa
->hw
.vpt
.cmd
[R300_VPT_XSCALE
] = r300PackFloat32(sx
);
1094 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
1095 rmesa
->hw
.vpt
.cmd
[R300_VPT_YSCALE
] = r300PackFloat32(sy
);
1096 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
1097 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZSCALE
] = r300PackFloat32(sz
);
1098 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZOFFSET
] = r300PackFloat32(tz
);
1101 static void r300Viewport(GLcontext
* ctx
, GLint x
, GLint y
,
1102 GLsizei width
, GLsizei height
)
1104 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1105 __DRIcontext
*driContext
= rmesa
->radeon
.dri
.context
;
1106 /* Don't pipeline viewport changes, conflict with window offset
1107 * setting below. Could apply deltas to rescue pipelined viewport
1108 * values, or keep the originals hanging around.
1110 if (rmesa
->radeon
.radeonScreen
->driScreen
->dri2
.enabled
) {
1111 radeon_update_renderbuffers(driContext
, driContext
->driDrawablePriv
);
1112 if (driContext
->driDrawablePriv
!= driContext
->driReadablePriv
) {
1113 radeon_update_renderbuffers(driContext
,
1114 driContext
->driReadablePriv
);
1117 r300UpdateWindow(ctx
);
1120 static void r300DepthRange(GLcontext
* ctx
, GLclampd nearval
, GLclampd farval
)
1122 r300UpdateWindow(ctx
);
1125 void r300UpdateViewportOffset(GLcontext
* ctx
)
1127 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1128 __DRIdrawablePrivate
*dPriv
= ((radeonContextPtr
) rmesa
)->dri
.drawable
;
1129 GLfloat xoffset
= (GLfloat
) dPriv
->x
;
1130 GLfloat yoffset
= (GLfloat
) dPriv
->y
+ dPriv
->h
;
1131 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1133 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1134 GLfloat ty
= (-v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1136 if (rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] != r300PackFloat32(tx
) ||
1137 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] != r300PackFloat32(ty
)) {
1138 /* Note: this should also modify whatever data the context reset
1141 R300_STATECHANGE(rmesa
, vpt
);
1142 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
1143 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
1147 radeonUpdateScissor(ctx
);
1151 * Tell the card where to render (offset, pitch).
1152 * Effected by glDrawBuffer, etc
1154 void r300UpdateDrawBuffer(GLcontext
* ctx
)
1156 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1157 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
1158 struct radeon_renderbuffer
*rrb
;
1160 if (fb
->_ColorDrawBufferIndexes
[0] == BUFFER_FRONT_LEFT
) {
1163 (void *) fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
;
1164 } else if (fb
->_ColorDrawBufferIndexes
[0] == BUFFER_BACK_LEFT
) {
1166 rrb
= (void *) fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
;
1168 /* drawing to multiple buffers, or none */
1175 R300_STATECHANGE(rmesa
, cb
);
1179 r300FetchStateParameter(GLcontext
* ctx
,
1180 const gl_state_index state
[STATE_LENGTH
],
1183 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1186 case STATE_INTERNAL
:
1188 case STATE_R300_WINDOW_DIMENSION
:
1189 value
[0] = r300
->radeon
.dri
.drawable
->w
* 0.5f
; /* width*0.5 */
1190 value
[1] = r300
->radeon
.dri
.drawable
->h
* 0.5f
; /* height*0.5 */
1191 value
[2] = 0.5F
; /* for moving range [-1 1] -> [0 1] */
1192 value
[3] = 1.0F
; /* not used */
1195 case STATE_R300_TEXRECT_FACTOR
:{
1196 struct gl_texture_object
*t
=
1197 ctx
->Texture
.Unit
[state
[2]].CurrentRect
;
1199 if (t
&& t
->Image
[0][t
->BaseLevel
]) {
1200 struct gl_texture_image
*image
=
1201 t
->Image
[0][t
->BaseLevel
];
1202 value
[0] = 1.0 / image
->Width2
;
1203 value
[1] = 1.0 / image
->Height2
;
1224 * Update R300's own internal state parameters.
1225 * For now just STATE_R300_WINDOW_DIMENSION
1227 void r300UpdateStateParameters(GLcontext
* ctx
, GLuint new_state
)
1229 struct r300_fragment_program
*fp
;
1230 struct gl_program_parameter_list
*paramList
;
1233 if (!(new_state
& (_NEW_BUFFERS
| _NEW_PROGRAM
)))
1236 fp
= (struct r300_fragment_program
*)ctx
->FragmentProgram
._Current
;
1240 paramList
= fp
->mesa_program
.Base
.Parameters
;
1245 for (i
= 0; i
< paramList
->NumParameters
; i
++) {
1246 if (paramList
->Parameters
[i
].Type
== PROGRAM_STATE_VAR
) {
1247 r300FetchStateParameter(ctx
,
1248 paramList
->Parameters
[i
].
1250 paramList
->ParameterValues
[i
]);
1255 /* =============================================================
1258 static void r300PolygonOffset(GLcontext
* ctx
, GLfloat factor
, GLfloat units
)
1260 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1261 GLfloat constant
= units
;
1263 switch (ctx
->Visual
.depthBits
) {
1274 /* fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */
1276 R300_STATECHANGE(rmesa
, zbs
);
1277 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_FACTOR
] = r300PackFloat32(factor
);
1278 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_CONSTANT
] = r300PackFloat32(constant
);
1279 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_FACTOR
] = r300PackFloat32(factor
);
1280 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_CONSTANT
] = r300PackFloat32(constant
);
1283 /* Routing and texture-related */
1285 /* r300 doesnt handle GL_CLAMP and GL_MIRROR_CLAMP_EXT correctly when filter is NEAREST.
1286 * Since texwrap produces same results for GL_CLAMP and GL_CLAMP_TO_EDGE we use them instead.
1287 * We need to recalculate wrap modes whenever filter mode is changed because someone might do:
1288 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1289 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1290 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1291 * Since r300 completely ignores R300_TX_CLAMP when either min or mag is nearest it cant handle
1292 * combinations where only one of them is nearest.
1294 static unsigned long gen_fixed_filter(unsigned long f
)
1296 unsigned long mag
, min
, needs_fixing
= 0;
1299 /* We ignore MIRROR bit so we dont have to do everything twice */
1300 if ((f
& ((7 - 1) << R300_TX_WRAP_S_SHIFT
)) ==
1301 (R300_TX_CLAMP
<< R300_TX_WRAP_S_SHIFT
)) {
1304 if ((f
& ((7 - 1) << R300_TX_WRAP_T_SHIFT
)) ==
1305 (R300_TX_CLAMP
<< R300_TX_WRAP_T_SHIFT
)) {
1308 if ((f
& ((7 - 1) << R300_TX_WRAP_R_SHIFT
)) ==
1309 (R300_TX_CLAMP
<< R300_TX_WRAP_R_SHIFT
)) {
1316 mag
= f
& R300_TX_MAG_FILTER_MASK
;
1317 min
= f
& (R300_TX_MIN_FILTER_MASK
|R300_TX_MIN_FILTER_MIP_MASK
);
1319 /* TODO: Check for anisto filters too */
1320 if ((mag
!= R300_TX_MAG_FILTER_NEAREST
)
1321 && (min
!= R300_TX_MIN_FILTER_NEAREST
))
1324 /* r300 cant handle these modes hence we force nearest to linear */
1325 if ((mag
== R300_TX_MAG_FILTER_NEAREST
)
1326 && (min
!= R300_TX_MIN_FILTER_NEAREST
)) {
1327 f
&= ~R300_TX_MAG_FILTER_NEAREST
;
1328 f
|= R300_TX_MAG_FILTER_LINEAR
;
1332 if ((min
== R300_TX_MIN_FILTER_NEAREST
)
1333 && (mag
!= R300_TX_MAG_FILTER_NEAREST
)) {
1334 f
&= ~R300_TX_MIN_FILTER_NEAREST
;
1335 f
|= R300_TX_MIN_FILTER_LINEAR
;
1339 /* Both are nearest */
1340 if (needs_fixing
& 1) {
1341 f
&= ~((7 - 1) << R300_TX_WRAP_S_SHIFT
);
1342 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_S_SHIFT
;
1344 if (needs_fixing
& 2) {
1345 f
&= ~((7 - 1) << R300_TX_WRAP_T_SHIFT
);
1346 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_T_SHIFT
;
1348 if (needs_fixing
& 4) {
1349 f
&= ~((7 - 1) << R300_TX_WRAP_R_SHIFT
);
1350 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_R_SHIFT
;
1355 static void r300SetupFragmentShaderTextures(GLcontext
*ctx
, int *tmu_mappings
)
1357 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1359 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
1360 (char *)ctx
->FragmentProgram
._Current
;
1361 struct r300_fragment_program_code
*code
= &fp
->code
;
1363 R300_STATECHANGE(r300
, fpt
);
1365 for (i
= 0; i
< code
->tex
.length
; i
++) {
1370 unit
= code
->tex
.inst
[i
] >> R300_TEX_ID_SHIFT
;
1373 val
= code
->tex
.inst
[i
];
1374 val
&= ~R300_TEX_ID_MASK
;
1377 (val
& R300_TEX_INST_MASK
) >> R300_TEX_INST_SHIFT
;
1378 if (opcode
== R300_TEX_OP_KIL
) {
1379 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1381 if (tmu_mappings
[unit
] >= 0) {
1383 tmu_mappings
[unit
] <<
1385 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1387 // We get here when the corresponding texture image is incomplete
1388 // (e.g. incomplete mipmaps etc.)
1389 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1394 r300
->hw
.fpt
.cmd
[R300_FPT_CMD_0
] =
1395 cmdpacket0(r300
->radeon
.radeonScreen
,
1396 R300_US_TEX_INST_0
, code
->tex
.length
);
1399 static void r500SetupFragmentShaderTextures(GLcontext
*ctx
, int *tmu_mappings
)
1402 struct r500_fragment_program
*fp
= (struct r500_fragment_program
*)
1403 (char *)ctx
->FragmentProgram
._Current
;
1404 struct r500_fragment_program_code
*code
= &fp
->code
;
1406 /* find all the texture instructions and relocate the texture units */
1407 for (i
= 0; i
< code
->inst_end
+ 1; i
++) {
1408 if ((code
->inst
[i
].inst0
& 0x3) == R500_INST_TYPE_TEX
) {
1410 int unit
, opcode
, new_unit
;
1412 val
= code
->inst
[i
].inst1
;
1414 unit
= (val
>> 16) & 0xf;
1416 val
&= ~(0xf << 16);
1418 opcode
= val
& (0x7 << 22);
1419 if (opcode
== R500_TEX_INST_TEXKILL
) {
1422 if (tmu_mappings
[unit
] >= 0) {
1423 new_unit
= tmu_mappings
[unit
];
1428 val
|= R500_TEX_ID(new_unit
);
1429 code
->inst
[i
].inst1
= val
;
1434 static GLuint
translate_lod_bias(GLfloat bias
)
1436 GLint b
= (int)(bias
*32);
1439 else if (b
< -(1 << 9))
1441 return (((GLuint
)b
) << R300_LOD_BIAS_SHIFT
) & R300_LOD_BIAS_MASK
;
1444 static void r300SetupTextures(GLcontext
* ctx
)
1447 struct radeon_tex_obj
*t
;
1448 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1450 int last_hw_tmu
= -1; /* -1 translates into no setup costs for fields */
1451 int tmu_mappings
[R300_MAX_TEXTURE_UNITS
] = { -1, };
1452 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
1453 (char *)ctx
->FragmentProgram
._Current
;
1455 R300_STATECHANGE(r300
, txe
);
1456 R300_STATECHANGE(r300
, tex
.filter
);
1457 R300_STATECHANGE(r300
, tex
.filter_1
);
1458 R300_STATECHANGE(r300
, tex
.size
);
1459 R300_STATECHANGE(r300
, tex
.format
);
1460 R300_STATECHANGE(r300
, tex
.pitch
);
1461 R300_STATECHANGE(r300
, tex
.offset
);
1462 R300_STATECHANGE(r300
, tex
.chroma_key
);
1463 R300_STATECHANGE(r300
, tex
.border_color
);
1465 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] = 0x0;
1467 mtu
= r300
->radeon
.glCtx
->Const
.MaxTextureUnits
;
1468 if (RADEON_DEBUG
& DEBUG_STATE
)
1469 fprintf(stderr
, "mtu=%d\n", mtu
);
1471 if (mtu
> R300_MAX_TEXTURE_UNITS
) {
1473 "Aiiee ! mtu=%d is greater than R300_MAX_TEXTURE_UNITS=%d\n",
1474 mtu
, R300_MAX_TEXTURE_UNITS
);
1478 /* We cannot let disabled tmu offsets pass DRM */
1479 for (i
= 0; i
< mtu
; i
++) {
1480 if (ctx
->Texture
.Unit
[i
]._ReallyEnabled
) {
1481 tmu_mappings
[i
] = hw_tmu
;
1483 t
= radeon_tex_obj(ctx
->Texture
.Unit
[i
]._Current
);
1487 if ((t
->pp_txformat
& 0xffffff00) == 0xffffff00) {
1489 ("unknown texture format (entry %x) encountered. Help me !\n",
1490 t
->pp_txformat
& 0xff);
1493 if (RADEON_DEBUG
& DEBUG_STATE
)
1495 "Activating texture unit %d\n", i
);
1497 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] |= (1 << hw_tmu
);
1499 r300
->hw
.tex
.filter
.cmd
[R300_TEX_VALUE_0
+
1501 gen_fixed_filter(t
->pp_txfilter
) | (hw_tmu
<< 28);
1502 /* Note: There is a LOD bias per texture unit and a LOD bias
1503 * per texture object. We add them here to get the correct behaviour.
1504 * (The per-texture object LOD bias was introduced in OpenGL 1.4
1505 * and is not present in the EXT_texture_object extension).
1507 r300
->hw
.tex
.filter_1
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] =
1509 translate_lod_bias(ctx
->Texture
.Unit
[i
].LodBias
+ t
->base
.LodBias
);
1510 r300
->hw
.tex
.size
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] =
1512 r300
->hw
.tex
.format
.cmd
[R300_TEX_VALUE_0
+
1513 hw_tmu
] = t
->pp_txformat
;
1514 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] =
1516 r300
->hw
.textures
[hw_tmu
] = t
;
1518 if (t
->tile_bits
& R300_TXO_MACRO_TILE
) {
1519 WARN_ONCE("macro tiling enabled!\n");
1522 if (t
->tile_bits
& R300_TXO_MICRO_TILE
) {
1523 WARN_ONCE("micro tiling enabled!\n");
1526 r300
->hw
.tex
.chroma_key
.cmd
[R300_TEX_VALUE_0
+
1528 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_VALUE_0
+
1532 last_hw_tmu
= hw_tmu
;
1538 r300
->hw
.tex
.filter
.cmd
[R300_TEX_CMD_0
] =
1539 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_FILTER0_0
, last_hw_tmu
+ 1);
1540 r300
->hw
.tex
.filter_1
.cmd
[R300_TEX_CMD_0
] =
1541 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_FILTER1_0
, last_hw_tmu
+ 1);
1542 r300
->hw
.tex
.size
.cmd
[R300_TEX_CMD_0
] =
1543 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_SIZE_0
, last_hw_tmu
+ 1);
1544 r300
->hw
.tex
.format
.cmd
[R300_TEX_CMD_0
] =
1545 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_FORMAT_0
, last_hw_tmu
+ 1);
1546 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_CMD_0
] =
1547 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_FORMAT2_0
, last_hw_tmu
+ 1);
1548 r300
->hw
.tex
.offset
.cmd
[R300_TEX_CMD_0
] =
1549 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_OFFSET_0
, last_hw_tmu
+ 1);
1550 r300
->hw
.tex
.chroma_key
.cmd
[R300_TEX_CMD_0
] =
1551 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_CHROMA_KEY_0
, last_hw_tmu
+ 1);
1552 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_CMD_0
] =
1553 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_BORDER_COLOR_0
, last_hw_tmu
+ 1);
1555 if (!fp
) /* should only happenen once, just after context is created */
1558 if (r300
->radeon
.radeonScreen
->chip_family
< CHIP_FAMILY_RV515
) {
1559 if (fp
->mesa_program
.UsesKill
&& last_hw_tmu
< 0) {
1560 // The KILL operation requires the first texture unit
1562 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] |= 1;
1563 r300
->hw
.tex
.filter
.cmd
[R300_TEX_VALUE_0
] = 0;
1564 r300
->hw
.tex
.filter
.cmd
[R300_TEX_CMD_0
] =
1565 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_FILTER0_0
, 1);
1567 r300SetupFragmentShaderTextures(ctx
, tmu_mappings
);
1569 r500SetupFragmentShaderTextures(ctx
, tmu_mappings
);
1571 if (RADEON_DEBUG
& DEBUG_STATE
)
1572 fprintf(stderr
, "TX_ENABLE: %08x last_hw_tmu=%d\n",
1573 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
], last_hw_tmu
);
1576 union r300_outputs_written
{
1577 GLuint vp_outputs
; /* hw_tcl_on */
1578 DECLARE_RENDERINPUTS(index_bitset
); /* !hw_tcl_on */
1581 #define R300_OUTPUTS_WRITTEN_TEST(ow, vp_result, tnl_attrib) \
1582 ((hw_tcl_on) ? (ow).vp_outputs & (1 << (vp_result)) : \
1583 RENDERINPUTS_TEST( (ow.index_bitset), (tnl_attrib) ))
1585 static void r300SetupRSUnit(GLcontext
* ctx
)
1587 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1588 /* I'm still unsure if these are needed */
1589 GLuint interp_col
[8];
1590 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1591 struct vertex_buffer
*VB
= &tnl
->vb
;
1592 union r300_outputs_written OutputsWritten
;
1594 int fp_reg
, high_rr
;
1596 int rs_tex_count
= 0, rs_col_count
= 0;
1599 memset(interp_col
, 0, sizeof(interp_col
));
1602 OutputsWritten
.vp_outputs
= CURRENT_VERTEX_SHADER(ctx
)->key
.OutputsWritten
;
1604 RENDERINPUTS_COPY(OutputsWritten
.index_bitset
, r300
->state
.render_inputs_bitset
);
1606 if (ctx
->FragmentProgram
._Current
)
1607 InputsRead
= ctx
->FragmentProgram
._Current
->Base
.InputsRead
;
1609 fprintf(stderr
, "No ctx->FragmentProgram._Current!!\n");
1610 return; /* This should only ever happen once.. */
1613 R300_STATECHANGE(r300
, ri
);
1614 R300_STATECHANGE(r300
, rc
);
1615 R300_STATECHANGE(r300
, rr
);
1617 fp_reg
= col_interp_nr
= high_rr
= 0;
1619 r300
->hw
.rr
.cmd
[R300_RR_INST_1
] = 0;
1621 if (InputsRead
& FRAG_BIT_WPOS
) {
1622 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++)
1623 if (!(InputsRead
& (FRAG_BIT_TEX0
<< i
)))
1626 if (i
== ctx
->Const
.MaxTextureUnits
) {
1627 fprintf(stderr
, "\tno free texcoord found...\n");
1631 InputsRead
|= (FRAG_BIT_TEX0
<< i
);
1632 InputsRead
&= ~FRAG_BIT_WPOS
;
1635 if (InputsRead
& FRAG_BIT_COL0
) {
1636 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR0
]->size
;
1637 interp_col
[0] |= R300_RS_COL_PTR(rs_col_count
);
1639 interp_col
[0] |= R300_RS_COL_FMT(R300_RS_COL_FMT_RGB1
);
1640 rs_col_count
+= count
;
1643 interp_col
[0] = R300_RS_COL_FMT(R300_RS_COL_FMT_0001
);
1645 if (InputsRead
& FRAG_BIT_COL1
) {
1646 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR1
]->size
;
1648 interp_col
[1] |= R300_RS_COL_FMT(R300_RS_COL_FMT_RGB0
);
1649 interp_col
[1] |= R300_RS_COL_PTR(1);
1650 rs_col_count
+= count
;
1654 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
1657 /* with TCL we always seem to route 4 components */
1661 count
= VB
->AttribPtr
[_TNL_ATTRIB_TEX(i
)]->size
;
1663 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ i
] = interp_col
[i
] | rs_tex_count
;
1665 case 4: swiz
= R300_RS_SEL_S(0) | R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(3); break;
1666 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;
1669 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;
1672 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ i
] |= swiz
;
1674 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ fp_reg
] = 0;
1675 if (InputsRead
& (FRAG_BIT_TEX0
<< i
)) {
1677 rs_tex_count
+= count
;
1679 //assert(r300->state.texture.tc_count != 0);
1680 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ fp_reg
] |= R300_RS_INST_TEX_CN_WRITE
| i
/* source INTERP */
1681 | (fp_reg
<< R300_RS_INST_TEX_ADDR_SHIFT
);
1684 /* Passing invalid data here can lock the GPU. */
1685 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_TEX0
+ i
, _TNL_ATTRIB_TEX(i
))) {
1686 InputsRead
&= ~(FRAG_BIT_TEX0
<< i
);
1689 WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i
);
1694 if (InputsRead
& FRAG_BIT_COL0
) {
1695 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL0
, _TNL_ATTRIB_COLOR0
)) {
1696 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
);
1697 InputsRead
&= ~FRAG_BIT_COL0
;
1700 WARN_ONCE("fragprog wants col0, vp doesn't provide it\n");
1704 if (InputsRead
& FRAG_BIT_COL1
) {
1705 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL1
, _TNL_ATTRIB_COLOR1
)) {
1706 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
);
1707 InputsRead
&= ~FRAG_BIT_COL1
;
1712 WARN_ONCE("fragprog wants col1, vp doesn't provide it\n");
1716 /* Need at least one. This might still lock as the values are undefined... */
1717 if (rs_tex_count
== 0 && col_interp_nr
== 0) {
1718 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
);
1722 r300
->hw
.rc
.cmd
[1] = 0 | (rs_tex_count
<< R300_IT_COUNT_SHIFT
)
1723 | (col_interp_nr
<< R300_IC_COUNT_SHIFT
)
1726 assert(high_rr
>= 0);
1727 r300
->hw
.rr
.cmd
[R300_RR_CMD_0
] = cmdpacket0(r300
->radeon
.radeonScreen
, R300_RS_INST_0
, high_rr
+ 1);
1728 r300
->hw
.rc
.cmd
[2] = high_rr
;
1731 WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead
);
1734 static void r500SetupRSUnit(GLcontext
* ctx
)
1736 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1737 /* I'm still unsure if these are needed */
1738 GLuint interp_col
[8];
1739 union r300_outputs_written OutputsWritten
;
1740 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1741 struct vertex_buffer
*VB
= &tnl
->vb
;
1743 int fp_reg
, high_rr
;
1744 int rs_col_count
= 0;
1745 int in_texcoords
, col_interp_nr
;
1748 memset(interp_col
, 0, sizeof(interp_col
));
1750 OutputsWritten
.vp_outputs
= CURRENT_VERTEX_SHADER(ctx
)->key
.OutputsWritten
;
1752 RENDERINPUTS_COPY(OutputsWritten
.index_bitset
, r300
->state
.render_inputs_bitset
);
1754 if (ctx
->FragmentProgram
._Current
)
1755 InputsRead
= ctx
->FragmentProgram
._Current
->Base
.InputsRead
;
1757 fprintf(stderr
, "No ctx->FragmentProgram._Current!!\n");
1758 return; /* This should only ever happen once.. */
1761 R300_STATECHANGE(r300
, ri
);
1762 R300_STATECHANGE(r300
, rc
);
1763 R300_STATECHANGE(r300
, rr
);
1765 fp_reg
= col_interp_nr
= high_rr
= in_texcoords
= 0;
1767 r300
->hw
.rr
.cmd
[R300_RR_INST_1
] = 0;
1769 if (InputsRead
& FRAG_BIT_WPOS
) {
1770 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++)
1771 if (!(InputsRead
& (FRAG_BIT_TEX0
<< i
)))
1774 if (i
== ctx
->Const
.MaxTextureUnits
) {
1775 fprintf(stderr
, "\tno free texcoord found...\n");
1779 InputsRead
|= (FRAG_BIT_TEX0
<< i
);
1780 InputsRead
&= ~FRAG_BIT_WPOS
;
1783 if (InputsRead
& FRAG_BIT_COL0
) {
1784 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR0
]->size
;
1785 interp_col
[0] |= R500_RS_COL_PTR(rs_col_count
);
1787 interp_col
[0] |= R500_RS_COL_FMT(R300_RS_COL_FMT_RGB1
);
1788 rs_col_count
+= count
;
1791 interp_col
[0] = R500_RS_COL_FMT(R300_RS_COL_FMT_0001
);
1793 if (InputsRead
& FRAG_BIT_COL1
) {
1794 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR1
]->size
;
1795 interp_col
[1] |= R500_RS_COL_PTR(1);
1797 interp_col
[1] |= R500_RS_COL_FMT(R300_RS_COL_FMT_RGB0
);
1798 rs_col_count
+= count
;
1801 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
1804 /* with TCL we always seem to route 4 components */
1805 if (InputsRead
& (FRAG_BIT_TEX0
<< i
)) {
1810 count
= VB
->AttribPtr
[_TNL_ATTRIB_TEX(i
)]->size
;
1812 /* always have on texcoord */
1813 swiz
|= in_texcoords
++ << R500_RS_IP_TEX_PTR_S_SHIFT
;
1815 swiz
|= in_texcoords
++ << R500_RS_IP_TEX_PTR_T_SHIFT
;
1817 swiz
|= R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_T_SHIFT
;
1820 swiz
|= in_texcoords
++ << R500_RS_IP_TEX_PTR_R_SHIFT
;
1822 swiz
|= R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_R_SHIFT
;
1825 swiz
|= in_texcoords
++ << R500_RS_IP_TEX_PTR_Q_SHIFT
;
1827 swiz
|= R500_RS_IP_PTR_K1
<< R500_RS_IP_TEX_PTR_Q_SHIFT
;
1830 swiz
= (R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_S_SHIFT
) |
1831 (R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_T_SHIFT
) |
1832 (R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_R_SHIFT
) |
1833 (R500_RS_IP_PTR_K1
<< R500_RS_IP_TEX_PTR_Q_SHIFT
);
1835 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ i
] = interp_col
[i
] | swiz
;
1837 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ fp_reg
] = 0;
1838 if (InputsRead
& (FRAG_BIT_TEX0
<< i
)) {
1839 //assert(r300->state.texture.tc_count != 0);
1840 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ fp_reg
] |= R500_RS_INST_TEX_CN_WRITE
| i
/* source INTERP */
1841 | (fp_reg
<< R500_RS_INST_TEX_ADDR_SHIFT
);
1844 /* Passing invalid data here can lock the GPU. */
1845 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_TEX0
+ i
, _TNL_ATTRIB_TEX(i
))) {
1846 InputsRead
&= ~(FRAG_BIT_TEX0
<< i
);
1849 WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i
);
1854 if (InputsRead
& FRAG_BIT_COL0
) {
1855 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL0
, _TNL_ATTRIB_COLOR0
)) {
1856 r300
->hw
.rr
.cmd
[R300_RR_INST_0
] |= R500_RS_INST_COL_CN_WRITE
| (fp_reg
++ << R500_RS_INST_COL_ADDR_SHIFT
);
1857 InputsRead
&= ~FRAG_BIT_COL0
;
1860 WARN_ONCE("fragprog wants col0, vp doesn't provide it\n");
1864 if (InputsRead
& FRAG_BIT_COL1
) {
1865 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL1
, _TNL_ATTRIB_COLOR1
)) {
1866 r300
->hw
.rr
.cmd
[R300_RR_INST_1
] |= (1 << 12) | R500_RS_INST_COL_CN_WRITE
| (fp_reg
++ << R500_RS_INST_COL_ADDR_SHIFT
);
1867 InputsRead
&= ~FRAG_BIT_COL1
;
1872 WARN_ONCE("fragprog wants col1, vp doesn't provide it\n");
1876 /* Need at least one. This might still lock as the values are undefined... */
1877 if (in_texcoords
== 0 && col_interp_nr
== 0) {
1878 r300
->hw
.rr
.cmd
[R300_RR_INST_0
] |= 0 | R500_RS_INST_COL_CN_WRITE
| (fp_reg
++ << R500_RS_INST_COL_ADDR_SHIFT
);
1882 r300
->hw
.rc
.cmd
[1] = 0 | (in_texcoords
<< R300_IT_COUNT_SHIFT
)
1883 | (col_interp_nr
<< R300_IC_COUNT_SHIFT
)
1886 assert(high_rr
>= 0);
1887 r300
->hw
.rr
.cmd
[R300_RR_CMD_0
] = cmdpacket0(r300
->radeon
.radeonScreen
, R500_RS_INST_0
, high_rr
+ 1);
1888 r300
->hw
.rc
.cmd
[2] = 0xC0 | high_rr
;
1891 WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead
);
1897 #define bump_vpu_count(ptr, new_count) do{\
1898 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
1899 int _nc=(new_count)/4; \
1900 assert(_nc < 256); \
1901 if(_nc>_p->vpu.count)_p->vpu.count=_nc;\
1904 static INLINE
void r300SetupVertexProgramFragment(r300ContextPtr r300
, int dest
, struct r300_vertex_shader_fragment
*vsf
)
1908 if (vsf
->length
== 0)
1911 if (vsf
->length
& 0x3) {
1912 fprintf(stderr
, "VERTEX_SHADER_FRAGMENT must have length divisible by 4\n");
1916 switch ((dest
>> 8) & 0xf) {
1918 R300_STATECHANGE(r300
, vpi
);
1919 for (i
= 0; i
< vsf
->length
; i
++)
1920 r300
->hw
.vpi
.cmd
[R300_VPI_INSTR_0
+ i
+ 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1921 bump_vpu_count(r300
->hw
.vpi
.cmd
, vsf
->length
+ 4 * (dest
& 0xff));
1925 R300_STATECHANGE(r300
, vpp
);
1926 for (i
= 0; i
< vsf
->length
; i
++)
1927 r300
->hw
.vpp
.cmd
[R300_VPP_PARAM_0
+ i
+ 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1928 bump_vpu_count(r300
->hw
.vpp
.cmd
, vsf
->length
+ 4 * (dest
& 0xff));
1931 R300_STATECHANGE(r300
, vps
);
1932 for (i
= 0; i
< vsf
->length
; i
++)
1933 r300
->hw
.vps
.cmd
[1 + i
+ 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1934 bump_vpu_count(r300
->hw
.vps
.cmd
, vsf
->length
+ 4 * (dest
& 0xff));
1937 fprintf(stderr
, "%s:%s don't know how to handle dest %04x\n", __FILE__
, __FUNCTION__
, dest
);
1942 #define MIN3(a, b, c) ((a) < (b) ? MIN2(a, c) : MIN2(b, c))
1945 static void r300VapCntl(r300ContextPtr rmesa
, GLuint input_count
,
1946 GLuint output_count
, GLuint temp_count
)
1952 /* Flush PVS engine before changing PVS_NUM_SLOTS, PVS_NUM_CNTRLS.
1953 * See r500 docs 6.5.2 - done in emit */
1955 /* avoid division by zero */
1956 if (input_count
== 0) input_count
= 1;
1957 if (output_count
== 0) output_count
= 1;
1958 if (temp_count
== 0) temp_count
= 1;
1960 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
1965 pvs_num_slots
= MIN3(10, vtx_mem_size
/input_count
, vtx_mem_size
/output_count
);
1966 pvs_num_cntrls
= MIN2(6, vtx_mem_size
/temp_count
);
1968 R300_STATECHANGE(rmesa
, vap_cntl
);
1969 if (rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
) {
1970 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] =
1971 (pvs_num_slots
<< R300_PVS_NUM_SLOTS_SHIFT
) |
1972 (pvs_num_cntrls
<< R300_PVS_NUM_CNTLRS_SHIFT
) |
1973 (12 << R300_VF_MAX_VTX_NUM_SHIFT
);
1974 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
1975 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= R500_TCL_STATE_OPTIMIZATION
;
1977 /* not sure about non-tcl */
1978 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] = ((10 << R300_PVS_NUM_SLOTS_SHIFT
) |
1979 (5 << R300_PVS_NUM_CNTLRS_SHIFT
) |
1980 (5 << R300_VF_MAX_VTX_NUM_SHIFT
));
1982 if (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV515
)
1983 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (2 << R300_PVS_NUM_FPUS_SHIFT
);
1984 else if ((rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV530
) ||
1985 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV560
) ||
1986 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV570
))
1987 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (5 << R300_PVS_NUM_FPUS_SHIFT
);
1988 else if ((rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV410
) ||
1989 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R420
))
1990 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (6 << R300_PVS_NUM_FPUS_SHIFT
);
1991 else if ((rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R520
) ||
1992 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R580
))
1993 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (8 << R300_PVS_NUM_FPUS_SHIFT
);
1995 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (4 << R300_PVS_NUM_FPUS_SHIFT
);
1999 static void r300SetupDefaultVertexProgram(r300ContextPtr rmesa
)
2001 struct r300_vertex_shader_state
*prog
= &(rmesa
->state
.vertex_shader
);
2006 int param_count
= 0;
2007 int program_end
= 0;
2009 for (i
= VERT_ATTRIB_POS
; i
< VERT_ATTRIB_MAX
; i
++) {
2010 if (rmesa
->state
.sw_tcl_inputs
[i
] != -1) {
2011 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
);
2012 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
);
2013 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
);
2014 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
);
2020 prog
->program
.length
= program_end
;
2022 r300SetupVertexProgramFragment(rmesa
, R300_PVS_CODE_START
,
2024 inst_count
= (prog
->program
.length
/ 4) - 1;
2026 r300VapCntl(rmesa
, i_reg
, o_reg
, 0);
2028 R300_STATECHANGE(rmesa
, pvs
);
2029 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] =
2030 (0 << R300_PVS_FIRST_INST_SHIFT
) |
2031 (inst_count
<< R300_PVS_XYZW_VALID_INST_SHIFT
) |
2032 (inst_count
<< R300_PVS_LAST_INST_SHIFT
);
2033 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] =
2034 (0 << R300_PVS_CONST_BASE_OFFSET_SHIFT
) |
2035 (param_count
<< R300_PVS_MAX_CONST_ADDR_SHIFT
);
2036 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] =
2037 (inst_count
<< R300_PVS_LAST_VTX_SRC_INST_SHIFT
);
2040 static int bit_count (int x
)
2042 x
= ((x
& 0xaaaaaaaaU
) >> 1) + (x
& 0x55555555U
);
2043 x
= ((x
& 0xccccccccU
) >> 2) + (x
& 0x33333333U
);
2044 x
= (x
>> 16) + (x
& 0xffff);
2045 x
= ((x
& 0xf0f0) >> 4) + (x
& 0x0f0f);
2046 return (x
>> 8) + (x
& 0x00ff);
2049 static void r300SetupRealVertexProgram(r300ContextPtr rmesa
)
2051 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
2052 struct r300_vertex_program
*prog
= (struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
);
2054 int param_count
= 0;
2056 /* FIXME: r300SetupVertexProgramFragment */
2057 R300_STATECHANGE(rmesa
, vpp
);
2059 r300VertexProgUpdateParams(ctx
,
2060 (struct r300_vertex_program_cont
*)
2061 ctx
->VertexProgram
._Current
,
2062 (float *)&rmesa
->hw
.vpp
.
2063 cmd
[R300_VPP_PARAM_0
]);
2064 bump_vpu_count(rmesa
->hw
.vpp
.cmd
, param_count
);
2067 r300SetupVertexProgramFragment(rmesa
, R300_PVS_CODE_START
, &(prog
->program
));
2068 inst_count
= (prog
->program
.length
/ 4) - 1;
2070 r300VapCntl(rmesa
, bit_count(prog
->key
.InputsRead
),
2071 bit_count(prog
->key
.OutputsWritten
), prog
->num_temporaries
);
2073 R300_STATECHANGE(rmesa
, pvs
);
2074 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] =
2075 (0 << R300_PVS_FIRST_INST_SHIFT
) |
2076 (inst_count
<< R300_PVS_XYZW_VALID_INST_SHIFT
) |
2077 (inst_count
<< R300_PVS_LAST_INST_SHIFT
);
2078 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] =
2079 (0 << R300_PVS_CONST_BASE_OFFSET_SHIFT
) |
2080 (param_count
<< R300_PVS_MAX_CONST_ADDR_SHIFT
);
2081 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] =
2082 (inst_count
<< R300_PVS_LAST_VTX_SRC_INST_SHIFT
);
2086 static void r300SetupVertexProgram(r300ContextPtr rmesa
)
2088 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
2090 /* Reset state, in case we don't use something */
2091 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vpp
.cmd
)->vpu
.count
= 0;
2092 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vpi
.cmd
)->vpu
.count
= 0;
2093 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vps
.cmd
)->vpu
.count
= 0;
2095 /* Not sure why this doesnt work...
2096 0x400 area might have something to do with pixel shaders as it appears right after pfs programming.
2097 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. */
2098 //setup_vertex_shader_fragment(rmesa, 0x406, &unk4);
2099 if (hw_tcl_on
&& ((struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
))->translated
) {
2100 r300SetupRealVertexProgram(rmesa
);
2102 /* FIXME: This needs to be replaced by vertex shader generation code. */
2103 r300SetupDefaultVertexProgram(rmesa
);
2109 * Enable/Disable states.
2111 * \note Mesa already filters redundant calls to this function.
2113 static void r300Enable(GLcontext
* ctx
, GLenum cap
, GLboolean state
)
2115 if (RADEON_DEBUG
& DEBUG_STATE
)
2116 fprintf(stderr
, "%s( %s = %s )\n", __FUNCTION__
,
2117 _mesa_lookup_enum_by_nr(cap
),
2118 state
? "GL_TRUE" : "GL_FALSE");
2127 r300SetFogState(ctx
, state
);
2130 r300SetAlphaState(ctx
);
2132 case GL_COLOR_LOGIC_OP
:
2133 r300SetLogicOpState(ctx
);
2134 /* fall-through, because logic op overrides blending */
2136 r300SetBlendState(ctx
);
2138 case GL_CLIP_PLANE0
:
2139 case GL_CLIP_PLANE1
:
2140 case GL_CLIP_PLANE2
:
2141 case GL_CLIP_PLANE3
:
2142 case GL_CLIP_PLANE4
:
2143 case GL_CLIP_PLANE5
:
2144 r300SetClipPlaneState(ctx
, cap
, state
);
2147 r300SetDepthState(ctx
);
2149 case GL_STENCIL_TEST
:
2150 r300SetStencilState(ctx
, state
);
2153 r300UpdateCulling(ctx
);
2155 case GL_POLYGON_OFFSET_POINT
:
2156 case GL_POLYGON_OFFSET_LINE
:
2157 case GL_POLYGON_OFFSET_FILL
:
2158 r300SetPolygonOffsetState(ctx
, state
);
2161 radeonEnable(ctx
, cap
, state
);
2167 * Completely recalculates hardware state based on the Mesa state.
2169 static void r300ResetHwState(r300ContextPtr r300
)
2171 GLcontext
*ctx
= r300
->radeon
.glCtx
;
2172 struct radeon_renderbuffer
*rrb
;
2175 if (!(r300
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
2178 if (RADEON_DEBUG
& DEBUG_STATE
)
2179 fprintf(stderr
, "%s\n", __FUNCTION__
);
2181 r300UpdateWindow(ctx
);
2184 ctx
->Color
.ColorMask
[RCOMP
],
2185 ctx
->Color
.ColorMask
[GCOMP
],
2186 ctx
->Color
.ColorMask
[BCOMP
], ctx
->Color
.ColorMask
[ACOMP
]);
2188 r300Enable(ctx
, GL_DEPTH_TEST
, ctx
->Depth
.Test
);
2189 r300DepthMask(ctx
, ctx
->Depth
.Mask
);
2190 r300DepthFunc(ctx
, ctx
->Depth
.Func
);
2193 r300Enable(ctx
, GL_STENCIL_TEST
, ctx
->Stencil
.Enabled
);
2194 r300StencilMaskSeparate(ctx
, 0, ctx
->Stencil
.WriteMask
[0]);
2195 r300StencilFuncSeparate(ctx
, 0, ctx
->Stencil
.Function
[0],
2196 ctx
->Stencil
.Ref
[0], ctx
->Stencil
.ValueMask
[0]);
2197 r300StencilOpSeparate(ctx
, 0, ctx
->Stencil
.FailFunc
[0],
2198 ctx
->Stencil
.ZFailFunc
[0],
2199 ctx
->Stencil
.ZPassFunc
[0]);
2201 r300UpdateCulling(ctx
);
2203 r300SetBlendState(ctx
);
2204 r300SetLogicOpState(ctx
);
2206 r300AlphaFunc(ctx
, ctx
->Color
.AlphaFunc
, ctx
->Color
.AlphaRef
);
2207 r300Enable(ctx
, GL_ALPHA_TEST
, ctx
->Color
.AlphaEnabled
);
2209 r300
->hw
.vte
.cmd
[1] = R300_VPORT_X_SCALE_ENA
2210 | R300_VPORT_X_OFFSET_ENA
2211 | R300_VPORT_Y_SCALE_ENA
2212 | R300_VPORT_Y_OFFSET_ENA
2213 | R300_VPORT_Z_SCALE_ENA
2214 | R300_VPORT_Z_OFFSET_ENA
| R300_VTX_W0_FMT
;
2215 r300
->hw
.vte
.cmd
[2] = 0x00000008;
2217 r300
->hw
.vap_vf_max_vtx_indx
.cmd
[1] = 0x00FFFFFF;
2218 r300
->hw
.vap_vf_max_vtx_indx
.cmd
[2] = 0x00000000;
2220 #ifdef MESA_LITTLE_ENDIAN
2221 r300
->hw
.vap_cntl_status
.cmd
[1] = R300_VC_NO_SWAP
;
2223 r300
->hw
.vap_cntl_status
.cmd
[1] = R300_VC_32BIT_SWAP
;
2226 /* disable VAP/TCL on non-TCL capable chips */
2228 r300
->hw
.vap_cntl_status
.cmd
[1] |= R300_VAP_TCL_BYPASS
;
2230 r300
->hw
.vap_psc_sgn_norm_cntl
.cmd
[1] = 0xAAAAAAAA;
2232 /* XXX: Other families? */
2234 r300
->hw
.vap_clip_cntl
.cmd
[1] = R300_PS_UCP_MODE_DIST_COP
;
2236 r300
->hw
.vap_clip
.cmd
[1] = r300PackFloat32(1.0); /* X */
2237 r300
->hw
.vap_clip
.cmd
[2] = r300PackFloat32(1.0); /* X */
2238 r300
->hw
.vap_clip
.cmd
[3] = r300PackFloat32(1.0); /* Y */
2239 r300
->hw
.vap_clip
.cmd
[4] = r300PackFloat32(1.0); /* Y */
2241 switch (r300
->radeon
.radeonScreen
->chip_family
) {
2242 case CHIP_FAMILY_R300
:
2243 r300
->hw
.vap_pvs_vtx_timeout_reg
.cmd
[1] = R300_2288_R300
;
2246 r300
->hw
.vap_pvs_vtx_timeout_reg
.cmd
[1] = R300_2288_RV350
;
2251 r300
->hw
.gb_enable
.cmd
[1] = R300_GB_POINT_STUFF_ENABLE
2252 | R300_GB_LINE_STUFF_ENABLE
2253 | R300_GB_TRIANGLE_STUFF_ENABLE
;
2255 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_0
] = 0x66666666;
2256 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_1
] = 0x06666666;
2258 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] =
2259 R300_GB_TILE_ENABLE
| R300_GB_TILE_SIZE_16
/*| R300_GB_SUBPIXEL_1_16*/;
2260 switch (r300
->radeon
.radeonScreen
->num_gb_pipes
) {
2263 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2264 R300_GB_TILE_PIPE_COUNT_RV300
;
2267 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2268 R300_GB_TILE_PIPE_COUNT_R300
;
2271 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2272 R300_GB_TILE_PIPE_COUNT_R420_3P
;
2275 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2276 R300_GB_TILE_PIPE_COUNT_R420
;
2280 /* XXX: set to 0 when fog is disabled? */
2281 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_SELECT
] = R300_GB_FOG_SELECT_1_1_W
;
2283 /* XXX: Enable anti-aliasing? */
2284 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_AA_CONFIG
] = GB_AA_CONFIG_AA_DISABLE
;
2286 r300
->hw
.ga_point_s0
.cmd
[1] = r300PackFloat32(0.0);
2287 r300
->hw
.ga_point_s0
.cmd
[2] = r300PackFloat32(0.0);
2288 r300
->hw
.ga_point_s0
.cmd
[3] = r300PackFloat32(1.0);
2289 r300
->hw
.ga_point_s0
.cmd
[4] = r300PackFloat32(1.0);
2291 r300
->hw
.ga_triangle_stipple
.cmd
[1] = 0x00050005;
2293 r300PointSize(ctx
, 1.0);
2295 r300
->hw
.ga_point_minmax
.cmd
[1] = 0x18000006;
2296 r300
->hw
.ga_point_minmax
.cmd
[2] = 0x00020006;
2297 r300
->hw
.ga_point_minmax
.cmd
[3] = r300PackFloat32(1.0 / 192.0);
2299 r300LineWidth(ctx
, 1.0);
2301 r300
->hw
.ga_line_stipple
.cmd
[1] = 0;
2302 r300
->hw
.ga_line_stipple
.cmd
[2] = r300PackFloat32(0.0);
2303 r300
->hw
.ga_line_stipple
.cmd
[3] = r300PackFloat32(1.0);
2305 r300ShadeModel(ctx
, ctx
->Light
.ShadeModel
);
2307 r300PolygonMode(ctx
, GL_FRONT
, ctx
->Polygon
.FrontMode
);
2308 r300PolygonMode(ctx
, GL_BACK
, ctx
->Polygon
.BackMode
);
2309 r300
->hw
.zbias_cntl
.cmd
[1] = 0x00000000;
2311 r300PolygonOffset(ctx
, ctx
->Polygon
.OffsetFactor
,
2312 ctx
->Polygon
.OffsetUnits
);
2313 r300Enable(ctx
, GL_POLYGON_OFFSET_POINT
, ctx
->Polygon
.OffsetPoint
);
2314 r300Enable(ctx
, GL_POLYGON_OFFSET_LINE
, ctx
->Polygon
.OffsetLine
);
2315 r300Enable(ctx
, GL_POLYGON_OFFSET_FILL
, ctx
->Polygon
.OffsetFill
);
2317 r300
->hw
.su_depth_scale
.cmd
[1] = 0x4B7FFFFF;
2318 r300
->hw
.su_depth_scale
.cmd
[2] = 0x00000000;
2320 r300
->hw
.sc_hyperz
.cmd
[1] = 0x0000001C;
2321 r300
->hw
.sc_hyperz
.cmd
[2] = 0x2DA49525;
2323 r300
->hw
.sc_screendoor
.cmd
[1] = 0x00FFFFFF;
2325 r300
->hw
.us_out_fmt
.cmd
[1] = R500_OUT_FMT_C4_8
|
2326 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2327 r300
->hw
.us_out_fmt
.cmd
[2] = R500_OUT_FMT_UNUSED
|
2328 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2329 r300
->hw
.us_out_fmt
.cmd
[3] = R500_OUT_FMT_UNUSED
|
2330 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2331 r300
->hw
.us_out_fmt
.cmd
[4] = R500_OUT_FMT_UNUSED
|
2332 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2333 r300
->hw
.us_out_fmt
.cmd
[5] = R300_W_FMT_W24
;
2335 r300Enable(ctx
, GL_FOG
, ctx
->Fog
.Enabled
);
2336 r300Fogfv(ctx
, GL_FOG_MODE
, NULL
);
2337 r300Fogfv(ctx
, GL_FOG_DENSITY
, &ctx
->Fog
.Density
);
2338 r300Fogfv(ctx
, GL_FOG_START
, &ctx
->Fog
.Start
);
2339 r300Fogfv(ctx
, GL_FOG_END
, &ctx
->Fog
.End
);
2340 r300Fogfv(ctx
, GL_FOG_COLOR
, ctx
->Fog
.Color
);
2341 r300Fogfv(ctx
, GL_FOG_COORDINATE_SOURCE_EXT
, NULL
);
2343 r300
->hw
.fg_depth_src
.cmd
[1] = 0;
2345 r300
->hw
.rb3d_cctl
.cmd
[1] = 0;
2347 r300BlendColor(ctx
, ctx
->Color
.BlendColor
);
2349 r300
->hw
.rb3d_dither_ctl
.cmd
[1] = 0;
2350 r300
->hw
.rb3d_dither_ctl
.cmd
[2] = 0;
2351 r300
->hw
.rb3d_dither_ctl
.cmd
[3] = 0;
2352 r300
->hw
.rb3d_dither_ctl
.cmd
[4] = 0;
2353 r300
->hw
.rb3d_dither_ctl
.cmd
[5] = 0;
2354 r300
->hw
.rb3d_dither_ctl
.cmd
[6] = 0;
2355 r300
->hw
.rb3d_dither_ctl
.cmd
[7] = 0;
2356 r300
->hw
.rb3d_dither_ctl
.cmd
[8] = 0;
2357 r300
->hw
.rb3d_dither_ctl
.cmd
[9] = 0;
2359 r300
->hw
.rb3d_aaresolve_ctl
.cmd
[1] = 0;
2361 r300
->hw
.rb3d_discard_src_pixel_lte_threshold
.cmd
[1] = 0x00000000;
2362 r300
->hw
.rb3d_discard_src_pixel_lte_threshold
.cmd
[2] = 0xffffffff;
2364 rrb
= r300
->radeon
.state
.depth
.rrb
;
2365 if (rrb
&& rrb
->bo
&& (rrb
->bo
->flags
& RADEON_BO_FLAGS_MACRO_TILE
)) {
2366 /* XXX: Turn off when clearing buffers ? */
2367 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] |= R300_DEPTHMACROTILE_ENABLE
;
2369 if (ctx
->Visual
.depthBits
== 24)
2370 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] |=
2371 R300_DEPTHMICROTILE_TILED
;
2374 r300
->hw
.zb_depthclearvalue
.cmd
[1] = 0;
2376 switch (ctx
->Visual
.depthBits
) {
2378 r300
->hw
.zstencil_format
.cmd
[1] = R300_DEPTHFORMAT_16BIT_INT_Z
;
2381 r300
->hw
.zstencil_format
.cmd
[1] = R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL
;
2384 fprintf(stderr
, "Error: Unsupported depth %d... exiting\n", ctx
->Visual
.depthBits
);
2388 r300
->hw
.zstencil_format
.cmd
[2] = R300_ZTOP_DISABLE
;
2389 r300
->hw
.zstencil_format
.cmd
[3] = 0x00000003;
2390 r300
->hw
.zstencil_format
.cmd
[4] = 0x00000000;
2391 r300SetEarlyZState(ctx
);
2393 r300
->hw
.unk4F30
.cmd
[1] = 0;
2394 r300
->hw
.unk4F30
.cmd
[2] = 0;
2396 r300
->hw
.zb_hiz_offset
.cmd
[1] = 0;
2398 r300
->hw
.zb_hiz_pitch
.cmd
[1] = 0;
2400 r300VapCntl(r300
, 0, 0, 0);
2402 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_0
] = 0;
2403 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_1
] = 0;
2404 r300
->hw
.vps
.cmd
[R300_VPS_POINTSIZE
] = r300PackFloat32(1.0);
2405 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_3
] = 0;
2408 r300
->hw
.all_dirty
= GL_TRUE
;
2411 void r300UpdateShaders(r300ContextPtr rmesa
)
2414 struct r300_vertex_program
*vp
;
2417 ctx
= rmesa
->radeon
.glCtx
;
2419 if (rmesa
->radeon
.NewGLState
&& hw_tcl_on
) {
2420 rmesa
->radeon
.NewGLState
= 0;
2422 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
2423 rmesa
->temp_attrib
[i
] =
2424 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
];
2425 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] =
2426 &rmesa
->dummy_attrib
[i
];
2429 _tnl_UpdateFixedFunctionProgram(ctx
);
2431 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
2432 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] =
2433 rmesa
->temp_attrib
[i
];
2436 r300SelectVertexShader(rmesa
);
2437 vp
= (struct r300_vertex_program
*)
2438 CURRENT_VERTEX_SHADER(ctx
);
2439 /*if (vp->translated == GL_FALSE)
2440 r300TranslateVertexShader(vp); */
2441 if (vp
->translated
== GL_FALSE
) {
2442 fprintf(stderr
, "Failing back to sw-tcl\n");
2443 hw_tcl_on
= future_hw_tcl_on
= 0;
2444 r300ResetHwState(rmesa
);
2446 r300UpdateStateParameters(ctx
, _NEW_PROGRAM
);
2450 r300UpdateStateParameters(ctx
, _NEW_PROGRAM
);
2453 static const GLfloat
*get_fragmentprogram_constant(GLcontext
*ctx
,
2454 struct gl_program
*program
, struct prog_src_register srcreg
)
2456 static const GLfloat dummy
[4] = { 0, 0, 0, 0 };
2458 switch(srcreg
.File
) {
2459 case PROGRAM_LOCAL_PARAM
:
2460 return program
->LocalParams
[srcreg
.Index
];
2461 case PROGRAM_ENV_PARAM
:
2462 return ctx
->FragmentProgram
.Parameters
[srcreg
.Index
];
2463 case PROGRAM_STATE_VAR
:
2464 case PROGRAM_NAMED_PARAM
:
2465 case PROGRAM_CONSTANT
:
2466 return program
->Parameters
->ParameterValues
[srcreg
.Index
];
2468 _mesa_problem(ctx
, "get_fragmentprogram_constant: Unknown\n");
2474 static void r300SetupPixelShader(r300ContextPtr rmesa
)
2476 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
2477 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
2478 (char *)ctx
->FragmentProgram
._Current
;
2479 struct r300_fragment_program_code
*code
;
2482 if (!fp
) /* should only happenen once, just after context is created */
2485 r300TranslateFragmentShader(rmesa
, fp
);
2486 if (!fp
->translated
) {
2487 fprintf(stderr
, "%s: No valid fragment shader, exiting\n",
2493 r300SetupTextures(ctx
);
2495 R300_STATECHANGE(rmesa
, fpi
[0]);
2496 R300_STATECHANGE(rmesa
, fpi
[1]);
2497 R300_STATECHANGE(rmesa
, fpi
[2]);
2498 R300_STATECHANGE(rmesa
, fpi
[3]);
2499 rmesa
->hw
.fpi
[0].cmd
[R300_FPI_CMD_0
] = cmdpacket0(rmesa
->radeon
.radeonScreen
, R300_US_ALU_RGB_INST_0
, code
->alu
.length
);
2500 rmesa
->hw
.fpi
[1].cmd
[R300_FPI_CMD_0
] = cmdpacket0(rmesa
->radeon
.radeonScreen
, R300_US_ALU_RGB_ADDR_0
, code
->alu
.length
);
2501 rmesa
->hw
.fpi
[2].cmd
[R300_FPI_CMD_0
] = cmdpacket0(rmesa
->radeon
.radeonScreen
, R300_US_ALU_ALPHA_INST_0
, code
->alu
.length
);
2502 rmesa
->hw
.fpi
[3].cmd
[R300_FPI_CMD_0
] = cmdpacket0(rmesa
->radeon
.radeonScreen
, R300_US_ALU_ALPHA_ADDR_0
, code
->alu
.length
);
2503 for (i
= 0; i
< code
->alu
.length
; i
++) {
2504 rmesa
->hw
.fpi
[0].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst0
;
2505 rmesa
->hw
.fpi
[1].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst1
;
2506 rmesa
->hw
.fpi
[2].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst2
;
2507 rmesa
->hw
.fpi
[3].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst3
;
2510 R300_STATECHANGE(rmesa
, fp
);
2511 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL0
] = code
->cur_node
| (code
->first_node_has_tex
<< 3);
2512 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL1
] = code
->max_temp_idx
;
2513 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL2
] =
2514 (0 << R300_PFS_CNTL_ALU_OFFSET_SHIFT
) |
2515 ((code
->alu
.length
-1) << R300_PFS_CNTL_ALU_END_SHIFT
) |
2516 (0 << R300_PFS_CNTL_TEX_OFFSET_SHIFT
) |
2517 ((code
->tex
.length
? code
->tex
.length
-1 : 0) << R300_PFS_CNTL_TEX_END_SHIFT
);
2518 /* I just want to say, the way these nodes are stored.. weird.. */
2519 for (i
= 0, k
= (4 - (code
->cur_node
+ 1)); i
< 4; i
++, k
++) {
2520 if (i
< (code
->cur_node
+ 1)) {
2521 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+ k
] =
2522 (code
->node
[i
].alu_offset
<< R300_ALU_START_SHIFT
) |
2523 (code
->node
[i
].alu_end
<< R300_ALU_SIZE_SHIFT
) |
2524 (code
->node
[i
].tex_offset
<< R300_TEX_START_SHIFT
) |
2525 (code
->node
[i
].tex_end
<< R300_TEX_SIZE_SHIFT
) |
2526 code
->node
[i
].flags
;
2528 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+ (3 - i
)] = 0;
2532 R300_STATECHANGE(rmesa
, fpp
);
2533 rmesa
->hw
.fpp
.cmd
[R300_FPP_CMD_0
] = cmdpacket0(rmesa
->radeon
.radeonScreen
, R300_PFS_PARAM_0_X
, code
->const_nr
* 4);
2534 for (i
= 0; i
< code
->const_nr
; i
++) {
2535 const GLfloat
*constant
= get_fragmentprogram_constant(ctx
,
2536 &fp
->mesa_program
.Base
, code
->constant
[i
]);
2537 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 0] = r300PackFloat24(constant
[0]);
2538 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 1] = r300PackFloat24(constant
[1]);
2539 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 2] = r300PackFloat24(constant
[2]);
2540 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 3] = r300PackFloat24(constant
[3]);
2544 #define bump_r500fp_count(ptr, new_count) do{\
2545 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
2546 int _nc=(new_count)/6; \
2547 assert(_nc < 256); \
2548 if(_nc>_p->r500fp.count)_p->r500fp.count=_nc;\
2551 #define bump_r500fp_const_count(ptr, new_count) do{\
2552 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
2553 int _nc=(new_count)/4; \
2554 assert(_nc < 256); \
2555 if(_nc>_p->r500fp.count)_p->r500fp.count=_nc;\
2558 static void r500SetupPixelShader(r300ContextPtr rmesa
)
2560 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
2561 struct r500_fragment_program
*fp
= (struct r500_fragment_program
*)
2562 (char *)ctx
->FragmentProgram
._Current
;
2564 struct r500_fragment_program_code
*code
;
2566 if (!fp
) /* should only happenen once, just after context is created */
2569 ((drm_r300_cmd_header_t
*) rmesa
->hw
.r500fp
.cmd
)->r500fp
.count
= 0;
2570 ((drm_r300_cmd_header_t
*) rmesa
->hw
.r500fp_const
.cmd
)->r500fp
.count
= 0;
2572 r500TranslateFragmentShader(rmesa
, fp
);
2573 if (!fp
->translated
) {
2574 fprintf(stderr
, "%s: No valid fragment shader, exiting\n",
2580 if (fp
->mesa_program
.FogOption
!= GL_NONE
) {
2581 /* Enable HW fog. Try not to squish GL context.
2582 * (Anybody sane remembered to set glFog() opts first!) */
2583 r300SetFogState(ctx
, GL_TRUE
);
2584 ctx
->Fog
.Mode
= fp
->mesa_program
.FogOption
;
2585 r300Fogfv(ctx
, GL_FOG_MODE
, NULL
);
2587 /* Make sure HW is matching GL context. */
2588 r300SetFogState(ctx
, ctx
->Fog
.Enabled
);
2590 r300SetupTextures(ctx
);
2592 R300_STATECHANGE(rmesa
, fp
);
2593 rmesa
->hw
.fp
.cmd
[R500_FP_PIXSIZE
] = code
->max_temp_idx
;
2595 rmesa
->hw
.fp
.cmd
[R500_FP_CODE_ADDR
] =
2596 R500_US_CODE_START_ADDR(code
->inst_offset
) |
2597 R500_US_CODE_END_ADDR(code
->inst_end
);
2598 rmesa
->hw
.fp
.cmd
[R500_FP_CODE_RANGE
] =
2599 R500_US_CODE_RANGE_ADDR(code
->inst_offset
) |
2600 R500_US_CODE_RANGE_SIZE(code
->inst_end
);
2601 rmesa
->hw
.fp
.cmd
[R500_FP_CODE_OFFSET
] =
2602 R500_US_CODE_OFFSET_ADDR(0); /* FIXME when we add flow control */
2604 R300_STATECHANGE(rmesa
, r500fp
);
2605 /* Emit our shader... */
2606 for (i
= 0; i
< code
->inst_end
+1; i
++) {
2607 rmesa
->hw
.r500fp
.cmd
[i
*6+1] = code
->inst
[i
].inst0
;
2608 rmesa
->hw
.r500fp
.cmd
[i
*6+2] = code
->inst
[i
].inst1
;
2609 rmesa
->hw
.r500fp
.cmd
[i
*6+3] = code
->inst
[i
].inst2
;
2610 rmesa
->hw
.r500fp
.cmd
[i
*6+4] = code
->inst
[i
].inst3
;
2611 rmesa
->hw
.r500fp
.cmd
[i
*6+5] = code
->inst
[i
].inst4
;
2612 rmesa
->hw
.r500fp
.cmd
[i
*6+6] = code
->inst
[i
].inst5
;
2615 bump_r500fp_count(rmesa
->hw
.r500fp
.cmd
, (code
->inst_end
+ 1) * 6);
2617 R300_STATECHANGE(rmesa
, r500fp_const
);
2618 for (i
= 0; i
< code
->const_nr
; i
++) {
2619 const GLfloat
*constant
= get_fragmentprogram_constant(ctx
,
2620 &fp
->mesa_program
.Base
, code
->constant
[i
]);
2621 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 0] = r300PackFloat32(constant
[0]);
2622 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 1] = r300PackFloat32(constant
[1]);
2623 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 2] = r300PackFloat32(constant
[2]);
2624 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 3] = r300PackFloat32(constant
[3]);
2626 bump_r500fp_const_count(rmesa
->hw
.r500fp_const
.cmd
, code
->const_nr
* 4);
2630 void r300UpdateShaderStates(r300ContextPtr rmesa
)
2633 ctx
= rmesa
->radeon
.glCtx
;
2635 r300SetEarlyZState(ctx
);
2637 GLuint fgdepthsrc
= R300_FG_DEPTH_SRC_SCAN
;
2638 if (current_fragment_program_writes_depth(ctx
))
2639 fgdepthsrc
= R300_FG_DEPTH_SRC_SHADER
;
2640 if (fgdepthsrc
!= rmesa
->hw
.fg_depth_src
.cmd
[1]) {
2641 R300_STATECHANGE(rmesa
, fg_depth_src
);
2642 rmesa
->hw
.fg_depth_src
.cmd
[1] = fgdepthsrc
;
2645 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
2646 r500SetupPixelShader(rmesa
);
2648 r300SetupPixelShader(rmesa
);
2650 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
2651 r500SetupRSUnit(ctx
);
2653 r300SetupRSUnit(ctx
);
2655 if ((rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
2656 r300SetupVertexProgram(rmesa
);
2661 * Called by Mesa after an internal state update.
2663 static void r300InvalidateState(GLcontext
* ctx
, GLuint new_state
)
2665 r300ContextPtr r300
= R300_CONTEXT(ctx
);
2667 _swrast_InvalidateState(ctx
, new_state
);
2668 _swsetup_InvalidateState(ctx
, new_state
);
2669 _vbo_InvalidateState(ctx
, new_state
);
2670 _tnl_InvalidateState(ctx
, new_state
);
2671 _ae_invalidate_state(ctx
, new_state
);
2673 if (new_state
& (_NEW_BUFFERS
| _NEW_COLOR
| _NEW_PIXEL
)) {
2674 r300UpdateDrawBuffer(ctx
);
2677 r300UpdateStateParameters(ctx
, new_state
);
2679 r300
->radeon
.NewGLState
|= new_state
;
2683 * Calculate initial hardware state and register state functions.
2684 * Assumes that the command buffer and state atoms have been
2685 * initialized already.
2687 void r300InitState(r300ContextPtr r300
)
2689 GLcontext
*ctx
= r300
->radeon
.glCtx
;
2692 radeonInitState(&r300
->radeon
);
2694 switch (ctx
->Visual
.depthBits
) {
2696 r300
->radeon
.state
.depth
.scale
= 1.0 / (GLfloat
) 0xffff;
2697 depth_fmt
= R300_DEPTHFORMAT_16BIT_INT_Z
;
2700 r300
->radeon
.state
.depth
.scale
= 1.0 / (GLfloat
) 0xffffff;
2701 depth_fmt
= R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL
;
2704 fprintf(stderr
, "Error: Unsupported depth %d... exiting\n",
2705 ctx
->Visual
.depthBits
);
2709 /* Only have hw stencil when depth buffer is 24 bits deep */
2710 r300
->radeon
.state
.stencil
.hwBuffer
= (ctx
->Visual
.stencilBits
> 0 &&
2711 ctx
->Visual
.depthBits
== 24);
2713 memset(&(r300
->state
.texture
), 0, sizeof(r300
->state
.texture
));
2715 r300ResetHwState(r300
);
2718 static void r300RenderMode(GLcontext
* ctx
, GLenum mode
)
2720 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
2725 void r300UpdateClipPlanes( GLcontext
*ctx
)
2727 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
2730 for (p
= 0; p
< ctx
->Const
.MaxClipPlanes
; p
++) {
2731 if (ctx
->Transform
.ClipPlanesEnabled
& (1 << p
)) {
2732 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
2734 R300_STATECHANGE( rmesa
, vpucp
[p
] );
2735 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_X
] = ip
[0];
2736 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_Y
] = ip
[1];
2737 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_Z
] = ip
[2];
2738 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_W
] = ip
[3];
2744 * Initialize driver's state callback functions
2746 void r300InitStateFuncs(struct dd_function_table
*functions
)
2748 radeonInitStateFuncs(functions
);
2750 functions
->UpdateState
= r300InvalidateState
;
2751 functions
->AlphaFunc
= r300AlphaFunc
;
2752 functions
->BlendColor
= r300BlendColor
;
2753 functions
->BlendEquationSeparate
= r300BlendEquationSeparate
;
2754 functions
->BlendFuncSeparate
= r300BlendFuncSeparate
;
2755 functions
->Enable
= r300Enable
;
2756 functions
->ColorMask
= r300ColorMask
;
2757 functions
->DepthFunc
= r300DepthFunc
;
2758 functions
->DepthMask
= r300DepthMask
;
2759 functions
->CullFace
= r300CullFace
;
2760 functions
->Fogfv
= r300Fogfv
;
2761 functions
->FrontFace
= r300FrontFace
;
2762 functions
->ShadeModel
= r300ShadeModel
;
2763 functions
->LogicOpcode
= r300LogicOpcode
;
2765 /* ARB_point_parameters */
2766 functions
->PointParameterfv
= r300PointParameter
;
2768 /* Stencil related */
2769 functions
->StencilFuncSeparate
= r300StencilFuncSeparate
;
2770 functions
->StencilMaskSeparate
= r300StencilMaskSeparate
;
2771 functions
->StencilOpSeparate
= r300StencilOpSeparate
;
2773 /* Viewport related */
2774 functions
->Viewport
= r300Viewport
;
2775 functions
->DepthRange
= r300DepthRange
;
2776 functions
->PointSize
= r300PointSize
;
2777 functions
->LineWidth
= r300LineWidth
;
2779 functions
->PolygonOffset
= r300PolygonOffset
;
2780 functions
->PolygonMode
= r300PolygonMode
;
2782 functions
->RenderMode
= r300RenderMode
;
2784 functions
->ClipPlane
= r300ClipPlane
;