1 /**************************************************************************
3 Copyright (C) 2004 Nicolai Haehnle.
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:
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
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.
26 **************************************************************************/
30 * Nicolai Haehnle <prefect_@gmx.net>
40 #include "simple_list.h"
42 #include "api_arrayelt.h"
43 #include "swrast/swrast.h"
44 #include "swrast_setup/swrast_setup.h"
45 #include "array_cache/acache.h"
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"
56 #include "r300_program.h"
58 #include "r300_maos.h"
59 #include "r300_emit.h"
61 /**********************************************************************
62 * Hardware rasterization
64 * When we fell back to software TCL, we still try to use the
65 * rasterization hardware for rendering.
66 **********************************************************************/
68 static int r300_get_primitive_type(r300ContextPtr rmesa
, GLcontext
*ctx
, int prim
)
70 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
71 struct vertex_buffer
*VB
= &tnl
->vb
;
75 switch (prim
& PRIM_MODE_MASK
) {
77 type
=R300_VAP_VF_CNTL__PRIM_POINTS
;
80 type
=R300_VAP_VF_CNTL__PRIM_LINES
;
83 type
=R300_VAP_VF_CNTL__PRIM_LINE_STRIP
;
86 type
=R300_VAP_VF_CNTL__PRIM_LINE_LOOP
;
89 type
=R300_VAP_VF_CNTL__PRIM_TRIANGLES
;
91 case GL_TRIANGLE_STRIP
:
92 type
=R300_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP
;
95 type
=R300_VAP_VF_CNTL__PRIM_TRIANGLE_FAN
;
98 type
=R300_VAP_VF_CNTL__PRIM_QUADS
;
101 type
=R300_VAP_VF_CNTL__PRIM_QUAD_STRIP
;
104 type
=R300_VAP_VF_CNTL__PRIM_POLYGON
;
107 fprintf(stderr
, "%s:%s Do not know how to handle primitive %02x - help me !\n",
108 __FILE__
, __FUNCTION__
,
109 prim
& PRIM_MODE_MASK
);
116 static int r300_get_num_verts(r300ContextPtr rmesa
,
121 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
122 struct vertex_buffer
*VB
= &tnl
->vb
;
124 int type
=-1, verts_off
=0;
125 char *name
="UNKNOWN";
127 switch (prim
& PRIM_MODE_MASK
) {
134 verts_off
= num_verts
% 2;
139 verts_off
= num_verts
;
144 verts_off
= num_verts
;
148 verts_off
= num_verts
% 3;
150 case GL_TRIANGLE_STRIP
:
153 verts_off
= num_verts
;
155 case GL_TRIANGLE_FAN
:
158 verts_off
= num_verts
;
162 verts_off
= num_verts
% 4;
167 verts_off
= num_verts
;
169 verts_off
= num_verts
% 2;
174 verts_off
= num_verts
;
177 fprintf(stderr
, "%s:%s Do not know how to handle primitive %02x - help me !\n",
178 __FILE__
, __FUNCTION__
,
179 prim
& PRIM_MODE_MASK
);
184 if(num_verts
- verts_off
== 0){
185 WARN_ONCE("user error: Need more than %d vertices to draw primitive %s !\n", num_verts
, name
);
190 WARN_ONCE("user error: %d is not a valid number of vertices for primitive %s !\n", num_verts
, name
);
193 return num_verts
- verts_off
;
196 void dump_inputs(GLcontext
*ctx
, int render_inputs
)
199 fprintf(stderr
, "inputs:");
200 fprintf(stderr
, "%08x ", render_inputs
);
202 if(render_inputs
& _TNL_BIT_POS
)
203 fprintf(stderr
, "_TNL_BIT_POS ");
204 if(render_inputs
& _TNL_BIT_NORMAL
)
205 fprintf(stderr
, "_TNL_BIT_NORMAL ");
207 /* color components */
208 if(render_inputs
& _TNL_BIT_COLOR0
)
209 fprintf(stderr
, "_TNL_BIT_COLOR0 ");
210 if(render_inputs
& _TNL_BIT_COLOR1
)
211 fprintf(stderr
, "_TNL_BIT_COLOR1 ");
213 if(render_inputs
& _TNL_BIT_FOG
)
214 fprintf(stderr
, "_TNL_BIT_FOG ");
216 /* texture coordinates */
217 for(k
=0;k
< ctx
->Const
.MaxTextureUnits
;k
++)
218 if(render_inputs
& (_TNL_BIT_TEX0
<<k
))
219 fprintf(stderr
, "_TNL_BIT_TEX%d ", k
);
221 if(render_inputs
& _TNL_BIT_INDEX
)
222 fprintf(stderr
, "_TNL_BIT_INDEX ");
223 if(render_inputs
& _TNL_BIT_POINTSIZE
)
224 fprintf(stderr
, "_TNL_BIT_POINTSIZE ");
226 fprintf(stderr
, "\n");
229 /* This function compiles GL context into state registers that
230 describe data routing inside of R300 pipeline.
232 In particular, it programs input_route, output_vtx_fmt, texture
233 unit configuration and gb_output_vtx_fmt
235 This function encompasses setup_AOS() from r300_lib.c
241 /* Immediate implementation - vertex data is sent via command stream */
243 static GLfloat default_vector
[4]={0.0, 0.0, 0.0, 1.0};
245 #define output_vector(v, i) \
248 for(_i=0;_i<v->size;_i++){ \
249 efloat(VEC_ELT(v, GLfloat, i)[_i]); \
251 for(_i=v->size;_i<4;_i++){ \
252 efloat(default_vector[_i]); \
256 /* Immediate implementation - vertex data is sent via command stream */
258 static void r300_render_immediate_primitive(r300ContextPtr rmesa
,
264 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
265 struct vertex_buffer
*VB
= &tnl
->vb
;
266 GLuint i
, render_inputs
;
267 int k
, type
, num_verts
;
270 type
=r300_get_primitive_type(rmesa
, ctx
, prim
);
271 num_verts
=r300_get_num_verts(rmesa
, ctx
, end
-start
, prim
);
274 fprintf(stderr
,"ObjPtr: size=%d stride=%d\n",
275 VB
->ObjPtr
->size
, VB
->ObjPtr
->stride
);
276 fprintf(stderr
,"ColorPtr[0]: size=%d stride=%d\n",
277 VB
->ColorPtr
[0]->size
, VB
->ColorPtr
[0]->stride
);
278 fprintf(stderr
,"TexCoordPtr[0]: size=%d stride=%d\n",
279 VB
->TexCoordPtr
[0]->size
, VB
->TexCoordPtr
[0]->stride
);
282 if(type
<0 || num_verts
<= 0)return;
285 WARN_ONCE("FIXME: Don't know how to handle GL_ARB_vertex_buffer_object correctly\n");
288 /* A packet cannot have more than 16383 data words.. */
289 if((num_verts
*4*rmesa
->state
.aos_count
)>16380){
290 WARN_ONCE("Too many vertices to paint. Fix me !\n");
294 //fprintf(stderr, "aos_count=%d start=%d end=%d\n", rmesa->state.aos_count, start, end);
296 if(rmesa
->state
.aos_count
==0){
297 WARN_ONCE("Aeiee ! aos_count==0, while it shouldn't. Skipping rendering\n");
301 render_inputs
= rmesa
->state
.render_inputs
;
304 WARN_ONCE("Aeiee ! render_inputs==0. Skipping rendering.\n");
308 //dump_inputs(ctx, render_inputs); return ;
310 start_immediate_packet(num_verts
, type
, 4*rmesa
->state
.aos_count
);
312 for(i
=start
;i
<start
+num_verts
;i
++){
314 fprintf(stderr
, "* (%f %f %f %f) (%f %f %f %f)\n",
315 VEC_ELT(VB
->ObjPtr
, GLfloat
, i
)[0],
316 VEC_ELT(VB
->ObjPtr
, GLfloat
, i
)[1],
317 VEC_ELT(VB
->ObjPtr
, GLfloat
, i
)[2],
318 VEC_ELT(VB
->ObjPtr
, GLfloat
, i
)[3],
320 VEC_ELT(VB
->ColorPtr
[0], GLfloat
, i
)[0],
321 VEC_ELT(VB
->ColorPtr
[0], GLfloat
, i
)[1],
322 VEC_ELT(VB
->ColorPtr
[0], GLfloat
, i
)[2],
323 VEC_ELT(VB
->ColorPtr
[0], GLfloat
, i
)[3]
329 if(render_inputs
& _TNL_BIT_POS
)
330 output_vector(VB
->ObjPtr
, i
);
331 if(render_inputs
& _TNL_BIT_NORMAL
)
332 output_vector(VB
->NormalPtr
, i
);
334 /* color components */
335 if(render_inputs
& _TNL_BIT_COLOR0
)
336 output_vector(VB
->ColorPtr
[0], i
);
337 if(render_inputs
& _TNL_BIT_COLOR1
)
338 output_vector(VB
->SecondaryColorPtr
[0], i
);
340 /* if(render_inputs & _TNL_BIT_FOG) // Causes lock ups when immediate mode is on
341 output_vector(VB->FogCoordPtr, i);*/
343 /* texture coordinates */
344 for(k
=0;k
< ctx
->Const
.MaxTextureUnits
;k
++)
345 if(render_inputs
& (_TNL_BIT_TEX0
<<k
))
346 output_vector(VB
->TexCoordPtr
[k
], i
);
348 if(render_inputs
& _TNL_BIT_INDEX
)
349 output_vector(VB
->IndexPtr
[0], i
);
350 if(render_inputs
& _TNL_BIT_POINTSIZE
)
351 output_vector(VB
->PointSizePtr
, i
);
357 static GLboolean
r300_run_immediate_render(GLcontext
*ctx
,
358 struct tnl_pipeline_stage
*stage
)
360 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
361 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
362 struct vertex_buffer
*VB
= &tnl
->vb
;
364 /* Only do 2d textures */
365 struct gl_texture_object
*to
=ctx
->Texture
.Unit
[0].Current2D
;
366 r300TexObjPtr t
=to
->DriverData
;
370 /* Update texture state - needs to be done only when actually changed..
371 All the time for now.. */
374 if (RADEON_DEBUG
== DEBUG_PRIMS
)
375 fprintf(stderr
, "%s\n", __FUNCTION__
);
377 #if 1 /* we need this, somehow */
378 /* Flush state - make sure command buffer is nice and large */
380 /* Make sure we have enough space */
382 /* Count is very imprecize, but should be good upper bound */
383 r300EnsureCmdBufSpace(rmesa
, rmesa
->hw
.max_state_size
+ 4+2+30
384 +VB
->PrimitiveCount
*(1+8)+VB
->Count
*4*rmesa
->state
.texture
.tc_count
+4, __FUNCTION__
);
387 /* needed before starting 3d operation .. */
388 reg_start(R300_RB3D_DSTCACHE_CTLSTAT
,0);
395 #if 0 /* looks like the Z offset issue got fixed */
396 rmesa
->hw
.vte
.cmd
[1] = R300_VPORT_X_SCALE_ENA
397 | R300_VPORT_X_OFFSET_ENA
398 | R300_VPORT_Y_SCALE_ENA
399 | R300_VPORT_Y_OFFSET_ENA
401 R300_STATECHANGE(rmesa
, vte
);
406 /* Magic register - note it is right after 20b0 */
409 if(rmesa
->state
.texture
.tc_count
>0){
415 r300EmitState(rmesa
);
418 reg_start(R300_RB3D_COLORMASK
, 0);
421 vsf_start_fragment(0x406, 4);
427 vsf_start_fragment(0x400, 4);
434 /* Setup INPUT_ROUTE and INPUT_CNTL */
435 r300EmitArrays(ctx
, GL_TRUE
);
437 /* Why do we need this for immediate mode?? Vertex processor needs it to know proper regs */
438 // r300EmitLOAD_VBPNTR(rmesa, 0);
439 /* Okay, it seems I misunderstood something, EmitAOS does the same thing */
440 r300EmitAOS(rmesa
, rmesa
->state
.aos_count
, 0);
442 for(i
=0; i
< VB
->PrimitiveCount
; i
++){
443 GLuint prim
= VB
->Primitive
[i
].mode
;
444 GLuint start
= VB
->Primitive
[i
].start
;
445 GLuint length
= VB
->Primitive
[i
].count
;
447 r300_render_immediate_primitive(rmesa
, ctx
, start
, start
+ length
, prim
);
450 /* This sequence is required after any 3d drawing packet
451 I suspect it work arounds a bug (or deficiency) in hardware */
453 reg_start(R300_RB3D_DSTCACHE_CTLSTAT
,0);
462 /* vertex buffer implementation */
464 static void inline fire_EB(PREFIX
unsigned long addr
, int vertex_count
, int type
)
467 unsigned long addr_a
;
469 addr_a
= addr
& 0x1c;
473 start_packet3(RADEON_CP_PACKET3_3D_DRAW_INDX_2
, 0);
474 /* TODO: Check if R300_VAP_VF_CNTL__INDEX_SIZE_32bit works. */
475 e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES
| (vertex_count
<<16) | type
);
477 start_packet3(RADEON_CP_PACKET3_INDX_BUFFER
, 2);
478 e32(R300_EB_UNK1
| (addr_a
<< 16) | R300_EB_UNK2
);
479 e32(addr
& 0xffffffe3);
480 e32((vertex_count
+1)/2 + addr_a
/4);
483 static void r300_render_vb_primitive(r300ContextPtr rmesa
,
490 radeonScreenPtr rsp
=rmesa
->radeon
.radeonScreen
;
492 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
493 struct vertex_buffer
*VB
= &tnl
->vb
;
496 type
=r300_get_primitive_type(rmesa
, ctx
, prim
);
497 num_verts
=r300_get_num_verts(rmesa
, ctx
, end
-start
, prim
);
499 if(type
<0 || num_verts
<= 0)return;
501 if(rmesa
->state
.Elts
){
502 r300EmitAOS(rmesa
, rmesa
->state
.aos_count
, 0);
504 start_index32_packet(num_verts
, type
);
505 for(i
=0; i
< num_verts
; i
++)
506 e32(rmesa
->state
.Elts
[start
+i
]); /* start ? */
508 WARN_ONCE("Rendering with elt buffers\n");
510 start_index32_packet(num_verts
, type
);
511 e32(rmesa
->state
.Elts
[start
]);
515 if(num_verts
> 65535){ /* not implemented yet */
516 WARN_ONCE("Too many elts\n");
519 r300EmitElts(ctx
, rmesa
->state
.Elts
+start
, num_verts
);
520 fire_EB(PASS_PREFIX
GET_START(&(rmesa
->state
.elt_dma
)), num_verts
, type
);
523 r300EmitAOS(rmesa
, rmesa
->state
.aos_count
, start
);
524 fire_AOS(PASS_PREFIX num_verts
, type
);
528 static GLboolean
r300_run_vb_render(GLcontext
*ctx
,
529 struct tnl_pipeline_stage
*stage
)
531 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
532 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
533 struct vertex_buffer
*VB
= &tnl
->vb
;
537 if (RADEON_DEBUG
& DEBUG_PRIMS
)
538 fprintf(stderr
, "%s\n", __FUNCTION__
);
541 r300ReleaseArrays(ctx
);
542 r300EmitArrays(ctx
, GL_FALSE
);
543 //dump_inputs(ctx, rmesa->state.render_inputs);
545 // LOCK_HARDWARE(&(rmesa->radeon));
547 reg_start(R300_RB3D_DSTCACHE_CTLSTAT
,0);
552 r300EmitState(rmesa
);
554 rmesa
->state
.Elts
= VB
->Elts
;
556 for(i
=0; i
< VB
->PrimitiveCount
; i
++){
557 GLuint prim
= VB
->Primitive
[i
].mode
;
558 GLuint start
= VB
->Primitive
[i
].start
;
559 GLuint length
= VB
->Primitive
[i
].count
;
561 r300_render_vb_primitive(rmesa
, ctx
, start
, start
+ length
, prim
);
564 reg_start(R300_RB3D_DSTCACHE_CTLSTAT
,0);
570 // end_3d(PASS_PREFIX_VOID);
572 /* Flush state - we are done drawing.. */
573 // r300FlushCmdBufLocked(rmesa, __FUNCTION__);
574 // radeonWaitForIdleLocked(&(rmesa->radeon));
576 // UNLOCK_HARDWARE(&(rmesa->radeon));
581 * Called by the pipeline manager to render a batch of primitives.
582 * We can return true to pass on to the next stage (i.e. software
583 * rasterization) or false to indicate that the pipeline has finished
584 * after we render something.
586 static GLboolean
r300_run_render(GLcontext
*ctx
,
587 struct tnl_pipeline_stage
*stage
)
589 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
590 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
591 struct vertex_buffer
*VB
= &tnl
->vb
;
594 if (RADEON_DEBUG
& DEBUG_PRIMS
)
595 fprintf(stderr
, "%s\n", __FUNCTION__
);
601 return r300_run_immediate_render(ctx
, stage
);
603 return r300_run_vb_render(ctx
, stage
);
610 mgaContextPtr mmesa
= MGA_CONTEXT(ctx
);
611 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
612 struct vertex_buffer
*VB
= &tnl
->vb
;
615 /* Don't handle clipping or indexed vertices or vertex manipulations.
617 if (mmesa
->RenderIndex
!= 0 ||
618 !mga_validate_render( ctx
, VB
)) {
622 tnl
->Driver
.Render
.Start( ctx
);
623 mmesa
->SetupNewInputs
= ~0;
625 for (i
= 0 ; i
< VB
->PrimitiveCount
; i
++)
627 GLuint prim
= VB
->Primitive
[i
].mode
;
628 GLuint start
= VB
->Primitive
[i
].start
;
629 GLuint length
= VB
->Primitive
[i
].count
;
634 mga_render_tab_verts
[prim
& PRIM_MODE_MASK
]( ctx
, start
, start
+ length
,
638 tnl
->Driver
.Render
.Finish( ctx
);
640 return GL_FALSE
; /* finished the pipe */
646 * Called by the pipeline manager once before rendering.
647 * We check the GL state here to
648 * a) decide whether we can do the current state in hardware and
649 * b) update hardware registers
651 #define FALLBACK_IF(expr) \
654 if (1 || RADEON_DEBUG & DEBUG_FALLBACKS) \
655 fprintf(stderr, "%s: fallback:%s\n", \
656 __FUNCTION__, #expr); \
657 stage->active = GL_FALSE; \
662 static void r300_check_render(GLcontext
*ctx
, struct tnl_pipeline_stage
*stage
)
664 r300ContextPtr r300
= R300_CONTEXT(ctx
);
667 if (RADEON_DEBUG
& DEBUG_STATE
)
668 fprintf(stderr
, "%s\n", __FUNCTION__
);
670 /* We only support rendering in hardware for now */
671 if (ctx
->RenderMode
!= GL_RENDER
) {
672 stage
->active
= GL_FALSE
;
677 /* I'm almost certain I forgot something here */
678 #if 0 /* These should work now.. */
679 FALLBACK_IF(ctx
->Color
.DitherFlag
);
680 FALLBACK_IF(ctx
->Color
.AlphaEnabled
); // GL_ALPHA_TEST
681 FALLBACK_IF(ctx
->Color
.BlendEnabled
); // GL_BLEND
682 FALLBACK_IF(ctx
->Polygon
.OffsetFill
); // GL_POLYGON_OFFSET_FILL
684 //FALLBACK_IF(ctx->Polygon.OffsetPoint); // GL_POLYGON_OFFSET_POINT
685 //FALLBACK_IF(ctx->Polygon.OffsetLine); // GL_POLYGON_OFFSET_LINE
686 //FALLBACK_IF(ctx->Stencil.Enabled); // GL_STENCIL_TEST
688 //FALLBACK_IF(ctx->Fog.Enabled); // GL_FOG disable as swtcl doesnt seem to support this
689 //FALLBACK_IF(ctx->Polygon.SmoothFlag); // GL_POLYGON_SMOOTH disabling to get blender going
690 FALLBACK_IF(ctx
->Polygon
.StippleFlag
); // GL_POLYGON_STIPPLE
691 FALLBACK_IF(ctx
->Multisample
.Enabled
); // GL_MULTISAMPLE_ARB
693 #if 0 /* ut2k3 fails to start if this is on */
694 /* One step at a time - let one texture pass.. */
695 for (i
= 1; i
< ctx
->Const
.MaxTextureUnits
; i
++)
696 FALLBACK_IF(ctx
->Texture
.Unit
[i
].Enabled
);
699 /* Assumed factor reg is found but pattern is still missing */
700 //FALLBACK_IF(ctx->Line.StippleFlag); // GL_LINE_STIPPLE disabling to get blender going
702 /* HW doesnt appear to directly support these */
703 //FALLBACK_IF(ctx->Line.SmoothFlag); // GL_LINE_SMOOTH disabling to get blender going
704 FALLBACK_IF(ctx
->Point
.SmoothFlag
); // GL_POINT_SMOOTH
705 /* Rest could be done with vertex fragments */
706 if (ctx
->Extensions
.NV_point_sprite
|| ctx
->Extensions
.ARB_point_sprite
)
707 FALLBACK_IF(ctx
->Point
.PointSprite
); // GL_POINT_SPRITE_NV
708 //GL_POINT_DISTANCE_ATTENUATION_ARB
709 //GL_POINT_FADE_THRESHOLD_SIZE_ARB
711 /* let r300_run_render do its job */
713 stage
->active
= GL_FALSE
;
718 static void dtr(struct tnl_pipeline_stage
*stage
)
723 const struct tnl_pipeline_stage _r300_render_stage
= {
725 _NEW_ALL
, /* re-check (always re-check for now) */
726 0, /* re-run (always runs) */
727 GL_TRUE
, /* active */
728 0, 0, /* inputs (set in check_render), outputs */
729 0, 0, /* changed_inputs, private */
730 dtr
, /* destructor */
731 r300_check_render
, /* check */
732 r300_run_render
/* run */
735 static GLboolean
r300_run_tcl_render(GLcontext
*ctx
,
736 struct tnl_pipeline_stage
*stage
)
738 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
739 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
740 struct vertex_buffer
*VB
= &tnl
->vb
;
743 if (RADEON_DEBUG
& DEBUG_PRIMS
)
744 fprintf(stderr
, "%s\n", __FUNCTION__
);
746 return r300_run_vb_render(ctx
, stage
);
749 static void r300_check_tcl_render(GLcontext
*ctx
, struct tnl_pipeline_stage
*stage
)
751 r300ContextPtr r300
= R300_CONTEXT(ctx
);
754 if (RADEON_DEBUG
& DEBUG_STATE
)
755 fprintf(stderr
, "%s\n", __FUNCTION__
);
757 /* We only support rendering in hardware for now */
758 if (ctx
->RenderMode
!= GL_RENDER
) {
759 stage
->active
= GL_FALSE
;
762 if(VERTPROG_ACTIVE(ctx
)) {
763 stage
->active
= GL_TRUE
;
764 stage
->inputs
= ctx
->VertexProgram
.Current
->InputsRead
;
766 stage
->active
= GL_FALSE
;
770 const struct tnl_pipeline_stage _r300_tcl_stage
= {
772 _NEW_ALL
, /* re-check (always re-check for now) */
773 0, /* re-run (always runs) */
774 GL_TRUE
, /* active */
775 0, 0, /* inputs (set in check_render), outputs */
776 0, 0, /* changed_inputs, private */
777 dtr
, /* destructor */
778 r300_check_tcl_render
, /* check */
779 r300_run_tcl_render
/* run */