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 */
45 #include "swrast/s_context.h"
46 #include "swrast/s_fog.h"
47 #include "swrast_setup/swrast_setup.h"
48 #include "math/m_translate.h"
50 #include "tnl/t_context.h"
51 #include "tnl/t_pipeline.h"
53 #include "r300_context.h"
54 #include "r300_swtcl.h"
55 #include "r300_state.h"
56 #include "r300_ioctl.h"
57 #include "r300_emit.h"
60 #define R300_NEWPRIM( rmesa ) \
62 if ( rmesa->dma.flush ) \
63 rmesa->dma.flush( rmesa ); \
66 static void flush_last_swtcl_prim( r300ContextPtr rmesa
);
69 void r300EmitVertexAOS(r300ContextPtr rmesa
, GLuint vertex_size
, GLuint offset
);
70 void r300EmitVbufPrim(r300ContextPtr rmesa
, GLuint primitive
, GLuint vertex_nr
);
71 #define EMIT_ATTR( ATTR, STYLE ) \
73 rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].attrib = (ATTR); \
74 rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].format = (STYLE); \
75 rmesa->swtcl.vertex_attr_count++; \
78 #define EMIT_PAD( N ) \
80 rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].attrib = 0; \
81 rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].format = EMIT_PAD; \
82 rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].offset = (N); \
83 rmesa->swtcl.vertex_attr_count++; \
86 static GLuint
r300VAPInputRoute0(uint32_t * dst
, GLvector4f
** attribptr
,
87 int *inputs
, GLint
* tab
, GLuint nr
)
91 /* type, inputs, stop bit, size */
92 for (i
= 0; i
+ 1 < nr
; i
+= 2) {
93 dw
= (inputs
[tab
[i
]] << 8) | 0x3;
94 dw
|= ((inputs
[tab
[i
+ 1]] << 8) | 0x3) << 16;
96 dw
|= (R300_VAP_INPUT_ROUTE_END
<< 16);
102 dw
= (inputs
[tab
[nr
- 1]] << 8) | 0x3;
103 dw
|= R300_VAP_INPUT_ROUTE_END
;
107 return (nr
+ 1) >> 1;
110 static GLuint
r300VAPInputRoute1Swizzle(int swizzle
[4])
112 return (swizzle
[0] << R300_INPUT_ROUTE_X_SHIFT
) |
113 (swizzle
[1] << R300_INPUT_ROUTE_Y_SHIFT
) |
114 (swizzle
[2] << R300_INPUT_ROUTE_Z_SHIFT
) |
115 (swizzle
[3] << R300_INPUT_ROUTE_W_SHIFT
);
118 static GLuint
r300VAPInputRoute1(uint32_t * dst
, int swizzle
[][4], GLuint nr
)
122 for (i
= 0; i
+ 1 < nr
; i
+= 2) {
123 dst
[i
>> 1] = r300VAPInputRoute1Swizzle(swizzle
[i
]) | R300_INPUT_ROUTE_ENABLE
;
124 dst
[i
>> 1] |= (r300VAPInputRoute1Swizzle(swizzle
[i
+ 1]) | R300_INPUT_ROUTE_ENABLE
) << 16;
128 dst
[nr
>> 1] = r300VAPInputRoute1Swizzle(swizzle
[nr
- 1]) | R300_INPUT_ROUTE_ENABLE
;
131 return (nr
+ 1) >> 1;
134 static GLuint
r300VAPInputCntl0(GLcontext
* ctx
, GLuint InputsRead
)
136 /* No idea what this value means. I have seen other values written to
137 * this register... */
141 static GLuint
r300VAPInputCntl1(GLcontext
* ctx
, GLuint InputsRead
)
143 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
146 if (InputsRead
& (1 << VERT_ATTRIB_POS
))
147 vic_1
|= R300_INPUT_CNTL_POS
;
149 if (InputsRead
& (1 << VERT_ATTRIB_NORMAL
))
150 vic_1
|= R300_INPUT_CNTL_NORMAL
;
152 if (InputsRead
& (1 << VERT_ATTRIB_COLOR0
))
153 vic_1
|= R300_INPUT_CNTL_COLOR
;
155 rmesa
->state
.texture
.tc_count
= 0;
156 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++)
157 if (InputsRead
& (1 << (VERT_ATTRIB_TEX0
+ i
))) {
158 rmesa
->state
.texture
.tc_count
++;
159 vic_1
|= R300_INPUT_CNTL_TC0
<< i
;
165 static GLuint
r300VAPOutputCntl0(GLcontext
* ctx
, GLuint OutputsWritten
)
169 if (OutputsWritten
& (1 << VERT_RESULT_HPOS
))
170 ret
|= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
;
172 if (OutputsWritten
& (1 << VERT_RESULT_COL0
))
173 ret
|= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT
;
175 if (OutputsWritten
& (1 << VERT_RESULT_COL1
))
176 ret
|= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT
;
179 if (OutputsWritten
& (1 << VERT_RESULT_BFC0
))
180 ret
|= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT
;
182 if (OutputsWritten
& (1 << VERT_RESULT_BFC1
))
183 ret
|= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT
;
185 if (OutputsWritten
& (1 << VERT_RESULT_FOGC
)) ;
188 if (OutputsWritten
& (1 << VERT_RESULT_PSIZ
))
189 ret
|= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT
;
194 static GLuint
r300VAPOutputCntl1(GLcontext
* ctx
, GLuint OutputsWritten
)
198 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
199 if (OutputsWritten
& (1 << (VERT_RESULT_TEX0
+ i
))) {
200 ret
|= (4 << (3 * i
));
207 static void r300SetVertexFormat( GLcontext
*ctx
)
209 r300ContextPtr rmesa
= R300_CONTEXT( ctx
);
210 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
211 struct vertex_buffer
*VB
= &tnl
->vb
;
212 DECLARE_RENDERINPUTS(index_bitset
);
213 GLuint InputsRead
= 0, OutputsWritten
= 0;
215 int vap_vte_cntl
= 0;
218 GLuint inputs
[VERT_ATTRIB_MAX
];
219 GLint tab
[VERT_ATTRIB_MAX
];
220 int swizzle
[VERT_ATTRIB_MAX
][4];
223 DECLARE_RENDERINPUTS(render_inputs_bitset
);
225 RENDERINPUTS_COPY(render_inputs_bitset
, tnl
->render_inputs_bitset
);
227 RENDERINPUTS_COPY( index_bitset
, tnl
->render_inputs_bitset
);
229 RENDERINPUTS_COPY(rmesa
->state
.render_inputs_bitset
, render_inputs_bitset
);
233 if ( VB
->NdcPtr
!= NULL
) {
234 VB
->AttribPtr
[VERT_ATTRIB_POS
] = VB
->NdcPtr
;
237 VB
->AttribPtr
[VERT_ATTRIB_POS
] = VB
->ClipPtr
;
240 assert( VB
->AttribPtr
[VERT_ATTRIB_POS
] != NULL
);
241 rmesa
->swtcl
.vertex_attr_count
= 0;
243 /* EMIT_ATTR's must be in order as they tell t_vertex.c how to
244 * build up a hardware vertex.
246 EMIT_ATTR( _TNL_ATTRIB_POS
, EMIT_4F
);
247 vap_vte_cntl
|= R300_VTX_W0_FMT
;
248 InputsRead
|= 1 << VERT_ATTRIB_POS
;
249 OutputsWritten
|= 1 << VERT_RESULT_HPOS
;
252 if (RENDERINPUTS_TEST( index_bitset
, _TNL_ATTRIB_POINTSIZE
)) {
253 EMIT_ATTR( _TNL_ATTRIB_POINTSIZE
, EMIT_1F
);
254 vap_fmt_0
|= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT
;
258 rmesa
->swtcl
.coloroffset
= offset
;
259 #if MESA_LITTLE_ENDIAN
260 EMIT_ATTR( _TNL_ATTRIB_COLOR0
, EMIT_4F
);
262 EMIT_ATTR( _TNL_ATTRIB_COLOR0
, EMIT_4F
);
265 InputsRead
|= 1 << VERT_ATTRIB_COLOR0
;
266 OutputsWritten
|= 1 << VERT_RESULT_COL0
;
269 rmesa
->swtcl
.specoffset
= 0;
270 if (RENDERINPUTS_TEST( index_bitset
, _TNL_ATTRIB_COLOR1
) ||
271 RENDERINPUTS_TEST( index_bitset
, _TNL_ATTRIB_FOG
)) {
273 #if MESA_LITTLE_ENDIAN
274 if (RENDERINPUTS_TEST( index_bitset
, _TNL_ATTRIB_COLOR1
)) {
275 rmesa
->swtcl
.specoffset
= offset
;
276 EMIT_ATTR( _TNL_ATTRIB_COLOR1
, EMIT_3F
);
277 InputsRead
|= 1 << VERT_ATTRIB_COLOR1
;
278 OutputsWritten
|= 1 << VERT_RESULT_COL1
;
284 if (RENDERINPUTS_TEST( index_bitset
, _TNL_ATTRIB_FOG
)) {
285 EMIT_ATTR( _TNL_ATTRIB_FOG
, EMIT_1UB_1F
);
286 InputsRead
|= 1 << VERT_ATTRIB_COLOR1
;
287 OutputsWritten
|= 1 << VERT_RESULT_COL1
;
293 if (RENDERINPUTS_TEST( index_bitset
, _TNL_ATTRIB_FOG
)) {
294 EMIT_ATTR( _TNL_ATTRIB_FOG
, EMIT_1UB_1F
);
295 InputsRead
|= 1 << VERT_ATTRIB_COLOR1
;
296 OutputsWritten
|= 1 << VERT_RESULT_COL1
;
302 if (RENDERINPUTS_TEST( index_bitset
, _TNL_ATTRIB_COLOR1
)) {
303 rmesa
->swtcl
.specoffset
= offset
;
304 EMIT_ATTR( _TNL_ATTRIB_COLOR1
, EMIT_3UB_3F_BGR
);
305 InputsRead
|= 1 << VERT_ATTRIB_COLOR1
;
306 OutputsWritten
|= 1 << VERT_RESULT_COL1
;
314 if (RENDERINPUTS_TEST_RANGE( index_bitset
, _TNL_FIRST_TEX
, _TNL_LAST_TEX
)) {
317 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
318 if (RENDERINPUTS_TEST( index_bitset
, _TNL_ATTRIB_TEX(i
) )) {
319 GLuint sz
= VB
->TexCoordPtr
[i
]->size
;
321 InputsRead
|= 1 << (VERT_ATTRIB_TEX0
+ i
);
322 OutputsWritten
|= 1 << (VERT_RESULT_TEX0
+ i
);
323 EMIT_ATTR( _TNL_ATTRIB_TEX0
+i
, EMIT_4F
);
329 if ( (rmesa
->hw
.ctx
.cmd
[CTX_PP_FOG_COLOR
] & R200_FOG_USE_MASK
)
330 != R200_FOG_USE_SPEC_ALPHA
) {
331 R200_STATECHANGE( rmesa
, ctx
);
332 rmesa
->hw
.ctx
.cmd
[CTX_PP_FOG_COLOR
] &= ~R200_FOG_USE_MASK
;
333 rmesa
->hw
.ctx
.cmd
[CTX_PP_FOG_COLOR
] |= R200_FOG_USE_SPEC_ALPHA
;
337 for (i
= 0, nr
= 0; i
< VERT_ATTRIB_MAX
; i
++) {
338 if (InputsRead
& (1 << i
)) {
345 /* Fixed, apply to vir0 only */
346 if (InputsRead
& VERT_ATTRIB_POS
)
347 inputs
[VERT_ATTRIB_POS
] = 0;
348 if (InputsRead
& (1 << VERT_ATTRIB_COLOR0
))
349 inputs
[VERT_ATTRIB_COLOR0
] = 2;
350 if (InputsRead
& (1 << VERT_ATTRIB_COLOR1
))
351 inputs
[VERT_ATTRIB_COLOR1
] = 3;
352 for (i
= VERT_ATTRIB_TEX0
; i
<= VERT_ATTRIB_TEX7
; i
++)
353 if (InputsRead
& (1 << i
))
354 inputs
[i
] = 6 + (i
- VERT_ATTRIB_TEX0
);
356 for (i
= 0, nr
= 0; i
< VERT_ATTRIB_MAX
; i
++) {
357 if (InputsRead
& (1 << i
)) {
362 for (i
= 0; i
< nr
; i
++) {
363 int ci
, fix
, found
= 0;
365 swizzle
[i
][0] = SWIZZLE_ZERO
;
366 swizzle
[i
][1] = SWIZZLE_ZERO
;
367 swizzle
[i
][2] = SWIZZLE_ZERO
;
368 swizzle
[i
][3] = SWIZZLE_ONE
;
370 for (ci
= 0; ci
< VB
->AttribPtr
[tab
[i
]]->size
; ci
++) {
375 R300_STATECHANGE(rmesa
, vir
[0]);
376 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vir
[0].cmd
)->packet0
.count
=
377 r300VAPInputRoute0(&rmesa
->hw
.vir
[0].cmd
[R300_VIR_CNTL_0
],
378 VB
->AttribPtr
, inputs
, tab
, nr
);
379 R300_STATECHANGE(rmesa
, vir
[1]);
380 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vir
[1].cmd
)->packet0
.count
=
381 r300VAPInputRoute1(&rmesa
->hw
.vir
[1].cmd
[R300_VIR_CNTL_0
], swizzle
,
384 R300_STATECHANGE(rmesa
, vic
);
385 rmesa
->hw
.vic
.cmd
[R300_VIC_CNTL_0
] = r300VAPInputCntl0(ctx
, InputsRead
);
386 rmesa
->hw
.vic
.cmd
[R300_VIC_CNTL_1
] = r300VAPInputCntl1(ctx
, InputsRead
);
388 R300_STATECHANGE(rmesa
, vof
);
389 rmesa
->hw
.vof
.cmd
[R300_VOF_CNTL_0
] = r300VAPOutputCntl0(ctx
, OutputsWritten
);
390 rmesa
->hw
.vof
.cmd
[R300_VOF_CNTL_1
] = r300VAPOutputCntl1(ctx
, OutputsWritten
);
392 if (!RENDERINPUTS_EQUAL( rmesa
->tnl_index_bitset
, index_bitset
)) {
394 rmesa
->swtcl
.vertex_size
=
395 _tnl_install_attrs( ctx
,
396 rmesa
->swtcl
.vertex_attrs
,
397 rmesa
->swtcl
.vertex_attr_count
,
400 rmesa
->swtcl
.vertex_size
/= 4;
401 RENDERINPUTS_COPY( rmesa
->tnl_index_bitset
, index_bitset
);
403 vte
= rmesa
->hw
.vte
.cmd
[1];
404 R300_STATECHANGE(rmesa
, vte
);
405 rmesa
->hw
.vte
.cmd
[1] = vte
;
406 rmesa
->hw
.vte
.cmd
[2] = rmesa
->swtcl
.vertex_size
;
411 /* Flush vertices in the current dma region.
413 static void flush_last_swtcl_prim( r300ContextPtr rmesa
)
415 if (RADEON_DEBUG
& DEBUG_IOCTL
)
416 fprintf(stderr
, "%s\n", __FUNCTION__
);
418 rmesa
->dma
.flush
= NULL
;
420 if (rmesa
->dma
.current
.buf
) {
421 struct r300_dma_region
*current
= &rmesa
->dma
.current
;
422 GLuint current_offset
= GET_START(current
);
424 assert (current
->start
+
425 rmesa
->swtcl
.numverts
* rmesa
->swtcl
.vertex_size
* 4 ==
428 if (rmesa
->dma
.current
.start
!= rmesa
->dma
.current
.ptr
) {
430 r300EmitVertexAOS( rmesa
,
431 rmesa
->swtcl
.vertex_size
,
434 r300EmitVbufPrim( rmesa
,
435 rmesa
->swtcl
.hw_primitive
,
436 rmesa
->swtcl
.numverts
);
439 rmesa
->swtcl
.numverts
= 0;
440 current
->start
= current
->ptr
;
444 /* Alloc space in the current dma region.
447 r300AllocDmaLowVerts( r300ContextPtr rmesa
, int nverts
, int vsize
)
449 GLuint bytes
= vsize
* nverts
;
451 if ( rmesa
->dma
.current
.ptr
+ bytes
> rmesa
->dma
.current
.end
)
452 r300RefillCurrentDmaRegion( rmesa
, bytes
);
454 if (!rmesa
->dma
.flush
) {
455 rmesa
->radeon
.glCtx
->Driver
.NeedFlush
|= FLUSH_STORED_VERTICES
;
456 rmesa
->dma
.flush
= flush_last_swtcl_prim
;
459 ASSERT( vsize
== rmesa
->swtcl
.vertex_size
* 4 );
460 ASSERT( rmesa
->dma
.flush
== flush_last_swtcl_prim
);
461 ASSERT( rmesa
->dma
.current
.start
+
462 rmesa
->swtcl
.numverts
* rmesa
->swtcl
.vertex_size
* 4 ==
463 rmesa
->dma
.current
.ptr
);
467 GLubyte
*head
= (GLubyte
*) (rmesa
->dma
.current
.address
+ rmesa
->dma
.current
.ptr
);
468 rmesa
->dma
.current
.ptr
+= bytes
;
469 rmesa
->swtcl
.numverts
+= nverts
;
475 static GLuint reduced_prim
[] = {
488 static void r300RasterPrimitive( GLcontext
*ctx
, GLuint prim
);
489 static void r300RenderPrimitive( GLcontext
*ctx
, GLenum prim
);
490 //static void r300ResetLineStipple( GLcontext *ctx );
492 /***********************************************************************
493 * Emit primitives as inline vertices *
494 ***********************************************************************/
497 #define HAVE_POINTS 1
499 #define HAVE_LINE_STRIPS 1
500 #define HAVE_TRIANGLES 1
501 #define HAVE_TRI_STRIPS 1
502 #define HAVE_TRI_STRIP_1 0
503 #define HAVE_TRI_FANS 1
505 #define HAVE_QUAD_STRIPS 0
506 #define HAVE_POLYGONS 1
511 #define CTX_ARG r300ContextPtr rmesa
512 #define GET_VERTEX_DWORDS() rmesa->swtcl.vertex_size
513 #define ALLOC_VERTS( n, size ) r300AllocDmaLowVerts( rmesa, n, size * 4 )
515 r300ContextPtr rmesa = R300_CONTEXT(ctx); \
516 const char *r300verts = (char *)rmesa->swtcl.verts;
517 #define VERT(x) (r300Vertex *)(r300verts + ((x) * vertsize * sizeof(int)))
518 #define VERTEX r300Vertex
519 #define DO_DEBUG_VERTS (1 && (RADEON_DEBUG & DEBUG_VERTS))
520 #define PRINT_VERTEX(x)
522 #define TAG(x) r300_##x
523 #include "tnl_dd/t_dd_triemit.h"
527 /***********************************************************************
528 * Macros for t_dd_tritmp.h to draw basic primitives *
529 ***********************************************************************/
531 #define QUAD( a, b, c, d ) r300_quad( rmesa, a, b, c, d )
532 #define TRI( a, b, c ) r300_triangle( rmesa, a, b, c )
533 #define LINE( a, b ) r300_line( rmesa, a, b )
534 #define POINT( a ) r300_point( rmesa, a )
536 /***********************************************************************
537 * Build render functions from dd templates *
538 ***********************************************************************/
540 #define R300_TWOSIDE_BIT 0x01
541 #define R300_UNFILLED_BIT 0x02
542 #define R300_MAX_TRIFUNC 0x04
545 tnl_points_func points
;
547 tnl_triangle_func triangle
;
549 } rast_tab
[R300_MAX_TRIFUNC
];
551 #define DO_FALLBACK 0
552 #define DO_UNFILLED (IND & R300_UNFILLED_BIT)
553 #define DO_TWOSIDE (IND & R300_TWOSIDE_BIT)
560 #define DO_FULL_QUAD 1
564 #define HAVE_BACK_COLORS 0
565 #define HAVE_HW_FLATSHADE 1
568 #define DEPTH_SCALE 1.0
569 #define UNFILLED_TRI unfilled_tri
570 #define UNFILLED_QUAD unfilled_quad
571 #define VERT_X(_v) _v->v.x
572 #define VERT_Y(_v) _v->v.y
573 #define VERT_Z(_v) _v->v.z
574 #define AREA_IS_CCW( a ) (a < 0)
575 #define GET_VERTEX(e) (rmesa->swtcl.verts + (e*rmesa->swtcl.vertex_size*sizeof(int)))
577 /* Only used to pull back colors into vertices (ie, we know color is
580 #define R300_COLOR( dst, src ) \
582 UNCLAMPED_FLOAT_TO_UBYTE((dst)[0], (src)[2]); \
583 UNCLAMPED_FLOAT_TO_UBYTE((dst)[1], (src)[1]); \
584 UNCLAMPED_FLOAT_TO_UBYTE((dst)[2], (src)[0]); \
585 UNCLAMPED_FLOAT_TO_UBYTE((dst)[3], (src)[3]); \
588 #define VERT_SET_RGBA( v, c ) if (coloroffset) R300_COLOR( v->ub4[coloroffset], c )
589 #define VERT_COPY_RGBA( v0, v1 ) if (coloroffset) v0->ui[coloroffset] = v1->ui[coloroffset]
590 #define VERT_SAVE_RGBA( idx ) if (coloroffset) color[idx] = v[idx]->ui[coloroffset]
591 #define VERT_RESTORE_RGBA( idx ) if (coloroffset) v[idx]->ui[coloroffset] = color[idx]
593 #define R300_SPEC( dst, src ) \
595 UNCLAMPED_FLOAT_TO_UBYTE((dst)[0], (src)[2]); \
596 UNCLAMPED_FLOAT_TO_UBYTE((dst)[1], (src)[1]); \
597 UNCLAMPED_FLOAT_TO_UBYTE((dst)[2], (src)[0]); \
600 #define VERT_SET_SPEC( v, c ) if (specoffset) R300_SPEC( v->ub4[specoffset], c )
601 #define VERT_COPY_SPEC( v0, v1 ) if (specoffset) COPY_3V(v0->ub4[specoffset], v1->ub4[specoffset])
602 #define VERT_SAVE_SPEC( idx ) if (specoffset) spec[idx] = v[idx]->ui[specoffset]
603 #define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->ui[specoffset] = spec[idx]
609 #define LOCAL_VARS(n) \
610 r300ContextPtr rmesa = R300_CONTEXT(ctx); \
611 GLuint color[n], spec[n]; \
612 GLuint coloroffset = rmesa->swtcl.coloroffset; \
613 GLuint specoffset = rmesa->swtcl.specoffset; \
614 (void) color; (void) spec; (void) coloroffset; (void) specoffset;
616 /***********************************************************************
617 * Helpers for rendering unfilled primitives *
618 ***********************************************************************/
620 #define RASTERIZE(x) r300RasterPrimitive( ctx, reduced_prim[x] )
621 #define RENDER_PRIMITIVE rmesa->swtcl.render_primitive
624 #include "tnl_dd/t_dd_unfilled.h"
628 /***********************************************************************
629 * Generate GL render functions *
630 ***********************************************************************/
635 #include "tnl_dd/t_dd_tritmp.h"
637 #define IND (R300_TWOSIDE_BIT)
638 #define TAG(x) x##_twoside
639 #include "tnl_dd/t_dd_tritmp.h"
641 #define IND (R300_UNFILLED_BIT)
642 #define TAG(x) x##_unfilled
643 #include "tnl_dd/t_dd_tritmp.h"
645 #define IND (R300_TWOSIDE_BIT|R300_UNFILLED_BIT)
646 #define TAG(x) x##_twoside_unfilled
647 #include "tnl_dd/t_dd_tritmp.h"
651 static void init_rast_tab( void )
656 init_twoside_unfilled();
659 /**********************************************************************/
660 /* Render unclipped begin/end objects */
661 /**********************************************************************/
663 #define RENDER_POINTS( start, count ) \
664 for ( ; start < count ; start++) \
665 r300_point( rmesa, VERT(start) )
666 #define RENDER_LINE( v0, v1 ) \
667 r300_line( rmesa, VERT(v0), VERT(v1) )
668 #define RENDER_TRI( v0, v1, v2 ) \
669 r300_triangle( rmesa, VERT(v0), VERT(v1), VERT(v2) )
670 #define RENDER_QUAD( v0, v1, v2, v3 ) \
671 r300_quad( rmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) )
672 #define INIT(x) do { \
673 r300RenderPrimitive( ctx, x ); \
677 r300ContextPtr rmesa = R300_CONTEXT(ctx); \
678 const GLuint vertsize = rmesa->swtcl.vertex_size; \
679 const char *r300verts = (char *)rmesa->swtcl.verts; \
680 const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
681 const GLboolean stipple = ctx->Line.StippleFlag; \
682 (void) elt; (void) stipple;
683 #define RESET_STIPPLE //if ( stipple ) r200ResetLineStipple( ctx );
684 #define RESET_OCCLUSION
685 #define PRESERVE_VB_DEFS
687 #define TAG(x) r300_##x##_verts
688 #include "tnl/t_vb_rendertmp.h"
691 #define TAG(x) r300_##x##_elts
692 #define ELT(x) elt[x]
693 #include "tnl/t_vb_rendertmp.h"
698 /**********************************************************************/
699 /* Choose render functions */
700 /**********************************************************************/
701 static void r300ChooseRenderState( GLcontext
*ctx
)
703 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
704 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
706 GLuint flags
= ctx
->_TriangleCaps
;
708 // if (!rmesa->TclFallback || rmesa->Fallback)
711 if (flags
& DD_TRI_LIGHT_TWOSIDE
) index
|= R300_TWOSIDE_BIT
;
712 if (flags
& DD_TRI_UNFILLED
) index
|= R300_UNFILLED_BIT
;
714 if (index
!= rmesa
->swtcl
.RenderIndex
) {
715 tnl
->Driver
.Render
.Points
= rast_tab
[index
].points
;
716 tnl
->Driver
.Render
.Line
= rast_tab
[index
].line
;
717 tnl
->Driver
.Render
.ClippedLine
= rast_tab
[index
].line
;
718 tnl
->Driver
.Render
.Triangle
= rast_tab
[index
].triangle
;
719 tnl
->Driver
.Render
.Quad
= rast_tab
[index
].quad
;
722 tnl
->Driver
.Render
.PrimTabVerts
= r300_render_tab_verts
;
723 tnl
->Driver
.Render
.PrimTabElts
= r300_render_tab_elts
;
724 tnl
->Driver
.Render
.ClippedPolygon
= r300_fast_clipped_poly
;
726 tnl
->Driver
.Render
.PrimTabVerts
= _tnl_render_tab_verts
;
727 tnl
->Driver
.Render
.PrimTabElts
= _tnl_render_tab_elts
;
728 tnl
->Driver
.Render
.ClippedPolygon
= _tnl_RenderClippedPolygon
;
731 rmesa
->swtcl
.RenderIndex
= index
;
736 static void r300RenderStart(GLcontext
*ctx
)
738 r300ContextPtr rmesa
= R300_CONTEXT( ctx
);
739 int cmd_reserved
= 0;
741 drm_radeon_cmd_header_t
*cmd
= NULL
;
743 // fprintf(stderr, "%s\n", __FUNCTION__);
745 r300SetVertexFormat(ctx
);
747 r300UpdateShaderStates(rmesa
);
749 reg_start(R300_RB3D_DSTCACHE_CTLSTAT
, 0);
750 e32(R300_RB3D_DSTCACHE_UNKNOWN_0A
);
752 reg_start(R300_RB3D_ZCACHE_CTLSTAT
, 0);
753 e32(R300_RB3D_ZCACHE_UNKNOWN_03
);
756 if (rmesa
->dma
.flush
!= 0 &&
757 rmesa
->dma
.flush
!= flush_last_swtcl_prim
)
758 rmesa
->dma
.flush( rmesa
);
761 static void r300RenderFinish(GLcontext
*ctx
)
763 r300ContextPtr rmesa
= R300_CONTEXT( ctx
);
764 int cmd_reserved
= 0;
766 drm_radeon_cmd_header_t
*cmd
= NULL
;
768 reg_start(R300_RB3D_DSTCACHE_CTLSTAT
, 0);
769 e32(R300_RB3D_DSTCACHE_UNKNOWN_0A
);
771 reg_start(R300_RB3D_ZCACHE_CTLSTAT
, 0);
772 e32(R300_RB3D_ZCACHE_UNKNOWN_03
);
775 static void r300RasterPrimitive( GLcontext
*ctx
, GLuint hwprim
)
777 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
779 if (rmesa
->swtcl
.hw_primitive
!= hwprim
) {
780 R300_NEWPRIM( rmesa
);
781 rmesa
->swtcl
.hw_primitive
= hwprim
;
785 static void r300RenderPrimitive(GLcontext
*ctx
, GLenum prim
)
788 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
789 rmesa
->swtcl
.render_primitive
= prim
;
790 if (prim
< GL_TRIANGLES
|| !(ctx
->_TriangleCaps
& DD_TRI_UNFILLED
))
791 r300RasterPrimitive( ctx
, reduced_prim
[prim
] );
792 // fprintf(stderr, "%s\n", __FUNCTION__);
796 static void r300ResetLineStipple(GLcontext
*ctx
)
802 void r300InitSwtcl(GLcontext
*ctx
)
804 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
805 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
806 static int firsttime
= 1;
813 tnl
->Driver
.Render
.Start
= r300RenderStart
;
814 tnl
->Driver
.Render
.Finish
= r300RenderFinish
;
815 tnl
->Driver
.Render
.PrimitiveNotify
= r300RenderPrimitive
;
816 tnl
->Driver
.Render
.ResetLineStipple
= r300ResetLineStipple
;
817 tnl
->Driver
.Render
.BuildVertices
= _tnl_build_vertices
;
818 tnl
->Driver
.Render
.CopyPV
= _tnl_copy_pv
;
819 tnl
->Driver
.Render
.Interp
= _tnl_interp
;
821 /* FIXME: what are these numbers? */
822 _tnl_init_vertices( ctx
, ctx
->Const
.MaxArrayLockSize
+ 12,
823 48 * sizeof(GLfloat
) );
825 rmesa
->swtcl
.verts
= (GLubyte
*)tnl
->clipspace
.vertex_buf
;
826 rmesa
->swtcl
.RenderIndex
= ~0;
827 rmesa
->swtcl
.render_primitive
= GL_TRIANGLES
;
828 rmesa
->swtcl
.hw_primitive
= 0;
830 _tnl_invalidate_vertex_state( ctx
, ~0 );
831 _tnl_invalidate_vertices( ctx
, ~0 );
832 RENDERINPUTS_ZERO( rmesa
->tnl_index_bitset
);
834 _tnl_need_projected_coords( ctx
, GL_FALSE
);
835 r300ChooseRenderState(ctx
);
838 void r300DestroySwtcl(GLcontext
*ctx
)
842 void r300EmitVertexAOS(r300ContextPtr rmesa
, GLuint vertex_size
, GLuint offset
)
844 int cmd_reserved
= 0;
849 drm_radeon_cmd_header_t
*cmd
= NULL
;
850 if (RADEON_DEBUG
& DEBUG_VERTS
)
851 fprintf(stderr
, "%s: vertex_size %d, offset 0x%x \n",
852 __FUNCTION__
, vertex_size
, offset
);
856 start_packet3(CP_PACKET3(R300_PACKET3_3D_LOAD_VBPNTR
, 2), 2);
858 e32(vertex_size
| (vertex_size
<< 8));
862 void r300EmitVbufPrim(r300ContextPtr rmesa
, GLuint primitive
, GLuint vertex_nr
)
865 int cmd_reserved
= 0;
868 drm_radeon_cmd_header_t
*cmd
= NULL
;
870 type
= r300PrimitiveType(rmesa
, primitive
);
871 num_verts
= r300NumVerts(rmesa
, vertex_nr
, primitive
);
873 r300EmitState(rmesa
);
875 start_packet3(CP_PACKET3(R300_PACKET3_3D_DRAW_VBUF_2
, 0), 0);
876 e32(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST
| (num_verts
<< 16) | type
);