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/framebuffer.h"
46 #include "main/simple_list.h"
47 #include "main/api_arrayelt.h"
48 #include "main/texformat.h"
50 #include "swrast/swrast.h"
51 #include "swrast_setup/swrast_setup.h"
52 #include "shader/prog_parameter.h"
53 #include "shader/prog_statevars.h"
57 #include "r300_context.h"
58 #include "r300_ioctl.h"
59 #include "r300_state.h"
61 #include "r300_emit.h"
62 #include "r300_fragprog.h"
65 #include "drirenderbuffer.h"
67 extern int future_hw_tcl_on
;
68 extern void _tnl_UpdateFixedFunctionProgram(GLcontext
* ctx
);
70 static void r300BlendColor(GLcontext
* ctx
, const GLfloat cf
[4])
72 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
74 R300_STATECHANGE(rmesa
, blend_color
);
76 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
) {
77 GLuint r
= IROUND(cf
[0]*1023.0f
);
78 GLuint g
= IROUND(cf
[1]*1023.0f
);
79 GLuint b
= IROUND(cf
[2]*1023.0f
);
80 GLuint a
= IROUND(cf
[3]*1023.0f
);
82 rmesa
->hw
.blend_color
.cmd
[1] = r
| (a
<< 16);
83 rmesa
->hw
.blend_color
.cmd
[2] = b
| (g
<< 16);
86 CLAMPED_FLOAT_TO_UBYTE(color
[0], cf
[0]);
87 CLAMPED_FLOAT_TO_UBYTE(color
[1], cf
[1]);
88 CLAMPED_FLOAT_TO_UBYTE(color
[2], cf
[2]);
89 CLAMPED_FLOAT_TO_UBYTE(color
[3], cf
[3]);
91 rmesa
->hw
.blend_color
.cmd
[1] = PACK_COLOR_8888(color
[3], color
[0],
97 * Calculate the hardware blend factor setting. This same function is used
98 * for source and destination of both alpha and RGB.
101 * The hardware register value for the specified blend factor. This value
102 * will need to be shifted into the correct position for either source or
103 * destination factor.
106 * Since the two cases where source and destination are handled differently
107 * are essentially error cases, they should never happen. Determine if these
108 * cases can be removed.
110 static int blend_factor(GLenum factor
, GLboolean is_src
)
114 return R300_BLEND_GL_ZERO
;
117 return R300_BLEND_GL_ONE
;
120 return R300_BLEND_GL_DST_COLOR
;
122 case GL_ONE_MINUS_DST_COLOR
:
123 return R300_BLEND_GL_ONE_MINUS_DST_COLOR
;
126 return R300_BLEND_GL_SRC_COLOR
;
128 case GL_ONE_MINUS_SRC_COLOR
:
129 return R300_BLEND_GL_ONE_MINUS_SRC_COLOR
;
132 return R300_BLEND_GL_SRC_ALPHA
;
134 case GL_ONE_MINUS_SRC_ALPHA
:
135 return R300_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
138 return R300_BLEND_GL_DST_ALPHA
;
140 case GL_ONE_MINUS_DST_ALPHA
:
141 return R300_BLEND_GL_ONE_MINUS_DST_ALPHA
;
143 case GL_SRC_ALPHA_SATURATE
:
144 return (is_src
) ? R300_BLEND_GL_SRC_ALPHA_SATURATE
:
147 case GL_CONSTANT_COLOR
:
148 return R300_BLEND_GL_CONST_COLOR
;
150 case GL_ONE_MINUS_CONSTANT_COLOR
:
151 return R300_BLEND_GL_ONE_MINUS_CONST_COLOR
;
153 case GL_CONSTANT_ALPHA
:
154 return R300_BLEND_GL_CONST_ALPHA
;
156 case GL_ONE_MINUS_CONSTANT_ALPHA
:
157 return R300_BLEND_GL_ONE_MINUS_CONST_ALPHA
;
160 fprintf(stderr
, "unknown blend factor %x\n", factor
);
161 return (is_src
) ? R300_BLEND_GL_ONE
: R300_BLEND_GL_ZERO
;
167 * Sets both the blend equation and the blend function.
168 * This is done in a single
169 * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX)
170 * change the interpretation of the blend function.
171 * Also, make sure that blend function and blend equation are set to their
172 * default value if color blending is not enabled, since at least blend
173 * equations GL_MIN and GL_FUNC_REVERSE_SUBTRACT will cause wrong results
174 * otherwise for unknown reasons.
177 /* helper function */
178 static void r300SetBlendCntl(r300ContextPtr r300
, int func
, int eqn
,
179 int cbits
, int funcA
, int eqnA
)
181 GLuint new_ablend
, new_cblend
;
185 "eqnA=%08x funcA=%08x eqn=%08x func=%08x cbits=%08x\n",
186 eqnA
, funcA
, eqn
, func
, cbits
);
188 new_ablend
= eqnA
| funcA
;
189 new_cblend
= eqn
| func
;
191 /* Some blend factor combinations don't seem to work when the
192 * BLEND_NO_SEPARATE bit is set.
194 * Especially problematic candidates are the ONE_MINUS_* flags,
195 * but I can't see a real pattern.
198 if (new_ablend
== new_cblend
) {
199 new_cblend
|= R300_DISCARD_SRC_PIXELS_SRC_ALPHA_0
;
204 if ((new_ablend
!= r300
->hw
.bld
.cmd
[R300_BLD_ABLEND
]) ||
205 (new_cblend
!= r300
->hw
.bld
.cmd
[R300_BLD_CBLEND
])) {
206 R300_STATECHANGE(r300
, bld
);
207 r300
->hw
.bld
.cmd
[R300_BLD_ABLEND
] = new_ablend
;
208 r300
->hw
.bld
.cmd
[R300_BLD_CBLEND
] = new_cblend
;
212 static void r300SetBlendState(GLcontext
* ctx
)
214 r300ContextPtr r300
= R300_CONTEXT(ctx
);
215 int func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
216 (R300_BLEND_GL_ZERO
<< R300_DST_BLEND_SHIFT
);
217 int eqn
= R300_COMB_FCN_ADD_CLAMP
;
218 int funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
219 (R300_BLEND_GL_ZERO
<< R300_DST_BLEND_SHIFT
);
220 int eqnA
= R300_COMB_FCN_ADD_CLAMP
;
222 if (RGBA_LOGICOP_ENABLED(ctx
) || !ctx
->Color
.BlendEnabled
) {
223 r300SetBlendCntl(r300
, func
, eqn
, 0, func
, eqn
);
228 (blend_factor(ctx
->Color
.BlendSrcRGB
, GL_TRUE
) <<
229 R300_SRC_BLEND_SHIFT
) | (blend_factor(ctx
->Color
.BlendDstRGB
,
231 R300_DST_BLEND_SHIFT
);
233 switch (ctx
->Color
.BlendEquationRGB
) {
235 eqn
= R300_COMB_FCN_ADD_CLAMP
;
238 case GL_FUNC_SUBTRACT
:
239 eqn
= R300_COMB_FCN_SUB_CLAMP
;
242 case GL_FUNC_REVERSE_SUBTRACT
:
243 eqn
= R300_COMB_FCN_RSUB_CLAMP
;
247 eqn
= R300_COMB_FCN_MIN
;
248 func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
249 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
253 eqn
= R300_COMB_FCN_MAX
;
254 func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
255 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
260 "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
261 __FUNCTION__
, __LINE__
, ctx
->Color
.BlendEquationRGB
);
266 (blend_factor(ctx
->Color
.BlendSrcA
, GL_TRUE
) <<
267 R300_SRC_BLEND_SHIFT
) | (blend_factor(ctx
->Color
.BlendDstA
,
269 R300_DST_BLEND_SHIFT
);
271 switch (ctx
->Color
.BlendEquationA
) {
273 eqnA
= R300_COMB_FCN_ADD_CLAMP
;
276 case GL_FUNC_SUBTRACT
:
277 eqnA
= R300_COMB_FCN_SUB_CLAMP
;
280 case GL_FUNC_REVERSE_SUBTRACT
:
281 eqnA
= R300_COMB_FCN_RSUB_CLAMP
;
285 eqnA
= R300_COMB_FCN_MIN
;
286 funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
287 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
291 eqnA
= R300_COMB_FCN_MAX
;
292 funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
293 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
298 "[%s:%u] Invalid A blend equation (0x%04x).\n",
299 __FUNCTION__
, __LINE__
, ctx
->Color
.BlendEquationA
);
303 r300SetBlendCntl(r300
,
305 (R300_SEPARATE_ALPHA_ENABLE
|
307 R300_ALPHA_BLEND_ENABLE
), funcA
, eqnA
);
310 static void r300BlendEquationSeparate(GLcontext
* ctx
,
311 GLenum modeRGB
, GLenum modeA
)
313 r300SetBlendState(ctx
);
316 static void r300BlendFuncSeparate(GLcontext
* ctx
,
317 GLenum sfactorRGB
, GLenum dfactorRGB
,
318 GLenum sfactorA
, GLenum dfactorA
)
320 r300SetBlendState(ctx
);
324 * Translate LogicOp enums into hardware representation.
325 * Both use a very logical bit-wise layout, but unfortunately the order
326 * of bits is reversed.
328 static GLuint
translate_logicop(GLenum logicop
)
330 GLuint bits
= logicop
- GL_CLEAR
;
331 bits
= ((bits
& 1) << 3) | ((bits
& 2) << 1) | ((bits
& 4) >> 1) | ((bits
& 8) >> 3);
332 return bits
<< R300_RB3D_ROPCNTL_ROP_SHIFT
;
336 * Used internally to update the r300->hw hardware state to match the
337 * current OpenGL state.
339 static void r300SetLogicOpState(GLcontext
*ctx
)
341 r300ContextPtr r300
= R300_CONTEXT(ctx
);
342 R300_STATECHANGE(r300
, rop
);
343 if (RGBA_LOGICOP_ENABLED(ctx
)) {
344 r300
->hw
.rop
.cmd
[1] = R300_RB3D_ROPCNTL_ROP_ENABLE
|
345 translate_logicop(ctx
->Color
.LogicOp
);
347 r300
->hw
.rop
.cmd
[1] = 0;
352 * Called by Mesa when an application program changes the LogicOp state
355 static void r300LogicOpcode(GLcontext
*ctx
, GLenum logicop
)
357 if (RGBA_LOGICOP_ENABLED(ctx
))
358 r300SetLogicOpState(ctx
);
361 static void r300ClipPlane( GLcontext
*ctx
, GLenum plane
, const GLfloat
*eq
)
363 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
367 /* no VAP UCP on non-TCL chipsets */
368 if (!(rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
371 p
= (GLint
) plane
- (GLint
) GL_CLIP_PLANE0
;
372 ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
374 R300_STATECHANGE( rmesa
, vpucp
[p
] );
375 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_X
] = ip
[0];
376 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_Y
] = ip
[1];
377 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_Z
] = ip
[2];
378 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_W
] = ip
[3];
381 static void r300SetClipPlaneState(GLcontext
* ctx
, GLenum cap
, GLboolean state
)
383 r300ContextPtr r300
= R300_CONTEXT(ctx
);
386 /* no VAP UCP on non-TCL chipsets */
387 if (!(r300
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
390 p
= cap
- GL_CLIP_PLANE0
;
391 R300_STATECHANGE(r300
, vap_clip_cntl
);
393 r300
->hw
.vap_clip_cntl
.cmd
[1] |= (R300_VAP_UCP_ENABLE_0
<< p
);
394 r300ClipPlane(ctx
, cap
, NULL
);
396 r300
->hw
.vap_clip_cntl
.cmd
[1] &= ~(R300_VAP_UCP_ENABLE_0
<< p
);
401 * Update our tracked culling state based on Mesa's state.
403 static void r300UpdateCulling(GLcontext
* ctx
)
405 r300ContextPtr r300
= R300_CONTEXT(ctx
);
408 if (ctx
->Polygon
.CullFlag
) {
409 switch (ctx
->Polygon
.CullFaceMode
) {
411 val
= R300_CULL_FRONT
;
414 val
= R300_CULL_BACK
;
416 case GL_FRONT_AND_BACK
:
417 val
= R300_CULL_FRONT
| R300_CULL_BACK
;
424 switch (ctx
->Polygon
.FrontFace
) {
426 val
|= R300_FRONT_FACE_CW
;
429 val
|= R300_FRONT_FACE_CCW
;
435 R300_STATECHANGE(r300
, cul
);
436 r300
->hw
.cul
.cmd
[R300_CUL_CULL
] = val
;
439 static void r300SetPolygonOffsetState(GLcontext
* ctx
, GLboolean state
)
441 r300ContextPtr r300
= R300_CONTEXT(ctx
);
443 R300_STATECHANGE(r300
, occlusion_cntl
);
445 r300
->hw
.occlusion_cntl
.cmd
[1] |= (3 << 0);
447 r300
->hw
.occlusion_cntl
.cmd
[1] &= ~(3 << 0);
451 static GLboolean
current_fragment_program_writes_depth(GLcontext
* ctx
)
453 r300ContextPtr r300
= R300_CONTEXT(ctx
);
455 if (r300
->radeon
.radeonScreen
->chip_family
< CHIP_FAMILY_RV515
) {
456 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
457 (char *)ctx
->FragmentProgram
._Current
;
458 return (fp
&& fp
->WritesDepth
);
460 struct r500_fragment_program
* fp
=
461 (struct r500_fragment_program
*)(char*)
462 ctx
->FragmentProgram
._Current
;
463 return (fp
&& fp
->writes_depth
);
467 static void r300SetEarlyZState(GLcontext
* ctx
)
469 r300ContextPtr r300
= R300_CONTEXT(ctx
);
470 GLuint topZ
= R300_ZTOP_ENABLE
;
472 if (ctx
->Color
.AlphaEnabled
&& ctx
->Color
.AlphaFunc
!= GL_ALWAYS
)
473 topZ
= R300_ZTOP_DISABLE
;
474 if (current_fragment_program_writes_depth(ctx
))
475 topZ
= R300_ZTOP_DISABLE
;
477 if (topZ
!= r300
->hw
.zstencil_format
.cmd
[2]) {
478 /* Note: This completely reemits the stencil format.
479 * I have not tested whether this is strictly necessary,
480 * or if emitting a write to ZB_ZTOP is enough.
482 R300_STATECHANGE(r300
, zstencil_format
);
483 r300
->hw
.zstencil_format
.cmd
[2] = topZ
;
487 static void r300SetAlphaState(GLcontext
* ctx
)
489 r300ContextPtr r300
= R300_CONTEXT(ctx
);
491 uint32_t pp_misc
= 0x0;
492 GLboolean really_enabled
= ctx
->Color
.AlphaEnabled
;
494 CLAMPED_FLOAT_TO_UBYTE(refByte
, ctx
->Color
.AlphaRef
);
496 switch (ctx
->Color
.AlphaFunc
) {
498 pp_misc
|= R300_FG_ALPHA_FUNC_NEVER
;
501 pp_misc
|= R300_FG_ALPHA_FUNC_LESS
;
504 pp_misc
|= R300_FG_ALPHA_FUNC_EQUAL
;
507 pp_misc
|= R300_FG_ALPHA_FUNC_LE
;
510 pp_misc
|= R300_FG_ALPHA_FUNC_GREATER
;
513 pp_misc
|= R300_FG_ALPHA_FUNC_NOTEQUAL
;
516 pp_misc
|= R300_FG_ALPHA_FUNC_GE
;
519 /*pp_misc |= FG_ALPHA_FUNC_ALWAYS; */
520 really_enabled
= GL_FALSE
;
524 if (really_enabled
) {
525 pp_misc
|= R300_FG_ALPHA_FUNC_ENABLE
;
526 pp_misc
|= R500_FG_ALPHA_FUNC_8BIT
;
527 pp_misc
|= (refByte
& R300_FG_ALPHA_FUNC_VAL_MASK
);
532 R300_STATECHANGE(r300
, at
);
533 r300
->hw
.at
.cmd
[R300_AT_ALPHA_TEST
] = pp_misc
;
534 r300
->hw
.at
.cmd
[R300_AT_UNKNOWN
] = 0;
536 r300SetEarlyZState(ctx
);
539 static void r300AlphaFunc(GLcontext
* ctx
, GLenum func
, GLfloat ref
)
543 r300SetAlphaState(ctx
);
546 static int translate_func(int func
)
550 return R300_ZS_NEVER
;
554 return R300_ZS_EQUAL
;
556 return R300_ZS_LEQUAL
;
558 return R300_ZS_GREATER
;
560 return R300_ZS_NOTEQUAL
;
562 return R300_ZS_GEQUAL
;
564 return R300_ZS_ALWAYS
;
569 static void r300SetDepthState(GLcontext
* ctx
)
571 r300ContextPtr r300
= R300_CONTEXT(ctx
);
573 R300_STATECHANGE(r300
, zs
);
574 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &= R300_STENCIL_ENABLE
|R300_STENCIL_FRONT_BACK
;
575 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= ~(R300_ZS_MASK
<< R300_Z_FUNC_SHIFT
);
577 if (ctx
->Depth
.Test
) {
578 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_Z_ENABLE
;
580 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_Z_WRITE_ENABLE
;
581 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
582 translate_func(ctx
->Depth
.Func
) << R300_Z_FUNC_SHIFT
;
585 r300SetEarlyZState(ctx
);
588 static void r300SetStencilState(GLcontext
* ctx
, GLboolean state
)
590 r300ContextPtr r300
= R300_CONTEXT(ctx
);
591 GLboolean hw_stencil
= GL_FALSE
;
592 if (ctx
->DrawBuffer
) {
593 struct radeon_renderbuffer
*rrbStencil
594 = radeon_get_renderbuffer(ctx
->DrawBuffer
, BUFFER_STENCIL
);
595 hw_stencil
= (rrbStencil
&& rrbStencil
->bo
);
599 R300_STATECHANGE(r300
, zs
);
601 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |=
604 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &=
605 ~R300_STENCIL_ENABLE
;
609 FALLBACK(&r300
->radeon
, RADEON_FALLBACK_STENCIL
, state
);
614 static void r300UpdatePolygonMode(GLcontext
* ctx
)
616 r300ContextPtr r300
= R300_CONTEXT(ctx
);
617 uint32_t hw_mode
= R300_GA_POLY_MODE_DISABLE
;
619 /* Only do something if a polygon mode is wanted, default is GL_FILL */
620 if (ctx
->Polygon
.FrontMode
!= GL_FILL
||
621 ctx
->Polygon
.BackMode
!= GL_FILL
) {
624 /* Handle GL_CW (clock wise and GL_CCW (counter clock wise)
625 * correctly by selecting the correct front and back face
627 if (ctx
->Polygon
.FrontFace
== GL_CCW
) {
628 f
= ctx
->Polygon
.FrontMode
;
629 b
= ctx
->Polygon
.BackMode
;
631 f
= ctx
->Polygon
.BackMode
;
632 b
= ctx
->Polygon
.FrontMode
;
635 /* Enable polygon mode */
636 hw_mode
|= R300_GA_POLY_MODE_DUAL
;
640 hw_mode
|= R300_GA_POLY_MODE_FRONT_PTYPE_LINE
;
643 hw_mode
|= R300_GA_POLY_MODE_FRONT_PTYPE_POINT
;
646 hw_mode
|= R300_GA_POLY_MODE_FRONT_PTYPE_TRI
;
652 hw_mode
|= R300_GA_POLY_MODE_BACK_PTYPE_LINE
;
655 hw_mode
|= R300_GA_POLY_MODE_BACK_PTYPE_POINT
;
658 hw_mode
|= R300_GA_POLY_MODE_BACK_PTYPE_TRI
;
663 if (r300
->hw
.polygon_mode
.cmd
[1] != hw_mode
) {
664 R300_STATECHANGE(r300
, polygon_mode
);
665 r300
->hw
.polygon_mode
.cmd
[1] = hw_mode
;
668 r300
->hw
.polygon_mode
.cmd
[2] = 0x00000001;
669 r300
->hw
.polygon_mode
.cmd
[3] = 0x00000000;
673 * Change the culling mode.
675 * \note Mesa already filters redundant calls to this function.
677 static void r300CullFace(GLcontext
* ctx
, GLenum mode
)
681 r300UpdateCulling(ctx
);
685 * Change the polygon orientation.
687 * \note Mesa already filters redundant calls to this function.
689 static void r300FrontFace(GLcontext
* ctx
, GLenum mode
)
693 r300UpdateCulling(ctx
);
694 r300UpdatePolygonMode(ctx
);
698 * Change the depth testing function.
700 * \note Mesa already filters redundant calls to this function.
702 static void r300DepthFunc(GLcontext
* ctx
, GLenum func
)
705 r300SetDepthState(ctx
);
709 * Enable/Disable depth writing.
711 * \note Mesa already filters redundant calls to this function.
713 static void r300DepthMask(GLcontext
* ctx
, GLboolean mask
)
716 r300SetDepthState(ctx
);
720 * Handle glColorMask()
722 static void r300ColorMask(GLcontext
* ctx
,
723 GLboolean r
, GLboolean g
, GLboolean b
, GLboolean a
)
725 r300ContextPtr r300
= R300_CONTEXT(ctx
);
726 int mask
= (r
? RB3D_COLOR_CHANNEL_MASK_RED_MASK0
: 0) |
727 (g
? RB3D_COLOR_CHANNEL_MASK_GREEN_MASK0
: 0) |
728 (b
? RB3D_COLOR_CHANNEL_MASK_BLUE_MASK0
: 0) |
729 (a
? RB3D_COLOR_CHANNEL_MASK_ALPHA_MASK0
: 0);
731 if (mask
!= r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
]) {
732 R300_STATECHANGE(r300
, cmk
);
733 r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
] = mask
;
737 /* =============================================================
740 static void r300PointSize(GLcontext
* ctx
, GLfloat size
)
742 r300ContextPtr r300
= R300_CONTEXT(ctx
);
743 /* same size limits for AA, non-AA points */
744 size
= CLAMP(size
, ctx
->Const
.MinPointSize
, ctx
->Const
.MaxPointSize
);
746 R300_STATECHANGE(r300
, ps
);
747 r300
->hw
.ps
.cmd
[R300_PS_POINTSIZE
] =
748 ((int)(size
* 6) << R300_POINTSIZE_X_SHIFT
) |
749 ((int)(size
* 6) << R300_POINTSIZE_Y_SHIFT
);
752 static void r300PointParameter(GLcontext
* ctx
, GLenum pname
, const GLfloat
* param
)
754 r300ContextPtr r300
= R300_CONTEXT(ctx
);
757 case GL_POINT_SIZE_MIN
:
758 R300_STATECHANGE(r300
, ga_point_minmax
);
759 r300
->hw
.ga_point_minmax
.cmd
[1] &= ~R300_GA_POINT_MINMAX_MIN_MASK
;
760 r300
->hw
.ga_point_minmax
.cmd
[1] |= (GLuint
)(ctx
->Point
.MinSize
* 6.0);
762 case GL_POINT_SIZE_MAX
:
763 R300_STATECHANGE(r300
, ga_point_minmax
);
764 r300
->hw
.ga_point_minmax
.cmd
[1] &= ~R300_GA_POINT_MINMAX_MAX_MASK
;
765 r300
->hw
.ga_point_minmax
.cmd
[1] |= (GLuint
)(ctx
->Point
.MaxSize
* 6.0)
766 << R300_GA_POINT_MINMAX_MAX_SHIFT
;
768 case GL_POINT_DISTANCE_ATTENUATION
:
770 case GL_POINT_FADE_THRESHOLD_SIZE
:
777 /* =============================================================
780 static void r300LineWidth(GLcontext
* ctx
, GLfloat widthf
)
782 r300ContextPtr r300
= R300_CONTEXT(ctx
);
784 widthf
= CLAMP(widthf
,
785 ctx
->Const
.MinPointSize
,
786 ctx
->Const
.MaxPointSize
);
787 R300_STATECHANGE(r300
, lcntl
);
788 r300
->hw
.lcntl
.cmd
[1] =
789 R300_LINE_CNT_HO
| R300_LINE_CNT_VE
| (int)(widthf
* 6.0);
792 static void r300PolygonMode(GLcontext
* ctx
, GLenum face
, GLenum mode
)
797 r300UpdatePolygonMode(ctx
);
800 /* =============================================================
804 static int translate_stencil_op(int op
)
812 return R300_ZS_REPLACE
;
817 case GL_INCR_WRAP_EXT
:
818 return R300_ZS_INCR_WRAP
;
819 case GL_DECR_WRAP_EXT
:
820 return R300_ZS_DECR_WRAP
;
822 return R300_ZS_INVERT
;
824 WARN_ONCE("Do not know how to translate stencil op");
830 static void r300ShadeModel(GLcontext
* ctx
, GLenum mode
)
832 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
834 R300_STATECHANGE(rmesa
, shade
);
835 rmesa
->hw
.shade
.cmd
[1] = 0x00000002;
838 rmesa
->hw
.shade
.cmd
[2] = R300_RE_SHADE_MODEL_FLAT
;
841 rmesa
->hw
.shade
.cmd
[2] = R300_RE_SHADE_MODEL_SMOOTH
;
846 rmesa
->hw
.shade
.cmd
[3] = 0x00000000;
847 rmesa
->hw
.shade
.cmd
[4] = 0x00000000;
850 static void r300StencilFuncSeparate(GLcontext
* ctx
, GLenum face
,
851 GLenum func
, GLint ref
, GLuint mask
)
853 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
855 ((ctx
->Stencil
.Ref
[0] & 0xff) << R300_STENCILREF_SHIFT
)
856 | ((ctx
->Stencil
.ValueMask
[0] & 0xff) << R300_STENCILMASK_SHIFT
);
857 const unsigned back
= ctx
->Stencil
._BackFace
;
860 R300_STATECHANGE(rmesa
, zs
);
861 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_STENCIL_FRONT_BACK
;
862 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= ~((R300_ZS_MASK
<<
863 R300_S_FRONT_FUNC_SHIFT
)
865 R300_S_BACK_FUNC_SHIFT
));
867 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &=
868 ~((R300_STENCILREF_MASK
<< R300_STENCILREF_SHIFT
) |
869 (R300_STENCILREF_MASK
<< R300_STENCILMASK_SHIFT
));
871 flag
= translate_func(ctx
->Stencil
.Function
[0]);
872 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
873 (flag
<< R300_S_FRONT_FUNC_SHIFT
);
875 flag
= translate_func(ctx
->Stencil
.Function
[back
]);
877 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
878 (flag
<< R300_S_BACK_FUNC_SHIFT
);
879 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |= refmask
;
882 static void r300StencilMaskSeparate(GLcontext
* ctx
, GLenum face
, GLuint mask
)
884 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
886 R300_STATECHANGE(rmesa
, zs
);
887 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &=
888 ~(R300_STENCILREF_MASK
<<
889 R300_STENCILWRITEMASK_SHIFT
);
890 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |=
892 WriteMask
[0] & R300_STENCILREF_MASK
) <<
893 R300_STENCILWRITEMASK_SHIFT
;
896 static void r300StencilOpSeparate(GLcontext
* ctx
, GLenum face
,
897 GLenum fail
, GLenum zfail
, GLenum zpass
)
899 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
900 const unsigned back
= ctx
->Stencil
._BackFace
;
902 R300_STATECHANGE(rmesa
, zs
);
903 /* It is easier to mask what's left.. */
904 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &=
905 (R300_ZS_MASK
<< R300_Z_FUNC_SHIFT
) |
906 (R300_ZS_MASK
<< R300_S_FRONT_FUNC_SHIFT
) |
907 (R300_ZS_MASK
<< R300_S_BACK_FUNC_SHIFT
);
909 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
910 (translate_stencil_op(ctx
->Stencil
.FailFunc
[0]) <<
911 R300_S_FRONT_SFAIL_OP_SHIFT
)
912 | (translate_stencil_op(ctx
->Stencil
.ZFailFunc
[0]) <<
913 R300_S_FRONT_ZFAIL_OP_SHIFT
)
914 | (translate_stencil_op(ctx
->Stencil
.ZPassFunc
[0]) <<
915 R300_S_FRONT_ZPASS_OP_SHIFT
);
917 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
918 (translate_stencil_op(ctx
->Stencil
.FailFunc
[back
]) <<
919 R300_S_BACK_SFAIL_OP_SHIFT
)
920 | (translate_stencil_op(ctx
->Stencil
.ZFailFunc
[back
]) <<
921 R300_S_BACK_ZFAIL_OP_SHIFT
)
922 | (translate_stencil_op(ctx
->Stencil
.ZPassFunc
[back
]) <<
923 R300_S_BACK_ZPASS_OP_SHIFT
);
926 /* =============================================================
927 * Window position and viewport transformation
931 * To correctly position primitives:
933 #define SUBPIXEL_X 0.125
934 #define SUBPIXEL_Y 0.125
936 static void r300UpdateWindow(GLcontext
* ctx
)
938 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
939 __DRIdrawablePrivate
*dPriv
= rmesa
->radeon
.dri
.drawable
;
940 GLfloat xoffset
= dPriv
? (GLfloat
) dPriv
->x
: 0;
941 GLfloat yoffset
= dPriv
? (GLfloat
) dPriv
->y
+ dPriv
->h
: 0;
942 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
943 const GLfloat depthScale
= 1.0F
/ ctx
->DrawBuffer
->_DepthMaxF
;
944 const GLboolean render_to_fbo
= (ctx
->DrawBuffer
->Name
!= 0);
945 GLfloat y_scale
, y_bias
;
955 GLfloat sx
= v
[MAT_SX
];
956 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
957 GLfloat sy
= v
[MAT_SY
] * y_scale
;
958 GLfloat ty
= (v
[MAT_TY
] * y_scale
) + y_bias
+ SUBPIXEL_Y
;
959 GLfloat sz
= v
[MAT_SZ
] * depthScale
;
960 GLfloat tz
= v
[MAT_TZ
] * depthScale
;
962 R300_STATECHANGE(rmesa
, vpt
);
964 rmesa
->hw
.vpt
.cmd
[R300_VPT_XSCALE
] = r300PackFloat32(sx
);
965 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
966 rmesa
->hw
.vpt
.cmd
[R300_VPT_YSCALE
] = r300PackFloat32(sy
);
967 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
968 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZSCALE
] = r300PackFloat32(sz
);
969 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZOFFSET
] = r300PackFloat32(tz
);
972 static void r300Viewport(GLcontext
* ctx
, GLint x
, GLint y
,
973 GLsizei width
, GLsizei height
)
975 /* Don't pipeline viewport changes, conflict with window offset
976 * setting below. Could apply deltas to rescue pipelined viewport
977 * values, or keep the originals hanging around.
979 r300UpdateWindow(ctx
);
981 radeon_viewport(ctx
, x
, y
, width
, height
);
984 static void r300DepthRange(GLcontext
* ctx
, GLclampd nearval
, GLclampd farval
)
986 r300UpdateWindow(ctx
);
989 void r300UpdateViewportOffset(GLcontext
* ctx
)
991 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
992 __DRIdrawablePrivate
*dPriv
= ((radeonContextPtr
) rmesa
)->dri
.drawable
;
993 GLfloat xoffset
= (GLfloat
) dPriv
->x
;
994 GLfloat yoffset
= (GLfloat
) dPriv
->y
+ dPriv
->h
;
995 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
997 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
998 GLfloat ty
= (-v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1000 if (rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] != r300PackFloat32(tx
) ||
1001 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] != r300PackFloat32(ty
)) {
1002 /* Note: this should also modify whatever data the context reset
1005 R300_STATECHANGE(rmesa
, vpt
);
1006 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
1007 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
1011 radeonUpdateScissor(ctx
);
1015 r300FetchStateParameter(GLcontext
* ctx
,
1016 const gl_state_index state
[STATE_LENGTH
],
1019 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1022 case STATE_INTERNAL
:
1024 case STATE_R300_WINDOW_DIMENSION
:
1025 value
[0] = r300
->radeon
.dri
.drawable
->w
* 0.5f
; /* width*0.5 */
1026 value
[1] = r300
->radeon
.dri
.drawable
->h
* 0.5f
; /* height*0.5 */
1027 value
[2] = 0.5F
; /* for moving range [-1 1] -> [0 1] */
1028 value
[3] = 1.0F
; /* not used */
1031 case STATE_R300_TEXRECT_FACTOR
:{
1032 struct gl_texture_object
*t
=
1033 ctx
->Texture
.Unit
[state
[2]].CurrentTex
[TEXTURE_RECT_INDEX
];
1035 if (t
&& t
->Image
[0][t
->BaseLevel
]) {
1036 struct gl_texture_image
*image
=
1037 t
->Image
[0][t
->BaseLevel
];
1038 value
[0] = 1.0 / image
->Width2
;
1039 value
[1] = 1.0 / image
->Height2
;
1060 * Update R300's own internal state parameters.
1061 * For now just STATE_R300_WINDOW_DIMENSION
1063 void r300UpdateStateParameters(GLcontext
* ctx
, GLuint new_state
)
1065 struct r300_fragment_program
*fp
;
1066 struct gl_program_parameter_list
*paramList
;
1069 if (!(new_state
& (_NEW_BUFFERS
| _NEW_PROGRAM
)))
1072 fp
= (struct r300_fragment_program
*)ctx
->FragmentProgram
._Current
;
1076 paramList
= fp
->mesa_program
.Base
.Parameters
;
1081 for (i
= 0; i
< paramList
->NumParameters
; i
++) {
1082 if (paramList
->Parameters
[i
].Type
== PROGRAM_STATE_VAR
) {
1083 r300FetchStateParameter(ctx
,
1084 paramList
->Parameters
[i
].
1086 paramList
->ParameterValues
[i
]);
1091 /* =============================================================
1094 static void r300PolygonOffset(GLcontext
* ctx
, GLfloat factor
, GLfloat units
)
1096 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1097 GLfloat constant
= units
;
1099 switch (ctx
->Visual
.depthBits
) {
1110 /* fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */
1112 R300_STATECHANGE(rmesa
, zbs
);
1113 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_FACTOR
] = r300PackFloat32(factor
);
1114 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_CONSTANT
] = r300PackFloat32(constant
);
1115 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_FACTOR
] = r300PackFloat32(factor
);
1116 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_CONSTANT
] = r300PackFloat32(constant
);
1119 /* Routing and texture-related */
1121 /* r300 doesnt handle GL_CLAMP and GL_MIRROR_CLAMP_EXT correctly when filter is NEAREST.
1122 * Since texwrap produces same results for GL_CLAMP and GL_CLAMP_TO_EDGE we use them instead.
1123 * We need to recalculate wrap modes whenever filter mode is changed because someone might do:
1124 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1125 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1126 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1127 * Since r300 completely ignores R300_TX_CLAMP when either min or mag is nearest it cant handle
1128 * combinations where only one of them is nearest.
1130 static unsigned long gen_fixed_filter(unsigned long f
)
1132 unsigned long mag
, min
, needs_fixing
= 0;
1135 /* We ignore MIRROR bit so we dont have to do everything twice */
1136 if ((f
& ((7 - 1) << R300_TX_WRAP_S_SHIFT
)) ==
1137 (R300_TX_CLAMP
<< R300_TX_WRAP_S_SHIFT
)) {
1140 if ((f
& ((7 - 1) << R300_TX_WRAP_T_SHIFT
)) ==
1141 (R300_TX_CLAMP
<< R300_TX_WRAP_T_SHIFT
)) {
1144 if ((f
& ((7 - 1) << R300_TX_WRAP_R_SHIFT
)) ==
1145 (R300_TX_CLAMP
<< R300_TX_WRAP_R_SHIFT
)) {
1152 mag
= f
& R300_TX_MAG_FILTER_MASK
;
1153 min
= f
& (R300_TX_MIN_FILTER_MASK
|R300_TX_MIN_FILTER_MIP_MASK
);
1155 /* TODO: Check for anisto filters too */
1156 if ((mag
!= R300_TX_MAG_FILTER_NEAREST
)
1157 && (min
!= R300_TX_MIN_FILTER_NEAREST
))
1160 /* r300 cant handle these modes hence we force nearest to linear */
1161 if ((mag
== R300_TX_MAG_FILTER_NEAREST
)
1162 && (min
!= R300_TX_MIN_FILTER_NEAREST
)) {
1163 f
&= ~R300_TX_MAG_FILTER_NEAREST
;
1164 f
|= R300_TX_MAG_FILTER_LINEAR
;
1168 if ((min
== R300_TX_MIN_FILTER_NEAREST
)
1169 && (mag
!= R300_TX_MAG_FILTER_NEAREST
)) {
1170 f
&= ~R300_TX_MIN_FILTER_NEAREST
;
1171 f
|= R300_TX_MIN_FILTER_LINEAR
;
1175 /* Both are nearest */
1176 if (needs_fixing
& 1) {
1177 f
&= ~((7 - 1) << R300_TX_WRAP_S_SHIFT
);
1178 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_S_SHIFT
;
1180 if (needs_fixing
& 2) {
1181 f
&= ~((7 - 1) << R300_TX_WRAP_T_SHIFT
);
1182 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_T_SHIFT
;
1184 if (needs_fixing
& 4) {
1185 f
&= ~((7 - 1) << R300_TX_WRAP_R_SHIFT
);
1186 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_R_SHIFT
;
1191 static void r300SetupFragmentShaderTextures(GLcontext
*ctx
, int *tmu_mappings
)
1193 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1195 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
1196 (char *)ctx
->FragmentProgram
._Current
;
1197 struct r300_fragment_program_code
*code
= &fp
->code
;
1199 R300_STATECHANGE(r300
, fpt
);
1201 for (i
= 0; i
< code
->tex
.length
; i
++) {
1206 unit
= code
->tex
.inst
[i
] >> R300_TEX_ID_SHIFT
;
1209 val
= code
->tex
.inst
[i
];
1210 val
&= ~R300_TEX_ID_MASK
;
1213 (val
& R300_TEX_INST_MASK
) >> R300_TEX_INST_SHIFT
;
1214 if (opcode
== R300_TEX_OP_KIL
) {
1215 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1217 if (tmu_mappings
[unit
] >= 0) {
1219 tmu_mappings
[unit
] <<
1221 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1223 // We get here when the corresponding texture image is incomplete
1224 // (e.g. incomplete mipmaps etc.)
1225 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1230 r300
->hw
.fpt
.cmd
[R300_FPT_CMD_0
] =
1231 cmdpacket0(r300
->radeon
.radeonScreen
,
1232 R300_US_TEX_INST_0
, code
->tex
.length
);
1235 static void r500SetupFragmentShaderTextures(GLcontext
*ctx
, int *tmu_mappings
)
1238 struct r500_fragment_program
*fp
= (struct r500_fragment_program
*)
1239 (char *)ctx
->FragmentProgram
._Current
;
1240 struct r500_fragment_program_code
*code
= &fp
->code
;
1242 /* find all the texture instructions and relocate the texture units */
1243 for (i
= 0; i
< code
->inst_end
+ 1; i
++) {
1244 if ((code
->inst
[i
].inst0
& 0x3) == R500_INST_TYPE_TEX
) {
1246 int unit
, opcode
, new_unit
;
1248 val
= code
->inst
[i
].inst1
;
1250 unit
= (val
>> 16) & 0xf;
1252 val
&= ~(0xf << 16);
1254 opcode
= val
& (0x7 << 22);
1255 if (opcode
== R500_TEX_INST_TEXKILL
) {
1258 if (tmu_mappings
[unit
] >= 0) {
1259 new_unit
= tmu_mappings
[unit
];
1264 val
|= R500_TEX_ID(new_unit
);
1265 code
->inst
[i
].inst1
= val
;
1270 static GLuint
translate_lod_bias(GLfloat bias
)
1272 GLint b
= (int)(bias
*32);
1275 else if (b
< -(1 << 9))
1277 return (((GLuint
)b
) << R300_LOD_BIAS_SHIFT
) & R300_LOD_BIAS_MASK
;
1280 static void r300SetupTextures(GLcontext
* ctx
)
1283 struct radeon_tex_obj
*t
;
1284 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1286 int last_hw_tmu
= -1; /* -1 translates into no setup costs for fields */
1287 int tmu_mappings
[R300_MAX_TEXTURE_UNITS
] = { -1, };
1288 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
1289 (char *)ctx
->FragmentProgram
._Current
;
1291 R300_STATECHANGE(r300
, txe
);
1292 R300_STATECHANGE(r300
, tex
.filter
);
1293 R300_STATECHANGE(r300
, tex
.filter_1
);
1294 R300_STATECHANGE(r300
, tex
.size
);
1295 R300_STATECHANGE(r300
, tex
.format
);
1296 R300_STATECHANGE(r300
, tex
.pitch
);
1297 R300_STATECHANGE(r300
, tex
.offset
);
1298 R300_STATECHANGE(r300
, tex
.chroma_key
);
1299 R300_STATECHANGE(r300
, tex
.border_color
);
1301 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] = 0x0;
1303 mtu
= r300
->radeon
.glCtx
->Const
.MaxTextureUnits
;
1304 if (RADEON_DEBUG
& DEBUG_STATE
)
1305 fprintf(stderr
, "mtu=%d\n", mtu
);
1307 if (mtu
> R300_MAX_TEXTURE_UNITS
) {
1309 "Aiiee ! mtu=%d is greater than R300_MAX_TEXTURE_UNITS=%d\n",
1310 mtu
, R300_MAX_TEXTURE_UNITS
);
1314 /* We cannot let disabled tmu offsets pass DRM */
1315 for (i
= 0; i
< mtu
; i
++) {
1316 if (ctx
->Texture
.Unit
[i
]._ReallyEnabled
) {
1317 tmu_mappings
[i
] = hw_tmu
;
1319 t
= radeon_tex_obj(ctx
->Texture
.Unit
[i
]._Current
);
1323 if ((t
->pp_txformat
& 0xffffff00) == 0xffffff00) {
1325 ("unknown texture format (entry %x) encountered. Help me !\n",
1326 t
->pp_txformat
& 0xff);
1329 if (RADEON_DEBUG
& DEBUG_STATE
)
1331 "Activating texture unit %d\n", i
);
1333 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] |= (1 << hw_tmu
);
1335 r300
->hw
.tex
.filter
.cmd
[R300_TEX_VALUE_0
+
1337 gen_fixed_filter(t
->pp_txfilter
) | (hw_tmu
<< 28);
1338 /* Note: There is a LOD bias per texture unit and a LOD bias
1339 * per texture object. We add them here to get the correct behaviour.
1340 * (The per-texture object LOD bias was introduced in OpenGL 1.4
1341 * and is not present in the EXT_texture_object extension).
1343 r300
->hw
.tex
.filter_1
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] =
1345 translate_lod_bias(ctx
->Texture
.Unit
[i
].LodBias
+ t
->base
.LodBias
);
1346 r300
->hw
.tex
.size
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] =
1348 r300
->hw
.tex
.format
.cmd
[R300_TEX_VALUE_0
+
1349 hw_tmu
] = t
->pp_txformat
;
1350 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] =
1352 r300
->hw
.textures
[hw_tmu
] = t
;
1354 if (t
->tile_bits
& R300_TXO_MACRO_TILE
) {
1355 WARN_ONCE("macro tiling enabled!\n");
1358 if (t
->tile_bits
& R300_TXO_MICRO_TILE
) {
1359 WARN_ONCE("micro tiling enabled!\n");
1362 r300
->hw
.tex
.chroma_key
.cmd
[R300_TEX_VALUE_0
+
1364 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_VALUE_0
+
1368 last_hw_tmu
= hw_tmu
;
1374 r300
->hw
.tex
.filter
.cmd
[R300_TEX_CMD_0
] =
1375 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_FILTER0_0
, last_hw_tmu
+ 1);
1376 r300
->hw
.tex
.filter_1
.cmd
[R300_TEX_CMD_0
] =
1377 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_FILTER1_0
, last_hw_tmu
+ 1);
1378 r300
->hw
.tex
.size
.cmd
[R300_TEX_CMD_0
] =
1379 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_SIZE_0
, last_hw_tmu
+ 1);
1380 r300
->hw
.tex
.format
.cmd
[R300_TEX_CMD_0
] =
1381 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_FORMAT_0
, last_hw_tmu
+ 1);
1382 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_CMD_0
] =
1383 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_FORMAT2_0
, last_hw_tmu
+ 1);
1384 r300
->hw
.tex
.offset
.cmd
[R300_TEX_CMD_0
] =
1385 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_OFFSET_0
, last_hw_tmu
+ 1);
1386 r300
->hw
.tex
.chroma_key
.cmd
[R300_TEX_CMD_0
] =
1387 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_CHROMA_KEY_0
, last_hw_tmu
+ 1);
1388 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_CMD_0
] =
1389 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_BORDER_COLOR_0
, last_hw_tmu
+ 1);
1391 if (!fp
) /* should only happenen once, just after context is created */
1394 if (r300
->radeon
.radeonScreen
->chip_family
< CHIP_FAMILY_RV515
) {
1395 if (fp
->mesa_program
.UsesKill
&& last_hw_tmu
< 0) {
1396 // The KILL operation requires the first texture unit
1398 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] |= 1;
1399 r300
->hw
.tex
.filter
.cmd
[R300_TEX_VALUE_0
] = 0;
1400 r300
->hw
.tex
.filter
.cmd
[R300_TEX_CMD_0
] =
1401 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_FILTER0_0
, 1);
1403 r300SetupFragmentShaderTextures(ctx
, tmu_mappings
);
1405 r500SetupFragmentShaderTextures(ctx
, tmu_mappings
);
1407 if (RADEON_DEBUG
& DEBUG_STATE
)
1408 fprintf(stderr
, "TX_ENABLE: %08x last_hw_tmu=%d\n",
1409 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
], last_hw_tmu
);
1412 union r300_outputs_written
{
1413 GLuint vp_outputs
; /* hw_tcl_on */
1414 DECLARE_RENDERINPUTS(index_bitset
); /* !hw_tcl_on */
1417 #define R300_OUTPUTS_WRITTEN_TEST(ow, vp_result, tnl_attrib) \
1418 ((hw_tcl_on) ? (ow).vp_outputs & (1 << (vp_result)) : \
1419 RENDERINPUTS_TEST( (ow.index_bitset), (tnl_attrib) ))
1421 static void r300SetupRSUnit(GLcontext
* ctx
)
1423 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1424 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1425 struct vertex_buffer
*VB
= &tnl
->vb
;
1426 union r300_outputs_written OutputsWritten
;
1428 int fp_reg
, high_rr
;
1430 int rs_tex_count
= 0;
1431 int i
, count
, col_fmt
;
1434 OutputsWritten
.vp_outputs
= CURRENT_VERTEX_SHADER(ctx
)->key
.OutputsWritten
;
1436 RENDERINPUTS_COPY(OutputsWritten
.index_bitset
, r300
->state
.render_inputs_bitset
);
1438 if (ctx
->FragmentProgram
._Current
)
1439 InputsRead
= ctx
->FragmentProgram
._Current
->Base
.InputsRead
;
1441 fprintf(stderr
, "No ctx->FragmentProgram._Current!!\n");
1442 return; /* This should only ever happen once.. */
1445 R300_STATECHANGE(r300
, ri
);
1446 R300_STATECHANGE(r300
, rc
);
1447 R300_STATECHANGE(r300
, rr
);
1449 fp_reg
= col_ip
= tex_ip
= col_fmt
= 0;
1451 r300
->hw
.rc
.cmd
[1] = 0;
1452 r300
->hw
.rc
.cmd
[2] = 0;
1453 for (i
=0; i
<R300_RR_CMDSIZE
-1; ++i
)
1454 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ i
] = 0;
1456 for (i
=0; i
<R300_RI_CMDSIZE
-1; ++i
)
1457 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ i
] = 0;
1460 if (InputsRead
& FRAG_BIT_COL0
) {
1461 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL0
, _TNL_ATTRIB_COLOR0
)) {
1462 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR0
]->size
;
1464 col_fmt
= R300_RS_COL_FMT_RGBA
;
1465 else if (count
== 3)
1466 col_fmt
= R300_RS_COL_FMT_RGB1
;
1468 col_fmt
= R300_RS_COL_FMT_0001
;
1470 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ col_ip
] = R300_RS_COL_PTR(col_ip
) | R300_RS_COL_FMT(col_fmt
);
1471 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ col_ip
] = R300_RS_INST_COL_ID(col_ip
) | R300_RS_INST_COL_CN_WRITE
| R300_RS_INST_COL_ADDR(fp_reg
);
1472 InputsRead
&= ~FRAG_BIT_COL0
;
1476 WARN_ONCE("fragprog wants col0, vp doesn't provide it\n");
1480 if (InputsRead
& FRAG_BIT_COL1
) {
1481 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL1
, _TNL_ATTRIB_COLOR1
)) {
1482 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR1
]->size
;
1484 col_fmt
= R300_RS_COL_FMT_RGBA
;
1485 else if (count
== 3)
1486 col_fmt
= R300_RS_COL_FMT_RGB1
;
1488 col_fmt
= R300_RS_COL_FMT_0001
;
1490 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ col_ip
] = R300_RS_COL_PTR(col_ip
) | R300_RS_COL_FMT(col_fmt
);
1491 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ col_ip
] = R300_RS_INST_COL_ID(col_ip
) | R300_RS_INST_COL_CN_WRITE
| R300_RS_INST_COL_ADDR(fp_reg
);
1492 InputsRead
&= ~FRAG_BIT_COL1
;
1496 WARN_ONCE("fragprog wants col1, vp doesn't provide it\n");
1500 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
1501 if (! ( InputsRead
& FRAG_BIT_TEX(i
) ) )
1504 if (!R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_TEX0
+ i
, _TNL_ATTRIB_TEX(i
))) {
1505 WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i
);
1511 /* with TCL we always seem to route 4 components */
1515 count
= VB
->AttribPtr
[_TNL_ATTRIB_TEX(i
)]->size
;
1518 case 4: swiz
= R300_RS_SEL_S(0) | R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(3); break;
1519 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;
1522 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;
1525 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ tex_ip
] |= swiz
| R300_RS_TEX_PTR(rs_tex_count
);
1526 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ tex_ip
] |= R300_RS_INST_TEX_ID(tex_ip
) | R300_RS_INST_TEX_CN_WRITE
| R300_RS_INST_TEX_ADDR(fp_reg
);
1527 InputsRead
&= ~(FRAG_BIT_TEX0
<< i
);
1528 rs_tex_count
+= count
;
1533 if (InputsRead
& FRAG_BIT_FOGC
) {
1534 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_FOGC
, _TNL_ATTRIB_FOG
)) {
1535 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ tex_ip
] |= R300_RS_SEL_S(0) | R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(3) | R300_RS_TEX_PTR(rs_tex_count
);
1536 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ tex_ip
] |= R300_RS_INST_TEX_ID(tex_ip
) | R300_RS_INST_TEX_CN_WRITE
| R300_RS_INST_TEX_ADDR(fp_reg
);
1537 InputsRead
&= ~FRAG_BIT_FOGC
;
1542 WARN_ONCE("fragprog wants fogc, vp doesn't provide it\n");
1546 if (InputsRead
& FRAG_BIT_WPOS
) {
1547 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ tex_ip
] |= R300_RS_SEL_S(0) | R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(3) | R300_RS_TEX_PTR(rs_tex_count
);
1548 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ tex_ip
] |= R300_RS_INST_TEX_ID(tex_ip
) | R300_RS_INST_TEX_CN_WRITE
| R300_RS_INST_TEX_ADDR(fp_reg
);
1549 InputsRead
&= ~FRAG_BIT_WPOS
;
1554 InputsRead
&= ~FRAG_BIT_WPOS
;
1556 /* Setup default color if no color or tex was set */
1557 if (rs_tex_count
== 0 && col_ip
== 0) {
1558 r300
->hw
.rr
.cmd
[R300_RR_INST_0
] = R300_RS_INST_COL_ID(0) | R300_RS_INST_COL_CN_WRITE
| R300_RS_INST_COL_ADDR(0) | R300_RS_COL_FMT(R300_RS_COL_FMT_0001
);
1562 high_rr
= (col_ip
> tex_ip
) ? col_ip
: tex_ip
;
1563 r300
->hw
.rc
.cmd
[1] |= (rs_tex_count
<< R300_IT_COUNT_SHIFT
) | (col_ip
<< R300_IC_COUNT_SHIFT
) | R300_HIRES_EN
;
1564 r300
->hw
.rc
.cmd
[2] |= high_rr
- 1;
1566 r300
->hw
.rr
.cmd
[R300_RR_CMD_0
] = cmdpacket0(r300
->radeon
.radeonScreen
, R300_RS_INST_0
, high_rr
);
1569 WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead
);
1572 static void r500SetupRSUnit(GLcontext
* ctx
)
1574 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1575 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1576 struct vertex_buffer
*VB
= &tnl
->vb
;
1577 union r300_outputs_written OutputsWritten
;
1579 int fp_reg
, high_rr
;
1581 int rs_tex_count
= 0;
1582 int i
, count
, col_fmt
;
1585 OutputsWritten
.vp_outputs
= CURRENT_VERTEX_SHADER(ctx
)->key
.OutputsWritten
;
1587 RENDERINPUTS_COPY(OutputsWritten
.index_bitset
, r300
->state
.render_inputs_bitset
);
1589 if (ctx
->FragmentProgram
._Current
)
1590 InputsRead
= ctx
->FragmentProgram
._Current
->Base
.InputsRead
;
1592 fprintf(stderr
, "No ctx->FragmentProgram._Current!!\n");
1593 return; /* This should only ever happen once.. */
1596 R300_STATECHANGE(r300
, ri
);
1597 R300_STATECHANGE(r300
, rc
);
1598 R300_STATECHANGE(r300
, rr
);
1600 fp_reg
= col_ip
= tex_ip
= col_fmt
= 0;
1602 r300
->hw
.rc
.cmd
[1] = 0;
1603 r300
->hw
.rc
.cmd
[2] = 0;
1604 for (i
=0; i
<R300_RR_CMDSIZE
-1; ++i
)
1605 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ i
] = 0;
1607 for (i
=0; i
<R500_RI_CMDSIZE
-1; ++i
)
1608 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ i
] = 0;
1611 if (InputsRead
& FRAG_BIT_COL0
) {
1612 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL0
, _TNL_ATTRIB_COLOR0
)) {
1613 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR0
]->size
;
1615 col_fmt
= R300_RS_COL_FMT_RGBA
;
1616 else if (count
== 3)
1617 col_fmt
= R300_RS_COL_FMT_RGB1
;
1619 col_fmt
= R300_RS_COL_FMT_0001
;
1621 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ col_ip
] = R500_RS_COL_PTR(col_ip
) | R500_RS_COL_FMT(col_fmt
);
1622 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ col_ip
] = R500_RS_INST_COL_ID(col_ip
) | R500_RS_INST_COL_CN_WRITE
| R500_RS_INST_COL_ADDR(fp_reg
);
1623 InputsRead
&= ~FRAG_BIT_COL0
;
1627 WARN_ONCE("fragprog wants col0, vp doesn't provide it\n");
1631 if (InputsRead
& FRAG_BIT_COL1
) {
1632 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL1
, _TNL_ATTRIB_COLOR1
)) {
1633 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR1
]->size
;
1635 col_fmt
= R300_RS_COL_FMT_RGBA
;
1636 else if (count
== 3)
1637 col_fmt
= R300_RS_COL_FMT_RGB1
;
1639 col_fmt
= R300_RS_COL_FMT_0001
;
1641 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ col_ip
] = R500_RS_COL_PTR(col_ip
) | R500_RS_COL_FMT(col_fmt
);
1642 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ col_ip
] = R500_RS_INST_COL_ID(col_ip
) | R500_RS_INST_COL_CN_WRITE
| R500_RS_INST_COL_ADDR(fp_reg
);
1643 InputsRead
&= ~FRAG_BIT_COL1
;
1647 WARN_ONCE("fragprog wants col1, vp doesn't provide it\n");
1652 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
1653 if (! ( InputsRead
& FRAG_BIT_TEX(i
) ) )
1656 if (!R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_TEX0
+ i
, _TNL_ATTRIB_TEX(i
))) {
1657 WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i
);
1663 /* with TCL we always seem to route 4 components */
1667 count
= VB
->AttribPtr
[_TNL_ATTRIB_TEX(i
)]->size
;
1670 swiz
|= (rs_tex_count
+ 0) << R500_RS_IP_TEX_PTR_S_SHIFT
;
1671 swiz
|= (rs_tex_count
+ 1) << R500_RS_IP_TEX_PTR_T_SHIFT
;
1672 swiz
|= (rs_tex_count
+ 2) << R500_RS_IP_TEX_PTR_R_SHIFT
;
1673 swiz
|= (rs_tex_count
+ 3) << R500_RS_IP_TEX_PTR_Q_SHIFT
;
1674 } else if (count
== 3) {
1675 swiz
|= (rs_tex_count
+ 0) << R500_RS_IP_TEX_PTR_S_SHIFT
;
1676 swiz
|= (rs_tex_count
+ 1) << R500_RS_IP_TEX_PTR_T_SHIFT
;
1677 swiz
|= (rs_tex_count
+ 2) << R500_RS_IP_TEX_PTR_R_SHIFT
;
1678 swiz
|= R500_RS_IP_PTR_K1
<< R500_RS_IP_TEX_PTR_Q_SHIFT
;
1679 } else if (count
== 2) {
1680 swiz
|= (rs_tex_count
+ 0) << R500_RS_IP_TEX_PTR_S_SHIFT
;
1681 swiz
|= (rs_tex_count
+ 1) << R500_RS_IP_TEX_PTR_T_SHIFT
;
1682 swiz
|= R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_R_SHIFT
;
1683 swiz
|= R500_RS_IP_PTR_K1
<< R500_RS_IP_TEX_PTR_Q_SHIFT
;
1684 } else if (count
== 1) {
1685 swiz
|= (rs_tex_count
+ 0) << R500_RS_IP_TEX_PTR_S_SHIFT
;
1686 swiz
|= R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_T_SHIFT
;
1687 swiz
|= R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_R_SHIFT
;
1688 swiz
|= R500_RS_IP_PTR_K1
<< R500_RS_IP_TEX_PTR_Q_SHIFT
;
1690 swiz
|= R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_S_SHIFT
;
1691 swiz
|= R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_T_SHIFT
;
1692 swiz
|= R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_R_SHIFT
;
1693 swiz
|= R500_RS_IP_PTR_K1
<< R500_RS_IP_TEX_PTR_Q_SHIFT
;
1696 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ tex_ip
] |= swiz
;
1697 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ tex_ip
] |= R500_RS_INST_TEX_ID(tex_ip
) | R500_RS_INST_TEX_CN_WRITE
| R500_RS_INST_TEX_ADDR(fp_reg
);
1698 InputsRead
&= ~(FRAG_BIT_TEX0
<< i
);
1699 rs_tex_count
+= count
;
1704 if (InputsRead
& FRAG_BIT_FOGC
) {
1705 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_FOGC
, _TNL_ATTRIB_FOG
)) {
1706 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ tex_ip
] |= ((rs_tex_count
+ 0) << R500_RS_IP_TEX_PTR_S_SHIFT
) |
1707 ((rs_tex_count
+ 1) << R500_RS_IP_TEX_PTR_T_SHIFT
) |
1708 ((rs_tex_count
+ 2) << R500_RS_IP_TEX_PTR_R_SHIFT
) |
1709 ((rs_tex_count
+ 3) << R500_RS_IP_TEX_PTR_Q_SHIFT
);
1711 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ tex_ip
] |= R500_RS_INST_TEX_ID(tex_ip
) | R500_RS_INST_TEX_CN_WRITE
| R500_RS_INST_TEX_ADDR(fp_reg
);
1712 InputsRead
&= ~FRAG_BIT_FOGC
;
1717 WARN_ONCE("fragprog wants fogc, vp doesn't provide it\n");
1721 if (InputsRead
& FRAG_BIT_WPOS
) {
1722 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ tex_ip
] |= ((rs_tex_count
+ 0) << R500_RS_IP_TEX_PTR_S_SHIFT
) |
1723 ((rs_tex_count
+ 1) << R500_RS_IP_TEX_PTR_T_SHIFT
) |
1724 ((rs_tex_count
+ 2) << R500_RS_IP_TEX_PTR_R_SHIFT
) |
1725 ((rs_tex_count
+ 3) << R500_RS_IP_TEX_PTR_Q_SHIFT
);
1727 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ tex_ip
] |= R500_RS_INST_TEX_ID(tex_ip
) | R500_RS_INST_TEX_CN_WRITE
| R500_RS_INST_TEX_ADDR(fp_reg
);
1728 InputsRead
&= ~FRAG_BIT_WPOS
;
1734 /* Setup default color if no color or tex was set */
1735 if (rs_tex_count
== 0 && col_ip
== 0) {
1736 r300
->hw
.rr
.cmd
[R300_RR_INST_0
] |= R500_RS_INST_COL_ID(0) | R500_RS_INST_COL_CN_WRITE
| R500_RS_INST_COL_ADDR(0) | R500_RS_COL_FMT(R300_RS_COL_FMT_0001
);
1740 high_rr
= (col_ip
> tex_ip
) ? col_ip
: tex_ip
;
1741 r300
->hw
.rc
.cmd
[1] |= (rs_tex_count
<< R300_IT_COUNT_SHIFT
) | (col_ip
<< R300_IC_COUNT_SHIFT
) | R300_HIRES_EN
;
1742 r300
->hw
.rc
.cmd
[2] |= 0xC0 | (high_rr
- 1);
1744 r300
->hw
.rr
.cmd
[R300_RR_CMD_0
] = cmdpacket0(r300
->radeon
.radeonScreen
, R500_RS_INST_0
, high_rr
);
1747 WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead
);
1753 #define bump_vpu_count(ptr, new_count) do{\
1754 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
1755 int _nc=(new_count)/4; \
1756 assert(_nc < 256); \
1757 if(_nc>_p->vpu.count)_p->vpu.count=_nc;\
1760 static INLINE
void r300SetupVertexProgramFragment(r300ContextPtr r300
, int dest
, struct r300_vertex_shader_fragment
*vsf
)
1764 if (vsf
->length
== 0)
1767 if (vsf
->length
& 0x3) {
1768 fprintf(stderr
, "VERTEX_SHADER_FRAGMENT must have length divisible by 4\n");
1772 switch ((dest
>> 8) & 0xf) {
1774 R300_STATECHANGE(r300
, vpi
);
1775 for (i
= 0; i
< vsf
->length
; i
++)
1776 r300
->hw
.vpi
.cmd
[R300_VPI_INSTR_0
+ i
+ 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1777 bump_vpu_count(r300
->hw
.vpi
.cmd
, vsf
->length
+ 4 * (dest
& 0xff));
1781 R300_STATECHANGE(r300
, vpp
);
1782 for (i
= 0; i
< vsf
->length
; i
++)
1783 r300
->hw
.vpp
.cmd
[R300_VPP_PARAM_0
+ i
+ 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1784 bump_vpu_count(r300
->hw
.vpp
.cmd
, vsf
->length
+ 4 * (dest
& 0xff));
1787 R300_STATECHANGE(r300
, vps
);
1788 for (i
= 0; i
< vsf
->length
; i
++)
1789 r300
->hw
.vps
.cmd
[1 + i
+ 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1790 bump_vpu_count(r300
->hw
.vps
.cmd
, vsf
->length
+ 4 * (dest
& 0xff));
1793 fprintf(stderr
, "%s:%s don't know how to handle dest %04x\n", __FILE__
, __FUNCTION__
, dest
);
1798 #define MIN3(a, b, c) ((a) < (b) ? MIN2(a, c) : MIN2(b, c))
1801 static void r300VapCntl(r300ContextPtr rmesa
, GLuint input_count
,
1802 GLuint output_count
, GLuint temp_count
)
1808 /* Flush PVS engine before changing PVS_NUM_SLOTS, PVS_NUM_CNTRLS.
1809 * See r500 docs 6.5.2 - done in emit */
1811 /* avoid division by zero */
1812 if (input_count
== 0) input_count
= 1;
1813 if (output_count
== 0) output_count
= 1;
1814 if (temp_count
== 0) temp_count
= 1;
1816 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
1821 pvs_num_slots
= MIN3(10, vtx_mem_size
/input_count
, vtx_mem_size
/output_count
);
1822 pvs_num_cntrls
= MIN2(6, vtx_mem_size
/temp_count
);
1824 R300_STATECHANGE(rmesa
, vap_cntl
);
1825 if (rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
) {
1826 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] =
1827 (pvs_num_slots
<< R300_PVS_NUM_SLOTS_SHIFT
) |
1828 (pvs_num_cntrls
<< R300_PVS_NUM_CNTLRS_SHIFT
) |
1829 (12 << R300_VF_MAX_VTX_NUM_SHIFT
);
1830 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
1831 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= R500_TCL_STATE_OPTIMIZATION
;
1833 /* not sure about non-tcl */
1834 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] = ((10 << R300_PVS_NUM_SLOTS_SHIFT
) |
1835 (5 << R300_PVS_NUM_CNTLRS_SHIFT
) |
1836 (5 << R300_VF_MAX_VTX_NUM_SHIFT
));
1838 if (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV515
)
1839 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (2 << R300_PVS_NUM_FPUS_SHIFT
);
1840 else if ((rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV530
) ||
1841 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV560
) ||
1842 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV570
))
1843 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (5 << R300_PVS_NUM_FPUS_SHIFT
);
1844 else if ((rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV410
) ||
1845 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R420
))
1846 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (6 << R300_PVS_NUM_FPUS_SHIFT
);
1847 else if ((rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R520
) ||
1848 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R580
))
1849 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (8 << R300_PVS_NUM_FPUS_SHIFT
);
1851 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (4 << R300_PVS_NUM_FPUS_SHIFT
);
1855 static void r300SetupDefaultVertexProgram(r300ContextPtr rmesa
)
1857 struct r300_vertex_shader_state
*prog
= &(rmesa
->state
.vertex_shader
);
1862 int param_count
= 0;
1863 int program_end
= 0;
1865 for (i
= VERT_ATTRIB_POS
; i
< VERT_ATTRIB_MAX
; i
++) {
1866 if (rmesa
->state
.sw_tcl_inputs
[i
] != -1) {
1867 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
);
1868 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
);
1869 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
);
1870 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
);
1876 prog
->program
.length
= program_end
;
1878 r300SetupVertexProgramFragment(rmesa
, R300_PVS_CODE_START
,
1880 inst_count
= (prog
->program
.length
/ 4) - 1;
1882 r300VapCntl(rmesa
, i_reg
, o_reg
, 0);
1884 R300_STATECHANGE(rmesa
, pvs
);
1885 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] =
1886 (0 << R300_PVS_FIRST_INST_SHIFT
) |
1887 (inst_count
<< R300_PVS_XYZW_VALID_INST_SHIFT
) |
1888 (inst_count
<< R300_PVS_LAST_INST_SHIFT
);
1889 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] =
1890 (0 << R300_PVS_CONST_BASE_OFFSET_SHIFT
) |
1891 (param_count
<< R300_PVS_MAX_CONST_ADDR_SHIFT
);
1892 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] =
1893 (inst_count
<< R300_PVS_LAST_VTX_SRC_INST_SHIFT
);
1896 static int bit_count (int x
)
1898 x
= ((x
& 0xaaaaaaaaU
) >> 1) + (x
& 0x55555555U
);
1899 x
= ((x
& 0xccccccccU
) >> 2) + (x
& 0x33333333U
);
1900 x
= (x
>> 16) + (x
& 0xffff);
1901 x
= ((x
& 0xf0f0) >> 4) + (x
& 0x0f0f);
1902 return (x
>> 8) + (x
& 0x00ff);
1905 static void r300SetupRealVertexProgram(r300ContextPtr rmesa
)
1907 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
1908 struct r300_vertex_program
*prog
= (struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
);
1910 int param_count
= 0;
1912 /* FIXME: r300SetupVertexProgramFragment */
1913 R300_STATECHANGE(rmesa
, vpp
);
1915 r300VertexProgUpdateParams(ctx
,
1916 (struct r300_vertex_program_cont
*)
1917 ctx
->VertexProgram
._Current
,
1918 (float *)&rmesa
->hw
.vpp
.
1919 cmd
[R300_VPP_PARAM_0
]);
1920 bump_vpu_count(rmesa
->hw
.vpp
.cmd
, param_count
);
1923 r300SetupVertexProgramFragment(rmesa
, R300_PVS_CODE_START
, &(prog
->program
));
1924 inst_count
= (prog
->program
.length
/ 4) - 1;
1926 r300VapCntl(rmesa
, bit_count(prog
->key
.InputsRead
),
1927 bit_count(prog
->key
.OutputsWritten
), prog
->num_temporaries
);
1929 R300_STATECHANGE(rmesa
, pvs
);
1930 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] =
1931 (0 << R300_PVS_FIRST_INST_SHIFT
) |
1932 (inst_count
<< R300_PVS_XYZW_VALID_INST_SHIFT
) |
1933 (inst_count
<< R300_PVS_LAST_INST_SHIFT
);
1934 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] =
1935 (0 << R300_PVS_CONST_BASE_OFFSET_SHIFT
) |
1936 (param_count
<< R300_PVS_MAX_CONST_ADDR_SHIFT
);
1937 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] =
1938 (inst_count
<< R300_PVS_LAST_VTX_SRC_INST_SHIFT
);
1942 static void r300SetupVertexProgram(r300ContextPtr rmesa
)
1944 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
1946 /* Reset state, in case we don't use something */
1947 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vpp
.cmd
)->vpu
.count
= 0;
1948 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vpi
.cmd
)->vpu
.count
= 0;
1949 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vps
.cmd
)->vpu
.count
= 0;
1951 /* Not sure why this doesnt work...
1952 0x400 area might have something to do with pixel shaders as it appears right after pfs programming.
1953 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. */
1954 //setup_vertex_shader_fragment(rmesa, 0x406, &unk4);
1955 if (hw_tcl_on
&& ((struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
))->translated
) {
1956 r300SetupRealVertexProgram(rmesa
);
1958 /* FIXME: This needs to be replaced by vertex shader generation code. */
1959 r300SetupDefaultVertexProgram(rmesa
);
1965 * Enable/Disable states.
1967 * \note Mesa already filters redundant calls to this function.
1969 static void r300Enable(GLcontext
* ctx
, GLenum cap
, GLboolean state
)
1971 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1972 if (RADEON_DEBUG
& DEBUG_STATE
)
1973 fprintf(stderr
, "%s( %s = %s )\n", __FUNCTION__
,
1974 _mesa_lookup_enum_by_nr(cap
),
1975 state
? "GL_TRUE" : "GL_FALSE");
1987 r300SetAlphaState(ctx
);
1989 case GL_COLOR_LOGIC_OP
:
1990 r300SetLogicOpState(ctx
);
1991 /* fall-through, because logic op overrides blending */
1993 r300SetBlendState(ctx
);
1995 case GL_CLIP_PLANE0
:
1996 case GL_CLIP_PLANE1
:
1997 case GL_CLIP_PLANE2
:
1998 case GL_CLIP_PLANE3
:
1999 case GL_CLIP_PLANE4
:
2000 case GL_CLIP_PLANE5
:
2001 r300SetClipPlaneState(ctx
, cap
, state
);
2004 r300SetDepthState(ctx
);
2006 case GL_STENCIL_TEST
:
2007 r300SetStencilState(ctx
, state
);
2010 r300UpdateCulling(ctx
);
2012 case GL_POLYGON_OFFSET_POINT
:
2013 case GL_POLYGON_OFFSET_LINE
:
2014 case GL_POLYGON_OFFSET_FILL
:
2015 r300SetPolygonOffsetState(ctx
, state
);
2017 case GL_SCISSOR_TEST
:
2018 radeon_firevertices(&rmesa
->radeon
);
2019 rmesa
->radeon
.state
.scissor
.enabled
= state
;
2020 radeonUpdateScissor( ctx
);
2028 * Completely recalculates hardware state based on the Mesa state.
2030 static void r300ResetHwState(r300ContextPtr r300
)
2032 GLcontext
*ctx
= r300
->radeon
.glCtx
;
2035 if (!(r300
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
2038 if (RADEON_DEBUG
& DEBUG_STATE
)
2039 fprintf(stderr
, "%s\n", __FUNCTION__
);
2041 radeon_firevertices(&r300
->radeon
);
2044 ctx
->Color
.ColorMask
[RCOMP
],
2045 ctx
->Color
.ColorMask
[GCOMP
],
2046 ctx
->Color
.ColorMask
[BCOMP
], ctx
->Color
.ColorMask
[ACOMP
]);
2048 r300Enable(ctx
, GL_DEPTH_TEST
, ctx
->Depth
.Test
);
2049 r300DepthMask(ctx
, ctx
->Depth
.Mask
);
2050 r300DepthFunc(ctx
, ctx
->Depth
.Func
);
2053 r300Enable(ctx
, GL_STENCIL_TEST
, ctx
->Stencil
._Enabled
);
2054 r300StencilMaskSeparate(ctx
, 0, ctx
->Stencil
.WriteMask
[0]);
2055 r300StencilFuncSeparate(ctx
, 0, ctx
->Stencil
.Function
[0],
2056 ctx
->Stencil
.Ref
[0], ctx
->Stencil
.ValueMask
[0]);
2057 r300StencilOpSeparate(ctx
, 0, ctx
->Stencil
.FailFunc
[0],
2058 ctx
->Stencil
.ZFailFunc
[0],
2059 ctx
->Stencil
.ZPassFunc
[0]);
2061 r300UpdateCulling(ctx
);
2063 r300SetBlendState(ctx
);
2064 r300SetLogicOpState(ctx
);
2066 r300AlphaFunc(ctx
, ctx
->Color
.AlphaFunc
, ctx
->Color
.AlphaRef
);
2067 r300Enable(ctx
, GL_ALPHA_TEST
, ctx
->Color
.AlphaEnabled
);
2069 r300
->hw
.vte
.cmd
[1] = R300_VPORT_X_SCALE_ENA
2070 | R300_VPORT_X_OFFSET_ENA
2071 | R300_VPORT_Y_SCALE_ENA
2072 | R300_VPORT_Y_OFFSET_ENA
2073 | R300_VPORT_Z_SCALE_ENA
2074 | R300_VPORT_Z_OFFSET_ENA
| R300_VTX_W0_FMT
;
2075 r300
->hw
.vte
.cmd
[2] = 0x00000008;
2077 r300
->hw
.vap_vf_max_vtx_indx
.cmd
[1] = 0x00FFFFFF;
2078 r300
->hw
.vap_vf_max_vtx_indx
.cmd
[2] = 0x00000000;
2080 #ifdef MESA_LITTLE_ENDIAN
2081 r300
->hw
.vap_cntl_status
.cmd
[1] = R300_VC_NO_SWAP
;
2083 r300
->hw
.vap_cntl_status
.cmd
[1] = R300_VC_32BIT_SWAP
;
2086 /* disable VAP/TCL on non-TCL capable chips */
2088 r300
->hw
.vap_cntl_status
.cmd
[1] |= R300_VAP_TCL_BYPASS
;
2090 r300
->hw
.vap_psc_sgn_norm_cntl
.cmd
[1] = 0xAAAAAAAA;
2092 /* XXX: Other families? */
2094 r300
->hw
.vap_clip_cntl
.cmd
[1] = R300_PS_UCP_MODE_DIST_COP
;
2096 r300
->hw
.vap_clip
.cmd
[1] = r300PackFloat32(1.0); /* X */
2097 r300
->hw
.vap_clip
.cmd
[2] = r300PackFloat32(1.0); /* X */
2098 r300
->hw
.vap_clip
.cmd
[3] = r300PackFloat32(1.0); /* Y */
2099 r300
->hw
.vap_clip
.cmd
[4] = r300PackFloat32(1.0); /* Y */
2101 switch (r300
->radeon
.radeonScreen
->chip_family
) {
2102 case CHIP_FAMILY_R300
:
2103 r300
->hw
.vap_pvs_vtx_timeout_reg
.cmd
[1] = R300_2288_R300
;
2106 r300
->hw
.vap_pvs_vtx_timeout_reg
.cmd
[1] = R300_2288_RV350
;
2111 r300
->hw
.gb_enable
.cmd
[1] = R300_GB_POINT_STUFF_ENABLE
2112 | R300_GB_LINE_STUFF_ENABLE
2113 | R300_GB_TRIANGLE_STUFF_ENABLE
;
2115 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_0
] = 0x66666666;
2116 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_1
] = 0x06666666;
2118 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] =
2119 R300_GB_TILE_ENABLE
| R300_GB_TILE_SIZE_16
/*| R300_GB_SUBPIXEL_1_16*/;
2120 switch (r300
->radeon
.radeonScreen
->num_gb_pipes
) {
2123 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2124 R300_GB_TILE_PIPE_COUNT_RV300
;
2127 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2128 R300_GB_TILE_PIPE_COUNT_R300
;
2131 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2132 R300_GB_TILE_PIPE_COUNT_R420_3P
;
2135 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2136 R300_GB_TILE_PIPE_COUNT_R420
;
2140 /* XXX: Enable anti-aliasing? */
2141 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_AA_CONFIG
] = GB_AA_CONFIG_AA_DISABLE
;
2142 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_SELECT
] = 0;
2144 r300
->hw
.ga_point_s0
.cmd
[1] = r300PackFloat32(0.0);
2145 r300
->hw
.ga_point_s0
.cmd
[2] = r300PackFloat32(0.0);
2146 r300
->hw
.ga_point_s0
.cmd
[3] = r300PackFloat32(1.0);
2147 r300
->hw
.ga_point_s0
.cmd
[4] = r300PackFloat32(1.0);
2149 r300
->hw
.ga_triangle_stipple
.cmd
[1] = 0x00050005;
2151 r300PointSize(ctx
, 1.0);
2153 r300
->hw
.ga_point_minmax
.cmd
[1] = 0x18000006;
2154 r300
->hw
.ga_point_minmax
.cmd
[2] = 0x00020006;
2155 r300
->hw
.ga_point_minmax
.cmd
[3] = r300PackFloat32(1.0 / 192.0);
2157 r300LineWidth(ctx
, 1.0);
2159 r300
->hw
.ga_line_stipple
.cmd
[1] = 0;
2160 r300
->hw
.ga_line_stipple
.cmd
[2] = r300PackFloat32(0.0);
2161 r300
->hw
.ga_line_stipple
.cmd
[3] = r300PackFloat32(1.0);
2163 r300ShadeModel(ctx
, ctx
->Light
.ShadeModel
);
2165 r300PolygonMode(ctx
, GL_FRONT
, ctx
->Polygon
.FrontMode
);
2166 r300PolygonMode(ctx
, GL_BACK
, ctx
->Polygon
.BackMode
);
2167 r300
->hw
.zbias_cntl
.cmd
[1] = 0x00000000;
2169 r300PolygonOffset(ctx
, ctx
->Polygon
.OffsetFactor
,
2170 ctx
->Polygon
.OffsetUnits
);
2171 r300Enable(ctx
, GL_POLYGON_OFFSET_POINT
, ctx
->Polygon
.OffsetPoint
);
2172 r300Enable(ctx
, GL_POLYGON_OFFSET_LINE
, ctx
->Polygon
.OffsetLine
);
2173 r300Enable(ctx
, GL_POLYGON_OFFSET_FILL
, ctx
->Polygon
.OffsetFill
);
2175 r300
->hw
.su_depth_scale
.cmd
[1] = 0x4B7FFFFF;
2176 r300
->hw
.su_depth_scale
.cmd
[2] = 0x00000000;
2178 r300
->hw
.sc_hyperz
.cmd
[1] = 0x0000001C;
2179 r300
->hw
.sc_hyperz
.cmd
[2] = 0x2DA49525;
2181 r300
->hw
.sc_screendoor
.cmd
[1] = 0x00FFFFFF;
2183 r300
->hw
.us_out_fmt
.cmd
[1] = R500_OUT_FMT_C4_8
|
2184 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2185 r300
->hw
.us_out_fmt
.cmd
[2] = R500_OUT_FMT_UNUSED
|
2186 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2187 r300
->hw
.us_out_fmt
.cmd
[3] = R500_OUT_FMT_UNUSED
|
2188 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2189 r300
->hw
.us_out_fmt
.cmd
[4] = R500_OUT_FMT_UNUSED
|
2190 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2191 r300
->hw
.us_out_fmt
.cmd
[5] = R300_W_FMT_W0
| R300_W_SRC_US
;
2193 /* disable fog unit */
2194 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] = 0;
2195 r300
->hw
.fg_depth_src
.cmd
[1] = R300_FG_DEPTH_SRC_SCAN
;
2197 r300
->hw
.rb3d_cctl
.cmd
[1] = 0;
2199 r300BlendColor(ctx
, ctx
->Color
.BlendColor
);
2201 r300
->hw
.rb3d_dither_ctl
.cmd
[1] = 0;
2202 r300
->hw
.rb3d_dither_ctl
.cmd
[2] = 0;
2203 r300
->hw
.rb3d_dither_ctl
.cmd
[3] = 0;
2204 r300
->hw
.rb3d_dither_ctl
.cmd
[4] = 0;
2205 r300
->hw
.rb3d_dither_ctl
.cmd
[5] = 0;
2206 r300
->hw
.rb3d_dither_ctl
.cmd
[6] = 0;
2207 r300
->hw
.rb3d_dither_ctl
.cmd
[7] = 0;
2208 r300
->hw
.rb3d_dither_ctl
.cmd
[8] = 0;
2209 r300
->hw
.rb3d_dither_ctl
.cmd
[9] = 0;
2211 r300
->hw
.rb3d_aaresolve_ctl
.cmd
[1] = 0;
2213 r300
->hw
.rb3d_discard_src_pixel_lte_threshold
.cmd
[1] = 0x00000000;
2214 r300
->hw
.rb3d_discard_src_pixel_lte_threshold
.cmd
[2] = 0xffffffff;
2216 r300
->hw
.zb_depthclearvalue
.cmd
[1] = 0;
2218 r300
->hw
.zstencil_format
.cmd
[2] = R300_ZTOP_DISABLE
;
2219 r300
->hw
.zstencil_format
.cmd
[3] = 0x00000003;
2220 r300
->hw
.zstencil_format
.cmd
[4] = 0x00000000;
2221 r300SetEarlyZState(ctx
);
2223 r300
->hw
.unk4F30
.cmd
[1] = 0;
2224 r300
->hw
.unk4F30
.cmd
[2] = 0;
2226 r300
->hw
.zb_hiz_offset
.cmd
[1] = 0;
2228 r300
->hw
.zb_hiz_pitch
.cmd
[1] = 0;
2230 r300VapCntl(r300
, 0, 0, 0);
2232 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_0
] = 0;
2233 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_1
] = 0;
2234 r300
->hw
.vps
.cmd
[R300_VPS_POINTSIZE
] = r300PackFloat32(1.0);
2235 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_3
] = 0;
2238 r300
->radeon
.hw
.all_dirty
= GL_TRUE
;
2241 void r300UpdateShaders(r300ContextPtr rmesa
)
2244 struct r300_vertex_program
*vp
;
2247 ctx
= rmesa
->radeon
.glCtx
;
2249 if (rmesa
->radeon
.NewGLState
&& hw_tcl_on
) {
2250 rmesa
->radeon
.NewGLState
= 0;
2252 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
2253 rmesa
->temp_attrib
[i
] =
2254 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
];
2255 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] =
2256 &rmesa
->dummy_attrib
[i
];
2259 _tnl_UpdateFixedFunctionProgram(ctx
);
2261 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
2262 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] =
2263 rmesa
->temp_attrib
[i
];
2266 r300SelectVertexShader(rmesa
);
2267 vp
= (struct r300_vertex_program
*)
2268 CURRENT_VERTEX_SHADER(ctx
);
2269 /*if (vp->translated == GL_FALSE)
2270 r300TranslateVertexShader(vp); */
2271 if (vp
->translated
== GL_FALSE
) {
2272 fprintf(stderr
, "Failing back to sw-tcl\n");
2273 hw_tcl_on
= future_hw_tcl_on
= 0;
2274 r300ResetHwState(rmesa
);
2276 r300UpdateStateParameters(ctx
, _NEW_PROGRAM
);
2280 r300UpdateStateParameters(ctx
, _NEW_PROGRAM
);
2283 static const GLfloat
*get_fragmentprogram_constant(GLcontext
*ctx
,
2284 struct gl_program
*program
, struct prog_src_register srcreg
)
2286 static const GLfloat dummy
[4] = { 0, 0, 0, 0 };
2288 switch(srcreg
.File
) {
2289 case PROGRAM_LOCAL_PARAM
:
2290 return program
->LocalParams
[srcreg
.Index
];
2291 case PROGRAM_ENV_PARAM
:
2292 return ctx
->FragmentProgram
.Parameters
[srcreg
.Index
];
2293 case PROGRAM_STATE_VAR
:
2294 case PROGRAM_NAMED_PARAM
:
2295 case PROGRAM_CONSTANT
:
2296 return program
->Parameters
->ParameterValues
[srcreg
.Index
];
2298 _mesa_problem(ctx
, "get_fragmentprogram_constant: Unknown\n");
2304 static void r300SetupPixelShader(r300ContextPtr rmesa
)
2306 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
2307 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
2308 (char *)ctx
->FragmentProgram
._Current
;
2309 struct r300_fragment_program_code
*code
;
2312 if (!fp
) /* should only happenen once, just after context is created */
2315 r300TranslateFragmentShader(rmesa
, fp
);
2316 if (!fp
->translated
) {
2317 fprintf(stderr
, "%s: No valid fragment shader, exiting\n",
2323 r300SetupTextures(ctx
);
2325 R300_STATECHANGE(rmesa
, fpi
[0]);
2326 R300_STATECHANGE(rmesa
, fpi
[1]);
2327 R300_STATECHANGE(rmesa
, fpi
[2]);
2328 R300_STATECHANGE(rmesa
, fpi
[3]);
2329 rmesa
->hw
.fpi
[0].cmd
[R300_FPI_CMD_0
] = cmdpacket0(rmesa
->radeon
.radeonScreen
, R300_US_ALU_RGB_INST_0
, code
->alu
.length
);
2330 rmesa
->hw
.fpi
[1].cmd
[R300_FPI_CMD_0
] = cmdpacket0(rmesa
->radeon
.radeonScreen
, R300_US_ALU_RGB_ADDR_0
, code
->alu
.length
);
2331 rmesa
->hw
.fpi
[2].cmd
[R300_FPI_CMD_0
] = cmdpacket0(rmesa
->radeon
.radeonScreen
, R300_US_ALU_ALPHA_INST_0
, code
->alu
.length
);
2332 rmesa
->hw
.fpi
[3].cmd
[R300_FPI_CMD_0
] = cmdpacket0(rmesa
->radeon
.radeonScreen
, R300_US_ALU_ALPHA_ADDR_0
, code
->alu
.length
);
2333 for (i
= 0; i
< code
->alu
.length
; i
++) {
2334 rmesa
->hw
.fpi
[0].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst0
;
2335 rmesa
->hw
.fpi
[1].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst1
;
2336 rmesa
->hw
.fpi
[2].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst2
;
2337 rmesa
->hw
.fpi
[3].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst3
;
2340 R300_STATECHANGE(rmesa
, fp
);
2341 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL0
] = code
->cur_node
| (code
->first_node_has_tex
<< 3);
2342 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL1
] = code
->max_temp_idx
;
2343 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL2
] =
2344 (0 << R300_PFS_CNTL_ALU_OFFSET_SHIFT
) |
2345 ((code
->alu
.length
-1) << R300_PFS_CNTL_ALU_END_SHIFT
) |
2346 (0 << R300_PFS_CNTL_TEX_OFFSET_SHIFT
) |
2347 ((code
->tex
.length
? code
->tex
.length
-1 : 0) << R300_PFS_CNTL_TEX_END_SHIFT
);
2348 /* I just want to say, the way these nodes are stored.. weird.. */
2349 for (i
= 0, k
= (4 - (code
->cur_node
+ 1)); i
< 4; i
++, k
++) {
2350 if (i
< (code
->cur_node
+ 1)) {
2351 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+ k
] =
2352 (code
->node
[i
].alu_offset
<< R300_ALU_START_SHIFT
) |
2353 (code
->node
[i
].alu_end
<< R300_ALU_SIZE_SHIFT
) |
2354 (code
->node
[i
].tex_offset
<< R300_TEX_START_SHIFT
) |
2355 (code
->node
[i
].tex_end
<< R300_TEX_SIZE_SHIFT
) |
2356 code
->node
[i
].flags
;
2358 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+ (3 - i
)] = 0;
2362 R300_STATECHANGE(rmesa
, fpp
);
2363 rmesa
->hw
.fpp
.cmd
[R300_FPP_CMD_0
] = cmdpacket0(rmesa
->radeon
.radeonScreen
, R300_PFS_PARAM_0_X
, code
->const_nr
* 4);
2364 for (i
= 0; i
< code
->const_nr
; i
++) {
2365 const GLfloat
*constant
= get_fragmentprogram_constant(ctx
,
2366 &fp
->mesa_program
.Base
, code
->constant
[i
]);
2367 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 0] = r300PackFloat24(constant
[0]);
2368 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 1] = r300PackFloat24(constant
[1]);
2369 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 2] = r300PackFloat24(constant
[2]);
2370 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 3] = r300PackFloat24(constant
[3]);
2374 #define bump_r500fp_count(ptr, new_count) do{\
2375 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
2376 int _nc=(new_count)/6; \
2377 assert(_nc < 256); \
2378 if(_nc>_p->r500fp.count)_p->r500fp.count=_nc;\
2381 #define bump_r500fp_const_count(ptr, new_count) do{\
2382 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
2383 int _nc=(new_count)/4; \
2384 assert(_nc < 256); \
2385 if(_nc>_p->r500fp.count)_p->r500fp.count=_nc;\
2388 static void r500SetupPixelShader(r300ContextPtr rmesa
)
2390 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
2391 struct r500_fragment_program
*fp
= (struct r500_fragment_program
*)
2392 (char *)ctx
->FragmentProgram
._Current
;
2394 struct r500_fragment_program_code
*code
;
2396 if (!fp
) /* should only happenen once, just after context is created */
2399 ((drm_r300_cmd_header_t
*) rmesa
->hw
.r500fp
.cmd
)->r500fp
.count
= 0;
2400 ((drm_r300_cmd_header_t
*) rmesa
->hw
.r500fp_const
.cmd
)->r500fp
.count
= 0;
2402 r500TranslateFragmentShader(rmesa
, fp
);
2403 if (!fp
->translated
) {
2404 fprintf(stderr
, "%s: No valid fragment shader, exiting\n",
2410 r300SetupTextures(ctx
);
2412 R300_STATECHANGE(rmesa
, fp
);
2413 rmesa
->hw
.fp
.cmd
[R500_FP_PIXSIZE
] = code
->max_temp_idx
;
2415 rmesa
->hw
.fp
.cmd
[R500_FP_CODE_ADDR
] =
2416 R500_US_CODE_START_ADDR(code
->inst_offset
) |
2417 R500_US_CODE_END_ADDR(code
->inst_end
);
2418 rmesa
->hw
.fp
.cmd
[R500_FP_CODE_RANGE
] =
2419 R500_US_CODE_RANGE_ADDR(code
->inst_offset
) |
2420 R500_US_CODE_RANGE_SIZE(code
->inst_end
);
2421 rmesa
->hw
.fp
.cmd
[R500_FP_CODE_OFFSET
] =
2422 R500_US_CODE_OFFSET_ADDR(0); /* FIXME when we add flow control */
2424 R300_STATECHANGE(rmesa
, r500fp
);
2425 /* Emit our shader... */
2426 for (i
= 0; i
< code
->inst_end
+1; i
++) {
2427 rmesa
->hw
.r500fp
.cmd
[i
*6+1] = code
->inst
[i
].inst0
;
2428 rmesa
->hw
.r500fp
.cmd
[i
*6+2] = code
->inst
[i
].inst1
;
2429 rmesa
->hw
.r500fp
.cmd
[i
*6+3] = code
->inst
[i
].inst2
;
2430 rmesa
->hw
.r500fp
.cmd
[i
*6+4] = code
->inst
[i
].inst3
;
2431 rmesa
->hw
.r500fp
.cmd
[i
*6+5] = code
->inst
[i
].inst4
;
2432 rmesa
->hw
.r500fp
.cmd
[i
*6+6] = code
->inst
[i
].inst5
;
2435 bump_r500fp_count(rmesa
->hw
.r500fp
.cmd
, (code
->inst_end
+ 1) * 6);
2437 R300_STATECHANGE(rmesa
, r500fp_const
);
2438 for (i
= 0; i
< code
->const_nr
; i
++) {
2439 const GLfloat
*constant
= get_fragmentprogram_constant(ctx
,
2440 &fp
->mesa_program
.Base
, code
->constant
[i
]);
2441 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 0] = r300PackFloat32(constant
[0]);
2442 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 1] = r300PackFloat32(constant
[1]);
2443 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 2] = r300PackFloat32(constant
[2]);
2444 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 3] = r300PackFloat32(constant
[3]);
2446 bump_r500fp_const_count(rmesa
->hw
.r500fp_const
.cmd
, code
->const_nr
* 4);
2450 void r300UpdateShaderStates(r300ContextPtr rmesa
)
2453 ctx
= rmesa
->radeon
.glCtx
;
2455 r300SetEarlyZState(ctx
);
2457 /* w_fmt value is set to get best performance
2458 * see p.130 R5xx 3D acceleration guide v1.3 */
2459 GLuint w_fmt
, fgdepthsrc
;
2460 if (current_fragment_program_writes_depth(ctx
)) {
2461 fgdepthsrc
= R300_FG_DEPTH_SRC_SHADER
;
2462 w_fmt
= R300_W_FMT_W24
| R300_W_SRC_US
;
2464 fgdepthsrc
= R300_FG_DEPTH_SRC_SCAN
;
2465 w_fmt
= R300_W_FMT_W0
| R300_W_SRC_US
;
2468 if (w_fmt
!= rmesa
->hw
.us_out_fmt
.cmd
[5]) {
2469 R300_STATECHANGE(rmesa
, us_out_fmt
);
2470 rmesa
->hw
.us_out_fmt
.cmd
[5] = w_fmt
;
2473 if (fgdepthsrc
!= rmesa
->hw
.fg_depth_src
.cmd
[1]) {
2474 R300_STATECHANGE(rmesa
, fg_depth_src
);
2475 rmesa
->hw
.fg_depth_src
.cmd
[1] = fgdepthsrc
;
2478 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
2479 r500SetupPixelShader(rmesa
);
2481 r300SetupPixelShader(rmesa
);
2483 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
2484 r500SetupRSUnit(ctx
);
2486 r300SetupRSUnit(ctx
);
2488 if ((rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
2489 r300SetupVertexProgram(rmesa
);
2494 * Called by Mesa after an internal state update.
2496 static void r300InvalidateState(GLcontext
* ctx
, GLuint new_state
)
2498 r300ContextPtr r300
= R300_CONTEXT(ctx
);
2500 _swrast_InvalidateState(ctx
, new_state
);
2501 _swsetup_InvalidateState(ctx
, new_state
);
2502 _vbo_InvalidateState(ctx
, new_state
);
2503 _tnl_InvalidateState(ctx
, new_state
);
2504 _ae_invalidate_state(ctx
, new_state
);
2506 if (new_state
& (_NEW_BUFFERS
| _NEW_COLOR
| _NEW_PIXEL
)) {
2507 _mesa_update_framebuffer(ctx
);
2508 /* this updates the DrawBuffer's Width/Height if it's a FBO */
2509 _mesa_update_draw_buffer_bounds(ctx
);
2511 R300_STATECHANGE(r300
, cb
);
2514 r300UpdateStateParameters(ctx
, new_state
);
2516 r300
->radeon
.NewGLState
|= new_state
;
2520 * Calculate initial hardware state and register state functions.
2521 * Assumes that the command buffer and state atoms have been
2522 * initialized already.
2524 void r300InitState(r300ContextPtr r300
)
2526 memset(&(r300
->state
.texture
), 0, sizeof(r300
->state
.texture
));
2528 r300ResetHwState(r300
);
2531 static void r300RenderMode(GLcontext
* ctx
, GLenum mode
)
2533 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
2538 void r300UpdateClipPlanes( GLcontext
*ctx
)
2540 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
2543 for (p
= 0; p
< ctx
->Const
.MaxClipPlanes
; p
++) {
2544 if (ctx
->Transform
.ClipPlanesEnabled
& (1 << p
)) {
2545 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
2547 R300_STATECHANGE( rmesa
, vpucp
[p
] );
2548 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_X
] = ip
[0];
2549 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_Y
] = ip
[1];
2550 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_Z
] = ip
[2];
2551 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_W
] = ip
[3];
2557 * Initialize driver's state callback functions
2559 void r300InitStateFuncs(struct dd_function_table
*functions
)
2562 functions
->UpdateState
= r300InvalidateState
;
2563 functions
->AlphaFunc
= r300AlphaFunc
;
2564 functions
->BlendColor
= r300BlendColor
;
2565 functions
->BlendEquationSeparate
= r300BlendEquationSeparate
;
2566 functions
->BlendFuncSeparate
= r300BlendFuncSeparate
;
2567 functions
->Enable
= r300Enable
;
2568 functions
->ColorMask
= r300ColorMask
;
2569 functions
->DepthFunc
= r300DepthFunc
;
2570 functions
->DepthMask
= r300DepthMask
;
2571 functions
->CullFace
= r300CullFace
;
2572 functions
->FrontFace
= r300FrontFace
;
2573 functions
->ShadeModel
= r300ShadeModel
;
2574 functions
->LogicOpcode
= r300LogicOpcode
;
2576 /* ARB_point_parameters */
2577 functions
->PointParameterfv
= r300PointParameter
;
2579 /* Stencil related */
2580 functions
->StencilFuncSeparate
= r300StencilFuncSeparate
;
2581 functions
->StencilMaskSeparate
= r300StencilMaskSeparate
;
2582 functions
->StencilOpSeparate
= r300StencilOpSeparate
;
2584 /* Viewport related */
2585 functions
->Viewport
= r300Viewport
;
2586 functions
->DepthRange
= r300DepthRange
;
2587 functions
->PointSize
= r300PointSize
;
2588 functions
->LineWidth
= r300LineWidth
;
2590 functions
->PolygonOffset
= r300PolygonOffset
;
2591 functions
->PolygonMode
= r300PolygonMode
;
2593 functions
->RenderMode
= r300RenderMode
;
2595 functions
->ClipPlane
= r300ClipPlane
;
2596 functions
->Scissor
= radeonScissor
;
2598 functions
->DrawBuffer
= radeonDrawBuffer
;
2599 functions
->ReadBuffer
= radeonReadBuffer
;