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
;
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
;
1678 if (InputsRead
& FRAG_BIT_FOGC
) {
1680 * Just turn off the bit for now.
1681 * Need to do something similar to the color/texcoord inputs.
1683 InputsRead
&= ~FRAG_BIT_FOGC
;
1686 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
1689 /* with TCL we always seem to route 4 components */
1693 count
= VB
->AttribPtr
[_TNL_ATTRIB_TEX(i
)]->size
;
1695 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ i
] = interp_col
[i
] | rs_tex_count
;
1697 case 4: swiz
= R300_RS_SEL_S(0) | R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(3); break;
1698 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;
1701 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;
1704 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ i
] |= swiz
;
1706 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ fp_reg
] = 0;
1707 if (InputsRead
& (FRAG_BIT_TEX0
<< i
)) {
1709 rs_tex_count
+= count
;
1711 //assert(r300->state.texture.tc_count != 0);
1712 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ fp_reg
] |= R300_RS_INST_TEX_CN_WRITE
| i
/* source INTERP */
1713 | (fp_reg
<< R300_RS_INST_TEX_ADDR_SHIFT
);
1716 /* Passing invalid data here can lock the GPU. */
1717 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_TEX0
+ i
, _TNL_ATTRIB_TEX(i
))) {
1718 InputsRead
&= ~(FRAG_BIT_TEX0
<< i
);
1721 WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i
);
1726 if (InputsRead
& FRAG_BIT_COL0
) {
1727 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL0
, _TNL_ATTRIB_COLOR0
)) {
1728 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
);
1729 InputsRead
&= ~FRAG_BIT_COL0
;
1732 WARN_ONCE("fragprog wants col0, vp doesn't provide it\n");
1736 if (InputsRead
& FRAG_BIT_COL1
) {
1737 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL1
, _TNL_ATTRIB_COLOR1
)) {
1738 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
);
1739 InputsRead
&= ~FRAG_BIT_COL1
;
1744 WARN_ONCE("fragprog wants col1, vp doesn't provide it\n");
1748 /* Need at least one. This might still lock as the values are undefined... */
1749 if (rs_tex_count
== 0 && col_interp_nr
== 0) {
1750 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
);
1754 r300
->hw
.rc
.cmd
[1] = 0 | (rs_tex_count
<< R300_IT_COUNT_SHIFT
)
1755 | (col_interp_nr
<< R300_IC_COUNT_SHIFT
)
1758 assert(high_rr
>= 0);
1759 r300
->hw
.rr
.cmd
[R300_RR_CMD_0
] = cmdpacket0(R300_RS_INST_0
, high_rr
+ 1);
1760 r300
->hw
.rc
.cmd
[2] = high_rr
;
1763 WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead
);
1766 static void r500SetupRSUnit(GLcontext
* ctx
)
1768 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1769 /* I'm still unsure if these are needed */
1770 GLuint interp_col
[8];
1771 union r300_outputs_written OutputsWritten
;
1772 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1773 struct vertex_buffer
*VB
= &tnl
->vb
;
1775 int fp_reg
, high_rr
;
1776 int rs_col_count
= 0;
1777 int in_texcoords
, col_interp_nr
;
1780 memset(interp_col
, 0, sizeof(interp_col
));
1782 OutputsWritten
.vp_outputs
= CURRENT_VERTEX_SHADER(ctx
)->key
.OutputsWritten
;
1784 RENDERINPUTS_COPY(OutputsWritten
.index_bitset
, r300
->state
.render_inputs_bitset
);
1786 if (ctx
->FragmentProgram
._Current
)
1787 InputsRead
= ctx
->FragmentProgram
._Current
->Base
.InputsRead
;
1789 fprintf(stderr
, "No ctx->FragmentProgram._Current!!\n");
1790 return; /* This should only ever happen once.. */
1793 R300_STATECHANGE(r300
, ri
);
1794 R300_STATECHANGE(r300
, rc
);
1795 R300_STATECHANGE(r300
, rr
);
1797 fp_reg
= col_interp_nr
= high_rr
= in_texcoords
= 0;
1799 r300
->hw
.rr
.cmd
[R300_RR_INST_1
] = 0;
1801 if (InputsRead
& FRAG_BIT_WPOS
) {
1802 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++)
1803 if (!(InputsRead
& (FRAG_BIT_TEX0
<< i
)))
1806 if (i
== ctx
->Const
.MaxTextureUnits
) {
1807 fprintf(stderr
, "\tno free texcoord found...\n");
1811 InputsRead
|= (FRAG_BIT_TEX0
<< i
);
1812 InputsRead
&= ~FRAG_BIT_WPOS
;
1815 if (InputsRead
& FRAG_BIT_COL0
) {
1816 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR0
]->size
;
1817 interp_col
[0] |= R500_RS_COL_PTR(rs_col_count
);
1819 interp_col
[0] |= R500_RS_COL_FMT(R300_RS_COL_FMT_RGB1
);
1820 rs_col_count
+= count
;
1823 interp_col
[0] = R500_RS_COL_FMT(R300_RS_COL_FMT_0001
);
1825 if (InputsRead
& FRAG_BIT_COL1
) {
1826 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR1
]->size
;
1827 interp_col
[1] |= R500_RS_COL_PTR(1);
1829 interp_col
[1] |= R500_RS_COL_FMT(R300_RS_COL_FMT_RGB0
);
1830 rs_col_count
+= count
;
1833 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
1836 /* with TCL we always seem to route 4 components */
1837 if (InputsRead
& (FRAG_BIT_TEX0
<< i
)) {
1842 count
= VB
->AttribPtr
[_TNL_ATTRIB_TEX(i
)]->size
;
1844 /* always have on texcoord */
1845 swiz
|= in_texcoords
++ << R500_RS_IP_TEX_PTR_S_SHIFT
;
1847 swiz
|= in_texcoords
++ << R500_RS_IP_TEX_PTR_T_SHIFT
;
1849 swiz
|= R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_T_SHIFT
;
1852 swiz
|= in_texcoords
++ << R500_RS_IP_TEX_PTR_R_SHIFT
;
1854 swiz
|= R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_R_SHIFT
;
1857 swiz
|= in_texcoords
++ << R500_RS_IP_TEX_PTR_Q_SHIFT
;
1859 swiz
|= R500_RS_IP_PTR_K1
<< R500_RS_IP_TEX_PTR_Q_SHIFT
;
1862 swiz
= (R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_S_SHIFT
) |
1863 (R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_T_SHIFT
) |
1864 (R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_R_SHIFT
) |
1865 (R500_RS_IP_PTR_K1
<< R500_RS_IP_TEX_PTR_Q_SHIFT
);
1867 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ i
] = interp_col
[i
] | swiz
;
1869 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ fp_reg
] = 0;
1870 if (InputsRead
& (FRAG_BIT_TEX0
<< i
)) {
1871 //assert(r300->state.texture.tc_count != 0);
1872 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ fp_reg
] |= R500_RS_INST_TEX_CN_WRITE
| i
/* source INTERP */
1873 | (fp_reg
<< R500_RS_INST_TEX_ADDR_SHIFT
);
1876 /* Passing invalid data here can lock the GPU. */
1877 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_TEX0
+ i
, _TNL_ATTRIB_TEX(i
))) {
1878 InputsRead
&= ~(FRAG_BIT_TEX0
<< i
);
1881 WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i
);
1886 if (InputsRead
& FRAG_BIT_COL0
) {
1887 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL0
, _TNL_ATTRIB_COLOR0
)) {
1888 r300
->hw
.rr
.cmd
[R300_RR_INST_0
] |= R500_RS_INST_COL_CN_WRITE
| (fp_reg
++ << R500_RS_INST_COL_ADDR_SHIFT
);
1889 InputsRead
&= ~FRAG_BIT_COL0
;
1892 WARN_ONCE("fragprog wants col0, vp doesn't provide it\n");
1896 if (InputsRead
& FRAG_BIT_COL1
) {
1897 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL1
, _TNL_ATTRIB_COLOR1
)) {
1898 r300
->hw
.rr
.cmd
[R300_RR_INST_1
] |= (1 << 12) | R500_RS_INST_COL_CN_WRITE
| (fp_reg
++ << R500_RS_INST_COL_ADDR_SHIFT
);
1899 InputsRead
&= ~FRAG_BIT_COL1
;
1904 WARN_ONCE("fragprog wants col1, vp doesn't provide it\n");
1908 /* Need at least one. This might still lock as the values are undefined... */
1909 if (in_texcoords
== 0 && col_interp_nr
== 0) {
1910 r300
->hw
.rr
.cmd
[R300_RR_INST_0
] |= 0 | R500_RS_INST_COL_CN_WRITE
| (fp_reg
++ << R500_RS_INST_COL_ADDR_SHIFT
);
1914 r300
->hw
.rc
.cmd
[1] = 0 | (in_texcoords
<< R300_IT_COUNT_SHIFT
)
1915 | (col_interp_nr
<< R300_IC_COUNT_SHIFT
)
1918 assert(high_rr
>= 0);
1919 r300
->hw
.rr
.cmd
[R300_RR_CMD_0
] = cmdpacket0(R500_RS_INST_0
, high_rr
+ 1);
1920 r300
->hw
.rc
.cmd
[2] = 0xC0 | high_rr
;
1923 WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead
);
1929 #define bump_vpu_count(ptr, new_count) do{\
1930 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
1931 int _nc=(new_count)/4; \
1932 assert(_nc < 256); \
1933 if(_nc>_p->vpu.count)_p->vpu.count=_nc;\
1936 static INLINE
void r300SetupVertexProgramFragment(r300ContextPtr r300
, int dest
, struct r300_vertex_shader_fragment
*vsf
)
1940 if (vsf
->length
== 0)
1943 if (vsf
->length
& 0x3) {
1944 fprintf(stderr
, "VERTEX_SHADER_FRAGMENT must have length divisible by 4\n");
1948 switch ((dest
>> 8) & 0xf) {
1950 R300_STATECHANGE(r300
, vpi
);
1951 for (i
= 0; i
< vsf
->length
; i
++)
1952 r300
->hw
.vpi
.cmd
[R300_VPI_INSTR_0
+ i
+ 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1953 bump_vpu_count(r300
->hw
.vpi
.cmd
, vsf
->length
+ 4 * (dest
& 0xff));
1957 R300_STATECHANGE(r300
, vpp
);
1958 for (i
= 0; i
< vsf
->length
; i
++)
1959 r300
->hw
.vpp
.cmd
[R300_VPP_PARAM_0
+ i
+ 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1960 bump_vpu_count(r300
->hw
.vpp
.cmd
, vsf
->length
+ 4 * (dest
& 0xff));
1963 R300_STATECHANGE(r300
, vps
);
1964 for (i
= 0; i
< vsf
->length
; i
++)
1965 r300
->hw
.vps
.cmd
[1 + i
+ 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1966 bump_vpu_count(r300
->hw
.vps
.cmd
, vsf
->length
+ 4 * (dest
& 0xff));
1969 fprintf(stderr
, "%s:%s don't know how to handle dest %04x\n", __FILE__
, __FUNCTION__
, dest
);
1974 #define MIN3(a, b, c) ((a) < (b) ? MIN2(a, c) : MIN2(b, c))
1977 static void r300VapCntl(r300ContextPtr rmesa
, GLuint input_count
,
1978 GLuint output_count
, GLuint temp_count
)
1984 /* Flush PVS engine before changing PVS_NUM_SLOTS, PVS_NUM_CNTRLS.
1985 * See r500 docs 6.5.2 - done in emit */
1987 /* avoid division by zero */
1988 if (input_count
== 0) input_count
= 1;
1989 if (output_count
== 0) output_count
= 1;
1990 if (temp_count
== 0) temp_count
= 1;
1992 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
1997 pvs_num_slots
= MIN3(10, vtx_mem_size
/input_count
, vtx_mem_size
/output_count
);
1998 pvs_num_cntrls
= MIN2(6, vtx_mem_size
/temp_count
);
2000 R300_STATECHANGE(rmesa
, vap_cntl
);
2001 if (rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
) {
2002 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] =
2003 (pvs_num_slots
<< R300_PVS_NUM_SLOTS_SHIFT
) |
2004 (pvs_num_cntrls
<< R300_PVS_NUM_CNTLRS_SHIFT
) |
2005 (12 << R300_VF_MAX_VTX_NUM_SHIFT
);
2006 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
2007 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= R500_TCL_STATE_OPTIMIZATION
;
2009 /* not sure about non-tcl */
2010 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] = ((10 << R300_PVS_NUM_SLOTS_SHIFT
) |
2011 (5 << R300_PVS_NUM_CNTLRS_SHIFT
) |
2012 (5 << R300_VF_MAX_VTX_NUM_SHIFT
));
2014 if (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV515
)
2015 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (2 << R300_PVS_NUM_FPUS_SHIFT
);
2016 else if ((rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV530
) ||
2017 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV560
) ||
2018 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV570
))
2019 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (5 << R300_PVS_NUM_FPUS_SHIFT
);
2020 else if ((rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV410
) ||
2021 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R420
))
2022 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (6 << R300_PVS_NUM_FPUS_SHIFT
);
2023 else if ((rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R520
) ||
2024 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R580
))
2025 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (8 << R300_PVS_NUM_FPUS_SHIFT
);
2027 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (4 << R300_PVS_NUM_FPUS_SHIFT
);
2031 static void r300SetupDefaultVertexProgram(r300ContextPtr rmesa
)
2033 struct r300_vertex_shader_state
*prog
= &(rmesa
->state
.vertex_shader
);
2038 int param_count
= 0;
2039 int program_end
= 0;
2041 for (i
= VERT_ATTRIB_POS
; i
< VERT_ATTRIB_MAX
; i
++) {
2042 if (rmesa
->state
.sw_tcl_inputs
[i
] != -1) {
2043 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
);
2044 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
);
2045 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
);
2046 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
);
2052 prog
->program
.length
= program_end
;
2054 r300SetupVertexProgramFragment(rmesa
, R300_PVS_CODE_START
,
2056 inst_count
= (prog
->program
.length
/ 4) - 1;
2058 r300VapCntl(rmesa
, i_reg
, o_reg
, 0);
2060 R300_STATECHANGE(rmesa
, pvs
);
2061 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] =
2062 (0 << R300_PVS_FIRST_INST_SHIFT
) |
2063 (inst_count
<< R300_PVS_XYZW_VALID_INST_SHIFT
) |
2064 (inst_count
<< R300_PVS_LAST_INST_SHIFT
);
2065 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] =
2066 (0 << R300_PVS_CONST_BASE_OFFSET_SHIFT
) |
2067 (param_count
<< R300_PVS_MAX_CONST_ADDR_SHIFT
);
2068 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] =
2069 (inst_count
<< R300_PVS_LAST_VTX_SRC_INST_SHIFT
);
2072 static int bit_count (int x
)
2074 x
= ((x
& 0xaaaaaaaaU
) >> 1) + (x
& 0x55555555U
);
2075 x
= ((x
& 0xccccccccU
) >> 2) + (x
& 0x33333333U
);
2076 x
= (x
>> 16) + (x
& 0xffff);
2077 x
= ((x
& 0xf0f0) >> 4) + (x
& 0x0f0f);
2078 return (x
>> 8) + (x
& 0x00ff);
2081 static void r300SetupRealVertexProgram(r300ContextPtr rmesa
)
2083 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
2084 struct r300_vertex_program
*prog
= (struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
);
2086 int param_count
= 0;
2088 /* FIXME: r300SetupVertexProgramFragment */
2089 R300_STATECHANGE(rmesa
, vpp
);
2091 r300VertexProgUpdateParams(ctx
,
2092 (struct r300_vertex_program_cont
*)
2093 ctx
->VertexProgram
._Current
,
2094 (float *)&rmesa
->hw
.vpp
.
2095 cmd
[R300_VPP_PARAM_0
]);
2096 bump_vpu_count(rmesa
->hw
.vpp
.cmd
, param_count
);
2099 r300SetupVertexProgramFragment(rmesa
, R300_PVS_CODE_START
, &(prog
->program
));
2100 inst_count
= (prog
->program
.length
/ 4) - 1;
2102 r300VapCntl(rmesa
, bit_count(prog
->key
.InputsRead
),
2103 bit_count(prog
->key
.OutputsWritten
), prog
->num_temporaries
);
2105 R300_STATECHANGE(rmesa
, pvs
);
2106 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] =
2107 (0 << R300_PVS_FIRST_INST_SHIFT
) |
2108 (inst_count
<< R300_PVS_XYZW_VALID_INST_SHIFT
) |
2109 (inst_count
<< R300_PVS_LAST_INST_SHIFT
);
2110 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] =
2111 (0 << R300_PVS_CONST_BASE_OFFSET_SHIFT
) |
2112 (param_count
<< R300_PVS_MAX_CONST_ADDR_SHIFT
);
2113 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] =
2114 (inst_count
<< R300_PVS_LAST_VTX_SRC_INST_SHIFT
);
2117 static void r300SetupVertexProgram(r300ContextPtr rmesa
)
2119 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
2121 /* Reset state, in case we don't use something */
2122 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vpp
.cmd
)->vpu
.count
= 0;
2123 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vpi
.cmd
)->vpu
.count
= 0;
2124 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vps
.cmd
)->vpu
.count
= 0;
2126 /* Not sure why this doesnt work...
2127 0x400 area might have something to do with pixel shaders as it appears right after pfs programming.
2128 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. */
2129 //setup_vertex_shader_fragment(rmesa, 0x406, &unk4);
2130 if (hw_tcl_on
&& ((struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
))->translated
) {
2131 r300SetupRealVertexProgram(rmesa
);
2133 /* FIXME: This needs to be replaced by vertex shader generation code. */
2134 r300SetupDefaultVertexProgram(rmesa
);
2140 * Enable/Disable states.
2142 * \note Mesa already filters redundant calls to this function.
2144 static void r300Enable(GLcontext
* ctx
, GLenum cap
, GLboolean state
)
2146 if (RADEON_DEBUG
& DEBUG_STATE
)
2147 fprintf(stderr
, "%s( %s = %s )\n", __FUNCTION__
,
2148 _mesa_lookup_enum_by_nr(cap
),
2149 state
? "GL_TRUE" : "GL_FALSE");
2158 r300SetFogState(ctx
, state
);
2161 r300SetAlphaState(ctx
);
2163 case GL_COLOR_LOGIC_OP
:
2164 r300SetLogicOpState(ctx
);
2165 /* fall-through, because logic op overrides blending */
2167 r300SetBlendState(ctx
);
2169 case GL_CLIP_PLANE0
:
2170 case GL_CLIP_PLANE1
:
2171 case GL_CLIP_PLANE2
:
2172 case GL_CLIP_PLANE3
:
2173 case GL_CLIP_PLANE4
:
2174 case GL_CLIP_PLANE5
:
2175 r300SetClipPlaneState(ctx
, cap
, state
);
2178 r300SetDepthState(ctx
);
2180 case GL_STENCIL_TEST
:
2181 r300SetStencilState(ctx
, state
);
2184 r300UpdateCulling(ctx
);
2186 case GL_POLYGON_OFFSET_POINT
:
2187 case GL_POLYGON_OFFSET_LINE
:
2188 case GL_POLYGON_OFFSET_FILL
:
2189 r300SetPolygonOffsetState(ctx
, state
);
2192 radeonEnable(ctx
, cap
, state
);
2198 * Completely recalculates hardware state based on the Mesa state.
2200 static void r300ResetHwState(r300ContextPtr r300
)
2202 GLcontext
*ctx
= r300
->radeon
.glCtx
;
2205 if (!(r300
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
2208 if (RADEON_DEBUG
& DEBUG_STATE
)
2209 fprintf(stderr
, "%s\n", __FUNCTION__
);
2211 r300UpdateWindow(ctx
);
2214 ctx
->Color
.ColorMask
[RCOMP
],
2215 ctx
->Color
.ColorMask
[GCOMP
],
2216 ctx
->Color
.ColorMask
[BCOMP
], ctx
->Color
.ColorMask
[ACOMP
]);
2218 r300Enable(ctx
, GL_DEPTH_TEST
, ctx
->Depth
.Test
);
2219 r300DepthMask(ctx
, ctx
->Depth
.Mask
);
2220 r300DepthFunc(ctx
, ctx
->Depth
.Func
);
2223 r300Enable(ctx
, GL_STENCIL_TEST
, ctx
->Stencil
.Enabled
);
2224 r300StencilMaskSeparate(ctx
, 0, ctx
->Stencil
.WriteMask
[0]);
2225 r300StencilFuncSeparate(ctx
, 0, ctx
->Stencil
.Function
[0],
2226 ctx
->Stencil
.Ref
[0], ctx
->Stencil
.ValueMask
[0]);
2227 r300StencilOpSeparate(ctx
, 0, ctx
->Stencil
.FailFunc
[0],
2228 ctx
->Stencil
.ZFailFunc
[0],
2229 ctx
->Stencil
.ZPassFunc
[0]);
2231 r300UpdateCulling(ctx
);
2233 r300UpdateTextureState(ctx
);
2235 r300SetBlendState(ctx
);
2236 r300SetLogicOpState(ctx
);
2238 r300AlphaFunc(ctx
, ctx
->Color
.AlphaFunc
, ctx
->Color
.AlphaRef
);
2239 r300Enable(ctx
, GL_ALPHA_TEST
, ctx
->Color
.AlphaEnabled
);
2241 r300
->hw
.vte
.cmd
[1] = R300_VPORT_X_SCALE_ENA
2242 | R300_VPORT_X_OFFSET_ENA
2243 | R300_VPORT_Y_SCALE_ENA
2244 | R300_VPORT_Y_OFFSET_ENA
2245 | R300_VPORT_Z_SCALE_ENA
2246 | R300_VPORT_Z_OFFSET_ENA
| R300_VTX_W0_FMT
;
2247 r300
->hw
.vte
.cmd
[2] = 0x00000008;
2249 r300
->hw
.vap_vf_max_vtx_indx
.cmd
[1] = 0x00FFFFFF;
2250 r300
->hw
.vap_vf_max_vtx_indx
.cmd
[2] = 0x00000000;
2252 #ifdef MESA_LITTLE_ENDIAN
2253 r300
->hw
.vap_cntl_status
.cmd
[1] = R300_VC_NO_SWAP
;
2255 r300
->hw
.vap_cntl_status
.cmd
[1] = R300_VC_32BIT_SWAP
;
2258 /* disable VAP/TCL on non-TCL capable chips */
2260 r300
->hw
.vap_cntl_status
.cmd
[1] |= R300_VAP_TCL_BYPASS
;
2262 r300
->hw
.vap_psc_sgn_norm_cntl
.cmd
[1] = 0xAAAAAAAA;
2264 /* XXX: Other families? */
2266 r300
->hw
.vap_clip_cntl
.cmd
[1] = R300_PS_UCP_MODE_DIST_COP
;
2268 r300
->hw
.vap_clip
.cmd
[1] = r300PackFloat32(1.0); /* X */
2269 r300
->hw
.vap_clip
.cmd
[2] = r300PackFloat32(1.0); /* X */
2270 r300
->hw
.vap_clip
.cmd
[3] = r300PackFloat32(1.0); /* Y */
2271 r300
->hw
.vap_clip
.cmd
[4] = r300PackFloat32(1.0); /* Y */
2273 switch (r300
->radeon
.radeonScreen
->chip_family
) {
2274 case CHIP_FAMILY_R300
:
2275 r300
->hw
.vap_pvs_vtx_timeout_reg
.cmd
[1] = R300_2288_R300
;
2278 r300
->hw
.vap_pvs_vtx_timeout_reg
.cmd
[1] = R300_2288_RV350
;
2283 r300
->hw
.gb_enable
.cmd
[1] = R300_GB_POINT_STUFF_ENABLE
2284 | R300_GB_LINE_STUFF_ENABLE
2285 | R300_GB_TRIANGLE_STUFF_ENABLE
;
2287 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_0
] = 0x66666666;
2288 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_1
] = 0x06666666;
2290 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] =
2291 R300_GB_TILE_ENABLE
| R300_GB_TILE_SIZE_16
/*| R300_GB_SUBPIXEL_1_16*/;
2292 switch (r300
->radeon
.radeonScreen
->num_gb_pipes
) {
2295 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2296 R300_GB_TILE_PIPE_COUNT_RV300
;
2299 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2300 R300_GB_TILE_PIPE_COUNT_R300
;
2303 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2304 R300_GB_TILE_PIPE_COUNT_R420_3P
;
2307 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2308 R300_GB_TILE_PIPE_COUNT_R420
;
2312 /* XXX: set to 0 when fog is disabled? */
2313 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_SELECT
] = R300_GB_FOG_SELECT_1_1_W
;
2315 /* XXX: Enable anti-aliasing? */
2316 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_AA_CONFIG
] = GB_AA_CONFIG_AA_DISABLE
;
2318 r300
->hw
.ga_point_s0
.cmd
[1] = r300PackFloat32(0.0);
2319 r300
->hw
.ga_point_s0
.cmd
[2] = r300PackFloat32(0.0);
2320 r300
->hw
.ga_point_s0
.cmd
[3] = r300PackFloat32(1.0);
2321 r300
->hw
.ga_point_s0
.cmd
[4] = r300PackFloat32(1.0);
2323 r300
->hw
.ga_triangle_stipple
.cmd
[1] = 0x00050005;
2325 r300PointSize(ctx
, 1.0);
2327 r300
->hw
.ga_point_minmax
.cmd
[1] = 0x18000006;
2328 r300
->hw
.ga_point_minmax
.cmd
[2] = 0x00020006;
2329 r300
->hw
.ga_point_minmax
.cmd
[3] = r300PackFloat32(1.0 / 192.0);
2331 r300LineWidth(ctx
, 1.0);
2333 r300
->hw
.ga_line_stipple
.cmd
[1] = 0;
2334 r300
->hw
.ga_line_stipple
.cmd
[2] = r300PackFloat32(0.0);
2335 r300
->hw
.ga_line_stipple
.cmd
[3] = r300PackFloat32(1.0);
2337 r300ShadeModel(ctx
, ctx
->Light
.ShadeModel
);
2339 r300PolygonMode(ctx
, GL_FRONT
, ctx
->Polygon
.FrontMode
);
2340 r300PolygonMode(ctx
, GL_BACK
, ctx
->Polygon
.BackMode
);
2341 r300
->hw
.zbias_cntl
.cmd
[1] = 0x00000000;
2343 r300PolygonOffset(ctx
, ctx
->Polygon
.OffsetFactor
,
2344 ctx
->Polygon
.OffsetUnits
);
2345 r300Enable(ctx
, GL_POLYGON_OFFSET_POINT
, ctx
->Polygon
.OffsetPoint
);
2346 r300Enable(ctx
, GL_POLYGON_OFFSET_LINE
, ctx
->Polygon
.OffsetLine
);
2347 r300Enable(ctx
, GL_POLYGON_OFFSET_FILL
, ctx
->Polygon
.OffsetFill
);
2349 r300
->hw
.su_depth_scale
.cmd
[1] = 0x4B7FFFFF;
2350 r300
->hw
.su_depth_scale
.cmd
[2] = 0x00000000;
2352 r300
->hw
.sc_hyperz
.cmd
[1] = 0x0000001C;
2353 r300
->hw
.sc_hyperz
.cmd
[2] = 0x2DA49525;
2355 r300
->hw
.sc_screendoor
.cmd
[1] = 0x00FFFFFF;
2357 r300
->hw
.us_out_fmt
.cmd
[1] = R500_OUT_FMT_C4_8
|
2358 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2359 r300
->hw
.us_out_fmt
.cmd
[2] = R500_OUT_FMT_UNUSED
|
2360 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2361 r300
->hw
.us_out_fmt
.cmd
[3] = R500_OUT_FMT_UNUSED
|
2362 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2363 r300
->hw
.us_out_fmt
.cmd
[4] = R500_OUT_FMT_UNUSED
|
2364 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2365 r300
->hw
.us_out_fmt
.cmd
[5] = R300_W_FMT_W24
;
2367 r300Enable(ctx
, GL_FOG
, ctx
->Fog
.Enabled
);
2368 r300Fogfv(ctx
, GL_FOG_MODE
, NULL
);
2369 r300Fogfv(ctx
, GL_FOG_DENSITY
, &ctx
->Fog
.Density
);
2370 r300Fogfv(ctx
, GL_FOG_START
, &ctx
->Fog
.Start
);
2371 r300Fogfv(ctx
, GL_FOG_END
, &ctx
->Fog
.End
);
2372 r300Fogfv(ctx
, GL_FOG_COLOR
, ctx
->Fog
.Color
);
2373 r300Fogfv(ctx
, GL_FOG_COORDINATE_SOURCE_EXT
, NULL
);
2375 r300
->hw
.fg_depth_src
.cmd
[1] = 0;
2377 r300
->hw
.rb3d_cctl
.cmd
[1] = 0;
2379 r300BlendColor(ctx
, ctx
->Color
.BlendColor
);
2381 /* Again, r300ClearBuffer uses this */
2382 r300
->hw
.cb
.cmd
[R300_CB_OFFSET
] =
2383 r300
->radeon
.state
.color
.drawOffset
+
2384 r300
->radeon
.radeonScreen
->fbLocation
;
2385 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] = r300
->radeon
.state
.color
.drawPitch
;
2387 if (r300
->radeon
.radeonScreen
->cpp
== 4)
2388 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_ARGB8888
;
2390 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_RGB565
;
2392 if (r300
->radeon
.sarea
->tiling_enabled
)
2393 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_TILE_ENABLE
;
2395 r300
->hw
.rb3d_dither_ctl
.cmd
[1] = 0;
2396 r300
->hw
.rb3d_dither_ctl
.cmd
[2] = 0;
2397 r300
->hw
.rb3d_dither_ctl
.cmd
[3] = 0;
2398 r300
->hw
.rb3d_dither_ctl
.cmd
[4] = 0;
2399 r300
->hw
.rb3d_dither_ctl
.cmd
[5] = 0;
2400 r300
->hw
.rb3d_dither_ctl
.cmd
[6] = 0;
2401 r300
->hw
.rb3d_dither_ctl
.cmd
[7] = 0;
2402 r300
->hw
.rb3d_dither_ctl
.cmd
[8] = 0;
2403 r300
->hw
.rb3d_dither_ctl
.cmd
[9] = 0;
2405 r300
->hw
.rb3d_aaresolve_ctl
.cmd
[1] = 0;
2407 r300
->hw
.rb3d_discard_src_pixel_lte_threshold
.cmd
[1] = 0x00000000;
2408 r300
->hw
.rb3d_discard_src_pixel_lte_threshold
.cmd
[2] = 0xffffffff;
2410 r300
->hw
.zb
.cmd
[R300_ZB_OFFSET
] =
2411 r300
->radeon
.radeonScreen
->depthOffset
+
2412 r300
->radeon
.radeonScreen
->fbLocation
;
2413 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] = r300
->radeon
.radeonScreen
->depthPitch
;
2415 if (r300
->radeon
.sarea
->tiling_enabled
) {
2416 /* XXX: Turn off when clearing buffers ? */
2417 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] |= R300_DEPTHMACROTILE_ENABLE
;
2419 if (ctx
->Visual
.depthBits
== 24)
2420 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] |=
2421 R300_DEPTHMICROTILE_TILED
;
2424 r300
->hw
.zb_depthclearvalue
.cmd
[1] = 0;
2426 switch (ctx
->Visual
.depthBits
) {
2428 r300
->hw
.zstencil_format
.cmd
[1] = R300_DEPTHFORMAT_16BIT_INT_Z
;
2431 r300
->hw
.zstencil_format
.cmd
[1] = R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL
;
2434 fprintf(stderr
, "Error: Unsupported depth %d... exiting\n", ctx
->Visual
.depthBits
);
2438 r300
->hw
.zstencil_format
.cmd
[2] = R300_ZTOP_DISABLE
;
2439 r300
->hw
.zstencil_format
.cmd
[3] = 0x00000003;
2440 r300
->hw
.zstencil_format
.cmd
[4] = 0x00000000;
2441 r300SetEarlyZState(ctx
);
2443 r300
->hw
.unk4F30
.cmd
[1] = 0;
2444 r300
->hw
.unk4F30
.cmd
[2] = 0;
2446 r300
->hw
.zb_hiz_offset
.cmd
[1] = 0;
2448 r300
->hw
.zb_hiz_pitch
.cmd
[1] = 0;
2450 r300VapCntl(r300
, 0, 0, 0);
2452 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_0
] = 0;
2453 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_1
] = 0;
2454 r300
->hw
.vps
.cmd
[R300_VPS_POINTSIZE
] = r300PackFloat32(1.0);
2455 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_3
] = 0;
2458 r300
->hw
.all_dirty
= GL_TRUE
;
2461 void r300UpdateShaders(r300ContextPtr rmesa
)
2464 struct r300_vertex_program
*vp
;
2467 ctx
= rmesa
->radeon
.glCtx
;
2469 if (rmesa
->NewGLState
&& hw_tcl_on
) {
2470 rmesa
->NewGLState
= 0;
2472 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
2473 rmesa
->temp_attrib
[i
] =
2474 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
];
2475 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] =
2476 &rmesa
->dummy_attrib
[i
];
2479 _tnl_UpdateFixedFunctionProgram(ctx
);
2481 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
2482 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] =
2483 rmesa
->temp_attrib
[i
];
2486 r300SelectVertexShader(rmesa
);
2487 vp
= (struct r300_vertex_program
*)
2488 CURRENT_VERTEX_SHADER(ctx
);
2489 /*if (vp->translated == GL_FALSE)
2490 r300TranslateVertexShader(vp); */
2491 if (vp
->translated
== GL_FALSE
) {
2492 fprintf(stderr
, "Failing back to sw-tcl\n");
2493 hw_tcl_on
= future_hw_tcl_on
= 0;
2494 r300ResetHwState(rmesa
);
2496 r300UpdateStateParameters(ctx
, _NEW_PROGRAM
);
2500 r300UpdateStateParameters(ctx
, _NEW_PROGRAM
);
2503 static const GLfloat
*get_fragmentprogram_constant(GLcontext
*ctx
,
2504 struct gl_program
*program
, struct prog_src_register srcreg
)
2506 static const GLfloat dummy
[4] = { 0, 0, 0, 0 };
2508 switch(srcreg
.File
) {
2509 case PROGRAM_LOCAL_PARAM
:
2510 return program
->LocalParams
[srcreg
.Index
];
2511 case PROGRAM_ENV_PARAM
:
2512 return ctx
->FragmentProgram
.Parameters
[srcreg
.Index
];
2513 case PROGRAM_STATE_VAR
:
2514 case PROGRAM_NAMED_PARAM
:
2515 case PROGRAM_CONSTANT
:
2516 return program
->Parameters
->ParameterValues
[srcreg
.Index
];
2518 _mesa_problem(ctx
, "get_fragmentprogram_constant: Unknown\n");
2524 static void r300SetupPixelShader(r300ContextPtr rmesa
)
2526 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
2527 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
2528 (char *)ctx
->FragmentProgram
._Current
;
2529 struct r300_fragment_program_code
*code
;
2532 if (!fp
) /* should only happenen once, just after context is created */
2535 r300TranslateFragmentShader(rmesa
, fp
);
2536 if (!fp
->translated
) {
2537 fprintf(stderr
, "%s: No valid fragment shader, exiting\n",
2543 r300SetupTextures(ctx
);
2545 R300_STATECHANGE(rmesa
, fpi
[0]);
2546 R300_STATECHANGE(rmesa
, fpi
[1]);
2547 R300_STATECHANGE(rmesa
, fpi
[2]);
2548 R300_STATECHANGE(rmesa
, fpi
[3]);
2549 rmesa
->hw
.fpi
[0].cmd
[R300_FPI_CMD_0
] = cmdpacket0(R300_US_ALU_RGB_INST_0
, code
->alu
.length
);
2550 rmesa
->hw
.fpi
[1].cmd
[R300_FPI_CMD_0
] = cmdpacket0(R300_US_ALU_RGB_ADDR_0
, code
->alu
.length
);
2551 rmesa
->hw
.fpi
[2].cmd
[R300_FPI_CMD_0
] = cmdpacket0(R300_US_ALU_ALPHA_INST_0
, code
->alu
.length
);
2552 rmesa
->hw
.fpi
[3].cmd
[R300_FPI_CMD_0
] = cmdpacket0(R300_US_ALU_ALPHA_ADDR_0
, code
->alu
.length
);
2553 for (i
= 0; i
< code
->alu
.length
; i
++) {
2554 rmesa
->hw
.fpi
[0].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst0
;
2555 rmesa
->hw
.fpi
[1].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst1
;
2556 rmesa
->hw
.fpi
[2].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst2
;
2557 rmesa
->hw
.fpi
[3].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst3
;
2560 R300_STATECHANGE(rmesa
, fp
);
2561 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL0
] = code
->cur_node
| (code
->first_node_has_tex
<< 3);
2562 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL1
] = code
->max_temp_idx
;
2563 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL2
] =
2564 (0 << R300_PFS_CNTL_ALU_OFFSET_SHIFT
) |
2565 ((code
->alu
.length
-1) << R300_PFS_CNTL_ALU_END_SHIFT
) |
2566 (0 << R300_PFS_CNTL_TEX_OFFSET_SHIFT
) |
2567 ((code
->tex
.length
? code
->tex
.length
-1 : 0) << R300_PFS_CNTL_TEX_END_SHIFT
);
2568 /* I just want to say, the way these nodes are stored.. weird.. */
2569 for (i
= 0, k
= (4 - (code
->cur_node
+ 1)); i
< 4; i
++, k
++) {
2570 if (i
< (code
->cur_node
+ 1)) {
2571 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+ k
] =
2572 (code
->node
[i
].alu_offset
<< R300_ALU_START_SHIFT
) |
2573 (code
->node
[i
].alu_end
<< R300_ALU_SIZE_SHIFT
) |
2574 (code
->node
[i
].tex_offset
<< R300_TEX_START_SHIFT
) |
2575 (code
->node
[i
].tex_end
<< R300_TEX_SIZE_SHIFT
) |
2576 code
->node
[i
].flags
;
2578 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+ (3 - i
)] = 0;
2582 R300_STATECHANGE(rmesa
, fpp
);
2583 rmesa
->hw
.fpp
.cmd
[R300_FPP_CMD_0
] = cmdpacket0(R300_PFS_PARAM_0_X
, code
->const_nr
* 4);
2584 for (i
= 0; i
< code
->const_nr
; i
++) {
2585 const GLfloat
*constant
= get_fragmentprogram_constant(ctx
,
2586 &fp
->mesa_program
.Base
, code
->constant
[i
]);
2587 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 0] = r300PackFloat24(constant
[0]);
2588 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 1] = r300PackFloat24(constant
[1]);
2589 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 2] = r300PackFloat24(constant
[2]);
2590 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 3] = r300PackFloat24(constant
[3]);
2594 #define bump_r500fp_count(ptr, new_count) do{\
2595 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
2596 int _nc=(new_count)/6; \
2597 assert(_nc < 256); \
2598 if(_nc>_p->r500fp.count)_p->r500fp.count=_nc;\
2601 #define bump_r500fp_const_count(ptr, new_count) do{\
2602 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
2603 int _nc=(new_count)/4; \
2604 assert(_nc < 256); \
2605 if(_nc>_p->r500fp.count)_p->r500fp.count=_nc;\
2608 static void r500SetupPixelShader(r300ContextPtr rmesa
)
2610 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
2611 struct r500_fragment_program
*fp
= (struct r500_fragment_program
*)
2612 (char *)ctx
->FragmentProgram
._Current
;
2614 struct r500_fragment_program_code
*code
;
2616 if (!fp
) /* should only happenen once, just after context is created */
2619 ((drm_r300_cmd_header_t
*) rmesa
->hw
.r500fp
.cmd
)->r500fp
.count
= 0;
2620 ((drm_r300_cmd_header_t
*) rmesa
->hw
.r500fp_const
.cmd
)->r500fp
.count
= 0;
2622 r500TranslateFragmentShader(rmesa
, fp
);
2623 if (!fp
->translated
) {
2624 fprintf(stderr
, "%s: No valid fragment shader, exiting\n",
2630 if (fp
->mesa_program
.FogOption
!= GL_NONE
) {
2631 /* Enable HW fog. Try not to squish GL context.
2632 * (Anybody sane remembered to set glFog() opts first!) */
2633 r300SetFogState(ctx
, GL_TRUE
);
2634 ctx
->Fog
.Mode
= fp
->mesa_program
.FogOption
;
2635 r300Fogfv(ctx
, GL_FOG_MODE
, NULL
);
2637 /* Make sure HW is matching GL context. */
2638 r300SetFogState(ctx
, ctx
->Fog
.Enabled
);
2640 r300SetupTextures(ctx
);
2642 R300_STATECHANGE(rmesa
, fp
);
2643 rmesa
->hw
.fp
.cmd
[R500_FP_PIXSIZE
] = code
->max_temp_idx
;
2645 rmesa
->hw
.fp
.cmd
[R500_FP_CODE_ADDR
] =
2646 R500_US_CODE_START_ADDR(code
->inst_offset
) |
2647 R500_US_CODE_END_ADDR(code
->inst_end
);
2648 rmesa
->hw
.fp
.cmd
[R500_FP_CODE_RANGE
] =
2649 R500_US_CODE_RANGE_ADDR(code
->inst_offset
) |
2650 R500_US_CODE_RANGE_SIZE(code
->inst_end
);
2651 rmesa
->hw
.fp
.cmd
[R500_FP_CODE_OFFSET
] =
2652 R500_US_CODE_OFFSET_ADDR(0); /* FIXME when we add flow control */
2654 R300_STATECHANGE(rmesa
, r500fp
);
2655 /* Emit our shader... */
2656 for (i
= 0; i
< code
->inst_end
+1; i
++) {
2657 rmesa
->hw
.r500fp
.cmd
[i
*6+1] = code
->inst
[i
].inst0
;
2658 rmesa
->hw
.r500fp
.cmd
[i
*6+2] = code
->inst
[i
].inst1
;
2659 rmesa
->hw
.r500fp
.cmd
[i
*6+3] = code
->inst
[i
].inst2
;
2660 rmesa
->hw
.r500fp
.cmd
[i
*6+4] = code
->inst
[i
].inst3
;
2661 rmesa
->hw
.r500fp
.cmd
[i
*6+5] = code
->inst
[i
].inst4
;
2662 rmesa
->hw
.r500fp
.cmd
[i
*6+6] = code
->inst
[i
].inst5
;
2665 bump_r500fp_count(rmesa
->hw
.r500fp
.cmd
, (code
->inst_end
+ 1) * 6);
2667 R300_STATECHANGE(rmesa
, r500fp_const
);
2668 for (i
= 0; i
< code
->const_nr
; i
++) {
2669 const GLfloat
*constant
= get_fragmentprogram_constant(ctx
,
2670 &fp
->mesa_program
.Base
, code
->constant
[i
]);
2671 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 0] = r300PackFloat32(constant
[0]);
2672 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 1] = r300PackFloat32(constant
[1]);
2673 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 2] = r300PackFloat32(constant
[2]);
2674 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 3] = r300PackFloat32(constant
[3]);
2676 bump_r500fp_const_count(rmesa
->hw
.r500fp_const
.cmd
, code
->const_nr
* 4);
2680 void r300UpdateShaderStates(r300ContextPtr rmesa
)
2683 ctx
= rmesa
->radeon
.glCtx
;
2685 r300UpdateTextureState(ctx
);
2686 r300SetEarlyZState(ctx
);
2688 GLuint fgdepthsrc
= R300_FG_DEPTH_SRC_SCAN
;
2689 if (current_fragment_program_writes_depth(ctx
))
2690 fgdepthsrc
= R300_FG_DEPTH_SRC_SHADER
;
2691 if (fgdepthsrc
!= rmesa
->hw
.fg_depth_src
.cmd
[1]) {
2692 R300_STATECHANGE(rmesa
, fg_depth_src
);
2693 rmesa
->hw
.fg_depth_src
.cmd
[1] = fgdepthsrc
;
2696 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
2697 r500SetupPixelShader(rmesa
);
2699 r300SetupPixelShader(rmesa
);
2701 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
2702 r500SetupRSUnit(ctx
);
2704 r300SetupRSUnit(ctx
);
2706 if ((rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
2707 r300SetupVertexProgram(rmesa
);
2712 * Called by Mesa after an internal state update.
2714 static void r300InvalidateState(GLcontext
* ctx
, GLuint new_state
)
2716 r300ContextPtr r300
= R300_CONTEXT(ctx
);
2718 _swrast_InvalidateState(ctx
, new_state
);
2719 _swsetup_InvalidateState(ctx
, new_state
);
2720 _vbo_InvalidateState(ctx
, new_state
);
2721 _tnl_InvalidateState(ctx
, new_state
);
2722 _ae_invalidate_state(ctx
, new_state
);
2724 if (new_state
& (_NEW_BUFFERS
| _NEW_COLOR
| _NEW_PIXEL
)) {
2725 r300UpdateDrawBuffer(ctx
);
2728 r300UpdateStateParameters(ctx
, new_state
);
2730 r300
->NewGLState
|= new_state
;
2734 * Calculate initial hardware state and register state functions.
2735 * Assumes that the command buffer and state atoms have been
2736 * initialized already.
2738 void r300InitState(r300ContextPtr r300
)
2740 GLcontext
*ctx
= r300
->radeon
.glCtx
;
2743 radeonInitState(&r300
->radeon
);
2745 switch (ctx
->Visual
.depthBits
) {
2747 r300
->state
.depth
.scale
= 1.0 / (GLfloat
) 0xffff;
2748 depth_fmt
= R300_DEPTHFORMAT_16BIT_INT_Z
;
2751 r300
->state
.depth
.scale
= 1.0 / (GLfloat
) 0xffffff;
2752 depth_fmt
= R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL
;
2755 fprintf(stderr
, "Error: Unsupported depth %d... exiting\n",
2756 ctx
->Visual
.depthBits
);
2760 /* Only have hw stencil when depth buffer is 24 bits deep */
2761 r300
->state
.stencil
.hw_stencil
= (ctx
->Visual
.stencilBits
> 0 &&
2762 ctx
->Visual
.depthBits
== 24);
2764 memset(&(r300
->state
.texture
), 0, sizeof(r300
->state
.texture
));
2766 r300ResetHwState(r300
);
2769 static void r300RenderMode(GLcontext
* ctx
, GLenum mode
)
2771 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
2776 void r300UpdateClipPlanes( GLcontext
*ctx
)
2778 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
2781 for (p
= 0; p
< ctx
->Const
.MaxClipPlanes
; p
++) {
2782 if (ctx
->Transform
.ClipPlanesEnabled
& (1 << p
)) {
2783 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
2785 R300_STATECHANGE( rmesa
, vpucp
[p
] );
2786 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_X
] = ip
[0];
2787 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_Y
] = ip
[1];
2788 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_Z
] = ip
[2];
2789 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_W
] = ip
[3];
2795 * Initialize driver's state callback functions
2797 void r300InitStateFuncs(struct dd_function_table
*functions
)
2799 radeonInitStateFuncs(functions
);
2801 functions
->UpdateState
= r300InvalidateState
;
2802 functions
->AlphaFunc
= r300AlphaFunc
;
2803 functions
->BlendColor
= r300BlendColor
;
2804 functions
->BlendEquationSeparate
= r300BlendEquationSeparate
;
2805 functions
->BlendFuncSeparate
= r300BlendFuncSeparate
;
2806 functions
->Enable
= r300Enable
;
2807 functions
->ColorMask
= r300ColorMask
;
2808 functions
->DepthFunc
= r300DepthFunc
;
2809 functions
->DepthMask
= r300DepthMask
;
2810 functions
->CullFace
= r300CullFace
;
2811 functions
->Fogfv
= r300Fogfv
;
2812 functions
->FrontFace
= r300FrontFace
;
2813 functions
->ShadeModel
= r300ShadeModel
;
2814 functions
->LogicOpcode
= r300LogicOpcode
;
2816 /* ARB_point_parameters */
2817 functions
->PointParameterfv
= r300PointParameter
;
2819 /* Stencil related */
2820 functions
->StencilFuncSeparate
= r300StencilFuncSeparate
;
2821 functions
->StencilMaskSeparate
= r300StencilMaskSeparate
;
2822 functions
->StencilOpSeparate
= r300StencilOpSeparate
;
2824 /* Viewport related */
2825 functions
->Viewport
= r300Viewport
;
2826 functions
->DepthRange
= r300DepthRange
;
2827 functions
->PointSize
= r300PointSize
;
2828 functions
->LineWidth
= r300LineWidth
;
2830 functions
->PolygonOffset
= r300PolygonOffset
;
2831 functions
->PolygonMode
= r300PolygonMode
;
2833 functions
->RenderMode
= r300RenderMode
;
2835 functions
->ClipPlane
= r300ClipPlane
;