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
);
325 * Translate LogicOp enums into hardware representation.
326 * Both use a very logical bit-wise layout, but unfortunately the order
327 * of bits is reversed.
329 static GLuint
translate_logicop(GLenum logicop
)
331 GLuint bits
= logicop
- GL_CLEAR
;
332 bits
= ((bits
& 1) << 3) | ((bits
& 2) << 1) | ((bits
& 4) >> 1) | ((bits
& 8) >> 3);
333 return bits
<< R300_RB3D_ROPCNTL_ROP_SHIFT
;
337 * Used internally to update the r300->hw hardware state to match the
338 * current OpenGL state.
340 static void r300SetLogicOpState(GLcontext
*ctx
)
342 r300ContextPtr r300
= R300_CONTEXT(ctx
);
343 R300_STATECHANGE(r300
, rop
);
344 if (RGBA_LOGICOP_ENABLED(ctx
)) {
345 r300
->hw
.rop
.cmd
[1] = R300_RB3D_ROPCNTL_ROP_ENABLE
|
346 translate_logicop(ctx
->Color
.LogicOp
);
348 r300
->hw
.rop
.cmd
[1] = 0;
353 * Called by Mesa when an application program changes the LogicOp state
356 static void r300LogicOpcode(GLcontext
*ctx
, GLenum logicop
)
358 if (RGBA_LOGICOP_ENABLED(ctx
))
359 r300SetLogicOpState(ctx
);
362 static void r300ClipPlane( GLcontext
*ctx
, GLenum plane
, const GLfloat
*eq
)
364 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
368 /* no VAP UCP on non-TCL chipsets */
369 if (!(rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
372 p
= (GLint
) plane
- (GLint
) GL_CLIP_PLANE0
;
373 ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
375 R300_STATECHANGE( rmesa
, vpucp
[p
] );
376 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_X
] = ip
[0];
377 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_Y
] = ip
[1];
378 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_Z
] = ip
[2];
379 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_W
] = ip
[3];
382 static void r300SetClipPlaneState(GLcontext
* ctx
, GLenum cap
, GLboolean state
)
384 r300ContextPtr r300
= R300_CONTEXT(ctx
);
387 /* no VAP UCP on non-TCL chipsets */
388 if (!(r300
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
391 p
= cap
- GL_CLIP_PLANE0
;
392 R300_STATECHANGE(r300
, vap_clip_cntl
);
394 r300
->hw
.vap_clip_cntl
.cmd
[1] |= (R300_VAP_UCP_ENABLE_0
<< p
);
395 r300ClipPlane(ctx
, cap
, NULL
);
397 r300
->hw
.vap_clip_cntl
.cmd
[1] &= ~(R300_VAP_UCP_ENABLE_0
<< p
);
402 * Update our tracked culling state based on Mesa's state.
404 static void r300UpdateCulling(GLcontext
* ctx
)
406 r300ContextPtr r300
= R300_CONTEXT(ctx
);
409 if (ctx
->Polygon
.CullFlag
) {
410 switch (ctx
->Polygon
.CullFaceMode
) {
412 val
= R300_CULL_FRONT
;
415 val
= R300_CULL_BACK
;
417 case GL_FRONT_AND_BACK
:
418 val
= R300_CULL_FRONT
| R300_CULL_BACK
;
425 switch (ctx
->Polygon
.FrontFace
) {
427 val
|= R300_FRONT_FACE_CW
;
430 val
|= R300_FRONT_FACE_CCW
;
436 R300_STATECHANGE(r300
, cul
);
437 r300
->hw
.cul
.cmd
[R300_CUL_CULL
] = val
;
440 static void r300SetPolygonOffsetState(GLcontext
* ctx
, GLboolean state
)
442 r300ContextPtr r300
= R300_CONTEXT(ctx
);
444 R300_STATECHANGE(r300
, occlusion_cntl
);
446 r300
->hw
.occlusion_cntl
.cmd
[1] |= (3 << 0);
448 r300
->hw
.occlusion_cntl
.cmd
[1] &= ~(3 << 0);
452 static GLboolean
current_fragment_program_writes_depth(GLcontext
* ctx
)
454 r300ContextPtr r300
= R300_CONTEXT(ctx
);
456 if (r300
->radeon
.radeonScreen
->chip_family
< CHIP_FAMILY_RV515
) {
457 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
458 (char *)ctx
->FragmentProgram
._Current
;
459 return (fp
&& fp
->WritesDepth
);
461 struct r500_fragment_program
* fp
=
462 (struct r500_fragment_program
*)(char*)
463 ctx
->FragmentProgram
._Current
;
464 return (fp
&& fp
->writes_depth
);
468 static void r300SetEarlyZState(GLcontext
* ctx
)
470 r300ContextPtr r300
= R300_CONTEXT(ctx
);
471 GLuint topZ
= R300_ZTOP_ENABLE
;
473 if (ctx
->Color
.AlphaEnabled
&& ctx
->Color
.AlphaFunc
!= GL_ALWAYS
)
474 topZ
= R300_ZTOP_DISABLE
;
475 if (current_fragment_program_writes_depth(ctx
))
476 topZ
= R300_ZTOP_DISABLE
;
478 if (topZ
!= r300
->hw
.zstencil_format
.cmd
[2]) {
479 /* Note: This completely reemits the stencil format.
480 * I have not tested whether this is strictly necessary,
481 * or if emitting a write to ZB_ZTOP is enough.
483 R300_STATECHANGE(r300
, zstencil_format
);
484 r300
->hw
.zstencil_format
.cmd
[2] = topZ
;
488 static void r300SetAlphaState(GLcontext
* ctx
)
490 r300ContextPtr r300
= R300_CONTEXT(ctx
);
492 uint32_t pp_misc
= 0x0;
493 GLboolean really_enabled
= ctx
->Color
.AlphaEnabled
;
495 CLAMPED_FLOAT_TO_UBYTE(refByte
, ctx
->Color
.AlphaRef
);
497 switch (ctx
->Color
.AlphaFunc
) {
499 pp_misc
|= R300_FG_ALPHA_FUNC_NEVER
;
502 pp_misc
|= R300_FG_ALPHA_FUNC_LESS
;
505 pp_misc
|= R300_FG_ALPHA_FUNC_EQUAL
;
508 pp_misc
|= R300_FG_ALPHA_FUNC_LE
;
511 pp_misc
|= R300_FG_ALPHA_FUNC_GREATER
;
514 pp_misc
|= R300_FG_ALPHA_FUNC_NOTEQUAL
;
517 pp_misc
|= R300_FG_ALPHA_FUNC_GE
;
520 /*pp_misc |= FG_ALPHA_FUNC_ALWAYS; */
521 really_enabled
= GL_FALSE
;
525 if (really_enabled
) {
526 pp_misc
|= R300_FG_ALPHA_FUNC_ENABLE
;
527 pp_misc
|= R500_FG_ALPHA_FUNC_8BIT
;
528 pp_misc
|= (refByte
& R300_FG_ALPHA_FUNC_VAL_MASK
);
533 R300_STATECHANGE(r300
, at
);
534 r300
->hw
.at
.cmd
[R300_AT_ALPHA_TEST
] = pp_misc
;
535 r300
->hw
.at
.cmd
[R300_AT_UNKNOWN
] = 0;
537 r300SetEarlyZState(ctx
);
540 static void r300AlphaFunc(GLcontext
* ctx
, GLenum func
, GLfloat ref
)
544 r300SetAlphaState(ctx
);
547 static int translate_func(int func
)
551 return R300_ZS_NEVER
;
555 return R300_ZS_EQUAL
;
557 return R300_ZS_LEQUAL
;
559 return R300_ZS_GREATER
;
561 return R300_ZS_NOTEQUAL
;
563 return R300_ZS_GEQUAL
;
565 return R300_ZS_ALWAYS
;
570 static void r300SetDepthState(GLcontext
* ctx
)
572 r300ContextPtr r300
= R300_CONTEXT(ctx
);
574 R300_STATECHANGE(r300
, zs
);
575 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &= R300_STENCIL_ENABLE
|R300_STENCIL_FRONT_BACK
;
576 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= ~(R300_ZS_MASK
<< R300_Z_FUNC_SHIFT
);
578 if (ctx
->Depth
.Test
) {
579 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_Z_ENABLE
;
581 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_Z_WRITE_ENABLE
;
582 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
583 translate_func(ctx
->Depth
.Func
) << R300_Z_FUNC_SHIFT
;
586 r300SetEarlyZState(ctx
);
589 static void r300SetStencilState(GLcontext
* ctx
, GLboolean state
)
591 r300ContextPtr r300
= R300_CONTEXT(ctx
);
593 if (r300
->state
.stencil
.hw_stencil
) {
594 R300_STATECHANGE(r300
, zs
);
596 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |=
599 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &=
600 ~R300_STENCIL_ENABLE
;
604 FALLBACK(&r300
->radeon
, RADEON_FALLBACK_STENCIL
, state
);
609 static void r300UpdatePolygonMode(GLcontext
* ctx
)
611 r300ContextPtr r300
= R300_CONTEXT(ctx
);
612 uint32_t hw_mode
= R300_GA_POLY_MODE_DISABLE
;
614 /* Only do something if a polygon mode is wanted, default is GL_FILL */
615 if (ctx
->Polygon
.FrontMode
!= GL_FILL
||
616 ctx
->Polygon
.BackMode
!= GL_FILL
) {
619 /* Handle GL_CW (clock wise and GL_CCW (counter clock wise)
620 * correctly by selecting the correct front and back face
622 if (ctx
->Polygon
.FrontFace
== GL_CCW
) {
623 f
= ctx
->Polygon
.FrontMode
;
624 b
= ctx
->Polygon
.BackMode
;
626 f
= ctx
->Polygon
.BackMode
;
627 b
= ctx
->Polygon
.FrontMode
;
630 /* Enable polygon mode */
631 hw_mode
|= R300_GA_POLY_MODE_DUAL
;
635 hw_mode
|= R300_GA_POLY_MODE_FRONT_PTYPE_LINE
;
638 hw_mode
|= R300_GA_POLY_MODE_FRONT_PTYPE_POINT
;
641 hw_mode
|= R300_GA_POLY_MODE_FRONT_PTYPE_TRI
;
647 hw_mode
|= R300_GA_POLY_MODE_BACK_PTYPE_LINE
;
650 hw_mode
|= R300_GA_POLY_MODE_BACK_PTYPE_POINT
;
653 hw_mode
|= R300_GA_POLY_MODE_BACK_PTYPE_TRI
;
658 if (r300
->hw
.polygon_mode
.cmd
[1] != hw_mode
) {
659 R300_STATECHANGE(r300
, polygon_mode
);
660 r300
->hw
.polygon_mode
.cmd
[1] = hw_mode
;
663 r300
->hw
.polygon_mode
.cmd
[2] = 0x00000001;
664 r300
->hw
.polygon_mode
.cmd
[3] = 0x00000000;
668 * Change the culling mode.
670 * \note Mesa already filters redundant calls to this function.
672 static void r300CullFace(GLcontext
* ctx
, GLenum mode
)
676 r300UpdateCulling(ctx
);
680 * Change the polygon orientation.
682 * \note Mesa already filters redundant calls to this function.
684 static void r300FrontFace(GLcontext
* ctx
, GLenum mode
)
688 r300UpdateCulling(ctx
);
689 r300UpdatePolygonMode(ctx
);
693 * Change the depth testing function.
695 * \note Mesa already filters redundant calls to this function.
697 static void r300DepthFunc(GLcontext
* ctx
, GLenum func
)
700 r300SetDepthState(ctx
);
704 * Enable/Disable depth writing.
706 * \note Mesa already filters redundant calls to this function.
708 static void r300DepthMask(GLcontext
* ctx
, GLboolean mask
)
711 r300SetDepthState(ctx
);
715 * Handle glColorMask()
717 static void r300ColorMask(GLcontext
* ctx
,
718 GLboolean r
, GLboolean g
, GLboolean b
, GLboolean a
)
720 r300ContextPtr r300
= R300_CONTEXT(ctx
);
721 int mask
= (r
? RB3D_COLOR_CHANNEL_MASK_RED_MASK0
: 0) |
722 (g
? RB3D_COLOR_CHANNEL_MASK_GREEN_MASK0
: 0) |
723 (b
? RB3D_COLOR_CHANNEL_MASK_BLUE_MASK0
: 0) |
724 (a
? RB3D_COLOR_CHANNEL_MASK_ALPHA_MASK0
: 0);
726 if (mask
!= r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
]) {
727 R300_STATECHANGE(r300
, cmk
);
728 r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
] = mask
;
732 /* =============================================================
735 static void r300Fogfv(GLcontext
* ctx
, GLenum pname
, const GLfloat
* param
)
737 r300ContextPtr r300
= R300_CONTEXT(ctx
);
741 } fogScale
, fogStart
;
745 fogScale
.i
= r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
];
746 fogStart
.i
= r300
->hw
.fogp
.cmd
[R300_FOGP_START
];
750 switch (ctx
->Fog
.Mode
) {
752 R300_STATECHANGE(r300
, fogs
);
753 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
755 cmd
[R300_FOGS_STATE
] & ~R300_FG_FOG_BLEND_FN_MASK
) |
756 R300_FG_FOG_BLEND_FN_LINEAR
;
758 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
763 1.0 / (ctx
->Fog
.End
- ctx
->Fog
.Start
);
765 -ctx
->Fog
.Start
/ (ctx
->Fog
.End
-
770 R300_STATECHANGE(r300
, fogs
);
771 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
773 cmd
[R300_FOGS_STATE
] & ~R300_FG_FOG_BLEND_FN_MASK
) |
774 R300_FG_FOG_BLEND_FN_EXP
;
775 fogScale
.f
= 0.0933 * ctx
->Fog
.Density
;
779 R300_STATECHANGE(r300
, fogs
);
780 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
782 cmd
[R300_FOGS_STATE
] & ~R300_FG_FOG_BLEND_FN_MASK
) |
783 R300_FG_FOG_BLEND_FN_EXP2
;
784 fogScale
.f
= 0.3 * ctx
->Fog
.Density
;
791 switch (ctx
->Fog
.Mode
) {
793 fogScale
.f
= 0.0933 * ctx
->Fog
.Density
;
797 fogScale
.f
= 0.3 * ctx
->Fog
.Density
;
805 if (ctx
->Fog
.Mode
== GL_LINEAR
) {
806 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
811 1.0 / (ctx
->Fog
.End
- ctx
->Fog
.Start
);
813 -ctx
->Fog
.Start
/ (ctx
->Fog
.End
-
819 R300_STATECHANGE(r300
, fogc
);
820 r300
->hw
.fogc
.cmd
[R300_FOGC_R
] =
821 (GLuint
) (ctx
->Fog
.Color
[0] * 1023.0F
) & 0x3FF;
822 r300
->hw
.fogc
.cmd
[R300_FOGC_G
] =
823 (GLuint
) (ctx
->Fog
.Color
[1] * 1023.0F
) & 0x3FF;
824 r300
->hw
.fogc
.cmd
[R300_FOGC_B
] =
825 (GLuint
) (ctx
->Fog
.Color
[2] * 1023.0F
) & 0x3FF;
827 case GL_FOG_COORD_SRC
:
833 if (fogScale
.i
!= r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
] ||
834 fogStart
.i
!= r300
->hw
.fogp
.cmd
[R300_FOGP_START
]) {
835 R300_STATECHANGE(r300
, fogp
);
836 r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
] = fogScale
.i
;
837 r300
->hw
.fogp
.cmd
[R300_FOGP_START
] = fogStart
.i
;
841 static void r300SetFogState(GLcontext
* ctx
, GLboolean state
)
843 r300ContextPtr r300
= R300_CONTEXT(ctx
);
845 R300_STATECHANGE(r300
, fogs
);
847 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] |= R300_FG_FOG_BLEND_ENABLE
;
849 r300Fogfv(ctx
, GL_FOG_MODE
, NULL
);
850 r300Fogfv(ctx
, GL_FOG_DENSITY
, &ctx
->Fog
.Density
);
851 r300Fogfv(ctx
, GL_FOG_START
, &ctx
->Fog
.Start
);
852 r300Fogfv(ctx
, GL_FOG_END
, &ctx
->Fog
.End
);
853 r300Fogfv(ctx
, GL_FOG_COLOR
, ctx
->Fog
.Color
);
855 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] &= ~R300_FG_FOG_BLEND_ENABLE
;
859 /* =============================================================
862 static void r300PointSize(GLcontext
* ctx
, GLfloat size
)
864 r300ContextPtr r300
= R300_CONTEXT(ctx
);
865 /* same size limits for AA, non-AA points */
866 size
= CLAMP(size
, ctx
->Const
.MinPointSize
, ctx
->Const
.MaxPointSize
);
868 R300_STATECHANGE(r300
, ps
);
869 r300
->hw
.ps
.cmd
[R300_PS_POINTSIZE
] =
870 ((int)(size
* 6) << R300_POINTSIZE_X_SHIFT
) |
871 ((int)(size
* 6) << R300_POINTSIZE_Y_SHIFT
);
874 static void r300PointParameter(GLcontext
* ctx
, GLenum pname
, const GLfloat
* param
)
876 r300ContextPtr r300
= R300_CONTEXT(ctx
);
879 case GL_POINT_SIZE_MIN
:
880 R300_STATECHANGE(r300
, ga_point_minmax
);
881 r300
->hw
.ga_point_minmax
.cmd
[1] &= ~R300_GA_POINT_MINMAX_MIN_MASK
;
882 r300
->hw
.ga_point_minmax
.cmd
[1] |= (GLuint
)(ctx
->Point
.MinSize
* 6.0);
884 case GL_POINT_SIZE_MAX
:
885 R300_STATECHANGE(r300
, ga_point_minmax
);
886 r300
->hw
.ga_point_minmax
.cmd
[1] &= ~R300_GA_POINT_MINMAX_MAX_MASK
;
887 r300
->hw
.ga_point_minmax
.cmd
[1] |= (GLuint
)(ctx
->Point
.MaxSize
* 6.0)
888 << R300_GA_POINT_MINMAX_MAX_SHIFT
;
890 case GL_POINT_DISTANCE_ATTENUATION
:
892 case GL_POINT_FADE_THRESHOLD_SIZE
:
899 /* =============================================================
902 static void r300LineWidth(GLcontext
* ctx
, GLfloat widthf
)
904 r300ContextPtr r300
= R300_CONTEXT(ctx
);
906 widthf
= CLAMP(widthf
,
907 ctx
->Const
.MinPointSize
,
908 ctx
->Const
.MaxPointSize
);
909 R300_STATECHANGE(r300
, lcntl
);
910 r300
->hw
.lcntl
.cmd
[1] =
911 R300_LINE_CNT_HO
| R300_LINE_CNT_VE
| (int)(widthf
* 6.0);
914 static void r300PolygonMode(GLcontext
* ctx
, GLenum face
, GLenum mode
)
919 r300UpdatePolygonMode(ctx
);
922 /* =============================================================
926 static int translate_stencil_op(int op
)
934 return R300_ZS_REPLACE
;
939 case GL_INCR_WRAP_EXT
:
940 return R300_ZS_INCR_WRAP
;
941 case GL_DECR_WRAP_EXT
:
942 return R300_ZS_DECR_WRAP
;
944 return R300_ZS_INVERT
;
946 WARN_ONCE("Do not know how to translate stencil op");
952 static void r300ShadeModel(GLcontext
* ctx
, GLenum mode
)
954 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
956 R300_STATECHANGE(rmesa
, shade
);
957 rmesa
->hw
.shade
.cmd
[1] = 0x00000002;
960 rmesa
->hw
.shade
.cmd
[2] = R300_RE_SHADE_MODEL_FLAT
;
963 rmesa
->hw
.shade
.cmd
[2] = R300_RE_SHADE_MODEL_SMOOTH
;
968 rmesa
->hw
.shade
.cmd
[3] = 0x00000000;
969 rmesa
->hw
.shade
.cmd
[4] = 0x00000000;
972 static void r300StencilFuncSeparate(GLcontext
* ctx
, GLenum face
,
973 GLenum func
, GLint ref
, GLuint mask
)
975 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
978 Ref
[0] & 0xff) << R300_STENCILREF_SHIFT
) | ((ctx
->
984 R300_STENCILMASK_SHIFT
));
988 R300_STATECHANGE(rmesa
, zs
);
989 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_STENCIL_FRONT_BACK
;
990 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= ~((R300_ZS_MASK
<<
991 R300_S_FRONT_FUNC_SHIFT
)
993 R300_S_BACK_FUNC_SHIFT
));
995 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &=
996 ~((R300_STENCILREF_MASK
<< R300_STENCILREF_SHIFT
) |
997 (R300_STENCILREF_MASK
<< R300_STENCILMASK_SHIFT
));
999 flag
= translate_func(ctx
->Stencil
.Function
[0]);
1000 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
1001 (flag
<< R300_S_FRONT_FUNC_SHIFT
);
1003 if (ctx
->Stencil
._TestTwoSide
)
1004 flag
= translate_func(ctx
->Stencil
.Function
[1]);
1006 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
1007 (flag
<< R300_S_BACK_FUNC_SHIFT
);
1008 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |= refmask
;
1011 static void r300StencilMaskSeparate(GLcontext
* ctx
, GLenum face
, GLuint mask
)
1013 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1015 R300_STATECHANGE(rmesa
, zs
);
1016 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &=
1017 ~(R300_STENCILREF_MASK
<<
1018 R300_STENCILWRITEMASK_SHIFT
);
1019 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |=
1021 WriteMask
[0] & R300_STENCILREF_MASK
) <<
1022 R300_STENCILWRITEMASK_SHIFT
;
1025 static void r300StencilOpSeparate(GLcontext
* ctx
, GLenum face
,
1026 GLenum fail
, GLenum zfail
, GLenum zpass
)
1028 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1030 R300_STATECHANGE(rmesa
, zs
);
1031 /* It is easier to mask what's left.. */
1032 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &=
1033 (R300_ZS_MASK
<< R300_Z_FUNC_SHIFT
) |
1034 (R300_ZS_MASK
<< R300_S_FRONT_FUNC_SHIFT
) |
1035 (R300_ZS_MASK
<< R300_S_BACK_FUNC_SHIFT
);
1037 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
1038 (translate_stencil_op(ctx
->Stencil
.FailFunc
[0]) <<
1039 R300_S_FRONT_SFAIL_OP_SHIFT
)
1040 | (translate_stencil_op(ctx
->Stencil
.ZFailFunc
[0]) <<
1041 R300_S_FRONT_ZFAIL_OP_SHIFT
)
1042 | (translate_stencil_op(ctx
->Stencil
.ZPassFunc
[0]) <<
1043 R300_S_FRONT_ZPASS_OP_SHIFT
);
1045 if (ctx
->Stencil
._TestTwoSide
) {
1046 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
1047 (translate_stencil_op(ctx
->Stencil
.FailFunc
[1]) <<
1048 R300_S_BACK_SFAIL_OP_SHIFT
)
1049 | (translate_stencil_op(ctx
->Stencil
.ZFailFunc
[1]) <<
1050 R300_S_BACK_ZFAIL_OP_SHIFT
)
1051 | (translate_stencil_op(ctx
->Stencil
.ZPassFunc
[1]) <<
1052 R300_S_BACK_ZPASS_OP_SHIFT
);
1054 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
1055 (translate_stencil_op(ctx
->Stencil
.FailFunc
[0]) <<
1056 R300_S_BACK_SFAIL_OP_SHIFT
)
1057 | (translate_stencil_op(ctx
->Stencil
.ZFailFunc
[0]) <<
1058 R300_S_BACK_ZFAIL_OP_SHIFT
)
1059 | (translate_stencil_op(ctx
->Stencil
.ZPassFunc
[0]) <<
1060 R300_S_BACK_ZPASS_OP_SHIFT
);
1064 /* =============================================================
1065 * Window position and viewport transformation
1069 * To correctly position primitives:
1071 #define SUBPIXEL_X 0.125
1072 #define SUBPIXEL_Y 0.125
1074 static void r300UpdateWindow(GLcontext
* ctx
)
1076 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1077 __DRIdrawablePrivate
*dPriv
= rmesa
->radeon
.dri
.drawable
;
1078 GLfloat xoffset
= dPriv
? (GLfloat
) dPriv
->x
: 0;
1079 GLfloat yoffset
= dPriv
? (GLfloat
) dPriv
->y
+ dPriv
->h
: 0;
1080 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1082 GLfloat sx
= v
[MAT_SX
];
1083 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1084 GLfloat sy
= -v
[MAT_SY
];
1085 GLfloat ty
= (-v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1086 GLfloat sz
= v
[MAT_SZ
] * rmesa
->state
.depth
.scale
;
1087 GLfloat tz
= v
[MAT_TZ
] * rmesa
->state
.depth
.scale
;
1089 R300_FIREVERTICES(rmesa
);
1090 R300_STATECHANGE(rmesa
, vpt
);
1092 rmesa
->hw
.vpt
.cmd
[R300_VPT_XSCALE
] = r300PackFloat32(sx
);
1093 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
1094 rmesa
->hw
.vpt
.cmd
[R300_VPT_YSCALE
] = r300PackFloat32(sy
);
1095 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
1096 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZSCALE
] = r300PackFloat32(sz
);
1097 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZOFFSET
] = r300PackFloat32(tz
);
1100 static void r300Viewport(GLcontext
* ctx
, GLint x
, GLint y
,
1101 GLsizei width
, GLsizei height
)
1103 /* Don't pipeline viewport changes, conflict with window offset
1104 * setting below. Could apply deltas to rescue pipelined viewport
1105 * values, or keep the originals hanging around.
1107 r300UpdateWindow(ctx
);
1110 static void r300DepthRange(GLcontext
* ctx
, GLclampd nearval
, GLclampd farval
)
1112 r300UpdateWindow(ctx
);
1115 void r300UpdateViewportOffset(GLcontext
* ctx
)
1117 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1118 __DRIdrawablePrivate
*dPriv
= ((radeonContextPtr
) rmesa
)->dri
.drawable
;
1119 GLfloat xoffset
= (GLfloat
) dPriv
->x
;
1120 GLfloat yoffset
= (GLfloat
) dPriv
->y
+ dPriv
->h
;
1121 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1123 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1124 GLfloat ty
= (-v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1126 if (rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] != r300PackFloat32(tx
) ||
1127 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] != r300PackFloat32(ty
)) {
1128 /* Note: this should also modify whatever data the context reset
1131 R300_STATECHANGE(rmesa
, vpt
);
1132 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
1133 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
1137 radeonUpdateScissor(ctx
);
1141 * Tell the card where to render (offset, pitch).
1142 * Effected by glDrawBuffer, etc
1144 void r300UpdateDrawBuffer(GLcontext
* ctx
)
1146 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1147 r300ContextPtr r300
= rmesa
;
1148 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
1149 driRenderbuffer
*drb
;
1151 if (fb
->_ColorDrawBufferIndexes
[0] == BUFFER_FRONT_LEFT
) {
1154 (driRenderbuffer
*) fb
->Attachment
[BUFFER_FRONT_LEFT
].
1156 } else if (fb
->_ColorDrawBufferIndexes
[0] == BUFFER_BACK_LEFT
) {
1159 (driRenderbuffer
*) fb
->Attachment
[BUFFER_BACK_LEFT
].
1162 /* drawing to multiple buffers, or none */
1167 assert(drb
->flippedPitch
);
1169 R300_STATECHANGE(rmesa
, cb
);
1171 r300
->hw
.cb
.cmd
[R300_CB_OFFSET
] = drb
->flippedOffset
+ //r300->radeon.state.color.drawOffset +
1172 r300
->radeon
.radeonScreen
->fbLocation
;
1173 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] = drb
->flippedPitch
; //r300->radeon.state.color.drawPitch;
1175 if (r300
->radeon
.radeonScreen
->cpp
== 4)
1176 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_ARGB8888
;
1178 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_RGB565
;
1180 if (r300
->radeon
.sarea
->tiling_enabled
)
1181 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_TILE_ENABLE
;
1183 R200_STATECHANGE(rmesa
, ctx
);
1185 /* Note: we used the (possibly) page-flipped values */
1186 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLOROFFSET
]
1187 = ((drb
->flippedOffset
+ rmesa
->r200Screen
->fbLocation
)
1188 & R200_COLOROFFSET_MASK
);
1189 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] = drb
->flippedPitch
;
1191 if (rmesa
->sarea
->tiling_enabled
) {
1192 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] |=
1193 R200_COLOR_TILE_ENABLE
;
1199 r300FetchStateParameter(GLcontext
* ctx
,
1200 const gl_state_index state
[STATE_LENGTH
],
1203 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1206 case STATE_INTERNAL
:
1208 case STATE_R300_WINDOW_DIMENSION
:
1209 value
[0] = r300
->radeon
.dri
.drawable
->w
* 0.5f
; /* width*0.5 */
1210 value
[1] = r300
->radeon
.dri
.drawable
->h
* 0.5f
; /* height*0.5 */
1211 value
[2] = 0.5F
; /* for moving range [-1 1] -> [0 1] */
1212 value
[3] = 1.0F
; /* not used */
1215 case STATE_R300_TEXRECT_FACTOR
:{
1216 struct gl_texture_object
*t
=
1217 ctx
->Texture
.Unit
[state
[2]].CurrentRect
;
1219 if (t
&& t
->Image
[0][t
->BaseLevel
]) {
1220 struct gl_texture_image
*image
=
1221 t
->Image
[0][t
->BaseLevel
];
1222 value
[0] = 1.0 / image
->Width2
;
1223 value
[1] = 1.0 / image
->Height2
;
1244 * Update R300's own internal state parameters.
1245 * For now just STATE_R300_WINDOW_DIMENSION
1247 void r300UpdateStateParameters(GLcontext
* ctx
, GLuint new_state
)
1249 struct r300_fragment_program
*fp
;
1250 struct gl_program_parameter_list
*paramList
;
1253 if (!(new_state
& (_NEW_BUFFERS
| _NEW_PROGRAM
)))
1256 fp
= (struct r300_fragment_program
*)ctx
->FragmentProgram
._Current
;
1260 paramList
= fp
->mesa_program
.Base
.Parameters
;
1265 for (i
= 0; i
< paramList
->NumParameters
; i
++) {
1266 if (paramList
->Parameters
[i
].Type
== PROGRAM_STATE_VAR
) {
1267 r300FetchStateParameter(ctx
,
1268 paramList
->Parameters
[i
].
1270 paramList
->ParameterValues
[i
]);
1275 /* =============================================================
1278 static void r300PolygonOffset(GLcontext
* ctx
, GLfloat factor
, GLfloat units
)
1280 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1281 GLfloat constant
= units
;
1283 switch (ctx
->Visual
.depthBits
) {
1294 /* fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */
1296 R300_STATECHANGE(rmesa
, zbs
);
1297 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_FACTOR
] = r300PackFloat32(factor
);
1298 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_CONSTANT
] = r300PackFloat32(constant
);
1299 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_FACTOR
] = r300PackFloat32(factor
);
1300 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_CONSTANT
] = r300PackFloat32(constant
);
1303 /* Routing and texture-related */
1305 /* r300 doesnt handle GL_CLAMP and GL_MIRROR_CLAMP_EXT correctly when filter is NEAREST.
1306 * Since texwrap produces same results for GL_CLAMP and GL_CLAMP_TO_EDGE we use them instead.
1307 * We need to recalculate wrap modes whenever filter mode is changed because someone might do:
1308 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1309 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1310 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1311 * Since r300 completely ignores R300_TX_CLAMP when either min or mag is nearest it cant handle
1312 * combinations where only one of them is nearest.
1314 static unsigned long gen_fixed_filter(unsigned long f
)
1316 unsigned long mag
, min
, needs_fixing
= 0;
1319 /* We ignore MIRROR bit so we dont have to do everything twice */
1320 if ((f
& ((7 - 1) << R300_TX_WRAP_S_SHIFT
)) ==
1321 (R300_TX_CLAMP
<< R300_TX_WRAP_S_SHIFT
)) {
1324 if ((f
& ((7 - 1) << R300_TX_WRAP_T_SHIFT
)) ==
1325 (R300_TX_CLAMP
<< R300_TX_WRAP_T_SHIFT
)) {
1328 if ((f
& ((7 - 1) << R300_TX_WRAP_R_SHIFT
)) ==
1329 (R300_TX_CLAMP
<< R300_TX_WRAP_R_SHIFT
)) {
1336 mag
= f
& R300_TX_MAG_FILTER_MASK
;
1337 min
= f
& (R300_TX_MIN_FILTER_MASK
|R300_TX_MIN_FILTER_MIP_MASK
);
1339 /* TODO: Check for anisto filters too */
1340 if ((mag
!= R300_TX_MAG_FILTER_NEAREST
)
1341 && (min
!= R300_TX_MIN_FILTER_NEAREST
))
1344 /* r300 cant handle these modes hence we force nearest to linear */
1345 if ((mag
== R300_TX_MAG_FILTER_NEAREST
)
1346 && (min
!= R300_TX_MIN_FILTER_NEAREST
)) {
1347 f
&= ~R300_TX_MAG_FILTER_NEAREST
;
1348 f
|= R300_TX_MAG_FILTER_LINEAR
;
1352 if ((min
== R300_TX_MIN_FILTER_NEAREST
)
1353 && (mag
!= R300_TX_MAG_FILTER_NEAREST
)) {
1354 f
&= ~R300_TX_MIN_FILTER_NEAREST
;
1355 f
|= R300_TX_MIN_FILTER_LINEAR
;
1359 /* Both are nearest */
1360 if (needs_fixing
& 1) {
1361 f
&= ~((7 - 1) << R300_TX_WRAP_S_SHIFT
);
1362 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_S_SHIFT
;
1364 if (needs_fixing
& 2) {
1365 f
&= ~((7 - 1) << R300_TX_WRAP_T_SHIFT
);
1366 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_T_SHIFT
;
1368 if (needs_fixing
& 4) {
1369 f
&= ~((7 - 1) << R300_TX_WRAP_R_SHIFT
);
1370 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_R_SHIFT
;
1375 static void r300SetupFragmentShaderTextures(GLcontext
*ctx
, int *tmu_mappings
)
1377 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1379 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
1380 (char *)ctx
->FragmentProgram
._Current
;
1381 struct r300_fragment_program_code
*code
= &fp
->code
;
1383 R300_STATECHANGE(r300
, fpt
);
1385 for (i
= 0; i
< code
->tex
.length
; i
++) {
1390 unit
= code
->tex
.inst
[i
] >> R300_TEX_ID_SHIFT
;
1393 val
= code
->tex
.inst
[i
];
1394 val
&= ~R300_TEX_ID_MASK
;
1397 (val
& R300_TEX_INST_MASK
) >> R300_TEX_INST_SHIFT
;
1398 if (opcode
== R300_TEX_OP_KIL
) {
1399 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1401 if (tmu_mappings
[unit
] >= 0) {
1403 tmu_mappings
[unit
] <<
1405 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1407 // We get here when the corresponding texture image is incomplete
1408 // (e.g. incomplete mipmaps etc.)
1409 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1414 r300
->hw
.fpt
.cmd
[R300_FPT_CMD_0
] =
1415 cmdpacket0(R300_US_TEX_INST_0
, code
->tex
.length
);
1418 static void r500SetupFragmentShaderTextures(GLcontext
*ctx
, int *tmu_mappings
)
1421 struct r500_fragment_program
*fp
= (struct r500_fragment_program
*)
1422 (char *)ctx
->FragmentProgram
._Current
;
1423 struct r500_fragment_program_code
*code
= &fp
->code
;
1425 /* find all the texture instructions and relocate the texture units */
1426 for (i
= 0; i
< code
->inst_end
+ 1; i
++) {
1427 if ((code
->inst
[i
].inst0
& 0x3) == R500_INST_TYPE_TEX
) {
1429 int unit
, opcode
, new_unit
;
1431 val
= code
->inst
[i
].inst1
;
1433 unit
= (val
>> 16) & 0xf;
1435 val
&= ~(0xf << 16);
1437 opcode
= val
& (0x7 << 22);
1438 if (opcode
== R500_TEX_INST_TEXKILL
) {
1441 if (tmu_mappings
[unit
] >= 0) {
1442 new_unit
= tmu_mappings
[unit
];
1447 val
|= R500_TEX_ID(new_unit
);
1448 code
->inst
[i
].inst1
= val
;
1453 static GLuint
translate_lod_bias(GLfloat bias
)
1455 GLint b
= (int)(bias
*32);
1458 else if (b
< -(1 << 9))
1460 return (((GLuint
)b
) << R300_LOD_BIAS_SHIFT
) & R300_LOD_BIAS_MASK
;
1463 static void r300SetupTextures(GLcontext
* ctx
)
1466 struct r300_tex_obj
*t
;
1467 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1469 int last_hw_tmu
= -1; /* -1 translates into no setup costs for fields */
1470 int tmu_mappings
[R300_MAX_TEXTURE_UNITS
] = { -1, };
1471 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
1472 (char *)ctx
->FragmentProgram
._Current
;
1474 R300_STATECHANGE(r300
, txe
);
1475 R300_STATECHANGE(r300
, tex
.filter
);
1476 R300_STATECHANGE(r300
, tex
.filter_1
);
1477 R300_STATECHANGE(r300
, tex
.size
);
1478 R300_STATECHANGE(r300
, tex
.format
);
1479 R300_STATECHANGE(r300
, tex
.pitch
);
1480 R300_STATECHANGE(r300
, tex
.offset
);
1481 R300_STATECHANGE(r300
, tex
.chroma_key
);
1482 R300_STATECHANGE(r300
, tex
.border_color
);
1484 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] = 0x0;
1486 mtu
= r300
->radeon
.glCtx
->Const
.MaxTextureUnits
;
1487 if (RADEON_DEBUG
& DEBUG_STATE
)
1488 fprintf(stderr
, "mtu=%d\n", mtu
);
1490 if (mtu
> R300_MAX_TEXTURE_UNITS
) {
1492 "Aiiee ! mtu=%d is greater than R300_MAX_TEXTURE_UNITS=%d\n",
1493 mtu
, R300_MAX_TEXTURE_UNITS
);
1497 /* We cannot let disabled tmu offsets pass DRM */
1498 for (i
= 0; i
< mtu
; i
++) {
1499 if (ctx
->Texture
.Unit
[i
]._ReallyEnabled
) {
1501 #if 0 /* Enables old behaviour */
1504 tmu_mappings
[i
] = hw_tmu
;
1506 t
= r300
->state
.texture
.unit
[i
].texobj
;
1507 /* XXX questionable fix for bug 9170: */
1511 if ((t
->format
& 0xffffff00) == 0xffffff00) {
1513 ("unknown texture format (entry %x) encountered. Help me !\n",
1517 if (RADEON_DEBUG
& DEBUG_STATE
)
1519 "Activating texture unit %d\n", i
);
1521 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] |= (1 << hw_tmu
);
1523 r300
->hw
.tex
.filter
.cmd
[R300_TEX_VALUE_0
+
1525 gen_fixed_filter(t
->filter
) | (hw_tmu
<< 28);
1526 /* Note: There is a LOD bias per texture unit and a LOD bias
1527 * per texture object. We add them here to get the correct behaviour.
1528 * (The per-texture object LOD bias was introduced in OpenGL 1.4
1529 * and is not present in the EXT_texture_object extension).
1531 r300
->hw
.tex
.filter_1
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] =
1533 translate_lod_bias(ctx
->Texture
.Unit
[i
].LodBias
+ t
->base
.tObj
->LodBias
);
1534 r300
->hw
.tex
.size
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] =
1536 r300
->hw
.tex
.format
.cmd
[R300_TEX_VALUE_0
+
1537 hw_tmu
] = t
->format
;
1538 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] =
1540 r300
->hw
.tex
.offset
.cmd
[R300_TEX_VALUE_0
+
1541 hw_tmu
] = t
->offset
;
1543 if (t
->offset
& R300_TXO_MACRO_TILE
) {
1544 WARN_ONCE("macro tiling enabled!\n");
1547 if (t
->offset
& R300_TXO_MICRO_TILE
) {
1548 WARN_ONCE("micro tiling enabled!\n");
1551 r300
->hw
.tex
.chroma_key
.cmd
[R300_TEX_VALUE_0
+
1553 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_VALUE_0
+
1557 last_hw_tmu
= hw_tmu
;
1563 r300
->hw
.tex
.filter
.cmd
[R300_TEX_CMD_0
] =
1564 cmdpacket0(R300_TX_FILTER0_0
, last_hw_tmu
+ 1);
1565 r300
->hw
.tex
.filter_1
.cmd
[R300_TEX_CMD_0
] =
1566 cmdpacket0(R300_TX_FILTER1_0
, last_hw_tmu
+ 1);
1567 r300
->hw
.tex
.size
.cmd
[R300_TEX_CMD_0
] =
1568 cmdpacket0(R300_TX_SIZE_0
, last_hw_tmu
+ 1);
1569 r300
->hw
.tex
.format
.cmd
[R300_TEX_CMD_0
] =
1570 cmdpacket0(R300_TX_FORMAT_0
, last_hw_tmu
+ 1);
1571 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_CMD_0
] =
1572 cmdpacket0(R300_TX_FORMAT2_0
, last_hw_tmu
+ 1);
1573 r300
->hw
.tex
.offset
.cmd
[R300_TEX_CMD_0
] =
1574 cmdpacket0(R300_TX_OFFSET_0
, last_hw_tmu
+ 1);
1575 r300
->hw
.tex
.chroma_key
.cmd
[R300_TEX_CMD_0
] =
1576 cmdpacket0(R300_TX_CHROMA_KEY_0
, last_hw_tmu
+ 1);
1577 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_CMD_0
] =
1578 cmdpacket0(R300_TX_BORDER_COLOR_0
, last_hw_tmu
+ 1);
1580 if (!fp
) /* should only happenen once, just after context is created */
1583 if (r300
->radeon
.radeonScreen
->chip_family
< CHIP_FAMILY_RV515
) {
1584 if (fp
->mesa_program
.UsesKill
&& last_hw_tmu
< 0) {
1585 // The KILL operation requires the first texture unit
1587 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] |= 1;
1588 r300
->hw
.tex
.filter
.cmd
[R300_TEX_VALUE_0
] = 0;
1589 r300
->hw
.tex
.filter
.cmd
[R300_TEX_CMD_0
] =
1590 cmdpacket0(R300_TX_FILTER0_0
, 1);
1592 r300SetupFragmentShaderTextures(ctx
, tmu_mappings
);
1594 r500SetupFragmentShaderTextures(ctx
, tmu_mappings
);
1596 if (RADEON_DEBUG
& DEBUG_STATE
)
1597 fprintf(stderr
, "TX_ENABLE: %08x last_hw_tmu=%d\n",
1598 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
], last_hw_tmu
);
1601 union r300_outputs_written
{
1602 GLuint vp_outputs
; /* hw_tcl_on */
1603 DECLARE_RENDERINPUTS(index_bitset
); /* !hw_tcl_on */
1606 #define R300_OUTPUTS_WRITTEN_TEST(ow, vp_result, tnl_attrib) \
1607 ((hw_tcl_on) ? (ow).vp_outputs & (1 << (vp_result)) : \
1608 RENDERINPUTS_TEST( (ow.index_bitset), (tnl_attrib) ))
1610 static void r300SetupRSUnit(GLcontext
* ctx
)
1612 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1613 /* I'm still unsure if these are needed */
1614 GLuint interp_col
[8];
1615 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1616 struct vertex_buffer
*VB
= &tnl
->vb
;
1617 union r300_outputs_written OutputsWritten
;
1619 int fp_reg
, high_rr
;
1621 int rs_tex_count
= 0, rs_col_count
= 0;
1624 memset(interp_col
, 0, sizeof(interp_col
));
1627 OutputsWritten
.vp_outputs
= CURRENT_VERTEX_SHADER(ctx
)->key
.OutputsWritten
;
1629 RENDERINPUTS_COPY(OutputsWritten
.index_bitset
, r300
->state
.render_inputs_bitset
);
1631 if (ctx
->FragmentProgram
._Current
)
1632 InputsRead
= ctx
->FragmentProgram
._Current
->Base
.InputsRead
;
1634 fprintf(stderr
, "No ctx->FragmentProgram._Current!!\n");
1635 return; /* This should only ever happen once.. */
1638 R300_STATECHANGE(r300
, ri
);
1639 R300_STATECHANGE(r300
, rc
);
1640 R300_STATECHANGE(r300
, rr
);
1642 fp_reg
= col_interp_nr
= high_rr
= 0;
1644 r300
->hw
.rr
.cmd
[R300_RR_INST_1
] = 0;
1646 if (InputsRead
& FRAG_BIT_WPOS
) {
1647 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++)
1648 if (!(InputsRead
& (FRAG_BIT_TEX0
<< i
)))
1651 if (i
== ctx
->Const
.MaxTextureUnits
) {
1652 fprintf(stderr
, "\tno free texcoord found...\n");
1656 InputsRead
|= (FRAG_BIT_TEX0
<< i
);
1657 InputsRead
&= ~FRAG_BIT_WPOS
;
1660 if (InputsRead
& FRAG_BIT_COL0
) {
1661 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR0
]->size
;
1662 interp_col
[0] |= R300_RS_COL_PTR(rs_col_count
);
1664 interp_col
[0] |= R300_RS_COL_FMT(R300_RS_COL_FMT_RGB1
);
1665 rs_col_count
+= count
;
1668 interp_col
[0] = R300_RS_COL_FMT(R300_RS_COL_FMT_0001
);
1670 if (InputsRead
& FRAG_BIT_COL1
) {
1671 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR1
]->size
;
1673 interp_col
[1] |= R300_RS_COL_FMT(R300_RS_COL_FMT_RGB0
);
1674 interp_col
[1] |= R300_RS_COL_PTR(1);
1675 rs_col_count
+= count
;
1679 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
1682 /* with TCL we always seem to route 4 components */
1686 count
= VB
->AttribPtr
[_TNL_ATTRIB_TEX(i
)]->size
;
1688 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ i
] = interp_col
[i
] | rs_tex_count
;
1690 case 4: swiz
= R300_RS_SEL_S(0) | R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(3); break;
1691 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;
1694 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;
1697 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ i
] |= swiz
;
1699 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ fp_reg
] = 0;
1700 if (InputsRead
& (FRAG_BIT_TEX0
<< i
)) {
1702 rs_tex_count
+= count
;
1704 //assert(r300->state.texture.tc_count != 0);
1705 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ fp_reg
] |= R300_RS_INST_TEX_CN_WRITE
| i
/* source INTERP */
1706 | (fp_reg
<< R300_RS_INST_TEX_ADDR_SHIFT
);
1709 /* Passing invalid data here can lock the GPU. */
1710 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_TEX0
+ i
, _TNL_ATTRIB_TEX(i
))) {
1711 InputsRead
&= ~(FRAG_BIT_TEX0
<< i
);
1714 WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i
);
1719 if (InputsRead
& FRAG_BIT_COL0
) {
1720 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL0
, _TNL_ATTRIB_COLOR0
)) {
1721 r300
->hw
.rr
.cmd
[R300_RR_INST_0
] |= R300_RS_INST_COL_ID(0) | R300_RS_INST_COL_CN_WRITE
| (fp_reg
++ << R300_RS_INST_COL_ADDR_SHIFT
);
1722 InputsRead
&= ~FRAG_BIT_COL0
;
1725 WARN_ONCE("fragprog wants col0, vp doesn't provide it\n");
1729 if (InputsRead
& FRAG_BIT_COL1
) {
1730 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL1
, _TNL_ATTRIB_COLOR1
)) {
1731 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
);
1732 InputsRead
&= ~FRAG_BIT_COL1
;
1737 WARN_ONCE("fragprog wants col1, vp doesn't provide it\n");
1741 /* Need at least one. This might still lock as the values are undefined... */
1742 if (rs_tex_count
== 0 && col_interp_nr
== 0) {
1743 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
);
1747 r300
->hw
.rc
.cmd
[1] = 0 | (rs_tex_count
<< R300_IT_COUNT_SHIFT
)
1748 | (col_interp_nr
<< R300_IC_COUNT_SHIFT
)
1751 assert(high_rr
>= 0);
1752 r300
->hw
.rr
.cmd
[R300_RR_CMD_0
] = cmdpacket0(R300_RS_INST_0
, high_rr
+ 1);
1753 r300
->hw
.rc
.cmd
[2] = high_rr
;
1756 WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead
);
1759 static void r500SetupRSUnit(GLcontext
* ctx
)
1761 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1762 /* I'm still unsure if these are needed */
1763 GLuint interp_col
[8];
1764 union r300_outputs_written OutputsWritten
;
1765 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1766 struct vertex_buffer
*VB
= &tnl
->vb
;
1768 int fp_reg
, high_rr
;
1769 int rs_col_count
= 0;
1770 int in_texcoords
, col_interp_nr
;
1773 memset(interp_col
, 0, sizeof(interp_col
));
1775 OutputsWritten
.vp_outputs
= CURRENT_VERTEX_SHADER(ctx
)->key
.OutputsWritten
;
1777 RENDERINPUTS_COPY(OutputsWritten
.index_bitset
, r300
->state
.render_inputs_bitset
);
1779 if (ctx
->FragmentProgram
._Current
)
1780 InputsRead
= ctx
->FragmentProgram
._Current
->Base
.InputsRead
;
1782 fprintf(stderr
, "No ctx->FragmentProgram._Current!!\n");
1783 return; /* This should only ever happen once.. */
1786 R300_STATECHANGE(r300
, ri
);
1787 R300_STATECHANGE(r300
, rc
);
1788 R300_STATECHANGE(r300
, rr
);
1790 fp_reg
= col_interp_nr
= high_rr
= in_texcoords
= 0;
1792 r300
->hw
.rr
.cmd
[R300_RR_INST_1
] = 0;
1794 if (InputsRead
& FRAG_BIT_WPOS
) {
1795 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++)
1796 if (!(InputsRead
& (FRAG_BIT_TEX0
<< i
)))
1799 if (i
== ctx
->Const
.MaxTextureUnits
) {
1800 fprintf(stderr
, "\tno free texcoord found...\n");
1804 InputsRead
|= (FRAG_BIT_TEX0
<< i
);
1805 InputsRead
&= ~FRAG_BIT_WPOS
;
1808 if (InputsRead
& FRAG_BIT_COL0
) {
1809 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR0
]->size
;
1810 interp_col
[0] |= R500_RS_COL_PTR(rs_col_count
);
1812 interp_col
[0] |= R500_RS_COL_FMT(R300_RS_COL_FMT_RGB1
);
1813 rs_col_count
+= count
;
1816 interp_col
[0] = R500_RS_COL_FMT(R300_RS_COL_FMT_0001
);
1818 if (InputsRead
& FRAG_BIT_COL1
) {
1819 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR1
]->size
;
1820 interp_col
[1] |= R500_RS_COL_PTR(1);
1822 interp_col
[1] |= R500_RS_COL_FMT(R300_RS_COL_FMT_RGB0
);
1823 rs_col_count
+= count
;
1826 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
1829 /* with TCL we always seem to route 4 components */
1830 if (InputsRead
& (FRAG_BIT_TEX0
<< i
)) {
1835 count
= VB
->AttribPtr
[_TNL_ATTRIB_TEX(i
)]->size
;
1837 /* always have on texcoord */
1838 swiz
|= in_texcoords
++ << R500_RS_IP_TEX_PTR_S_SHIFT
;
1840 swiz
|= in_texcoords
++ << R500_RS_IP_TEX_PTR_T_SHIFT
;
1842 swiz
|= R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_T_SHIFT
;
1845 swiz
|= in_texcoords
++ << R500_RS_IP_TEX_PTR_R_SHIFT
;
1847 swiz
|= R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_R_SHIFT
;
1850 swiz
|= in_texcoords
++ << R500_RS_IP_TEX_PTR_Q_SHIFT
;
1852 swiz
|= R500_RS_IP_PTR_K1
<< R500_RS_IP_TEX_PTR_Q_SHIFT
;
1855 swiz
= (R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_S_SHIFT
) |
1856 (R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_T_SHIFT
) |
1857 (R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_R_SHIFT
) |
1858 (R500_RS_IP_PTR_K1
<< R500_RS_IP_TEX_PTR_Q_SHIFT
);
1860 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ i
] = interp_col
[i
] | swiz
;
1862 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ fp_reg
] = 0;
1863 if (InputsRead
& (FRAG_BIT_TEX0
<< i
)) {
1864 //assert(r300->state.texture.tc_count != 0);
1865 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ fp_reg
] |= R500_RS_INST_TEX_CN_WRITE
| i
/* source INTERP */
1866 | (fp_reg
<< R500_RS_INST_TEX_ADDR_SHIFT
);
1869 /* Passing invalid data here can lock the GPU. */
1870 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_TEX0
+ i
, _TNL_ATTRIB_TEX(i
))) {
1871 InputsRead
&= ~(FRAG_BIT_TEX0
<< i
);
1874 WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i
);
1879 if (InputsRead
& FRAG_BIT_COL0
) {
1880 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL0
, _TNL_ATTRIB_COLOR0
)) {
1881 r300
->hw
.rr
.cmd
[R300_RR_INST_0
] |= R500_RS_INST_COL_CN_WRITE
| (fp_reg
++ << R500_RS_INST_COL_ADDR_SHIFT
);
1882 InputsRead
&= ~FRAG_BIT_COL0
;
1885 WARN_ONCE("fragprog wants col0, vp doesn't provide it\n");
1889 if (InputsRead
& FRAG_BIT_COL1
) {
1890 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL1
, _TNL_ATTRIB_COLOR1
)) {
1891 r300
->hw
.rr
.cmd
[R300_RR_INST_1
] |= (1 << 12) | R500_RS_INST_COL_CN_WRITE
| (fp_reg
++ << R500_RS_INST_COL_ADDR_SHIFT
);
1892 InputsRead
&= ~FRAG_BIT_COL1
;
1897 WARN_ONCE("fragprog wants col1, vp doesn't provide it\n");
1901 /* Need at least one. This might still lock as the values are undefined... */
1902 if (in_texcoords
== 0 && col_interp_nr
== 0) {
1903 r300
->hw
.rr
.cmd
[R300_RR_INST_0
] |= 0 | R500_RS_INST_COL_CN_WRITE
| (fp_reg
++ << R500_RS_INST_COL_ADDR_SHIFT
);
1907 r300
->hw
.rc
.cmd
[1] = 0 | (in_texcoords
<< R300_IT_COUNT_SHIFT
)
1908 | (col_interp_nr
<< R300_IC_COUNT_SHIFT
)
1911 assert(high_rr
>= 0);
1912 r300
->hw
.rr
.cmd
[R300_RR_CMD_0
] = cmdpacket0(R500_RS_INST_0
, high_rr
+ 1);
1913 r300
->hw
.rc
.cmd
[2] = 0xC0 | high_rr
;
1916 WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead
);
1922 #define bump_vpu_count(ptr, new_count) do{\
1923 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
1924 int _nc=(new_count)/4; \
1925 assert(_nc < 256); \
1926 if(_nc>_p->vpu.count)_p->vpu.count=_nc;\
1929 static INLINE
void r300SetupVertexProgramFragment(r300ContextPtr r300
, int dest
, struct r300_vertex_shader_fragment
*vsf
)
1933 if (vsf
->length
== 0)
1936 if (vsf
->length
& 0x3) {
1937 fprintf(stderr
, "VERTEX_SHADER_FRAGMENT must have length divisible by 4\n");
1941 switch ((dest
>> 8) & 0xf) {
1943 R300_STATECHANGE(r300
, vpi
);
1944 for (i
= 0; i
< vsf
->length
; i
++)
1945 r300
->hw
.vpi
.cmd
[R300_VPI_INSTR_0
+ i
+ 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1946 bump_vpu_count(r300
->hw
.vpi
.cmd
, vsf
->length
+ 4 * (dest
& 0xff));
1950 R300_STATECHANGE(r300
, vpp
);
1951 for (i
= 0; i
< vsf
->length
; i
++)
1952 r300
->hw
.vpp
.cmd
[R300_VPP_PARAM_0
+ i
+ 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1953 bump_vpu_count(r300
->hw
.vpp
.cmd
, vsf
->length
+ 4 * (dest
& 0xff));
1956 R300_STATECHANGE(r300
, vps
);
1957 for (i
= 0; i
< vsf
->length
; i
++)
1958 r300
->hw
.vps
.cmd
[1 + i
+ 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1959 bump_vpu_count(r300
->hw
.vps
.cmd
, vsf
->length
+ 4 * (dest
& 0xff));
1962 fprintf(stderr
, "%s:%s don't know how to handle dest %04x\n", __FILE__
, __FUNCTION__
, dest
);
1967 #define MIN3(a, b, c) ((a) < (b) ? MIN2(a, c) : MIN2(b, c))
1970 static void r300VapCntl(r300ContextPtr rmesa
, GLuint input_count
,
1971 GLuint output_count
, GLuint temp_count
)
1977 /* Flush PVS engine before changing PVS_NUM_SLOTS, PVS_NUM_CNTRLS.
1978 * See r500 docs 6.5.2 - done in emit */
1980 /* avoid division by zero */
1981 if (input_count
== 0) input_count
= 1;
1982 if (output_count
== 0) output_count
= 1;
1983 if (temp_count
== 0) temp_count
= 1;
1985 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
1990 pvs_num_slots
= MIN3(10, vtx_mem_size
/input_count
, vtx_mem_size
/output_count
);
1991 pvs_num_cntrls
= MIN2(6, vtx_mem_size
/temp_count
);
1993 R300_STATECHANGE(rmesa
, vap_cntl
);
1994 if (rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
) {
1995 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] =
1996 (pvs_num_slots
<< R300_PVS_NUM_SLOTS_SHIFT
) |
1997 (pvs_num_cntrls
<< R300_PVS_NUM_CNTLRS_SHIFT
) |
1998 (12 << R300_VF_MAX_VTX_NUM_SHIFT
);
1999 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
2000 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= R500_TCL_STATE_OPTIMIZATION
;
2002 /* not sure about non-tcl */
2003 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] = ((10 << R300_PVS_NUM_SLOTS_SHIFT
) |
2004 (5 << R300_PVS_NUM_CNTLRS_SHIFT
) |
2005 (5 << R300_VF_MAX_VTX_NUM_SHIFT
));
2007 if (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV515
)
2008 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (2 << R300_PVS_NUM_FPUS_SHIFT
);
2009 else if ((rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV530
) ||
2010 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV560
) ||
2011 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV570
))
2012 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (5 << R300_PVS_NUM_FPUS_SHIFT
);
2013 else if ((rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV410
) ||
2014 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R420
))
2015 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (6 << R300_PVS_NUM_FPUS_SHIFT
);
2016 else if ((rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R520
) ||
2017 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R580
))
2018 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (8 << R300_PVS_NUM_FPUS_SHIFT
);
2020 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (4 << R300_PVS_NUM_FPUS_SHIFT
);
2024 static void r300SetupDefaultVertexProgram(r300ContextPtr rmesa
)
2026 struct r300_vertex_shader_state
*prog
= &(rmesa
->state
.vertex_shader
);
2031 int param_count
= 0;
2032 int program_end
= 0;
2034 for (i
= VERT_ATTRIB_POS
; i
< VERT_ATTRIB_MAX
; i
++) {
2035 if (rmesa
->state
.sw_tcl_inputs
[i
] != -1) {
2036 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
);
2037 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
);
2038 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
);
2039 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
);
2045 prog
->program
.length
= program_end
;
2047 r300SetupVertexProgramFragment(rmesa
, R300_PVS_CODE_START
,
2049 inst_count
= (prog
->program
.length
/ 4) - 1;
2051 r300VapCntl(rmesa
, i_reg
, o_reg
, 0);
2053 R300_STATECHANGE(rmesa
, pvs
);
2054 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] =
2055 (0 << R300_PVS_FIRST_INST_SHIFT
) |
2056 (inst_count
<< R300_PVS_XYZW_VALID_INST_SHIFT
) |
2057 (inst_count
<< R300_PVS_LAST_INST_SHIFT
);
2058 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] =
2059 (0 << R300_PVS_CONST_BASE_OFFSET_SHIFT
) |
2060 (param_count
<< R300_PVS_MAX_CONST_ADDR_SHIFT
);
2061 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] =
2062 (inst_count
<< R300_PVS_LAST_VTX_SRC_INST_SHIFT
);
2065 static int bit_count (int x
)
2067 x
= ((x
& 0xaaaaaaaaU
) >> 1) + (x
& 0x55555555U
);
2068 x
= ((x
& 0xccccccccU
) >> 2) + (x
& 0x33333333U
);
2069 x
= (x
>> 16) + (x
& 0xffff);
2070 x
= ((x
& 0xf0f0) >> 4) + (x
& 0x0f0f);
2071 return (x
>> 8) + (x
& 0x00ff);
2074 static void r300SetupRealVertexProgram(r300ContextPtr rmesa
)
2076 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
2077 struct r300_vertex_program
*prog
= (struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
);
2079 int param_count
= 0;
2081 /* FIXME: r300SetupVertexProgramFragment */
2082 R300_STATECHANGE(rmesa
, vpp
);
2084 r300VertexProgUpdateParams(ctx
,
2085 (struct r300_vertex_program_cont
*)
2086 ctx
->VertexProgram
._Current
,
2087 (float *)&rmesa
->hw
.vpp
.
2088 cmd
[R300_VPP_PARAM_0
]);
2089 bump_vpu_count(rmesa
->hw
.vpp
.cmd
, param_count
);
2092 r300SetupVertexProgramFragment(rmesa
, R300_PVS_CODE_START
, &(prog
->program
));
2093 inst_count
= (prog
->program
.length
/ 4) - 1;
2095 r300VapCntl(rmesa
, bit_count(prog
->key
.InputsRead
),
2096 bit_count(prog
->key
.OutputsWritten
), prog
->num_temporaries
);
2098 R300_STATECHANGE(rmesa
, pvs
);
2099 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] =
2100 (0 << R300_PVS_FIRST_INST_SHIFT
) |
2101 (inst_count
<< R300_PVS_XYZW_VALID_INST_SHIFT
) |
2102 (inst_count
<< R300_PVS_LAST_INST_SHIFT
);
2103 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] =
2104 (0 << R300_PVS_CONST_BASE_OFFSET_SHIFT
) |
2105 (param_count
<< R300_PVS_MAX_CONST_ADDR_SHIFT
);
2106 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] =
2107 (inst_count
<< R300_PVS_LAST_VTX_SRC_INST_SHIFT
);
2110 static void r300SetupVertexProgram(r300ContextPtr rmesa
)
2112 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
2114 /* Reset state, in case we don't use something */
2115 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vpp
.cmd
)->vpu
.count
= 0;
2116 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vpi
.cmd
)->vpu
.count
= 0;
2117 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vps
.cmd
)->vpu
.count
= 0;
2119 /* Not sure why this doesnt work...
2120 0x400 area might have something to do with pixel shaders as it appears right after pfs programming.
2121 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. */
2122 //setup_vertex_shader_fragment(rmesa, 0x406, &unk4);
2123 if (hw_tcl_on
&& ((struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
))->translated
) {
2124 r300SetupRealVertexProgram(rmesa
);
2126 /* FIXME: This needs to be replaced by vertex shader generation code. */
2127 r300SetupDefaultVertexProgram(rmesa
);
2133 * Enable/Disable states.
2135 * \note Mesa already filters redundant calls to this function.
2137 static void r300Enable(GLcontext
* ctx
, GLenum cap
, GLboolean state
)
2139 if (RADEON_DEBUG
& DEBUG_STATE
)
2140 fprintf(stderr
, "%s( %s = %s )\n", __FUNCTION__
,
2141 _mesa_lookup_enum_by_nr(cap
),
2142 state
? "GL_TRUE" : "GL_FALSE");
2151 r300SetFogState(ctx
, state
);
2154 r300SetAlphaState(ctx
);
2156 case GL_COLOR_LOGIC_OP
:
2157 r300SetLogicOpState(ctx
);
2158 /* fall-through, because logic op overrides blending */
2160 r300SetBlendState(ctx
);
2162 case GL_CLIP_PLANE0
:
2163 case GL_CLIP_PLANE1
:
2164 case GL_CLIP_PLANE2
:
2165 case GL_CLIP_PLANE3
:
2166 case GL_CLIP_PLANE4
:
2167 case GL_CLIP_PLANE5
:
2168 r300SetClipPlaneState(ctx
, cap
, state
);
2171 r300SetDepthState(ctx
);
2173 case GL_STENCIL_TEST
:
2174 r300SetStencilState(ctx
, state
);
2177 r300UpdateCulling(ctx
);
2179 case GL_POLYGON_OFFSET_POINT
:
2180 case GL_POLYGON_OFFSET_LINE
:
2181 case GL_POLYGON_OFFSET_FILL
:
2182 r300SetPolygonOffsetState(ctx
, state
);
2185 radeonEnable(ctx
, cap
, state
);
2191 * Completely recalculates hardware state based on the Mesa state.
2193 static void r300ResetHwState(r300ContextPtr r300
)
2195 GLcontext
*ctx
= r300
->radeon
.glCtx
;
2198 if (!(r300
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
2201 if (RADEON_DEBUG
& DEBUG_STATE
)
2202 fprintf(stderr
, "%s\n", __FUNCTION__
);
2204 r300UpdateWindow(ctx
);
2207 ctx
->Color
.ColorMask
[RCOMP
],
2208 ctx
->Color
.ColorMask
[GCOMP
],
2209 ctx
->Color
.ColorMask
[BCOMP
], ctx
->Color
.ColorMask
[ACOMP
]);
2211 r300Enable(ctx
, GL_DEPTH_TEST
, ctx
->Depth
.Test
);
2212 r300DepthMask(ctx
, ctx
->Depth
.Mask
);
2213 r300DepthFunc(ctx
, ctx
->Depth
.Func
);
2216 r300Enable(ctx
, GL_STENCIL_TEST
, ctx
->Stencil
.Enabled
);
2217 r300StencilMaskSeparate(ctx
, 0, ctx
->Stencil
.WriteMask
[0]);
2218 r300StencilFuncSeparate(ctx
, 0, ctx
->Stencil
.Function
[0],
2219 ctx
->Stencil
.Ref
[0], ctx
->Stencil
.ValueMask
[0]);
2220 r300StencilOpSeparate(ctx
, 0, ctx
->Stencil
.FailFunc
[0],
2221 ctx
->Stencil
.ZFailFunc
[0],
2222 ctx
->Stencil
.ZPassFunc
[0]);
2224 r300UpdateCulling(ctx
);
2226 r300UpdateTextureState(ctx
);
2228 r300SetBlendState(ctx
);
2229 r300SetLogicOpState(ctx
);
2231 r300AlphaFunc(ctx
, ctx
->Color
.AlphaFunc
, ctx
->Color
.AlphaRef
);
2232 r300Enable(ctx
, GL_ALPHA_TEST
, ctx
->Color
.AlphaEnabled
);
2234 r300
->hw
.vte
.cmd
[1] = R300_VPORT_X_SCALE_ENA
2235 | R300_VPORT_X_OFFSET_ENA
2236 | R300_VPORT_Y_SCALE_ENA
2237 | R300_VPORT_Y_OFFSET_ENA
2238 | R300_VPORT_Z_SCALE_ENA
2239 | R300_VPORT_Z_OFFSET_ENA
| R300_VTX_W0_FMT
;
2240 r300
->hw
.vte
.cmd
[2] = 0x00000008;
2242 r300
->hw
.vap_vf_max_vtx_indx
.cmd
[1] = 0x00FFFFFF;
2243 r300
->hw
.vap_vf_max_vtx_indx
.cmd
[2] = 0x00000000;
2245 #ifdef MESA_LITTLE_ENDIAN
2246 r300
->hw
.vap_cntl_status
.cmd
[1] = R300_VC_NO_SWAP
;
2248 r300
->hw
.vap_cntl_status
.cmd
[1] = R300_VC_32BIT_SWAP
;
2251 /* disable VAP/TCL on non-TCL capable chips */
2253 r300
->hw
.vap_cntl_status
.cmd
[1] |= R300_VAP_TCL_BYPASS
;
2255 r300
->hw
.vap_psc_sgn_norm_cntl
.cmd
[1] = 0xAAAAAAAA;
2257 /* XXX: Other families? */
2259 r300
->hw
.vap_clip_cntl
.cmd
[1] = R300_PS_UCP_MODE_DIST_COP
;
2261 r300
->hw
.vap_clip
.cmd
[1] = r300PackFloat32(1.0); /* X */
2262 r300
->hw
.vap_clip
.cmd
[2] = r300PackFloat32(1.0); /* X */
2263 r300
->hw
.vap_clip
.cmd
[3] = r300PackFloat32(1.0); /* Y */
2264 r300
->hw
.vap_clip
.cmd
[4] = r300PackFloat32(1.0); /* Y */
2266 switch (r300
->radeon
.radeonScreen
->chip_family
) {
2267 case CHIP_FAMILY_R300
:
2268 r300
->hw
.vap_pvs_vtx_timeout_reg
.cmd
[1] = R300_2288_R300
;
2271 r300
->hw
.vap_pvs_vtx_timeout_reg
.cmd
[1] = R300_2288_RV350
;
2276 r300
->hw
.gb_enable
.cmd
[1] = R300_GB_POINT_STUFF_ENABLE
2277 | R300_GB_LINE_STUFF_ENABLE
2278 | R300_GB_TRIANGLE_STUFF_ENABLE
;
2280 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_0
] = 0x66666666;
2281 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_1
] = 0x06666666;
2283 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] =
2284 R300_GB_TILE_ENABLE
| R300_GB_TILE_SIZE_16
/*| R300_GB_SUBPIXEL_1_16*/;
2285 switch (r300
->radeon
.radeonScreen
->num_gb_pipes
) {
2288 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2289 R300_GB_TILE_PIPE_COUNT_RV300
;
2292 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2293 R300_GB_TILE_PIPE_COUNT_R300
;
2296 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2297 R300_GB_TILE_PIPE_COUNT_R420_3P
;
2300 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2301 R300_GB_TILE_PIPE_COUNT_R420
;
2305 /* XXX: set to 0 when fog is disabled? */
2306 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_SELECT
] = R300_GB_FOG_SELECT_1_1_W
;
2308 /* XXX: Enable anti-aliasing? */
2309 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_AA_CONFIG
] = GB_AA_CONFIG_AA_DISABLE
;
2311 r300
->hw
.ga_point_s0
.cmd
[1] = r300PackFloat32(0.0);
2312 r300
->hw
.ga_point_s0
.cmd
[2] = r300PackFloat32(0.0);
2313 r300
->hw
.ga_point_s0
.cmd
[3] = r300PackFloat32(1.0);
2314 r300
->hw
.ga_point_s0
.cmd
[4] = r300PackFloat32(1.0);
2316 r300
->hw
.ga_triangle_stipple
.cmd
[1] = 0x00050005;
2318 r300PointSize(ctx
, 1.0);
2320 r300
->hw
.ga_point_minmax
.cmd
[1] = 0x18000006;
2321 r300
->hw
.ga_point_minmax
.cmd
[2] = 0x00020006;
2322 r300
->hw
.ga_point_minmax
.cmd
[3] = r300PackFloat32(1.0 / 192.0);
2324 r300LineWidth(ctx
, 1.0);
2326 r300
->hw
.ga_line_stipple
.cmd
[1] = 0;
2327 r300
->hw
.ga_line_stipple
.cmd
[2] = r300PackFloat32(0.0);
2328 r300
->hw
.ga_line_stipple
.cmd
[3] = r300PackFloat32(1.0);
2330 r300ShadeModel(ctx
, ctx
->Light
.ShadeModel
);
2332 r300PolygonMode(ctx
, GL_FRONT
, ctx
->Polygon
.FrontMode
);
2333 r300PolygonMode(ctx
, GL_BACK
, ctx
->Polygon
.BackMode
);
2334 r300
->hw
.zbias_cntl
.cmd
[1] = 0x00000000;
2336 r300PolygonOffset(ctx
, ctx
->Polygon
.OffsetFactor
,
2337 ctx
->Polygon
.OffsetUnits
);
2338 r300Enable(ctx
, GL_POLYGON_OFFSET_POINT
, ctx
->Polygon
.OffsetPoint
);
2339 r300Enable(ctx
, GL_POLYGON_OFFSET_LINE
, ctx
->Polygon
.OffsetLine
);
2340 r300Enable(ctx
, GL_POLYGON_OFFSET_FILL
, ctx
->Polygon
.OffsetFill
);
2342 r300
->hw
.su_depth_scale
.cmd
[1] = 0x4B7FFFFF;
2343 r300
->hw
.su_depth_scale
.cmd
[2] = 0x00000000;
2345 r300
->hw
.sc_hyperz
.cmd
[1] = 0x0000001C;
2346 r300
->hw
.sc_hyperz
.cmd
[2] = 0x2DA49525;
2348 r300
->hw
.sc_screendoor
.cmd
[1] = 0x00FFFFFF;
2350 r300
->hw
.us_out_fmt
.cmd
[1] = R500_OUT_FMT_C4_8
|
2351 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2352 r300
->hw
.us_out_fmt
.cmd
[2] = R500_OUT_FMT_UNUSED
|
2353 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2354 r300
->hw
.us_out_fmt
.cmd
[3] = R500_OUT_FMT_UNUSED
|
2355 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2356 r300
->hw
.us_out_fmt
.cmd
[4] = R500_OUT_FMT_UNUSED
|
2357 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2358 r300
->hw
.us_out_fmt
.cmd
[5] = R300_W_FMT_W24
;
2360 r300Enable(ctx
, GL_FOG
, ctx
->Fog
.Enabled
);
2361 r300Fogfv(ctx
, GL_FOG_MODE
, NULL
);
2362 r300Fogfv(ctx
, GL_FOG_DENSITY
, &ctx
->Fog
.Density
);
2363 r300Fogfv(ctx
, GL_FOG_START
, &ctx
->Fog
.Start
);
2364 r300Fogfv(ctx
, GL_FOG_END
, &ctx
->Fog
.End
);
2365 r300Fogfv(ctx
, GL_FOG_COLOR
, ctx
->Fog
.Color
);
2366 r300Fogfv(ctx
, GL_FOG_COORDINATE_SOURCE_EXT
, NULL
);
2368 r300
->hw
.fg_depth_src
.cmd
[1] = 0;
2370 r300
->hw
.rb3d_cctl
.cmd
[1] = 0;
2372 r300BlendColor(ctx
, ctx
->Color
.BlendColor
);
2374 /* Again, r300ClearBuffer uses this */
2375 r300
->hw
.cb
.cmd
[R300_CB_OFFSET
] =
2376 r300
->radeon
.state
.color
.drawOffset
+
2377 r300
->radeon
.radeonScreen
->fbLocation
;
2378 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] = r300
->radeon
.state
.color
.drawPitch
;
2380 if (r300
->radeon
.radeonScreen
->cpp
== 4)
2381 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_ARGB8888
;
2383 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_RGB565
;
2385 if (r300
->radeon
.sarea
->tiling_enabled
)
2386 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_TILE_ENABLE
;
2388 r300
->hw
.rb3d_dither_ctl
.cmd
[1] = 0;
2389 r300
->hw
.rb3d_dither_ctl
.cmd
[2] = 0;
2390 r300
->hw
.rb3d_dither_ctl
.cmd
[3] = 0;
2391 r300
->hw
.rb3d_dither_ctl
.cmd
[4] = 0;
2392 r300
->hw
.rb3d_dither_ctl
.cmd
[5] = 0;
2393 r300
->hw
.rb3d_dither_ctl
.cmd
[6] = 0;
2394 r300
->hw
.rb3d_dither_ctl
.cmd
[7] = 0;
2395 r300
->hw
.rb3d_dither_ctl
.cmd
[8] = 0;
2396 r300
->hw
.rb3d_dither_ctl
.cmd
[9] = 0;
2398 r300
->hw
.rb3d_aaresolve_ctl
.cmd
[1] = 0;
2400 r300
->hw
.rb3d_discard_src_pixel_lte_threshold
.cmd
[1] = 0x00000000;
2401 r300
->hw
.rb3d_discard_src_pixel_lte_threshold
.cmd
[2] = 0xffffffff;
2403 r300
->hw
.zb
.cmd
[R300_ZB_OFFSET
] =
2404 r300
->radeon
.radeonScreen
->depthOffset
+
2405 r300
->radeon
.radeonScreen
->fbLocation
;
2406 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] = r300
->radeon
.radeonScreen
->depthPitch
;
2408 if (r300
->radeon
.sarea
->tiling_enabled
) {
2409 /* XXX: Turn off when clearing buffers ? */
2410 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] |= R300_DEPTHMACROTILE_ENABLE
;
2412 if (ctx
->Visual
.depthBits
== 24)
2413 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] |=
2414 R300_DEPTHMICROTILE_TILED
;
2417 r300
->hw
.zb_depthclearvalue
.cmd
[1] = 0;
2419 switch (ctx
->Visual
.depthBits
) {
2421 r300
->hw
.zstencil_format
.cmd
[1] = R300_DEPTHFORMAT_16BIT_INT_Z
;
2424 r300
->hw
.zstencil_format
.cmd
[1] = R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL
;
2427 fprintf(stderr
, "Error: Unsupported depth %d... exiting\n", ctx
->Visual
.depthBits
);
2431 r300
->hw
.zstencil_format
.cmd
[2] = R300_ZTOP_DISABLE
;
2432 r300
->hw
.zstencil_format
.cmd
[3] = 0x00000003;
2433 r300
->hw
.zstencil_format
.cmd
[4] = 0x00000000;
2434 r300SetEarlyZState(ctx
);
2436 r300
->hw
.unk4F30
.cmd
[1] = 0;
2437 r300
->hw
.unk4F30
.cmd
[2] = 0;
2439 r300
->hw
.zb_hiz_offset
.cmd
[1] = 0;
2441 r300
->hw
.zb_hiz_pitch
.cmd
[1] = 0;
2443 r300VapCntl(r300
, 0, 0, 0);
2445 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_0
] = 0;
2446 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_1
] = 0;
2447 r300
->hw
.vps
.cmd
[R300_VPS_POINTSIZE
] = r300PackFloat32(1.0);
2448 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_3
] = 0;
2451 r300
->hw
.all_dirty
= GL_TRUE
;
2454 void r300UpdateShaders(r300ContextPtr rmesa
)
2457 struct r300_vertex_program
*vp
;
2460 ctx
= rmesa
->radeon
.glCtx
;
2462 if (rmesa
->NewGLState
&& hw_tcl_on
) {
2463 rmesa
->NewGLState
= 0;
2465 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
2466 rmesa
->temp_attrib
[i
] =
2467 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
];
2468 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] =
2469 &rmesa
->dummy_attrib
[i
];
2472 _tnl_UpdateFixedFunctionProgram(ctx
);
2474 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
2475 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] =
2476 rmesa
->temp_attrib
[i
];
2479 r300SelectVertexShader(rmesa
);
2480 vp
= (struct r300_vertex_program
*)
2481 CURRENT_VERTEX_SHADER(ctx
);
2482 /*if (vp->translated == GL_FALSE)
2483 r300TranslateVertexShader(vp); */
2484 if (vp
->translated
== GL_FALSE
) {
2485 fprintf(stderr
, "Failing back to sw-tcl\n");
2486 hw_tcl_on
= future_hw_tcl_on
= 0;
2487 r300ResetHwState(rmesa
);
2489 r300UpdateStateParameters(ctx
, _NEW_PROGRAM
);
2493 r300UpdateStateParameters(ctx
, _NEW_PROGRAM
);
2496 static const GLfloat
*get_fragmentprogram_constant(GLcontext
*ctx
,
2497 struct gl_program
*program
, struct prog_src_register srcreg
)
2499 static const GLfloat dummy
[4] = { 0, 0, 0, 0 };
2501 switch(srcreg
.File
) {
2502 case PROGRAM_LOCAL_PARAM
:
2503 return program
->LocalParams
[srcreg
.Index
];
2504 case PROGRAM_ENV_PARAM
:
2505 return ctx
->FragmentProgram
.Parameters
[srcreg
.Index
];
2506 case PROGRAM_STATE_VAR
:
2507 case PROGRAM_NAMED_PARAM
:
2508 case PROGRAM_CONSTANT
:
2509 return program
->Parameters
->ParameterValues
[srcreg
.Index
];
2511 _mesa_problem(ctx
, "get_fragmentprogram_constant: Unknown\n");
2517 static void r300SetupPixelShader(r300ContextPtr rmesa
)
2519 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
2520 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
2521 (char *)ctx
->FragmentProgram
._Current
;
2522 struct r300_fragment_program_code
*code
;
2525 if (!fp
) /* should only happenen once, just after context is created */
2528 r300TranslateFragmentShader(rmesa
, fp
);
2529 if (!fp
->translated
) {
2530 fprintf(stderr
, "%s: No valid fragment shader, exiting\n",
2536 r300SetupTextures(ctx
);
2538 R300_STATECHANGE(rmesa
, fpi
[0]);
2539 R300_STATECHANGE(rmesa
, fpi
[1]);
2540 R300_STATECHANGE(rmesa
, fpi
[2]);
2541 R300_STATECHANGE(rmesa
, fpi
[3]);
2542 rmesa
->hw
.fpi
[0].cmd
[R300_FPI_CMD_0
] = cmdpacket0(R300_US_ALU_RGB_INST_0
, code
->alu
.length
);
2543 rmesa
->hw
.fpi
[1].cmd
[R300_FPI_CMD_0
] = cmdpacket0(R300_US_ALU_RGB_ADDR_0
, code
->alu
.length
);
2544 rmesa
->hw
.fpi
[2].cmd
[R300_FPI_CMD_0
] = cmdpacket0(R300_US_ALU_ALPHA_INST_0
, code
->alu
.length
);
2545 rmesa
->hw
.fpi
[3].cmd
[R300_FPI_CMD_0
] = cmdpacket0(R300_US_ALU_ALPHA_ADDR_0
, code
->alu
.length
);
2546 for (i
= 0; i
< code
->alu
.length
; i
++) {
2547 rmesa
->hw
.fpi
[0].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst0
;
2548 rmesa
->hw
.fpi
[1].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst1
;
2549 rmesa
->hw
.fpi
[2].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst2
;
2550 rmesa
->hw
.fpi
[3].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst3
;
2553 R300_STATECHANGE(rmesa
, fp
);
2554 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL0
] = code
->cur_node
| (code
->first_node_has_tex
<< 3);
2555 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL1
] = code
->max_temp_idx
;
2556 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL2
] =
2557 (0 << R300_PFS_CNTL_ALU_OFFSET_SHIFT
) |
2558 ((code
->alu
.length
-1) << R300_PFS_CNTL_ALU_END_SHIFT
) |
2559 (0 << R300_PFS_CNTL_TEX_OFFSET_SHIFT
) |
2560 ((code
->tex
.length
? code
->tex
.length
-1 : 0) << R300_PFS_CNTL_TEX_END_SHIFT
);
2561 /* I just want to say, the way these nodes are stored.. weird.. */
2562 for (i
= 0, k
= (4 - (code
->cur_node
+ 1)); i
< 4; i
++, k
++) {
2563 if (i
< (code
->cur_node
+ 1)) {
2564 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+ k
] =
2565 (code
->node
[i
].alu_offset
<< R300_ALU_START_SHIFT
) |
2566 (code
->node
[i
].alu_end
<< R300_ALU_SIZE_SHIFT
) |
2567 (code
->node
[i
].tex_offset
<< R300_TEX_START_SHIFT
) |
2568 (code
->node
[i
].tex_end
<< R300_TEX_SIZE_SHIFT
) |
2569 code
->node
[i
].flags
;
2571 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+ (3 - i
)] = 0;
2575 R300_STATECHANGE(rmesa
, fpp
);
2576 rmesa
->hw
.fpp
.cmd
[R300_FPP_CMD_0
] = cmdpacket0(R300_PFS_PARAM_0_X
, code
->const_nr
* 4);
2577 for (i
= 0; i
< code
->const_nr
; i
++) {
2578 const GLfloat
*constant
= get_fragmentprogram_constant(ctx
,
2579 &fp
->mesa_program
.Base
, code
->constant
[i
]);
2580 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 0] = r300PackFloat24(constant
[0]);
2581 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 1] = r300PackFloat24(constant
[1]);
2582 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 2] = r300PackFloat24(constant
[2]);
2583 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 3] = r300PackFloat24(constant
[3]);
2587 #define bump_r500fp_count(ptr, new_count) do{\
2588 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
2589 int _nc=(new_count)/6; \
2590 assert(_nc < 256); \
2591 if(_nc>_p->r500fp.count)_p->r500fp.count=_nc;\
2594 #define bump_r500fp_const_count(ptr, new_count) do{\
2595 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
2596 int _nc=(new_count)/4; \
2597 assert(_nc < 256); \
2598 if(_nc>_p->r500fp.count)_p->r500fp.count=_nc;\
2601 static void r500SetupPixelShader(r300ContextPtr rmesa
)
2603 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
2604 struct r500_fragment_program
*fp
= (struct r500_fragment_program
*)
2605 (char *)ctx
->FragmentProgram
._Current
;
2607 struct r500_fragment_program_code
*code
;
2609 if (!fp
) /* should only happenen once, just after context is created */
2612 ((drm_r300_cmd_header_t
*) rmesa
->hw
.r500fp
.cmd
)->r500fp
.count
= 0;
2613 ((drm_r300_cmd_header_t
*) rmesa
->hw
.r500fp_const
.cmd
)->r500fp
.count
= 0;
2615 r500TranslateFragmentShader(rmesa
, fp
);
2616 if (!fp
->translated
) {
2617 fprintf(stderr
, "%s: No valid fragment shader, exiting\n",
2623 if (fp
->mesa_program
.FogOption
!= GL_NONE
) {
2624 /* Enable HW fog. Try not to squish GL context.
2625 * (Anybody sane remembered to set glFog() opts first!) */
2626 r300SetFogState(ctx
, GL_TRUE
);
2627 ctx
->Fog
.Mode
= fp
->mesa_program
.FogOption
;
2628 r300Fogfv(ctx
, GL_FOG_MODE
, NULL
);
2630 /* Make sure HW is matching GL context. */
2631 r300SetFogState(ctx
, ctx
->Fog
.Enabled
);
2633 r300SetupTextures(ctx
);
2635 R300_STATECHANGE(rmesa
, fp
);
2636 rmesa
->hw
.fp
.cmd
[R500_FP_PIXSIZE
] = code
->max_temp_idx
;
2638 rmesa
->hw
.fp
.cmd
[R500_FP_CODE_ADDR
] =
2639 R500_US_CODE_START_ADDR(code
->inst_offset
) |
2640 R500_US_CODE_END_ADDR(code
->inst_end
);
2641 rmesa
->hw
.fp
.cmd
[R500_FP_CODE_RANGE
] =
2642 R500_US_CODE_RANGE_ADDR(code
->inst_offset
) |
2643 R500_US_CODE_RANGE_SIZE(code
->inst_end
);
2644 rmesa
->hw
.fp
.cmd
[R500_FP_CODE_OFFSET
] =
2645 R500_US_CODE_OFFSET_ADDR(0); /* FIXME when we add flow control */
2647 R300_STATECHANGE(rmesa
, r500fp
);
2648 /* Emit our shader... */
2649 for (i
= 0; i
< code
->inst_end
+1; i
++) {
2650 rmesa
->hw
.r500fp
.cmd
[i
*6+1] = code
->inst
[i
].inst0
;
2651 rmesa
->hw
.r500fp
.cmd
[i
*6+2] = code
->inst
[i
].inst1
;
2652 rmesa
->hw
.r500fp
.cmd
[i
*6+3] = code
->inst
[i
].inst2
;
2653 rmesa
->hw
.r500fp
.cmd
[i
*6+4] = code
->inst
[i
].inst3
;
2654 rmesa
->hw
.r500fp
.cmd
[i
*6+5] = code
->inst
[i
].inst4
;
2655 rmesa
->hw
.r500fp
.cmd
[i
*6+6] = code
->inst
[i
].inst5
;
2658 bump_r500fp_count(rmesa
->hw
.r500fp
.cmd
, (code
->inst_end
+ 1) * 6);
2660 R300_STATECHANGE(rmesa
, r500fp_const
);
2661 for (i
= 0; i
< code
->const_nr
; i
++) {
2662 const GLfloat
*constant
= get_fragmentprogram_constant(ctx
,
2663 &fp
->mesa_program
.Base
, code
->constant
[i
]);
2664 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 0] = r300PackFloat32(constant
[0]);
2665 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 1] = r300PackFloat32(constant
[1]);
2666 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 2] = r300PackFloat32(constant
[2]);
2667 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 3] = r300PackFloat32(constant
[3]);
2669 bump_r500fp_const_count(rmesa
->hw
.r500fp_const
.cmd
, code
->const_nr
* 4);
2673 void r300UpdateShaderStates(r300ContextPtr rmesa
)
2676 ctx
= rmesa
->radeon
.glCtx
;
2678 r300UpdateTextureState(ctx
);
2679 r300SetEarlyZState(ctx
);
2681 GLuint fgdepthsrc
= R300_FG_DEPTH_SRC_SCAN
;
2682 if (current_fragment_program_writes_depth(ctx
))
2683 fgdepthsrc
= R300_FG_DEPTH_SRC_SHADER
;
2684 if (fgdepthsrc
!= rmesa
->hw
.fg_depth_src
.cmd
[1]) {
2685 R300_STATECHANGE(rmesa
, fg_depth_src
);
2686 rmesa
->hw
.fg_depth_src
.cmd
[1] = fgdepthsrc
;
2689 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
2690 r500SetupPixelShader(rmesa
);
2692 r300SetupPixelShader(rmesa
);
2694 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
2695 r500SetupRSUnit(ctx
);
2697 r300SetupRSUnit(ctx
);
2699 if ((rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
2700 r300SetupVertexProgram(rmesa
);
2705 * Called by Mesa after an internal state update.
2707 static void r300InvalidateState(GLcontext
* ctx
, GLuint new_state
)
2709 r300ContextPtr r300
= R300_CONTEXT(ctx
);
2711 _swrast_InvalidateState(ctx
, new_state
);
2712 _swsetup_InvalidateState(ctx
, new_state
);
2713 _vbo_InvalidateState(ctx
, new_state
);
2714 _tnl_InvalidateState(ctx
, new_state
);
2715 _ae_invalidate_state(ctx
, new_state
);
2717 if (new_state
& (_NEW_BUFFERS
| _NEW_COLOR
| _NEW_PIXEL
)) {
2718 r300UpdateDrawBuffer(ctx
);
2721 r300UpdateStateParameters(ctx
, new_state
);
2723 r300
->NewGLState
|= new_state
;
2727 * Calculate initial hardware state and register state functions.
2728 * Assumes that the command buffer and state atoms have been
2729 * initialized already.
2731 void r300InitState(r300ContextPtr r300
)
2733 GLcontext
*ctx
= r300
->radeon
.glCtx
;
2736 radeonInitState(&r300
->radeon
);
2738 switch (ctx
->Visual
.depthBits
) {
2740 r300
->state
.depth
.scale
= 1.0 / (GLfloat
) 0xffff;
2741 depth_fmt
= R300_DEPTHFORMAT_16BIT_INT_Z
;
2744 r300
->state
.depth
.scale
= 1.0 / (GLfloat
) 0xffffff;
2745 depth_fmt
= R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL
;
2748 fprintf(stderr
, "Error: Unsupported depth %d... exiting\n",
2749 ctx
->Visual
.depthBits
);
2753 /* Only have hw stencil when depth buffer is 24 bits deep */
2754 r300
->state
.stencil
.hw_stencil
= (ctx
->Visual
.stencilBits
> 0 &&
2755 ctx
->Visual
.depthBits
== 24);
2757 memset(&(r300
->state
.texture
), 0, sizeof(r300
->state
.texture
));
2759 r300ResetHwState(r300
);
2762 static void r300RenderMode(GLcontext
* ctx
, GLenum mode
)
2764 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
2769 void r300UpdateClipPlanes( GLcontext
*ctx
)
2771 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
2774 for (p
= 0; p
< ctx
->Const
.MaxClipPlanes
; p
++) {
2775 if (ctx
->Transform
.ClipPlanesEnabled
& (1 << p
)) {
2776 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
2778 R300_STATECHANGE( rmesa
, vpucp
[p
] );
2779 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_X
] = ip
[0];
2780 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_Y
] = ip
[1];
2781 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_Z
] = ip
[2];
2782 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_W
] = ip
[3];
2788 * Initialize driver's state callback functions
2790 void r300InitStateFuncs(struct dd_function_table
*functions
)
2792 radeonInitStateFuncs(functions
);
2794 functions
->UpdateState
= r300InvalidateState
;
2795 functions
->AlphaFunc
= r300AlphaFunc
;
2796 functions
->BlendColor
= r300BlendColor
;
2797 functions
->BlendEquationSeparate
= r300BlendEquationSeparate
;
2798 functions
->BlendFuncSeparate
= r300BlendFuncSeparate
;
2799 functions
->Enable
= r300Enable
;
2800 functions
->ColorMask
= r300ColorMask
;
2801 functions
->DepthFunc
= r300DepthFunc
;
2802 functions
->DepthMask
= r300DepthMask
;
2803 functions
->CullFace
= r300CullFace
;
2804 functions
->Fogfv
= r300Fogfv
;
2805 functions
->FrontFace
= r300FrontFace
;
2806 functions
->ShadeModel
= r300ShadeModel
;
2807 functions
->LogicOpcode
= r300LogicOpcode
;
2809 /* ARB_point_parameters */
2810 functions
->PointParameterfv
= r300PointParameter
;
2812 /* Stencil related */
2813 functions
->StencilFuncSeparate
= r300StencilFuncSeparate
;
2814 functions
->StencilMaskSeparate
= r300StencilMaskSeparate
;
2815 functions
->StencilOpSeparate
= r300StencilOpSeparate
;
2817 /* Viewport related */
2818 functions
->Viewport
= r300Viewport
;
2819 functions
->DepthRange
= r300DepthRange
;
2820 functions
->PointSize
= r300PointSize
;
2821 functions
->LineWidth
= r300LineWidth
;
2823 functions
->PolygonOffset
= r300PolygonOffset
;
2824 functions
->PolygonMode
= r300PolygonMode
;
2826 functions
->RenderMode
= r300RenderMode
;
2828 functions
->ClipPlane
= r300ClipPlane
;