r500: default rsunit swizzle like fglrx
[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 * \file
34 *
35 * \author Nicolai Haehnle <prefect_@gmx.net>
36 */
37
38 #include "glheader.h"
39 #include "state.h"
40 #include "imports.h"
41 #include "enums.h"
42 #include "macros.h"
43 #include "context.h"
44 #include "dd.h"
45 #include "simple_list.h"
46
47 #include "api_arrayelt.h"
48 #include "swrast/swrast.h"
49 #include "swrast_setup/swrast_setup.h"
50 #include "shader/prog_parameter.h"
51 #include "shader/prog_statevars.h"
52 #include "vbo/vbo.h"
53 #include "tnl/tnl.h"
54 #include "texformat.h"
55
56 #include "radeon_ioctl.h"
57 #include "radeon_state.h"
58 #include "r300_context.h"
59 #include "r300_ioctl.h"
60 #include "r300_state.h"
61 #include "r300_reg.h"
62 #include "r300_emit.h"
63 #include "r300_fragprog.h"
64 #include "r300_tex.h"
65
66 #include "drirenderbuffer.h"
67
68 extern int future_hw_tcl_on;
69 extern void _tnl_UpdateFixedFunctionProgram(GLcontext * ctx);
70
71 static void r300BlendColor(GLcontext * ctx, const GLfloat cf[4])
72 {
73 GLubyte color[4];
74 r300ContextPtr rmesa = R300_CONTEXT(ctx);
75
76 R300_STATECHANGE(rmesa, blend_color);
77
78 CLAMPED_FLOAT_TO_UBYTE(color[0], cf[0]);
79 CLAMPED_FLOAT_TO_UBYTE(color[1], cf[1]);
80 CLAMPED_FLOAT_TO_UBYTE(color[2], cf[2]);
81 CLAMPED_FLOAT_TO_UBYTE(color[3], cf[3]);
82
83 rmesa->hw.blend_color.cmd[1] = PACK_COLOR_8888(color[3], color[0],
84 color[1], color[2]);
85 rmesa->hw.blend_color.cmd[2] = 0;
86 rmesa->hw.blend_color.cmd[3] = 0;
87 }
88
89 /**
90 * Calculate the hardware blend factor setting. This same function is used
91 * for source and destination of both alpha and RGB.
92 *
93 * \returns
94 * The hardware register value for the specified blend factor. This value
95 * will need to be shifted into the correct position for either source or
96 * destination factor.
97 *
98 * \todo
99 * Since the two cases where source and destination are handled differently
100 * are essentially error cases, they should never happen. Determine if these
101 * cases can be removed.
102 */
103 static int blend_factor(GLenum factor, GLboolean is_src)
104 {
105 switch (factor) {
106 case GL_ZERO:
107 return R300_BLEND_GL_ZERO;
108 break;
109 case GL_ONE:
110 return R300_BLEND_GL_ONE;
111 break;
112 case GL_DST_COLOR:
113 return R300_BLEND_GL_DST_COLOR;
114 break;
115 case GL_ONE_MINUS_DST_COLOR:
116 return R300_BLEND_GL_ONE_MINUS_DST_COLOR;
117 break;
118 case GL_SRC_COLOR:
119 return R300_BLEND_GL_SRC_COLOR;
120 break;
121 case GL_ONE_MINUS_SRC_COLOR:
122 return R300_BLEND_GL_ONE_MINUS_SRC_COLOR;
123 break;
124 case GL_SRC_ALPHA:
125 return R300_BLEND_GL_SRC_ALPHA;
126 break;
127 case GL_ONE_MINUS_SRC_ALPHA:
128 return R300_BLEND_GL_ONE_MINUS_SRC_ALPHA;
129 break;
130 case GL_DST_ALPHA:
131 return R300_BLEND_GL_DST_ALPHA;
132 break;
133 case GL_ONE_MINUS_DST_ALPHA:
134 return R300_BLEND_GL_ONE_MINUS_DST_ALPHA;
135 break;
136 case GL_SRC_ALPHA_SATURATE:
137 return (is_src) ? R300_BLEND_GL_SRC_ALPHA_SATURATE :
138 R300_BLEND_GL_ZERO;
139 break;
140 case GL_CONSTANT_COLOR:
141 return R300_BLEND_GL_CONST_COLOR;
142 break;
143 case GL_ONE_MINUS_CONSTANT_COLOR:
144 return R300_BLEND_GL_ONE_MINUS_CONST_COLOR;
145 break;
146 case GL_CONSTANT_ALPHA:
147 return R300_BLEND_GL_CONST_ALPHA;
148 break;
149 case GL_ONE_MINUS_CONSTANT_ALPHA:
150 return R300_BLEND_GL_ONE_MINUS_CONST_ALPHA;
151 break;
152 default:
153 fprintf(stderr, "unknown blend factor %x\n", factor);
154 return (is_src) ? R300_BLEND_GL_ONE : R300_BLEND_GL_ZERO;
155 break;
156 }
157 }
158
159 /**
160 * Sets both the blend equation and the blend function.
161 * This is done in a single
162 * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX)
163 * change the interpretation of the blend function.
164 * Also, make sure that blend function and blend equation are set to their
165 * default value if color blending is not enabled, since at least blend
166 * equations GL_MIN and GL_FUNC_REVERSE_SUBTRACT will cause wrong results
167 * otherwise for unknown reasons.
168 */
169
170 /* helper function */
171 static void r300SetBlendCntl(r300ContextPtr r300, int func, int eqn,
172 int cbits, int funcA, int eqnA)
173 {
174 GLuint new_ablend, new_cblend;
175
176 #if 0
177 fprintf(stderr,
178 "eqnA=%08x funcA=%08x eqn=%08x func=%08x cbits=%08x\n",
179 eqnA, funcA, eqn, func, cbits);
180 #endif
181 new_ablend = eqnA | funcA;
182 new_cblend = eqn | func;
183
184 /* Some blend factor combinations don't seem to work when the
185 * BLEND_NO_SEPARATE bit is set.
186 *
187 * Especially problematic candidates are the ONE_MINUS_* flags,
188 * but I can't see a real pattern.
189 */
190 #if 0
191 if (new_ablend == new_cblend) {
192 new_cblend |= R300_DISCARD_SRC_PIXELS_SRC_ALPHA_0;
193 }
194 #endif
195 new_cblend |= cbits;
196
197 if ((new_ablend != r300->hw.bld.cmd[R300_BLD_ABLEND]) ||
198 (new_cblend != r300->hw.bld.cmd[R300_BLD_CBLEND])) {
199 R300_STATECHANGE(r300, bld);
200 r300->hw.bld.cmd[R300_BLD_ABLEND] = new_ablend;
201 r300->hw.bld.cmd[R300_BLD_CBLEND] = new_cblend;
202 }
203 }
204
205 static void r300SetBlendState(GLcontext * ctx)
206 {
207 r300ContextPtr r300 = R300_CONTEXT(ctx);
208 int func = (R300_BLEND_GL_ONE << R300_SRC_BLEND_SHIFT) |
209 (R300_BLEND_GL_ZERO << R300_DST_BLEND_SHIFT);
210 int eqn = R300_COMB_FCN_ADD_CLAMP;
211 int funcA = (R300_BLEND_GL_ONE << R300_SRC_BLEND_SHIFT) |
212 (R300_BLEND_GL_ZERO << R300_DST_BLEND_SHIFT);
213 int eqnA = R300_COMB_FCN_ADD_CLAMP;
214
215 if (RGBA_LOGICOP_ENABLED(ctx) || !ctx->Color.BlendEnabled) {
216 r300SetBlendCntl(r300, func, eqn, 0, func, eqn);
217 return;
218 }
219
220 func =
221 (blend_factor(ctx->Color.BlendSrcRGB, GL_TRUE) <<
222 R300_SRC_BLEND_SHIFT) | (blend_factor(ctx->Color.BlendDstRGB,
223 GL_FALSE) <<
224 R300_DST_BLEND_SHIFT);
225
226 switch (ctx->Color.BlendEquationRGB) {
227 case GL_FUNC_ADD:
228 eqn = R300_COMB_FCN_ADD_CLAMP;
229 break;
230
231 case GL_FUNC_SUBTRACT:
232 eqn = R300_COMB_FCN_SUB_CLAMP;
233 break;
234
235 case GL_FUNC_REVERSE_SUBTRACT:
236 eqn = R300_COMB_FCN_RSUB_CLAMP;
237 break;
238
239 case GL_MIN:
240 eqn = R300_COMB_FCN_MIN;
241 func = (R300_BLEND_GL_ONE << R300_SRC_BLEND_SHIFT) |
242 (R300_BLEND_GL_ONE << R300_DST_BLEND_SHIFT);
243 break;
244
245 case GL_MAX:
246 eqn = R300_COMB_FCN_MAX;
247 func = (R300_BLEND_GL_ONE << R300_SRC_BLEND_SHIFT) |
248 (R300_BLEND_GL_ONE << R300_DST_BLEND_SHIFT);
249 break;
250
251 default:
252 fprintf(stderr,
253 "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
254 __FUNCTION__, __LINE__, ctx->Color.BlendEquationRGB);
255 return;
256 }
257
258 funcA =
259 (blend_factor(ctx->Color.BlendSrcA, GL_TRUE) <<
260 R300_SRC_BLEND_SHIFT) | (blend_factor(ctx->Color.BlendDstA,
261 GL_FALSE) <<
262 R300_DST_BLEND_SHIFT);
263
264 switch (ctx->Color.BlendEquationA) {
265 case GL_FUNC_ADD:
266 eqnA = R300_COMB_FCN_ADD_CLAMP;
267 break;
268
269 case GL_FUNC_SUBTRACT:
270 eqnA = R300_COMB_FCN_SUB_CLAMP;
271 break;
272
273 case GL_FUNC_REVERSE_SUBTRACT:
274 eqnA = R300_COMB_FCN_RSUB_CLAMP;
275 break;
276
277 case GL_MIN:
278 eqnA = R300_COMB_FCN_MIN;
279 funcA = (R300_BLEND_GL_ONE << R300_SRC_BLEND_SHIFT) |
280 (R300_BLEND_GL_ONE << R300_DST_BLEND_SHIFT);
281 break;
282
283 case GL_MAX:
284 eqnA = R300_COMB_FCN_MAX;
285 funcA = (R300_BLEND_GL_ONE << R300_SRC_BLEND_SHIFT) |
286 (R300_BLEND_GL_ONE << R300_DST_BLEND_SHIFT);
287 break;
288
289 default:
290 fprintf(stderr,
291 "[%s:%u] Invalid A blend equation (0x%04x).\n",
292 __FUNCTION__, __LINE__, ctx->Color.BlendEquationA);
293 return;
294 }
295
296 r300SetBlendCntl(r300,
297 func, eqn,
298 (R300_SEPARATE_ALPHA_ENABLE |
299 R300_READ_ENABLE |
300 R300_ALPHA_BLEND_ENABLE), funcA, eqnA);
301 }
302
303 static void r300BlendEquationSeparate(GLcontext * ctx,
304 GLenum modeRGB, GLenum modeA)
305 {
306 r300SetBlendState(ctx);
307 }
308
309 static void r300BlendFuncSeparate(GLcontext * ctx,
310 GLenum sfactorRGB, GLenum dfactorRGB,
311 GLenum sfactorA, GLenum dfactorA)
312 {
313 r300SetBlendState(ctx);
314 }
315
316 static void r300ClipPlane( GLcontext *ctx, GLenum plane, const GLfloat *eq )
317 {
318 r300ContextPtr rmesa = R300_CONTEXT(ctx);
319 GLint p;
320 GLint *ip;
321
322 /* no VAP UCP on non-TCL chipsets */
323 if (!(rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL))
324 return;
325
326 p = (GLint) plane - (GLint) GL_CLIP_PLANE0;
327 ip = (GLint *)ctx->Transform._ClipUserPlane[p];
328
329 R300_STATECHANGE( rmesa, vpucp[p] );
330 rmesa->hw.vpucp[p].cmd[R300_VPUCP_X] = ip[0];
331 rmesa->hw.vpucp[p].cmd[R300_VPUCP_Y] = ip[1];
332 rmesa->hw.vpucp[p].cmd[R300_VPUCP_Z] = ip[2];
333 rmesa->hw.vpucp[p].cmd[R300_VPUCP_W] = ip[3];
334 }
335
336 static void r300SetClipPlaneState(GLcontext * ctx, GLenum cap, GLboolean state)
337 {
338 r300ContextPtr r300 = R300_CONTEXT(ctx);
339 GLuint p;
340
341 /* no VAP UCP on non-TCL chipsets */
342 if (!(r300->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL))
343 return;
344
345 p = cap - GL_CLIP_PLANE0;
346 R300_STATECHANGE(r300, vap_clip_cntl);
347 if (state) {
348 r300->hw.vap_clip_cntl.cmd[1] |= (R300_VAP_UCP_ENABLE_0 << p);
349 r300ClipPlane(ctx, cap, NULL);
350 } else {
351 r300->hw.vap_clip_cntl.cmd[1] &= ~(R300_VAP_UCP_ENABLE_0 << p);
352 }
353 }
354
355 /**
356 * Update our tracked culling state based on Mesa's state.
357 */
358 static void r300UpdateCulling(GLcontext * ctx)
359 {
360 r300ContextPtr r300 = R300_CONTEXT(ctx);
361 uint32_t val = 0;
362
363 if (ctx->Polygon.CullFlag) {
364 switch (ctx->Polygon.CullFaceMode) {
365 case GL_FRONT:
366 val = R300_CULL_FRONT;
367 break;
368 case GL_BACK:
369 val = R300_CULL_BACK;
370 break;
371 case GL_FRONT_AND_BACK:
372 val = R300_CULL_FRONT | R300_CULL_BACK;
373 break;
374 default:
375 break;
376 }
377 }
378
379 switch (ctx->Polygon.FrontFace) {
380 case GL_CW:
381 val |= R300_FRONT_FACE_CW;
382 break;
383 case GL_CCW:
384 val |= R300_FRONT_FACE_CCW;
385 break;
386 default:
387 break;
388 }
389
390 R300_STATECHANGE(r300, cul);
391 r300->hw.cul.cmd[R300_CUL_CULL] = val;
392 }
393
394 static void r300SetPolygonOffsetState(GLcontext * ctx, GLboolean state)
395 {
396 r300ContextPtr r300 = R300_CONTEXT(ctx);
397
398 R300_STATECHANGE(r300, occlusion_cntl);
399 if (state) {
400 r300->hw.occlusion_cntl.cmd[1] |= (3 << 0);
401 } else {
402 r300->hw.occlusion_cntl.cmd[1] &= ~(3 << 0);
403 }
404 }
405
406 static void r300SetEarlyZState(GLcontext * ctx)
407 {
408 /* updates register R300_RB3D_EARLY_Z (0x4F14)
409 if depth test is not enabled it should be R300_EARLY_Z_DISABLE
410 if depth is enabled and alpha not it should be R300_EARLY_Z_ENABLE
411 if depth and alpha is enabled it should be R300_EARLY_Z_DISABLE
412 */
413 r300ContextPtr r300 = R300_CONTEXT(ctx);
414
415 R300_STATECHANGE(r300, zstencil_format);
416 switch (ctx->Visual.depthBits) {
417 case 16:
418 r300->hw.zstencil_format.cmd[1] = R300_DEPTHFORMAT_16BIT_INT_Z;
419 break;
420 case 24:
421 r300->hw.zstencil_format.cmd[1] = R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL;
422 break;
423 default:
424 fprintf(stderr, "Error: Unsupported depth %d... exiting\n", ctx->Visual.depthBits);
425 _mesa_exit(-1);
426 }
427
428 if (ctx->Color.AlphaEnabled && ctx->Color.AlphaFunc != GL_ALWAYS)
429 /* disable early Z */
430 r300->hw.zstencil_format.cmd[2] = R300_ZTOP_DISABLE;
431 else {
432 if (ctx->Depth.Test && ctx->Depth.Func != GL_NEVER)
433 /* enable early Z */
434 r300->hw.zstencil_format.cmd[2] = R300_ZTOP_ENABLE;
435 else
436 /* disable early Z */
437 r300->hw.zstencil_format.cmd[2] = R300_ZTOP_DISABLE;
438 }
439
440 r300->hw.zstencil_format.cmd[3] = 0x00000003;
441 r300->hw.zstencil_format.cmd[4] = 0x00000000;
442 }
443
444 static void r300SetAlphaState(GLcontext * ctx)
445 {
446 r300ContextPtr r300 = R300_CONTEXT(ctx);
447 GLubyte refByte;
448 uint32_t pp_misc = 0x0;
449 GLboolean really_enabled = ctx->Color.AlphaEnabled;
450
451 CLAMPED_FLOAT_TO_UBYTE(refByte, ctx->Color.AlphaRef);
452
453 switch (ctx->Color.AlphaFunc) {
454 case GL_NEVER:
455 pp_misc |= R300_FG_ALPHA_FUNC_NEVER;
456 break;
457 case GL_LESS:
458 pp_misc |= R300_FG_ALPHA_FUNC_LESS;
459 break;
460 case GL_EQUAL:
461 pp_misc |= R300_FG_ALPHA_FUNC_EQUAL;
462 break;
463 case GL_LEQUAL:
464 pp_misc |= R300_FG_ALPHA_FUNC_LE;
465 break;
466 case GL_GREATER:
467 pp_misc |= R300_FG_ALPHA_FUNC_GREATER;
468 break;
469 case GL_NOTEQUAL:
470 pp_misc |= R300_FG_ALPHA_FUNC_NOTEQUAL;
471 break;
472 case GL_GEQUAL:
473 pp_misc |= R300_FG_ALPHA_FUNC_GE;
474 break;
475 case GL_ALWAYS:
476 /*pp_misc |= FG_ALPHA_FUNC_ALWAYS; */
477 really_enabled = GL_FALSE;
478 break;
479 }
480
481 if (really_enabled) {
482 pp_misc |= R300_FG_ALPHA_FUNC_ENABLE;
483 pp_misc |= (refByte & R300_FG_ALPHA_FUNC_VAL_MASK);
484 } else {
485 pp_misc = 0x0;
486 }
487
488 R300_STATECHANGE(r300, at);
489 r300->hw.at.cmd[R300_AT_ALPHA_TEST] = pp_misc;
490 r300->hw.at.cmd[R300_AT_UNKNOWN] = 0;
491
492 r300SetEarlyZState(ctx);
493 }
494
495 static void r300AlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref)
496 {
497 (void)func;
498 (void)ref;
499 r300SetAlphaState(ctx);
500 }
501
502 static int translate_func(int func)
503 {
504 switch (func) {
505 case GL_NEVER:
506 return R300_ZS_NEVER;
507 case GL_LESS:
508 return R300_ZS_LESS;
509 case GL_EQUAL:
510 return R300_ZS_EQUAL;
511 case GL_LEQUAL:
512 return R300_ZS_LEQUAL;
513 case GL_GREATER:
514 return R300_ZS_GREATER;
515 case GL_NOTEQUAL:
516 return R300_ZS_NOTEQUAL;
517 case GL_GEQUAL:
518 return R300_ZS_GEQUAL;
519 case GL_ALWAYS:
520 return R300_ZS_ALWAYS;
521 }
522 return 0;
523 }
524
525 static void r300SetDepthState(GLcontext * ctx)
526 {
527 r300ContextPtr r300 = R300_CONTEXT(ctx);
528
529 R300_STATECHANGE(r300, zs);
530 r300->hw.zs.cmd[R300_ZS_CNTL_0] &= R300_STENCIL_ENABLE; // XXX
531 r300->hw.zs.cmd[R300_ZS_CNTL_1] &=
532 ~(R300_ZS_MASK << R300_Z_FUNC_SHIFT);
533
534 if (ctx->Depth.Test && ctx->Depth.Func != GL_NEVER) {
535 if (ctx->Depth.Mask)
536 r300->hw.zs.cmd[R300_ZS_CNTL_0] |=
537 R300_Z_ENABLE | R300_Z_WRITE_ENABLE | R300_STENCIL_FRONT_BACK; // XXX
538 else
539 r300->hw.zs.cmd[R300_ZS_CNTL_0] |= R300_Z_ENABLE | R300_STENCIL_FRONT_BACK; // XXX
540
541 r300->hw.zs.cmd[R300_ZS_CNTL_1] |=
542 translate_func(ctx->Depth.
543 Func) << R300_Z_FUNC_SHIFT;
544 } else {
545 r300->hw.zs.cmd[R300_ZS_CNTL_0] |= R300_STENCIL_FRONT_BACK; // XXX
546 r300->hw.zs.cmd[R300_ZS_CNTL_1] |=
547 translate_func(GL_NEVER) << R300_Z_FUNC_SHIFT;
548 }
549
550 r300SetEarlyZState(ctx);
551 }
552
553 static void r300SetStencilState(GLcontext * ctx, GLboolean state)
554 {
555 r300ContextPtr r300 = R300_CONTEXT(ctx);
556
557 if (r300->state.stencil.hw_stencil) {
558 R300_STATECHANGE(r300, zs);
559 if (state) {
560 r300->hw.zs.cmd[R300_ZS_CNTL_0] |=
561 R300_STENCIL_ENABLE;
562 } else {
563 r300->hw.zs.cmd[R300_ZS_CNTL_0] &=
564 ~R300_STENCIL_ENABLE;
565 }
566 } else {
567 #if R200_MERGED
568 FALLBACK(&r300->radeon, RADEON_FALLBACK_STENCIL, state);
569 #endif
570 }
571 }
572
573 static void r300UpdatePolygonMode(GLcontext * ctx)
574 {
575 r300ContextPtr r300 = R300_CONTEXT(ctx);
576 uint32_t hw_mode = R300_GA_POLY_MODE_DISABLE;
577
578 /* Only do something if a polygon mode is wanted, default is GL_FILL */
579 if (ctx->Polygon.FrontMode != GL_FILL ||
580 ctx->Polygon.BackMode != GL_FILL) {
581 GLenum f, b;
582
583 /* Handle GL_CW (clock wise and GL_CCW (counter clock wise)
584 * correctly by selecting the correct front and back face
585 */
586 if (ctx->Polygon.FrontFace == GL_CCW) {
587 f = ctx->Polygon.FrontMode;
588 b = ctx->Polygon.BackMode;
589 } else {
590 f = ctx->Polygon.BackMode;
591 b = ctx->Polygon.FrontMode;
592 }
593
594 /* Enable polygon mode */
595 hw_mode |= R300_GA_POLY_MODE_DUAL;
596
597 switch (f) {
598 case GL_LINE:
599 hw_mode |= R300_GA_POLY_MODE_FRONT_PTYPE_LINE;
600 break;
601 case GL_POINT:
602 hw_mode |= R300_GA_POLY_MODE_FRONT_PTYPE_POINT;
603 break;
604 case GL_FILL:
605 hw_mode |= R300_GA_POLY_MODE_FRONT_PTYPE_TRI;
606 break;
607 }
608
609 switch (b) {
610 case GL_LINE:
611 hw_mode |= R300_GA_POLY_MODE_BACK_PTYPE_LINE;
612 break;
613 case GL_POINT:
614 hw_mode |= R300_GA_POLY_MODE_BACK_PTYPE_POINT;
615 break;
616 case GL_FILL:
617 hw_mode |= R300_GA_POLY_MODE_BACK_PTYPE_TRI;
618 break;
619 }
620 }
621
622 if (r300->hw.polygon_mode.cmd[1] != hw_mode) {
623 R300_STATECHANGE(r300, polygon_mode);
624 r300->hw.polygon_mode.cmd[1] = hw_mode;
625 }
626
627 r300->hw.polygon_mode.cmd[2] = 0x00000001;
628 r300->hw.polygon_mode.cmd[3] = 0x00000000;
629 }
630
631 /**
632 * Change the culling mode.
633 *
634 * \note Mesa already filters redundant calls to this function.
635 */
636 static void r300CullFace(GLcontext * ctx, GLenum mode)
637 {
638 (void)mode;
639
640 r300UpdateCulling(ctx);
641 }
642
643 /**
644 * Change the polygon orientation.
645 *
646 * \note Mesa already filters redundant calls to this function.
647 */
648 static void r300FrontFace(GLcontext * ctx, GLenum mode)
649 {
650 (void)mode;
651
652 r300UpdateCulling(ctx);
653 r300UpdatePolygonMode(ctx);
654 }
655
656 /**
657 * Change the depth testing function.
658 *
659 * \note Mesa already filters redundant calls to this function.
660 */
661 static void r300DepthFunc(GLcontext * ctx, GLenum func)
662 {
663 (void)func;
664 r300SetDepthState(ctx);
665 }
666
667 /**
668 * Enable/Disable depth writing.
669 *
670 * \note Mesa already filters redundant calls to this function.
671 */
672 static void r300DepthMask(GLcontext * ctx, GLboolean mask)
673 {
674 (void)mask;
675 r300SetDepthState(ctx);
676 }
677
678 /**
679 * Handle glColorMask()
680 */
681 static void r300ColorMask(GLcontext * ctx,
682 GLboolean r, GLboolean g, GLboolean b, GLboolean a)
683 {
684 r300ContextPtr r300 = R300_CONTEXT(ctx);
685 int mask = (r ? RB3D_COLOR_CHANNEL_MASK_RED_MASK0 : 0) |
686 (g ? RB3D_COLOR_CHANNEL_MASK_GREEN_MASK0 : 0) |
687 (b ? RB3D_COLOR_CHANNEL_MASK_BLUE_MASK0 : 0) |
688 (a ? RB3D_COLOR_CHANNEL_MASK_ALPHA_MASK0 : 0);
689
690 if (mask != r300->hw.cmk.cmd[R300_CMK_COLORMASK]) {
691 R300_STATECHANGE(r300, cmk);
692 r300->hw.cmk.cmd[R300_CMK_COLORMASK] = mask;
693 }
694 }
695
696 /* =============================================================
697 * Fog
698 */
699 static void r300Fogfv(GLcontext * ctx, GLenum pname, const GLfloat * param)
700 {
701 r300ContextPtr r300 = R300_CONTEXT(ctx);
702 union {
703 int i;
704 float f;
705 } fogScale, fogStart;
706
707 (void)param;
708
709 fogScale.i = r300->hw.fogp.cmd[R300_FOGP_SCALE];
710 fogStart.i = r300->hw.fogp.cmd[R300_FOGP_START];
711
712 switch (pname) {
713 case GL_FOG_MODE:
714 if (!ctx->Fog.Enabled)
715 return;
716 switch (ctx->Fog.Mode) {
717 case GL_LINEAR:
718 R300_STATECHANGE(r300, fogs);
719 r300->hw.fogs.cmd[R300_FOGS_STATE] =
720 (r300->hw.fogs.
721 cmd[R300_FOGS_STATE] & ~R300_FG_FOG_BLEND_FN_MASK) |
722 R300_FG_FOG_BLEND_FN_LINEAR;
723
724 if (ctx->Fog.Start == ctx->Fog.End) {
725 fogScale.f = -1.0;
726 fogStart.f = 1.0;
727 } else {
728 fogScale.f =
729 1.0 / (ctx->Fog.End - ctx->Fog.Start);
730 fogStart.f =
731 -ctx->Fog.Start / (ctx->Fog.End -
732 ctx->Fog.Start);
733 }
734 break;
735 case GL_EXP:
736 R300_STATECHANGE(r300, fogs);
737 r300->hw.fogs.cmd[R300_FOGS_STATE] =
738 (r300->hw.fogs.
739 cmd[R300_FOGS_STATE] & ~R300_FG_FOG_BLEND_FN_MASK) |
740 R300_FG_FOG_BLEND_FN_EXP;
741 fogScale.f = 0.0933 * ctx->Fog.Density;
742 fogStart.f = 0.0;
743 break;
744 case GL_EXP2:
745 R300_STATECHANGE(r300, fogs);
746 r300->hw.fogs.cmd[R300_FOGS_STATE] =
747 (r300->hw.fogs.
748 cmd[R300_FOGS_STATE] & ~R300_FG_FOG_BLEND_FN_MASK) |
749 R300_FG_FOG_BLEND_FN_EXP2;
750 fogScale.f = 0.3 * ctx->Fog.Density;
751 fogStart.f = 0.0;
752 default:
753 return;
754 }
755 break;
756 case GL_FOG_DENSITY:
757 switch (ctx->Fog.Mode) {
758 case GL_EXP:
759 fogScale.f = 0.0933 * ctx->Fog.Density;
760 fogStart.f = 0.0;
761 break;
762 case GL_EXP2:
763 fogScale.f = 0.3 * ctx->Fog.Density;
764 fogStart.f = 0.0;
765 default:
766 break;
767 }
768 break;
769 case GL_FOG_START:
770 case GL_FOG_END:
771 if (ctx->Fog.Mode == GL_LINEAR) {
772 if (ctx->Fog.Start == ctx->Fog.End) {
773 fogScale.f = -1.0;
774 fogStart.f = 1.0;
775 } else {
776 fogScale.f =
777 1.0 / (ctx->Fog.End - ctx->Fog.Start);
778 fogStart.f =
779 -ctx->Fog.Start / (ctx->Fog.End -
780 ctx->Fog.Start);
781 }
782 }
783 break;
784 case GL_FOG_COLOR:
785 R300_STATECHANGE(r300, fogc);
786 r300->hw.fogc.cmd[R300_FOGC_R] =
787 (GLuint) (ctx->Fog.Color[0] * 1023.0F) & 0x3FF;
788 r300->hw.fogc.cmd[R300_FOGC_G] =
789 (GLuint) (ctx->Fog.Color[1] * 1023.0F) & 0x3FF;
790 r300->hw.fogc.cmd[R300_FOGC_B] =
791 (GLuint) (ctx->Fog.Color[2] * 1023.0F) & 0x3FF;
792 break;
793 case GL_FOG_COORD_SRC:
794 break;
795 default:
796 return;
797 }
798
799 if (fogScale.i != r300->hw.fogp.cmd[R300_FOGP_SCALE] ||
800 fogStart.i != r300->hw.fogp.cmd[R300_FOGP_START]) {
801 R300_STATECHANGE(r300, fogp);
802 r300->hw.fogp.cmd[R300_FOGP_SCALE] = fogScale.i;
803 r300->hw.fogp.cmd[R300_FOGP_START] = fogStart.i;
804 }
805 }
806
807 static void r300SetFogState(GLcontext * ctx, GLboolean state)
808 {
809 r300ContextPtr r300 = R300_CONTEXT(ctx);
810
811 R300_STATECHANGE(r300, fogs);
812 if (state) {
813 r300->hw.fogs.cmd[R300_FOGS_STATE] |= R300_FG_FOG_BLEND_ENABLE;
814
815 r300Fogfv(ctx, GL_FOG_MODE, NULL);
816 r300Fogfv(ctx, GL_FOG_DENSITY, &ctx->Fog.Density);
817 r300Fogfv(ctx, GL_FOG_START, &ctx->Fog.Start);
818 r300Fogfv(ctx, GL_FOG_END, &ctx->Fog.End);
819 r300Fogfv(ctx, GL_FOG_COLOR, ctx->Fog.Color);
820 } else {
821 r300->hw.fogs.cmd[R300_FOGS_STATE] &= ~R300_FG_FOG_BLEND_ENABLE;
822 }
823 }
824
825 /* =============================================================
826 * Point state
827 */
828 static void r300PointSize(GLcontext * ctx, GLfloat size)
829 {
830 r300ContextPtr r300 = R300_CONTEXT(ctx);
831 /* same size limits for AA, non-AA points */
832 size = CLAMP(size, ctx->Const.MinPointSize, ctx->Const.MaxPointSize);
833
834 R300_STATECHANGE(r300, ps);
835 r300->hw.ps.cmd[R300_PS_POINTSIZE] =
836 ((int)(size * 6) << R300_POINTSIZE_X_SHIFT) |
837 ((int)(size * 6) << R300_POINTSIZE_Y_SHIFT);
838 }
839
840 /* =============================================================
841 * Line state
842 */
843 static void r300LineWidth(GLcontext * ctx, GLfloat widthf)
844 {
845 r300ContextPtr r300 = R300_CONTEXT(ctx);
846
847 widthf = CLAMP(widthf,
848 ctx->Const.MinPointSize,
849 ctx->Const.MaxPointSize);
850 R300_STATECHANGE(r300, lcntl);
851 r300->hw.lcntl.cmd[1] =
852 R300_LINE_CNT_HO | R300_LINE_CNT_VE | (int)(widthf * 6.0);
853 }
854
855 static void r300PolygonMode(GLcontext * ctx, GLenum face, GLenum mode)
856 {
857 (void)face;
858 (void)mode;
859
860 r300UpdatePolygonMode(ctx);
861 }
862
863 /* =============================================================
864 * Stencil
865 */
866
867 static int translate_stencil_op(int op)
868 {
869 switch (op) {
870 case GL_KEEP:
871 return R300_ZS_KEEP;
872 case GL_ZERO:
873 return R300_ZS_ZERO;
874 case GL_REPLACE:
875 return R300_ZS_REPLACE;
876 case GL_INCR:
877 return R300_ZS_INCR;
878 case GL_DECR:
879 return R300_ZS_DECR;
880 case GL_INCR_WRAP_EXT:
881 return R300_ZS_INCR_WRAP;
882 case GL_DECR_WRAP_EXT:
883 return R300_ZS_DECR_WRAP;
884 case GL_INVERT:
885 return R300_ZS_INVERT;
886 default:
887 WARN_ONCE("Do not know how to translate stencil op");
888 return R300_ZS_KEEP;
889 }
890 return 0;
891 }
892
893 static void r300ShadeModel(GLcontext * ctx, GLenum mode)
894 {
895 r300ContextPtr rmesa = R300_CONTEXT(ctx);
896
897 R300_STATECHANGE(rmesa, shade);
898 rmesa->hw.shade.cmd[1] = 0x00000002;
899 switch (mode) {
900 case GL_FLAT:
901 rmesa->hw.shade.cmd[2] = R300_RE_SHADE_MODEL_FLAT;
902 break;
903 case GL_SMOOTH:
904 rmesa->hw.shade.cmd[2] = R300_RE_SHADE_MODEL_SMOOTH;
905 break;
906 default:
907 return;
908 }
909 rmesa->hw.shade.cmd[3] = 0x00000000;
910 rmesa->hw.shade.cmd[4] = 0x00000000;
911 }
912
913 static void r300StencilFuncSeparate(GLcontext * ctx, GLenum face,
914 GLenum func, GLint ref, GLuint mask)
915 {
916 r300ContextPtr rmesa = R300_CONTEXT(ctx);
917 GLuint refmask =
918 (((ctx->Stencil.
919 Ref[0] & 0xff) << R300_STENCILREF_SHIFT) | ((ctx->
920 Stencil.
921 ValueMask
922 [0] &
923 0xff)
924 <<
925 R300_STENCILMASK_SHIFT));
926
927 GLuint flag;
928
929 R300_STATECHANGE(rmesa, zs);
930
931 rmesa->hw.zs.cmd[R300_ZS_CNTL_1] &= ~((R300_ZS_MASK <<
932 R300_S_FRONT_FUNC_SHIFT)
933 | (R300_ZS_MASK <<
934 R300_S_BACK_FUNC_SHIFT));
935
936 rmesa->hw.zs.cmd[R300_ZS_CNTL_2] &=
937 ~((R300_STENCILREF_MASK << R300_STENCILREF_SHIFT) |
938 (R300_STENCILREF_MASK << R300_STENCILMASK_SHIFT));
939
940 flag = translate_func(ctx->Stencil.Function[0]);
941 rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=
942 (flag << R300_S_FRONT_FUNC_SHIFT);
943
944 if (ctx->Stencil._TestTwoSide)
945 flag = translate_func(ctx->Stencil.Function[1]);
946
947 rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=
948 (flag << R300_S_BACK_FUNC_SHIFT);
949 rmesa->hw.zs.cmd[R300_ZS_CNTL_2] |= refmask;
950 }
951
952 static void r300StencilMaskSeparate(GLcontext * ctx, GLenum face, GLuint mask)
953 {
954 r300ContextPtr rmesa = R300_CONTEXT(ctx);
955
956 R300_STATECHANGE(rmesa, zs);
957 rmesa->hw.zs.cmd[R300_ZS_CNTL_2] &=
958 ~(R300_STENCILREF_MASK <<
959 R300_STENCILWRITEMASK_SHIFT);
960 rmesa->hw.zs.cmd[R300_ZS_CNTL_2] |=
961 (ctx->Stencil.
962 WriteMask[0] & R300_STENCILREF_MASK) <<
963 R300_STENCILWRITEMASK_SHIFT;
964 }
965
966 static void r300StencilOpSeparate(GLcontext * ctx, GLenum face,
967 GLenum fail, GLenum zfail, GLenum zpass)
968 {
969 r300ContextPtr rmesa = R300_CONTEXT(ctx);
970
971 R300_STATECHANGE(rmesa, zs);
972 /* It is easier to mask what's left.. */
973 rmesa->hw.zs.cmd[R300_ZS_CNTL_1] &=
974 (R300_ZS_MASK << R300_Z_FUNC_SHIFT) |
975 (R300_ZS_MASK << R300_S_FRONT_FUNC_SHIFT) |
976 (R300_ZS_MASK << R300_S_BACK_FUNC_SHIFT);
977
978 rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=
979 (translate_stencil_op(ctx->Stencil.FailFunc[0]) <<
980 R300_S_FRONT_SFAIL_OP_SHIFT)
981 | (translate_stencil_op(ctx->Stencil.ZFailFunc[0]) <<
982 R300_S_FRONT_ZFAIL_OP_SHIFT)
983 | (translate_stencil_op(ctx->Stencil.ZPassFunc[0]) <<
984 R300_S_FRONT_ZPASS_OP_SHIFT);
985
986 if (ctx->Stencil._TestTwoSide) {
987 rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=
988 (translate_stencil_op(ctx->Stencil.FailFunc[1]) <<
989 R300_S_BACK_SFAIL_OP_SHIFT)
990 | (translate_stencil_op(ctx->Stencil.ZFailFunc[1]) <<
991 R300_S_BACK_ZFAIL_OP_SHIFT)
992 | (translate_stencil_op(ctx->Stencil.ZPassFunc[1]) <<
993 R300_S_BACK_ZPASS_OP_SHIFT);
994 } else {
995 rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=
996 (translate_stencil_op(ctx->Stencil.FailFunc[0]) <<
997 R300_S_BACK_SFAIL_OP_SHIFT)
998 | (translate_stencil_op(ctx->Stencil.ZFailFunc[0]) <<
999 R300_S_BACK_ZFAIL_OP_SHIFT)
1000 | (translate_stencil_op(ctx->Stencil.ZPassFunc[0]) <<
1001 R300_S_BACK_ZPASS_OP_SHIFT);
1002 }
1003 }
1004
1005 static void r300ClearStencil(GLcontext * ctx, GLint s)
1006 {
1007 r300ContextPtr rmesa = R300_CONTEXT(ctx);
1008
1009 rmesa->state.stencil.clear =
1010 ((GLuint) (ctx->Stencil.Clear & R300_STENCILREF_MASK) |
1011 (R300_STENCILREF_MASK << R300_STENCILMASK_SHIFT) |
1012 ((ctx->Stencil.WriteMask[0] & R300_STENCILREF_MASK) <<
1013 R300_STENCILMASK_SHIFT));
1014 }
1015
1016 /* =============================================================
1017 * Window position and viewport transformation
1018 */
1019
1020 /*
1021 * To correctly position primitives:
1022 */
1023 #define SUBPIXEL_X 0.125
1024 #define SUBPIXEL_Y 0.125
1025
1026 static void r300UpdateWindow(GLcontext * ctx)
1027 {
1028 r300ContextPtr rmesa = R300_CONTEXT(ctx);
1029 __DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable;
1030 GLfloat xoffset = dPriv ? (GLfloat) dPriv->x : 0;
1031 GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0;
1032 const GLfloat *v = ctx->Viewport._WindowMap.m;
1033
1034 GLfloat sx = v[MAT_SX];
1035 GLfloat tx = v[MAT_TX] + xoffset + SUBPIXEL_X;
1036 GLfloat sy = -v[MAT_SY];
1037 GLfloat ty = (-v[MAT_TY]) + yoffset + SUBPIXEL_Y;
1038 GLfloat sz = v[MAT_SZ] * rmesa->state.depth.scale;
1039 GLfloat tz = v[MAT_TZ] * rmesa->state.depth.scale;
1040
1041 R300_FIREVERTICES(rmesa);
1042 R300_STATECHANGE(rmesa, vpt);
1043
1044 rmesa->hw.vpt.cmd[R300_VPT_XSCALE] = r300PackFloat32(sx);
1045 rmesa->hw.vpt.cmd[R300_VPT_XOFFSET] = r300PackFloat32(tx);
1046 rmesa->hw.vpt.cmd[R300_VPT_YSCALE] = r300PackFloat32(sy);
1047 rmesa->hw.vpt.cmd[R300_VPT_YOFFSET] = r300PackFloat32(ty);
1048 rmesa->hw.vpt.cmd[R300_VPT_ZSCALE] = r300PackFloat32(sz);
1049 rmesa->hw.vpt.cmd[R300_VPT_ZOFFSET] = r300PackFloat32(tz);
1050 }
1051
1052 static void r300Viewport(GLcontext * ctx, GLint x, GLint y,
1053 GLsizei width, GLsizei height)
1054 {
1055 /* Don't pipeline viewport changes, conflict with window offset
1056 * setting below. Could apply deltas to rescue pipelined viewport
1057 * values, or keep the originals hanging around.
1058 */
1059 r300UpdateWindow(ctx);
1060 }
1061
1062 static void r300DepthRange(GLcontext * ctx, GLclampd nearval, GLclampd farval)
1063 {
1064 r300UpdateWindow(ctx);
1065 }
1066
1067 void r300UpdateViewportOffset(GLcontext * ctx)
1068 {
1069 r300ContextPtr rmesa = R300_CONTEXT(ctx);
1070 __DRIdrawablePrivate *dPriv = ((radeonContextPtr) rmesa)->dri.drawable;
1071 GLfloat xoffset = (GLfloat) dPriv->x;
1072 GLfloat yoffset = (GLfloat) dPriv->y + dPriv->h;
1073 const GLfloat *v = ctx->Viewport._WindowMap.m;
1074
1075 GLfloat tx = v[MAT_TX] + xoffset + SUBPIXEL_X;
1076 GLfloat ty = (-v[MAT_TY]) + yoffset + SUBPIXEL_Y;
1077
1078 if (rmesa->hw.vpt.cmd[R300_VPT_XOFFSET] != r300PackFloat32(tx) ||
1079 rmesa->hw.vpt.cmd[R300_VPT_YOFFSET] != r300PackFloat32(ty)) {
1080 /* Note: this should also modify whatever data the context reset
1081 * code uses...
1082 */
1083 R300_STATECHANGE(rmesa, vpt);
1084 rmesa->hw.vpt.cmd[R300_VPT_XOFFSET] = r300PackFloat32(tx);
1085 rmesa->hw.vpt.cmd[R300_VPT_YOFFSET] = r300PackFloat32(ty);
1086
1087 }
1088
1089 radeonUpdateScissor(ctx);
1090 }
1091
1092 /**
1093 * Tell the card where to render (offset, pitch).
1094 * Effected by glDrawBuffer, etc
1095 */
1096 void r300UpdateDrawBuffer(GLcontext * ctx)
1097 {
1098 r300ContextPtr rmesa = R300_CONTEXT(ctx);
1099 r300ContextPtr r300 = rmesa;
1100 struct gl_framebuffer *fb = ctx->DrawBuffer;
1101 driRenderbuffer *drb;
1102
1103 if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) {
1104 /* draw to front */
1105 drb =
1106 (driRenderbuffer *) fb->Attachment[BUFFER_FRONT_LEFT].
1107 Renderbuffer;
1108 } else if (fb->_ColorDrawBufferIndexes[0] == BUFFER_BACK_LEFT) {
1109 /* draw to back */
1110 drb =
1111 (driRenderbuffer *) fb->Attachment[BUFFER_BACK_LEFT].
1112 Renderbuffer;
1113 } else {
1114 /* drawing to multiple buffers, or none */
1115 return;
1116 }
1117
1118 assert(drb);
1119 assert(drb->flippedPitch);
1120
1121 R300_STATECHANGE(rmesa, cb);
1122
1123 r300->hw.cb.cmd[R300_CB_OFFSET] = drb->flippedOffset + //r300->radeon.state.color.drawOffset +
1124 r300->radeon.radeonScreen->fbLocation;
1125 r300->hw.cb.cmd[R300_CB_PITCH] = drb->flippedPitch; //r300->radeon.state.color.drawPitch;
1126
1127 if (r300->radeon.radeonScreen->cpp == 4)
1128 r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_FORMAT_ARGB8888;
1129 else
1130 r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_FORMAT_RGB565;
1131
1132 if (r300->radeon.sarea->tiling_enabled)
1133 r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_TILE_ENABLE;
1134 #if 0
1135 R200_STATECHANGE(rmesa, ctx);
1136
1137 /* Note: we used the (possibly) page-flipped values */
1138 rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET]
1139 = ((drb->flippedOffset + rmesa->r200Screen->fbLocation)
1140 & R200_COLOROFFSET_MASK);
1141 rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = drb->flippedPitch;
1142
1143 if (rmesa->sarea->tiling_enabled) {
1144 rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |=
1145 R200_COLOR_TILE_ENABLE;
1146 }
1147 #endif
1148 }
1149
1150 static void
1151 r300FetchStateParameter(GLcontext * ctx,
1152 const gl_state_index state[STATE_LENGTH],
1153 GLfloat * value)
1154 {
1155 r300ContextPtr r300 = R300_CONTEXT(ctx);
1156
1157 switch (state[0]) {
1158 case STATE_INTERNAL:
1159 switch (state[1]) {
1160 case STATE_R300_WINDOW_DIMENSION:
1161 value[0] = r300->radeon.dri.drawable->w * 0.5f; /* width*0.5 */
1162 value[1] = r300->radeon.dri.drawable->h * 0.5f; /* height*0.5 */
1163 value[2] = 0.5F; /* for moving range [-1 1] -> [0 1] */
1164 value[3] = 1.0F; /* not used */
1165 break;
1166
1167 case STATE_R300_TEXRECT_FACTOR:{
1168 struct gl_texture_object *t =
1169 ctx->Texture.Unit[state[2]].CurrentRect;
1170
1171 if (t && t->Image[0][t->BaseLevel]) {
1172 struct gl_texture_image *image =
1173 t->Image[0][t->BaseLevel];
1174 value[0] = 1.0 / image->Width2;
1175 value[1] = 1.0 / image->Height2;
1176 } else {
1177 value[0] = 1.0;
1178 value[1] = 1.0;
1179 }
1180 value[2] = 1.0;
1181 value[3] = 1.0;
1182 break;
1183 }
1184
1185 default:
1186 break;
1187 }
1188 break;
1189
1190 default:
1191 break;
1192 }
1193 }
1194
1195 /**
1196 * Update R300's own internal state parameters.
1197 * For now just STATE_R300_WINDOW_DIMENSION
1198 */
1199 void r300UpdateStateParameters(GLcontext * ctx, GLuint new_state)
1200 {
1201 struct r300_fragment_program *fp;
1202 struct gl_program_parameter_list *paramList;
1203 GLuint i;
1204
1205 if (!(new_state & (_NEW_BUFFERS | _NEW_PROGRAM)))
1206 return;
1207
1208 fp = (struct r300_fragment_program *)ctx->FragmentProgram._Current;
1209 if (!fp)
1210 return;
1211
1212 paramList = fp->mesa_program.Base.Parameters;
1213
1214 if (!paramList)
1215 return;
1216
1217 for (i = 0; i < paramList->NumParameters; i++) {
1218 if (paramList->Parameters[i].Type == PROGRAM_STATE_VAR) {
1219 r300FetchStateParameter(ctx,
1220 paramList->Parameters[i].
1221 StateIndexes,
1222 paramList->ParameterValues[i]);
1223 }
1224 }
1225 }
1226
1227 /* =============================================================
1228 * Polygon state
1229 */
1230 static void r300PolygonOffset(GLcontext * ctx, GLfloat factor, GLfloat units)
1231 {
1232 r300ContextPtr rmesa = R300_CONTEXT(ctx);
1233 GLfloat constant = units;
1234
1235 switch (ctx->Visual.depthBits) {
1236 case 16:
1237 constant *= 4.0;
1238 break;
1239 case 24:
1240 constant *= 2.0;
1241 break;
1242 }
1243
1244 factor *= 12.0;
1245
1246 /* fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */
1247
1248 R300_STATECHANGE(rmesa, zbs);
1249 rmesa->hw.zbs.cmd[R300_ZBS_T_FACTOR] = r300PackFloat32(factor);
1250 rmesa->hw.zbs.cmd[R300_ZBS_T_CONSTANT] = r300PackFloat32(constant);
1251 rmesa->hw.zbs.cmd[R300_ZBS_W_FACTOR] = r300PackFloat32(factor);
1252 rmesa->hw.zbs.cmd[R300_ZBS_W_CONSTANT] = r300PackFloat32(constant);
1253 }
1254
1255 /* Routing and texture-related */
1256
1257 /* r300 doesnt handle GL_CLAMP and GL_MIRROR_CLAMP_EXT correctly when filter is NEAREST.
1258 * Since texwrap produces same results for GL_CLAMP and GL_CLAMP_TO_EDGE we use them instead.
1259 * We need to recalculate wrap modes whenever filter mode is changed because someone might do:
1260 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1261 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1262 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1263 * Since r300 completely ignores R300_TX_CLAMP when either min or mag is nearest it cant handle
1264 * combinations where only one of them is nearest.
1265 */
1266 static unsigned long gen_fixed_filter(unsigned long f)
1267 {
1268 unsigned long mag, min, needs_fixing = 0;
1269 //return f;
1270
1271 /* We ignore MIRROR bit so we dont have to do everything twice */
1272 if ((f & ((7 - 1) << R300_TX_WRAP_S_SHIFT)) ==
1273 (R300_TX_CLAMP << R300_TX_WRAP_S_SHIFT)) {
1274 needs_fixing |= 1;
1275 }
1276 if ((f & ((7 - 1) << R300_TX_WRAP_T_SHIFT)) ==
1277 (R300_TX_CLAMP << R300_TX_WRAP_T_SHIFT)) {
1278 needs_fixing |= 2;
1279 }
1280 if ((f & ((7 - 1) << R300_TX_WRAP_Q_SHIFT)) ==
1281 (R300_TX_CLAMP << R300_TX_WRAP_Q_SHIFT)) {
1282 needs_fixing |= 4;
1283 }
1284
1285 if (!needs_fixing)
1286 return f;
1287
1288 mag = f & R300_TX_MAG_FILTER_MASK;
1289 min = f & R300_TX_MIN_FILTER_MASK;
1290
1291 /* TODO: Check for anisto filters too */
1292 if ((mag != R300_TX_MAG_FILTER_NEAREST)
1293 && (min != R300_TX_MIN_FILTER_NEAREST))
1294 return f;
1295
1296 /* r300 cant handle these modes hence we force nearest to linear */
1297 if ((mag == R300_TX_MAG_FILTER_NEAREST)
1298 && (min != R300_TX_MIN_FILTER_NEAREST)) {
1299 f &= ~R300_TX_MAG_FILTER_NEAREST;
1300 f |= R300_TX_MAG_FILTER_LINEAR;
1301 return f;
1302 }
1303
1304 if ((min == R300_TX_MIN_FILTER_NEAREST)
1305 && (mag != R300_TX_MAG_FILTER_NEAREST)) {
1306 f &= ~R300_TX_MIN_FILTER_NEAREST;
1307 f |= R300_TX_MIN_FILTER_LINEAR;
1308 return f;
1309 }
1310
1311 /* Both are nearest */
1312 if (needs_fixing & 1) {
1313 f &= ~((7 - 1) << R300_TX_WRAP_S_SHIFT);
1314 f |= R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_S_SHIFT;
1315 }
1316 if (needs_fixing & 2) {
1317 f &= ~((7 - 1) << R300_TX_WRAP_T_SHIFT);
1318 f |= R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_T_SHIFT;
1319 }
1320 if (needs_fixing & 4) {
1321 f &= ~((7 - 1) << R300_TX_WRAP_Q_SHIFT);
1322 f |= R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_Q_SHIFT;
1323 }
1324 return f;
1325 }
1326
1327 static void r300SetupTextures(GLcontext * ctx)
1328 {
1329 int i, mtu;
1330 struct r300_tex_obj *t;
1331 r300ContextPtr r300 = R300_CONTEXT(ctx);
1332 int hw_tmu = 0;
1333 int last_hw_tmu = -1; /* -1 translates into no setup costs for fields */
1334 int tmu_mappings[R300_MAX_TEXTURE_UNITS] = { -1, };
1335 struct r300_fragment_program *fp = (struct r300_fragment_program *)
1336 (char *)ctx->FragmentProgram._Current;
1337
1338 R300_STATECHANGE(r300, txe);
1339 R300_STATECHANGE(r300, tex.filter);
1340 R300_STATECHANGE(r300, tex.filter_1);
1341 R300_STATECHANGE(r300, tex.size);
1342 R300_STATECHANGE(r300, tex.format);
1343 R300_STATECHANGE(r300, tex.pitch);
1344 R300_STATECHANGE(r300, tex.offset);
1345 R300_STATECHANGE(r300, tex.chroma_key);
1346 R300_STATECHANGE(r300, tex.border_color);
1347
1348 r300->hw.txe.cmd[R300_TXE_ENABLE] = 0x0;
1349
1350 mtu = r300->radeon.glCtx->Const.MaxTextureUnits;
1351 if (RADEON_DEBUG & DEBUG_STATE)
1352 fprintf(stderr, "mtu=%d\n", mtu);
1353
1354 if (mtu > R300_MAX_TEXTURE_UNITS) {
1355 fprintf(stderr,
1356 "Aiiee ! mtu=%d is greater than R300_MAX_TEXTURE_UNITS=%d\n",
1357 mtu, R300_MAX_TEXTURE_UNITS);
1358 _mesa_exit(-1);
1359 }
1360
1361 /* We cannot let disabled tmu offsets pass DRM */
1362 for (i = 0; i < mtu; i++) {
1363 if (ctx->Texture.Unit[i]._ReallyEnabled) {
1364
1365 #if 0 /* Enables old behaviour */
1366 hw_tmu = i;
1367 #endif
1368 tmu_mappings[i] = hw_tmu;
1369
1370 t = r300->state.texture.unit[i].texobj;
1371 /* XXX questionable fix for bug 9170: */
1372 if (!t)
1373 continue;
1374
1375 if ((t->format & 0xffffff00) == 0xffffff00) {
1376 WARN_ONCE
1377 ("unknown texture format (entry %x) encountered. Help me !\n",
1378 t->format & 0xff);
1379 }
1380
1381 if (RADEON_DEBUG & DEBUG_STATE)
1382 fprintf(stderr,
1383 "Activating texture unit %d\n", i);
1384
1385 r300->hw.txe.cmd[R300_TXE_ENABLE] |= (1 << hw_tmu);
1386
1387 r300->hw.tex.filter.cmd[R300_TEX_VALUE_0 +
1388 hw_tmu] =
1389 gen_fixed_filter(t->filter) | (hw_tmu << 28);
1390 /* Currently disabled! */
1391 r300->hw.tex.filter_1.cmd[R300_TEX_VALUE_0 + hw_tmu] = 0x0; //0x20501f80;
1392 r300->hw.tex.size.cmd[R300_TEX_VALUE_0 + hw_tmu] =
1393 t->size;
1394 r300->hw.tex.format.cmd[R300_TEX_VALUE_0 +
1395 hw_tmu] = t->format;
1396 r300->hw.tex.pitch.cmd[R300_TEX_VALUE_0 + hw_tmu] =
1397 t->pitch_reg;
1398 r300->hw.tex.offset.cmd[R300_TEX_VALUE_0 +
1399 hw_tmu] = t->offset;
1400
1401 if (t->offset & R300_TXO_MACRO_TILE) {
1402 WARN_ONCE("macro tiling enabled!\n");
1403 }
1404
1405 if (t->offset & R300_TXO_MICRO_TILE) {
1406 WARN_ONCE("micro tiling enabled!\n");
1407 }
1408
1409 r300->hw.tex.chroma_key.cmd[R300_TEX_VALUE_0 +
1410 hw_tmu] = 0x0;
1411 r300->hw.tex.border_color.cmd[R300_TEX_VALUE_0 +
1412 hw_tmu] =
1413 t->pp_border_color;
1414
1415 last_hw_tmu = hw_tmu;
1416
1417 hw_tmu++;
1418 }
1419 }
1420
1421 r300->hw.tex.filter.cmd[R300_TEX_CMD_0] =
1422 cmdpacket0(R300_TX_FILTER0_0, last_hw_tmu + 1);
1423 r300->hw.tex.filter_1.cmd[R300_TEX_CMD_0] =
1424 cmdpacket0(R300_TX_FILTER1_0, last_hw_tmu + 1);
1425 r300->hw.tex.size.cmd[R300_TEX_CMD_0] =
1426 cmdpacket0(R300_TX_SIZE_0, last_hw_tmu + 1);
1427 r300->hw.tex.format.cmd[R300_TEX_CMD_0] =
1428 cmdpacket0(R300_TX_FORMAT_0, last_hw_tmu + 1);
1429 r300->hw.tex.pitch.cmd[R300_TEX_CMD_0] =
1430 cmdpacket0(R300_TX_FORMAT2_0, last_hw_tmu + 1);
1431 r300->hw.tex.offset.cmd[R300_TEX_CMD_0] =
1432 cmdpacket0(R300_TX_OFFSET_0, last_hw_tmu + 1);
1433 r300->hw.tex.chroma_key.cmd[R300_TEX_CMD_0] =
1434 cmdpacket0(R300_TX_CHROMA_KEY_0, last_hw_tmu + 1);
1435 r300->hw.tex.border_color.cmd[R300_TEX_CMD_0] =
1436 cmdpacket0(R300_TX_BORDER_COLOR_0, last_hw_tmu + 1);
1437
1438 if (!fp) /* should only happenen once, just after context is created */
1439 return;
1440
1441
1442 if (r300->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV515) {
1443 R300_STATECHANGE(r300, fpt);
1444
1445 for (i = 0; i < fp->tex.length; i++) {
1446 int unit;
1447 int opcode;
1448 unsigned long val;
1449
1450 unit = fp->tex.inst[i] >> R300_TEX_ID_SHIFT;
1451 unit &= 15;
1452
1453 val = fp->tex.inst[i];
1454 val &= ~R300_TEX_ID_MASK;
1455
1456 opcode =
1457 (val & R300_TEX_INST_MASK) >> R300_TEX_INST_SHIFT;
1458 if (opcode == R300_TEX_OP_KIL) {
1459 r300->hw.fpt.cmd[R300_FPT_INSTR_0 + i] = val;
1460 } else {
1461 if (tmu_mappings[unit] >= 0) {
1462 val |=
1463 tmu_mappings[unit] <<
1464 R300_TEX_ID_SHIFT;
1465 r300->hw.fpt.cmd[R300_FPT_INSTR_0 + i] = val;
1466 } else {
1467 // We get here when the corresponding texture image is incomplete
1468 // (e.g. incomplete mipmaps etc.)
1469 r300->hw.fpt.cmd[R300_FPT_INSTR_0 + i] = val;
1470 }
1471 }
1472 }
1473
1474 r300->hw.fpt.cmd[R300_FPT_CMD_0] =
1475 cmdpacket0(R300_US_TEX_INST_0, fp->tex.length);
1476 }
1477
1478 if (RADEON_DEBUG & DEBUG_STATE)
1479 fprintf(stderr, "TX_ENABLE: %08x last_hw_tmu=%d\n",
1480 r300->hw.txe.cmd[R300_TXE_ENABLE], last_hw_tmu);
1481 }
1482
1483 union r300_outputs_written {
1484 GLuint vp_outputs; /* hw_tcl_on */
1485 DECLARE_RENDERINPUTS(index_bitset); /* !hw_tcl_on */
1486 };
1487
1488 #define R300_OUTPUTS_WRITTEN_TEST(ow, vp_result, tnl_attrib) \
1489 ((hw_tcl_on) ? (ow).vp_outputs & (1 << (vp_result)) : \
1490 RENDERINPUTS_TEST( (ow.index_bitset), (tnl_attrib) ))
1491
1492 static void r300SetupRSUnit(GLcontext * ctx)
1493 {
1494 r300ContextPtr r300 = R300_CONTEXT(ctx);
1495 /* I'm still unsure if these are needed */
1496 GLuint interp_col[8];
1497 TNLcontext *tnl = TNL_CONTEXT(ctx);
1498 struct vertex_buffer *VB = &tnl->vb;
1499 union r300_outputs_written OutputsWritten;
1500 GLuint InputsRead;
1501 int fp_reg, high_rr;
1502 int col_interp_nr;
1503 int rs_tex_count = 0, rs_col_count = 0;
1504 int i, count;
1505
1506 memset(interp_col, 0, sizeof(interp_col));
1507
1508 if (hw_tcl_on)
1509 OutputsWritten.vp_outputs = CURRENT_VERTEX_SHADER(ctx)->key.OutputsWritten;
1510 else
1511 RENDERINPUTS_COPY(OutputsWritten.index_bitset, r300->state.render_inputs_bitset);
1512
1513 if (ctx->FragmentProgram._Current)
1514 InputsRead = ctx->FragmentProgram._Current->Base.InputsRead;
1515 else {
1516 fprintf(stderr, "No ctx->FragmentProgram._Current!!\n");
1517 return; /* This should only ever happen once.. */
1518 }
1519
1520 R300_STATECHANGE(r300, ri);
1521 R300_STATECHANGE(r300, rc);
1522 R300_STATECHANGE(r300, rr);
1523
1524 fp_reg = col_interp_nr = high_rr = 0;
1525
1526 r300->hw.rr.cmd[R300_RR_INST_1] = 0;
1527
1528 if (InputsRead & FRAG_BIT_WPOS) {
1529 for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
1530 if (!(InputsRead & (FRAG_BIT_TEX0 << i)))
1531 break;
1532
1533 if (i == ctx->Const.MaxTextureUnits) {
1534 fprintf(stderr, "\tno free texcoord found...\n");
1535 _mesa_exit(-1);
1536 }
1537
1538 InputsRead |= (FRAG_BIT_TEX0 << i);
1539 InputsRead &= ~FRAG_BIT_WPOS;
1540 }
1541
1542 if (InputsRead & FRAG_BIT_COL0) {
1543 count = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->size;
1544 interp_col[0] |= R300_RS_COL_PTR(rs_col_count);
1545 if (count == 3)
1546 interp_col[0] |= R300_RS_COL_FMT(R300_RS_COL_FMT_RGB1);
1547 rs_col_count += count;
1548 }
1549 else
1550 interp_col[0] = R300_RS_COL_FMT(R300_RS_COL_FMT_0001);
1551
1552 if (InputsRead & FRAG_BIT_COL1) {
1553 count = VB->AttribPtr[_TNL_ATTRIB_COLOR1]->size;
1554 if (count == 3)
1555 interp_col[1] |= R300_RS_COL_FMT(R300_RS_COL_FMT_RGB1);
1556 interp_col[1] |= R300_RS_COL_PTR(1);
1557 rs_col_count += count;
1558 }
1559
1560
1561 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
1562 int swiz;
1563
1564 /* with TCL we always seem to route 4 components */
1565 if (hw_tcl_on)
1566 count = 4;
1567 else
1568 count = VB->AttribPtr[_TNL_ATTRIB_TEX(i)]->size;
1569
1570 r300->hw.ri.cmd[R300_RI_INTERP_0 + i] = interp_col[i] | rs_tex_count;
1571 switch(count) {
1572 case 4: swiz = R300_RS_SEL_S(0) | R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(3); break;
1573 case 3: swiz = R300_RS_SEL_S(0) | R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(R300_RS_SEL_K1); break;
1574 default:
1575 case 1:
1576 case 2: swiz = R300_RS_SEL_S(0) | R300_RS_SEL_T(1) | R300_RS_SEL_R(R300_RS_SEL_K0) | R300_RS_SEL_Q(R300_RS_SEL_K1); break;
1577 };
1578
1579 r300->hw.ri.cmd[R300_RI_INTERP_0 + i] |= swiz;
1580
1581 r300->hw.rr.cmd[R300_RR_INST_0 + fp_reg] = 0;
1582 if (InputsRead & (FRAG_BIT_TEX0 << i)) {
1583
1584 rs_tex_count += count;
1585
1586 //assert(r300->state.texture.tc_count != 0);
1587 r300->hw.rr.cmd[R300_RR_INST_0 + fp_reg] |= R300_RS_INST_TEX_CN_WRITE | i /* source INTERP */
1588 | (fp_reg << R300_RS_INST_TEX_ADDR_SHIFT);
1589 high_rr = fp_reg;
1590
1591 /* Passing invalid data here can lock the GPU. */
1592 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_TEX0 + i, _TNL_ATTRIB_TEX(i))) {
1593 InputsRead &= ~(FRAG_BIT_TEX0 << i);
1594 fp_reg++;
1595 } else {
1596 WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i);
1597 }
1598 }
1599 }
1600
1601 if (InputsRead & FRAG_BIT_COL0) {
1602 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_COL0, _TNL_ATTRIB_COLOR0)) {
1603 r300->hw.rr.cmd[R300_RR_INST_0] |= R300_RS_INST_COL_ID(0) | R300_RS_INST_COL_CN_WRITE | (fp_reg++ << R300_RS_INST_COL_ADDR_SHIFT);
1604 InputsRead &= ~FRAG_BIT_COL0;
1605 col_interp_nr++;
1606 } else {
1607 WARN_ONCE("fragprog wants col0, vp doesn't provide it\n");
1608 }
1609 }
1610
1611 if (InputsRead & FRAG_BIT_COL1) {
1612 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_COL1, _TNL_ATTRIB_COLOR1)) {
1613 r300->hw.rr.cmd[R300_RR_INST_1] |= R300_RS_INST_COL_ID(1) | R300_RS_INST_COL_CN_WRITE | (fp_reg++ << R300_RS_INST_COL_ADDR_SHIFT);
1614 InputsRead &= ~FRAG_BIT_COL1;
1615 if (high_rr < 1)
1616 high_rr = 1;
1617 col_interp_nr++;
1618 } else {
1619 WARN_ONCE("fragprog wants col1, vp doesn't provide it\n");
1620 }
1621 }
1622
1623 /* Need at least one. This might still lock as the values are undefined... */
1624 if (rs_tex_count == 0 && col_interp_nr == 0) {
1625 r300->hw.rr.cmd[R300_RR_INST_0] |= R300_RS_INST_COL_ID(0) | R300_RS_INST_COL_CN_WRITE | (fp_reg++ << R300_RS_INST_COL_ADDR_SHIFT);
1626 col_interp_nr++;
1627 }
1628
1629 r300->hw.rc.cmd[1] = 0 | (rs_tex_count << R300_IT_COUNT_SHIFT)
1630 | (col_interp_nr << R300_IC_COUNT_SHIFT)
1631 | R300_HIRES_EN;
1632
1633 assert(high_rr >= 0);
1634 r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(R300_RS_INST_0, high_rr + 1);
1635 r300->hw.rc.cmd[2] = high_rr;
1636
1637 if (InputsRead)
1638 WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead);
1639 }
1640
1641 static void r500SetupRSUnit(GLcontext * ctx)
1642 {
1643 r300ContextPtr r300 = R300_CONTEXT(ctx);
1644 /* I'm still unsure if these are needed */
1645 GLuint interp_col[8];
1646 union r300_outputs_written OutputsWritten;
1647 TNLcontext *tnl = TNL_CONTEXT(ctx);
1648 struct vertex_buffer *VB = &tnl->vb;
1649 GLuint InputsRead;
1650 int fp_reg, high_rr;
1651 int rs_col_count = 0;
1652 int in_texcoords, col_interp_nr;
1653 int i, count;
1654
1655 memset(interp_col, 0, sizeof(interp_col));
1656 if (hw_tcl_on)
1657 OutputsWritten.vp_outputs = CURRENT_VERTEX_SHADER(ctx)->key.OutputsWritten;
1658 else
1659 RENDERINPUTS_COPY(OutputsWritten.index_bitset, r300->state.render_inputs_bitset);
1660
1661 if (ctx->FragmentProgram._Current)
1662 InputsRead = ctx->FragmentProgram._Current->Base.InputsRead;
1663 else {
1664 fprintf(stderr, "No ctx->FragmentProgram._Current!!\n");
1665 return; /* This should only ever happen once.. */
1666 }
1667
1668 R300_STATECHANGE(r300, ri);
1669 R300_STATECHANGE(r300, rc);
1670 R300_STATECHANGE(r300, rr);
1671
1672 fp_reg = col_interp_nr = high_rr = in_texcoords = 0;
1673
1674 r300->hw.rr.cmd[R300_RR_INST_1] = 0;
1675
1676 if (InputsRead & FRAG_BIT_WPOS) {
1677 for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
1678 if (!(InputsRead & (FRAG_BIT_TEX0 << i)))
1679 break;
1680
1681 if (i == ctx->Const.MaxTextureUnits) {
1682 fprintf(stderr, "\tno free texcoord found...\n");
1683 _mesa_exit(-1);
1684 }
1685
1686 InputsRead |= (FRAG_BIT_TEX0 << i);
1687 InputsRead &= ~FRAG_BIT_WPOS;
1688 }
1689
1690 if (InputsRead & FRAG_BIT_COL0) {
1691 count = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->size;
1692 interp_col[0] |= R500_RS_COL_PTR(rs_col_count);
1693 if (count == 3)
1694 interp_col[0] |= R500_RS_COL_FMT(R300_RS_COL_FMT_RGB1);
1695 rs_col_count += count;
1696 }
1697 else
1698 interp_col[0] = R500_RS_COL_FMT(R300_RS_COL_FMT_0001);
1699
1700 if (InputsRead & FRAG_BIT_COL1) {
1701 count = VB->AttribPtr[_TNL_ATTRIB_COLOR1]->size;
1702 interp_col[1] |= R500_RS_COL_PTR(1);
1703 if (count == 3)
1704 interp_col[1] |= R500_RS_COL_FMT(R300_RS_COL_FMT_RGB1);
1705 rs_col_count += count;
1706 }
1707
1708 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
1709 GLuint swiz = 0;
1710
1711 /* with TCL we always seem to route 4 components */
1712 if (InputsRead & (FRAG_BIT_TEX0 << i)) {
1713
1714 if (hw_tcl_on)
1715 count = 4;
1716 else
1717 count = VB->AttribPtr[_TNL_ATTRIB_TEX(i)]->size;
1718
1719 /* always have a least 2 tex coords */
1720 swiz |= in_texcoords++ << R500_RS_IP_TEX_PTR_S_SHIFT;
1721 swiz |= in_texcoords++ << R500_RS_IP_TEX_PTR_T_SHIFT;
1722
1723 if (count >= 3)
1724 swiz |= in_texcoords++ << R500_RS_IP_TEX_PTR_R_SHIFT;
1725 else
1726 swiz |= R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT;
1727
1728 if (count == 4)
1729 swiz |= in_texcoords++ << R500_RS_IP_TEX_PTR_Q_SHIFT;
1730 else
1731 swiz |= R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT;
1732
1733 } else
1734 swiz = (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_S_SHIFT) |
1735 (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_T_SHIFT) |
1736 (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT) |
1737 (R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT);
1738
1739 r300->hw.ri.cmd[R300_RI_INTERP_0 + i] = interp_col[i] | swiz;
1740
1741 r300->hw.rr.cmd[R300_RR_INST_0 + fp_reg] = 0;
1742 if (InputsRead & (FRAG_BIT_TEX0 << i)) {
1743 //assert(r300->state.texture.tc_count != 0);
1744 r300->hw.rr.cmd[R300_RR_INST_0 + fp_reg] |= R500_RS_INST_TEX_CN_WRITE | i /* source INTERP */
1745 | (fp_reg << R500_RS_INST_TEX_ADDR_SHIFT);
1746 high_rr = fp_reg;
1747
1748 /* Passing invalid data here can lock the GPU. */
1749 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_TEX0 + i, _TNL_ATTRIB_TEX(i))) {
1750 InputsRead &= ~(FRAG_BIT_TEX0 << i);
1751 fp_reg++;
1752 } else {
1753 WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i);
1754 }
1755 }
1756 }
1757
1758 if (InputsRead & FRAG_BIT_COL0) {
1759 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_COL0, _TNL_ATTRIB_COLOR0)) {
1760 r300->hw.rr.cmd[R300_RR_INST_0] |= R500_RS_INST_COL_CN_WRITE | (fp_reg++ << R500_RS_INST_COL_ADDR_SHIFT);
1761 InputsRead &= ~FRAG_BIT_COL0;
1762 col_interp_nr++;
1763 } else {
1764 WARN_ONCE("fragprog wants col0, vp doesn't provide it\n");
1765 }
1766 }
1767
1768 if (InputsRead & FRAG_BIT_COL1) {
1769 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_COL1, _TNL_ATTRIB_COLOR1)) {
1770 r300->hw.rr.cmd[R300_RR_INST_1] |= (1 << 12) | R500_RS_INST_COL_CN_WRITE | (fp_reg++ << R500_RS_INST_COL_ADDR_SHIFT);
1771 InputsRead &= ~FRAG_BIT_COL1;
1772 if (high_rr < 1)
1773 high_rr = 1;
1774 col_interp_nr++;
1775 } else {
1776 WARN_ONCE("fragprog wants col1, vp doesn't provide it\n");
1777 }
1778 }
1779
1780 /* Need at least one. This might still lock as the values are undefined... */
1781 if (in_texcoords == 0 && col_interp_nr == 0) {
1782 r300->hw.rr.cmd[R300_RR_INST_0] |= 0 | R500_RS_INST_COL_CN_WRITE | (fp_reg++ << R500_RS_INST_COL_ADDR_SHIFT);
1783 col_interp_nr++;
1784 }
1785
1786 r300->hw.rc.cmd[1] = 0 | (in_texcoords << R300_IT_COUNT_SHIFT)
1787 | (col_interp_nr << R300_IC_COUNT_SHIFT)
1788 | R300_HIRES_EN;
1789
1790 assert(high_rr >= 0);
1791 r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(R300_RS_INST_0, high_rr + 1);
1792 r300->hw.rc.cmd[2] = 0xC0 | high_rr;
1793
1794 if (InputsRead)
1795 WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead);
1796 }
1797
1798
1799
1800
1801 #define bump_vpu_count(ptr, new_count) do{\
1802 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
1803 int _nc=(new_count)/4; \
1804 assert(_nc < 256); \
1805 if(_nc>_p->vpu.count)_p->vpu.count=_nc;\
1806 }while(0)
1807
1808 static inline void r300SetupVertexProgramFragment(r300ContextPtr r300, int dest, struct r300_vertex_shader_fragment *vsf)
1809 {
1810 int i;
1811
1812 if (vsf->length == 0)
1813 return;
1814
1815 if (vsf->length & 0x3) {
1816 fprintf(stderr, "VERTEX_SHADER_FRAGMENT must have length divisible by 4\n");
1817 _mesa_exit(-1);
1818 }
1819
1820 switch ((dest >> 8) & 0xf) {
1821 case 0:
1822 R300_STATECHANGE(r300, vpi);
1823 for (i = 0; i < vsf->length; i++)
1824 r300->hw.vpi.cmd[R300_VPI_INSTR_0 + i + 4 * (dest & 0xff)] = (vsf->body.d[i]);
1825 bump_vpu_count(r300->hw.vpi.cmd, vsf->length + 4 * (dest & 0xff));
1826 break;
1827
1828 case 2:
1829 R300_STATECHANGE(r300, vpp);
1830 for (i = 0; i < vsf->length; i++)
1831 r300->hw.vpp.cmd[R300_VPP_PARAM_0 + i + 4 * (dest & 0xff)] = (vsf->body.d[i]);
1832 bump_vpu_count(r300->hw.vpp.cmd, vsf->length + 4 * (dest & 0xff));
1833 break;
1834 case 4:
1835 R300_STATECHANGE(r300, vps);
1836 for (i = 0; i < vsf->length; i++)
1837 r300->hw.vps.cmd[1 + i + 4 * (dest & 0xff)] = (vsf->body.d[i]);
1838 bump_vpu_count(r300->hw.vps.cmd, vsf->length + 4 * (dest & 0xff));
1839 break;
1840 default:
1841 fprintf(stderr, "%s:%s don't know how to handle dest %04x\n", __FILE__, __FUNCTION__, dest);
1842 _mesa_exit(-1);
1843 }
1844 }
1845
1846 #define MIN3(a,b,c) ((a)<(b) ? MIN2(a, c): MIN2(b, c))
1847
1848 static void r300VapCntl(r300ContextPtr rmesa, GLuint input_count, GLuint output_count, GLuint temp_count)
1849 {
1850 int vtx_mem_size;
1851 int cmd_reserved = 0;
1852 int cmd_written = 0;
1853 drm_radeon_cmd_header_t *cmd = NULL;
1854 int pvs_num_slots;
1855 int pvs_num_cntrls;
1856
1857 /* Flush PVS engine before changing PVS_NUM_SLOTS, PVS_NUM_CNTRLS.
1858 * See r500 docs 6.5.2 */
1859 reg_start(R300_VAP_PVS_STATE_FLUSH_REG, 0);
1860 e32(0x00000000);
1861
1862 /* avoid division by zero */
1863 if (input_count == 0) input_count = 1;
1864 if (output_count == 0) output_count = 1;
1865 if (temp_count == 0) temp_count = 1;
1866
1867 if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515)
1868 vtx_mem_size = 128;
1869 else
1870 vtx_mem_size = 72;
1871
1872 pvs_num_slots = MIN3(10, vtx_mem_size/input_count, vtx_mem_size/output_count);
1873 pvs_num_cntrls = MIN2(6, vtx_mem_size/temp_count);
1874
1875 R300_STATECHANGE(rmesa, vap_cntl);
1876 if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) {
1877 rmesa->hw.vap_cntl.cmd[1] =
1878 (pvs_num_slots << R300_PVS_NUM_SLOTS_SHIFT) |
1879 (pvs_num_cntrls << R300_PVS_NUM_CNTLRS_SHIFT) |
1880 (12 << R300_VF_MAX_VTX_NUM_SHIFT);
1881 if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515)
1882 rmesa->hw.vap_cntl.cmd[1] |= R500_TCL_STATE_OPTIMIZATION;
1883 } else
1884 /* not sure about non-tcl */
1885 rmesa->hw.vap_cntl.cmd[1] = ((10 << R300_PVS_NUM_SLOTS_SHIFT) |
1886 (5 << R300_PVS_NUM_CNTLRS_SHIFT) |
1887 (5 << R300_VF_MAX_VTX_NUM_SHIFT));
1888
1889 if (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV515)
1890 rmesa->hw.vap_cntl.cmd[1] |= (2 << R300_PVS_NUM_FPUS_SHIFT);
1891 else if ((rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV530) ||
1892 (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV560))
1893 rmesa->hw.vap_cntl.cmd[1] |= (5 << R300_PVS_NUM_FPUS_SHIFT);
1894 else if (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R420)
1895 rmesa->hw.vap_cntl.cmd[1] |= (6 << R300_PVS_NUM_FPUS_SHIFT);
1896 else if ((rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R520) ||
1897 (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R580) ||
1898 (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV570))
1899 rmesa->hw.vap_cntl.cmd[1] |= (8 << R300_PVS_NUM_FPUS_SHIFT);
1900 else
1901 rmesa->hw.vap_cntl.cmd[1] |= (4 << R300_PVS_NUM_FPUS_SHIFT);
1902
1903 }
1904
1905 static void r300SetupDefaultVertexProgram(r300ContextPtr rmesa)
1906 {
1907 struct r300_vertex_shader_state *prog = &(rmesa->state.vertex_shader);
1908 GLuint o_reg = 0;
1909 GLuint i_reg = 0;
1910 int i;
1911 int inst_count = 0;
1912 int param_count = 0;
1913 int program_end = 0;
1914
1915 for (i = VERT_ATTRIB_POS; i < VERT_ATTRIB_MAX; i++) {
1916 if (rmesa->state.sw_tcl_inputs[i] != -1) {
1917 prog->program.body.i[program_end + 0] = PVS_OP_DST_OPERAND(VE_MULTIPLY, GL_FALSE, GL_FALSE, o_reg++, VSF_FLAG_ALL, PVS_DST_REG_OUT);
1918 prog->program.body.i[program_end + 1] = PVS_SRC_OPERAND(rmesa->state.sw_tcl_inputs[i], PVS_SRC_SELECT_X, PVS_SRC_SELECT_Y, PVS_SRC_SELECT_Z, PVS_SRC_SELECT_W, PVS_SRC_REG_INPUT, VSF_FLAG_NONE);
1919 prog->program.body.i[program_end + 2] = PVS_SRC_OPERAND(rmesa->state.sw_tcl_inputs[i], PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_REG_INPUT, VSF_FLAG_NONE);
1920 prog->program.body.i[program_end + 3] = PVS_SRC_OPERAND(rmesa->state.sw_tcl_inputs[i], PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_REG_INPUT, VSF_FLAG_NONE);
1921 program_end += 4;
1922 i_reg++;
1923 }
1924 }
1925
1926 prog->program.length = program_end;
1927
1928 r300SetupVertexProgramFragment(rmesa, R300_PVS_CODE_START,
1929 &(prog->program));
1930 inst_count = (prog->program.length / 4) - 1;
1931
1932 r300VapCntl(rmesa, i_reg, o_reg, 0);
1933
1934 R300_STATECHANGE(rmesa, pvs);
1935 rmesa->hw.pvs.cmd[R300_PVS_CNTL_1] =
1936 (0 << R300_PVS_FIRST_INST_SHIFT) |
1937 (inst_count << R300_PVS_XYZW_VALID_INST_SHIFT) |
1938 (inst_count << R300_PVS_LAST_INST_SHIFT);
1939 rmesa->hw.pvs.cmd[R300_PVS_CNTL_2] =
1940 (0 << R300_PVS_CONST_BASE_OFFSET_SHIFT) |
1941 (param_count << R300_PVS_MAX_CONST_ADDR_SHIFT);
1942 rmesa->hw.pvs.cmd[R300_PVS_CNTL_3] =
1943 (inst_count << R300_PVS_LAST_VTX_SRC_INST_SHIFT);
1944 }
1945
1946 static int bit_count (int x)
1947 {
1948 x = ((x & 0xaaaaaaaaU) >> 1) + (x & 0x55555555U);
1949 x = ((x & 0xccccccccU) >> 2) + (x & 0x33333333U);
1950 x = (x >> 16) + (x & 0xffff);
1951 x = ((x & 0xf0f0) >> 4) + (x & 0x0f0f);
1952 return (x >> 8) + (x & 0x00ff);
1953 }
1954
1955 static void r300SetupRealVertexProgram(r300ContextPtr rmesa)
1956 {
1957 GLcontext *ctx = rmesa->radeon.glCtx;
1958 struct r300_vertex_program *prog = (struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx);
1959 int inst_count = 0;
1960 int param_count = 0;
1961
1962 /* FIXME: r300SetupVertexProgramFragment */
1963 R300_STATECHANGE(rmesa, vpp);
1964 param_count =
1965 r300VertexProgUpdateParams(ctx,
1966 (struct r300_vertex_program_cont *)
1967 ctx->VertexProgram._Current,
1968 (float *)&rmesa->hw.vpp.
1969 cmd[R300_VPP_PARAM_0]);
1970 bump_vpu_count(rmesa->hw.vpp.cmd, param_count);
1971 param_count /= 4;
1972
1973 r300SetupVertexProgramFragment(rmesa, R300_PVS_CODE_START, &(prog->program));
1974 inst_count = (prog->program.length / 4) - 1;
1975
1976 r300VapCntl(rmesa, bit_count(prog->key.InputsRead),
1977 bit_count(prog->key.OutputsWritten), prog->num_temporaries);
1978
1979 R300_STATECHANGE(rmesa, pvs);
1980 rmesa->hw.pvs.cmd[R300_PVS_CNTL_1] =
1981 (0 << R300_PVS_FIRST_INST_SHIFT) |
1982 (inst_count << R300_PVS_XYZW_VALID_INST_SHIFT) |
1983 (inst_count << R300_PVS_LAST_INST_SHIFT);
1984 rmesa->hw.pvs.cmd[R300_PVS_CNTL_2] =
1985 (0 << R300_PVS_CONST_BASE_OFFSET_SHIFT) |
1986 (param_count << R300_PVS_MAX_CONST_ADDR_SHIFT);
1987 rmesa->hw.pvs.cmd[R300_PVS_CNTL_3] =
1988 (inst_count << R300_PVS_LAST_VTX_SRC_INST_SHIFT);
1989 }
1990
1991 static void r300SetupVertexProgram(r300ContextPtr rmesa)
1992 {
1993 GLcontext *ctx = rmesa->radeon.glCtx;
1994
1995 /* Reset state, in case we don't use something */
1996 ((drm_r300_cmd_header_t *) rmesa->hw.vpp.cmd)->vpu.count = 0;
1997 ((drm_r300_cmd_header_t *) rmesa->hw.vpi.cmd)->vpu.count = 0;
1998 ((drm_r300_cmd_header_t *) rmesa->hw.vps.cmd)->vpu.count = 0;
1999
2000 /* Not sure why this doesnt work...
2001 0x400 area might have something to do with pixel shaders as it appears right after pfs programming.
2002 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. */
2003 //setup_vertex_shader_fragment(rmesa, 0x406, &unk4);
2004 if (hw_tcl_on && ((struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx))->translated) {
2005 r300SetupRealVertexProgram(rmesa);
2006 } else {
2007 /* FIXME: This needs to be replaced by vertex shader generation code. */
2008 r300SetupDefaultVertexProgram(rmesa);
2009 }
2010
2011 }
2012
2013 /**
2014 * Enable/Disable states.
2015 *
2016 * \note Mesa already filters redundant calls to this function.
2017 */
2018 static void r300Enable(GLcontext * ctx, GLenum cap, GLboolean state)
2019 {
2020 if (RADEON_DEBUG & DEBUG_STATE)
2021 fprintf(stderr, "%s( %s = %s )\n", __FUNCTION__,
2022 _mesa_lookup_enum_by_nr(cap),
2023 state ? "GL_TRUE" : "GL_FALSE");
2024
2025 switch (cap) {
2026 case GL_TEXTURE_1D:
2027 case GL_TEXTURE_2D:
2028 case GL_TEXTURE_3D:
2029 /* empty */
2030 break;
2031 case GL_FOG:
2032 r300SetFogState(ctx, state);
2033 break;
2034 case GL_ALPHA_TEST:
2035 r300SetAlphaState(ctx);
2036 break;
2037 case GL_BLEND:
2038 case GL_COLOR_LOGIC_OP:
2039 r300SetBlendState(ctx);
2040 break;
2041 case GL_CLIP_PLANE0:
2042 case GL_CLIP_PLANE1:
2043 case GL_CLIP_PLANE2:
2044 case GL_CLIP_PLANE3:
2045 case GL_CLIP_PLANE4:
2046 case GL_CLIP_PLANE5:
2047 r300SetClipPlaneState(ctx, cap, state);
2048 break;
2049 case GL_DEPTH_TEST:
2050 r300SetDepthState(ctx);
2051 break;
2052 case GL_STENCIL_TEST:
2053 r300SetStencilState(ctx, state);
2054 break;
2055 case GL_CULL_FACE:
2056 r300UpdateCulling(ctx);
2057 break;
2058 case GL_POLYGON_OFFSET_POINT:
2059 case GL_POLYGON_OFFSET_LINE:
2060 case GL_POLYGON_OFFSET_FILL:
2061 r300SetPolygonOffsetState(ctx, state);
2062 break;
2063 default:
2064 radeonEnable(ctx, cap, state);
2065 break;
2066 }
2067 }
2068
2069 /**
2070 * Completely recalculates hardware state based on the Mesa state.
2071 */
2072 static void r300ResetHwState(r300ContextPtr r300)
2073 {
2074 GLcontext *ctx = r300->radeon.glCtx;
2075 int has_tcl = 1;
2076
2077 if (!(r300->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL))
2078 has_tcl = 0;
2079
2080 if (RADEON_DEBUG & DEBUG_STATE)
2081 fprintf(stderr, "%s\n", __FUNCTION__);
2082
2083 r300UpdateWindow(ctx);
2084
2085 r300ColorMask(ctx,
2086 ctx->Color.ColorMask[RCOMP],
2087 ctx->Color.ColorMask[GCOMP],
2088 ctx->Color.ColorMask[BCOMP], ctx->Color.ColorMask[ACOMP]);
2089
2090 r300Enable(ctx, GL_DEPTH_TEST, ctx->Depth.Test);
2091 r300DepthMask(ctx, ctx->Depth.Mask);
2092 r300DepthFunc(ctx, ctx->Depth.Func);
2093
2094 /* stencil */
2095 r300Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled);
2096 r300StencilMaskSeparate(ctx, 0, ctx->Stencil.WriteMask[0]);
2097 r300StencilFuncSeparate(ctx, 0, ctx->Stencil.Function[0],
2098 ctx->Stencil.Ref[0], ctx->Stencil.ValueMask[0]);
2099 r300StencilOpSeparate(ctx, 0, ctx->Stencil.FailFunc[0],
2100 ctx->Stencil.ZFailFunc[0],
2101 ctx->Stencil.ZPassFunc[0]);
2102
2103 r300UpdateCulling(ctx);
2104
2105 r300UpdateTextureState(ctx);
2106
2107 r300SetBlendState(ctx);
2108
2109 r300AlphaFunc(ctx, ctx->Color.AlphaFunc, ctx->Color.AlphaRef);
2110 r300Enable(ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled);
2111
2112 r300->hw.vte.cmd[1] = R300_VPORT_X_SCALE_ENA
2113 | R300_VPORT_X_OFFSET_ENA
2114 | R300_VPORT_Y_SCALE_ENA
2115 | R300_VPORT_Y_OFFSET_ENA
2116 | R300_VPORT_Z_SCALE_ENA
2117 | R300_VPORT_Z_OFFSET_ENA | R300_VTX_W0_FMT;
2118 r300->hw.vte.cmd[2] = 0x00000008;
2119
2120 r300->hw.vap_vf_max_vtx_indx.cmd[1] = 0x00FFFFFF;
2121 r300->hw.vap_vf_max_vtx_indx.cmd[2] = 0x00000000;
2122
2123 #ifdef MESA_LITTLE_ENDIAN
2124 r300->hw.vap_cntl_status.cmd[1] = R300_VC_NO_SWAP;
2125 #else
2126 r300->hw.vap_cntl_status.cmd[1] = R300_VC_32BIT_SWAP;
2127 #endif
2128
2129 /* disable VAP/TCL on non-TCL capable chips */
2130 if (!has_tcl)
2131 r300->hw.vap_cntl_status.cmd[1] |= R300_VAP_TCL_BYPASS;
2132
2133 r300->hw.vap_psc_sgn_norm_cntl.cmd[1] = 0xAAAAAAAA;
2134
2135 /* XXX: Other families? */
2136 if (has_tcl) {
2137 r300->hw.vap_clip_cntl.cmd[1] = R300_PS_UCP_MODE_DIST_COP;
2138
2139 r300->hw.vap_clip.cmd[1] = r300PackFloat32(1.0); /* X */
2140 r300->hw.vap_clip.cmd[2] = r300PackFloat32(1.0); /* X */
2141 r300->hw.vap_clip.cmd[3] = r300PackFloat32(1.0); /* Y */
2142 r300->hw.vap_clip.cmd[4] = r300PackFloat32(1.0); /* Y */
2143
2144 switch (r300->radeon.radeonScreen->chip_family) {
2145 case CHIP_FAMILY_R300:
2146 r300->hw.vap_pvs_vtx_timeout_reg.cmd[1] = R300_2288_R300;
2147 break;
2148 default:
2149 r300->hw.vap_pvs_vtx_timeout_reg.cmd[1] = R300_2288_RV350;
2150 break;
2151 }
2152 }
2153
2154 r300->hw.gb_enable.cmd[1] = R300_GB_POINT_STUFF_ENABLE
2155 | R300_GB_LINE_STUFF_ENABLE
2156 | R300_GB_TRIANGLE_STUFF_ENABLE;
2157
2158 r300->hw.gb_misc.cmd[R300_GB_MISC_MSPOS_0] = 0x66666666;
2159 r300->hw.gb_misc.cmd[R300_GB_MISC_MSPOS_1] = 0x06666666;
2160
2161 /* num pipes needs to be read back from the GB_PIPE_SELECT register
2162 * on r4xx/r5xx/rs4xx/rs6xx
2163 * should move this to the drm
2164 */
2165 r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] =
2166 R300_GB_TILE_ENABLE | R300_GB_TILE_SIZE_16 /*| R300_GB_SUBPIXEL_1_16*/;
2167 switch (r300->radeon.radeonScreen->chip_family) {
2168 case CHIP_FAMILY_R300:
2169 case CHIP_FAMILY_R350:
2170 r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] |=
2171 R300_GB_TILE_PIPE_COUNT_R300;
2172 break;
2173 case CHIP_FAMILY_RV350:
2174 case CHIP_FAMILY_RV515:
2175 case CHIP_FAMILY_RV530:
2176 case CHIP_FAMILY_RV410:
2177 r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] |=
2178 R300_GB_TILE_PIPE_COUNT_RV300;
2179 break;
2180 case CHIP_FAMILY_R420:
2181 case CHIP_FAMILY_R520:
2182 case CHIP_FAMILY_R580:
2183 case CHIP_FAMILY_RV560:
2184 case CHIP_FAMILY_RV570:
2185 r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] |=
2186 R300_GB_TILE_PIPE_COUNT_R420;
2187 break;
2188 default:
2189 r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] |=
2190 R300_GB_TILE_DISABLE; /* TODO: This disables tiling totally. I guess it happened accidentially. */
2191 break;
2192 }
2193
2194 /* XXX: set to 0 when fog is disabled? */
2195 r300->hw.gb_misc.cmd[R300_GB_MISC_SELECT] = R300_GB_FOG_SELECT_1_1_W;
2196
2197 /* XXX: Enable anti-aliasing? */
2198 r300->hw.gb_misc.cmd[R300_GB_MISC_AA_CONFIG] = GB_AA_CONFIG_AA_DISABLE;
2199
2200 r300->hw.ga_point_s0.cmd[1] = r300PackFloat32(0.0);
2201 r300->hw.ga_point_s0.cmd[2] = r300PackFloat32(0.0);
2202 r300->hw.ga_point_s0.cmd[3] = r300PackFloat32(1.0);
2203 r300->hw.ga_point_s0.cmd[4] = r300PackFloat32(1.0);
2204
2205 r300->hw.ga_triangle_stipple.cmd[1] = 0x00050005;
2206
2207 r300PointSize(ctx, 1.0);
2208
2209 r300->hw.ga_point_minmax.cmd[1] = 0x18000006;
2210 r300->hw.ga_point_minmax.cmd[2] = 0x00020006;
2211 r300->hw.ga_point_minmax.cmd[3] = r300PackFloat32(1.0 / 192.0);
2212
2213 r300LineWidth(ctx, 1.0);
2214
2215 r300->hw.ga_line_stipple.cmd[1] = 0;
2216 r300->hw.ga_line_stipple.cmd[2] = r300PackFloat32(0.0);
2217 r300->hw.ga_line_stipple.cmd[3] = r300PackFloat32(1.0);
2218
2219 r300ShadeModel(ctx, ctx->Light.ShadeModel);
2220
2221 r300PolygonMode(ctx, GL_FRONT, ctx->Polygon.FrontMode);
2222 r300PolygonMode(ctx, GL_BACK, ctx->Polygon.BackMode);
2223 r300->hw.zbias_cntl.cmd[1] = 0x00000000;
2224
2225 r300PolygonOffset(ctx, ctx->Polygon.OffsetFactor,
2226 ctx->Polygon.OffsetUnits);
2227 r300Enable(ctx, GL_POLYGON_OFFSET_POINT, ctx->Polygon.OffsetPoint);
2228 r300Enable(ctx, GL_POLYGON_OFFSET_LINE, ctx->Polygon.OffsetLine);
2229 r300Enable(ctx, GL_POLYGON_OFFSET_FILL, ctx->Polygon.OffsetFill);
2230
2231 r300->hw.su_depth_scale.cmd[1] = 0x4B7FFFFF;
2232 r300->hw.su_depth_scale.cmd[2] = 0x00000000;
2233
2234 r300->hw.sc_hyperz.cmd[1] = 0x0000001C;
2235 r300->hw.sc_hyperz.cmd[2] = 0x2DA49525;
2236
2237 r300->hw.sc_screendoor.cmd[1] = 0x00FFFFFF;
2238
2239 r300->hw.us_out_fmt.cmd[1] = 0x00001B01;
2240 r300->hw.us_out_fmt.cmd[2] = 0x00001B0F;
2241 r300->hw.us_out_fmt.cmd[3] = 0x00001B0F;
2242 r300->hw.us_out_fmt.cmd[4] = 0x00001B0F;
2243 r300->hw.us_out_fmt.cmd[5] = 0x00000001;
2244
2245 r300Enable(ctx, GL_FOG, ctx->Fog.Enabled);
2246 r300Fogfv(ctx, GL_FOG_MODE, NULL);
2247 r300Fogfv(ctx, GL_FOG_DENSITY, &ctx->Fog.Density);
2248 r300Fogfv(ctx, GL_FOG_START, &ctx->Fog.Start);
2249 r300Fogfv(ctx, GL_FOG_END, &ctx->Fog.End);
2250 r300Fogfv(ctx, GL_FOG_COLOR, ctx->Fog.Color);
2251 r300Fogfv(ctx, GL_FOG_COORDINATE_SOURCE_EXT, NULL);
2252
2253 r300->hw.fg_depth_src.cmd[1] = 0;
2254
2255 r300->hw.rb3d_cctl.cmd[1] = 0;
2256
2257 r300BlendColor(ctx, ctx->Color.BlendColor);
2258
2259 /* Again, r300ClearBuffer uses this */
2260 r300->hw.cb.cmd[R300_CB_OFFSET] =
2261 r300->radeon.state.color.drawOffset +
2262 r300->radeon.radeonScreen->fbLocation;
2263 r300->hw.cb.cmd[R300_CB_PITCH] = r300->radeon.state.color.drawPitch;
2264
2265 if (r300->radeon.radeonScreen->cpp == 4)
2266 r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_FORMAT_ARGB8888;
2267 else
2268 r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_FORMAT_RGB565;
2269
2270 if (r300->radeon.sarea->tiling_enabled)
2271 r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_TILE_ENABLE;
2272
2273 r300->hw.rb3d_dither_ctl.cmd[1] = 0;
2274 r300->hw.rb3d_dither_ctl.cmd[2] = 0;
2275 r300->hw.rb3d_dither_ctl.cmd[3] = 0;
2276 r300->hw.rb3d_dither_ctl.cmd[4] = 0;
2277 r300->hw.rb3d_dither_ctl.cmd[5] = 0;
2278 r300->hw.rb3d_dither_ctl.cmd[6] = 0;
2279 r300->hw.rb3d_dither_ctl.cmd[7] = 0;
2280 r300->hw.rb3d_dither_ctl.cmd[8] = 0;
2281 r300->hw.rb3d_dither_ctl.cmd[9] = 0;
2282
2283 r300->hw.rb3d_aaresolve_ctl.cmd[1] = 0;
2284
2285 r300->hw.rb3d_discard_src_pixel_lte_threshold.cmd[1] = 0x00000000;
2286 r300->hw.rb3d_discard_src_pixel_lte_threshold.cmd[2] = 0xffffffff;
2287
2288 r300->hw.zb.cmd[R300_ZB_OFFSET] =
2289 r300->radeon.radeonScreen->depthOffset +
2290 r300->radeon.radeonScreen->fbLocation;
2291 r300->hw.zb.cmd[R300_ZB_PITCH] = r300->radeon.radeonScreen->depthPitch;
2292
2293 if (r300->radeon.sarea->tiling_enabled) {
2294 /* XXX: Turn off when clearing buffers ? */
2295 r300->hw.zb.cmd[R300_ZB_PITCH] |= R300_DEPTHMACROTILE_ENABLE;
2296
2297 if (ctx->Visual.depthBits == 24)
2298 r300->hw.zb.cmd[R300_ZB_PITCH] |=
2299 R300_DEPTHMICROTILE_TILED;
2300 }
2301
2302 r300->hw.zb_depthclearvalue.cmd[1] = 0;
2303
2304 r300->hw.unk4F30.cmd[1] = 0;
2305 r300->hw.unk4F30.cmd[2] = 0;
2306
2307 r300->hw.zb_hiz_offset.cmd[1] = 0;
2308
2309 r300->hw.zb_hiz_pitch.cmd[1] = 0;
2310
2311 if (has_tcl) {
2312 r300->hw.vps.cmd[R300_VPS_ZERO_0] = 0;
2313 r300->hw.vps.cmd[R300_VPS_ZERO_1] = 0;
2314 r300->hw.vps.cmd[R300_VPS_POINTSIZE] = r300PackFloat32(1.0);
2315 r300->hw.vps.cmd[R300_VPS_ZERO_3] = 0;
2316 }
2317
2318 r300->hw.all_dirty = GL_TRUE;
2319 }
2320
2321 void r300UpdateShaders(r300ContextPtr rmesa)
2322 {
2323 GLcontext *ctx;
2324 struct r300_vertex_program *vp;
2325 int i;
2326
2327 ctx = rmesa->radeon.glCtx;
2328
2329 if (rmesa->NewGLState && hw_tcl_on) {
2330 rmesa->NewGLState = 0;
2331
2332 for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) {
2333 rmesa->temp_attrib[i] =
2334 TNL_CONTEXT(ctx)->vb.AttribPtr[i];
2335 TNL_CONTEXT(ctx)->vb.AttribPtr[i] =
2336 &rmesa->dummy_attrib[i];
2337 }
2338
2339 _tnl_UpdateFixedFunctionProgram(ctx);
2340
2341 for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) {
2342 TNL_CONTEXT(ctx)->vb.AttribPtr[i] =
2343 rmesa->temp_attrib[i];
2344 }
2345
2346 r300SelectVertexShader(rmesa);
2347 vp = (struct r300_vertex_program *)
2348 CURRENT_VERTEX_SHADER(ctx);
2349 /*if (vp->translated == GL_FALSE)
2350 r300TranslateVertexShader(vp); */
2351 if (vp->translated == GL_FALSE) {
2352 fprintf(stderr, "Failing back to sw-tcl\n");
2353 hw_tcl_on = future_hw_tcl_on = 0;
2354 r300ResetHwState(rmesa);
2355
2356 r300UpdateStateParameters(ctx, _NEW_PROGRAM);
2357 return;
2358 }
2359 }
2360 r300UpdateStateParameters(ctx, _NEW_PROGRAM);
2361 }
2362
2363 static void r300SetupPixelShader(r300ContextPtr rmesa)
2364 {
2365 GLcontext *ctx = rmesa->radeon.glCtx;
2366 struct r300_fragment_program *fp = (struct r300_fragment_program *)
2367 (char *)ctx->FragmentProgram._Current;
2368 int i, k;
2369
2370 if (!fp) /* should only happenen once, just after context is created */
2371 return;
2372
2373 r300TranslateFragmentShader(rmesa, fp);
2374 if (!fp->translated) {
2375 fprintf(stderr, "%s: No valid fragment shader, exiting\n",
2376 __FUNCTION__);
2377 return;
2378 }
2379
2380 R300_STATECHANGE(rmesa, fpi[0]);
2381 rmesa->hw.fpi[0].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_RGB_INST_0, fp->alu_end + 1);
2382 for (i = 0; i <= fp->alu_end; i++) {
2383 rmesa->hw.fpi[0].cmd[R300_FPI_INSTR_0 + i] = fp->alu.inst[i].inst0;
2384 }
2385
2386 R300_STATECHANGE(rmesa, fpi[1]);
2387 rmesa->hw.fpi[1].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_RGB_ADDR_0, fp->alu_end + 1);
2388 for (i = 0; i <= fp->alu_end; i++) {
2389 rmesa->hw.fpi[1].cmd[R300_FPI_INSTR_0 + i] = fp->alu.inst[i].inst1;
2390 }
2391
2392 R300_STATECHANGE(rmesa, fpi[2]);
2393 rmesa->hw.fpi[2].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_ALPHA_INST_0, fp->alu_end + 1);
2394 for (i = 0; i <= fp->alu_end; i++) {
2395 rmesa->hw.fpi[2].cmd[R300_FPI_INSTR_0 + i] = fp->alu.inst[i].inst2;
2396 }
2397
2398 R300_STATECHANGE(rmesa, fpi[3]);
2399 rmesa->hw.fpi[3].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_ALPHA_ADDR_0, fp->alu_end + 1);
2400 for (i = 0; i <= fp->alu_end; i++) {
2401 rmesa->hw.fpi[3].cmd[R300_FPI_INSTR_0 + i] = fp->alu.inst[i].inst3;
2402 }
2403
2404 R300_STATECHANGE(rmesa, fp);
2405 rmesa->hw.fp.cmd[R300_FP_CNTL0] = fp->cur_node | (fp->first_node_has_tex << 3);
2406 rmesa->hw.fp.cmd[R300_FP_CNTL1] = fp->max_temp_idx;
2407 rmesa->hw.fp.cmd[R300_FP_CNTL2] =
2408 (fp->alu_offset << R300_PFS_CNTL_ALU_OFFSET_SHIFT) |
2409 (fp->alu_end << R300_PFS_CNTL_ALU_END_SHIFT) |
2410 (fp->tex_offset << R300_PFS_CNTL_TEX_OFFSET_SHIFT) |
2411 (fp->tex_end << R300_PFS_CNTL_TEX_END_SHIFT);
2412 /* I just want to say, the way these nodes are stored.. weird.. */
2413 for (i = 0, k = (4 - (fp->cur_node + 1)); i < 4; i++, k++) {
2414 if (i < (fp->cur_node + 1)) {
2415 rmesa->hw.fp.cmd[R300_FP_NODE0 + k] =
2416 (fp->node[i].alu_offset << R300_ALU_START_SHIFT) |
2417 (fp->node[i].alu_end << R300_ALU_SIZE_SHIFT) |
2418 (fp->node[i].tex_offset << R300_TEX_START_SHIFT) |
2419 (fp->node[i].tex_end << R300_TEX_SIZE_SHIFT) |
2420 fp->node[i].flags;
2421 } else {
2422 rmesa->hw.fp.cmd[R300_FP_NODE0 + (3 - i)] = 0;
2423 }
2424 }
2425
2426 R300_STATECHANGE(rmesa, fpp);
2427 rmesa->hw.fpp.cmd[R300_FPP_CMD_0] = cmdpacket0(R300_PFS_PARAM_0_X, fp->const_nr * 4);
2428 for (i = 0; i < fp->const_nr; i++) {
2429 rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 0] = r300PackFloat24(fp->constant[i][0]);
2430 rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 1] = r300PackFloat24(fp->constant[i][1]);
2431 rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 2] = r300PackFloat24(fp->constant[i][2]);
2432 rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 3] = r300PackFloat24(fp->constant[i][3]);
2433 }
2434 }
2435
2436 #define bump_r500fp_count(ptr, new_count) do{\
2437 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
2438 int _nc=(new_count)/6; \
2439 assert(_nc < 256); \
2440 if(_nc>_p->r500fp.count)_p->r500fp.count=_nc;\
2441 } while(0)
2442
2443 #define bump_r500fp_const_count(ptr, new_count) do{\
2444 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
2445 int _nc=(new_count)/4; \
2446 assert(_nc < 256); \
2447 if(_nc>_p->r500fp.count)_p->r500fp.count=_nc;\
2448 } while(0)
2449
2450 static void r500SetupPixelShader(r300ContextPtr rmesa)
2451 {
2452 GLcontext *ctx = rmesa->radeon.glCtx;
2453 struct r500_fragment_program *fp = (struct r500_fragment_program *)
2454 (char *)ctx->FragmentProgram._Current;
2455 int i;
2456
2457 if (!fp) /* should only happenen once, just after context is created */
2458 return;
2459
2460 r500TranslateFragmentShader(rmesa, fp);
2461 if (!fp->translated) {
2462 fprintf(stderr, "%s: No valid fragment shader, exiting\n",
2463 __FUNCTION__);
2464 return;
2465 }
2466
2467 R300_STATECHANGE(rmesa, fp);
2468 rmesa->hw.fp.cmd[R500_FP_PIXSIZE] = fp->max_temp_idx;
2469
2470 R300_STATECHANGE(rmesa, r500fp);
2471 /* Emit our shader... */
2472 for (i = 0; i < fp->cs->nrslots; i++) {
2473 rmesa->hw.r500fp.cmd[i*6+1] = fp->inst[i].inst0;
2474 rmesa->hw.r500fp.cmd[i*6+2] = fp->inst[i].inst1;
2475 rmesa->hw.r500fp.cmd[i*6+3] = fp->inst[i].inst2;
2476 rmesa->hw.r500fp.cmd[i*6+4] = fp->inst[i].inst3;
2477 rmesa->hw.r500fp.cmd[i*6+5] = fp->inst[i].inst4;
2478 rmesa->hw.r500fp.cmd[i*6+6] = fp->inst[i].inst5;
2479 }
2480
2481 bump_r500fp_count(rmesa->hw.r500fp.cmd, fp->cs->nrslots * 6);
2482
2483
2484 R300_STATECHANGE(rmesa, r500fp_const);
2485 for (i = 0; i < fp->const_nr; i++) {
2486 rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 0] = r300PackFloat32(fp->constant[i][0]);
2487 rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 1] = r300PackFloat32(fp->constant[i][1]);
2488 rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 2] = r300PackFloat32(fp->constant[i][2]);
2489 rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 3] = r300PackFloat32(fp->constant[i][3]);
2490 }
2491 bump_r500fp_const_count(rmesa->hw.r500fp_const.cmd, fp->const_nr * 4);
2492
2493 }
2494
2495 void r300UpdateShaderStates(r300ContextPtr rmesa)
2496 {
2497 GLcontext *ctx;
2498 ctx = rmesa->radeon.glCtx;
2499
2500 r300UpdateTextureState(ctx);
2501
2502 if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515)
2503 r500SetupPixelShader(rmesa);
2504 else
2505 r300SetupPixelShader(rmesa);
2506 r300SetupTextures(ctx);
2507
2508 if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515)
2509 r500SetupRSUnit(ctx);
2510 else
2511 r300SetupRSUnit(ctx);
2512
2513 if ((rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL))
2514 r300SetupVertexProgram(rmesa);
2515
2516 }
2517
2518 /**
2519 * Called by Mesa after an internal state update.
2520 */
2521 static void r300InvalidateState(GLcontext * ctx, GLuint new_state)
2522 {
2523 r300ContextPtr r300 = R300_CONTEXT(ctx);
2524
2525 _swrast_InvalidateState(ctx, new_state);
2526 _swsetup_InvalidateState(ctx, new_state);
2527 _vbo_InvalidateState(ctx, new_state);
2528 _tnl_InvalidateState(ctx, new_state);
2529 _ae_invalidate_state(ctx, new_state);
2530
2531 if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) {
2532 r300UpdateDrawBuffer(ctx);
2533 }
2534
2535 r300UpdateStateParameters(ctx, new_state);
2536
2537 r300->NewGLState |= new_state;
2538 }
2539
2540 /**
2541 * Calculate initial hardware state and register state functions.
2542 * Assumes that the command buffer and state atoms have been
2543 * initialized already.
2544 */
2545 void r300InitState(r300ContextPtr r300)
2546 {
2547 GLcontext *ctx = r300->radeon.glCtx;
2548 GLuint depth_fmt;
2549
2550 radeonInitState(&r300->radeon);
2551
2552 switch (ctx->Visual.depthBits) {
2553 case 16:
2554 r300->state.depth.scale = 1.0 / (GLfloat) 0xffff;
2555 depth_fmt = R300_DEPTHFORMAT_16BIT_INT_Z;
2556 r300->state.stencil.clear = 0x00000000;
2557 break;
2558 case 24:
2559 r300->state.depth.scale = 1.0 / (GLfloat) 0xffffff;
2560 depth_fmt = R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL;
2561 r300->state.stencil.clear = 0x00ff0000;
2562 break;
2563 default:
2564 fprintf(stderr, "Error: Unsupported depth %d... exiting\n",
2565 ctx->Visual.depthBits);
2566 _mesa_exit(-1);
2567 }
2568
2569 /* Only have hw stencil when depth buffer is 24 bits deep */
2570 r300->state.stencil.hw_stencil = (ctx->Visual.stencilBits > 0 &&
2571 ctx->Visual.depthBits == 24);
2572
2573 memset(&(r300->state.texture), 0, sizeof(r300->state.texture));
2574
2575 r300ResetHwState(r300);
2576 }
2577
2578 static void r300RenderMode(GLcontext * ctx, GLenum mode)
2579 {
2580 r300ContextPtr rmesa = R300_CONTEXT(ctx);
2581 (void)rmesa;
2582 (void)mode;
2583 }
2584
2585 void r300UpdateClipPlanes( GLcontext *ctx )
2586 {
2587 r300ContextPtr rmesa = R300_CONTEXT(ctx);
2588 GLuint p;
2589
2590 for (p = 0; p < ctx->Const.MaxClipPlanes; p++) {
2591 if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
2592 GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p];
2593
2594 R300_STATECHANGE( rmesa, vpucp[p] );
2595 rmesa->hw.vpucp[p].cmd[R300_VPUCP_X] = ip[0];
2596 rmesa->hw.vpucp[p].cmd[R300_VPUCP_Y] = ip[1];
2597 rmesa->hw.vpucp[p].cmd[R300_VPUCP_Z] = ip[2];
2598 rmesa->hw.vpucp[p].cmd[R300_VPUCP_W] = ip[3];
2599 }
2600 }
2601 }
2602
2603 /**
2604 * Initialize driver's state callback functions
2605 */
2606 void r300InitStateFuncs(struct dd_function_table *functions)
2607 {
2608 radeonInitStateFuncs(functions);
2609
2610 functions->UpdateState = r300InvalidateState;
2611 functions->AlphaFunc = r300AlphaFunc;
2612 functions->BlendColor = r300BlendColor;
2613 functions->BlendEquationSeparate = r300BlendEquationSeparate;
2614 functions->BlendFuncSeparate = r300BlendFuncSeparate;
2615 functions->Enable = r300Enable;
2616 functions->ColorMask = r300ColorMask;
2617 functions->DepthFunc = r300DepthFunc;
2618 functions->DepthMask = r300DepthMask;
2619 functions->CullFace = r300CullFace;
2620 functions->Fogfv = r300Fogfv;
2621 functions->FrontFace = r300FrontFace;
2622 functions->ShadeModel = r300ShadeModel;
2623
2624 /* Stencil related */
2625 functions->ClearStencil = r300ClearStencil;
2626 functions->StencilFuncSeparate = r300StencilFuncSeparate;
2627 functions->StencilMaskSeparate = r300StencilMaskSeparate;
2628 functions->StencilOpSeparate = r300StencilOpSeparate;
2629
2630 /* Viewport related */
2631 functions->Viewport = r300Viewport;
2632 functions->DepthRange = r300DepthRange;
2633 functions->PointSize = r300PointSize;
2634 functions->LineWidth = r300LineWidth;
2635
2636 functions->PolygonOffset = r300PolygonOffset;
2637 functions->PolygonMode = r300PolygonMode;
2638
2639 functions->RenderMode = r300RenderMode;
2640
2641 functions->ClipPlane = r300ClipPlane;
2642 }