2 Copyright (C) The Weather Channel, Inc. 2002.
3 Copyright (C) 2004 Nicolai Haehnle.
6 The Weather Channel (TM) funded Tungsten Graphics to develop the
7 initial release of the Radeon 8500 driver under the XFree86 license.
8 This notice must be preserved.
10 Permission is hereby granted, free of charge, to any person obtaining
11 a copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sublicense, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial
20 portions of the Software.
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
26 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 **************************************************************************/
35 * \author Nicolai Haehnle <prefect_@gmx.net>
45 #include "simple_list.h"
47 #include "api_arrayelt.h"
48 #include "swrast/swrast.h"
49 #include "swrast_setup/swrast_setup.h"
50 #include "shader/prog_parameter.h"
51 #include "shader/prog_statevars.h"
54 #include "texformat.h"
56 #include "radeon_ioctl.h"
57 #include "radeon_state.h"
58 #include "r300_context.h"
59 #include "r300_ioctl.h"
60 #include "r300_state.h"
62 #include "r300_emit.h"
63 #include "r300_fragprog.h"
66 #include "drirenderbuffer.h"
68 extern int future_hw_tcl_on
;
69 extern void _tnl_UpdateFixedFunctionProgram(GLcontext
* ctx
);
71 static void r300BlendColor(GLcontext
* ctx
, const GLfloat cf
[4])
73 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
75 R300_STATECHANGE(rmesa
, blend_color
);
77 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
) {
78 GLuint r
= IROUND(cf
[0]*1023.0f
);
79 GLuint g
= IROUND(cf
[1]*1023.0f
);
80 GLuint b
= IROUND(cf
[2]*1023.0f
);
81 GLuint a
= IROUND(cf
[3]*1023.0f
);
83 rmesa
->hw
.blend_color
.cmd
[1] = r
| (a
<< 16);
84 rmesa
->hw
.blend_color
.cmd
[2] = b
| (g
<< 16);
87 CLAMPED_FLOAT_TO_UBYTE(color
[0], cf
[0]);
88 CLAMPED_FLOAT_TO_UBYTE(color
[1], cf
[1]);
89 CLAMPED_FLOAT_TO_UBYTE(color
[2], cf
[2]);
90 CLAMPED_FLOAT_TO_UBYTE(color
[3], cf
[3]);
92 rmesa
->hw
.blend_color
.cmd
[1] = PACK_COLOR_8888(color
[3], color
[0],
98 * Calculate the hardware blend factor setting. This same function is used
99 * for source and destination of both alpha and RGB.
102 * The hardware register value for the specified blend factor. This value
103 * will need to be shifted into the correct position for either source or
104 * destination factor.
107 * Since the two cases where source and destination are handled differently
108 * are essentially error cases, they should never happen. Determine if these
109 * cases can be removed.
111 static int blend_factor(GLenum factor
, GLboolean is_src
)
115 return R300_BLEND_GL_ZERO
;
118 return R300_BLEND_GL_ONE
;
121 return R300_BLEND_GL_DST_COLOR
;
123 case GL_ONE_MINUS_DST_COLOR
:
124 return R300_BLEND_GL_ONE_MINUS_DST_COLOR
;
127 return R300_BLEND_GL_SRC_COLOR
;
129 case GL_ONE_MINUS_SRC_COLOR
:
130 return R300_BLEND_GL_ONE_MINUS_SRC_COLOR
;
133 return R300_BLEND_GL_SRC_ALPHA
;
135 case GL_ONE_MINUS_SRC_ALPHA
:
136 return R300_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
139 return R300_BLEND_GL_DST_ALPHA
;
141 case GL_ONE_MINUS_DST_ALPHA
:
142 return R300_BLEND_GL_ONE_MINUS_DST_ALPHA
;
144 case GL_SRC_ALPHA_SATURATE
:
145 return (is_src
) ? R300_BLEND_GL_SRC_ALPHA_SATURATE
:
148 case GL_CONSTANT_COLOR
:
149 return R300_BLEND_GL_CONST_COLOR
;
151 case GL_ONE_MINUS_CONSTANT_COLOR
:
152 return R300_BLEND_GL_ONE_MINUS_CONST_COLOR
;
154 case GL_CONSTANT_ALPHA
:
155 return R300_BLEND_GL_CONST_ALPHA
;
157 case GL_ONE_MINUS_CONSTANT_ALPHA
:
158 return R300_BLEND_GL_ONE_MINUS_CONST_ALPHA
;
161 fprintf(stderr
, "unknown blend factor %x\n", factor
);
162 return (is_src
) ? R300_BLEND_GL_ONE
: R300_BLEND_GL_ZERO
;
168 * Sets both the blend equation and the blend function.
169 * This is done in a single
170 * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX)
171 * change the interpretation of the blend function.
172 * Also, make sure that blend function and blend equation are set to their
173 * default value if color blending is not enabled, since at least blend
174 * equations GL_MIN and GL_FUNC_REVERSE_SUBTRACT will cause wrong results
175 * otherwise for unknown reasons.
178 /* helper function */
179 static void r300SetBlendCntl(r300ContextPtr r300
, int func
, int eqn
,
180 int cbits
, int funcA
, int eqnA
)
182 GLuint new_ablend
, new_cblend
;
186 "eqnA=%08x funcA=%08x eqn=%08x func=%08x cbits=%08x\n",
187 eqnA
, funcA
, eqn
, func
, cbits
);
189 new_ablend
= eqnA
| funcA
;
190 new_cblend
= eqn
| func
;
192 /* Some blend factor combinations don't seem to work when the
193 * BLEND_NO_SEPARATE bit is set.
195 * Especially problematic candidates are the ONE_MINUS_* flags,
196 * but I can't see a real pattern.
199 if (new_ablend
== new_cblend
) {
200 new_cblend
|= R300_DISCARD_SRC_PIXELS_SRC_ALPHA_0
;
205 if ((new_ablend
!= r300
->hw
.bld
.cmd
[R300_BLD_ABLEND
]) ||
206 (new_cblend
!= r300
->hw
.bld
.cmd
[R300_BLD_CBLEND
])) {
207 R300_STATECHANGE(r300
, bld
);
208 r300
->hw
.bld
.cmd
[R300_BLD_ABLEND
] = new_ablend
;
209 r300
->hw
.bld
.cmd
[R300_BLD_CBLEND
] = new_cblend
;
213 static void r300SetBlendState(GLcontext
* ctx
)
215 r300ContextPtr r300
= R300_CONTEXT(ctx
);
216 int func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
217 (R300_BLEND_GL_ZERO
<< R300_DST_BLEND_SHIFT
);
218 int eqn
= R300_COMB_FCN_ADD_CLAMP
;
219 int funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
220 (R300_BLEND_GL_ZERO
<< R300_DST_BLEND_SHIFT
);
221 int eqnA
= R300_COMB_FCN_ADD_CLAMP
;
223 if (RGBA_LOGICOP_ENABLED(ctx
) || !ctx
->Color
.BlendEnabled
) {
224 r300SetBlendCntl(r300
, func
, eqn
, 0, func
, eqn
);
229 (blend_factor(ctx
->Color
.BlendSrcRGB
, GL_TRUE
) <<
230 R300_SRC_BLEND_SHIFT
) | (blend_factor(ctx
->Color
.BlendDstRGB
,
232 R300_DST_BLEND_SHIFT
);
234 switch (ctx
->Color
.BlendEquationRGB
) {
236 eqn
= R300_COMB_FCN_ADD_CLAMP
;
239 case GL_FUNC_SUBTRACT
:
240 eqn
= R300_COMB_FCN_SUB_CLAMP
;
243 case GL_FUNC_REVERSE_SUBTRACT
:
244 eqn
= R300_COMB_FCN_RSUB_CLAMP
;
248 eqn
= R300_COMB_FCN_MIN
;
249 func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
250 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
254 eqn
= R300_COMB_FCN_MAX
;
255 func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
256 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
261 "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
262 __FUNCTION__
, __LINE__
, ctx
->Color
.BlendEquationRGB
);
267 (blend_factor(ctx
->Color
.BlendSrcA
, GL_TRUE
) <<
268 R300_SRC_BLEND_SHIFT
) | (blend_factor(ctx
->Color
.BlendDstA
,
270 R300_DST_BLEND_SHIFT
);
272 switch (ctx
->Color
.BlendEquationA
) {
274 eqnA
= R300_COMB_FCN_ADD_CLAMP
;
277 case GL_FUNC_SUBTRACT
:
278 eqnA
= R300_COMB_FCN_SUB_CLAMP
;
281 case GL_FUNC_REVERSE_SUBTRACT
:
282 eqnA
= R300_COMB_FCN_RSUB_CLAMP
;
286 eqnA
= R300_COMB_FCN_MIN
;
287 funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
288 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
292 eqnA
= R300_COMB_FCN_MAX
;
293 funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
294 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
299 "[%s:%u] Invalid A blend equation (0x%04x).\n",
300 __FUNCTION__
, __LINE__
, ctx
->Color
.BlendEquationA
);
304 r300SetBlendCntl(r300
,
306 (R300_SEPARATE_ALPHA_ENABLE
|
308 R300_ALPHA_BLEND_ENABLE
), funcA
, eqnA
);
311 static void r300BlendEquationSeparate(GLcontext
* ctx
,
312 GLenum modeRGB
, GLenum modeA
)
314 r300SetBlendState(ctx
);
317 static void r300BlendFuncSeparate(GLcontext
* ctx
,
318 GLenum sfactorRGB
, GLenum dfactorRGB
,
319 GLenum sfactorA
, GLenum dfactorA
)
321 r300SetBlendState(ctx
);
324 static void r300ClipPlane( GLcontext
*ctx
, GLenum plane
, const GLfloat
*eq
)
326 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
330 /* no VAP UCP on non-TCL chipsets */
331 if (!(rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
334 p
= (GLint
) plane
- (GLint
) GL_CLIP_PLANE0
;
335 ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
337 R300_STATECHANGE( rmesa
, vpucp
[p
] );
338 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_X
] = ip
[0];
339 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_Y
] = ip
[1];
340 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_Z
] = ip
[2];
341 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_W
] = ip
[3];
344 static void r300SetClipPlaneState(GLcontext
* ctx
, GLenum cap
, GLboolean state
)
346 r300ContextPtr r300
= R300_CONTEXT(ctx
);
349 /* no VAP UCP on non-TCL chipsets */
350 if (!(r300
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
353 p
= cap
- GL_CLIP_PLANE0
;
354 R300_STATECHANGE(r300
, vap_clip_cntl
);
356 r300
->hw
.vap_clip_cntl
.cmd
[1] |= (R300_VAP_UCP_ENABLE_0
<< p
);
357 r300ClipPlane(ctx
, cap
, NULL
);
359 r300
->hw
.vap_clip_cntl
.cmd
[1] &= ~(R300_VAP_UCP_ENABLE_0
<< p
);
364 * Update our tracked culling state based on Mesa's state.
366 static void r300UpdateCulling(GLcontext
* ctx
)
368 r300ContextPtr r300
= R300_CONTEXT(ctx
);
371 if (ctx
->Polygon
.CullFlag
) {
372 switch (ctx
->Polygon
.CullFaceMode
) {
374 val
= R300_CULL_FRONT
;
377 val
= R300_CULL_BACK
;
379 case GL_FRONT_AND_BACK
:
380 val
= R300_CULL_FRONT
| R300_CULL_BACK
;
387 switch (ctx
->Polygon
.FrontFace
) {
389 val
|= R300_FRONT_FACE_CW
;
392 val
|= R300_FRONT_FACE_CCW
;
398 R300_STATECHANGE(r300
, cul
);
399 r300
->hw
.cul
.cmd
[R300_CUL_CULL
] = val
;
402 static void r300SetPolygonOffsetState(GLcontext
* ctx
, GLboolean state
)
404 r300ContextPtr r300
= R300_CONTEXT(ctx
);
406 R300_STATECHANGE(r300
, occlusion_cntl
);
408 r300
->hw
.occlusion_cntl
.cmd
[1] |= (3 << 0);
410 r300
->hw
.occlusion_cntl
.cmd
[1] &= ~(3 << 0);
414 static GLboolean
current_fragment_program_writes_depth(GLcontext
* ctx
)
416 r300ContextPtr r300
= R300_CONTEXT(ctx
);
418 if (r300
->radeon
.radeonScreen
->chip_family
< CHIP_FAMILY_RV515
) {
419 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
420 (char *)ctx
->FragmentProgram
._Current
;
421 return (fp
&& fp
->WritesDepth
);
423 struct r500_fragment_program
* fp
=
424 (struct r500_fragment_program
*)(char*)
425 ctx
->FragmentProgram
._Current
;
426 return (fp
&& fp
->writes_depth
);
430 static void r300SetEarlyZState(GLcontext
* ctx
)
432 r300ContextPtr r300
= R300_CONTEXT(ctx
);
433 GLuint topZ
= R300_ZTOP_ENABLE
;
435 if (ctx
->Color
.AlphaEnabled
&& ctx
->Color
.AlphaFunc
!= GL_ALWAYS
)
436 topZ
= R300_ZTOP_DISABLE
;
437 if (current_fragment_program_writes_depth(ctx
))
438 topZ
= R300_ZTOP_DISABLE
;
440 if (topZ
!= r300
->hw
.zstencil_format
.cmd
[2]) {
441 /* Note: This completely reemits the stencil format.
442 * I have not tested whether this is strictly necessary,
443 * or if emitting a write to ZB_ZTOP is enough.
445 R300_STATECHANGE(r300
, zstencil_format
);
446 r300
->hw
.zstencil_format
.cmd
[2] = topZ
;
450 static void r300SetAlphaState(GLcontext
* ctx
)
452 r300ContextPtr r300
= R300_CONTEXT(ctx
);
454 uint32_t pp_misc
= 0x0;
455 GLboolean really_enabled
= ctx
->Color
.AlphaEnabled
;
457 CLAMPED_FLOAT_TO_UBYTE(refByte
, ctx
->Color
.AlphaRef
);
459 switch (ctx
->Color
.AlphaFunc
) {
461 pp_misc
|= R300_FG_ALPHA_FUNC_NEVER
;
464 pp_misc
|= R300_FG_ALPHA_FUNC_LESS
;
467 pp_misc
|= R300_FG_ALPHA_FUNC_EQUAL
;
470 pp_misc
|= R300_FG_ALPHA_FUNC_LE
;
473 pp_misc
|= R300_FG_ALPHA_FUNC_GREATER
;
476 pp_misc
|= R300_FG_ALPHA_FUNC_NOTEQUAL
;
479 pp_misc
|= R300_FG_ALPHA_FUNC_GE
;
482 /*pp_misc |= FG_ALPHA_FUNC_ALWAYS; */
483 really_enabled
= GL_FALSE
;
487 if (really_enabled
) {
488 pp_misc
|= R300_FG_ALPHA_FUNC_ENABLE
;
489 pp_misc
|= R500_FG_ALPHA_FUNC_8BIT
;
490 pp_misc
|= (refByte
& R300_FG_ALPHA_FUNC_VAL_MASK
);
495 R300_STATECHANGE(r300
, at
);
496 r300
->hw
.at
.cmd
[R300_AT_ALPHA_TEST
] = pp_misc
;
497 r300
->hw
.at
.cmd
[R300_AT_UNKNOWN
] = 0;
499 r300SetEarlyZState(ctx
);
502 static void r300AlphaFunc(GLcontext
* ctx
, GLenum func
, GLfloat ref
)
506 r300SetAlphaState(ctx
);
509 static int translate_func(int func
)
513 return R300_ZS_NEVER
;
517 return R300_ZS_EQUAL
;
519 return R300_ZS_LEQUAL
;
521 return R300_ZS_GREATER
;
523 return R300_ZS_NOTEQUAL
;
525 return R300_ZS_GEQUAL
;
527 return R300_ZS_ALWAYS
;
532 static void r300SetDepthState(GLcontext
* ctx
)
534 r300ContextPtr r300
= R300_CONTEXT(ctx
);
536 R300_STATECHANGE(r300
, zs
);
537 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &= R300_STENCIL_ENABLE
|R300_STENCIL_FRONT_BACK
;
538 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= ~(R300_ZS_MASK
<< R300_Z_FUNC_SHIFT
);
540 if (ctx
->Depth
.Test
) {
541 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_Z_ENABLE
;
543 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_Z_WRITE_ENABLE
;
544 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
545 translate_func(ctx
->Depth
.Func
) << R300_Z_FUNC_SHIFT
;
548 r300SetEarlyZState(ctx
);
551 static void r300SetStencilState(GLcontext
* ctx
, GLboolean state
)
553 r300ContextPtr r300
= R300_CONTEXT(ctx
);
555 if (r300
->state
.stencil
.hw_stencil
) {
556 R300_STATECHANGE(r300
, zs
);
558 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |=
561 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &=
562 ~R300_STENCIL_ENABLE
;
566 FALLBACK(&r300
->radeon
, RADEON_FALLBACK_STENCIL
, state
);
571 static void r300UpdatePolygonMode(GLcontext
* ctx
)
573 r300ContextPtr r300
= R300_CONTEXT(ctx
);
574 uint32_t hw_mode
= R300_GA_POLY_MODE_DISABLE
;
576 /* Only do something if a polygon mode is wanted, default is GL_FILL */
577 if (ctx
->Polygon
.FrontMode
!= GL_FILL
||
578 ctx
->Polygon
.BackMode
!= GL_FILL
) {
581 /* Handle GL_CW (clock wise and GL_CCW (counter clock wise)
582 * correctly by selecting the correct front and back face
584 if (ctx
->Polygon
.FrontFace
== GL_CCW
) {
585 f
= ctx
->Polygon
.FrontMode
;
586 b
= ctx
->Polygon
.BackMode
;
588 f
= ctx
->Polygon
.BackMode
;
589 b
= ctx
->Polygon
.FrontMode
;
592 /* Enable polygon mode */
593 hw_mode
|= R300_GA_POLY_MODE_DUAL
;
597 hw_mode
|= R300_GA_POLY_MODE_FRONT_PTYPE_LINE
;
600 hw_mode
|= R300_GA_POLY_MODE_FRONT_PTYPE_POINT
;
603 hw_mode
|= R300_GA_POLY_MODE_FRONT_PTYPE_TRI
;
609 hw_mode
|= R300_GA_POLY_MODE_BACK_PTYPE_LINE
;
612 hw_mode
|= R300_GA_POLY_MODE_BACK_PTYPE_POINT
;
615 hw_mode
|= R300_GA_POLY_MODE_BACK_PTYPE_TRI
;
620 if (r300
->hw
.polygon_mode
.cmd
[1] != hw_mode
) {
621 R300_STATECHANGE(r300
, polygon_mode
);
622 r300
->hw
.polygon_mode
.cmd
[1] = hw_mode
;
625 r300
->hw
.polygon_mode
.cmd
[2] = 0x00000001;
626 r300
->hw
.polygon_mode
.cmd
[3] = 0x00000000;
630 * Change the culling mode.
632 * \note Mesa already filters redundant calls to this function.
634 static void r300CullFace(GLcontext
* ctx
, GLenum mode
)
638 r300UpdateCulling(ctx
);
642 * Change the polygon orientation.
644 * \note Mesa already filters redundant calls to this function.
646 static void r300FrontFace(GLcontext
* ctx
, GLenum mode
)
650 r300UpdateCulling(ctx
);
651 r300UpdatePolygonMode(ctx
);
655 * Change the depth testing function.
657 * \note Mesa already filters redundant calls to this function.
659 static void r300DepthFunc(GLcontext
* ctx
, GLenum func
)
662 r300SetDepthState(ctx
);
666 * Enable/Disable depth writing.
668 * \note Mesa already filters redundant calls to this function.
670 static void r300DepthMask(GLcontext
* ctx
, GLboolean mask
)
673 r300SetDepthState(ctx
);
677 * Handle glColorMask()
679 static void r300ColorMask(GLcontext
* ctx
,
680 GLboolean r
, GLboolean g
, GLboolean b
, GLboolean a
)
682 r300ContextPtr r300
= R300_CONTEXT(ctx
);
683 int mask
= (r
? RB3D_COLOR_CHANNEL_MASK_RED_MASK0
: 0) |
684 (g
? RB3D_COLOR_CHANNEL_MASK_GREEN_MASK0
: 0) |
685 (b
? RB3D_COLOR_CHANNEL_MASK_BLUE_MASK0
: 0) |
686 (a
? RB3D_COLOR_CHANNEL_MASK_ALPHA_MASK0
: 0);
688 if (mask
!= r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
]) {
689 R300_STATECHANGE(r300
, cmk
);
690 r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
] = mask
;
694 /* =============================================================
697 static void r300Fogfv(GLcontext
* ctx
, GLenum pname
, const GLfloat
* param
)
699 r300ContextPtr r300
= R300_CONTEXT(ctx
);
703 } fogScale
, fogStart
;
707 fogScale
.i
= r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
];
708 fogStart
.i
= r300
->hw
.fogp
.cmd
[R300_FOGP_START
];
712 if (!ctx
->Fog
.Enabled
)
714 switch (ctx
->Fog
.Mode
) {
716 R300_STATECHANGE(r300
, fogs
);
717 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
719 cmd
[R300_FOGS_STATE
] & ~R300_FG_FOG_BLEND_FN_MASK
) |
720 R300_FG_FOG_BLEND_FN_LINEAR
;
722 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
727 1.0 / (ctx
->Fog
.End
- ctx
->Fog
.Start
);
729 -ctx
->Fog
.Start
/ (ctx
->Fog
.End
-
734 R300_STATECHANGE(r300
, fogs
);
735 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
737 cmd
[R300_FOGS_STATE
] & ~R300_FG_FOG_BLEND_FN_MASK
) |
738 R300_FG_FOG_BLEND_FN_EXP
;
739 fogScale
.f
= 0.0933 * ctx
->Fog
.Density
;
743 R300_STATECHANGE(r300
, fogs
);
744 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
746 cmd
[R300_FOGS_STATE
] & ~R300_FG_FOG_BLEND_FN_MASK
) |
747 R300_FG_FOG_BLEND_FN_EXP2
;
748 fogScale
.f
= 0.3 * ctx
->Fog
.Density
;
755 switch (ctx
->Fog
.Mode
) {
757 fogScale
.f
= 0.0933 * ctx
->Fog
.Density
;
761 fogScale
.f
= 0.3 * ctx
->Fog
.Density
;
769 if (ctx
->Fog
.Mode
== GL_LINEAR
) {
770 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
775 1.0 / (ctx
->Fog
.End
- ctx
->Fog
.Start
);
777 -ctx
->Fog
.Start
/ (ctx
->Fog
.End
-
783 R300_STATECHANGE(r300
, fogc
);
784 r300
->hw
.fogc
.cmd
[R300_FOGC_R
] =
785 (GLuint
) (ctx
->Fog
.Color
[0] * 1023.0F
) & 0x3FF;
786 r300
->hw
.fogc
.cmd
[R300_FOGC_G
] =
787 (GLuint
) (ctx
->Fog
.Color
[1] * 1023.0F
) & 0x3FF;
788 r300
->hw
.fogc
.cmd
[R300_FOGC_B
] =
789 (GLuint
) (ctx
->Fog
.Color
[2] * 1023.0F
) & 0x3FF;
791 case GL_FOG_COORD_SRC
:
797 if (fogScale
.i
!= r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
] ||
798 fogStart
.i
!= r300
->hw
.fogp
.cmd
[R300_FOGP_START
]) {
799 R300_STATECHANGE(r300
, fogp
);
800 r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
] = fogScale
.i
;
801 r300
->hw
.fogp
.cmd
[R300_FOGP_START
] = fogStart
.i
;
805 static void r300SetFogState(GLcontext
* ctx
, GLboolean state
)
807 r300ContextPtr r300
= R300_CONTEXT(ctx
);
809 R300_STATECHANGE(r300
, fogs
);
811 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] |= R300_FG_FOG_BLEND_ENABLE
;
813 r300Fogfv(ctx
, GL_FOG_MODE
, NULL
);
814 r300Fogfv(ctx
, GL_FOG_DENSITY
, &ctx
->Fog
.Density
);
815 r300Fogfv(ctx
, GL_FOG_START
, &ctx
->Fog
.Start
);
816 r300Fogfv(ctx
, GL_FOG_END
, &ctx
->Fog
.End
);
817 r300Fogfv(ctx
, GL_FOG_COLOR
, ctx
->Fog
.Color
);
819 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] &= ~R300_FG_FOG_BLEND_ENABLE
;
823 /* =============================================================
826 static void r300PointSize(GLcontext
* ctx
, GLfloat size
)
828 r300ContextPtr r300
= R300_CONTEXT(ctx
);
829 /* same size limits for AA, non-AA points */
830 size
= CLAMP(size
, ctx
->Const
.MinPointSize
, ctx
->Const
.MaxPointSize
);
832 R300_STATECHANGE(r300
, ps
);
833 r300
->hw
.ps
.cmd
[R300_PS_POINTSIZE
] =
834 ((int)(size
* 6) << R300_POINTSIZE_X_SHIFT
) |
835 ((int)(size
* 6) << R300_POINTSIZE_Y_SHIFT
);
838 static void r300PointParameter(GLcontext
* ctx
, GLenum pname
, const GLfloat
* param
)
840 r300ContextPtr r300
= R300_CONTEXT(ctx
);
843 case GL_POINT_SIZE_MIN
:
844 R300_STATECHANGE(r300
, ga_point_minmax
);
845 r300
->hw
.ga_point_minmax
.cmd
[1] &= ~R300_GA_POINT_MINMAX_MIN_MASK
;
846 r300
->hw
.ga_point_minmax
.cmd
[1] |= (GLuint
)(ctx
->Point
.MinSize
* 16.0);
848 case GL_POINT_SIZE_MAX
:
849 R300_STATECHANGE(r300
, ga_point_minmax
);
850 r300
->hw
.ga_point_minmax
.cmd
[1] &= ~R300_GA_POINT_MINMAX_MAX_MASK
;
851 r300
->hw
.ga_point_minmax
.cmd
[1] |= (GLuint
)(ctx
->Point
.MaxSize
* 16.0)
852 << R300_GA_POINT_MINMAX_MAX_SHIFT
;
854 case GL_POINT_DISTANCE_ATTENUATION
:
856 case GL_POINT_FADE_THRESHOLD_SIZE
:
863 /* =============================================================
866 static void r300LineWidth(GLcontext
* ctx
, GLfloat widthf
)
868 r300ContextPtr r300
= R300_CONTEXT(ctx
);
870 widthf
= CLAMP(widthf
,
871 ctx
->Const
.MinPointSize
,
872 ctx
->Const
.MaxPointSize
);
873 R300_STATECHANGE(r300
, lcntl
);
874 r300
->hw
.lcntl
.cmd
[1] =
875 R300_LINE_CNT_HO
| R300_LINE_CNT_VE
| (int)(widthf
* 6.0);
878 static void r300PolygonMode(GLcontext
* ctx
, GLenum face
, GLenum mode
)
883 r300UpdatePolygonMode(ctx
);
886 /* =============================================================
890 static int translate_stencil_op(int op
)
898 return R300_ZS_REPLACE
;
903 case GL_INCR_WRAP_EXT
:
904 return R300_ZS_INCR_WRAP
;
905 case GL_DECR_WRAP_EXT
:
906 return R300_ZS_DECR_WRAP
;
908 return R300_ZS_INVERT
;
910 WARN_ONCE("Do not know how to translate stencil op");
916 static void r300ShadeModel(GLcontext
* ctx
, GLenum mode
)
918 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
920 R300_STATECHANGE(rmesa
, shade
);
921 rmesa
->hw
.shade
.cmd
[1] = 0x00000002;
924 rmesa
->hw
.shade
.cmd
[2] = R300_RE_SHADE_MODEL_FLAT
;
927 rmesa
->hw
.shade
.cmd
[2] = R300_RE_SHADE_MODEL_SMOOTH
;
932 rmesa
->hw
.shade
.cmd
[3] = 0x00000000;
933 rmesa
->hw
.shade
.cmd
[4] = 0x00000000;
936 static void r300StencilFuncSeparate(GLcontext
* ctx
, GLenum face
,
937 GLenum func
, GLint ref
, GLuint mask
)
939 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
942 Ref
[0] & 0xff) << R300_STENCILREF_SHIFT
) | ((ctx
->
948 R300_STENCILMASK_SHIFT
));
952 R300_STATECHANGE(rmesa
, zs
);
953 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_STENCIL_FRONT_BACK
;
954 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= ~((R300_ZS_MASK
<<
955 R300_S_FRONT_FUNC_SHIFT
)
957 R300_S_BACK_FUNC_SHIFT
));
959 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &=
960 ~((R300_STENCILREF_MASK
<< R300_STENCILREF_SHIFT
) |
961 (R300_STENCILREF_MASK
<< R300_STENCILMASK_SHIFT
));
963 flag
= translate_func(ctx
->Stencil
.Function
[0]);
964 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
965 (flag
<< R300_S_FRONT_FUNC_SHIFT
);
967 if (ctx
->Stencil
._TestTwoSide
)
968 flag
= translate_func(ctx
->Stencil
.Function
[1]);
970 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
971 (flag
<< R300_S_BACK_FUNC_SHIFT
);
972 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |= refmask
;
975 static void r300StencilMaskSeparate(GLcontext
* ctx
, GLenum face
, GLuint mask
)
977 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
979 R300_STATECHANGE(rmesa
, zs
);
980 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &=
981 ~(R300_STENCILREF_MASK
<<
982 R300_STENCILWRITEMASK_SHIFT
);
983 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |=
985 WriteMask
[0] & R300_STENCILREF_MASK
) <<
986 R300_STENCILWRITEMASK_SHIFT
;
989 static void r300StencilOpSeparate(GLcontext
* ctx
, GLenum face
,
990 GLenum fail
, GLenum zfail
, GLenum zpass
)
992 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
994 R300_STATECHANGE(rmesa
, zs
);
995 /* It is easier to mask what's left.. */
996 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &=
997 (R300_ZS_MASK
<< R300_Z_FUNC_SHIFT
) |
998 (R300_ZS_MASK
<< R300_S_FRONT_FUNC_SHIFT
) |
999 (R300_ZS_MASK
<< R300_S_BACK_FUNC_SHIFT
);
1001 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
1002 (translate_stencil_op(ctx
->Stencil
.FailFunc
[0]) <<
1003 R300_S_FRONT_SFAIL_OP_SHIFT
)
1004 | (translate_stencil_op(ctx
->Stencil
.ZFailFunc
[0]) <<
1005 R300_S_FRONT_ZFAIL_OP_SHIFT
)
1006 | (translate_stencil_op(ctx
->Stencil
.ZPassFunc
[0]) <<
1007 R300_S_FRONT_ZPASS_OP_SHIFT
);
1009 if (ctx
->Stencil
._TestTwoSide
) {
1010 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
1011 (translate_stencil_op(ctx
->Stencil
.FailFunc
[1]) <<
1012 R300_S_BACK_SFAIL_OP_SHIFT
)
1013 | (translate_stencil_op(ctx
->Stencil
.ZFailFunc
[1]) <<
1014 R300_S_BACK_ZFAIL_OP_SHIFT
)
1015 | (translate_stencil_op(ctx
->Stencil
.ZPassFunc
[1]) <<
1016 R300_S_BACK_ZPASS_OP_SHIFT
);
1018 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
1019 (translate_stencil_op(ctx
->Stencil
.FailFunc
[0]) <<
1020 R300_S_BACK_SFAIL_OP_SHIFT
)
1021 | (translate_stencil_op(ctx
->Stencil
.ZFailFunc
[0]) <<
1022 R300_S_BACK_ZFAIL_OP_SHIFT
)
1023 | (translate_stencil_op(ctx
->Stencil
.ZPassFunc
[0]) <<
1024 R300_S_BACK_ZPASS_OP_SHIFT
);
1028 /* =============================================================
1029 * Window position and viewport transformation
1033 * To correctly position primitives:
1035 #define SUBPIXEL_X 0.125
1036 #define SUBPIXEL_Y 0.125
1038 static void r300UpdateWindow(GLcontext
* ctx
)
1040 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1041 __DRIdrawablePrivate
*dPriv
= rmesa
->radeon
.dri
.drawable
;
1042 GLfloat xoffset
= dPriv
? (GLfloat
) dPriv
->x
: 0;
1043 GLfloat yoffset
= dPriv
? (GLfloat
) dPriv
->y
+ dPriv
->h
: 0;
1044 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1046 GLfloat sx
= v
[MAT_SX
];
1047 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1048 GLfloat sy
= -v
[MAT_SY
];
1049 GLfloat ty
= (-v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1050 GLfloat sz
= v
[MAT_SZ
] * rmesa
->state
.depth
.scale
;
1051 GLfloat tz
= v
[MAT_TZ
] * rmesa
->state
.depth
.scale
;
1053 R300_FIREVERTICES(rmesa
);
1054 R300_STATECHANGE(rmesa
, vpt
);
1056 rmesa
->hw
.vpt
.cmd
[R300_VPT_XSCALE
] = r300PackFloat32(sx
);
1057 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
1058 rmesa
->hw
.vpt
.cmd
[R300_VPT_YSCALE
] = r300PackFloat32(sy
);
1059 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
1060 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZSCALE
] = r300PackFloat32(sz
);
1061 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZOFFSET
] = r300PackFloat32(tz
);
1064 static void r300Viewport(GLcontext
* ctx
, GLint x
, GLint y
,
1065 GLsizei width
, GLsizei height
)
1067 /* Don't pipeline viewport changes, conflict with window offset
1068 * setting below. Could apply deltas to rescue pipelined viewport
1069 * values, or keep the originals hanging around.
1071 r300UpdateWindow(ctx
);
1074 static void r300DepthRange(GLcontext
* ctx
, GLclampd nearval
, GLclampd farval
)
1076 r300UpdateWindow(ctx
);
1079 void r300UpdateViewportOffset(GLcontext
* ctx
)
1081 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1082 __DRIdrawablePrivate
*dPriv
= ((radeonContextPtr
) rmesa
)->dri
.drawable
;
1083 GLfloat xoffset
= (GLfloat
) dPriv
->x
;
1084 GLfloat yoffset
= (GLfloat
) dPriv
->y
+ dPriv
->h
;
1085 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1087 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1088 GLfloat ty
= (-v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1090 if (rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] != r300PackFloat32(tx
) ||
1091 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] != r300PackFloat32(ty
)) {
1092 /* Note: this should also modify whatever data the context reset
1095 R300_STATECHANGE(rmesa
, vpt
);
1096 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
1097 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
1101 radeonUpdateScissor(ctx
);
1105 * Tell the card where to render (offset, pitch).
1106 * Effected by glDrawBuffer, etc
1108 void r300UpdateDrawBuffer(GLcontext
* ctx
)
1110 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1111 r300ContextPtr r300
= rmesa
;
1112 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
1113 driRenderbuffer
*drb
;
1115 if (fb
->_ColorDrawBufferIndexes
[0] == BUFFER_FRONT_LEFT
) {
1118 (driRenderbuffer
*) fb
->Attachment
[BUFFER_FRONT_LEFT
].
1120 } else if (fb
->_ColorDrawBufferIndexes
[0] == BUFFER_BACK_LEFT
) {
1123 (driRenderbuffer
*) fb
->Attachment
[BUFFER_BACK_LEFT
].
1126 /* drawing to multiple buffers, or none */
1131 assert(drb
->flippedPitch
);
1133 R300_STATECHANGE(rmesa
, cb
);
1135 r300
->hw
.cb
.cmd
[R300_CB_OFFSET
] = drb
->flippedOffset
+ //r300->radeon.state.color.drawOffset +
1136 r300
->radeon
.radeonScreen
->fbLocation
;
1137 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] = drb
->flippedPitch
; //r300->radeon.state.color.drawPitch;
1139 if (r300
->radeon
.radeonScreen
->cpp
== 4)
1140 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_ARGB8888
;
1142 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_RGB565
;
1144 if (r300
->radeon
.sarea
->tiling_enabled
)
1145 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_TILE_ENABLE
;
1147 R200_STATECHANGE(rmesa
, ctx
);
1149 /* Note: we used the (possibly) page-flipped values */
1150 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLOROFFSET
]
1151 = ((drb
->flippedOffset
+ rmesa
->r200Screen
->fbLocation
)
1152 & R200_COLOROFFSET_MASK
);
1153 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] = drb
->flippedPitch
;
1155 if (rmesa
->sarea
->tiling_enabled
) {
1156 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] |=
1157 R200_COLOR_TILE_ENABLE
;
1163 r300FetchStateParameter(GLcontext
* ctx
,
1164 const gl_state_index state
[STATE_LENGTH
],
1167 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1170 case STATE_INTERNAL
:
1172 case STATE_R300_WINDOW_DIMENSION
:
1173 value
[0] = r300
->radeon
.dri
.drawable
->w
* 0.5f
; /* width*0.5 */
1174 value
[1] = r300
->radeon
.dri
.drawable
->h
* 0.5f
; /* height*0.5 */
1175 value
[2] = 0.5F
; /* for moving range [-1 1] -> [0 1] */
1176 value
[3] = 1.0F
; /* not used */
1179 case STATE_R300_TEXRECT_FACTOR
:{
1180 struct gl_texture_object
*t
=
1181 ctx
->Texture
.Unit
[state
[2]].CurrentRect
;
1183 if (t
&& t
->Image
[0][t
->BaseLevel
]) {
1184 struct gl_texture_image
*image
=
1185 t
->Image
[0][t
->BaseLevel
];
1186 value
[0] = 1.0 / image
->Width2
;
1187 value
[1] = 1.0 / image
->Height2
;
1208 * Update R300's own internal state parameters.
1209 * For now just STATE_R300_WINDOW_DIMENSION
1211 void r300UpdateStateParameters(GLcontext
* ctx
, GLuint new_state
)
1213 struct r300_fragment_program
*fp
;
1214 struct gl_program_parameter_list
*paramList
;
1217 if (!(new_state
& (_NEW_BUFFERS
| _NEW_PROGRAM
)))
1220 fp
= (struct r300_fragment_program
*)ctx
->FragmentProgram
._Current
;
1224 paramList
= fp
->mesa_program
.Base
.Parameters
;
1229 for (i
= 0; i
< paramList
->NumParameters
; i
++) {
1230 if (paramList
->Parameters
[i
].Type
== PROGRAM_STATE_VAR
) {
1231 r300FetchStateParameter(ctx
,
1232 paramList
->Parameters
[i
].
1234 paramList
->ParameterValues
[i
]);
1239 /* =============================================================
1242 static void r300PolygonOffset(GLcontext
* ctx
, GLfloat factor
, GLfloat units
)
1244 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1245 GLfloat constant
= units
;
1247 switch (ctx
->Visual
.depthBits
) {
1258 /* fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */
1260 R300_STATECHANGE(rmesa
, zbs
);
1261 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_FACTOR
] = r300PackFloat32(factor
);
1262 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_CONSTANT
] = r300PackFloat32(constant
);
1263 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_FACTOR
] = r300PackFloat32(factor
);
1264 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_CONSTANT
] = r300PackFloat32(constant
);
1267 /* Routing and texture-related */
1269 /* r300 doesnt handle GL_CLAMP and GL_MIRROR_CLAMP_EXT correctly when filter is NEAREST.
1270 * Since texwrap produces same results for GL_CLAMP and GL_CLAMP_TO_EDGE we use them instead.
1271 * We need to recalculate wrap modes whenever filter mode is changed because someone might do:
1272 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1273 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1274 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1275 * Since r300 completely ignores R300_TX_CLAMP when either min or mag is nearest it cant handle
1276 * combinations where only one of them is nearest.
1278 static unsigned long gen_fixed_filter(unsigned long f
)
1280 unsigned long mag
, min
, needs_fixing
= 0;
1283 /* We ignore MIRROR bit so we dont have to do everything twice */
1284 if ((f
& ((7 - 1) << R300_TX_WRAP_S_SHIFT
)) ==
1285 (R300_TX_CLAMP
<< R300_TX_WRAP_S_SHIFT
)) {
1288 if ((f
& ((7 - 1) << R300_TX_WRAP_T_SHIFT
)) ==
1289 (R300_TX_CLAMP
<< R300_TX_WRAP_T_SHIFT
)) {
1292 if ((f
& ((7 - 1) << R300_TX_WRAP_R_SHIFT
)) ==
1293 (R300_TX_CLAMP
<< R300_TX_WRAP_R_SHIFT
)) {
1300 mag
= f
& R300_TX_MAG_FILTER_MASK
;
1301 min
= f
& (R300_TX_MIN_FILTER_MASK
|R300_TX_MIN_FILTER_MIP_MASK
);
1303 /* TODO: Check for anisto filters too */
1304 if ((mag
!= R300_TX_MAG_FILTER_NEAREST
)
1305 && (min
!= R300_TX_MIN_FILTER_NEAREST
))
1308 /* r300 cant handle these modes hence we force nearest to linear */
1309 if ((mag
== R300_TX_MAG_FILTER_NEAREST
)
1310 && (min
!= R300_TX_MIN_FILTER_NEAREST
)) {
1311 f
&= ~R300_TX_MAG_FILTER_NEAREST
;
1312 f
|= R300_TX_MAG_FILTER_LINEAR
;
1316 if ((min
== R300_TX_MIN_FILTER_NEAREST
)
1317 && (mag
!= R300_TX_MAG_FILTER_NEAREST
)) {
1318 f
&= ~R300_TX_MIN_FILTER_NEAREST
;
1319 f
|= R300_TX_MIN_FILTER_LINEAR
;
1323 /* Both are nearest */
1324 if (needs_fixing
& 1) {
1325 f
&= ~((7 - 1) << R300_TX_WRAP_S_SHIFT
);
1326 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_S_SHIFT
;
1328 if (needs_fixing
& 2) {
1329 f
&= ~((7 - 1) << R300_TX_WRAP_T_SHIFT
);
1330 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_T_SHIFT
;
1332 if (needs_fixing
& 4) {
1333 f
&= ~((7 - 1) << R300_TX_WRAP_R_SHIFT
);
1334 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_R_SHIFT
;
1339 static void r300SetupFragmentShaderTextures(GLcontext
*ctx
, int *tmu_mappings
)
1341 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1343 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
1344 (char *)ctx
->FragmentProgram
._Current
;
1345 struct r300_fragment_program_code
*code
= &fp
->code
;
1347 R300_STATECHANGE(r300
, fpt
);
1349 for (i
= 0; i
< code
->tex
.length
; i
++) {
1354 unit
= code
->tex
.inst
[i
] >> R300_TEX_ID_SHIFT
;
1357 val
= code
->tex
.inst
[i
];
1358 val
&= ~R300_TEX_ID_MASK
;
1361 (val
& R300_TEX_INST_MASK
) >> R300_TEX_INST_SHIFT
;
1362 if (opcode
== R300_TEX_OP_KIL
) {
1363 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1365 if (tmu_mappings
[unit
] >= 0) {
1367 tmu_mappings
[unit
] <<
1369 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1371 // We get here when the corresponding texture image is incomplete
1372 // (e.g. incomplete mipmaps etc.)
1373 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1378 r300
->hw
.fpt
.cmd
[R300_FPT_CMD_0
] =
1379 cmdpacket0(R300_US_TEX_INST_0
, code
->tex
.length
);
1382 static void r500SetupFragmentShaderTextures(GLcontext
*ctx
, int *tmu_mappings
)
1385 struct r500_fragment_program
*fp
= (struct r500_fragment_program
*)
1386 (char *)ctx
->FragmentProgram
._Current
;
1387 struct r500_fragment_program_code
*code
= &fp
->code
;
1389 /* find all the texture instructions and relocate the texture units */
1390 for (i
= 0; i
< code
->inst_end
+ 1; i
++) {
1391 if ((code
->inst
[i
].inst0
& 0x3) == R500_INST_TYPE_TEX
) {
1393 int unit
, opcode
, new_unit
;
1395 val
= code
->inst
[i
].inst1
;
1397 unit
= (val
>> 16) & 0xf;
1399 val
&= ~(0xf << 16);
1401 opcode
= val
& (0x7 << 22);
1402 if (opcode
== R500_TEX_INST_TEXKILL
) {
1405 if (tmu_mappings
[unit
] >= 0) {
1406 new_unit
= tmu_mappings
[unit
];
1411 val
|= R500_TEX_ID(new_unit
);
1412 code
->inst
[i
].inst1
= val
;
1417 static GLuint
translate_lod_bias(GLfloat bias
)
1419 GLint b
= (int)(bias
*32);
1422 else if (b
< -(1 << 9))
1424 return (((GLuint
)b
) << R300_LOD_BIAS_SHIFT
) & R300_LOD_BIAS_MASK
;
1427 static void r300SetupTextures(GLcontext
* ctx
)
1430 struct r300_tex_obj
*t
;
1431 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1433 int last_hw_tmu
= -1; /* -1 translates into no setup costs for fields */
1434 int tmu_mappings
[R300_MAX_TEXTURE_UNITS
] = { -1, };
1435 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
1436 (char *)ctx
->FragmentProgram
._Current
;
1438 R300_STATECHANGE(r300
, txe
);
1439 R300_STATECHANGE(r300
, tex
.filter
);
1440 R300_STATECHANGE(r300
, tex
.filter_1
);
1441 R300_STATECHANGE(r300
, tex
.size
);
1442 R300_STATECHANGE(r300
, tex
.format
);
1443 R300_STATECHANGE(r300
, tex
.pitch
);
1444 R300_STATECHANGE(r300
, tex
.offset
);
1445 R300_STATECHANGE(r300
, tex
.chroma_key
);
1446 R300_STATECHANGE(r300
, tex
.border_color
);
1448 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] = 0x0;
1450 mtu
= r300
->radeon
.glCtx
->Const
.MaxTextureUnits
;
1451 if (RADEON_DEBUG
& DEBUG_STATE
)
1452 fprintf(stderr
, "mtu=%d\n", mtu
);
1454 if (mtu
> R300_MAX_TEXTURE_UNITS
) {
1456 "Aiiee ! mtu=%d is greater than R300_MAX_TEXTURE_UNITS=%d\n",
1457 mtu
, R300_MAX_TEXTURE_UNITS
);
1461 /* We cannot let disabled tmu offsets pass DRM */
1462 for (i
= 0; i
< mtu
; i
++) {
1463 if (ctx
->Texture
.Unit
[i
]._ReallyEnabled
) {
1465 #if 0 /* Enables old behaviour */
1468 tmu_mappings
[i
] = hw_tmu
;
1470 t
= r300
->state
.texture
.unit
[i
].texobj
;
1471 /* XXX questionable fix for bug 9170: */
1475 if ((t
->format
& 0xffffff00) == 0xffffff00) {
1477 ("unknown texture format (entry %x) encountered. Help me !\n",
1481 if (RADEON_DEBUG
& DEBUG_STATE
)
1483 "Activating texture unit %d\n", i
);
1485 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] |= (1 << hw_tmu
);
1487 r300
->hw
.tex
.filter
.cmd
[R300_TEX_VALUE_0
+
1489 gen_fixed_filter(t
->filter
) | (hw_tmu
<< 28);
1490 /* Note: There is a LOD bias per texture unit and a LOD bias
1491 * per texture object. We add them here to get the correct behaviour.
1492 * (The per-texture object LOD bias was introduced in OpenGL 1.4
1493 * and is not present in the EXT_texture_object extension).
1495 r300
->hw
.tex
.filter_1
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] =
1497 translate_lod_bias(ctx
->Texture
.Unit
[i
].LodBias
+ t
->base
.tObj
->LodBias
);
1498 r300
->hw
.tex
.size
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] =
1500 r300
->hw
.tex
.format
.cmd
[R300_TEX_VALUE_0
+
1501 hw_tmu
] = t
->format
;
1502 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] =
1504 r300
->hw
.tex
.offset
.cmd
[R300_TEX_VALUE_0
+
1505 hw_tmu
] = t
->offset
;
1507 if (t
->offset
& R300_TXO_MACRO_TILE
) {
1508 WARN_ONCE("macro tiling enabled!\n");
1511 if (t
->offset
& R300_TXO_MICRO_TILE
) {
1512 WARN_ONCE("micro tiling enabled!\n");
1515 r300
->hw
.tex
.chroma_key
.cmd
[R300_TEX_VALUE_0
+
1517 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_VALUE_0
+
1521 last_hw_tmu
= hw_tmu
;
1527 r300
->hw
.tex
.filter
.cmd
[R300_TEX_CMD_0
] =
1528 cmdpacket0(R300_TX_FILTER0_0
, last_hw_tmu
+ 1);
1529 r300
->hw
.tex
.filter_1
.cmd
[R300_TEX_CMD_0
] =
1530 cmdpacket0(R300_TX_FILTER1_0
, last_hw_tmu
+ 1);
1531 r300
->hw
.tex
.size
.cmd
[R300_TEX_CMD_0
] =
1532 cmdpacket0(R300_TX_SIZE_0
, last_hw_tmu
+ 1);
1533 r300
->hw
.tex
.format
.cmd
[R300_TEX_CMD_0
] =
1534 cmdpacket0(R300_TX_FORMAT_0
, last_hw_tmu
+ 1);
1535 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_CMD_0
] =
1536 cmdpacket0(R300_TX_FORMAT2_0
, last_hw_tmu
+ 1);
1537 r300
->hw
.tex
.offset
.cmd
[R300_TEX_CMD_0
] =
1538 cmdpacket0(R300_TX_OFFSET_0
, last_hw_tmu
+ 1);
1539 r300
->hw
.tex
.chroma_key
.cmd
[R300_TEX_CMD_0
] =
1540 cmdpacket0(R300_TX_CHROMA_KEY_0
, last_hw_tmu
+ 1);
1541 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_CMD_0
] =
1542 cmdpacket0(R300_TX_BORDER_COLOR_0
, last_hw_tmu
+ 1);
1544 if (!fp
) /* should only happenen once, just after context is created */
1547 if (r300
->radeon
.radeonScreen
->chip_family
< CHIP_FAMILY_RV515
) {
1548 if (fp
->mesa_program
.UsesKill
&& last_hw_tmu
< 0) {
1549 // The KILL operation requires the first texture unit
1551 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] |= 1;
1552 r300
->hw
.tex
.filter
.cmd
[R300_TEX_VALUE_0
] = 0;
1553 r300
->hw
.tex
.filter
.cmd
[R300_TEX_CMD_0
] =
1554 cmdpacket0(R300_TX_FILTER0_0
, 1);
1556 r300SetupFragmentShaderTextures(ctx
, tmu_mappings
);
1558 r500SetupFragmentShaderTextures(ctx
, tmu_mappings
);
1560 if (RADEON_DEBUG
& DEBUG_STATE
)
1561 fprintf(stderr
, "TX_ENABLE: %08x last_hw_tmu=%d\n",
1562 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
], last_hw_tmu
);
1565 union r300_outputs_written
{
1566 GLuint vp_outputs
; /* hw_tcl_on */
1567 DECLARE_RENDERINPUTS(index_bitset
); /* !hw_tcl_on */
1570 #define R300_OUTPUTS_WRITTEN_TEST(ow, vp_result, tnl_attrib) \
1571 ((hw_tcl_on) ? (ow).vp_outputs & (1 << (vp_result)) : \
1572 RENDERINPUTS_TEST( (ow.index_bitset), (tnl_attrib) ))
1574 static void r300SetupRSUnit(GLcontext
* ctx
)
1576 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1577 /* I'm still unsure if these are needed */
1578 GLuint interp_col
[8];
1579 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1580 struct vertex_buffer
*VB
= &tnl
->vb
;
1581 union r300_outputs_written OutputsWritten
;
1583 int fp_reg
, high_rr
;
1585 int rs_tex_count
= 0, rs_col_count
= 0;
1588 memset(interp_col
, 0, sizeof(interp_col
));
1591 OutputsWritten
.vp_outputs
= CURRENT_VERTEX_SHADER(ctx
)->key
.OutputsWritten
;
1593 RENDERINPUTS_COPY(OutputsWritten
.index_bitset
, r300
->state
.render_inputs_bitset
);
1595 if (ctx
->FragmentProgram
._Current
)
1596 InputsRead
= ctx
->FragmentProgram
._Current
->Base
.InputsRead
;
1598 fprintf(stderr
, "No ctx->FragmentProgram._Current!!\n");
1599 return; /* This should only ever happen once.. */
1602 R300_STATECHANGE(r300
, ri
);
1603 R300_STATECHANGE(r300
, rc
);
1604 R300_STATECHANGE(r300
, rr
);
1606 fp_reg
= col_interp_nr
= high_rr
= 0;
1608 r300
->hw
.rr
.cmd
[R300_RR_INST_1
] = 0;
1610 if (InputsRead
& FRAG_BIT_WPOS
) {
1611 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++)
1612 if (!(InputsRead
& (FRAG_BIT_TEX0
<< i
)))
1615 if (i
== ctx
->Const
.MaxTextureUnits
) {
1616 fprintf(stderr
, "\tno free texcoord found...\n");
1620 InputsRead
|= (FRAG_BIT_TEX0
<< i
);
1621 InputsRead
&= ~FRAG_BIT_WPOS
;
1624 if (InputsRead
& FRAG_BIT_COL0
) {
1625 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR0
]->size
;
1626 interp_col
[0] |= R300_RS_COL_PTR(rs_col_count
);
1628 interp_col
[0] |= R300_RS_COL_FMT(R300_RS_COL_FMT_RGB1
);
1629 rs_col_count
+= count
;
1632 interp_col
[0] = R300_RS_COL_FMT(R300_RS_COL_FMT_0001
);
1634 if (InputsRead
& FRAG_BIT_COL1
) {
1635 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR1
]->size
;
1637 interp_col
[1] |= R300_RS_COL_FMT(R300_RS_COL_FMT_RGB0
);
1638 interp_col
[1] |= R300_RS_COL_PTR(1);
1639 rs_col_count
+= count
;
1643 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
1646 /* with TCL we always seem to route 4 components */
1650 count
= VB
->AttribPtr
[_TNL_ATTRIB_TEX(i
)]->size
;
1652 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ i
] = interp_col
[i
] | rs_tex_count
;
1654 case 4: swiz
= R300_RS_SEL_S(0) | R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(3); break;
1655 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;
1658 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;
1661 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ i
] |= swiz
;
1663 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ fp_reg
] = 0;
1664 if (InputsRead
& (FRAG_BIT_TEX0
<< i
)) {
1666 rs_tex_count
+= count
;
1668 //assert(r300->state.texture.tc_count != 0);
1669 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ fp_reg
] |= R300_RS_INST_TEX_CN_WRITE
| i
/* source INTERP */
1670 | (fp_reg
<< R300_RS_INST_TEX_ADDR_SHIFT
);
1673 /* Passing invalid data here can lock the GPU. */
1674 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_TEX0
+ i
, _TNL_ATTRIB_TEX(i
))) {
1675 InputsRead
&= ~(FRAG_BIT_TEX0
<< i
);
1678 WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i
);
1683 if (InputsRead
& FRAG_BIT_COL0
) {
1684 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL0
, _TNL_ATTRIB_COLOR0
)) {
1685 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
);
1686 InputsRead
&= ~FRAG_BIT_COL0
;
1689 WARN_ONCE("fragprog wants col0, vp doesn't provide it\n");
1693 if (InputsRead
& FRAG_BIT_COL1
) {
1694 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL1
, _TNL_ATTRIB_COLOR1
)) {
1695 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
);
1696 InputsRead
&= ~FRAG_BIT_COL1
;
1701 WARN_ONCE("fragprog wants col1, vp doesn't provide it\n");
1705 /* Need at least one. This might still lock as the values are undefined... */
1706 if (rs_tex_count
== 0 && col_interp_nr
== 0) {
1707 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
);
1711 r300
->hw
.rc
.cmd
[1] = 0 | (rs_tex_count
<< R300_IT_COUNT_SHIFT
)
1712 | (col_interp_nr
<< R300_IC_COUNT_SHIFT
)
1715 assert(high_rr
>= 0);
1716 r300
->hw
.rr
.cmd
[R300_RR_CMD_0
] = cmdpacket0(R300_RS_INST_0
, high_rr
+ 1);
1717 r300
->hw
.rc
.cmd
[2] = high_rr
;
1720 WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead
);
1723 static void r500SetupRSUnit(GLcontext
* ctx
)
1725 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1726 /* I'm still unsure if these are needed */
1727 GLuint interp_col
[8];
1728 union r300_outputs_written OutputsWritten
;
1729 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1730 struct vertex_buffer
*VB
= &tnl
->vb
;
1732 int fp_reg
, high_rr
;
1733 int rs_col_count
= 0;
1734 int in_texcoords
, col_interp_nr
;
1737 memset(interp_col
, 0, sizeof(interp_col
));
1739 OutputsWritten
.vp_outputs
= CURRENT_VERTEX_SHADER(ctx
)->key
.OutputsWritten
;
1741 RENDERINPUTS_COPY(OutputsWritten
.index_bitset
, r300
->state
.render_inputs_bitset
);
1743 if (ctx
->FragmentProgram
._Current
)
1744 InputsRead
= ctx
->FragmentProgram
._Current
->Base
.InputsRead
;
1746 fprintf(stderr
, "No ctx->FragmentProgram._Current!!\n");
1747 return; /* This should only ever happen once.. */
1750 R300_STATECHANGE(r300
, ri
);
1751 R300_STATECHANGE(r300
, rc
);
1752 R300_STATECHANGE(r300
, rr
);
1754 fp_reg
= col_interp_nr
= high_rr
= in_texcoords
= 0;
1756 r300
->hw
.rr
.cmd
[R300_RR_INST_1
] = 0;
1758 if (InputsRead
& FRAG_BIT_WPOS
) {
1759 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++)
1760 if (!(InputsRead
& (FRAG_BIT_TEX0
<< i
)))
1763 if (i
== ctx
->Const
.MaxTextureUnits
) {
1764 fprintf(stderr
, "\tno free texcoord found...\n");
1768 InputsRead
|= (FRAG_BIT_TEX0
<< i
);
1769 InputsRead
&= ~FRAG_BIT_WPOS
;
1772 if (InputsRead
& FRAG_BIT_COL0
) {
1773 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR0
]->size
;
1774 interp_col
[0] |= R500_RS_COL_PTR(rs_col_count
);
1776 interp_col
[0] |= R500_RS_COL_FMT(R300_RS_COL_FMT_RGB1
);
1777 rs_col_count
+= count
;
1780 interp_col
[0] = R500_RS_COL_FMT(R300_RS_COL_FMT_0001
);
1782 if (InputsRead
& FRAG_BIT_COL1
) {
1783 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR1
]->size
;
1784 interp_col
[1] |= R500_RS_COL_PTR(1);
1786 interp_col
[1] |= R500_RS_COL_FMT(R300_RS_COL_FMT_RGB0
);
1787 rs_col_count
+= count
;
1790 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
1793 /* with TCL we always seem to route 4 components */
1794 if (InputsRead
& (FRAG_BIT_TEX0
<< i
)) {
1799 count
= VB
->AttribPtr
[_TNL_ATTRIB_TEX(i
)]->size
;
1801 /* always have on texcoord */
1802 swiz
|= in_texcoords
++ << R500_RS_IP_TEX_PTR_S_SHIFT
;
1804 swiz
|= in_texcoords
++ << R500_RS_IP_TEX_PTR_T_SHIFT
;
1806 swiz
|= R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_T_SHIFT
;
1809 swiz
|= in_texcoords
++ << R500_RS_IP_TEX_PTR_R_SHIFT
;
1811 swiz
|= R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_R_SHIFT
;
1814 swiz
|= in_texcoords
++ << R500_RS_IP_TEX_PTR_Q_SHIFT
;
1816 swiz
|= R500_RS_IP_PTR_K1
<< R500_RS_IP_TEX_PTR_Q_SHIFT
;
1819 swiz
= (R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_S_SHIFT
) |
1820 (R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_T_SHIFT
) |
1821 (R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_R_SHIFT
) |
1822 (R500_RS_IP_PTR_K1
<< R500_RS_IP_TEX_PTR_Q_SHIFT
);
1824 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ i
] = interp_col
[i
] | swiz
;
1826 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ fp_reg
] = 0;
1827 if (InputsRead
& (FRAG_BIT_TEX0
<< i
)) {
1828 //assert(r300->state.texture.tc_count != 0);
1829 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ fp_reg
] |= R500_RS_INST_TEX_CN_WRITE
| i
/* source INTERP */
1830 | (fp_reg
<< R500_RS_INST_TEX_ADDR_SHIFT
);
1833 /* Passing invalid data here can lock the GPU. */
1834 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_TEX0
+ i
, _TNL_ATTRIB_TEX(i
))) {
1835 InputsRead
&= ~(FRAG_BIT_TEX0
<< i
);
1838 WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i
);
1843 if (InputsRead
& FRAG_BIT_COL0
) {
1844 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL0
, _TNL_ATTRIB_COLOR0
)) {
1845 r300
->hw
.rr
.cmd
[R300_RR_INST_0
] |= R500_RS_INST_COL_CN_WRITE
| (fp_reg
++ << R500_RS_INST_COL_ADDR_SHIFT
);
1846 InputsRead
&= ~FRAG_BIT_COL0
;
1849 WARN_ONCE("fragprog wants col0, vp doesn't provide it\n");
1853 if (InputsRead
& FRAG_BIT_COL1
) {
1854 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL1
, _TNL_ATTRIB_COLOR1
)) {
1855 r300
->hw
.rr
.cmd
[R300_RR_INST_1
] |= (1 << 12) | R500_RS_INST_COL_CN_WRITE
| (fp_reg
++ << R500_RS_INST_COL_ADDR_SHIFT
);
1856 InputsRead
&= ~FRAG_BIT_COL1
;
1861 WARN_ONCE("fragprog wants col1, vp doesn't provide it\n");
1865 /* Need at least one. This might still lock as the values are undefined... */
1866 if (in_texcoords
== 0 && col_interp_nr
== 0) {
1867 r300
->hw
.rr
.cmd
[R300_RR_INST_0
] |= 0 | R500_RS_INST_COL_CN_WRITE
| (fp_reg
++ << R500_RS_INST_COL_ADDR_SHIFT
);
1871 r300
->hw
.rc
.cmd
[1] = 0 | (in_texcoords
<< R300_IT_COUNT_SHIFT
)
1872 | (col_interp_nr
<< R300_IC_COUNT_SHIFT
)
1875 assert(high_rr
>= 0);
1876 r300
->hw
.rr
.cmd
[R300_RR_CMD_0
] = cmdpacket0(R500_RS_INST_0
, high_rr
+ 1);
1877 r300
->hw
.rc
.cmd
[2] = 0xC0 | high_rr
;
1880 WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead
);
1886 #define bump_vpu_count(ptr, new_count) do{\
1887 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
1888 int _nc=(new_count)/4; \
1889 assert(_nc < 256); \
1890 if(_nc>_p->vpu.count)_p->vpu.count=_nc;\
1893 static INLINE
void r300SetupVertexProgramFragment(r300ContextPtr r300
, int dest
, struct r300_vertex_shader_fragment
*vsf
)
1897 if (vsf
->length
== 0)
1900 if (vsf
->length
& 0x3) {
1901 fprintf(stderr
, "VERTEX_SHADER_FRAGMENT must have length divisible by 4\n");
1905 switch ((dest
>> 8) & 0xf) {
1907 R300_STATECHANGE(r300
, vpi
);
1908 for (i
= 0; i
< vsf
->length
; i
++)
1909 r300
->hw
.vpi
.cmd
[R300_VPI_INSTR_0
+ i
+ 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1910 bump_vpu_count(r300
->hw
.vpi
.cmd
, vsf
->length
+ 4 * (dest
& 0xff));
1914 R300_STATECHANGE(r300
, vpp
);
1915 for (i
= 0; i
< vsf
->length
; i
++)
1916 r300
->hw
.vpp
.cmd
[R300_VPP_PARAM_0
+ i
+ 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1917 bump_vpu_count(r300
->hw
.vpp
.cmd
, vsf
->length
+ 4 * (dest
& 0xff));
1920 R300_STATECHANGE(r300
, vps
);
1921 for (i
= 0; i
< vsf
->length
; i
++)
1922 r300
->hw
.vps
.cmd
[1 + i
+ 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1923 bump_vpu_count(r300
->hw
.vps
.cmd
, vsf
->length
+ 4 * (dest
& 0xff));
1926 fprintf(stderr
, "%s:%s don't know how to handle dest %04x\n", __FILE__
, __FUNCTION__
, dest
);
1931 #define MIN3(a, b, c) ((a) < (b) ? MIN2(a, c) : MIN2(b, c))
1934 static void r300VapCntl(r300ContextPtr rmesa
, GLuint input_count
,
1935 GLuint output_count
, GLuint temp_count
)
1941 /* Flush PVS engine before changing PVS_NUM_SLOTS, PVS_NUM_CNTRLS.
1942 * See r500 docs 6.5.2 - done in emit */
1944 /* avoid division by zero */
1945 if (input_count
== 0) input_count
= 1;
1946 if (output_count
== 0) output_count
= 1;
1947 if (temp_count
== 0) temp_count
= 1;
1949 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
1954 pvs_num_slots
= MIN3(10, vtx_mem_size
/input_count
, vtx_mem_size
/output_count
);
1955 pvs_num_cntrls
= MIN2(6, vtx_mem_size
/temp_count
);
1957 R300_STATECHANGE(rmesa
, vap_cntl
);
1958 if (rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
) {
1959 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] =
1960 (pvs_num_slots
<< R300_PVS_NUM_SLOTS_SHIFT
) |
1961 (pvs_num_cntrls
<< R300_PVS_NUM_CNTLRS_SHIFT
) |
1962 (12 << R300_VF_MAX_VTX_NUM_SHIFT
);
1963 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
1964 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= R500_TCL_STATE_OPTIMIZATION
;
1966 /* not sure about non-tcl */
1967 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] = ((10 << R300_PVS_NUM_SLOTS_SHIFT
) |
1968 (5 << R300_PVS_NUM_CNTLRS_SHIFT
) |
1969 (5 << R300_VF_MAX_VTX_NUM_SHIFT
));
1971 if (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV515
)
1972 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (2 << R300_PVS_NUM_FPUS_SHIFT
);
1973 else if ((rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV530
) ||
1974 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV560
) ||
1975 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV570
))
1976 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (5 << R300_PVS_NUM_FPUS_SHIFT
);
1977 else if ((rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV410
) ||
1978 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R420
))
1979 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (6 << R300_PVS_NUM_FPUS_SHIFT
);
1980 else if ((rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R520
) ||
1981 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R580
))
1982 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (8 << R300_PVS_NUM_FPUS_SHIFT
);
1984 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (4 << R300_PVS_NUM_FPUS_SHIFT
);
1988 static void r300SetupDefaultVertexProgram(r300ContextPtr rmesa
)
1990 struct r300_vertex_shader_state
*prog
= &(rmesa
->state
.vertex_shader
);
1995 int param_count
= 0;
1996 int program_end
= 0;
1998 for (i
= VERT_ATTRIB_POS
; i
< VERT_ATTRIB_MAX
; i
++) {
1999 if (rmesa
->state
.sw_tcl_inputs
[i
] != -1) {
2000 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
);
2001 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
);
2002 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
);
2003 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
);
2009 prog
->program
.length
= program_end
;
2011 r300SetupVertexProgramFragment(rmesa
, R300_PVS_CODE_START
,
2013 inst_count
= (prog
->program
.length
/ 4) - 1;
2015 r300VapCntl(rmesa
, i_reg
, o_reg
, 0);
2017 R300_STATECHANGE(rmesa
, pvs
);
2018 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] =
2019 (0 << R300_PVS_FIRST_INST_SHIFT
) |
2020 (inst_count
<< R300_PVS_XYZW_VALID_INST_SHIFT
) |
2021 (inst_count
<< R300_PVS_LAST_INST_SHIFT
);
2022 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] =
2023 (0 << R300_PVS_CONST_BASE_OFFSET_SHIFT
) |
2024 (param_count
<< R300_PVS_MAX_CONST_ADDR_SHIFT
);
2025 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] =
2026 (inst_count
<< R300_PVS_LAST_VTX_SRC_INST_SHIFT
);
2029 static int bit_count (int x
)
2031 x
= ((x
& 0xaaaaaaaaU
) >> 1) + (x
& 0x55555555U
);
2032 x
= ((x
& 0xccccccccU
) >> 2) + (x
& 0x33333333U
);
2033 x
= (x
>> 16) + (x
& 0xffff);
2034 x
= ((x
& 0xf0f0) >> 4) + (x
& 0x0f0f);
2035 return (x
>> 8) + (x
& 0x00ff);
2038 static void r300SetupRealVertexProgram(r300ContextPtr rmesa
)
2040 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
2041 struct r300_vertex_program
*prog
= (struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
);
2043 int param_count
= 0;
2045 /* FIXME: r300SetupVertexProgramFragment */
2046 R300_STATECHANGE(rmesa
, vpp
);
2048 r300VertexProgUpdateParams(ctx
,
2049 (struct r300_vertex_program_cont
*)
2050 ctx
->VertexProgram
._Current
,
2051 (float *)&rmesa
->hw
.vpp
.
2052 cmd
[R300_VPP_PARAM_0
]);
2053 bump_vpu_count(rmesa
->hw
.vpp
.cmd
, param_count
);
2056 r300SetupVertexProgramFragment(rmesa
, R300_PVS_CODE_START
, &(prog
->program
));
2057 inst_count
= (prog
->program
.length
/ 4) - 1;
2059 r300VapCntl(rmesa
, bit_count(prog
->key
.InputsRead
),
2060 bit_count(prog
->key
.OutputsWritten
), prog
->num_temporaries
);
2062 R300_STATECHANGE(rmesa
, pvs
);
2063 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] =
2064 (0 << R300_PVS_FIRST_INST_SHIFT
) |
2065 (inst_count
<< R300_PVS_XYZW_VALID_INST_SHIFT
) |
2066 (inst_count
<< R300_PVS_LAST_INST_SHIFT
);
2067 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] =
2068 (0 << R300_PVS_CONST_BASE_OFFSET_SHIFT
) |
2069 (param_count
<< R300_PVS_MAX_CONST_ADDR_SHIFT
);
2070 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] =
2071 (inst_count
<< R300_PVS_LAST_VTX_SRC_INST_SHIFT
);
2074 static void r300SetupVertexProgram(r300ContextPtr rmesa
)
2076 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
2078 /* Reset state, in case we don't use something */
2079 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vpp
.cmd
)->vpu
.count
= 0;
2080 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vpi
.cmd
)->vpu
.count
= 0;
2081 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vps
.cmd
)->vpu
.count
= 0;
2083 /* Not sure why this doesnt work...
2084 0x400 area might have something to do with pixel shaders as it appears right after pfs programming.
2085 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. */
2086 //setup_vertex_shader_fragment(rmesa, 0x406, &unk4);
2087 if (hw_tcl_on
&& ((struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
))->translated
) {
2088 r300SetupRealVertexProgram(rmesa
);
2090 /* FIXME: This needs to be replaced by vertex shader generation code. */
2091 r300SetupDefaultVertexProgram(rmesa
);
2097 * Enable/Disable states.
2099 * \note Mesa already filters redundant calls to this function.
2101 static void r300Enable(GLcontext
* ctx
, GLenum cap
, GLboolean state
)
2103 if (RADEON_DEBUG
& DEBUG_STATE
)
2104 fprintf(stderr
, "%s( %s = %s )\n", __FUNCTION__
,
2105 _mesa_lookup_enum_by_nr(cap
),
2106 state
? "GL_TRUE" : "GL_FALSE");
2115 r300SetFogState(ctx
, state
);
2118 r300SetAlphaState(ctx
);
2121 case GL_COLOR_LOGIC_OP
:
2122 r300SetBlendState(ctx
);
2124 case GL_CLIP_PLANE0
:
2125 case GL_CLIP_PLANE1
:
2126 case GL_CLIP_PLANE2
:
2127 case GL_CLIP_PLANE3
:
2128 case GL_CLIP_PLANE4
:
2129 case GL_CLIP_PLANE5
:
2130 r300SetClipPlaneState(ctx
, cap
, state
);
2133 r300SetDepthState(ctx
);
2135 case GL_STENCIL_TEST
:
2136 r300SetStencilState(ctx
, state
);
2139 r300UpdateCulling(ctx
);
2141 case GL_POLYGON_OFFSET_POINT
:
2142 case GL_POLYGON_OFFSET_LINE
:
2143 case GL_POLYGON_OFFSET_FILL
:
2144 r300SetPolygonOffsetState(ctx
, state
);
2147 radeonEnable(ctx
, cap
, state
);
2153 * Completely recalculates hardware state based on the Mesa state.
2155 static void r300ResetHwState(r300ContextPtr r300
)
2157 GLcontext
*ctx
= r300
->radeon
.glCtx
;
2160 if (!(r300
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
2163 if (RADEON_DEBUG
& DEBUG_STATE
)
2164 fprintf(stderr
, "%s\n", __FUNCTION__
);
2166 r300UpdateWindow(ctx
);
2169 ctx
->Color
.ColorMask
[RCOMP
],
2170 ctx
->Color
.ColorMask
[GCOMP
],
2171 ctx
->Color
.ColorMask
[BCOMP
], ctx
->Color
.ColorMask
[ACOMP
]);
2173 r300Enable(ctx
, GL_DEPTH_TEST
, ctx
->Depth
.Test
);
2174 r300DepthMask(ctx
, ctx
->Depth
.Mask
);
2175 r300DepthFunc(ctx
, ctx
->Depth
.Func
);
2178 r300Enable(ctx
, GL_STENCIL_TEST
, ctx
->Stencil
.Enabled
);
2179 r300StencilMaskSeparate(ctx
, 0, ctx
->Stencil
.WriteMask
[0]);
2180 r300StencilFuncSeparate(ctx
, 0, ctx
->Stencil
.Function
[0],
2181 ctx
->Stencil
.Ref
[0], ctx
->Stencil
.ValueMask
[0]);
2182 r300StencilOpSeparate(ctx
, 0, ctx
->Stencil
.FailFunc
[0],
2183 ctx
->Stencil
.ZFailFunc
[0],
2184 ctx
->Stencil
.ZPassFunc
[0]);
2186 r300UpdateCulling(ctx
);
2188 r300UpdateTextureState(ctx
);
2190 r300SetBlendState(ctx
);
2192 r300AlphaFunc(ctx
, ctx
->Color
.AlphaFunc
, ctx
->Color
.AlphaRef
);
2193 r300Enable(ctx
, GL_ALPHA_TEST
, ctx
->Color
.AlphaEnabled
);
2195 r300
->hw
.vte
.cmd
[1] = R300_VPORT_X_SCALE_ENA
2196 | R300_VPORT_X_OFFSET_ENA
2197 | R300_VPORT_Y_SCALE_ENA
2198 | R300_VPORT_Y_OFFSET_ENA
2199 | R300_VPORT_Z_SCALE_ENA
2200 | R300_VPORT_Z_OFFSET_ENA
| R300_VTX_W0_FMT
;
2201 r300
->hw
.vte
.cmd
[2] = 0x00000008;
2203 r300
->hw
.vap_vf_max_vtx_indx
.cmd
[1] = 0x00FFFFFF;
2204 r300
->hw
.vap_vf_max_vtx_indx
.cmd
[2] = 0x00000000;
2206 #ifdef MESA_LITTLE_ENDIAN
2207 r300
->hw
.vap_cntl_status
.cmd
[1] = R300_VC_NO_SWAP
;
2209 r300
->hw
.vap_cntl_status
.cmd
[1] = R300_VC_32BIT_SWAP
;
2212 /* disable VAP/TCL on non-TCL capable chips */
2214 r300
->hw
.vap_cntl_status
.cmd
[1] |= R300_VAP_TCL_BYPASS
;
2216 r300
->hw
.vap_psc_sgn_norm_cntl
.cmd
[1] = 0xAAAAAAAA;
2218 /* XXX: Other families? */
2220 r300
->hw
.vap_clip_cntl
.cmd
[1] = R300_PS_UCP_MODE_DIST_COP
;
2222 r300
->hw
.vap_clip
.cmd
[1] = r300PackFloat32(1.0); /* X */
2223 r300
->hw
.vap_clip
.cmd
[2] = r300PackFloat32(1.0); /* X */
2224 r300
->hw
.vap_clip
.cmd
[3] = r300PackFloat32(1.0); /* Y */
2225 r300
->hw
.vap_clip
.cmd
[4] = r300PackFloat32(1.0); /* Y */
2227 switch (r300
->radeon
.radeonScreen
->chip_family
) {
2228 case CHIP_FAMILY_R300
:
2229 r300
->hw
.vap_pvs_vtx_timeout_reg
.cmd
[1] = R300_2288_R300
;
2232 r300
->hw
.vap_pvs_vtx_timeout_reg
.cmd
[1] = R300_2288_RV350
;
2237 r300
->hw
.gb_enable
.cmd
[1] = R300_GB_POINT_STUFF_ENABLE
2238 | R300_GB_LINE_STUFF_ENABLE
2239 | R300_GB_TRIANGLE_STUFF_ENABLE
;
2241 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_0
] = 0x66666666;
2242 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_1
] = 0x06666666;
2244 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] =
2245 R300_GB_TILE_ENABLE
| R300_GB_TILE_SIZE_16
/*| R300_GB_SUBPIXEL_1_16*/;
2246 switch (r300
->radeon
.radeonScreen
->num_gb_pipes
) {
2249 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2250 R300_GB_TILE_PIPE_COUNT_RV300
;
2253 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2254 R300_GB_TILE_PIPE_COUNT_R300
;
2257 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2258 R300_GB_TILE_PIPE_COUNT_R420_3P
;
2261 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2262 R300_GB_TILE_PIPE_COUNT_R420
;
2266 /* XXX: set to 0 when fog is disabled? */
2267 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_SELECT
] = R300_GB_FOG_SELECT_1_1_W
;
2269 /* XXX: Enable anti-aliasing? */
2270 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_AA_CONFIG
] = GB_AA_CONFIG_AA_DISABLE
;
2272 r300
->hw
.ga_point_s0
.cmd
[1] = r300PackFloat32(0.0);
2273 r300
->hw
.ga_point_s0
.cmd
[2] = r300PackFloat32(0.0);
2274 r300
->hw
.ga_point_s0
.cmd
[3] = r300PackFloat32(1.0);
2275 r300
->hw
.ga_point_s0
.cmd
[4] = r300PackFloat32(1.0);
2277 r300
->hw
.ga_triangle_stipple
.cmd
[1] = 0x00050005;
2279 r300PointSize(ctx
, 1.0);
2281 r300
->hw
.ga_point_minmax
.cmd
[1] = 0x18000006;
2282 r300
->hw
.ga_point_minmax
.cmd
[2] = 0x00020006;
2283 r300
->hw
.ga_point_minmax
.cmd
[3] = r300PackFloat32(1.0 / 192.0);
2285 r300LineWidth(ctx
, 1.0);
2287 r300
->hw
.ga_line_stipple
.cmd
[1] = 0;
2288 r300
->hw
.ga_line_stipple
.cmd
[2] = r300PackFloat32(0.0);
2289 r300
->hw
.ga_line_stipple
.cmd
[3] = r300PackFloat32(1.0);
2291 r300ShadeModel(ctx
, ctx
->Light
.ShadeModel
);
2293 r300PolygonMode(ctx
, GL_FRONT
, ctx
->Polygon
.FrontMode
);
2294 r300PolygonMode(ctx
, GL_BACK
, ctx
->Polygon
.BackMode
);
2295 r300
->hw
.zbias_cntl
.cmd
[1] = 0x00000000;
2297 r300PolygonOffset(ctx
, ctx
->Polygon
.OffsetFactor
,
2298 ctx
->Polygon
.OffsetUnits
);
2299 r300Enable(ctx
, GL_POLYGON_OFFSET_POINT
, ctx
->Polygon
.OffsetPoint
);
2300 r300Enable(ctx
, GL_POLYGON_OFFSET_LINE
, ctx
->Polygon
.OffsetLine
);
2301 r300Enable(ctx
, GL_POLYGON_OFFSET_FILL
, ctx
->Polygon
.OffsetFill
);
2303 r300
->hw
.su_depth_scale
.cmd
[1] = 0x4B7FFFFF;
2304 r300
->hw
.su_depth_scale
.cmd
[2] = 0x00000000;
2306 r300
->hw
.sc_hyperz
.cmd
[1] = 0x0000001C;
2307 r300
->hw
.sc_hyperz
.cmd
[2] = 0x2DA49525;
2309 r300
->hw
.sc_screendoor
.cmd
[1] = 0x00FFFFFF;
2311 r300
->hw
.us_out_fmt
.cmd
[1] = R500_OUT_FMT_C4_8
|
2312 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2313 r300
->hw
.us_out_fmt
.cmd
[2] = R500_OUT_FMT_UNUSED
|
2314 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2315 r300
->hw
.us_out_fmt
.cmd
[3] = R500_OUT_FMT_UNUSED
|
2316 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2317 r300
->hw
.us_out_fmt
.cmd
[4] = R500_OUT_FMT_UNUSED
|
2318 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2319 r300
->hw
.us_out_fmt
.cmd
[5] = R300_W_FMT_W24
;
2321 r300Enable(ctx
, GL_FOG
, ctx
->Fog
.Enabled
);
2322 r300Fogfv(ctx
, GL_FOG_MODE
, NULL
);
2323 r300Fogfv(ctx
, GL_FOG_DENSITY
, &ctx
->Fog
.Density
);
2324 r300Fogfv(ctx
, GL_FOG_START
, &ctx
->Fog
.Start
);
2325 r300Fogfv(ctx
, GL_FOG_END
, &ctx
->Fog
.End
);
2326 r300Fogfv(ctx
, GL_FOG_COLOR
, ctx
->Fog
.Color
);
2327 r300Fogfv(ctx
, GL_FOG_COORDINATE_SOURCE_EXT
, NULL
);
2329 r300
->hw
.fg_depth_src
.cmd
[1] = 0;
2331 r300
->hw
.rb3d_cctl
.cmd
[1] = 0;
2333 r300BlendColor(ctx
, ctx
->Color
.BlendColor
);
2335 /* Again, r300ClearBuffer uses this */
2336 r300
->hw
.cb
.cmd
[R300_CB_OFFSET
] =
2337 r300
->radeon
.state
.color
.drawOffset
+
2338 r300
->radeon
.radeonScreen
->fbLocation
;
2339 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] = r300
->radeon
.state
.color
.drawPitch
;
2341 if (r300
->radeon
.radeonScreen
->cpp
== 4)
2342 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_ARGB8888
;
2344 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_RGB565
;
2346 if (r300
->radeon
.sarea
->tiling_enabled
)
2347 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_TILE_ENABLE
;
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 r300
->hw
.zb
.cmd
[R300_ZB_OFFSET
] =
2365 r300
->radeon
.radeonScreen
->depthOffset
+
2366 r300
->radeon
.radeonScreen
->fbLocation
;
2367 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] = r300
->radeon
.radeonScreen
->depthPitch
;
2369 if (r300
->radeon
.sarea
->tiling_enabled
) {
2370 /* XXX: Turn off when clearing buffers ? */
2371 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] |= R300_DEPTHMACROTILE_ENABLE
;
2373 if (ctx
->Visual
.depthBits
== 24)
2374 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] |=
2375 R300_DEPTHMICROTILE_TILED
;
2378 r300
->hw
.zb_depthclearvalue
.cmd
[1] = 0;
2380 switch (ctx
->Visual
.depthBits
) {
2382 r300
->hw
.zstencil_format
.cmd
[1] = R300_DEPTHFORMAT_16BIT_INT_Z
;
2385 r300
->hw
.zstencil_format
.cmd
[1] = R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL
;
2388 fprintf(stderr
, "Error: Unsupported depth %d... exiting\n", ctx
->Visual
.depthBits
);
2392 r300
->hw
.zstencil_format
.cmd
[2] = R300_ZTOP_DISABLE
;
2393 r300
->hw
.zstencil_format
.cmd
[3] = 0x00000003;
2394 r300
->hw
.zstencil_format
.cmd
[4] = 0x00000000;
2395 r300SetEarlyZState(ctx
);
2397 r300
->hw
.unk4F30
.cmd
[1] = 0;
2398 r300
->hw
.unk4F30
.cmd
[2] = 0;
2400 r300
->hw
.zb_hiz_offset
.cmd
[1] = 0;
2402 r300
->hw
.zb_hiz_pitch
.cmd
[1] = 0;
2404 r300VapCntl(r300
, 0, 0, 0);
2406 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_0
] = 0;
2407 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_1
] = 0;
2408 r300
->hw
.vps
.cmd
[R300_VPS_POINTSIZE
] = r300PackFloat32(1.0);
2409 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_3
] = 0;
2412 r300
->hw
.all_dirty
= GL_TRUE
;
2415 void r300UpdateShaders(r300ContextPtr rmesa
)
2418 struct r300_vertex_program
*vp
;
2421 ctx
= rmesa
->radeon
.glCtx
;
2423 if (rmesa
->NewGLState
&& hw_tcl_on
) {
2424 rmesa
->NewGLState
= 0;
2426 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
2427 rmesa
->temp_attrib
[i
] =
2428 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
];
2429 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] =
2430 &rmesa
->dummy_attrib
[i
];
2433 _tnl_UpdateFixedFunctionProgram(ctx
);
2435 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
2436 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] =
2437 rmesa
->temp_attrib
[i
];
2440 r300SelectVertexShader(rmesa
);
2441 vp
= (struct r300_vertex_program
*)
2442 CURRENT_VERTEX_SHADER(ctx
);
2443 /*if (vp->translated == GL_FALSE)
2444 r300TranslateVertexShader(vp); */
2445 if (vp
->translated
== GL_FALSE
) {
2446 fprintf(stderr
, "Failing back to sw-tcl\n");
2447 hw_tcl_on
= future_hw_tcl_on
= 0;
2448 r300ResetHwState(rmesa
);
2450 r300UpdateStateParameters(ctx
, _NEW_PROGRAM
);
2454 r300UpdateStateParameters(ctx
, _NEW_PROGRAM
);
2457 static const GLfloat
*get_fragmentprogram_constant(GLcontext
*ctx
,
2458 struct gl_program
*program
, struct prog_src_register srcreg
)
2460 static const GLfloat dummy
[4] = { 0, 0, 0, 0 };
2462 switch(srcreg
.File
) {
2463 case PROGRAM_LOCAL_PARAM
:
2464 return program
->LocalParams
[srcreg
.Index
];
2465 case PROGRAM_ENV_PARAM
:
2466 return ctx
->FragmentProgram
.Parameters
[srcreg
.Index
];
2467 case PROGRAM_STATE_VAR
:
2468 case PROGRAM_NAMED_PARAM
:
2469 case PROGRAM_CONSTANT
:
2470 return program
->Parameters
->ParameterValues
[srcreg
.Index
];
2472 _mesa_problem(ctx
, "get_fragmentprogram_constant: Unknown\n");
2478 static void r300SetupPixelShader(r300ContextPtr rmesa
)
2480 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
2481 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
2482 (char *)ctx
->FragmentProgram
._Current
;
2483 struct r300_fragment_program_code
*code
;
2486 if (!fp
) /* should only happenen once, just after context is created */
2489 r300TranslateFragmentShader(rmesa
, fp
);
2490 if (!fp
->translated
) {
2491 fprintf(stderr
, "%s: No valid fragment shader, exiting\n",
2497 r300SetupTextures(ctx
);
2499 R300_STATECHANGE(rmesa
, fpi
[0]);
2500 rmesa
->hw
.fpi
[0].cmd
[R300_FPI_CMD_0
] = cmdpacket0(R300_US_ALU_RGB_INST_0
, code
->alu_end
+ 1);
2501 for (i
= 0; i
<= code
->alu_end
; i
++) {
2502 rmesa
->hw
.fpi
[0].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst0
;
2505 R300_STATECHANGE(rmesa
, fpi
[1]);
2506 rmesa
->hw
.fpi
[1].cmd
[R300_FPI_CMD_0
] = cmdpacket0(R300_US_ALU_RGB_ADDR_0
, code
->alu_end
+ 1);
2507 for (i
= 0; i
<= code
->alu_end
; i
++) {
2508 rmesa
->hw
.fpi
[1].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst1
;
2511 R300_STATECHANGE(rmesa
, fpi
[2]);
2512 rmesa
->hw
.fpi
[2].cmd
[R300_FPI_CMD_0
] = cmdpacket0(R300_US_ALU_ALPHA_INST_0
, code
->alu_end
+ 1);
2513 for (i
= 0; i
<= code
->alu_end
; i
++) {
2514 rmesa
->hw
.fpi
[2].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst2
;
2517 R300_STATECHANGE(rmesa
, fpi
[3]);
2518 rmesa
->hw
.fpi
[3].cmd
[R300_FPI_CMD_0
] = cmdpacket0(R300_US_ALU_ALPHA_ADDR_0
, code
->alu_end
+ 1);
2519 for (i
= 0; i
<= code
->alu_end
; i
++) {
2520 rmesa
->hw
.fpi
[3].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst3
;
2523 R300_STATECHANGE(rmesa
, fp
);
2524 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL0
] = code
->cur_node
| (code
->first_node_has_tex
<< 3);
2525 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL1
] = code
->max_temp_idx
;
2526 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL2
] =
2527 (code
->alu_offset
<< R300_PFS_CNTL_ALU_OFFSET_SHIFT
) |
2528 (code
->alu_end
<< R300_PFS_CNTL_ALU_END_SHIFT
) |
2529 (code
->tex_offset
<< R300_PFS_CNTL_TEX_OFFSET_SHIFT
) |
2530 (code
->tex_end
<< R300_PFS_CNTL_TEX_END_SHIFT
);
2531 /* I just want to say, the way these nodes are stored.. weird.. */
2532 for (i
= 0, k
= (4 - (code
->cur_node
+ 1)); i
< 4; i
++, k
++) {
2533 if (i
< (code
->cur_node
+ 1)) {
2534 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+ k
] =
2535 (code
->node
[i
].alu_offset
<< R300_ALU_START_SHIFT
) |
2536 (code
->node
[i
].alu_end
<< R300_ALU_SIZE_SHIFT
) |
2537 (code
->node
[i
].tex_offset
<< R300_TEX_START_SHIFT
) |
2538 (code
->node
[i
].tex_end
<< R300_TEX_SIZE_SHIFT
) |
2539 code
->node
[i
].flags
;
2541 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+ (3 - i
)] = 0;
2545 R300_STATECHANGE(rmesa
, fpp
);
2546 rmesa
->hw
.fpp
.cmd
[R300_FPP_CMD_0
] = cmdpacket0(R300_PFS_PARAM_0_X
, code
->const_nr
* 4);
2547 for (i
= 0; i
< code
->const_nr
; i
++) {
2548 const GLfloat
*constant
= get_fragmentprogram_constant(ctx
,
2549 &fp
->mesa_program
.Base
, code
->constant
[i
]);
2550 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 0] = r300PackFloat24(constant
[0]);
2551 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 1] = r300PackFloat24(constant
[1]);
2552 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 2] = r300PackFloat24(constant
[2]);
2553 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 3] = r300PackFloat24(constant
[3]);
2557 #define bump_r500fp_count(ptr, new_count) do{\
2558 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
2559 int _nc=(new_count)/6; \
2560 assert(_nc < 256); \
2561 if(_nc>_p->r500fp.count)_p->r500fp.count=_nc;\
2564 #define bump_r500fp_const_count(ptr, new_count) do{\
2565 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
2566 int _nc=(new_count)/4; \
2567 assert(_nc < 256); \
2568 if(_nc>_p->r500fp.count)_p->r500fp.count=_nc;\
2571 static void r500SetupPixelShader(r300ContextPtr rmesa
)
2573 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
2574 struct r500_fragment_program
*fp
= (struct r500_fragment_program
*)
2575 (char *)ctx
->FragmentProgram
._Current
;
2577 struct r500_fragment_program_code
*code
;
2579 if (!fp
) /* should only happenen once, just after context is created */
2582 ((drm_r300_cmd_header_t
*) rmesa
->hw
.r500fp
.cmd
)->r500fp
.count
= 0;
2583 ((drm_r300_cmd_header_t
*) rmesa
->hw
.r500fp_const
.cmd
)->r500fp
.count
= 0;
2585 r500TranslateFragmentShader(rmesa
, fp
);
2586 if (!fp
->translated
) {
2587 fprintf(stderr
, "%s: No valid fragment shader, exiting\n",
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 r300UpdateTextureState(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
;
2768 /* ARB_point_parameters */
2769 functions
->PointParameterfv
= r300PointParameter
;
2771 /* Stencil related */
2772 functions
->StencilFuncSeparate
= r300StencilFuncSeparate
;
2773 functions
->StencilMaskSeparate
= r300StencilMaskSeparate
;
2774 functions
->StencilOpSeparate
= r300StencilOpSeparate
;
2776 /* Viewport related */
2777 functions
->Viewport
= r300Viewport
;
2778 functions
->DepthRange
= r300DepthRange
;
2779 functions
->PointSize
= r300PointSize
;
2780 functions
->LineWidth
= r300LineWidth
;
2782 functions
->PolygonOffset
= r300PolygonOffset
;
2783 functions
->PolygonMode
= r300PolygonMode
;
2785 functions
->RenderMode
= r300RenderMode
;
2787 functions
->ClipPlane
= r300ClipPlane
;