9f391a27a09c2fc26ea4cb62c9ae50c2773cc26a
[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 "shader/prog_parameter.h"
50 #include "shader/prog_statevars.h"
51 #include "vbo/vbo.h"
52 #include "tnl/tnl.h"
53 #include "texformat.h"
54
55 #include "radeon_ioctl.h"
56 #include "radeon_state.h"
57 #include "r300_context.h"
58 #include "r300_ioctl.h"
59 #include "r300_state.h"
60 #include "r300_reg.h"
61 #include "r300_emit.h"
62 #include "r300_fragprog.h"
63 #include "r300_tex.h"
64 #include "r300_maos.h"
65
66 #include "drirenderbuffer.h"
67
68 static void r300BlendColor(GLcontext * ctx, const GLfloat cf[4])
69 {
70 GLubyte color[4];
71 r300ContextPtr rmesa = R300_CONTEXT(ctx);
72
73 R300_STATECHANGE(rmesa, blend_color);
74
75 CLAMPED_FLOAT_TO_UBYTE(color[0], cf[0]);
76 CLAMPED_FLOAT_TO_UBYTE(color[1], cf[1]);
77 CLAMPED_FLOAT_TO_UBYTE(color[2], cf[2]);
78 CLAMPED_FLOAT_TO_UBYTE(color[3], cf[3]);
79
80 rmesa->hw.blend_color.cmd[1] = PACK_COLOR_8888(color[3], color[0],
81 color[1], color[2]);
82 }
83
84 /**
85 * Calculate the hardware blend factor setting. This same function is used
86 * for source and destination of both alpha and RGB.
87 *
88 * \returns
89 * The hardware register value for the specified blend factor. This value
90 * will need to be shifted into the correct position for either source or
91 * destination factor.
92 *
93 * \todo
94 * Since the two cases where source and destination are handled differently
95 * are essentially error cases, they should never happen. Determine if these
96 * cases can be removed.
97 */
98 static int blend_factor(GLenum factor, GLboolean is_src)
99 {
100 int func;
101
102 switch (factor) {
103 case GL_ZERO:
104 func = R300_BLEND_GL_ZERO;
105 break;
106 case GL_ONE:
107 func = R300_BLEND_GL_ONE;
108 break;
109 case GL_DST_COLOR:
110 func = R300_BLEND_GL_DST_COLOR;
111 break;
112 case GL_ONE_MINUS_DST_COLOR:
113 func = R300_BLEND_GL_ONE_MINUS_DST_COLOR;
114 break;
115 case GL_SRC_COLOR:
116 func = R300_BLEND_GL_SRC_COLOR;
117 break;
118 case GL_ONE_MINUS_SRC_COLOR:
119 func = R300_BLEND_GL_ONE_MINUS_SRC_COLOR;
120 break;
121 case GL_SRC_ALPHA:
122 func = R300_BLEND_GL_SRC_ALPHA;
123 break;
124 case GL_ONE_MINUS_SRC_ALPHA:
125 func = R300_BLEND_GL_ONE_MINUS_SRC_ALPHA;
126 break;
127 case GL_DST_ALPHA:
128 func = R300_BLEND_GL_DST_ALPHA;
129 break;
130 case GL_ONE_MINUS_DST_ALPHA:
131 func = R300_BLEND_GL_ONE_MINUS_DST_ALPHA;
132 break;
133 case GL_SRC_ALPHA_SATURATE:
134 func = (is_src) ? R300_BLEND_GL_SRC_ALPHA_SATURATE :
135 R300_BLEND_GL_ZERO;
136 break;
137 case GL_CONSTANT_COLOR:
138 func = R300_BLEND_GL_CONST_COLOR;
139 break;
140 case GL_ONE_MINUS_CONSTANT_COLOR:
141 func = R300_BLEND_GL_ONE_MINUS_CONST_COLOR;
142 break;
143 case GL_CONSTANT_ALPHA:
144 func = R300_BLEND_GL_CONST_ALPHA;
145 break;
146 case GL_ONE_MINUS_CONSTANT_ALPHA:
147 func = R300_BLEND_GL_ONE_MINUS_CONST_ALPHA;
148 break;
149 default:
150 fprintf(stderr, "unknown blend factor %x\n", factor);
151 func = (is_src) ? R300_BLEND_GL_ONE : R300_BLEND_GL_ZERO;
152 }
153 return func;
154 }
155
156 /**
157 * Sets both the blend equation and the blend function.
158 * This is done in a single
159 * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX)
160 * change the interpretation of the blend function.
161 * Also, make sure that blend function and blend equation are set to their
162 * default value if color blending is not enabled, since at least blend
163 * equations GL_MIN and GL_FUNC_REVERSE_SUBTRACT will cause wrong results
164 * otherwise for unknown reasons.
165 */
166
167 /* helper function */
168 static void r300SetBlendCntl(r300ContextPtr r300, int func, int eqn,
169 int cbits, int funcA, int eqnA)
170 {
171 GLuint new_ablend, new_cblend;
172
173 #if 0
174 fprintf(stderr,
175 "eqnA=%08x funcA=%08x eqn=%08x func=%08x cbits=%08x\n",
176 eqnA, funcA, eqn, func, cbits);
177 #endif
178 new_ablend = eqnA | funcA;
179 new_cblend = eqn | func;
180
181 /* Some blend factor combinations don't seem to work when the
182 * BLEND_NO_SEPARATE bit is set.
183 *
184 * Especially problematic candidates are the ONE_MINUS_* flags,
185 * but I can't see a real pattern.
186 */
187 #if 0
188 if (new_ablend == new_cblend) {
189 new_cblend |= R300_BLEND_NO_SEPARATE;
190 }
191 #endif
192 new_cblend |= cbits;
193
194 if ((new_ablend != r300->hw.bld.cmd[R300_BLD_ABLEND]) ||
195 (new_cblend != r300->hw.bld.cmd[R300_BLD_CBLEND])) {
196 R300_STATECHANGE(r300, bld);
197 r300->hw.bld.cmd[R300_BLD_ABLEND] = new_ablend;
198 r300->hw.bld.cmd[R300_BLD_CBLEND] = new_cblend;
199 }
200 }
201
202 static void r300SetBlendState(GLcontext * ctx)
203 {
204 r300ContextPtr r300 = R300_CONTEXT(ctx);
205 int func = (R300_BLEND_GL_ONE << R300_SRC_BLEND_SHIFT) |
206 (R300_BLEND_GL_ZERO << R300_DST_BLEND_SHIFT);
207 int eqn = R300_COMB_FCN_ADD_CLAMP;
208 int funcA = (R300_BLEND_GL_ONE << R300_SRC_BLEND_SHIFT) |
209 (R300_BLEND_GL_ZERO << R300_DST_BLEND_SHIFT);
210 int eqnA = R300_COMB_FCN_ADD_CLAMP;
211
212 if (RGBA_LOGICOP_ENABLED(ctx) || !ctx->Color.BlendEnabled) {
213 r300SetBlendCntl(r300, func, eqn, 0, func, eqn);
214 return;
215 }
216
217 func =
218 (blend_factor(ctx->Color.BlendSrcRGB, GL_TRUE) <<
219 R300_SRC_BLEND_SHIFT) | (blend_factor(ctx->Color.BlendDstRGB,
220 GL_FALSE) <<
221 R300_DST_BLEND_SHIFT);
222
223 switch (ctx->Color.BlendEquationRGB) {
224 case GL_FUNC_ADD:
225 eqn = R300_COMB_FCN_ADD_CLAMP;
226 break;
227
228 case GL_FUNC_SUBTRACT:
229 eqn = R300_COMB_FCN_SUB_CLAMP;
230 break;
231
232 case GL_FUNC_REVERSE_SUBTRACT:
233 eqn = R300_COMB_FCN_RSUB_CLAMP;
234 break;
235
236 case GL_MIN:
237 eqn = R300_COMB_FCN_MIN;
238 func = (R300_BLEND_GL_ONE << R300_SRC_BLEND_SHIFT) |
239 (R300_BLEND_GL_ONE << R300_DST_BLEND_SHIFT);
240 break;
241
242 case GL_MAX:
243 eqn = R300_COMB_FCN_MAX;
244 func = (R300_BLEND_GL_ONE << R300_SRC_BLEND_SHIFT) |
245 (R300_BLEND_GL_ONE << R300_DST_BLEND_SHIFT);
246 break;
247
248 default:
249 fprintf(stderr,
250 "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
251 __func__, __LINE__, ctx->Color.BlendEquationRGB);
252 return;
253 }
254
255 funcA =
256 (blend_factor(ctx->Color.BlendSrcA, GL_TRUE) <<
257 R300_SRC_BLEND_SHIFT) | (blend_factor(ctx->Color.BlendDstA,
258 GL_FALSE) <<
259 R300_DST_BLEND_SHIFT);
260
261 switch (ctx->Color.BlendEquationA) {
262 case GL_FUNC_ADD:
263 eqnA = R300_COMB_FCN_ADD_CLAMP;
264 break;
265
266 case GL_FUNC_SUBTRACT:
267 eqnA = R300_COMB_FCN_SUB_CLAMP;
268 break;
269
270 case GL_FUNC_REVERSE_SUBTRACT:
271 eqnA = R300_COMB_FCN_RSUB_CLAMP;
272 break;
273
274 case GL_MIN:
275 eqnA = R300_COMB_FCN_MIN;
276 funcA = (R300_BLEND_GL_ONE << R300_SRC_BLEND_SHIFT) |
277 (R300_BLEND_GL_ONE << R300_DST_BLEND_SHIFT);
278 break;
279
280 case GL_MAX:
281 eqnA = R300_COMB_FCN_MAX;
282 funcA = (R300_BLEND_GL_ONE << R300_SRC_BLEND_SHIFT) |
283 (R300_BLEND_GL_ONE << R300_DST_BLEND_SHIFT);
284 break;
285
286 default:
287 fprintf(stderr,
288 "[%s:%u] Invalid A blend equation (0x%04x).\n",
289 __func__, __LINE__, ctx->Color.BlendEquationA);
290 return;
291 }
292
293 r300SetBlendCntl(r300,
294 func, eqn,
295 R300_BLEND_UNKNOWN | R300_BLEND_ENABLE, funcA, eqnA);
296 }
297
298 static void r300BlendEquationSeparate(GLcontext * ctx,
299 GLenum modeRGB, GLenum modeA)
300 {
301 r300SetBlendState(ctx);
302 }
303
304 static void r300BlendFuncSeparate(GLcontext * ctx,
305 GLenum sfactorRGB, GLenum dfactorRGB,
306 GLenum sfactorA, GLenum dfactorA)
307 {
308 r300SetBlendState(ctx);
309 }
310
311 /**
312 * Update our tracked culling state based on Mesa's state.
313 */
314 static void r300UpdateCulling(GLcontext * ctx)
315 {
316 r300ContextPtr r300 = R300_CONTEXT(ctx);
317 uint32_t val = 0;
318
319 R300_STATECHANGE(r300, cul);
320 if (ctx->Polygon.CullFlag) {
321 if (ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK)
322 val = R300_CULL_FRONT | R300_CULL_BACK;
323 else if (ctx->Polygon.CullFaceMode == GL_FRONT)
324 val = R300_CULL_FRONT;
325 else
326 val = R300_CULL_BACK;
327
328 if (ctx->Polygon.FrontFace == GL_CW)
329 val |= R300_FRONT_FACE_CW;
330 else
331 val |= R300_FRONT_FACE_CCW;
332 }
333 r300->hw.cul.cmd[R300_CUL_CULL] = val;
334 }
335
336 static void update_early_z(GLcontext * ctx)
337 {
338 /* updates register R300_RB3D_EARLY_Z (0x4F14)
339 if depth test is not enabled it should be R300_EARLY_Z_DISABLE
340 if depth is enabled and alpha not it should be R300_EARLY_Z_ENABLE
341 if depth and alpha is enabled it should be R300_EARLY_Z_DISABLE
342 */
343 r300ContextPtr r300 = R300_CONTEXT(ctx);
344
345 R300_STATECHANGE(r300, zstencil_format);
346 if (ctx->Color.AlphaEnabled && ctx->Color.AlphaFunc != GL_ALWAYS)
347 /* disable early Z */
348 r300->hw.zstencil_format.cmd[2] = R300_EARLY_Z_DISABLE;
349 else {
350 if (ctx->Depth.Test && ctx->Depth.Func != GL_NEVER)
351 /* enable early Z */
352 r300->hw.zstencil_format.cmd[2] = R300_EARLY_Z_ENABLE;
353 else
354 /* disable early Z */
355 r300->hw.zstencil_format.cmd[2] = R300_EARLY_Z_DISABLE;
356 }
357 }
358
359 static void update_alpha(GLcontext * ctx)
360 {
361 r300ContextPtr r300 = R300_CONTEXT(ctx);
362 GLubyte refByte;
363 uint32_t pp_misc = 0x0;
364 GLboolean really_enabled = ctx->Color.AlphaEnabled;
365
366 CLAMPED_FLOAT_TO_UBYTE(refByte, ctx->Color.AlphaRef);
367
368 switch (ctx->Color.AlphaFunc) {
369 case GL_NEVER:
370 pp_misc |= R300_ALPHA_TEST_FAIL;
371 break;
372 case GL_LESS:
373 pp_misc |= R300_ALPHA_TEST_LESS;
374 break;
375 case GL_EQUAL:
376 pp_misc |= R300_ALPHA_TEST_EQUAL;
377 break;
378 case GL_LEQUAL:
379 pp_misc |= R300_ALPHA_TEST_LEQUAL;
380 break;
381 case GL_GREATER:
382 pp_misc |= R300_ALPHA_TEST_GREATER;
383 break;
384 case GL_NOTEQUAL:
385 pp_misc |= R300_ALPHA_TEST_NEQUAL;
386 break;
387 case GL_GEQUAL:
388 pp_misc |= R300_ALPHA_TEST_GEQUAL;
389 break;
390 case GL_ALWAYS:
391 /*pp_misc |= R300_ALPHA_TEST_PASS; */
392 really_enabled = GL_FALSE;
393 break;
394 }
395
396 if (really_enabled) {
397 pp_misc |= R300_ALPHA_TEST_ENABLE;
398 pp_misc |= (refByte & R300_REF_ALPHA_MASK);
399 } else {
400 pp_misc = 0x0;
401 }
402
403 R300_STATECHANGE(r300, at);
404 r300->hw.at.cmd[R300_AT_ALPHA_TEST] = pp_misc;
405 update_early_z(ctx);
406 }
407
408 static void r300AlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref)
409 {
410 (void)func;
411 (void)ref;
412 update_alpha(ctx);
413 }
414
415 static int translate_func(int func)
416 {
417 switch (func) {
418 case GL_NEVER:
419 return R300_ZS_NEVER;
420 case GL_LESS:
421 return R300_ZS_LESS;
422 case GL_EQUAL:
423 return R300_ZS_EQUAL;
424 case GL_LEQUAL:
425 return R300_ZS_LEQUAL;
426 case GL_GREATER:
427 return R300_ZS_GREATER;
428 case GL_NOTEQUAL:
429 return R300_ZS_NOTEQUAL;
430 case GL_GEQUAL:
431 return R300_ZS_GEQUAL;
432 case GL_ALWAYS:
433 return R300_ZS_ALWAYS;
434 }
435 return 0;
436 }
437
438 static void update_depth(GLcontext * ctx)
439 {
440 r300ContextPtr r300 = R300_CONTEXT(ctx);
441
442 R300_STATECHANGE(r300, zs);
443 r300->hw.zs.cmd[R300_ZS_CNTL_0] &= R300_RB3D_STENCIL_ENABLE;
444 r300->hw.zs.cmd[R300_ZS_CNTL_1] &=
445 ~(R300_ZS_MASK << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT);
446
447 if (ctx->Depth.Test && ctx->Depth.Func != GL_NEVER) {
448 if (ctx->Depth.Mask)
449 r300->hw.zs.cmd[R300_ZS_CNTL_0] |=
450 R300_RB3D_Z_TEST_AND_WRITE;
451 else
452 r300->hw.zs.cmd[R300_ZS_CNTL_0] |= R300_RB3D_Z_TEST;
453
454 r300->hw.zs.cmd[R300_ZS_CNTL_1] |=
455 translate_func(ctx->Depth.
456 Func) << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT;
457 } else {
458 r300->hw.zs.cmd[R300_ZS_CNTL_0] |= R300_RB3D_Z_DISABLED_1;
459 r300->hw.zs.cmd[R300_ZS_CNTL_1] |=
460 translate_func(GL_NEVER) << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT;
461 }
462
463 update_early_z(ctx);
464 }
465
466 /**
467 * Handle glEnable()/glDisable().
468 *
469 * \note Mesa already filters redundant calls to glEnable/glDisable.
470 */
471 static void r300Enable(GLcontext * ctx, GLenum cap, GLboolean state)
472 {
473 r300ContextPtr r300 = R300_CONTEXT(ctx);
474
475 if (RADEON_DEBUG & DEBUG_STATE)
476 fprintf(stderr, "%s( %s = %s )\n", __FUNCTION__,
477 _mesa_lookup_enum_by_nr(cap),
478 state ? "GL_TRUE" : "GL_FALSE");
479
480 switch (cap) {
481 /* Fast track this one...
482 */
483 case GL_TEXTURE_1D:
484 case GL_TEXTURE_2D:
485 case GL_TEXTURE_3D:
486 break;
487
488 case GL_FOG:
489 R300_STATECHANGE(r300, fogs);
490 if (state) {
491 r300->hw.fogs.cmd[R300_FOGS_STATE] |= R300_FOG_ENABLE;
492
493 ctx->Driver.Fogfv(ctx, GL_FOG_MODE, NULL);
494 ctx->Driver.Fogfv(ctx, GL_FOG_DENSITY,
495 &ctx->Fog.Density);
496 ctx->Driver.Fogfv(ctx, GL_FOG_START, &ctx->Fog.Start);
497 ctx->Driver.Fogfv(ctx, GL_FOG_END, &ctx->Fog.End);
498 ctx->Driver.Fogfv(ctx, GL_FOG_COLOR, ctx->Fog.Color);
499 } else {
500 r300->hw.fogs.cmd[R300_FOGS_STATE] &= ~R300_FOG_ENABLE;
501 }
502
503 break;
504
505 case GL_ALPHA_TEST:
506 update_alpha(ctx);
507 break;
508
509 case GL_BLEND:
510 case GL_COLOR_LOGIC_OP:
511 r300SetBlendState(ctx);
512 break;
513
514 case GL_DEPTH_TEST:
515 update_depth(ctx);
516 break;
517
518 case GL_STENCIL_TEST:
519 if (r300->state.stencil.hw_stencil) {
520 R300_STATECHANGE(r300, zs);
521 if (state) {
522 r300->hw.zs.cmd[R300_ZS_CNTL_0] |=
523 R300_RB3D_STENCIL_ENABLE;
524 } else {
525 r300->hw.zs.cmd[R300_ZS_CNTL_0] &=
526 ~R300_RB3D_STENCIL_ENABLE;
527 }
528 } else {
529 #if R200_MERGED
530 FALLBACK(&r300->radeon, RADEON_FALLBACK_STENCIL, state);
531 #endif
532 }
533 break;
534
535 case GL_CULL_FACE:
536 r300UpdateCulling(ctx);
537 break;
538
539 case GL_POLYGON_OFFSET_POINT:
540 case GL_POLYGON_OFFSET_LINE:
541 break;
542
543 case GL_POLYGON_OFFSET_FILL:
544 R300_STATECHANGE(r300, occlusion_cntl);
545 if (state) {
546 r300->hw.occlusion_cntl.cmd[1] |= (3 << 0);
547 } else {
548 r300->hw.occlusion_cntl.cmd[1] &= ~(3 << 0);
549 }
550 break;
551 default:
552 radeonEnable(ctx, cap, state);
553 return;
554 }
555 }
556
557 static void r300UpdatePolygonMode(GLcontext * ctx)
558 {
559 r300ContextPtr r300 = R300_CONTEXT(ctx);
560 uint32_t hw_mode = 0;
561
562 if (ctx->Polygon.FrontMode != GL_FILL ||
563 ctx->Polygon.BackMode != GL_FILL) {
564 GLenum f, b;
565
566 if (ctx->Polygon.FrontFace == GL_CCW) {
567 f = ctx->Polygon.FrontMode;
568 b = ctx->Polygon.BackMode;
569 } else {
570 f = ctx->Polygon.BackMode;
571 b = ctx->Polygon.FrontMode;
572 }
573
574 hw_mode |= R300_PM_ENABLED;
575
576 switch (f) {
577 case GL_LINE:
578 hw_mode |= R300_PM_FRONT_LINE;
579 break;
580 case GL_POINT: /* noop */
581 hw_mode |= R300_PM_FRONT_POINT;
582 break;
583 case GL_FILL:
584 hw_mode |= R300_PM_FRONT_FILL;
585 break;
586 }
587
588 switch (b) {
589 case GL_LINE:
590 hw_mode |= R300_PM_BACK_LINE;
591 break;
592 case GL_POINT: /* noop */
593 hw_mode |= R300_PM_BACK_POINT;
594 break;
595 case GL_FILL:
596 hw_mode |= R300_PM_BACK_FILL;
597 break;
598 }
599 }
600
601 if (r300->hw.polygon_mode.cmd[1] != hw_mode) {
602 R300_STATECHANGE(r300, polygon_mode);
603 r300->hw.polygon_mode.cmd[1] = hw_mode;
604 }
605 }
606
607 /**
608 * Change the culling mode.
609 *
610 * \note Mesa already filters redundant calls to this function.
611 */
612 static void r300CullFace(GLcontext * ctx, GLenum mode)
613 {
614 (void)mode;
615
616 r300UpdateCulling(ctx);
617 }
618
619 /**
620 * Change the polygon orientation.
621 *
622 * \note Mesa already filters redundant calls to this function.
623 */
624 static void r300FrontFace(GLcontext * ctx, GLenum mode)
625 {
626 (void)mode;
627
628 r300UpdateCulling(ctx);
629 r300UpdatePolygonMode(ctx);
630 }
631
632 /**
633 * Change the depth testing function.
634 *
635 * \note Mesa already filters redundant calls to this function.
636 */
637 static void r300DepthFunc(GLcontext * ctx, GLenum func)
638 {
639 (void)func;
640 update_depth(ctx);
641 }
642
643 /**
644 * Enable/Disable depth writing.
645 *
646 * \note Mesa already filters redundant calls to this function.
647 */
648 static void r300DepthMask(GLcontext * ctx, GLboolean mask)
649 {
650 (void)mask;
651 update_depth(ctx);
652 }
653
654 /**
655 * Handle glColorMask()
656 */
657 static void r300ColorMask(GLcontext * ctx,
658 GLboolean r, GLboolean g, GLboolean b, GLboolean a)
659 {
660 r300ContextPtr r300 = R300_CONTEXT(ctx);
661 int mask = (r ? R300_COLORMASK0_R : 0) |
662 (g ? R300_COLORMASK0_G : 0) |
663 (b ? R300_COLORMASK0_B : 0) | (a ? R300_COLORMASK0_A : 0);
664
665 if (mask != r300->hw.cmk.cmd[R300_CMK_COLORMASK]) {
666 R300_STATECHANGE(r300, cmk);
667 r300->hw.cmk.cmd[R300_CMK_COLORMASK] = mask;
668 }
669 }
670
671 /* =============================================================
672 * Fog
673 */
674 static void r300Fogfv(GLcontext * ctx, GLenum pname, const GLfloat * param)
675 {
676 r300ContextPtr r300 = R300_CONTEXT(ctx);
677 union {
678 int i;
679 float f;
680 } fogScale, fogStart;
681
682 (void)param;
683
684 fogScale.i = r300->hw.fogp.cmd[R300_FOGP_SCALE];
685 fogStart.i = r300->hw.fogp.cmd[R300_FOGP_START];
686
687 switch (pname) {
688 case GL_FOG_MODE:
689 if (!ctx->Fog.Enabled)
690 return;
691 switch (ctx->Fog.Mode) {
692 case GL_LINEAR:
693 R300_STATECHANGE(r300, fogs);
694 r300->hw.fogs.cmd[R300_FOGS_STATE] =
695 (r300->hw.fogs.
696 cmd[R300_FOGS_STATE] & ~R300_FOG_MODE_MASK) |
697 R300_FOG_MODE_LINEAR;
698
699 if (ctx->Fog.Start == ctx->Fog.End) {
700 fogScale.f = -1.0;
701 fogStart.f = 1.0;
702 } else {
703 fogScale.f =
704 1.0 / (ctx->Fog.End - ctx->Fog.Start);
705 fogStart.f =
706 -ctx->Fog.Start / (ctx->Fog.End -
707 ctx->Fog.Start);
708 }
709 break;
710 case GL_EXP:
711 R300_STATECHANGE(r300, fogs);
712 r300->hw.fogs.cmd[R300_FOGS_STATE] =
713 (r300->hw.fogs.
714 cmd[R300_FOGS_STATE] & ~R300_FOG_MODE_MASK) |
715 R300_FOG_MODE_EXP;
716 fogScale.f = 0.0933 * ctx->Fog.Density;
717 fogStart.f = 0.0;
718 break;
719 case GL_EXP2:
720 R300_STATECHANGE(r300, fogs);
721 r300->hw.fogs.cmd[R300_FOGS_STATE] =
722 (r300->hw.fogs.
723 cmd[R300_FOGS_STATE] & ~R300_FOG_MODE_MASK) |
724 R300_FOG_MODE_EXP2;
725 fogScale.f = 0.3 * ctx->Fog.Density;
726 fogStart.f = 0.0;
727 default:
728 return;
729 }
730 break;
731 case GL_FOG_DENSITY:
732 switch (ctx->Fog.Mode) {
733 case GL_EXP:
734 fogScale.f = 0.0933 * ctx->Fog.Density;
735 fogStart.f = 0.0;
736 break;
737 case GL_EXP2:
738 fogScale.f = 0.3 * ctx->Fog.Density;
739 fogStart.f = 0.0;
740 default:
741 break;
742 }
743 break;
744 case GL_FOG_START:
745 case GL_FOG_END:
746 if (ctx->Fog.Mode == GL_LINEAR) {
747 if (ctx->Fog.Start == ctx->Fog.End) {
748 fogScale.f = -1.0;
749 fogStart.f = 1.0;
750 } else {
751 fogScale.f =
752 1.0 / (ctx->Fog.End - ctx->Fog.Start);
753 fogStart.f =
754 -ctx->Fog.Start / (ctx->Fog.End -
755 ctx->Fog.Start);
756 }
757 }
758 break;
759 case GL_FOG_COLOR:
760 R300_STATECHANGE(r300, fogc);
761 r300->hw.fogc.cmd[R300_FOGC_R] =
762 (GLuint) (ctx->Fog.Color[0] * 1023.0F) & 0x3FF;
763 r300->hw.fogc.cmd[R300_FOGC_G] =
764 (GLuint) (ctx->Fog.Color[1] * 1023.0F) & 0x3FF;
765 r300->hw.fogc.cmd[R300_FOGC_B] =
766 (GLuint) (ctx->Fog.Color[2] * 1023.0F) & 0x3FF;
767 break;
768 case GL_FOG_COORD_SRC:
769 break;
770 default:
771 return;
772 }
773
774 if (fogScale.i != r300->hw.fogp.cmd[R300_FOGP_SCALE] ||
775 fogStart.i != r300->hw.fogp.cmd[R300_FOGP_START]) {
776 R300_STATECHANGE(r300, fogp);
777 r300->hw.fogp.cmd[R300_FOGP_SCALE] = fogScale.i;
778 r300->hw.fogp.cmd[R300_FOGP_START] = fogStart.i;
779 }
780 }
781
782 /* =============================================================
783 * Point state
784 */
785 static void r300PointSize(GLcontext * ctx, GLfloat size)
786 {
787 r300ContextPtr r300 = R300_CONTEXT(ctx);
788
789 size = ctx->Point._Size;
790
791 R300_STATECHANGE(r300, ps);
792 r300->hw.ps.cmd[R300_PS_POINTSIZE] =
793 ((int)(size * 6) << R300_POINTSIZE_X_SHIFT) |
794 ((int)(size * 6) << R300_POINTSIZE_Y_SHIFT);
795 }
796
797 /* =============================================================
798 * Line state
799 */
800 static void r300LineWidth(GLcontext * ctx, GLfloat widthf)
801 {
802 r300ContextPtr r300 = R300_CONTEXT(ctx);
803
804 widthf = ctx->Line._Width;
805
806 R300_STATECHANGE(r300, lcntl);
807 r300->hw.lcntl.cmd[1] = (int)(widthf * 6.0);
808 r300->hw.lcntl.cmd[1] |= R300_LINE_CNT_VE;
809 }
810
811 static void r300PolygonMode(GLcontext * ctx, GLenum face, GLenum mode)
812 {
813 (void)face;
814 (void)mode;
815
816 r300UpdatePolygonMode(ctx);
817 }
818
819 /* =============================================================
820 * Stencil
821 */
822
823 static int translate_stencil_op(int op)
824 {
825 switch (op) {
826 case GL_KEEP:
827 return R300_ZS_KEEP;
828 case GL_ZERO:
829 return R300_ZS_ZERO;
830 case GL_REPLACE:
831 return R300_ZS_REPLACE;
832 case GL_INCR:
833 return R300_ZS_INCR;
834 case GL_DECR:
835 return R300_ZS_DECR;
836 case GL_INCR_WRAP_EXT:
837 return R300_ZS_INCR_WRAP;
838 case GL_DECR_WRAP_EXT:
839 return R300_ZS_DECR_WRAP;
840 case GL_INVERT:
841 return R300_ZS_INVERT;
842 default:
843 WARN_ONCE("Do not know how to translate stencil op");
844 return R300_ZS_KEEP;
845 }
846 return 0;
847 }
848
849 static void r300ShadeModel(GLcontext * ctx, GLenum mode)
850 {
851 r300ContextPtr rmesa = R300_CONTEXT(ctx);
852
853 R300_STATECHANGE(rmesa, shade);
854 switch (mode) {
855 case GL_FLAT:
856 rmesa->hw.shade.cmd[2] = R300_RE_SHADE_MODEL_FLAT;
857 break;
858 case GL_SMOOTH:
859 rmesa->hw.shade.cmd[2] = R300_RE_SHADE_MODEL_SMOOTH;
860 break;
861 default:
862 return;
863 }
864 }
865
866 static void r300StencilFuncSeparate(GLcontext * ctx, GLenum face,
867 GLenum func, GLint ref, GLuint mask)
868 {
869 r300ContextPtr rmesa = R300_CONTEXT(ctx);
870 GLuint refmask =
871 (((ctx->Stencil.
872 Ref[0] & 0xff) << R300_RB3D_ZS2_STENCIL_REF_SHIFT) | ((ctx->
873 Stencil.
874 ValueMask
875 [0] &
876 0xff)
877 <<
878 R300_RB3D_ZS2_STENCIL_MASK_SHIFT));
879
880 GLuint flag;
881
882 R300_STATECHANGE(rmesa, zs);
883
884 rmesa->hw.zs.cmd[R300_ZS_CNTL_1] &= ~((R300_ZS_MASK <<
885 R300_RB3D_ZS1_FRONT_FUNC_SHIFT)
886 | (R300_ZS_MASK <<
887 R300_RB3D_ZS1_BACK_FUNC_SHIFT));
888
889 rmesa->hw.zs.cmd[R300_ZS_CNTL_2] &=
890 ~((R300_RB3D_ZS2_STENCIL_MASK <<
891 R300_RB3D_ZS2_STENCIL_REF_SHIFT) |
892 (R300_RB3D_ZS2_STENCIL_MASK << R300_RB3D_ZS2_STENCIL_MASK_SHIFT));
893
894 flag = translate_func(ctx->Stencil.Function[0]);
895 rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=
896 (flag << R300_RB3D_ZS1_FRONT_FUNC_SHIFT);
897
898 if (ctx->Stencil._TestTwoSide)
899 flag = translate_func(ctx->Stencil.Function[1]);
900
901 rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=
902 (flag << R300_RB3D_ZS1_BACK_FUNC_SHIFT);
903 rmesa->hw.zs.cmd[R300_ZS_CNTL_2] |= refmask;
904 }
905
906 static void r300StencilMaskSeparate(GLcontext * ctx, GLenum face, GLuint mask)
907 {
908 r300ContextPtr rmesa = R300_CONTEXT(ctx);
909
910 R300_STATECHANGE(rmesa, zs);
911 rmesa->hw.zs.cmd[R300_ZS_CNTL_2] &=
912 ~(R300_RB3D_ZS2_STENCIL_MASK <<
913 R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT);
914 rmesa->hw.zs.cmd[R300_ZS_CNTL_2] |=
915 (ctx->Stencil.
916 WriteMask[0] & 0xff) << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT;
917 }
918
919 static void r300StencilOpSeparate(GLcontext * ctx, GLenum face,
920 GLenum fail, GLenum zfail, GLenum zpass)
921 {
922 r300ContextPtr rmesa = R300_CONTEXT(ctx);
923
924 R300_STATECHANGE(rmesa, zs);
925 /* It is easier to mask what's left.. */
926 rmesa->hw.zs.cmd[R300_ZS_CNTL_1] &=
927 (R300_ZS_MASK << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT) |
928 (R300_ZS_MASK << R300_RB3D_ZS1_FRONT_FUNC_SHIFT) |
929 (R300_ZS_MASK << R300_RB3D_ZS1_BACK_FUNC_SHIFT);
930
931 rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=
932 (translate_stencil_op(ctx->Stencil.FailFunc[0]) <<
933 R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT)
934 | (translate_stencil_op(ctx->Stencil.ZFailFunc[0]) <<
935 R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT)
936 | (translate_stencil_op(ctx->Stencil.ZPassFunc[0]) <<
937 R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT);
938
939 if (ctx->Stencil._TestTwoSide) {
940 rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=
941 (translate_stencil_op(ctx->Stencil.FailFunc[1]) <<
942 R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT)
943 | (translate_stencil_op(ctx->Stencil.ZFailFunc[1]) <<
944 R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT)
945 | (translate_stencil_op(ctx->Stencil.ZPassFunc[1]) <<
946 R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT);
947 } else {
948 rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=
949 (translate_stencil_op(ctx->Stencil.FailFunc[0]) <<
950 R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT)
951 | (translate_stencil_op(ctx->Stencil.ZFailFunc[0]) <<
952 R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT)
953 | (translate_stencil_op(ctx->Stencil.ZPassFunc[0]) <<
954 R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT);
955 }
956 }
957
958 static void r300ClearStencil(GLcontext * ctx, GLint s)
959 {
960 r300ContextPtr rmesa = R300_CONTEXT(ctx);
961
962 rmesa->state.stencil.clear =
963 ((GLuint) (ctx->Stencil.Clear & 0xff) |
964 (R300_RB3D_ZS2_STENCIL_MASK <<
965 R300_RB3D_ZS2_STENCIL_MASK_SHIFT) | ((ctx->Stencil.
966 WriteMask[0] & 0xff) <<
967 R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT));
968 }
969
970 /* =============================================================
971 * Window position and viewport transformation
972 */
973
974 /*
975 * To correctly position primitives:
976 */
977 #define SUBPIXEL_X 0.125
978 #define SUBPIXEL_Y 0.125
979
980 void r300UpdateWindow(GLcontext * ctx)
981 {
982 r300ContextPtr rmesa = R300_CONTEXT(ctx);
983 __DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable;
984 GLfloat xoffset = dPriv ? (GLfloat) dPriv->x : 0;
985 GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0;
986 const GLfloat *v = ctx->Viewport._WindowMap.m;
987
988 GLfloat sx = v[MAT_SX];
989 GLfloat tx = v[MAT_TX] + xoffset + SUBPIXEL_X;
990 GLfloat sy = -v[MAT_SY];
991 GLfloat ty = (-v[MAT_TY]) + yoffset + SUBPIXEL_Y;
992 GLfloat sz = v[MAT_SZ] * rmesa->state.depth.scale;
993 GLfloat tz = v[MAT_TZ] * rmesa->state.depth.scale;
994
995 R300_FIREVERTICES(rmesa);
996 R300_STATECHANGE(rmesa, vpt);
997
998 rmesa->hw.vpt.cmd[R300_VPT_XSCALE] = r300PackFloat32(sx);
999 rmesa->hw.vpt.cmd[R300_VPT_XOFFSET] = r300PackFloat32(tx);
1000 rmesa->hw.vpt.cmd[R300_VPT_YSCALE] = r300PackFloat32(sy);
1001 rmesa->hw.vpt.cmd[R300_VPT_YOFFSET] = r300PackFloat32(ty);
1002 rmesa->hw.vpt.cmd[R300_VPT_ZSCALE] = r300PackFloat32(sz);
1003 rmesa->hw.vpt.cmd[R300_VPT_ZOFFSET] = r300PackFloat32(tz);
1004 }
1005
1006 static void r300Viewport(GLcontext * ctx, GLint x, GLint y,
1007 GLsizei width, GLsizei height)
1008 {
1009 /* Don't pipeline viewport changes, conflict with window offset
1010 * setting below. Could apply deltas to rescue pipelined viewport
1011 * values, or keep the originals hanging around.
1012 */
1013 r300UpdateWindow(ctx);
1014 }
1015
1016 static void r300DepthRange(GLcontext * ctx, GLclampd nearval, GLclampd farval)
1017 {
1018 r300UpdateWindow(ctx);
1019 }
1020
1021 void r300UpdateViewportOffset(GLcontext * ctx)
1022 {
1023 r300ContextPtr rmesa = R300_CONTEXT(ctx);
1024 __DRIdrawablePrivate *dPriv = ((radeonContextPtr) rmesa)->dri.drawable;
1025 GLfloat xoffset = (GLfloat) dPriv->x;
1026 GLfloat yoffset = (GLfloat) dPriv->y + dPriv->h;
1027 const GLfloat *v = ctx->Viewport._WindowMap.m;
1028
1029 GLfloat tx = v[MAT_TX] + xoffset + SUBPIXEL_X;
1030 GLfloat ty = (-v[MAT_TY]) + yoffset + SUBPIXEL_Y;
1031
1032 if (rmesa->hw.vpt.cmd[R300_VPT_XOFFSET] != r300PackFloat32(tx) ||
1033 rmesa->hw.vpt.cmd[R300_VPT_YOFFSET] != r300PackFloat32(ty)) {
1034 /* Note: this should also modify whatever data the context reset
1035 * code uses...
1036 */
1037 R300_STATECHANGE(rmesa, vpt);
1038 rmesa->hw.vpt.cmd[R300_VPT_XOFFSET] = r300PackFloat32(tx);
1039 rmesa->hw.vpt.cmd[R300_VPT_YOFFSET] = r300PackFloat32(ty);
1040
1041 }
1042
1043 radeonUpdateScissor(ctx);
1044 }
1045
1046 /**
1047 * Tell the card where to render (offset, pitch).
1048 * Effected by glDrawBuffer, etc
1049 */
1050 void r300UpdateDrawBuffer(GLcontext * ctx)
1051 {
1052 r300ContextPtr rmesa = R300_CONTEXT(ctx);
1053 r300ContextPtr r300 = rmesa;
1054 struct gl_framebuffer *fb = ctx->DrawBuffer;
1055 driRenderbuffer *drb;
1056
1057 if (fb->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT) {
1058 /* draw to front */
1059 drb =
1060 (driRenderbuffer *) fb->Attachment[BUFFER_FRONT_LEFT].
1061 Renderbuffer;
1062 } else if (fb->_ColorDrawBufferMask[0] == BUFFER_BIT_BACK_LEFT) {
1063 /* draw to back */
1064 drb =
1065 (driRenderbuffer *) fb->Attachment[BUFFER_BACK_LEFT].
1066 Renderbuffer;
1067 } else {
1068 /* drawing to multiple buffers, or none */
1069 return;
1070 }
1071
1072 assert(drb);
1073 assert(drb->flippedPitch);
1074
1075 R300_STATECHANGE(rmesa, cb);
1076
1077 r300->hw.cb.cmd[R300_CB_OFFSET] = drb->flippedOffset + //r300->radeon.state.color.drawOffset +
1078 r300->radeon.radeonScreen->fbLocation;
1079 r300->hw.cb.cmd[R300_CB_PITCH] = drb->flippedPitch; //r300->radeon.state.color.drawPitch;
1080
1081 if (r300->radeon.radeonScreen->cpp == 4)
1082 r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_FORMAT_ARGB8888;
1083 else
1084 r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_FORMAT_RGB565;
1085
1086 if (r300->radeon.sarea->tiling_enabled)
1087 r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_TILE_ENABLE;
1088 #if 0
1089 R200_STATECHANGE(rmesa, ctx);
1090
1091 /* Note: we used the (possibly) page-flipped values */
1092 rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET]
1093 = ((drb->flippedOffset + rmesa->r200Screen->fbLocation)
1094 & R200_COLOROFFSET_MASK);
1095 rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = drb->flippedPitch;
1096
1097 if (rmesa->sarea->tiling_enabled) {
1098 rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |=
1099 R200_COLOR_TILE_ENABLE;
1100 }
1101 #endif
1102 }
1103
1104 static void
1105 r300FetchStateParameter(GLcontext * ctx,
1106 const gl_state_index state[STATE_LENGTH],
1107 GLfloat * value)
1108 {
1109 r300ContextPtr r300 = R300_CONTEXT(ctx);
1110
1111 switch (state[0]) {
1112 case STATE_INTERNAL:
1113 switch (state[1]) {
1114 case STATE_R300_WINDOW_DIMENSION:
1115 value[0] = r300->radeon.dri.drawable->w * 0.5f; /* width*0.5 */
1116 value[1] = r300->radeon.dri.drawable->h * 0.5f; /* height*0.5 */
1117 value[2] = 0.5F; /* for moving range [-1 1] -> [0 1] */
1118 value[3] = 1.0F; /* not used */
1119 break;
1120
1121 case STATE_R300_TEXRECT_FACTOR:{
1122 struct gl_texture_object *t =
1123 ctx->Texture.Unit[state[2]].CurrentRect;
1124
1125 if (t && t->Image[0][t->BaseLevel]) {
1126 struct gl_texture_image *image =
1127 t->Image[0][t->BaseLevel];
1128 value[0] = 1.0 / image->Width2;
1129 value[1] = 1.0 / image->Height2;
1130 } else {
1131 value[0] = 1.0;
1132 value[1] = 1.0;
1133 }
1134 value[2] = 1.0;
1135 value[3] = 1.0;
1136 break;
1137 }
1138
1139 default:
1140 break;
1141 }
1142 break;
1143
1144 default:
1145 break;
1146 }
1147 }
1148
1149 /**
1150 * Update R300's own internal state parameters.
1151 * For now just STATE_R300_WINDOW_DIMENSION
1152 */
1153 void r300UpdateStateParameters(GLcontext * ctx, GLuint new_state)
1154 {
1155 struct r300_fragment_program *fp;
1156 struct gl_program_parameter_list *paramList;
1157 GLuint i;
1158
1159 if (!(new_state & (_NEW_BUFFERS | _NEW_PROGRAM)))
1160 return;
1161
1162 fp = (struct r300_fragment_program *)ctx->FragmentProgram._Current;
1163 if (!fp)
1164 return;
1165
1166 paramList = fp->mesa_program.Base.Parameters;
1167
1168 if (!paramList)
1169 return;
1170
1171 for (i = 0; i < paramList->NumParameters; i++) {
1172 if (paramList->Parameters[i].Type == PROGRAM_STATE_VAR) {
1173 r300FetchStateParameter(ctx,
1174 paramList->Parameters[i].
1175 StateIndexes,
1176 paramList->ParameterValues[i]);
1177 }
1178 }
1179 }
1180
1181 /* =============================================================
1182 * Polygon state
1183 */
1184 static void r300PolygonOffset(GLcontext * ctx, GLfloat factor, GLfloat units)
1185 {
1186 r300ContextPtr rmesa = R300_CONTEXT(ctx);
1187 GLfloat constant = units;
1188
1189 switch (ctx->Visual.depthBits) {
1190 case 16:
1191 constant *= 4.0;
1192 break;
1193 case 24:
1194 constant *= 2.0;
1195 break;
1196 }
1197
1198 factor *= 12.0;
1199
1200 /* fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */
1201
1202 R300_STATECHANGE(rmesa, zbs);
1203 rmesa->hw.zbs.cmd[R300_ZBS_T_FACTOR] = r300PackFloat32(factor);
1204 rmesa->hw.zbs.cmd[R300_ZBS_T_CONSTANT] = r300PackFloat32(constant);
1205 rmesa->hw.zbs.cmd[R300_ZBS_W_FACTOR] = r300PackFloat32(factor);
1206 rmesa->hw.zbs.cmd[R300_ZBS_W_CONSTANT] = r300PackFloat32(constant);
1207 }
1208
1209 /* Routing and texture-related */
1210
1211 /* r300 doesnt handle GL_CLAMP and GL_MIRROR_CLAMP_EXT correctly when filter is NEAREST.
1212 * Since texwrap produces same results for GL_CLAMP and GL_CLAMP_TO_EDGE we use them instead.
1213 * We need to recalculate wrap modes whenever filter mode is changed because someone might do:
1214 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1215 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1216 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1217 * Since r300 completely ignores R300_TX_CLAMP when either min or mag is nearest it cant handle
1218 * combinations where only one of them is nearest.
1219 */
1220 static unsigned long gen_fixed_filter(unsigned long f)
1221 {
1222 unsigned long mag, min, needs_fixing = 0;
1223 //return f;
1224
1225 /* We ignore MIRROR bit so we dont have to do everything twice */
1226 if ((f & ((7 - 1) << R300_TX_WRAP_S_SHIFT)) ==
1227 (R300_TX_CLAMP << R300_TX_WRAP_S_SHIFT)) {
1228 needs_fixing |= 1;
1229 }
1230 if ((f & ((7 - 1) << R300_TX_WRAP_T_SHIFT)) ==
1231 (R300_TX_CLAMP << R300_TX_WRAP_T_SHIFT)) {
1232 needs_fixing |= 2;
1233 }
1234 if ((f & ((7 - 1) << R300_TX_WRAP_Q_SHIFT)) ==
1235 (R300_TX_CLAMP << R300_TX_WRAP_Q_SHIFT)) {
1236 needs_fixing |= 4;
1237 }
1238
1239 if (!needs_fixing)
1240 return f;
1241
1242 mag = f & R300_TX_MAG_FILTER_MASK;
1243 min = f & R300_TX_MIN_FILTER_MASK;
1244
1245 /* TODO: Check for anisto filters too */
1246 if ((mag != R300_TX_MAG_FILTER_NEAREST)
1247 && (min != R300_TX_MIN_FILTER_NEAREST))
1248 return f;
1249
1250 /* r300 cant handle these modes hence we force nearest to linear */
1251 if ((mag == R300_TX_MAG_FILTER_NEAREST)
1252 && (min != R300_TX_MIN_FILTER_NEAREST)) {
1253 f &= ~R300_TX_MAG_FILTER_NEAREST;
1254 f |= R300_TX_MAG_FILTER_LINEAR;
1255 return f;
1256 }
1257
1258 if ((min == R300_TX_MIN_FILTER_NEAREST)
1259 && (mag != R300_TX_MAG_FILTER_NEAREST)) {
1260 f &= ~R300_TX_MIN_FILTER_NEAREST;
1261 f |= R300_TX_MIN_FILTER_LINEAR;
1262 return f;
1263 }
1264
1265 /* Both are nearest */
1266 if (needs_fixing & 1) {
1267 f &= ~((7 - 1) << R300_TX_WRAP_S_SHIFT);
1268 f |= R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_S_SHIFT;
1269 }
1270 if (needs_fixing & 2) {
1271 f &= ~((7 - 1) << R300_TX_WRAP_T_SHIFT);
1272 f |= R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_T_SHIFT;
1273 }
1274 if (needs_fixing & 4) {
1275 f &= ~((7 - 1) << R300_TX_WRAP_Q_SHIFT);
1276 f |= R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_Q_SHIFT;
1277 }
1278 return f;
1279 }
1280
1281 static void r300SetupTextures(GLcontext * ctx)
1282 {
1283 int i, mtu;
1284 struct r300_tex_obj *t;
1285 r300ContextPtr r300 = R300_CONTEXT(ctx);
1286 int hw_tmu = 0;
1287 int last_hw_tmu = -1; /* -1 translates into no setup costs for fields */
1288 int tmu_mappings[R300_MAX_TEXTURE_UNITS] = { -1, };
1289 struct r300_fragment_program *fp = (struct r300_fragment_program *)
1290 (char *)ctx->FragmentProgram._Current;
1291
1292 R300_STATECHANGE(r300, txe);
1293 R300_STATECHANGE(r300, tex.filter);
1294 R300_STATECHANGE(r300, tex.filter_1);
1295 R300_STATECHANGE(r300, tex.size);
1296 R300_STATECHANGE(r300, tex.format);
1297 R300_STATECHANGE(r300, tex.pitch);
1298 R300_STATECHANGE(r300, tex.offset);
1299 R300_STATECHANGE(r300, tex.chroma_key);
1300 R300_STATECHANGE(r300, tex.border_color);
1301
1302 r300->hw.txe.cmd[R300_TXE_ENABLE] = 0x0;
1303
1304 mtu = r300->radeon.glCtx->Const.MaxTextureUnits;
1305 if (RADEON_DEBUG & DEBUG_STATE)
1306 fprintf(stderr, "mtu=%d\n", mtu);
1307
1308 if (mtu > R300_MAX_TEXTURE_UNITS) {
1309 fprintf(stderr,
1310 "Aiiee ! mtu=%d is greater than R300_MAX_TEXTURE_UNITS=%d\n",
1311 mtu, R300_MAX_TEXTURE_UNITS);
1312 _mesa_exit(-1);
1313 }
1314
1315 /* We cannot let disabled tmu offsets pass DRM */
1316 for (i = 0; i < mtu; i++) {
1317 if (ctx->Texture.Unit[i]._ReallyEnabled) {
1318
1319 #if 0 /* Enables old behaviour */
1320 hw_tmu = i;
1321 #endif
1322 tmu_mappings[i] = hw_tmu;
1323
1324 t = r300->state.texture.unit[i].texobj;
1325 /* XXX questionable fix for bug 9170: */
1326 if (!t)
1327 continue;
1328
1329 if ((t->format & 0xffffff00) == 0xffffff00) {
1330 WARN_ONCE
1331 ("unknown texture format (entry %x) encountered. Help me !\n",
1332 t->format & 0xff);
1333 }
1334
1335 if (RADEON_DEBUG & DEBUG_STATE)
1336 fprintf(stderr,
1337 "Activating texture unit %d\n", i);
1338
1339 r300->hw.txe.cmd[R300_TXE_ENABLE] |= (1 << hw_tmu);
1340
1341 r300->hw.tex.filter.cmd[R300_TEX_VALUE_0 +
1342 hw_tmu] =
1343 gen_fixed_filter(t->filter) | (hw_tmu << 28);
1344 /* Currently disabled! */
1345 r300->hw.tex.filter_1.cmd[R300_TEX_VALUE_0 + hw_tmu] = 0x0; //0x20501f80;
1346 r300->hw.tex.size.cmd[R300_TEX_VALUE_0 + hw_tmu] =
1347 t->size;
1348 r300->hw.tex.format.cmd[R300_TEX_VALUE_0 +
1349 hw_tmu] = t->format;
1350 r300->hw.tex.pitch.cmd[R300_TEX_VALUE_0 + hw_tmu] =
1351 t->pitch_reg;
1352 r300->hw.tex.offset.cmd[R300_TEX_VALUE_0 +
1353 hw_tmu] = t->offset;
1354
1355 if (t->offset & R300_TXO_MACRO_TILE) {
1356 WARN_ONCE("macro tiling enabled!\n");
1357 }
1358
1359 if (t->offset & R300_TXO_MICRO_TILE) {
1360 WARN_ONCE("micro tiling enabled!\n");
1361 }
1362
1363 r300->hw.tex.chroma_key.cmd[R300_TEX_VALUE_0 +
1364 hw_tmu] = 0x0;
1365 r300->hw.tex.border_color.cmd[R300_TEX_VALUE_0 +
1366 hw_tmu] =
1367 t->pp_border_color;
1368
1369 last_hw_tmu = hw_tmu;
1370
1371 hw_tmu++;
1372 }
1373 }
1374
1375 r300->hw.tex.filter.cmd[R300_TEX_CMD_0] =
1376 cmdpacket0(R300_TX_FILTER_0, last_hw_tmu + 1);
1377 r300->hw.tex.filter_1.cmd[R300_TEX_CMD_0] =
1378 cmdpacket0(R300_TX_FILTER1_0, last_hw_tmu + 1);
1379 r300->hw.tex.size.cmd[R300_TEX_CMD_0] =
1380 cmdpacket0(R300_TX_SIZE_0, last_hw_tmu + 1);
1381 r300->hw.tex.format.cmd[R300_TEX_CMD_0] =
1382 cmdpacket0(R300_TX_FORMAT_0, last_hw_tmu + 1);
1383 r300->hw.tex.pitch.cmd[R300_TEX_CMD_0] =
1384 cmdpacket0(R300_TX_PITCH_0, last_hw_tmu + 1);
1385 r300->hw.tex.offset.cmd[R300_TEX_CMD_0] =
1386 cmdpacket0(R300_TX_OFFSET_0, last_hw_tmu + 1);
1387 r300->hw.tex.chroma_key.cmd[R300_TEX_CMD_0] =
1388 cmdpacket0(R300_TX_CHROMA_KEY_0, last_hw_tmu + 1);
1389 r300->hw.tex.border_color.cmd[R300_TEX_CMD_0] =
1390 cmdpacket0(R300_TX_BORDER_COLOR_0, last_hw_tmu + 1);
1391
1392 if (!fp) /* should only happenen once, just after context is created */
1393 return;
1394
1395 R300_STATECHANGE(r300, fpt);
1396
1397 for (i = 0; i < fp->tex.length; i++) {
1398 int unit;
1399 int opcode;
1400 unsigned long val;
1401
1402 unit = fp->tex.inst[i] >> R300_FPITX_IMAGE_SHIFT;
1403 unit &= 15;
1404
1405 val = fp->tex.inst[i];
1406 val &= ~R300_FPITX_IMAGE_MASK;
1407
1408 opcode =
1409 (val & R300_FPITX_OPCODE_MASK) >> R300_FPITX_OPCODE_SHIFT;
1410 if (opcode == R300_FPITX_OP_KIL) {
1411 r300->hw.fpt.cmd[R300_FPT_INSTR_0 + i] = val;
1412 } else {
1413 if (tmu_mappings[unit] >= 0) {
1414 val |=
1415 tmu_mappings[unit] <<
1416 R300_FPITX_IMAGE_SHIFT;
1417 r300->hw.fpt.cmd[R300_FPT_INSTR_0 + i] = val;
1418 } else {
1419 // We get here when the corresponding texture image is incomplete
1420 // (e.g. incomplete mipmaps etc.)
1421 r300->hw.fpt.cmd[R300_FPT_INSTR_0 + i] = val;
1422 }
1423 }
1424 }
1425
1426 r300->hw.fpt.cmd[R300_FPT_CMD_0] =
1427 cmdpacket0(R300_PFS_TEXI_0, fp->tex.length);
1428
1429 if (RADEON_DEBUG & DEBUG_STATE)
1430 fprintf(stderr, "TX_ENABLE: %08x last_hw_tmu=%d\n",
1431 r300->hw.txe.cmd[R300_TXE_ENABLE], last_hw_tmu);
1432 }
1433
1434 union r300_outputs_written {
1435 GLuint vp_outputs; /* hw_tcl_on */
1436 DECLARE_RENDERINPUTS(index_bitset); /* !hw_tcl_on */
1437 };
1438
1439 #define R300_OUTPUTS_WRITTEN_TEST(ow, vp_result, tnl_attrib) \
1440 ((hw_tcl_on) ? (ow).vp_outputs & (1 << (vp_result)) : \
1441 RENDERINPUTS_TEST( (ow.index_bitset), (tnl_attrib) ))
1442
1443 void r300SetupRSUnit(GLcontext * ctx)
1444 {
1445 r300ContextPtr r300 = R300_CONTEXT(ctx);
1446 /* I'm still unsure if these are needed */
1447 GLuint interp_magic[8] = {
1448 0x00,
1449 0x40,
1450 0x80,
1451 0xC0,
1452 0x00,
1453 0x00,
1454 0x00,
1455 0x00
1456 };
1457 union r300_outputs_written OutputsWritten;
1458 GLuint InputsRead;
1459 int fp_reg, high_rr;
1460 int in_texcoords, col_interp_nr;
1461 int i;
1462
1463 if (hw_tcl_on)
1464 OutputsWritten.vp_outputs =
1465 CURRENT_VERTEX_SHADER(ctx)->key.OutputsWritten;
1466 else
1467 RENDERINPUTS_COPY(OutputsWritten.index_bitset,
1468 r300->state.render_inputs_bitset);
1469
1470 if (ctx->FragmentProgram._Current)
1471 InputsRead = ctx->FragmentProgram._Current->Base.InputsRead;
1472 else {
1473 fprintf(stderr, "No ctx->FragmentProgram._Current!!\n");
1474 return; /* This should only ever happen once.. */
1475 }
1476
1477 R300_STATECHANGE(r300, ri);
1478 R300_STATECHANGE(r300, rc);
1479 R300_STATECHANGE(r300, rr);
1480
1481 fp_reg = in_texcoords = col_interp_nr = high_rr = 0;
1482
1483 r300->hw.rr.cmd[R300_RR_ROUTE_1] = 0;
1484
1485 if (InputsRead & FRAG_BIT_WPOS) {
1486 for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
1487 if (!(InputsRead & (FRAG_BIT_TEX0 << i)))
1488 break;
1489
1490 if (i == ctx->Const.MaxTextureUnits) {
1491 fprintf(stderr, "\tno free texcoord found...\n");
1492 _mesa_exit(-1);
1493 }
1494
1495 InputsRead |= (FRAG_BIT_TEX0 << i);
1496 InputsRead &= ~FRAG_BIT_WPOS;
1497 }
1498
1499 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
1500 r300->hw.ri.cmd[R300_RI_INTERP_0 + i] = 0
1501 | R300_RS_INTERP_USED
1502 | (in_texcoords << R300_RS_INTERP_SRC_SHIFT)
1503 | interp_magic[i];
1504
1505 r300->hw.rr.cmd[R300_RR_ROUTE_0 + fp_reg] = 0;
1506 if (InputsRead & (FRAG_BIT_TEX0 << i)) {
1507 //assert(r300->state.texture.tc_count != 0);
1508 r300->hw.rr.cmd[R300_RR_ROUTE_0 + fp_reg] |= R300_RS_ROUTE_ENABLE | i /* source INTERP */
1509 | (fp_reg << R300_RS_ROUTE_DEST_SHIFT);
1510 high_rr = fp_reg;
1511
1512 if (!R300_OUTPUTS_WRITTEN_TEST
1513 (OutputsWritten, VERT_RESULT_TEX0 + i,
1514 _TNL_ATTRIB_TEX(i))) {
1515 /* Passing invalid data here can lock the GPU. */
1516 WARN_ONCE
1517 ("fragprog wants coords for tex%d, vp doesn't provide them!\n",
1518 i);
1519 //_mesa_print_program(&CURRENT_VERTEX_SHADER(ctx)->Base);
1520 //_mesa_exit(-1);
1521 }
1522 InputsRead &= ~(FRAG_BIT_TEX0 << i);
1523 fp_reg++;
1524 }
1525 /* Need to count all coords enabled at vof */
1526 if (R300_OUTPUTS_WRITTEN_TEST
1527 (OutputsWritten, VERT_RESULT_TEX0 + i, _TNL_ATTRIB_TEX(i)))
1528 in_texcoords++;
1529 }
1530
1531 if (InputsRead & FRAG_BIT_COL0) {
1532 if (!R300_OUTPUTS_WRITTEN_TEST
1533 (OutputsWritten, VERT_RESULT_COL0, _TNL_ATTRIB_COLOR0)) {
1534 WARN_ONCE
1535 ("fragprog wants col0, vp doesn't provide it\n");
1536 goto out; /* FIXME */
1537 //_mesa_print_program(&CURRENT_VERTEX_SHADER(ctx)->Base);
1538 //_mesa_exit(-1);
1539 }
1540
1541 r300->hw.rr.cmd[R300_RR_ROUTE_0] |= 0
1542 | R300_RS_ROUTE_0_COLOR
1543 | (fp_reg++ << R300_RS_ROUTE_0_COLOR_DEST_SHIFT);
1544 InputsRead &= ~FRAG_BIT_COL0;
1545 col_interp_nr++;
1546 }
1547 out:
1548
1549 if (InputsRead & FRAG_BIT_COL1) {
1550 if (!R300_OUTPUTS_WRITTEN_TEST
1551 (OutputsWritten, VERT_RESULT_COL1, _TNL_ATTRIB_COLOR1)) {
1552 WARN_ONCE
1553 ("fragprog wants col1, vp doesn't provide it\n");
1554 //_mesa_exit(-1);
1555 }
1556
1557 r300->hw.rr.cmd[R300_RR_ROUTE_1] |=
1558 R300_RS_ROUTE_1_UNKNOWN11 | R300_RS_ROUTE_1_COLOR1 |
1559 (fp_reg++ << R300_RS_ROUTE_1_COLOR1_DEST_SHIFT);
1560 InputsRead &= ~FRAG_BIT_COL1;
1561 if (high_rr < 1)
1562 high_rr = 1;
1563 col_interp_nr++;
1564 }
1565
1566 /* Need at least one. This might still lock as the values are undefined... */
1567 if (in_texcoords == 0 && col_interp_nr == 0) {
1568 r300->hw.rr.cmd[R300_RR_ROUTE_0] |= 0
1569 | R300_RS_ROUTE_0_COLOR
1570 | (fp_reg++ << R300_RS_ROUTE_0_COLOR_DEST_SHIFT);
1571 col_interp_nr++;
1572 }
1573
1574 r300->hw.rc.cmd[1] = 0 | (in_texcoords << R300_RS_CNTL_TC_CNT_SHIFT)
1575 | (col_interp_nr << R300_RS_CNTL_CI_CNT_SHIFT)
1576 | R300_RS_CNTL_0_UNKNOWN_18;
1577
1578 assert(high_rr >= 0);
1579 r300->hw.rr.cmd[R300_RR_CMD_0] =
1580 cmdpacket0(R300_RS_ROUTE_0, high_rr + 1);
1581 r300->hw.rc.cmd[2] = 0xC0 | high_rr;
1582
1583 if (InputsRead)
1584 WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n",
1585 InputsRead);
1586 }
1587
1588 #define vpucount(ptr) (((drm_r300_cmd_header_t*)(ptr))->vpu.count)
1589
1590 #define bump_vpu_count(ptr, new_count) do{\
1591 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
1592 int _nc=(new_count)/4; \
1593 assert(_nc < 256); \
1594 if(_nc>_p->vpu.count)_p->vpu.count=_nc;\
1595 }while(0)
1596
1597 void static inline setup_vertex_shader_fragment(r300ContextPtr r300, int dest, struct
1598 r300_vertex_shader_fragment
1599 *vsf)
1600 {
1601 int i;
1602
1603 if (vsf->length == 0)
1604 return;
1605
1606 if (vsf->length & 0x3) {
1607 fprintf(stderr,
1608 "VERTEX_SHADER_FRAGMENT must have length divisible by 4\n");
1609 _mesa_exit(-1);
1610 }
1611
1612 switch ((dest >> 8) & 0xf) {
1613 case 0:
1614 R300_STATECHANGE(r300, vpi);
1615 for (i = 0; i < vsf->length; i++)
1616 r300->hw.vpi.cmd[R300_VPI_INSTR_0 + i +
1617 4 * (dest & 0xff)] = (vsf->body.d[i]);
1618 bump_vpu_count(r300->hw.vpi.cmd,
1619 vsf->length + 4 * (dest & 0xff));
1620 break;
1621
1622 case 2:
1623 R300_STATECHANGE(r300, vpp);
1624 for (i = 0; i < vsf->length; i++)
1625 r300->hw.vpp.cmd[R300_VPP_PARAM_0 + i +
1626 4 * (dest & 0xff)] = (vsf->body.d[i]);
1627 bump_vpu_count(r300->hw.vpp.cmd,
1628 vsf->length + 4 * (dest & 0xff));
1629 break;
1630 case 4:
1631 R300_STATECHANGE(r300, vps);
1632 for (i = 0; i < vsf->length; i++)
1633 r300->hw.vps.cmd[1 + i + 4 * (dest & 0xff)] =
1634 (vsf->body.d[i]);
1635 bump_vpu_count(r300->hw.vps.cmd,
1636 vsf->length + 4 * (dest & 0xff));
1637 break;
1638 default:
1639 fprintf(stderr,
1640 "%s:%s don't know how to handle dest %04x\n",
1641 __FILE__, __FUNCTION__, dest);
1642 _mesa_exit(-1);
1643 }
1644 }
1645
1646 void r300SetupVertexProgram(r300ContextPtr rmesa);
1647
1648 /* just a skeleton for now.. */
1649
1650 /* Generate a vertex shader that simply transforms vertex and texture coordinates,
1651 while leaving colors intact. Nothing fancy (like lights)
1652
1653 If implementing lights make a copy first, so it is easy to switch between the two versions */
1654 static void r300GenerateSimpleVertexShader(r300ContextPtr r300)
1655 {
1656 int i;
1657 GLuint o_reg = 0;
1658
1659 /* Allocate parameters */
1660 r300->state.vap_param.transform_offset = 0x0; /* transform matrix */
1661 r300->state.vertex_shader.param_offset = 0x0;
1662 r300->state.vertex_shader.param_count = 0x4; /* 4 vector values - 4x4 matrix */
1663
1664 r300->state.vertex_shader.program_start = 0x0;
1665 r300->state.vertex_shader.unknown_ptr1 = 0x4; /* magic value ? */
1666 r300->state.vertex_shader.program_end = 0x0;
1667
1668 r300->state.vertex_shader.unknown_ptr2 = 0x0; /* magic value */
1669 r300->state.vertex_shader.unknown_ptr3 = 0x4; /* magic value */
1670
1671 r300->state.vertex_shader.unknown1.length = 0;
1672 r300->state.vertex_shader.unknown2.length = 0;
1673
1674 #define WRITE_OP(oper,source1,source2,source3) {\
1675 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].op=(oper); \
1676 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src[0]=(source1); \
1677 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src[1]=(source2); \
1678 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src[2]=(source3); \
1679 r300->state.vertex_shader.program_end++; \
1680 }
1681
1682 for (i = VERT_ATTRIB_POS; i < VERT_ATTRIB_MAX; i++)
1683 if (r300->state.sw_tcl_inputs[i] != -1) {
1684 WRITE_OP(EASY_VSF_OP(MUL, o_reg++, ALL, RESULT),
1685 VSF_REG(r300->state.sw_tcl_inputs[i]),
1686 VSF_ATTR_UNITY(r300->state.
1687 sw_tcl_inputs[i]),
1688 VSF_UNITY(r300->state.sw_tcl_inputs[i])
1689 )
1690
1691 }
1692
1693 r300->state.vertex_shader.program_end--; /* r300 wants program length to be one more - no idea why */
1694 r300->state.vertex_shader.program.length =
1695 (r300->state.vertex_shader.program_end + 1) * 4;
1696
1697 r300->state.vertex_shader.unknown_ptr1 = r300->state.vertex_shader.program_end; /* magic value ? */
1698 r300->state.vertex_shader.unknown_ptr2 = r300->state.vertex_shader.program_end; /* magic value ? */
1699 r300->state.vertex_shader.unknown_ptr3 = r300->state.vertex_shader.program_end; /* magic value ? */
1700
1701 }
1702
1703 void r300SetupVertexShader(r300ContextPtr rmesa)
1704 {
1705 GLcontext *ctx = rmesa->radeon.glCtx;
1706
1707 /* Reset state, in case we don't use something */
1708 ((drm_r300_cmd_header_t *) rmesa->hw.vpp.cmd)->vpu.count = 0;
1709 ((drm_r300_cmd_header_t *) rmesa->hw.vpi.cmd)->vpu.count = 0;
1710 ((drm_r300_cmd_header_t *) rmesa->hw.vps.cmd)->vpu.count = 0;
1711
1712 /* Not sure why this doesnt work...
1713 0x400 area might have something to do with pixel shaders as it appears right after pfs programming.
1714 0x406 is set to { 0.0, 0.0, 1.0, 0.0 } most of the time but should change with smooth points and in other rare cases. */
1715 //setup_vertex_shader_fragment(rmesa, 0x406, &unk4);
1716 if (hw_tcl_on
1717 && ((struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx))->
1718 translated) {
1719 r300SetupVertexProgram(rmesa);
1720 return;
1721 }
1722
1723 /* This needs to be replaced by vertex shader generation code */
1724 r300GenerateSimpleVertexShader(rmesa);
1725
1726 setup_vertex_shader_fragment(rmesa, VSF_DEST_PROGRAM,
1727 &(rmesa->state.vertex_shader.program));
1728
1729 #if 0
1730 setup_vertex_shader_fragment(rmesa, VSF_DEST_UNKNOWN1,
1731 &(rmesa->state.vertex_shader.unknown1));
1732 setup_vertex_shader_fragment(rmesa, VSF_DEST_UNKNOWN2,
1733 &(rmesa->state.vertex_shader.unknown2));
1734 #endif
1735
1736 R300_STATECHANGE(rmesa, pvs);
1737 rmesa->hw.pvs.cmd[R300_PVS_CNTL_1] =
1738 (rmesa->state.vertex_shader.
1739 program_start << R300_PVS_CNTL_1_PROGRAM_START_SHIFT)
1740 | (rmesa->state.vertex_shader.
1741 unknown_ptr1 << R300_PVS_CNTL_1_POS_END_SHIFT)
1742 | (rmesa->state.vertex_shader.
1743 program_end << R300_PVS_CNTL_1_PROGRAM_END_SHIFT);
1744 rmesa->hw.pvs.cmd[R300_PVS_CNTL_2] =
1745 (rmesa->state.vertex_shader.
1746 param_offset << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT)
1747 | (rmesa->state.vertex_shader.
1748 param_count << R300_PVS_CNTL_2_PARAM_COUNT_SHIFT);
1749 rmesa->hw.pvs.cmd[R300_PVS_CNTL_3] =
1750 (rmesa->state.vertex_shader.
1751 unknown_ptr2 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT)
1752 | (rmesa->state.vertex_shader.unknown_ptr3 << 0);
1753
1754 /* This is done for vertex shader fragments, but also needs to be done for vap_pvs,
1755 so I leave it as a reminder */
1756 #if 0
1757 reg_start(R300_VAP_PVS_WAITIDLE, 0);
1758 e32(0x00000000);
1759 #endif
1760 }
1761
1762 void r300SetupVertexProgram(r300ContextPtr rmesa)
1763 {
1764 GLcontext *ctx = rmesa->radeon.glCtx;
1765 int inst_count;
1766 int param_count;
1767 struct r300_vertex_program *prog =
1768 (struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx);
1769
1770 ((drm_r300_cmd_header_t *) rmesa->hw.vpp.cmd)->vpu.count = 0;
1771 R300_STATECHANGE(rmesa, vpp);
1772 param_count =
1773 r300VertexProgUpdateParams(ctx, (struct r300_vertex_program_cont *)
1774 ctx->VertexProgram._Current /*prog */ ,
1775 (float *)&rmesa->hw.vpp.
1776 cmd[R300_VPP_PARAM_0]);
1777 bump_vpu_count(rmesa->hw.vpp.cmd, param_count);
1778 param_count /= 4;
1779
1780 /* Reset state, in case we don't use something */
1781 ((drm_r300_cmd_header_t *) rmesa->hw.vpi.cmd)->vpu.count = 0;
1782 ((drm_r300_cmd_header_t *) rmesa->hw.vps.cmd)->vpu.count = 0;
1783
1784 setup_vertex_shader_fragment(rmesa, VSF_DEST_PROGRAM, &(prog->program));
1785
1786 #if 0
1787 setup_vertex_shader_fragment(rmesa, VSF_DEST_UNKNOWN1,
1788 &(rmesa->state.vertex_shader.unknown1));
1789 setup_vertex_shader_fragment(rmesa, VSF_DEST_UNKNOWN2,
1790 &(rmesa->state.vertex_shader.unknown2));
1791 #endif
1792
1793 inst_count = prog->program.length / 4 - 1;
1794
1795 R300_STATECHANGE(rmesa, pvs);
1796 rmesa->hw.pvs.cmd[R300_PVS_CNTL_1] =
1797 (0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT)
1798 | (inst_count /*pos_end */ << R300_PVS_CNTL_1_POS_END_SHIFT)
1799 | (inst_count << R300_PVS_CNTL_1_PROGRAM_END_SHIFT);
1800 rmesa->hw.pvs.cmd[R300_PVS_CNTL_2] =
1801 (0 << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT)
1802 | (param_count << R300_PVS_CNTL_2_PARAM_COUNT_SHIFT);
1803 rmesa->hw.pvs.cmd[R300_PVS_CNTL_3] =
1804 (0 /*rmesa->state.vertex_shader.unknown_ptr2 */ <<
1805 R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT)
1806 | (inst_count /*rmesa->state.vertex_shader.unknown_ptr3 */ <<
1807 0);
1808
1809 /* This is done for vertex shader fragments, but also needs to be done for vap_pvs,
1810 so I leave it as a reminder */
1811 #if 0
1812 reg_start(R300_VAP_PVS_WAITIDLE, 0);
1813 e32(0x00000000);
1814 #endif
1815 }
1816
1817 extern void _tnl_UpdateFixedFunctionProgram(GLcontext * ctx);
1818
1819 extern int future_hw_tcl_on;
1820 void r300UpdateShaders(r300ContextPtr rmesa)
1821 {
1822 GLcontext *ctx;
1823 struct r300_vertex_program *vp;
1824 int i;
1825
1826 ctx = rmesa->radeon.glCtx;
1827
1828 if (rmesa->NewGLState && hw_tcl_on) {
1829 rmesa->NewGLState = 0;
1830
1831 for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) {
1832 rmesa->temp_attrib[i] =
1833 TNL_CONTEXT(ctx)->vb.AttribPtr[i];
1834 TNL_CONTEXT(ctx)->vb.AttribPtr[i] =
1835 &rmesa->dummy_attrib[i];
1836 }
1837
1838 _tnl_UpdateFixedFunctionProgram(ctx);
1839
1840 for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) {
1841 TNL_CONTEXT(ctx)->vb.AttribPtr[i] =
1842 rmesa->temp_attrib[i];
1843 }
1844
1845 r300SelectVertexShader(rmesa);
1846 vp = (struct r300_vertex_program *)
1847 CURRENT_VERTEX_SHADER(ctx);
1848 /*if (vp->translated == GL_FALSE)
1849 r300TranslateVertexShader(vp); */
1850 if (vp->translated == GL_FALSE) {
1851 fprintf(stderr, "Failing back to sw-tcl\n");
1852 hw_tcl_on = future_hw_tcl_on = 0;
1853 r300ResetHwState(rmesa);
1854
1855 return;
1856 }
1857 r300UpdateStateParameters(ctx, _NEW_PROGRAM);
1858 }
1859
1860 }
1861
1862 void r300UpdateShaderStates(r300ContextPtr rmesa)
1863 {
1864 GLcontext *ctx;
1865 ctx = rmesa->radeon.glCtx;
1866
1867 r300UpdateTextureState(ctx);
1868
1869 r300SetupPixelShader(rmesa);
1870 r300SetupTextures(ctx);
1871
1872 if ((rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL))
1873 r300SetupVertexShader(rmesa);
1874 r300SetupRSUnit(ctx);
1875 }
1876
1877 /* This is probably wrong for some values, I need to test this
1878 * some more. Range checking would be a good idea also..
1879 *
1880 * But it works for most things. I'll fix it later if someone
1881 * else with a better clue doesn't
1882 */
1883 static unsigned int r300PackFloat24(float f)
1884 {
1885 float mantissa;
1886 int exponent;
1887 unsigned int float24 = 0;
1888
1889 if (f == 0.0)
1890 return 0;
1891
1892 mantissa = frexpf(f, &exponent);
1893
1894 /* Handle -ve */
1895 if (mantissa < 0) {
1896 float24 |= (1 << 23);
1897 mantissa = mantissa * -1.0;
1898 }
1899 /* Handle exponent, bias of 63 */
1900 exponent += 62;
1901 float24 |= (exponent << 16);
1902 /* Kill 7 LSB of mantissa */
1903 float24 |= (r300PackFloat32(mantissa) & 0x7FFFFF) >> 7;
1904
1905 return float24;
1906 }
1907
1908 void r300SetupPixelShader(r300ContextPtr rmesa)
1909 {
1910 GLcontext *ctx = rmesa->radeon.glCtx;
1911 struct r300_fragment_program *fp = (struct r300_fragment_program *)
1912 (char *)ctx->FragmentProgram._Current;
1913 int i, k;
1914
1915 if (!fp) /* should only happenen once, just after context is created */
1916 return;
1917
1918 r300TranslateFragmentShader(rmesa, fp);
1919 if (!fp->translated) {
1920 fprintf(stderr, "%s: No valid fragment shader, exiting\n",
1921 __func__);
1922 return;
1923 }
1924 #define OUTPUT_FIELD(st, reg, field) \
1925 R300_STATECHANGE(rmesa, st); \
1926 for(i=0;i<=fp->alu_end;i++) \
1927 rmesa->hw.st.cmd[R300_FPI_INSTR_0+i]=fp->alu.inst[i].field;\
1928 rmesa->hw.st.cmd[R300_FPI_CMD_0]=cmdpacket0(reg, fp->alu_end+1);
1929
1930 OUTPUT_FIELD(fpi[0], R300_PFS_INSTR0_0, inst0);
1931 OUTPUT_FIELD(fpi[1], R300_PFS_INSTR1_0, inst1);
1932 OUTPUT_FIELD(fpi[2], R300_PFS_INSTR2_0, inst2);
1933 OUTPUT_FIELD(fpi[3], R300_PFS_INSTR3_0, inst3);
1934 #undef OUTPUT_FIELD
1935
1936 R300_STATECHANGE(rmesa, fp);
1937 /* I just want to say, the way these nodes are stored.. weird.. */
1938 for (i = 0, k = (4 - (fp->cur_node + 1)); i < 4; i++, k++) {
1939 if (i < (fp->cur_node + 1)) {
1940 rmesa->hw.fp.cmd[R300_FP_NODE0 + k] =
1941 (fp->node[i].
1942 alu_offset << R300_PFS_NODE_ALU_OFFSET_SHIFT)
1943 | (fp->node[i].
1944 alu_end << R300_PFS_NODE_ALU_END_SHIFT)
1945 | (fp->node[i].
1946 tex_offset << R300_PFS_NODE_TEX_OFFSET_SHIFT)
1947 | (fp->node[i].
1948 tex_end << R300_PFS_NODE_TEX_END_SHIFT)
1949 | fp->node[i].flags; /* ( (k==3) ? R300_PFS_NODE_LAST_NODE : 0); */
1950 } else {
1951 rmesa->hw.fp.cmd[R300_FP_NODE0 + (3 - i)] = 0;
1952 }
1953 }
1954
1955 /* PFS_CNTL_0 */
1956 rmesa->hw.fp.cmd[R300_FP_CNTL0] =
1957 fp->cur_node | (fp->first_node_has_tex << 3);
1958 /* PFS_CNTL_1 */
1959 rmesa->hw.fp.cmd[R300_FP_CNTL1] = fp->max_temp_idx;
1960 /* PFS_CNTL_2 */
1961 rmesa->hw.fp.cmd[R300_FP_CNTL2] =
1962 (fp->alu_offset << R300_PFS_CNTL_ALU_OFFSET_SHIFT)
1963 | (fp->alu_end << R300_PFS_CNTL_ALU_END_SHIFT)
1964 | (fp->tex_offset << R300_PFS_CNTL_TEX_OFFSET_SHIFT)
1965 | (fp->tex_end << R300_PFS_CNTL_TEX_END_SHIFT);
1966
1967 R300_STATECHANGE(rmesa, fpp);
1968 for (i = 0; i < fp->const_nr; i++) {
1969 rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 0] =
1970 r300PackFloat24(fp->constant[i][0]);
1971 rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 1] =
1972 r300PackFloat24(fp->constant[i][1]);
1973 rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 2] =
1974 r300PackFloat24(fp->constant[i][2]);
1975 rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 3] =
1976 r300PackFloat24(fp->constant[i][3]);
1977 }
1978 rmesa->hw.fpp.cmd[R300_FPP_CMD_0] =
1979 cmdpacket0(R300_PFS_PARAM_0_X, fp->const_nr * 4);
1980 }
1981
1982 /**
1983 * Called by Mesa after an internal state update.
1984 */
1985 static void r300InvalidateState(GLcontext * ctx, GLuint new_state)
1986 {
1987 r300ContextPtr r300 = R300_CONTEXT(ctx);
1988
1989 _swrast_InvalidateState(ctx, new_state);
1990 _swsetup_InvalidateState(ctx, new_state);
1991 _vbo_InvalidateState(ctx, new_state);
1992 _tnl_InvalidateState(ctx, new_state);
1993 _ae_invalidate_state(ctx, new_state);
1994
1995 if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) {
1996 r300UpdateDrawBuffer(ctx);
1997 }
1998
1999 r300UpdateStateParameters(ctx, new_state);
2000
2001 r300->NewGLState |= new_state;
2002 }
2003
2004 /**
2005 * Completely recalculates hardware state based on the Mesa state.
2006 */
2007 void r300ResetHwState(r300ContextPtr r300)
2008 {
2009 GLcontext *ctx = r300->radeon.glCtx;
2010 int has_tcl = 1;
2011
2012 if (!(r300->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL))
2013 has_tcl = 0;
2014
2015 if (RADEON_DEBUG & DEBUG_STATE)
2016 fprintf(stderr, "%s\n", __FUNCTION__);
2017
2018 /* This is a place to initialize registers which
2019 have bitfields accessed by different functions
2020 and not all bits are used */
2021
2022 /* go and compute register values from GL state */
2023
2024 r300UpdateWindow(ctx);
2025
2026 r300ColorMask(ctx,
2027 ctx->Color.ColorMask[RCOMP],
2028 ctx->Color.ColorMask[GCOMP],
2029 ctx->Color.ColorMask[BCOMP], ctx->Color.ColorMask[ACOMP]);
2030
2031 r300Enable(ctx, GL_DEPTH_TEST, ctx->Depth.Test);
2032 r300DepthMask(ctx, ctx->Depth.Mask);
2033 r300DepthFunc(ctx, ctx->Depth.Func);
2034
2035 /* stencil */
2036 r300Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled);
2037 r300StencilMaskSeparate(ctx, 0, ctx->Stencil.WriteMask[0]);
2038 r300StencilFuncSeparate(ctx, 0, ctx->Stencil.Function[0],
2039 ctx->Stencil.Ref[0], ctx->Stencil.ValueMask[0]);
2040 r300StencilOpSeparate(ctx, 0, ctx->Stencil.FailFunc[0],
2041 ctx->Stencil.ZFailFunc[0],
2042 ctx->Stencil.ZPassFunc[0]);
2043
2044 r300UpdateCulling(ctx);
2045
2046 r300UpdateTextureState(ctx);
2047
2048 r300SetBlendState(ctx);
2049
2050 r300AlphaFunc(ctx, ctx->Color.AlphaFunc, ctx->Color.AlphaRef);
2051 r300Enable(ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled);
2052
2053 /* Initialize magic registers
2054 TODO : learn what they really do, or get rid of
2055 those we don't have to touch */
2056 if (!has_tcl)
2057 r300->hw.vap_cntl.cmd[1] = 0x0014045a;
2058 else
2059 r300->hw.vap_cntl.cmd[1] = 0x0030045A; //0x0030065a /* Dangerous */
2060 r300->hw.vte.cmd[1] = R300_VPORT_X_SCALE_ENA
2061 | R300_VPORT_X_OFFSET_ENA
2062 | R300_VPORT_Y_SCALE_ENA
2063 | R300_VPORT_Y_OFFSET_ENA
2064 | R300_VPORT_Z_SCALE_ENA
2065 | R300_VPORT_Z_OFFSET_ENA | R300_VTX_W0_FMT;
2066 r300->hw.vte.cmd[2] = 0x00000008;
2067
2068 r300->hw.unk2134.cmd[1] = 0x00FFFFFF;
2069 r300->hw.unk2134.cmd[2] = 0x00000000;
2070 if (_mesa_little_endian())
2071 r300->hw.vap_cntl_status.cmd[1] = R300_VC_NO_SWAP;
2072 else
2073 r300->hw.vap_cntl_status.cmd[1] = R300_VC_32BIT_SWAP;
2074
2075 /* disable VAP/TCL on non-TCL capable chips */
2076 if (!has_tcl)
2077 r300->hw.vap_cntl_status.cmd[1] |= R300_VAP_TCL_BYPASS;
2078
2079 r300->hw.unk21DC.cmd[1] = 0xAAAAAAAA;
2080
2081 r300->hw.unk221C.cmd[1] = R300_221C_NORMAL;
2082
2083 r300->hw.unk2220.cmd[1] = r300PackFloat32(1.0);
2084 r300->hw.unk2220.cmd[2] = r300PackFloat32(1.0);
2085 r300->hw.unk2220.cmd[3] = r300PackFloat32(1.0);
2086 r300->hw.unk2220.cmd[4] = r300PackFloat32(1.0);
2087
2088 /* what about other chips than r300 or rv350??? */
2089 if (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_R300)
2090 r300->hw.unk2288.cmd[1] = R300_2288_R300;
2091 else
2092 r300->hw.unk2288.cmd[1] = R300_2288_RV350;
2093
2094 r300->hw.gb_enable.cmd[1] = R300_GB_POINT_STUFF_ENABLE
2095 | R300_GB_LINE_STUFF_ENABLE
2096 | R300_GB_TRIANGLE_STUFF_ENABLE /*| R300_GB_UNK31 */ ;
2097
2098 r300->hw.gb_misc.cmd[R300_GB_MISC_MSPOS_0] = 0x66666666;
2099 r300->hw.gb_misc.cmd[R300_GB_MISC_MSPOS_1] = 0x06666666;
2100 if ((r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_R300) ||
2101 (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_R350))
2102 r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] =
2103 R300_GB_TILE_ENABLE | R300_GB_TILE_PIPE_COUNT_R300 |
2104 R300_GB_TILE_SIZE_16;
2105 else if (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV410)
2106 r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] =
2107 R300_GB_TILE_ENABLE | R300_GB_TILE_PIPE_COUNT_RV410 |
2108 R300_GB_TILE_SIZE_16;
2109 else if (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_R420)
2110 r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] =
2111 R300_GB_TILE_ENABLE | R300_GB_TILE_PIPE_COUNT_R420 |
2112 R300_GB_TILE_SIZE_16;
2113 else
2114 r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] =
2115 R300_GB_TILE_ENABLE | R300_GB_TILE_PIPE_COUNT_RV300 |
2116 R300_GB_TILE_SIZE_16;
2117 /* set to 0 when fog is disabled? */
2118 r300->hw.gb_misc.cmd[R300_GB_MISC_SELECT] = R300_GB_FOG_SELECT_1_1_W;
2119 r300->hw.gb_misc.cmd[R300_GB_MISC_AA_CONFIG] = R300_AA_DISABLE; /* No antialiasing */
2120
2121 r300->hw.unk4200.cmd[1] = r300PackFloat32(0.0);
2122 r300->hw.unk4200.cmd[2] = r300PackFloat32(0.0);
2123 r300->hw.unk4200.cmd[3] = r300PackFloat32(1.0);
2124 r300->hw.unk4200.cmd[4] = r300PackFloat32(1.0);
2125
2126 r300->hw.unk4214.cmd[1] = 0x00050005;
2127
2128 r300PointSize(ctx, 0.0);
2129
2130 r300->hw.unk4230.cmd[1] = 0x18000006;
2131 r300->hw.unk4230.cmd[2] = 0x00020006;
2132 r300->hw.unk4230.cmd[3] = r300PackFloat32(1.0 / 192.0);
2133
2134 r300LineWidth(ctx, 0.0);
2135
2136 r300->hw.unk4260.cmd[1] = 0;
2137 r300->hw.unk4260.cmd[2] = r300PackFloat32(0.0);
2138 r300->hw.unk4260.cmd[3] = r300PackFloat32(1.0);
2139
2140 r300->hw.shade.cmd[1] = 0x00000002;
2141 r300ShadeModel(ctx, ctx->Light.ShadeModel);
2142 r300->hw.shade.cmd[3] = 0x00000000;
2143 r300->hw.shade.cmd[4] = 0x00000000;
2144
2145 r300PolygonMode(ctx, GL_FRONT, ctx->Polygon.FrontMode);
2146 r300PolygonMode(ctx, GL_BACK, ctx->Polygon.BackMode);
2147 r300->hw.polygon_mode.cmd[2] = 0x00000001;
2148 r300->hw.polygon_mode.cmd[3] = 0x00000000;
2149 r300->hw.zbias_cntl.cmd[1] = 0x00000000;
2150
2151 r300PolygonOffset(ctx, ctx->Polygon.OffsetFactor,
2152 ctx->Polygon.OffsetUnits);
2153 r300Enable(ctx, GL_POLYGON_OFFSET_FILL, ctx->Polygon.OffsetFill);
2154
2155 r300->hw.unk42C0.cmd[1] = 0x4B7FFFFF;
2156 r300->hw.unk42C0.cmd[2] = 0x00000000;
2157
2158 r300->hw.unk43A4.cmd[1] = 0x0000001C;
2159 r300->hw.unk43A4.cmd[2] = 0x2DA49525;
2160
2161 r300->hw.unk43E8.cmd[1] = 0x00FFFFFF;
2162
2163 r300->hw.unk46A4.cmd[1] = 0x00001B01;
2164 r300->hw.unk46A4.cmd[2] = 0x00001B0F;
2165 r300->hw.unk46A4.cmd[3] = 0x00001B0F;
2166 r300->hw.unk46A4.cmd[4] = 0x00001B0F;
2167 r300->hw.unk46A4.cmd[5] = 0x00000001;
2168
2169 r300Enable(ctx, GL_FOG, ctx->Fog.Enabled);
2170 ctx->Driver.Fogfv(ctx, GL_FOG_MODE, NULL);
2171 ctx->Driver.Fogfv(ctx, GL_FOG_DENSITY, &ctx->Fog.Density);
2172 ctx->Driver.Fogfv(ctx, GL_FOG_START, &ctx->Fog.Start);
2173 ctx->Driver.Fogfv(ctx, GL_FOG_END, &ctx->Fog.End);
2174 ctx->Driver.Fogfv(ctx, GL_FOG_COLOR, ctx->Fog.Color);
2175 ctx->Driver.Fogfv(ctx, GL_FOG_COORDINATE_SOURCE_EXT, NULL);
2176
2177 r300->hw.at.cmd[R300_AT_UNKNOWN] = 0;
2178 r300->hw.unk4BD8.cmd[1] = 0;
2179
2180 r300->hw.unk4E00.cmd[1] = 0;
2181
2182 r300BlendColor(ctx, ctx->Color.BlendColor);
2183 r300->hw.blend_color.cmd[2] = 0;
2184 r300->hw.blend_color.cmd[3] = 0;
2185
2186 /* Again, r300ClearBuffer uses this */
2187 r300->hw.cb.cmd[R300_CB_OFFSET] =
2188 r300->radeon.state.color.drawOffset +
2189 r300->radeon.radeonScreen->fbLocation;
2190 r300->hw.cb.cmd[R300_CB_PITCH] = r300->radeon.state.color.drawPitch;
2191
2192 if (r300->radeon.radeonScreen->cpp == 4)
2193 r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_FORMAT_ARGB8888;
2194 else
2195 r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_FORMAT_RGB565;
2196
2197 if (r300->radeon.sarea->tiling_enabled)
2198 r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_TILE_ENABLE;
2199
2200 r300->hw.unk4E50.cmd[1] = 0;
2201 r300->hw.unk4E50.cmd[2] = 0;
2202 r300->hw.unk4E50.cmd[3] = 0;
2203 r300->hw.unk4E50.cmd[4] = 0;
2204 r300->hw.unk4E50.cmd[5] = 0;
2205 r300->hw.unk4E50.cmd[6] = 0;
2206 r300->hw.unk4E50.cmd[7] = 0;
2207 r300->hw.unk4E50.cmd[8] = 0;
2208 r300->hw.unk4E50.cmd[9] = 0;
2209
2210 r300->hw.unk4E88.cmd[1] = 0;
2211
2212 r300->hw.unk4EA0.cmd[1] = 0x00000000;
2213 r300->hw.unk4EA0.cmd[2] = 0xffffffff;
2214
2215 switch (ctx->Visual.depthBits) {
2216 case 16:
2217 r300->hw.zstencil_format.cmd[1] = R300_DEPTH_FORMAT_16BIT_INT_Z;
2218 break;
2219 case 24:
2220 r300->hw.zstencil_format.cmd[1] = R300_DEPTH_FORMAT_24BIT_INT_Z;
2221 break;
2222 default:
2223 fprintf(stderr, "Error: Unsupported depth %d... exiting\n",
2224 ctx->Visual.depthBits);
2225 _mesa_exit(-1);
2226
2227 }
2228 /* z compress? */
2229 //r300->hw.zstencil_format.cmd[1] |= R300_DEPTH_FORMAT_UNK32;
2230
2231 r300->hw.zstencil_format.cmd[3] = 0x00000003;
2232 r300->hw.zstencil_format.cmd[4] = 0x00000000;
2233
2234 r300->hw.zb.cmd[R300_ZB_OFFSET] =
2235 r300->radeon.radeonScreen->depthOffset +
2236 r300->radeon.radeonScreen->fbLocation;
2237 r300->hw.zb.cmd[R300_ZB_PITCH] = r300->radeon.radeonScreen->depthPitch;
2238
2239 if (r300->radeon.sarea->tiling_enabled) {
2240 /* Turn off when clearing buffers ? */
2241 r300->hw.zb.cmd[R300_ZB_PITCH] |= R300_DEPTH_TILE_ENABLE;
2242
2243 if (ctx->Visual.depthBits == 24)
2244 r300->hw.zb.cmd[R300_ZB_PITCH] |=
2245 R300_DEPTH_MICROTILE_ENABLE;
2246 }
2247
2248 r300->hw.unk4F28.cmd[1] = 0;
2249
2250 r300->hw.unk4F30.cmd[1] = 0;
2251 r300->hw.unk4F30.cmd[2] = 0;
2252
2253 r300->hw.unk4F44.cmd[1] = 0;
2254
2255 r300->hw.unk4F54.cmd[1] = 0;
2256
2257 if (has_tcl) {
2258 r300->hw.vps.cmd[R300_VPS_ZERO_0] = 0;
2259 r300->hw.vps.cmd[R300_VPS_ZERO_1] = 0;
2260 r300->hw.vps.cmd[R300_VPS_POINTSIZE] = r300PackFloat32(1.0);
2261 r300->hw.vps.cmd[R300_VPS_ZERO_3] = 0;
2262 }
2263 //END: TODO
2264 r300->hw.all_dirty = GL_TRUE;
2265 }
2266
2267 /**
2268 * Calculate initial hardware state and register state functions.
2269 * Assumes that the command buffer and state atoms have been
2270 * initialized already.
2271 */
2272 void r300InitState(r300ContextPtr r300)
2273 {
2274 GLcontext *ctx = r300->radeon.glCtx;
2275 GLuint depth_fmt;
2276
2277 radeonInitState(&r300->radeon);
2278
2279 switch (ctx->Visual.depthBits) {
2280 case 16:
2281 r300->state.depth.scale = 1.0 / (GLfloat) 0xffff;
2282 depth_fmt = R300_DEPTH_FORMAT_16BIT_INT_Z;
2283 r300->state.stencil.clear = 0x00000000;
2284 break;
2285 case 24:
2286 r300->state.depth.scale = 1.0 / (GLfloat) 0xffffff;
2287 depth_fmt = R300_DEPTH_FORMAT_24BIT_INT_Z;
2288 r300->state.stencil.clear = 0x00ff0000;
2289 break;
2290 default:
2291 fprintf(stderr, "Error: Unsupported depth %d... exiting\n",
2292 ctx->Visual.depthBits);
2293 _mesa_exit(-1);
2294 }
2295
2296 /* Only have hw stencil when depth buffer is 24 bits deep */
2297 r300->state.stencil.hw_stencil = (ctx->Visual.stencilBits > 0 &&
2298 ctx->Visual.depthBits == 24);
2299
2300 memset(&(r300->state.texture), 0, sizeof(r300->state.texture));
2301
2302 r300ResetHwState(r300);
2303 }
2304
2305 static void r300RenderMode(GLcontext * ctx, GLenum mode)
2306 {
2307 r300ContextPtr rmesa = R300_CONTEXT(ctx);
2308 (void)rmesa;
2309 (void)mode;
2310 }
2311
2312 /**
2313 * Initialize driver's state callback functions
2314 */
2315 void r300InitStateFuncs(struct dd_function_table *functions)
2316 {
2317 radeonInitStateFuncs(functions);
2318
2319 functions->UpdateState = r300InvalidateState;
2320 functions->AlphaFunc = r300AlphaFunc;
2321 functions->BlendColor = r300BlendColor;
2322 functions->BlendEquationSeparate = r300BlendEquationSeparate;
2323 functions->BlendFuncSeparate = r300BlendFuncSeparate;
2324 functions->Enable = r300Enable;
2325 functions->ColorMask = r300ColorMask;
2326 functions->DepthFunc = r300DepthFunc;
2327 functions->DepthMask = r300DepthMask;
2328 functions->CullFace = r300CullFace;
2329 functions->Fogfv = r300Fogfv;
2330 functions->FrontFace = r300FrontFace;
2331 functions->ShadeModel = r300ShadeModel;
2332
2333 /* Stencil related */
2334 functions->ClearStencil = r300ClearStencil;
2335 functions->StencilFuncSeparate = r300StencilFuncSeparate;
2336 functions->StencilMaskSeparate = r300StencilMaskSeparate;
2337 functions->StencilOpSeparate = r300StencilOpSeparate;
2338
2339 /* Viewport related */
2340 functions->Viewport = r300Viewport;
2341 functions->DepthRange = r300DepthRange;
2342 functions->PointSize = r300PointSize;
2343 functions->LineWidth = r300LineWidth;
2344
2345 functions->PolygonOffset = r300PolygonOffset;
2346 functions->PolygonMode = r300PolygonMode;
2347
2348 functions->RenderMode = r300RenderMode;
2349 }