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 /* Turns out we might not need this after all... */
62 void update_zbias(GLcontext
* ctx
, int prim
)
64 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
68 switch(prim
& PRIM_MODE_MASK
) {
70 if(ctx
->Polygon
.OffsetPoint
== GL_TRUE
)
76 if(ctx
->Polygon
.OffsetLine
== GL_TRUE
)
80 case GL_TRIANGLE_STRIP
:
85 if(ctx
->Polygon
.OffsetFill
== GL_TRUE
)
89 fprintf(stderr
, "%s:%s Do not know how to handle primitive %02x - help me !\n",
90 __FILE__
, __FUNCTION__
,
91 prim
& PRIM_MODE_MASK
);
96 values
[0]=values
[2]=r300PackFloat32(ctx
->Polygon
.OffsetFactor
* 12.0);
97 values
[1]=values
[3]=r300PackFloat32(ctx
->Polygon
.OffsetUnits
* 4.0);
99 values
[0]=values
[2]=r300PackFloat32(0.0);
100 values
[1]=values
[3]=r300PackFloat32(0.0);
103 if(values
[0] != rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_FACTOR
] ||
104 values
[1] != rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_CONSTANT
] ||
105 values
[2] != rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_FACTOR
] ||
106 values
[3] != rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_CONSTANT
]){
108 R300_STATECHANGE(rmesa
, zbs
);
109 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_FACTOR
] = values
[0];
110 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_CONSTANT
] = values
[1];
111 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_FACTOR
] = values
[2];
112 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_CONSTANT
] = values
[3];
117 /**********************************************************************
118 * Hardware rasterization
120 * When we fell back to software TCL, we still try to use the
121 * rasterization hardware for rendering.
122 **********************************************************************/
124 static int r300_get_primitive_type(r300ContextPtr rmesa
, GLcontext
*ctx
, int prim
)
126 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
127 struct vertex_buffer
*VB
= &tnl
->vb
;
131 switch (prim
& PRIM_MODE_MASK
) {
133 type
=R300_VAP_VF_CNTL__PRIM_POINTS
;
136 type
=R300_VAP_VF_CNTL__PRIM_LINES
;
139 type
=R300_VAP_VF_CNTL__PRIM_LINE_STRIP
;
142 type
=R300_VAP_VF_CNTL__PRIM_LINE_LOOP
;
145 type
=R300_VAP_VF_CNTL__PRIM_TRIANGLES
;
147 case GL_TRIANGLE_STRIP
:
148 type
=R300_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP
;
150 case GL_TRIANGLE_FAN
:
151 type
=R300_VAP_VF_CNTL__PRIM_TRIANGLE_FAN
;
154 type
=R300_VAP_VF_CNTL__PRIM_QUADS
;
157 type
=R300_VAP_VF_CNTL__PRIM_QUAD_STRIP
;
160 type
=R300_VAP_VF_CNTL__PRIM_POLYGON
;
163 fprintf(stderr
, "%s:%s Do not know how to handle primitive %02x - help me !\n",
164 __FILE__
, __FUNCTION__
,
165 prim
& PRIM_MODE_MASK
);
172 static int r300_get_num_verts(r300ContextPtr rmesa
,
177 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
178 struct vertex_buffer
*VB
= &tnl
->vb
;
180 int type
=-1, verts_off
=0;
181 char *name
="UNKNOWN";
183 switch (prim
& PRIM_MODE_MASK
) {
190 verts_off
= num_verts
% 2;
195 verts_off
= num_verts
;
200 verts_off
= num_verts
;
204 verts_off
= num_verts
% 3;
206 case GL_TRIANGLE_STRIP
:
209 verts_off
= num_verts
;
211 case GL_TRIANGLE_FAN
:
214 verts_off
= num_verts
;
218 verts_off
= num_verts
% 4;
223 verts_off
= num_verts
;
225 verts_off
= num_verts
% 2;
230 verts_off
= num_verts
;
233 fprintf(stderr
, "%s:%s Do not know how to handle primitive %02x - help me !\n",
234 __FILE__
, __FUNCTION__
,
235 prim
& PRIM_MODE_MASK
);
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
);
246 WARN_ONCE("user error: %d is not a valid number of vertices for primitive %s !\n", num_verts
, name
);
249 return num_verts
- verts_off
;
252 void dump_inputs(GLcontext
*ctx
, int render_inputs
)
255 fprintf(stderr
, "inputs:");
256 fprintf(stderr
, "%08x ", render_inputs
);
258 if(render_inputs
& _TNL_BIT_POS
)
259 fprintf(stderr
, "_TNL_BIT_POS ");
260 if(render_inputs
& _TNL_BIT_NORMAL
)
261 fprintf(stderr
, "_TNL_BIT_NORMAL ");
263 /* color components */
264 if(render_inputs
& _TNL_BIT_COLOR0
)
265 fprintf(stderr
, "_TNL_BIT_COLOR0 ");
266 if(render_inputs
& _TNL_BIT_COLOR1
)
267 fprintf(stderr
, "_TNL_BIT_COLOR1 ");
269 if(render_inputs
& _TNL_BIT_FOG
)
270 fprintf(stderr
, "_TNL_BIT_FOG ");
272 /* texture coordinates */
273 for(k
=0;k
< ctx
->Const
.MaxTextureUnits
;k
++)
274 if(render_inputs
& (_TNL_BIT_TEX0
<<k
))
275 fprintf(stderr
, "_TNL_BIT_TEX%d ", k
);
277 if(render_inputs
& _TNL_BIT_INDEX
)
278 fprintf(stderr
, "_TNL_BIT_INDEX ");
279 if(render_inputs
& _TNL_BIT_POINTSIZE
)
280 fprintf(stderr
, "_TNL_BIT_POINTSIZE ");
282 fprintf(stderr
, "\n");
285 /* This function compiles GL context into state registers that
286 describe data routing inside of R300 pipeline.
288 In particular, it programs input_route, output_vtx_fmt, texture
289 unit configuration and gb_output_vtx_fmt
291 This function encompasses setup_AOS() from r300_lib.c
297 /* Immediate implementation - vertex data is sent via command stream */
299 static GLfloat default_vector
[4]={0.0, 0.0, 0.0, 1.0};
301 #define output_vector(v, i) \
304 for(_i=0;_i<v->size;_i++){ \
305 efloat(VEC_ELT(v, GLfloat, i)[_i]); \
307 for(_i=v->size;_i<4;_i++){ \
308 efloat(default_vector[_i]); \
312 /* Immediate implementation - vertex data is sent via command stream */
314 static void r300_render_immediate_primitive(r300ContextPtr rmesa
,
320 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
321 struct vertex_buffer
*VB
= &tnl
->vb
;
322 GLuint i
, render_inputs
;
323 int k
, type
, num_verts
;
326 type
=r300_get_primitive_type(rmesa
, ctx
, prim
);
327 num_verts
=r300_get_num_verts(rmesa
, ctx
, end
-start
, prim
);
330 fprintf(stderr
,"ObjPtr: size=%d stride=%d\n",
331 VB
->ObjPtr
->size
, VB
->ObjPtr
->stride
);
332 fprintf(stderr
,"ColorPtr[0]: size=%d stride=%d\n",
333 VB
->ColorPtr
[0]->size
, VB
->ColorPtr
[0]->stride
);
334 fprintf(stderr
,"TexCoordPtr[0]: size=%d stride=%d\n",
335 VB
->TexCoordPtr
[0]->size
, VB
->TexCoordPtr
[0]->stride
);
338 if(type
<0 || num_verts
<= 0)return;
341 WARN_ONCE("FIXME: Don't know how to handle GL_ARB_vertex_buffer_object correctly\n");
344 /* A packet cannot have more than 16383 data words.. */
345 if((num_verts
*4*rmesa
->state
.aos_count
)>16380){
346 WARN_ONCE("Too many vertices to paint. Fix me !\n");
350 //fprintf(stderr, "aos_count=%d start=%d end=%d\n", rmesa->state.aos_count, start, end);
352 if(rmesa
->state
.aos_count
==0){
353 WARN_ONCE("Aeiee ! aos_count==0, while it shouldn't. Skipping rendering\n");
357 render_inputs
= rmesa
->state
.render_inputs
;
360 WARN_ONCE("Aeiee ! render_inputs==0. Skipping rendering.\n");
364 //dump_inputs(ctx, render_inputs); return ;
366 start_immediate_packet(num_verts
, type
, 4*rmesa
->state
.aos_count
);
368 for(i
=start
;i
<start
+num_verts
;i
++){
370 fprintf(stderr
, "* (%f %f %f %f) (%f %f %f %f)\n",
371 VEC_ELT(VB
->ObjPtr
, GLfloat
, i
)[0],
372 VEC_ELT(VB
->ObjPtr
, GLfloat
, i
)[1],
373 VEC_ELT(VB
->ObjPtr
, GLfloat
, i
)[2],
374 VEC_ELT(VB
->ObjPtr
, GLfloat
, i
)[3],
376 VEC_ELT(VB
->ColorPtr
[0], GLfloat
, i
)[0],
377 VEC_ELT(VB
->ColorPtr
[0], GLfloat
, i
)[1],
378 VEC_ELT(VB
->ColorPtr
[0], GLfloat
, i
)[2],
379 VEC_ELT(VB
->ColorPtr
[0], GLfloat
, i
)[3]
385 if(render_inputs
& _TNL_BIT_POS
)
386 output_vector(VB
->ObjPtr
, i
);
387 if(render_inputs
& _TNL_BIT_NORMAL
)
388 output_vector(VB
->NormalPtr
, i
);
390 /* color components */
391 if(render_inputs
& _TNL_BIT_COLOR0
)
392 output_vector(VB
->ColorPtr
[0], i
);
393 if(render_inputs
& _TNL_BIT_COLOR1
)
394 output_vector(VB
->SecondaryColorPtr
[0], i
);
396 /* if(render_inputs & _TNL_BIT_FOG) // Causes lock ups when immediate mode is on
397 output_vector(VB->FogCoordPtr, i);*/
399 /* texture coordinates */
400 for(k
=0;k
< ctx
->Const
.MaxTextureUnits
;k
++)
401 if(render_inputs
& (_TNL_BIT_TEX0
<<k
))
402 output_vector(VB
->TexCoordPtr
[k
], i
);
404 if(render_inputs
& _TNL_BIT_INDEX
)
405 output_vector(VB
->IndexPtr
[0], i
);
406 if(render_inputs
& _TNL_BIT_POINTSIZE
)
407 output_vector(VB
->PointSizePtr
, i
);
413 static GLboolean
r300_run_immediate_render(GLcontext
*ctx
,
414 struct tnl_pipeline_stage
*stage
)
416 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
417 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
418 struct vertex_buffer
*VB
= &tnl
->vb
;
420 /* Only do 2d textures */
421 struct gl_texture_object
*to
=ctx
->Texture
.Unit
[0].Current2D
;
422 r300TexObjPtr t
=to
->DriverData
;
426 /* Update texture state - needs to be done only when actually changed..
427 All the time for now.. */
430 if (RADEON_DEBUG
== DEBUG_PRIMS
)
431 fprintf(stderr
, "%s\n", __FUNCTION__
);
433 #if 1 /* we need this, somehow */
434 /* Flush state - make sure command buffer is nice and large */
436 /* Make sure we have enough space */
438 /* Count is very imprecize, but should be good upper bound */
439 r300EnsureCmdBufSpace(rmesa
, rmesa
->hw
.max_state_size
+ 4+2+30
440 +VB
->PrimitiveCount
*(1+8)+VB
->Count
*4*rmesa
->state
.texture
.tc_count
+4, __FUNCTION__
);
443 /* needed before starting 3d operation .. */
444 reg_start(R300_RB3D_DSTCACHE_CTLSTAT
,0);
451 #if 0 /* looks like the Z offset issue got fixed */
452 rmesa
->hw
.vte
.cmd
[1] = R300_VPORT_X_SCALE_ENA
453 | R300_VPORT_X_OFFSET_ENA
454 | R300_VPORT_Y_SCALE_ENA
455 | R300_VPORT_Y_OFFSET_ENA
457 R300_STATECHANGE(rmesa
, vte
);
462 /* Magic register - note it is right after 20b0 */
465 if(rmesa
->state
.texture
.tc_count
>0){
471 r300EmitState(rmesa
);
474 reg_start(R300_RB3D_COLORMASK
, 0);
477 vsf_start_fragment(0x406, 4);
483 vsf_start_fragment(0x400, 4);
490 /* Setup INPUT_ROUTE and INPUT_CNTL */
491 r300EmitArrays(ctx
, GL_TRUE
);
493 /* Why do we need this for immediate mode?? Vertex processor needs it to know proper regs */
494 // r300EmitLOAD_VBPNTR(rmesa, 0);
495 /* Okay, it seems I misunderstood something, EmitAOS does the same thing */
496 r300EmitAOS(rmesa
, rmesa
->state
.aos_count
, 0);
498 for(i
=0; i
< VB
->PrimitiveCount
; i
++){
499 GLuint prim
= VB
->Primitive
[i
].mode
;
500 GLuint start
= VB
->Primitive
[i
].start
;
501 GLuint length
= VB
->Primitive
[i
].count
;
503 r300_render_immediate_primitive(rmesa
, ctx
, start
, start
+ length
, prim
);
506 /* This sequence is required after any 3d drawing packet
507 I suspect it work arounds a bug (or deficiency) in hardware */
509 reg_start(R300_RB3D_DSTCACHE_CTLSTAT
,0);
518 /* vertex buffer implementation */
519 void emit_elts(GLcontext
* ctx
, GLuint
*elts
, int oec
, int ec
);
521 # define R300_EB_UNK1_SHIFT 24
522 # define R300_EB_UNK1 (0x80<<24)
523 # define R300_EB_UNK2 0x0810
525 unsigned long get_num_elts(unsigned long count
)
527 unsigned long magic_1
;
529 /* round up elt count so that magic_1 is 0 (divisable by 4)*/
530 return (count
+3) & (~3);
531 //return count - (count % 4);
534 static void inline fire_EB(PREFIX
unsigned long addr
, int vertex_count
, int type
)
537 unsigned long magic_1
;
538 unsigned char magic1_tbl
[4]={ 0, 6, 4, 2 };
540 magic_1
= magic1_tbl
[vertex_count
% 4];
543 WARN_ONCE("Dont know how to handle this yet!\n");
549 start_packet3(RADEON_CP_PACKET3_3D_DRAW_INDX_2
, 0);
550 e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES
| (vertex_count
<<16) | type
);
552 start_packet3(RADEON_CP_PACKET3_INDX_BUFFER
, 2);
553 e32(R300_EB_UNK1
| (magic_1
<< 16) | R300_EB_UNK2
);
555 e32(((vertex_count
+1) / 2) + magic_1
);
558 static void r300_render_vb_primitive(r300ContextPtr rmesa
,
565 radeonScreenPtr rsp
=rmesa
->radeon
.radeonScreen
;
567 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
568 struct vertex_buffer
*VB
= &tnl
->vb
;
570 type
=r300_get_primitive_type(rmesa
, ctx
, prim
);
571 num_verts
=r300_get_num_verts(rmesa
, ctx
, end
-start
, prim
);
573 if(type
<0 || num_verts
<= 0)return;
575 if(rmesa
->state
.Elts
){
576 unsigned long elt_count
;
578 WARN_ONCE("Rendering with elts\n");
580 elt_count
=get_num_elts(num_verts
);
581 //emit_elts(ctx, rmesa->state.Elts, VB->Count, get_num_elts(VB->Count));
582 emit_elts(ctx
, rmesa
->state
.Elts
+start
, num_verts
, elt_count
);
583 fire_EB(PASS_PREFIX rsp
->gartTextures
.handle
/*rmesa->state.elt_ao.aos_offset*/, elt_count
, type
);
585 fire_AOS(PASS_PREFIX num_verts
, type
);
588 static GLboolean
r300_run_vb_render(GLcontext
*ctx
,
589 struct tnl_pipeline_stage
*stage
)
591 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
592 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
593 struct vertex_buffer
*VB
= &tnl
->vb
;
597 if (RADEON_DEBUG
== DEBUG_PRIMS
)
598 fprintf(stderr
, "%s\n", __FUNCTION__
);
601 r300ReleaseArrays(ctx
);
602 r300EmitArrays(ctx
, GL_FALSE
);
603 //dump_inputs(ctx, rmesa->state.render_inputs);
604 #if 0 /* Cant do this here yet due to magic_1 */
605 if(rmesa
->state
.Elts
)
606 emit_elts(ctx
, rmesa
->state
.Elts
, /*600*/VB
->Count
, get_num_elts(/*600*/VB
->Count
));
609 // LOCK_HARDWARE(&(rmesa->radeon));
611 reg_start(R300_RB3D_DSTCACHE_CTLSTAT
,0);
617 r300EmitState(rmesa
);
619 rmesa
->state
.Elts
= VB
->Elts
;
621 for(i
=0; i
< VB
->PrimitiveCount
; i
++){
622 GLuint prim
= VB
->Primitive
[i
].mode
;
623 GLuint start
= VB
->Primitive
[i
].start
;
624 GLuint length
= VB
->Primitive
[i
].count
;
626 r300EmitAOS(rmesa
, rmesa
->state
.aos_count
, start
);
628 r300_render_vb_primitive(rmesa
, ctx
, start
, start
+ length
, prim
);
631 reg_start(R300_RB3D_DSTCACHE_CTLSTAT
,0);
637 // end_3d(PASS_PREFIX_VOID);
639 /* Flush state - we are done drawing.. */
640 // r300FlushCmdBufLocked(rmesa, __FUNCTION__);
641 // radeonWaitForIdleLocked(&(rmesa->radeon));
643 // UNLOCK_HARDWARE(&(rmesa->radeon));
648 * Called by the pipeline manager to render a batch of primitives.
649 * We can return true to pass on to the next stage (i.e. software
650 * rasterization) or false to indicate that the pipeline has finished
651 * after we render something.
653 static GLboolean
r300_run_render(GLcontext
*ctx
,
654 struct tnl_pipeline_stage
*stage
)
656 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
657 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
658 struct vertex_buffer
*VB
= &tnl
->vb
;
661 if (RADEON_DEBUG
== DEBUG_PRIMS
)
662 fprintf(stderr
, "%s\n", __FUNCTION__
);
668 return r300_run_immediate_render(ctx
, stage
);
670 return r300_run_vb_render(ctx
, stage
);
677 mgaContextPtr mmesa
= MGA_CONTEXT(ctx
);
678 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
679 struct vertex_buffer
*VB
= &tnl
->vb
;
682 /* Don't handle clipping or indexed vertices or vertex manipulations.
684 if (mmesa
->RenderIndex
!= 0 ||
685 !mga_validate_render( ctx
, VB
)) {
689 tnl
->Driver
.Render
.Start( ctx
);
690 mmesa
->SetupNewInputs
= ~0;
692 for (i
= 0 ; i
< VB
->PrimitiveCount
; i
++)
694 GLuint prim
= VB
->Primitive
[i
].mode
;
695 GLuint start
= VB
->Primitive
[i
].start
;
696 GLuint length
= VB
->Primitive
[i
].count
;
701 mga_render_tab_verts
[prim
& PRIM_MODE_MASK
]( ctx
, start
, start
+ length
,
705 tnl
->Driver
.Render
.Finish( ctx
);
707 return GL_FALSE
; /* finished the pipe */
713 * Called by the pipeline manager once before rendering.
714 * We check the GL state here to
715 * a) decide whether we can do the current state in hardware and
716 * b) update hardware registers
718 #define FALLBACK_IF(expr) \
721 if (1 || RADEON_DEBUG & DEBUG_FALLBACKS) \
722 fprintf(stderr, "%s: fallback:%s\n", \
723 __FUNCTION__, #expr); \
724 stage->active = GL_FALSE; \
729 static void r300_check_render(GLcontext
*ctx
, struct tnl_pipeline_stage
*stage
)
731 r300ContextPtr r300
= R300_CONTEXT(ctx
);
734 if (RADEON_DEBUG
& DEBUG_STATE
)
735 fprintf(stderr
, "%s\n", __FUNCTION__
);
737 /* We only support rendering in hardware for now */
738 if (ctx
->RenderMode
!= GL_RENDER
) {
739 stage
->active
= GL_FALSE
;
743 // I failed to figure out how dither works in hardware,
744 // let's just ignore it for now
745 //FALLBACK_IF(ctx->Color.DitherFlag);
747 /* I'm almost certain I forgot something here */
748 #if 0 /* This should work now.. */
749 FALLBACK_IF(ctx
->Color
.AlphaEnabled
); // GL_ALPHA_TEST
750 FALLBACK_IF(ctx
->Color
.BlendEnabled
); // GL_BLEND
752 //FALLBACK_IF(ctx->Fog.Enabled); // GL_FOG disable as swtcl doesnt seem to support this
753 FALLBACK_IF(ctx
->Line
.SmoothFlag
); // GL_LINE_SMOOTH
754 FALLBACK_IF(ctx
->Line
.StippleFlag
); // GL_LINE_STIPPLE
755 FALLBACK_IF(ctx
->Point
.SmoothFlag
); // GL_POINT_SMOOTH
756 if (ctx
->Extensions
.NV_point_sprite
|| ctx
->Extensions
.ARB_point_sprite
)
757 FALLBACK_IF(ctx
->Point
.PointSprite
); // GL_POINT_SPRITE_NV
758 //FALLBACK_IF(ctx->Polygon.OffsetPoint); // GL_POLYGON_OFFSET_POINT
759 //FALLBACK_IF(ctx->Polygon.OffsetLine); // GL_POLYGON_OFFSET_LINE
760 //FALLBACK_IF(ctx->Polygon.OffsetFill); // GL_POLYGON_OFFSET_FILL
761 //if(ctx->Polygon.OffsetFill)WARN_ONCE("Polygon.OffsetFill not implemented, ignoring\n");
762 FALLBACK_IF(ctx
->Polygon
.SmoothFlag
); // GL_POLYGON_SMOOTH
763 FALLBACK_IF(ctx
->Polygon
.StippleFlag
); // GL_POLYGON_STIPPLE
764 //FALLBACK_IF(ctx->Stencil.Enabled); // GL_STENCIL_TEST
765 FALLBACK_IF(ctx
->Multisample
.Enabled
); // GL_MULTISAMPLE_ARB
767 /* One step at a time - let one texture pass.. */
768 for (i
= 1; i
< ctx
->Const
.MaxTextureUnits
; i
++)
769 FALLBACK_IF(ctx
->Texture
.Unit
[i
].Enabled
);
771 /* let r300_run_render do its job */
773 stage
->active
= GL_FALSE
;
778 static void dtr(struct tnl_pipeline_stage
*stage
)
783 const struct tnl_pipeline_stage _r300_render_stage
= {
785 _NEW_ALL
, /* re-check (always re-check for now) */
786 0, /* re-run (always runs) */
787 GL_TRUE
, /* active */
788 0, 0, /* inputs (set in check_render), outputs */
789 0, 0, /* changed_inputs, private */
790 dtr
, /* destructor */
791 r300_check_render
, /* check */
792 r300_run_render
/* run */