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"
52 #include "radeon_ioctl.h"
53 #include "radeon_state.h"
54 #include "r300_context.h"
55 #include "r300_ioctl.h"
56 #include "r300_state.h"
58 #include "r300_program.h"
60 static void r300AlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref)
62 r300ContextPtr rmesa = R300_CONTEXT(ctx);
63 int pp_misc = rmesa->hw.at.cmd[R300_AT_ALPHA_TEST];
66 CLAMPED_FLOAT_TO_UBYTE(refByte, ref);
68 R300_STATECHANGE(rmesa, at);
70 pp_misc &= ~(R300_ALPHA_TEST_OP_MASK | R300_REF_ALPHA_MASK);
71 pp_misc |= (refByte & R300_REF_ALPHA_MASK);
75 pp_misc |= R300_ALPHA_TEST_FAIL;
78 pp_misc |= R300_ALPHA_TEST_LESS;
81 pp_misc |= R300_ALPHA_TEST_EQUAL;
84 pp_misc |= R300_ALPHA_TEST_LEQUAL;
87 pp_misc |= R300_ALPHA_TEST_GREATER;
90 pp_misc |= R300_ALPHA_TEST_NEQUAL;
93 pp_misc |= R300_ALPHA_TEST_GEQUAL;
96 pp_misc |= R300_ALPHA_TEST_PASS;
100 rmesa->hw.at.cmd[R300_AT_ALPHA_TEST] = pp_misc;
103 static void r300BlendColor(GLcontext * ctx, const GLfloat cf[4])
106 r300ContextPtr rmesa = R300_CONTEXT(ctx);
107 fprintf(stderr, "%s:%s is not implemented yet. Fixme !\n", __FILE__, __FUNCTION__);
109 R200_STATECHANGE(rmesa, ctx);
110 CLAMPED_FLOAT_TO_UBYTE(color[0], cf[0]);
111 CLAMPED_FLOAT_TO_UBYTE(color[1], cf[1]);
112 CLAMPED_FLOAT_TO_UBYTE(color[2], cf[2]);
113 CLAMPED_FLOAT_TO_UBYTE(color[3], cf[3]);
114 if (rmesa->radeon.radeonScreen->drmSupportsBlendColor)
115 rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCOLOR] =
116 radeonPackColor(4, color[0], color[1], color[2], color[3]);
121 * Calculate the hardware blend factor setting. This same function is used
122 * for source and destination of both alpha and RGB.
125 * The hardware register value for the specified blend factor. This value
126 * will need to be shifted into the correct position for either source or
127 * destination factor.
130 * Since the two cases where source and destination are handled differently
131 * are essentially error cases, they should never happen. Determine if these
132 * cases can be removed.
134 static int blend_factor(GLenum factor, GLboolean is_src)
140 func = R200_BLEND_GL_ZERO;
143 func = R200_BLEND_GL_ONE;
146 func = R200_BLEND_GL_DST_COLOR;
148 case GL_ONE_MINUS_DST_COLOR:
149 func = R200_BLEND_GL_ONE_MINUS_DST_COLOR;
152 func = R200_BLEND_GL_SRC_COLOR;
154 case GL_ONE_MINUS_SRC_COLOR:
155 func = R200_BLEND_GL_ONE_MINUS_SRC_COLOR;
158 func = R200_BLEND_GL_SRC_ALPHA;
160 case GL_ONE_MINUS_SRC_ALPHA:
161 func = R200_BLEND_GL_ONE_MINUS_SRC_ALPHA;
164 func = R200_BLEND_GL_DST_ALPHA;
166 case GL_ONE_MINUS_DST_ALPHA:
167 func = R200_BLEND_GL_ONE_MINUS_DST_ALPHA;
169 case GL_SRC_ALPHA_SATURATE:
171 (is_src) ? R200_BLEND_GL_SRC_ALPHA_SATURATE :
174 case GL_CONSTANT_COLOR:
175 func = R200_BLEND_GL_CONST_COLOR;
177 case GL_ONE_MINUS_CONSTANT_COLOR:
178 func = R200_BLEND_GL_ONE_MINUS_CONST_COLOR;
180 case GL_CONSTANT_ALPHA:
181 func = R200_BLEND_GL_CONST_ALPHA;
183 case GL_ONE_MINUS_CONSTANT_ALPHA:
184 func = R200_BLEND_GL_ONE_MINUS_CONST_ALPHA;
187 func = (is_src) ? R200_BLEND_GL_ONE : R200_BLEND_GL_ZERO;
193 * Sets both the blend equation and the blend function.
194 * This is done in a single
195 * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX)
196 * change the interpretation of the blend function.
197 * Also, make sure that blend function and blend equation are set to their default
198 * value if color blending is not enabled, since at least blend equations GL_MIN
199 * and GL_FUNC_REVERSE_SUBTRACT will cause wrong results otherwise for
202 static void r300_set_blend_state(GLcontext * ctx)
204 r300ContextPtr rmesa = R300_CONTEXT(ctx);
206 GLuint cntl = rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &
207 ~(R300_ROP_ENABLE | R300_ALPHA_BLEND_ENABLE |
208 R300_SEPARATE_ALPHA_ENABLE);
211 int func = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
212 (R200_BLEND_GL_ZERO << R200_DST_BLEND_SHIFT);
213 int eqn = R200_COMB_FCN_ADD_CLAMP;
214 int funcA = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
215 (R200_BLEND_GL_ZERO << R200_DST_BLEND_SHIFT);
216 int eqnA = R200_COMB_FCN_ADD_CLAMP;
218 R300_STATECHANGE(rmesa, bld);
220 if (rmesa->radeon.radeonScreen->drmSupportsBlendColor) {
221 if (ctx->Color._LogicOpEnabled) {
223 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] =
224 cntl | R300_ROP_ENABLE;
226 rmesa->hw.bld.cmd[R300_BLD_ABLEND] = eqn | func;
227 rmesa->hw.bld.cmd[R300_BLD_CBLEND] = eqn | func;
229 } else if (ctx->Color.BlendEnabled) {
231 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] =
232 cntl | R300_ALPHA_BLEND_ENABLE |
233 R300_SEPARATE_ALPHA_ENABLE;
237 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = cntl;
239 rmesa->hw.bld.cmd[R300_BLD_ABLEND] = eqn | func;
240 rmesa->hw.bld.cmd[R300_BLD_CBLEND] = eqn | func;
244 if (ctx->Color._LogicOpEnabled) {
246 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] =
247 cntl | R300_ROP_ENABLE;
248 rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = eqn | func;
251 } else if (ctx->Color.BlendEnabled) {
253 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] =
254 cntl | R300_ALPHA_BLEND_ENABLE;
258 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = cntl;
259 rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = eqn | func;
266 (blend_factor(ctx->Color.BlendSrcRGB, GL_TRUE) <<
267 R200_SRC_BLEND_SHIFT) | (blend_factor(ctx->Color.BlendDstRGB,
269 R200_DST_BLEND_SHIFT);
271 switch (ctx->Color.BlendEquationRGB) {
273 eqn = R300_COMB_FCN_ADD_CLAMP;
276 case GL_FUNC_SUBTRACT:
277 eqn = R300_COMB_FCN_SUB_CLAMP;
280 case GL_FUNC_REVERSE_SUBTRACT:
281 eqn = R200_COMB_FCN_RSUB_CLAMP;
285 eqn = R200_COMB_FCN_MIN;
286 func = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
287 (R200_BLEND_GL_ONE << R200_DST_BLEND_SHIFT);
291 eqn = R200_COMB_FCN_MAX;
292 func = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
293 (R200_BLEND_GL_ONE << R200_DST_BLEND_SHIFT);
298 "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
299 __func__, __LINE__, ctx->Color.BlendEquationRGB);
303 if (!rmesa->radeon.radeonScreen->drmSupportsBlendColor) {
305 rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = eqn | func;
311 (blend_factor(ctx->Color.BlendSrcA, GL_TRUE) <<
312 R200_SRC_BLEND_SHIFT) | (blend_factor(ctx->Color.BlendDstA,
314 R200_DST_BLEND_SHIFT);
316 switch (ctx->Color.BlendEquationA) {
318 eqnA = R300_COMB_FCN_ADD_CLAMP;
321 case GL_FUNC_SUBTRACT:
322 eqnA = R300_COMB_FCN_SUB_CLAMP;
325 case GL_FUNC_REVERSE_SUBTRACT:
326 eqnA = R200_COMB_FCN_RSUB_CLAMP;
330 eqnA = R200_COMB_FCN_MIN;
331 funcA = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
332 (R200_BLEND_GL_ONE << R200_DST_BLEND_SHIFT);
336 eqnA = R200_COMB_FCN_MAX;
337 funcA = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
338 (R200_BLEND_GL_ONE << R200_DST_BLEND_SHIFT);
342 fprintf(stderr, "[%s:%u] Invalid A blend equation (0x%04x).\n",
343 __func__, __LINE__, ctx->Color.BlendEquationA);
347 rmesa->hw.bld.cmd[R300_BLD_ABLEND] = eqnA | funcA;
348 rmesa->hw.bld.cmd[R300_BLD_CBLEND] = eqn | func ;
349 if(rmesa->hw.bld.cmd[R300_BLD_ABLEND] == rmesa->hw.bld.cmd[R300_BLD_CBLEND]){
350 rmesa->hw.bld.cmd[R300_BLD_CBLEND] |= R300_BLEND_UNKNOWN | R300_BLEND_ENABLE | R300_BLEND_NO_SEPARATE;
352 rmesa->hw.bld.cmd[R300_BLD_CBLEND] |= R300_BLEND_UNKNOWN | R300_BLEND_ENABLE;
357 static void r300BlendEquationSeparate(GLcontext * ctx,
358 GLenum modeRGB, GLenum modeA)
360 r300_set_blend_state(ctx);
363 static void r300BlendFuncSeparate(GLcontext * ctx,
364 GLenum sfactorRGB, GLenum dfactorRGB,
365 GLenum sfactorA, GLenum dfactorA)
367 r300_set_blend_state(ctx);
371 * Update our tracked culling state based on Mesa's state.
373 static void r300UpdateCulling(GLcontext* ctx)
375 r300ContextPtr r300 = R300_CONTEXT(ctx);
378 R300_STATECHANGE(r300, cul);
379 if (ctx->Polygon.CullFlag) {
380 if (ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK)
381 val = R300_CULL_FRONT|R300_CULL_BACK;
382 else if (ctx->Polygon.CullFaceMode == GL_FRONT)
383 val = R300_CULL_FRONT;
385 val = R300_CULL_BACK;
387 if (ctx->Polygon.FrontFace == GL_CW)
388 val |= R300_FRONT_FACE_CW;
390 val |= R300_FRONT_FACE_CCW;
393 r300->hw.cul.cmd[R300_CUL_CULL] = val;
398 * Handle glEnable()/glDisable().
400 * \note Mesa already filters redundant calls to glEnable/glDisable.
402 static void r300Enable(GLcontext* ctx, GLenum cap, GLboolean state)
404 r300ContextPtr r300 = R300_CONTEXT(ctx);
407 if (RADEON_DEBUG & DEBUG_STATE)
408 fprintf(stderr, "%s( %s = %s )\n", __FUNCTION__,
409 _mesa_lookup_enum_by_nr(cap),
410 state ? "GL_TRUE" : "GL_FALSE");
414 R300_STATECHANGE(r300, zc);
418 newval = R300_RB3D_Z_TEST_AND_WRITE;
420 newval = R300_RB3D_Z_TEST;
424 r300->hw.zc.cmd[R300_ZC_CNTL_0] = newval;
428 r300UpdateCulling(ctx);
432 radeonEnable(ctx, cap, state);
439 * Change the culling mode.
441 * \note Mesa already filters redundant calls to this function.
443 static void r300CullFace(GLcontext* ctx, GLenum mode)
447 r300UpdateCulling(ctx);
452 * Change the polygon orientation.
454 * \note Mesa already filters redundant calls to this function.
456 static void r300FrontFace(GLcontext* ctx, GLenum mode)
460 r300UpdateCulling(ctx);
465 * Change the depth testing function.
467 * \note Mesa already filters redundant calls to this function.
469 static void r300DepthFunc(GLcontext* ctx, GLenum func)
471 r300ContextPtr r300 = R300_CONTEXT(ctx);
473 R300_STATECHANGE(r300, zc);
477 r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_NEVER;
480 r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_LESS;
483 r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_EQUAL;
486 r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_LEQUAL;
489 r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_GREATER;
492 r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_NEQUAL;
495 r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_GEQUAL;
498 r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_ALWAYS;
505 * Enable/Disable depth writing.
507 * \note Mesa already filters redundant calls to this function.
509 static void r300DepthMask(GLcontext* ctx, GLboolean mask)
511 r300ContextPtr r300 = R300_CONTEXT(ctx);
513 if (!ctx->Depth.Test)
516 R300_STATECHANGE(r300, zc);
517 r300->hw.zc.cmd[R300_ZC_CNTL_0] = mask
518 ? R300_RB3D_Z_TEST_AND_WRITE : R300_RB3D_Z_TEST;
523 * Handle glColorMask()
525 static void r300ColorMask(GLcontext* ctx,
526 GLboolean r, GLboolean g, GLboolean b, GLboolean a)
528 r300ContextPtr r300 = R300_CONTEXT(ctx);
529 int mask = (b << 0) | (g << 1) | (r << 2) | (a << 3);
531 if (mask != r300->hw.cmk.cmd[R300_CMK_COLORMASK]) {
532 R300_STATECHANGE(r300, cmk);
533 r300->hw.cmk.cmd[R300_CMK_COLORMASK] = mask;
537 /* =============================================================
540 static void r300PointSize(GLcontext * ctx, GLfloat size)
542 r300ContextPtr r300 = R300_CONTEXT(ctx);
544 /* This might need fixing later */
545 R300_STATECHANGE(r300, vps);
546 r300->hw.vps.cmd[R300_VPS_POINTSIZE] = r300PackFloat32(1.0);
549 /* =============================================================
550 * Window position and viewport transformation
554 * To correctly position primitives:
556 #define SUBPIXEL_X 0.125
557 #define SUBPIXEL_Y 0.125
559 void r300UpdateWindow(GLcontext * ctx)
561 r300ContextPtr rmesa = R300_CONTEXT(ctx);
562 __DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable;
563 GLfloat xoffset = dPriv ? (GLfloat) dPriv->x : 0;
564 GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0;
565 const GLfloat *v = ctx->Viewport._WindowMap.m;
567 GLfloat sx = v[MAT_SX];
568 GLfloat tx = v[MAT_TX] + xoffset + SUBPIXEL_X;
569 GLfloat sy = -v[MAT_SY];
570 GLfloat ty = (-v[MAT_TY]) + yoffset + SUBPIXEL_Y;
571 GLfloat sz = v[MAT_SZ] * rmesa->state.depth.scale;
572 GLfloat tz = v[MAT_TZ] * rmesa->state.depth.scale;
574 R300_FIREVERTICES(rmesa);
575 R300_STATECHANGE(rmesa, vpt);
577 rmesa->hw.vpt.cmd[R300_VPT_XSCALE] = r300PackFloat32(sx);
578 rmesa->hw.vpt.cmd[R300_VPT_XOFFSET] = r300PackFloat32(tx);
579 rmesa->hw.vpt.cmd[R300_VPT_YSCALE] = r300PackFloat32(sy);
580 rmesa->hw.vpt.cmd[R300_VPT_YOFFSET] = r300PackFloat32(ty);
581 rmesa->hw.vpt.cmd[R300_VPT_ZSCALE] = r300PackFloat32(sz);
582 rmesa->hw.vpt.cmd[R300_VPT_ZOFFSET] = r300PackFloat32(tz);
585 static void r300Viewport(GLcontext * ctx, GLint x, GLint y,
586 GLsizei width, GLsizei height)
588 /* Don't pipeline viewport changes, conflict with window offset
589 * setting below. Could apply deltas to rescue pipelined viewport
590 * values, or keep the originals hanging around.
592 R200_FIREVERTICES(R200_CONTEXT(ctx));
593 r300UpdateWindow(ctx);
596 static void r300DepthRange(GLcontext * ctx, GLclampd nearval, GLclampd farval)
598 r300UpdateWindow(ctx);
601 /* Routing and texture-related */
603 void r300_setup_routing(GLcontext *ctx, GLboolean immediate)
605 int i, count=0,reg=0;
607 TNLcontext *tnl = TNL_CONTEXT(ctx);
608 struct vertex_buffer *VB = &tnl->vb;
609 r300ContextPtr r300 = R300_CONTEXT(ctx);
612 /* Stage 1 - input to VAP */
614 /* Assign register number automatically, retaining it in rmesa->state.reg */
616 /* Note: immediate vertex data includes all coordinates.
617 To save bandwidth use either VBUF or state-based vertex generation */
619 #define CONFIGURE_AOS(v, o, r, f) \
622 r300->state.aos[count].element_size=4; \
623 r300->state.aos[count].stride=4; \
624 r300->state.aos[count].ncomponents=4; \
626 r300->state.aos[count].element_size=v->size; \
627 r300->state.aos[count].stride=v->size; \
628 r300->state.aos[count].ncomponents=v->size; \
630 r300->state.aos[count].offset=o; \
631 r300->state.aos[count].reg=reg; \
632 r300->state.aos[count].format=(f); \
633 r300->state.vap_reg.r=reg; \
638 /* All offsets are 0 - for use by immediate mode.
639 Should change later to handle vertex buffers */
640 CONFIGURE_AOS(VB->ObjPtr, 0, i_coords, AOS_FORMAT_FLOAT);
641 CONFIGURE_AOS(VB->ColorPtr[0], 0, i_color[0], AOS_FORMAT_FLOAT_COLOR);
642 for(i=0;i < ctx->Const.MaxTextureUnits;i++)
643 if(ctx->Texture.Unit[i].Enabled)
644 CONFIGURE_AOS(VB->TexCoordPtr[i], 0, i_tex[i], AOS_FORMAT_FLOAT);
646 r300->state.aos_count=count;
648 if (RADEON_DEBUG & DEBUG_STATE)
649 fprintf(stderr, "aos_count=%d\n", count);
651 if(count>R300_MAX_AOS_ARRAYS){
652 fprintf(stderr, "Aieee ! AOS array count exceeded !\n");
658 /* setup INPUT_ROUTE */
659 R300_STATECHANGE(r300, vir[0]);
660 for(i=0;i+1<count;i+=2){
661 dw=(r300->state.aos[i].ncomponents-1)
662 | ((r300->state.aos[i].reg)<<8)
663 | (r300->state.aos[i].format<<14)
664 | (((r300->state.aos[i+1].ncomponents-1)
665 | ((r300->state.aos[i+1].reg)<<8)
666 | (r300->state.aos[i+1].format<<14))<<16);
671 r300->hw.vir[0].cmd[R300_VIR_CNTL_0+(i>>1)]=dw;
674 dw=(r300->state.aos[count-1].ncomponents-1)
675 | (r300->state.aos[count-1].format<<14)
676 | ((r300->state.aos[count-1].reg)<<8)
678 r300->hw.vir[0].cmd[R300_VIR_CNTL_0+(count>>1)]=dw;
679 //fprintf(stderr, "vir0 dw=%08x\n", dw);
681 /* Set the rest of INPUT_ROUTE_0 to 0 */
682 //for(i=((count+1)>>1); i<8; i++)r300->hw.vir[0].cmd[R300_VIR_CNTL_0+i]=(0x0);
683 ((drm_r300_cmd_header_t*)r300->hw.vir[0].cmd)->unchecked_state.count = (count+1)>>1;
686 /* Mesa assumes that all missing components are from (0, 0, 0, 1) */
687 #define ALL_COMPONENTS ((R300_INPUT_ROUTE_SELECT_X<<R300_INPUT_ROUTE_X_SHIFT) \
688 | (R300_INPUT_ROUTE_SELECT_Y<<R300_INPUT_ROUTE_Y_SHIFT) \
689 | (R300_INPUT_ROUTE_SELECT_Z<<R300_INPUT_ROUTE_Z_SHIFT) \
690 | (R300_INPUT_ROUTE_SELECT_W<<R300_INPUT_ROUTE_W_SHIFT))
692 #define ALL_DEFAULT ((R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_X_SHIFT) \
693 | (R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_Y_SHIFT) \
694 | (R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_Z_SHIFT) \
695 | (R300_INPUT_ROUTE_SELECT_ONE<<R300_INPUT_ROUTE_W_SHIFT))
697 R300_STATECHANGE(r300, vir[1]);
699 for(i=0;i+1<count;i+=2){
701 mask=(1<<(r300->state.aos[i].ncomponents*3))-1;
702 dw=(ALL_COMPONENTS & mask)
703 | (ALL_DEFAULT & ~mask)
704 | R300_INPUT_ROUTE_ENABLE;
707 mask=(1<<(r300->state.aos[i+1].ncomponents*3))-1;
709 (ALL_COMPONENTS & mask)
710 | (ALL_DEFAULT & ~mask)
711 | R300_INPUT_ROUTE_ENABLE
714 r300->hw.vir[1].cmd[R300_VIR_CNTL_0+(i>>1)]=dw;
717 mask=(1<<(r300->state.aos[count-1].ncomponents*3))-1;
718 dw=(ALL_COMPONENTS & mask)
719 | (ALL_DEFAULT & ~mask)
720 | R300_INPUT_ROUTE_ENABLE;
721 r300->hw.vir[1].cmd[R300_VIR_CNTL_0+(count>>1)]=dw;
722 //fprintf(stderr, "vir1 dw=%08x\n", dw);
724 /* Set the rest of INPUT_ROUTE_1 to 0 */
725 //for(i=((count+1)>>1); i<8; i++)r300->hw.vir[1].cmd[R300_VIR_CNTL_0+i]=0x0;
726 ((drm_r300_cmd_header_t*)r300->hw.vir[1].cmd)->unchecked_state.count = (count+1)>>1;
728 /* Set up input_cntl */
730 R300_STATECHANGE(r300, vic);
731 r300->hw.vic.cmd[R300_VIC_CNTL_0]=0x5555; /* Hard coded value, no idea what it means */
733 r300->hw.vic.cmd[R300_VIC_CNTL_1]=R300_INPUT_CNTL_POS
734 | R300_INPUT_CNTL_COLOR;
736 for(i=0;i < ctx->Const.MaxTextureUnits;i++)
737 if(ctx->Texture.Unit[i].Enabled)
738 r300->hw.vic.cmd[R300_VIC_CNTL_1]|=(R300_INPUT_CNTL_TC0<<i);
740 /* Stage 3: VAP output */
741 R300_STATECHANGE(r300, vof);
742 r300->hw.vof.cmd[R300_VOF_CNTL_0]=R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
743 | R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT;
745 r300->hw.vof.cmd[R300_VOF_CNTL_1]=0;
746 for(i=0;i < ctx->Const.MaxTextureUnits;i++)
747 if(ctx->Texture.Unit[i].Enabled)
748 r300->hw.vof.cmd[R300_VOF_CNTL_1]|=(4<<(3*i));
752 static r300TexObj default_tex_obj={
753 filter:R300_TX_MAG_FILTER_LINEAR | R300_TX_MIN_FILTER_LINEAR,
755 size: (0xff << R300_TX_WIDTHMASK_SHIFT)
756 | (0xff << R300_TX_HEIGHTMASK_SHIFT)
757 | (0x8 << R300_TX_SIZE_SHIFT),
764 /* there is probably a system to these value, but, for now,
765 we just try by hand */
767 static int inline translate_src(int src)
776 case GL_PRIMARY_COLOR:
793 /* I think 357 and 457 are prime numbers.. wiggle them if you get coincidences */
794 #define FORMAT_HASH(opRGB, srcRGB, modeRGB, opA, srcA, modeA, format, intFormat) ( \
796 ((opRGB)<<30) | ((opA)<<28) | \
797 ((srcRGB)<< 25) | ((srcA)<<22) | \
801 ^ (((format)) *457) \
802 ^ ((intFormat) * 7) \
805 static GLuint translate_texture_format(GLcontext *ctx, GLint tex_unit, GLuint format, GLint IntFormat)
807 const struct gl_texture_unit *texUnit= &ctx->Texture.Unit[tex_unit];
808 int i=0; /* number of alpha args .. */
810 /* Size field in format specific first */
812 texUnit->_CurrentCombine->OperandRGB[i] -GL_SRC_COLOR,
813 translate_src(texUnit->_CurrentCombine->SourceRGB[i]),
814 texUnit->_CurrentCombine->ModeRGB,
815 texUnit->_CurrentCombine->OperandA[i] -GL_SRC_ALPHA,
816 translate_src(texUnit->_CurrentCombine->SourceA[i]),
817 texUnit->_CurrentCombine->ModeA,
821 case FORMAT_HASH(0, 1, 0x2100, 0, 1, 0x2100, 0x00088047, 0x1908):
825 return 0x7a0c; /* kfiresaver.kss */
826 case FORMAT_HASH(0, 1, 0x2100, 0, 1, 0x2100, 0x00088047, 0x8058):
830 return 0x8a0c; /* Quake3demo -small font on the bottom */
831 case FORMAT_HASH(0, 1, 0x2100, 0, 1, 0x2100, 0x00077047, 4):
836 case FORMAT_HASH(0, 1, 0x2100, 0, 1, 0x2100, 0x00055047, 4):
842 case FORMAT_HASH(0, 1, 0x2100, 0, 4, 0x1e01, 0x00088047, 3):
848 //case FORMAT_HASH(0, 1, 0x2100, 0, 4, 0x1e01, 0x00055047, 0):
849 /* Can't remember what I tested this with..
850 try putting return 0 of you see broken textures which
851 are not being complained about */
853 case FORMAT_HASH(0, 1, 0x2100, 0, 4, 0x1e01, 0x00099047, 0x8051):
854 //case FORMAT_HASH(0, 1, 0x2100, 0, 4, 0x1e01, 0x00089047, 0x8058):
855 case FORMAT_HASH(0, 1, 0x2100, 0, 4, 0x1e01, 0x00077047, 0x8051):
860 case FORMAT_HASH(0, 1, 0x2100, 0, 1, 0x2100, 0x00055045, 0x00008056):
861 case FORMAT_HASH(0, 1, 0x2100, 0, 1, 0x2100, 0x00088045, 0x00008056):
863 case FORMAT_HASH(0, 1, 0x2100, 0, 4, 0x1e01, 0x00099004, 0x00008050):
869 /* Just key on internal format - useful for quick tryouts*/
885 //fprintf(stderr, "%08x\n", format);
898 static int warn_once=1;
900 fprintf(stderr, "%s:%s Do not know how to translate texture format - help me !\n",
901 __FILE__, __FUNCTION__);
908 void r300_setup_textures(GLcontext *ctx)
911 struct r300_tex_obj *t;
912 r300ContextPtr r300 = R300_CONTEXT(ctx);
913 int max_texture_unit=-1; /* -1 translates into no setup costs for fields */
914 struct gl_texture_unit *texUnit;
916 R300_STATECHANGE(r300, txe);
917 R300_STATECHANGE(r300, tex.filter);
918 R300_STATECHANGE(r300, tex.unknown1);
919 R300_STATECHANGE(r300, tex.size);
920 R300_STATECHANGE(r300, tex.format);
921 R300_STATECHANGE(r300, tex.offset);
922 R300_STATECHANGE(r300, tex.unknown4);
923 R300_STATECHANGE(r300, tex.unknown5);
925 r300->state.texture.tc_count=0;
927 r300->hw.txe.cmd[R300_TXE_ENABLE]=0x0;
929 mtu = r300->radeon.glCtx->Const.MaxTextureUnits;
930 if (RADEON_DEBUG & DEBUG_STATE)
931 fprintf(stderr, "mtu=%d\n", mtu);
933 if(mtu>R300_MAX_TEXTURE_UNITS){
934 fprintf(stderr, "Aiiee ! mtu=%d is greater than R300_MAX_TEXTURE_UNITS=%d\n",
935 mtu, R300_MAX_TEXTURE_UNITS);
939 if(ctx->Texture.Unit[i].Enabled){
940 t=r300->state.texture.unit[i].texobj;
941 r300->state.texture.tc_count++;
943 fprintf(stderr, "Texture unit %d enabled, but corresponding texobj is NULL, using default object.\n", i);
947 if (RADEON_DEBUG & DEBUG_STATE)
948 fprintf(stderr, "Activating texture unit %d\n", i);
950 r300->hw.txe.cmd[R300_TXE_ENABLE]|=(1<<i);
952 r300->hw.tex.filter.cmd[R300_TEX_VALUE_0+i]=t->filter;
953 r300->hw.tex.unknown1.cmd[R300_TEX_VALUE_0+i]=t->pitch;
954 r300->hw.tex.size.cmd[R300_TEX_VALUE_0+i]=t->size;
955 r300->hw.tex.format.cmd[R300_TEX_VALUE_0+i]=t->format;
956 r300->hw.tex.offset.cmd[R300_TEX_VALUE_0+i]=r300->radeon.radeonScreen->fbLocation+t->offset;
957 r300->hw.tex.unknown4.cmd[R300_TEX_VALUE_0+i]=0x0;
958 r300->hw.tex.unknown5.cmd[R300_TEX_VALUE_0+i]=0x0;
962 /* We don't know how to set this yet */
963 //value from r300_lib.c for RGB24
964 //r300->hw.tex.format.cmd[R300_TEX_VALUE_0+i]=0x88a0c;
965 r300->hw.tex.format.cmd[R300_TEX_VALUE_0+i]=translate_texture_format(ctx, i, t->format, t->base.tObj->Image[0][0]->IntFormat);
966 /* Use the code below to quickly find matching texture
967 formats. Requires an app that displays the same texture
970 if(r300->hw.tex.format.cmd[R300_TEX_VALUE_0+i]==0){
977 texUnit = &ctx->Texture.Unit[i];
978 fprintf(stderr, "Want to set FORMAT_HASH(%d, %d, 0x%04x, %d, %d, 0x%04x, 0x%08x, 0x%08x)\n",
979 texUnit->_CurrentCombine->OperandRGB[0] -GL_SRC_COLOR,
980 translate_src(texUnit->_CurrentCombine->SourceRGB[0]),
981 texUnit->_CurrentCombine->ModeRGB,
982 texUnit->_CurrentCombine->OperandA[0] -GL_SRC_ALPHA,
983 translate_src(texUnit->_CurrentCombine->SourceA[0]),
984 texUnit->_CurrentCombine->ModeA,
986 t->base.tObj->Image[0][0]->IntFormat
988 fprintf(stderr, "Also known: format_x=%08x border_color=%08x cubic_faces=%08x\n", t->format_x, t->pp_border_color, t->pp_cubic_faces);
989 fprintf(stderr, "\t_ReallyEnabled=%08x EnvMode=%08x IntFormat=%08x\n", texUnit->_ReallyEnabled, texUnit->EnvMode, t->base.tObj->Image[0][0]->IntFormat);
995 fprintf(stderr, "Now trying format %08x\n",
996 0x00a0c | (fmt<<12));
997 fprintf(stderr, "size=%08x\n", t->size);
999 r300->hw.tex.format.cmd[R300_TEX_VALUE_0+i]=0x00a0b | (fmt<<12);
1000 //r300->hw.tex.format.cmd[R300_TEX_VALUE_0+i]=0x51a00 | (fmt);
1001 //r300->hw.tex.format.cmd[R300_TEX_VALUE_0+i]=0x53a0c | (fmt<<24);
1008 ((drm_r300_cmd_header_t*)r300->hw.tex.filter.cmd)->unchecked_state.count = max_texture_unit+1;
1009 ((drm_r300_cmd_header_t*)r300->hw.tex.unknown1.cmd)->unchecked_state.count = max_texture_unit+1;
1010 ((drm_r300_cmd_header_t*)r300->hw.tex.size.cmd)->unchecked_state.count = max_texture_unit+1;
1011 ((drm_r300_cmd_header_t*)r300->hw.tex.format.cmd)->unchecked_state.count = max_texture_unit+1;
1012 ((drm_r300_cmd_header_t*)r300->hw.tex.offset.cmd)->unchecked_state.count = max_texture_unit+1;
1013 ((drm_r300_cmd_header_t*)r300->hw.tex.unknown4.cmd)->unchecked_state.count = max_texture_unit+1;
1014 ((drm_r300_cmd_header_t*)r300->hw.tex.unknown5.cmd)->unchecked_state.count = max_texture_unit+1;
1016 if (RADEON_DEBUG & DEBUG_STATE)
1017 fprintf(stderr, "TX_ENABLE: %08x max_texture_unit=%d\n", r300->hw.txe.cmd[R300_TXE_ENABLE], max_texture_unit);
1020 void r300_setup_rs_unit(GLcontext *ctx)
1022 r300ContextPtr r300 = R300_CONTEXT(ctx);
1025 /* This needs to be rewritten - it is a hack at best */
1027 R300_STATECHANGE(r300, ri);
1028 R300_STATECHANGE(r300, rc);
1029 R300_STATECHANGE(r300, rr);
1031 for(i = 1; i <= 8; ++i)
1032 r300->hw.ri.cmd[i] = 0x00d10000;
1033 r300->hw.ri.cmd[R300_RI_INTERP_1] |= R300_RS_INTERP_1_UNKNOWN;
1034 r300->hw.ri.cmd[R300_RI_INTERP_2] |= R300_RS_INTERP_2_UNKNOWN;
1035 r300->hw.ri.cmd[R300_RI_INTERP_3] |= R300_RS_INTERP_3_UNKNOWN;
1037 for(i = 1; i <= 8; ++i)
1038 r300->hw.rr.cmd[i] = 0;
1039 /* textures enabled ? */
1040 if(r300->state.texture.tc_count>0){
1042 /* This code only really works with one set of texture coordinates */
1044 /* The second constant is needed to get glxgears display anything .. */
1045 r300->hw.rc.cmd[1] = R300_RS_CNTL_0_UNKNOWN_7
1046 | R300_RS_CNTL_0_UNKNOWN_18
1047 | (r300->state.texture.tc_count<<R300_RS_CNTL_TC_CNT_SHIFT);
1048 r300->hw.rc.cmd[2] = 0xc0;
1051 ((drm_r300_cmd_header_t*)r300->hw.rr.cmd)->unchecked_state.count = 1;
1052 r300->hw.rr.cmd[R300_RR_ROUTE_0] = 0x24008;
1056 /* The second constant is needed to get glxgears display anything .. */
1057 r300->hw.rc.cmd[1] = R300_RS_CNTL_0_UNKNOWN_7 | R300_RS_CNTL_0_UNKNOWN_18;
1058 r300->hw.rc.cmd[2] = 0;
1060 ((drm_r300_cmd_header_t*)r300->hw.rr.cmd)->unchecked_state.count = 1;
1061 r300->hw.rr.cmd[R300_RR_ROUTE_0] = 0x4000;
1066 #define vpucount(ptr) (((drm_r300_cmd_header_t*)(ptr))->vpu.count)
1068 #define bump_vpu_count(ptr, new_count) do{\
1069 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
1070 int _nc=(new_count)/4; \
1071 if(_nc>_p->vpu.count)_p->vpu.count=_nc;\
1074 void static inline setup_vertex_shader_fragment(r300ContextPtr r300, int dest, struct r300_vertex_shader_fragment *vsf)
1078 if(vsf->length==0)return;
1080 if(vsf->length & 0x3){
1081 fprintf(stderr,"VERTEX_SHADER_FRAGMENT must have length divisible by 4\n");
1085 switch((dest>>8) & 0xf){
1087 R300_STATECHANGE(r300, vpi);
1088 for(i=0;i<vsf->length;i++)
1089 r300->hw.vpi.cmd[R300_VPI_INSTR_0+i+4*(dest & 0xff)]=(vsf->body.d[i]);
1090 bump_vpu_count(r300->hw.vpi.cmd, vsf->length+4*(dest & 0xff));
1094 R300_STATECHANGE(r300, vpp);
1095 for(i=0;i<vsf->length;i++)
1096 r300->hw.vpp.cmd[R300_VPP_PARAM_0+i+4*(dest & 0xff)]=(vsf->body.d[i]);
1097 bump_vpu_count(r300->hw.vpp.cmd, vsf->length+4*(dest & 0xff));
1100 R300_STATECHANGE(r300, vps);
1101 for(i=0;i<vsf->length;i++)
1102 r300->hw.vps.cmd[1+i+4*(dest & 0xff)]=(vsf->body.d[i]);
1103 bump_vpu_count(r300->hw.vps.cmd, vsf->length+4*(dest & 0xff));
1106 fprintf(stderr, "%s:%s don't know how to handle dest %04x\n", __FILE__, __FUNCTION__, dest);
1112 #include "r300_lib.h"
1114 void r300SetupVertexShader(r300ContextPtr rmesa)
1116 GLcontext* ctx = rmesa->radeon.glCtx;
1118 /* Reset state, in case we don't use something */
1119 ((drm_r300_cmd_header_t*)rmesa->hw.vpp.cmd)->vpu.count = 0;
1120 ((drm_r300_cmd_header_t*)rmesa->hw.vpi.cmd)->vpu.count = 0;
1121 ((drm_r300_cmd_header_t*)rmesa->hw.vps.cmd)->vpu.count = 0;
1124 /* This needs to be replaced by vertex shader generation code */
1127 /* Watch out ! This is buggy .. but will do for now */
1129 /* At least one sanity check is in order */
1130 if(sizeof(rmesa->state.vertex_shader) != sizeof(FLAT_COLOR_PIPELINE.vertex_shader)){
1131 fprintf(stderr, "Aieee ! vertex_shader sizes don't match.\n");
1134 /* textures enabled ? */
1135 if(rmesa->state.texture.tc_count>0){
1136 memcpy(&rmesa->state.vertex_shader, &(SINGLE_TEXTURE_PIPELINE.vertex_shader), sizeof(rmesa->state.vertex_shader));
1138 memcpy(&rmesa->state.vertex_shader, &(FLAT_COLOR_PIPELINE.vertex_shader), sizeof(rmesa->state.vertex_shader));
1142 rmesa->state.vertex_shader.matrix[0].length=16;
1143 memcpy(rmesa->state.vertex_shader.matrix[0].body.f, ctx->_ModelProjectMatrix.m, 16*4);
1145 setup_vertex_shader_fragment(rmesa, VSF_DEST_PROGRAM, &(rmesa->state.vertex_shader.program));
1147 setup_vertex_shader_fragment(rmesa, VSF_DEST_MATRIX0, &(rmesa->state.vertex_shader.matrix[0]));
1149 setup_vertex_shader_fragment(rmesa, VSF_DEST_MATRIX1, &(rmesa->state.vertex_shader.matrix[0]));
1150 setup_vertex_shader_fragment(rmesa, VSF_DEST_MATRIX2, &(rmesa->state.vertex_shader.matrix[0]));
1152 setup_vertex_shader_fragment(rmesa, VSF_DEST_VECTOR0, &(rmesa->state.vertex_shader.vector[0]));
1153 setup_vertex_shader_fragment(rmesa, VSF_DEST_VECTOR1, &(rmesa->state.vertex_shader.vector[1]));
1157 setup_vertex_shader_fragment(rmesa, VSF_DEST_UNKNOWN1, &(rmesa->state.vertex_shader.unknown1));
1158 setup_vertex_shader_fragment(rmesa, VSF_DEST_UNKNOWN2, &(rmesa->state.vertex_shader.unknown2));
1161 R300_STATECHANGE(rmesa, pvs);
1162 rmesa->hw.pvs.cmd[R300_PVS_CNTL_1]=(rmesa->state.vertex_shader.program_start << R300_PVS_CNTL_1_PROGRAM_START_SHIFT)
1163 | (rmesa->state.vertex_shader.unknown_ptr1 << R300_PVS_CNTL_1_UNKNOWN_SHIFT)
1164 | (rmesa->state.vertex_shader.program_end << R300_PVS_CNTL_1_PROGRAM_END_SHIFT);
1165 rmesa->hw.pvs.cmd[R300_PVS_CNTL_2]=(rmesa->state.vertex_shader.param_offset << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT)
1166 | (rmesa->state.vertex_shader.param_count << R300_PVS_CNTL_2_PARAM_COUNT_SHIFT);
1167 rmesa->hw.pvs.cmd[R300_PVS_CNTL_3]=(rmesa->state.vertex_shader.unknown_ptr2 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT)
1168 | (rmesa->state.vertex_shader.unknown_ptr3 << 0);
1170 /* This is done for vertex shader fragments, but also needs to be done for vap_pvs,
1171 so I leave it as a reminder */
1173 reg_start(R300_VAP_PVS_WAITIDLE,0);
1178 void r300SetupPixelShader(r300ContextPtr rmesa)
1182 /* This needs to be replaced by pixel shader generation code */
1185 /* Watch out ! This is buggy .. but will do for now */
1187 /* At least one sanity check is in order */
1188 if(sizeof(rmesa->state.pixel_shader) != sizeof(FLAT_COLOR_PIPELINE.pixel_shader)){
1189 fprintf(stderr, "Aieee ! pixel_shader sizes don't match.\n");
1192 /* textures enabled ? */
1193 if(rmesa->state.texture.tc_count>0){
1194 memcpy(&rmesa->state.pixel_shader, &(SINGLE_TEXTURE_PIPELINE.pixel_shader), sizeof(rmesa->state.pixel_shader));
1196 memcpy(&rmesa->state.pixel_shader, &(FLAT_COLOR_PIPELINE.pixel_shader), sizeof(rmesa->state.pixel_shader));
1199 R300_STATECHANGE(rmesa, fpt);
1200 for(i=0;i<rmesa->state.pixel_shader.program.tex.length;i++)
1201 rmesa->hw.fpt.cmd[R300_FPT_INSTR_0+i]=rmesa->state.pixel_shader.program.tex.inst[i];
1202 rmesa->hw.fpt.cmd[R300_FPT_CMD_0]=cmducs(R300_PFS_TEXI_0, rmesa->state.pixel_shader.program.tex.length);
1204 #define OUTPUT_FIELD(st, reg, field) \
1205 R300_STATECHANGE(rmesa, st); \
1206 for(i=0;i<rmesa->state.pixel_shader.program.alu.length;i++) \
1207 rmesa->hw.st.cmd[R300_FPI_INSTR_0+i]=rmesa->state.pixel_shader.program.alu.inst[i].field;\
1208 rmesa->hw.st.cmd[R300_FPI_CMD_0]=cmducs(reg, rmesa->state.pixel_shader.program.alu.length);
1210 OUTPUT_FIELD(fpi[0], R300_PFS_INSTR0_0, inst0);
1211 OUTPUT_FIELD(fpi[1], R300_PFS_INSTR1_0, inst1);
1212 OUTPUT_FIELD(fpi[2], R300_PFS_INSTR2_0, inst2);
1213 OUTPUT_FIELD(fpi[3], R300_PFS_INSTR3_0, inst3);
1216 R300_STATECHANGE(rmesa, fp);
1218 rmesa->hw.fp.cmd[R300_FP_NODE0+i]=
1219 (rmesa->state.pixel_shader.program.node[i].alu_offset << R300_PFS_NODE_ALU_OFFSET_SHIFT)
1220 | (rmesa->state.pixel_shader.program.node[i].alu_end << R300_PFS_NODE_ALU_END_SHIFT)
1221 | (rmesa->state.pixel_shader.program.node[i].tex_offset << R300_PFS_NODE_TEX_OFFSET_SHIFT)
1222 | (rmesa->state.pixel_shader.program.node[i].tex_end << R300_PFS_NODE_TEX_END_SHIFT)
1223 | ( (i==3) ? R300_PFS_NODE_LAST_NODE : 0);
1227 rmesa->hw.fp.cmd[R300_FP_CNTL0]=
1228 (rmesa->state.pixel_shader.program.active_nodes-1)
1229 | (rmesa->state.pixel_shader.program.first_node_has_tex<<3);
1231 rmesa->hw.fp.cmd[R300_FP_CNTL1]=rmesa->state.pixel_shader.program.temp_register_count;
1233 rmesa->hw.fp.cmd[R300_FP_CNTL2]=
1234 (rmesa->state.pixel_shader.program.alu_offset << R300_PFS_CNTL_ALU_OFFSET_SHIFT)
1235 | (rmesa->state.pixel_shader.program.alu_end << R300_PFS_CNTL_ALU_END_SHIFT)
1236 | (rmesa->state.pixel_shader.program.tex_offset << R300_PFS_CNTL_TEX_OFFSET_SHIFT)
1237 | (rmesa->state.pixel_shader.program.tex_end << R300_PFS_CNTL_TEX_END_SHIFT);
1239 R300_STATECHANGE(rmesa, fpp);
1240 for(i=0;i<rmesa->state.pixel_shader.param_length;i++){
1241 rmesa->hw.fpp.cmd[R300_FPP_PARAM_0+4*i+0]=r300PackFloat32(rmesa->state.pixel_shader.param[i].x);
1242 rmesa->hw.fpp.cmd[R300_FPP_PARAM_0+4*i+1]=r300PackFloat32(rmesa->state.pixel_shader.param[i].y);
1243 rmesa->hw.fpp.cmd[R300_FPP_PARAM_0+4*i+2]=r300PackFloat32(rmesa->state.pixel_shader.param[i].z);
1244 rmesa->hw.fpp.cmd[R300_FPP_PARAM_0+4*i+3]=r300PackFloat32(rmesa->state.pixel_shader.param[i].w);
1246 rmesa->hw.fpp.cmd[R300_FPP_CMD_0]=cmducs(R300_PFS_PARAM_0_X, rmesa->state.pixel_shader.param_length);
1251 * Called by Mesa after an internal state update.
1253 static void r300InvalidateState(GLcontext * ctx, GLuint new_state)
1255 r300ContextPtr r300 = R300_CONTEXT(ctx);
1257 _swrast_InvalidateState(ctx, new_state);
1258 _swsetup_InvalidateState(ctx, new_state);
1259 _ac_InvalidateState(ctx, new_state);
1260 _tnl_InvalidateState(ctx, new_state);
1261 _ae_invalidate_state(ctx, new_state);
1263 /* Go inefficiency! */
1264 r300ResetHwState(r300);
1269 * Completely recalculates hardware state based on the Mesa state.
1271 void r300ResetHwState(r300ContextPtr r300)
1273 GLcontext* ctx = r300->radeon.glCtx;
1276 if (RADEON_DEBUG & DEBUG_STATE)
1277 fprintf(stderr, "%s\n", __FUNCTION__);
1279 r300UpdateWindow(ctx);
1282 ctx->Color.ColorMask[RCOMP],
1283 ctx->Color.ColorMask[GCOMP],
1284 ctx->Color.ColorMask[BCOMP],
1285 ctx->Color.ColorMask[ACOMP]);
1287 r300Enable(ctx, GL_DEPTH_TEST, ctx->Depth.Test);
1288 r300DepthMask(ctx, ctx->Depth.Mask);
1289 r300DepthFunc(ctx, ctx->Depth.Func);
1291 r300UpdateCulling(ctx);
1293 r300_setup_routing(ctx, GL_TRUE);
1295 r300UpdateTextureState(ctx);
1296 r300_setup_textures(ctx);
1297 r300_setup_rs_unit(ctx);
1299 r300SetupVertexShader(r300);
1300 r300SetupPixelShader(r300);
1302 r300_set_blend_state(ctx);
1303 r300AlphaFunc(ctx, ctx->Color.AlphaFunc, ctx->Color.AlphaRef);
1306 r300->hw.unk2080.cmd[1] = 0x0030045A;
1308 r300->hw.ovf.cmd[R300_OVF_FMT_0] = 0x00000003;
1309 r300->hw.ovf.cmd[R300_OVF_FMT_1] = 0x00000000;
1311 r300->hw.vte.cmd[1] = R300_VPORT_X_SCALE_ENA
1312 | R300_VPORT_X_OFFSET_ENA
1313 | R300_VPORT_Y_SCALE_ENA
1314 | R300_VPORT_Y_OFFSET_ENA
1315 | R300_VPORT_Z_SCALE_ENA
1316 | R300_VPORT_Z_OFFSET_ENA
1318 r300->hw.vte.cmd[2] = 0x00000008;
1320 r300->hw.unk2134.cmd[1] = 0x00FFFFFF;
1321 r300->hw.unk2134.cmd[2] = 0x00000000;
1323 r300->hw.unk2140.cmd[1] = 0x00000000;
1325 #if 0 /* Done in setup routing */
1326 ((drm_r300_cmd_header_t*)r300->hw.vir[0].cmd)->unchecked_state.count = 1;
1327 r300->hw.vir[0].cmd[1] = 0x21030003;
1329 ((drm_r300_cmd_header_t*)r300->hw.vir[1].cmd)->unchecked_state.count = 1;
1330 r300->hw.vir[1].cmd[1] = 0xF688F688;
1332 r300->hw.vic.cmd[R300_VIR_CNTL_0] = 0x00000001;
1333 r300->hw.vic.cmd[R300_VIR_CNTL_1] = 0x00000405;
1336 r300->hw.unk21DC.cmd[1] = 0xAAAAAAAA;
1338 r300->hw.unk221C.cmd[1] = R300_221C_NORMAL;
1340 r300->hw.unk2220.cmd[1] = r300PackFloat32(1.0);
1341 r300->hw.unk2220.cmd[2] = r300PackFloat32(1.0);
1342 r300->hw.unk2220.cmd[3] = r300PackFloat32(1.0);
1343 r300->hw.unk2220.cmd[4] = r300PackFloat32(1.0);
1345 if (GET_CHIP(r300->radeon.radeonScreen) == RADEON_CHIP_R300)
1346 r300->hw.unk2288.cmd[1] = R300_2288_R300;
1348 r300->hw.unk2288.cmd[1] = R300_2288_RV350;
1351 r300->hw.vof.cmd[R300_VOF_CNTL_0] = R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
1352 | R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT;
1353 r300->hw.vof.cmd[R300_VOF_CNTL_1] = 0; /* no textures */
1356 r300->hw.pvs.cmd[R300_PVS_CNTL_1] = 0;
1357 r300->hw.pvs.cmd[R300_PVS_CNTL_2] = 0;
1358 r300->hw.pvs.cmd[R300_PVS_CNTL_3] = 0;
1361 r300->hw.gb_enable.cmd[1] = R300_GB_POINT_STUFF_ENABLE
1362 | R300_GB_LINE_STUFF_ENABLE
1363 | R300_GB_TRIANGLE_STUFF_ENABLE;
1365 r300->hw.gb_misc.cmd[R300_GB_MISC_MSPOS_0] = 0x66666666;
1366 r300->hw.gb_misc.cmd[R300_GB_MISC_MSPOS_1] = 0x06666666;
1367 if (GET_CHIP(r300->radeon.radeonScreen) == RADEON_CHIP_R300)
1368 r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] = R300_GB_TILE_ENABLE
1369 | R300_GB_TILE_PIPE_COUNT_R300
1370 | R300_GB_TILE_SIZE_16;
1372 r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] = R300_GB_TILE_ENABLE
1373 | R300_GB_TILE_PIPE_COUNT_RV300
1374 | R300_GB_TILE_SIZE_16;
1375 r300->hw.gb_misc.cmd[R300_GB_MISC_SELECT] = 0x00000000;
1376 r300->hw.gb_misc.cmd[R300_GB_MISC_AA_CONFIG] = 0x00000000; /* No antialiasing */
1378 //r300->hw.txe.cmd[R300_TXE_ENABLE] = 0;
1380 r300->hw.unk4200.cmd[1] = r300PackFloat32(0.0);
1381 r300->hw.unk4200.cmd[2] = r300PackFloat32(0.0);
1382 r300->hw.unk4200.cmd[3] = r300PackFloat32(1.0);
1383 r300->hw.unk4200.cmd[4] = r300PackFloat32(1.0);
1385 r300->hw.unk4214.cmd[1] = 0x00050005;
1387 r300->hw.ps.cmd[R300_PS_POINTSIZE] = (6 << R300_POINTSIZE_X_SHIFT) |
1388 (6 << R300_POINTSIZE_Y_SHIFT);
1390 r300->hw.unk4230.cmd[1] = 0x01800000;
1391 r300->hw.unk4230.cmd[2] = 0x00020006;
1392 r300->hw.unk4230.cmd[3] = r300PackFloat32(1.0 / 192.0);
1394 r300->hw.unk4260.cmd[1] = 0;
1395 r300->hw.unk4260.cmd[2] = r300PackFloat32(0.0);
1396 r300->hw.unk4260.cmd[3] = r300PackFloat32(1.0);
1398 r300->hw.unk4274.cmd[1] = 0x00000002;
1399 r300->hw.unk4274.cmd[2] = 0x0003AAAA;
1400 r300->hw.unk4274.cmd[3] = 0x00000000;
1401 r300->hw.unk4274.cmd[4] = 0x00000000;
1403 r300->hw.unk4288.cmd[1] = 0x00000000;
1404 r300->hw.unk4288.cmd[2] = 0x00000001;
1405 r300->hw.unk4288.cmd[3] = 0x00000000;
1406 r300->hw.unk4288.cmd[4] = 0x00000000;
1407 r300->hw.unk4288.cmd[5] = 0x00000000;
1409 r300->hw.unk42A0.cmd[1] = 0x00000000;
1411 r300->hw.unk42B4.cmd[1] = 0x00000000;
1413 r300->hw.unk42C0.cmd[1] = 0x4B7FFFFF;
1414 r300->hw.unk42C0.cmd[2] = 0x00000000;
1417 r300->hw.unk43A4.cmd[1] = 0x0000001C;
1418 r300->hw.unk43A4.cmd[2] = 0x2DA49525;
1420 r300->hw.unk43E8.cmd[1] = 0x00FFFFFF;
1423 r300->hw.fp.cmd[R300_FP_CNTL0] = 0;
1424 r300->hw.fp.cmd[R300_FP_CNTL1] = 0;
1425 r300->hw.fp.cmd[R300_FP_CNTL2] = 0;
1426 r300->hw.fp.cmd[R300_FP_NODE0] = 0;
1427 r300->hw.fp.cmd[R300_FP_NODE1] = 0;
1428 r300->hw.fp.cmd[R300_FP_NODE2] = 0;
1429 r300->hw.fp.cmd[R300_FP_NODE3] = 0;
1432 r300->hw.unk46A4.cmd[1] = 0x00001B01;
1433 r300->hw.unk46A4.cmd[2] = 0x00001B0F;
1434 r300->hw.unk46A4.cmd[3] = 0x00001B0F;
1435 r300->hw.unk46A4.cmd[4] = 0x00001B0F;
1436 r300->hw.unk46A4.cmd[5] = 0x00000001;
1439 for(i = 1; i <= 64; ++i) {
1440 /* create NOP instructions */
1441 r300->hw.fpi[0].cmd[i] = FP_INSTRC(MAD, FP_ARGC(SRC0C_XYZ), FP_ARGC(ONE), FP_ARGC(ZERO));
1442 r300->hw.fpi[1].cmd[i] = FP_SELC(0,XYZ,NO,FP_TMP(0),0,0);
1443 r300->hw.fpi[2].cmd[i] = FP_INSTRA(MAD, FP_ARGA(SRC0A), FP_ARGA(ONE), FP_ARGA(ZERO));
1444 r300->hw.fpi[3].cmd[i] = FP_SELA(0,W,NO,FP_TMP(0),0,0);
1448 r300->hw.unk4BC0.cmd[1] = 0;
1450 r300->hw.unk4BC8.cmd[1] = 0;
1451 r300->hw.unk4BC8.cmd[2] = 0;
1452 r300->hw.unk4BC8.cmd[3] = 0;
1455 r300->hw.at.cmd[R300_AT_ALPHA_TEST] = 0;
1458 r300->hw.unk4BD8.cmd[1] = 0;
1460 r300->hw.unk4E00.cmd[1] = 0;
1463 r300->hw.bld.cmd[R300_BLD_CBLEND] = 0;
1464 r300->hw.bld.cmd[R300_BLD_ABLEND] = 0;
1467 r300->hw.unk4E10.cmd[1] = 0;
1468 r300->hw.unk4E10.cmd[2] = 0;
1469 r300->hw.unk4E10.cmd[3] = 0;
1471 r300->hw.cb.cmd[R300_CB_OFFSET] =
1472 r300->radeon.radeonScreen->backOffset +
1473 r300->radeon.radeonScreen->fbLocation;
1474 r300->hw.cb.cmd[R300_CB_PITCH] = r300->radeon.radeonScreen->backPitch
1475 | R300_COLOR_UNKNOWN_22_23;
1477 r300->hw.unk4E50.cmd[1] = 0;
1478 r300->hw.unk4E50.cmd[2] = 0;
1479 r300->hw.unk4E50.cmd[3] = 0;
1480 r300->hw.unk4E50.cmd[4] = 0;
1481 r300->hw.unk4E50.cmd[5] = 0;
1482 r300->hw.unk4E50.cmd[6] = 0;
1483 r300->hw.unk4E50.cmd[7] = 0;
1484 r300->hw.unk4E50.cmd[8] = 0;
1485 r300->hw.unk4E50.cmd[9] = 0;
1487 r300->hw.unk4E88.cmd[1] = 0;
1489 r300->hw.unk4EA0.cmd[1] = 0x00000000;
1490 r300->hw.unk4EA0.cmd[2] = 0xffffffff;
1492 r300->hw.unk4F08.cmd[1] = 0x00FFFF00;
1494 r300->hw.unk4F10.cmd[1] = 0x00000002; // depthbuffer format?
1495 r300->hw.unk4F10.cmd[2] = 0x00000000;
1496 r300->hw.unk4F10.cmd[3] = 0x00000003;
1497 r300->hw.unk4F10.cmd[4] = 0x00000000;
1499 r300->hw.zb.cmd[R300_ZB_OFFSET] =
1500 r300->radeon.radeonScreen->depthOffset +
1501 r300->radeon.radeonScreen->fbLocation;
1502 r300->hw.zb.cmd[R300_ZB_PITCH] = r300->radeon.radeonScreen->depthPitch;
1504 r300->hw.unk4F28.cmd[1] = 0;
1506 r300->hw.unk4F30.cmd[1] = 0;
1507 r300->hw.unk4F30.cmd[2] = 0;
1509 r300->hw.unk4F44.cmd[1] = 0;
1511 r300->hw.unk4F54.cmd[1] = 0;
1514 ((drm_r300_cmd_header_t*)r300->hw.vpi.cmd)->vpu.count = 0;
1515 for(i = 1; i < R300_VPI_CMDSIZE; i += 4) {
1517 r300->hw.vpi.cmd[i+0] = VP_OUT(ADD,TMP,0,XYZW);
1518 r300->hw.vpi.cmd[i+1] = VP_IN(TMP,0);
1519 r300->hw.vpi.cmd[i+2] = VP_ZERO();
1520 r300->hw.vpi.cmd[i+3] = VP_ZERO();
1523 ((drm_r300_cmd_header_t*)r300->hw.vpp.cmd)->vpu.count = 0;
1524 for(i = 1; i < R300_VPP_CMDSIZE; ++i)
1525 r300->hw.vpp.cmd[i] = 0;
1528 r300->hw.vps.cmd[R300_VPS_ZERO_0] = 0;
1529 r300->hw.vps.cmd[R300_VPS_ZERO_1] = 0;
1530 r300->hw.vps.cmd[R300_VPS_POINTSIZE] = r300PackFloat32(1.0);
1531 r300->hw.vps.cmd[R300_VPS_ZERO_3] = 0;
1535 r300->hw.all_dirty = GL_TRUE;
1541 * Calculate initial hardware state and register state functions.
1542 * Assumes that the command buffer and state atoms have been
1543 * initialized already.
1545 void r300InitState(r300ContextPtr r300)
1547 GLcontext *ctx = r300->radeon.glCtx;
1550 radeonInitState(&r300->radeon);
1552 switch (ctx->Visual.depthBits) {
1554 r300->state.depth.scale = 1.0 / (GLfloat) 0xffff;
1555 depth_fmt = R200_DEPTH_FORMAT_16BIT_INT_Z;
1556 //r300->state.stencil.clear = 0x00000000;
1559 r300->state.depth.scale = 1.0 / (GLfloat) 0xffffff;
1560 depth_fmt = R200_DEPTH_FORMAT_24BIT_INT_Z;
1561 //r300->state.stencil.clear = 0xff000000;
1564 fprintf(stderr, "Error: Unsupported depth %d... exiting\n",
1565 ctx->Visual.depthBits);
1569 memset(&(r300->state.texture), 0, sizeof(r300->state.texture));
1571 r300ResetHwState(r300);
1577 * Initialize driver's state callback functions
1579 void r300InitStateFuncs(struct dd_function_table* functions)
1581 radeonInitStateFuncs(functions);
1583 functions->UpdateState = r300InvalidateState;
1584 //functions->AlphaFunc = r300AlphaFunc;
1585 functions->BlendColor = r300BlendColor;
1586 functions->BlendEquationSeparate = r300BlendEquationSeparate;
1587 functions->BlendFuncSeparate = r300BlendFuncSeparate;
1588 functions->Enable = r300Enable;
1589 functions->ColorMask = r300ColorMask;
1590 functions->DepthFunc = r300DepthFunc;
1591 functions->DepthMask = r300DepthMask;
1592 functions->CullFace = r300CullFace;
1593 functions->FrontFace = r300FrontFace;
1595 /* Viewport related */
1596 functions->Viewport = r300Viewport;
1597 functions->DepthRange = r300DepthRange;
1598 functions->PointSize = r300PointSize;