2 Copyright (C) The Weather Channel, Inc. 2002.
3 Copyright (C) 2004 Nicolai Haehnle.
6 The Weather Channel (TM) funded Tungsten Graphics to develop the
7 initial release of the Radeon 8500 driver under the XFree86 license.
8 This notice must be preserved.
10 Permission is hereby granted, free of charge, to any person obtaining
11 a copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sublicense, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial
20 portions of the Software.
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
26 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 **************************************************************************/
35 * \author Nicolai Haehnle <prefect_@gmx.net>
38 #include "main/glheader.h"
39 #include "main/state.h"
40 #include "main/imports.h"
41 #include "main/enums.h"
42 #include "main/macros.h"
43 #include "main/context.h"
45 #include "main/simple_list.h"
46 #include "main/api_arrayelt.h"
47 #include "main/texformat.h"
49 #include "swrast/swrast.h"
50 #include "swrast_setup/swrast_setup.h"
51 #include "shader/prog_parameter.h"
52 #include "shader/prog_statevars.h"
56 #include "radeon_ioctl.h"
57 #include "radeon_state.h"
58 #include "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
;
792 switch (ctx
->Fog
.Mode
) {
794 fogScale
.f
= 0.0933 * ctx
->Fog
.Density
;
798 fogScale
.f
= 0.3 * ctx
->Fog
.Density
;
806 if (ctx
->Fog
.Mode
== GL_LINEAR
) {
807 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
812 1.0 / (ctx
->Fog
.End
- ctx
->Fog
.Start
);
814 -ctx
->Fog
.Start
/ (ctx
->Fog
.End
-
820 R300_STATECHANGE(r300
, fogc
);
821 r300
->hw
.fogc
.cmd
[R300_FOGC_R
] =
822 (GLuint
) (ctx
->Fog
.Color
[0] * 1023.0F
) & 0x3FF;
823 r300
->hw
.fogc
.cmd
[R300_FOGC_G
] =
824 (GLuint
) (ctx
->Fog
.Color
[1] * 1023.0F
) & 0x3FF;
825 r300
->hw
.fogc
.cmd
[R300_FOGC_B
] =
826 (GLuint
) (ctx
->Fog
.Color
[2] * 1023.0F
) & 0x3FF;
828 case GL_FOG_COORD_SRC
:
834 if (fogScale
.i
!= r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
] ||
835 fogStart
.i
!= r300
->hw
.fogp
.cmd
[R300_FOGP_START
]) {
836 R300_STATECHANGE(r300
, fogp
);
837 r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
] = fogScale
.i
;
838 r300
->hw
.fogp
.cmd
[R300_FOGP_START
] = fogStart
.i
;
842 static void r300SetFogState(GLcontext
* ctx
, GLboolean state
)
844 r300ContextPtr r300
= R300_CONTEXT(ctx
);
846 R300_STATECHANGE(r300
, fogs
);
848 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] |= R300_FG_FOG_BLEND_ENABLE
;
850 r300Fogfv(ctx
, GL_FOG_MODE
, NULL
);
851 r300Fogfv(ctx
, GL_FOG_DENSITY
, &ctx
->Fog
.Density
);
852 r300Fogfv(ctx
, GL_FOG_START
, &ctx
->Fog
.Start
);
853 r300Fogfv(ctx
, GL_FOG_END
, &ctx
->Fog
.End
);
854 r300Fogfv(ctx
, GL_FOG_COLOR
, ctx
->Fog
.Color
);
856 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] &= ~R300_FG_FOG_BLEND_ENABLE
;
860 /* =============================================================
863 static void r300PointSize(GLcontext
* ctx
, GLfloat size
)
865 r300ContextPtr r300
= R300_CONTEXT(ctx
);
866 /* same size limits for AA, non-AA points */
867 size
= CLAMP(size
, ctx
->Const
.MinPointSize
, ctx
->Const
.MaxPointSize
);
869 R300_STATECHANGE(r300
, ps
);
870 r300
->hw
.ps
.cmd
[R300_PS_POINTSIZE
] =
871 ((int)(size
* 6) << R300_POINTSIZE_X_SHIFT
) |
872 ((int)(size
* 6) << R300_POINTSIZE_Y_SHIFT
);
875 static void r300PointParameter(GLcontext
* ctx
, GLenum pname
, const GLfloat
* param
)
877 r300ContextPtr r300
= R300_CONTEXT(ctx
);
880 case GL_POINT_SIZE_MIN
:
881 R300_STATECHANGE(r300
, ga_point_minmax
);
882 r300
->hw
.ga_point_minmax
.cmd
[1] &= ~R300_GA_POINT_MINMAX_MIN_MASK
;
883 r300
->hw
.ga_point_minmax
.cmd
[1] |= (GLuint
)(ctx
->Point
.MinSize
* 6.0);
885 case GL_POINT_SIZE_MAX
:
886 R300_STATECHANGE(r300
, ga_point_minmax
);
887 r300
->hw
.ga_point_minmax
.cmd
[1] &= ~R300_GA_POINT_MINMAX_MAX_MASK
;
888 r300
->hw
.ga_point_minmax
.cmd
[1] |= (GLuint
)(ctx
->Point
.MaxSize
* 6.0)
889 << R300_GA_POINT_MINMAX_MAX_SHIFT
;
891 case GL_POINT_DISTANCE_ATTENUATION
:
893 case GL_POINT_FADE_THRESHOLD_SIZE
:
900 /* =============================================================
903 static void r300LineWidth(GLcontext
* ctx
, GLfloat widthf
)
905 r300ContextPtr r300
= R300_CONTEXT(ctx
);
907 widthf
= CLAMP(widthf
,
908 ctx
->Const
.MinPointSize
,
909 ctx
->Const
.MaxPointSize
);
910 R300_STATECHANGE(r300
, lcntl
);
911 r300
->hw
.lcntl
.cmd
[1] =
912 R300_LINE_CNT_HO
| R300_LINE_CNT_VE
| (int)(widthf
* 6.0);
915 static void r300PolygonMode(GLcontext
* ctx
, GLenum face
, GLenum mode
)
920 r300UpdatePolygonMode(ctx
);
923 /* =============================================================
927 static int translate_stencil_op(int op
)
935 return R300_ZS_REPLACE
;
940 case GL_INCR_WRAP_EXT
:
941 return R300_ZS_INCR_WRAP
;
942 case GL_DECR_WRAP_EXT
:
943 return R300_ZS_DECR_WRAP
;
945 return R300_ZS_INVERT
;
947 WARN_ONCE("Do not know how to translate stencil op");
953 static void r300ShadeModel(GLcontext
* ctx
, GLenum mode
)
955 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
957 R300_STATECHANGE(rmesa
, shade
);
958 rmesa
->hw
.shade
.cmd
[1] = 0x00000002;
961 rmesa
->hw
.shade
.cmd
[2] = R300_RE_SHADE_MODEL_FLAT
;
964 rmesa
->hw
.shade
.cmd
[2] = R300_RE_SHADE_MODEL_SMOOTH
;
969 rmesa
->hw
.shade
.cmd
[3] = 0x00000000;
970 rmesa
->hw
.shade
.cmd
[4] = 0x00000000;
973 static void r300StencilFuncSeparate(GLcontext
* ctx
, GLenum face
,
974 GLenum func
, GLint ref
, GLuint mask
)
976 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
978 ((ctx
->Stencil
.Ref
[0] & 0xff) << R300_STENCILREF_SHIFT
)
979 | ((ctx
->Stencil
.ValueMask
[0] & 0xff) << R300_STENCILMASK_SHIFT
);
980 const unsigned back
= ctx
->Stencil
._BackFace
;
983 R300_STATECHANGE(rmesa
, zs
);
984 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_STENCIL_FRONT_BACK
;
985 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= ~((R300_ZS_MASK
<<
986 R300_S_FRONT_FUNC_SHIFT
)
988 R300_S_BACK_FUNC_SHIFT
));
990 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &=
991 ~((R300_STENCILREF_MASK
<< R300_STENCILREF_SHIFT
) |
992 (R300_STENCILREF_MASK
<< R300_STENCILMASK_SHIFT
));
994 flag
= translate_func(ctx
->Stencil
.Function
[0]);
995 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
996 (flag
<< R300_S_FRONT_FUNC_SHIFT
);
998 flag
= translate_func(ctx
->Stencil
.Function
[back
]);
1000 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
1001 (flag
<< R300_S_BACK_FUNC_SHIFT
);
1002 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |= refmask
;
1005 static void r300StencilMaskSeparate(GLcontext
* ctx
, GLenum face
, GLuint mask
)
1007 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1009 R300_STATECHANGE(rmesa
, zs
);
1010 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &=
1011 ~(R300_STENCILREF_MASK
<<
1012 R300_STENCILWRITEMASK_SHIFT
);
1013 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |=
1015 WriteMask
[0] & R300_STENCILREF_MASK
) <<
1016 R300_STENCILWRITEMASK_SHIFT
;
1019 static void r300StencilOpSeparate(GLcontext
* ctx
, GLenum face
,
1020 GLenum fail
, GLenum zfail
, GLenum zpass
)
1022 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1023 const unsigned back
= ctx
->Stencil
._BackFace
;
1025 R300_STATECHANGE(rmesa
, zs
);
1026 /* It is easier to mask what's left.. */
1027 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &=
1028 (R300_ZS_MASK
<< R300_Z_FUNC_SHIFT
) |
1029 (R300_ZS_MASK
<< R300_S_FRONT_FUNC_SHIFT
) |
1030 (R300_ZS_MASK
<< R300_S_BACK_FUNC_SHIFT
);
1032 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
1033 (translate_stencil_op(ctx
->Stencil
.FailFunc
[0]) <<
1034 R300_S_FRONT_SFAIL_OP_SHIFT
)
1035 | (translate_stencil_op(ctx
->Stencil
.ZFailFunc
[0]) <<
1036 R300_S_FRONT_ZFAIL_OP_SHIFT
)
1037 | (translate_stencil_op(ctx
->Stencil
.ZPassFunc
[0]) <<
1038 R300_S_FRONT_ZPASS_OP_SHIFT
);
1040 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
1041 (translate_stencil_op(ctx
->Stencil
.FailFunc
[back
]) <<
1042 R300_S_BACK_SFAIL_OP_SHIFT
)
1043 | (translate_stencil_op(ctx
->Stencil
.ZFailFunc
[back
]) <<
1044 R300_S_BACK_ZFAIL_OP_SHIFT
)
1045 | (translate_stencil_op(ctx
->Stencil
.ZPassFunc
[back
]) <<
1046 R300_S_BACK_ZPASS_OP_SHIFT
);
1049 /* =============================================================
1050 * Window position and viewport transformation
1054 * To correctly position primitives:
1056 #define SUBPIXEL_X 0.125
1057 #define SUBPIXEL_Y 0.125
1059 static void r300UpdateWindow(GLcontext
* ctx
)
1061 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1062 __DRIdrawablePrivate
*dPriv
= rmesa
->radeon
.dri
.drawable
;
1063 GLfloat xoffset
= dPriv
? (GLfloat
) dPriv
->x
: 0;
1064 GLfloat yoffset
= dPriv
? (GLfloat
) dPriv
->y
+ dPriv
->h
: 0;
1065 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1067 GLfloat sx
= v
[MAT_SX
];
1068 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1069 GLfloat sy
= -v
[MAT_SY
];
1070 GLfloat ty
= (-v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1071 GLfloat sz
= v
[MAT_SZ
] * rmesa
->state
.depth
.scale
;
1072 GLfloat tz
= v
[MAT_TZ
] * rmesa
->state
.depth
.scale
;
1074 R300_FIREVERTICES(rmesa
);
1075 R300_STATECHANGE(rmesa
, vpt
);
1077 rmesa
->hw
.vpt
.cmd
[R300_VPT_XSCALE
] = r300PackFloat32(sx
);
1078 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
1079 rmesa
->hw
.vpt
.cmd
[R300_VPT_YSCALE
] = r300PackFloat32(sy
);
1080 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
1081 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZSCALE
] = r300PackFloat32(sz
);
1082 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZOFFSET
] = r300PackFloat32(tz
);
1085 static void r300Viewport(GLcontext
* ctx
, GLint x
, GLint y
,
1086 GLsizei width
, GLsizei height
)
1088 /* Don't pipeline viewport changes, conflict with window offset
1089 * setting below. Could apply deltas to rescue pipelined viewport
1090 * values, or keep the originals hanging around.
1092 r300UpdateWindow(ctx
);
1095 static void r300DepthRange(GLcontext
* ctx
, GLclampd nearval
, GLclampd farval
)
1097 r300UpdateWindow(ctx
);
1100 void r300UpdateViewportOffset(GLcontext
* ctx
)
1102 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1103 __DRIdrawablePrivate
*dPriv
= ((radeonContextPtr
) rmesa
)->dri
.drawable
;
1104 GLfloat xoffset
= (GLfloat
) dPriv
->x
;
1105 GLfloat yoffset
= (GLfloat
) dPriv
->y
+ dPriv
->h
;
1106 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1108 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1109 GLfloat ty
= (-v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1111 if (rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] != r300PackFloat32(tx
) ||
1112 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] != r300PackFloat32(ty
)) {
1113 /* Note: this should also modify whatever data the context reset
1116 R300_STATECHANGE(rmesa
, vpt
);
1117 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
1118 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
1122 radeonUpdateScissor(ctx
);
1126 * Tell the card where to render (offset, pitch).
1127 * Effected by glDrawBuffer, etc
1129 void r300UpdateDrawBuffer(GLcontext
* ctx
)
1131 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1132 r300ContextPtr r300
= rmesa
;
1133 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
1134 driRenderbuffer
*drb
;
1136 if (fb
->_ColorDrawBufferIndexes
[0] == BUFFER_FRONT_LEFT
) {
1139 (driRenderbuffer
*) fb
->Attachment
[BUFFER_FRONT_LEFT
].
1141 } else if (fb
->_ColorDrawBufferIndexes
[0] == BUFFER_BACK_LEFT
) {
1144 (driRenderbuffer
*) fb
->Attachment
[BUFFER_BACK_LEFT
].
1147 /* drawing to multiple buffers, or none */
1152 assert(drb
->flippedPitch
);
1154 R300_STATECHANGE(rmesa
, cb
);
1156 r300
->hw
.cb
.cmd
[R300_CB_OFFSET
] = drb
->flippedOffset
+ //r300->radeon.state.color.drawOffset +
1157 r300
->radeon
.radeonScreen
->fbLocation
;
1158 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] = drb
->flippedPitch
; //r300->radeon.state.color.drawPitch;
1160 if (r300
->radeon
.radeonScreen
->cpp
== 4)
1161 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_ARGB8888
;
1163 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_RGB565
;
1165 if (r300
->radeon
.sarea
->tiling_enabled
)
1166 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_TILE_ENABLE
;
1168 R200_STATECHANGE(rmesa
, ctx
);
1170 /* Note: we used the (possibly) page-flipped values */
1171 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLOROFFSET
]
1172 = ((drb
->flippedOffset
+ rmesa
->r200Screen
->fbLocation
)
1173 & R200_COLOROFFSET_MASK
);
1174 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] = drb
->flippedPitch
;
1176 if (rmesa
->sarea
->tiling_enabled
) {
1177 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] |=
1178 R200_COLOR_TILE_ENABLE
;
1184 r300FetchStateParameter(GLcontext
* ctx
,
1185 const gl_state_index state
[STATE_LENGTH
],
1188 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1191 case STATE_INTERNAL
:
1193 case STATE_R300_WINDOW_DIMENSION
:
1194 value
[0] = r300
->radeon
.dri
.drawable
->w
* 0.5f
; /* width*0.5 */
1195 value
[1] = r300
->radeon
.dri
.drawable
->h
* 0.5f
; /* height*0.5 */
1196 value
[2] = 0.5F
; /* for moving range [-1 1] -> [0 1] */
1197 value
[3] = 1.0F
; /* not used */
1200 case STATE_R300_TEXRECT_FACTOR
:{
1201 struct gl_texture_object
*t
=
1202 ctx
->Texture
.Unit
[state
[2]].CurrentRect
;
1204 if (t
&& t
->Image
[0][t
->BaseLevel
]) {
1205 struct gl_texture_image
*image
=
1206 t
->Image
[0][t
->BaseLevel
];
1207 value
[0] = 1.0 / image
->Width2
;
1208 value
[1] = 1.0 / image
->Height2
;
1229 * Update R300's own internal state parameters.
1230 * For now just STATE_R300_WINDOW_DIMENSION
1232 void r300UpdateStateParameters(GLcontext
* ctx
, GLuint new_state
)
1234 struct r300_fragment_program
*fp
;
1235 struct gl_program_parameter_list
*paramList
;
1238 if (!(new_state
& (_NEW_BUFFERS
| _NEW_PROGRAM
)))
1241 fp
= (struct r300_fragment_program
*)ctx
->FragmentProgram
._Current
;
1245 paramList
= fp
->mesa_program
.Base
.Parameters
;
1250 for (i
= 0; i
< paramList
->NumParameters
; i
++) {
1251 if (paramList
->Parameters
[i
].Type
== PROGRAM_STATE_VAR
) {
1252 r300FetchStateParameter(ctx
,
1253 paramList
->Parameters
[i
].
1255 paramList
->ParameterValues
[i
]);
1260 /* =============================================================
1263 static void r300PolygonOffset(GLcontext
* ctx
, GLfloat factor
, GLfloat units
)
1265 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1266 GLfloat constant
= units
;
1268 switch (ctx
->Visual
.depthBits
) {
1279 /* fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */
1281 R300_STATECHANGE(rmesa
, zbs
);
1282 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_FACTOR
] = r300PackFloat32(factor
);
1283 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_CONSTANT
] = r300PackFloat32(constant
);
1284 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_FACTOR
] = r300PackFloat32(factor
);
1285 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_CONSTANT
] = r300PackFloat32(constant
);
1288 /* Routing and texture-related */
1290 /* r300 doesnt handle GL_CLAMP and GL_MIRROR_CLAMP_EXT correctly when filter is NEAREST.
1291 * Since texwrap produces same results for GL_CLAMP and GL_CLAMP_TO_EDGE we use them instead.
1292 * We need to recalculate wrap modes whenever filter mode is changed because someone might do:
1293 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1294 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1295 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1296 * Since r300 completely ignores R300_TX_CLAMP when either min or mag is nearest it cant handle
1297 * combinations where only one of them is nearest.
1299 static unsigned long gen_fixed_filter(unsigned long f
)
1301 unsigned long mag
, min
, needs_fixing
= 0;
1304 /* We ignore MIRROR bit so we dont have to do everything twice */
1305 if ((f
& ((7 - 1) << R300_TX_WRAP_S_SHIFT
)) ==
1306 (R300_TX_CLAMP
<< R300_TX_WRAP_S_SHIFT
)) {
1309 if ((f
& ((7 - 1) << R300_TX_WRAP_T_SHIFT
)) ==
1310 (R300_TX_CLAMP
<< R300_TX_WRAP_T_SHIFT
)) {
1313 if ((f
& ((7 - 1) << R300_TX_WRAP_R_SHIFT
)) ==
1314 (R300_TX_CLAMP
<< R300_TX_WRAP_R_SHIFT
)) {
1321 mag
= f
& R300_TX_MAG_FILTER_MASK
;
1322 min
= f
& (R300_TX_MIN_FILTER_MASK
|R300_TX_MIN_FILTER_MIP_MASK
);
1324 /* TODO: Check for anisto filters too */
1325 if ((mag
!= R300_TX_MAG_FILTER_NEAREST
)
1326 && (min
!= R300_TX_MIN_FILTER_NEAREST
))
1329 /* r300 cant handle these modes hence we force nearest to linear */
1330 if ((mag
== R300_TX_MAG_FILTER_NEAREST
)
1331 && (min
!= R300_TX_MIN_FILTER_NEAREST
)) {
1332 f
&= ~R300_TX_MAG_FILTER_NEAREST
;
1333 f
|= R300_TX_MAG_FILTER_LINEAR
;
1337 if ((min
== R300_TX_MIN_FILTER_NEAREST
)
1338 && (mag
!= R300_TX_MAG_FILTER_NEAREST
)) {
1339 f
&= ~R300_TX_MIN_FILTER_NEAREST
;
1340 f
|= R300_TX_MIN_FILTER_LINEAR
;
1344 /* Both are nearest */
1345 if (needs_fixing
& 1) {
1346 f
&= ~((7 - 1) << R300_TX_WRAP_S_SHIFT
);
1347 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_S_SHIFT
;
1349 if (needs_fixing
& 2) {
1350 f
&= ~((7 - 1) << R300_TX_WRAP_T_SHIFT
);
1351 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_T_SHIFT
;
1353 if (needs_fixing
& 4) {
1354 f
&= ~((7 - 1) << R300_TX_WRAP_R_SHIFT
);
1355 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_R_SHIFT
;
1360 static void r300SetupFragmentShaderTextures(GLcontext
*ctx
, int *tmu_mappings
)
1362 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1364 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
1365 (char *)ctx
->FragmentProgram
._Current
;
1366 struct r300_fragment_program_code
*code
= &fp
->code
;
1368 R300_STATECHANGE(r300
, fpt
);
1370 for (i
= 0; i
< code
->tex
.length
; i
++) {
1375 unit
= code
->tex
.inst
[i
] >> R300_TEX_ID_SHIFT
;
1378 val
= code
->tex
.inst
[i
];
1379 val
&= ~R300_TEX_ID_MASK
;
1382 (val
& R300_TEX_INST_MASK
) >> R300_TEX_INST_SHIFT
;
1383 if (opcode
== R300_TEX_OP_KIL
) {
1384 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1386 if (tmu_mappings
[unit
] >= 0) {
1388 tmu_mappings
[unit
] <<
1390 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1392 // We get here when the corresponding texture image is incomplete
1393 // (e.g. incomplete mipmaps etc.)
1394 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1399 r300
->hw
.fpt
.cmd
[R300_FPT_CMD_0
] =
1400 cmdpacket0(R300_US_TEX_INST_0
, code
->tex
.length
);
1403 static void r500SetupFragmentShaderTextures(GLcontext
*ctx
, int *tmu_mappings
)
1406 struct r500_fragment_program
*fp
= (struct r500_fragment_program
*)
1407 (char *)ctx
->FragmentProgram
._Current
;
1408 struct r500_fragment_program_code
*code
= &fp
->code
;
1410 /* find all the texture instructions and relocate the texture units */
1411 for (i
= 0; i
< code
->inst_end
+ 1; i
++) {
1412 if ((code
->inst
[i
].inst0
& 0x3) == R500_INST_TYPE_TEX
) {
1414 int unit
, opcode
, new_unit
;
1416 val
= code
->inst
[i
].inst1
;
1418 unit
= (val
>> 16) & 0xf;
1420 val
&= ~(0xf << 16);
1422 opcode
= val
& (0x7 << 22);
1423 if (opcode
== R500_TEX_INST_TEXKILL
) {
1426 if (tmu_mappings
[unit
] >= 0) {
1427 new_unit
= tmu_mappings
[unit
];
1432 val
|= R500_TEX_ID(new_unit
);
1433 code
->inst
[i
].inst1
= val
;
1438 static GLuint
translate_lod_bias(GLfloat bias
)
1440 GLint b
= (int)(bias
*32);
1443 else if (b
< -(1 << 9))
1445 return (((GLuint
)b
) << R300_LOD_BIAS_SHIFT
) & R300_LOD_BIAS_MASK
;
1448 static void r300SetupTextures(GLcontext
* ctx
)
1451 struct r300_tex_obj
*t
;
1452 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1454 int last_hw_tmu
= -1; /* -1 translates into no setup costs for fields */
1455 int tmu_mappings
[R300_MAX_TEXTURE_UNITS
] = { -1, };
1456 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
1457 (char *)ctx
->FragmentProgram
._Current
;
1459 R300_STATECHANGE(r300
, txe
);
1460 R300_STATECHANGE(r300
, tex
.filter
);
1461 R300_STATECHANGE(r300
, tex
.filter_1
);
1462 R300_STATECHANGE(r300
, tex
.size
);
1463 R300_STATECHANGE(r300
, tex
.format
);
1464 R300_STATECHANGE(r300
, tex
.pitch
);
1465 R300_STATECHANGE(r300
, tex
.offset
);
1466 R300_STATECHANGE(r300
, tex
.chroma_key
);
1467 R300_STATECHANGE(r300
, tex
.border_color
);
1469 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] = 0x0;
1471 mtu
= r300
->radeon
.glCtx
->Const
.MaxTextureUnits
;
1472 if (RADEON_DEBUG
& DEBUG_STATE
)
1473 fprintf(stderr
, "mtu=%d\n", mtu
);
1475 if (mtu
> R300_MAX_TEXTURE_UNITS
) {
1477 "Aiiee ! mtu=%d is greater than R300_MAX_TEXTURE_UNITS=%d\n",
1478 mtu
, R300_MAX_TEXTURE_UNITS
);
1482 /* We cannot let disabled tmu offsets pass DRM */
1483 for (i
= 0; i
< mtu
; i
++) {
1484 if (ctx
->Texture
.Unit
[i
]._ReallyEnabled
) {
1486 #if 0 /* Enables old behaviour */
1489 tmu_mappings
[i
] = hw_tmu
;
1491 t
= r300
->state
.texture
.unit
[i
].texobj
;
1492 /* XXX questionable fix for bug 9170: */
1496 if ((t
->format
& 0xffffff00) == 0xffffff00) {
1498 ("unknown texture format (entry %x) encountered. Help me !\n",
1502 if (RADEON_DEBUG
& DEBUG_STATE
)
1504 "Activating texture unit %d\n", i
);
1506 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] |= (1 << hw_tmu
);
1508 r300
->hw
.tex
.filter
.cmd
[R300_TEX_VALUE_0
+
1510 gen_fixed_filter(t
->filter
) | (hw_tmu
<< 28);
1511 /* Note: There is a LOD bias per texture unit and a LOD bias
1512 * per texture object. We add them here to get the correct behaviour.
1513 * (The per-texture object LOD bias was introduced in OpenGL 1.4
1514 * and is not present in the EXT_texture_object extension).
1516 r300
->hw
.tex
.filter_1
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] =
1518 translate_lod_bias(ctx
->Texture
.Unit
[i
].LodBias
+ t
->base
.tObj
->LodBias
);
1519 r300
->hw
.tex
.size
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] =
1521 r300
->hw
.tex
.format
.cmd
[R300_TEX_VALUE_0
+
1522 hw_tmu
] = t
->format
;
1523 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] =
1525 r300
->hw
.tex
.offset
.cmd
[R300_TEX_VALUE_0
+
1526 hw_tmu
] = t
->offset
;
1528 if (t
->offset
& R300_TXO_MACRO_TILE
) {
1529 WARN_ONCE("macro tiling enabled!\n");
1532 if (t
->offset
& R300_TXO_MICRO_TILE
) {
1533 WARN_ONCE("micro tiling enabled!\n");
1536 r300
->hw
.tex
.chroma_key
.cmd
[R300_TEX_VALUE_0
+
1538 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_VALUE_0
+
1542 last_hw_tmu
= hw_tmu
;
1548 r300
->hw
.tex
.filter
.cmd
[R300_TEX_CMD_0
] =
1549 cmdpacket0(R300_TX_FILTER0_0
, last_hw_tmu
+ 1);
1550 r300
->hw
.tex
.filter_1
.cmd
[R300_TEX_CMD_0
] =
1551 cmdpacket0(R300_TX_FILTER1_0
, last_hw_tmu
+ 1);
1552 r300
->hw
.tex
.size
.cmd
[R300_TEX_CMD_0
] =
1553 cmdpacket0(R300_TX_SIZE_0
, last_hw_tmu
+ 1);
1554 r300
->hw
.tex
.format
.cmd
[R300_TEX_CMD_0
] =
1555 cmdpacket0(R300_TX_FORMAT_0
, last_hw_tmu
+ 1);
1556 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_CMD_0
] =
1557 cmdpacket0(R300_TX_FORMAT2_0
, last_hw_tmu
+ 1);
1558 r300
->hw
.tex
.offset
.cmd
[R300_TEX_CMD_0
] =
1559 cmdpacket0(R300_TX_OFFSET_0
, last_hw_tmu
+ 1);
1560 r300
->hw
.tex
.chroma_key
.cmd
[R300_TEX_CMD_0
] =
1561 cmdpacket0(R300_TX_CHROMA_KEY_0
, last_hw_tmu
+ 1);
1562 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_CMD_0
] =
1563 cmdpacket0(R300_TX_BORDER_COLOR_0
, last_hw_tmu
+ 1);
1565 if (!fp
) /* should only happenen once, just after context is created */
1568 if (r300
->radeon
.radeonScreen
->chip_family
< CHIP_FAMILY_RV515
) {
1569 if (fp
->mesa_program
.UsesKill
&& last_hw_tmu
< 0) {
1570 // The KILL operation requires the first texture unit
1572 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] |= 1;
1573 r300
->hw
.tex
.filter
.cmd
[R300_TEX_VALUE_0
] = 0;
1574 r300
->hw
.tex
.filter
.cmd
[R300_TEX_CMD_0
] =
1575 cmdpacket0(R300_TX_FILTER0_0
, 1);
1577 r300SetupFragmentShaderTextures(ctx
, tmu_mappings
);
1579 r500SetupFragmentShaderTextures(ctx
, tmu_mappings
);
1581 if (RADEON_DEBUG
& DEBUG_STATE
)
1582 fprintf(stderr
, "TX_ENABLE: %08x last_hw_tmu=%d\n",
1583 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
], last_hw_tmu
);
1586 union r300_outputs_written
{
1587 GLuint vp_outputs
; /* hw_tcl_on */
1588 DECLARE_RENDERINPUTS(index_bitset
); /* !hw_tcl_on */
1591 #define R300_OUTPUTS_WRITTEN_TEST(ow, vp_result, tnl_attrib) \
1592 ((hw_tcl_on) ? (ow).vp_outputs & (1 << (vp_result)) : \
1593 RENDERINPUTS_TEST( (ow.index_bitset), (tnl_attrib) ))
1595 static void r300SetupRSUnit(GLcontext
* ctx
)
1597 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1598 /* I'm still unsure if these are needed */
1599 GLuint interp_col
[8];
1600 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1601 struct vertex_buffer
*VB
= &tnl
->vb
;
1602 union r300_outputs_written OutputsWritten
;
1604 int fp_reg
, high_rr
;
1606 int rs_tex_count
= 0, rs_col_count
= 0;
1609 memset(interp_col
, 0, sizeof(interp_col
));
1612 OutputsWritten
.vp_outputs
= CURRENT_VERTEX_SHADER(ctx
)->key
.OutputsWritten
;
1614 RENDERINPUTS_COPY(OutputsWritten
.index_bitset
, r300
->state
.render_inputs_bitset
);
1616 if (ctx
->FragmentProgram
._Current
)
1617 InputsRead
= ctx
->FragmentProgram
._Current
->Base
.InputsRead
;
1619 fprintf(stderr
, "No ctx->FragmentProgram._Current!!\n");
1620 return; /* This should only ever happen once.. */
1623 R300_STATECHANGE(r300
, ri
);
1624 R300_STATECHANGE(r300
, rc
);
1625 R300_STATECHANGE(r300
, rr
);
1627 fp_reg
= col_interp_nr
= high_rr
= 0;
1629 r300
->hw
.rr
.cmd
[R300_RR_INST_1
] = 0;
1631 if (InputsRead
& FRAG_BIT_WPOS
) {
1632 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++)
1633 if (!(InputsRead
& (FRAG_BIT_TEX0
<< i
)))
1636 if (i
== ctx
->Const
.MaxTextureUnits
) {
1637 fprintf(stderr
, "\tno free texcoord found...\n");
1641 InputsRead
|= (FRAG_BIT_TEX0
<< i
);
1642 InputsRead
&= ~FRAG_BIT_WPOS
;
1645 if (InputsRead
& FRAG_BIT_COL0
) {
1646 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR0
]->size
;
1647 interp_col
[0] |= R300_RS_COL_PTR(rs_col_count
);
1649 interp_col
[0] |= R300_RS_COL_FMT(R300_RS_COL_FMT_RGB1
);
1650 rs_col_count
+= count
;
1653 interp_col
[0] = R300_RS_COL_FMT(R300_RS_COL_FMT_0001
);
1655 if (InputsRead
& FRAG_BIT_COL1
) {
1656 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR1
]->size
;
1658 interp_col
[1] |= R300_RS_COL_FMT(R300_RS_COL_FMT_RGB0
);
1659 interp_col
[1] |= R300_RS_COL_PTR(1);
1660 rs_col_count
+= count
;
1663 if (InputsRead
& FRAG_BIT_FOGC
) {
1665 * Just turn off the bit for now.
1666 * Need to do something similar to the color/texcoord inputs.
1668 InputsRead
&= ~FRAG_BIT_FOGC
;
1671 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
1674 /* with TCL we always seem to route 4 components */
1678 count
= VB
->AttribPtr
[_TNL_ATTRIB_TEX(i
)]->size
;
1680 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ i
] = interp_col
[i
] | rs_tex_count
;
1682 case 4: swiz
= R300_RS_SEL_S(0) | R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(3); break;
1683 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;
1686 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;
1689 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ i
] |= swiz
;
1691 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ fp_reg
] = 0;
1692 if (InputsRead
& (FRAG_BIT_TEX0
<< i
)) {
1694 rs_tex_count
+= count
;
1696 //assert(r300->state.texture.tc_count != 0);
1697 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ fp_reg
] |= R300_RS_INST_TEX_CN_WRITE
| i
/* source INTERP */
1698 | (fp_reg
<< R300_RS_INST_TEX_ADDR_SHIFT
);
1701 /* Passing invalid data here can lock the GPU. */
1702 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_TEX0
+ i
, _TNL_ATTRIB_TEX(i
))) {
1703 InputsRead
&= ~(FRAG_BIT_TEX0
<< i
);
1706 WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i
);
1711 if (InputsRead
& FRAG_BIT_COL0
) {
1712 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL0
, _TNL_ATTRIB_COLOR0
)) {
1713 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
);
1714 InputsRead
&= ~FRAG_BIT_COL0
;
1717 WARN_ONCE("fragprog wants col0, vp doesn't provide it\n");
1721 if (InputsRead
& FRAG_BIT_COL1
) {
1722 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL1
, _TNL_ATTRIB_COLOR1
)) {
1723 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
);
1724 InputsRead
&= ~FRAG_BIT_COL1
;
1729 WARN_ONCE("fragprog wants col1, vp doesn't provide it\n");
1733 /* Need at least one. This might still lock as the values are undefined... */
1734 if (rs_tex_count
== 0 && col_interp_nr
== 0) {
1735 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
);
1739 r300
->hw
.rc
.cmd
[1] = 0 | (rs_tex_count
<< R300_IT_COUNT_SHIFT
)
1740 | (col_interp_nr
<< R300_IC_COUNT_SHIFT
)
1743 assert(high_rr
>= 0);
1744 r300
->hw
.rr
.cmd
[R300_RR_CMD_0
] = cmdpacket0(R300_RS_INST_0
, high_rr
+ 1);
1745 r300
->hw
.rc
.cmd
[2] = high_rr
;
1748 WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead
);
1751 static void r500SetupRSUnit(GLcontext
* ctx
)
1753 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1754 /* I'm still unsure if these are needed */
1755 GLuint interp_col
[8];
1756 union r300_outputs_written OutputsWritten
;
1757 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1758 struct vertex_buffer
*VB
= &tnl
->vb
;
1760 int fp_reg
, high_rr
;
1761 int rs_col_count
= 0;
1762 int in_texcoords
, col_interp_nr
;
1765 memset(interp_col
, 0, sizeof(interp_col
));
1767 OutputsWritten
.vp_outputs
= CURRENT_VERTEX_SHADER(ctx
)->key
.OutputsWritten
;
1769 RENDERINPUTS_COPY(OutputsWritten
.index_bitset
, r300
->state
.render_inputs_bitset
);
1771 if (ctx
->FragmentProgram
._Current
)
1772 InputsRead
= ctx
->FragmentProgram
._Current
->Base
.InputsRead
;
1774 fprintf(stderr
, "No ctx->FragmentProgram._Current!!\n");
1775 return; /* This should only ever happen once.. */
1778 R300_STATECHANGE(r300
, ri
);
1779 R300_STATECHANGE(r300
, rc
);
1780 R300_STATECHANGE(r300
, rr
);
1782 fp_reg
= col_interp_nr
= high_rr
= in_texcoords
= 0;
1784 r300
->hw
.rr
.cmd
[R300_RR_INST_1
] = 0;
1786 if (InputsRead
& FRAG_BIT_WPOS
) {
1787 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++)
1788 if (!(InputsRead
& (FRAG_BIT_TEX0
<< i
)))
1791 if (i
== ctx
->Const
.MaxTextureUnits
) {
1792 fprintf(stderr
, "\tno free texcoord found...\n");
1796 InputsRead
|= (FRAG_BIT_TEX0
<< i
);
1797 InputsRead
&= ~FRAG_BIT_WPOS
;
1800 if (InputsRead
& FRAG_BIT_COL0
) {
1801 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR0
]->size
;
1802 interp_col
[0] |= R500_RS_COL_PTR(rs_col_count
);
1804 interp_col
[0] |= R500_RS_COL_FMT(R300_RS_COL_FMT_RGB1
);
1805 rs_col_count
+= count
;
1808 interp_col
[0] = R500_RS_COL_FMT(R300_RS_COL_FMT_0001
);
1810 if (InputsRead
& FRAG_BIT_COL1
) {
1811 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR1
]->size
;
1812 interp_col
[1] |= R500_RS_COL_PTR(1);
1814 interp_col
[1] |= R500_RS_COL_FMT(R300_RS_COL_FMT_RGB0
);
1815 rs_col_count
+= count
;
1818 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
1821 /* with TCL we always seem to route 4 components */
1822 if (InputsRead
& (FRAG_BIT_TEX0
<< i
)) {
1827 count
= VB
->AttribPtr
[_TNL_ATTRIB_TEX(i
)]->size
;
1829 /* always have on texcoord */
1830 swiz
|= in_texcoords
++ << R500_RS_IP_TEX_PTR_S_SHIFT
;
1832 swiz
|= in_texcoords
++ << R500_RS_IP_TEX_PTR_T_SHIFT
;
1834 swiz
|= R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_T_SHIFT
;
1837 swiz
|= in_texcoords
++ << R500_RS_IP_TEX_PTR_R_SHIFT
;
1839 swiz
|= R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_R_SHIFT
;
1842 swiz
|= in_texcoords
++ << R500_RS_IP_TEX_PTR_Q_SHIFT
;
1844 swiz
|= R500_RS_IP_PTR_K1
<< R500_RS_IP_TEX_PTR_Q_SHIFT
;
1847 swiz
= (R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_S_SHIFT
) |
1848 (R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_T_SHIFT
) |
1849 (R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_R_SHIFT
) |
1850 (R500_RS_IP_PTR_K1
<< R500_RS_IP_TEX_PTR_Q_SHIFT
);
1852 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ i
] = interp_col
[i
] | swiz
;
1854 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ fp_reg
] = 0;
1855 if (InputsRead
& (FRAG_BIT_TEX0
<< i
)) {
1856 //assert(r300->state.texture.tc_count != 0);
1857 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ fp_reg
] |= R500_RS_INST_TEX_CN_WRITE
| i
/* source INTERP */
1858 | (fp_reg
<< R500_RS_INST_TEX_ADDR_SHIFT
);
1861 /* Passing invalid data here can lock the GPU. */
1862 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_TEX0
+ i
, _TNL_ATTRIB_TEX(i
))) {
1863 InputsRead
&= ~(FRAG_BIT_TEX0
<< i
);
1866 WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i
);
1871 if (InputsRead
& FRAG_BIT_COL0
) {
1872 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL0
, _TNL_ATTRIB_COLOR0
)) {
1873 r300
->hw
.rr
.cmd
[R300_RR_INST_0
] |= R500_RS_INST_COL_CN_WRITE
| (fp_reg
++ << R500_RS_INST_COL_ADDR_SHIFT
);
1874 InputsRead
&= ~FRAG_BIT_COL0
;
1877 WARN_ONCE("fragprog wants col0, vp doesn't provide it\n");
1881 if (InputsRead
& FRAG_BIT_COL1
) {
1882 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL1
, _TNL_ATTRIB_COLOR1
)) {
1883 r300
->hw
.rr
.cmd
[R300_RR_INST_1
] |= (1 << 12) | R500_RS_INST_COL_CN_WRITE
| (fp_reg
++ << R500_RS_INST_COL_ADDR_SHIFT
);
1884 InputsRead
&= ~FRAG_BIT_COL1
;
1889 WARN_ONCE("fragprog wants col1, vp doesn't provide it\n");
1893 /* Need at least one. This might still lock as the values are undefined... */
1894 if (in_texcoords
== 0 && col_interp_nr
== 0) {
1895 r300
->hw
.rr
.cmd
[R300_RR_INST_0
] |= 0 | R500_RS_INST_COL_CN_WRITE
| (fp_reg
++ << R500_RS_INST_COL_ADDR_SHIFT
);
1899 r300
->hw
.rc
.cmd
[1] = 0 | (in_texcoords
<< R300_IT_COUNT_SHIFT
)
1900 | (col_interp_nr
<< R300_IC_COUNT_SHIFT
)
1903 assert(high_rr
>= 0);
1904 r300
->hw
.rr
.cmd
[R300_RR_CMD_0
] = cmdpacket0(R500_RS_INST_0
, high_rr
+ 1);
1905 r300
->hw
.rc
.cmd
[2] = 0xC0 | high_rr
;
1908 WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead
);
1914 #define bump_vpu_count(ptr, new_count) do{\
1915 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
1916 int _nc=(new_count)/4; \
1917 assert(_nc < 256); \
1918 if(_nc>_p->vpu.count)_p->vpu.count=_nc;\
1921 static INLINE
void r300SetupVertexProgramFragment(r300ContextPtr r300
, int dest
, struct r300_vertex_shader_fragment
*vsf
)
1925 if (vsf
->length
== 0)
1928 if (vsf
->length
& 0x3) {
1929 fprintf(stderr
, "VERTEX_SHADER_FRAGMENT must have length divisible by 4\n");
1933 switch ((dest
>> 8) & 0xf) {
1935 R300_STATECHANGE(r300
, vpi
);
1936 for (i
= 0; i
< vsf
->length
; i
++)
1937 r300
->hw
.vpi
.cmd
[R300_VPI_INSTR_0
+ i
+ 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1938 bump_vpu_count(r300
->hw
.vpi
.cmd
, vsf
->length
+ 4 * (dest
& 0xff));
1942 R300_STATECHANGE(r300
, vpp
);
1943 for (i
= 0; i
< vsf
->length
; i
++)
1944 r300
->hw
.vpp
.cmd
[R300_VPP_PARAM_0
+ i
+ 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1945 bump_vpu_count(r300
->hw
.vpp
.cmd
, vsf
->length
+ 4 * (dest
& 0xff));
1948 R300_STATECHANGE(r300
, vps
);
1949 for (i
= 0; i
< vsf
->length
; i
++)
1950 r300
->hw
.vps
.cmd
[1 + i
+ 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1951 bump_vpu_count(r300
->hw
.vps
.cmd
, vsf
->length
+ 4 * (dest
& 0xff));
1954 fprintf(stderr
, "%s:%s don't know how to handle dest %04x\n", __FILE__
, __FUNCTION__
, dest
);
1959 #define MIN3(a, b, c) ((a) < (b) ? MIN2(a, c) : MIN2(b, c))
1962 static void r300VapCntl(r300ContextPtr rmesa
, GLuint input_count
,
1963 GLuint output_count
, GLuint temp_count
)
1969 /* Flush PVS engine before changing PVS_NUM_SLOTS, PVS_NUM_CNTRLS.
1970 * See r500 docs 6.5.2 - done in emit */
1972 /* avoid division by zero */
1973 if (input_count
== 0) input_count
= 1;
1974 if (output_count
== 0) output_count
= 1;
1975 if (temp_count
== 0) temp_count
= 1;
1977 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
1982 pvs_num_slots
= MIN3(10, vtx_mem_size
/input_count
, vtx_mem_size
/output_count
);
1983 pvs_num_cntrls
= MIN2(6, vtx_mem_size
/temp_count
);
1985 R300_STATECHANGE(rmesa
, vap_cntl
);
1986 if (rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
) {
1987 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] =
1988 (pvs_num_slots
<< R300_PVS_NUM_SLOTS_SHIFT
) |
1989 (pvs_num_cntrls
<< R300_PVS_NUM_CNTLRS_SHIFT
) |
1990 (12 << R300_VF_MAX_VTX_NUM_SHIFT
);
1991 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
1992 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= R500_TCL_STATE_OPTIMIZATION
;
1994 /* not sure about non-tcl */
1995 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] = ((10 << R300_PVS_NUM_SLOTS_SHIFT
) |
1996 (5 << R300_PVS_NUM_CNTLRS_SHIFT
) |
1997 (5 << 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
] |= (2 << R300_PVS_NUM_FPUS_SHIFT
);
2001 else if ((rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV530
) ||
2002 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV560
) ||
2003 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV570
))
2004 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (5 << R300_PVS_NUM_FPUS_SHIFT
);
2005 else if ((rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV410
) ||
2006 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R420
))
2007 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (6 << R300_PVS_NUM_FPUS_SHIFT
);
2008 else if ((rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R520
) ||
2009 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R580
))
2010 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (8 << R300_PVS_NUM_FPUS_SHIFT
);
2012 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (4 << R300_PVS_NUM_FPUS_SHIFT
);
2016 static void r300SetupDefaultVertexProgram(r300ContextPtr rmesa
)
2018 struct r300_vertex_shader_state
*prog
= &(rmesa
->state
.vertex_shader
);
2023 int param_count
= 0;
2024 int program_end
= 0;
2026 for (i
= VERT_ATTRIB_POS
; i
< VERT_ATTRIB_MAX
; i
++) {
2027 if (rmesa
->state
.sw_tcl_inputs
[i
] != -1) {
2028 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
);
2029 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
);
2030 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
);
2031 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
);
2037 prog
->program
.length
= program_end
;
2039 r300SetupVertexProgramFragment(rmesa
, R300_PVS_CODE_START
,
2041 inst_count
= (prog
->program
.length
/ 4) - 1;
2043 r300VapCntl(rmesa
, i_reg
, o_reg
, 0);
2045 R300_STATECHANGE(rmesa
, pvs
);
2046 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] =
2047 (0 << R300_PVS_FIRST_INST_SHIFT
) |
2048 (inst_count
<< R300_PVS_XYZW_VALID_INST_SHIFT
) |
2049 (inst_count
<< R300_PVS_LAST_INST_SHIFT
);
2050 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] =
2051 (0 << R300_PVS_CONST_BASE_OFFSET_SHIFT
) |
2052 (param_count
<< R300_PVS_MAX_CONST_ADDR_SHIFT
);
2053 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] =
2054 (inst_count
<< R300_PVS_LAST_VTX_SRC_INST_SHIFT
);
2057 static int bit_count (int x
)
2059 x
= ((x
& 0xaaaaaaaaU
) >> 1) + (x
& 0x55555555U
);
2060 x
= ((x
& 0xccccccccU
) >> 2) + (x
& 0x33333333U
);
2061 x
= (x
>> 16) + (x
& 0xffff);
2062 x
= ((x
& 0xf0f0) >> 4) + (x
& 0x0f0f);
2063 return (x
>> 8) + (x
& 0x00ff);
2066 static void r300SetupRealVertexProgram(r300ContextPtr rmesa
)
2068 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
2069 struct r300_vertex_program
*prog
= (struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
);
2071 int param_count
= 0;
2073 /* FIXME: r300SetupVertexProgramFragment */
2074 R300_STATECHANGE(rmesa
, vpp
);
2076 r300VertexProgUpdateParams(ctx
,
2077 (struct r300_vertex_program_cont
*)
2078 ctx
->VertexProgram
._Current
,
2079 (float *)&rmesa
->hw
.vpp
.
2080 cmd
[R300_VPP_PARAM_0
]);
2081 bump_vpu_count(rmesa
->hw
.vpp
.cmd
, param_count
);
2084 r300SetupVertexProgramFragment(rmesa
, R300_PVS_CODE_START
, &(prog
->program
));
2085 inst_count
= (prog
->program
.length
/ 4) - 1;
2087 r300VapCntl(rmesa
, bit_count(prog
->key
.InputsRead
),
2088 bit_count(prog
->key
.OutputsWritten
), prog
->num_temporaries
);
2090 R300_STATECHANGE(rmesa
, pvs
);
2091 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] =
2092 (0 << R300_PVS_FIRST_INST_SHIFT
) |
2093 (inst_count
<< R300_PVS_XYZW_VALID_INST_SHIFT
) |
2094 (inst_count
<< R300_PVS_LAST_INST_SHIFT
);
2095 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] =
2096 (0 << R300_PVS_CONST_BASE_OFFSET_SHIFT
) |
2097 (param_count
<< R300_PVS_MAX_CONST_ADDR_SHIFT
);
2098 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] =
2099 (inst_count
<< R300_PVS_LAST_VTX_SRC_INST_SHIFT
);
2102 static void r300SetupVertexProgram(r300ContextPtr rmesa
)
2104 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
2106 /* Reset state, in case we don't use something */
2107 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vpp
.cmd
)->vpu
.count
= 0;
2108 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vpi
.cmd
)->vpu
.count
= 0;
2109 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vps
.cmd
)->vpu
.count
= 0;
2111 /* Not sure why this doesnt work...
2112 0x400 area might have something to do with pixel shaders as it appears right after pfs programming.
2113 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. */
2114 //setup_vertex_shader_fragment(rmesa, 0x406, &unk4);
2115 if (hw_tcl_on
&& ((struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
))->translated
) {
2116 r300SetupRealVertexProgram(rmesa
);
2118 /* FIXME: This needs to be replaced by vertex shader generation code. */
2119 r300SetupDefaultVertexProgram(rmesa
);
2125 * Enable/Disable states.
2127 * \note Mesa already filters redundant calls to this function.
2129 static void r300Enable(GLcontext
* ctx
, GLenum cap
, GLboolean state
)
2131 if (RADEON_DEBUG
& DEBUG_STATE
)
2132 fprintf(stderr
, "%s( %s = %s )\n", __FUNCTION__
,
2133 _mesa_lookup_enum_by_nr(cap
),
2134 state
? "GL_TRUE" : "GL_FALSE");
2143 r300SetFogState(ctx
, state
);
2146 r300SetAlphaState(ctx
);
2148 case GL_COLOR_LOGIC_OP
:
2149 r300SetLogicOpState(ctx
);
2150 /* fall-through, because logic op overrides blending */
2152 r300SetBlendState(ctx
);
2154 case GL_CLIP_PLANE0
:
2155 case GL_CLIP_PLANE1
:
2156 case GL_CLIP_PLANE2
:
2157 case GL_CLIP_PLANE3
:
2158 case GL_CLIP_PLANE4
:
2159 case GL_CLIP_PLANE5
:
2160 r300SetClipPlaneState(ctx
, cap
, state
);
2163 r300SetDepthState(ctx
);
2165 case GL_STENCIL_TEST
:
2166 r300SetStencilState(ctx
, state
);
2169 r300UpdateCulling(ctx
);
2171 case GL_POLYGON_OFFSET_POINT
:
2172 case GL_POLYGON_OFFSET_LINE
:
2173 case GL_POLYGON_OFFSET_FILL
:
2174 r300SetPolygonOffsetState(ctx
, state
);
2177 radeonEnable(ctx
, cap
, state
);
2183 * Completely recalculates hardware state based on the Mesa state.
2185 static void r300ResetHwState(r300ContextPtr r300
)
2187 GLcontext
*ctx
= r300
->radeon
.glCtx
;
2190 if (!(r300
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
2193 if (RADEON_DEBUG
& DEBUG_STATE
)
2194 fprintf(stderr
, "%s\n", __FUNCTION__
);
2196 r300UpdateWindow(ctx
);
2199 ctx
->Color
.ColorMask
[RCOMP
],
2200 ctx
->Color
.ColorMask
[GCOMP
],
2201 ctx
->Color
.ColorMask
[BCOMP
], ctx
->Color
.ColorMask
[ACOMP
]);
2203 r300Enable(ctx
, GL_DEPTH_TEST
, ctx
->Depth
.Test
);
2204 r300DepthMask(ctx
, ctx
->Depth
.Mask
);
2205 r300DepthFunc(ctx
, ctx
->Depth
.Func
);
2208 r300Enable(ctx
, GL_STENCIL_TEST
, ctx
->Stencil
.Enabled
);
2209 r300StencilMaskSeparate(ctx
, 0, ctx
->Stencil
.WriteMask
[0]);
2210 r300StencilFuncSeparate(ctx
, 0, ctx
->Stencil
.Function
[0],
2211 ctx
->Stencil
.Ref
[0], ctx
->Stencil
.ValueMask
[0]);
2212 r300StencilOpSeparate(ctx
, 0, ctx
->Stencil
.FailFunc
[0],
2213 ctx
->Stencil
.ZFailFunc
[0],
2214 ctx
->Stencil
.ZPassFunc
[0]);
2216 r300UpdateCulling(ctx
);
2218 r300UpdateTextureState(ctx
);
2220 r300SetBlendState(ctx
);
2221 r300SetLogicOpState(ctx
);
2223 r300AlphaFunc(ctx
, ctx
->Color
.AlphaFunc
, ctx
->Color
.AlphaRef
);
2224 r300Enable(ctx
, GL_ALPHA_TEST
, ctx
->Color
.AlphaEnabled
);
2226 r300
->hw
.vte
.cmd
[1] = R300_VPORT_X_SCALE_ENA
2227 | R300_VPORT_X_OFFSET_ENA
2228 | R300_VPORT_Y_SCALE_ENA
2229 | R300_VPORT_Y_OFFSET_ENA
2230 | R300_VPORT_Z_SCALE_ENA
2231 | R300_VPORT_Z_OFFSET_ENA
| R300_VTX_W0_FMT
;
2232 r300
->hw
.vte
.cmd
[2] = 0x00000008;
2234 r300
->hw
.vap_vf_max_vtx_indx
.cmd
[1] = 0x00FFFFFF;
2235 r300
->hw
.vap_vf_max_vtx_indx
.cmd
[2] = 0x00000000;
2237 #ifdef MESA_LITTLE_ENDIAN
2238 r300
->hw
.vap_cntl_status
.cmd
[1] = R300_VC_NO_SWAP
;
2240 r300
->hw
.vap_cntl_status
.cmd
[1] = R300_VC_32BIT_SWAP
;
2243 /* disable VAP/TCL on non-TCL capable chips */
2245 r300
->hw
.vap_cntl_status
.cmd
[1] |= R300_VAP_TCL_BYPASS
;
2247 r300
->hw
.vap_psc_sgn_norm_cntl
.cmd
[1] = 0xAAAAAAAA;
2249 /* XXX: Other families? */
2251 r300
->hw
.vap_clip_cntl
.cmd
[1] = R300_PS_UCP_MODE_DIST_COP
;
2253 r300
->hw
.vap_clip
.cmd
[1] = r300PackFloat32(1.0); /* X */
2254 r300
->hw
.vap_clip
.cmd
[2] = r300PackFloat32(1.0); /* X */
2255 r300
->hw
.vap_clip
.cmd
[3] = r300PackFloat32(1.0); /* Y */
2256 r300
->hw
.vap_clip
.cmd
[4] = r300PackFloat32(1.0); /* Y */
2258 switch (r300
->radeon
.radeonScreen
->chip_family
) {
2259 case CHIP_FAMILY_R300
:
2260 r300
->hw
.vap_pvs_vtx_timeout_reg
.cmd
[1] = R300_2288_R300
;
2263 r300
->hw
.vap_pvs_vtx_timeout_reg
.cmd
[1] = R300_2288_RV350
;
2268 r300
->hw
.gb_enable
.cmd
[1] = R300_GB_POINT_STUFF_ENABLE
2269 | R300_GB_LINE_STUFF_ENABLE
2270 | R300_GB_TRIANGLE_STUFF_ENABLE
;
2272 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_0
] = 0x66666666;
2273 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_1
] = 0x06666666;
2275 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] =
2276 R300_GB_TILE_ENABLE
| R300_GB_TILE_SIZE_16
/*| R300_GB_SUBPIXEL_1_16*/;
2277 switch (r300
->radeon
.radeonScreen
->num_gb_pipes
) {
2280 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2281 R300_GB_TILE_PIPE_COUNT_RV300
;
2284 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2285 R300_GB_TILE_PIPE_COUNT_R300
;
2288 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2289 R300_GB_TILE_PIPE_COUNT_R420_3P
;
2292 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2293 R300_GB_TILE_PIPE_COUNT_R420
;
2297 /* XXX: set to 0 when fog is disabled? */
2298 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_SELECT
] = R300_GB_FOG_SELECT_1_1_W
;
2300 /* XXX: Enable anti-aliasing? */
2301 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_AA_CONFIG
] = GB_AA_CONFIG_AA_DISABLE
;
2303 r300
->hw
.ga_point_s0
.cmd
[1] = r300PackFloat32(0.0);
2304 r300
->hw
.ga_point_s0
.cmd
[2] = r300PackFloat32(0.0);
2305 r300
->hw
.ga_point_s0
.cmd
[3] = r300PackFloat32(1.0);
2306 r300
->hw
.ga_point_s0
.cmd
[4] = r300PackFloat32(1.0);
2308 r300
->hw
.ga_triangle_stipple
.cmd
[1] = 0x00050005;
2310 r300PointSize(ctx
, 1.0);
2312 r300
->hw
.ga_point_minmax
.cmd
[1] = 0x18000006;
2313 r300
->hw
.ga_point_minmax
.cmd
[2] = 0x00020006;
2314 r300
->hw
.ga_point_minmax
.cmd
[3] = r300PackFloat32(1.0 / 192.0);
2316 r300LineWidth(ctx
, 1.0);
2318 r300
->hw
.ga_line_stipple
.cmd
[1] = 0;
2319 r300
->hw
.ga_line_stipple
.cmd
[2] = r300PackFloat32(0.0);
2320 r300
->hw
.ga_line_stipple
.cmd
[3] = r300PackFloat32(1.0);
2322 r300ShadeModel(ctx
, ctx
->Light
.ShadeModel
);
2324 r300PolygonMode(ctx
, GL_FRONT
, ctx
->Polygon
.FrontMode
);
2325 r300PolygonMode(ctx
, GL_BACK
, ctx
->Polygon
.BackMode
);
2326 r300
->hw
.zbias_cntl
.cmd
[1] = 0x00000000;
2328 r300PolygonOffset(ctx
, ctx
->Polygon
.OffsetFactor
,
2329 ctx
->Polygon
.OffsetUnits
);
2330 r300Enable(ctx
, GL_POLYGON_OFFSET_POINT
, ctx
->Polygon
.OffsetPoint
);
2331 r300Enable(ctx
, GL_POLYGON_OFFSET_LINE
, ctx
->Polygon
.OffsetLine
);
2332 r300Enable(ctx
, GL_POLYGON_OFFSET_FILL
, ctx
->Polygon
.OffsetFill
);
2334 r300
->hw
.su_depth_scale
.cmd
[1] = 0x4B7FFFFF;
2335 r300
->hw
.su_depth_scale
.cmd
[2] = 0x00000000;
2337 r300
->hw
.sc_hyperz
.cmd
[1] = 0x0000001C;
2338 r300
->hw
.sc_hyperz
.cmd
[2] = 0x2DA49525;
2340 r300
->hw
.sc_screendoor
.cmd
[1] = 0x00FFFFFF;
2342 r300
->hw
.us_out_fmt
.cmd
[1] = R500_OUT_FMT_C4_8
|
2343 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2344 r300
->hw
.us_out_fmt
.cmd
[2] = R500_OUT_FMT_UNUSED
|
2345 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2346 r300
->hw
.us_out_fmt
.cmd
[3] = R500_OUT_FMT_UNUSED
|
2347 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2348 r300
->hw
.us_out_fmt
.cmd
[4] = R500_OUT_FMT_UNUSED
|
2349 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2350 r300
->hw
.us_out_fmt
.cmd
[5] = R300_W_FMT_W24
;
2352 r300Enable(ctx
, GL_FOG
, ctx
->Fog
.Enabled
);
2353 r300Fogfv(ctx
, GL_FOG_MODE
, NULL
);
2354 r300Fogfv(ctx
, GL_FOG_DENSITY
, &ctx
->Fog
.Density
);
2355 r300Fogfv(ctx
, GL_FOG_START
, &ctx
->Fog
.Start
);
2356 r300Fogfv(ctx
, GL_FOG_END
, &ctx
->Fog
.End
);
2357 r300Fogfv(ctx
, GL_FOG_COLOR
, ctx
->Fog
.Color
);
2358 r300Fogfv(ctx
, GL_FOG_COORDINATE_SOURCE_EXT
, NULL
);
2360 r300
->hw
.fg_depth_src
.cmd
[1] = 0;
2362 r300
->hw
.rb3d_cctl
.cmd
[1] = 0;
2364 r300BlendColor(ctx
, ctx
->Color
.BlendColor
);
2366 /* Again, r300ClearBuffer uses this */
2367 r300
->hw
.cb
.cmd
[R300_CB_OFFSET
] =
2368 r300
->radeon
.state
.color
.drawOffset
+
2369 r300
->radeon
.radeonScreen
->fbLocation
;
2370 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] = r300
->radeon
.state
.color
.drawPitch
;
2372 if (r300
->radeon
.radeonScreen
->cpp
== 4)
2373 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_ARGB8888
;
2375 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_RGB565
;
2377 if (r300
->radeon
.sarea
->tiling_enabled
)
2378 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_TILE_ENABLE
;
2380 r300
->hw
.rb3d_dither_ctl
.cmd
[1] = 0;
2381 r300
->hw
.rb3d_dither_ctl
.cmd
[2] = 0;
2382 r300
->hw
.rb3d_dither_ctl
.cmd
[3] = 0;
2383 r300
->hw
.rb3d_dither_ctl
.cmd
[4] = 0;
2384 r300
->hw
.rb3d_dither_ctl
.cmd
[5] = 0;
2385 r300
->hw
.rb3d_dither_ctl
.cmd
[6] = 0;
2386 r300
->hw
.rb3d_dither_ctl
.cmd
[7] = 0;
2387 r300
->hw
.rb3d_dither_ctl
.cmd
[8] = 0;
2388 r300
->hw
.rb3d_dither_ctl
.cmd
[9] = 0;
2390 r300
->hw
.rb3d_aaresolve_ctl
.cmd
[1] = 0;
2392 r300
->hw
.rb3d_discard_src_pixel_lte_threshold
.cmd
[1] = 0x00000000;
2393 r300
->hw
.rb3d_discard_src_pixel_lte_threshold
.cmd
[2] = 0xffffffff;
2395 r300
->hw
.zb
.cmd
[R300_ZB_OFFSET
] =
2396 r300
->radeon
.radeonScreen
->depthOffset
+
2397 r300
->radeon
.radeonScreen
->fbLocation
;
2398 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] = r300
->radeon
.radeonScreen
->depthPitch
;
2400 if (r300
->radeon
.sarea
->tiling_enabled
) {
2401 /* XXX: Turn off when clearing buffers ? */
2402 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] |= R300_DEPTHMACROTILE_ENABLE
;
2404 if (ctx
->Visual
.depthBits
== 24)
2405 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] |=
2406 R300_DEPTHMICROTILE_TILED
;
2409 r300
->hw
.zb_depthclearvalue
.cmd
[1] = 0;
2411 switch (ctx
->Visual
.depthBits
) {
2413 r300
->hw
.zstencil_format
.cmd
[1] = R300_DEPTHFORMAT_16BIT_INT_Z
;
2416 r300
->hw
.zstencil_format
.cmd
[1] = R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL
;
2419 fprintf(stderr
, "Error: Unsupported depth %d... exiting\n", ctx
->Visual
.depthBits
);
2423 r300
->hw
.zstencil_format
.cmd
[2] = R300_ZTOP_DISABLE
;
2424 r300
->hw
.zstencil_format
.cmd
[3] = 0x00000003;
2425 r300
->hw
.zstencil_format
.cmd
[4] = 0x00000000;
2426 r300SetEarlyZState(ctx
);
2428 r300
->hw
.unk4F30
.cmd
[1] = 0;
2429 r300
->hw
.unk4F30
.cmd
[2] = 0;
2431 r300
->hw
.zb_hiz_offset
.cmd
[1] = 0;
2433 r300
->hw
.zb_hiz_pitch
.cmd
[1] = 0;
2435 r300VapCntl(r300
, 0, 0, 0);
2437 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_0
] = 0;
2438 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_1
] = 0;
2439 r300
->hw
.vps
.cmd
[R300_VPS_POINTSIZE
] = r300PackFloat32(1.0);
2440 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_3
] = 0;
2443 r300
->hw
.all_dirty
= GL_TRUE
;
2446 void r300UpdateShaders(r300ContextPtr rmesa
)
2449 struct r300_vertex_program
*vp
;
2452 ctx
= rmesa
->radeon
.glCtx
;
2454 if (rmesa
->NewGLState
&& hw_tcl_on
) {
2455 rmesa
->NewGLState
= 0;
2457 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
2458 rmesa
->temp_attrib
[i
] =
2459 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
];
2460 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] =
2461 &rmesa
->dummy_attrib
[i
];
2464 _tnl_UpdateFixedFunctionProgram(ctx
);
2466 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
2467 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] =
2468 rmesa
->temp_attrib
[i
];
2471 r300SelectVertexShader(rmesa
);
2472 vp
= (struct r300_vertex_program
*)
2473 CURRENT_VERTEX_SHADER(ctx
);
2474 /*if (vp->translated == GL_FALSE)
2475 r300TranslateVertexShader(vp); */
2476 if (vp
->translated
== GL_FALSE
) {
2477 fprintf(stderr
, "Failing back to sw-tcl\n");
2478 hw_tcl_on
= future_hw_tcl_on
= 0;
2479 r300ResetHwState(rmesa
);
2481 r300UpdateStateParameters(ctx
, _NEW_PROGRAM
);
2485 r300UpdateStateParameters(ctx
, _NEW_PROGRAM
);
2488 static const GLfloat
*get_fragmentprogram_constant(GLcontext
*ctx
,
2489 struct gl_program
*program
, struct prog_src_register srcreg
)
2491 static const GLfloat dummy
[4] = { 0, 0, 0, 0 };
2493 switch(srcreg
.File
) {
2494 case PROGRAM_LOCAL_PARAM
:
2495 return program
->LocalParams
[srcreg
.Index
];
2496 case PROGRAM_ENV_PARAM
:
2497 return ctx
->FragmentProgram
.Parameters
[srcreg
.Index
];
2498 case PROGRAM_STATE_VAR
:
2499 case PROGRAM_NAMED_PARAM
:
2500 case PROGRAM_CONSTANT
:
2501 return program
->Parameters
->ParameterValues
[srcreg
.Index
];
2503 _mesa_problem(ctx
, "get_fragmentprogram_constant: Unknown\n");
2509 static void r300SetupPixelShader(r300ContextPtr rmesa
)
2511 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
2512 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
2513 (char *)ctx
->FragmentProgram
._Current
;
2514 struct r300_fragment_program_code
*code
;
2517 if (!fp
) /* should only happenen once, just after context is created */
2520 r300TranslateFragmentShader(rmesa
, fp
);
2521 if (!fp
->translated
) {
2522 fprintf(stderr
, "%s: No valid fragment shader, exiting\n",
2528 r300SetupTextures(ctx
);
2530 R300_STATECHANGE(rmesa
, fpi
[0]);
2531 R300_STATECHANGE(rmesa
, fpi
[1]);
2532 R300_STATECHANGE(rmesa
, fpi
[2]);
2533 R300_STATECHANGE(rmesa
, fpi
[3]);
2534 rmesa
->hw
.fpi
[0].cmd
[R300_FPI_CMD_0
] = cmdpacket0(R300_US_ALU_RGB_INST_0
, code
->alu
.length
);
2535 rmesa
->hw
.fpi
[1].cmd
[R300_FPI_CMD_0
] = cmdpacket0(R300_US_ALU_RGB_ADDR_0
, code
->alu
.length
);
2536 rmesa
->hw
.fpi
[2].cmd
[R300_FPI_CMD_0
] = cmdpacket0(R300_US_ALU_ALPHA_INST_0
, code
->alu
.length
);
2537 rmesa
->hw
.fpi
[3].cmd
[R300_FPI_CMD_0
] = cmdpacket0(R300_US_ALU_ALPHA_ADDR_0
, code
->alu
.length
);
2538 for (i
= 0; i
< code
->alu
.length
; i
++) {
2539 rmesa
->hw
.fpi
[0].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst0
;
2540 rmesa
->hw
.fpi
[1].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst1
;
2541 rmesa
->hw
.fpi
[2].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst2
;
2542 rmesa
->hw
.fpi
[3].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst3
;
2545 R300_STATECHANGE(rmesa
, fp
);
2546 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL0
] = code
->cur_node
| (code
->first_node_has_tex
<< 3);
2547 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL1
] = code
->max_temp_idx
;
2548 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL2
] =
2549 (0 << R300_PFS_CNTL_ALU_OFFSET_SHIFT
) |
2550 ((code
->alu
.length
-1) << R300_PFS_CNTL_ALU_END_SHIFT
) |
2551 (0 << R300_PFS_CNTL_TEX_OFFSET_SHIFT
) |
2552 ((code
->tex
.length
? code
->tex
.length
-1 : 0) << R300_PFS_CNTL_TEX_END_SHIFT
);
2553 /* I just want to say, the way these nodes are stored.. weird.. */
2554 for (i
= 0, k
= (4 - (code
->cur_node
+ 1)); i
< 4; i
++, k
++) {
2555 if (i
< (code
->cur_node
+ 1)) {
2556 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+ k
] =
2557 (code
->node
[i
].alu_offset
<< R300_ALU_START_SHIFT
) |
2558 (code
->node
[i
].alu_end
<< R300_ALU_SIZE_SHIFT
) |
2559 (code
->node
[i
].tex_offset
<< R300_TEX_START_SHIFT
) |
2560 (code
->node
[i
].tex_end
<< R300_TEX_SIZE_SHIFT
) |
2561 code
->node
[i
].flags
;
2563 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+ (3 - i
)] = 0;
2567 R300_STATECHANGE(rmesa
, fpp
);
2568 rmesa
->hw
.fpp
.cmd
[R300_FPP_CMD_0
] = cmdpacket0(R300_PFS_PARAM_0_X
, code
->const_nr
* 4);
2569 for (i
= 0; i
< code
->const_nr
; i
++) {
2570 const GLfloat
*constant
= get_fragmentprogram_constant(ctx
,
2571 &fp
->mesa_program
.Base
, code
->constant
[i
]);
2572 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 0] = r300PackFloat24(constant
[0]);
2573 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 1] = r300PackFloat24(constant
[1]);
2574 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 2] = r300PackFloat24(constant
[2]);
2575 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 3] = r300PackFloat24(constant
[3]);
2579 #define bump_r500fp_count(ptr, new_count) do{\
2580 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
2581 int _nc=(new_count)/6; \
2582 assert(_nc < 256); \
2583 if(_nc>_p->r500fp.count)_p->r500fp.count=_nc;\
2586 #define bump_r500fp_const_count(ptr, new_count) do{\
2587 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
2588 int _nc=(new_count)/4; \
2589 assert(_nc < 256); \
2590 if(_nc>_p->r500fp.count)_p->r500fp.count=_nc;\
2593 static void r500SetupPixelShader(r300ContextPtr rmesa
)
2595 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
2596 struct r500_fragment_program
*fp
= (struct r500_fragment_program
*)
2597 (char *)ctx
->FragmentProgram
._Current
;
2599 struct r500_fragment_program_code
*code
;
2601 if (!fp
) /* should only happenen once, just after context is created */
2604 ((drm_r300_cmd_header_t
*) rmesa
->hw
.r500fp
.cmd
)->r500fp
.count
= 0;
2605 ((drm_r300_cmd_header_t
*) rmesa
->hw
.r500fp_const
.cmd
)->r500fp
.count
= 0;
2607 r500TranslateFragmentShader(rmesa
, fp
);
2608 if (!fp
->translated
) {
2609 fprintf(stderr
, "%s: No valid fragment shader, exiting\n",
2615 if (fp
->mesa_program
.FogOption
!= GL_NONE
) {
2616 /* Enable HW fog. Try not to squish GL context.
2617 * (Anybody sane remembered to set glFog() opts first!) */
2618 r300SetFogState(ctx
, GL_TRUE
);
2619 ctx
->Fog
.Mode
= fp
->mesa_program
.FogOption
;
2620 r300Fogfv(ctx
, GL_FOG_MODE
, NULL
);
2622 /* Make sure HW is matching GL context. */
2623 r300SetFogState(ctx
, ctx
->Fog
.Enabled
);
2625 r300SetupTextures(ctx
);
2627 R300_STATECHANGE(rmesa
, fp
);
2628 rmesa
->hw
.fp
.cmd
[R500_FP_PIXSIZE
] = code
->max_temp_idx
;
2630 rmesa
->hw
.fp
.cmd
[R500_FP_CODE_ADDR
] =
2631 R500_US_CODE_START_ADDR(code
->inst_offset
) |
2632 R500_US_CODE_END_ADDR(code
->inst_end
);
2633 rmesa
->hw
.fp
.cmd
[R500_FP_CODE_RANGE
] =
2634 R500_US_CODE_RANGE_ADDR(code
->inst_offset
) |
2635 R500_US_CODE_RANGE_SIZE(code
->inst_end
);
2636 rmesa
->hw
.fp
.cmd
[R500_FP_CODE_OFFSET
] =
2637 R500_US_CODE_OFFSET_ADDR(0); /* FIXME when we add flow control */
2639 R300_STATECHANGE(rmesa
, r500fp
);
2640 /* Emit our shader... */
2641 for (i
= 0; i
< code
->inst_end
+1; i
++) {
2642 rmesa
->hw
.r500fp
.cmd
[i
*6+1] = code
->inst
[i
].inst0
;
2643 rmesa
->hw
.r500fp
.cmd
[i
*6+2] = code
->inst
[i
].inst1
;
2644 rmesa
->hw
.r500fp
.cmd
[i
*6+3] = code
->inst
[i
].inst2
;
2645 rmesa
->hw
.r500fp
.cmd
[i
*6+4] = code
->inst
[i
].inst3
;
2646 rmesa
->hw
.r500fp
.cmd
[i
*6+5] = code
->inst
[i
].inst4
;
2647 rmesa
->hw
.r500fp
.cmd
[i
*6+6] = code
->inst
[i
].inst5
;
2650 bump_r500fp_count(rmesa
->hw
.r500fp
.cmd
, (code
->inst_end
+ 1) * 6);
2652 R300_STATECHANGE(rmesa
, r500fp_const
);
2653 for (i
= 0; i
< code
->const_nr
; i
++) {
2654 const GLfloat
*constant
= get_fragmentprogram_constant(ctx
,
2655 &fp
->mesa_program
.Base
, code
->constant
[i
]);
2656 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 0] = r300PackFloat32(constant
[0]);
2657 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 1] = r300PackFloat32(constant
[1]);
2658 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 2] = r300PackFloat32(constant
[2]);
2659 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 3] = r300PackFloat32(constant
[3]);
2661 bump_r500fp_const_count(rmesa
->hw
.r500fp_const
.cmd
, code
->const_nr
* 4);
2665 void r300UpdateShaderStates(r300ContextPtr rmesa
)
2668 ctx
= rmesa
->radeon
.glCtx
;
2670 r300UpdateTextureState(ctx
);
2671 r300SetEarlyZState(ctx
);
2673 GLuint fgdepthsrc
= R300_FG_DEPTH_SRC_SCAN
;
2674 if (current_fragment_program_writes_depth(ctx
))
2675 fgdepthsrc
= R300_FG_DEPTH_SRC_SHADER
;
2676 if (fgdepthsrc
!= rmesa
->hw
.fg_depth_src
.cmd
[1]) {
2677 R300_STATECHANGE(rmesa
, fg_depth_src
);
2678 rmesa
->hw
.fg_depth_src
.cmd
[1] = fgdepthsrc
;
2681 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
2682 r500SetupPixelShader(rmesa
);
2684 r300SetupPixelShader(rmesa
);
2686 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
2687 r500SetupRSUnit(ctx
);
2689 r300SetupRSUnit(ctx
);
2691 if ((rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
2692 r300SetupVertexProgram(rmesa
);
2697 * Called by Mesa after an internal state update.
2699 static void r300InvalidateState(GLcontext
* ctx
, GLuint new_state
)
2701 r300ContextPtr r300
= R300_CONTEXT(ctx
);
2703 _swrast_InvalidateState(ctx
, new_state
);
2704 _swsetup_InvalidateState(ctx
, new_state
);
2705 _vbo_InvalidateState(ctx
, new_state
);
2706 _tnl_InvalidateState(ctx
, new_state
);
2707 _ae_invalidate_state(ctx
, new_state
);
2709 if (new_state
& (_NEW_BUFFERS
| _NEW_COLOR
| _NEW_PIXEL
)) {
2710 r300UpdateDrawBuffer(ctx
);
2713 r300UpdateStateParameters(ctx
, new_state
);
2715 r300
->NewGLState
|= new_state
;
2719 * Calculate initial hardware state and register state functions.
2720 * Assumes that the command buffer and state atoms have been
2721 * initialized already.
2723 void r300InitState(r300ContextPtr r300
)
2725 GLcontext
*ctx
= r300
->radeon
.glCtx
;
2728 radeonInitState(&r300
->radeon
);
2730 switch (ctx
->Visual
.depthBits
) {
2732 r300
->state
.depth
.scale
= 1.0 / (GLfloat
) 0xffff;
2733 depth_fmt
= R300_DEPTHFORMAT_16BIT_INT_Z
;
2736 r300
->state
.depth
.scale
= 1.0 / (GLfloat
) 0xffffff;
2737 depth_fmt
= R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL
;
2740 fprintf(stderr
, "Error: Unsupported depth %d... exiting\n",
2741 ctx
->Visual
.depthBits
);
2745 /* Only have hw stencil when depth buffer is 24 bits deep */
2746 r300
->state
.stencil
.hw_stencil
= (ctx
->Visual
.stencilBits
> 0 &&
2747 ctx
->Visual
.depthBits
== 24);
2749 memset(&(r300
->state
.texture
), 0, sizeof(r300
->state
.texture
));
2751 r300ResetHwState(r300
);
2754 static void r300RenderMode(GLcontext
* ctx
, GLenum mode
)
2756 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
2761 void r300UpdateClipPlanes( GLcontext
*ctx
)
2763 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
2766 for (p
= 0; p
< ctx
->Const
.MaxClipPlanes
; p
++) {
2767 if (ctx
->Transform
.ClipPlanesEnabled
& (1 << p
)) {
2768 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
2770 R300_STATECHANGE( rmesa
, vpucp
[p
] );
2771 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_X
] = ip
[0];
2772 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_Y
] = ip
[1];
2773 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_Z
] = ip
[2];
2774 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_W
] = ip
[3];
2780 * Initialize driver's state callback functions
2782 void r300InitStateFuncs(struct dd_function_table
*functions
)
2784 radeonInitStateFuncs(functions
);
2786 functions
->UpdateState
= r300InvalidateState
;
2787 functions
->AlphaFunc
= r300AlphaFunc
;
2788 functions
->BlendColor
= r300BlendColor
;
2789 functions
->BlendEquationSeparate
= r300BlendEquationSeparate
;
2790 functions
->BlendFuncSeparate
= r300BlendFuncSeparate
;
2791 functions
->Enable
= r300Enable
;
2792 functions
->ColorMask
= r300ColorMask
;
2793 functions
->DepthFunc
= r300DepthFunc
;
2794 functions
->DepthMask
= r300DepthMask
;
2795 functions
->CullFace
= r300CullFace
;
2796 functions
->Fogfv
= r300Fogfv
;
2797 functions
->FrontFace
= r300FrontFace
;
2798 functions
->ShadeModel
= r300ShadeModel
;
2799 functions
->LogicOpcode
= r300LogicOpcode
;
2801 /* ARB_point_parameters */
2802 functions
->PointParameterfv
= r300PointParameter
;
2804 /* Stencil related */
2805 functions
->StencilFuncSeparate
= r300StencilFuncSeparate
;
2806 functions
->StencilMaskSeparate
= r300StencilMaskSeparate
;
2807 functions
->StencilOpSeparate
= r300StencilOpSeparate
;
2809 /* Viewport related */
2810 functions
->Viewport
= r300Viewport
;
2811 functions
->DepthRange
= r300DepthRange
;
2812 functions
->PointSize
= r300PointSize
;
2813 functions
->LineWidth
= r300LineWidth
;
2815 functions
->PolygonOffset
= r300PolygonOffset
;
2816 functions
->PolygonMode
= r300PolygonMode
;
2818 functions
->RenderMode
= r300RenderMode
;
2820 functions
->ClipPlane
= r300ClipPlane
;