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;
104 * Update our tracked culling state based on Mesa's state.
106 static void r300UpdateCulling(GLcontext* ctx)
108 r300ContextPtr r300 = R300_CONTEXT(ctx);
111 R300_STATECHANGE(r300, cul);
112 if (ctx->Polygon.CullFlag) {
113 if (ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK)
114 val = R300_CULL_FRONT|R300_CULL_BACK;
115 else if (ctx->Polygon.CullFaceMode == GL_FRONT)
116 val = R300_CULL_FRONT;
118 val = R300_CULL_BACK;
120 if (ctx->Polygon.FrontFace == GL_CW)
121 val |= R300_FRONT_FACE_CW;
123 val |= R300_FRONT_FACE_CCW;
126 r300->hw.cul.cmd[R300_CUL_CULL] = val;
131 * Handle glEnable()/glDisable().
133 * \note Mesa already filters redundant calls to glEnable/glDisable.
135 static void r300Enable(GLcontext* ctx, GLenum cap, GLboolean state)
137 r300ContextPtr r300 = R300_CONTEXT(ctx);
140 if (RADEON_DEBUG & DEBUG_STATE)
141 fprintf(stderr, "%s( %s = %s )\n", __FUNCTION__,
142 _mesa_lookup_enum_by_nr(cap),
143 state ? "GL_TRUE" : "GL_FALSE");
147 R300_STATECHANGE(r300, zc);
151 newval = R300_RB3D_Z_TEST_AND_WRITE;
153 newval = R300_RB3D_Z_TEST;
157 r300->hw.zc.cmd[R300_ZC_CNTL_0] = newval;
161 r300UpdateCulling(ctx);
165 radeonEnable(ctx, cap, state);
172 * Change the culling mode.
174 * \note Mesa already filters redundant calls to this function.
176 static void r300CullFace(GLcontext* ctx, GLenum mode)
180 r300UpdateCulling(ctx);
185 * Change the polygon orientation.
187 * \note Mesa already filters redundant calls to this function.
189 static void r300FrontFace(GLcontext* ctx, GLenum mode)
193 r300UpdateCulling(ctx);
198 * Change the depth testing function.
200 * \note Mesa already filters redundant calls to this function.
202 static void r300DepthFunc(GLcontext* ctx, GLenum func)
204 r300ContextPtr r300 = R300_CONTEXT(ctx);
206 R300_STATECHANGE(r300, zc);
210 r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_NEVER;
213 r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_LESS;
216 r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_EQUAL;
219 r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_LEQUAL;
222 r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_GREATER;
225 r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_NEQUAL;
228 r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_GEQUAL;
231 r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_ALWAYS;
238 * Enable/Disable depth writing.
240 * \note Mesa already filters redundant calls to this function.
242 static void r300DepthMask(GLcontext* ctx, GLboolean mask)
244 r300ContextPtr r300 = R300_CONTEXT(ctx);
246 if (!ctx->Depth.Test)
249 R300_STATECHANGE(r300, zc);
250 r300->hw.zc.cmd[R300_ZC_CNTL_0] = mask
251 ? R300_RB3D_Z_TEST_AND_WRITE : R300_RB3D_Z_TEST;
256 * Handle glColorMask()
258 static void r300ColorMask(GLcontext* ctx,
259 GLboolean r, GLboolean g, GLboolean b, GLboolean a)
261 r300ContextPtr r300 = R300_CONTEXT(ctx);
262 int mask = (b << 0) | (g << 1) | (r << 2) | (a << 3);
264 if (mask != r300->hw.cmk.cmd[R300_CMK_COLORMASK]) {
265 R300_STATECHANGE(r300, cmk);
266 r300->hw.cmk.cmd[R300_CMK_COLORMASK] = mask;
270 /* =============================================================
273 static void r300PointSize(GLcontext * ctx, GLfloat size)
275 r300ContextPtr r300 = R300_CONTEXT(ctx);
277 /* This might need fixing later */
278 R300_STATECHANGE(r300, vps);
279 r300->hw.vps.cmd[R300_VPS_POINTSIZE] = r300PackFloat32(1.0);
282 /* =============================================================
283 * Window position and viewport transformation
287 * To correctly position primitives:
289 #define SUBPIXEL_X 0.125
290 #define SUBPIXEL_Y 0.125
292 void r300UpdateWindow(GLcontext * ctx)
294 r300ContextPtr rmesa = R300_CONTEXT(ctx);
295 __DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable;
296 GLfloat xoffset = dPriv ? (GLfloat) dPriv->x : 0;
297 GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0;
298 const GLfloat *v = ctx->Viewport._WindowMap.m;
300 GLfloat sx = v[MAT_SX];
301 GLfloat tx = v[MAT_TX] + xoffset + SUBPIXEL_X;
302 GLfloat sy = -v[MAT_SY];
303 GLfloat ty = (-v[MAT_TY]) + yoffset + SUBPIXEL_Y;
304 GLfloat sz = v[MAT_SZ] * rmesa->state.depth.scale;
305 GLfloat tz = v[MAT_TZ] * rmesa->state.depth.scale;
307 R300_FIREVERTICES(rmesa);
308 R300_STATECHANGE(rmesa, vpt);
310 rmesa->hw.vpt.cmd[R300_VPT_XSCALE] = r300PackFloat32(sx);
311 rmesa->hw.vpt.cmd[R300_VPT_XOFFSET] = r300PackFloat32(tx);
312 rmesa->hw.vpt.cmd[R300_VPT_YSCALE] = r300PackFloat32(sy);
313 rmesa->hw.vpt.cmd[R300_VPT_YOFFSET] = r300PackFloat32(ty);
314 rmesa->hw.vpt.cmd[R300_VPT_ZSCALE] = r300PackFloat32(sz);
315 rmesa->hw.vpt.cmd[R300_VPT_ZOFFSET] = r300PackFloat32(tz);
318 static void r300Viewport(GLcontext * ctx, GLint x, GLint y,
319 GLsizei width, GLsizei height)
321 /* Don't pipeline viewport changes, conflict with window offset
322 * setting below. Could apply deltas to rescue pipelined viewport
323 * values, or keep the originals hanging around.
325 R200_FIREVERTICES(R200_CONTEXT(ctx));
326 r300UpdateWindow(ctx);
329 static void r300DepthRange(GLcontext * ctx, GLclampd nearval, GLclampd farval)
331 r300UpdateWindow(ctx);
334 /* Routing and texture-related */
336 void r300_setup_routing(GLcontext *ctx, GLboolean immediate)
338 int i, count=0,reg=0;
340 TNLcontext *tnl = TNL_CONTEXT(ctx);
341 struct vertex_buffer *VB = &tnl->vb;
342 r300ContextPtr r300 = R300_CONTEXT(ctx);
345 /* Stage 1 - input to VAP */
347 /* Assign register number automatically, retaining it in rmesa->state.reg */
349 /* Note: immediate vertex data includes all coordinates.
350 To save bandwidth use either VBUF or state-based vertex generation */
352 #define CONFIGURE_AOS(v, o, r, f) \
355 r300->state.aos[count].element_size=4; \
356 r300->state.aos[count].stride=4; \
357 r300->state.aos[count].ncomponents=4; \
359 r300->state.aos[count].element_size=v->size; \
360 r300->state.aos[count].stride=v->size; \
361 r300->state.aos[count].ncomponents=v->size; \
363 r300->state.aos[count].offset=o; \
364 r300->state.aos[count].reg=reg; \
365 r300->state.aos[count].format=(f); \
366 r300->state.vap_reg.r=reg; \
371 /* All offsets are 0 - for use by immediate mode.
372 Should change later to handle vertex buffers */
373 CONFIGURE_AOS(VB->ObjPtr, 0, i_coords, AOS_FORMAT_FLOAT);
374 CONFIGURE_AOS(VB->ColorPtr[0], 0, i_color[0], AOS_FORMAT_FLOAT_COLOR);
375 for(i=0;i < ctx->Const.MaxTextureUnits;i++)
376 if(ctx->Texture.Unit[i].Enabled)
377 CONFIGURE_AOS(VB->TexCoordPtr[i], 0, i_tex[i], AOS_FORMAT_FLOAT);
379 r300->state.aos_count=count;
381 if (RADEON_DEBUG & DEBUG_STATE)
382 fprintf(stderr, "aos_count=%d\n", count);
384 if(count>R300_MAX_AOS_ARRAYS){
385 fprintf(stderr, "Aieee ! AOS array count exceeded !\n");
391 /* setup INPUT_ROUTE */
392 R300_STATECHANGE(r300, vir[0]);
393 for(i=0;i+1<count;i+=2){
394 dw=(r300->state.aos[i].ncomponents-1)
395 | ((r300->state.aos[i].reg)<<8)
396 | (r300->state.aos[i].format<<14)
397 | (((r300->state.aos[i+1].ncomponents-1)
398 | ((r300->state.aos[i+1].reg)<<8)
399 | (r300->state.aos[i+1].format<<14))<<16);
404 r300->hw.vir[0].cmd[R300_VIR_CNTL_0+(i>>1)]=dw;
407 dw=(r300->state.aos[count-1].ncomponents-1)
408 | (r300->state.aos[count-1].format<<14)
409 | ((r300->state.aos[count-1].reg)<<8)
411 r300->hw.vir[0].cmd[R300_VIR_CNTL_0+(count>>1)]=dw;
412 //fprintf(stderr, "vir0 dw=%08x\n", dw);
414 /* Set the rest of INPUT_ROUTE_0 to 0 */
415 //for(i=((count+1)>>1); i<8; i++)r300->hw.vir[0].cmd[R300_VIR_CNTL_0+i]=(0x0);
416 ((drm_r300_cmd_header_t*)r300->hw.vir[0].cmd)->unchecked_state.count = (count+1)>>1;
419 /* Mesa assumes that all missing components are from (0, 0, 0, 1) */
420 #define ALL_COMPONENTS ((R300_INPUT_ROUTE_SELECT_X<<R300_INPUT_ROUTE_X_SHIFT) \
421 | (R300_INPUT_ROUTE_SELECT_Y<<R300_INPUT_ROUTE_Y_SHIFT) \
422 | (R300_INPUT_ROUTE_SELECT_Z<<R300_INPUT_ROUTE_Z_SHIFT) \
423 | (R300_INPUT_ROUTE_SELECT_W<<R300_INPUT_ROUTE_W_SHIFT))
425 #define ALL_DEFAULT ((R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_X_SHIFT) \
426 | (R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_Y_SHIFT) \
427 | (R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_Z_SHIFT) \
428 | (R300_INPUT_ROUTE_SELECT_ONE<<R300_INPUT_ROUTE_W_SHIFT))
430 R300_STATECHANGE(r300, vir[1]);
432 for(i=0;i+1<count;i+=2){
434 mask=(1<<(r300->state.aos[i].ncomponents*3))-1;
435 dw=(ALL_COMPONENTS & mask)
436 | (ALL_DEFAULT & ~mask)
437 | R300_INPUT_ROUTE_ENABLE;
440 mask=(1<<(r300->state.aos[i+1].ncomponents*3))-1;
442 (ALL_COMPONENTS & mask)
443 | (ALL_DEFAULT & ~mask)
444 | R300_INPUT_ROUTE_ENABLE
447 r300->hw.vir[1].cmd[R300_VIR_CNTL_0+(i>>1)]=dw;
450 mask=(1<<(r300->state.aos[count-1].ncomponents*3))-1;
451 dw=(ALL_COMPONENTS & mask)
452 | (ALL_DEFAULT & ~mask)
453 | R300_INPUT_ROUTE_ENABLE;
454 r300->hw.vir[1].cmd[R300_VIR_CNTL_0+(count>>1)]=dw;
455 //fprintf(stderr, "vir1 dw=%08x\n", dw);
457 /* Set the rest of INPUT_ROUTE_1 to 0 */
458 //for(i=((count+1)>>1); i<8; i++)r300->hw.vir[1].cmd[R300_VIR_CNTL_0+i]=0x0;
459 ((drm_r300_cmd_header_t*)r300->hw.vir[1].cmd)->unchecked_state.count = (count+1)>>1;
461 /* Set up input_cntl */
463 R300_STATECHANGE(r300, vic);
464 r300->hw.vic.cmd[R300_VIC_CNTL_0]=0x5555; /* Hard coded value, no idea what it means */
466 r300->hw.vic.cmd[R300_VIC_CNTL_1]=R300_INPUT_CNTL_POS
467 | R300_INPUT_CNTL_COLOR;
469 for(i=0;i < ctx->Const.MaxTextureUnits;i++)
470 if(ctx->Texture.Unit[i].Enabled)
471 r300->hw.vic.cmd[R300_VIC_CNTL_1]|=(R300_INPUT_CNTL_TC0<<i);
473 /* Stage 3: VAP output */
474 R300_STATECHANGE(r300, vof);
475 r300->hw.vof.cmd[R300_VOF_CNTL_0]=R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
476 | R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT;
478 r300->hw.vof.cmd[R300_VOF_CNTL_1]=0;
479 for(i=0;i < ctx->Const.MaxTextureUnits;i++)
480 if(ctx->Texture.Unit[i].Enabled)
481 r300->hw.vof.cmd[R300_VOF_CNTL_1]|=(4<<(3*i));
485 static r300TexObj default_tex_obj={
486 filter:R300_TX_MAG_FILTER_LINEAR | R300_TX_MIN_FILTER_LINEAR,
488 size: (0xff << R300_TX_WIDTHMASK_SHIFT)
489 | (0xff << R300_TX_HEIGHTMASK_SHIFT)
490 | (0x8 << R300_TX_SIZE_SHIFT),
497 void r300_setup_textures(GLcontext *ctx)
500 struct r300_tex_obj *t;
501 r300ContextPtr r300 = R300_CONTEXT(ctx);
502 int max_texture_unit=-1; /* -1 translates into no setup costs for fields */
504 R300_STATECHANGE(r300, txe);
505 R300_STATECHANGE(r300, tex.filter);
506 R300_STATECHANGE(r300, tex.unknown1);
507 R300_STATECHANGE(r300, tex.size);
508 R300_STATECHANGE(r300, tex.format);
509 R300_STATECHANGE(r300, tex.offset);
510 R300_STATECHANGE(r300, tex.unknown4);
511 R300_STATECHANGE(r300, tex.unknown5);
513 r300->state.texture.tc_count=0;
515 r300->hw.txe.cmd[R300_TXE_ENABLE]=0x0;
517 mtu = r300->radeon.glCtx->Const.MaxTextureUnits;
518 if (RADEON_DEBUG & DEBUG_STATE)
519 fprintf(stderr, "mtu=%d\n", mtu);
521 if(mtu>R300_MAX_TEXTURE_UNITS){
522 fprintf(stderr, "Aiiee ! mtu=%d is greater than R300_MAX_TEXTURE_UNITS=%d\n",
523 mtu, R300_MAX_TEXTURE_UNITS);
527 if(ctx->Texture.Unit[i].Enabled!=NULL){
528 t=r300->state.texture.unit[i].texobj;
529 r300->state.texture.tc_count++;
531 fprintf(stderr, "Texture unit %d enabled, but corresponding texobj is NULL, using default object.\n", i);
535 if (RADEON_DEBUG & DEBUG_STATE)
536 fprintf(stderr, "Activating texture unit %d\n", i);
538 r300->hw.txe.cmd[R300_TXE_ENABLE]|=(1<<i);
540 r300->hw.tex.filter.cmd[R300_TEX_VALUE_0+i]=t->filter;
541 r300->hw.tex.unknown1.cmd[R300_TEX_VALUE_0+i]=t->pitch;
542 r300->hw.tex.size.cmd[R300_TEX_VALUE_0+i]=t->size;
543 r300->hw.tex.format.cmd[R300_TEX_VALUE_0+i]=t->format;
544 r300->hw.tex.offset.cmd[R300_TEX_VALUE_0+i]=r300->radeon.radeonScreen->fbLocation+t->offset;
545 r300->hw.tex.unknown4.cmd[R300_TEX_VALUE_0+i]=0x0;
546 r300->hw.tex.unknown5.cmd[R300_TEX_VALUE_0+i]=0x0;
548 /* We don't know how to set this yet */
549 r300->hw.tex.format.cmd[R300_TEX_VALUE_0+i]=0x88a0c;
552 /* Fill in with 0's */
553 #if 0 /* No need.. */
554 r300->hw.tex.filter.cmd[R300_TEX_VALUE_0+i]=0x0;
555 r300->hw.tex.unknown1.cmd[R300_TEX_VALUE_0+i]=0x0;
556 r300->hw.tex.size.cmd[R300_TEX_VALUE_0+i]=0x0;
557 r300->hw.tex.format.cmd[R300_TEX_VALUE_0+i]=0x0;
558 r300->hw.tex.offset.cmd[R300_TEX_VALUE_0+i]=r300->radeon.radeonScreen->fbLocation;
559 r300->hw.tex.unknown4.cmd[R300_TEX_VALUE_0+i]=0x0;
560 r300->hw.tex.unknown5.cmd[R300_TEX_VALUE_0+i]=0x0;
565 ((drm_r300_cmd_header_t*)r300->hw.tex.filter.cmd)->unchecked_state.count = max_texture_unit+1;
566 ((drm_r300_cmd_header_t*)r300->hw.tex.unknown1.cmd)->unchecked_state.count = max_texture_unit+1;
567 ((drm_r300_cmd_header_t*)r300->hw.tex.size.cmd)->unchecked_state.count = max_texture_unit+1;
568 ((drm_r300_cmd_header_t*)r300->hw.tex.format.cmd)->unchecked_state.count = max_texture_unit+1;
569 ((drm_r300_cmd_header_t*)r300->hw.tex.offset.cmd)->unchecked_state.count = max_texture_unit+1;
570 ((drm_r300_cmd_header_t*)r300->hw.tex.unknown4.cmd)->unchecked_state.count = max_texture_unit+1;
571 ((drm_r300_cmd_header_t*)r300->hw.tex.unknown5.cmd)->unchecked_state.count = max_texture_unit+1;
573 if (RADEON_DEBUG & DEBUG_STATE)
574 fprintf(stderr, "TX_ENABLE: %08x max_texture_unit=%d\n", r300->hw.txe.cmd[R300_TXE_ENABLE], max_texture_unit);
577 void r300_setup_rs_unit(GLcontext *ctx)
579 r300ContextPtr r300 = R300_CONTEXT(ctx);
582 /* This needs to be rewritten - it is a hack at best */
584 R300_STATECHANGE(r300, ri);
585 R300_STATECHANGE(r300, rc);
586 R300_STATECHANGE(r300, rr);
588 for(i = 1; i <= 8; ++i)
589 r300->hw.ri.cmd[i] = 0x00d10000;
590 r300->hw.ri.cmd[R300_RI_INTERP_1] |= R300_RS_INTERP_1_UNKNOWN;
591 r300->hw.ri.cmd[R300_RI_INTERP_2] |= R300_RS_INTERP_2_UNKNOWN;
592 r300->hw.ri.cmd[R300_RI_INTERP_3] |= R300_RS_INTERP_3_UNKNOWN;
594 for(i = 1; i <= 8; ++i)
595 r300->hw.rr.cmd[i] = 0;
596 /* textures enabled ? */
597 if(r300->state.texture.tc_count>0){
599 /* This code only really works with one set of texture coordinates */
601 /* The second constant is needed to get glxgears display anything .. */
602 r300->hw.rc.cmd[1] = R300_RS_CNTL_0_UNKNOWN_7
603 | R300_RS_CNTL_0_UNKNOWN_18
604 | (r300->state.texture.tc_count<<R300_RS_CNTL_TC_CNT_SHIFT);
605 r300->hw.rc.cmd[2] = 0xc0;
608 ((drm_r300_cmd_header_t*)r300->hw.rr.cmd)->unchecked_state.count = 1;
609 r300->hw.rr.cmd[R300_RR_ROUTE_0] = 0x24008;
613 /* The second constant is needed to get glxgears display anything .. */
614 r300->hw.rc.cmd[1] = R300_RS_CNTL_0_UNKNOWN_7 | R300_RS_CNTL_0_UNKNOWN_18;
615 r300->hw.rc.cmd[2] = 0;
617 ((drm_r300_cmd_header_t*)r300->hw.rr.cmd)->unchecked_state.count = 1;
618 r300->hw.rr.cmd[R300_RR_ROUTE_0] = 0x4000;
624 * Called by Mesa after an internal state update.
626 static void r300InvalidateState(GLcontext * ctx, GLuint new_state)
628 r300ContextPtr r300 = R300_CONTEXT(ctx);
630 _swrast_InvalidateState(ctx, new_state);
631 _swsetup_InvalidateState(ctx, new_state);
632 _ac_InvalidateState(ctx, new_state);
633 _tnl_InvalidateState(ctx, new_state);
634 _ae_invalidate_state(ctx, new_state);
636 /* Go inefficiency! */
637 r300ResetHwState(r300);
642 * Completely recalculates hardware state based on the Mesa state.
644 void r300ResetHwState(r300ContextPtr r300)
646 GLcontext* ctx = r300->radeon.glCtx;
649 if (RADEON_DEBUG & DEBUG_STATE)
650 fprintf(stderr, "%s\n", __FUNCTION__);
652 r300UpdateWindow(ctx);
655 ctx->Color.ColorMask[RCOMP],
656 ctx->Color.ColorMask[GCOMP],
657 ctx->Color.ColorMask[BCOMP],
658 ctx->Color.ColorMask[ACOMP]);
660 r300Enable(ctx, GL_DEPTH_TEST, ctx->Depth.Test);
661 r300DepthMask(ctx, ctx->Depth.Mask);
662 r300DepthFunc(ctx, ctx->Depth.Func);
664 r300UpdateCulling(ctx);
666 r300_setup_routing(ctx, GL_TRUE);
668 r300UpdateTextureState(ctx);
669 r300_setup_textures(ctx);
670 r300_setup_rs_unit(ctx);
673 r300->hw.unk2080.cmd[1] = 0x0030045A;
675 r300->hw.ovf.cmd[R300_OVF_FMT_0] = 0x00000003;
676 r300->hw.ovf.cmd[R300_OVF_FMT_1] = 0x00000000;
678 r300->hw.vte.cmd[1] = R300_VPORT_X_SCALE_ENA
679 | R300_VPORT_X_OFFSET_ENA
680 | R300_VPORT_Y_SCALE_ENA
681 | R300_VPORT_Y_OFFSET_ENA
682 | R300_VPORT_Z_SCALE_ENA
683 | R300_VPORT_Z_OFFSET_ENA
685 r300->hw.vte.cmd[2] = 0x00000008;
687 r300->hw.unk2134.cmd[1] = 0x00FFFFFF;
688 r300->hw.unk2134.cmd[2] = 0x00000000;
690 r300->hw.unk2140.cmd[1] = 0x00000000;
692 #if 0 /* Done in setup routing */
693 ((drm_r300_cmd_header_t*)r300->hw.vir[0].cmd)->unchecked_state.count = 1;
694 r300->hw.vir[0].cmd[1] = 0x21030003;
696 ((drm_r300_cmd_header_t*)r300->hw.vir[1].cmd)->unchecked_state.count = 1;
697 r300->hw.vir[1].cmd[1] = 0xF688F688;
699 r300->hw.vic.cmd[R300_VIR_CNTL_0] = 0x00000001;
700 r300->hw.vic.cmd[R300_VIR_CNTL_1] = 0x00000405;
703 r300->hw.unk21DC.cmd[1] = 0xAAAAAAAA;
705 r300->hw.unk221C.cmd[1] = R300_221C_NORMAL;
707 r300->hw.unk2220.cmd[1] = r300PackFloat32(1.0);
708 r300->hw.unk2220.cmd[2] = r300PackFloat32(1.0);
709 r300->hw.unk2220.cmd[3] = r300PackFloat32(1.0);
710 r300->hw.unk2220.cmd[4] = r300PackFloat32(1.0);
712 if (GET_CHIP(r300->radeon.radeonScreen) == RADEON_CHIP_R300)
713 r300->hw.unk2288.cmd[1] = R300_2288_R300;
715 r300->hw.unk2288.cmd[1] = R300_2288_RV350;
718 r300->hw.vof.cmd[R300_VOF_CNTL_0] = R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
719 | R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT;
720 r300->hw.vof.cmd[R300_VOF_CNTL_1] = 0; /* no textures */
723 r300->hw.pvs.cmd[R300_PVS_CNTL_1] = 0;
724 r300->hw.pvs.cmd[R300_PVS_CNTL_2] = 0;
725 r300->hw.pvs.cmd[R300_PVS_CNTL_3] = 0;
727 r300->hw.gb_enable.cmd[1] = R300_GB_POINT_STUFF_ENABLE
728 | R300_GB_LINE_STUFF_ENABLE
729 | R300_GB_TRIANGLE_STUFF_ENABLE;
731 r300->hw.gb_misc.cmd[R300_GB_MISC_MSPOS_0] = 0x66666666;
732 r300->hw.gb_misc.cmd[R300_GB_MISC_MSPOS_1] = 0x06666666;
733 if (GET_CHIP(r300->radeon.radeonScreen) == RADEON_CHIP_R300)
734 r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] = R300_GB_TILE_ENABLE
735 | R300_GB_TILE_PIPE_COUNT_R300
736 | R300_GB_TILE_SIZE_16;
738 r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] = R300_GB_TILE_ENABLE
739 | R300_GB_TILE_PIPE_COUNT_RV300
740 | R300_GB_TILE_SIZE_16;
741 r300->hw.gb_misc.cmd[R300_GB_MISC_SELECT] = 0x00000000;
742 r300->hw.gb_misc.cmd[R300_GB_MISC_AA_CONFIG] = 0x00000000; /* No antialiasing */
744 //r300->hw.txe.cmd[R300_TXE_ENABLE] = 0;
746 r300->hw.unk4200.cmd[1] = r300PackFloat32(0.0);
747 r300->hw.unk4200.cmd[2] = r300PackFloat32(0.0);
748 r300->hw.unk4200.cmd[3] = r300PackFloat32(1.0);
749 r300->hw.unk4200.cmd[4] = r300PackFloat32(1.0);
751 r300->hw.unk4214.cmd[1] = 0x00050005;
753 r300->hw.ps.cmd[R300_PS_POINTSIZE] = (6 << R300_POINTSIZE_X_SHIFT) |
754 (6 << R300_POINTSIZE_Y_SHIFT);
756 r300->hw.unk4230.cmd[1] = 0x01800000;
757 r300->hw.unk4230.cmd[2] = 0x00020006;
758 r300->hw.unk4230.cmd[3] = r300PackFloat32(1.0 / 192.0);
760 r300->hw.unk4260.cmd[1] = 0;
761 r300->hw.unk4260.cmd[2] = r300PackFloat32(0.0);
762 r300->hw.unk4260.cmd[3] = r300PackFloat32(1.0);
764 r300->hw.unk4274.cmd[1] = 0x00000002;
765 r300->hw.unk4274.cmd[2] = 0x0003AAAA;
766 r300->hw.unk4274.cmd[3] = 0x00000000;
767 r300->hw.unk4274.cmd[4] = 0x00000000;
769 r300->hw.unk4288.cmd[1] = 0x00000000;
770 r300->hw.unk4288.cmd[2] = 0x00000001;
771 r300->hw.unk4288.cmd[3] = 0x00000000;
772 r300->hw.unk4288.cmd[4] = 0x00000000;
773 r300->hw.unk4288.cmd[5] = 0x00000000;
775 r300->hw.unk42A0.cmd[1] = 0x00000000;
777 r300->hw.unk42B4.cmd[1] = 0x00000000;
779 r300->hw.unk42C0.cmd[1] = 0x4B7FFFFF;
780 r300->hw.unk42C0.cmd[2] = 0x00000000;
783 r300->hw.unk43A4.cmd[1] = 0x0000001C;
784 r300->hw.unk43A4.cmd[2] = 0x2DA49525;
786 r300->hw.unk43E8.cmd[1] = 0x00FFFFFF;
788 r300->hw.fp.cmd[R300_FP_CNTL0] = 0;
789 r300->hw.fp.cmd[R300_FP_CNTL1] = 0;
790 r300->hw.fp.cmd[R300_FP_CNTL2] = 0;
791 r300->hw.fp.cmd[R300_FP_NODE0] = 0;
792 r300->hw.fp.cmd[R300_FP_NODE1] = 0;
793 r300->hw.fp.cmd[R300_FP_NODE2] = 0;
794 r300->hw.fp.cmd[R300_FP_NODE3] = 0;
796 r300->hw.unk46A4.cmd[1] = 0x00001B01;
797 r300->hw.unk46A4.cmd[2] = 0x00001B0F;
798 r300->hw.unk46A4.cmd[3] = 0x00001B0F;
799 r300->hw.unk46A4.cmd[4] = 0x00001B0F;
800 r300->hw.unk46A4.cmd[5] = 0x00000001;
802 for(i = 1; i <= 64; ++i) {
803 /* create NOP instructions */
804 r300->hw.fpi[0].cmd[i] = FP_INSTRC(MAD, FP_ARGC(SRC0C_XYZ), FP_ARGC(ONE), FP_ARGC(ZERO));
805 r300->hw.fpi[1].cmd[i] = FP_SELC(0,XYZ,NO,FP_TMP(0),0,0);
806 r300->hw.fpi[2].cmd[i] = FP_INSTRA(MAD, FP_ARGA(SRC0A), FP_ARGA(ONE), FP_ARGA(ZERO));
807 r300->hw.fpi[3].cmd[i] = FP_SELA(0,W,NO,FP_TMP(0),0,0);
810 r300->hw.unk4BC0.cmd[1] = 0;
812 r300->hw.unk4BC8.cmd[1] = 0;
813 r300->hw.unk4BC8.cmd[2] = 0;
814 r300->hw.unk4BC8.cmd[3] = 0;
816 r300->hw.at.cmd[R300_AT_ALPHA_TEST] = 0;
818 r300->hw.unk4BD8.cmd[1] = 0;
820 r300->hw.unk4E00.cmd[1] = 0;
822 r300->hw.bld.cmd[R300_BLD_CBLEND] = 0;
823 r300->hw.bld.cmd[R300_BLD_ABLEND] = 0;
825 r300->hw.unk4E10.cmd[1] = 0;
826 r300->hw.unk4E10.cmd[2] = 0;
827 r300->hw.unk4E10.cmd[3] = 0;
829 r300->hw.cb.cmd[R300_CB_OFFSET] =
830 r300->radeon.radeonScreen->backOffset +
831 r300->radeon.radeonScreen->fbLocation;
832 r300->hw.cb.cmd[R300_CB_PITCH] = r300->radeon.radeonScreen->backPitch
833 | R300_COLOR_UNKNOWN_22_23;
835 r300->hw.unk4E50.cmd[1] = 0;
836 r300->hw.unk4E50.cmd[2] = 0;
837 r300->hw.unk4E50.cmd[3] = 0;
838 r300->hw.unk4E50.cmd[4] = 0;
839 r300->hw.unk4E50.cmd[5] = 0;
840 r300->hw.unk4E50.cmd[6] = 0;
841 r300->hw.unk4E50.cmd[7] = 0;
842 r300->hw.unk4E50.cmd[8] = 0;
843 r300->hw.unk4E50.cmd[9] = 0;
845 r300->hw.unk4E88.cmd[1] = 0;
847 r300->hw.unk4EA0.cmd[1] = 0x00000000;
848 r300->hw.unk4EA0.cmd[2] = 0xffffffff;
850 r300->hw.unk4F08.cmd[1] = 0x00FFFF00;
852 r300->hw.unk4F10.cmd[1] = 0x00000002; // depthbuffer format?
853 r300->hw.unk4F10.cmd[2] = 0x00000000;
854 r300->hw.unk4F10.cmd[3] = 0x00000003;
855 r300->hw.unk4F10.cmd[4] = 0x00000000;
857 r300->hw.zb.cmd[R300_ZB_OFFSET] =
858 r300->radeon.radeonScreen->depthOffset +
859 r300->radeon.radeonScreen->fbLocation;
860 r300->hw.zb.cmd[R300_ZB_PITCH] = r300->radeon.radeonScreen->depthPitch;
862 r300->hw.unk4F28.cmd[1] = 0;
864 r300->hw.unk4F30.cmd[1] = 0;
865 r300->hw.unk4F30.cmd[2] = 0;
867 r300->hw.unk4F44.cmd[1] = 0;
869 r300->hw.unk4F54.cmd[1] = 0;
871 ((drm_r300_cmd_header_t*)r300->hw.vpi.cmd)->vpu.count = 0;
872 for(i = 1; i < R300_VPI_CMDSIZE; i += 4) {
874 r300->hw.vpi.cmd[i+0] = VP_OUT(ADD,TMP,0,XYZW);
875 r300->hw.vpi.cmd[i+1] = VP_IN(TMP,0);
876 r300->hw.vpi.cmd[i+2] = VP_ZERO();
877 r300->hw.vpi.cmd[i+3] = VP_ZERO();
880 ((drm_r300_cmd_header_t*)r300->hw.vpp.cmd)->vpu.count = 0;
881 for(i = 1; i < R300_VPP_CMDSIZE; ++i)
882 r300->hw.vpp.cmd[i] = 0;
884 r300->hw.vps.cmd[R300_VPS_ZERO_0] = 0;
885 r300->hw.vps.cmd[R300_VPS_ZERO_1] = 0;
886 r300->hw.vps.cmd[R300_VPS_POINTSIZE] = r300PackFloat32(1.0);
887 r300->hw.vps.cmd[R300_VPS_ZERO_3] = 0;
891 r300->hw.all_dirty = GL_TRUE;
897 * Calculate initial hardware state and register state functions.
898 * Assumes that the command buffer and state atoms have been
899 * initialized already.
901 void r300InitState(r300ContextPtr r300)
903 GLcontext *ctx = r300->radeon.glCtx;
906 radeonInitState(&r300->radeon);
908 switch (ctx->Visual.depthBits) {
910 r300->state.depth.scale = 1.0 / (GLfloat) 0xffff;
911 depth_fmt = R200_DEPTH_FORMAT_16BIT_INT_Z;
912 //r300->state.stencil.clear = 0x00000000;
915 r300->state.depth.scale = 1.0 / (GLfloat) 0xffffff;
916 depth_fmt = R200_DEPTH_FORMAT_24BIT_INT_Z;
917 //r300->state.stencil.clear = 0xff000000;
920 fprintf(stderr, "Error: Unsupported depth %d... exiting\n",
921 ctx->Visual.depthBits);
925 memset(&(r300->state.texture), 0, sizeof(r300->state.texture));
927 r300ResetHwState(r300);
933 * Initialize driver's state callback functions
935 void r300InitStateFuncs(struct dd_function_table* functions)
937 radeonInitStateFuncs(functions);
939 functions->UpdateState = r300InvalidateState;
940 functions->AlphaFunc = r300AlphaFunc;
941 functions->Enable = r300Enable;
942 functions->ColorMask = r300ColorMask;
943 functions->DepthFunc = r300DepthFunc;
944 functions->DepthMask = r300DepthMask;
945 functions->CullFace = r300CullFace;
946 functions->FrontFace = r300FrontFace;
948 /* Viewport related */
949 functions->Viewport = r300Viewport;
950 functions->DepthRange = r300DepthRange;
951 functions->PointSize = r300PointSize;