Get Polygon offset fill to work.
[profile/ivi/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 /**********************************************************************
62 *                     Hardware rasterization
63 *
64 * When we fell back to software TCL, we still try to use the
65 * rasterization hardware for rendering.
66 **********************************************************************/
67
68 static int r300_get_primitive_type(r300ContextPtr rmesa, 
69         GLcontext *ctx,
70         int start,
71         int end,
72         int prim)
73 {
74    TNLcontext *tnl = TNL_CONTEXT(ctx);
75    struct vertex_buffer *VB = &tnl->vb;
76    GLuint i;
77    int type=-1, min_vertices=0;
78    char *name="UNKNOWN";
79    
80    if(end<=start)return -1; /* do we need to watch for this ? */
81    
82         switch (prim & PRIM_MODE_MASK) {
83         case GL_POINTS:
84                 name="P";
85                 type=R300_VAP_VF_CNTL__PRIM_POINTS;
86                 min_vertices=1;
87                 break;          
88         case GL_LINES:
89                 name="L";
90                 type=R300_VAP_VF_CNTL__PRIM_LINES;
91                 min_vertices=2;
92                 break;          
93         case GL_LINE_STRIP:
94                 name="LS";
95                 type=R300_VAP_VF_CNTL__PRIM_LINE_STRIP;
96                 min_vertices=2;
97                 break;
98         case GL_LINE_LOOP:
99                 name="LL";
100                 min_vertices=2;
101                 return -1;
102                 break;
103         case GL_TRIANGLES:
104                 name="T";
105                 type=R300_VAP_VF_CNTL__PRIM_TRIANGLES;
106                 min_vertices=3;
107                 break;
108         case GL_TRIANGLE_STRIP:
109                 name="TS";
110                 type=R300_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP;
111                 min_vertices=3;
112                 break;
113         case GL_TRIANGLE_FAN:
114                 name="TF";
115                 type=R300_VAP_VF_CNTL__PRIM_TRIANGLE_FAN;
116                 min_vertices=3;
117                 break;
118         case GL_QUADS:
119                 name="Q";
120                 type=R300_VAP_VF_CNTL__PRIM_QUADS;
121                 min_vertices=4;
122                 break;
123         case GL_QUAD_STRIP:
124                 name="QS";
125                 type=R300_VAP_VF_CNTL__PRIM_QUAD_STRIP;
126                 min_vertices=4;
127                 break;
128         case GL_POLYGON:
129                 name="P";
130                         type=R300_VAP_VF_CNTL__PRIM_POLYGON;
131                 min_vertices=3;
132                 break;
133         default:
134                 fprintf(stderr, "%s:%s Do not know how to handle primitive %02x - help me !\n",
135                         __FILE__, __FUNCTION__,
136                         prim & PRIM_MODE_MASK);
137                 return -1;
138                 break;
139         }
140    #if 0
141    fprintf(stderr, "[%d-%d]%s ", start, end, name);
142    #endif
143    if(start+min_vertices>end){
144         static int warn_once=1;
145         if(warn_once){
146                 fprintf(stderr, "%s:%s ***WARN_ONCE*** Not enough vertices to draw primitive %02x - help me !\n",
147                                 __FILE__, __FUNCTION__,
148                                 prim & PRIM_MODE_MASK);
149                         warn_once=0;
150                         }
151         return -1;
152         }
153    return type;
154 }
155
156 /* This function compiles GL context into state registers that 
157    describe data routing inside of R300 pipeline.
158    
159    In particular, it programs input_route, output_vtx_fmt, texture
160    unit configuration and gb_output_vtx_fmt
161    
162    This function encompasses setup_AOS() from r300_lib.c
163 */
164
165
166
167
168 /* Immediate implementation - vertex data is sent via command stream */
169
170 static GLfloat default_vector[4]={0.0, 0.0, 0.0, 1.0};
171
172 #define output_vector(v, i) \
173         { \
174         int _i; \
175         for(_i=0;_i<v->size;_i++){ \
176                 efloat(VEC_ELT(v, GLfloat, i)[_i]); \
177                 } \
178         for(_i=v->size;_i<4;_i++){ \
179                         efloat(default_vector[_i]); \
180                         } \
181         }
182
183 /* Immediate implementation - vertex data is sent via command stream */
184
185 static void r300_render_immediate_primitive(r300ContextPtr rmesa, 
186         GLcontext *ctx,
187         int start,
188         int end,
189         int prim)
190 {
191    TNLcontext *tnl = TNL_CONTEXT(ctx);
192    struct vertex_buffer *VB = &tnl->vb;
193    GLuint i;
194    int k, type;
195    LOCAL_VARS
196                    
197    type=r300_get_primitive_type(rmesa, ctx, start, end, prim);
198                 
199                 #if 0
200                 fprintf(stderr,"ObjPtr: size=%d stride=%d\n", 
201                         VB->ObjPtr->size, VB->ObjPtr->stride);
202                 fprintf(stderr,"ColorPtr[0]: size=%d stride=%d\n", 
203                         VB->ColorPtr[0]->size, VB->ColorPtr[0]->stride);
204                 fprintf(stderr,"TexCoordPtr[0]: size=%d stride=%d\n", 
205                         VB->TexCoordPtr[0]->size, VB->TexCoordPtr[0]->stride);
206                 #endif
207    
208    if(type<0)return;
209    
210    if(!VB->ObjPtr){
211         WARN_ONCE("FIXME: Don't know how to handle GL_ARB_vertex_buffer_object correctly\n");
212         return;
213    }
214    /* A packet cannot have more than 16383 data words.. */
215    if(((end-start)*4*rmesa->state.aos_count)>16380){
216         WARN_ONCE("Too many vertices to paint. Fix me !\n");
217         return;         
218         }
219
220    //fprintf(stderr, "aos_count=%d start=%d end=%d\n", rmesa->state.aos_count, start, end);
221
222    if(rmesa->state.aos_count==0){
223         WARN_ONCE("Aeiee ! aos_count==0, while it shouldn't. Skipping rendering\n");
224         return;
225         }
226    
227    start_immediate_packet(end-start, type, 4*rmesa->state.aos_count);
228
229         for(i=start;i<end;i++){
230                 #if 0
231                 fprintf(stderr, "* (%f %f %f %f) (%f %f %f %f)\n", 
232                         VEC_ELT(VB->ObjPtr, GLfloat, i)[0],
233                         VEC_ELT(VB->ObjPtr, GLfloat, i)[1],
234                         VEC_ELT(VB->ObjPtr, GLfloat, i)[2],
235                         VEC_ELT(VB->ObjPtr, GLfloat, i)[3],
236                         
237                         VEC_ELT(VB->ColorPtr[0], GLfloat, i)[0],
238                         VEC_ELT(VB->ColorPtr[0], GLfloat, i)[1],
239                         VEC_ELT(VB->ColorPtr[0], GLfloat, i)[2],
240                         VEC_ELT(VB->ColorPtr[0], GLfloat, i)[3]
241                         );
242                 #endif
243                 
244                 
245                 /* coordinates */
246                 if(tnl->render_inputs & _TNL_BIT_POS)
247                         output_vector(VB->ObjPtr, i);
248                 if(tnl->render_inputs & _TNL_BIT_NORMAL)
249                         output_vector(VB->NormalPtr, i);
250                 
251                 /* color components */
252                 if(tnl->render_inputs & _TNL_BIT_COLOR0)
253                         output_vector(VB->ColorPtr[0], i);
254                 if(tnl->render_inputs & _TNL_BIT_COLOR1)
255                         output_vector(VB->SecondaryColorPtr[0], i);
256
257                 if(tnl->render_inputs & _TNL_BIT_FOG)
258                         output_vector(VB->FogCoordPtr, i);
259                                         
260                 /* texture coordinates */
261                 for(k=0;k < ctx->Const.MaxTextureUnits;k++)
262                         if(tnl->render_inputs & (_TNL_BIT_TEX0<<k))
263                                 output_vector(VB->TexCoordPtr[k], i);
264                 
265                 if(tnl->render_inputs & _TNL_BIT_INDEX)
266                         output_vector(VB->IndexPtr[0], i);
267                 if(tnl->render_inputs & _TNL_BIT_POINTSIZE)
268                         output_vector(VB->PointSizePtr, i);
269                 }
270
271 }
272
273
274 static GLboolean r300_run_immediate_render(GLcontext *ctx,
275                                  struct tnl_pipeline_stage *stage)
276 {
277    r300ContextPtr rmesa = R300_CONTEXT(ctx);
278    TNLcontext *tnl = TNL_CONTEXT(ctx);
279    struct vertex_buffer *VB = &tnl->vb;
280    GLuint i;
281    /* Only do 2d textures */
282    struct gl_texture_object *to=ctx->Texture.Unit[0].Current2D;
283    r300TexObjPtr t=to->DriverData;
284    LOCAL_VARS
285         
286   
287    /* Update texture state - needs to be done only when actually changed..
288       All the time for now.. */
289
290
291         if (RADEON_DEBUG == DEBUG_PRIMS)
292                 fprintf(stderr, "%s\n", __FUNCTION__);
293
294    #if 1 /* we need this, somehow */
295    /* Flush state - make sure command buffer is nice and large */
296    r300Flush(ctx);
297    /* Make sure we have enough space */
298    #else 0
299    /* Count is very imprecize, but should be good upper bound */
300    r300EnsureCmdBufSpace(rmesa, rmesa->hw.max_state_size + 4+2+30
301         +VB->PrimitiveCount*(1+8)+VB->Count*4*rmesa->state.texture.tc_count+4, __FUNCTION__);
302    #endif
303      
304    /* needed before starting 3d operation .. */
305    reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
306         e32(0x0000000a);
307    
308    reg_start(0x4f18,0);
309         e32(0x00000003);
310         
311    
312         #if 0 /* looks like the Z offset issue got fixed */
313    rmesa->hw.vte.cmd[1] = R300_VPORT_X_SCALE_ENA
314                                 | R300_VPORT_X_OFFSET_ENA
315                                 | R300_VPORT_Y_SCALE_ENA
316                                 | R300_VPORT_Y_OFFSET_ENA
317                                 | R300_VTX_W0_FMT;
318    R300_STATECHANGE(rmesa, vte);
319         #endif
320    
321         
322       
323    /* Magic register - note it is right after 20b0 */
324
325    
326    if(rmesa->state.texture.tc_count>0){
327         reg_start(0x20b4,0);
328                 e32(0x0000000c);
329    
330         }
331                 
332    r300EmitState(rmesa);
333    
334    #if 0
335    reg_start(R300_RB3D_COLORMASK, 0);
336         e32(0xf);
337    
338    vsf_start_fragment(0x406, 4);
339    efloat(0.0);
340    efloat(0.0);
341    efloat(0.0);
342    efloat(1.0);
343
344    vsf_start_fragment(0x400, 4);
345    efloat(0.0);
346    efloat(0.0);
347    efloat(0.0);
348    efloat(1.0);
349    #endif
350    
351    /* We need LOAD_VBPNTR to setup AOS_ATTR fields.. the offsets are irrelevant */
352    r300EmitLOAD_VBPNTR(rmesa, 0);
353    
354    for(i=0; i < VB->PrimitiveCount; i++){
355        GLuint prim = VB->Primitive[i].mode;
356        GLuint start = VB->Primitive[i].start;
357        GLuint length = VB->Primitive[i].count;
358         r300_render_immediate_primitive(rmesa, ctx, start, start + length, prim);
359         }
360         
361     /* This sequence is required after any 3d drawing packet
362       I suspect it work arounds a bug (or deficiency) in hardware */
363   
364    reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
365         e32(0x0000000a);
366    
367    reg_start(0x4f18,0);
368         e32(0x00000003);
369          
370    return GL_FALSE;
371 }
372
373
374 /* vertex buffer implementation */
375
376 /* We use the start part of GART texture buffer for vertices */
377
378
379 static void upload_vertex_buffer(r300ContextPtr rmesa, GLcontext *ctx)
380 {
381         TNLcontext *tnl = TNL_CONTEXT(ctx);
382         struct vertex_buffer *VB = &tnl->vb;
383         int idx=0;
384         int i,j,k;
385         radeonScreenPtr rsp=rmesa->radeon.radeonScreen;
386         
387         /* A hack - we don't want to overwrite vertex buffers, so we
388         just use AGP space for them.. Fix me ! */
389         static int offset=0;
390         if(offset>2*1024*1024){
391                 //fprintf(stderr, "Wrapping agp vertex buffer offset\n");
392                 offset=0;
393                 }
394         /* Not the most efficient implementation, but, for now, I just want something that
395         works */
396         /* to do - make single memcpy per column (is it possible ?) */
397         /* to do - use dirty flags to avoid redundant copies */
398         #define UPLOAD_VECTOR(v)\
399                 { \
400                 /* Is the data dirty ? */ \
401                 if (v->flags & ((1<<v->size)-1)) { \
402                         /* fprintf(stderr, "size=%d vs stride=%d\n", v->size, v->stride); */ \
403                         if(v->size*4==v->stride){\
404                                 /* fast path */  \
405                                 memcpy(rsp->gartTextures.map+offset, v->data, v->stride*VB->Count); \
406                                 } else { \
407                                 for(i=0;i<VB->Count;i++){ \
408                                         /* copy one vertex at a time*/ \
409                                         memcpy(rsp->gartTextures.map+offset+i*v->size*4, VEC_ELT(v, GLfloat, i), v->size*4); \
410                                         } \
411                                 } \
412                         /* v->flags &= ~((1<<v->size)-1);*/ \
413                         } \
414                 rmesa->state.aos[idx].offset=rsp->gartTextures.handle+offset; \
415                 offset+=v->size*4*VB->Count; \
416                 idx++; \
417                 }
418
419         UPLOAD_VECTOR(VB->ObjPtr);
420         UPLOAD_VECTOR(VB->ColorPtr[0]);
421         /* texture coordinates */
422         for(k=0;k < ctx->Const.MaxTextureUnits;k++)
423                 if(ctx->Texture.Unit[k].Enabled)
424                         UPLOAD_VECTOR(VB->TexCoordPtr[k]);
425
426         if(idx>=R300_MAX_AOS_ARRAYS){
427                 fprintf(stderr, "Aieee ! Maximum AOS arrays count exceeded.. \n");
428                 exit(-1);
429                 }
430 }
431
432 static void r300_render_vb_primitive(r300ContextPtr rmesa, 
433         GLcontext *ctx,
434         int start,
435         int end,
436         int prim)
437 {
438    int type;
439    LOCAL_VARS
440         
441    if(end<=start)return; /* do we need to watch for this ? */
442    
443    type=r300_get_primitive_type(rmesa, ctx, start, end, prim);
444    if(type<0)return;
445
446    fire_AOS(PASS_PREFIX end-start, type);
447 }
448
449 static GLboolean r300_run_vb_render(GLcontext *ctx,
450                                  struct tnl_pipeline_stage *stage)
451 {
452    r300ContextPtr rmesa = R300_CONTEXT(ctx);
453    TNLcontext *tnl = TNL_CONTEXT(ctx);
454    struct vertex_buffer *VB = &tnl->vb;
455    int i, j;
456    LOCAL_VARS
457         
458         if (RADEON_DEBUG == DEBUG_PRIMS)
459                 fprintf(stderr, "%s\n", __FUNCTION__);
460
461    
462    reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
463         e32(0x0000000a);
464    
465    reg_start(0x4f18,0);
466         e32(0x00000003);
467    
468    r300_setup_routing(ctx, GL_FALSE);
469         
470    r300EmitState(rmesa);
471
472    /* setup array of structures data */
473    LOCK_HARDWARE(&(rmesa->radeon));
474
475    upload_vertex_buffer(rmesa, ctx);
476    //fprintf(stderr, "Using %d AOS arrays\n", n_arrays);
477    
478    for(i=0; i < VB->PrimitiveCount; i++){
479        GLuint prim = VB->Primitive[i].mode;
480        GLuint start = VB->Primitive[i].start;
481        GLuint length = VB->Primitive[i].count;
482                 
483            /* We need LOAD_VBPNTR to setup AOS_ATTR fields.. */
484         r300EmitLOAD_VBPNTR(rmesa, start);
485        
486         r300_render_vb_primitive(rmesa, ctx, start, start + length, prim);
487         }
488         
489     /* This sequence is required after any 3d drawing packet
490       I suspect it works around a bug (or deficiency) in hardware */
491   
492   reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
493         e32(0x0000000a);
494    
495    reg_start(0x4f18,0);
496         e32(0x00000003);
497    
498    end_3d(PASS_PREFIX_VOID);
499    
500    /* Flush state - we are done drawing.. */
501    r300FlushCmdBufLocked(ctx, __FUNCTION__);
502    radeonWaitForIdleLocked(&(rmesa->radeon));
503    
504    UNLOCK_HARDWARE(&(rmesa->radeon));
505    return GL_FALSE;
506 }
507
508
509 /**
510  * Called by the pipeline manager to render a batch of primitives.
511  * We can return true to pass on to the next stage (i.e. software
512  * rasterization) or false to indicate that the pipeline has finished
513  * after we render something.
514  */
515 static GLboolean r300_run_render(GLcontext *ctx,
516                                  struct tnl_pipeline_stage *stage)
517 {
518    r300ContextPtr rmesa = R300_CONTEXT(ctx);
519    TNLcontext *tnl = TNL_CONTEXT(ctx);
520    struct vertex_buffer *VB = &tnl->vb;
521    GLuint i;
522         
523         if (RADEON_DEBUG == DEBUG_PRIMS)
524                 fprintf(stderr, "%s\n", __FUNCTION__);
525         
526         
527    #if 1
528         
529         #if 1
530         return r300_run_immediate_render(ctx, stage);
531         #else 
532         return r300_run_vb_render(ctx, stage);
533         #endif
534    #else
535         return GL_TRUE;
536    #endif
537
538 #if 0
539    mgaContextPtr mmesa = MGA_CONTEXT(ctx);
540    TNLcontext *tnl = TNL_CONTEXT(ctx);
541    struct vertex_buffer *VB = &tnl->vb;
542    GLuint i;
543
544    /* Don't handle clipping or indexed vertices or vertex manipulations.
545     */
546    if (mmesa->RenderIndex != 0 ||
547        !mga_validate_render( ctx, VB )) {
548       return GL_TRUE;
549    }
550
551    tnl->Driver.Render.Start( ctx );
552    mmesa->SetupNewInputs = ~0;
553
554    for (i = 0 ; i < VB->PrimitiveCount ; i++)
555    {
556       GLuint prim = VB->Primitive[i].mode;
557       GLuint start = VB->Primitive[i].start;
558       GLuint length = VB->Primitive[i].count;
559
560       if (!length)
561          continue;
562
563       mga_render_tab_verts[prim & PRIM_MODE_MASK]( ctx, start, start + length,
564                                                    prim);
565    }
566
567    tnl->Driver.Render.Finish( ctx );
568
569    return GL_FALSE;             /* finished the pipe */
570 #endif
571 }
572
573
574 /**
575  * Called by the pipeline manager once before rendering.
576  * We check the GL state here to
577  *  a) decide whether we can do the current state in hardware and
578  *  b) update hardware registers
579  */
580 #define FALLBACK_IF(expr) \
581 do {                                                                            \
582         if (expr) {                                                             \
583                 if (1 || RADEON_DEBUG & DEBUG_FALLBACKS)                                \
584                         fprintf(stderr, "%s: fallback:%s\n",                    \
585                                 __FUNCTION__, #expr);                           \
586                 stage->active = GL_FALSE;                                       \
587                 return;                                                         \
588         }                                                                       \
589 } while(0)
590
591 static void r300_check_render(GLcontext *ctx, struct tnl_pipeline_stage *stage)
592 {
593         r300ContextPtr r300 = R300_CONTEXT(ctx);
594         int i;
595
596         if (RADEON_DEBUG & DEBUG_STATE)
597                 fprintf(stderr, "%s\n", __FUNCTION__);
598
599         /* We only support rendering in hardware for now */
600         if (ctx->RenderMode != GL_RENDER) {
601                 stage->active = GL_FALSE;
602                 return;
603         }
604         
605 #if 0 // selecting VERT_BIT_NORMAL still doesnt give us normals but why?
606         stage->inputs |= VERT_BIT_POS;
607         stage->inputs |= VERT_BIT_NORMAL;
608         stage->inputs |= VERT_BIT_COLOR0;
609 #endif
610         
611         // I failed to figure out how dither works in hardware,
612         // let's just ignore it for now
613         //FALLBACK_IF(ctx->Color.DitherFlag);
614
615         /* I'm almost certain I forgot something here */
616         #if 0 /* This should work now.. */
617         FALLBACK_IF(ctx->Color.AlphaEnabled); // GL_ALPHA_TEST
618         FALLBACK_IF(ctx->Color.BlendEnabled); // GL_BLEND
619         #endif
620         FALLBACK_IF(ctx->Fog.Enabled); // GL_FOG
621         FALLBACK_IF(ctx->Line.SmoothFlag); // GL_LINE_SMOOTH
622         FALLBACK_IF(ctx->Line.StippleFlag); // GL_LINE_STIPPLE
623         FALLBACK_IF(ctx->Point.SmoothFlag); // GL_POINT_SMOOTH
624         if (ctx->Extensions.NV_point_sprite || ctx->Extensions.ARB_point_sprite)
625                 FALLBACK_IF(ctx->Point.PointSprite); // GL_POINT_SPRITE_NV
626         FALLBACK_IF(ctx->Polygon.OffsetPoint); // GL_POLYGON_OFFSET_POINT
627         FALLBACK_IF(ctx->Polygon.OffsetLine); // GL_POLYGON_OFFSET_LINE
628         //FALLBACK_IF(ctx->Polygon.OffsetFill); // GL_POLYGON_OFFSET_FILL
629         //if(ctx->Polygon.OffsetFill)WARN_ONCE("Polygon.OffsetFill not implemented, ignoring\n");
630         FALLBACK_IF(ctx->Polygon.SmoothFlag); // GL_POLYGON_SMOOTH
631         FALLBACK_IF(ctx->Polygon.StippleFlag); // GL_POLYGON_STIPPLE
632         //FALLBACK_IF(ctx->Stencil.Enabled); // GL_STENCIL_TEST
633         FALLBACK_IF(ctx->Multisample.Enabled); // GL_MULTISAMPLE_ARB
634
635         /* One step at a time - let one texture pass.. */
636         for (i = 1; i < ctx->Const.MaxTextureUnits; i++)
637                 FALLBACK_IF(ctx->Texture.Unit[i].Enabled);
638
639         /* let r300_run_render do its job */
640         #if 0  
641         stage->active = GL_FALSE;
642         #endif
643 }
644
645
646 static void dtr(struct tnl_pipeline_stage *stage)
647 {
648         (void)stage;
649 }
650
651 const struct tnl_pipeline_stage _r300_render_stage = {
652         "r300 hw rasterize",
653         _NEW_ALL,               /* re-check (always re-check for now) */
654         0,                      /* re-run (always runs) */
655         GL_TRUE,                /* active */
656         0, 0,                   /* inputs (set in check_render), outputs */
657         0, 0,                   /* changed_inputs, private */
658         dtr,                    /* destructor */
659         r300_check_render,      /* check */
660         r300_run_render         /* run */
661 };