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"
56 #include "tnl/t_vp_build.h"
58 #include "r300_context.h"
59 #include "r300_ioctl.h"
60 #include "r300_state.h"
62 #include "r300_emit.h"
64 #include "r300_fragprog_common.h"
65 #include "r300_fragprog.h"
66 #include "r500_fragprog.h"
68 #include "drirenderbuffer.h"
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
->options
.hw_tcl_enabled
)
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
->options
.hw_tcl_enabled
)
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 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*) ctx
->FragmentProgram
._Current
;
455 return (fp
&& fp
->writes_depth
);
458 static void r300SetEarlyZState(GLcontext
* ctx
)
460 r300ContextPtr r300
= R300_CONTEXT(ctx
);
461 GLuint topZ
= R300_ZTOP_ENABLE
;
463 if (ctx
->Color
.AlphaEnabled
&& ctx
->Color
.AlphaFunc
!= GL_ALWAYS
)
464 topZ
= R300_ZTOP_DISABLE
;
465 else if (current_fragment_program_writes_depth(ctx
))
466 topZ
= R300_ZTOP_DISABLE
;
467 else if (ctx
->FragmentProgram
._Current
&& ctx
->FragmentProgram
._Current
->UsesKill
)
468 topZ
= R300_ZTOP_DISABLE
;
470 if (topZ
!= r300
->hw
.zstencil_format
.cmd
[2]) {
471 /* Note: This completely reemits the stencil format.
472 * I have not tested whether this is strictly necessary,
473 * or if emitting a write to ZB_ZTOP is enough.
475 R300_STATECHANGE(r300
, zstencil_format
);
476 r300
->hw
.zstencil_format
.cmd
[2] = topZ
;
480 static void r300SetAlphaState(GLcontext
* ctx
)
482 r300ContextPtr r300
= R300_CONTEXT(ctx
);
484 uint32_t pp_misc
= 0x0;
485 GLboolean really_enabled
= ctx
->Color
.AlphaEnabled
;
487 CLAMPED_FLOAT_TO_UBYTE(refByte
, ctx
->Color
.AlphaRef
);
489 switch (ctx
->Color
.AlphaFunc
) {
491 pp_misc
|= R300_FG_ALPHA_FUNC_NEVER
;
494 pp_misc
|= R300_FG_ALPHA_FUNC_LESS
;
497 pp_misc
|= R300_FG_ALPHA_FUNC_EQUAL
;
500 pp_misc
|= R300_FG_ALPHA_FUNC_LE
;
503 pp_misc
|= R300_FG_ALPHA_FUNC_GREATER
;
506 pp_misc
|= R300_FG_ALPHA_FUNC_NOTEQUAL
;
509 pp_misc
|= R300_FG_ALPHA_FUNC_GE
;
512 /*pp_misc |= FG_ALPHA_FUNC_ALWAYS; */
513 really_enabled
= GL_FALSE
;
517 if (really_enabled
) {
518 pp_misc
|= R300_FG_ALPHA_FUNC_ENABLE
;
519 pp_misc
|= R500_FG_ALPHA_FUNC_8BIT
;
520 pp_misc
|= (refByte
& R300_FG_ALPHA_FUNC_VAL_MASK
);
525 R300_STATECHANGE(r300
, at
);
526 r300
->hw
.at
.cmd
[R300_AT_ALPHA_TEST
] = pp_misc
;
527 r300
->hw
.at
.cmd
[R300_AT_UNKNOWN
] = 0;
530 static void r300AlphaFunc(GLcontext
* ctx
, GLenum func
, GLfloat ref
)
534 r300SetAlphaState(ctx
);
537 static int translate_func(int func
)
541 return R300_ZS_NEVER
;
545 return R300_ZS_EQUAL
;
547 return R300_ZS_LEQUAL
;
549 return R300_ZS_GREATER
;
551 return R300_ZS_NOTEQUAL
;
553 return R300_ZS_GEQUAL
;
555 return R300_ZS_ALWAYS
;
560 static void r300SetDepthState(GLcontext
* ctx
)
562 r300ContextPtr r300
= R300_CONTEXT(ctx
);
564 R300_STATECHANGE(r300
, zs
);
565 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &= R300_STENCIL_ENABLE
|R300_STENCIL_FRONT_BACK
;
566 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= ~(R300_ZS_MASK
<< R300_Z_FUNC_SHIFT
);
568 if (ctx
->Depth
.Test
) {
569 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_Z_ENABLE
;
571 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_Z_WRITE_ENABLE
;
572 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
573 translate_func(ctx
->Depth
.Func
) << R300_Z_FUNC_SHIFT
;
577 static void r300SetStencilState(GLcontext
* ctx
, GLboolean state
)
579 r300ContextPtr r300
= R300_CONTEXT(ctx
);
580 GLboolean hw_stencil
= GL_FALSE
;
581 if (ctx
->DrawBuffer
) {
582 struct radeon_renderbuffer
*rrbStencil
583 = radeon_get_renderbuffer(ctx
->DrawBuffer
, BUFFER_STENCIL
);
584 hw_stencil
= (rrbStencil
&& rrbStencil
->bo
);
588 R300_STATECHANGE(r300
, zs
);
590 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |=
593 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &=
594 ~R300_STENCIL_ENABLE
;
598 FALLBACK(&r300
->radeon
, RADEON_FALLBACK_STENCIL
, state
);
603 static void r300UpdatePolygonMode(GLcontext
* ctx
)
605 r300ContextPtr r300
= R300_CONTEXT(ctx
);
606 uint32_t hw_mode
= R300_GA_POLY_MODE_DISABLE
;
608 /* Only do something if a polygon mode is wanted, default is GL_FILL */
609 if (ctx
->Polygon
.FrontMode
!= GL_FILL
||
610 ctx
->Polygon
.BackMode
!= GL_FILL
) {
613 /* Handle GL_CW (clock wise and GL_CCW (counter clock wise)
614 * correctly by selecting the correct front and back face
616 if (ctx
->Polygon
.FrontFace
== GL_CCW
) {
617 f
= ctx
->Polygon
.FrontMode
;
618 b
= ctx
->Polygon
.BackMode
;
620 f
= ctx
->Polygon
.BackMode
;
621 b
= ctx
->Polygon
.FrontMode
;
624 /* Enable polygon mode */
625 hw_mode
|= R300_GA_POLY_MODE_DUAL
;
629 hw_mode
|= R300_GA_POLY_MODE_FRONT_PTYPE_LINE
;
632 hw_mode
|= R300_GA_POLY_MODE_FRONT_PTYPE_POINT
;
635 hw_mode
|= R300_GA_POLY_MODE_FRONT_PTYPE_TRI
;
641 hw_mode
|= R300_GA_POLY_MODE_BACK_PTYPE_LINE
;
644 hw_mode
|= R300_GA_POLY_MODE_BACK_PTYPE_POINT
;
647 hw_mode
|= R300_GA_POLY_MODE_BACK_PTYPE_TRI
;
652 if (r300
->hw
.polygon_mode
.cmd
[1] != hw_mode
) {
653 R300_STATECHANGE(r300
, polygon_mode
);
654 r300
->hw
.polygon_mode
.cmd
[1] = hw_mode
;
657 r300
->hw
.polygon_mode
.cmd
[2] = 0x00000001;
658 r300
->hw
.polygon_mode
.cmd
[3] = 0x00000000;
662 * Change the culling mode.
664 * \note Mesa already filters redundant calls to this function.
666 static void r300CullFace(GLcontext
* ctx
, GLenum mode
)
670 r300UpdateCulling(ctx
);
674 * Change the polygon orientation.
676 * \note Mesa already filters redundant calls to this function.
678 static void r300FrontFace(GLcontext
* ctx
, GLenum mode
)
682 r300UpdateCulling(ctx
);
683 r300UpdatePolygonMode(ctx
);
687 * Change the depth testing function.
689 * \note Mesa already filters redundant calls to this function.
691 static void r300DepthFunc(GLcontext
* ctx
, GLenum func
)
694 r300SetDepthState(ctx
);
698 * Enable/Disable depth writing.
700 * \note Mesa already filters redundant calls to this function.
702 static void r300DepthMask(GLcontext
* ctx
, GLboolean mask
)
705 r300SetDepthState(ctx
);
709 * Handle glColorMask()
711 static void r300ColorMask(GLcontext
* ctx
,
712 GLboolean r
, GLboolean g
, GLboolean b
, GLboolean a
)
714 r300ContextPtr r300
= R300_CONTEXT(ctx
);
715 int mask
= (r
? RB3D_COLOR_CHANNEL_MASK_RED_MASK0
: 0) |
716 (g
? RB3D_COLOR_CHANNEL_MASK_GREEN_MASK0
: 0) |
717 (b
? RB3D_COLOR_CHANNEL_MASK_BLUE_MASK0
: 0) |
718 (a
? RB3D_COLOR_CHANNEL_MASK_ALPHA_MASK0
: 0);
720 if (mask
!= r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
]) {
721 R300_STATECHANGE(r300
, cmk
);
722 r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
] = mask
;
726 /* =============================================================
729 static void r300PointSize(GLcontext
* ctx
, GLfloat size
)
731 r300ContextPtr r300
= R300_CONTEXT(ctx
);
733 /* We need to clamp to user defined range here, because
734 * the HW clamping happens only for per vertex point size. */
735 size
= CLAMP(size
, ctx
->Point
.MinSize
, ctx
->Point
.MaxSize
);
737 /* same size limits for AA, non-AA points */
738 size
= CLAMP(size
, ctx
->Const
.MinPointSize
, ctx
->Const
.MaxPointSize
);
740 R300_STATECHANGE(r300
, ps
);
741 r300
->hw
.ps
.cmd
[R300_PS_POINTSIZE
] =
742 ((int)(size
* 6) << R300_POINTSIZE_X_SHIFT
) |
743 ((int)(size
* 6) << R300_POINTSIZE_Y_SHIFT
);
746 static void r300PointParameter(GLcontext
* ctx
, GLenum pname
, const GLfloat
* param
)
748 r300ContextPtr r300
= R300_CONTEXT(ctx
);
751 case GL_POINT_SIZE_MIN
:
752 R300_STATECHANGE(r300
, ga_point_minmax
);
753 r300
->hw
.ga_point_minmax
.cmd
[1] &= ~R300_GA_POINT_MINMAX_MIN_MASK
;
754 r300
->hw
.ga_point_minmax
.cmd
[1] |= (GLuint
)(ctx
->Point
.MinSize
* 6.0);
756 case GL_POINT_SIZE_MAX
:
757 R300_STATECHANGE(r300
, ga_point_minmax
);
758 r300
->hw
.ga_point_minmax
.cmd
[1] &= ~R300_GA_POINT_MINMAX_MAX_MASK
;
759 r300
->hw
.ga_point_minmax
.cmd
[1] |= (GLuint
)(ctx
->Point
.MaxSize
* 6.0)
760 << R300_GA_POINT_MINMAX_MAX_SHIFT
;
762 case GL_POINT_DISTANCE_ATTENUATION
:
764 case GL_POINT_FADE_THRESHOLD_SIZE
:
771 /* =============================================================
774 static void r300LineWidth(GLcontext
* ctx
, GLfloat widthf
)
776 r300ContextPtr r300
= R300_CONTEXT(ctx
);
778 widthf
= CLAMP(widthf
,
779 ctx
->Const
.MinPointSize
,
780 ctx
->Const
.MaxPointSize
);
781 R300_STATECHANGE(r300
, lcntl
);
782 r300
->hw
.lcntl
.cmd
[1] =
783 R300_LINE_CNT_HO
| R300_LINE_CNT_VE
| (int)(widthf
* 6.0);
786 static void r300PolygonMode(GLcontext
* ctx
, GLenum face
, GLenum mode
)
791 r300UpdatePolygonMode(ctx
);
794 /* =============================================================
798 static int translate_stencil_op(int op
)
806 return R300_ZS_REPLACE
;
811 case GL_INCR_WRAP_EXT
:
812 return R300_ZS_INCR_WRAP
;
813 case GL_DECR_WRAP_EXT
:
814 return R300_ZS_DECR_WRAP
;
816 return R300_ZS_INVERT
;
818 WARN_ONCE("Do not know how to translate stencil op");
824 static void r300ShadeModel(GLcontext
* ctx
, GLenum mode
)
826 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
828 R300_STATECHANGE(rmesa
, shade
);
829 rmesa
->hw
.shade
.cmd
[1] = 0x00000002;
830 R300_STATECHANGE(rmesa
, shade2
);
833 rmesa
->hw
.shade2
.cmd
[1] = R300_RE_SHADE_MODEL_FLAT
;
836 rmesa
->hw
.shade2
.cmd
[1] = R300_RE_SHADE_MODEL_SMOOTH
;
841 rmesa
->hw
.shade2
.cmd
[2] = 0x00000000;
842 rmesa
->hw
.shade2
.cmd
[3] = 0x00000000;
845 static void r300StencilFuncSeparate(GLcontext
* ctx
, GLenum face
,
846 GLenum func
, GLint ref
, GLuint mask
)
848 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
850 ((ctx
->Stencil
.Ref
[0] & 0xff) << R300_STENCILREF_SHIFT
)
851 | ((ctx
->Stencil
.ValueMask
[0] & 0xff) << R300_STENCILMASK_SHIFT
);
852 const unsigned back
= ctx
->Stencil
._BackFace
;
855 R300_STATECHANGE(rmesa
, zs
);
856 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_STENCIL_FRONT_BACK
;
857 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= ~((R300_ZS_MASK
<<
858 R300_S_FRONT_FUNC_SHIFT
)
860 R300_S_BACK_FUNC_SHIFT
));
862 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &=
863 ~((R300_STENCILREF_MASK
<< R300_STENCILREF_SHIFT
) |
864 (R300_STENCILREF_MASK
<< R300_STENCILMASK_SHIFT
));
866 flag
= translate_func(ctx
->Stencil
.Function
[0]);
867 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
868 (flag
<< R300_S_FRONT_FUNC_SHIFT
);
870 flag
= translate_func(ctx
->Stencil
.Function
[back
]);
872 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
873 (flag
<< R300_S_BACK_FUNC_SHIFT
);
874 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |= refmask
;
877 static void r300StencilMaskSeparate(GLcontext
* ctx
, GLenum face
, GLuint mask
)
879 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
881 R300_STATECHANGE(rmesa
, zs
);
882 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &=
883 ~(R300_STENCILREF_MASK
<<
884 R300_STENCILWRITEMASK_SHIFT
);
885 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |=
887 WriteMask
[0] & R300_STENCILREF_MASK
) <<
888 R300_STENCILWRITEMASK_SHIFT
;
891 static void r300StencilOpSeparate(GLcontext
* ctx
, GLenum face
,
892 GLenum fail
, GLenum zfail
, GLenum zpass
)
894 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
895 const unsigned back
= ctx
->Stencil
._BackFace
;
897 R300_STATECHANGE(rmesa
, zs
);
898 /* It is easier to mask what's left.. */
899 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &=
900 (R300_ZS_MASK
<< R300_Z_FUNC_SHIFT
) |
901 (R300_ZS_MASK
<< R300_S_FRONT_FUNC_SHIFT
) |
902 (R300_ZS_MASK
<< R300_S_BACK_FUNC_SHIFT
);
904 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
905 (translate_stencil_op(ctx
->Stencil
.FailFunc
[0]) <<
906 R300_S_FRONT_SFAIL_OP_SHIFT
)
907 | (translate_stencil_op(ctx
->Stencil
.ZFailFunc
[0]) <<
908 R300_S_FRONT_ZFAIL_OP_SHIFT
)
909 | (translate_stencil_op(ctx
->Stencil
.ZPassFunc
[0]) <<
910 R300_S_FRONT_ZPASS_OP_SHIFT
);
912 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
913 (translate_stencil_op(ctx
->Stencil
.FailFunc
[back
]) <<
914 R300_S_BACK_SFAIL_OP_SHIFT
)
915 | (translate_stencil_op(ctx
->Stencil
.ZFailFunc
[back
]) <<
916 R300_S_BACK_ZFAIL_OP_SHIFT
)
917 | (translate_stencil_op(ctx
->Stencil
.ZPassFunc
[back
]) <<
918 R300_S_BACK_ZPASS_OP_SHIFT
);
921 /* =============================================================
922 * Window position and viewport transformation
925 static void r300UpdateWindow(GLcontext
* ctx
)
927 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
928 __DRIdrawablePrivate
*dPriv
= rmesa
->radeon
.dri
.drawable
;
929 GLfloat xoffset
= dPriv
? (GLfloat
) dPriv
->x
: 0;
930 GLfloat yoffset
= dPriv
? (GLfloat
) dPriv
->y
+ dPriv
->h
: 0;
931 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
932 const GLfloat depthScale
= 1.0F
/ ctx
->DrawBuffer
->_DepthMaxF
;
933 const GLboolean render_to_fbo
= (ctx
->DrawBuffer
->Name
!= 0);
934 GLfloat y_scale
, y_bias
;
944 GLfloat sx
= v
[MAT_SX
];
945 GLfloat tx
= v
[MAT_TX
] + xoffset
;
946 GLfloat sy
= v
[MAT_SY
] * y_scale
;
947 GLfloat ty
= (v
[MAT_TY
] * y_scale
) + y_bias
;
948 GLfloat sz
= v
[MAT_SZ
] * depthScale
;
949 GLfloat tz
= v
[MAT_TZ
] * depthScale
;
951 R300_STATECHANGE(rmesa
, vpt
);
953 rmesa
->hw
.vpt
.cmd
[R300_VPT_XSCALE
] = r300PackFloat32(sx
);
954 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
955 rmesa
->hw
.vpt
.cmd
[R300_VPT_YSCALE
] = r300PackFloat32(sy
);
956 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
957 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZSCALE
] = r300PackFloat32(sz
);
958 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZOFFSET
] = r300PackFloat32(tz
);
961 static void r300Viewport(GLcontext
* ctx
, GLint x
, GLint y
,
962 GLsizei width
, GLsizei height
)
964 /* Don't pipeline viewport changes, conflict with window offset
965 * setting below. Could apply deltas to rescue pipelined viewport
966 * values, or keep the originals hanging around.
968 r300UpdateWindow(ctx
);
970 radeon_viewport(ctx
, x
, y
, width
, height
);
973 static void r300DepthRange(GLcontext
* ctx
, GLclampd nearval
, GLclampd farval
)
975 r300UpdateWindow(ctx
);
978 void r300UpdateViewportOffset(GLcontext
* ctx
)
980 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
981 __DRIdrawablePrivate
*dPriv
= ((radeonContextPtr
) rmesa
)->dri
.drawable
;
982 GLfloat xoffset
= (GLfloat
) dPriv
->x
;
983 GLfloat yoffset
= (GLfloat
) dPriv
->y
+ dPriv
->h
;
984 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
986 GLfloat tx
= v
[MAT_TX
] + xoffset
;
987 GLfloat ty
= (-v
[MAT_TY
]) + yoffset
;
989 if (rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] != r300PackFloat32(tx
) ||
990 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] != r300PackFloat32(ty
)) {
991 /* Note: this should also modify whatever data the context reset
994 R300_STATECHANGE(rmesa
, vpt
);
995 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
996 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
1000 radeonUpdateScissor(ctx
);
1004 r300FetchStateParameter(GLcontext
* ctx
,
1005 const gl_state_index state
[STATE_LENGTH
],
1008 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1011 case STATE_INTERNAL
:
1013 case STATE_R300_WINDOW_DIMENSION
:
1014 value
[0] = r300
->radeon
.dri
.drawable
->w
* 0.5f
; /* width*0.5 */
1015 value
[1] = r300
->radeon
.dri
.drawable
->h
* 0.5f
; /* height*0.5 */
1016 value
[2] = 0.5F
; /* for moving range [-1 1] -> [0 1] */
1017 value
[3] = 1.0F
; /* not used */
1020 case STATE_R300_TEXRECT_FACTOR
:{
1021 struct gl_texture_object
*t
=
1022 ctx
->Texture
.Unit
[state
[2]].CurrentTex
[TEXTURE_RECT_INDEX
];
1024 if (t
&& t
->Image
[0][t
->BaseLevel
]) {
1025 struct gl_texture_image
*image
=
1026 t
->Image
[0][t
->BaseLevel
];
1027 value
[0] = 1.0 / image
->Width2
;
1028 value
[1] = 1.0 / image
->Height2
;
1049 * Update R300's own internal state parameters.
1050 * For now just STATE_R300_WINDOW_DIMENSION
1052 void r300UpdateStateParameters(GLcontext
* ctx
, GLuint new_state
)
1054 struct r300_fragment_program
*fp
;
1055 struct gl_program_parameter_list
*paramList
;
1058 if (!(new_state
& (_NEW_BUFFERS
| _NEW_PROGRAM
| _NEW_PROGRAM_CONSTANTS
)))
1061 fp
= (struct r300_fragment_program
*)ctx
->FragmentProgram
._Current
;
1065 paramList
= fp
->Base
.Base
.Parameters
;
1070 for (i
= 0; i
< paramList
->NumParameters
; i
++) {
1071 if (paramList
->Parameters
[i
].Type
== PROGRAM_STATE_VAR
) {
1072 r300FetchStateParameter(ctx
,
1073 paramList
->Parameters
[i
].
1075 paramList
->ParameterValues
[i
]);
1080 /* =============================================================
1083 static void r300PolygonOffset(GLcontext
* ctx
, GLfloat factor
, GLfloat units
)
1085 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1086 GLfloat constant
= units
;
1088 switch (ctx
->Visual
.depthBits
) {
1099 /* fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */
1101 R300_STATECHANGE(rmesa
, zbs
);
1102 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_FACTOR
] = r300PackFloat32(factor
);
1103 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_CONSTANT
] = r300PackFloat32(constant
);
1104 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_FACTOR
] = r300PackFloat32(factor
);
1105 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_CONSTANT
] = r300PackFloat32(constant
);
1108 /* Routing and texture-related */
1110 /* r300 doesnt handle GL_CLAMP and GL_MIRROR_CLAMP_EXT correctly when filter is NEAREST.
1111 * Since texwrap produces same results for GL_CLAMP and GL_CLAMP_TO_EDGE we use them instead.
1112 * We need to recalculate wrap modes whenever filter mode is changed because someone might do:
1113 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1114 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1115 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1116 * Since r300 completely ignores R300_TX_CLAMP when either min or mag is nearest it cant handle
1117 * combinations where only one of them is nearest.
1119 static unsigned long gen_fixed_filter(unsigned long f
)
1121 unsigned long mag
, min
, needs_fixing
= 0;
1124 /* We ignore MIRROR bit so we dont have to do everything twice */
1125 if ((f
& ((7 - 1) << R300_TX_WRAP_S_SHIFT
)) ==
1126 (R300_TX_CLAMP
<< R300_TX_WRAP_S_SHIFT
)) {
1129 if ((f
& ((7 - 1) << R300_TX_WRAP_T_SHIFT
)) ==
1130 (R300_TX_CLAMP
<< R300_TX_WRAP_T_SHIFT
)) {
1133 if ((f
& ((7 - 1) << R300_TX_WRAP_R_SHIFT
)) ==
1134 (R300_TX_CLAMP
<< R300_TX_WRAP_R_SHIFT
)) {
1141 mag
= f
& R300_TX_MAG_FILTER_MASK
;
1142 min
= f
& (R300_TX_MIN_FILTER_MASK
|R300_TX_MIN_FILTER_MIP_MASK
);
1144 /* TODO: Check for anisto filters too */
1145 if ((mag
!= R300_TX_MAG_FILTER_NEAREST
)
1146 && (min
!= R300_TX_MIN_FILTER_NEAREST
))
1149 /* r300 cant handle these modes hence we force nearest to linear */
1150 if ((mag
== R300_TX_MAG_FILTER_NEAREST
)
1151 && (min
!= R300_TX_MIN_FILTER_NEAREST
)) {
1152 f
&= ~R300_TX_MAG_FILTER_NEAREST
;
1153 f
|= R300_TX_MAG_FILTER_LINEAR
;
1157 if ((min
== R300_TX_MIN_FILTER_NEAREST
)
1158 && (mag
!= R300_TX_MAG_FILTER_NEAREST
)) {
1159 f
&= ~R300_TX_MIN_FILTER_NEAREST
;
1160 f
|= R300_TX_MIN_FILTER_LINEAR
;
1164 /* Both are nearest */
1165 if (needs_fixing
& 1) {
1166 f
&= ~((7 - 1) << R300_TX_WRAP_S_SHIFT
);
1167 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_S_SHIFT
;
1169 if (needs_fixing
& 2) {
1170 f
&= ~((7 - 1) << R300_TX_WRAP_T_SHIFT
);
1171 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_T_SHIFT
;
1173 if (needs_fixing
& 4) {
1174 f
&= ~((7 - 1) << R300_TX_WRAP_R_SHIFT
);
1175 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_R_SHIFT
;
1180 static void r300SetupFragmentShaderTextures(GLcontext
*ctx
, int *tmu_mappings
)
1182 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1184 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*) ctx
->FragmentProgram
._Current
;
1185 struct r300_fragment_program_code
*code
= &fp
->code
.r300
;
1187 R300_STATECHANGE(r300
, fpt
);
1189 for (i
= 0; i
< code
->tex
.length
; i
++) {
1194 unit
= code
->tex
.inst
[i
] >> R300_TEX_ID_SHIFT
;
1197 val
= code
->tex
.inst
[i
];
1198 val
&= ~R300_TEX_ID_MASK
;
1201 (val
& R300_TEX_INST_MASK
) >> R300_TEX_INST_SHIFT
;
1202 if (opcode
== R300_TEX_OP_KIL
) {
1203 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1205 if (tmu_mappings
[unit
] >= 0) {
1207 tmu_mappings
[unit
] <<
1209 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1211 // We get here when the corresponding texture image is incomplete
1212 // (e.g. incomplete mipmaps etc.)
1213 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1218 r300
->hw
.fpt
.cmd
[R300_FPT_CMD_0
] =
1219 cmdpacket0(r300
->radeon
.radeonScreen
,
1220 R300_US_TEX_INST_0
, code
->tex
.length
);
1223 static void r500SetupFragmentShaderTextures(GLcontext
*ctx
, int *tmu_mappings
)
1226 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*) ctx
->FragmentProgram
._Current
;
1227 struct r500_fragment_program_code
*code
= &fp
->code
.r500
;
1229 /* find all the texture instructions and relocate the texture units */
1230 for (i
= 0; i
< code
->inst_end
+ 1; i
++) {
1231 if ((code
->inst
[i
].inst0
& 0x3) == R500_INST_TYPE_TEX
) {
1233 int unit
, opcode
, new_unit
;
1235 val
= code
->inst
[i
].inst1
;
1237 unit
= (val
>> 16) & 0xf;
1239 val
&= ~(0xf << 16);
1241 opcode
= val
& (0x7 << 22);
1242 if (opcode
== R500_TEX_INST_TEXKILL
) {
1245 if (tmu_mappings
[unit
] >= 0) {
1246 new_unit
= tmu_mappings
[unit
];
1251 val
|= R500_TEX_ID(new_unit
);
1252 code
->inst
[i
].inst1
= val
;
1257 static GLuint
translate_lod_bias(GLfloat bias
)
1259 GLint b
= (int)(bias
*32);
1262 else if (b
< -(1 << 9))
1264 return (((GLuint
)b
) << R300_LOD_BIAS_SHIFT
) & R300_LOD_BIAS_MASK
;
1267 static void r300SetupTextures(GLcontext
* ctx
)
1270 struct radeon_tex_obj
*t
;
1271 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1273 int last_hw_tmu
= -1; /* -1 translates into no setup costs for fields */
1274 int tmu_mappings
[R300_MAX_TEXTURE_UNITS
] = { -1, };
1275 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
1276 (char *)ctx
->FragmentProgram
._Current
;
1278 R300_STATECHANGE(r300
, txe
);
1279 R300_STATECHANGE(r300
, tex
.filter
);
1280 R300_STATECHANGE(r300
, tex
.filter_1
);
1281 R300_STATECHANGE(r300
, tex
.size
);
1282 R300_STATECHANGE(r300
, tex
.format
);
1283 R300_STATECHANGE(r300
, tex
.pitch
);
1284 R300_STATECHANGE(r300
, tex
.offset
);
1285 R300_STATECHANGE(r300
, tex
.chroma_key
);
1286 R300_STATECHANGE(r300
, tex
.border_color
);
1288 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] = 0x0;
1290 mtu
= r300
->radeon
.glCtx
->Const
.MaxTextureUnits
;
1291 if (RADEON_DEBUG
& DEBUG_STATE
)
1292 fprintf(stderr
, "mtu=%d\n", mtu
);
1294 if (mtu
> R300_MAX_TEXTURE_UNITS
) {
1296 "Aiiee ! mtu=%d is greater than R300_MAX_TEXTURE_UNITS=%d\n",
1297 mtu
, R300_MAX_TEXTURE_UNITS
);
1301 /* We cannot let disabled tmu offsets pass DRM */
1302 for (i
= 0; i
< mtu
; i
++) {
1303 if (ctx
->Texture
.Unit
[i
]._ReallyEnabled
) {
1304 tmu_mappings
[i
] = hw_tmu
;
1306 t
= radeon_tex_obj(ctx
->Texture
.Unit
[i
]._Current
);
1310 if ((t
->pp_txformat
& 0xffffff00) == 0xffffff00) {
1312 ("unknown texture format (entry %x) encountered. Help me !\n",
1313 t
->pp_txformat
& 0xff);
1316 if (RADEON_DEBUG
& DEBUG_STATE
)
1318 "Activating texture unit %d\n", i
);
1320 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] |= (1 << hw_tmu
);
1322 r300
->hw
.tex
.filter
.cmd
[R300_TEX_VALUE_0
+
1324 gen_fixed_filter(t
->pp_txfilter
) | (hw_tmu
<< 28);
1325 /* Note: There is a LOD bias per texture unit and a LOD bias
1326 * per texture object. We add them here to get the correct behaviour.
1327 * (The per-texture object LOD bias was introduced in OpenGL 1.4
1328 * and is not present in the EXT_texture_object extension).
1330 r300
->hw
.tex
.filter_1
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] =
1332 translate_lod_bias(ctx
->Texture
.Unit
[i
].LodBias
+ t
->base
.LodBias
);
1333 r300
->hw
.tex
.size
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] =
1335 r300
->hw
.tex
.format
.cmd
[R300_TEX_VALUE_0
+
1336 hw_tmu
] = t
->pp_txformat
;
1337 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] =
1339 r300
->hw
.textures
[hw_tmu
] = t
;
1341 if (t
->tile_bits
& R300_TXO_MACRO_TILE
) {
1342 WARN_ONCE("macro tiling enabled!\n");
1345 if (t
->tile_bits
& R300_TXO_MICRO_TILE
) {
1346 WARN_ONCE("micro tiling enabled!\n");
1349 r300
->hw
.tex
.chroma_key
.cmd
[R300_TEX_VALUE_0
+
1351 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_VALUE_0
+
1355 last_hw_tmu
= hw_tmu
;
1361 r300
->hw
.tex
.filter
.cmd
[R300_TEX_CMD_0
] =
1362 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_FILTER0_0
, last_hw_tmu
+ 1);
1363 r300
->hw
.tex
.filter_1
.cmd
[R300_TEX_CMD_0
] =
1364 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_FILTER1_0
, last_hw_tmu
+ 1);
1365 r300
->hw
.tex
.size
.cmd
[R300_TEX_CMD_0
] =
1366 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_SIZE_0
, last_hw_tmu
+ 1);
1367 r300
->hw
.tex
.format
.cmd
[R300_TEX_CMD_0
] =
1368 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_FORMAT_0
, last_hw_tmu
+ 1);
1369 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_CMD_0
] =
1370 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_FORMAT2_0
, last_hw_tmu
+ 1);
1371 r300
->hw
.tex
.offset
.cmd
[R300_TEX_CMD_0
] =
1372 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_OFFSET_0
, last_hw_tmu
+ 1);
1373 r300
->hw
.tex
.chroma_key
.cmd
[R300_TEX_CMD_0
] =
1374 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_CHROMA_KEY_0
, last_hw_tmu
+ 1);
1375 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_CMD_0
] =
1376 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_BORDER_COLOR_0
, last_hw_tmu
+ 1);
1378 if (!fp
) /* should only happenen once, just after context is created */
1381 if (r300
->radeon
.radeonScreen
->chip_family
< CHIP_FAMILY_RV515
) {
1382 if (fp
->Base
.UsesKill
&& last_hw_tmu
< 0) {
1383 // The KILL operation requires the first texture unit
1385 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] |= 1;
1386 r300
->hw
.tex
.filter
.cmd
[R300_TEX_VALUE_0
] = 0;
1387 r300
->hw
.tex
.filter
.cmd
[R300_TEX_CMD_0
] =
1388 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_FILTER0_0
, 1);
1391 r300
->vtbl
.SetupFragmentShaderTextures(ctx
, tmu_mappings
);
1393 if (RADEON_DEBUG
& DEBUG_STATE
)
1394 fprintf(stderr
, "TX_ENABLE: %08x last_hw_tmu=%d\n",
1395 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
], last_hw_tmu
);
1398 union r300_outputs_written
{
1399 GLuint vp_outputs
; /* hw_tcl_on */
1400 DECLARE_RENDERINPUTS(index_bitset
); /* !hw_tcl_on */
1403 #define R300_OUTPUTS_WRITTEN_TEST(ow, vp_result, tnl_attrib) \
1404 ((hw_tcl_on) ? (ow).vp_outputs & (1 << (vp_result)) : \
1405 RENDERINPUTS_TEST( (ow.index_bitset), (tnl_attrib) ))
1407 static void r300SetupRSUnit(GLcontext
* ctx
)
1409 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1410 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1411 struct vertex_buffer
*VB
= &tnl
->vb
;
1412 union r300_outputs_written OutputsWritten
;
1414 int fp_reg
, high_rr
;
1416 int rs_tex_count
= 0;
1417 int i
, count
, col_fmt
, hw_tcl_on
;
1419 hw_tcl_on
= r300
->options
.hw_tcl_enabled
;
1421 OutputsWritten
.vp_outputs
= CURRENT_VERTEX_SHADER(ctx
)->key
.OutputsWritten
;
1423 RENDERINPUTS_COPY(OutputsWritten
.index_bitset
, r300
->render_inputs_bitset
);
1425 if (ctx
->FragmentProgram
._Current
)
1426 InputsRead
= ctx
->FragmentProgram
._Current
->Base
.InputsRead
;
1428 fprintf(stderr
, "No ctx->FragmentProgram._Current!!\n");
1429 return; /* This should only ever happen once.. */
1432 R300_STATECHANGE(r300
, ri
);
1433 R300_STATECHANGE(r300
, rc
);
1434 R300_STATECHANGE(r300
, rr
);
1436 fp_reg
= col_ip
= tex_ip
= col_fmt
= 0;
1438 r300
->hw
.rc
.cmd
[1] = 0;
1439 r300
->hw
.rc
.cmd
[2] = 0;
1440 for (i
=0; i
<R300_RR_CMDSIZE
-1; ++i
)
1441 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ i
] = 0;
1443 for (i
=0; i
<R300_RI_CMDSIZE
-1; ++i
)
1444 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ i
] = 0;
1447 if (InputsRead
& FRAG_BIT_COL0
) {
1448 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL0
, _TNL_ATTRIB_COLOR0
)) {
1449 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR0
]->size
;
1451 col_fmt
= R300_RS_COL_FMT_RGBA
;
1452 else if (count
== 3)
1453 col_fmt
= R300_RS_COL_FMT_RGB1
;
1455 col_fmt
= R300_RS_COL_FMT_0001
;
1457 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ col_ip
] = R300_RS_COL_PTR(col_ip
) | R300_RS_COL_FMT(col_fmt
);
1458 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
);
1459 InputsRead
&= ~FRAG_BIT_COL0
;
1463 WARN_ONCE("fragprog wants col0, vp doesn't provide it\n");
1467 if (InputsRead
& FRAG_BIT_COL1
) {
1468 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL1
, _TNL_ATTRIB_COLOR1
)) {
1469 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR1
]->size
;
1471 col_fmt
= R300_RS_COL_FMT_RGBA
;
1472 else if (count
== 3)
1473 col_fmt
= R300_RS_COL_FMT_RGB1
;
1475 col_fmt
= R300_RS_COL_FMT_0001
;
1477 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ col_ip
] = R300_RS_COL_PTR(col_ip
) | R300_RS_COL_FMT(col_fmt
);
1478 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
);
1479 InputsRead
&= ~FRAG_BIT_COL1
;
1483 WARN_ONCE("fragprog wants col1, vp doesn't provide it\n");
1487 /* We always route 4 texcoord components */
1488 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
1489 if (! ( InputsRead
& FRAG_BIT_TEX(i
) ) )
1492 if (!R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_TEX0
+ i
, _TNL_ATTRIB_TEX(i
))) {
1493 WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i
);
1497 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
);
1498 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
);
1499 InputsRead
&= ~(FRAG_BIT_TEX0
<< i
);
1505 if (InputsRead
& FRAG_BIT_WPOS
) {
1506 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
);
1507 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
);
1508 InputsRead
&= ~FRAG_BIT_WPOS
;
1514 if (InputsRead
& FRAG_BIT_FOGC
) {
1515 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_FOGC
, _TNL_ATTRIB_FOG
)) {
1516 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ tex_ip
] |= R300_RS_SEL_S(0) | R300_RS_SEL_T(R300_RS_SEL_K0
) | R300_RS_SEL_R(R300_RS_SEL_K0
);
1517 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ tex_ip
] |= R300_RS_SEL_Q(R300_RS_SEL_K1
) | R300_RS_TEX_PTR(rs_tex_count
);
1518 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
);
1519 InputsRead
&= ~FRAG_BIT_FOGC
;
1524 WARN_ONCE("fragprog wants fogc, vp doesn't provide it\n");
1528 /* Setup default color if no color or tex was set */
1529 if (rs_tex_count
== 0 && col_ip
== 0) {
1530 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
);
1534 high_rr
= (col_ip
> tex_ip
) ? col_ip
: tex_ip
;
1535 r300
->hw
.rc
.cmd
[1] |= (rs_tex_count
<< R300_IT_COUNT_SHIFT
) | (col_ip
<< R300_IC_COUNT_SHIFT
) | R300_HIRES_EN
;
1536 r300
->hw
.rc
.cmd
[2] |= high_rr
- 1;
1538 r300
->hw
.rr
.cmd
[R300_RR_CMD_0
] = cmdpacket0(r300
->radeon
.radeonScreen
, R300_RS_INST_0
, high_rr
);
1541 WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead
);
1544 static void r500SetupRSUnit(GLcontext
* ctx
)
1546 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1547 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1548 struct vertex_buffer
*VB
= &tnl
->vb
;
1549 union r300_outputs_written OutputsWritten
;
1551 int fp_reg
, high_rr
;
1553 int rs_tex_count
= 0;
1554 int i
, count
, col_fmt
, hw_tcl_on
;
1556 hw_tcl_on
= r300
->options
.hw_tcl_enabled
;
1558 OutputsWritten
.vp_outputs
= CURRENT_VERTEX_SHADER(ctx
)->key
.OutputsWritten
;
1560 RENDERINPUTS_COPY(OutputsWritten
.index_bitset
, r300
->render_inputs_bitset
);
1562 if (ctx
->FragmentProgram
._Current
)
1563 InputsRead
= ctx
->FragmentProgram
._Current
->Base
.InputsRead
;
1565 fprintf(stderr
, "No ctx->FragmentProgram._Current!!\n");
1566 return; /* This should only ever happen once.. */
1569 R300_STATECHANGE(r300
, ri
);
1570 R300_STATECHANGE(r300
, rc
);
1571 R300_STATECHANGE(r300
, rr
);
1573 fp_reg
= col_ip
= tex_ip
= col_fmt
= 0;
1575 r300
->hw
.rc
.cmd
[1] = 0;
1576 r300
->hw
.rc
.cmd
[2] = 0;
1577 for (i
=0; i
<R300_RR_CMDSIZE
-1; ++i
)
1578 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ i
] = 0;
1580 for (i
=0; i
<R500_RI_CMDSIZE
-1; ++i
)
1581 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ i
] = 0;
1584 if (InputsRead
& FRAG_BIT_COL0
) {
1585 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL0
, _TNL_ATTRIB_COLOR0
)) {
1586 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR0
]->size
;
1588 col_fmt
= R300_RS_COL_FMT_RGBA
;
1589 else if (count
== 3)
1590 col_fmt
= R300_RS_COL_FMT_RGB1
;
1592 col_fmt
= R300_RS_COL_FMT_0001
;
1594 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ col_ip
] = R500_RS_COL_PTR(col_ip
) | R500_RS_COL_FMT(col_fmt
);
1595 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
);
1596 InputsRead
&= ~FRAG_BIT_COL0
;
1600 WARN_ONCE("fragprog wants col0, vp doesn't provide it\n");
1604 if (InputsRead
& FRAG_BIT_COL1
) {
1605 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL1
, _TNL_ATTRIB_COLOR1
)) {
1606 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR1
]->size
;
1608 col_fmt
= R300_RS_COL_FMT_RGBA
;
1609 else if (count
== 3)
1610 col_fmt
= R300_RS_COL_FMT_RGB1
;
1612 col_fmt
= R300_RS_COL_FMT_0001
;
1614 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ col_ip
] = R500_RS_COL_PTR(col_ip
) | R500_RS_COL_FMT(col_fmt
);
1615 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
);
1616 InputsRead
&= ~FRAG_BIT_COL1
;
1620 WARN_ONCE("fragprog wants col1, vp doesn't provide it\n");
1624 /* We always route 4 texcoord components */
1625 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
1626 if (! ( InputsRead
& FRAG_BIT_TEX(i
) ) )
1629 if (!R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_TEX0
+ i
, _TNL_ATTRIB_TEX(i
))) {
1630 WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i
);
1634 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ tex_ip
] |= ((rs_tex_count
+ 0) << R500_RS_IP_TEX_PTR_S_SHIFT
) |
1635 ((rs_tex_count
+ 1) << R500_RS_IP_TEX_PTR_T_SHIFT
) |
1636 ((rs_tex_count
+ 2) << R500_RS_IP_TEX_PTR_R_SHIFT
) |
1637 ((rs_tex_count
+ 3) << R500_RS_IP_TEX_PTR_Q_SHIFT
);
1639 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
);
1640 InputsRead
&= ~(FRAG_BIT_TEX0
<< i
);
1646 if (InputsRead
& FRAG_BIT_WPOS
) {
1647 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ tex_ip
] |= ((rs_tex_count
+ 0) << R500_RS_IP_TEX_PTR_S_SHIFT
) |
1648 ((rs_tex_count
+ 1) << R500_RS_IP_TEX_PTR_T_SHIFT
) |
1649 ((rs_tex_count
+ 2) << R500_RS_IP_TEX_PTR_R_SHIFT
) |
1650 ((rs_tex_count
+ 3) << R500_RS_IP_TEX_PTR_Q_SHIFT
);
1652 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
);
1653 InputsRead
&= ~FRAG_BIT_WPOS
;
1659 if (InputsRead
& FRAG_BIT_FOGC
) {
1660 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_FOGC
, _TNL_ATTRIB_FOG
)) {
1661 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ tex_ip
] |= (rs_tex_count
<< R500_RS_IP_TEX_PTR_S_SHIFT
) |
1662 (R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_T_SHIFT
) |
1663 (R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_R_SHIFT
) |
1664 (R500_RS_IP_PTR_K1
<< R500_RS_IP_TEX_PTR_Q_SHIFT
);
1666 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
);
1667 InputsRead
&= ~FRAG_BIT_FOGC
;
1672 WARN_ONCE("fragprog wants fogc, vp doesn't provide it\n");
1676 /* Setup default color if no color or tex was set */
1677 if (rs_tex_count
== 0 && col_ip
== 0) {
1678 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
);
1682 high_rr
= (col_ip
> tex_ip
) ? col_ip
: tex_ip
;
1683 r300
->hw
.rc
.cmd
[1] |= (rs_tex_count
<< R300_IT_COUNT_SHIFT
) | (col_ip
<< R300_IC_COUNT_SHIFT
) | R300_HIRES_EN
;
1684 r300
->hw
.rc
.cmd
[2] |= 0xC0 | (high_rr
- 1);
1686 r300
->hw
.rr
.cmd
[R300_RR_CMD_0
] = cmdpacket0(r300
->radeon
.radeonScreen
, R500_RS_INST_0
, high_rr
);
1689 WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead
);
1695 #define bump_vpu_count(ptr, new_count) do{\
1696 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
1697 int _nc=(new_count)/4; \
1698 assert(_nc < 256); \
1699 if(_nc>_p->vpu.count)_p->vpu.count=_nc;\
1702 static INLINE
void r300SetupVertexProgramFragment(r300ContextPtr r300
, int dest
, struct r300_vertex_shader_fragment
*vsf
)
1706 if (vsf
->length
== 0)
1709 if (vsf
->length
& 0x3) {
1710 fprintf(stderr
, "VERTEX_SHADER_FRAGMENT must have length divisible by 4\n");
1714 switch ((dest
>> 8) & 0xf) {
1716 R300_STATECHANGE(r300
, vpi
);
1717 for (i
= 0; i
< vsf
->length
; i
++)
1718 r300
->hw
.vpi
.cmd
[R300_VPI_INSTR_0
+ i
+ 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1719 bump_vpu_count(r300
->hw
.vpi
.cmd
, vsf
->length
+ 4 * (dest
& 0xff));
1723 R300_STATECHANGE(r300
, vpp
);
1724 for (i
= 0; i
< vsf
->length
; i
++)
1725 r300
->hw
.vpp
.cmd
[R300_VPP_PARAM_0
+ i
+ 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1726 bump_vpu_count(r300
->hw
.vpp
.cmd
, vsf
->length
+ 4 * (dest
& 0xff));
1729 R300_STATECHANGE(r300
, vps
);
1730 for (i
= 0; i
< vsf
->length
; i
++)
1731 r300
->hw
.vps
.cmd
[1 + i
+ 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1732 bump_vpu_count(r300
->hw
.vps
.cmd
, vsf
->length
+ 4 * (dest
& 0xff));
1735 fprintf(stderr
, "%s:%s don't know how to handle dest %04x\n", __FILE__
, __FUNCTION__
, dest
);
1740 #define MIN3(a, b, c) ((a) < (b) ? MIN2(a, c) : MIN2(b, c))
1743 static void r300VapCntl(r300ContextPtr rmesa
, GLuint input_count
,
1744 GLuint output_count
, GLuint temp_count
)
1750 /* Flush PVS engine before changing PVS_NUM_SLOTS, PVS_NUM_CNTRLS.
1751 * See r500 docs 6.5.2 - done in emit */
1753 /* avoid division by zero */
1754 if (input_count
== 0) input_count
= 1;
1755 if (output_count
== 0) output_count
= 1;
1756 if (temp_count
== 0) temp_count
= 1;
1758 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
1763 pvs_num_slots
= MIN3(10, vtx_mem_size
/input_count
, vtx_mem_size
/output_count
);
1764 pvs_num_cntrls
= MIN2(6, vtx_mem_size
/temp_count
);
1766 R300_STATECHANGE(rmesa
, vap_cntl
);
1767 if (rmesa
->options
.hw_tcl_enabled
) {
1768 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] =
1769 (pvs_num_slots
<< R300_PVS_NUM_SLOTS_SHIFT
) |
1770 (pvs_num_cntrls
<< R300_PVS_NUM_CNTLRS_SHIFT
) |
1771 (12 << R300_VF_MAX_VTX_NUM_SHIFT
);
1772 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
1773 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= R500_TCL_STATE_OPTIMIZATION
;
1775 /* not sure about non-tcl */
1776 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] = ((10 << R300_PVS_NUM_SLOTS_SHIFT
) |
1777 (5 << R300_PVS_NUM_CNTLRS_SHIFT
) |
1778 (5 << R300_VF_MAX_VTX_NUM_SHIFT
));
1780 if (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV515
)
1781 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (2 << R300_PVS_NUM_FPUS_SHIFT
);
1782 else if ((rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV530
) ||
1783 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV560
) ||
1784 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV570
))
1785 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (5 << R300_PVS_NUM_FPUS_SHIFT
);
1786 else if ((rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV410
) ||
1787 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R420
))
1788 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (6 << R300_PVS_NUM_FPUS_SHIFT
);
1789 else if ((rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R520
) ||
1790 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R580
))
1791 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (8 << R300_PVS_NUM_FPUS_SHIFT
);
1793 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (4 << R300_PVS_NUM_FPUS_SHIFT
);
1797 static void r300SetupDefaultVertexProgram(r300ContextPtr rmesa
)
1799 struct r300_vertex_shader_state
*prog
= &(rmesa
->vertex_shader
);
1804 int param_count
= 0;
1805 int program_end
= 0;
1807 for (i
= VERT_ATTRIB_POS
; i
< VERT_ATTRIB_MAX
; i
++) {
1808 if (rmesa
->swtcl
.sw_tcl_inputs
[i
] != -1) {
1809 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
);
1810 prog
->program
.body
.i
[program_end
+ 1] = PVS_SRC_OPERAND(rmesa
->swtcl
.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
);
1811 prog
->program
.body
.i
[program_end
+ 2] = PVS_SRC_OPERAND(rmesa
->swtcl
.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
);
1812 prog
->program
.body
.i
[program_end
+ 3] = PVS_SRC_OPERAND(rmesa
->swtcl
.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
);
1818 prog
->program
.length
= program_end
;
1820 r300SetupVertexProgramFragment(rmesa
, R300_PVS_CODE_START
,
1822 inst_count
= (prog
->program
.length
/ 4) - 1;
1824 r300VapCntl(rmesa
, i_reg
, o_reg
, 0);
1826 R300_STATECHANGE(rmesa
, pvs
);
1827 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] =
1828 (0 << R300_PVS_FIRST_INST_SHIFT
) |
1829 (inst_count
<< R300_PVS_XYZW_VALID_INST_SHIFT
) |
1830 (inst_count
<< R300_PVS_LAST_INST_SHIFT
);
1831 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] =
1832 (0 << R300_PVS_CONST_BASE_OFFSET_SHIFT
) |
1833 (param_count
<< R300_PVS_MAX_CONST_ADDR_SHIFT
);
1834 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] =
1835 (inst_count
<< R300_PVS_LAST_VTX_SRC_INST_SHIFT
);
1838 static int bit_count (int x
)
1840 x
= ((x
& 0xaaaaaaaaU
) >> 1) + (x
& 0x55555555U
);
1841 x
= ((x
& 0xccccccccU
) >> 2) + (x
& 0x33333333U
);
1842 x
= (x
>> 16) + (x
& 0xffff);
1843 x
= ((x
& 0xf0f0) >> 4) + (x
& 0x0f0f);
1844 return (x
>> 8) + (x
& 0x00ff);
1847 static void r300SetupRealVertexProgram(r300ContextPtr rmesa
)
1849 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
1850 struct r300_vertex_program
*prog
= (struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
);
1852 int param_count
= 0;
1854 /* FIXME: r300SetupVertexProgramFragment */
1855 R300_STATECHANGE(rmesa
, vpp
);
1857 r300VertexProgUpdateParams(ctx
,
1858 (struct r300_vertex_program_cont
*)
1859 ctx
->VertexProgram
._Current
,
1860 (float *)&rmesa
->hw
.vpp
.
1861 cmd
[R300_VPP_PARAM_0
]);
1862 bump_vpu_count(rmesa
->hw
.vpp
.cmd
, param_count
);
1865 r300SetupVertexProgramFragment(rmesa
, R300_PVS_CODE_START
, &(prog
->program
));
1866 inst_count
= (prog
->program
.length
/ 4) - 1;
1868 r300VapCntl(rmesa
, bit_count(prog
->key
.InputsRead
),
1869 bit_count(prog
->key
.OutputsWritten
), prog
->num_temporaries
);
1871 R300_STATECHANGE(rmesa
, pvs
);
1872 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] =
1873 (0 << R300_PVS_FIRST_INST_SHIFT
) |
1874 (inst_count
<< R300_PVS_XYZW_VALID_INST_SHIFT
) |
1875 (inst_count
<< R300_PVS_LAST_INST_SHIFT
);
1876 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] =
1877 (0 << R300_PVS_CONST_BASE_OFFSET_SHIFT
) |
1878 (param_count
<< R300_PVS_MAX_CONST_ADDR_SHIFT
);
1879 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] =
1880 (inst_count
<< R300_PVS_LAST_VTX_SRC_INST_SHIFT
);
1884 static void r300SetupVertexProgram(r300ContextPtr rmesa
)
1886 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
1888 /* Reset state, in case we don't use something */
1889 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vpp
.cmd
)->vpu
.count
= 0;
1890 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vpi
.cmd
)->vpu
.count
= 0;
1891 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vps
.cmd
)->vpu
.count
= 0;
1893 /* Not sure why this doesnt work...
1894 0x400 area might have something to do with pixel shaders as it appears right after pfs programming.
1895 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. */
1896 //setup_vertex_shader_fragment(rmesa, 0x406, &unk4);
1897 if (rmesa
->options
.hw_tcl_enabled
&& ((struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
))->translated
) {
1898 r300SetupRealVertexProgram(rmesa
);
1900 /* FIXME: This needs to be replaced by vertex shader generation code. */
1901 r300SetupDefaultVertexProgram(rmesa
);
1907 * Enable/Disable states.
1909 * \note Mesa already filters redundant calls to this function.
1911 static void r300Enable(GLcontext
* ctx
, GLenum cap
, GLboolean state
)
1913 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1914 if (RADEON_DEBUG
& DEBUG_STATE
)
1915 fprintf(stderr
, "%s( %s = %s )\n", __FUNCTION__
,
1916 _mesa_lookup_enum_by_nr(cap
),
1917 state
? "GL_TRUE" : "GL_FALSE");
1929 r300SetAlphaState(ctx
);
1931 case GL_COLOR_LOGIC_OP
:
1932 r300SetLogicOpState(ctx
);
1933 /* fall-through, because logic op overrides blending */
1935 r300SetBlendState(ctx
);
1937 case GL_CLIP_PLANE0
:
1938 case GL_CLIP_PLANE1
:
1939 case GL_CLIP_PLANE2
:
1940 case GL_CLIP_PLANE3
:
1941 case GL_CLIP_PLANE4
:
1942 case GL_CLIP_PLANE5
:
1943 r300SetClipPlaneState(ctx
, cap
, state
);
1946 r300SetDepthState(ctx
);
1948 case GL_STENCIL_TEST
:
1949 r300SetStencilState(ctx
, state
);
1952 r300UpdateCulling(ctx
);
1954 case GL_POLYGON_OFFSET_POINT
:
1955 case GL_POLYGON_OFFSET_LINE
:
1956 case GL_POLYGON_OFFSET_FILL
:
1957 r300SetPolygonOffsetState(ctx
, state
);
1959 case GL_SCISSOR_TEST
:
1960 radeon_firevertices(&rmesa
->radeon
);
1961 rmesa
->radeon
.state
.scissor
.enabled
= state
;
1962 radeonUpdateScissor( ctx
);
1970 * Completely recalculates hardware state based on the Mesa state.
1972 static void r300ResetHwState(r300ContextPtr r300
)
1974 GLcontext
*ctx
= r300
->radeon
.glCtx
;
1977 has_tcl
= r300
->options
.hw_tcl_enabled
;
1979 if (RADEON_DEBUG
& DEBUG_STATE
)
1980 fprintf(stderr
, "%s\n", __FUNCTION__
);
1982 radeon_firevertices(&r300
->radeon
);
1985 ctx
->Color
.ColorMask
[RCOMP
],
1986 ctx
->Color
.ColorMask
[GCOMP
],
1987 ctx
->Color
.ColorMask
[BCOMP
], ctx
->Color
.ColorMask
[ACOMP
]);
1989 r300Enable(ctx
, GL_DEPTH_TEST
, ctx
->Depth
.Test
);
1990 r300DepthMask(ctx
, ctx
->Depth
.Mask
);
1991 r300DepthFunc(ctx
, ctx
->Depth
.Func
);
1994 r300Enable(ctx
, GL_STENCIL_TEST
, ctx
->Stencil
._Enabled
);
1995 r300StencilMaskSeparate(ctx
, 0, ctx
->Stencil
.WriteMask
[0]);
1996 r300StencilFuncSeparate(ctx
, 0, ctx
->Stencil
.Function
[0],
1997 ctx
->Stencil
.Ref
[0], ctx
->Stencil
.ValueMask
[0]);
1998 r300StencilOpSeparate(ctx
, 0, ctx
->Stencil
.FailFunc
[0],
1999 ctx
->Stencil
.ZFailFunc
[0],
2000 ctx
->Stencil
.ZPassFunc
[0]);
2002 r300UpdateCulling(ctx
);
2004 r300SetBlendState(ctx
);
2005 r300SetLogicOpState(ctx
);
2007 r300AlphaFunc(ctx
, ctx
->Color
.AlphaFunc
, ctx
->Color
.AlphaRef
);
2008 r300Enable(ctx
, GL_ALPHA_TEST
, ctx
->Color
.AlphaEnabled
);
2010 r300
->hw
.vte
.cmd
[1] = R300_VPORT_X_SCALE_ENA
2011 | R300_VPORT_X_OFFSET_ENA
2012 | R300_VPORT_Y_SCALE_ENA
2013 | R300_VPORT_Y_OFFSET_ENA
2014 | R300_VPORT_Z_SCALE_ENA
2015 | R300_VPORT_Z_OFFSET_ENA
| R300_VTX_W0_FMT
;
2016 r300
->hw
.vte
.cmd
[2] = 0x00000008;
2018 r300
->hw
.vap_vf_max_vtx_indx
.cmd
[1] = 0x00FFFFFF;
2019 r300
->hw
.vap_vf_max_vtx_indx
.cmd
[2] = 0x00000000;
2021 #ifdef MESA_LITTLE_ENDIAN
2022 r300
->hw
.vap_cntl_status
.cmd
[1] = R300_VC_NO_SWAP
;
2024 r300
->hw
.vap_cntl_status
.cmd
[1] = R300_VC_32BIT_SWAP
;
2027 /* disable VAP/TCL on non-TCL capable chips */
2029 r300
->hw
.vap_cntl_status
.cmd
[1] |= R300_VAP_TCL_BYPASS
;
2031 r300
->hw
.vap_psc_sgn_norm_cntl
.cmd
[1] = 0xAAAAAAAA;
2033 /* XXX: Other families? */
2035 r300
->hw
.vap_clip_cntl
.cmd
[1] = R300_PS_UCP_MODE_DIST_COP
;
2037 r300
->hw
.vap_clip
.cmd
[1] = r300PackFloat32(1.0); /* X */
2038 r300
->hw
.vap_clip
.cmd
[2] = r300PackFloat32(1.0); /* X */
2039 r300
->hw
.vap_clip
.cmd
[3] = r300PackFloat32(1.0); /* Y */
2040 r300
->hw
.vap_clip
.cmd
[4] = r300PackFloat32(1.0); /* Y */
2042 switch (r300
->radeon
.radeonScreen
->chip_family
) {
2043 case CHIP_FAMILY_R300
:
2044 r300
->hw
.vap_pvs_vtx_timeout_reg
.cmd
[1] = R300_2288_R300
;
2047 r300
->hw
.vap_pvs_vtx_timeout_reg
.cmd
[1] = R300_2288_RV350
;
2052 r300
->hw
.gb_enable
.cmd
[1] = R300_GB_POINT_STUFF_ENABLE
2053 | R300_GB_LINE_STUFF_ENABLE
2054 | R300_GB_TRIANGLE_STUFF_ENABLE
;
2056 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_0
] = 0x66666666;
2057 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_1
] = 0x06666666;
2059 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] =
2060 R300_GB_TILE_ENABLE
| R300_GB_TILE_SIZE_16
/*| R300_GB_SUBPIXEL_1_16*/;
2061 switch (r300
->radeon
.radeonScreen
->num_gb_pipes
) {
2064 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2065 R300_GB_TILE_PIPE_COUNT_RV300
;
2068 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2069 R300_GB_TILE_PIPE_COUNT_R300
;
2072 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2073 R300_GB_TILE_PIPE_COUNT_R420_3P
;
2076 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2077 R300_GB_TILE_PIPE_COUNT_R420
;
2081 /* XXX: Enable anti-aliasing? */
2082 r300
->hw
.gb_misc2
.cmd
[R300_GB_MISC2_AA_CONFIG
] = GB_AA_CONFIG_AA_DISABLE
;
2083 r300
->hw
.gb_misc2
.cmd
[R300_GB_MISC2_SELECT
] = 0;
2085 r300
->hw
.ga_point_s0
.cmd
[1] = r300PackFloat32(0.0);
2086 r300
->hw
.ga_point_s0
.cmd
[2] = r300PackFloat32(0.0);
2087 r300
->hw
.ga_point_s0
.cmd
[3] = r300PackFloat32(1.0);
2088 r300
->hw
.ga_point_s0
.cmd
[4] = r300PackFloat32(1.0);
2090 r300
->hw
.ga_triangle_stipple
.cmd
[1] = 0x00050005;
2092 r300PointSize(ctx
, 1.0);
2094 r300
->hw
.ga_point_minmax
.cmd
[1] = 0x18000006;
2095 r300
->hw
.ga_point_minmax
.cmd
[2] = 0x00020006;
2096 r300
->hw
.ga_point_minmax
.cmd
[3] = r300PackFloat32(1.0 / 192.0);
2098 r300LineWidth(ctx
, 1.0);
2100 r300
->hw
.ga_line_stipple
.cmd
[1] = 0;
2101 r300
->hw
.ga_line_stipple
.cmd
[2] = r300PackFloat32(0.0);
2102 r300
->hw
.ga_line_stipple
.cmd
[3] = r300PackFloat32(1.0);
2104 r300ShadeModel(ctx
, ctx
->Light
.ShadeModel
);
2106 r300PolygonMode(ctx
, GL_FRONT
, ctx
->Polygon
.FrontMode
);
2107 r300PolygonMode(ctx
, GL_BACK
, ctx
->Polygon
.BackMode
);
2108 r300
->hw
.zbias_cntl
.cmd
[1] = 0x00000000;
2110 r300PolygonOffset(ctx
, ctx
->Polygon
.OffsetFactor
,
2111 ctx
->Polygon
.OffsetUnits
);
2112 r300Enable(ctx
, GL_POLYGON_OFFSET_POINT
, ctx
->Polygon
.OffsetPoint
);
2113 r300Enable(ctx
, GL_POLYGON_OFFSET_LINE
, ctx
->Polygon
.OffsetLine
);
2114 r300Enable(ctx
, GL_POLYGON_OFFSET_FILL
, ctx
->Polygon
.OffsetFill
);
2116 r300
->hw
.su_depth_scale
.cmd
[1] = 0x4B7FFFFF;
2117 r300
->hw
.su_depth_scale
.cmd
[2] = 0x00000000;
2119 r300
->hw
.sc_hyperz
.cmd
[1] = 0x0000001C;
2120 r300
->hw
.sc_hyperz
.cmd
[2] = 0x2DA49525;
2122 r300
->hw
.sc_screendoor
.cmd
[1] = 0x00FFFFFF;
2124 r300
->hw
.us_out_fmt
.cmd
[1] = R500_OUT_FMT_C4_8
|
2125 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2126 r300
->hw
.us_out_fmt
.cmd
[2] = R500_OUT_FMT_UNUSED
|
2127 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2128 r300
->hw
.us_out_fmt
.cmd
[3] = R500_OUT_FMT_UNUSED
|
2129 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2130 r300
->hw
.us_out_fmt
.cmd
[4] = R500_OUT_FMT_UNUSED
|
2131 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2132 r300
->hw
.us_out_fmt
.cmd
[5] = R300_W_FMT_W0
| R300_W_SRC_US
;
2134 /* disable fog unit */
2135 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] = 0;
2136 r300
->hw
.fg_depth_src
.cmd
[1] = R300_FG_DEPTH_SRC_SCAN
;
2138 r300
->hw
.rb3d_cctl
.cmd
[1] = 0;
2140 r300BlendColor(ctx
, ctx
->Color
.BlendColor
);
2142 r300
->hw
.rb3d_dither_ctl
.cmd
[1] = 0;
2143 r300
->hw
.rb3d_dither_ctl
.cmd
[2] = 0;
2144 r300
->hw
.rb3d_dither_ctl
.cmd
[3] = 0;
2145 r300
->hw
.rb3d_dither_ctl
.cmd
[4] = 0;
2146 r300
->hw
.rb3d_dither_ctl
.cmd
[5] = 0;
2147 r300
->hw
.rb3d_dither_ctl
.cmd
[6] = 0;
2148 r300
->hw
.rb3d_dither_ctl
.cmd
[7] = 0;
2149 r300
->hw
.rb3d_dither_ctl
.cmd
[8] = 0;
2150 r300
->hw
.rb3d_dither_ctl
.cmd
[9] = 0;
2152 r300
->hw
.rb3d_aaresolve_ctl
.cmd
[1] = 0;
2154 if (r300
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
) {
2155 r300
->hw
.rb3d_discard_src_pixel_lte_threshold
.cmd
[1] = 0x00000000;
2156 r300
->hw
.rb3d_discard_src_pixel_lte_threshold
.cmd
[2] = 0xffffffff;
2158 r300
->hw
.rb3d_discard_src_pixel_lte_threshold
.cmd
[1] = (2 << 30);
2159 r300
->hw
.rb3d_discard_src_pixel_lte_threshold
.cmd
[2] = (2 << 30);
2162 r300
->hw
.zb_depthclearvalue
.cmd
[1] = 0;
2164 r300
->hw
.zstencil_format
.cmd
[2] = R300_ZTOP_DISABLE
;
2165 r300
->hw
.zstencil_format
.cmd
[3] = 0x00000003;
2166 r300
->hw
.zstencil_format
.cmd
[4] = 0x00000000;
2167 r300SetEarlyZState(ctx
);
2169 r300
->hw
.zb_zmask
.cmd
[1] = 0;
2170 r300
->hw
.zb_zmask
.cmd
[2] = 0;
2172 r300
->hw
.zb_hiz_offset
.cmd
[1] = 0;
2174 r300
->hw
.zb_hiz_pitch
.cmd
[1] = 0;
2176 r300VapCntl(r300
, 0, 0, 0);
2178 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_0
] = 0;
2179 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_1
] = 0;
2180 r300
->hw
.vps
.cmd
[R300_VPS_POINTSIZE
] = r300PackFloat32(1.0);
2181 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_3
] = 0;
2184 r300
->radeon
.hw
.all_dirty
= GL_TRUE
;
2187 void r300UpdateShaders(r300ContextPtr rmesa
)
2190 struct r300_vertex_program
*vp
;
2193 ctx
= rmesa
->radeon
.glCtx
;
2195 if (rmesa
->radeon
.NewGLState
&& rmesa
->options
.hw_tcl_enabled
) {
2196 rmesa
->radeon
.NewGLState
= 0;
2198 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
2199 rmesa
->temp_attrib
[i
] =
2200 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
];
2201 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] =
2202 &rmesa
->dummy_attrib
[i
];
2205 _tnl_UpdateFixedFunctionProgram(ctx
);
2207 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
2208 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] =
2209 rmesa
->temp_attrib
[i
];
2212 r300SelectVertexShader(rmesa
);
2213 vp
= (struct r300_vertex_program
*)
2214 CURRENT_VERTEX_SHADER(ctx
);
2215 /*if (vp->translated == GL_FALSE)
2216 r300TranslateVertexShader(vp); */
2217 if (vp
->translated
== GL_FALSE
) {
2218 fprintf(stderr
, "Failing back to sw-tcl\n");
2219 rmesa
->options
.hw_tcl_enabled
= 0;
2220 r300ResetHwState(rmesa
);
2222 r300UpdateStateParameters(ctx
, _NEW_PROGRAM
|
2223 _NEW_PROGRAM_CONSTANTS
);
2227 r300UpdateStateParameters(ctx
, _NEW_PROGRAM
| _NEW_PROGRAM_CONSTANTS
);
2230 static const GLfloat
*get_fragmentprogram_constant(GLcontext
*ctx
,
2231 struct gl_program
*program
, struct prog_src_register srcreg
)
2233 static const GLfloat dummy
[4] = { 0, 0, 0, 0 };
2235 switch(srcreg
.File
) {
2236 case PROGRAM_LOCAL_PARAM
:
2237 return program
->LocalParams
[srcreg
.Index
];
2238 case PROGRAM_ENV_PARAM
:
2239 return ctx
->FragmentProgram
.Parameters
[srcreg
.Index
];
2240 case PROGRAM_STATE_VAR
:
2241 case PROGRAM_NAMED_PARAM
:
2242 case PROGRAM_CONSTANT
:
2243 return program
->Parameters
->ParameterValues
[srcreg
.Index
];
2245 _mesa_problem(ctx
, "get_fragmentprogram_constant: Unknown\n");
2251 static GLboolean
r300SetupPixelShader(GLcontext
*ctx
)
2253 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
2254 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*) ctx
->FragmentProgram
._Current
;
2255 struct r300_fragment_program_code
*code
;
2258 /* Program is not native, fallback to software */
2262 code
= &fp
->code
.r300
;
2264 r300SetupTextures(ctx
);
2266 R300_STATECHANGE(rmesa
, fpi
[0]);
2267 R300_STATECHANGE(rmesa
, fpi
[1]);
2268 R300_STATECHANGE(rmesa
, fpi
[2]);
2269 R300_STATECHANGE(rmesa
, fpi
[3]);
2270 rmesa
->hw
.fpi
[0].cmd
[R300_FPI_CMD_0
] = cmdpacket0(rmesa
->radeon
.radeonScreen
, R300_US_ALU_RGB_INST_0
, code
->alu
.length
);
2271 rmesa
->hw
.fpi
[1].cmd
[R300_FPI_CMD_0
] = cmdpacket0(rmesa
->radeon
.radeonScreen
, R300_US_ALU_RGB_ADDR_0
, code
->alu
.length
);
2272 rmesa
->hw
.fpi
[2].cmd
[R300_FPI_CMD_0
] = cmdpacket0(rmesa
->radeon
.radeonScreen
, R300_US_ALU_ALPHA_INST_0
, code
->alu
.length
);
2273 rmesa
->hw
.fpi
[3].cmd
[R300_FPI_CMD_0
] = cmdpacket0(rmesa
->radeon
.radeonScreen
, R300_US_ALU_ALPHA_ADDR_0
, code
->alu
.length
);
2274 for (i
= 0; i
< code
->alu
.length
; i
++) {
2275 rmesa
->hw
.fpi
[0].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst0
;
2276 rmesa
->hw
.fpi
[1].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst1
;
2277 rmesa
->hw
.fpi
[2].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst2
;
2278 rmesa
->hw
.fpi
[3].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst3
;
2281 R300_STATECHANGE(rmesa
, fp
);
2282 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL0
] = code
->cur_node
| (code
->first_node_has_tex
<< 3);
2283 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL1
] = code
->max_temp_idx
;
2284 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL2
] =
2285 (0 << R300_PFS_CNTL_ALU_OFFSET_SHIFT
) |
2286 ((code
->alu
.length
-1) << R300_PFS_CNTL_ALU_END_SHIFT
) |
2287 (0 << R300_PFS_CNTL_TEX_OFFSET_SHIFT
) |
2288 ((code
->tex
.length
? code
->tex
.length
-1 : 0) << R300_PFS_CNTL_TEX_END_SHIFT
);
2289 /* I just want to say, the way these nodes are stored.. weird.. */
2290 for (i
= 0, k
= (4 - (code
->cur_node
+ 1)); i
< 4; i
++, k
++) {
2291 if (i
< (code
->cur_node
+ 1)) {
2292 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+ k
] =
2293 (code
->node
[i
].alu_offset
<< R300_ALU_START_SHIFT
) |
2294 (code
->node
[i
].alu_end
<< R300_ALU_SIZE_SHIFT
) |
2295 (code
->node
[i
].tex_offset
<< R300_TEX_START_SHIFT
) |
2296 (code
->node
[i
].tex_end
<< R300_TEX_SIZE_SHIFT
) |
2297 code
->node
[i
].flags
;
2299 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+ (3 - i
)] = 0;
2303 R300_STATECHANGE(rmesa
, fpp
);
2304 rmesa
->hw
.fpp
.cmd
[R300_FPP_CMD_0
] = cmdpacket0(rmesa
->radeon
.radeonScreen
, R300_PFS_PARAM_0_X
, code
->const_nr
* 4);
2305 for (i
= 0; i
< code
->const_nr
; i
++) {
2306 const GLfloat
*constant
= get_fragmentprogram_constant(ctx
,
2307 &fp
->Base
.Base
, code
->constant
[i
]);
2308 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 0] = r300PackFloat24(constant
[0]);
2309 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 1] = r300PackFloat24(constant
[1]);
2310 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 2] = r300PackFloat24(constant
[2]);
2311 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 3] = r300PackFloat24(constant
[3]);
2317 #define bump_r500fp_count(ptr, new_count) do{\
2318 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
2319 int _nc=(new_count)/6; \
2320 assert(_nc < 256); \
2321 if(_nc>_p->r500fp.count)_p->r500fp.count=_nc;\
2324 #define bump_r500fp_const_count(ptr, new_count) do{\
2325 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
2326 int _nc=(new_count)/4; \
2327 assert(_nc < 256); \
2328 if(_nc>_p->r500fp.count)_p->r500fp.count=_nc;\
2331 static GLboolean
r500SetupPixelShader(GLcontext
*ctx
)
2333 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
2334 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*) ctx
->FragmentProgram
._Current
;
2336 struct r500_fragment_program_code
*code
;
2338 ((drm_r300_cmd_header_t
*) rmesa
->hw
.r500fp
.cmd
)->r500fp
.count
= 0;
2339 ((drm_r300_cmd_header_t
*) rmesa
->hw
.r500fp_const
.cmd
)->r500fp
.count
= 0;
2341 /* Program is not native, fallback to software */
2345 code
= &fp
->code
.r500
;
2347 r300SetupTextures(ctx
);
2349 R300_STATECHANGE(rmesa
, fp
);
2350 rmesa
->hw
.fp
.cmd
[R500_FP_PIXSIZE
] = code
->max_temp_idx
;
2352 rmesa
->hw
.fp
.cmd
[R500_FP_CODE_ADDR
] =
2353 R500_US_CODE_START_ADDR(code
->inst_offset
) |
2354 R500_US_CODE_END_ADDR(code
->inst_end
);
2355 rmesa
->hw
.fp
.cmd
[R500_FP_CODE_RANGE
] =
2356 R500_US_CODE_RANGE_ADDR(code
->inst_offset
) |
2357 R500_US_CODE_RANGE_SIZE(code
->inst_end
);
2358 rmesa
->hw
.fp
.cmd
[R500_FP_CODE_OFFSET
] =
2359 R500_US_CODE_OFFSET_ADDR(0); /* FIXME when we add flow control */
2361 R300_STATECHANGE(rmesa
, r500fp
);
2362 /* Emit our shader... */
2363 for (i
= 0; i
< code
->inst_end
+1; i
++) {
2364 rmesa
->hw
.r500fp
.cmd
[i
*6+1] = code
->inst
[i
].inst0
;
2365 rmesa
->hw
.r500fp
.cmd
[i
*6+2] = code
->inst
[i
].inst1
;
2366 rmesa
->hw
.r500fp
.cmd
[i
*6+3] = code
->inst
[i
].inst2
;
2367 rmesa
->hw
.r500fp
.cmd
[i
*6+4] = code
->inst
[i
].inst3
;
2368 rmesa
->hw
.r500fp
.cmd
[i
*6+5] = code
->inst
[i
].inst4
;
2369 rmesa
->hw
.r500fp
.cmd
[i
*6+6] = code
->inst
[i
].inst5
;
2372 bump_r500fp_count(rmesa
->hw
.r500fp
.cmd
, (code
->inst_end
+ 1) * 6);
2374 R300_STATECHANGE(rmesa
, r500fp_const
);
2375 for (i
= 0; i
< code
->const_nr
; i
++) {
2376 const GLfloat
*constant
= get_fragmentprogram_constant(ctx
,
2377 &fp
->Base
.Base
, code
->constant
[i
]);
2378 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 0] = r300PackFloat32(constant
[0]);
2379 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 1] = r300PackFloat32(constant
[1]);
2380 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 2] = r300PackFloat32(constant
[2]);
2381 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 3] = r300PackFloat32(constant
[3]);
2383 bump_r500fp_const_count(rmesa
->hw
.r500fp_const
.cmd
, code
->const_nr
* 4);
2388 void r300UpdateShaderStates(r300ContextPtr rmesa
)
2391 ctx
= rmesa
->radeon
.glCtx
;
2393 /* should only happenen once, just after context is created */
2394 if (!ctx
->FragmentProgram
._Current
)
2397 r300SetEarlyZState(ctx
);
2399 /* w_fmt value is set to get best performance
2400 * see p.130 R5xx 3D acceleration guide v1.3 */
2401 GLuint w_fmt
, fgdepthsrc
;
2402 if (current_fragment_program_writes_depth(ctx
)) {
2403 fgdepthsrc
= R300_FG_DEPTH_SRC_SHADER
;
2404 w_fmt
= R300_W_FMT_W24
| R300_W_SRC_US
;
2406 fgdepthsrc
= R300_FG_DEPTH_SRC_SCAN
;
2407 w_fmt
= R300_W_FMT_W0
| R300_W_SRC_US
;
2410 if (w_fmt
!= rmesa
->hw
.us_out_fmt
.cmd
[5]) {
2411 R300_STATECHANGE(rmesa
, us_out_fmt
);
2412 rmesa
->hw
.us_out_fmt
.cmd
[5] = w_fmt
;
2415 if (fgdepthsrc
!= rmesa
->hw
.fg_depth_src
.cmd
[1]) {
2416 R300_STATECHANGE(rmesa
, fg_depth_src
);
2417 rmesa
->hw
.fg_depth_src
.cmd
[1] = fgdepthsrc
;
2420 r300TranslateFragmentShader(ctx
, ctx
->FragmentProgram
._Current
);
2422 if (!rmesa
->vtbl
.SetupPixelShader(ctx
))
2425 rmesa
->vtbl
.SetupRSUnit(ctx
);
2427 if (rmesa
->options
.hw_tcl_enabled
)
2428 r300SetupVertexProgram(rmesa
);
2432 * Called by Mesa after an internal state update.
2434 static void r300InvalidateState(GLcontext
* ctx
, GLuint new_state
)
2436 r300ContextPtr r300
= R300_CONTEXT(ctx
);
2438 _swrast_InvalidateState(ctx
, new_state
);
2439 _swsetup_InvalidateState(ctx
, new_state
);
2440 _vbo_InvalidateState(ctx
, new_state
);
2441 _tnl_InvalidateState(ctx
, new_state
);
2443 if (new_state
& _NEW_BUFFERS
) {
2444 _mesa_update_framebuffer(ctx
);
2445 /* this updates the DrawBuffer's Width/Height if it's a FBO */
2446 _mesa_update_draw_buffer_bounds(ctx
);
2448 R300_STATECHANGE(r300
, cb
);
2451 r300UpdateStateParameters(ctx
, new_state
);
2453 r300
->radeon
.NewGLState
|= new_state
;
2457 * Calculate initial hardware state and register state functions.
2458 * Assumes that the command buffer and state atoms have been
2459 * initialized already.
2461 void r300InitState(r300ContextPtr r300
)
2463 r300ResetHwState(r300
);
2466 static void r300RenderMode(GLcontext
* ctx
, GLenum mode
)
2468 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
2474 * Initialize driver's state callback functions
2476 void r300InitStateFuncs(struct dd_function_table
*functions
)
2479 functions
->UpdateState
= r300InvalidateState
;
2480 functions
->AlphaFunc
= r300AlphaFunc
;
2481 functions
->BlendColor
= r300BlendColor
;
2482 functions
->BlendEquationSeparate
= r300BlendEquationSeparate
;
2483 functions
->BlendFuncSeparate
= r300BlendFuncSeparate
;
2484 functions
->Enable
= r300Enable
;
2485 functions
->ColorMask
= r300ColorMask
;
2486 functions
->DepthFunc
= r300DepthFunc
;
2487 functions
->DepthMask
= r300DepthMask
;
2488 functions
->CullFace
= r300CullFace
;
2489 functions
->FrontFace
= r300FrontFace
;
2490 functions
->ShadeModel
= r300ShadeModel
;
2491 functions
->LogicOpcode
= r300LogicOpcode
;
2493 /* ARB_point_parameters */
2494 functions
->PointParameterfv
= r300PointParameter
;
2496 /* Stencil related */
2497 functions
->StencilFuncSeparate
= r300StencilFuncSeparate
;
2498 functions
->StencilMaskSeparate
= r300StencilMaskSeparate
;
2499 functions
->StencilOpSeparate
= r300StencilOpSeparate
;
2501 /* Viewport related */
2502 functions
->Viewport
= r300Viewport
;
2503 functions
->DepthRange
= r300DepthRange
;
2504 functions
->PointSize
= r300PointSize
;
2505 functions
->LineWidth
= r300LineWidth
;
2507 functions
->PolygonOffset
= r300PolygonOffset
;
2508 functions
->PolygonMode
= r300PolygonMode
;
2510 functions
->RenderMode
= r300RenderMode
;
2512 functions
->ClipPlane
= r300ClipPlane
;
2513 functions
->Scissor
= radeonScissor
;
2515 functions
->DrawBuffer
= radeonDrawBuffer
;
2516 functions
->ReadBuffer
= radeonReadBuffer
;
2519 void r300InitShaderFunctions(r300ContextPtr r300
)
2521 if (r300
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
) {
2522 r300
->vtbl
.SetupRSUnit
= r500SetupRSUnit
;
2523 r300
->vtbl
.SetupPixelShader
= r500SetupPixelShader
;
2524 r300
->vtbl
.SetupFragmentShaderTextures
= r500SetupFragmentShaderTextures
;
2525 r300
->vtbl
.FragmentProgramEmit
= r500FragmentProgramEmit
;
2526 r300
->vtbl
.FragmentProgramDump
= r500FragmentProgramDump
;
2528 r300
->vtbl
.SetupRSUnit
= r300SetupRSUnit
;
2529 r300
->vtbl
.SetupPixelShader
= r300SetupPixelShader
;
2530 r300
->vtbl
.SetupFragmentShaderTextures
= r300SetupFragmentShaderTextures
;
2531 r300
->vtbl
.FragmentProgramEmit
= r300FragmentProgramEmit
;
2532 r300
->vtbl
.FragmentProgramDump
= r300FragmentProgramDump
;