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>
31 * Maciej Cencora <m.cencora@gmail.com>
35 #include "tnl/t_pipeline.h"
37 #include "r300_swtcl.h"
38 #include "r300_emit.h"
41 #define EMIT_ATTR( ATTR, STYLE ) \
43 rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].attrib = (ATTR); \
44 rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].format = (STYLE); \
45 rmesa->radeon.swtcl.vertex_attr_count++; \
48 #define EMIT_PAD( N ) \
50 rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].attrib = 0; \
51 rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].format = EMIT_PAD; \
52 rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].offset = (N); \
53 rmesa->radeon.swtcl.vertex_attr_count++; \
56 #define ADD_ATTR(_attr, _format, _dst_loc, _swizzle, _write_mask) \
58 attrs[num_attrs].attr = (_attr); \
59 attrs[num_attrs].format = (_format); \
60 attrs[num_attrs].dst_loc = (_dst_loc); \
61 attrs[num_attrs].swizzle = (_swizzle); \
62 attrs[num_attrs].write_mask = (_write_mask); \
66 static void r300SwtclVAPSetup(GLcontext
*ctx
, GLuint InputsRead
, GLuint OutputsWritten
, GLuint vap_out_fmt_1
)
68 r300ContextPtr rmesa
= R300_CONTEXT( ctx
);
69 struct vertex_attribute
*attrs
= rmesa
->swtcl
.vert_attrs
;
71 uint32_t *vir0
= &rmesa
->hw
.vir
[0].cmd
[1];
72 uint32_t *vir1
= &rmesa
->hw
.vir
[1].cmd
[1];
74 for (i
= 0; i
< R300_VIR_CMDSIZE
-1; ++i
)
75 vir0
[i
] = vir1
[i
] = 0;
77 for (i
= 0, j
= 0; i
< rmesa
->radeon
.swtcl
.vertex_attr_count
; ++i
) {
79 switch (attrs
[i
].format
) {
81 data_format
= R300_DATA_TYPE_FLOAT_1
;
84 data_format
= R300_DATA_TYPE_FLOAT_2
;
87 data_format
= R300_DATA_TYPE_FLOAT_3
;
90 data_format
= R300_DATA_TYPE_FLOAT_4
;
92 case EMIT_4UB_4F_RGBA
:
93 case EMIT_4UB_4F_ABGR
:
94 data_format
= R300_DATA_TYPE_BYTE
| R300_NORMALIZE
;
97 fprintf(stderr
, "%s: Invalid data format type", __FUNCTION__
);
102 tmp
= data_format
| (attrs
[i
].dst_loc
<< R300_DST_VEC_LOC_SHIFT
);
104 vir0
[j
] = tmp
<< R300_DATA_TYPE_0_SHIFT
;
105 vir1
[j
] = attrs
[i
].swizzle
| (attrs
[i
].write_mask
<< R300_WRITE_ENA_SHIFT
);
107 vir0
[j
] |= tmp
<< R300_DATA_TYPE_1_SHIFT
;
108 vir1
[j
] |= (attrs
[i
].swizzle
| (attrs
[i
].write_mask
<< R300_WRITE_ENA_SHIFT
)) << R300_SWIZZLE1_SHIFT
;
113 reg_count
= (rmesa
->radeon
.swtcl
.vertex_attr_count
+ 1) >> 1;
114 if (rmesa
->radeon
.swtcl
.vertex_attr_count
% 2 != 0) {
115 vir0
[reg_count
-1] |= R300_LAST_VEC
<< R300_DATA_TYPE_0_SHIFT
;
117 vir0
[reg_count
-1] |= R300_LAST_VEC
<< R300_DATA_TYPE_1_SHIFT
;
120 R300_STATECHANGE(rmesa
, vir
[0]);
121 R300_STATECHANGE(rmesa
, vir
[1]);
122 R300_STATECHANGE(rmesa
, vof
);
123 R300_STATECHANGE(rmesa
, vic
);
125 if (rmesa
->radeon
.radeonScreen
->kernel_mm
) {
126 rmesa
->hw
.vir
[0].cmd
[0] &= 0xC000FFFF;
127 rmesa
->hw
.vir
[1].cmd
[0] &= 0xC000FFFF;
128 rmesa
->hw
.vir
[0].cmd
[0] |= (reg_count
& 0x3FFF) << 16;
129 rmesa
->hw
.vir
[1].cmd
[0] |= (reg_count
& 0x3FFF) << 16;
131 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vir
[0].cmd
)->packet0
.count
= reg_count
;
132 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vir
[1].cmd
)->packet0
.count
= reg_count
;
135 rmesa
->hw
.vic
.cmd
[R300_VIC_CNTL_0
] = r300VAPInputCntl0(ctx
, InputsRead
);
136 rmesa
->hw
.vic
.cmd
[R300_VIC_CNTL_1
] = r300VAPInputCntl1(ctx
, InputsRead
);
137 rmesa
->hw
.vof
.cmd
[R300_VOF_CNTL_0
] = r300VAPOutputCntl0(ctx
, OutputsWritten
);
139 * Can't use r300VAPOutputCntl1 function because it assumes
140 * that all texture coords have 4 components and that's the case
141 * for HW TCL path, but not for SW TCL.
143 rmesa
->hw
.vof
.cmd
[R300_VOF_CNTL_1
] = vap_out_fmt_1
;
147 static void r300SetVertexFormat( GLcontext
*ctx
)
149 r300ContextPtr rmesa
= R300_CONTEXT( ctx
);
150 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
151 struct vertex_buffer
*VB
= &tnl
->vb
;
152 int first_free_tex
= 0, vap_out_fmt_1
= 0;
153 GLuint InputsRead
= 0;
154 GLuint OutputsWritten
= 0;
156 struct vertex_attribute
*attrs
= rmesa
->swtcl
.vert_attrs
;
158 rmesa
->swtcl
.coloroffset
= rmesa
->swtcl
.specoffset
= 0;
159 rmesa
->radeon
.swtcl
.vertex_attr_count
= 0;
161 /* We always want non Ndc coords format */
162 VB
->AttribPtr
[VERT_ATTRIB_POS
] = VB
->ClipPtr
;
164 if (RENDERINPUTS_TEST(tnl
->render_inputs_bitset
, _TNL_ATTRIB_POS
)) {
165 InputsRead
|= 1 << VERT_ATTRIB_POS
;
166 OutputsWritten
|= 1 << VERT_RESULT_HPOS
;
167 EMIT_ATTR( _TNL_ATTRIB_POS
, EMIT_4F
);
168 ADD_ATTR(VERT_ATTRIB_POS
, EMIT_4F
, SWTCL_OVM_POS
, SWIZZLE_XYZW
, MASK_XYZW
);
169 rmesa
->swtcl
.coloroffset
= 4;
172 if (RENDERINPUTS_TEST(tnl
->render_inputs_bitset
, _TNL_ATTRIB_COLOR0
)) {
173 InputsRead
|= 1 << VERT_ATTRIB_COLOR0
;
174 OutputsWritten
|= 1 << VERT_RESULT_COL0
;
175 #if MESA_LITTLE_ENDIAN
176 EMIT_ATTR( _TNL_ATTRIB_COLOR0
, EMIT_4UB_4F_RGBA
);
177 ADD_ATTR(VERT_ATTRIB_COLOR0
, EMIT_4UB_4F_RGBA
, SWTCL_OVM_COLOR0
, SWIZZLE_XYZW
, MASK_XYZW
);
179 EMIT_ATTR( _TNL_ATTRIB_COLOR0
, EMIT_4UB_4F_ABGR
);
180 ADD_ATTR(VERT_ATTRIB_COLOR0
, EMIT_4UB_4F_ABGR
, SWTCL_OVM_COLOR0
, SWIZZLE_XYZW
, MASK_XYZW
);
184 if (RENDERINPUTS_TEST(tnl
->render_inputs_bitset
, _TNL_ATTRIB_COLOR1
)) {
185 GLuint swiz
= MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_Y
, SWIZZLE_Z
, SWIZZLE_ONE
);
186 InputsRead
|= 1 << VERT_ATTRIB_COLOR1
;
187 OutputsWritten
|= 1 << VERT_RESULT_COL1
;
188 #if MESA_LITTLE_ENDIAN
189 EMIT_ATTR( _TNL_ATTRIB_COLOR1
, EMIT_4UB_4F_RGBA
);
190 ADD_ATTR(VERT_ATTRIB_COLOR1
, EMIT_4UB_4F_RGBA
, SWTCL_OVM_COLOR1
, swiz
, MASK_XYZW
);
192 EMIT_ATTR( _TNL_ATTRIB_COLOR1
, EMIT_4UB_4F_ABGR
);
193 ADD_ATTR(VERT_ATTRIB_COLOR1
, EMIT_4UB_4F_ABGR
, SWTCL_OVM_COLOR1
, swiz
, MASK_XYZW
);
195 rmesa
->swtcl
.specoffset
= rmesa
->swtcl
.coloroffset
+ 1;
198 if (RENDERINPUTS_TEST(tnl
->render_inputs_bitset
, _TNL_ATTRIB_POINTSIZE
)) {
199 GLuint swiz
= MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_ZERO
, SWIZZLE_ZERO
, SWIZZLE_ZERO
);
200 InputsRead
|= 1 << VERT_ATTRIB_POINT_SIZE
;
201 OutputsWritten
|= 1 << VERT_RESULT_PSIZ
;
202 EMIT_ATTR( _TNL_ATTRIB_POINTSIZE
, EMIT_1F
);
203 ADD_ATTR(VERT_ATTRIB_POINT_SIZE
, EMIT_1F
, SWTCL_OVM_POINT_SIZE
, swiz
, MASK_X
);
206 if (RENDERINPUTS_TEST_RANGE(tnl
->render_inputs_bitset
, _TNL_FIRST_TEX
, _TNL_LAST_TEX
)) {
208 GLuint swiz
, mask
, format
;
209 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
210 if (RENDERINPUTS_TEST(tnl
->render_inputs_bitset
, _TNL_ATTRIB_TEX(i
) )) {
211 switch (VB
->TexCoordPtr
[i
]->size
) {
215 swiz
= MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_Y
, SWIZZLE_ZERO
, SWIZZLE_ZERO
);
216 mask
= MASK_X
| MASK_Y
;
221 swiz
= MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_Y
, SWIZZLE_Z
, SWIZZLE_ZERO
);
222 mask
= MASK_X
| MASK_Y
| MASK_Z
;
234 InputsRead
|= 1 << (VERT_ATTRIB_TEX0
+ i
);
235 OutputsWritten
|= 1 << (VERT_RESULT_TEX0
+ i
);
236 EMIT_ATTR(_TNL_ATTRIB_TEX(i
), format
);
237 ADD_ATTR(VERT_ATTRIB_TEX0
+ i
, format
, SWTCL_OVM_TEX(i
), swiz
, mask
);
238 vap_out_fmt_1
|= size
<< (i
* 3);
244 /* RS can't put fragment position on the pixel stack, so stuff it in texcoord if needed */
245 if (RENDERINPUTS_TEST(tnl
->render_inputs_bitset
, _TNL_ATTRIB_POS
) && (ctx
->FragmentProgram
._Current
->Base
.InputsRead
& FRAG_BIT_WPOS
)) {
246 if (first_free_tex
>= ctx
->Const
.MaxTextureUnits
) {
247 fprintf(stderr
, "\tout of free texcoords to write w pos\n");
251 InputsRead
|= 1 << (VERT_ATTRIB_TEX0
+ first_free_tex
);
252 OutputsWritten
|= 1 << (VERT_RESULT_TEX0
+ first_free_tex
);
253 EMIT_ATTR( _TNL_ATTRIB_POS
, EMIT_4F
);
254 ADD_ATTR(VERT_ATTRIB_POS
, EMIT_4F
, SWTCL_OVM_TEX(first_free_tex
), SWIZZLE_XYZW
, MASK_XYZW
);
255 vap_out_fmt_1
|= 4 << (first_free_tex
* 3);
259 if (RENDERINPUTS_TEST(tnl
->render_inputs_bitset
, _TNL_ATTRIB_FOG
)) {
260 if (first_free_tex
>= ctx
->Const
.MaxTextureUnits
) {
261 fprintf(stderr
, "\tout of free texcoords to write fog coordinate\n");
265 InputsRead
|= 1 << VERT_ATTRIB_FOG
;
266 OutputsWritten
|= 1 << VERT_RESULT_FOGC
;
267 GLuint swiz
= MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_ZERO
, SWIZZLE_ZERO
, SWIZZLE_ZERO
);
268 EMIT_ATTR( _TNL_ATTRIB_FOG
, EMIT_1F
);
269 ADD_ATTR(VERT_ATTRIB_FOG
, EMIT_1F
, SWTCL_OVM_TEX(first_free_tex
), swiz
, MASK_X
);
270 vap_out_fmt_1
|= 1 << (first_free_tex
* 3);
274 r300SwtclVAPSetup(ctx
, InputsRead
, OutputsWritten
, vap_out_fmt_1
);
276 rmesa
->radeon
.swtcl
.vertex_size
=
277 _tnl_install_attrs( ctx
,
278 rmesa
->radeon
.swtcl
.vertex_attrs
,
279 rmesa
->radeon
.swtcl
.vertex_attr_count
,
282 rmesa
->radeon
.swtcl
.vertex_size
/= 4;
284 RENDERINPUTS_COPY(rmesa
->render_inputs_bitset
, tnl
->render_inputs_bitset
);
288 static GLuint reduced_prim
[] = {
301 static void r300RasterPrimitive( GLcontext
*ctx
, GLuint prim
);
302 static void r300RenderPrimitive( GLcontext
*ctx
, GLenum prim
);
304 /***********************************************************************
305 * Emit primitives as inline vertices *
306 ***********************************************************************/
309 #define HAVE_POINTS 1
311 #define HAVE_LINE_STRIPS 1
312 #define HAVE_TRIANGLES 1
313 #define HAVE_TRI_STRIPS 1
314 #define HAVE_TRI_STRIP_1 0
315 #define HAVE_TRI_FANS 1
317 #define HAVE_QUAD_STRIPS 0
318 #define HAVE_POLYGONS 1
323 #define CTX_ARG r300ContextPtr rmesa
324 #define GET_VERTEX_DWORDS() rmesa->radeon.swtcl.vertex_size
325 #define ALLOC_VERTS( n, size ) rcommonAllocDmaLowVerts( &rmesa->radeon, n, size * 4 )
327 r300ContextPtr rmesa = R300_CONTEXT(ctx); \
328 const char *r300verts = (char *)rmesa->radeon.swtcl.verts;
329 #define VERT(x) (r300Vertex *)(r300verts + ((x) * vertsize * sizeof(int)))
330 #define VERTEX r300Vertex
332 #define TAG(x) r300_##x
333 #include "tnl_dd/t_dd_triemit.h"
337 /***********************************************************************
338 * Macros for t_dd_tritmp.h to draw basic primitives *
339 ***********************************************************************/
341 #define QUAD( a, b, c, d ) r300_quad( rmesa, a, b, c, d )
342 #define TRI( a, b, c ) r300_triangle( rmesa, a, b, c )
343 #define LINE( a, b ) r300_line( rmesa, a, b )
344 #define POINT( a ) r300_point( rmesa, a )
346 /***********************************************************************
347 * Build render functions from dd templates *
348 ***********************************************************************/
350 #define R300_TWOSIDE_BIT 0x01
351 #define R300_UNFILLED_BIT 0x02
352 #define R300_MAX_TRIFUNC 0x04
355 tnl_points_func points
;
357 tnl_triangle_func triangle
;
359 } rast_tab
[R300_MAX_TRIFUNC
];
361 #define DO_FALLBACK 0
362 #define DO_UNFILLED (IND & R300_UNFILLED_BIT)
363 #define DO_TWOSIDE (IND & R300_TWOSIDE_BIT)
370 #define DO_FULL_QUAD 1
374 #define HAVE_BACK_COLORS 0
375 #define HAVE_HW_FLATSHADE 1
378 #define DEPTH_SCALE 1.0
379 #define UNFILLED_TRI unfilled_tri
380 #define UNFILLED_QUAD unfilled_quad
381 #define VERT_X(_v) _v->v.x
382 #define VERT_Y(_v) _v->v.y
383 #define VERT_Z(_v) _v->v.z
384 #define AREA_IS_CCW( a ) (a < 0)
385 #define GET_VERTEX(e) (rmesa->radeon.swtcl.verts + (e*rmesa->radeon.swtcl.vertex_size*sizeof(int)))
387 #define VERT_SET_RGBA( v, c ) \
389 r300_color_t *color = (r300_color_t *)&((v)->ui[coloroffset]); \
390 UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]); \
391 UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]); \
392 UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]); \
393 UNCLAMPED_FLOAT_TO_UBYTE(color->alpha, (c)[3]); \
396 #define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
398 #define VERT_SET_SPEC( v0, c ) \
401 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.red, (c)[0]); \
402 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.green, (c)[1]); \
403 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.blue, (c)[2]); \
407 #define VERT_COPY_SPEC( v0, v1 ) \
410 v0->v.specular.red = v1->v.specular.red; \
411 v0->v.specular.green = v1->v.specular.green; \
412 v0->v.specular.blue = v1->v.specular.blue; \
416 #define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[coloroffset]
417 #define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx]
418 #define VERT_SAVE_SPEC( idx ) if (specoffset) spec[idx] = v[idx]->ui[specoffset]
419 #define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->ui[specoffset] = spec[idx]
425 #define LOCAL_VARS(n) \
426 r300ContextPtr rmesa = R300_CONTEXT(ctx); \
427 GLuint color[n] = { 0, }, spec[n] = { 0, }; \
428 GLuint coloroffset = rmesa->swtcl.coloroffset; \
429 GLuint specoffset = rmesa->swtcl.specoffset; \
430 (void) color; (void) spec; (void) coloroffset; (void) specoffset;
432 /***********************************************************************
433 * Helpers for rendering unfilled primitives *
434 ***********************************************************************/
436 #define RASTERIZE(x) r300RasterPrimitive( ctx, reduced_prim[x] )
437 #define RENDER_PRIMITIVE rmesa->radeon.swtcl.render_primitive
440 #include "tnl_dd/t_dd_unfilled.h"
444 /***********************************************************************
445 * Generate GL render functions *
446 ***********************************************************************/
451 #include "tnl_dd/t_dd_tritmp.h"
453 #define IND (R300_TWOSIDE_BIT)
454 #define TAG(x) x##_twoside
455 #include "tnl_dd/t_dd_tritmp.h"
457 #define IND (R300_UNFILLED_BIT)
458 #define TAG(x) x##_unfilled
459 #include "tnl_dd/t_dd_tritmp.h"
461 #define IND (R300_TWOSIDE_BIT|R300_UNFILLED_BIT)
462 #define TAG(x) x##_twoside_unfilled
463 #include "tnl_dd/t_dd_tritmp.h"
467 static void init_rast_tab( void )
472 init_twoside_unfilled();
475 /**********************************************************************/
476 /* Render unclipped begin/end objects */
477 /**********************************************************************/
479 #define RENDER_POINTS( start, count ) \
480 for ( ; start < count ; start++) \
481 r300_point( rmesa, VERT(start) )
482 #define RENDER_LINE( v0, v1 ) \
483 r300_line( rmesa, VERT(v0), VERT(v1) )
484 #define RENDER_TRI( v0, v1, v2 ) \
485 r300_triangle( rmesa, VERT(v0), VERT(v1), VERT(v2) )
486 #define RENDER_QUAD( v0, v1, v2, v3 ) \
487 r300_quad( rmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) )
488 #define INIT(x) do { \
489 r300RenderPrimitive( ctx, x ); \
493 r300ContextPtr rmesa = R300_CONTEXT(ctx); \
494 const GLuint vertsize = rmesa->radeon.swtcl.vertex_size; \
495 const char *r300verts = (char *)rmesa->radeon.swtcl.verts; \
496 const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
497 const GLboolean stipple = ctx->Line.StippleFlag; \
498 (void) elt; (void) stipple;
499 #define RESET_STIPPLE //if ( stipple ) r200ResetLineStipple( ctx );
500 #define RESET_OCCLUSION
501 #define PRESERVE_VB_DEFS
503 #define TAG(x) r300_##x##_verts
504 #include "tnl/t_vb_rendertmp.h"
507 #define TAG(x) r300_##x##_elts
508 #define ELT(x) elt[x]
509 #include "tnl/t_vb_rendertmp.h"
514 /**********************************************************************/
515 /* Choose render functions */
516 /**********************************************************************/
517 static void r300ChooseRenderState( GLcontext
*ctx
)
519 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
520 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
522 GLuint flags
= ctx
->_TriangleCaps
;
524 if (flags
& DD_TRI_LIGHT_TWOSIDE
) index
|= R300_TWOSIDE_BIT
;
525 if (flags
& DD_TRI_UNFILLED
) index
|= R300_UNFILLED_BIT
;
527 if (index
!= rmesa
->radeon
.swtcl
.RenderIndex
) {
528 tnl
->Driver
.Render
.Points
= rast_tab
[index
].points
;
529 tnl
->Driver
.Render
.Line
= rast_tab
[index
].line
;
530 tnl
->Driver
.Render
.ClippedLine
= rast_tab
[index
].line
;
531 tnl
->Driver
.Render
.Triangle
= rast_tab
[index
].triangle
;
532 tnl
->Driver
.Render
.Quad
= rast_tab
[index
].quad
;
535 tnl
->Driver
.Render
.PrimTabVerts
= r300_render_tab_verts
;
536 tnl
->Driver
.Render
.PrimTabElts
= r300_render_tab_elts
;
537 tnl
->Driver
.Render
.ClippedPolygon
= r300_fast_clipped_poly
;
539 tnl
->Driver
.Render
.PrimTabVerts
= _tnl_render_tab_verts
;
540 tnl
->Driver
.Render
.PrimTabElts
= _tnl_render_tab_elts
;
541 tnl
->Driver
.Render
.ClippedPolygon
= _tnl_RenderClippedPolygon
;
544 rmesa
->radeon
.swtcl
.RenderIndex
= index
;
549 static void r300RenderStart(GLcontext
*ctx
)
551 r300ContextPtr rmesa
= R300_CONTEXT( ctx
);
553 r300ChooseRenderState(ctx
);
554 r300SetVertexFormat(ctx
);
556 r300ValidateBuffers(ctx
);
558 r300UpdateShaders(rmesa
);
559 r300UpdateShaderStates(rmesa
);
561 r300EmitCacheFlush(rmesa
);
563 /* investigate if we can put back flush optimisation if needed */
564 if (rmesa
->radeon
.dma
.flush
!= NULL
) {
565 rmesa
->radeon
.dma
.flush(ctx
);
569 static void r300RenderFinish(GLcontext
*ctx
)
573 static void r300RasterPrimitive( GLcontext
*ctx
, GLuint hwprim
)
575 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
577 if (rmesa
->radeon
.swtcl
.hw_primitive
!= hwprim
) {
578 R300_NEWPRIM( rmesa
);
579 rmesa
->radeon
.swtcl
.hw_primitive
= hwprim
;
583 static void r300RenderPrimitive(GLcontext
*ctx
, GLenum prim
)
586 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
587 rmesa
->radeon
.swtcl
.render_primitive
= prim
;
589 if ((prim
== GL_TRIANGLES
) && (ctx
->_TriangleCaps
& DD_TRI_UNFILLED
))
592 r300RasterPrimitive( ctx
, reduced_prim
[prim
] );
595 static void r300ResetLineStipple(GLcontext
*ctx
)
599 void r300InitSwtcl(GLcontext
*ctx
)
601 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
602 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
603 static int firsttime
= 1;
610 tnl
->Driver
.Render
.Start
= r300RenderStart
;
611 tnl
->Driver
.Render
.Finish
= r300RenderFinish
;
612 tnl
->Driver
.Render
.PrimitiveNotify
= r300RenderPrimitive
;
613 tnl
->Driver
.Render
.ResetLineStipple
= r300ResetLineStipple
;
614 tnl
->Driver
.Render
.BuildVertices
= _tnl_build_vertices
;
615 tnl
->Driver
.Render
.CopyPV
= _tnl_copy_pv
;
616 tnl
->Driver
.Render
.Interp
= _tnl_interp
;
618 /* FIXME: what are these numbers? */
619 _tnl_init_vertices( ctx
, ctx
->Const
.MaxArrayLockSize
+ 12,
620 48 * sizeof(GLfloat
) );
622 rmesa
->radeon
.swtcl
.verts
= (GLubyte
*)tnl
->clipspace
.vertex_buf
;
623 rmesa
->radeon
.swtcl
.RenderIndex
= ~0;
624 rmesa
->radeon
.swtcl
.render_primitive
= GL_TRIANGLES
;
625 rmesa
->radeon
.swtcl
.hw_primitive
= 0;
627 _tnl_invalidate_vertex_state( ctx
, ~0 );
628 _tnl_invalidate_vertices( ctx
, ~0 );
630 _tnl_need_projected_coords( ctx
, GL_FALSE
);
631 r300ChooseRenderState(ctx
);
634 void r300DestroySwtcl(GLcontext
*ctx
)
638 static void r300EmitVertexAOS(r300ContextPtr rmesa
, GLuint vertex_size
, struct radeon_bo
*bo
, GLuint offset
)
640 BATCH_LOCALS(&rmesa
->radeon
);
642 if (RADEON_DEBUG
& DEBUG_VERTS
)
643 fprintf(stderr
, "%s: vertex_size %d, offset 0x%x \n",
644 __FUNCTION__
, vertex_size
, offset
);
647 OUT_BATCH_PACKET3(R300_PACKET3_3D_LOAD_VBPNTR
, 2);
649 OUT_BATCH(vertex_size
| (vertex_size
<< 8));
650 OUT_BATCH_RELOC(offset
, bo
, offset
, RADEON_GEM_DOMAIN_GTT
, 0, 0);
654 static void r300EmitVbufPrim(r300ContextPtr rmesa
, GLuint primitive
, GLuint vertex_nr
)
656 BATCH_LOCALS(&rmesa
->radeon
);
659 type
= r300PrimitiveType(rmesa
, primitive
);
660 num_verts
= r300NumVerts(rmesa
, vertex_nr
, primitive
);
663 OUT_BATCH_PACKET3(R300_PACKET3_3D_DRAW_VBUF_2
, 0);
664 OUT_BATCH(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST
| (num_verts
<< 16) | type
);
668 void r300_swtcl_flush(GLcontext
*ctx
, uint32_t current_offset
)
670 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
672 rcommonEnsureCmdBufSpace(&rmesa
->radeon
,
673 rmesa
->radeon
.hw
.max_state_size
+ (12*sizeof(int)),
675 radeonEmitState(&rmesa
->radeon
);
676 r300EmitVertexAOS(rmesa
,
677 rmesa
->radeon
.swtcl
.vertex_size
,
678 rmesa
->radeon
.dma
.current
,
681 r300EmitVbufPrim(rmesa
,
682 rmesa
->radeon
.swtcl
.hw_primitive
,
683 rmesa
->radeon
.swtcl
.numverts
);
684 r300EmitCacheFlush(rmesa
);