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