Get Polygon offset fill to work.
[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 };