Port code from r200 that implements color blending. Seems to work.
[profile/ivi/mesa.git] / src / mesa / drivers / dri / r300 / r300_state.c
1 /*
2 Copyright (C) The Weather Channel, Inc.  2002.
3 Copyright (C) 2004 Nicolai Haehnle.
4 All Rights Reserved.
5
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.
9
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:
17
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.
21
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.
29
30 **************************************************************************/
31
32 /*
33  * Authors:
34  *   Nicolai Haehnle <prefect_@gmx.net>
35  */
36
37 #include "glheader.h"
38 #include "state.h"
39 #include "imports.h"
40 #include "enums.h"
41 #include "macros.h"
42 #include "context.h"
43 #include "dd.h"
44 #include "simple_list.h"
45
46 #include "api_arrayelt.h"
47 #include "swrast/swrast.h"
48 #include "swrast_setup/swrast_setup.h"
49 #include "array_cache/acache.h"
50 #include "tnl/tnl.h"
51
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"
57 #include "r300_reg.h"
58 #include "r300_program.h"
59
60 static void r300AlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref)
61 {
62         r300ContextPtr rmesa = R300_CONTEXT(ctx);
63         int pp_misc = rmesa->hw.at.cmd[R300_AT_ALPHA_TEST];
64         GLubyte refByte;
65
66         CLAMPED_FLOAT_TO_UBYTE(refByte, ref);
67
68         R300_STATECHANGE(rmesa, at);
69
70         pp_misc &= ~(R300_ALPHA_TEST_OP_MASK | R300_REF_ALPHA_MASK);
71         pp_misc |= (refByte & R300_REF_ALPHA_MASK);
72
73         switch (func) {
74         case GL_NEVER:
75                 pp_misc |= R300_ALPHA_TEST_FAIL;
76                 break;
77         case GL_LESS:
78                 pp_misc |= R300_ALPHA_TEST_LESS;
79                 break;
80         case GL_EQUAL:
81                 pp_misc |= R300_ALPHA_TEST_EQUAL;
82                 break;
83         case GL_LEQUAL:
84                 pp_misc |= R300_ALPHA_TEST_LEQUAL;
85                 break;
86         case GL_GREATER:
87                 pp_misc |= R300_ALPHA_TEST_GREATER;
88                 break;
89         case GL_NOTEQUAL:
90                 pp_misc |= R300_ALPHA_TEST_NEQUAL;
91                 break;
92         case GL_GEQUAL:
93                 pp_misc |= R300_ALPHA_TEST_GEQUAL;
94                 break;
95         case GL_ALWAYS:
96                 pp_misc |= R300_ALPHA_TEST_PASS;
97                 break;
98         }
99
100         rmesa->hw.at.cmd[R300_AT_ALPHA_TEST] = pp_misc;
101 }
102
103 static void r300BlendColor(GLcontext * ctx, const GLfloat cf[4])
104 {
105         GLubyte color[4];
106         r300ContextPtr rmesa = R300_CONTEXT(ctx);
107         fprintf(stderr, "%s:%s is not implemented yet. Fixme !\n", __FILE__, __FUNCTION__);
108         #if 0
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]);
117         #endif
118 }
119
120 /**
121  * Calculate the hardware blend factor setting.  This same function is used
122  * for source and destination of both alpha and RGB.
123  *
124  * \returns
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.
128  *
129  * \todo
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.
133  */
134 static int blend_factor(GLenum factor, GLboolean is_src)
135 {
136         int func;
137
138         switch (factor) {
139         case GL_ZERO:
140                 func = R200_BLEND_GL_ZERO;
141                 break;
142         case GL_ONE:
143                 func = R200_BLEND_GL_ONE;
144                 break;
145         case GL_DST_COLOR:
146                 func = R200_BLEND_GL_DST_COLOR;
147                 break;
148         case GL_ONE_MINUS_DST_COLOR:
149                 func = R200_BLEND_GL_ONE_MINUS_DST_COLOR;
150                 break;
151         case GL_SRC_COLOR:
152                 func = R200_BLEND_GL_SRC_COLOR;
153                 break;
154         case GL_ONE_MINUS_SRC_COLOR:
155                 func = R200_BLEND_GL_ONE_MINUS_SRC_COLOR;
156                 break;
157         case GL_SRC_ALPHA:
158                 func = R200_BLEND_GL_SRC_ALPHA;
159                 break;
160         case GL_ONE_MINUS_SRC_ALPHA:
161                 func = R200_BLEND_GL_ONE_MINUS_SRC_ALPHA;
162                 break;
163         case GL_DST_ALPHA:
164                 func = R200_BLEND_GL_DST_ALPHA;
165                 break;
166         case GL_ONE_MINUS_DST_ALPHA:
167                 func = R200_BLEND_GL_ONE_MINUS_DST_ALPHA;
168                 break;
169         case GL_SRC_ALPHA_SATURATE:
170                 func =
171                     (is_src) ? R200_BLEND_GL_SRC_ALPHA_SATURATE :
172                     R200_BLEND_GL_ZERO;
173                 break;
174         case GL_CONSTANT_COLOR:
175                 func = R200_BLEND_GL_CONST_COLOR;
176                 break;
177         case GL_ONE_MINUS_CONSTANT_COLOR:
178                 func = R200_BLEND_GL_ONE_MINUS_CONST_COLOR;
179                 break;
180         case GL_CONSTANT_ALPHA:
181                 func = R200_BLEND_GL_CONST_ALPHA;
182                 break;
183         case GL_ONE_MINUS_CONSTANT_ALPHA:
184                 func = R200_BLEND_GL_ONE_MINUS_CONST_ALPHA;
185                 break;
186         default:
187                 func = (is_src) ? R200_BLEND_GL_ONE : R200_BLEND_GL_ZERO;
188         }
189         return func;
190 }
191
192 /**
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
200  * unknown reasons.
201  */
202 static void r300_set_blend_state(GLcontext * ctx)
203 {
204         r300ContextPtr rmesa = R300_CONTEXT(ctx);
205         #if 0
206         GLuint cntl = rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &
207             ~(R300_ROP_ENABLE | R300_ALPHA_BLEND_ENABLE |
208               R300_SEPARATE_ALPHA_ENABLE);
209         #endif
210
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;
217
218         R300_STATECHANGE(rmesa, bld);
219
220         if (rmesa->radeon.radeonScreen->drmSupportsBlendColor) {
221                 if (ctx->Color._LogicOpEnabled) {
222                         #if 0
223                         rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] =
224                             cntl | R300_ROP_ENABLE;
225                         #endif
226                         rmesa->hw.bld.cmd[R300_BLD_ABLEND] = eqn | func;
227                         rmesa->hw.bld.cmd[R300_BLD_CBLEND] = eqn | func;
228                         return;
229                 } else if (ctx->Color.BlendEnabled) {
230                         #if 0
231                         rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] =
232                             cntl | R300_ALPHA_BLEND_ENABLE |
233                             R300_SEPARATE_ALPHA_ENABLE;
234                         #endif
235                 } else {
236                         #if 0
237                         rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = cntl;
238                         #endif
239                         rmesa->hw.bld.cmd[R300_BLD_ABLEND] = eqn | func;
240                         rmesa->hw.bld.cmd[R300_BLD_CBLEND] = eqn | func;
241                         return;
242                 }
243         } else {
244                 if (ctx->Color._LogicOpEnabled) {
245                         #if 0
246                         rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] =
247                             cntl | R300_ROP_ENABLE;
248                         rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = eqn | func;
249                         #endif
250                         return;
251                 } else if (ctx->Color.BlendEnabled) {
252                         #if 0
253                         rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] =
254                             cntl | R300_ALPHA_BLEND_ENABLE;
255                         #endif
256                 } else {
257                         #if 0
258                         rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = cntl;
259                         rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = eqn | func;
260                         #endif
261                         return;
262                 }
263         }
264
265         func =
266             (blend_factor(ctx->Color.BlendSrcRGB, GL_TRUE) <<
267              R200_SRC_BLEND_SHIFT) | (blend_factor(ctx->Color.BlendDstRGB,
268                                                    GL_FALSE) <<
269                                       R200_DST_BLEND_SHIFT);
270
271         switch (ctx->Color.BlendEquationRGB) {
272         case GL_FUNC_ADD:
273                 eqn = R300_COMB_FCN_ADD_CLAMP;
274                 break;
275
276         case GL_FUNC_SUBTRACT:
277                 eqn = R300_COMB_FCN_SUB_CLAMP;
278                 break;
279
280         case GL_FUNC_REVERSE_SUBTRACT:
281                 eqn = R200_COMB_FCN_RSUB_CLAMP;
282                 break;
283
284         case GL_MIN:
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);
288                 break;
289
290         case GL_MAX:
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);
294                 break;
295
296         default:
297                 fprintf(stderr,
298                         "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
299                         __func__, __LINE__, ctx->Color.BlendEquationRGB);
300                 return;
301         }
302
303         if (!rmesa->radeon.radeonScreen->drmSupportsBlendColor) {
304                 #if 0
305                 rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = eqn | func;
306                 #endif
307                 return;
308         }
309
310         funcA =
311             (blend_factor(ctx->Color.BlendSrcA, GL_TRUE) <<
312              R200_SRC_BLEND_SHIFT) | (blend_factor(ctx->Color.BlendDstA,
313                                                    GL_FALSE) <<
314                                       R200_DST_BLEND_SHIFT);
315
316         switch (ctx->Color.BlendEquationA) {
317         case GL_FUNC_ADD:
318                 eqnA = R300_COMB_FCN_ADD_CLAMP;
319                 break;
320
321         case GL_FUNC_SUBTRACT:
322                 eqnA = R300_COMB_FCN_SUB_CLAMP;
323                 break;
324
325         case GL_FUNC_REVERSE_SUBTRACT:
326                 eqnA = R200_COMB_FCN_RSUB_CLAMP;
327                 break;
328
329         case GL_MIN:
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);
333                 break;
334
335         case GL_MAX:
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);
339                 break;
340
341         default:
342                 fprintf(stderr, "[%s:%u] Invalid A blend equation (0x%04x).\n",
343                         __func__, __LINE__, ctx->Color.BlendEquationA);
344                 return;
345         }
346
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;
351                 } else {
352                 rmesa->hw.bld.cmd[R300_BLD_CBLEND] |= R300_BLEND_UNKNOWN | R300_BLEND_ENABLE;
353                 }
354
355 }
356
357 static void r300BlendEquationSeparate(GLcontext * ctx,
358                                       GLenum modeRGB, GLenum modeA)
359 {
360         r300_set_blend_state(ctx);
361 }
362
363 static void r300BlendFuncSeparate(GLcontext * ctx,
364                                   GLenum sfactorRGB, GLenum dfactorRGB,
365                                   GLenum sfactorA, GLenum dfactorA)
366 {
367         r300_set_blend_state(ctx);
368 }
369
370 /**
371  * Update our tracked culling state based on Mesa's state.
372  */
373 static void r300UpdateCulling(GLcontext* ctx)
374 {
375         r300ContextPtr r300 = R300_CONTEXT(ctx);
376         uint32_t val = 0;
377
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;
384                 else
385                         val = R300_CULL_BACK;
386
387                 if (ctx->Polygon.FrontFace == GL_CW)
388                         val |= R300_FRONT_FACE_CW;
389                 else
390                         val |= R300_FRONT_FACE_CCW;
391         }
392
393         r300->hw.cul.cmd[R300_CUL_CULL] = val;
394 }
395
396
397 /**
398  * Handle glEnable()/glDisable().
399  *
400  * \note Mesa already filters redundant calls to glEnable/glDisable.
401  */
402 static void r300Enable(GLcontext* ctx, GLenum cap, GLboolean state)
403 {
404         r300ContextPtr r300 = R300_CONTEXT(ctx);
405         uint32_t newval;
406
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");
411
412         switch (cap) {
413         case GL_DEPTH_TEST:
414                 R300_STATECHANGE(r300, zc);
415
416                 if (state) {
417                         if (ctx->Depth.Mask)
418                                 newval = R300_RB3D_Z_TEST_AND_WRITE;
419                         else
420                                 newval = R300_RB3D_Z_TEST;
421                 } else
422                         newval = 0;
423
424                 r300->hw.zc.cmd[R300_ZC_CNTL_0] = newval;
425                 break;
426
427         case GL_CULL_FACE:
428                 r300UpdateCulling(ctx);
429                 break;
430
431         default:
432                 radeonEnable(ctx, cap, state);
433                 return;
434         }
435 }
436
437
438 /**
439  * Change the culling mode.
440  *
441  * \note Mesa already filters redundant calls to this function.
442  */
443 static void r300CullFace(GLcontext* ctx, GLenum mode)
444 {
445         (void)mode;
446
447         r300UpdateCulling(ctx);
448 }
449
450
451 /**
452  * Change the polygon orientation.
453  *
454  * \note Mesa already filters redundant calls to this function.
455  */
456 static void r300FrontFace(GLcontext* ctx, GLenum mode)
457 {
458         (void)mode;
459
460         r300UpdateCulling(ctx);
461 }
462
463
464 /**
465  * Change the depth testing function.
466  *
467  * \note Mesa already filters redundant calls to this function.
468  */
469 static void r300DepthFunc(GLcontext* ctx, GLenum func)
470 {
471         r300ContextPtr r300 = R300_CONTEXT(ctx);
472
473         R300_STATECHANGE(r300, zc);
474
475         switch(func) {
476         case GL_NEVER:
477                 r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_NEVER;
478                 break;
479         case GL_LESS:
480                 r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_LESS;
481                 break;
482         case GL_EQUAL:
483                 r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_EQUAL;
484                 break;
485         case GL_LEQUAL:
486                 r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_LEQUAL;
487                 break;
488         case GL_GREATER:
489                 r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_GREATER;
490                 break;
491         case GL_NOTEQUAL:
492                 r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_NEQUAL;
493                 break;
494         case GL_GEQUAL:
495                 r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_GEQUAL;
496                 break;
497         case GL_ALWAYS:
498                 r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_ALWAYS;
499                 break;
500         }
501 }
502
503
504 /**
505  * Enable/Disable depth writing.
506  *
507  * \note Mesa already filters redundant calls to this function.
508  */
509 static void r300DepthMask(GLcontext* ctx, GLboolean mask)
510 {
511         r300ContextPtr r300 = R300_CONTEXT(ctx);
512
513         if (!ctx->Depth.Test)
514                 return;
515
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;
519 }
520
521
522 /**
523  * Handle glColorMask()
524  */
525 static void r300ColorMask(GLcontext* ctx,
526                           GLboolean r, GLboolean g, GLboolean b, GLboolean a)
527 {
528         r300ContextPtr r300 = R300_CONTEXT(ctx);
529         int mask = (b << 0) | (g << 1) | (r << 2) | (a << 3);
530
531         if (mask != r300->hw.cmk.cmd[R300_CMK_COLORMASK]) {
532                 R300_STATECHANGE(r300, cmk);
533                 r300->hw.cmk.cmd[R300_CMK_COLORMASK] = mask;
534         }
535 }
536
537 /* =============================================================
538  * Point state
539  */
540 static void r300PointSize(GLcontext * ctx, GLfloat size)
541 {
542         r300ContextPtr r300 = R300_CONTEXT(ctx);
543         
544         /* This might need fixing later */
545         R300_STATECHANGE(r300, vps);
546         r300->hw.vps.cmd[R300_VPS_POINTSIZE] = r300PackFloat32(1.0);
547 }
548
549 /* =============================================================
550  * Window position and viewport transformation
551  */
552
553 /*
554  * To correctly position primitives:
555  */
556 #define SUBPIXEL_X 0.125
557 #define SUBPIXEL_Y 0.125
558
559 void r300UpdateWindow(GLcontext * ctx)
560 {
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;
566
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;
573
574         R300_FIREVERTICES(rmesa);
575         R300_STATECHANGE(rmesa, vpt);
576
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);
583 }
584
585 static void r300Viewport(GLcontext * ctx, GLint x, GLint y,
586                          GLsizei width, GLsizei height)
587 {
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.
591          */
592         R200_FIREVERTICES(R200_CONTEXT(ctx));
593         r300UpdateWindow(ctx);
594 }
595
596 static void r300DepthRange(GLcontext * ctx, GLclampd nearval, GLclampd farval)
597 {
598         r300UpdateWindow(ctx);
599 }
600
601 /* Routing and texture-related */
602
603 void r300_setup_routing(GLcontext *ctx, GLboolean immediate)
604 {
605         int i, count=0,reg=0;
606         GLuint dw, mask;
607         TNLcontext *tnl = TNL_CONTEXT(ctx);
608         struct vertex_buffer *VB = &tnl->vb;
609         r300ContextPtr r300 = R300_CONTEXT(ctx);
610         
611         
612         /* Stage 1 - input to VAP */
613         
614         /* Assign register number automatically, retaining it in rmesa->state.reg */
615         
616         /* Note: immediate vertex data includes all coordinates.
617         To save bandwidth use either VBUF or state-based vertex generation */
618         
619         #define CONFIGURE_AOS(v, o, r, f) \
620                 {\
621                 if(immediate){ \
622                         r300->state.aos[count].element_size=4; \
623                         r300->state.aos[count].stride=4; \
624                         r300->state.aos[count].ncomponents=4; \
625                         } else { \
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; \
629                         } \
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; \
634                 count++; \
635                 reg++; \
636                 }
637         
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);
645                         
646         r300->state.aos_count=count;
647         
648         if (RADEON_DEBUG & DEBUG_STATE)
649                 fprintf(stderr, "aos_count=%d\n", count);
650         
651         if(count>R300_MAX_AOS_ARRAYS){
652                 fprintf(stderr, "Aieee ! AOS array count exceeded !\n");
653                 exit(-1);
654                 }
655                         
656         /* Implement AOS */
657         
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);
667                 
668                 if(i+2==count){
669                         dw|=(1<<(13+16));
670                         }
671                 r300->hw.vir[0].cmd[R300_VIR_CNTL_0+(i>>1)]=dw;
672                 }
673         if(count & 1){
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)
677                 | (1<<13);
678                 r300->hw.vir[0].cmd[R300_VIR_CNTL_0+(count>>1)]=dw;
679                 //fprintf(stderr, "vir0 dw=%08x\n", dw);
680                 }
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;
684         
685         
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))
691         
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))
696         
697         R300_STATECHANGE(r300, vir[1]);
698                 
699         for(i=0;i+1<count;i+=2){
700                 /* do i first.. */
701                 mask=(1<<(r300->state.aos[i].ncomponents*3))-1;
702                 dw=(ALL_COMPONENTS & mask)
703                 | (ALL_DEFAULT & ~mask)
704                 | R300_INPUT_ROUTE_ENABLE;
705                 
706                 /* i+1 */
707                 mask=(1<<(r300->state.aos[i+1].ncomponents*3))-1;
708                 dw|=( 
709                 (ALL_COMPONENTS & mask)
710                 | (ALL_DEFAULT & ~mask)
711                 | R300_INPUT_ROUTE_ENABLE
712                 )<<16;
713         
714                 r300->hw.vir[1].cmd[R300_VIR_CNTL_0+(i>>1)]=dw;
715                 }
716         if(count & 1){
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);
723                 }
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;
727         
728         /* Set up input_cntl */
729         
730         R300_STATECHANGE(r300, vic);
731         r300->hw.vic.cmd[R300_VIC_CNTL_0]=0x5555;  /* Hard coded value, no idea what it means */
732         
733         r300->hw.vic.cmd[R300_VIC_CNTL_1]=R300_INPUT_CNTL_POS
734                                         | R300_INPUT_CNTL_COLOR;
735         
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);
739         
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;
744         
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));
749         
750 }
751
752 static r300TexObj default_tex_obj={
753         filter:R300_TX_MAG_FILTER_LINEAR | R300_TX_MIN_FILTER_LINEAR,
754         pitch: 0x8000,
755         size: (0xff << R300_TX_WIDTHMASK_SHIFT) 
756               | (0xff << R300_TX_HEIGHTMASK_SHIFT)
757               | (0x8 << R300_TX_SIZE_SHIFT),
758         format: 0x88a0c,
759         offset: 0x0,
760         unknown4: 0x0,
761         unknown5: 0x0
762         };
763
764 void r300_setup_textures(GLcontext *ctx)
765 {
766         int i, mtu;
767         struct r300_tex_obj *t;
768         r300ContextPtr r300 = R300_CONTEXT(ctx);
769         int max_texture_unit=-1; /* -1 translates into no setup costs for fields */
770         
771         R300_STATECHANGE(r300, txe);
772         R300_STATECHANGE(r300, tex.filter);
773         R300_STATECHANGE(r300, tex.unknown1);
774         R300_STATECHANGE(r300, tex.size);
775         R300_STATECHANGE(r300, tex.format);
776         R300_STATECHANGE(r300, tex.offset);
777         R300_STATECHANGE(r300, tex.unknown4);
778         R300_STATECHANGE(r300, tex.unknown5);
779         
780         r300->state.texture.tc_count=0;
781         
782         r300->hw.txe.cmd[R300_TXE_ENABLE]=0x0;
783         
784         mtu = r300->radeon.glCtx->Const.MaxTextureUnits;
785         if (RADEON_DEBUG & DEBUG_STATE)
786                 fprintf(stderr, "mtu=%d\n", mtu);
787         
788         if(mtu>R300_MAX_TEXTURE_UNITS){
789                 fprintf(stderr, "Aiiee ! mtu=%d is greater than R300_MAX_TEXTURE_UNITS=%d\n", 
790                         mtu, R300_MAX_TEXTURE_UNITS);
791                 exit(-1);
792                 }
793         for(i=0;i<mtu;i++){
794                 if(ctx->Texture.Unit[i].Enabled){
795                         t=r300->state.texture.unit[i].texobj;
796                         r300->state.texture.tc_count++;
797                         if(t==NULL){
798                                 fprintf(stderr, "Texture unit %d enabled, but corresponding texobj is NULL, using default object.\n", i);
799                                 //exit(-1);
800                                 t=&default_tex_obj;
801                                 }
802                         if (RADEON_DEBUG & DEBUG_STATE)
803                                 fprintf(stderr, "Activating texture unit %d\n", i);
804                         max_texture_unit=i;
805                         r300->hw.txe.cmd[R300_TXE_ENABLE]|=(1<<i);
806                         
807                         r300->hw.tex.filter.cmd[R300_TEX_VALUE_0+i]=t->filter;
808                         r300->hw.tex.unknown1.cmd[R300_TEX_VALUE_0+i]=t->pitch;
809                         r300->hw.tex.size.cmd[R300_TEX_VALUE_0+i]=t->size;
810                         r300->hw.tex.format.cmd[R300_TEX_VALUE_0+i]=t->format;
811                         r300->hw.tex.offset.cmd[R300_TEX_VALUE_0+i]=r300->radeon.radeonScreen->fbLocation+t->offset;
812                         r300->hw.tex.unknown4.cmd[R300_TEX_VALUE_0+i]=0x0;
813                         r300->hw.tex.unknown5.cmd[R300_TEX_VALUE_0+i]=0x0;
814                         
815                         /* We don't know how to set this yet */
816                         r300->hw.tex.format.cmd[R300_TEX_VALUE_0+i]=0x88a0c;
817                         
818                         } else {
819                         /* Fill in with 0's */
820                         #if 0 /* No need.. */
821                         r300->hw.tex.filter.cmd[R300_TEX_VALUE_0+i]=0x0;
822                         r300->hw.tex.unknown1.cmd[R300_TEX_VALUE_0+i]=0x0;
823                         r300->hw.tex.size.cmd[R300_TEX_VALUE_0+i]=0x0;
824                         r300->hw.tex.format.cmd[R300_TEX_VALUE_0+i]=0x0;
825                         r300->hw.tex.offset.cmd[R300_TEX_VALUE_0+i]=r300->radeon.radeonScreen->fbLocation;
826                         r300->hw.tex.unknown4.cmd[R300_TEX_VALUE_0+i]=0x0;
827                         r300->hw.tex.unknown5.cmd[R300_TEX_VALUE_0+i]=0x0;
828                         #endif
829                         }
830                         
831                 }
832         ((drm_r300_cmd_header_t*)r300->hw.tex.filter.cmd)->unchecked_state.count = max_texture_unit+1;
833         ((drm_r300_cmd_header_t*)r300->hw.tex.unknown1.cmd)->unchecked_state.count = max_texture_unit+1;
834         ((drm_r300_cmd_header_t*)r300->hw.tex.size.cmd)->unchecked_state.count = max_texture_unit+1;
835         ((drm_r300_cmd_header_t*)r300->hw.tex.format.cmd)->unchecked_state.count = max_texture_unit+1;
836         ((drm_r300_cmd_header_t*)r300->hw.tex.offset.cmd)->unchecked_state.count = max_texture_unit+1;
837         ((drm_r300_cmd_header_t*)r300->hw.tex.unknown4.cmd)->unchecked_state.count = max_texture_unit+1;
838         ((drm_r300_cmd_header_t*)r300->hw.tex.unknown5.cmd)->unchecked_state.count = max_texture_unit+1;
839         
840         if (RADEON_DEBUG & DEBUG_STATE)
841                 fprintf(stderr, "TX_ENABLE: %08x  max_texture_unit=%d\n", r300->hw.txe.cmd[R300_TXE_ENABLE], max_texture_unit);
842 }
843
844 void r300_setup_rs_unit(GLcontext *ctx)
845 {
846         r300ContextPtr r300 = R300_CONTEXT(ctx);
847         int i;
848         
849         /* This needs to be rewritten - it is a hack at best */
850         
851         R300_STATECHANGE(r300, ri);
852         R300_STATECHANGE(r300, rc);
853         R300_STATECHANGE(r300, rr);
854         
855         for(i = 1; i <= 8; ++i)
856                 r300->hw.ri.cmd[i] = 0x00d10000;
857         r300->hw.ri.cmd[R300_RI_INTERP_1] |= R300_RS_INTERP_1_UNKNOWN;
858         r300->hw.ri.cmd[R300_RI_INTERP_2] |= R300_RS_INTERP_2_UNKNOWN;
859         r300->hw.ri.cmd[R300_RI_INTERP_3] |= R300_RS_INTERP_3_UNKNOWN;
860         
861         for(i = 1; i <= 8; ++i)
862                 r300->hw.rr.cmd[i] = 0;
863         /* textures enabled ? */
864         if(r300->state.texture.tc_count>0){
865         
866                 /* This code only really works with one set of texture coordinates */
867                 
868                 /* The second constant is needed to get glxgears display anything .. */
869                 r300->hw.rc.cmd[1] = R300_RS_CNTL_0_UNKNOWN_7 
870                                 | R300_RS_CNTL_0_UNKNOWN_18 
871                                 | (r300->state.texture.tc_count<<R300_RS_CNTL_TC_CNT_SHIFT);
872                 r300->hw.rc.cmd[2] = 0xc0;
873         
874         
875                 ((drm_r300_cmd_header_t*)r300->hw.rr.cmd)->unchecked_state.count = 1;
876                 r300->hw.rr.cmd[R300_RR_ROUTE_0] = 0x24008;
877                 
878                 } else {
879                 
880                 /* The second constant is needed to get glxgears display anything .. */
881                 r300->hw.rc.cmd[1] = R300_RS_CNTL_0_UNKNOWN_7 | R300_RS_CNTL_0_UNKNOWN_18;
882                 r300->hw.rc.cmd[2] = 0;
883                 
884                 ((drm_r300_cmd_header_t*)r300->hw.rr.cmd)->unchecked_state.count = 1;
885                 r300->hw.rr.cmd[R300_RR_ROUTE_0] = 0x4000;
886                 
887                 }
888 }
889
890 /**
891  * Called by Mesa after an internal state update.
892  */
893 static void r300InvalidateState(GLcontext * ctx, GLuint new_state)
894 {
895         r300ContextPtr r300 = R300_CONTEXT(ctx);
896
897         _swrast_InvalidateState(ctx, new_state);
898         _swsetup_InvalidateState(ctx, new_state);
899         _ac_InvalidateState(ctx, new_state);
900         _tnl_InvalidateState(ctx, new_state);
901         _ae_invalidate_state(ctx, new_state);
902
903         /* Go inefficiency! */
904         r300ResetHwState(r300);
905 }
906
907
908 /**
909  * Completely recalculates hardware state based on the Mesa state.
910  */
911 void r300ResetHwState(r300ContextPtr r300)
912 {
913         GLcontext* ctx = r300->radeon.glCtx;
914         int i;
915
916         if (RADEON_DEBUG & DEBUG_STATE)
917                 fprintf(stderr, "%s\n", __FUNCTION__);
918
919         r300UpdateWindow(ctx);
920         
921         r300ColorMask(ctx,
922                 ctx->Color.ColorMask[RCOMP],
923                 ctx->Color.ColorMask[GCOMP],
924                 ctx->Color.ColorMask[BCOMP],
925                 ctx->Color.ColorMask[ACOMP]);
926
927         r300Enable(ctx, GL_DEPTH_TEST, ctx->Depth.Test);
928         r300DepthMask(ctx, ctx->Depth.Mask);
929         r300DepthFunc(ctx, ctx->Depth.Func);
930
931         r300UpdateCulling(ctx);
932         
933         r300_setup_routing(ctx, GL_TRUE);
934         
935         r300UpdateTextureState(ctx);
936         r300_setup_textures(ctx);
937         r300_setup_rs_unit(ctx);
938         
939         
940         r300_set_blend_state(ctx);
941         r300AlphaFunc(ctx, ctx->Color.AlphaFunc, ctx->Color.AlphaRef);
942
943 //BEGIN: TODO
944         r300->hw.unk2080.cmd[1] = 0x0030045A;
945
946         r300->hw.ovf.cmd[R300_OVF_FMT_0] = 0x00000003;
947         r300->hw.ovf.cmd[R300_OVF_FMT_1] = 0x00000000;
948
949         r300->hw.vte.cmd[1] = R300_VPORT_X_SCALE_ENA
950                                 | R300_VPORT_X_OFFSET_ENA
951                                 | R300_VPORT_Y_SCALE_ENA
952                                 | R300_VPORT_Y_OFFSET_ENA
953                                 | R300_VPORT_Z_SCALE_ENA
954                                 | R300_VPORT_Z_OFFSET_ENA
955                                 | R300_VTX_W0_FMT;
956         r300->hw.vte.cmd[2] = 0x00000008;
957
958         r300->hw.unk2134.cmd[1] = 0x00FFFFFF;
959         r300->hw.unk2134.cmd[2] = 0x00000000;
960
961         r300->hw.unk2140.cmd[1] = 0x00000000;
962
963         #if 0 /* Done in setup routing */
964         ((drm_r300_cmd_header_t*)r300->hw.vir[0].cmd)->unchecked_state.count = 1;
965         r300->hw.vir[0].cmd[1] = 0x21030003;
966
967         ((drm_r300_cmd_header_t*)r300->hw.vir[1].cmd)->unchecked_state.count = 1;
968         r300->hw.vir[1].cmd[1] = 0xF688F688;
969
970         r300->hw.vic.cmd[R300_VIR_CNTL_0] = 0x00000001;
971         r300->hw.vic.cmd[R300_VIR_CNTL_1] = 0x00000405;
972         #endif
973         
974         r300->hw.unk21DC.cmd[1] = 0xAAAAAAAA;
975
976         r300->hw.unk221C.cmd[1] = R300_221C_NORMAL;
977
978         r300->hw.unk2220.cmd[1] = r300PackFloat32(1.0);
979         r300->hw.unk2220.cmd[2] = r300PackFloat32(1.0);
980         r300->hw.unk2220.cmd[3] = r300PackFloat32(1.0);
981         r300->hw.unk2220.cmd[4] = r300PackFloat32(1.0);
982
983         if (GET_CHIP(r300->radeon.radeonScreen) == RADEON_CHIP_R300)
984                 r300->hw.unk2288.cmd[1] = R300_2288_R300;
985         else
986                 r300->hw.unk2288.cmd[1] = R300_2288_RV350;
987
988         #if 0
989         r300->hw.vof.cmd[R300_VOF_CNTL_0] = R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
990                                 | R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT;
991         r300->hw.vof.cmd[R300_VOF_CNTL_1] = 0; /* no textures */
992         #endif  
993         
994         r300->hw.pvs.cmd[R300_PVS_CNTL_1] = 0;
995         r300->hw.pvs.cmd[R300_PVS_CNTL_2] = 0;
996         r300->hw.pvs.cmd[R300_PVS_CNTL_3] = 0;
997
998         r300->hw.gb_enable.cmd[1] = R300_GB_POINT_STUFF_ENABLE
999                 | R300_GB_LINE_STUFF_ENABLE
1000                 | R300_GB_TRIANGLE_STUFF_ENABLE;
1001
1002         r300->hw.gb_misc.cmd[R300_GB_MISC_MSPOS_0] = 0x66666666;
1003         r300->hw.gb_misc.cmd[R300_GB_MISC_MSPOS_1] = 0x06666666;
1004         if (GET_CHIP(r300->radeon.radeonScreen) == RADEON_CHIP_R300)
1005                 r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] = R300_GB_TILE_ENABLE
1006                                                         | R300_GB_TILE_PIPE_COUNT_R300
1007                                                         | R300_GB_TILE_SIZE_16;
1008         else
1009                 r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] = R300_GB_TILE_ENABLE
1010                                                         | R300_GB_TILE_PIPE_COUNT_RV300
1011                                                         | R300_GB_TILE_SIZE_16;
1012         r300->hw.gb_misc.cmd[R300_GB_MISC_SELECT] = 0x00000000;
1013         r300->hw.gb_misc.cmd[R300_GB_MISC_AA_CONFIG] = 0x00000000; /* No antialiasing */
1014
1015         //r300->hw.txe.cmd[R300_TXE_ENABLE] = 0;
1016
1017         r300->hw.unk4200.cmd[1] = r300PackFloat32(0.0);
1018         r300->hw.unk4200.cmd[2] = r300PackFloat32(0.0);
1019         r300->hw.unk4200.cmd[3] = r300PackFloat32(1.0);
1020         r300->hw.unk4200.cmd[4] = r300PackFloat32(1.0);
1021
1022         r300->hw.unk4214.cmd[1] = 0x00050005;
1023
1024         r300->hw.ps.cmd[R300_PS_POINTSIZE] = (6 << R300_POINTSIZE_X_SHIFT) |
1025                                              (6 << R300_POINTSIZE_Y_SHIFT);
1026
1027         r300->hw.unk4230.cmd[1] = 0x01800000;
1028         r300->hw.unk4230.cmd[2] = 0x00020006;
1029         r300->hw.unk4230.cmd[3] = r300PackFloat32(1.0 / 192.0);
1030
1031         r300->hw.unk4260.cmd[1] = 0;
1032         r300->hw.unk4260.cmd[2] = r300PackFloat32(0.0);
1033         r300->hw.unk4260.cmd[3] = r300PackFloat32(1.0);
1034
1035         r300->hw.unk4274.cmd[1] = 0x00000002;
1036         r300->hw.unk4274.cmd[2] = 0x0003AAAA;
1037         r300->hw.unk4274.cmd[3] = 0x00000000;
1038         r300->hw.unk4274.cmd[4] = 0x00000000;
1039
1040         r300->hw.unk4288.cmd[1] = 0x00000000;
1041         r300->hw.unk4288.cmd[2] = 0x00000001;
1042         r300->hw.unk4288.cmd[3] = 0x00000000;
1043         r300->hw.unk4288.cmd[4] = 0x00000000;
1044         r300->hw.unk4288.cmd[5] = 0x00000000;
1045
1046         r300->hw.unk42A0.cmd[1] = 0x00000000;
1047
1048         r300->hw.unk42B4.cmd[1] = 0x00000000;
1049
1050         r300->hw.unk42C0.cmd[1] = 0x4B7FFFFF;
1051         r300->hw.unk42C0.cmd[2] = 0x00000000;
1052
1053
1054         r300->hw.unk43A4.cmd[1] = 0x0000001C;
1055         r300->hw.unk43A4.cmd[2] = 0x2DA49525;
1056
1057         r300->hw.unk43E8.cmd[1] = 0x00FFFFFF;
1058
1059         r300->hw.fp.cmd[R300_FP_CNTL0] = 0;
1060         r300->hw.fp.cmd[R300_FP_CNTL1] = 0;
1061         r300->hw.fp.cmd[R300_FP_CNTL2] = 0;
1062         r300->hw.fp.cmd[R300_FP_NODE0] = 0;
1063         r300->hw.fp.cmd[R300_FP_NODE1] = 0;
1064         r300->hw.fp.cmd[R300_FP_NODE2] = 0;
1065         r300->hw.fp.cmd[R300_FP_NODE3] = 0;
1066
1067         r300->hw.unk46A4.cmd[1] = 0x00001B01;
1068         r300->hw.unk46A4.cmd[2] = 0x00001B0F;
1069         r300->hw.unk46A4.cmd[3] = 0x00001B0F;
1070         r300->hw.unk46A4.cmd[4] = 0x00001B0F;
1071         r300->hw.unk46A4.cmd[5] = 0x00000001;
1072
1073         for(i = 1; i <= 64; ++i) {
1074                 /* create NOP instructions */
1075                 r300->hw.fpi[0].cmd[i] = FP_INSTRC(MAD, FP_ARGC(SRC0C_XYZ), FP_ARGC(ONE), FP_ARGC(ZERO));
1076                 r300->hw.fpi[1].cmd[i] = FP_SELC(0,XYZ,NO,FP_TMP(0),0,0);
1077                 r300->hw.fpi[2].cmd[i] = FP_INSTRA(MAD, FP_ARGA(SRC0A), FP_ARGA(ONE), FP_ARGA(ZERO));
1078                 r300->hw.fpi[3].cmd[i] = FP_SELA(0,W,NO,FP_TMP(0),0,0);
1079         }
1080
1081         r300->hw.unk4BC0.cmd[1] = 0;
1082
1083         r300->hw.unk4BC8.cmd[1] = 0;
1084         r300->hw.unk4BC8.cmd[2] = 0;
1085         r300->hw.unk4BC8.cmd[3] = 0;
1086
1087         #if 0
1088         r300->hw.at.cmd[R300_AT_ALPHA_TEST] = 0;
1089         #endif
1090
1091         r300->hw.unk4BD8.cmd[1] = 0;
1092
1093         r300->hw.unk4E00.cmd[1] = 0;
1094
1095         #if 0
1096         r300->hw.bld.cmd[R300_BLD_CBLEND] = 0;
1097         r300->hw.bld.cmd[R300_BLD_ABLEND] = 0;
1098         #endif
1099
1100         r300->hw.unk4E10.cmd[1] = 0;
1101         r300->hw.unk4E10.cmd[2] = 0;
1102         r300->hw.unk4E10.cmd[3] = 0;
1103
1104         r300->hw.cb.cmd[R300_CB_OFFSET] =
1105                 r300->radeon.radeonScreen->backOffset +
1106                 r300->radeon.radeonScreen->fbLocation;
1107         r300->hw.cb.cmd[R300_CB_PITCH] = r300->radeon.radeonScreen->backPitch
1108                 | R300_COLOR_UNKNOWN_22_23;
1109
1110         r300->hw.unk4E50.cmd[1] = 0;
1111         r300->hw.unk4E50.cmd[2] = 0;
1112         r300->hw.unk4E50.cmd[3] = 0;
1113         r300->hw.unk4E50.cmd[4] = 0;
1114         r300->hw.unk4E50.cmd[5] = 0;
1115         r300->hw.unk4E50.cmd[6] = 0;
1116         r300->hw.unk4E50.cmd[7] = 0;
1117         r300->hw.unk4E50.cmd[8] = 0;
1118         r300->hw.unk4E50.cmd[9] = 0;
1119
1120         r300->hw.unk4E88.cmd[1] = 0;
1121
1122         r300->hw.unk4EA0.cmd[1] = 0x00000000;
1123         r300->hw.unk4EA0.cmd[2] = 0xffffffff;
1124
1125         r300->hw.unk4F08.cmd[1] = 0x00FFFF00;
1126
1127         r300->hw.unk4F10.cmd[1] = 0x00000002; // depthbuffer format?
1128         r300->hw.unk4F10.cmd[2] = 0x00000000;
1129         r300->hw.unk4F10.cmd[3] = 0x00000003;
1130         r300->hw.unk4F10.cmd[4] = 0x00000000;
1131
1132         r300->hw.zb.cmd[R300_ZB_OFFSET] =
1133                 r300->radeon.radeonScreen->depthOffset +
1134                 r300->radeon.radeonScreen->fbLocation;
1135         r300->hw.zb.cmd[R300_ZB_PITCH] = r300->radeon.radeonScreen->depthPitch;
1136
1137         r300->hw.unk4F28.cmd[1] = 0;
1138
1139         r300->hw.unk4F30.cmd[1] = 0;
1140         r300->hw.unk4F30.cmd[2] = 0;
1141
1142         r300->hw.unk4F44.cmd[1] = 0;
1143
1144         r300->hw.unk4F54.cmd[1] = 0;
1145
1146         ((drm_r300_cmd_header_t*)r300->hw.vpi.cmd)->vpu.count = 0;
1147         for(i = 1; i < R300_VPI_CMDSIZE; i += 4) {
1148                 /* MOV t0, t0 */
1149                 r300->hw.vpi.cmd[i+0] = VP_OUT(ADD,TMP,0,XYZW);
1150                 r300->hw.vpi.cmd[i+1] = VP_IN(TMP,0);
1151                 r300->hw.vpi.cmd[i+2] = VP_ZERO();
1152                 r300->hw.vpi.cmd[i+3] = VP_ZERO();
1153         }
1154
1155         ((drm_r300_cmd_header_t*)r300->hw.vpp.cmd)->vpu.count = 0;
1156         for(i = 1; i < R300_VPP_CMDSIZE; ++i)
1157                 r300->hw.vpp.cmd[i] = 0;
1158
1159         r300->hw.vps.cmd[R300_VPS_ZERO_0] = 0;
1160         r300->hw.vps.cmd[R300_VPS_ZERO_1] = 0;
1161         r300->hw.vps.cmd[R300_VPS_POINTSIZE] = r300PackFloat32(1.0);
1162         r300->hw.vps.cmd[R300_VPS_ZERO_3] = 0;
1163         
1164 //END: TODO
1165         
1166         r300->hw.all_dirty = GL_TRUE;
1167 }
1168
1169
1170
1171 /**
1172  * Calculate initial hardware state and register state functions.
1173  * Assumes that the command buffer and state atoms have been
1174  * initialized already.
1175  */
1176 void r300InitState(r300ContextPtr r300)
1177 {
1178         GLcontext *ctx = r300->radeon.glCtx;
1179         GLuint depth_fmt;
1180
1181         radeonInitState(&r300->radeon);
1182         
1183         switch (ctx->Visual.depthBits) {
1184         case 16:
1185                 r300->state.depth.scale = 1.0 / (GLfloat) 0xffff;
1186                 depth_fmt = R200_DEPTH_FORMAT_16BIT_INT_Z;
1187                 //r300->state.stencil.clear = 0x00000000;
1188                 break;
1189         case 24:
1190                 r300->state.depth.scale = 1.0 / (GLfloat) 0xffffff;
1191                 depth_fmt = R200_DEPTH_FORMAT_24BIT_INT_Z;
1192                 //r300->state.stencil.clear = 0xff000000;
1193                 break;
1194         default:
1195                 fprintf(stderr, "Error: Unsupported depth %d... exiting\n",
1196                         ctx->Visual.depthBits);
1197                 exit(-1);
1198         }
1199         
1200         memset(&(r300->state.texture), 0, sizeof(r300->state.texture));
1201
1202         r300ResetHwState(r300);
1203 }
1204
1205
1206
1207 /**
1208  * Initialize driver's state callback functions
1209  */
1210 void r300InitStateFuncs(struct dd_function_table* functions)
1211 {
1212         radeonInitStateFuncs(functions);
1213
1214         functions->UpdateState = r300InvalidateState;
1215         //functions->AlphaFunc = r300AlphaFunc;
1216         functions->BlendColor = r300BlendColor;
1217         functions->BlendEquationSeparate = r300BlendEquationSeparate;
1218         functions->BlendFuncSeparate = r300BlendFuncSeparate;
1219         functions->Enable = r300Enable;
1220         functions->ColorMask = r300ColorMask;
1221         functions->DepthFunc = r300DepthFunc;
1222         functions->DepthMask = r300DepthMask;
1223         functions->CullFace = r300CullFace;
1224         functions->FrontFace = r300FrontFace;
1225
1226         /* Viewport related */
1227         functions->Viewport = r300Viewport;
1228         functions->DepthRange = r300DepthRange;
1229         functions->PointSize = r300PointSize;
1230 }
1231