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);
501 case GL_POLYGON_OFFSET_FILL:
502 R300_STATECHANGE(r300, unk42B4);
504 r300->hw.unk42B4.cmd[1] = (1<<1);
506 r300->hw.unk42B4.cmd[1] = 0;
509 case GL_VERTEX_PROGRAM_ARB:
510 //TCL_FALLBACK(rmesa->glCtx, R200_TCL_FALLBACK_TCL_DISABLE, state);
514 radeonEnable(ctx, cap, state);
521 * Change the culling mode.
523 * \note Mesa already filters redundant calls to this function.
525 static void r300CullFace(GLcontext* ctx, GLenum mode)
529 r300UpdateCulling(ctx);
534 * Change the polygon orientation.
536 * \note Mesa already filters redundant calls to this function.
538 static void r300FrontFace(GLcontext* ctx, GLenum mode)
542 r300UpdateCulling(ctx);
547 * Change the depth testing function.
549 * \note Mesa already filters redundant calls to this function.
551 static void r300DepthFunc(GLcontext* ctx, GLenum func)
553 r300ContextPtr r300 = R300_CONTEXT(ctx);
555 R300_STATECHANGE(r300, zs);
557 r300->hw.zs.cmd[R300_ZS_CNTL_1] &= ~(R300_ZS_MASK << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT);
561 r300->hw.zs.cmd[R300_ZS_CNTL_1] |= R300_ZS_NEVER << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT;
564 r300->hw.zs.cmd[R300_ZS_CNTL_1] |= R300_ZS_LESS << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT;
567 r300->hw.zs.cmd[R300_ZS_CNTL_1] |= R300_ZS_EQUAL << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT;
570 r300->hw.zs.cmd[R300_ZS_CNTL_1] |= R300_ZS_LEQUAL << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT;
573 r300->hw.zs.cmd[R300_ZS_CNTL_1] |= R300_ZS_GREATER << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT;
576 r300->hw.zs.cmd[R300_ZS_CNTL_1] |= R300_ZS_NOTEQUAL << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT;
579 r300->hw.zs.cmd[R300_ZS_CNTL_1] |= R300_ZS_GEQUAL << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT;
582 r300->hw.zs.cmd[R300_ZS_CNTL_1] |= R300_ZS_ALWAYS << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT;
590 * Enable/Disable depth writing.
592 * \note Mesa already filters redundant calls to this function.
594 static void r300DepthMask(GLcontext* ctx, GLboolean mask)
596 r300ContextPtr r300 = R300_CONTEXT(ctx);
598 if (!ctx->Depth.Test)
601 R300_STATECHANGE(r300, zs);
602 r300->hw.zs.cmd[R300_ZS_CNTL_0] = mask
603 ? R300_RB3D_Z_TEST_AND_WRITE : R300_RB3D_Z_TEST;
608 * Handle glColorMask()
610 static void r300ColorMask(GLcontext* ctx,
611 GLboolean r, GLboolean g, GLboolean b, GLboolean a)
613 r300ContextPtr r300 = R300_CONTEXT(ctx);
614 int mask = (b << 0) | (g << 1) | (r << 2) | (a << 3);
616 if (mask != r300->hw.cmk.cmd[R300_CMK_COLORMASK]) {
617 R300_STATECHANGE(r300, cmk);
618 r300->hw.cmk.cmd[R300_CMK_COLORMASK] = mask;
622 /* =============================================================
625 static void r300PointSize(GLcontext * ctx, GLfloat size)
627 r300ContextPtr r300 = R300_CONTEXT(ctx);
629 /* This might need fixing later */
630 R300_STATECHANGE(r300, vps);
631 r300->hw.vps.cmd[R300_VPS_POINTSIZE] = r300PackFloat32(1.0);
633 /* =============================================================
637 static int translate_stencil_func(int func)
641 return R300_ZS_NEVER;
647 return R300_ZS_EQUAL;
650 return R300_ZS_LEQUAL;
653 return R300_ZS_GREATER;
656 return R300_ZS_NOTEQUAL;
659 return R300_ZS_GEQUAL;
662 return R300_ZS_ALWAYS;
668 static int translate_stencil_op(int op)
676 return R300_ZS_REPLACE;
681 case GL_INCR_WRAP_EXT:
682 return R300_ZS_INCR_WRAP;
683 case GL_DECR_WRAP_EXT:
684 return R300_ZS_DECR_WRAP;
686 return R300_ZS_INVERT;
688 WARN_ONCE("Do not know how to translate stencil op");
693 static void r300StencilFunc(GLcontext * ctx, GLenum func,
694 GLint ref, GLuint mask)
696 r300ContextPtr rmesa = R300_CONTEXT(ctx);
697 GLuint refmask = ((ctx->Stencil.Ref[0] << R300_RB3D_ZS2_STENCIL_REF_SHIFT) |
699 ValueMask[0] << R300_RB3D_ZS2_STENCIL_MASK_SHIFT));
702 R200_STATECHANGE(rmesa, zs);
704 rmesa->hw.zs.cmd[R300_ZS_CNTL_1] &= ~(
705 (R300_ZS_MASK << R300_RB3D_ZS1_FRONT_FUNC_SHIFT)
706 | (R300_ZS_MASK << R300_RB3D_ZS1_BACK_FUNC_SHIFT));
707 rmesa->hw.zs.cmd[R300_ZS_CNTL_2] &= ~((R300_ZS_MASK << R300_RB3D_ZS2_STENCIL_REF_SHIFT) |
708 (R300_ZS_MASK << R300_RB3D_ZS2_STENCIL_MASK_SHIFT));
710 flag = translate_stencil_func(ctx->Stencil.Function[0]);
712 rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= (flag << R300_RB3D_ZS1_FRONT_FUNC_SHIFT)
713 | (flag << R300_RB3D_ZS1_BACK_FUNC_SHIFT);
714 rmesa->hw.zs.cmd[R300_ZS_CNTL_2] |= refmask;
717 static void r300StencilMask(GLcontext * ctx, GLuint mask)
719 r300ContextPtr rmesa = R300_CONTEXT(ctx);
721 R200_STATECHANGE(rmesa, zs);
722 rmesa->hw.zs.cmd[R300_ZS_CNTL_2] &= ~(R300_ZS_MASK << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT);
723 rmesa->hw.zs.cmd[R300_ZS_CNTL_2] |= ctx->Stencil.WriteMask[0] << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT;
727 static void r300StencilOp(GLcontext * ctx, GLenum fail,
728 GLenum zfail, GLenum zpass)
730 r300ContextPtr rmesa = R300_CONTEXT(ctx);
732 R200_STATECHANGE(rmesa, zs);
733 /* It is easier to mask what's left.. */
734 rmesa->hw.zs.cmd[R300_ZS_CNTL_1] &= (R300_ZS_MASK << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT);
736 rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=
737 (translate_stencil_op(ctx->Stencil.FailFunc[0]) << R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT)
738 |(translate_stencil_op(ctx->Stencil.ZFailFunc[0]) << R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT)
739 |(translate_stencil_op(ctx->Stencil.ZPassFunc[0]) << R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT)
740 |(translate_stencil_op(ctx->Stencil.FailFunc[0]) << R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT)
741 |(translate_stencil_op(ctx->Stencil.ZFailFunc[0]) << R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT)
742 |(translate_stencil_op(ctx->Stencil.ZPassFunc[0]) << R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT);
746 static void r300ClearStencil(GLcontext * ctx, GLint s)
748 r300ContextPtr rmesa = R300_CONTEXT(ctx);
750 /* Not sure whether this is correct.. */
751 R200_STATECHANGE(rmesa, zs);
752 rmesa->hw.zs.cmd[R300_ZS_CNTL_2] =
753 ((GLuint) ctx->Stencil.Clear |
754 (0xff << R200_STENCIL_MASK_SHIFT) |
755 (ctx->Stencil.WriteMask[0] << R200_STENCIL_WRITEMASK_SHIFT));
758 /* =============================================================
759 * Window position and viewport transformation
763 * To correctly position primitives:
765 #define SUBPIXEL_X 0.125
766 #define SUBPIXEL_Y 0.125
768 void r300UpdateWindow(GLcontext * ctx)
770 r300ContextPtr rmesa = R300_CONTEXT(ctx);
771 __DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable;
772 GLfloat xoffset = dPriv ? (GLfloat) dPriv->x : 0;
773 GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0;
774 const GLfloat *v = ctx->Viewport._WindowMap.m;
776 GLfloat sx = v[MAT_SX];
777 GLfloat tx = v[MAT_TX] + xoffset + SUBPIXEL_X;
778 GLfloat sy = -v[MAT_SY];
779 GLfloat ty = (-v[MAT_TY]) + yoffset + SUBPIXEL_Y;
780 GLfloat sz = v[MAT_SZ] * rmesa->state.depth.scale;
781 GLfloat tz = v[MAT_TZ] * rmesa->state.depth.scale;
783 R300_FIREVERTICES(rmesa);
784 R300_STATECHANGE(rmesa, vpt);
786 rmesa->hw.vpt.cmd[R300_VPT_XSCALE] = r300PackFloat32(sx);
787 rmesa->hw.vpt.cmd[R300_VPT_XOFFSET] = r300PackFloat32(tx);
788 rmesa->hw.vpt.cmd[R300_VPT_YSCALE] = r300PackFloat32(sy);
789 rmesa->hw.vpt.cmd[R300_VPT_YOFFSET] = r300PackFloat32(ty);
790 rmesa->hw.vpt.cmd[R300_VPT_ZSCALE] = r300PackFloat32(sz);
791 rmesa->hw.vpt.cmd[R300_VPT_ZOFFSET] = r300PackFloat32(tz);
794 static void r300Viewport(GLcontext * ctx, GLint x, GLint y,
795 GLsizei width, GLsizei height)
797 /* Don't pipeline viewport changes, conflict with window offset
798 * setting below. Could apply deltas to rescue pipelined viewport
799 * values, or keep the originals hanging around.
801 R200_FIREVERTICES(R200_CONTEXT(ctx));
802 r300UpdateWindow(ctx);
805 static void r300DepthRange(GLcontext * ctx, GLclampd nearval, GLclampd farval)
807 r300UpdateWindow(ctx);
810 /* =============================================================
814 static void r300PolygonOffset(GLcontext * ctx, GLfloat factor, GLfloat units)
816 r300ContextPtr rmesa = R300_CONTEXT(ctx);
817 GLfloat constant = units * rmesa->state.depth.scale;
822 /* fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */
824 WARN_ONCE("ZBIAS registers locations might not be correct\n");
826 R200_STATECHANGE(rmesa, zbs);
827 rmesa->hw.zbs.cmd[R300_ZBS_FACTOR] = r300PackFloat32(factor);
828 rmesa->hw.zbs.cmd[R300_ZBS_CONSTANT] = r300PackFloat32(constant);
832 /* Routing and texture-related */
834 void r300_setup_routing(GLcontext *ctx, GLboolean immediate)
836 int i, count=0,reg=0;
838 TNLcontext *tnl = TNL_CONTEXT(ctx);
839 struct vertex_buffer *VB = &tnl->vb;
840 r300ContextPtr r300 = R300_CONTEXT(ctx);
843 /* Stage 1 - input to VAP */
845 /* Assign register number automatically, retaining it in rmesa->state.reg */
847 /* Note: immediate vertex data includes all coordinates.
848 To save bandwidth use either VBUF or state-based vertex generation */
850 #define CONFIGURE_AOS(v, o, r, f) \
852 if (RADEON_DEBUG & DEBUG_STATE)fprintf(stderr, "Enabling "#r "\n"); \
854 r300->state.aos[count].element_size=4; \
855 r300->state.aos[count].stride=4; \
856 r300->state.aos[count].ncomponents=4; \
858 r300->state.aos[count].element_size=v->size; \
859 r300->state.aos[count].stride=v->size; \
860 r300->state.aos[count].ncomponents=v->size; \
862 r300->state.aos[count].offset=o; \
863 r300->state.aos[count].reg=reg; \
864 r300->state.aos[count].format=(f); \
865 r300->state.vap_reg.r=reg; \
870 /* All offsets are 0 - for use by immediate mode.
871 Should change later to handle vertex buffers */
872 if(r300->current_vp){
874 /* VERT_ATTRIB_WEIGHT, VERT_ATTRIB_SIX, VERT_ATTRIB_SEVEN, VERT_ATTRIB_GENERIC0,
875 VERT_ATTRIB_GENERIC1, VERT_ATTRIB_GENERIC2, VERT_ATTRIB_GENERIC3 */
877 if(r300->current_vp->inputs[VERT_ATTRIB_POS] != -1){
878 if(tnl->render_inputs & _TNL_BIT_POS){
879 reg=r300->current_vp->inputs[VERT_ATTRIB_POS];
880 CONFIGURE_AOS(VB->ObjPtr, 0, i_coords, AOS_FORMAT_FLOAT);
881 }else WARN_ONCE("vp expects pos but none was given\n");
883 if(r300->current_vp->inputs[VERT_ATTRIB_NORMAL] != -1){
884 if(tnl->render_inputs & _TNL_BIT_NORMAL){
885 reg=r300->current_vp->inputs[VERT_ATTRIB_NORMAL];
886 CONFIGURE_AOS(VB->NormalPtr, 0, i_normal, AOS_FORMAT_FLOAT);
887 }else WARN_ONCE("vp expects normal but none was given\n");
889 if(r300->current_vp->inputs[VERT_ATTRIB_COLOR0] != -1){
890 if(tnl->render_inputs & _TNL_BIT_COLOR0){
891 reg=r300->current_vp->inputs[VERT_ATTRIB_COLOR0];
892 CONFIGURE_AOS(VB->ColorPtr[0], 0, i_color[0], AOS_FORMAT_FLOAT_COLOR);
893 }else WARN_ONCE("vp expects primary color but none was given\n");
895 if(r300->current_vp->inputs[VERT_ATTRIB_COLOR1] != -1){
896 if(tnl->render_inputs & _TNL_BIT_COLOR1){
897 reg=r300->current_vp->inputs[VERT_ATTRIB_COLOR1];
898 CONFIGURE_AOS(VB->SecondaryColorPtr[0], 0, i_color[1], AOS_FORMAT_FLOAT_COLOR);
899 }else WARN_ONCE("vp expects secondary color but none was given\n");
901 if(r300->current_vp->inputs[VERT_ATTRIB_FOG] != -1){
902 if(tnl->render_inputs & _TNL_BIT_FOG){
903 reg=r300->current_vp->inputs[VERT_ATTRIB_FOG];
904 CONFIGURE_AOS(VB->FogCoordPtr, 0, i_fog, AOS_FORMAT_FLOAT);
905 }else WARN_ONCE("vp expects fog but none was given\n");
907 for(i=0;i < ctx->Const.MaxTextureUnits;i++) // tex 7 is last
908 if(r300->current_vp->inputs[VERT_ATTRIB_TEX0+i] != -1){
909 if(tnl->render_inputs & (_TNL_BIT_TEX0<<i)){
910 reg=r300->current_vp->inputs[VERT_ATTRIB_TEX0+i];
911 CONFIGURE_AOS(VB->TexCoordPtr[i], 0, i_tex[i], AOS_FORMAT_FLOAT);
912 }else fprintf(stderr, "vp expects tex%d but none was given\n", i);
915 if((tnl->render_inputs & _TNL_BIT_INDEX))
916 CONFIGURE_AOS(VB->IndexPtr[0], 0, i_index, AOS_FORMAT_FLOAT);
918 if((tnl->render_inputs & _TNL_BIT_POINTSIZE))
919 CONFIGURE_AOS(VB->PointSizePtr, 0, i_pointsize, AOS_FORMAT_FLOAT);
923 if(tnl->render_inputs & _TNL_BIT_POS)
924 CONFIGURE_AOS(VB->ObjPtr, 0, i_coords, AOS_FORMAT_FLOAT);
925 if(tnl->render_inputs & _TNL_BIT_NORMAL)
926 CONFIGURE_AOS(VB->NormalPtr, 0, i_normal, AOS_FORMAT_FLOAT);
928 if(tnl->render_inputs & _TNL_BIT_COLOR0)
929 CONFIGURE_AOS(VB->ColorPtr[0], 0, i_color[0], AOS_FORMAT_FLOAT_COLOR);
930 if(tnl->render_inputs & _TNL_BIT_COLOR1)
931 CONFIGURE_AOS(VB->SecondaryColorPtr[0], 0, i_color[1], AOS_FORMAT_FLOAT_COLOR);
933 if(tnl->render_inputs & _TNL_BIT_FOG)
934 CONFIGURE_AOS(VB->FogCoordPtr, 0, i_fog, AOS_FORMAT_FLOAT);
936 for(i=0;i < ctx->Const.MaxTextureUnits;i++)
937 if(tnl->render_inputs & (_TNL_BIT_TEX0<<i))
938 CONFIGURE_AOS(VB->TexCoordPtr[i], 0, i_tex[i], AOS_FORMAT_FLOAT);
940 if(tnl->render_inputs & _TNL_BIT_INDEX)
941 CONFIGURE_AOS(VB->IndexPtr[0], 0, i_index, AOS_FORMAT_FLOAT);
942 if(tnl->render_inputs & _TNL_BIT_POINTSIZE)
943 CONFIGURE_AOS(VB->PointSizePtr, 0, i_pointsize, AOS_FORMAT_FLOAT);
946 r300->state.aos_count=count;
948 if (RADEON_DEBUG & DEBUG_STATE)
949 fprintf(stderr, "aos_count=%d\n", count);
951 if(count>R300_MAX_AOS_ARRAYS){
952 fprintf(stderr, "Aieee ! AOS array count exceeded !\n");
958 /* setup INPUT_ROUTE */
959 R300_STATECHANGE(r300, vir[0]);
960 for(i=0;i+1<count;i+=2){
961 dw=(r300->state.aos[i].ncomponents-1)
962 | ((r300->state.aos[i].reg)<<8)
963 | (r300->state.aos[i].format<<14)
964 | (((r300->state.aos[i+1].ncomponents-1)
965 | ((r300->state.aos[i+1].reg)<<8)
966 | (r300->state.aos[i+1].format<<14))<<16);
971 r300->hw.vir[0].cmd[R300_VIR_CNTL_0+(i>>1)]=dw;
974 dw=(r300->state.aos[count-1].ncomponents-1)
975 | (r300->state.aos[count-1].format<<14)
976 | ((r300->state.aos[count-1].reg)<<8)
978 r300->hw.vir[0].cmd[R300_VIR_CNTL_0+(count>>1)]=dw;
979 //fprintf(stderr, "vir0 dw=%08x\n", dw);
981 /* Set the rest of INPUT_ROUTE_0 to 0 */
982 //for(i=((count+1)>>1); i<8; i++)r300->hw.vir[0].cmd[R300_VIR_CNTL_0+i]=(0x0);
983 ((drm_r300_cmd_header_t*)r300->hw.vir[0].cmd)->unchecked_state.count = (count+1)>>1;
986 /* Mesa assumes that all missing components are from (0, 0, 0, 1) */
987 #define ALL_COMPONENTS ((R300_INPUT_ROUTE_SELECT_X<<R300_INPUT_ROUTE_X_SHIFT) \
988 | (R300_INPUT_ROUTE_SELECT_Y<<R300_INPUT_ROUTE_Y_SHIFT) \
989 | (R300_INPUT_ROUTE_SELECT_Z<<R300_INPUT_ROUTE_Z_SHIFT) \
990 | (R300_INPUT_ROUTE_SELECT_W<<R300_INPUT_ROUTE_W_SHIFT))
992 #define ALL_DEFAULT ((R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_X_SHIFT) \
993 | (R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_Y_SHIFT) \
994 | (R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_Z_SHIFT) \
995 | (R300_INPUT_ROUTE_SELECT_ONE<<R300_INPUT_ROUTE_W_SHIFT))
997 R300_STATECHANGE(r300, vir[1]);
999 for(i=0;i+1<count;i+=2){
1001 mask=(1<<(r300->state.aos[i].ncomponents*3))-1;
1002 dw=(ALL_COMPONENTS & mask)
1003 | (ALL_DEFAULT & ~mask)
1004 | R300_INPUT_ROUTE_ENABLE;
1007 mask=(1<<(r300->state.aos[i+1].ncomponents*3))-1;
1009 (ALL_COMPONENTS & mask)
1010 | (ALL_DEFAULT & ~mask)
1011 | R300_INPUT_ROUTE_ENABLE
1014 r300->hw.vir[1].cmd[R300_VIR_CNTL_0+(i>>1)]=dw;
1017 mask=(1<<(r300->state.aos[count-1].ncomponents*3))-1;
1018 dw=(ALL_COMPONENTS & mask)
1019 | (ALL_DEFAULT & ~mask)
1020 | R300_INPUT_ROUTE_ENABLE;
1021 r300->hw.vir[1].cmd[R300_VIR_CNTL_0+(count>>1)]=dw;
1022 //fprintf(stderr, "vir1 dw=%08x\n", dw);
1024 /* Set the rest of INPUT_ROUTE_1 to 0 */
1025 //for(i=((count+1)>>1); i<8; i++)r300->hw.vir[1].cmd[R300_VIR_CNTL_0+i]=0x0;
1026 ((drm_r300_cmd_header_t*)r300->hw.vir[1].cmd)->unchecked_state.count = (count+1)>>1;
1028 /* Set up input_cntl */
1030 R300_STATECHANGE(r300, vic);
1031 r300->hw.vic.cmd[R300_VIC_CNTL_0]=0x5555; /* Hard coded value, no idea what it means */
1033 r300->hw.vic.cmd[R300_VIC_CNTL_1]=R300_INPUT_CNTL_POS
1034 | R300_INPUT_CNTL_COLOR;
1036 for(i=0;i < ctx->Const.MaxTextureUnits;i++)
1037 if(ctx->Texture.Unit[i].Enabled)
1038 r300->hw.vic.cmd[R300_VIC_CNTL_1]|=(R300_INPUT_CNTL_TC0<<i);
1040 /* Stage 3: VAP output */
1041 R300_STATECHANGE(r300, vof);
1042 r300->hw.vof.cmd[R300_VOF_CNTL_0]=R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
1043 | R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT;
1045 r300->hw.vof.cmd[R300_VOF_CNTL_1]=0;
1046 for(i=0;i < ctx->Const.MaxTextureUnits;i++)
1047 if(ctx->Texture.Unit[i].Enabled)
1048 r300->hw.vof.cmd[R300_VOF_CNTL_1]|=(4<<(3*i));
1052 static r300TexObj default_tex_obj={
1053 filter:R300_TX_MAG_FILTER_LINEAR | R300_TX_MIN_FILTER_LINEAR,
1055 size: (0xff << R300_TX_WIDTHMASK_SHIFT)
1056 | (0xff << R300_TX_HEIGHTMASK_SHIFT)
1057 | (0x8 << R300_TX_SIZE_SHIFT),
1064 /* there is probably a system to these value, but, for now,
1065 we just try by hand */
1067 static int inline translate_src(int src)
1076 case GL_PRIMARY_COLOR:
1093 /* r300 doesnt handle GL_CLAMP and GL_MIRROR_CLAMP_EXT correctly when filter is NEAREST.
1094 * Since texwrap produces same results for GL_CLAMP and GL_CLAMP_TO_EDGE we use them instead.
1095 * We need to recalculate wrap modes whenever filter mode is changed because someone might do:
1096 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1097 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1098 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1099 * Since r300 completely ignores R300_TX_CLAMP when either min or mag is nearest it cant handle
1100 * combinations where only one of them is nearest.
1102 static unsigned long gen_fixed_filter(unsigned long f)
1104 unsigned long mag, min, needs_fixing=0;
1107 /* We ignore MIRROR bit so we dont have to do everything twice */
1108 if((f & ((7-1) << R300_TX_WRAP_S_SHIFT)) == (R300_TX_CLAMP << R300_TX_WRAP_S_SHIFT)){
1111 if((f & ((7-1) << R300_TX_WRAP_T_SHIFT)) == (R300_TX_CLAMP << R300_TX_WRAP_T_SHIFT)){
1114 if((f & ((7-1) << R300_TX_WRAP_Q_SHIFT)) == (R300_TX_CLAMP << R300_TX_WRAP_Q_SHIFT)){
1121 mag=f & R300_TX_MAG_FILTER_MASK;
1122 min=f & R300_TX_MIN_FILTER_MASK;
1124 /* TODO: Check for anisto filters too */
1125 if((mag != R300_TX_MAG_FILTER_NEAREST) && (min != R300_TX_MIN_FILTER_NEAREST))
1128 /* r300 cant handle these modes hence we force nearest to linear */
1129 if((mag == R300_TX_MAG_FILTER_NEAREST) && (min != R300_TX_MIN_FILTER_NEAREST)){
1130 f &= ~R300_TX_MAG_FILTER_NEAREST;
1131 f |= R300_TX_MAG_FILTER_LINEAR;
1135 if((min == R300_TX_MIN_FILTER_NEAREST) && (mag != R300_TX_MAG_FILTER_NEAREST)){
1136 f &= ~R300_TX_MIN_FILTER_NEAREST;
1137 f |= R300_TX_MIN_FILTER_LINEAR;
1141 /* Both are nearest */
1142 if(needs_fixing & 1){
1143 f &= ~((7-1) << R300_TX_WRAP_S_SHIFT);
1144 f |= R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_S_SHIFT;
1146 if(needs_fixing & 2){
1147 f &= ~((7-1) << R300_TX_WRAP_T_SHIFT);
1148 f |= R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_T_SHIFT;
1150 if(needs_fixing & 4){
1151 f &= ~((7-1) << R300_TX_WRAP_Q_SHIFT);
1152 f |= R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_Q_SHIFT;
1157 void r300_setup_textures(GLcontext *ctx)
1160 struct r300_tex_obj *t;
1161 r300ContextPtr r300 = R300_CONTEXT(ctx);
1162 int max_texture_unit=-1; /* -1 translates into no setup costs for fields */
1163 struct gl_texture_unit *texUnit;
1165 R300_STATECHANGE(r300, txe);
1166 R300_STATECHANGE(r300, tex.filter);
1167 R300_STATECHANGE(r300, tex.unknown1);
1168 R300_STATECHANGE(r300, tex.size);
1169 R300_STATECHANGE(r300, tex.format);
1170 R300_STATECHANGE(r300, tex.offset);
1171 R300_STATECHANGE(r300, tex.unknown4);
1172 R300_STATECHANGE(r300, tex.unknown5);
1173 //R300_STATECHANGE(r300, tex.border_color);
1175 r300->state.texture.tc_count=0;
1177 r300->hw.txe.cmd[R300_TXE_ENABLE]=0x0;
1179 mtu = r300->radeon.glCtx->Const.MaxTextureUnits;
1180 if (RADEON_DEBUG & DEBUG_STATE)
1181 fprintf(stderr, "mtu=%d\n", mtu);
1183 if(mtu>R300_MAX_TEXTURE_UNITS){
1184 fprintf(stderr, "Aiiee ! mtu=%d is greater than R300_MAX_TEXTURE_UNITS=%d\n",
1185 mtu, R300_MAX_TEXTURE_UNITS);
1189 if(ctx->Texture.Unit[i].Enabled){
1190 t=r300->state.texture.unit[i].texobj;
1191 //fprintf(stderr, "format=%08x\n", r300->state.texture.unit[i].format);
1192 r300->state.texture.tc_count++;
1194 fprintf(stderr, "Texture unit %d enabled, but corresponding texobj is NULL, using default object.\n", i);
1198 //fprintf(stderr, "t->format=%08x\n", t->format);
1199 if (RADEON_DEBUG & DEBUG_STATE)
1200 fprintf(stderr, "Activating texture unit %d\n", i);
1202 r300->hw.txe.cmd[R300_TXE_ENABLE]|=(1<<i);
1204 r300->hw.tex.filter.cmd[R300_TEX_VALUE_0+i]=gen_fixed_filter(t->filter);
1205 /* No idea why linear filtered textures shake when puting random data */
1206 /*r300->hw.tex.unknown1.cmd[R300_TEX_VALUE_0+i]=(rand()%0xffffffff) & (~0x1fff);*/
1207 r300->hw.tex.size.cmd[R300_TEX_VALUE_0+i]=t->size;
1208 r300->hw.tex.format.cmd[R300_TEX_VALUE_0+i]=t->format;
1209 //fprintf(stderr, "t->format=%08x\n", t->format);
1210 r300->hw.tex.offset.cmd[R300_TEX_VALUE_0+i]=r300->radeon.radeonScreen->fbLocation+t->offset;
1211 r300->hw.tex.unknown4.cmd[R300_TEX_VALUE_0+i]=0x0;
1212 r300->hw.tex.unknown5.cmd[R300_TEX_VALUE_0+i]=0x0;
1213 //r300->hw.tex.border_color.cmd[R300_TEX_VALUE_0+i]=t->pp_border_color;
1216 ((drm_r300_cmd_header_t*)r300->hw.tex.filter.cmd)->unchecked_state.count = max_texture_unit+1;
1217 ((drm_r300_cmd_header_t*)r300->hw.tex.unknown1.cmd)->unchecked_state.count = max_texture_unit+1;
1218 ((drm_r300_cmd_header_t*)r300->hw.tex.size.cmd)->unchecked_state.count = max_texture_unit+1;
1219 ((drm_r300_cmd_header_t*)r300->hw.tex.format.cmd)->unchecked_state.count = max_texture_unit+1;
1220 ((drm_r300_cmd_header_t*)r300->hw.tex.offset.cmd)->unchecked_state.count = max_texture_unit+1;
1221 ((drm_r300_cmd_header_t*)r300->hw.tex.unknown4.cmd)->unchecked_state.count = max_texture_unit+1;
1222 ((drm_r300_cmd_header_t*)r300->hw.tex.unknown5.cmd)->unchecked_state.count = max_texture_unit+1;
1223 //((drm_r300_cmd_header_t*)r300->hw.tex.border_color.cmd)->unchecked_state.count = max_texture_unit+1;
1225 if (RADEON_DEBUG & DEBUG_STATE)
1226 fprintf(stderr, "TX_ENABLE: %08x max_texture_unit=%d\n", r300->hw.txe.cmd[R300_TXE_ENABLE], max_texture_unit);
1229 void r300_setup_rs_unit(GLcontext *ctx)
1231 r300ContextPtr r300 = R300_CONTEXT(ctx);
1234 /* This needs to be rewritten - it is a hack at best */
1236 R300_STATECHANGE(r300, ri);
1237 R300_STATECHANGE(r300, rc);
1238 R300_STATECHANGE(r300, rr);
1240 for(i = 1; i <= 8; ++i)
1241 r300->hw.ri.cmd[i] = 0x00d10000;
1242 r300->hw.ri.cmd[R300_RI_INTERP_1] |= R300_RS_INTERP_1_UNKNOWN;
1243 r300->hw.ri.cmd[R300_RI_INTERP_2] |= R300_RS_INTERP_2_UNKNOWN;
1244 r300->hw.ri.cmd[R300_RI_INTERP_3] |= R300_RS_INTERP_3_UNKNOWN;
1247 for(i = 2; i <= 8; ++i)
1248 r300->hw.ri.cmd[i] |= 4;
1251 for(i = 1; i <= 8; ++i)
1252 r300->hw.rr.cmd[i] = 0;
1253 /* textures enabled ? */
1254 if(r300->state.texture.tc_count>0){
1256 /* This code only really works with one set of texture coordinates */
1258 /* The second constant is needed to get glxgears display anything .. */
1259 r300->hw.rc.cmd[1] = R300_RS_CNTL_0_UNKNOWN_7
1260 | R300_RS_CNTL_0_UNKNOWN_18
1261 | (r300->state.texture.tc_count<<R300_RS_CNTL_TC_CNT_SHIFT);
1262 r300->hw.rc.cmd[2] = 0xc0;
1265 ((drm_r300_cmd_header_t*)r300->hw.rr.cmd)->unchecked_state.count = 1;
1266 r300->hw.rr.cmd[R300_RR_ROUTE_0] = 0x24008;
1270 /* The second constant is needed to get glxgears display anything .. */
1271 r300->hw.rc.cmd[1] = R300_RS_CNTL_0_UNKNOWN_7 | R300_RS_CNTL_0_UNKNOWN_18;
1272 r300->hw.rc.cmd[2] = 0;
1274 ((drm_r300_cmd_header_t*)r300->hw.rr.cmd)->unchecked_state.count = 1;
1275 r300->hw.rr.cmd[R300_RR_ROUTE_0] = 0x4000;
1280 #define vpucount(ptr) (((drm_r300_cmd_header_t*)(ptr))->vpu.count)
1282 #define bump_vpu_count(ptr, new_count) do{\
1283 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
1284 int _nc=(new_count)/4; \
1285 if(_nc>_p->vpu.count)_p->vpu.count=_nc;\
1288 void static inline setup_vertex_shader_fragment(r300ContextPtr r300, int dest, struct r300_vertex_shader_fragment *vsf)
1292 if(vsf->length==0)return;
1294 if(vsf->length & 0x3){
1295 fprintf(stderr,"VERTEX_SHADER_FRAGMENT must have length divisible by 4\n");
1299 switch((dest>>8) & 0xf){
1301 R300_STATECHANGE(r300, vpi);
1302 for(i=0;i<vsf->length;i++)
1303 r300->hw.vpi.cmd[R300_VPI_INSTR_0+i+4*(dest & 0xff)]=(vsf->body.d[i]);
1304 bump_vpu_count(r300->hw.vpi.cmd, vsf->length+4*(dest & 0xff));
1308 R300_STATECHANGE(r300, vpp);
1309 for(i=0;i<vsf->length;i++)
1310 r300->hw.vpp.cmd[R300_VPP_PARAM_0+i+4*(dest & 0xff)]=(vsf->body.d[i]);
1311 bump_vpu_count(r300->hw.vpp.cmd, vsf->length+4*(dest & 0xff));
1314 R300_STATECHANGE(r300, vps);
1315 for(i=0;i<vsf->length;i++)
1316 r300->hw.vps.cmd[1+i+4*(dest & 0xff)]=(vsf->body.d[i]);
1317 bump_vpu_count(r300->hw.vps.cmd, vsf->length+4*(dest & 0xff));
1320 fprintf(stderr, "%s:%s don't know how to handle dest %04x\n", __FILE__, __FUNCTION__, dest);
1325 void r300SetupVertexProgram(r300ContextPtr rmesa);
1327 void r300SetupVertexShader(r300ContextPtr rmesa)
1329 GLcontext* ctx = rmesa->radeon.glCtx;
1331 if(rmesa->current_vp){
1332 r300SetupVertexProgram(rmesa);
1335 /* Reset state, in case we don't use something */
1336 ((drm_r300_cmd_header_t*)rmesa->hw.vpp.cmd)->vpu.count = 0;
1337 ((drm_r300_cmd_header_t*)rmesa->hw.vpi.cmd)->vpu.count = 0;
1338 ((drm_r300_cmd_header_t*)rmesa->hw.vps.cmd)->vpu.count = 0;
1341 /* This needs to be replaced by vertex shader generation code */
1344 /* textures enabled ? */
1345 if(rmesa->state.texture.tc_count>0){
1346 rmesa->state.vertex_shader=SINGLE_TEXTURE_VERTEX_SHADER;
1348 rmesa->state.vertex_shader=FLAT_COLOR_VERTEX_SHADER;
1352 rmesa->state.vertex_shader.matrix[0].length=16;
1353 memcpy(rmesa->state.vertex_shader.matrix[0].body.f, ctx->_ModelProjectMatrix.m, 16*4);
1355 setup_vertex_shader_fragment(rmesa, VSF_DEST_PROGRAM, &(rmesa->state.vertex_shader.program));
1357 setup_vertex_shader_fragment(rmesa, VSF_DEST_MATRIX0, &(rmesa->state.vertex_shader.matrix[0]));
1359 setup_vertex_shader_fragment(rmesa, VSF_DEST_MATRIX1, &(rmesa->state.vertex_shader.matrix[0]));
1360 setup_vertex_shader_fragment(rmesa, VSF_DEST_MATRIX2, &(rmesa->state.vertex_shader.matrix[0]));
1362 setup_vertex_shader_fragment(rmesa, VSF_DEST_VECTOR0, &(rmesa->state.vertex_shader.vector[0]));
1363 setup_vertex_shader_fragment(rmesa, VSF_DEST_VECTOR1, &(rmesa->state.vertex_shader.vector[1]));
1367 setup_vertex_shader_fragment(rmesa, VSF_DEST_UNKNOWN1, &(rmesa->state.vertex_shader.unknown1));
1368 setup_vertex_shader_fragment(rmesa, VSF_DEST_UNKNOWN2, &(rmesa->state.vertex_shader.unknown2));
1371 R300_STATECHANGE(rmesa, pvs);
1372 rmesa->hw.pvs.cmd[R300_PVS_CNTL_1]=(rmesa->state.vertex_shader.program_start << R300_PVS_CNTL_1_PROGRAM_START_SHIFT)
1373 | (rmesa->state.vertex_shader.unknown_ptr1 << R300_PVS_CNTL_1_UNKNOWN_SHIFT)
1374 | (rmesa->state.vertex_shader.program_end << R300_PVS_CNTL_1_PROGRAM_END_SHIFT);
1375 rmesa->hw.pvs.cmd[R300_PVS_CNTL_2]=(rmesa->state.vertex_shader.param_offset << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT)
1376 | (rmesa->state.vertex_shader.param_count << R300_PVS_CNTL_2_PARAM_COUNT_SHIFT);
1377 rmesa->hw.pvs.cmd[R300_PVS_CNTL_3]=(rmesa->state.vertex_shader.unknown_ptr2 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT)
1378 | (rmesa->state.vertex_shader.unknown_ptr3 << 0);
1380 /* This is done for vertex shader fragments, but also needs to be done for vap_pvs,
1381 so I leave it as a reminder */
1383 reg_start(R300_VAP_PVS_WAITIDLE,0);
1388 void r300SetupVertexProgram(r300ContextPtr rmesa)
1390 GLcontext* ctx = rmesa->radeon.glCtx;
1394 /* Reset state, in case we don't use something */
1395 ((drm_r300_cmd_header_t*)rmesa->hw.vpp.cmd)->vpu.count = 0;
1396 ((drm_r300_cmd_header_t*)rmesa->hw.vpi.cmd)->vpu.count = 0;
1397 ((drm_r300_cmd_header_t*)rmesa->hw.vps.cmd)->vpu.count = 0;
1399 r300VertexProgUpdateParams(ctx, rmesa->current_vp);
1401 setup_vertex_shader_fragment(rmesa, VSF_DEST_PROGRAM, &(rmesa->current_vp->program));
1403 setup_vertex_shader_fragment(rmesa, VSF_DEST_MATRIX0, &(rmesa->current_vp->params));
1406 setup_vertex_shader_fragment(rmesa, VSF_DEST_UNKNOWN1, &(rmesa->state.vertex_shader.unknown1));
1407 setup_vertex_shader_fragment(rmesa, VSF_DEST_UNKNOWN2, &(rmesa->state.vertex_shader.unknown2));
1410 inst_count=rmesa->current_vp->program.length/4 - 1;
1411 param_count=rmesa->current_vp->params.length/4;
1413 R300_STATECHANGE(rmesa, pvs);
1414 rmesa->hw.pvs.cmd[R300_PVS_CNTL_1]=(0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT)
1415 | (inst_count/*0*/ << R300_PVS_CNTL_1_UNKNOWN_SHIFT)
1416 | (inst_count << R300_PVS_CNTL_1_PROGRAM_END_SHIFT);
1417 rmesa->hw.pvs.cmd[R300_PVS_CNTL_2]=(0 << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT)
1418 | (param_count << R300_PVS_CNTL_2_PARAM_COUNT_SHIFT);
1419 rmesa->hw.pvs.cmd[R300_PVS_CNTL_3]=(0/*rmesa->state.vertex_shader.unknown_ptr2*/ << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT)
1420 | ((inst_count-rmesa->current_vp->t2rs) /*rmesa->state.vertex_shader.unknown_ptr3*/ << 0);
1422 /* This is done for vertex shader fragments, but also needs to be done for vap_pvs,
1423 so I leave it as a reminder */
1425 reg_start(R300_VAP_PVS_WAITIDLE,0);
1430 void r300SetupPixelShader(r300ContextPtr rmesa)
1434 /* This needs to be replaced by pixel shader generation code */
1436 /* textures enabled ? */
1437 if(rmesa->state.texture.tc_count>0){
1438 rmesa->state.pixel_shader=SINGLE_TEXTURE_PIXEL_SHADER;
1440 rmesa->state.pixel_shader=FLAT_COLOR_PIXEL_SHADER;
1443 R300_STATECHANGE(rmesa, fpt);
1444 for(i=0;i<rmesa->state.pixel_shader.program.tex.length;i++)
1445 rmesa->hw.fpt.cmd[R300_FPT_INSTR_0+i]=rmesa->state.pixel_shader.program.tex.inst[i];
1446 rmesa->hw.fpt.cmd[R300_FPT_CMD_0]=cmducs(R300_PFS_TEXI_0, rmesa->state.pixel_shader.program.tex.length);
1448 #define OUTPUT_FIELD(st, reg, field) \
1449 R300_STATECHANGE(rmesa, st); \
1450 for(i=0;i<rmesa->state.pixel_shader.program.alu.length;i++) \
1451 rmesa->hw.st.cmd[R300_FPI_INSTR_0+i]=rmesa->state.pixel_shader.program.alu.inst[i].field;\
1452 rmesa->hw.st.cmd[R300_FPI_CMD_0]=cmducs(reg, rmesa->state.pixel_shader.program.alu.length);
1454 OUTPUT_FIELD(fpi[0], R300_PFS_INSTR0_0, inst0);
1455 OUTPUT_FIELD(fpi[1], R300_PFS_INSTR1_0, inst1);
1456 OUTPUT_FIELD(fpi[2], R300_PFS_INSTR2_0, inst2);
1457 OUTPUT_FIELD(fpi[3], R300_PFS_INSTR3_0, inst3);
1460 R300_STATECHANGE(rmesa, fp);
1462 rmesa->hw.fp.cmd[R300_FP_NODE0+i]=
1463 (rmesa->state.pixel_shader.program.node[i].alu_offset << R300_PFS_NODE_ALU_OFFSET_SHIFT)
1464 | (rmesa->state.pixel_shader.program.node[i].alu_end << R300_PFS_NODE_ALU_END_SHIFT)
1465 | (rmesa->state.pixel_shader.program.node[i].tex_offset << R300_PFS_NODE_TEX_OFFSET_SHIFT)
1466 | (rmesa->state.pixel_shader.program.node[i].tex_end << R300_PFS_NODE_TEX_END_SHIFT)
1467 | ( (i==3) ? R300_PFS_NODE_LAST_NODE : 0);
1471 rmesa->hw.fp.cmd[R300_FP_CNTL0]=
1472 (rmesa->state.pixel_shader.program.active_nodes-1)
1473 | (rmesa->state.pixel_shader.program.first_node_has_tex<<3);
1475 rmesa->hw.fp.cmd[R300_FP_CNTL1]=rmesa->state.pixel_shader.program.temp_register_count;
1477 rmesa->hw.fp.cmd[R300_FP_CNTL2]=
1478 (rmesa->state.pixel_shader.program.alu_offset << R300_PFS_CNTL_ALU_OFFSET_SHIFT)
1479 | (rmesa->state.pixel_shader.program.alu_end << R300_PFS_CNTL_ALU_END_SHIFT)
1480 | (rmesa->state.pixel_shader.program.tex_offset << R300_PFS_CNTL_TEX_OFFSET_SHIFT)
1481 | (rmesa->state.pixel_shader.program.tex_end << R300_PFS_CNTL_TEX_END_SHIFT);
1483 R300_STATECHANGE(rmesa, fpp);
1484 for(i=0;i<rmesa->state.pixel_shader.param_length;i++){
1485 rmesa->hw.fpp.cmd[R300_FPP_PARAM_0+4*i+0]=r300PackFloat32(rmesa->state.pixel_shader.param[i].x);
1486 rmesa->hw.fpp.cmd[R300_FPP_PARAM_0+4*i+1]=r300PackFloat32(rmesa->state.pixel_shader.param[i].y);
1487 rmesa->hw.fpp.cmd[R300_FPP_PARAM_0+4*i+2]=r300PackFloat32(rmesa->state.pixel_shader.param[i].z);
1488 rmesa->hw.fpp.cmd[R300_FPP_PARAM_0+4*i+3]=r300PackFloat32(rmesa->state.pixel_shader.param[i].w);
1490 rmesa->hw.fpp.cmd[R300_FPP_CMD_0]=cmducs(R300_PFS_PARAM_0_X, rmesa->state.pixel_shader.param_length);
1495 * Called by Mesa after an internal state update.
1497 static void r300InvalidateState(GLcontext * ctx, GLuint new_state)
1499 r300ContextPtr r300 = R300_CONTEXT(ctx);
1501 _swrast_InvalidateState(ctx, new_state);
1502 _swsetup_InvalidateState(ctx, new_state);
1503 _ac_InvalidateState(ctx, new_state);
1504 _tnl_InvalidateState(ctx, new_state);
1505 _ae_invalidate_state(ctx, new_state);
1507 /* Go inefficiency! */
1508 r300ResetHwState(r300);
1513 * Completely recalculates hardware state based on the Mesa state.
1515 void r300ResetHwState(r300ContextPtr r300)
1517 GLcontext* ctx = r300->radeon.glCtx;
1520 if (RADEON_DEBUG & DEBUG_STATE)
1521 fprintf(stderr, "%s\n", __FUNCTION__);
1523 /* This is a place to initialize registers which
1524 have bitfields accessed by different functions
1525 and not all bits are used */
1527 r300->hw.zs.cmd[R300_ZS_CNTL_0] = 0;
1528 r300->hw.zs.cmd[R300_ZS_CNTL_1] = 0;
1529 r300->hw.zs.cmd[R300_ZS_CNTL_2] = 0xffff00;
1532 /* go and compute register values from GL state */
1534 r300UpdateWindow(ctx);
1537 ctx->Color.ColorMask[RCOMP],
1538 ctx->Color.ColorMask[GCOMP],
1539 ctx->Color.ColorMask[BCOMP],
1540 ctx->Color.ColorMask[ACOMP]);
1542 r300Enable(ctx, GL_DEPTH_TEST, ctx->Depth.Test);
1543 r300DepthMask(ctx, ctx->Depth.Mask);
1544 r300DepthFunc(ctx, ctx->Depth.Func);
1546 r300UpdateCulling(ctx);
1548 r300_setup_routing(ctx, GL_TRUE);
1550 r300UpdateTextureState(ctx);
1551 r300_setup_textures(ctx);
1552 r300_setup_rs_unit(ctx);
1554 r300SetupVertexShader(r300);
1555 r300SetupPixelShader(r300);
1557 r300_set_blend_state(ctx);
1558 r300AlphaFunc(ctx, ctx->Color.AlphaFunc, ctx->Color.AlphaRef);
1560 /* Initialize magic registers
1561 TODO : learn what they really do, or get rid of
1562 those we don't have to touch */
1563 r300->hw.unk2080.cmd[1] = 0x0030045A;
1565 r300->hw.vte.cmd[1] = R300_VPORT_X_SCALE_ENA
1566 | R300_VPORT_X_OFFSET_ENA
1567 | R300_VPORT_Y_SCALE_ENA
1568 | R300_VPORT_Y_OFFSET_ENA
1569 | R300_VPORT_Z_SCALE_ENA
1570 | R300_VPORT_Z_OFFSET_ENA
1572 r300->hw.vte.cmd[2] = 0x00000008;
1574 r300->hw.unk2134.cmd[1] = 0x00FFFFFF;
1575 r300->hw.unk2134.cmd[2] = 0x00000000;
1577 r300->hw.unk2140.cmd[1] = 0x00000000;
1579 #if 0 /* Done in setup routing */
1580 ((drm_r300_cmd_header_t*)r300->hw.vir[0].cmd)->unchecked_state.count = 1;
1581 r300->hw.vir[0].cmd[1] = 0x21030003;
1583 ((drm_r300_cmd_header_t*)r300->hw.vir[1].cmd)->unchecked_state.count = 1;
1584 r300->hw.vir[1].cmd[1] = 0xF688F688;
1586 r300->hw.vic.cmd[R300_VIR_CNTL_0] = 0x00000001;
1587 r300->hw.vic.cmd[R300_VIR_CNTL_1] = 0x00000405;
1590 r300->hw.unk21DC.cmd[1] = 0xAAAAAAAA;
1592 r300->hw.unk221C.cmd[1] = R300_221C_NORMAL;
1594 r300->hw.unk2220.cmd[1] = r300PackFloat32(1.0);
1595 r300->hw.unk2220.cmd[2] = r300PackFloat32(1.0);
1596 r300->hw.unk2220.cmd[3] = r300PackFloat32(1.0);
1597 r300->hw.unk2220.cmd[4] = r300PackFloat32(1.0);
1599 if (GET_CHIP(r300->radeon.radeonScreen) == RADEON_CHIP_R300)
1600 r300->hw.unk2288.cmd[1] = R300_2288_R300;
1602 r300->hw.unk2288.cmd[1] = R300_2288_RV350;
1605 r300->hw.vof.cmd[R300_VOF_CNTL_0] = R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
1606 | R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT;
1607 r300->hw.vof.cmd[R300_VOF_CNTL_1] = 0; /* no textures */
1610 r300->hw.pvs.cmd[R300_PVS_CNTL_1] = 0;
1611 r300->hw.pvs.cmd[R300_PVS_CNTL_2] = 0;
1612 r300->hw.pvs.cmd[R300_PVS_CNTL_3] = 0;
1615 r300->hw.gb_enable.cmd[1] = R300_GB_POINT_STUFF_ENABLE
1616 | R300_GB_LINE_STUFF_ENABLE
1617 | R300_GB_TRIANGLE_STUFF_ENABLE;
1619 r300->hw.gb_misc.cmd[R300_GB_MISC_MSPOS_0] = 0x66666666;
1620 r300->hw.gb_misc.cmd[R300_GB_MISC_MSPOS_1] = 0x06666666;
1621 if (GET_CHIP(r300->radeon.radeonScreen) == RADEON_CHIP_R300)
1622 r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] = R300_GB_TILE_ENABLE
1623 | R300_GB_TILE_PIPE_COUNT_R300
1624 | R300_GB_TILE_SIZE_16;
1626 r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] = R300_GB_TILE_ENABLE
1627 | R300_GB_TILE_PIPE_COUNT_RV300
1628 | R300_GB_TILE_SIZE_16;
1629 r300->hw.gb_misc.cmd[R300_GB_MISC_SELECT] = 0x00000000;
1630 r300->hw.gb_misc.cmd[R300_GB_MISC_AA_CONFIG] = 0x00000000; /* No antialiasing */
1632 //r300->hw.txe.cmd[R300_TXE_ENABLE] = 0;
1634 r300->hw.unk4200.cmd[1] = r300PackFloat32(0.0);
1635 r300->hw.unk4200.cmd[2] = r300PackFloat32(0.0);
1636 r300->hw.unk4200.cmd[3] = r300PackFloat32(1.0);
1637 r300->hw.unk4200.cmd[4] = r300PackFloat32(1.0);
1639 r300->hw.unk4214.cmd[1] = 0x00050005;
1641 r300->hw.ps.cmd[R300_PS_POINTSIZE] = (6 << R300_POINTSIZE_X_SHIFT) |
1642 (6 << R300_POINTSIZE_Y_SHIFT);
1644 r300->hw.unk4230.cmd[1] = 0x01800000;
1645 r300->hw.unk4230.cmd[2] = 0x00020006;
1646 r300->hw.unk4230.cmd[3] = r300PackFloat32(1.0 / 192.0);
1648 r300->hw.unk4260.cmd[1] = 0;
1649 r300->hw.unk4260.cmd[2] = r300PackFloat32(0.0);
1650 r300->hw.unk4260.cmd[3] = r300PackFloat32(1.0);
1652 r300->hw.unk4274.cmd[1] = 0x00000002;
1653 r300->hw.unk4274.cmd[2] = 0x0003AAAA;
1654 r300->hw.unk4274.cmd[3] = 0x00000000;
1655 r300->hw.unk4274.cmd[4] = 0x00000000;
1657 r300->hw.unk4288.cmd[1] = 0x00000000;
1658 r300->hw.unk4288.cmd[2] = 0x00000001;
1659 r300->hw.unk4288.cmd[3] = 0x00000000;
1660 r300->hw.unk4288.cmd[4] = 0x00000000;
1661 r300->hw.unk4288.cmd[5] = 0x00000000;
1663 r300->hw.unk42A0.cmd[1] = 0x00000000;
1666 r300->hw.unk42B4.cmd[1] = 0x00000000;
1669 r300->hw.unk42C0.cmd[1] = 0x4B7FFFFF;
1670 r300->hw.unk42C0.cmd[2] = 0x00000000;
1673 r300->hw.unk43A4.cmd[1] = 0x0000001C;
1674 r300->hw.unk43A4.cmd[2] = 0x2DA49525;
1676 r300->hw.unk43E8.cmd[1] = 0x00FFFFFF;
1679 r300->hw.fp.cmd[R300_FP_CNTL0] = 0;
1680 r300->hw.fp.cmd[R300_FP_CNTL1] = 0;
1681 r300->hw.fp.cmd[R300_FP_CNTL2] = 0;
1682 r300->hw.fp.cmd[R300_FP_NODE0] = 0;
1683 r300->hw.fp.cmd[R300_FP_NODE1] = 0;
1684 r300->hw.fp.cmd[R300_FP_NODE2] = 0;
1685 r300->hw.fp.cmd[R300_FP_NODE3] = 0;
1688 r300->hw.unk46A4.cmd[1] = 0x00001B01;
1689 r300->hw.unk46A4.cmd[2] = 0x00001B0F;
1690 r300->hw.unk46A4.cmd[3] = 0x00001B0F;
1691 r300->hw.unk46A4.cmd[4] = 0x00001B0F;
1692 r300->hw.unk46A4.cmd[5] = 0x00000001;
1695 for(i = 1; i <= 64; ++i) {
1696 /* create NOP instructions */
1697 r300->hw.fpi[0].cmd[i] = FP_INSTRC(MAD, FP_ARGC(SRC0C_XYZ), FP_ARGC(ONE), FP_ARGC(ZERO));
1698 r300->hw.fpi[1].cmd[i] = FP_SELC(0,XYZ,NO,FP_TMP(0),0,0);
1699 r300->hw.fpi[2].cmd[i] = FP_INSTRA(MAD, FP_ARGA(SRC0A), FP_ARGA(ONE), FP_ARGA(ZERO));
1700 r300->hw.fpi[3].cmd[i] = FP_SELA(0,W,NO,FP_TMP(0),0,0);
1704 r300->hw.unk4BC0.cmd[1] = 0;
1706 r300->hw.unk4BC8.cmd[1] = 0;
1707 r300->hw.unk4BC8.cmd[2] = 0;
1708 r300->hw.unk4BC8.cmd[3] = 0;
1711 r300->hw.at.cmd[R300_AT_ALPHA_TEST] = 0;
1714 r300->hw.at.cmd[R300_AT_UNKNOWN] = 0;
1715 r300->hw.unk4BD8.cmd[1] = 0;
1717 r300->hw.unk4E00.cmd[1] = 0;
1720 r300->hw.bld.cmd[R300_BLD_CBLEND] = 0;
1721 r300->hw.bld.cmd[R300_BLD_ABLEND] = 0;
1724 r300->hw.unk4E10.cmd[1] = 0;
1725 r300->hw.unk4E10.cmd[2] = 0;
1726 r300->hw.unk4E10.cmd[3] = 0;
1728 r300->hw.cb.cmd[R300_CB_OFFSET] =
1729 r300->radeon.radeonScreen->backOffset +
1730 r300->radeon.radeonScreen->fbLocation;
1731 r300->hw.cb.cmd[R300_CB_PITCH] = r300->radeon.radeonScreen->backPitch
1732 | R300_COLOR_UNKNOWN_22_23;
1734 r300->hw.unk4E50.cmd[1] = 0;
1735 r300->hw.unk4E50.cmd[2] = 0;
1736 r300->hw.unk4E50.cmd[3] = 0;
1737 r300->hw.unk4E50.cmd[4] = 0;
1738 r300->hw.unk4E50.cmd[5] = 0;
1739 r300->hw.unk4E50.cmd[6] = 0;
1740 r300->hw.unk4E50.cmd[7] = 0;
1741 r300->hw.unk4E50.cmd[8] = 0;
1742 r300->hw.unk4E50.cmd[9] = 0;
1744 r300->hw.unk4E88.cmd[1] = 0;
1746 r300->hw.unk4EA0.cmd[1] = 0x00000000;
1747 r300->hw.unk4EA0.cmd[2] = 0xffffffff;
1749 r300->hw.unk4F10.cmd[1] = 0x00000002; // depthbuffer format?
1750 r300->hw.unk4F10.cmd[2] = 0x00000000;
1751 r300->hw.unk4F10.cmd[3] = 0x00000003;
1752 r300->hw.unk4F10.cmd[4] = 0x00000000;
1754 /* experiment a bit */
1755 r300->hw.unk4F10.cmd[2] = 0x00000001; // depthbuffer format?
1757 r300->hw.zb.cmd[R300_ZB_OFFSET] =
1758 r300->radeon.radeonScreen->depthOffset +
1759 r300->radeon.radeonScreen->fbLocation;
1760 r300->hw.zb.cmd[R300_ZB_PITCH] = r300->radeon.radeonScreen->depthPitch;
1762 r300->hw.unk4F28.cmd[1] = 0;
1764 r300->hw.unk4F30.cmd[1] = 0;
1765 r300->hw.unk4F30.cmd[2] = 0;
1767 r300->hw.unk4F44.cmd[1] = 0;
1769 r300->hw.unk4F54.cmd[1] = 0;
1772 ((drm_r300_cmd_header_t*)r300->hw.vpi.cmd)->vpu.count = 0;
1773 for(i = 1; i < R300_VPI_CMDSIZE; i += 4) {
1775 r300->hw.vpi.cmd[i+0] = VP_OUT(ADD,TMP,0,XYZW);
1776 r300->hw.vpi.cmd[i+1] = VP_IN(TMP,0);
1777 r300->hw.vpi.cmd[i+2] = VP_ZERO();
1778 r300->hw.vpi.cmd[i+3] = VP_ZERO();
1781 ((drm_r300_cmd_header_t*)r300->hw.vpp.cmd)->vpu.count = 0;
1782 for(i = 1; i < R300_VPP_CMDSIZE; ++i)
1783 r300->hw.vpp.cmd[i] = 0;
1786 r300->hw.vps.cmd[R300_VPS_ZERO_0] = 0;
1787 r300->hw.vps.cmd[R300_VPS_ZERO_1] = 0;
1788 r300->hw.vps.cmd[R300_VPS_POINTSIZE] = r300PackFloat32(1.0);
1789 r300->hw.vps.cmd[R300_VPS_ZERO_3] = 0;
1793 r300->hw.all_dirty = GL_TRUE;
1799 * Calculate initial hardware state and register state functions.
1800 * Assumes that the command buffer and state atoms have been
1801 * initialized already.
1803 void r300InitState(r300ContextPtr r300)
1805 GLcontext *ctx = r300->radeon.glCtx;
1808 radeonInitState(&r300->radeon);
1810 switch (ctx->Visual.depthBits) {
1812 r300->state.depth.scale = 1.0 / (GLfloat) 0xffff;
1813 depth_fmt = R200_DEPTH_FORMAT_16BIT_INT_Z;
1814 //r300->state.stencil.clear = 0x00000000;
1817 r300->state.depth.scale = 1.0 / (GLfloat) 0xffffff;
1818 depth_fmt = R200_DEPTH_FORMAT_24BIT_INT_Z;
1819 //r300->state.stencil.clear = 0xff000000;
1822 fprintf(stderr, "Error: Unsupported depth %d... exiting\n",
1823 ctx->Visual.depthBits);
1827 /* Only have hw stencil when depth buffer is 24 bits deep */
1828 r300->state.hw_stencil = (ctx->Visual.stencilBits > 0 &&
1829 ctx->Visual.depthBits == 24);
1831 memset(&(r300->state.texture), 0, sizeof(r300->state.texture));
1833 r300ResetHwState(r300);
1838 * Initialize driver's state callback functions
1840 void r300InitStateFuncs(struct dd_function_table* functions)
1842 radeonInitStateFuncs(functions);
1844 functions->UpdateState = r300InvalidateState;
1845 functions->AlphaFunc = r300AlphaFunc;
1846 functions->BlendColor = r300BlendColor;
1847 functions->BlendEquationSeparate = r300BlendEquationSeparate;
1848 functions->BlendFuncSeparate = r300BlendFuncSeparate;
1849 functions->Enable = r300Enable;
1850 functions->ColorMask = r300ColorMask;
1851 functions->DepthFunc = r300DepthFunc;
1852 functions->DepthMask = r300DepthMask;
1853 functions->CullFace = r300CullFace;
1854 functions->FrontFace = r300FrontFace;
1856 /* Stencil related */
1857 functions->ClearStencil = r300ClearStencil;
1858 functions->StencilFunc = r300StencilFunc;
1859 functions->StencilMask = r300StencilMask;
1860 functions->StencilOp = r300StencilOp;
1862 /* Viewport related */
1863 functions->Viewport = r300Viewport;
1864 functions->DepthRange = r300DepthRange;
1865 functions->PointSize = r300PointSize;
1868 functions->PolygonOffset = r300PolygonOffset;