51d721cdb7948a679a54806f59716ee526e98bf8
[mesa.git] / src / mesa / drivers / dri / r300 / r300_render.c
1 /**************************************************************************
2
3 Copyright (C) 2004 Nicolai Haehnle.
4
5 All Rights Reserved.
6
7 Permission is hereby granted, free of charge, to any person obtaining a
8 copy of this software and associated documentation files (the "Software"),
9 to deal in the Software without restriction, including without limitation
10 on the rights to use, copy, modify, merge, publish, distribute, sub
11 license, and/or sell copies of the Software, and to permit persons to whom
12 the Software is furnished to do so, subject to the following conditions:
13
14 The above copyright notice and this permission notice (including the next
15 paragraph) shall be included in all copies or substantial portions of the
16 Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
22 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 USE OR OTHER DEALINGS IN THE SOFTWARE.
25
26 **************************************************************************/
27
28 /*
29 * Authors:
30 * Nicolai Haehnle <prefect_@gmx.net>
31 */
32
33 #include "glheader.h"
34 #include "state.h"
35 #include "imports.h"
36 #include "enums.h"
37 #include "macros.h"
38 #include "context.h"
39 #include "dd.h"
40 #include "simple_list.h"
41
42 #include "api_arrayelt.h"
43 #include "swrast/swrast.h"
44 #include "swrast_setup/swrast_setup.h"
45 #include "array_cache/acache.h"
46 #include "tnl/tnl.h"
47
48 #include "radeon_reg.h"
49 #include "radeon_macros.h"
50 #include "radeon_ioctl.h"
51 #include "radeon_state.h"
52 #include "r300_context.h"
53 #include "r300_ioctl.h"
54 #include "r300_state.h"
55 #include "r300_reg.h"
56 #include "r300_program.h"
57 #include "r300_tex.h"
58
59 #include "r300_emit.h"
60
61 #if 0
62 /* Turns out we might not need this after all... */
63 static void update_zbias(GLcontext * ctx, int prim)
64 {
65 r300ContextPtr rmesa = R300_CONTEXT(ctx);
66 int enabled = 0;
67 uint32_t values[4];
68 //return ;
69 switch(prim & PRIM_MODE_MASK) {
70 case GL_POINTS:
71 if(ctx->Polygon.OffsetPoint == GL_TRUE)
72 enabled=1;
73 break;
74 case GL_LINES:
75 case GL_LINE_STRIP:
76 case GL_LINE_LOOP:
77 if(ctx->Polygon.OffsetLine == GL_TRUE)
78 enabled=1;
79 break;
80 case GL_TRIANGLES:
81 case GL_TRIANGLE_STRIP:
82 case GL_TRIANGLE_FAN:
83 case GL_QUADS:
84 case GL_QUAD_STRIP:
85 case GL_POLYGON:
86 if(ctx->Polygon.OffsetFill == GL_TRUE)
87 enabled=1;
88 break;
89 default:
90 fprintf(stderr, "%s:%s Do not know how to handle primitive %02x - help me !\n",
91 __FILE__, __FUNCTION__,
92 prim & PRIM_MODE_MASK);
93
94 }
95
96 if(enabled){
97 values[0]=values[2]=r300PackFloat32(ctx->Polygon.OffsetFactor * 12.0);
98 values[1]=values[3]=r300PackFloat32(ctx->Polygon.OffsetUnits * 4.0);
99 }else{
100 values[0]=values[2]=r300PackFloat32(0.0);
101 values[1]=values[3]=r300PackFloat32(0.0);
102 }
103
104 if(values[0] != rmesa->hw.zbs.cmd[R300_ZBS_T_FACTOR] ||
105 values[1] != rmesa->hw.zbs.cmd[R300_ZBS_T_CONSTANT] ||
106 values[2] != rmesa->hw.zbs.cmd[R300_ZBS_W_FACTOR] ||
107 values[3] != rmesa->hw.zbs.cmd[R300_ZBS_W_CONSTANT]){
108
109 R300_STATECHANGE(rmesa, zbs);
110 rmesa->hw.zbs.cmd[R300_ZBS_T_FACTOR] = values[0];
111 rmesa->hw.zbs.cmd[R300_ZBS_T_CONSTANT] = values[1];
112 rmesa->hw.zbs.cmd[R300_ZBS_W_FACTOR] = values[2];
113 rmesa->hw.zbs.cmd[R300_ZBS_W_CONSTANT] = values[3];
114
115 }
116 }
117 #endif
118
119 /**********************************************************************
120 * Hardware rasterization
121 *
122 * When we fell back to software TCL, we still try to use the
123 * rasterization hardware for rendering.
124 **********************************************************************/
125
126 static int r300_get_primitive_type(r300ContextPtr rmesa, GLcontext *ctx, int prim)
127 {
128 TNLcontext *tnl = TNL_CONTEXT(ctx);
129 struct vertex_buffer *VB = &tnl->vb;
130 GLuint i;
131 int type=-1;
132
133 switch (prim & PRIM_MODE_MASK) {
134 case GL_POINTS:
135 type=R300_VAP_VF_CNTL__PRIM_POINTS;
136 break;
137 case GL_LINES:
138 type=R300_VAP_VF_CNTL__PRIM_LINES;
139 break;
140 case GL_LINE_STRIP:
141 type=R300_VAP_VF_CNTL__PRIM_LINE_STRIP;
142 break;
143 case GL_LINE_LOOP:
144 type=R300_VAP_VF_CNTL__PRIM_LINE_LOOP;
145 break;
146 case GL_TRIANGLES:
147 type=R300_VAP_VF_CNTL__PRIM_TRIANGLES;
148 break;
149 case GL_TRIANGLE_STRIP:
150 type=R300_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP;
151 break;
152 case GL_TRIANGLE_FAN:
153 type=R300_VAP_VF_CNTL__PRIM_TRIANGLE_FAN;
154 break;
155 case GL_QUADS:
156 type=R300_VAP_VF_CNTL__PRIM_QUADS;
157 break;
158 case GL_QUAD_STRIP:
159 type=R300_VAP_VF_CNTL__PRIM_QUAD_STRIP;
160 break;
161 case GL_POLYGON:
162 type=R300_VAP_VF_CNTL__PRIM_POLYGON;
163 break;
164 default:
165 fprintf(stderr, "%s:%s Do not know how to handle primitive %02x - help me !\n",
166 __FILE__, __FUNCTION__,
167 prim & PRIM_MODE_MASK);
168 return -1;
169 break;
170 }
171 return type;
172 }
173
174 static int r300_get_num_verts(r300ContextPtr rmesa,
175 GLcontext *ctx,
176 int num_verts,
177 int prim)
178 {
179 TNLcontext *tnl = TNL_CONTEXT(ctx);
180 struct vertex_buffer *VB = &tnl->vb;
181 GLuint i;
182 int type=-1, verts_off=0;
183 char *name="UNKNOWN";
184
185 switch (prim & PRIM_MODE_MASK) {
186 case GL_POINTS:
187 name="P";
188 verts_off = 0;
189 break;
190 case GL_LINES:
191 name="L";
192 verts_off = num_verts % 2;
193 break;
194 case GL_LINE_STRIP:
195 name="LS";
196 verts_off = num_verts % 2;
197 break;
198 case GL_LINE_LOOP:
199 name="LL";
200 verts_off = num_verts % 2;
201 break;
202 case GL_TRIANGLES:
203 name="T";
204 verts_off = num_verts % 3;
205 break;
206 case GL_TRIANGLE_STRIP:
207 name="TS";
208 if(num_verts < 3)
209 verts_off = num_verts;
210 break;
211 case GL_TRIANGLE_FAN:
212 name="TF";
213 if(num_verts < 3)
214 verts_off = num_verts;
215 break;
216 case GL_QUADS:
217 name="Q";
218 verts_off = num_verts % 4;
219 break;
220 case GL_QUAD_STRIP:
221 name="QS";
222 if(num_verts < 4)
223 verts_off = num_verts;
224 else
225 verts_off = num_verts % 2;
226 break;
227 case GL_POLYGON:
228 name="P";
229 if(num_verts < 3)
230 verts_off = num_verts;
231 break;
232 default:
233 fprintf(stderr, "%s:%s Do not know how to handle primitive %02x - help me !\n",
234 __FILE__, __FUNCTION__,
235 prim & PRIM_MODE_MASK);
236 return -1;
237 break;
238 }
239
240 if(num_verts - verts_off == 0){
241 WARN_ONCE("user error: Need more than %d vertices to draw primitive %s !\n", num_verts, name);
242 return 0;
243 }
244
245 if(verts_off > 0){
246 WARN_ONCE("user error: %d is not a valid number of vertices for primitive %s !\n", num_verts, name);
247 }
248
249 return num_verts - verts_off;
250 }
251
252 /* This function compiles GL context into state registers that
253 describe data routing inside of R300 pipeline.
254
255 In particular, it programs input_route, output_vtx_fmt, texture
256 unit configuration and gb_output_vtx_fmt
257
258 This function encompasses setup_AOS() from r300_lib.c
259 */
260
261
262
263
264 /* Immediate implementation - vertex data is sent via command stream */
265
266 static GLfloat default_vector[4]={0.0, 0.0, 0.0, 1.0};
267
268 #define output_vector(v, i) \
269 { \
270 int _i; \
271 for(_i=0;_i<v->size;_i++){ \
272 efloat(VEC_ELT(v, GLfloat, i)[_i]); \
273 } \
274 for(_i=v->size;_i<4;_i++){ \
275 efloat(default_vector[_i]); \
276 } \
277 }
278
279 /* Immediate implementation - vertex data is sent via command stream */
280
281 static void r300_render_immediate_primitive(r300ContextPtr rmesa,
282 GLcontext *ctx,
283 int start,
284 int end,
285 int prim)
286 {
287 TNLcontext *tnl = TNL_CONTEXT(ctx);
288 struct vertex_buffer *VB = &tnl->vb;
289 GLuint i, render_inputs;
290 int k, type, num_verts;
291 LOCAL_VARS
292
293 type=r300_get_primitive_type(rmesa, ctx, prim);
294 num_verts=r300_get_num_verts(rmesa, ctx, end-start, prim);
295
296 #if 0
297 fprintf(stderr,"ObjPtr: size=%d stride=%d\n",
298 VB->ObjPtr->size, VB->ObjPtr->stride);
299 fprintf(stderr,"ColorPtr[0]: size=%d stride=%d\n",
300 VB->ColorPtr[0]->size, VB->ColorPtr[0]->stride);
301 fprintf(stderr,"TexCoordPtr[0]: size=%d stride=%d\n",
302 VB->TexCoordPtr[0]->size, VB->TexCoordPtr[0]->stride);
303 #endif
304
305 if(type<0 || num_verts <= 0)return;
306
307 if(!VB->ObjPtr){
308 WARN_ONCE("FIXME: Don't know how to handle GL_ARB_vertex_buffer_object correctly\n");
309 return;
310 }
311 /* A packet cannot have more than 16383 data words.. */
312 if((num_verts*4*rmesa->state.aos_count)>16380){
313 WARN_ONCE("Too many vertices to paint. Fix me !\n");
314 return;
315 }
316
317 //fprintf(stderr, "aos_count=%d start=%d end=%d\n", rmesa->state.aos_count, start, end);
318
319 if(rmesa->state.aos_count==0){
320 WARN_ONCE("Aeiee ! aos_count==0, while it shouldn't. Skipping rendering\n");
321 return;
322 }
323
324 render_inputs = rmesa->state.render_inputs;
325
326 if(!render_inputs){
327 WARN_ONCE("Aeiee ! render_inputs==0. Skipping rendering.\n");
328 return;
329 }
330
331 start_immediate_packet(num_verts, type, 4*rmesa->state.aos_count);
332
333 for(i=start;i<start+num_verts;i++){
334 #if 0
335 fprintf(stderr, "* (%f %f %f %f) (%f %f %f %f)\n",
336 VEC_ELT(VB->ObjPtr, GLfloat, i)[0],
337 VEC_ELT(VB->ObjPtr, GLfloat, i)[1],
338 VEC_ELT(VB->ObjPtr, GLfloat, i)[2],
339 VEC_ELT(VB->ObjPtr, GLfloat, i)[3],
340
341 VEC_ELT(VB->ColorPtr[0], GLfloat, i)[0],
342 VEC_ELT(VB->ColorPtr[0], GLfloat, i)[1],
343 VEC_ELT(VB->ColorPtr[0], GLfloat, i)[2],
344 VEC_ELT(VB->ColorPtr[0], GLfloat, i)[3]
345 );
346 #endif
347
348
349 /* coordinates */
350 if(render_inputs & _TNL_BIT_POS)
351 output_vector(VB->ObjPtr, i);
352 if(render_inputs & _TNL_BIT_NORMAL)
353 output_vector(VB->NormalPtr, i);
354
355 /* color components */
356 if(render_inputs & _TNL_BIT_COLOR0)
357 output_vector(VB->ColorPtr[0], i);
358 if(render_inputs & _TNL_BIT_COLOR1)
359 output_vector(VB->SecondaryColorPtr[0], i);
360
361 if(render_inputs & _TNL_BIT_FOG)
362 output_vector(VB->FogCoordPtr, i);
363
364 /* texture coordinates */
365 for(k=0;k < ctx->Const.MaxTextureUnits;k++)
366 if(render_inputs & (_TNL_BIT_TEX0<<k))
367 output_vector(VB->TexCoordPtr[k], i);
368
369 if(render_inputs & _TNL_BIT_INDEX)
370 output_vector(VB->IndexPtr[0], i);
371 if(render_inputs & _TNL_BIT_POINTSIZE)
372 output_vector(VB->PointSizePtr, i);
373 }
374
375 }
376
377
378 static GLboolean r300_run_immediate_render(GLcontext *ctx,
379 struct tnl_pipeline_stage *stage)
380 {
381 r300ContextPtr rmesa = R300_CONTEXT(ctx);
382 TNLcontext *tnl = TNL_CONTEXT(ctx);
383 struct vertex_buffer *VB = &tnl->vb;
384 GLuint i;
385 /* Only do 2d textures */
386 struct gl_texture_object *to=ctx->Texture.Unit[0].Current2D;
387 r300TexObjPtr t=to->DriverData;
388 LOCAL_VARS
389
390
391 /* Update texture state - needs to be done only when actually changed..
392 All the time for now.. */
393
394
395 if (RADEON_DEBUG == DEBUG_PRIMS)
396 fprintf(stderr, "%s\n", __FUNCTION__);
397
398 #if 1 /* we need this, somehow */
399 /* Flush state - make sure command buffer is nice and large */
400 r300Flush(ctx);
401 /* Make sure we have enough space */
402 #else
403 /* Count is very imprecize, but should be good upper bound */
404 r300EnsureCmdBufSpace(rmesa, rmesa->hw.max_state_size + 4+2+30
405 +VB->PrimitiveCount*(1+8)+VB->Count*4*rmesa->state.texture.tc_count+4, __FUNCTION__);
406 #endif
407
408 /* needed before starting 3d operation .. */
409 reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
410 e32(0x0000000a);
411
412 reg_start(0x4f18,0);
413 e32(0x00000003);
414
415
416 #if 0 /* looks like the Z offset issue got fixed */
417 rmesa->hw.vte.cmd[1] = R300_VPORT_X_SCALE_ENA
418 | R300_VPORT_X_OFFSET_ENA
419 | R300_VPORT_Y_SCALE_ENA
420 | R300_VPORT_Y_OFFSET_ENA
421 | R300_VTX_W0_FMT;
422 R300_STATECHANGE(rmesa, vte);
423 #endif
424
425
426
427 /* Magic register - note it is right after 20b0 */
428
429
430 if(rmesa->state.texture.tc_count>0){
431 reg_start(0x20b4,0);
432 e32(0x0000000c);
433
434 }
435
436 r300EmitState(rmesa);
437
438 #if 0
439 reg_start(R300_RB3D_COLORMASK, 0);
440 e32(0xf);
441
442 vsf_start_fragment(0x406, 4);
443 efloat(0.0);
444 efloat(0.0);
445 efloat(0.0);
446 efloat(1.0);
447
448 vsf_start_fragment(0x400, 4);
449 efloat(0.0);
450 efloat(0.0);
451 efloat(0.0);
452 efloat(1.0);
453 #endif
454
455 /* We need LOAD_VBPNTR to setup AOS_ATTR fields.. the offsets are irrelevant */
456 r300EmitLOAD_VBPNTR(rmesa, 0);
457
458 for(i=0; i < VB->PrimitiveCount; i++){
459 GLuint prim = VB->Primitive[i].mode;
460 GLuint start = VB->Primitive[i].start;
461 GLuint length = VB->Primitive[i].count;
462
463 r300_render_immediate_primitive(rmesa, ctx, start, start + length, prim);
464 }
465
466 /* This sequence is required after any 3d drawing packet
467 I suspect it work arounds a bug (or deficiency) in hardware */
468
469 reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
470 e32(0x0000000a);
471
472 reg_start(0x4f18,0);
473 e32(0x00000003);
474
475 return GL_FALSE;
476 }
477
478
479 /* vertex buffer implementation */
480
481 /* We use the start part of GART texture buffer for vertices */
482
483
484 static void upload_vertex_buffer(r300ContextPtr rmesa, GLcontext *ctx)
485 {
486 TNLcontext *tnl = TNL_CONTEXT(ctx);
487 struct vertex_buffer *VB = &tnl->vb;
488 int idx=0;
489 int i,j,k;
490 radeonScreenPtr rsp=rmesa->radeon.radeonScreen;
491 GLuint render_inputs;
492
493 /* A hack - we don't want to overwrite vertex buffers, so we
494 just use AGP space for them.. Fix me ! */
495 static int offset=0;
496 if(offset>2*1024*1024){
497 //fprintf(stderr, "Wrapping agp vertex buffer offset\n");
498 offset=0;
499 }
500 /* Not the most efficient implementation, but, for now, I just want something that
501 works */
502 /* to do - make single memcpy per column (is it possible ?) */
503 /* to do - use dirty flags to avoid redundant copies */
504 #define UPLOAD_VECTOR(v)\
505 { \
506 /* Is the data dirty ? */ \
507 if (v->flags & ((1<<v->size)-1)) { \
508 /* fprintf(stderr, "size=%d vs stride=%d\n", v->size, v->stride); */ \
509 if(v->size*4==v->stride){\
510 /* fast path */ \
511 memcpy(rsp->gartTextures.map+offset, v->data, v->stride*VB->Count); \
512 } else { \
513 for(i=0;i<VB->Count;i++){ \
514 /* copy one vertex at a time*/ \
515 memcpy(rsp->gartTextures.map+offset+i*v->size*4, VEC_ELT(v, GLfloat, i), v->size*4); \
516 } \
517 } \
518 /* v->flags &= ~((1<<v->size)-1);*/ \
519 } \
520 rmesa->state.aos[idx].offset=rsp->gartTextures.handle+offset; \
521 offset+=v->size*4*VB->Count; \
522 idx++; \
523 }
524
525 render_inputs = rmesa->state.render_inputs;
526
527 if(!render_inputs){
528 WARN_ONCE("Aeiee ! render_inputs==0. Skipping rendering.\n");
529 return;
530 }
531 /* coordinates */
532 if(render_inputs & _TNL_BIT_POS)
533 UPLOAD_VECTOR(VB->ObjPtr);
534 if(render_inputs & _TNL_BIT_NORMAL)
535 UPLOAD_VECTOR(VB->NormalPtr);
536
537 /* color components */
538 if(render_inputs & _TNL_BIT_COLOR0)
539 UPLOAD_VECTOR(VB->ColorPtr[0]);
540 if(render_inputs & _TNL_BIT_COLOR1)
541 UPLOAD_VECTOR(VB->SecondaryColorPtr[0]);
542
543 if(render_inputs & _TNL_BIT_FOG)
544 UPLOAD_VECTOR(VB->FogCoordPtr);
545
546 /* texture coordinates */
547 for(k=0;k < ctx->Const.MaxTextureUnits;k++)
548 if(render_inputs & (_TNL_BIT_TEX0<<k))
549 UPLOAD_VECTOR(VB->TexCoordPtr[k]);
550
551 if(render_inputs & _TNL_BIT_INDEX)
552 UPLOAD_VECTOR(VB->IndexPtr[0]);
553 if(render_inputs & _TNL_BIT_POINTSIZE)
554 UPLOAD_VECTOR(VB->PointSizePtr);
555
556 if(idx>=R300_MAX_AOS_ARRAYS){
557 fprintf(stderr, "Aieee ! Maximum AOS arrays count exceeded.. \n");
558 exit(-1);
559 }
560 }
561
562 static void r300_render_vb_primitive(r300ContextPtr rmesa,
563 GLcontext *ctx,
564 int start,
565 int end,
566 int prim)
567 {
568 int type, num_verts;
569 LOCAL_VARS
570
571 type=r300_get_primitive_type(rmesa, ctx, prim);
572 num_verts=r300_get_num_verts(rmesa, ctx, end-start, prim);
573
574 if(type<0 || num_verts <= 0)return;
575
576
577 fire_AOS(PASS_PREFIX num_verts, type);
578 }
579
580 static GLboolean r300_run_vb_render(GLcontext *ctx,
581 struct tnl_pipeline_stage *stage)
582 {
583 r300ContextPtr rmesa = R300_CONTEXT(ctx);
584 TNLcontext *tnl = TNL_CONTEXT(ctx);
585 struct vertex_buffer *VB = &tnl->vb;
586 int i, j;
587 LOCAL_VARS
588
589 if (RADEON_DEBUG == DEBUG_PRIMS)
590 fprintf(stderr, "%s\n", __FUNCTION__);
591
592
593 reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
594 e32(0x0000000a);
595
596 reg_start(0x4f18,0);
597 e32(0x00000003);
598
599 r300_setup_routing(ctx, GL_FALSE);
600
601 r300EmitState(rmesa);
602
603 /* setup array of structures data */
604 LOCK_HARDWARE(&(rmesa->radeon));
605
606 upload_vertex_buffer(rmesa, ctx);
607 //fprintf(stderr, "Using %d AOS arrays\n", n_arrays);
608
609 for(i=0; i < VB->PrimitiveCount; i++){
610 GLuint prim = VB->Primitive[i].mode;
611 GLuint start = VB->Primitive[i].start;
612 GLuint length = VB->Primitive[i].count;
613
614 /* We need LOAD_VBPNTR to setup AOS_ATTR fields.. */
615 r300EmitLOAD_VBPNTR(rmesa, start);
616
617 r300_render_vb_primitive(rmesa, ctx, start, start + length, prim);
618 }
619
620 /* This sequence is required after any 3d drawing packet
621 I suspect it works around a bug (or deficiency) in hardware */
622
623 reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
624 e32(0x0000000a);
625
626 reg_start(0x4f18,0);
627 e32(0x00000003);
628
629 end_3d(PASS_PREFIX_VOID);
630
631 /* Flush state - we are done drawing.. */
632 r300FlushCmdBufLocked(ctx, __FUNCTION__);
633 radeonWaitForIdleLocked(&(rmesa->radeon));
634
635 UNLOCK_HARDWARE(&(rmesa->radeon));
636 return GL_FALSE;
637 }
638
639 /**
640 * Called by the pipeline manager to render a batch of primitives.
641 * We can return true to pass on to the next stage (i.e. software
642 * rasterization) or false to indicate that the pipeline has finished
643 * after we render something.
644 */
645 static GLboolean r300_run_render(GLcontext *ctx,
646 struct tnl_pipeline_stage *stage)
647 {
648 r300ContextPtr rmesa = R300_CONTEXT(ctx);
649 TNLcontext *tnl = TNL_CONTEXT(ctx);
650 struct vertex_buffer *VB = &tnl->vb;
651 GLuint i;
652
653 if (RADEON_DEBUG == DEBUG_PRIMS)
654 fprintf(stderr, "%s\n", __FUNCTION__);
655
656
657 #if 1
658
659 #if 1
660 /* I dont recall fog locking up before polygon offset modifications.
661 Or then having fog on only locks up if immediate mode is on... */
662 if(ctx->Fog.Enabled)
663 return GL_FALSE;
664
665 return r300_run_immediate_render(ctx, stage);
666 #else
667 return r300_run_vb_render(ctx, stage);
668 #endif
669 #else
670 return GL_TRUE;
671 #endif
672
673 #if 0
674 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
675 TNLcontext *tnl = TNL_CONTEXT(ctx);
676 struct vertex_buffer *VB = &tnl->vb;
677 GLuint i;
678
679 /* Don't handle clipping or indexed vertices or vertex manipulations.
680 */
681 if (mmesa->RenderIndex != 0 ||
682 !mga_validate_render( ctx, VB )) {
683 return GL_TRUE;
684 }
685
686 tnl->Driver.Render.Start( ctx );
687 mmesa->SetupNewInputs = ~0;
688
689 for (i = 0 ; i < VB->PrimitiveCount ; i++)
690 {
691 GLuint prim = VB->Primitive[i].mode;
692 GLuint start = VB->Primitive[i].start;
693 GLuint length = VB->Primitive[i].count;
694
695 if (!length)
696 continue;
697
698 mga_render_tab_verts[prim & PRIM_MODE_MASK]( ctx, start, start + length,
699 prim);
700 }
701
702 tnl->Driver.Render.Finish( ctx );
703
704 return GL_FALSE; /* finished the pipe */
705 #endif
706 }
707
708
709 /**
710 * Called by the pipeline manager once before rendering.
711 * We check the GL state here to
712 * a) decide whether we can do the current state in hardware and
713 * b) update hardware registers
714 */
715 #define FALLBACK_IF(expr) \
716 do { \
717 if (expr) { \
718 if (1 || RADEON_DEBUG & DEBUG_FALLBACKS) \
719 fprintf(stderr, "%s: fallback:%s\n", \
720 __FUNCTION__, #expr); \
721 stage->active = GL_FALSE; \
722 return; \
723 } \
724 } while(0)
725
726 static void r300_check_render(GLcontext *ctx, struct tnl_pipeline_stage *stage)
727 {
728 r300ContextPtr r300 = R300_CONTEXT(ctx);
729 int i;
730
731 if (RADEON_DEBUG & DEBUG_STATE)
732 fprintf(stderr, "%s\n", __FUNCTION__);
733
734 /* We only support rendering in hardware for now */
735 if (ctx->RenderMode != GL_RENDER) {
736 stage->active = GL_FALSE;
737 return;
738 }
739
740 // I failed to figure out how dither works in hardware,
741 // let's just ignore it for now
742 //FALLBACK_IF(ctx->Color.DitherFlag);
743
744 /* I'm almost certain I forgot something here */
745 #if 0 /* This should work now.. */
746 FALLBACK_IF(ctx->Color.AlphaEnabled); // GL_ALPHA_TEST
747 FALLBACK_IF(ctx->Color.BlendEnabled); // GL_BLEND
748 #endif
749 //FALLBACK_IF(ctx->Fog.Enabled); // GL_FOG disable as swtcl doesnt seem to support this
750 FALLBACK_IF(ctx->Line.SmoothFlag); // GL_LINE_SMOOTH
751 FALLBACK_IF(ctx->Line.StippleFlag); // GL_LINE_STIPPLE
752 FALLBACK_IF(ctx->Point.SmoothFlag); // GL_POINT_SMOOTH
753 if (ctx->Extensions.NV_point_sprite || ctx->Extensions.ARB_point_sprite)
754 FALLBACK_IF(ctx->Point.PointSprite); // GL_POINT_SPRITE_NV
755 FALLBACK_IF(ctx->Polygon.OffsetPoint); // GL_POLYGON_OFFSET_POINT
756 FALLBACK_IF(ctx->Polygon.OffsetLine); // GL_POLYGON_OFFSET_LINE
757 //FALLBACK_IF(ctx->Polygon.OffsetFill); // GL_POLYGON_OFFSET_FILL
758 //if(ctx->Polygon.OffsetFill)WARN_ONCE("Polygon.OffsetFill not implemented, ignoring\n");
759 FALLBACK_IF(ctx->Polygon.SmoothFlag); // GL_POLYGON_SMOOTH
760 FALLBACK_IF(ctx->Polygon.StippleFlag); // GL_POLYGON_STIPPLE
761 //FALLBACK_IF(ctx->Stencil.Enabled); // GL_STENCIL_TEST
762 FALLBACK_IF(ctx->Multisample.Enabled); // GL_MULTISAMPLE_ARB
763
764 /* One step at a time - let one texture pass.. */
765 for (i = 1; i < ctx->Const.MaxTextureUnits; i++)
766 FALLBACK_IF(ctx->Texture.Unit[i].Enabled);
767
768 /* let r300_run_render do its job */
769 #if 0
770 stage->active = GL_FALSE;
771 #endif
772 }
773
774
775 static void dtr(struct tnl_pipeline_stage *stage)
776 {
777 (void)stage;
778 }
779
780 const struct tnl_pipeline_stage _r300_render_stage = {
781 "r300 hw rasterize",
782 _NEW_ALL, /* re-check (always re-check for now) */
783 0, /* re-run (always runs) */
784 GL_TRUE, /* active */
785 0, 0, /* inputs (set in check_render), outputs */
786 0, 0, /* changed_inputs, private */
787 dtr, /* destructor */
788 r300_check_render, /* check */
789 r300_run_render /* run */
790 };