Reduce noiseness of the driver.
[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 #include "texformat.h"
52
53 #include "radeon_ioctl.h"
54 #include "radeon_state.h"
55 #include "r300_context.h"
56 #include "r300_ioctl.h"
57 #include "r300_state.h"
58 #include "r300_reg.h"
59 #include "r300_program.h"
60 #include "r300_emit.h"
61 #include "r300_fixed_pipelines.h"
62
63
64 static void r300AlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref)
65 {
66 r300ContextPtr rmesa = R300_CONTEXT(ctx);
67 int pp_misc = rmesa->hw.at.cmd[R300_AT_ALPHA_TEST];
68 GLubyte refByte;
69
70 CLAMPED_FLOAT_TO_UBYTE(refByte, ref);
71
72 R300_STATECHANGE(rmesa, at);
73
74 pp_misc &= ~(R300_ALPHA_TEST_OP_MASK | R300_REF_ALPHA_MASK);
75 pp_misc |= (refByte & R300_REF_ALPHA_MASK);
76
77 switch (func) {
78 case GL_NEVER:
79 pp_misc |= R300_ALPHA_TEST_FAIL;
80 break;
81 case GL_LESS:
82 pp_misc |= R300_ALPHA_TEST_LESS;
83 break;
84 case GL_EQUAL:
85 pp_misc |= R300_ALPHA_TEST_EQUAL;
86 break;
87 case GL_LEQUAL:
88 pp_misc |= R300_ALPHA_TEST_LEQUAL;
89 break;
90 case GL_GREATER:
91 pp_misc |= R300_ALPHA_TEST_GREATER;
92 break;
93 case GL_NOTEQUAL:
94 pp_misc |= R300_ALPHA_TEST_NEQUAL;
95 break;
96 case GL_GEQUAL:
97 pp_misc |= R300_ALPHA_TEST_GEQUAL;
98 break;
99 case GL_ALWAYS:
100 pp_misc |= R300_ALPHA_TEST_PASS;
101 break;
102 }
103
104 rmesa->hw.at.cmd[R300_AT_ALPHA_TEST] = pp_misc;
105 }
106
107 static void r300BlendColor(GLcontext * ctx, const GLfloat cf[4])
108 {
109 GLubyte color[4];
110 r300ContextPtr rmesa = R300_CONTEXT(ctx);
111 fprintf(stderr, "%s:%s is not implemented yet. Fixme !\n", __FILE__, __FUNCTION__);
112 #if 0
113 R200_STATECHANGE(rmesa, ctx);
114 CLAMPED_FLOAT_TO_UBYTE(color[0], cf[0]);
115 CLAMPED_FLOAT_TO_UBYTE(color[1], cf[1]);
116 CLAMPED_FLOAT_TO_UBYTE(color[2], cf[2]);
117 CLAMPED_FLOAT_TO_UBYTE(color[3], cf[3]);
118 if (rmesa->radeon.radeonScreen->drmSupportsBlendColor)
119 rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCOLOR] =
120 radeonPackColor(4, color[0], color[1], color[2], color[3]);
121 #endif
122 }
123
124 /**
125 * Calculate the hardware blend factor setting. This same function is used
126 * for source and destination of both alpha and RGB.
127 *
128 * \returns
129 * The hardware register value for the specified blend factor. This value
130 * will need to be shifted into the correct position for either source or
131 * destination factor.
132 *
133 * \todo
134 * Since the two cases where source and destination are handled differently
135 * are essentially error cases, they should never happen. Determine if these
136 * cases can be removed.
137 */
138 static int blend_factor(GLenum factor, GLboolean is_src)
139 {
140 int func;
141
142 switch (factor) {
143 case GL_ZERO:
144 func = R200_BLEND_GL_ZERO;
145 break;
146 case GL_ONE:
147 func = R200_BLEND_GL_ONE;
148 break;
149 case GL_DST_COLOR:
150 func = R200_BLEND_GL_DST_COLOR;
151 break;
152 case GL_ONE_MINUS_DST_COLOR:
153 func = R200_BLEND_GL_ONE_MINUS_DST_COLOR;
154 break;
155 case GL_SRC_COLOR:
156 func = R200_BLEND_GL_SRC_COLOR;
157 break;
158 case GL_ONE_MINUS_SRC_COLOR:
159 func = R200_BLEND_GL_ONE_MINUS_SRC_COLOR;
160 break;
161 case GL_SRC_ALPHA:
162 func = R200_BLEND_GL_SRC_ALPHA;
163 break;
164 case GL_ONE_MINUS_SRC_ALPHA:
165 func = R200_BLEND_GL_ONE_MINUS_SRC_ALPHA;
166 break;
167 case GL_DST_ALPHA:
168 func = R200_BLEND_GL_DST_ALPHA;
169 break;
170 case GL_ONE_MINUS_DST_ALPHA:
171 func = R200_BLEND_GL_ONE_MINUS_DST_ALPHA;
172 break;
173 case GL_SRC_ALPHA_SATURATE:
174 func =
175 (is_src) ? R200_BLEND_GL_SRC_ALPHA_SATURATE :
176 R200_BLEND_GL_ZERO;
177 break;
178 case GL_CONSTANT_COLOR:
179 func = R200_BLEND_GL_CONST_COLOR;
180 break;
181 case GL_ONE_MINUS_CONSTANT_COLOR:
182 func = R200_BLEND_GL_ONE_MINUS_CONST_COLOR;
183 break;
184 case GL_CONSTANT_ALPHA:
185 func = R200_BLEND_GL_CONST_ALPHA;
186 break;
187 case GL_ONE_MINUS_CONSTANT_ALPHA:
188 func = R200_BLEND_GL_ONE_MINUS_CONST_ALPHA;
189 break;
190 default:
191 func = (is_src) ? R200_BLEND_GL_ONE : R200_BLEND_GL_ZERO;
192 }
193 return func;
194 }
195
196 /**
197 * Sets both the blend equation and the blend function.
198 * This is done in a single
199 * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX)
200 * change the interpretation of the blend function.
201 * Also, make sure that blend function and blend equation are set to their default
202 * value if color blending is not enabled, since at least blend equations GL_MIN
203 * and GL_FUNC_REVERSE_SUBTRACT will cause wrong results otherwise for
204 * unknown reasons.
205 */
206
207 /* helper function */
208 static void r300_set_blend_cntl(r300ContextPtr rmesa, int func, int eqn, int cbits, int funcA, int eqnA)
209 {
210 GLuint new_ablend, new_cblend;
211
212 #if 0
213 fprintf(stderr, "eqnA=%08x funcA=%08x eqn=%08x func=%08x cbits=%08x\n", eqnA, funcA, eqn, func, cbits);
214 #endif
215 new_ablend = eqnA | funcA;
216 new_cblend = eqn | func;
217 if(funcA == func){
218 new_cblend |= R300_BLEND_NO_SEPARATE;
219 }
220 new_cblend |= cbits;
221
222 if((new_ablend != rmesa->hw.bld.cmd[R300_BLD_ABLEND])
223 || (new_cblend != rmesa->hw.bld.cmd[R300_BLD_CBLEND])){
224 R300_STATECHANGE(rmesa, bld);
225 rmesa->hw.bld.cmd[R300_BLD_ABLEND]=new_ablend;
226 rmesa->hw.bld.cmd[R300_BLD_CBLEND]=new_cblend;
227 }
228 }
229
230 static void r300_set_blend_state(GLcontext * ctx)
231 {
232 r300ContextPtr rmesa = R300_CONTEXT(ctx);
233 #if 0
234 GLuint cntl = rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &
235 ~(R300_ROP_ENABLE | R300_ALPHA_BLEND_ENABLE |
236 R300_SEPARATE_ALPHA_ENABLE);
237 #endif
238
239 int func = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
240 (R200_BLEND_GL_ZERO << R200_DST_BLEND_SHIFT);
241 int eqn = R200_COMB_FCN_ADD_CLAMP;
242 int funcA = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
243 (R200_BLEND_GL_ZERO << R200_DST_BLEND_SHIFT);
244 int eqnA = R200_COMB_FCN_ADD_CLAMP;
245
246
247 if (rmesa->radeon.radeonScreen->drmSupportsBlendColor) {
248 if (ctx->Color._LogicOpEnabled) {
249 #if 0
250 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] =
251 cntl | R300_ROP_ENABLE;
252 #endif
253 r300_set_blend_cntl(rmesa,
254 func, eqn, 0,
255 func, eqn);
256 return;
257 } else if (ctx->Color.BlendEnabled) {
258 #if 0
259 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] =
260 cntl | R300_ALPHA_BLEND_ENABLE |
261 R300_SEPARATE_ALPHA_ENABLE;
262 #endif
263 } else {
264 #if 0
265 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = cntl;
266 #endif
267 r300_set_blend_cntl(rmesa,
268 func, eqn, 0,
269 func, eqn);
270 return;
271 }
272 } else {
273 if (ctx->Color._LogicOpEnabled) {
274 #if 0
275 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] =
276 cntl | R300_ROP_ENABLE;
277 rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = eqn | func;
278 #endif
279 return;
280 } else if (ctx->Color.BlendEnabled) {
281 #if 0
282 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] =
283 cntl | R300_ALPHA_BLEND_ENABLE;
284 #endif
285 } else {
286 #if 0
287 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = cntl;
288 rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = eqn | func;
289 #endif
290 r300_set_blend_cntl(rmesa,
291 func, eqn, 0,
292 func, eqn);
293 return;
294 }
295 }
296
297 func =
298 (blend_factor(ctx->Color.BlendSrcRGB, GL_TRUE) <<
299 R200_SRC_BLEND_SHIFT) | (blend_factor(ctx->Color.BlendDstRGB,
300 GL_FALSE) <<
301 R200_DST_BLEND_SHIFT);
302
303 switch (ctx->Color.BlendEquationRGB) {
304 case GL_FUNC_ADD:
305 eqn = R300_COMB_FCN_ADD_CLAMP;
306 break;
307
308 case GL_FUNC_SUBTRACT:
309 eqn = R300_COMB_FCN_SUB_CLAMP;
310 break;
311
312 case GL_FUNC_REVERSE_SUBTRACT:
313 eqn = R200_COMB_FCN_RSUB_CLAMP;
314 break;
315
316 case GL_MIN:
317 eqn = R200_COMB_FCN_MIN;
318 func = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
319 (R200_BLEND_GL_ONE << R200_DST_BLEND_SHIFT);
320 break;
321
322 case GL_MAX:
323 eqn = R200_COMB_FCN_MAX;
324 func = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
325 (R200_BLEND_GL_ONE << R200_DST_BLEND_SHIFT);
326 break;
327
328 default:
329 fprintf(stderr,
330 "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
331 __func__, __LINE__, ctx->Color.BlendEquationRGB);
332 return;
333 }
334
335 if (!rmesa->radeon.radeonScreen->drmSupportsBlendColor) {
336 #if 0
337 rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = eqn | func;
338 #endif
339 return;
340 }
341
342 funcA =
343 (blend_factor(ctx->Color.BlendSrcA, GL_TRUE) <<
344 R200_SRC_BLEND_SHIFT) | (blend_factor(ctx->Color.BlendDstA,
345 GL_FALSE) <<
346 R200_DST_BLEND_SHIFT);
347
348 switch (ctx->Color.BlendEquationA) {
349 case GL_FUNC_ADD:
350 eqnA = R300_COMB_FCN_ADD_CLAMP;
351 break;
352
353 case GL_FUNC_SUBTRACT:
354 eqnA = R300_COMB_FCN_SUB_CLAMP;
355 break;
356
357 case GL_FUNC_REVERSE_SUBTRACT:
358 eqnA = R200_COMB_FCN_RSUB_CLAMP;
359 break;
360
361 case GL_MIN:
362 eqnA = R200_COMB_FCN_MIN;
363 funcA = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
364 (R200_BLEND_GL_ONE << R200_DST_BLEND_SHIFT);
365 break;
366
367 case GL_MAX:
368 eqnA = R200_COMB_FCN_MAX;
369 funcA = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
370 (R200_BLEND_GL_ONE << R200_DST_BLEND_SHIFT);
371 break;
372
373 default:
374 fprintf(stderr, "[%s:%u] Invalid A blend equation (0x%04x).\n",
375 __func__, __LINE__, ctx->Color.BlendEquationA);
376 return;
377 }
378
379 r300_set_blend_cntl(rmesa,
380 func, eqn, R300_BLEND_UNKNOWN | R300_BLEND_ENABLE,
381 funcA, eqnA);
382 r300_set_blend_cntl(rmesa,
383 func, eqn, R300_BLEND_UNKNOWN | R300_BLEND_ENABLE,
384 funcA, eqnA);
385 }
386
387 static void r300BlendEquationSeparate(GLcontext * ctx,
388 GLenum modeRGB, GLenum modeA)
389 {
390 r300_set_blend_state(ctx);
391 }
392
393 static void r300BlendFuncSeparate(GLcontext * ctx,
394 GLenum sfactorRGB, GLenum dfactorRGB,
395 GLenum sfactorA, GLenum dfactorA)
396 {
397 r300_set_blend_state(ctx);
398 }
399
400 /**
401 * Update our tracked culling state based on Mesa's state.
402 */
403 static void r300UpdateCulling(GLcontext* ctx)
404 {
405 r300ContextPtr r300 = R300_CONTEXT(ctx);
406 uint32_t val = 0;
407
408 R300_STATECHANGE(r300, cul);
409 if (ctx->Polygon.CullFlag) {
410 if (ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK)
411 val = R300_CULL_FRONT|R300_CULL_BACK;
412 else if (ctx->Polygon.CullFaceMode == GL_FRONT)
413 val = R300_CULL_FRONT;
414 else
415 val = R300_CULL_BACK;
416
417 if (ctx->Polygon.FrontFace == GL_CW)
418 val |= R300_FRONT_FACE_CW;
419 else
420 val |= R300_FRONT_FACE_CCW;
421 }
422
423 r300->hw.cul.cmd[R300_CUL_CULL] = val;
424 }
425
426
427 /**
428 * Handle glEnable()/glDisable().
429 *
430 * \note Mesa already filters redundant calls to glEnable/glDisable.
431 */
432 static void r300Enable(GLcontext* ctx, GLenum cap, GLboolean state)
433 {
434 r300ContextPtr r300 = R300_CONTEXT(ctx);
435 uint32_t newval;
436
437 if (RADEON_DEBUG & DEBUG_STATE)
438 fprintf(stderr, "%s( %s = %s )\n", __FUNCTION__,
439 _mesa_lookup_enum_by_nr(cap),
440 state ? "GL_TRUE" : "GL_FALSE");
441
442 switch (cap) {
443 /* Fast track this one...
444 */
445 case GL_TEXTURE_1D:
446 case GL_TEXTURE_2D:
447 case GL_TEXTURE_3D:
448 break;
449
450 case GL_ALPHA_TEST:
451 R200_STATECHANGE(r300, at);
452 if (state) {
453 r300->hw.at.cmd[R300_AT_ALPHA_TEST] |=
454 R300_ALPHA_TEST_ENABLE;
455 } else {
456 r300->hw.at.cmd[R300_AT_ALPHA_TEST] |=
457 ~R300_ALPHA_TEST_ENABLE;
458 }
459 break;
460
461 case GL_BLEND:
462 case GL_COLOR_LOGIC_OP:
463 r300_set_blend_state(ctx);
464 break;
465
466 case GL_DEPTH_TEST:
467 R300_STATECHANGE(r300, zs);
468
469 if (state) {
470 if (ctx->Depth.Mask)
471 newval = R300_RB3D_Z_TEST_AND_WRITE;
472 else
473 newval = R300_RB3D_Z_TEST;
474 } else
475 newval = 0;
476
477 r300->hw.zs.cmd[R300_ZS_CNTL_0] = newval;
478 break;
479
480 case GL_STENCIL_TEST:
481
482 {
483 static int stencil=1;
484 if(stencil){
485 fprintf(stderr, "%s:%s - do not know how to enable stencil. Help me !\n",
486 __FILE__, __FUNCTION__);
487 stencil=0;
488 }
489 }
490
491 if (r300->state.hw_stencil) {
492 //fprintf(stderr, "Stencil %s\n", state ? "enabled" : "disabled");
493 R300_STATECHANGE(r300, zs);
494 if (state) {
495 r300->hw.zs.cmd[R300_ZS_CNTL_0] |=
496 R300_RB3D_STENCIL_ENABLE;
497 } else {
498 r300->hw.zs.cmd[R300_ZS_CNTL_0] &=
499 ~R300_RB3D_STENCIL_ENABLE;
500 }
501 } else {
502 FALLBACK(&r300->radeon, RADEON_FALLBACK_STENCIL, state);
503 }
504 break;
505
506 case GL_CULL_FACE:
507 r300UpdateCulling(ctx);
508 break;
509 case GL_VERTEX_PROGRAM_ARB:
510 //TCL_FALLBACK(rmesa->glCtx, R200_TCL_FALLBACK_TCL_DISABLE, state);
511 break;
512
513 default:
514 radeonEnable(ctx, cap, state);
515 return;
516 }
517 }
518
519
520 /**
521 * Change the culling mode.
522 *
523 * \note Mesa already filters redundant calls to this function.
524 */
525 static void r300CullFace(GLcontext* ctx, GLenum mode)
526 {
527 (void)mode;
528
529 r300UpdateCulling(ctx);
530 }
531
532
533 /**
534 * Change the polygon orientation.
535 *
536 * \note Mesa already filters redundant calls to this function.
537 */
538 static void r300FrontFace(GLcontext* ctx, GLenum mode)
539 {
540 (void)mode;
541
542 r300UpdateCulling(ctx);
543 }
544
545
546 /**
547 * Change the depth testing function.
548 *
549 * \note Mesa already filters redundant calls to this function.
550 */
551 static void r300DepthFunc(GLcontext* ctx, GLenum func)
552 {
553 r300ContextPtr r300 = R300_CONTEXT(ctx);
554
555 R300_STATECHANGE(r300, zs);
556
557 r300->hw.zs.cmd[R300_ZS_CNTL_1] &= ~(R300_ZS_MASK << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT);
558
559 switch(func) {
560 case GL_NEVER:
561 r300->hw.zs.cmd[R300_ZS_CNTL_1] |= R300_ZS_NEVER << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT;
562 break;
563 case GL_LESS:
564 r300->hw.zs.cmd[R300_ZS_CNTL_1] |= R300_ZS_LESS << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT;
565 break;
566 case GL_EQUAL:
567 r300->hw.zs.cmd[R300_ZS_CNTL_1] |= R300_ZS_EQUAL << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT;
568 break;
569 case GL_LEQUAL:
570 r300->hw.zs.cmd[R300_ZS_CNTL_1] |= R300_ZS_LEQUAL << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT;
571 break;
572 case GL_GREATER:
573 r300->hw.zs.cmd[R300_ZS_CNTL_1] |= R300_ZS_GREATER << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT;
574 break;
575 case GL_NOTEQUAL:
576 r300->hw.zs.cmd[R300_ZS_CNTL_1] |= R300_ZS_NOTEQUAL << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT;
577 break;
578 case GL_GEQUAL:
579 r300->hw.zs.cmd[R300_ZS_CNTL_1] |= R300_ZS_GEQUAL << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT;
580 break;
581 case GL_ALWAYS:
582 r300->hw.zs.cmd[R300_ZS_CNTL_1] |= R300_ZS_ALWAYS << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT;
583 break;
584 }
585
586 }
587
588
589 /**
590 * Enable/Disable depth writing.
591 *
592 * \note Mesa already filters redundant calls to this function.
593 */
594 static void r300DepthMask(GLcontext* ctx, GLboolean mask)
595 {
596 r300ContextPtr r300 = R300_CONTEXT(ctx);
597
598 if (!ctx->Depth.Test)
599 return;
600
601 R300_STATECHANGE(r300, zs);
602 r300->hw.zs.cmd[R300_ZS_CNTL_0] = mask
603 ? R300_RB3D_Z_TEST_AND_WRITE : R300_RB3D_Z_TEST;
604 }
605
606
607 /**
608 * Handle glColorMask()
609 */
610 static void r300ColorMask(GLcontext* ctx,
611 GLboolean r, GLboolean g, GLboolean b, GLboolean a)
612 {
613 r300ContextPtr r300 = R300_CONTEXT(ctx);
614 int mask = (b << 0) | (g << 1) | (r << 2) | (a << 3);
615
616 if (mask != r300->hw.cmk.cmd[R300_CMK_COLORMASK]) {
617 R300_STATECHANGE(r300, cmk);
618 r300->hw.cmk.cmd[R300_CMK_COLORMASK] = mask;
619 }
620 }
621
622 /* =============================================================
623 * Point state
624 */
625 static void r300PointSize(GLcontext * ctx, GLfloat size)
626 {
627 r300ContextPtr r300 = R300_CONTEXT(ctx);
628
629 /* This might need fixing later */
630 R300_STATECHANGE(r300, vps);
631 r300->hw.vps.cmd[R300_VPS_POINTSIZE] = r300PackFloat32(1.0);
632 }
633 /* =============================================================
634 * Stencil
635 */
636
637 static int translate_stencil_func(int func)
638 {
639 switch (func) {
640 case GL_NEVER:
641 return R300_ZS_NEVER;
642 break;
643 case GL_LESS:
644 return R300_ZS_LESS;
645 break;
646 case GL_EQUAL:
647 return R300_ZS_EQUAL;
648 break;
649 case GL_LEQUAL:
650 return R300_ZS_LEQUAL;
651 break;
652 case GL_GREATER:
653 return R300_ZS_GREATER;
654 break;
655 case GL_NOTEQUAL:
656 return R300_ZS_NOTEQUAL;
657 break;
658 case GL_GEQUAL:
659 return R300_ZS_GEQUAL;
660 break;
661 case GL_ALWAYS:
662 return R300_ZS_ALWAYS;
663 break;
664 }
665 return 0;
666 }
667
668 static int translate_stencil_op(int op)
669 {
670 switch (op) {
671 case GL_KEEP:
672 return R300_ZS_KEEP;
673 case GL_ZERO:
674 return R300_ZS_ZERO;
675 case GL_REPLACE:
676 return R300_ZS_REPLACE;
677 case GL_INCR:
678 return R300_ZS_INCR;
679 case GL_DECR:
680 return R300_ZS_DECR;
681 case GL_INCR_WRAP_EXT:
682 return R300_ZS_INCR_WRAP;
683 case GL_DECR_WRAP_EXT:
684 return R300_ZS_DECR_WRAP;
685 case GL_INVERT:
686 return R300_ZS_INVERT;
687 }
688 }
689
690 static void r300StencilFunc(GLcontext * ctx, GLenum func,
691 GLint ref, GLuint mask)
692 {
693 r300ContextPtr rmesa = R300_CONTEXT(ctx);
694 GLuint refmask = ((ctx->Stencil.Ref[0] << R300_RB3D_ZS2_STENCIL_REF_SHIFT) |
695 (ctx->Stencil.
696 ValueMask[0] << R300_RB3D_ZS2_STENCIL_MASK_SHIFT));
697 GLuint flag;
698
699 R200_STATECHANGE(rmesa, zs);
700
701 rmesa->hw.zs.cmd[R300_ZS_CNTL_1] &= ~(
702 (R300_ZS_MASK << R300_RB3D_ZS1_FRONT_FUNC_SHIFT)
703 | (R300_ZS_MASK << R300_RB3D_ZS1_BACK_FUNC_SHIFT));
704 rmesa->hw.zs.cmd[R300_ZS_CNTL_2] &= ~((R300_ZS_MASK << R300_RB3D_ZS2_STENCIL_REF_SHIFT) |
705 (R300_ZS_MASK << R300_RB3D_ZS2_STENCIL_MASK_SHIFT));
706
707 flag = translate_stencil_func(ctx->Stencil.Function[0]);
708
709 rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= (flag << R300_RB3D_ZS1_FRONT_FUNC_SHIFT)
710 | (flag << R300_RB3D_ZS1_BACK_FUNC_SHIFT);
711 rmesa->hw.zs.cmd[R300_ZS_CNTL_2] |= refmask;
712 }
713
714 static void r300StencilMask(GLcontext * ctx, GLuint mask)
715 {
716 r300ContextPtr rmesa = R300_CONTEXT(ctx);
717
718 R200_STATECHANGE(rmesa, zs);
719 rmesa->hw.zs.cmd[R300_ZS_CNTL_2] &= ~(R300_ZS_MASK << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT);
720 rmesa->hw.zs.cmd[R300_ZS_CNTL_2] |= ctx->Stencil.WriteMask[0] << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT;
721 }
722
723
724 static void r300StencilOp(GLcontext * ctx, GLenum fail,
725 GLenum zfail, GLenum zpass)
726 {
727 r300ContextPtr rmesa = R300_CONTEXT(ctx);
728
729 R200_STATECHANGE(rmesa, zs);
730 /* It is easier to mask what's left.. */
731 rmesa->hw.zs.cmd[R300_ZS_CNTL_1] &= (R300_ZS_MASK << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT);
732
733 rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=
734 (translate_stencil_op(ctx->Stencil.FailFunc[0]) << R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT)
735 |(translate_stencil_op(ctx->Stencil.ZFailFunc[0]) << R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT)
736 |(translate_stencil_op(ctx->Stencil.ZPassFunc[0]) << R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT)
737 |(translate_stencil_op(ctx->Stencil.FailFunc[0]) << R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT)
738 |(translate_stencil_op(ctx->Stencil.ZFailFunc[0]) << R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT)
739 |(translate_stencil_op(ctx->Stencil.ZPassFunc[0]) << R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT);
740
741 }
742
743 static void r300ClearStencil(GLcontext * ctx, GLint s)
744 {
745 r300ContextPtr rmesa = R300_CONTEXT(ctx);
746
747 /* Not sure whether this is correct.. */
748 R200_STATECHANGE(rmesa, zs);
749 rmesa->hw.zs.cmd[R300_ZS_CNTL_2] =
750 ((GLuint) ctx->Stencil.Clear |
751 (0xff << R200_STENCIL_MASK_SHIFT) |
752 (ctx->Stencil.WriteMask[0] << R200_STENCIL_WRITEMASK_SHIFT));
753 }
754
755 /* =============================================================
756 * Window position and viewport transformation
757 */
758
759 /*
760 * To correctly position primitives:
761 */
762 #define SUBPIXEL_X 0.125
763 #define SUBPIXEL_Y 0.125
764
765 void r300UpdateWindow(GLcontext * ctx)
766 {
767 r300ContextPtr rmesa = R300_CONTEXT(ctx);
768 __DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable;
769 GLfloat xoffset = dPriv ? (GLfloat) dPriv->x : 0;
770 GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0;
771 const GLfloat *v = ctx->Viewport._WindowMap.m;
772
773 GLfloat sx = v[MAT_SX];
774 GLfloat tx = v[MAT_TX] + xoffset + SUBPIXEL_X;
775 GLfloat sy = -v[MAT_SY];
776 GLfloat ty = (-v[MAT_TY]) + yoffset + SUBPIXEL_Y;
777 GLfloat sz = v[MAT_SZ] * rmesa->state.depth.scale;
778 GLfloat tz = v[MAT_TZ] * rmesa->state.depth.scale;
779
780 R300_FIREVERTICES(rmesa);
781 R300_STATECHANGE(rmesa, vpt);
782
783 rmesa->hw.vpt.cmd[R300_VPT_XSCALE] = r300PackFloat32(sx);
784 rmesa->hw.vpt.cmd[R300_VPT_XOFFSET] = r300PackFloat32(tx);
785 rmesa->hw.vpt.cmd[R300_VPT_YSCALE] = r300PackFloat32(sy);
786 rmesa->hw.vpt.cmd[R300_VPT_YOFFSET] = r300PackFloat32(ty);
787 rmesa->hw.vpt.cmd[R300_VPT_ZSCALE] = r300PackFloat32(sz);
788 rmesa->hw.vpt.cmd[R300_VPT_ZOFFSET] = r300PackFloat32(tz);
789 }
790
791 static void r300Viewport(GLcontext * ctx, GLint x, GLint y,
792 GLsizei width, GLsizei height)
793 {
794 /* Don't pipeline viewport changes, conflict with window offset
795 * setting below. Could apply deltas to rescue pipelined viewport
796 * values, or keep the originals hanging around.
797 */
798 R200_FIREVERTICES(R200_CONTEXT(ctx));
799 r300UpdateWindow(ctx);
800 }
801
802 static void r300DepthRange(GLcontext * ctx, GLclampd nearval, GLclampd farval)
803 {
804 r300UpdateWindow(ctx);
805 }
806
807 /* Routing and texture-related */
808
809 void r300_setup_routing(GLcontext *ctx, GLboolean immediate)
810 {
811 int i, count=0,reg=0;
812 GLuint dw, mask;
813 TNLcontext *tnl = TNL_CONTEXT(ctx);
814 struct vertex_buffer *VB = &tnl->vb;
815 r300ContextPtr r300 = R300_CONTEXT(ctx);
816
817
818 /* Stage 1 - input to VAP */
819
820 /* Assign register number automatically, retaining it in rmesa->state.reg */
821
822 /* Note: immediate vertex data includes all coordinates.
823 To save bandwidth use either VBUF or state-based vertex generation */
824
825 #define CONFIGURE_AOS(v, o, r, f) \
826 {\
827 if (RADEON_DEBUG & DEBUG_STATE)fprintf(stderr, "Enabling "#r "\n"); \
828 if(immediate){ \
829 r300->state.aos[count].element_size=4; \
830 r300->state.aos[count].stride=4; \
831 r300->state.aos[count].ncomponents=4; \
832 } else { \
833 r300->state.aos[count].element_size=v->size; \
834 r300->state.aos[count].stride=v->size; \
835 r300->state.aos[count].ncomponents=v->size; \
836 } \
837 r300->state.aos[count].offset=o; \
838 r300->state.aos[count].reg=reg; \
839 r300->state.aos[count].format=(f); \
840 r300->state.vap_reg.r=reg; \
841 count++; \
842 reg++; \
843 }
844
845 /* All offsets are 0 - for use by immediate mode.
846 Should change later to handle vertex buffers */
847 if(tnl->render_inputs & _TNL_BIT_POS)
848 CONFIGURE_AOS(VB->ObjPtr, 0, i_coords, AOS_FORMAT_FLOAT);
849 if(tnl->render_inputs & _TNL_BIT_NORMAL)
850 CONFIGURE_AOS(VB->NormalPtr, 0, i_normal, AOS_FORMAT_FLOAT);
851
852 if(tnl->render_inputs & _TNL_BIT_COLOR0)
853 CONFIGURE_AOS(VB->ColorPtr[0], 0, i_color[0], AOS_FORMAT_FLOAT_COLOR);
854 if(tnl->render_inputs & _TNL_BIT_COLOR1)
855 CONFIGURE_AOS(VB->SecondaryColorPtr[0], 0, i_color[1], AOS_FORMAT_FLOAT_COLOR);
856
857 if(tnl->render_inputs & _TNL_BIT_FOG)
858 CONFIGURE_AOS(VB->FogCoordPtr, 0, i_fog, AOS_FORMAT_FLOAT);
859
860 for(i=0;i < ctx->Const.MaxTextureUnits;i++)
861 if(tnl->render_inputs & (_TNL_BIT_TEX0<<i))
862 CONFIGURE_AOS(VB->TexCoordPtr[i], 0, i_tex[i], AOS_FORMAT_FLOAT);
863
864 if(tnl->render_inputs & _TNL_BIT_INDEX)
865 CONFIGURE_AOS(VB->IndexPtr[0], 0, i_index, AOS_FORMAT_FLOAT);
866 if(tnl->render_inputs & _TNL_BIT_POINTSIZE)
867 CONFIGURE_AOS(VB->PointSizePtr, 0, i_pointsize, AOS_FORMAT_FLOAT);
868
869 r300->state.aos_count=count;
870
871 if (RADEON_DEBUG & DEBUG_STATE)
872 fprintf(stderr, "aos_count=%d\n", count);
873
874 if(count>R300_MAX_AOS_ARRAYS){
875 fprintf(stderr, "Aieee ! AOS array count exceeded !\n");
876 exit(-1);
877 }
878
879 /* Implement AOS */
880
881 /* setup INPUT_ROUTE */
882 R300_STATECHANGE(r300, vir[0]);
883 for(i=0;i+1<count;i+=2){
884 dw=(r300->state.aos[i].ncomponents-1)
885 | ((r300->state.aos[i].reg)<<8)
886 | (r300->state.aos[i].format<<14)
887 | (((r300->state.aos[i+1].ncomponents-1)
888 | ((r300->state.aos[i+1].reg)<<8)
889 | (r300->state.aos[i+1].format<<14))<<16);
890
891 if(i+2==count){
892 dw|=(1<<(13+16));
893 }
894 r300->hw.vir[0].cmd[R300_VIR_CNTL_0+(i>>1)]=dw;
895 }
896 if(count & 1){
897 dw=(r300->state.aos[count-1].ncomponents-1)
898 | (r300->state.aos[count-1].format<<14)
899 | ((r300->state.aos[count-1].reg)<<8)
900 | (1<<13);
901 r300->hw.vir[0].cmd[R300_VIR_CNTL_0+(count>>1)]=dw;
902 //fprintf(stderr, "vir0 dw=%08x\n", dw);
903 }
904 /* Set the rest of INPUT_ROUTE_0 to 0 */
905 //for(i=((count+1)>>1); i<8; i++)r300->hw.vir[0].cmd[R300_VIR_CNTL_0+i]=(0x0);
906 ((drm_r300_cmd_header_t*)r300->hw.vir[0].cmd)->unchecked_state.count = (count+1)>>1;
907
908
909 /* Mesa assumes that all missing components are from (0, 0, 0, 1) */
910 #define ALL_COMPONENTS ((R300_INPUT_ROUTE_SELECT_X<<R300_INPUT_ROUTE_X_SHIFT) \
911 | (R300_INPUT_ROUTE_SELECT_Y<<R300_INPUT_ROUTE_Y_SHIFT) \
912 | (R300_INPUT_ROUTE_SELECT_Z<<R300_INPUT_ROUTE_Z_SHIFT) \
913 | (R300_INPUT_ROUTE_SELECT_W<<R300_INPUT_ROUTE_W_SHIFT))
914
915 #define ALL_DEFAULT ((R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_X_SHIFT) \
916 | (R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_Y_SHIFT) \
917 | (R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_Z_SHIFT) \
918 | (R300_INPUT_ROUTE_SELECT_ONE<<R300_INPUT_ROUTE_W_SHIFT))
919
920 R300_STATECHANGE(r300, vir[1]);
921
922 for(i=0;i+1<count;i+=2){
923 /* do i first.. */
924 mask=(1<<(r300->state.aos[i].ncomponents*3))-1;
925 dw=(ALL_COMPONENTS & mask)
926 | (ALL_DEFAULT & ~mask)
927 | R300_INPUT_ROUTE_ENABLE;
928
929 /* i+1 */
930 mask=(1<<(r300->state.aos[i+1].ncomponents*3))-1;
931 dw|=(
932 (ALL_COMPONENTS & mask)
933 | (ALL_DEFAULT & ~mask)
934 | R300_INPUT_ROUTE_ENABLE
935 )<<16;
936
937 r300->hw.vir[1].cmd[R300_VIR_CNTL_0+(i>>1)]=dw;
938 }
939 if(count & 1){
940 mask=(1<<(r300->state.aos[count-1].ncomponents*3))-1;
941 dw=(ALL_COMPONENTS & mask)
942 | (ALL_DEFAULT & ~mask)
943 | R300_INPUT_ROUTE_ENABLE;
944 r300->hw.vir[1].cmd[R300_VIR_CNTL_0+(count>>1)]=dw;
945 //fprintf(stderr, "vir1 dw=%08x\n", dw);
946 }
947 /* Set the rest of INPUT_ROUTE_1 to 0 */
948 //for(i=((count+1)>>1); i<8; i++)r300->hw.vir[1].cmd[R300_VIR_CNTL_0+i]=0x0;
949 ((drm_r300_cmd_header_t*)r300->hw.vir[1].cmd)->unchecked_state.count = (count+1)>>1;
950
951 /* Set up input_cntl */
952
953 R300_STATECHANGE(r300, vic);
954 r300->hw.vic.cmd[R300_VIC_CNTL_0]=0x5555; /* Hard coded value, no idea what it means */
955
956 r300->hw.vic.cmd[R300_VIC_CNTL_1]=R300_INPUT_CNTL_POS
957 | R300_INPUT_CNTL_COLOR;
958
959 for(i=0;i < ctx->Const.MaxTextureUnits;i++)
960 if(ctx->Texture.Unit[i].Enabled)
961 r300->hw.vic.cmd[R300_VIC_CNTL_1]|=(R300_INPUT_CNTL_TC0<<i);
962
963 /* Stage 3: VAP output */
964 R300_STATECHANGE(r300, vof);
965 r300->hw.vof.cmd[R300_VOF_CNTL_0]=R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
966 | R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT;
967
968 r300->hw.vof.cmd[R300_VOF_CNTL_1]=0;
969 for(i=0;i < ctx->Const.MaxTextureUnits;i++)
970 if(ctx->Texture.Unit[i].Enabled)
971 r300->hw.vof.cmd[R300_VOF_CNTL_1]|=(4<<(3*i));
972
973 }
974
975 static r300TexObj default_tex_obj={
976 filter:R300_TX_MAG_FILTER_LINEAR | R300_TX_MIN_FILTER_LINEAR,
977 pitch: 0x8000,
978 size: (0xff << R300_TX_WIDTHMASK_SHIFT)
979 | (0xff << R300_TX_HEIGHTMASK_SHIFT)
980 | (0x8 << R300_TX_SIZE_SHIFT),
981 format: 0x88a0c,
982 offset: 0x0,
983 unknown4: 0x0,
984 unknown5: 0x0
985 };
986
987 /* there is probably a system to these value, but, for now,
988 we just try by hand */
989
990 static int inline translate_src(int src)
991 {
992 switch (src) {
993 case GL_TEXTURE:
994 return 1;
995 break;
996 case GL_CONSTANT:
997 return 2;
998 break;
999 case GL_PRIMARY_COLOR:
1000 return 3;
1001 break;
1002 case GL_PREVIOUS:
1003 return 4;
1004 break;
1005 case GL_ZERO:
1006 return 5;
1007 break;
1008 case GL_ONE:
1009 return 6;
1010 break;
1011 default:
1012 return 0;
1013 }
1014 }
1015
1016 /* r300 doesnt handle GL_CLAMP and GL_MIRROR_CLAMP_EXT correctly when filter is NEAREST.
1017 * Since texwrap produces same results for GL_CLAMP and GL_CLAMP_TO_EDGE we use them instead.
1018 * We need to recalculate wrap modes whenever filter mode is changed because someone might do:
1019 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1020 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1021 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1022 * Since r300 completely ignores R300_TX_CLAMP when either min or mag is nearest it cant handle
1023 * combinations where only one of them is nearest.
1024 */
1025 static unsigned long gen_fixed_filter(unsigned long f)
1026 {
1027 unsigned long mag, min, needs_fixing=0;
1028 //return f;
1029
1030 /* We ignore MIRROR bit so we dont have to do everything twice */
1031 if((f & ((7-1) << R300_TX_WRAP_S_SHIFT)) == (R300_TX_CLAMP << R300_TX_WRAP_S_SHIFT)){
1032 needs_fixing |= 1;
1033 }
1034 if((f & ((7-1) << R300_TX_WRAP_T_SHIFT)) == (R300_TX_CLAMP << R300_TX_WRAP_T_SHIFT)){
1035 needs_fixing |= 2;
1036 }
1037 if((f & ((7-1) << R300_TX_WRAP_Q_SHIFT)) == (R300_TX_CLAMP << R300_TX_WRAP_Q_SHIFT)){
1038 needs_fixing |= 4;
1039 }
1040
1041 if(!needs_fixing)
1042 return f;
1043
1044 mag=f & R300_TX_MAG_FILTER_MASK;
1045 min=f & R300_TX_MIN_FILTER_MASK;
1046
1047 /* TODO: Check for anisto filters too */
1048 if((mag != R300_TX_MAG_FILTER_NEAREST) && (min != R300_TX_MIN_FILTER_NEAREST))
1049 return f;
1050
1051 /* r300 cant handle these modes hence we force nearest to linear */
1052 if((mag == R300_TX_MAG_FILTER_NEAREST) && (min != R300_TX_MIN_FILTER_NEAREST)){
1053 f &= ~R300_TX_MAG_FILTER_NEAREST;
1054 f |= R300_TX_MAG_FILTER_LINEAR;
1055 return f;
1056 }
1057
1058 if((min == R300_TX_MIN_FILTER_NEAREST) && (mag != R300_TX_MAG_FILTER_NEAREST)){
1059 f &= ~R300_TX_MIN_FILTER_NEAREST;
1060 f |= R300_TX_MIN_FILTER_LINEAR;
1061 return f;
1062 }
1063
1064 /* Both are nearest */
1065 if(needs_fixing & 1){
1066 f &= ~((7-1) << R300_TX_WRAP_S_SHIFT);
1067 f |= R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_S_SHIFT;
1068 }
1069 if(needs_fixing & 2){
1070 f &= ~((7-1) << R300_TX_WRAP_T_SHIFT);
1071 f |= R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_T_SHIFT;
1072 }
1073 if(needs_fixing & 4){
1074 f &= ~((7-1) << R300_TX_WRAP_Q_SHIFT);
1075 f |= R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_Q_SHIFT;
1076 }
1077 return f;
1078 }
1079
1080 void r300_setup_textures(GLcontext *ctx)
1081 {
1082 int i, mtu;
1083 struct r300_tex_obj *t;
1084 r300ContextPtr r300 = R300_CONTEXT(ctx);
1085 int max_texture_unit=-1; /* -1 translates into no setup costs for fields */
1086 struct gl_texture_unit *texUnit;
1087
1088 R300_STATECHANGE(r300, txe);
1089 R300_STATECHANGE(r300, tex.filter);
1090 R300_STATECHANGE(r300, tex.unknown1);
1091 R300_STATECHANGE(r300, tex.size);
1092 R300_STATECHANGE(r300, tex.format);
1093 R300_STATECHANGE(r300, tex.offset);
1094 R300_STATECHANGE(r300, tex.unknown4);
1095 R300_STATECHANGE(r300, tex.unknown5);
1096 //R300_STATECHANGE(r300, tex.border_color);
1097
1098 r300->state.texture.tc_count=0;
1099
1100 r300->hw.txe.cmd[R300_TXE_ENABLE]=0x0;
1101
1102 mtu = r300->radeon.glCtx->Const.MaxTextureUnits;
1103 if (RADEON_DEBUG & DEBUG_STATE)
1104 fprintf(stderr, "mtu=%d\n", mtu);
1105
1106 if(mtu>R300_MAX_TEXTURE_UNITS){
1107 fprintf(stderr, "Aiiee ! mtu=%d is greater than R300_MAX_TEXTURE_UNITS=%d\n",
1108 mtu, R300_MAX_TEXTURE_UNITS);
1109 exit(-1);
1110 }
1111 for(i=0;i<mtu;i++){
1112 if(ctx->Texture.Unit[i].Enabled){
1113 t=r300->state.texture.unit[i].texobj;
1114 //fprintf(stderr, "format=%08x\n", r300->state.texture.unit[i].format);
1115 r300->state.texture.tc_count++;
1116 if(t==NULL){
1117 fprintf(stderr, "Texture unit %d enabled, but corresponding texobj is NULL, using default object.\n", i);
1118 //exit(-1);
1119 t=&default_tex_obj;
1120 }
1121 //fprintf(stderr, "t->format=%08x\n", t->format);
1122 if (RADEON_DEBUG & DEBUG_STATE)
1123 fprintf(stderr, "Activating texture unit %d\n", i);
1124 max_texture_unit=i;
1125 r300->hw.txe.cmd[R300_TXE_ENABLE]|=(1<<i);
1126
1127 r300->hw.tex.filter.cmd[R300_TEX_VALUE_0+i]=gen_fixed_filter(t->filter);
1128 /* No idea why linear filtered textures shake when puting random data */
1129 /*r300->hw.tex.unknown1.cmd[R300_TEX_VALUE_0+i]=(rand()%0xffffffff) & (~0x1fff);*/
1130 r300->hw.tex.size.cmd[R300_TEX_VALUE_0+i]=t->size;
1131 r300->hw.tex.format.cmd[R300_TEX_VALUE_0+i]=t->format;
1132 //fprintf(stderr, "t->format=%08x\n", t->format);
1133 r300->hw.tex.offset.cmd[R300_TEX_VALUE_0+i]=r300->radeon.radeonScreen->fbLocation+t->offset;
1134 r300->hw.tex.unknown4.cmd[R300_TEX_VALUE_0+i]=0x0;
1135 r300->hw.tex.unknown5.cmd[R300_TEX_VALUE_0+i]=0x0;
1136 //r300->hw.tex.border_color.cmd[R300_TEX_VALUE_0+i]=t->pp_border_color;
1137 }
1138 }
1139 ((drm_r300_cmd_header_t*)r300->hw.tex.filter.cmd)->unchecked_state.count = max_texture_unit+1;
1140 ((drm_r300_cmd_header_t*)r300->hw.tex.unknown1.cmd)->unchecked_state.count = max_texture_unit+1;
1141 ((drm_r300_cmd_header_t*)r300->hw.tex.size.cmd)->unchecked_state.count = max_texture_unit+1;
1142 ((drm_r300_cmd_header_t*)r300->hw.tex.format.cmd)->unchecked_state.count = max_texture_unit+1;
1143 ((drm_r300_cmd_header_t*)r300->hw.tex.offset.cmd)->unchecked_state.count = max_texture_unit+1;
1144 ((drm_r300_cmd_header_t*)r300->hw.tex.unknown4.cmd)->unchecked_state.count = max_texture_unit+1;
1145 ((drm_r300_cmd_header_t*)r300->hw.tex.unknown5.cmd)->unchecked_state.count = max_texture_unit+1;
1146 //((drm_r300_cmd_header_t*)r300->hw.tex.border_color.cmd)->unchecked_state.count = max_texture_unit+1;
1147
1148 if (RADEON_DEBUG & DEBUG_STATE)
1149 fprintf(stderr, "TX_ENABLE: %08x max_texture_unit=%d\n", r300->hw.txe.cmd[R300_TXE_ENABLE], max_texture_unit);
1150 }
1151
1152 void r300_setup_rs_unit(GLcontext *ctx)
1153 {
1154 r300ContextPtr r300 = R300_CONTEXT(ctx);
1155 int i;
1156
1157 /* This needs to be rewritten - it is a hack at best */
1158
1159 R300_STATECHANGE(r300, ri);
1160 R300_STATECHANGE(r300, rc);
1161 R300_STATECHANGE(r300, rr);
1162
1163 for(i = 1; i <= 8; ++i)
1164 r300->hw.ri.cmd[i] = 0x00d10000;
1165 r300->hw.ri.cmd[R300_RI_INTERP_1] |= R300_RS_INTERP_1_UNKNOWN;
1166 r300->hw.ri.cmd[R300_RI_INTERP_2] |= R300_RS_INTERP_2_UNKNOWN;
1167 r300->hw.ri.cmd[R300_RI_INTERP_3] |= R300_RS_INTERP_3_UNKNOWN;
1168
1169 #if 1
1170 for(i = 2; i <= 8; ++i)
1171 r300->hw.ri.cmd[i] |= 4;
1172 #endif
1173
1174 for(i = 1; i <= 8; ++i)
1175 r300->hw.rr.cmd[i] = 0;
1176 /* textures enabled ? */
1177 if(r300->state.texture.tc_count>0){
1178
1179 /* This code only really works with one set of texture coordinates */
1180
1181 /* The second constant is needed to get glxgears display anything .. */
1182 r300->hw.rc.cmd[1] = R300_RS_CNTL_0_UNKNOWN_7
1183 | R300_RS_CNTL_0_UNKNOWN_18
1184 | (r300->state.texture.tc_count<<R300_RS_CNTL_TC_CNT_SHIFT);
1185 r300->hw.rc.cmd[2] = 0xc0;
1186
1187
1188 ((drm_r300_cmd_header_t*)r300->hw.rr.cmd)->unchecked_state.count = 1;
1189 r300->hw.rr.cmd[R300_RR_ROUTE_0] = 0x24008;
1190
1191 } else {
1192
1193 /* The second constant is needed to get glxgears display anything .. */
1194 r300->hw.rc.cmd[1] = R300_RS_CNTL_0_UNKNOWN_7 | R300_RS_CNTL_0_UNKNOWN_18;
1195 r300->hw.rc.cmd[2] = 0;
1196
1197 ((drm_r300_cmd_header_t*)r300->hw.rr.cmd)->unchecked_state.count = 1;
1198 r300->hw.rr.cmd[R300_RR_ROUTE_0] = 0x4000;
1199
1200 }
1201 }
1202
1203 #define vpucount(ptr) (((drm_r300_cmd_header_t*)(ptr))->vpu.count)
1204
1205 #define bump_vpu_count(ptr, new_count) do{\
1206 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
1207 int _nc=(new_count)/4; \
1208 if(_nc>_p->vpu.count)_p->vpu.count=_nc;\
1209 }while(0)
1210
1211 void static inline setup_vertex_shader_fragment(r300ContextPtr r300, int dest, struct r300_vertex_shader_fragment *vsf)
1212 {
1213 int i;
1214
1215 if(vsf->length==0)return;
1216
1217 if(vsf->length & 0x3){
1218 fprintf(stderr,"VERTEX_SHADER_FRAGMENT must have length divisible by 4\n");
1219 exit(-1);
1220 }
1221
1222 switch((dest>>8) & 0xf){
1223 case 0:
1224 R300_STATECHANGE(r300, vpi);
1225 for(i=0;i<vsf->length;i++)
1226 r300->hw.vpi.cmd[R300_VPI_INSTR_0+i+4*(dest & 0xff)]=(vsf->body.d[i]);
1227 bump_vpu_count(r300->hw.vpi.cmd, vsf->length+4*(dest & 0xff));
1228 break;
1229
1230 case 2:
1231 R300_STATECHANGE(r300, vpp);
1232 for(i=0;i<vsf->length;i++)
1233 r300->hw.vpp.cmd[R300_VPP_PARAM_0+i+4*(dest & 0xff)]=(vsf->body.d[i]);
1234 bump_vpu_count(r300->hw.vpp.cmd, vsf->length+4*(dest & 0xff));
1235 break;
1236 case 4:
1237 R300_STATECHANGE(r300, vps);
1238 for(i=0;i<vsf->length;i++)
1239 r300->hw.vps.cmd[1+i+4*(dest & 0xff)]=(vsf->body.d[i]);
1240 bump_vpu_count(r300->hw.vps.cmd, vsf->length+4*(dest & 0xff));
1241 break;
1242 default:
1243 fprintf(stderr, "%s:%s don't know how to handle dest %04x\n", __FILE__, __FUNCTION__, dest);
1244 exit(-1);
1245 }
1246 }
1247
1248
1249 void r300SetupVertexShader(r300ContextPtr rmesa)
1250 {
1251 GLcontext* ctx = rmesa->radeon.glCtx;
1252
1253 /* Reset state, in case we don't use something */
1254 ((drm_r300_cmd_header_t*)rmesa->hw.vpp.cmd)->vpu.count = 0;
1255 ((drm_r300_cmd_header_t*)rmesa->hw.vpi.cmd)->vpu.count = 0;
1256 ((drm_r300_cmd_header_t*)rmesa->hw.vps.cmd)->vpu.count = 0;
1257
1258
1259 /* This needs to be replaced by vertex shader generation code */
1260
1261
1262 /* textures enabled ? */
1263 if(rmesa->state.texture.tc_count>0){
1264 rmesa->state.vertex_shader=SINGLE_TEXTURE_VERTEX_SHADER;
1265 } else {
1266 rmesa->state.vertex_shader=FLAT_COLOR_VERTEX_SHADER;
1267 }
1268
1269
1270 rmesa->state.vertex_shader.matrix[0].length=16;
1271 memcpy(rmesa->state.vertex_shader.matrix[0].body.f, ctx->_ModelProjectMatrix.m, 16*4);
1272
1273 setup_vertex_shader_fragment(rmesa, VSF_DEST_PROGRAM, &(rmesa->state.vertex_shader.program));
1274
1275 setup_vertex_shader_fragment(rmesa, VSF_DEST_MATRIX0, &(rmesa->state.vertex_shader.matrix[0]));
1276 #if 0
1277 setup_vertex_shader_fragment(rmesa, VSF_DEST_MATRIX1, &(rmesa->state.vertex_shader.matrix[0]));
1278 setup_vertex_shader_fragment(rmesa, VSF_DEST_MATRIX2, &(rmesa->state.vertex_shader.matrix[0]));
1279
1280 setup_vertex_shader_fragment(rmesa, VSF_DEST_VECTOR0, &(rmesa->state.vertex_shader.vector[0]));
1281 setup_vertex_shader_fragment(rmesa, VSF_DEST_VECTOR1, &(rmesa->state.vertex_shader.vector[1]));
1282 #endif
1283
1284 #if 0
1285 setup_vertex_shader_fragment(rmesa, VSF_DEST_UNKNOWN1, &(rmesa->state.vertex_shader.unknown1));
1286 setup_vertex_shader_fragment(rmesa, VSF_DEST_UNKNOWN2, &(rmesa->state.vertex_shader.unknown2));
1287 #endif
1288
1289 R300_STATECHANGE(rmesa, pvs);
1290 rmesa->hw.pvs.cmd[R300_PVS_CNTL_1]=(rmesa->state.vertex_shader.program_start << R300_PVS_CNTL_1_PROGRAM_START_SHIFT)
1291 | (rmesa->state.vertex_shader.unknown_ptr1 << R300_PVS_CNTL_1_UNKNOWN_SHIFT)
1292 | (rmesa->state.vertex_shader.program_end << R300_PVS_CNTL_1_PROGRAM_END_SHIFT);
1293 rmesa->hw.pvs.cmd[R300_PVS_CNTL_2]=(rmesa->state.vertex_shader.param_offset << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT)
1294 | (rmesa->state.vertex_shader.param_count << R300_PVS_CNTL_2_PARAM_COUNT_SHIFT);
1295 rmesa->hw.pvs.cmd[R300_PVS_CNTL_3]=(rmesa->state.vertex_shader.unknown_ptr2 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT)
1296 | (rmesa->state.vertex_shader.unknown_ptr3 << 0);
1297
1298 /* This is done for vertex shader fragments, but also needs to be done for vap_pvs,
1299 so I leave it as a reminder */
1300 #if 0
1301 reg_start(R300_VAP_PVS_WAITIDLE,0);
1302 e32(0x00000000);
1303 #endif
1304 }
1305
1306 void r300SetupVertexProgram(r300ContextPtr rmesa)
1307 {
1308 GLcontext* ctx = rmesa->radeon.glCtx;
1309
1310 /* Reset state, in case we don't use something */
1311 ((drm_r300_cmd_header_t*)rmesa->hw.vpp.cmd)->vpu.count = 0;
1312 ((drm_r300_cmd_header_t*)rmesa->hw.vpi.cmd)->vpu.count = 0;
1313 ((drm_r300_cmd_header_t*)rmesa->hw.vps.cmd)->vpu.count = 0;
1314
1315 #if 0
1316 /* This needs to be replaced by vertex shader generation code */
1317
1318
1319 /* textures enabled ? */
1320 if(rmesa->state.texture.tc_count>0){
1321 rmesa->state.vertex_shader=SINGLE_TEXTURE_VERTEX_SHADER;
1322 } else {
1323 rmesa->state.vertex_shader=FLAT_COLOR_VERTEX_SHADER;
1324 }
1325
1326
1327 rmesa->state.vertex_shader.matrix[0].length=16;
1328 memcpy(rmesa->state.vertex_shader.matrix[0].body.f, ctx->_ModelProjectMatrix.m, 16*4);
1329 #endif
1330
1331 setup_vertex_shader_fragment(rmesa, VSF_DEST_PROGRAM, &(rmesa->current_vp->program));
1332
1333 setup_vertex_shader_fragment(rmesa, VSF_DEST_MATRIX0, &(rmesa->current_vp->params));
1334
1335 #if 0
1336 setup_vertex_shader_fragment(rmesa, VSF_DEST_UNKNOWN1, &(rmesa->state.vertex_shader.unknown1));
1337 setup_vertex_shader_fragment(rmesa, VSF_DEST_UNKNOWN2, &(rmesa->state.vertex_shader.unknown2));
1338 #endif
1339
1340 R300_STATECHANGE(rmesa, pvs);
1341 rmesa->hw.pvs.cmd[R300_PVS_CNTL_1]=(0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT)
1342 | (rmesa->state.vertex_shader.unknown_ptr1 << R300_PVS_CNTL_1_UNKNOWN_SHIFT)
1343 | (rmesa->current_vp->program.length/4 << R300_PVS_CNTL_1_PROGRAM_END_SHIFT);
1344 rmesa->hw.pvs.cmd[R300_PVS_CNTL_2]=(0 << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT)
1345 | (rmesa->current_vp->params.length/4 << R300_PVS_CNTL_2_PARAM_COUNT_SHIFT);
1346 rmesa->hw.pvs.cmd[R300_PVS_CNTL_3]=(0/*rmesa->state.vertex_shader.unknown_ptr2*/ << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT)
1347 | (rmesa->current_vp->program.length/4/*rmesa->state.vertex_shader.unknown_ptr3*/ << 0);
1348
1349 /* This is done for vertex shader fragments, but also needs to be done for vap_pvs,
1350 so I leave it as a reminder */
1351 #if 0
1352 reg_start(R300_VAP_PVS_WAITIDLE,0);
1353 e32(0x00000000);
1354 #endif
1355 }
1356
1357 void r300SetupPixelShader(r300ContextPtr rmesa)
1358 {
1359 int i,k;
1360
1361 /* This needs to be replaced by pixel shader generation code */
1362
1363 /* textures enabled ? */
1364 if(rmesa->state.texture.tc_count>0){
1365 rmesa->state.pixel_shader=SINGLE_TEXTURE_PIXEL_SHADER;
1366 } else {
1367 rmesa->state.pixel_shader=FLAT_COLOR_PIXEL_SHADER;
1368 }
1369
1370 R300_STATECHANGE(rmesa, fpt);
1371 for(i=0;i<rmesa->state.pixel_shader.program.tex.length;i++)
1372 rmesa->hw.fpt.cmd[R300_FPT_INSTR_0+i]=rmesa->state.pixel_shader.program.tex.inst[i];
1373 rmesa->hw.fpt.cmd[R300_FPT_CMD_0]=cmducs(R300_PFS_TEXI_0, rmesa->state.pixel_shader.program.tex.length);
1374
1375 #define OUTPUT_FIELD(st, reg, field) \
1376 R300_STATECHANGE(rmesa, st); \
1377 for(i=0;i<rmesa->state.pixel_shader.program.alu.length;i++) \
1378 rmesa->hw.st.cmd[R300_FPI_INSTR_0+i]=rmesa->state.pixel_shader.program.alu.inst[i].field;\
1379 rmesa->hw.st.cmd[R300_FPI_CMD_0]=cmducs(reg, rmesa->state.pixel_shader.program.alu.length);
1380
1381 OUTPUT_FIELD(fpi[0], R300_PFS_INSTR0_0, inst0);
1382 OUTPUT_FIELD(fpi[1], R300_PFS_INSTR1_0, inst1);
1383 OUTPUT_FIELD(fpi[2], R300_PFS_INSTR2_0, inst2);
1384 OUTPUT_FIELD(fpi[3], R300_PFS_INSTR3_0, inst3);
1385 #undef OUTPUT_FIELD
1386
1387 R300_STATECHANGE(rmesa, fp);
1388 for(i=0;i<4;i++){
1389 rmesa->hw.fp.cmd[R300_FP_NODE0+i]=
1390 (rmesa->state.pixel_shader.program.node[i].alu_offset << R300_PFS_NODE_ALU_OFFSET_SHIFT)
1391 | (rmesa->state.pixel_shader.program.node[i].alu_end << R300_PFS_NODE_ALU_END_SHIFT)
1392 | (rmesa->state.pixel_shader.program.node[i].tex_offset << R300_PFS_NODE_TEX_OFFSET_SHIFT)
1393 | (rmesa->state.pixel_shader.program.node[i].tex_end << R300_PFS_NODE_TEX_END_SHIFT)
1394 | ( (i==3) ? R300_PFS_NODE_LAST_NODE : 0);
1395 }
1396
1397 /* PFS_CNTL_0 */
1398 rmesa->hw.fp.cmd[R300_FP_CNTL0]=
1399 (rmesa->state.pixel_shader.program.active_nodes-1)
1400 | (rmesa->state.pixel_shader.program.first_node_has_tex<<3);
1401 /* PFS_CNTL_1 */
1402 rmesa->hw.fp.cmd[R300_FP_CNTL1]=rmesa->state.pixel_shader.program.temp_register_count;
1403 /* PFS_CNTL_2 */
1404 rmesa->hw.fp.cmd[R300_FP_CNTL2]=
1405 (rmesa->state.pixel_shader.program.alu_offset << R300_PFS_CNTL_ALU_OFFSET_SHIFT)
1406 | (rmesa->state.pixel_shader.program.alu_end << R300_PFS_CNTL_ALU_END_SHIFT)
1407 | (rmesa->state.pixel_shader.program.tex_offset << R300_PFS_CNTL_TEX_OFFSET_SHIFT)
1408 | (rmesa->state.pixel_shader.program.tex_end << R300_PFS_CNTL_TEX_END_SHIFT);
1409
1410 R300_STATECHANGE(rmesa, fpp);
1411 for(i=0;i<rmesa->state.pixel_shader.param_length;i++){
1412 rmesa->hw.fpp.cmd[R300_FPP_PARAM_0+4*i+0]=r300PackFloat32(rmesa->state.pixel_shader.param[i].x);
1413 rmesa->hw.fpp.cmd[R300_FPP_PARAM_0+4*i+1]=r300PackFloat32(rmesa->state.pixel_shader.param[i].y);
1414 rmesa->hw.fpp.cmd[R300_FPP_PARAM_0+4*i+2]=r300PackFloat32(rmesa->state.pixel_shader.param[i].z);
1415 rmesa->hw.fpp.cmd[R300_FPP_PARAM_0+4*i+3]=r300PackFloat32(rmesa->state.pixel_shader.param[i].w);
1416 }
1417 rmesa->hw.fpp.cmd[R300_FPP_CMD_0]=cmducs(R300_PFS_PARAM_0_X, rmesa->state.pixel_shader.param_length);
1418
1419 }
1420
1421 /**
1422 * Called by Mesa after an internal state update.
1423 */
1424 static void r300InvalidateState(GLcontext * ctx, GLuint new_state)
1425 {
1426 r300ContextPtr r300 = R300_CONTEXT(ctx);
1427
1428 _swrast_InvalidateState(ctx, new_state);
1429 _swsetup_InvalidateState(ctx, new_state);
1430 _ac_InvalidateState(ctx, new_state);
1431 _tnl_InvalidateState(ctx, new_state);
1432 _ae_invalidate_state(ctx, new_state);
1433
1434 /* Go inefficiency! */
1435 r300ResetHwState(r300);
1436 }
1437
1438
1439 /**
1440 * Completely recalculates hardware state based on the Mesa state.
1441 */
1442 void r300ResetHwState(r300ContextPtr r300)
1443 {
1444 GLcontext* ctx = r300->radeon.glCtx;
1445 int i;
1446
1447 if (RADEON_DEBUG & DEBUG_STATE)
1448 fprintf(stderr, "%s\n", __FUNCTION__);
1449
1450 /* This is a place to initialize registers which
1451 have bitfields accessed by different functions
1452 and not all bits are used */
1453 #if 0
1454 r300->hw.zs.cmd[R300_ZS_CNTL_0] = 0;
1455 r300->hw.zs.cmd[R300_ZS_CNTL_1] = 0;
1456 r300->hw.zs.cmd[R300_ZS_CNTL_2] = 0xffff00;
1457 #endif
1458
1459 /* go and compute register values from GL state */
1460
1461 r300UpdateWindow(ctx);
1462
1463 r300ColorMask(ctx,
1464 ctx->Color.ColorMask[RCOMP],
1465 ctx->Color.ColorMask[GCOMP],
1466 ctx->Color.ColorMask[BCOMP],
1467 ctx->Color.ColorMask[ACOMP]);
1468
1469 r300Enable(ctx, GL_DEPTH_TEST, ctx->Depth.Test);
1470 r300DepthMask(ctx, ctx->Depth.Mask);
1471 r300DepthFunc(ctx, ctx->Depth.Func);
1472
1473 r300UpdateCulling(ctx);
1474
1475 r300_setup_routing(ctx, GL_TRUE);
1476
1477 r300UpdateTextureState(ctx);
1478 r300_setup_textures(ctx);
1479 r300_setup_rs_unit(ctx);
1480
1481 r300SetupVertexShader(r300);
1482 r300SetupPixelShader(r300);
1483
1484 r300_set_blend_state(ctx);
1485 r300AlphaFunc(ctx, ctx->Color.AlphaFunc, ctx->Color.AlphaRef);
1486
1487 /* Initialize magic registers
1488 TODO : learn what they really do, or get rid of
1489 those we don't have to touch */
1490 r300->hw.unk2080.cmd[1] = 0x0030045A;
1491
1492 r300->hw.vte.cmd[1] = R300_VPORT_X_SCALE_ENA
1493 | R300_VPORT_X_OFFSET_ENA
1494 | R300_VPORT_Y_SCALE_ENA
1495 | R300_VPORT_Y_OFFSET_ENA
1496 | R300_VPORT_Z_SCALE_ENA
1497 | R300_VPORT_Z_OFFSET_ENA
1498 | R300_VTX_W0_FMT;
1499 r300->hw.vte.cmd[2] = 0x00000008;
1500
1501 r300->hw.unk2134.cmd[1] = 0x00FFFFFF;
1502 r300->hw.unk2134.cmd[2] = 0x00000000;
1503
1504 r300->hw.unk2140.cmd[1] = 0x00000000;
1505
1506 #if 0 /* Done in setup routing */
1507 ((drm_r300_cmd_header_t*)r300->hw.vir[0].cmd)->unchecked_state.count = 1;
1508 r300->hw.vir[0].cmd[1] = 0x21030003;
1509
1510 ((drm_r300_cmd_header_t*)r300->hw.vir[1].cmd)->unchecked_state.count = 1;
1511 r300->hw.vir[1].cmd[1] = 0xF688F688;
1512
1513 r300->hw.vic.cmd[R300_VIR_CNTL_0] = 0x00000001;
1514 r300->hw.vic.cmd[R300_VIR_CNTL_1] = 0x00000405;
1515 #endif
1516
1517 r300->hw.unk21DC.cmd[1] = 0xAAAAAAAA;
1518
1519 r300->hw.unk221C.cmd[1] = R300_221C_NORMAL;
1520
1521 r300->hw.unk2220.cmd[1] = r300PackFloat32(1.0);
1522 r300->hw.unk2220.cmd[2] = r300PackFloat32(1.0);
1523 r300->hw.unk2220.cmd[3] = r300PackFloat32(1.0);
1524 r300->hw.unk2220.cmd[4] = r300PackFloat32(1.0);
1525
1526 if (GET_CHIP(r300->radeon.radeonScreen) == RADEON_CHIP_R300)
1527 r300->hw.unk2288.cmd[1] = R300_2288_R300;
1528 else
1529 r300->hw.unk2288.cmd[1] = R300_2288_RV350;
1530
1531 #if 0
1532 r300->hw.vof.cmd[R300_VOF_CNTL_0] = R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
1533 | R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT;
1534 r300->hw.vof.cmd[R300_VOF_CNTL_1] = 0; /* no textures */
1535
1536
1537 r300->hw.pvs.cmd[R300_PVS_CNTL_1] = 0;
1538 r300->hw.pvs.cmd[R300_PVS_CNTL_2] = 0;
1539 r300->hw.pvs.cmd[R300_PVS_CNTL_3] = 0;
1540 #endif
1541
1542 r300->hw.gb_enable.cmd[1] = R300_GB_POINT_STUFF_ENABLE
1543 | R300_GB_LINE_STUFF_ENABLE
1544 | R300_GB_TRIANGLE_STUFF_ENABLE;
1545
1546 r300->hw.gb_misc.cmd[R300_GB_MISC_MSPOS_0] = 0x66666666;
1547 r300->hw.gb_misc.cmd[R300_GB_MISC_MSPOS_1] = 0x06666666;
1548 if (GET_CHIP(r300->radeon.radeonScreen) == RADEON_CHIP_R300)
1549 r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] = R300_GB_TILE_ENABLE
1550 | R300_GB_TILE_PIPE_COUNT_R300
1551 | R300_GB_TILE_SIZE_16;
1552 else
1553 r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] = R300_GB_TILE_ENABLE
1554 | R300_GB_TILE_PIPE_COUNT_RV300
1555 | R300_GB_TILE_SIZE_16;
1556 r300->hw.gb_misc.cmd[R300_GB_MISC_SELECT] = 0x00000000;
1557 r300->hw.gb_misc.cmd[R300_GB_MISC_AA_CONFIG] = 0x00000000; /* No antialiasing */
1558
1559 //r300->hw.txe.cmd[R300_TXE_ENABLE] = 0;
1560
1561 r300->hw.unk4200.cmd[1] = r300PackFloat32(0.0);
1562 r300->hw.unk4200.cmd[2] = r300PackFloat32(0.0);
1563 r300->hw.unk4200.cmd[3] = r300PackFloat32(1.0);
1564 r300->hw.unk4200.cmd[4] = r300PackFloat32(1.0);
1565
1566 r300->hw.unk4214.cmd[1] = 0x00050005;
1567
1568 r300->hw.ps.cmd[R300_PS_POINTSIZE] = (6 << R300_POINTSIZE_X_SHIFT) |
1569 (6 << R300_POINTSIZE_Y_SHIFT);
1570
1571 r300->hw.unk4230.cmd[1] = 0x01800000;
1572 r300->hw.unk4230.cmd[2] = 0x00020006;
1573 r300->hw.unk4230.cmd[3] = r300PackFloat32(1.0 / 192.0);
1574
1575 r300->hw.unk4260.cmd[1] = 0;
1576 r300->hw.unk4260.cmd[2] = r300PackFloat32(0.0);
1577 r300->hw.unk4260.cmd[3] = r300PackFloat32(1.0);
1578
1579 r300->hw.unk4274.cmd[1] = 0x00000002;
1580 r300->hw.unk4274.cmd[2] = 0x0003AAAA;
1581 r300->hw.unk4274.cmd[3] = 0x00000000;
1582 r300->hw.unk4274.cmd[4] = 0x00000000;
1583
1584 r300->hw.unk4288.cmd[1] = 0x00000000;
1585 r300->hw.unk4288.cmd[2] = 0x00000001;
1586 r300->hw.unk4288.cmd[3] = 0x00000000;
1587 r300->hw.unk4288.cmd[4] = 0x00000000;
1588 r300->hw.unk4288.cmd[5] = 0x00000000;
1589
1590 r300->hw.unk42A0.cmd[1] = 0x00000000;
1591
1592 r300->hw.unk42B4.cmd[1] = 0x00000000;
1593
1594 r300->hw.unk42C0.cmd[1] = 0x4B7FFFFF;
1595 r300->hw.unk42C0.cmd[2] = 0x00000000;
1596
1597
1598 r300->hw.unk43A4.cmd[1] = 0x0000001C;
1599 r300->hw.unk43A4.cmd[2] = 0x2DA49525;
1600
1601 r300->hw.unk43E8.cmd[1] = 0x00FFFFFF;
1602
1603 #if 0
1604 r300->hw.fp.cmd[R300_FP_CNTL0] = 0;
1605 r300->hw.fp.cmd[R300_FP_CNTL1] = 0;
1606 r300->hw.fp.cmd[R300_FP_CNTL2] = 0;
1607 r300->hw.fp.cmd[R300_FP_NODE0] = 0;
1608 r300->hw.fp.cmd[R300_FP_NODE1] = 0;
1609 r300->hw.fp.cmd[R300_FP_NODE2] = 0;
1610 r300->hw.fp.cmd[R300_FP_NODE3] = 0;
1611 #endif
1612
1613 r300->hw.unk46A4.cmd[1] = 0x00001B01;
1614 r300->hw.unk46A4.cmd[2] = 0x00001B0F;
1615 r300->hw.unk46A4.cmd[3] = 0x00001B0F;
1616 r300->hw.unk46A4.cmd[4] = 0x00001B0F;
1617 r300->hw.unk46A4.cmd[5] = 0x00000001;
1618
1619 #if 0
1620 for(i = 1; i <= 64; ++i) {
1621 /* create NOP instructions */
1622 r300->hw.fpi[0].cmd[i] = FP_INSTRC(MAD, FP_ARGC(SRC0C_XYZ), FP_ARGC(ONE), FP_ARGC(ZERO));
1623 r300->hw.fpi[1].cmd[i] = FP_SELC(0,XYZ,NO,FP_TMP(0),0,0);
1624 r300->hw.fpi[2].cmd[i] = FP_INSTRA(MAD, FP_ARGA(SRC0A), FP_ARGA(ONE), FP_ARGA(ZERO));
1625 r300->hw.fpi[3].cmd[i] = FP_SELA(0,W,NO,FP_TMP(0),0,0);
1626 }
1627 #endif
1628
1629 r300->hw.unk4BC0.cmd[1] = 0;
1630
1631 r300->hw.unk4BC8.cmd[1] = 0;
1632 r300->hw.unk4BC8.cmd[2] = 0;
1633 r300->hw.unk4BC8.cmd[3] = 0;
1634
1635 #if 0
1636 r300->hw.at.cmd[R300_AT_ALPHA_TEST] = 0;
1637 #endif
1638
1639 r300->hw.at.cmd[R300_AT_UNKNOWN] = 0;
1640 r300->hw.unk4BD8.cmd[1] = 0;
1641
1642 r300->hw.unk4E00.cmd[1] = 0;
1643
1644 #if 0
1645 r300->hw.bld.cmd[R300_BLD_CBLEND] = 0;
1646 r300->hw.bld.cmd[R300_BLD_ABLEND] = 0;
1647 #endif
1648
1649 r300->hw.unk4E10.cmd[1] = 0;
1650 r300->hw.unk4E10.cmd[2] = 0;
1651 r300->hw.unk4E10.cmd[3] = 0;
1652
1653 r300->hw.cb.cmd[R300_CB_OFFSET] =
1654 r300->radeon.radeonScreen->backOffset +
1655 r300->radeon.radeonScreen->fbLocation;
1656 r300->hw.cb.cmd[R300_CB_PITCH] = r300->radeon.radeonScreen->backPitch
1657 | R300_COLOR_UNKNOWN_22_23;
1658
1659 r300->hw.unk4E50.cmd[1] = 0;
1660 r300->hw.unk4E50.cmd[2] = 0;
1661 r300->hw.unk4E50.cmd[3] = 0;
1662 r300->hw.unk4E50.cmd[4] = 0;
1663 r300->hw.unk4E50.cmd[5] = 0;
1664 r300->hw.unk4E50.cmd[6] = 0;
1665 r300->hw.unk4E50.cmd[7] = 0;
1666 r300->hw.unk4E50.cmd[8] = 0;
1667 r300->hw.unk4E50.cmd[9] = 0;
1668
1669 r300->hw.unk4E88.cmd[1] = 0;
1670
1671 r300->hw.unk4EA0.cmd[1] = 0x00000000;
1672 r300->hw.unk4EA0.cmd[2] = 0xffffffff;
1673
1674 r300->hw.unk4F10.cmd[1] = 0x00000002; // depthbuffer format?
1675 r300->hw.unk4F10.cmd[2] = 0x00000000;
1676 r300->hw.unk4F10.cmd[3] = 0x00000003;
1677 r300->hw.unk4F10.cmd[4] = 0x00000000;
1678
1679 /* experiment a bit */
1680 r300->hw.unk4F10.cmd[2] = 0x00000001; // depthbuffer format?
1681
1682 r300->hw.zb.cmd[R300_ZB_OFFSET] =
1683 r300->radeon.radeonScreen->depthOffset +
1684 r300->radeon.radeonScreen->fbLocation;
1685 r300->hw.zb.cmd[R300_ZB_PITCH] = r300->radeon.radeonScreen->depthPitch;
1686
1687 r300->hw.unk4F28.cmd[1] = 0;
1688
1689 r300->hw.unk4F30.cmd[1] = 0;
1690 r300->hw.unk4F30.cmd[2] = 0;
1691
1692 r300->hw.unk4F44.cmd[1] = 0;
1693
1694 r300->hw.unk4F54.cmd[1] = 0;
1695
1696 #if 0
1697 ((drm_r300_cmd_header_t*)r300->hw.vpi.cmd)->vpu.count = 0;
1698 for(i = 1; i < R300_VPI_CMDSIZE; i += 4) {
1699 /* MOV t0, t0 */
1700 r300->hw.vpi.cmd[i+0] = VP_OUT(ADD,TMP,0,XYZW);
1701 r300->hw.vpi.cmd[i+1] = VP_IN(TMP,0);
1702 r300->hw.vpi.cmd[i+2] = VP_ZERO();
1703 r300->hw.vpi.cmd[i+3] = VP_ZERO();
1704 }
1705
1706 ((drm_r300_cmd_header_t*)r300->hw.vpp.cmd)->vpu.count = 0;
1707 for(i = 1; i < R300_VPP_CMDSIZE; ++i)
1708 r300->hw.vpp.cmd[i] = 0;
1709 #endif
1710
1711 r300->hw.vps.cmd[R300_VPS_ZERO_0] = 0;
1712 r300->hw.vps.cmd[R300_VPS_ZERO_1] = 0;
1713 r300->hw.vps.cmd[R300_VPS_POINTSIZE] = r300PackFloat32(1.0);
1714 r300->hw.vps.cmd[R300_VPS_ZERO_3] = 0;
1715
1716 //END: TODO
1717
1718 r300->hw.all_dirty = GL_TRUE;
1719 }
1720
1721
1722
1723 /**
1724 * Calculate initial hardware state and register state functions.
1725 * Assumes that the command buffer and state atoms have been
1726 * initialized already.
1727 */
1728 void r300InitState(r300ContextPtr r300)
1729 {
1730 GLcontext *ctx = r300->radeon.glCtx;
1731 GLuint depth_fmt;
1732
1733 radeonInitState(&r300->radeon);
1734
1735 switch (ctx->Visual.depthBits) {
1736 case 16:
1737 r300->state.depth.scale = 1.0 / (GLfloat) 0xffff;
1738 depth_fmt = R200_DEPTH_FORMAT_16BIT_INT_Z;
1739 //r300->state.stencil.clear = 0x00000000;
1740 break;
1741 case 24:
1742 r300->state.depth.scale = 1.0 / (GLfloat) 0xffffff;
1743 depth_fmt = R200_DEPTH_FORMAT_24BIT_INT_Z;
1744 //r300->state.stencil.clear = 0xff000000;
1745 break;
1746 default:
1747 fprintf(stderr, "Error: Unsupported depth %d... exiting\n",
1748 ctx->Visual.depthBits);
1749 exit(-1);
1750 }
1751
1752 /* Only have hw stencil when depth buffer is 24 bits deep */
1753 r300->state.hw_stencil = (ctx->Visual.stencilBits > 0 &&
1754 ctx->Visual.depthBits == 24);
1755
1756 memset(&(r300->state.texture), 0, sizeof(r300->state.texture));
1757
1758 r300ResetHwState(r300);
1759 }
1760
1761
1762
1763 /**
1764 * Initialize driver's state callback functions
1765 */
1766 void r300InitStateFuncs(struct dd_function_table* functions)
1767 {
1768 radeonInitStateFuncs(functions);
1769
1770 functions->UpdateState = r300InvalidateState;
1771 functions->AlphaFunc = r300AlphaFunc;
1772 functions->BlendColor = r300BlendColor;
1773 functions->BlendEquationSeparate = r300BlendEquationSeparate;
1774 functions->BlendFuncSeparate = r300BlendFuncSeparate;
1775 functions->Enable = r300Enable;
1776 functions->ColorMask = r300ColorMask;
1777 functions->DepthFunc = r300DepthFunc;
1778 functions->DepthMask = r300DepthMask;
1779 functions->CullFace = r300CullFace;
1780 functions->FrontFace = r300FrontFace;
1781
1782 /* Stencil related */
1783 functions->ClearStencil = r300ClearStencil;
1784 functions->StencilFunc = r300StencilFunc;
1785 functions->StencilMask = r300StencilMask;
1786 functions->StencilOp = r300StencilOp;
1787
1788 /* Viewport related */
1789 functions->Viewport = r300Viewport;
1790 functions->DepthRange = r300DepthRange;
1791 functions->PointSize = r300PointSize;
1792 }
1793