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
->state
.stencil
.hw_stencil
) {
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
->state
.depth
.scale
;
1088 GLfloat tz
= v
[MAT_TZ
] * rmesa
->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 /* Don't pipeline viewport changes, conflict with window offset
1105 * setting below. Could apply deltas to rescue pipelined viewport
1106 * values, or keep the originals hanging around.
1108 r300UpdateWindow(ctx
);
1111 static void r300DepthRange(GLcontext
* ctx
, GLclampd nearval
, GLclampd farval
)
1113 r300UpdateWindow(ctx
);
1116 void r300UpdateViewportOffset(GLcontext
* ctx
)
1118 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1119 __DRIdrawablePrivate
*dPriv
= ((radeonContextPtr
) rmesa
)->dri
.drawable
;
1120 GLfloat xoffset
= (GLfloat
) dPriv
->x
;
1121 GLfloat yoffset
= (GLfloat
) dPriv
->y
+ dPriv
->h
;
1122 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1124 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1125 GLfloat ty
= (-v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1127 if (rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] != r300PackFloat32(tx
) ||
1128 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] != r300PackFloat32(ty
)) {
1129 /* Note: this should also modify whatever data the context reset
1132 R300_STATECHANGE(rmesa
, vpt
);
1133 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
1134 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
1138 radeonUpdateScissor(ctx
);
1142 * Tell the card where to render (offset, pitch).
1143 * Effected by glDrawBuffer, etc
1145 void r300UpdateDrawBuffer(GLcontext
* ctx
)
1147 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1148 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
1149 struct radeon_renderbuffer
*rrb
;
1151 if (fb
->_ColorDrawBufferIndexes
[0] == BUFFER_FRONT_LEFT
) {
1154 (void *) fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
;
1155 } else if (fb
->_ColorDrawBufferIndexes
[0] == BUFFER_BACK_LEFT
) {
1157 rrb
= (void *) fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
;
1159 /* drawing to multiple buffers, or none */
1166 R300_STATECHANGE(rmesa
, cb
);
1169 R200_STATECHANGE(rmesa
, ctx
);
1171 /* Note: we used the (possibly) page-flipped values */
1172 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLOROFFSET
]
1173 = ((drb
->flippedOffset
+ rmesa
->r200Screen
->fbLocation
)
1174 & R200_COLOROFFSET_MASK
);
1175 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] = drb
->flippedPitch
;
1177 if (rmesa
->sarea
->tiling_enabled
) {
1178 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] |=
1179 R200_COLOR_TILE_ENABLE
;
1185 r300FetchStateParameter(GLcontext
* ctx
,
1186 const gl_state_index state
[STATE_LENGTH
],
1189 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1192 case STATE_INTERNAL
:
1194 case STATE_R300_WINDOW_DIMENSION
:
1195 value
[0] = r300
->radeon
.dri
.drawable
->w
* 0.5f
; /* width*0.5 */
1196 value
[1] = r300
->radeon
.dri
.drawable
->h
* 0.5f
; /* height*0.5 */
1197 value
[2] = 0.5F
; /* for moving range [-1 1] -> [0 1] */
1198 value
[3] = 1.0F
; /* not used */
1201 case STATE_R300_TEXRECT_FACTOR
:{
1202 struct gl_texture_object
*t
=
1203 ctx
->Texture
.Unit
[state
[2]].CurrentRect
;
1205 if (t
&& t
->Image
[0][t
->BaseLevel
]) {
1206 struct gl_texture_image
*image
=
1207 t
->Image
[0][t
->BaseLevel
];
1208 value
[0] = 1.0 / image
->Width2
;
1209 value
[1] = 1.0 / image
->Height2
;
1230 * Update R300's own internal state parameters.
1231 * For now just STATE_R300_WINDOW_DIMENSION
1233 void r300UpdateStateParameters(GLcontext
* ctx
, GLuint new_state
)
1235 struct r300_fragment_program
*fp
;
1236 struct gl_program_parameter_list
*paramList
;
1239 if (!(new_state
& (_NEW_BUFFERS
| _NEW_PROGRAM
)))
1242 fp
= (struct r300_fragment_program
*)ctx
->FragmentProgram
._Current
;
1246 paramList
= fp
->mesa_program
.Base
.Parameters
;
1251 for (i
= 0; i
< paramList
->NumParameters
; i
++) {
1252 if (paramList
->Parameters
[i
].Type
== PROGRAM_STATE_VAR
) {
1253 r300FetchStateParameter(ctx
,
1254 paramList
->Parameters
[i
].
1256 paramList
->ParameterValues
[i
]);
1261 /* =============================================================
1264 static void r300PolygonOffset(GLcontext
* ctx
, GLfloat factor
, GLfloat units
)
1266 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1267 GLfloat constant
= units
;
1269 switch (ctx
->Visual
.depthBits
) {
1280 /* fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */
1282 R300_STATECHANGE(rmesa
, zbs
);
1283 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_FACTOR
] = r300PackFloat32(factor
);
1284 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_CONSTANT
] = r300PackFloat32(constant
);
1285 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_FACTOR
] = r300PackFloat32(factor
);
1286 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_CONSTANT
] = r300PackFloat32(constant
);
1289 /* Routing and texture-related */
1291 /* r300 doesnt handle GL_CLAMP and GL_MIRROR_CLAMP_EXT correctly when filter is NEAREST.
1292 * Since texwrap produces same results for GL_CLAMP and GL_CLAMP_TO_EDGE we use them instead.
1293 * We need to recalculate wrap modes whenever filter mode is changed because someone might do:
1294 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1295 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1296 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1297 * Since r300 completely ignores R300_TX_CLAMP when either min or mag is nearest it cant handle
1298 * combinations where only one of them is nearest.
1300 static unsigned long gen_fixed_filter(unsigned long f
)
1302 unsigned long mag
, min
, needs_fixing
= 0;
1305 /* We ignore MIRROR bit so we dont have to do everything twice */
1306 if ((f
& ((7 - 1) << R300_TX_WRAP_S_SHIFT
)) ==
1307 (R300_TX_CLAMP
<< R300_TX_WRAP_S_SHIFT
)) {
1310 if ((f
& ((7 - 1) << R300_TX_WRAP_T_SHIFT
)) ==
1311 (R300_TX_CLAMP
<< R300_TX_WRAP_T_SHIFT
)) {
1314 if ((f
& ((7 - 1) << R300_TX_WRAP_R_SHIFT
)) ==
1315 (R300_TX_CLAMP
<< R300_TX_WRAP_R_SHIFT
)) {
1322 mag
= f
& R300_TX_MAG_FILTER_MASK
;
1323 min
= f
& (R300_TX_MIN_FILTER_MASK
|R300_TX_MIN_FILTER_MIP_MASK
);
1325 /* TODO: Check for anisto filters too */
1326 if ((mag
!= R300_TX_MAG_FILTER_NEAREST
)
1327 && (min
!= R300_TX_MIN_FILTER_NEAREST
))
1330 /* r300 cant handle these modes hence we force nearest to linear */
1331 if ((mag
== R300_TX_MAG_FILTER_NEAREST
)
1332 && (min
!= R300_TX_MIN_FILTER_NEAREST
)) {
1333 f
&= ~R300_TX_MAG_FILTER_NEAREST
;
1334 f
|= R300_TX_MAG_FILTER_LINEAR
;
1338 if ((min
== R300_TX_MIN_FILTER_NEAREST
)
1339 && (mag
!= R300_TX_MAG_FILTER_NEAREST
)) {
1340 f
&= ~R300_TX_MIN_FILTER_NEAREST
;
1341 f
|= R300_TX_MIN_FILTER_LINEAR
;
1345 /* Both are nearest */
1346 if (needs_fixing
& 1) {
1347 f
&= ~((7 - 1) << R300_TX_WRAP_S_SHIFT
);
1348 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_S_SHIFT
;
1350 if (needs_fixing
& 2) {
1351 f
&= ~((7 - 1) << R300_TX_WRAP_T_SHIFT
);
1352 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_T_SHIFT
;
1354 if (needs_fixing
& 4) {
1355 f
&= ~((7 - 1) << R300_TX_WRAP_R_SHIFT
);
1356 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_R_SHIFT
;
1361 static void r300SetupFragmentShaderTextures(GLcontext
*ctx
, int *tmu_mappings
)
1363 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1365 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
1366 (char *)ctx
->FragmentProgram
._Current
;
1367 struct r300_fragment_program_code
*code
= &fp
->code
;
1369 R300_STATECHANGE(r300
, fpt
);
1371 for (i
= 0; i
< code
->tex
.length
; i
++) {
1376 unit
= code
->tex
.inst
[i
] >> R300_TEX_ID_SHIFT
;
1379 val
= code
->tex
.inst
[i
];
1380 val
&= ~R300_TEX_ID_MASK
;
1383 (val
& R300_TEX_INST_MASK
) >> R300_TEX_INST_SHIFT
;
1384 if (opcode
== R300_TEX_OP_KIL
) {
1385 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1387 if (tmu_mappings
[unit
] >= 0) {
1389 tmu_mappings
[unit
] <<
1391 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1393 // We get here when the corresponding texture image is incomplete
1394 // (e.g. incomplete mipmaps etc.)
1395 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1400 r300
->hw
.fpt
.cmd
[R300_FPT_CMD_0
] =
1401 cmdpacket0(R300_US_TEX_INST_0
, code
->tex
.length
);
1404 static void r500SetupFragmentShaderTextures(GLcontext
*ctx
, int *tmu_mappings
)
1407 struct r500_fragment_program
*fp
= (struct r500_fragment_program
*)
1408 (char *)ctx
->FragmentProgram
._Current
;
1409 struct r500_fragment_program_code
*code
= &fp
->code
;
1411 /* find all the texture instructions and relocate the texture units */
1412 for (i
= 0; i
< code
->inst_end
+ 1; i
++) {
1413 if ((code
->inst
[i
].inst0
& 0x3) == R500_INST_TYPE_TEX
) {
1415 int unit
, opcode
, new_unit
;
1417 val
= code
->inst
[i
].inst1
;
1419 unit
= (val
>> 16) & 0xf;
1421 val
&= ~(0xf << 16);
1423 opcode
= val
& (0x7 << 22);
1424 if (opcode
== R500_TEX_INST_TEXKILL
) {
1427 if (tmu_mappings
[unit
] >= 0) {
1428 new_unit
= tmu_mappings
[unit
];
1433 val
|= R500_TEX_ID(new_unit
);
1434 code
->inst
[i
].inst1
= val
;
1439 static GLuint
translate_lod_bias(GLfloat bias
)
1441 GLint b
= (int)(bias
*32);
1444 else if (b
< -(1 << 9))
1446 return (((GLuint
)b
) << R300_LOD_BIAS_SHIFT
) & R300_LOD_BIAS_MASK
;
1449 static void r300SetupTextures(GLcontext
* ctx
)
1452 struct r300_tex_obj
*t
;
1453 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1455 int last_hw_tmu
= -1; /* -1 translates into no setup costs for fields */
1456 int tmu_mappings
[R300_MAX_TEXTURE_UNITS
] = { -1, };
1457 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
1458 (char *)ctx
->FragmentProgram
._Current
;
1460 R300_STATECHANGE(r300
, txe
);
1461 R300_STATECHANGE(r300
, tex
.filter
);
1462 R300_STATECHANGE(r300
, tex
.filter_1
);
1463 R300_STATECHANGE(r300
, tex
.size
);
1464 R300_STATECHANGE(r300
, tex
.format
);
1465 R300_STATECHANGE(r300
, tex
.pitch
);
1466 R300_STATECHANGE(r300
, tex
.offset
);
1467 R300_STATECHANGE(r300
, tex
.chroma_key
);
1468 R300_STATECHANGE(r300
, tex
.border_color
);
1470 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] = 0x0;
1472 mtu
= r300
->radeon
.glCtx
->Const
.MaxTextureUnits
;
1473 if (RADEON_DEBUG
& DEBUG_STATE
)
1474 fprintf(stderr
, "mtu=%d\n", mtu
);
1476 if (mtu
> R300_MAX_TEXTURE_UNITS
) {
1478 "Aiiee ! mtu=%d is greater than R300_MAX_TEXTURE_UNITS=%d\n",
1479 mtu
, R300_MAX_TEXTURE_UNITS
);
1483 /* We cannot let disabled tmu offsets pass DRM */
1484 for (i
= 0; i
< mtu
; i
++) {
1485 if (ctx
->Texture
.Unit
[i
]._ReallyEnabled
) {
1486 tmu_mappings
[i
] = hw_tmu
;
1488 t
= r300_tex_obj(ctx
->Texture
.Unit
[i
]._Current
);
1492 if ((t
->format
& 0xffffff00) == 0xffffff00) {
1494 ("unknown texture format (entry %x) encountered. Help me !\n",
1498 if (RADEON_DEBUG
& DEBUG_STATE
)
1500 "Activating texture unit %d\n", i
);
1502 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] |= (1 << hw_tmu
);
1504 r300
->hw
.tex
.filter
.cmd
[R300_TEX_VALUE_0
+
1506 gen_fixed_filter(t
->filter
) | (hw_tmu
<< 28);
1507 /* Note: There is a LOD bias per texture unit and a LOD bias
1508 * per texture object. We add them here to get the correct behaviour.
1509 * (The per-texture object LOD bias was introduced in OpenGL 1.4
1510 * and is not present in the EXT_texture_object extension).
1512 r300
->hw
.tex
.filter_1
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] =
1514 translate_lod_bias(ctx
->Texture
.Unit
[i
].LodBias
+ t
->base
.LodBias
);
1515 r300
->hw
.tex
.size
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] =
1517 r300
->hw
.tex
.format
.cmd
[R300_TEX_VALUE_0
+
1518 hw_tmu
] = t
->format
;
1519 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] =
1521 r300
->hw
.textures
[hw_tmu
] = t
;
1523 if (t
->tile_bits
& R300_TXO_MACRO_TILE
) {
1524 WARN_ONCE("macro tiling enabled!\n");
1527 if (t
->tile_bits
& R300_TXO_MICRO_TILE
) {
1528 WARN_ONCE("micro tiling enabled!\n");
1531 r300
->hw
.tex
.chroma_key
.cmd
[R300_TEX_VALUE_0
+
1533 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_VALUE_0
+
1537 last_hw_tmu
= hw_tmu
;
1543 r300
->hw
.tex
.filter
.cmd
[R300_TEX_CMD_0
] =
1544 cmdpacket0(R300_TX_FILTER0_0
, last_hw_tmu
+ 1);
1545 r300
->hw
.tex
.filter_1
.cmd
[R300_TEX_CMD_0
] =
1546 cmdpacket0(R300_TX_FILTER1_0
, last_hw_tmu
+ 1);
1547 r300
->hw
.tex
.size
.cmd
[R300_TEX_CMD_0
] =
1548 cmdpacket0(R300_TX_SIZE_0
, last_hw_tmu
+ 1);
1549 r300
->hw
.tex
.format
.cmd
[R300_TEX_CMD_0
] =
1550 cmdpacket0(R300_TX_FORMAT_0
, last_hw_tmu
+ 1);
1551 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_CMD_0
] =
1552 cmdpacket0(R300_TX_FORMAT2_0
, last_hw_tmu
+ 1);
1553 r300
->hw
.tex
.offset
.cmd
[R300_TEX_CMD_0
] =
1554 cmdpacket0(R300_TX_OFFSET_0
, last_hw_tmu
+ 1);
1555 r300
->hw
.tex
.chroma_key
.cmd
[R300_TEX_CMD_0
] =
1556 cmdpacket0(R300_TX_CHROMA_KEY_0
, last_hw_tmu
+ 1);
1557 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_CMD_0
] =
1558 cmdpacket0(R300_TX_BORDER_COLOR_0
, last_hw_tmu
+ 1);
1560 if (!fp
) /* should only happenen once, just after context is created */
1563 if (r300
->radeon
.radeonScreen
->chip_family
< CHIP_FAMILY_RV515
) {
1564 if (fp
->mesa_program
.UsesKill
&& last_hw_tmu
< 0) {
1565 // The KILL operation requires the first texture unit
1567 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] |= 1;
1568 r300
->hw
.tex
.filter
.cmd
[R300_TEX_VALUE_0
] = 0;
1569 r300
->hw
.tex
.filter
.cmd
[R300_TEX_CMD_0
] =
1570 cmdpacket0(R300_TX_FILTER0_0
, 1);
1572 r300SetupFragmentShaderTextures(ctx
, tmu_mappings
);
1574 r500SetupFragmentShaderTextures(ctx
, tmu_mappings
);
1576 if (RADEON_DEBUG
& DEBUG_STATE
)
1577 fprintf(stderr
, "TX_ENABLE: %08x last_hw_tmu=%d\n",
1578 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
], last_hw_tmu
);
1581 union r300_outputs_written
{
1582 GLuint vp_outputs
; /* hw_tcl_on */
1583 DECLARE_RENDERINPUTS(index_bitset
); /* !hw_tcl_on */
1586 #define R300_OUTPUTS_WRITTEN_TEST(ow, vp_result, tnl_attrib) \
1587 ((hw_tcl_on) ? (ow).vp_outputs & (1 << (vp_result)) : \
1588 RENDERINPUTS_TEST( (ow.index_bitset), (tnl_attrib) ))
1590 static void r300SetupRSUnit(GLcontext
* ctx
)
1592 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1593 /* I'm still unsure if these are needed */
1594 GLuint interp_col
[8];
1595 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1596 struct vertex_buffer
*VB
= &tnl
->vb
;
1597 union r300_outputs_written OutputsWritten
;
1599 int fp_reg
, high_rr
;
1601 int rs_tex_count
= 0, rs_col_count
= 0;
1604 memset(interp_col
, 0, sizeof(interp_col
));
1607 OutputsWritten
.vp_outputs
= CURRENT_VERTEX_SHADER(ctx
)->key
.OutputsWritten
;
1609 RENDERINPUTS_COPY(OutputsWritten
.index_bitset
, r300
->state
.render_inputs_bitset
);
1611 if (ctx
->FragmentProgram
._Current
)
1612 InputsRead
= ctx
->FragmentProgram
._Current
->Base
.InputsRead
;
1614 fprintf(stderr
, "No ctx->FragmentProgram._Current!!\n");
1615 return; /* This should only ever happen once.. */
1618 R300_STATECHANGE(r300
, ri
);
1619 R300_STATECHANGE(r300
, rc
);
1620 R300_STATECHANGE(r300
, rr
);
1622 fp_reg
= col_interp_nr
= high_rr
= 0;
1624 r300
->hw
.rr
.cmd
[R300_RR_INST_1
] = 0;
1626 if (InputsRead
& FRAG_BIT_WPOS
) {
1627 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++)
1628 if (!(InputsRead
& (FRAG_BIT_TEX0
<< i
)))
1631 if (i
== ctx
->Const
.MaxTextureUnits
) {
1632 fprintf(stderr
, "\tno free texcoord found...\n");
1636 InputsRead
|= (FRAG_BIT_TEX0
<< i
);
1637 InputsRead
&= ~FRAG_BIT_WPOS
;
1640 if (InputsRead
& FRAG_BIT_COL0
) {
1641 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR0
]->size
;
1642 interp_col
[0] |= R300_RS_COL_PTR(rs_col_count
);
1644 interp_col
[0] |= R300_RS_COL_FMT(R300_RS_COL_FMT_RGB1
);
1645 rs_col_count
+= count
;
1648 interp_col
[0] = R300_RS_COL_FMT(R300_RS_COL_FMT_0001
);
1650 if (InputsRead
& FRAG_BIT_COL1
) {
1651 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR1
]->size
;
1653 interp_col
[1] |= R300_RS_COL_FMT(R300_RS_COL_FMT_RGB0
);
1654 interp_col
[1] |= R300_RS_COL_PTR(1);
1655 rs_col_count
+= count
;
1659 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
1662 /* with TCL we always seem to route 4 components */
1666 count
= VB
->AttribPtr
[_TNL_ATTRIB_TEX(i
)]->size
;
1668 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ i
] = interp_col
[i
] | rs_tex_count
;
1670 case 4: swiz
= R300_RS_SEL_S(0) | R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(3); break;
1671 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;
1674 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;
1677 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ i
] |= swiz
;
1679 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ fp_reg
] = 0;
1680 if (InputsRead
& (FRAG_BIT_TEX0
<< i
)) {
1682 rs_tex_count
+= count
;
1684 //assert(r300->state.texture.tc_count != 0);
1685 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ fp_reg
] |= R300_RS_INST_TEX_CN_WRITE
| i
/* source INTERP */
1686 | (fp_reg
<< R300_RS_INST_TEX_ADDR_SHIFT
);
1689 /* Passing invalid data here can lock the GPU. */
1690 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_TEX0
+ i
, _TNL_ATTRIB_TEX(i
))) {
1691 InputsRead
&= ~(FRAG_BIT_TEX0
<< i
);
1694 WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i
);
1699 if (InputsRead
& FRAG_BIT_COL0
) {
1700 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL0
, _TNL_ATTRIB_COLOR0
)) {
1701 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
);
1702 InputsRead
&= ~FRAG_BIT_COL0
;
1705 WARN_ONCE("fragprog wants col0, vp doesn't provide it\n");
1709 if (InputsRead
& FRAG_BIT_COL1
) {
1710 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL1
, _TNL_ATTRIB_COLOR1
)) {
1711 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
);
1712 InputsRead
&= ~FRAG_BIT_COL1
;
1717 WARN_ONCE("fragprog wants col1, vp doesn't provide it\n");
1721 /* Need at least one. This might still lock as the values are undefined... */
1722 if (rs_tex_count
== 0 && col_interp_nr
== 0) {
1723 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
);
1727 r300
->hw
.rc
.cmd
[1] = 0 | (rs_tex_count
<< R300_IT_COUNT_SHIFT
)
1728 | (col_interp_nr
<< R300_IC_COUNT_SHIFT
)
1731 assert(high_rr
>= 0);
1732 r300
->hw
.rr
.cmd
[R300_RR_CMD_0
] = cmdpacket0(R300_RS_INST_0
, high_rr
+ 1);
1733 r300
->hw
.rc
.cmd
[2] = high_rr
;
1736 WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead
);
1739 static void r500SetupRSUnit(GLcontext
* ctx
)
1741 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1742 /* I'm still unsure if these are needed */
1743 GLuint interp_col
[8];
1744 union r300_outputs_written OutputsWritten
;
1745 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1746 struct vertex_buffer
*VB
= &tnl
->vb
;
1748 int fp_reg
, high_rr
;
1749 int rs_col_count
= 0;
1750 int in_texcoords
, col_interp_nr
;
1753 memset(interp_col
, 0, sizeof(interp_col
));
1755 OutputsWritten
.vp_outputs
= CURRENT_VERTEX_SHADER(ctx
)->key
.OutputsWritten
;
1757 RENDERINPUTS_COPY(OutputsWritten
.index_bitset
, r300
->state
.render_inputs_bitset
);
1759 if (ctx
->FragmentProgram
._Current
)
1760 InputsRead
= ctx
->FragmentProgram
._Current
->Base
.InputsRead
;
1762 fprintf(stderr
, "No ctx->FragmentProgram._Current!!\n");
1763 return; /* This should only ever happen once.. */
1766 R300_STATECHANGE(r300
, ri
);
1767 R300_STATECHANGE(r300
, rc
);
1768 R300_STATECHANGE(r300
, rr
);
1770 fp_reg
= col_interp_nr
= high_rr
= in_texcoords
= 0;
1772 r300
->hw
.rr
.cmd
[R300_RR_INST_1
] = 0;
1774 if (InputsRead
& FRAG_BIT_WPOS
) {
1775 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++)
1776 if (!(InputsRead
& (FRAG_BIT_TEX0
<< i
)))
1779 if (i
== ctx
->Const
.MaxTextureUnits
) {
1780 fprintf(stderr
, "\tno free texcoord found...\n");
1784 InputsRead
|= (FRAG_BIT_TEX0
<< i
);
1785 InputsRead
&= ~FRAG_BIT_WPOS
;
1788 if (InputsRead
& FRAG_BIT_COL0
) {
1789 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR0
]->size
;
1790 interp_col
[0] |= R500_RS_COL_PTR(rs_col_count
);
1792 interp_col
[0] |= R500_RS_COL_FMT(R300_RS_COL_FMT_RGB1
);
1793 rs_col_count
+= count
;
1796 interp_col
[0] = R500_RS_COL_FMT(R300_RS_COL_FMT_0001
);
1798 if (InputsRead
& FRAG_BIT_COL1
) {
1799 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR1
]->size
;
1800 interp_col
[1] |= R500_RS_COL_PTR(1);
1802 interp_col
[1] |= R500_RS_COL_FMT(R300_RS_COL_FMT_RGB0
);
1803 rs_col_count
+= count
;
1806 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
1809 /* with TCL we always seem to route 4 components */
1810 if (InputsRead
& (FRAG_BIT_TEX0
<< i
)) {
1815 count
= VB
->AttribPtr
[_TNL_ATTRIB_TEX(i
)]->size
;
1817 /* always have on texcoord */
1818 swiz
|= in_texcoords
++ << R500_RS_IP_TEX_PTR_S_SHIFT
;
1820 swiz
|= in_texcoords
++ << R500_RS_IP_TEX_PTR_T_SHIFT
;
1822 swiz
|= R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_T_SHIFT
;
1825 swiz
|= in_texcoords
++ << R500_RS_IP_TEX_PTR_R_SHIFT
;
1827 swiz
|= R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_R_SHIFT
;
1830 swiz
|= in_texcoords
++ << R500_RS_IP_TEX_PTR_Q_SHIFT
;
1832 swiz
|= R500_RS_IP_PTR_K1
<< R500_RS_IP_TEX_PTR_Q_SHIFT
;
1835 swiz
= (R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_S_SHIFT
) |
1836 (R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_T_SHIFT
) |
1837 (R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_R_SHIFT
) |
1838 (R500_RS_IP_PTR_K1
<< R500_RS_IP_TEX_PTR_Q_SHIFT
);
1840 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ i
] = interp_col
[i
] | swiz
;
1842 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ fp_reg
] = 0;
1843 if (InputsRead
& (FRAG_BIT_TEX0
<< i
)) {
1844 //assert(r300->state.texture.tc_count != 0);
1845 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ fp_reg
] |= R500_RS_INST_TEX_CN_WRITE
| i
/* source INTERP */
1846 | (fp_reg
<< R500_RS_INST_TEX_ADDR_SHIFT
);
1849 /* Passing invalid data here can lock the GPU. */
1850 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_TEX0
+ i
, _TNL_ATTRIB_TEX(i
))) {
1851 InputsRead
&= ~(FRAG_BIT_TEX0
<< i
);
1854 WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i
);
1859 if (InputsRead
& FRAG_BIT_COL0
) {
1860 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL0
, _TNL_ATTRIB_COLOR0
)) {
1861 r300
->hw
.rr
.cmd
[R300_RR_INST_0
] |= R500_RS_INST_COL_CN_WRITE
| (fp_reg
++ << R500_RS_INST_COL_ADDR_SHIFT
);
1862 InputsRead
&= ~FRAG_BIT_COL0
;
1865 WARN_ONCE("fragprog wants col0, vp doesn't provide it\n");
1869 if (InputsRead
& FRAG_BIT_COL1
) {
1870 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL1
, _TNL_ATTRIB_COLOR1
)) {
1871 r300
->hw
.rr
.cmd
[R300_RR_INST_1
] |= (1 << 12) | R500_RS_INST_COL_CN_WRITE
| (fp_reg
++ << R500_RS_INST_COL_ADDR_SHIFT
);
1872 InputsRead
&= ~FRAG_BIT_COL1
;
1877 WARN_ONCE("fragprog wants col1, vp doesn't provide it\n");
1881 /* Need at least one. This might still lock as the values are undefined... */
1882 if (in_texcoords
== 0 && col_interp_nr
== 0) {
1883 r300
->hw
.rr
.cmd
[R300_RR_INST_0
] |= 0 | R500_RS_INST_COL_CN_WRITE
| (fp_reg
++ << R500_RS_INST_COL_ADDR_SHIFT
);
1887 r300
->hw
.rc
.cmd
[1] = 0 | (in_texcoords
<< R300_IT_COUNT_SHIFT
)
1888 | (col_interp_nr
<< R300_IC_COUNT_SHIFT
)
1891 assert(high_rr
>= 0);
1892 r300
->hw
.rr
.cmd
[R300_RR_CMD_0
] = cmdpacket0(R500_RS_INST_0
, high_rr
+ 1);
1893 r300
->hw
.rc
.cmd
[2] = 0xC0 | high_rr
;
1896 WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead
);
1902 #define bump_vpu_count(ptr, new_count) do{\
1903 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
1904 int _nc=(new_count)/4; \
1905 assert(_nc < 256); \
1906 if(_nc>_p->vpu.count)_p->vpu.count=_nc;\
1909 static INLINE
void r300SetupVertexProgramFragment(r300ContextPtr r300
, int dest
, struct r300_vertex_shader_fragment
*vsf
)
1913 if (vsf
->length
== 0)
1916 if (vsf
->length
& 0x3) {
1917 fprintf(stderr
, "VERTEX_SHADER_FRAGMENT must have length divisible by 4\n");
1921 switch ((dest
>> 8) & 0xf) {
1923 R300_STATECHANGE(r300
, vpi
);
1924 for (i
= 0; i
< vsf
->length
; i
++)
1925 r300
->hw
.vpi
.cmd
[R300_VPI_INSTR_0
+ i
+ 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1926 bump_vpu_count(r300
->hw
.vpi
.cmd
, vsf
->length
+ 4 * (dest
& 0xff));
1930 R300_STATECHANGE(r300
, vpp
);
1931 for (i
= 0; i
< vsf
->length
; i
++)
1932 r300
->hw
.vpp
.cmd
[R300_VPP_PARAM_0
+ i
+ 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1933 bump_vpu_count(r300
->hw
.vpp
.cmd
, vsf
->length
+ 4 * (dest
& 0xff));
1936 R300_STATECHANGE(r300
, vps
);
1937 for (i
= 0; i
< vsf
->length
; i
++)
1938 r300
->hw
.vps
.cmd
[1 + i
+ 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1939 bump_vpu_count(r300
->hw
.vps
.cmd
, vsf
->length
+ 4 * (dest
& 0xff));
1942 fprintf(stderr
, "%s:%s don't know how to handle dest %04x\n", __FILE__
, __FUNCTION__
, dest
);
1947 #define MIN3(a, b, c) ((a) < (b) ? MIN2(a, c) : MIN2(b, c))
1950 static void r300VapCntl(r300ContextPtr rmesa
, GLuint input_count
,
1951 GLuint output_count
, GLuint temp_count
)
1957 /* Flush PVS engine before changing PVS_NUM_SLOTS, PVS_NUM_CNTRLS.
1958 * See r500 docs 6.5.2 - done in emit */
1960 /* avoid division by zero */
1961 if (input_count
== 0) input_count
= 1;
1962 if (output_count
== 0) output_count
= 1;
1963 if (temp_count
== 0) temp_count
= 1;
1965 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
1970 pvs_num_slots
= MIN3(10, vtx_mem_size
/input_count
, vtx_mem_size
/output_count
);
1971 pvs_num_cntrls
= MIN2(6, vtx_mem_size
/temp_count
);
1973 R300_STATECHANGE(rmesa
, vap_cntl
);
1974 if (rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
) {
1975 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] =
1976 (pvs_num_slots
<< R300_PVS_NUM_SLOTS_SHIFT
) |
1977 (pvs_num_cntrls
<< R300_PVS_NUM_CNTLRS_SHIFT
) |
1978 (12 << R300_VF_MAX_VTX_NUM_SHIFT
);
1979 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
1980 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= R500_TCL_STATE_OPTIMIZATION
;
1982 /* not sure about non-tcl */
1983 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] = ((10 << R300_PVS_NUM_SLOTS_SHIFT
) |
1984 (5 << R300_PVS_NUM_CNTLRS_SHIFT
) |
1985 (5 << R300_VF_MAX_VTX_NUM_SHIFT
));
1987 if (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV515
)
1988 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (2 << R300_PVS_NUM_FPUS_SHIFT
);
1989 else if ((rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV530
) ||
1990 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV560
) ||
1991 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV570
))
1992 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (5 << R300_PVS_NUM_FPUS_SHIFT
);
1993 else if ((rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV410
) ||
1994 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R420
))
1995 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (6 << R300_PVS_NUM_FPUS_SHIFT
);
1996 else if ((rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R520
) ||
1997 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R580
))
1998 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (8 << R300_PVS_NUM_FPUS_SHIFT
);
2000 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (4 << R300_PVS_NUM_FPUS_SHIFT
);
2004 static void r300SetupDefaultVertexProgram(r300ContextPtr rmesa
)
2006 struct r300_vertex_shader_state
*prog
= &(rmesa
->state
.vertex_shader
);
2011 int param_count
= 0;
2012 int program_end
= 0;
2014 for (i
= VERT_ATTRIB_POS
; i
< VERT_ATTRIB_MAX
; i
++) {
2015 if (rmesa
->state
.sw_tcl_inputs
[i
] != -1) {
2016 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
);
2017 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
);
2018 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
);
2019 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
);
2025 prog
->program
.length
= program_end
;
2027 r300SetupVertexProgramFragment(rmesa
, R300_PVS_CODE_START
,
2029 inst_count
= (prog
->program
.length
/ 4) - 1;
2031 r300VapCntl(rmesa
, i_reg
, o_reg
, 0);
2033 R300_STATECHANGE(rmesa
, pvs
);
2034 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] =
2035 (0 << R300_PVS_FIRST_INST_SHIFT
) |
2036 (inst_count
<< R300_PVS_XYZW_VALID_INST_SHIFT
) |
2037 (inst_count
<< R300_PVS_LAST_INST_SHIFT
);
2038 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] =
2039 (0 << R300_PVS_CONST_BASE_OFFSET_SHIFT
) |
2040 (param_count
<< R300_PVS_MAX_CONST_ADDR_SHIFT
);
2041 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] =
2042 (inst_count
<< R300_PVS_LAST_VTX_SRC_INST_SHIFT
);
2045 static int bit_count (int x
)
2047 x
= ((x
& 0xaaaaaaaaU
) >> 1) + (x
& 0x55555555U
);
2048 x
= ((x
& 0xccccccccU
) >> 2) + (x
& 0x33333333U
);
2049 x
= (x
>> 16) + (x
& 0xffff);
2050 x
= ((x
& 0xf0f0) >> 4) + (x
& 0x0f0f);
2051 return (x
>> 8) + (x
& 0x00ff);
2054 static void r300SetupRealVertexProgram(r300ContextPtr rmesa
)
2056 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
2057 struct r300_vertex_program
*prog
= (struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
);
2059 int param_count
= 0;
2061 /* FIXME: r300SetupVertexProgramFragment */
2062 R300_STATECHANGE(rmesa
, vpp
);
2064 r300VertexProgUpdateParams(ctx
,
2065 (struct r300_vertex_program_cont
*)
2066 ctx
->VertexProgram
._Current
,
2067 (float *)&rmesa
->hw
.vpp
.
2068 cmd
[R300_VPP_PARAM_0
]);
2069 bump_vpu_count(rmesa
->hw
.vpp
.cmd
, param_count
);
2072 r300SetupVertexProgramFragment(rmesa
, R300_PVS_CODE_START
, &(prog
->program
));
2073 inst_count
= (prog
->program
.length
/ 4) - 1;
2075 r300VapCntl(rmesa
, bit_count(prog
->key
.InputsRead
),
2076 bit_count(prog
->key
.OutputsWritten
), prog
->num_temporaries
);
2078 R300_STATECHANGE(rmesa
, pvs
);
2079 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] =
2080 (0 << R300_PVS_FIRST_INST_SHIFT
) |
2081 (inst_count
<< R300_PVS_XYZW_VALID_INST_SHIFT
) |
2082 (inst_count
<< R300_PVS_LAST_INST_SHIFT
);
2083 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] =
2084 (0 << R300_PVS_CONST_BASE_OFFSET_SHIFT
) |
2085 (param_count
<< R300_PVS_MAX_CONST_ADDR_SHIFT
);
2086 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] =
2087 (inst_count
<< R300_PVS_LAST_VTX_SRC_INST_SHIFT
);
2090 static void r300SetupVertexProgram(r300ContextPtr rmesa
)
2092 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
2094 /* Reset state, in case we don't use something */
2095 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vpp
.cmd
)->vpu
.count
= 0;
2096 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vpi
.cmd
)->vpu
.count
= 0;
2097 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vps
.cmd
)->vpu
.count
= 0;
2099 /* Not sure why this doesnt work...
2100 0x400 area might have something to do with pixel shaders as it appears right after pfs programming.
2101 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. */
2102 //setup_vertex_shader_fragment(rmesa, 0x406, &unk4);
2103 if (hw_tcl_on
&& ((struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
))->translated
) {
2104 r300SetupRealVertexProgram(rmesa
);
2106 /* FIXME: This needs to be replaced by vertex shader generation code. */
2107 r300SetupDefaultVertexProgram(rmesa
);
2113 * Enable/Disable states.
2115 * \note Mesa already filters redundant calls to this function.
2117 static void r300Enable(GLcontext
* ctx
, GLenum cap
, GLboolean state
)
2119 if (RADEON_DEBUG
& DEBUG_STATE
)
2120 fprintf(stderr
, "%s( %s = %s )\n", __FUNCTION__
,
2121 _mesa_lookup_enum_by_nr(cap
),
2122 state
? "GL_TRUE" : "GL_FALSE");
2131 r300SetFogState(ctx
, state
);
2134 r300SetAlphaState(ctx
);
2136 case GL_COLOR_LOGIC_OP
:
2137 r300SetLogicOpState(ctx
);
2138 /* fall-through, because logic op overrides blending */
2140 r300SetBlendState(ctx
);
2142 case GL_CLIP_PLANE0
:
2143 case GL_CLIP_PLANE1
:
2144 case GL_CLIP_PLANE2
:
2145 case GL_CLIP_PLANE3
:
2146 case GL_CLIP_PLANE4
:
2147 case GL_CLIP_PLANE5
:
2148 r300SetClipPlaneState(ctx
, cap
, state
);
2151 r300SetDepthState(ctx
);
2153 case GL_STENCIL_TEST
:
2154 r300SetStencilState(ctx
, state
);
2157 r300UpdateCulling(ctx
);
2159 case GL_POLYGON_OFFSET_POINT
:
2160 case GL_POLYGON_OFFSET_LINE
:
2161 case GL_POLYGON_OFFSET_FILL
:
2162 r300SetPolygonOffsetState(ctx
, state
);
2165 radeonEnable(ctx
, cap
, state
);
2171 * Completely recalculates hardware state based on the Mesa state.
2173 static void r300ResetHwState(r300ContextPtr r300
)
2175 GLcontext
*ctx
= r300
->radeon
.glCtx
;
2178 if (!(r300
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
2181 if (RADEON_DEBUG
& DEBUG_STATE
)
2182 fprintf(stderr
, "%s\n", __FUNCTION__
);
2184 r300UpdateWindow(ctx
);
2187 ctx
->Color
.ColorMask
[RCOMP
],
2188 ctx
->Color
.ColorMask
[GCOMP
],
2189 ctx
->Color
.ColorMask
[BCOMP
], ctx
->Color
.ColorMask
[ACOMP
]);
2191 r300Enable(ctx
, GL_DEPTH_TEST
, ctx
->Depth
.Test
);
2192 r300DepthMask(ctx
, ctx
->Depth
.Mask
);
2193 r300DepthFunc(ctx
, ctx
->Depth
.Func
);
2196 r300Enable(ctx
, GL_STENCIL_TEST
, ctx
->Stencil
.Enabled
);
2197 r300StencilMaskSeparate(ctx
, 0, ctx
->Stencil
.WriteMask
[0]);
2198 r300StencilFuncSeparate(ctx
, 0, ctx
->Stencil
.Function
[0],
2199 ctx
->Stencil
.Ref
[0], ctx
->Stencil
.ValueMask
[0]);
2200 r300StencilOpSeparate(ctx
, 0, ctx
->Stencil
.FailFunc
[0],
2201 ctx
->Stencil
.ZFailFunc
[0],
2202 ctx
->Stencil
.ZPassFunc
[0]);
2204 r300UpdateCulling(ctx
);
2206 r300SetBlendState(ctx
);
2207 r300SetLogicOpState(ctx
);
2209 r300AlphaFunc(ctx
, ctx
->Color
.AlphaFunc
, ctx
->Color
.AlphaRef
);
2210 r300Enable(ctx
, GL_ALPHA_TEST
, ctx
->Color
.AlphaEnabled
);
2212 r300
->hw
.vte
.cmd
[1] = R300_VPORT_X_SCALE_ENA
2213 | R300_VPORT_X_OFFSET_ENA
2214 | R300_VPORT_Y_SCALE_ENA
2215 | R300_VPORT_Y_OFFSET_ENA
2216 | R300_VPORT_Z_SCALE_ENA
2217 | R300_VPORT_Z_OFFSET_ENA
| R300_VTX_W0_FMT
;
2218 r300
->hw
.vte
.cmd
[2] = 0x00000008;
2220 r300
->hw
.vap_vf_max_vtx_indx
.cmd
[1] = 0x00FFFFFF;
2221 r300
->hw
.vap_vf_max_vtx_indx
.cmd
[2] = 0x00000000;
2223 #ifdef MESA_LITTLE_ENDIAN
2224 r300
->hw
.vap_cntl_status
.cmd
[1] = R300_VC_NO_SWAP
;
2226 r300
->hw
.vap_cntl_status
.cmd
[1] = R300_VC_32BIT_SWAP
;
2229 /* disable VAP/TCL on non-TCL capable chips */
2231 r300
->hw
.vap_cntl_status
.cmd
[1] |= R300_VAP_TCL_BYPASS
;
2233 r300
->hw
.vap_psc_sgn_norm_cntl
.cmd
[1] = 0xAAAAAAAA;
2235 /* XXX: Other families? */
2237 r300
->hw
.vap_clip_cntl
.cmd
[1] = R300_PS_UCP_MODE_DIST_COP
;
2239 r300
->hw
.vap_clip
.cmd
[1] = r300PackFloat32(1.0); /* X */
2240 r300
->hw
.vap_clip
.cmd
[2] = r300PackFloat32(1.0); /* X */
2241 r300
->hw
.vap_clip
.cmd
[3] = r300PackFloat32(1.0); /* Y */
2242 r300
->hw
.vap_clip
.cmd
[4] = r300PackFloat32(1.0); /* Y */
2244 switch (r300
->radeon
.radeonScreen
->chip_family
) {
2245 case CHIP_FAMILY_R300
:
2246 r300
->hw
.vap_pvs_vtx_timeout_reg
.cmd
[1] = R300_2288_R300
;
2249 r300
->hw
.vap_pvs_vtx_timeout_reg
.cmd
[1] = R300_2288_RV350
;
2254 r300
->hw
.gb_enable
.cmd
[1] = R300_GB_POINT_STUFF_ENABLE
2255 | R300_GB_LINE_STUFF_ENABLE
2256 | R300_GB_TRIANGLE_STUFF_ENABLE
;
2258 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_0
] = 0x66666666;
2259 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_1
] = 0x06666666;
2261 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] =
2262 R300_GB_TILE_ENABLE
| R300_GB_TILE_SIZE_16
/*| R300_GB_SUBPIXEL_1_16*/;
2263 switch (r300
->radeon
.radeonScreen
->num_gb_pipes
) {
2266 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2267 R300_GB_TILE_PIPE_COUNT_RV300
;
2270 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2271 R300_GB_TILE_PIPE_COUNT_R300
;
2274 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2275 R300_GB_TILE_PIPE_COUNT_R420_3P
;
2278 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2279 R300_GB_TILE_PIPE_COUNT_R420
;
2283 /* XXX: set to 0 when fog is disabled? */
2284 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_SELECT
] = R300_GB_FOG_SELECT_1_1_W
;
2286 /* XXX: Enable anti-aliasing? */
2287 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_AA_CONFIG
] = GB_AA_CONFIG_AA_DISABLE
;
2289 r300
->hw
.ga_point_s0
.cmd
[1] = r300PackFloat32(0.0);
2290 r300
->hw
.ga_point_s0
.cmd
[2] = r300PackFloat32(0.0);
2291 r300
->hw
.ga_point_s0
.cmd
[3] = r300PackFloat32(1.0);
2292 r300
->hw
.ga_point_s0
.cmd
[4] = r300PackFloat32(1.0);
2294 r300
->hw
.ga_triangle_stipple
.cmd
[1] = 0x00050005;
2296 r300PointSize(ctx
, 1.0);
2298 r300
->hw
.ga_point_minmax
.cmd
[1] = 0x18000006;
2299 r300
->hw
.ga_point_minmax
.cmd
[2] = 0x00020006;
2300 r300
->hw
.ga_point_minmax
.cmd
[3] = r300PackFloat32(1.0 / 192.0);
2302 r300LineWidth(ctx
, 1.0);
2304 r300
->hw
.ga_line_stipple
.cmd
[1] = 0;
2305 r300
->hw
.ga_line_stipple
.cmd
[2] = r300PackFloat32(0.0);
2306 r300
->hw
.ga_line_stipple
.cmd
[3] = r300PackFloat32(1.0);
2308 r300ShadeModel(ctx
, ctx
->Light
.ShadeModel
);
2310 r300PolygonMode(ctx
, GL_FRONT
, ctx
->Polygon
.FrontMode
);
2311 r300PolygonMode(ctx
, GL_BACK
, ctx
->Polygon
.BackMode
);
2312 r300
->hw
.zbias_cntl
.cmd
[1] = 0x00000000;
2314 r300PolygonOffset(ctx
, ctx
->Polygon
.OffsetFactor
,
2315 ctx
->Polygon
.OffsetUnits
);
2316 r300Enable(ctx
, GL_POLYGON_OFFSET_POINT
, ctx
->Polygon
.OffsetPoint
);
2317 r300Enable(ctx
, GL_POLYGON_OFFSET_LINE
, ctx
->Polygon
.OffsetLine
);
2318 r300Enable(ctx
, GL_POLYGON_OFFSET_FILL
, ctx
->Polygon
.OffsetFill
);
2320 r300
->hw
.su_depth_scale
.cmd
[1] = 0x4B7FFFFF;
2321 r300
->hw
.su_depth_scale
.cmd
[2] = 0x00000000;
2323 r300
->hw
.sc_hyperz
.cmd
[1] = 0x0000001C;
2324 r300
->hw
.sc_hyperz
.cmd
[2] = 0x2DA49525;
2326 r300
->hw
.sc_screendoor
.cmd
[1] = 0x00FFFFFF;
2328 r300
->hw
.us_out_fmt
.cmd
[1] = R500_OUT_FMT_C4_8
|
2329 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2330 r300
->hw
.us_out_fmt
.cmd
[2] = R500_OUT_FMT_UNUSED
|
2331 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2332 r300
->hw
.us_out_fmt
.cmd
[3] = R500_OUT_FMT_UNUSED
|
2333 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2334 r300
->hw
.us_out_fmt
.cmd
[4] = R500_OUT_FMT_UNUSED
|
2335 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2336 r300
->hw
.us_out_fmt
.cmd
[5] = R300_W_FMT_W24
;
2338 r300Enable(ctx
, GL_FOG
, ctx
->Fog
.Enabled
);
2339 r300Fogfv(ctx
, GL_FOG_MODE
, NULL
);
2340 r300Fogfv(ctx
, GL_FOG_DENSITY
, &ctx
->Fog
.Density
);
2341 r300Fogfv(ctx
, GL_FOG_START
, &ctx
->Fog
.Start
);
2342 r300Fogfv(ctx
, GL_FOG_END
, &ctx
->Fog
.End
);
2343 r300Fogfv(ctx
, GL_FOG_COLOR
, ctx
->Fog
.Color
);
2344 r300Fogfv(ctx
, GL_FOG_COORDINATE_SOURCE_EXT
, NULL
);
2346 r300
->hw
.fg_depth_src
.cmd
[1] = 0;
2348 r300
->hw
.rb3d_cctl
.cmd
[1] = 0;
2350 r300BlendColor(ctx
, ctx
->Color
.BlendColor
);
2352 r300
->hw
.rb3d_dither_ctl
.cmd
[1] = 0;
2353 r300
->hw
.rb3d_dither_ctl
.cmd
[2] = 0;
2354 r300
->hw
.rb3d_dither_ctl
.cmd
[3] = 0;
2355 r300
->hw
.rb3d_dither_ctl
.cmd
[4] = 0;
2356 r300
->hw
.rb3d_dither_ctl
.cmd
[5] = 0;
2357 r300
->hw
.rb3d_dither_ctl
.cmd
[6] = 0;
2358 r300
->hw
.rb3d_dither_ctl
.cmd
[7] = 0;
2359 r300
->hw
.rb3d_dither_ctl
.cmd
[8] = 0;
2360 r300
->hw
.rb3d_dither_ctl
.cmd
[9] = 0;
2362 r300
->hw
.rb3d_aaresolve_ctl
.cmd
[1] = 0;
2364 r300
->hw
.rb3d_discard_src_pixel_lte_threshold
.cmd
[1] = 0x00000000;
2365 r300
->hw
.rb3d_discard_src_pixel_lte_threshold
.cmd
[2] = 0xffffffff;
2368 if (r300
->radeon
.sarea
->tiling_enabled
) {
2369 /* XXX: Turn off when clearing buffers ? */
2370 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] |= R300_DEPTHMACROTILE_ENABLE
;
2372 if (ctx
->Visual
.depthBits
== 24)
2373 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] |=
2374 R300_DEPTHMICROTILE_TILED
;
2377 r300
->hw
.zb_depthclearvalue
.cmd
[1] = 0;
2379 switch (ctx
->Visual
.depthBits
) {
2381 r300
->hw
.zstencil_format
.cmd
[1] = R300_DEPTHFORMAT_16BIT_INT_Z
;
2384 r300
->hw
.zstencil_format
.cmd
[1] = R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL
;
2387 fprintf(stderr
, "Error: Unsupported depth %d... exiting\n", ctx
->Visual
.depthBits
);
2391 r300
->hw
.zstencil_format
.cmd
[2] = R300_ZTOP_DISABLE
;
2392 r300
->hw
.zstencil_format
.cmd
[3] = 0x00000003;
2393 r300
->hw
.zstencil_format
.cmd
[4] = 0x00000000;
2394 r300SetEarlyZState(ctx
);
2396 r300
->hw
.unk4F30
.cmd
[1] = 0;
2397 r300
->hw
.unk4F30
.cmd
[2] = 0;
2399 r300
->hw
.zb_hiz_offset
.cmd
[1] = 0;
2401 r300
->hw
.zb_hiz_pitch
.cmd
[1] = 0;
2403 r300VapCntl(r300
, 0, 0, 0);
2405 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_0
] = 0;
2406 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_1
] = 0;
2407 r300
->hw
.vps
.cmd
[R300_VPS_POINTSIZE
] = r300PackFloat32(1.0);
2408 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_3
] = 0;
2411 r300
->hw
.all_dirty
= GL_TRUE
;
2414 void r300UpdateShaders(r300ContextPtr rmesa
)
2417 struct r300_vertex_program
*vp
;
2420 ctx
= rmesa
->radeon
.glCtx
;
2422 if (rmesa
->NewGLState
&& hw_tcl_on
) {
2423 rmesa
->NewGLState
= 0;
2425 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
2426 rmesa
->temp_attrib
[i
] =
2427 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
];
2428 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] =
2429 &rmesa
->dummy_attrib
[i
];
2432 _tnl_UpdateFixedFunctionProgram(ctx
);
2434 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
2435 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] =
2436 rmesa
->temp_attrib
[i
];
2439 r300SelectVertexShader(rmesa
);
2440 vp
= (struct r300_vertex_program
*)
2441 CURRENT_VERTEX_SHADER(ctx
);
2442 /*if (vp->translated == GL_FALSE)
2443 r300TranslateVertexShader(vp); */
2444 if (vp
->translated
== GL_FALSE
) {
2445 fprintf(stderr
, "Failing back to sw-tcl\n");
2446 hw_tcl_on
= future_hw_tcl_on
= 0;
2447 r300ResetHwState(rmesa
);
2449 r300UpdateStateParameters(ctx
, _NEW_PROGRAM
);
2453 r300UpdateStateParameters(ctx
, _NEW_PROGRAM
);
2456 static const GLfloat
*get_fragmentprogram_constant(GLcontext
*ctx
,
2457 struct gl_program
*program
, struct prog_src_register srcreg
)
2459 static const GLfloat dummy
[4] = { 0, 0, 0, 0 };
2461 switch(srcreg
.File
) {
2462 case PROGRAM_LOCAL_PARAM
:
2463 return program
->LocalParams
[srcreg
.Index
];
2464 case PROGRAM_ENV_PARAM
:
2465 return ctx
->FragmentProgram
.Parameters
[srcreg
.Index
];
2466 case PROGRAM_STATE_VAR
:
2467 case PROGRAM_NAMED_PARAM
:
2468 case PROGRAM_CONSTANT
:
2469 return program
->Parameters
->ParameterValues
[srcreg
.Index
];
2471 _mesa_problem(ctx
, "get_fragmentprogram_constant: Unknown\n");
2477 static void r300SetupPixelShader(r300ContextPtr rmesa
)
2479 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
2480 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
2481 (char *)ctx
->FragmentProgram
._Current
;
2482 struct r300_fragment_program_code
*code
;
2485 if (!fp
) /* should only happenen once, just after context is created */
2488 r300TranslateFragmentShader(rmesa
, fp
);
2489 if (!fp
->translated
) {
2490 fprintf(stderr
, "%s: No valid fragment shader, exiting\n",
2496 r300SetupTextures(ctx
);
2498 R300_STATECHANGE(rmesa
, fpi
[0]);
2499 R300_STATECHANGE(rmesa
, fpi
[1]);
2500 R300_STATECHANGE(rmesa
, fpi
[2]);
2501 R300_STATECHANGE(rmesa
, fpi
[3]);
2502 rmesa
->hw
.fpi
[0].cmd
[R300_FPI_CMD_0
] = cmdpacket0(R300_US_ALU_RGB_INST_0
, code
->alu
.length
);
2503 rmesa
->hw
.fpi
[1].cmd
[R300_FPI_CMD_0
] = cmdpacket0(R300_US_ALU_RGB_ADDR_0
, code
->alu
.length
);
2504 rmesa
->hw
.fpi
[2].cmd
[R300_FPI_CMD_0
] = cmdpacket0(R300_US_ALU_ALPHA_INST_0
, code
->alu
.length
);
2505 rmesa
->hw
.fpi
[3].cmd
[R300_FPI_CMD_0
] = cmdpacket0(R300_US_ALU_ALPHA_ADDR_0
, code
->alu
.length
);
2506 for (i
= 0; i
< code
->alu
.length
; i
++) {
2507 rmesa
->hw
.fpi
[0].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst0
;
2508 rmesa
->hw
.fpi
[1].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst1
;
2509 rmesa
->hw
.fpi
[2].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst2
;
2510 rmesa
->hw
.fpi
[3].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst3
;
2513 R300_STATECHANGE(rmesa
, fp
);
2514 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL0
] = code
->cur_node
| (code
->first_node_has_tex
<< 3);
2515 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL1
] = code
->max_temp_idx
;
2516 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL2
] =
2517 (0 << R300_PFS_CNTL_ALU_OFFSET_SHIFT
) |
2518 ((code
->alu
.length
-1) << R300_PFS_CNTL_ALU_END_SHIFT
) |
2519 (0 << R300_PFS_CNTL_TEX_OFFSET_SHIFT
) |
2520 ((code
->tex
.length
? code
->tex
.length
-1 : 0) << R300_PFS_CNTL_TEX_END_SHIFT
);
2521 /* I just want to say, the way these nodes are stored.. weird.. */
2522 for (i
= 0, k
= (4 - (code
->cur_node
+ 1)); i
< 4; i
++, k
++) {
2523 if (i
< (code
->cur_node
+ 1)) {
2524 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+ k
] =
2525 (code
->node
[i
].alu_offset
<< R300_ALU_START_SHIFT
) |
2526 (code
->node
[i
].alu_end
<< R300_ALU_SIZE_SHIFT
) |
2527 (code
->node
[i
].tex_offset
<< R300_TEX_START_SHIFT
) |
2528 (code
->node
[i
].tex_end
<< R300_TEX_SIZE_SHIFT
) |
2529 code
->node
[i
].flags
;
2531 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+ (3 - i
)] = 0;
2535 R300_STATECHANGE(rmesa
, fpp
);
2536 rmesa
->hw
.fpp
.cmd
[R300_FPP_CMD_0
] = cmdpacket0(R300_PFS_PARAM_0_X
, code
->const_nr
* 4);
2537 for (i
= 0; i
< code
->const_nr
; i
++) {
2538 const GLfloat
*constant
= get_fragmentprogram_constant(ctx
,
2539 &fp
->mesa_program
.Base
, code
->constant
[i
]);
2540 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 0] = r300PackFloat24(constant
[0]);
2541 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 1] = r300PackFloat24(constant
[1]);
2542 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 2] = r300PackFloat24(constant
[2]);
2543 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 3] = r300PackFloat24(constant
[3]);
2547 #define bump_r500fp_count(ptr, new_count) do{\
2548 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
2549 int _nc=(new_count)/6; \
2550 assert(_nc < 256); \
2551 if(_nc>_p->r500fp.count)_p->r500fp.count=_nc;\
2554 #define bump_r500fp_const_count(ptr, new_count) do{\
2555 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
2556 int _nc=(new_count)/4; \
2557 assert(_nc < 256); \
2558 if(_nc>_p->r500fp.count)_p->r500fp.count=_nc;\
2561 static void r500SetupPixelShader(r300ContextPtr rmesa
)
2563 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
2564 struct r500_fragment_program
*fp
= (struct r500_fragment_program
*)
2565 (char *)ctx
->FragmentProgram
._Current
;
2567 struct r500_fragment_program_code
*code
;
2569 if (!fp
) /* should only happenen once, just after context is created */
2572 ((drm_r300_cmd_header_t
*) rmesa
->hw
.r500fp
.cmd
)->r500fp
.count
= 0;
2573 ((drm_r300_cmd_header_t
*) rmesa
->hw
.r500fp_const
.cmd
)->r500fp
.count
= 0;
2575 r500TranslateFragmentShader(rmesa
, fp
);
2576 if (!fp
->translated
) {
2577 fprintf(stderr
, "%s: No valid fragment shader, exiting\n",
2583 if (fp
->mesa_program
.FogOption
!= GL_NONE
) {
2584 /* Enable HW fog. Try not to squish GL context.
2585 * (Anybody sane remembered to set glFog() opts first!) */
2586 r300SetFogState(ctx
, GL_TRUE
);
2587 ctx
->Fog
.Mode
= fp
->mesa_program
.FogOption
;
2588 r300Fogfv(ctx
, GL_FOG_MODE
, NULL
);
2590 /* Make sure HW is matching GL context. */
2591 r300SetFogState(ctx
, ctx
->Fog
.Enabled
);
2593 r300SetupTextures(ctx
);
2595 R300_STATECHANGE(rmesa
, fp
);
2596 rmesa
->hw
.fp
.cmd
[R500_FP_PIXSIZE
] = code
->max_temp_idx
;
2598 rmesa
->hw
.fp
.cmd
[R500_FP_CODE_ADDR
] =
2599 R500_US_CODE_START_ADDR(code
->inst_offset
) |
2600 R500_US_CODE_END_ADDR(code
->inst_end
);
2601 rmesa
->hw
.fp
.cmd
[R500_FP_CODE_RANGE
] =
2602 R500_US_CODE_RANGE_ADDR(code
->inst_offset
) |
2603 R500_US_CODE_RANGE_SIZE(code
->inst_end
);
2604 rmesa
->hw
.fp
.cmd
[R500_FP_CODE_OFFSET
] =
2605 R500_US_CODE_OFFSET_ADDR(0); /* FIXME when we add flow control */
2607 R300_STATECHANGE(rmesa
, r500fp
);
2608 /* Emit our shader... */
2609 for (i
= 0; i
< code
->inst_end
+1; i
++) {
2610 rmesa
->hw
.r500fp
.cmd
[i
*6+1] = code
->inst
[i
].inst0
;
2611 rmesa
->hw
.r500fp
.cmd
[i
*6+2] = code
->inst
[i
].inst1
;
2612 rmesa
->hw
.r500fp
.cmd
[i
*6+3] = code
->inst
[i
].inst2
;
2613 rmesa
->hw
.r500fp
.cmd
[i
*6+4] = code
->inst
[i
].inst3
;
2614 rmesa
->hw
.r500fp
.cmd
[i
*6+5] = code
->inst
[i
].inst4
;
2615 rmesa
->hw
.r500fp
.cmd
[i
*6+6] = code
->inst
[i
].inst5
;
2618 bump_r500fp_count(rmesa
->hw
.r500fp
.cmd
, (code
->inst_end
+ 1) * 6);
2620 R300_STATECHANGE(rmesa
, r500fp_const
);
2621 for (i
= 0; i
< code
->const_nr
; i
++) {
2622 const GLfloat
*constant
= get_fragmentprogram_constant(ctx
,
2623 &fp
->mesa_program
.Base
, code
->constant
[i
]);
2624 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 0] = r300PackFloat32(constant
[0]);
2625 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 1] = r300PackFloat32(constant
[1]);
2626 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 2] = r300PackFloat32(constant
[2]);
2627 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 3] = r300PackFloat32(constant
[3]);
2629 bump_r500fp_const_count(rmesa
->hw
.r500fp_const
.cmd
, code
->const_nr
* 4);
2633 void r300UpdateShaderStates(r300ContextPtr rmesa
)
2636 ctx
= rmesa
->radeon
.glCtx
;
2638 r300ValidateTextures(ctx
);
2639 r300SetEarlyZState(ctx
);
2641 GLuint fgdepthsrc
= R300_FG_DEPTH_SRC_SCAN
;
2642 if (current_fragment_program_writes_depth(ctx
))
2643 fgdepthsrc
= R300_FG_DEPTH_SRC_SHADER
;
2644 if (fgdepthsrc
!= rmesa
->hw
.fg_depth_src
.cmd
[1]) {
2645 R300_STATECHANGE(rmesa
, fg_depth_src
);
2646 rmesa
->hw
.fg_depth_src
.cmd
[1] = fgdepthsrc
;
2649 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
2650 r500SetupPixelShader(rmesa
);
2652 r300SetupPixelShader(rmesa
);
2654 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
2655 r500SetupRSUnit(ctx
);
2657 r300SetupRSUnit(ctx
);
2659 if ((rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
2660 r300SetupVertexProgram(rmesa
);
2665 * Called by Mesa after an internal state update.
2667 static void r300InvalidateState(GLcontext
* ctx
, GLuint new_state
)
2669 r300ContextPtr r300
= R300_CONTEXT(ctx
);
2671 _swrast_InvalidateState(ctx
, new_state
);
2672 _swsetup_InvalidateState(ctx
, new_state
);
2673 _vbo_InvalidateState(ctx
, new_state
);
2674 _tnl_InvalidateState(ctx
, new_state
);
2675 _ae_invalidate_state(ctx
, new_state
);
2677 if (new_state
& (_NEW_BUFFERS
| _NEW_COLOR
| _NEW_PIXEL
)) {
2678 r300UpdateDrawBuffer(ctx
);
2681 r300UpdateStateParameters(ctx
, new_state
);
2683 r300
->NewGLState
|= new_state
;
2687 * Calculate initial hardware state and register state functions.
2688 * Assumes that the command buffer and state atoms have been
2689 * initialized already.
2691 void r300InitState(r300ContextPtr r300
)
2693 GLcontext
*ctx
= r300
->radeon
.glCtx
;
2696 radeonInitState(&r300
->radeon
);
2698 switch (ctx
->Visual
.depthBits
) {
2700 r300
->state
.depth
.scale
= 1.0 / (GLfloat
) 0xffff;
2701 depth_fmt
= R300_DEPTHFORMAT_16BIT_INT_Z
;
2704 r300
->state
.depth
.scale
= 1.0 / (GLfloat
) 0xffffff;
2705 depth_fmt
= R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL
;
2708 fprintf(stderr
, "Error: Unsupported depth %d... exiting\n",
2709 ctx
->Visual
.depthBits
);
2713 /* Only have hw stencil when depth buffer is 24 bits deep */
2714 r300
->state
.stencil
.hw_stencil
= (ctx
->Visual
.stencilBits
> 0 &&
2715 ctx
->Visual
.depthBits
== 24);
2717 memset(&(r300
->state
.texture
), 0, sizeof(r300
->state
.texture
));
2719 r300ResetHwState(r300
);
2722 static void r300RenderMode(GLcontext
* ctx
, GLenum mode
)
2724 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
2729 void r300UpdateClipPlanes( GLcontext
*ctx
)
2731 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
2734 for (p
= 0; p
< ctx
->Const
.MaxClipPlanes
; p
++) {
2735 if (ctx
->Transform
.ClipPlanesEnabled
& (1 << p
)) {
2736 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
2738 R300_STATECHANGE( rmesa
, vpucp
[p
] );
2739 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_X
] = ip
[0];
2740 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_Y
] = ip
[1];
2741 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_Z
] = ip
[2];
2742 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_W
] = ip
[3];
2748 * Initialize driver's state callback functions
2750 void r300InitStateFuncs(struct dd_function_table
*functions
)
2752 radeonInitStateFuncs(functions
);
2754 functions
->UpdateState
= r300InvalidateState
;
2755 functions
->AlphaFunc
= r300AlphaFunc
;
2756 functions
->BlendColor
= r300BlendColor
;
2757 functions
->BlendEquationSeparate
= r300BlendEquationSeparate
;
2758 functions
->BlendFuncSeparate
= r300BlendFuncSeparate
;
2759 functions
->Enable
= r300Enable
;
2760 functions
->ColorMask
= r300ColorMask
;
2761 functions
->DepthFunc
= r300DepthFunc
;
2762 functions
->DepthMask
= r300DepthMask
;
2763 functions
->CullFace
= r300CullFace
;
2764 functions
->Fogfv
= r300Fogfv
;
2765 functions
->FrontFace
= r300FrontFace
;
2766 functions
->ShadeModel
= r300ShadeModel
;
2767 functions
->LogicOpcode
= r300LogicOpcode
;
2769 /* ARB_point_parameters */
2770 functions
->PointParameterfv
= r300PointParameter
;
2772 /* Stencil related */
2773 functions
->StencilFuncSeparate
= r300StencilFuncSeparate
;
2774 functions
->StencilMaskSeparate
= r300StencilMaskSeparate
;
2775 functions
->StencilOpSeparate
= r300StencilOpSeparate
;
2777 /* Viewport related */
2778 functions
->Viewport
= r300Viewport
;
2779 functions
->DepthRange
= r300DepthRange
;
2780 functions
->PointSize
= r300PointSize
;
2781 functions
->LineWidth
= r300LineWidth
;
2783 functions
->PolygonOffset
= r300PolygonOffset
;
2784 functions
->PolygonMode
= r300PolygonMode
;
2786 functions
->RenderMode
= r300RenderMode
;
2788 functions
->ClipPlane
= r300ClipPlane
;