1 /**************************************************************************
3 Copyright (C) 2007 Dave Airlie
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 THE COPYRIGHT OWNER(S) AND/OR ITS 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 * Dave Airlie <airlied@linux.ie>
33 /* derived from r200 swtcl path */
37 #include "main/glheader.h"
38 #include "main/mtypes.h"
39 #include "main/colormac.h"
40 #include "main/enums.h"
41 #include "main/image.h"
42 #include "main/imports.h"
43 #include "main/light.h"
44 #include "main/macros.h"
46 #include "swrast/s_context.h"
47 #include "swrast/s_fog.h"
48 #include "swrast_setup/swrast_setup.h"
49 #include "math/m_translate.h"
51 #include "tnl/t_context.h"
52 #include "tnl/t_pipeline.h"
54 #include "r300_context.h"
55 #include "r300_swtcl.h"
56 #include "r300_state.h"
57 #include "r300_ioctl.h"
58 #include "r300_emit.h"
61 static void flush_last_swtcl_prim( r300ContextPtr rmesa
);
64 void r300EmitVertexAOS(r300ContextPtr rmesa
, GLuint vertex_size
, GLuint offset
);
65 void r300EmitVbufPrim(r300ContextPtr rmesa
, GLuint primitive
, GLuint vertex_nr
);
66 #define EMIT_ATTR( ATTR, STYLE ) \
68 rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].attrib = (ATTR); \
69 rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].format = (STYLE); \
70 rmesa->swtcl.vertex_attr_count++; \
73 #define EMIT_PAD( N ) \
75 rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].attrib = 0; \
76 rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].format = EMIT_PAD; \
77 rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].offset = (N); \
78 rmesa->swtcl.vertex_attr_count++; \
81 static void r300SetVertexFormat( GLcontext
*ctx
)
83 r300ContextPtr rmesa
= R300_CONTEXT( ctx
);
84 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
85 struct vertex_buffer
*VB
= &tnl
->vb
;
86 DECLARE_RENDERINPUTS(index_bitset
);
87 GLuint InputsRead
= 0, OutputsWritten
= 0;
92 GLint inputs
[VERT_ATTRIB_MAX
];
93 GLint tab
[VERT_ATTRIB_MAX
];
94 int swizzle
[VERT_ATTRIB_MAX
][4];
98 DECLARE_RENDERINPUTS(render_inputs_bitset
);
99 RENDERINPUTS_COPY(render_inputs_bitset
, tnl
->render_inputs_bitset
);
100 RENDERINPUTS_COPY( index_bitset
, tnl
->render_inputs_bitset
);
101 RENDERINPUTS_COPY(rmesa
->state
.render_inputs_bitset
, render_inputs_bitset
);
103 vte
= rmesa
->hw
.vte
.cmd
[1];
104 vte
&= ~(R300_VTX_XY_FMT
| R300_VTX_Z_FMT
| R300_VTX_W0_FMT
);
107 if ( VB
->NdcPtr
!= NULL
) {
108 VB
->AttribPtr
[VERT_ATTRIB_POS
] = VB
->NdcPtr
;
109 vte
|= R300_VTX_XY_FMT
| R300_VTX_Z_FMT
;
112 VB
->AttribPtr
[VERT_ATTRIB_POS
] = VB
->ClipPtr
;
113 vte
|= R300_VTX_W0_FMT
;
116 assert( VB
->AttribPtr
[VERT_ATTRIB_POS
] != NULL
);
117 rmesa
->swtcl
.vertex_attr_count
= 0;
119 /* EMIT_ATTR's must be in order as they tell t_vertex.c how to
120 * build up a hardware vertex.
122 if (RENDERINPUTS_TEST( index_bitset
, _TNL_ATTRIB_POS
)) {
123 sz
= VB
->AttribPtr
[VERT_ATTRIB_POS
]->size
;
124 InputsRead
|= 1 << VERT_ATTRIB_POS
;
125 OutputsWritten
|= 1 << VERT_RESULT_HPOS
;
126 EMIT_ATTR( _TNL_ATTRIB_POS
, EMIT_1F
+ sz
- 1 );
130 EMIT_PAD(4 * sizeof(float));
133 if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_POINTSIZE )) {
134 EMIT_ATTR( _TNL_ATTRIB_POINTSIZE, EMIT_1F );
138 if (RENDERINPUTS_TEST(index_bitset
, _TNL_ATTRIB_COLOR0
)) {
139 sz
= VB
->AttribPtr
[VERT_ATTRIB_COLOR0
]->size
;
140 rmesa
->swtcl
.coloroffset
= offset
;
141 InputsRead
|= 1 << VERT_ATTRIB_COLOR0
;
142 OutputsWritten
|= 1 << VERT_RESULT_COL0
;
143 EMIT_ATTR( _TNL_ATTRIB_COLOR0
, EMIT_1F
+ sz
- 1 );
147 rmesa
->swtcl
.specoffset
= 0;
148 if (RENDERINPUTS_TEST( index_bitset
, _TNL_ATTRIB_COLOR1
)) {
149 sz
= VB
->AttribPtr
[VERT_ATTRIB_COLOR1
]->size
;
150 rmesa
->swtcl
.specoffset
= offset
;
151 EMIT_ATTR( _TNL_ATTRIB_COLOR1
, EMIT_1F
+ sz
- 1 );
152 InputsRead
|= 1 << VERT_ATTRIB_COLOR1
;
153 OutputsWritten
|= 1 << VERT_RESULT_COL1
;
157 if (RENDERINPUTS_TEST(index_bitset
, _TNL_ATTRIB_FOG
)) {
158 /* find first free tex coord slot */
159 if (RENDERINPUTS_TEST_RANGE( index_bitset
, _TNL_FIRST_TEX
, _TNL_LAST_TEX
)) {
161 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
162 if (!RENDERINPUTS_TEST( index_bitset
, _TNL_ATTRIB_TEX(i
) )) {
172 fprintf(stderr
, "\tout of free texcoords to do fog\n");
176 sz
= VB
->AttribPtr
[VERT_ATTRIB_FOG
]->size
;
177 EMIT_ATTR( _TNL_ATTRIB_FOG
, EMIT_1F
+ sz
- 1);
178 InputsRead
|= 1 << VERT_ATTRIB_FOG
;
179 OutputsWritten
|= 1 << VERT_RESULT_FOGC
;
180 vap_fmt_1
|= sz
<< (3 * fog_id
);
183 if (RENDERINPUTS_TEST_RANGE( index_bitset
, _TNL_FIRST_TEX
, _TNL_LAST_TEX
)) {
186 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
187 if (RENDERINPUTS_TEST( index_bitset
, _TNL_ATTRIB_TEX(i
) )) {
188 sz
= VB
->TexCoordPtr
[i
]->size
;
189 InputsRead
|= 1 << (VERT_ATTRIB_TEX0
+ i
);
190 OutputsWritten
|= 1 << (VERT_RESULT_TEX0
+ i
);
191 EMIT_ATTR( _TNL_ATTRIB_TEX0
+i
, EMIT_1F
+ sz
- 1 );
192 vap_fmt_1
|= sz
<< (3 * i
);
197 /* RS can't put fragment position on the pixel stack, so stuff it in texcoord if needed */
198 if (RENDERINPUTS_TEST( index_bitset
, _TNL_ATTRIB_POS
) && (ctx
->FragmentProgram
._Current
->Base
.InputsRead
& FRAG_BIT_WPOS
)) {
199 int first_free_tex
= -1;
201 first_free_tex
= fog_id
+1;
203 if (RENDERINPUTS_TEST_RANGE( index_bitset
, _TNL_FIRST_TEX
, _TNL_LAST_TEX
)) {
205 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
206 if (!RENDERINPUTS_TEST( index_bitset
, _TNL_ATTRIB_TEX(i
) )) {
216 if (first_free_tex
== -1) {
217 fprintf(stderr
, "\tout of free texcoords to write w pos\n");
221 sz
= VB
->AttribPtr
[VERT_ATTRIB_POS
]->size
;
222 InputsRead
|= 1 << (VERT_ATTRIB_TEX0
+ first_free_tex
);
223 OutputsWritten
|= 1 << (VERT_RESULT_TEX0
+ first_free_tex
);
224 EMIT_ATTR( _TNL_ATTRIB_POS
, EMIT_1F
+ sz
- 1 );
225 vap_fmt_1
|= sz
<< (3 * first_free_tex
);
228 for (i
= 0, nr
= 0; i
< VERT_ATTRIB_MAX
; i
++) {
229 if (InputsRead
& (1 << i
)) {
236 /* Fixed, apply to vir0 only */
237 if (InputsRead
& (1 << VERT_ATTRIB_POS
))
238 inputs
[VERT_ATTRIB_POS
] = 0;
239 if (InputsRead
& (1 << VERT_ATTRIB_COLOR0
))
240 inputs
[VERT_ATTRIB_COLOR0
] = 2;
241 if (InputsRead
& (1 << VERT_ATTRIB_COLOR1
))
242 inputs
[VERT_ATTRIB_COLOR1
] = 3;
243 if (InputsRead
& (1 << VERT_ATTRIB_FOG
))
244 inputs
[VERT_ATTRIB_FOG
] = 6 + fog_id
;
245 for (i
= VERT_ATTRIB_TEX0
; i
<= VERT_ATTRIB_TEX7
; i
++)
246 if (InputsRead
& (1 << i
))
247 inputs
[i
] = 6 + (i
- VERT_ATTRIB_TEX0
);
249 for (i
= 0, nr
= 0; i
< VERT_ATTRIB_MAX
; i
++) {
250 if (InputsRead
& (1 << i
)) {
255 for (i
= 0; i
< nr
; i
++) {
258 swizzle
[i
][0] = SWIZZLE_ZERO
;
259 swizzle
[i
][1] = SWIZZLE_ZERO
;
260 swizzle
[i
][2] = SWIZZLE_ZERO
;
261 swizzle
[i
][3] = SWIZZLE_ONE
;
263 for (ci
= 0; ci
< VB
->AttribPtr
[tab
[i
]]->size
; ci
++) {
269 R300_STATECHANGE(rmesa
, vir
[0]);
270 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vir
[0].cmd
)->packet0
.count
=
271 r300VAPInputRoute0(&rmesa
->hw
.vir
[0].cmd
[R300_VIR_CNTL_0
],
272 VB
->AttribPtr
, inputs
, tab
, nr
);
273 R300_STATECHANGE(rmesa
, vir
[1]);
274 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vir
[1].cmd
)->packet0
.count
=
275 r300VAPInputRoute1(&rmesa
->hw
.vir
[1].cmd
[R300_VIR_CNTL_0
], swizzle
,
278 R300_STATECHANGE(rmesa
, vic
);
279 rmesa
->hw
.vic
.cmd
[R300_VIC_CNTL_0
] = r300VAPInputCntl0(ctx
, InputsRead
);
280 rmesa
->hw
.vic
.cmd
[R300_VIC_CNTL_1
] = r300VAPInputCntl1(ctx
, InputsRead
);
282 R300_STATECHANGE(rmesa
, vof
);
283 rmesa
->hw
.vof
.cmd
[R300_VOF_CNTL_0
] = r300VAPOutputCntl0(ctx
, OutputsWritten
);
284 rmesa
->hw
.vof
.cmd
[R300_VOF_CNTL_1
] = vap_fmt_1
;
286 rmesa
->swtcl
.vertex_size
=
287 _tnl_install_attrs( ctx
,
288 rmesa
->swtcl
.vertex_attrs
,
289 rmesa
->swtcl
.vertex_attr_count
,
292 rmesa
->swtcl
.vertex_size
/= 4;
294 RENDERINPUTS_COPY( rmesa
->tnl_index_bitset
, index_bitset
);
297 R300_STATECHANGE(rmesa
, vte
);
298 rmesa
->hw
.vte
.cmd
[1] = vte
;
299 rmesa
->hw
.vte
.cmd
[2] = rmesa
->swtcl
.vertex_size
;
303 /* Flush vertices in the current dma region.
305 static void flush_last_swtcl_prim( r300ContextPtr rmesa
)
307 if (RADEON_DEBUG
& DEBUG_IOCTL
)
308 fprintf(stderr
, "%s\n", __FUNCTION__
);
310 rmesa
->dma
.flush
= NULL
;
312 if (rmesa
->dma
.current
.buf
) {
313 struct r300_dma_region
*current
= &rmesa
->dma
.current
;
314 GLuint current_offset
= GET_START(current
);
316 assert (current
->start
+
317 rmesa
->swtcl
.numverts
* rmesa
->swtcl
.vertex_size
* 4 ==
320 if (rmesa
->dma
.current
.start
!= rmesa
->dma
.current
.ptr
) {
322 r300EnsureCmdBufSpace( rmesa
, rmesa
->hw
.max_state_size
+ (12*sizeof(int)), __FUNCTION__
);
324 r300EmitState(rmesa
);
326 r300EmitVertexAOS( rmesa
,
327 rmesa
->swtcl
.vertex_size
,
330 r300EmitVbufPrim( rmesa
,
331 rmesa
->swtcl
.hw_primitive
,
332 rmesa
->swtcl
.numverts
);
334 r300EmitCacheFlush(rmesa
);
337 rmesa
->swtcl
.numverts
= 0;
338 current
->start
= current
->ptr
;
342 /* Alloc space in the current dma region.
345 r300AllocDmaLowVerts( r300ContextPtr rmesa
, int nverts
, int vsize
)
347 GLuint bytes
= vsize
* nverts
;
349 if ( rmesa
->dma
.current
.ptr
+ bytes
> rmesa
->dma
.current
.end
)
350 r300RefillCurrentDmaRegion( rmesa
, bytes
);
352 if (!rmesa
->dma
.flush
) {
353 rmesa
->radeon
.glCtx
->Driver
.NeedFlush
|= FLUSH_STORED_VERTICES
;
354 rmesa
->dma
.flush
= flush_last_swtcl_prim
;
357 ASSERT( vsize
== rmesa
->swtcl
.vertex_size
* 4 );
358 ASSERT( rmesa
->dma
.flush
== flush_last_swtcl_prim
);
359 ASSERT( rmesa
->dma
.current
.start
+
360 rmesa
->swtcl
.numverts
* rmesa
->swtcl
.vertex_size
* 4 ==
361 rmesa
->dma
.current
.ptr
);
364 GLubyte
*head
= (GLubyte
*) (rmesa
->dma
.current
.address
+ rmesa
->dma
.current
.ptr
);
365 rmesa
->dma
.current
.ptr
+= bytes
;
366 rmesa
->swtcl
.numverts
+= nverts
;
371 static GLuint reduced_prim
[] = {
384 static void r300RasterPrimitive( GLcontext
*ctx
, GLuint prim
);
385 static void r300RenderPrimitive( GLcontext
*ctx
, GLenum prim
);
386 //static void r300ResetLineStipple( GLcontext *ctx );
388 /***********************************************************************
389 * Emit primitives as inline vertices *
390 ***********************************************************************/
393 #define HAVE_POINTS 1
395 #define HAVE_LINE_STRIPS 1
396 #define HAVE_TRIANGLES 1
397 #define HAVE_TRI_STRIPS 1
398 #define HAVE_TRI_STRIP_1 0
399 #define HAVE_TRI_FANS 1
401 #define HAVE_QUAD_STRIPS 0
402 #define HAVE_POLYGONS 1
407 #define CTX_ARG r300ContextPtr rmesa
408 #define GET_VERTEX_DWORDS() rmesa->swtcl.vertex_size
409 #define ALLOC_VERTS( n, size ) r300AllocDmaLowVerts( rmesa, n, size * 4 )
411 r300ContextPtr rmesa = R300_CONTEXT(ctx); \
412 const char *r300verts = (char *)rmesa->swtcl.verts;
413 #define VERT(x) (r300Vertex *)(r300verts + ((x) * vertsize * sizeof(int)))
414 #define VERTEX r300Vertex
415 #define DO_DEBUG_VERTS (1 && (RADEON_DEBUG & DEBUG_VERTS))
416 #define PRINT_VERTEX(x)
418 #define TAG(x) r300_##x
419 #include "tnl_dd/t_dd_triemit.h"
423 /***********************************************************************
424 * Macros for t_dd_tritmp.h to draw basic primitives *
425 ***********************************************************************/
427 #define QUAD( a, b, c, d ) r300_quad( rmesa, a, b, c, d )
428 #define TRI( a, b, c ) r300_triangle( rmesa, a, b, c )
429 #define LINE( a, b ) r300_line( rmesa, a, b )
430 #define POINT( a ) r300_point( rmesa, a )
432 /***********************************************************************
433 * Build render functions from dd templates *
434 ***********************************************************************/
436 #define R300_TWOSIDE_BIT 0x01
437 #define R300_UNFILLED_BIT 0x02
438 #define R300_MAX_TRIFUNC 0x04
441 tnl_points_func points
;
443 tnl_triangle_func triangle
;
445 } rast_tab
[R300_MAX_TRIFUNC
];
447 #define DO_FALLBACK 0
448 #define DO_UNFILLED (IND & R300_UNFILLED_BIT)
449 #define DO_TWOSIDE (IND & R300_TWOSIDE_BIT)
456 #define DO_FULL_QUAD 1
460 #define HAVE_BACK_COLORS 0
461 #define HAVE_HW_FLATSHADE 1
464 #define DEPTH_SCALE 1.0
465 #define UNFILLED_TRI unfilled_tri
466 #define UNFILLED_QUAD unfilled_quad
467 #define VERT_X(_v) _v->v.x
468 #define VERT_Y(_v) _v->v.y
469 #define VERT_Z(_v) _v->v.z
470 #define AREA_IS_CCW( a ) (a < 0)
471 #define GET_VERTEX(e) (rmesa->swtcl.verts + (e*rmesa->swtcl.vertex_size*sizeof(int)))
473 /* Only used to pull back colors into vertices (ie, we know color is
476 #define R300_COLOR( dst, src ) \
478 UNCLAMPED_FLOAT_TO_UBYTE((dst)[0], (src)[2]); \
479 UNCLAMPED_FLOAT_TO_UBYTE((dst)[1], (src)[1]); \
480 UNCLAMPED_FLOAT_TO_UBYTE((dst)[2], (src)[0]); \
481 UNCLAMPED_FLOAT_TO_UBYTE((dst)[3], (src)[3]); \
484 #define VERT_SET_RGBA( v, c ) if (coloroffset) R300_COLOR( v->ub4[coloroffset], c )
485 #define VERT_COPY_RGBA( v0, v1 ) if (coloroffset) v0->ui[coloroffset] = v1->ui[coloroffset]
486 #define VERT_SAVE_RGBA( idx ) if (coloroffset) color[idx] = v[idx]->ui[coloroffset]
487 #define VERT_RESTORE_RGBA( idx ) if (coloroffset) v[idx]->ui[coloroffset] = color[idx]
489 #define R300_SPEC( dst, src ) \
491 UNCLAMPED_FLOAT_TO_UBYTE((dst)[0], (src)[2]); \
492 UNCLAMPED_FLOAT_TO_UBYTE((dst)[1], (src)[1]); \
493 UNCLAMPED_FLOAT_TO_UBYTE((dst)[2], (src)[0]); \
496 #define VERT_SET_SPEC( v, c ) if (specoffset) R300_SPEC( v->ub4[specoffset], c )
497 #define VERT_COPY_SPEC( v0, v1 ) if (specoffset) COPY_3V(v0->ub4[specoffset], v1->ub4[specoffset])
498 #define VERT_SAVE_SPEC( idx ) if (specoffset) spec[idx] = v[idx]->ui[specoffset]
499 #define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->ui[specoffset] = spec[idx]
505 #define LOCAL_VARS(n) \
506 r300ContextPtr rmesa = R300_CONTEXT(ctx); \
507 GLuint color[n], spec[n]; \
508 GLuint coloroffset = rmesa->swtcl.coloroffset; \
509 GLuint specoffset = rmesa->swtcl.specoffset; \
510 (void) color; (void) spec; (void) coloroffset; (void) specoffset;
512 /***********************************************************************
513 * Helpers for rendering unfilled primitives *
514 ***********************************************************************/
516 #define RASTERIZE(x) r300RasterPrimitive( ctx, reduced_prim[x] )
517 #define RENDER_PRIMITIVE rmesa->swtcl.render_primitive
520 #include "tnl_dd/t_dd_unfilled.h"
524 /***********************************************************************
525 * Generate GL render functions *
526 ***********************************************************************/
531 #include "tnl_dd/t_dd_tritmp.h"
533 #define IND (R300_TWOSIDE_BIT)
534 #define TAG(x) x##_twoside
535 #include "tnl_dd/t_dd_tritmp.h"
537 #define IND (R300_UNFILLED_BIT)
538 #define TAG(x) x##_unfilled
539 #include "tnl_dd/t_dd_tritmp.h"
541 #define IND (R300_TWOSIDE_BIT|R300_UNFILLED_BIT)
542 #define TAG(x) x##_twoside_unfilled
543 #include "tnl_dd/t_dd_tritmp.h"
547 static void init_rast_tab( void )
552 init_twoside_unfilled();
555 /**********************************************************************/
556 /* Render unclipped begin/end objects */
557 /**********************************************************************/
559 #define RENDER_POINTS( start, count ) \
560 for ( ; start < count ; start++) \
561 r300_point( rmesa, VERT(start) )
562 #define RENDER_LINE( v0, v1 ) \
563 r300_line( rmesa, VERT(v0), VERT(v1) )
564 #define RENDER_TRI( v0, v1, v2 ) \
565 r300_triangle( rmesa, VERT(v0), VERT(v1), VERT(v2) )
566 #define RENDER_QUAD( v0, v1, v2, v3 ) \
567 r300_quad( rmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) )
568 #define INIT(x) do { \
569 r300RenderPrimitive( ctx, x ); \
573 r300ContextPtr rmesa = R300_CONTEXT(ctx); \
574 const GLuint vertsize = rmesa->swtcl.vertex_size; \
575 const char *r300verts = (char *)rmesa->swtcl.verts; \
576 const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
577 const GLboolean stipple = ctx->Line.StippleFlag; \
578 (void) elt; (void) stipple;
579 #define RESET_STIPPLE //if ( stipple ) r200ResetLineStipple( ctx );
580 #define RESET_OCCLUSION
581 #define PRESERVE_VB_DEFS
583 #define TAG(x) r300_##x##_verts
584 #include "tnl/t_vb_rendertmp.h"
587 #define TAG(x) r300_##x##_elts
588 #define ELT(x) elt[x]
589 #include "tnl/t_vb_rendertmp.h"
594 /**********************************************************************/
595 /* Choose render functions */
596 /**********************************************************************/
597 static void r300ChooseRenderState( GLcontext
*ctx
)
599 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
600 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
602 GLuint flags
= ctx
->_TriangleCaps
;
604 if (flags
& DD_TRI_LIGHT_TWOSIDE
) index
|= R300_TWOSIDE_BIT
;
605 if (flags
& DD_TRI_UNFILLED
) index
|= R300_UNFILLED_BIT
;
607 if (index
!= rmesa
->swtcl
.RenderIndex
) {
608 tnl
->Driver
.Render
.Points
= rast_tab
[index
].points
;
609 tnl
->Driver
.Render
.Line
= rast_tab
[index
].line
;
610 tnl
->Driver
.Render
.ClippedLine
= rast_tab
[index
].line
;
611 tnl
->Driver
.Render
.Triangle
= rast_tab
[index
].triangle
;
612 tnl
->Driver
.Render
.Quad
= rast_tab
[index
].quad
;
615 tnl
->Driver
.Render
.PrimTabVerts
= r300_render_tab_verts
;
616 tnl
->Driver
.Render
.PrimTabElts
= r300_render_tab_elts
;
617 tnl
->Driver
.Render
.ClippedPolygon
= r300_fast_clipped_poly
;
619 tnl
->Driver
.Render
.PrimTabVerts
= _tnl_render_tab_verts
;
620 tnl
->Driver
.Render
.PrimTabElts
= _tnl_render_tab_elts
;
621 tnl
->Driver
.Render
.ClippedPolygon
= _tnl_RenderClippedPolygon
;
624 rmesa
->swtcl
.RenderIndex
= index
;
629 static void r300RenderStart(GLcontext
*ctx
)
631 r300ContextPtr rmesa
= R300_CONTEXT( ctx
);
632 // fprintf(stderr, "%s\n", __FUNCTION__);
634 r300ChooseRenderState(ctx
);
635 r300SetVertexFormat(ctx
);
637 r300UpdateShaders(rmesa
);
638 r300UpdateShaderStates(rmesa
);
640 r300EmitCacheFlush(rmesa
);
642 if (rmesa
->dma
.flush
!= 0 &&
643 rmesa
->dma
.flush
!= flush_last_swtcl_prim
)
644 rmesa
->dma
.flush( rmesa
);
648 static void r300RenderFinish(GLcontext
*ctx
)
652 static void r300RasterPrimitive( GLcontext
*ctx
, GLuint hwprim
)
654 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
656 if (rmesa
->swtcl
.hw_primitive
!= hwprim
) {
657 R300_NEWPRIM( rmesa
);
658 rmesa
->swtcl
.hw_primitive
= hwprim
;
662 static void r300RenderPrimitive(GLcontext
*ctx
, GLenum prim
)
665 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
666 rmesa
->swtcl
.render_primitive
= prim
;
668 if ((prim
== GL_TRIANGLES
) && (ctx
->_TriangleCaps
& DD_TRI_UNFILLED
))
671 r300RasterPrimitive( ctx
, reduced_prim
[prim
] );
672 // fprintf(stderr, "%s\n", __FUNCTION__);
676 static void r300ResetLineStipple(GLcontext
*ctx
)
682 void r300InitSwtcl(GLcontext
*ctx
)
684 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
685 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
686 static int firsttime
= 1;
693 tnl
->Driver
.Render
.Start
= r300RenderStart
;
694 tnl
->Driver
.Render
.Finish
= r300RenderFinish
;
695 tnl
->Driver
.Render
.PrimitiveNotify
= r300RenderPrimitive
;
696 tnl
->Driver
.Render
.ResetLineStipple
= r300ResetLineStipple
;
697 tnl
->Driver
.Render
.BuildVertices
= _tnl_build_vertices
;
698 tnl
->Driver
.Render
.CopyPV
= _tnl_copy_pv
;
699 tnl
->Driver
.Render
.Interp
= _tnl_interp
;
701 /* FIXME: what are these numbers? */
702 _tnl_init_vertices( ctx
, ctx
->Const
.MaxArrayLockSize
+ 12,
703 48 * sizeof(GLfloat
) );
705 rmesa
->swtcl
.verts
= (GLubyte
*)tnl
->clipspace
.vertex_buf
;
706 rmesa
->swtcl
.RenderIndex
= ~0;
707 rmesa
->swtcl
.render_primitive
= GL_TRIANGLES
;
708 rmesa
->swtcl
.hw_primitive
= 0;
710 _tnl_invalidate_vertex_state( ctx
, ~0 );
711 _tnl_invalidate_vertices( ctx
, ~0 );
712 RENDERINPUTS_ZERO( rmesa
->tnl_index_bitset
);
714 _tnl_need_projected_coords( ctx
, GL_FALSE
);
715 r300ChooseRenderState(ctx
);
717 _mesa_validate_all_lighting_tables( ctx
);
719 tnl
->Driver
.NotifyMaterialChange
=
720 _mesa_validate_all_lighting_tables
;
723 void r300DestroySwtcl(GLcontext
*ctx
)
727 void r300EmitVertexAOS(r300ContextPtr rmesa
, GLuint vertex_size
, GLuint offset
)
729 int cmd_reserved
= 0;
732 drm_radeon_cmd_header_t
*cmd
= NULL
;
733 if (RADEON_DEBUG
& DEBUG_VERTS
)
734 fprintf(stderr
, "%s: vertex_size %d, offset 0x%x \n",
735 __FUNCTION__
, vertex_size
, offset
);
737 start_packet3(CP_PACKET3(R300_PACKET3_3D_LOAD_VBPNTR
, 2), 2);
739 e32(vertex_size
| (vertex_size
<< 8));
743 void r300EmitVbufPrim(r300ContextPtr rmesa
, GLuint primitive
, GLuint vertex_nr
)
746 int cmd_reserved
= 0;
749 drm_radeon_cmd_header_t
*cmd
= NULL
;
751 type
= r300PrimitiveType(rmesa
, primitive
);
752 num_verts
= r300NumVerts(rmesa
, vertex_nr
, primitive
);
754 start_packet3(CP_PACKET3(R300_PACKET3_3D_DRAW_VBUF_2
, 0), 0);
755 e32(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST
| (num_verts
<< 16) | type
);