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 **************************************************************************/
34 * Nicolai Haehnle <prefect_@gmx.net>
44 #include "simple_list.h"
46 #include "api_arrayelt.h"
47 #include "swrast/swrast.h"
48 #include "swrast_setup/swrast_setup.h"
49 #include "array_cache/acache.h"
51 #include "texformat.h"
53 #include "radeon_ioctl.h"
54 #include "radeon_state.h"
55 #include "r300_context.h"
56 #include "r300_ioctl.h"
57 #include "r300_state.h"
59 #include "r300_program.h"
60 #include "r300_emit.h"
61 #include "r300_fixed_pipelines.h"
64 static void r300AlphaFunc(GLcontext
* ctx
, GLenum func
, GLfloat ref
)
66 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
67 int pp_misc
= rmesa
->hw
.at
.cmd
[R300_AT_ALPHA_TEST
];
70 CLAMPED_FLOAT_TO_UBYTE(refByte
, ref
);
72 R300_STATECHANGE(rmesa
, at
);
74 pp_misc
&= ~(R300_ALPHA_TEST_OP_MASK
| R300_REF_ALPHA_MASK
);
75 pp_misc
|= (refByte
& R300_REF_ALPHA_MASK
);
79 pp_misc
|= R300_ALPHA_TEST_FAIL
;
82 pp_misc
|= R300_ALPHA_TEST_LESS
;
85 pp_misc
|= R300_ALPHA_TEST_EQUAL
;
88 pp_misc
|= R300_ALPHA_TEST_LEQUAL
;
91 pp_misc
|= R300_ALPHA_TEST_GREATER
;
94 pp_misc
|= R300_ALPHA_TEST_NEQUAL
;
97 pp_misc
|= R300_ALPHA_TEST_GEQUAL
;
100 pp_misc
|= R300_ALPHA_TEST_PASS
;
104 rmesa
->hw
.at
.cmd
[R300_AT_ALPHA_TEST
] = pp_misc
;
107 static void r300BlendColor(GLcontext
* ctx
, const GLfloat cf
[4])
110 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
111 fprintf(stderr
, "%s:%s is not implemented yet. Fixme !\n", __FILE__
, __FUNCTION__
);
113 R200_STATECHANGE(rmesa
, ctx
);
114 CLAMPED_FLOAT_TO_UBYTE(color
[0], cf
[0]);
115 CLAMPED_FLOAT_TO_UBYTE(color
[1], cf
[1]);
116 CLAMPED_FLOAT_TO_UBYTE(color
[2], cf
[2]);
117 CLAMPED_FLOAT_TO_UBYTE(color
[3], cf
[3]);
118 if (rmesa
->radeon
.radeonScreen
->drmSupportsBlendColor
)
119 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCOLOR
] =
120 radeonPackColor(4, color
[0], color
[1], color
[2], color
[3]);
125 * Calculate the hardware blend factor setting. This same function is used
126 * for source and destination of both alpha and RGB.
129 * The hardware register value for the specified blend factor. This value
130 * will need to be shifted into the correct position for either source or
131 * destination factor.
134 * Since the two cases where source and destination are handled differently
135 * are essentially error cases, they should never happen. Determine if these
136 * cases can be removed.
138 static int blend_factor(GLenum factor
, GLboolean is_src
)
144 func
= R200_BLEND_GL_ZERO
;
147 func
= R200_BLEND_GL_ONE
;
150 func
= R200_BLEND_GL_DST_COLOR
;
152 case GL_ONE_MINUS_DST_COLOR
:
153 func
= R200_BLEND_GL_ONE_MINUS_DST_COLOR
;
156 func
= R200_BLEND_GL_SRC_COLOR
;
158 case GL_ONE_MINUS_SRC_COLOR
:
159 func
= R200_BLEND_GL_ONE_MINUS_SRC_COLOR
;
162 func
= R200_BLEND_GL_SRC_ALPHA
;
164 case GL_ONE_MINUS_SRC_ALPHA
:
165 func
= R200_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
168 func
= R200_BLEND_GL_DST_ALPHA
;
170 case GL_ONE_MINUS_DST_ALPHA
:
171 func
= R200_BLEND_GL_ONE_MINUS_DST_ALPHA
;
173 case GL_SRC_ALPHA_SATURATE
:
175 (is_src
) ? R200_BLEND_GL_SRC_ALPHA_SATURATE
:
178 case GL_CONSTANT_COLOR
:
179 func
= R200_BLEND_GL_CONST_COLOR
;
181 case GL_ONE_MINUS_CONSTANT_COLOR
:
182 func
= R200_BLEND_GL_ONE_MINUS_CONST_COLOR
;
184 case GL_CONSTANT_ALPHA
:
185 func
= R200_BLEND_GL_CONST_ALPHA
;
187 case GL_ONE_MINUS_CONSTANT_ALPHA
:
188 func
= R200_BLEND_GL_ONE_MINUS_CONST_ALPHA
;
191 func
= (is_src
) ? R200_BLEND_GL_ONE
: R200_BLEND_GL_ZERO
;
197 * Sets both the blend equation and the blend function.
198 * This is done in a single
199 * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX)
200 * change the interpretation of the blend function.
201 * Also, make sure that blend function and blend equation are set to their default
202 * value if color blending is not enabled, since at least blend equations GL_MIN
203 * and GL_FUNC_REVERSE_SUBTRACT will cause wrong results otherwise for
207 /* helper function */
208 static void r300_set_blend_cntl(r300ContextPtr rmesa
, int func
, int eqn
, int cbits
, int funcA
, int eqnA
)
210 GLuint new_ablend
, new_cblend
;
213 fprintf(stderr
, "eqnA=%08x funcA=%08x eqn=%08x func=%08x cbits=%08x\n", eqnA
, funcA
, eqn
, func
, cbits
);
215 new_ablend
= eqnA
| funcA
;
216 new_cblend
= eqn
| func
;
218 new_cblend
|= R300_BLEND_NO_SEPARATE
;
222 if((new_ablend
!= rmesa
->hw
.bld
.cmd
[R300_BLD_ABLEND
])
223 || (new_cblend
!= rmesa
->hw
.bld
.cmd
[R300_BLD_CBLEND
])){
224 R300_STATECHANGE(rmesa
, bld
);
225 rmesa
->hw
.bld
.cmd
[R300_BLD_ABLEND
]=new_ablend
;
226 rmesa
->hw
.bld
.cmd
[R300_BLD_CBLEND
]=new_cblend
;
230 static void r300_set_blend_state(GLcontext
* ctx
)
232 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
234 GLuint cntl
= rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &
235 ~(R300_ROP_ENABLE
| R300_ALPHA_BLEND_ENABLE
|
236 R300_SEPARATE_ALPHA_ENABLE
);
239 int func
= (R200_BLEND_GL_ONE
<< R200_SRC_BLEND_SHIFT
) |
240 (R200_BLEND_GL_ZERO
<< R200_DST_BLEND_SHIFT
);
241 int eqn
= R200_COMB_FCN_ADD_CLAMP
;
242 int funcA
= (R200_BLEND_GL_ONE
<< R200_SRC_BLEND_SHIFT
) |
243 (R200_BLEND_GL_ZERO
<< R200_DST_BLEND_SHIFT
);
244 int eqnA
= R200_COMB_FCN_ADD_CLAMP
;
247 if (rmesa
->radeon
.radeonScreen
->drmSupportsBlendColor
) {
248 if (ctx
->Color
._LogicOpEnabled
) {
250 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] =
251 cntl
| R300_ROP_ENABLE
;
253 r300_set_blend_cntl(rmesa
,
257 } else if (ctx
->Color
.BlendEnabled
) {
259 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] =
260 cntl
| R300_ALPHA_BLEND_ENABLE
|
261 R300_SEPARATE_ALPHA_ENABLE
;
265 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] = cntl
;
267 r300_set_blend_cntl(rmesa
,
273 if (ctx
->Color
._LogicOpEnabled
) {
275 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] =
276 cntl
| R300_ROP_ENABLE
;
277 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = eqn
| func
;
280 } else if (ctx
->Color
.BlendEnabled
) {
282 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] =
283 cntl
| R300_ALPHA_BLEND_ENABLE
;
287 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] = cntl
;
288 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = eqn
| func
;
290 r300_set_blend_cntl(rmesa
,
298 (blend_factor(ctx
->Color
.BlendSrcRGB
, GL_TRUE
) <<
299 R200_SRC_BLEND_SHIFT
) | (blend_factor(ctx
->Color
.BlendDstRGB
,
301 R200_DST_BLEND_SHIFT
);
303 switch (ctx
->Color
.BlendEquationRGB
) {
305 eqn
= R300_COMB_FCN_ADD_CLAMP
;
308 case GL_FUNC_SUBTRACT
:
309 eqn
= R300_COMB_FCN_SUB_CLAMP
;
312 case GL_FUNC_REVERSE_SUBTRACT
:
313 eqn
= R200_COMB_FCN_RSUB_CLAMP
;
317 eqn
= R200_COMB_FCN_MIN
;
318 func
= (R200_BLEND_GL_ONE
<< R200_SRC_BLEND_SHIFT
) |
319 (R200_BLEND_GL_ONE
<< R200_DST_BLEND_SHIFT
);
323 eqn
= R200_COMB_FCN_MAX
;
324 func
= (R200_BLEND_GL_ONE
<< R200_SRC_BLEND_SHIFT
) |
325 (R200_BLEND_GL_ONE
<< R200_DST_BLEND_SHIFT
);
330 "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
331 __func__
, __LINE__
, ctx
->Color
.BlendEquationRGB
);
335 if (!rmesa
->radeon
.radeonScreen
->drmSupportsBlendColor
) {
337 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = eqn
| func
;
343 (blend_factor(ctx
->Color
.BlendSrcA
, GL_TRUE
) <<
344 R200_SRC_BLEND_SHIFT
) | (blend_factor(ctx
->Color
.BlendDstA
,
346 R200_DST_BLEND_SHIFT
);
348 switch (ctx
->Color
.BlendEquationA
) {
350 eqnA
= R300_COMB_FCN_ADD_CLAMP
;
353 case GL_FUNC_SUBTRACT
:
354 eqnA
= R300_COMB_FCN_SUB_CLAMP
;
357 case GL_FUNC_REVERSE_SUBTRACT
:
358 eqnA
= R200_COMB_FCN_RSUB_CLAMP
;
362 eqnA
= R200_COMB_FCN_MIN
;
363 funcA
= (R200_BLEND_GL_ONE
<< R200_SRC_BLEND_SHIFT
) |
364 (R200_BLEND_GL_ONE
<< R200_DST_BLEND_SHIFT
);
368 eqnA
= R200_COMB_FCN_MAX
;
369 funcA
= (R200_BLEND_GL_ONE
<< R200_SRC_BLEND_SHIFT
) |
370 (R200_BLEND_GL_ONE
<< R200_DST_BLEND_SHIFT
);
374 fprintf(stderr
, "[%s:%u] Invalid A blend equation (0x%04x).\n",
375 __func__
, __LINE__
, ctx
->Color
.BlendEquationA
);
379 r300_set_blend_cntl(rmesa
,
380 func
, eqn
, R300_BLEND_UNKNOWN
| R300_BLEND_ENABLE
,
382 r300_set_blend_cntl(rmesa
,
383 func
, eqn
, R300_BLEND_UNKNOWN
| R300_BLEND_ENABLE
,
387 static void r300BlendEquationSeparate(GLcontext
* ctx
,
388 GLenum modeRGB
, GLenum modeA
)
390 r300_set_blend_state(ctx
);
393 static void r300BlendFuncSeparate(GLcontext
* ctx
,
394 GLenum sfactorRGB
, GLenum dfactorRGB
,
395 GLenum sfactorA
, GLenum dfactorA
)
397 r300_set_blend_state(ctx
);
401 * Update our tracked culling state based on Mesa's state.
403 static void r300UpdateCulling(GLcontext
* ctx
)
405 r300ContextPtr r300
= R300_CONTEXT(ctx
);
408 R300_STATECHANGE(r300
, cul
);
409 if (ctx
->Polygon
.CullFlag
) {
410 if (ctx
->Polygon
.CullFaceMode
== GL_FRONT_AND_BACK
)
411 val
= R300_CULL_FRONT
|R300_CULL_BACK
;
412 else if (ctx
->Polygon
.CullFaceMode
== GL_FRONT
)
413 val
= R300_CULL_FRONT
;
415 val
= R300_CULL_BACK
;
417 if (ctx
->Polygon
.FrontFace
== GL_CW
)
418 val
|= R300_FRONT_FACE_CW
;
420 val
|= R300_FRONT_FACE_CCW
;
422 r300
->hw
.cul
.cmd
[R300_CUL_CULL
] = val
;
427 * Handle glEnable()/glDisable().
429 * \note Mesa already filters redundant calls to glEnable/glDisable.
431 static void r300Enable(GLcontext
* ctx
, GLenum cap
, GLboolean state
)
433 r300ContextPtr r300
= R300_CONTEXT(ctx
);
436 if (RADEON_DEBUG
& DEBUG_STATE
)
437 fprintf(stderr
, "%s( %s = %s )\n", __FUNCTION__
,
438 _mesa_lookup_enum_by_nr(cap
),
439 state
? "GL_TRUE" : "GL_FALSE");
442 /* Fast track this one...
450 R200_STATECHANGE(r300
, at
);
452 r300
->hw
.at
.cmd
[R300_AT_ALPHA_TEST
] |=
453 R300_ALPHA_TEST_ENABLE
;
455 r300
->hw
.at
.cmd
[R300_AT_ALPHA_TEST
] |=
456 ~R300_ALPHA_TEST_ENABLE
;
461 case GL_COLOR_LOGIC_OP
:
462 r300_set_blend_state(ctx
);
466 R300_STATECHANGE(r300
, zs
);
470 newval
= R300_RB3D_Z_TEST_AND_WRITE
;
472 newval
= R300_RB3D_Z_TEST
;
476 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] = newval
;
479 case GL_STENCIL_TEST
:
481 WARN_ONCE("Do not know how to enable stencil. Help me !\n");
483 if (r300
->state
.hw_stencil
) {
484 //fprintf(stderr, "Stencil %s\n", state ? "enabled" : "disabled");
485 R300_STATECHANGE(r300
, zs
);
487 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |=
488 R300_RB3D_STENCIL_ENABLE
;
490 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &=
491 ~R300_RB3D_STENCIL_ENABLE
;
494 FALLBACK(&r300
->radeon
, RADEON_FALLBACK_STENCIL
, state
);
499 r300UpdateCulling(ctx
);
502 case GL_POLYGON_OFFSET_POINT
:
503 case GL_POLYGON_OFFSET_LINE
:
504 WARN_ONCE("Don't know how to enable polygon offset point/line. Help me !\n");
506 /* Something is apparently blocking these from working */
507 R300_STATECHANGE(r300
, unk42B4
);
509 r300
->hw
.unk42B4
.cmd
[1] |= ~(3<<0);
511 r300
->hw
.unk42B4
.cmd
[1] &= (3<<0);
515 case GL_POLYGON_OFFSET_FILL
:
516 R300_STATECHANGE(r300
, unk42B4
);
518 r300
->hw
.unk42B4
.cmd
[1] |= (3<<0);
520 r300
->hw
.unk42B4
.cmd
[1] &= ~(3<<0);
524 case GL_VERTEX_PROGRAM_ARB
:
525 //TCL_FALLBACK(rmesa->glCtx, R200_TCL_FALLBACK_TCL_DISABLE, state);
529 radeonEnable(ctx
, cap
, state
);
536 * Change the culling mode.
538 * \note Mesa already filters redundant calls to this function.
540 static void r300CullFace(GLcontext
* ctx
, GLenum mode
)
544 r300UpdateCulling(ctx
);
549 * Change the polygon orientation.
551 * \note Mesa already filters redundant calls to this function.
553 static void r300FrontFace(GLcontext
* ctx
, GLenum mode
)
557 r300UpdateCulling(ctx
);
562 * Change the depth testing function.
564 * \note Mesa already filters redundant calls to this function.
566 static void r300DepthFunc(GLcontext
* ctx
, GLenum func
)
568 r300ContextPtr r300
= R300_CONTEXT(ctx
);
570 R300_STATECHANGE(r300
, zs
);
572 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= ~(R300_ZS_MASK
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
);
576 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= R300_ZS_NEVER
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
;
579 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= R300_ZS_LESS
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
;
582 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= R300_ZS_EQUAL
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
;
585 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= R300_ZS_LEQUAL
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
;
588 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= R300_ZS_GREATER
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
;
591 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= R300_ZS_NOTEQUAL
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
;
594 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= R300_ZS_GEQUAL
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
;
597 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= R300_ZS_ALWAYS
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
;
605 * Enable/Disable depth writing.
607 * \note Mesa already filters redundant calls to this function.
609 static void r300DepthMask(GLcontext
* ctx
, GLboolean mask
)
611 r300ContextPtr r300
= R300_CONTEXT(ctx
);
613 if (!ctx
->Depth
.Test
)
616 R300_STATECHANGE(r300
, zs
);
617 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] = mask
618 ? R300_RB3D_Z_TEST_AND_WRITE
: R300_RB3D_Z_TEST
;
623 * Handle glColorMask()
625 static void r300ColorMask(GLcontext
* ctx
,
626 GLboolean r
, GLboolean g
, GLboolean b
, GLboolean a
)
628 r300ContextPtr r300
= R300_CONTEXT(ctx
);
629 int mask
= (b
<< 0) | (g
<< 1) | (r
<< 2) | (a
<< 3);
631 if (mask
!= r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
]) {
632 R300_STATECHANGE(r300
, cmk
);
633 r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
] = mask
;
637 /* =============================================================
640 static void r300PointSize(GLcontext
* ctx
, GLfloat size
)
642 r300ContextPtr r300
= R300_CONTEXT(ctx
);
644 /* TODO: Validate point size */
645 R300_STATECHANGE(r300
, ps
);
646 r300
->hw
.ps
.cmd
[R300_PS_POINTSIZE
] =
647 ((int)(size
* 6) << R300_POINTSIZE_X_SHIFT
) |
648 ((int)(size
* 6) << R300_POINTSIZE_Y_SHIFT
);
650 #if 0 /* r200 reg? */
651 /* This might need fixing later */
652 R300_STATECHANGE(r300
, vps
);
653 r300
->hw
.vps
.cmd
[R300_VPS_POINTSIZE
] = r300PackFloat32(1.0);
657 /* =============================================================
660 static void r300LineWidth(GLcontext
*ctx
, GLfloat widthf
)
662 r300ContextPtr r300
= R300_CONTEXT(ctx
);
663 /* IMHO mesa isnt clamping line widths according to ctx->Const.*LineWidth
664 before calling this from the dd function table.
665 Since r300ResetHwState calls these with clamped values,
666 they must be set properly. */
668 R300_STATECHANGE(r300
, lcntl
);
669 r300
->hw
.lcntl
.cmd
[1] = (int)(widthf
* 6.0);
670 /* Doesnt look very good without this... */
671 r300
->hw
.lcntl
.cmd
[1] |= R300_LINE_CNT_UNK1
;
676 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); : 00000091 ( 1001 0001)
677 glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); : 00000001 ( 1)
679 glPolygonMode(GL_FRONT, GL_LINE); : 00000111 (1 0001 0001)
680 glPolygonMode(GL_FRONT, GL_POINT); : 00000101 (1 0000 0001)
682 glPolygonMode(GL_BACK, GL_LINE); : 000000a1 ( 1010 0001)
683 glPolygonMode(GL_BACK, GL_POINT); : 00000021 ( 10 0001)
688 #define PM_NOT_BACK (1<<8)
689 #define PM_NOT_FRONT (1<<5)
691 #define PM_FRONT_LINE (1<<4)
692 #define PM_BACK_LINE (1<<7)
694 static void r300PolygonMode(GLcontext
*ctx
, GLenum face
, GLenum mode
)
696 r300ContextPtr r300
= R300_CONTEXT(ctx
);
697 unsigned long hw_mode
=0;
699 hw_mode
=r300
->hw
.unk4288
.cmd
[1];
700 hw_mode
|= 1; /* enables point mode by default */
704 //fprintf(stderr, "front\n");
705 hw_mode
&= ~PM_NOT_FRONT
;
708 hw_mode
|= PM_FRONT_LINE
;
711 hw_mode
&= ~PM_FRONT_LINE
;
713 case GL_FILL
: /* No idea */
720 //fprintf(stderr, "back\n");
721 hw_mode
&= ~PM_NOT_BACK
;
724 hw_mode
|= PM_BACK_LINE
;
727 hw_mode
&= ~PM_BACK_LINE
;
729 case GL_FILL
: /* No idea */
735 case GL_FRONT_AND_BACK
:
736 //fprintf(stderr, "front and back\n");
737 hw_mode
&= ~PM_NOT_FRONT
;
738 hw_mode
&= ~PM_NOT_BACK
;
741 hw_mode
|= PM_FRONT_LINE
;
742 hw_mode
|= PM_BACK_LINE
;
745 hw_mode
&= ~PM_FRONT_LINE
;
746 hw_mode
&= ~PM_BACK_LINE
;
755 //if( front and back fill) hw_mode=0;
757 if(r300
->hw
.unk4288
.cmd
[1] != hw_mode
){
758 R300_STATECHANGE(r300
, unk4288
);
759 r300
->hw
.unk4288
.cmd
[1] = hw_mode
;
763 /* =============================================================
767 static int translate_stencil_func(int func
)
771 return R300_ZS_NEVER
;
777 return R300_ZS_EQUAL
;
780 return R300_ZS_LEQUAL
;
783 return R300_ZS_GREATER
;
786 return R300_ZS_NOTEQUAL
;
789 return R300_ZS_GEQUAL
;
792 return R300_ZS_ALWAYS
;
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");
823 static void r300StencilFunc(GLcontext
* ctx
, GLenum func
,
824 GLint ref
, GLuint mask
)
826 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
827 GLuint refmask
= ((ctx
->Stencil
.Ref
[0] << R300_RB3D_ZS2_STENCIL_REF_SHIFT
) |
829 ValueMask
[0] << R300_RB3D_ZS2_STENCIL_MASK_SHIFT
));
832 R300_STATECHANGE(rmesa
, zs
);
834 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= ~(
835 (R300_ZS_MASK
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
)
836 | (R300_ZS_MASK
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
));
837 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &= ~((R300_ZS_MASK
<< R300_RB3D_ZS2_STENCIL_REF_SHIFT
) |
838 (R300_ZS_MASK
<< R300_RB3D_ZS2_STENCIL_MASK_SHIFT
));
840 flag
= translate_stencil_func(ctx
->Stencil
.Function
[0]);
842 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= (flag
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
)
843 | (flag
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
);
844 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |= refmask
;
847 static void r300StencilMask(GLcontext
* ctx
, GLuint mask
)
849 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
851 R300_STATECHANGE(rmesa
, zs
);
852 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &= ~(R300_ZS_MASK
<< R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT
);
853 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |= ctx
->Stencil
.WriteMask
[0] << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT
;
857 static void r300StencilOp(GLcontext
* ctx
, GLenum fail
,
858 GLenum zfail
, GLenum zpass
)
860 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
862 R300_STATECHANGE(rmesa
, zs
);
863 /* It is easier to mask what's left.. */
864 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= (R300_ZS_MASK
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
);
866 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
867 (translate_stencil_op(ctx
->Stencil
.FailFunc
[0]) << R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT
)
868 |(translate_stencil_op(ctx
->Stencil
.ZFailFunc
[0]) << R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT
)
869 |(translate_stencil_op(ctx
->Stencil
.ZPassFunc
[0]) << R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT
)
870 |(translate_stencil_op(ctx
->Stencil
.FailFunc
[0]) << R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT
)
871 |(translate_stencil_op(ctx
->Stencil
.ZFailFunc
[0]) << R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT
)
872 |(translate_stencil_op(ctx
->Stencil
.ZPassFunc
[0]) << R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT
);
876 static void r300ClearStencil(GLcontext
* ctx
, GLint s
)
878 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
880 /* Not sure whether this is correct.. */
881 R300_STATECHANGE(rmesa
, zs
);
882 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] =
883 ((GLuint
) ctx
->Stencil
.Clear
|
884 (0xff << R200_STENCIL_MASK_SHIFT
) |
885 (ctx
->Stencil
.WriteMask
[0] << R200_STENCIL_WRITEMASK_SHIFT
));
888 /* =============================================================
889 * Window position and viewport transformation
893 * To correctly position primitives:
895 #define SUBPIXEL_X 0.125
896 #define SUBPIXEL_Y 0.125
898 void r300UpdateWindow(GLcontext
* ctx
)
900 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
901 __DRIdrawablePrivate
*dPriv
= rmesa
->radeon
.dri
.drawable
;
902 GLfloat xoffset
= dPriv
? (GLfloat
) dPriv
->x
: 0;
903 GLfloat yoffset
= dPriv
? (GLfloat
) dPriv
->y
+ dPriv
->h
: 0;
904 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
906 GLfloat sx
= v
[MAT_SX
];
907 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
908 GLfloat sy
= -v
[MAT_SY
];
909 GLfloat ty
= (-v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
910 GLfloat sz
= v
[MAT_SZ
] * rmesa
->state
.depth
.scale
;
911 GLfloat tz
= v
[MAT_TZ
] * rmesa
->state
.depth
.scale
;
913 R300_FIREVERTICES(rmesa
);
914 R300_STATECHANGE(rmesa
, vpt
);
916 rmesa
->hw
.vpt
.cmd
[R300_VPT_XSCALE
] = r300PackFloat32(sx
);
917 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
918 rmesa
->hw
.vpt
.cmd
[R300_VPT_YSCALE
] = r300PackFloat32(sy
);
919 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
920 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZSCALE
] = r300PackFloat32(sz
);
921 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZOFFSET
] = r300PackFloat32(tz
);
924 static void r300Viewport(GLcontext
* ctx
, GLint x
, GLint y
,
925 GLsizei width
, GLsizei height
)
927 /* Don't pipeline viewport changes, conflict with window offset
928 * setting below. Could apply deltas to rescue pipelined viewport
929 * values, or keep the originals hanging around.
931 R300_FIREVERTICES(R300_CONTEXT(ctx
));
932 r300UpdateWindow(ctx
);
935 static void r300DepthRange(GLcontext
* ctx
, GLclampd nearval
, GLclampd farval
)
937 r300UpdateWindow(ctx
);
940 /* =============================================================
943 static void r300PolygonOffset(GLcontext
* ctx
, GLfloat factor
, GLfloat units
)
945 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
946 GLfloat constant
= units
* /*rmesa->state.depth.scale*/4;
950 /* fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */
952 R300_STATECHANGE(rmesa
, zbs
);
953 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_FACTOR
] = r300PackFloat32(factor
);
954 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_CONSTANT
] = r300PackFloat32(constant
);
955 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_FACTOR
] = r300PackFloat32(factor
);
956 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_CONSTANT
] = r300PackFloat32(constant
);
959 /* Routing and texture-related */
961 void r300_setup_routing(GLcontext
*ctx
, GLboolean immediate
)
963 int i
, count
=0,reg
=0;
965 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
966 struct vertex_buffer
*VB
= &tnl
->vb
;
967 r300ContextPtr r300
= R300_CONTEXT(ctx
);
970 /* Stage 1 - input to VAP */
972 /* Assign register number automatically, retaining it in rmesa->state.reg */
974 /* Note: immediate vertex data includes all coordinates.
975 To save bandwidth use either VBUF or state-based vertex generation */
977 #define CONFIGURE_AOS(v, o, r, f) \
979 if (RADEON_DEBUG & DEBUG_STATE)fprintf(stderr, "Enabling "#r "\n"); \
981 r300->state.aos[count].element_size=4; \
982 r300->state.aos[count].stride=4; \
983 r300->state.aos[count].ncomponents=4; \
985 r300->state.aos[count].element_size=v->size; \
986 r300->state.aos[count].stride=v->size; \
987 r300->state.aos[count].ncomponents=v->size; \
989 r300->state.aos[count].offset=o; \
990 r300->state.aos[count].reg=reg; \
991 r300->state.aos[count].format=(f); \
992 r300->state.vap_reg.r=reg; \
997 /* All offsets are 0 - for use by immediate mode.
998 Should change later to handle vertex buffers */
999 if(r300
->current_vp
!=NULL
){
1001 /* VERT_ATTRIB_WEIGHT, VERT_ATTRIB_SIX, VERT_ATTRIB_SEVEN, VERT_ATTRIB_GENERIC0,
1002 VERT_ATTRIB_GENERIC1, VERT_ATTRIB_GENERIC2, VERT_ATTRIB_GENERIC3 */
1003 r300
->state
.render_inputs
= 0;
1005 if(r300
->current_vp
->inputs
[VERT_ATTRIB_POS
] != -1){
1006 reg
=r300
->current_vp
->inputs
[VERT_ATTRIB_POS
];
1007 CONFIGURE_AOS(VB
->ObjPtr
, 0, i_coords
, AOS_FORMAT_FLOAT
);
1008 r300
->state
.render_inputs
|= _TNL_BIT_POS
;
1010 if(r300
->current_vp
->inputs
[VERT_ATTRIB_NORMAL
] != -1){
1011 reg
=r300
->current_vp
->inputs
[VERT_ATTRIB_NORMAL
];
1012 CONFIGURE_AOS(VB
->NormalPtr
, 0, i_normal
, AOS_FORMAT_FLOAT
);
1013 r300
->state
.render_inputs
|= _TNL_BIT_NORMAL
;
1015 if(r300
->current_vp
->inputs
[VERT_ATTRIB_COLOR0
] != -1){
1016 reg
=r300
->current_vp
->inputs
[VERT_ATTRIB_COLOR0
];
1017 CONFIGURE_AOS(VB
->ColorPtr
[0], 0, i_color
[0], AOS_FORMAT_FLOAT_COLOR
);
1018 r300
->state
.render_inputs
|= _TNL_BIT_COLOR0
;
1020 if(r300
->current_vp
->inputs
[VERT_ATTRIB_COLOR1
] != -1){
1021 reg
=r300
->current_vp
->inputs
[VERT_ATTRIB_COLOR1
];
1022 CONFIGURE_AOS(VB
->SecondaryColorPtr
[0], 0, i_color
[1], AOS_FORMAT_FLOAT_COLOR
);
1023 r300
->state
.render_inputs
|= _TNL_BIT_COLOR1
;
1025 if(r300
->current_vp
->inputs
[VERT_ATTRIB_FOG
] != -1){
1026 reg
=r300
->current_vp
->inputs
[VERT_ATTRIB_FOG
];
1027 CONFIGURE_AOS(VB
->FogCoordPtr
, 0, i_fog
, AOS_FORMAT_FLOAT
);
1028 r300
->state
.render_inputs
|= _TNL_BIT_FOG
;
1030 for(i
=0;i
< ctx
->Const
.MaxTextureUnits
;i
++) // tex 7 is last
1031 if(r300
->current_vp
->inputs
[VERT_ATTRIB_TEX0
+i
] != -1){
1032 reg
=r300
->current_vp
->inputs
[VERT_ATTRIB_TEX0
+i
];
1033 CONFIGURE_AOS(VB
->TexCoordPtr
[i
], 0, i_tex
[i
], AOS_FORMAT_FLOAT
);
1034 r300
->state
.render_inputs
|= _TNL_BIT_TEX0
<<i
;
1037 if((tnl
->render_inputs
& _TNL_BIT_INDEX
))
1038 CONFIGURE_AOS(VB
->IndexPtr
[0], 0, i_index
, AOS_FORMAT_FLOAT
);
1040 if((tnl
->render_inputs
& _TNL_BIT_POINTSIZE
))
1041 CONFIGURE_AOS(VB
->PointSizePtr
, 0, i_pointsize
, AOS_FORMAT_FLOAT
);
1045 r300
->state
.render_inputs
= tnl
->render_inputs
;
1047 if(tnl
->render_inputs
& _TNL_BIT_POS
)
1048 CONFIGURE_AOS(VB
->ObjPtr
, 0, i_coords
, AOS_FORMAT_FLOAT
);
1049 if(tnl
->render_inputs
& _TNL_BIT_NORMAL
)
1050 CONFIGURE_AOS(VB
->NormalPtr
, 0, i_normal
, AOS_FORMAT_FLOAT
);
1052 if(tnl
->render_inputs
& _TNL_BIT_COLOR0
)
1053 CONFIGURE_AOS(VB
->ColorPtr
[0], 0, i_color
[0], AOS_FORMAT_FLOAT_COLOR
);
1054 if(tnl
->render_inputs
& _TNL_BIT_COLOR1
)
1055 CONFIGURE_AOS(VB
->SecondaryColorPtr
[0], 0, i_color
[1], AOS_FORMAT_FLOAT_COLOR
);
1057 /*if(tnl->render_inputs & _TNL_BIT_FOG) // Causes lock ups when immediate mode is on
1058 CONFIGURE_AOS(VB->FogCoordPtr, 0, i_fog, AOS_FORMAT_FLOAT);*/
1060 for(i
=0;i
< ctx
->Const
.MaxTextureUnits
;i
++)
1061 if(tnl
->render_inputs
& (_TNL_BIT_TEX0
<<i
))
1062 CONFIGURE_AOS(VB
->TexCoordPtr
[i
], 0, i_tex
[i
], AOS_FORMAT_FLOAT
);
1064 if(tnl
->render_inputs
& _TNL_BIT_INDEX
)
1065 CONFIGURE_AOS(VB
->IndexPtr
[0], 0, i_index
, AOS_FORMAT_FLOAT
);
1066 if(tnl
->render_inputs
& _TNL_BIT_POINTSIZE
)
1067 CONFIGURE_AOS(VB
->PointSizePtr
, 0, i_pointsize
, AOS_FORMAT_FLOAT
);
1070 r300
->state
.aos_count
=count
;
1072 if (RADEON_DEBUG
& DEBUG_STATE
)
1073 fprintf(stderr
, "aos_count=%d render_inputs=%08x\n", count
, r300
->state
.render_inputs
);
1076 if(count
>R300_MAX_AOS_ARRAYS
){
1077 fprintf(stderr
, "Aieee ! AOS array count exceeded !\n");
1083 /* setup INPUT_ROUTE */
1084 R300_STATECHANGE(r300
, vir
[0]);
1085 for(i
=0;i
+1<count
;i
+=2){
1086 dw
=(r300
->state
.aos
[i
].ncomponents
-1)
1087 | ((r300
->state
.aos
[i
].reg
)<<8)
1088 | (r300
->state
.aos
[i
].format
<<14)
1089 | (((r300
->state
.aos
[i
+1].ncomponents
-1)
1090 | ((r300
->state
.aos
[i
+1].reg
)<<8)
1091 | (r300
->state
.aos
[i
+1].format
<<14))<<16);
1096 r300
->hw
.vir
[0].cmd
[R300_VIR_CNTL_0
+(i
>>1)]=dw
;
1099 dw
=(r300
->state
.aos
[count
-1].ncomponents
-1)
1100 | (r300
->state
.aos
[count
-1].format
<<14)
1101 | ((r300
->state
.aos
[count
-1].reg
)<<8)
1103 r300
->hw
.vir
[0].cmd
[R300_VIR_CNTL_0
+(count
>>1)]=dw
;
1104 //fprintf(stderr, "vir0 dw=%08x\n", dw);
1106 /* Set the rest of INPUT_ROUTE_0 to 0 */
1107 //for(i=((count+1)>>1); i<8; i++)r300->hw.vir[0].cmd[R300_VIR_CNTL_0+i]=(0x0);
1108 ((drm_r300_cmd_header_t
*)r300
->hw
.vir
[0].cmd
)->unchecked_state
.count
= (count
+1)>>1;
1111 /* Mesa assumes that all missing components are from (0, 0, 0, 1) */
1112 #define ALL_COMPONENTS ((R300_INPUT_ROUTE_SELECT_X<<R300_INPUT_ROUTE_X_SHIFT) \
1113 | (R300_INPUT_ROUTE_SELECT_Y<<R300_INPUT_ROUTE_Y_SHIFT) \
1114 | (R300_INPUT_ROUTE_SELECT_Z<<R300_INPUT_ROUTE_Z_SHIFT) \
1115 | (R300_INPUT_ROUTE_SELECT_W<<R300_INPUT_ROUTE_W_SHIFT))
1117 #define ALL_DEFAULT ((R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_X_SHIFT) \
1118 | (R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_Y_SHIFT) \
1119 | (R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_Z_SHIFT) \
1120 | (R300_INPUT_ROUTE_SELECT_ONE<<R300_INPUT_ROUTE_W_SHIFT))
1122 R300_STATECHANGE(r300
, vir
[1]);
1124 for(i
=0;i
+1<count
;i
+=2){
1126 mask
=(1<<(r300
->state
.aos
[i
].ncomponents
*3))-1;
1127 dw
=(ALL_COMPONENTS
& mask
)
1128 | (ALL_DEFAULT
& ~mask
)
1129 | R300_INPUT_ROUTE_ENABLE
;
1132 mask
=(1<<(r300
->state
.aos
[i
+1].ncomponents
*3))-1;
1134 (ALL_COMPONENTS
& mask
)
1135 | (ALL_DEFAULT
& ~mask
)
1136 | R300_INPUT_ROUTE_ENABLE
1139 r300
->hw
.vir
[1].cmd
[R300_VIR_CNTL_0
+(i
>>1)]=dw
;
1142 mask
=(1<<(r300
->state
.aos
[count
-1].ncomponents
*3))-1;
1143 dw
=(ALL_COMPONENTS
& mask
)
1144 | (ALL_DEFAULT
& ~mask
)
1145 | R300_INPUT_ROUTE_ENABLE
;
1146 r300
->hw
.vir
[1].cmd
[R300_VIR_CNTL_0
+(count
>>1)]=dw
;
1147 //fprintf(stderr, "vir1 dw=%08x\n", dw);
1149 /* Set the rest of INPUT_ROUTE_1 to 0 */
1150 //for(i=((count+1)>>1); i<8; i++)r300->hw.vir[1].cmd[R300_VIR_CNTL_0+i]=0x0;
1151 ((drm_r300_cmd_header_t
*)r300
->hw
.vir
[1].cmd
)->unchecked_state
.count
= (count
+1)>>1;
1153 /* Set up input_cntl */
1155 R300_STATECHANGE(r300
, vic
);
1156 r300
->hw
.vic
.cmd
[R300_VIC_CNTL_0
]=0x5555; /* Hard coded value, no idea what it means */
1158 r300
->hw
.vic
.cmd
[R300_VIC_CNTL_1
]=0;
1160 if(r300
->state
.render_inputs
& _TNL_BIT_POS
)
1161 r300
->hw
.vic
.cmd
[R300_VIC_CNTL_1
]|=R300_INPUT_CNTL_POS
;
1163 if(r300
->state
.render_inputs
& _TNL_BIT_NORMAL
)
1164 r300
->hw
.vic
.cmd
[R300_VIC_CNTL_1
]|=R300_INPUT_CNTL_NORMAL
;
1166 if(r300
->state
.render_inputs
& _TNL_BIT_COLOR0
)
1167 r300
->hw
.vic
.cmd
[R300_VIC_CNTL_1
]|=R300_INPUT_CNTL_COLOR
;
1169 for(i
=0;i
< ctx
->Const
.MaxTextureUnits
;i
++)
1170 if(r300
->state
.render_inputs
& (_TNL_BIT_TEX0
<<i
))
1171 r300
->hw
.vic
.cmd
[R300_VIC_CNTL_1
]|=(R300_INPUT_CNTL_TC0
<<i
);
1173 /* Stage 3: VAP output */
1174 R300_STATECHANGE(r300
, vof
);
1175 r300
->hw
.vof
.cmd
[R300_VOF_CNTL_0
]=R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
1176 | R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT
;
1178 r300
->hw
.vof
.cmd
[R300_VOF_CNTL_1
]=0;
1179 for(i
=0;i
< ctx
->Const
.MaxTextureUnits
;i
++)
1180 if(r300
->state
.render_inputs
& (_TNL_BIT_TEX0
<<i
))
1181 r300
->hw
.vof
.cmd
[R300_VOF_CNTL_1
]|=(4<<(3*i
));
1185 static r300TexObj default_tex_obj
={
1186 filter
:R300_TX_MAG_FILTER_LINEAR
| R300_TX_MIN_FILTER_LINEAR
,
1188 size
: (0xff << R300_TX_WIDTHMASK_SHIFT
)
1189 | (0xff << R300_TX_HEIGHTMASK_SHIFT
)
1190 | (0x8 << R300_TX_SIZE_SHIFT
),
1197 /* there is probably a system to these value, but, for now,
1198 we just try by hand */
1200 static int inline translate_src(int src
)
1209 case GL_PRIMARY_COLOR
:
1226 /* r300 doesnt handle GL_CLAMP and GL_MIRROR_CLAMP_EXT correctly when filter is NEAREST.
1227 * Since texwrap produces same results for GL_CLAMP and GL_CLAMP_TO_EDGE we use them instead.
1228 * We need to recalculate wrap modes whenever filter mode is changed because someone might do:
1229 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1230 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1231 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1232 * Since r300 completely ignores R300_TX_CLAMP when either min or mag is nearest it cant handle
1233 * combinations where only one of them is nearest.
1235 static unsigned long gen_fixed_filter(unsigned long f
)
1237 unsigned long mag
, min
, needs_fixing
=0;
1240 /* We ignore MIRROR bit so we dont have to do everything twice */
1241 if((f
& ((7-1) << R300_TX_WRAP_S_SHIFT
)) == (R300_TX_CLAMP
<< R300_TX_WRAP_S_SHIFT
)){
1244 if((f
& ((7-1) << R300_TX_WRAP_T_SHIFT
)) == (R300_TX_CLAMP
<< R300_TX_WRAP_T_SHIFT
)){
1247 if((f
& ((7-1) << R300_TX_WRAP_Q_SHIFT
)) == (R300_TX_CLAMP
<< R300_TX_WRAP_Q_SHIFT
)){
1254 mag
=f
& R300_TX_MAG_FILTER_MASK
;
1255 min
=f
& R300_TX_MIN_FILTER_MASK
;
1257 /* TODO: Check for anisto filters too */
1258 if((mag
!= R300_TX_MAG_FILTER_NEAREST
) && (min
!= R300_TX_MIN_FILTER_NEAREST
))
1261 /* r300 cant handle these modes hence we force nearest to linear */
1262 if((mag
== R300_TX_MAG_FILTER_NEAREST
) && (min
!= R300_TX_MIN_FILTER_NEAREST
)){
1263 f
&= ~R300_TX_MAG_FILTER_NEAREST
;
1264 f
|= R300_TX_MAG_FILTER_LINEAR
;
1268 if((min
== R300_TX_MIN_FILTER_NEAREST
) && (mag
!= R300_TX_MAG_FILTER_NEAREST
)){
1269 f
&= ~R300_TX_MIN_FILTER_NEAREST
;
1270 f
|= R300_TX_MIN_FILTER_LINEAR
;
1274 /* Both are nearest */
1275 if(needs_fixing
& 1){
1276 f
&= ~((7-1) << R300_TX_WRAP_S_SHIFT
);
1277 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_S_SHIFT
;
1279 if(needs_fixing
& 2){
1280 f
&= ~((7-1) << R300_TX_WRAP_T_SHIFT
);
1281 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_T_SHIFT
;
1283 if(needs_fixing
& 4){
1284 f
&= ~((7-1) << R300_TX_WRAP_Q_SHIFT
);
1285 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_Q_SHIFT
;
1290 void r300_setup_textures(GLcontext
*ctx
)
1293 struct r300_tex_obj
*t
;
1294 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1295 int max_texture_unit
=-1; /* -1 translates into no setup costs for fields */
1296 struct gl_texture_unit
*texUnit
;
1298 R300_STATECHANGE(r300
, txe
);
1299 R300_STATECHANGE(r300
, tex
.filter
);
1300 R300_STATECHANGE(r300
, tex
.unknown1
);
1301 R300_STATECHANGE(r300
, tex
.size
);
1302 R300_STATECHANGE(r300
, tex
.format
);
1303 R300_STATECHANGE(r300
, tex
.offset
);
1304 R300_STATECHANGE(r300
, tex
.unknown4
);
1305 R300_STATECHANGE(r300
, tex
.border_color
);
1307 r300
->state
.texture
.tc_count
=0;
1309 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
]=0x0;
1311 mtu
= r300
->radeon
.glCtx
->Const
.MaxTextureUnits
;
1312 if (RADEON_DEBUG
& DEBUG_STATE
)
1313 fprintf(stderr
, "mtu=%d\n", mtu
);
1315 if(mtu
>R300_MAX_TEXTURE_UNITS
){
1316 fprintf(stderr
, "Aiiee ! mtu=%d is greater than R300_MAX_TEXTURE_UNITS=%d\n",
1317 mtu
, R300_MAX_TEXTURE_UNITS
);
1321 if( ((r300
->state
.render_inputs
& (_TNL_BIT_TEX0
<<i
))!=0) != ((ctx
->Texture
.Unit
[i
].Enabled
)!=0) ) {
1322 WARN_ONCE("Mismatch between render_inputs and ctx->Texture.Unit[i].Enabled value.\n");
1324 if(r300
->state
.render_inputs
& (_TNL_BIT_TEX0
<<i
)){
1325 t
=r300
->state
.texture
.unit
[i
].texobj
;
1326 //fprintf(stderr, "format=%08x\n", r300->state.texture.unit[i].format);
1327 r300
->state
.texture
.tc_count
++;
1329 fprintf(stderr
, "Texture unit %d enabled, but corresponding texobj is NULL, using default object.\n", i
);
1333 //fprintf(stderr, "t->format=%08x\n", t->format);
1334 if((t
->format
& 0xffffff00)==0xffffff00){
1335 WARN_ONCE("unknown texture format (entry %x) encountered. Help me !\n", t
->format
& 0xff);
1336 //fprintf(stderr, "t->format=%08x\n", t->format);
1338 if (RADEON_DEBUG
& DEBUG_STATE
)
1339 fprintf(stderr
, "Activating texture unit %d\n", i
);
1341 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
]|=(1<<i
);
1343 r300
->hw
.tex
.filter
.cmd
[R300_TEX_VALUE_0
+i
]=gen_fixed_filter(t
->filter
);
1344 /* No idea why linear filtered textures shake when puting random data */
1345 /*r300->hw.tex.unknown1.cmd[R300_TEX_VALUE_0+i]=(rand()%0xffffffff) & (~0x1fff);*/
1346 r300
->hw
.tex
.size
.cmd
[R300_TEX_VALUE_0
+i
]=t
->size
;
1347 r300
->hw
.tex
.format
.cmd
[R300_TEX_VALUE_0
+i
]=t
->format
;
1348 //fprintf(stderr, "t->format=%08x\n", t->format);
1349 r300
->hw
.tex
.offset
.cmd
[R300_TEX_VALUE_0
+i
]=r300
->radeon
.radeonScreen
->fbLocation
+t
->offset
;
1350 r300
->hw
.tex
.unknown4
.cmd
[R300_TEX_VALUE_0
+i
]=0x0;
1351 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_VALUE_0
+i
]=t
->pp_border_color
;
1354 ((drm_r300_cmd_header_t
*)r300
->hw
.tex
.filter
.cmd
)->unchecked_state
.count
= max_texture_unit
+1;
1355 ((drm_r300_cmd_header_t
*)r300
->hw
.tex
.unknown1
.cmd
)->unchecked_state
.count
= max_texture_unit
+1;
1356 ((drm_r300_cmd_header_t
*)r300
->hw
.tex
.size
.cmd
)->unchecked_state
.count
= max_texture_unit
+1;
1357 ((drm_r300_cmd_header_t
*)r300
->hw
.tex
.format
.cmd
)->unchecked_state
.count
= max_texture_unit
+1;
1358 ((drm_r300_cmd_header_t
*)r300
->hw
.tex
.offset
.cmd
)->unchecked_state
.count
= max_texture_unit
+1;
1359 ((drm_r300_cmd_header_t
*)r300
->hw
.tex
.unknown4
.cmd
)->unchecked_state
.count
= max_texture_unit
+1;
1360 ((drm_r300_cmd_header_t
*)r300
->hw
.tex
.border_color
.cmd
)->unchecked_state
.count
= max_texture_unit
+1;
1362 if (RADEON_DEBUG
& DEBUG_STATE
)
1363 fprintf(stderr
, "TX_ENABLE: %08x max_texture_unit=%d\n", r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
], max_texture_unit
);
1366 void r300_setup_rs_unit(GLcontext
*ctx
)
1368 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1371 /* This needs to be rewritten - it is a hack at best */
1373 R300_STATECHANGE(r300
, ri
);
1374 R300_STATECHANGE(r300
, rc
);
1375 R300_STATECHANGE(r300
, rr
);
1377 for(i
= 1; i
<= 8; ++i
)
1378 r300
->hw
.ri
.cmd
[i
] = 0x00d10000;
1379 r300
->hw
.ri
.cmd
[R300_RI_INTERP_1
] |= R300_RS_INTERP_1_UNKNOWN
;
1380 r300
->hw
.ri
.cmd
[R300_RI_INTERP_2
] |= R300_RS_INTERP_2_UNKNOWN
;
1381 r300
->hw
.ri
.cmd
[R300_RI_INTERP_3
] |= R300_RS_INTERP_3_UNKNOWN
;
1384 for(i
= 2; i
<= 8; ++i
)
1385 r300
->hw
.ri
.cmd
[i
] |= 4;
1388 for(i
= 1; i
<= 8; ++i
)
1389 r300
->hw
.rr
.cmd
[i
] = 0;
1390 /* textures enabled ? */
1391 if(r300
->state
.texture
.tc_count
>0){
1393 /* This code only really works with one set of texture coordinates */
1395 /* The second constant is needed to get glxgears display anything .. */
1396 r300
->hw
.rc
.cmd
[1] = R300_RS_CNTL_0_UNKNOWN_7
1397 | R300_RS_CNTL_0_UNKNOWN_18
1398 | (r300
->state
.texture
.tc_count
<<R300_RS_CNTL_TC_CNT_SHIFT
);
1399 r300
->hw
.rc
.cmd
[2] = 0xc0;
1402 ((drm_r300_cmd_header_t
*)r300
->hw
.rr
.cmd
)->unchecked_state
.count
= 1;
1403 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
] = 0x24008;
1407 /* The second constant is needed to get glxgears display anything .. */
1408 r300
->hw
.rc
.cmd
[1] = R300_RS_CNTL_0_UNKNOWN_7
| R300_RS_CNTL_0_UNKNOWN_18
;
1409 r300
->hw
.rc
.cmd
[2] = 0;
1411 ((drm_r300_cmd_header_t
*)r300
->hw
.rr
.cmd
)->unchecked_state
.count
= 1;
1412 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
] = 0x4000;
1417 #define vpucount(ptr) (((drm_r300_cmd_header_t*)(ptr))->vpu.count)
1419 #define bump_vpu_count(ptr, new_count) do{\
1420 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
1421 int _nc=(new_count)/4; \
1422 if(_nc>_p->vpu.count)_p->vpu.count=_nc;\
1425 void static inline setup_vertex_shader_fragment(r300ContextPtr r300
, int dest
, struct r300_vertex_shader_fragment
*vsf
)
1429 if(vsf
->length
==0)return;
1431 if(vsf
->length
& 0x3){
1432 fprintf(stderr
,"VERTEX_SHADER_FRAGMENT must have length divisible by 4\n");
1436 switch((dest
>>8) & 0xf){
1438 R300_STATECHANGE(r300
, vpi
);
1439 for(i
=0;i
<vsf
->length
;i
++)
1440 r300
->hw
.vpi
.cmd
[R300_VPI_INSTR_0
+i
+4*(dest
& 0xff)]=(vsf
->body
.d
[i
]);
1441 bump_vpu_count(r300
->hw
.vpi
.cmd
, vsf
->length
+4*(dest
& 0xff));
1445 R300_STATECHANGE(r300
, vpp
);
1446 for(i
=0;i
<vsf
->length
;i
++)
1447 r300
->hw
.vpp
.cmd
[R300_VPP_PARAM_0
+i
+4*(dest
& 0xff)]=(vsf
->body
.d
[i
]);
1448 bump_vpu_count(r300
->hw
.vpp
.cmd
, vsf
->length
+4*(dest
& 0xff));
1451 R300_STATECHANGE(r300
, vps
);
1452 for(i
=0;i
<vsf
->length
;i
++)
1453 r300
->hw
.vps
.cmd
[1+i
+4*(dest
& 0xff)]=(vsf
->body
.d
[i
]);
1454 bump_vpu_count(r300
->hw
.vps
.cmd
, vsf
->length
+4*(dest
& 0xff));
1457 fprintf(stderr
, "%s:%s don't know how to handle dest %04x\n", __FILE__
, __FUNCTION__
, dest
);
1462 void r300SetupVertexProgram(r300ContextPtr rmesa
);
1464 void r300SetupVertexShader(r300ContextPtr rmesa
)
1466 GLcontext
* ctx
= rmesa
->radeon
.glCtx
;
1468 if(rmesa
->current_vp
!= NULL
){
1469 r300SetupVertexProgram(rmesa
);
1473 /* Reset state, in case we don't use something */
1474 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vpp
.cmd
)->vpu
.count
= 0;
1475 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vpi
.cmd
)->vpu
.count
= 0;
1476 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vps
.cmd
)->vpu
.count
= 0;
1479 /* This needs to be replaced by vertex shader generation code */
1482 /* textures enabled ? */
1483 if(rmesa
->state
.texture
.tc_count
>0){
1484 rmesa
->state
.vertex_shader
=SINGLE_TEXTURE_VERTEX_SHADER
;
1486 rmesa
->state
.vertex_shader
=FLAT_COLOR_VERTEX_SHADER
;
1490 rmesa
->state
.vertex_shader
.matrix
[0].length
=16;
1491 memcpy(rmesa
->state
.vertex_shader
.matrix
[0].body
.f
, ctx
->_ModelProjectMatrix
.m
, 16*4);
1493 setup_vertex_shader_fragment(rmesa
, VSF_DEST_PROGRAM
, &(rmesa
->state
.vertex_shader
.program
));
1495 setup_vertex_shader_fragment(rmesa
, VSF_DEST_MATRIX0
, &(rmesa
->state
.vertex_shader
.matrix
[0]));
1497 setup_vertex_shader_fragment(rmesa
, VSF_DEST_MATRIX1
, &(rmesa
->state
.vertex_shader
.matrix
[0]));
1498 setup_vertex_shader_fragment(rmesa
, VSF_DEST_MATRIX2
, &(rmesa
->state
.vertex_shader
.matrix
[0]));
1500 setup_vertex_shader_fragment(rmesa
, VSF_DEST_VECTOR0
, &(rmesa
->state
.vertex_shader
.vector
[0]));
1501 setup_vertex_shader_fragment(rmesa
, VSF_DEST_VECTOR1
, &(rmesa
->state
.vertex_shader
.vector
[1]));
1505 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN1
, &(rmesa
->state
.vertex_shader
.unknown1
));
1506 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN2
, &(rmesa
->state
.vertex_shader
.unknown2
));
1509 R300_STATECHANGE(rmesa
, pvs
);
1510 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
]=(rmesa
->state
.vertex_shader
.program_start
<< R300_PVS_CNTL_1_PROGRAM_START_SHIFT
)
1511 | (rmesa
->state
.vertex_shader
.unknown_ptr1
<< R300_PVS_CNTL_1_UNKNOWN_SHIFT
)
1512 | (rmesa
->state
.vertex_shader
.program_end
<< R300_PVS_CNTL_1_PROGRAM_END_SHIFT
);
1513 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
]=(rmesa
->state
.vertex_shader
.param_offset
<< R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT
)
1514 | (rmesa
->state
.vertex_shader
.param_count
<< R300_PVS_CNTL_2_PARAM_COUNT_SHIFT
);
1515 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
]=(rmesa
->state
.vertex_shader
.unknown_ptr2
<< R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT
)
1516 | (rmesa
->state
.vertex_shader
.unknown_ptr3
<< 0);
1518 /* This is done for vertex shader fragments, but also needs to be done for vap_pvs,
1519 so I leave it as a reminder */
1521 reg_start(R300_VAP_PVS_WAITIDLE
,0);
1526 void r300SetupVertexProgram(r300ContextPtr rmesa
)
1528 GLcontext
* ctx
= rmesa
->radeon
.glCtx
;
1532 /* Reset state, in case we don't use something */
1533 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vpp
.cmd
)->vpu
.count
= 0;
1534 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vpi
.cmd
)->vpu
.count
= 0;
1535 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vps
.cmd
)->vpu
.count
= 0;
1537 r300VertexProgUpdateParams(ctx
, rmesa
->current_vp
);
1539 setup_vertex_shader_fragment(rmesa
, VSF_DEST_PROGRAM
, &(rmesa
->current_vp
->program
));
1541 setup_vertex_shader_fragment(rmesa
, VSF_DEST_MATRIX0
, &(rmesa
->current_vp
->params
));
1544 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN1
, &(rmesa
->state
.vertex_shader
.unknown1
));
1545 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN2
, &(rmesa
->state
.vertex_shader
.unknown2
));
1548 inst_count
=rmesa
->current_vp
->program
.length
/4 - 1;
1549 param_count
=rmesa
->current_vp
->params
.length
/4;
1551 R300_STATECHANGE(rmesa
, pvs
);
1552 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
]=(0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT
)
1553 | (inst_count
/*0*/ << R300_PVS_CNTL_1_UNKNOWN_SHIFT
)
1554 | (inst_count
<< R300_PVS_CNTL_1_PROGRAM_END_SHIFT
);
1555 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
]=(0 << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT
)
1556 | (param_count
<< R300_PVS_CNTL_2_PARAM_COUNT_SHIFT
);
1557 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
]=(0/*rmesa->state.vertex_shader.unknown_ptr2*/ << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT
)
1558 | ((inst_count
-rmesa
->current_vp
->t2rs
) /*rmesa->state.vertex_shader.unknown_ptr3*/ << 0);
1560 /* This is done for vertex shader fragments, but also needs to be done for vap_pvs,
1561 so I leave it as a reminder */
1563 reg_start(R300_VAP_PVS_WAITIDLE
,0);
1569 /* just a skeleton for now.. */
1570 void r300GenerateTexturePixelShader(r300ContextPtr r300
)
1573 mtu
= r300
->radeon
.glCtx
->Const
.MaxTextureUnits
;
1576 int tex_inst
=0, alu_inst
=0;
1579 /* No need to proliferate {} */
1580 if(! (r300
->state
.render_inputs
& (_TNL_BIT_TEX0
<<i
)))continue;
1582 envMode
= r300
->radeon
.glCtx
->Texture
.Unit
[i
].EnvMode
;
1583 //fprintf(stderr, "envMode=%s\n", _mesa_lookup_enum_by_nr(envMode));
1585 /* Fetch textured pixel */
1587 r300
->state
.pixel_shader
.program
.tex
.inst
[tex_inst
]=0x00018000;
1590 switch(r300
->radeon
.glCtx
->Texture
.Unit
[i
]._CurrentCombine
->ModeRGB
){
1592 WARN_ONCE("ModeA==GL_REPLACE is possibly broken.\n");
1593 r300
->state
.pixel_shader
.program
.alu
.inst
[alu_inst
].inst0
=
1594 EASY_PFS_INSTR0(MAD
, SRC0C_XYZ
, ONE
, ZERO
);
1596 r300
->state
.pixel_shader
.program
.alu
.inst
[alu_inst
].inst1
=
1597 EASY_PFS_INSTR1(0, 0, 0 | PFS_FLAG_CONST
, 0 | PFS_FLAG_CONST
, NONE
, ALL
);
1600 WARN_ONCE("ModeRGB==GL_MODULATE is possibly broken.\n");
1601 r300
->state
.pixel_shader
.program
.alu
.inst
[alu_inst
].inst0
=
1602 EASY_PFS_INSTR0(MAD
, SRC0C_XYZ
, SRC1C_XYZ
, ZERO
);
1604 r300
->state
.pixel_shader
.program
.alu
.inst
[alu_inst
].inst1
=
1605 EASY_PFS_INSTR1(0, 0, 1, 0 | PFS_FLAG_CONST
, NONE
, ALL
);
1609 fprintf(stderr
, "ModeRGB=%s is not implemented yet !\n",
1610 _mesa_lookup_enum_by_nr(r300
->radeon
.glCtx
->Texture
.Unit
[i
]._CurrentCombine
->ModeRGB
));
1612 r300
->state
.pixel_shader
.program
.alu
.inst
[alu_inst
].inst0
=
1613 EASY_PFS_INSTR0(MAD
, SRC0C_XYZ
, ONE
, ZERO
);
1615 r300
->state
.pixel_shader
.program
.alu
.inst
[alu_inst
].inst1
=
1616 EASY_PFS_INSTR1(0, 0, 0 | PFS_FLAG_CONST
, 0 | PFS_FLAG_CONST
, NONE
, ALL
);
1618 switch(r300
->radeon
.glCtx
->Texture
.Unit
[i
]._CurrentCombine
->ModeA
){
1620 WARN_ONCE("ModeA==GL_REPLACE is possibly broken.\n");
1621 r300
->state
.pixel_shader
.program
.alu
.inst
[alu_inst
].inst2
=
1622 EASY_PFS_INSTR2(MAD
, SRC0A
, ONE
, ZERO
);
1624 r300
->state
.pixel_shader
.program
.alu
.inst
[alu_inst
].inst3
=
1625 EASY_PFS_INSTR3(0, 0, 0| PFS_FLAG_CONST
, 0 | PFS_FLAG_CONST
, OUTPUT
);
1628 fprintf(stderr
, "numArgsA=%d sourceA[0]=%s op=%d\n",
1629 r300
->radeon
.glCtx
->Texture
.Unit
[i
]._CurrentCombine
->_NumArgsA
,
1630 _mesa_lookup_enum_by_nr(r300
->radeon
.glCtx
->Texture
.Unit
[i
]._CurrentCombine
->SourceA
[0]),
1631 r300
->radeon
.glCtx
->Texture
.Unit
[i
]._CurrentCombine
->OperandA
[0]-GL_SRC_ALPHA
);
1635 WARN_ONCE("ModeA==GL_MODULATE is possibly broken.\n");
1637 r300
->state
.pixel_shader
.program
.alu
.inst
[alu_inst
].inst2
=
1638 EASY_PFS_INSTR2(MAD
, SRC0A
, SRC1A
, ZERO
);
1640 r300
->state
.pixel_shader
.program
.alu
.inst
[alu_inst
].inst3
=
1641 EASY_PFS_INSTR3(0, 0, 1, 0 | PFS_FLAG_CONST
, OUTPUT
);
1645 fprintf(stderr
, "ModeA=%s is not implemented yet !\n",
1646 _mesa_lookup_enum_by_nr(r300
->radeon
.glCtx
->Texture
.Unit
[i
]._CurrentCombine
->ModeA
));
1648 r300
->state
.pixel_shader
.program
.alu
.inst
[alu_inst
].inst2
=
1649 EASY_PFS_INSTR2(MAD
, SRC0A
, ONE
, ZERO
);
1651 r300
->state
.pixel_shader
.program
.alu
.inst
[alu_inst
].inst3
=
1652 EASY_PFS_INSTR3(0, 0, 0 | PFS_FLAG_CONST
, 0 | PFS_FLAG_CONST
, OUTPUT
);
1659 r300
->state
.pixel_shader
.program
.tex
.length
=tex_inst
;
1660 r300
->state
.pixel_shader
.program
.tex_offset
=0;
1661 r300
->state
.pixel_shader
.program
.tex_end
=tex_inst
-1;
1664 /* saturate last instruction, like i915 driver does */
1665 r300
->state
.pixel_shader
.program
.alu
.inst
[alu_inst
-1].inst0
|=R300_FPI0_OUTC_SAT
;
1666 r300
->state
.pixel_shader
.program
.alu
.inst
[alu_inst
-1].inst2
|=R300_FPI2_OUTA_SAT
;
1669 r300
->state
.pixel_shader
.program
.alu
.length
=alu_inst
;
1670 r300
->state
.pixel_shader
.program
.alu_offset
=0;
1671 r300
->state
.pixel_shader
.program
.alu_end
=alu_inst
-1;
1674 void r300SetupPixelShader(r300ContextPtr rmesa
)
1678 /* This needs to be replaced by pixel shader generation code */
1680 /* textures enabled ? */
1681 if(rmesa
->state
.texture
.tc_count
>0){
1682 rmesa
->state
.pixel_shader
=SINGLE_TEXTURE_PIXEL_SHADER
;
1683 r300GenerateTexturePixelShader(rmesa
);
1685 rmesa
->state
.pixel_shader
=FLAT_COLOR_PIXEL_SHADER
;
1688 R300_STATECHANGE(rmesa
, fpt
);
1689 for(i
=0;i
<rmesa
->state
.pixel_shader
.program
.tex
.length
;i
++)
1690 rmesa
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+i
]=rmesa
->state
.pixel_shader
.program
.tex
.inst
[i
];
1691 rmesa
->hw
.fpt
.cmd
[R300_FPT_CMD_0
]=cmducs(R300_PFS_TEXI_0
, rmesa
->state
.pixel_shader
.program
.tex
.length
);
1693 #define OUTPUT_FIELD(st, reg, field) \
1694 R300_STATECHANGE(rmesa, st); \
1695 for(i=0;i<rmesa->state.pixel_shader.program.alu.length;i++) \
1696 rmesa->hw.st.cmd[R300_FPI_INSTR_0+i]=rmesa->state.pixel_shader.program.alu.inst[i].field;\
1697 rmesa->hw.st.cmd[R300_FPI_CMD_0]=cmducs(reg, rmesa->state.pixel_shader.program.alu.length);
1699 OUTPUT_FIELD(fpi
[0], R300_PFS_INSTR0_0
, inst0
);
1700 OUTPUT_FIELD(fpi
[1], R300_PFS_INSTR1_0
, inst1
);
1701 OUTPUT_FIELD(fpi
[2], R300_PFS_INSTR2_0
, inst2
);
1702 OUTPUT_FIELD(fpi
[3], R300_PFS_INSTR3_0
, inst3
);
1705 R300_STATECHANGE(rmesa
, fp
);
1707 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+i
]=
1708 (rmesa
->state
.pixel_shader
.program
.node
[i
].alu_offset
<< R300_PFS_NODE_ALU_OFFSET_SHIFT
)
1709 | (rmesa
->state
.pixel_shader
.program
.node
[i
].alu_end
<< R300_PFS_NODE_ALU_END_SHIFT
)
1710 | (rmesa
->state
.pixel_shader
.program
.node
[i
].tex_offset
<< R300_PFS_NODE_TEX_OFFSET_SHIFT
)
1711 | (rmesa
->state
.pixel_shader
.program
.node
[i
].tex_end
<< R300_PFS_NODE_TEX_END_SHIFT
)
1712 | ( (i
==3) ? R300_PFS_NODE_LAST_NODE
: 0);
1716 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL0
]=
1717 (rmesa
->state
.pixel_shader
.program
.active_nodes
-1)
1718 | (rmesa
->state
.pixel_shader
.program
.first_node_has_tex
<<3);
1720 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL1
]=rmesa
->state
.pixel_shader
.program
.temp_register_count
;
1722 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL2
]=
1723 (rmesa
->state
.pixel_shader
.program
.alu_offset
<< R300_PFS_CNTL_ALU_OFFSET_SHIFT
)
1724 | (rmesa
->state
.pixel_shader
.program
.alu_end
<< R300_PFS_CNTL_ALU_END_SHIFT
)
1725 | (rmesa
->state
.pixel_shader
.program
.tex_offset
<< R300_PFS_CNTL_TEX_OFFSET_SHIFT
)
1726 | (rmesa
->state
.pixel_shader
.program
.tex_end
<< R300_PFS_CNTL_TEX_END_SHIFT
);
1728 R300_STATECHANGE(rmesa
, fpp
);
1729 for(i
=0;i
<rmesa
->state
.pixel_shader
.param_length
;i
++){
1730 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+4*i
+0]=r300PackFloat32(rmesa
->state
.pixel_shader
.param
[i
].x
);
1731 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+4*i
+1]=r300PackFloat32(rmesa
->state
.pixel_shader
.param
[i
].y
);
1732 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+4*i
+2]=r300PackFloat32(rmesa
->state
.pixel_shader
.param
[i
].z
);
1733 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+4*i
+3]=r300PackFloat32(rmesa
->state
.pixel_shader
.param
[i
].w
);
1735 rmesa
->hw
.fpp
.cmd
[R300_FPP_CMD_0
]=cmducs(R300_PFS_PARAM_0_X
, rmesa
->state
.pixel_shader
.param_length
);
1740 * Called by Mesa after an internal state update.
1742 static void r300InvalidateState(GLcontext
* ctx
, GLuint new_state
)
1744 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1746 _swrast_InvalidateState(ctx
, new_state
);
1747 _swsetup_InvalidateState(ctx
, new_state
);
1748 _ac_InvalidateState(ctx
, new_state
);
1749 _tnl_InvalidateState(ctx
, new_state
);
1750 _ae_invalidate_state(ctx
, new_state
);
1752 /* Go inefficiency! */
1753 r300ResetHwState(r300
);
1756 void update_zbias(GLcontext
* ctx
, int prim
);
1759 * Completely recalculates hardware state based on the Mesa state.
1761 void r300ResetHwState(r300ContextPtr r300
)
1763 GLcontext
* ctx
= r300
->radeon
.glCtx
;
1766 if (RADEON_DEBUG
& DEBUG_STATE
)
1767 fprintf(stderr
, "%s\n", __FUNCTION__
);
1769 /* This is a place to initialize registers which
1770 have bitfields accessed by different functions
1771 and not all bits are used */
1773 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] = 0;
1774 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] = 0;
1775 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] = 0xffff00;
1778 /* go and compute register values from GL state */
1780 r300UpdateWindow(ctx
);
1783 ctx
->Color
.ColorMask
[RCOMP
],
1784 ctx
->Color
.ColorMask
[GCOMP
],
1785 ctx
->Color
.ColorMask
[BCOMP
],
1786 ctx
->Color
.ColorMask
[ACOMP
]);
1788 r300Enable(ctx
, GL_DEPTH_TEST
, ctx
->Depth
.Test
);
1789 r300DepthMask(ctx
, ctx
->Depth
.Mask
);
1790 r300DepthFunc(ctx
, ctx
->Depth
.Func
);
1792 r300UpdateCulling(ctx
);
1794 r300UpdateTextureState(ctx
);
1796 r300_setup_routing(ctx
, GL_TRUE
);
1797 r300_setup_textures(ctx
);
1798 r300_setup_rs_unit(ctx
);
1800 r300SetupVertexShader(r300
);
1801 r300SetupPixelShader(r300
);
1803 r300_set_blend_state(ctx
);
1804 r300AlphaFunc(ctx
, ctx
->Color
.AlphaFunc
, ctx
->Color
.AlphaRef
);
1806 /* Initialize magic registers
1807 TODO : learn what they really do, or get rid of
1808 those we don't have to touch */
1809 r300
->hw
.unk2080
.cmd
[1] = 0x0030045A;
1811 r300
->hw
.vte
.cmd
[1] = R300_VPORT_X_SCALE_ENA
1812 | R300_VPORT_X_OFFSET_ENA
1813 | R300_VPORT_Y_SCALE_ENA
1814 | R300_VPORT_Y_OFFSET_ENA
1815 | R300_VPORT_Z_SCALE_ENA
1816 | R300_VPORT_Z_OFFSET_ENA
1818 r300
->hw
.vte
.cmd
[2] = 0x00000008;
1820 r300
->hw
.unk2134
.cmd
[1] = 0x00FFFFFF;
1821 r300
->hw
.unk2134
.cmd
[2] = 0x00000000;
1822 #ifdef MESA_BIG_ENDIAN
1823 r300
->hw
.unk2140
.cmd
[1] = 0x00000002;
1825 r300
->hw
.unk2140
.cmd
[1] = 0x00000000;
1828 #if 0 /* Done in setup routing */
1829 ((drm_r300_cmd_header_t
*)r300
->hw
.vir
[0].cmd
)->unchecked_state
.count
= 1;
1830 r300
->hw
.vir
[0].cmd
[1] = 0x21030003;
1832 ((drm_r300_cmd_header_t
*)r300
->hw
.vir
[1].cmd
)->unchecked_state
.count
= 1;
1833 r300
->hw
.vir
[1].cmd
[1] = 0xF688F688;
1835 r300
->hw
.vic
.cmd
[R300_VIR_CNTL_0
] = 0x00000001;
1836 r300
->hw
.vic
.cmd
[R300_VIR_CNTL_1
] = 0x00000405;
1839 r300
->hw
.unk21DC
.cmd
[1] = 0xAAAAAAAA;
1841 r300
->hw
.unk221C
.cmd
[1] = R300_221C_NORMAL
;
1843 r300
->hw
.unk2220
.cmd
[1] = r300PackFloat32(1.0);
1844 r300
->hw
.unk2220
.cmd
[2] = r300PackFloat32(1.0);
1845 r300
->hw
.unk2220
.cmd
[3] = r300PackFloat32(1.0);
1846 r300
->hw
.unk2220
.cmd
[4] = r300PackFloat32(1.0);
1848 if (GET_CHIP(r300
->radeon
.radeonScreen
) == RADEON_CHIP_R300
)
1849 r300
->hw
.unk2288
.cmd
[1] = R300_2288_R300
;
1851 r300
->hw
.unk2288
.cmd
[1] = R300_2288_RV350
;
1854 r300
->hw
.vof
.cmd
[R300_VOF_CNTL_0
] = R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
1855 | R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT
;
1856 r300
->hw
.vof
.cmd
[R300_VOF_CNTL_1
] = 0; /* no textures */
1859 r300
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] = 0;
1860 r300
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] = 0;
1861 r300
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] = 0;
1864 r300
->hw
.gb_enable
.cmd
[1] = R300_GB_POINT_STUFF_ENABLE
1865 | R300_GB_LINE_STUFF_ENABLE
1866 | R300_GB_TRIANGLE_STUFF_ENABLE
;
1868 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_0
] = 0x66666666;
1869 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_1
] = 0x06666666;
1870 if (GET_CHIP(r300
->radeon
.radeonScreen
) == RADEON_CHIP_R300
)
1871 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] = R300_GB_TILE_ENABLE
1872 | R300_GB_TILE_PIPE_COUNT_R300
1873 | R300_GB_TILE_SIZE_16
;
1875 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] = R300_GB_TILE_ENABLE
1876 | R300_GB_TILE_PIPE_COUNT_RV300
1877 | R300_GB_TILE_SIZE_16
;
1878 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_SELECT
] = 0x00000000;
1879 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_AA_CONFIG
] = 0x00000000; /* No antialiasing */
1881 //r300->hw.txe.cmd[R300_TXE_ENABLE] = 0;
1883 r300
->hw
.unk4200
.cmd
[1] = r300PackFloat32(0.0);
1884 r300
->hw
.unk4200
.cmd
[2] = r300PackFloat32(0.0);
1885 r300
->hw
.unk4200
.cmd
[3] = r300PackFloat32(1.0);
1886 r300
->hw
.unk4200
.cmd
[4] = r300PackFloat32(1.0);
1888 r300
->hw
.unk4214
.cmd
[1] = 0x00050005;
1890 r300PointSize(ctx
, ctx
->Point
._Size
);
1892 r300
->hw
.ps
.cmd
[R300_PS_POINTSIZE
] = (6 << R300_POINTSIZE_X_SHIFT
) |
1893 (6 << R300_POINTSIZE_Y_SHIFT
);
1896 r300
->hw
.unk4230
.cmd
[1] = 0x01800000;
1897 r300
->hw
.unk4230
.cmd
[2] = 0x00020006;
1898 r300
->hw
.unk4230
.cmd
[3] = r300PackFloat32(1.0 / 192.0);
1900 r300LineWidth(ctx
, ctx
->Line
._Width
);
1903 static int foobar
=0;
1904 r300
->hw
.lsf
.cmd
[1] = foobar
++; //0x3a088889;
1906 r300
->hw
.unk4260
.cmd
[1] = 0;
1907 r300
->hw
.unk4260
.cmd
[2] = r300PackFloat32(0.0);
1908 r300
->hw
.unk4260
.cmd
[3] = r300PackFloat32(1.0);
1910 r300
->hw
.unk4274
.cmd
[1] = 0x00000002;
1911 r300
->hw
.unk4274
.cmd
[2] = 0x0003AAAA;
1912 r300
->hw
.unk4274
.cmd
[3] = 0x00000000;
1913 r300
->hw
.unk4274
.cmd
[4] = 0x00000000;
1915 r300PolygonMode(ctx
, GL_FRONT
, ctx
->Polygon
.FrontMode
);
1916 r300PolygonMode(ctx
, GL_BACK
, ctx
->Polygon
.BackMode
);
1918 r300
->hw
.unk4288
.cmd
[1] = 0x00000000;
1920 r300
->hw
.unk4288
.cmd
[2] = 0x00000001;
1921 r300
->hw
.unk4288
.cmd
[3] = 0x00000000;
1922 r300
->hw
.unk4288
.cmd
[4] = 0x00000000;
1923 r300
->hw
.unk4288
.cmd
[5] = 0x00000000;
1925 r300
->hw
.unk42A0
.cmd
[1] = 0x00000000;
1927 update_zbias(ctx
, GL_TRIANGLES
);/* FIXME */
1929 r300
->hw
.unk42B4
.cmd
[1] = 0x00000000;
1931 r300
->hw
.unk42C0
.cmd
[1] = 0x4B7FFFFF;
1932 r300
->hw
.unk42C0
.cmd
[2] = 0x00000000;
1935 r300
->hw
.unk43A4
.cmd
[1] = 0x0000001C;
1936 r300
->hw
.unk43A4
.cmd
[2] = 0x2DA49525;
1938 r300
->hw
.unk43E8
.cmd
[1] = 0x00FFFFFF;
1941 r300
->hw
.fp
.cmd
[R300_FP_CNTL0
] = 0;
1942 r300
->hw
.fp
.cmd
[R300_FP_CNTL1
] = 0;
1943 r300
->hw
.fp
.cmd
[R300_FP_CNTL2
] = 0;
1944 r300
->hw
.fp
.cmd
[R300_FP_NODE0
] = 0;
1945 r300
->hw
.fp
.cmd
[R300_FP_NODE1
] = 0;
1946 r300
->hw
.fp
.cmd
[R300_FP_NODE2
] = 0;
1947 r300
->hw
.fp
.cmd
[R300_FP_NODE3
] = 0;
1950 r300
->hw
.unk46A4
.cmd
[1] = 0x00001B01;
1951 r300
->hw
.unk46A4
.cmd
[2] = 0x00001B0F;
1952 r300
->hw
.unk46A4
.cmd
[3] = 0x00001B0F;
1953 r300
->hw
.unk46A4
.cmd
[4] = 0x00001B0F;
1954 r300
->hw
.unk46A4
.cmd
[5] = 0x00000001;
1957 for(i
= 1; i
<= 64; ++i
) {
1958 /* create NOP instructions */
1959 r300
->hw
.fpi
[0].cmd
[i
] = FP_INSTRC(MAD
, FP_ARGC(SRC0C_XYZ
), FP_ARGC(ONE
), FP_ARGC(ZERO
));
1960 r300
->hw
.fpi
[1].cmd
[i
] = FP_SELC(0,XYZ
,NO
,FP_TMP(0),0,0);
1961 r300
->hw
.fpi
[2].cmd
[i
] = FP_INSTRA(MAD
, FP_ARGA(SRC0A
), FP_ARGA(ONE
), FP_ARGA(ZERO
));
1962 r300
->hw
.fpi
[3].cmd
[i
] = FP_SELA(0,W
,NO
,FP_TMP(0),0,0);
1966 r300
->hw
.unk4BC0
.cmd
[1] = 0;
1968 r300
->hw
.unk4BC8
.cmd
[1] = 0;
1969 r300
->hw
.unk4BC8
.cmd
[2] = 0;
1970 r300
->hw
.unk4BC8
.cmd
[3] = 0;
1973 r300
->hw
.at
.cmd
[R300_AT_ALPHA_TEST
] = 0;
1976 r300
->hw
.at
.cmd
[R300_AT_UNKNOWN
] = 0;
1977 r300
->hw
.unk4BD8
.cmd
[1] = 0;
1979 r300
->hw
.unk4E00
.cmd
[1] = 0;
1982 r300
->hw
.bld
.cmd
[R300_BLD_CBLEND
] = 0;
1983 r300
->hw
.bld
.cmd
[R300_BLD_ABLEND
] = 0;
1986 r300
->hw
.unk4E10
.cmd
[1] = 0;
1987 r300
->hw
.unk4E10
.cmd
[2] = 0;
1988 r300
->hw
.unk4E10
.cmd
[3] = 0;
1990 r300
->hw
.cb
.cmd
[R300_CB_OFFSET
] =
1991 r300
->radeon
.radeonScreen
->backOffset
+
1992 r300
->radeon
.radeonScreen
->fbLocation
;
1993 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] = r300
->radeon
.radeonScreen
->backPitch
1994 | R300_COLOR_UNKNOWN_22_23
;
1996 r300
->hw
.unk4E50
.cmd
[1] = 0;
1997 r300
->hw
.unk4E50
.cmd
[2] = 0;
1998 r300
->hw
.unk4E50
.cmd
[3] = 0;
1999 r300
->hw
.unk4E50
.cmd
[4] = 0;
2000 r300
->hw
.unk4E50
.cmd
[5] = 0;
2001 r300
->hw
.unk4E50
.cmd
[6] = 0;
2002 r300
->hw
.unk4E50
.cmd
[7] = 0;
2003 r300
->hw
.unk4E50
.cmd
[8] = 0;
2004 r300
->hw
.unk4E50
.cmd
[9] = 0;
2006 r300
->hw
.unk4E88
.cmd
[1] = 0;
2008 r300
->hw
.unk4EA0
.cmd
[1] = 0x00000000;
2009 r300
->hw
.unk4EA0
.cmd
[2] = 0xffffffff;
2011 r300
->hw
.unk4F10
.cmd
[1] = 0x00000002; // depthbuffer format?
2012 r300
->hw
.unk4F10
.cmd
[2] = 0x00000000;
2013 r300
->hw
.unk4F10
.cmd
[3] = 0x00000003;
2014 r300
->hw
.unk4F10
.cmd
[4] = 0x00000000;
2016 /* experiment a bit */
2017 r300
->hw
.unk4F10
.cmd
[2] = 0x00000001; // depthbuffer format?
2019 r300
->hw
.zb
.cmd
[R300_ZB_OFFSET
] =
2020 r300
->radeon
.radeonScreen
->depthOffset
+
2021 r300
->radeon
.radeonScreen
->fbLocation
;
2022 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] = r300
->radeon
.radeonScreen
->depthPitch
;
2024 r300
->hw
.unk4F28
.cmd
[1] = 0;
2026 r300
->hw
.unk4F30
.cmd
[1] = 0;
2027 r300
->hw
.unk4F30
.cmd
[2] = 0;
2029 r300
->hw
.unk4F44
.cmd
[1] = 0;
2031 r300
->hw
.unk4F54
.cmd
[1] = 0;
2034 ((drm_r300_cmd_header_t
*)r300
->hw
.vpi
.cmd
)->vpu
.count
= 0;
2035 for(i
= 1; i
< R300_VPI_CMDSIZE
; i
+= 4) {
2037 r300
->hw
.vpi
.cmd
[i
+0] = VP_OUT(ADD
,TMP
,0,XYZW
);
2038 r300
->hw
.vpi
.cmd
[i
+1] = VP_IN(TMP
,0);
2039 r300
->hw
.vpi
.cmd
[i
+2] = VP_ZERO();
2040 r300
->hw
.vpi
.cmd
[i
+3] = VP_ZERO();
2043 ((drm_r300_cmd_header_t
*)r300
->hw
.vpp
.cmd
)->vpu
.count
= 0;
2044 for(i
= 1; i
< R300_VPP_CMDSIZE
; ++i
)
2045 r300
->hw
.vpp
.cmd
[i
] = 0;
2048 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_0
] = 0;
2049 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_1
] = 0;
2050 r300
->hw
.vps
.cmd
[R300_VPS_POINTSIZE
] = r300PackFloat32(1.0);
2051 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_3
] = 0;
2055 r300
->hw
.all_dirty
= GL_TRUE
;
2061 * Calculate initial hardware state and register state functions.
2062 * Assumes that the command buffer and state atoms have been
2063 * initialized already.
2065 void r300InitState(r300ContextPtr r300
)
2067 GLcontext
*ctx
= r300
->radeon
.glCtx
;
2070 radeonInitState(&r300
->radeon
);
2072 switch (ctx
->Visual
.depthBits
) {
2074 r300
->state
.depth
.scale
= 1.0 / (GLfloat
) 0xffff;
2075 depth_fmt
= R200_DEPTH_FORMAT_16BIT_INT_Z
;
2076 //r300->state.stencil.clear = 0x00000000;
2079 r300
->state
.depth
.scale
= 1.0 / (GLfloat
) 0xffffff;
2080 depth_fmt
= R200_DEPTH_FORMAT_24BIT_INT_Z
;
2081 //r300->state.stencil.clear = 0xff000000;
2084 fprintf(stderr
, "Error: Unsupported depth %d... exiting\n",
2085 ctx
->Visual
.depthBits
);
2089 /* Only have hw stencil when depth buffer is 24 bits deep */
2090 r300
->state
.hw_stencil
= (ctx
->Visual
.stencilBits
> 0 &&
2091 ctx
->Visual
.depthBits
== 24);
2093 memset(&(r300
->state
.texture
), 0, sizeof(r300
->state
.texture
));
2095 r300ResetHwState(r300
);
2100 * Initialize driver's state callback functions
2102 void r300InitStateFuncs(struct dd_function_table
* functions
)
2104 radeonInitStateFuncs(functions
);
2106 functions
->UpdateState
= r300InvalidateState
;
2107 functions
->AlphaFunc
= r300AlphaFunc
;
2108 functions
->BlendColor
= r300BlendColor
;
2109 functions
->BlendEquationSeparate
= r300BlendEquationSeparate
;
2110 functions
->BlendFuncSeparate
= r300BlendFuncSeparate
;
2111 functions
->Enable
= r300Enable
;
2112 functions
->ColorMask
= r300ColorMask
;
2113 functions
->DepthFunc
= r300DepthFunc
;
2114 functions
->DepthMask
= r300DepthMask
;
2115 functions
->CullFace
= r300CullFace
;
2116 functions
->FrontFace
= r300FrontFace
;
2118 /* Stencil related */
2119 functions
->ClearStencil
= r300ClearStencil
;
2120 functions
->StencilFunc
= r300StencilFunc
;
2121 functions
->StencilMask
= r300StencilMask
;
2122 functions
->StencilOp
= r300StencilOp
;
2124 /* Viewport related */
2125 functions
->Viewport
= r300Viewport
;
2126 functions
->DepthRange
= r300DepthRange
;
2127 functions
->PointSize
= r300PointSize
;
2128 functions
->LineWidth
= r300LineWidth
;
2130 functions
->PolygonOffset
= r300PolygonOffset
;
2131 functions
->PolygonMode
= r300PolygonMode
;