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_state.h"
38 #include "r300_swtcl.h"
39 #include "r300_emit.h"
41 #include "r300_render.h"
42 #include "main/simple_list.h"
44 #define EMIT_ATTR( ATTR, STYLE ) \
46 rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].attrib = (ATTR); \
47 rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].format = (STYLE); \
48 rmesa->radeon.swtcl.vertex_attr_count++; \
51 #define EMIT_PAD( N ) \
53 rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].attrib = 0; \
54 rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].format = EMIT_PAD; \
55 rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].offset = (N); \
56 rmesa->radeon.swtcl.vertex_attr_count++; \
59 #define ADD_ATTR(_attr, _format, _dst_loc, _swizzle, _write_mask, _normalize) \
61 attrs[num_attrs].element = (_attr); \
62 attrs[num_attrs].data_type = (_format); \
63 attrs[num_attrs].dst_loc = (_dst_loc); \
64 attrs[num_attrs].swizzle = (_swizzle); \
65 attrs[num_attrs].write_mask = (_write_mask); \
66 attrs[num_attrs]._signed = 0; \
67 attrs[num_attrs].normalize = (_normalize); \
71 void r300ChooseSwtclVertexFormat(GLcontext
*ctx
, GLuint
*_InputsRead
, GLuint
*_OutputsWritten
)
73 r300ContextPtr rmesa
= R300_CONTEXT( ctx
);
74 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
75 struct vertex_buffer
*VB
= &tnl
->vb
;
76 int first_free_tex
= 0;
77 GLuint InputsRead
= 0;
78 GLuint OutputsWritten
= 0;
80 GLuint fp_reads
= rmesa
->selected_fp
->InputsRead
;
81 struct vertex_attribute
*attrs
= rmesa
->vbuf
.attribs
;
83 radeon_print(RADEON_SWRENDER
, RADEON_VERBOSE
, "%s\n", __func__
);
84 rmesa
->swtcl
.coloroffset
= rmesa
->swtcl
.specoffset
= 0;
85 rmesa
->radeon
.swtcl
.vertex_attr_count
= 0;
87 if (RADEON_DEBUG
& RADEON_VERTS
)
88 fprintf(stderr
, "%s\n", __func__
);
90 /* We always want non Ndc coords format */
91 VB
->AttribPtr
[VERT_ATTRIB_POS
] = VB
->ClipPtr
;
93 /* Always write position vector */
94 InputsRead
|= 1 << VERT_ATTRIB_POS
;
95 OutputsWritten
|= 1 << VERT_RESULT_HPOS
;
96 EMIT_ATTR( _TNL_ATTRIB_POS
, EMIT_4F
);
97 ADD_ATTR(VERT_ATTRIB_POS
, R300_DATA_TYPE_FLOAT_4
, SWTCL_OVM_POS
, SWIZZLE_XYZW
, MASK_XYZW
, 0);
98 rmesa
->swtcl
.coloroffset
= 4;
100 if (fp_reads
& FRAG_BIT_COL0
) {
101 InputsRead
|= 1 << VERT_ATTRIB_COLOR0
;
102 OutputsWritten
|= 1 << VERT_RESULT_COL0
;
103 #if MESA_LITTLE_ENDIAN
104 EMIT_ATTR( _TNL_ATTRIB_COLOR0
, EMIT_4UB_4F_RGBA
);
105 ADD_ATTR(VERT_ATTRIB_COLOR0
, R300_DATA_TYPE_BYTE
, SWTCL_OVM_COLOR0
, SWIZZLE_XYZW
, MASK_XYZW
, 1);
107 EMIT_ATTR( _TNL_ATTRIB_COLOR0
, EMIT_4UB_4F_ABGR
);
108 ADD_ATTR(VERT_ATTRIB_COLOR0
, R300_DATA_TYPE_BYTE
, SWTCL_OVM_COLOR0
, SWIZZLE_XYZW
, MASK_XYZW
, 1);
112 if (fp_reads
& FRAG_BIT_COL1
) {
113 GLuint swiz
= MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_Y
, SWIZZLE_Z
, SWIZZLE_ONE
);
114 InputsRead
|= 1 << VERT_ATTRIB_COLOR1
;
115 OutputsWritten
|= 1 << VERT_RESULT_COL1
;
116 #if MESA_LITTLE_ENDIAN
117 EMIT_ATTR( _TNL_ATTRIB_COLOR1
, EMIT_4UB_4F_RGBA
);
118 ADD_ATTR(VERT_ATTRIB_COLOR1
, R300_DATA_TYPE_BYTE
, SWTCL_OVM_COLOR1
, swiz
, MASK_XYZW
, 1);
120 EMIT_ATTR( _TNL_ATTRIB_COLOR1
, EMIT_4UB_4F_ABGR
);
121 ADD_ATTR(VERT_ATTRIB_COLOR1
, R300_DATA_TYPE_BYTE
, SWTCL_OVM_COLOR1
, swiz
, MASK_XYZW
, 1);
123 rmesa
->swtcl
.specoffset
= rmesa
->swtcl
.coloroffset
+ 1;
126 if (ctx
->Light
.Enabled
&& ctx
->Light
.Model
.TwoSide
) {
127 VB
->AttribPtr
[VERT_ATTRIB_GENERIC0
] = VB
->BackfaceColorPtr
;
128 OutputsWritten
|= 1 << VERT_RESULT_BFC0
;
129 #if MESA_LITTLE_ENDIAN
130 EMIT_ATTR( _TNL_ATTRIB_GENERIC0
, EMIT_4UB_4F_RGBA
);
131 ADD_ATTR(VERT_ATTRIB_GENERIC0
, R300_DATA_TYPE_BYTE
, SWTCL_OVM_COLOR2
, SWIZZLE_XYZW
, MASK_XYZW
, 1);
133 EMIT_ATTR( _TNL_ATTRIB_GENERIC0
, EMIT_4UB_4F_ABGR
);
134 ADD_ATTR(VERT_ATTRIB_GENERIC0
, R300_DATA_TYPE_BYTE
, SWTCL_OVM_COLOR2
, SWIZZLE_XYZW
, MASK_XYZW
, 1);
136 if (fp_reads
& FRAG_BIT_COL1
) {
137 VB
->AttribPtr
[VERT_ATTRIB_GENERIC1
] = VB
->BackfaceSecondaryColorPtr
;
138 GLuint swiz
= MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_Y
, SWIZZLE_Z
, SWIZZLE_ONE
);
139 OutputsWritten
|= 1 << VERT_RESULT_BFC1
;
140 #if MESA_LITTLE_ENDIAN
141 EMIT_ATTR( _TNL_ATTRIB_GENERIC1
, EMIT_4UB_4F_RGBA
);
142 ADD_ATTR(VERT_ATTRIB_GENERIC1
, R300_DATA_TYPE_BYTE
, SWTCL_OVM_COLOR3
, swiz
, MASK_XYZW
, 1);
144 EMIT_ATTR( _TNL_ATTRIB_GENERIC1
, EMIT_4UB_4F_ABGR
);
145 ADD_ATTR(VERT_ATTRIB_GENERIC1
, R300_DATA_TYPE_BYTE
, SWTCL_OVM_COLOR3
, swiz
, MASK_XYZW
, 1);
150 if (RENDERINPUTS_TEST(tnl
->render_inputs_bitset
, _TNL_ATTRIB_POINTSIZE
)) {
151 GLuint swiz
= MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_ZERO
, SWIZZLE_ZERO
, SWIZZLE_ZERO
);
152 InputsRead
|= 1 << VERT_ATTRIB_POINT_SIZE
;
153 OutputsWritten
|= 1 << VERT_RESULT_PSIZ
;
154 EMIT_ATTR( _TNL_ATTRIB_POINTSIZE
, EMIT_1F
);
155 ADD_ATTR(VERT_ATTRIB_POINT_SIZE
, R300_DATA_TYPE_FLOAT_1
, SWTCL_OVM_POINT_SIZE
, swiz
, MASK_X
, 0);
158 if (rmesa
->selected_fp
->wpos_attr
!= FRAG_ATTRIB_MAX
) {
159 int tex_id
= rmesa
->selected_fp
->wpos_attr
- FRAG_ATTRIB_TEX0
;
161 VB
->AttribPtr
[VERT_ATTRIB_TEX0
+ tex_id
] = VB
->AttribPtr
[VERT_ATTRIB_POS
];
162 VB
->AttribPtr
[_TNL_ATTRIB_TEX0
+ tex_id
] = VB
->AttribPtr
[VERT_ATTRIB_POS
];
163 RENDERINPUTS_SET(tnl
->render_inputs_bitset
, _TNL_ATTRIB_TEX0
+ tex_id
);
166 if (rmesa
->selected_fp
->fog_attr
!= FRAG_ATTRIB_MAX
) {
167 int tex_id
= rmesa
->selected_fp
->fog_attr
- FRAG_ATTRIB_TEX0
;
169 VB
->AttribPtr
[VERT_ATTRIB_TEX0
+ tex_id
] = VB
->AttribPtr
[VERT_ATTRIB_FOG
];
170 VB
->AttribPtr
[_TNL_ATTRIB_TEX0
+ tex_id
] = VB
->AttribPtr
[VERT_ATTRIB_FOG
];
171 RENDERINPUTS_SET(tnl
->render_inputs_bitset
, _TNL_ATTRIB_TEX0
+ tex_id
);
175 * Sending only one texcoord component may lead to lock up,
176 * so for all textures always output 4 texcoord components to RS.
180 GLuint swiz
, format
, hw_format
;
181 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
182 if (fp_reads
& FRAG_BIT_TEX(i
)) {
183 switch (VB
->AttribPtr
[_TNL_ATTRIB_TEX0
+ i
]->size
) {
186 hw_format
= R300_DATA_TYPE_FLOAT_1
;
187 swiz
= MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_ZERO
, SWIZZLE_ZERO
, SWIZZLE_ONE
);
191 hw_format
= R300_DATA_TYPE_FLOAT_2
;
192 swiz
= MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_Y
, SWIZZLE_ZERO
, SWIZZLE_ONE
);
196 hw_format
= R300_DATA_TYPE_FLOAT_3
;
197 swiz
= MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_Y
, SWIZZLE_Z
, SWIZZLE_ONE
);
201 hw_format
= R300_DATA_TYPE_FLOAT_4
;
207 InputsRead
|= 1 << (VERT_ATTRIB_TEX0
+ i
);
208 OutputsWritten
|= 1 << (VERT_RESULT_TEX0
+ i
);
209 EMIT_ATTR(_TNL_ATTRIB_TEX(i
), format
);
210 ADD_ATTR(VERT_ATTRIB_TEX0
+ i
, hw_format
, SWTCL_OVM_TEX(first_free_tex
), swiz
, MASK_XYZW
, 0);
216 if (first_free_tex
>= ctx
->Const
.MaxTextureUnits
) {
217 fprintf(stderr
, "\tout of free texcoords to write fog coordinate\n");
222 rmesa
->vbuf
.num_attribs
= num_attrs
;
223 *_InputsRead
= InputsRead
;
224 *_OutputsWritten
= OutputsWritten
;
226 RENDERINPUTS_COPY(rmesa
->render_inputs_bitset
, tnl
->render_inputs_bitset
);
229 static void r300PrepareVertices(GLcontext
*ctx
)
231 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
232 GLuint InputsRead
, OutputsWritten
;
233 radeon_print(RADEON_SWRENDER
, RADEON_TRACE
, "%s\n", __func__
);
235 r300ChooseSwtclVertexFormat(ctx
, &InputsRead
, &OutputsWritten
);
236 r300SetupVAP(ctx
, InputsRead
, OutputsWritten
);
238 rmesa
->radeon
.swtcl
.vertex_size
=
239 _tnl_install_attrs( ctx
,
240 rmesa
->radeon
.swtcl
.vertex_attrs
,
241 rmesa
->radeon
.swtcl
.vertex_attr_count
,
244 rmesa
->radeon
.swtcl
.vertex_size
/= 4;
247 static void r300_predict_emit_size( r300ContextPtr rmesa
)
249 if (!rmesa
->radeon
.swtcl
.emit_prediction
) {
250 const int vertex_size
= 7;
251 const int prim_size
= 3;
252 const int cache_flush_size
= 4;
253 const int pre_emit_state
= 4;
254 const int scissor_size
= 3;
255 const int state_size
= radeonCountStateEmitSize(&rmesa
->radeon
);
257 if (rcommonEnsureCmdBufSpace(&rmesa
->radeon
,
258 state_size
+ pre_emit_state
+ scissor_size
259 + vertex_size
+ prim_size
+ cache_flush_size
* 2,
261 rmesa
->radeon
.swtcl
.emit_prediction
= radeonCountStateEmitSize(&rmesa
->radeon
);
263 rmesa
->radeon
.swtcl
.emit_prediction
= state_size
;
265 rmesa
->radeon
.swtcl
.emit_prediction
+= rmesa
->radeon
.cmdbuf
.cs
->cdw
266 + vertex_size
+ scissor_size
+ prim_size
+ cache_flush_size
* 2 + pre_emit_state
;
267 radeon_print(RADEON_SWRENDER
, RADEON_VERBOSE
,
269 __func__
, rmesa
->radeon
.cmdbuf
.cs
->cdw
270 + vertex_size
+ scissor_size
+ prim_size
+ cache_flush_size
* 2 + pre_emit_state
);
275 static GLuint reduced_prim
[] = {
288 static void r300RasterPrimitive( GLcontext
*ctx
, GLuint prim
);
290 /***********************************************************************
291 * Emit primitives as inline vertices *
292 ***********************************************************************/
295 #define HAVE_POINTS 1
297 #define HAVE_LINE_STRIPS 1
298 #define HAVE_TRIANGLES 1
299 #define HAVE_TRI_STRIPS 1
300 #define HAVE_TRI_STRIP_1 0
301 #define HAVE_TRI_FANS 1
303 #define HAVE_QUAD_STRIPS 0
304 #define HAVE_POLYGONS 1
307 static void* r300_alloc_verts(r300ContextPtr rmesa
, GLuint n
, GLuint size
)
311 r300_predict_emit_size( rmesa
);
312 rv
= rcommonAllocDmaLowVerts( &rmesa
->radeon
, n
, size
* 4 );
319 #define CTX_ARG r300ContextPtr rmesa
320 #define GET_VERTEX_DWORDS() rmesa->radeon.swtcl.vertex_size
321 #define ALLOC_VERTS( n, size ) r300_alloc_verts(rmesa, n, size);
323 r300ContextPtr rmesa = R300_CONTEXT(ctx); \
324 const char *r300verts = (char *)rmesa->radeon.swtcl.verts;
325 #define VERT(x) (r300Vertex *)(r300verts + ((x) * vertsize * sizeof(int)))
326 #define VERTEX r300Vertex
328 #define TAG(x) r300_##x
329 #include "tnl_dd/t_dd_triemit.h"
333 /***********************************************************************
334 * Macros for t_dd_tritmp.h to draw basic primitives *
335 ***********************************************************************/
337 #define QUAD( a, b, c, d ) r300_quad( rmesa, a, b, c, d )
338 #define TRI( a, b, c ) r300_triangle( rmesa, a, b, c )
339 #define LINE( a, b ) r300_line( rmesa, a, b )
340 #define POINT( a ) r300_point( rmesa, a )
342 /***********************************************************************
343 * Build render functions from dd templates *
344 ***********************************************************************/
346 #define R300_UNFILLED_BIT 0x01
347 #define R300_MAX_TRIFUNC 0x02
350 tnl_points_func points
;
352 tnl_triangle_func triangle
;
354 } rast_tab
[R300_MAX_TRIFUNC
];
356 #define DO_FALLBACK 0
357 #define DO_UNFILLED (IND & R300_UNFILLED_BIT)
365 #define DO_FULL_QUAD 1
369 #define HAVE_BACK_COLORS 0
370 #define HAVE_HW_FLATSHADE 1
373 #define DEPTH_SCALE 1.0
374 #define UNFILLED_TRI unfilled_tri
375 #define UNFILLED_QUAD unfilled_quad
376 #define VERT_X(_v) _v->v.x
377 #define VERT_Y(_v) _v->v.y
378 #define VERT_Z(_v) _v->v.z
379 #define AREA_IS_CCW( a ) (a < 0)
380 #define GET_VERTEX(e) (rmesa->radeon.swtcl.verts + (e*rmesa->radeon.swtcl.vertex_size*sizeof(int)))
382 #define VERT_SET_RGBA( v, c ) \
384 r300_color_t *color = (r300_color_t *)&((v)->ui[coloroffset]); \
385 UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]); \
386 UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]); \
387 UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]); \
388 UNCLAMPED_FLOAT_TO_UBYTE(color->alpha, (c)[3]); \
391 #define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
393 #define VERT_SET_SPEC( v0, c ) \
396 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.red, (c)[0]); \
397 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.green, (c)[1]); \
398 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.blue, (c)[2]); \
402 #define VERT_COPY_SPEC( v0, v1 ) \
405 v0->v.specular.red = v1->v.specular.red; \
406 v0->v.specular.green = v1->v.specular.green; \
407 v0->v.specular.blue = v1->v.specular.blue; \
411 #define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[coloroffset]
412 #define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx]
413 #define VERT_SAVE_SPEC( idx ) if (specoffset) spec[idx] = v[idx]->ui[specoffset]
414 #define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->ui[specoffset] = spec[idx]
420 #define LOCAL_VARS(n) \
421 r300ContextPtr rmesa = R300_CONTEXT(ctx); \
422 GLuint color[n] = { 0, }, spec[n] = { 0, }; \
423 GLuint coloroffset = rmesa->swtcl.coloroffset; \
424 GLuint specoffset = rmesa->swtcl.specoffset; \
425 (void) color; (void) spec; (void) coloroffset; (void) specoffset;
427 /***********************************************************************
428 * Helpers for rendering unfilled primitives *
429 ***********************************************************************/
431 #define RASTERIZE(x) r300RasterPrimitive( ctx, reduced_prim[x] )
432 #define RENDER_PRIMITIVE rmesa->radeon.swtcl.render_primitive
435 #include "tnl_dd/t_dd_unfilled.h"
439 /***********************************************************************
440 * Generate GL render functions *
441 ***********************************************************************/
446 #include "tnl_dd/t_dd_tritmp.h"
448 #define IND (R300_UNFILLED_BIT)
449 #define TAG(x) x##_unfilled
450 #include "tnl_dd/t_dd_tritmp.h"
453 static void init_rast_tab( void )
459 /**********************************************************************/
460 /* Render unclipped begin/end objects */
461 /**********************************************************************/
463 #define RENDER_POINTS( start, count ) \
464 for ( ; start < count ; start++) \
465 r300_point( rmesa, VERT(start) )
466 #define RENDER_LINE( v0, v1 ) \
467 r300_line( rmesa, VERT(v0), VERT(v1) )
468 #define RENDER_TRI( v0, v1, v2 ) \
469 r300_triangle( rmesa, VERT(v0), VERT(v1), VERT(v2) )
470 #define RENDER_QUAD( v0, v1, v2, v3 ) \
471 r300_quad( rmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) )
472 #define INIT(x) do { \
473 r300RenderPrimitive( ctx, x ); \
477 r300ContextPtr rmesa = R300_CONTEXT(ctx); \
478 const GLuint vertsize = rmesa->radeon.swtcl.vertex_size; \
479 const char *r300verts = (char *)rmesa->radeon.swtcl.verts; \
480 const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
481 const GLboolean stipple = ctx->Line.StippleFlag; \
482 (void) elt; (void) stipple;
483 #define RESET_STIPPLE //if ( stipple ) r200ResetLineStipple( ctx );
484 #define RESET_OCCLUSION
485 #define PRESERVE_VB_DEFS
487 #define TAG(x) r300_##x##_verts
488 #include "tnl/t_vb_rendertmp.h"
491 #define TAG(x) r300_##x##_elts
492 #define ELT(x) elt[x]
493 #include "tnl/t_vb_rendertmp.h"
498 /**********************************************************************/
499 /* Choose render functions */
500 /**********************************************************************/
501 static void r300ChooseRenderState( GLcontext
*ctx
)
503 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
504 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
506 GLuint flags
= ctx
->_TriangleCaps
;
507 radeon_print(RADEON_SWRENDER
, RADEON_VERBOSE
, "%s\n", __func__
);
509 if (flags
& DD_TRI_UNFILLED
) index
|= R300_UNFILLED_BIT
;
511 if (index
!= rmesa
->radeon
.swtcl
.RenderIndex
) {
512 tnl
->Driver
.Render
.Points
= rast_tab
[index
].points
;
513 tnl
->Driver
.Render
.Line
= rast_tab
[index
].line
;
514 tnl
->Driver
.Render
.ClippedLine
= rast_tab
[index
].line
;
515 tnl
->Driver
.Render
.Triangle
= rast_tab
[index
].triangle
;
516 tnl
->Driver
.Render
.Quad
= rast_tab
[index
].quad
;
519 tnl
->Driver
.Render
.PrimTabVerts
= r300_render_tab_verts
;
520 tnl
->Driver
.Render
.PrimTabElts
= r300_render_tab_elts
;
521 tnl
->Driver
.Render
.ClippedPolygon
= r300_fast_clipped_poly
;
523 tnl
->Driver
.Render
.PrimTabVerts
= _tnl_render_tab_verts
;
524 tnl
->Driver
.Render
.PrimTabElts
= _tnl_render_tab_elts
;
525 tnl
->Driver
.Render
.ClippedPolygon
= _tnl_RenderClippedPolygon
;
528 rmesa
->radeon
.swtcl
.RenderIndex
= index
;
532 void r300RenderStart(GLcontext
*ctx
)
534 radeon_print(RADEON_SWRENDER
, RADEON_VERBOSE
, "%s\n", __func__
);
535 r300ContextPtr rmesa
= R300_CONTEXT( ctx
);
537 r300ChooseRenderState(ctx
);
539 r300UpdateShaders(rmesa
);
541 r300PrepareVertices(ctx
);
543 r300ValidateBuffers(ctx
);
545 r300UpdateShaderStates(rmesa
);
548 /* investigate if we can put back flush optimisation if needed */
549 if (rmesa
->radeon
.dma
.flush
!= NULL
) {
550 rmesa
->radeon
.dma
.flush(ctx
);
554 void r300RenderFinish(GLcontext
*ctx
)
558 static void r300RasterPrimitive( GLcontext
*ctx
, GLuint hwprim
)
560 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
561 radeon_print(RADEON_SWRENDER
, RADEON_TRACE
, "%s\n", __func__
);
563 if (rmesa
->radeon
.swtcl
.hw_primitive
!= hwprim
) {
564 R300_NEWPRIM( rmesa
);
565 rmesa
->radeon
.swtcl
.hw_primitive
= hwprim
;
569 void r300RenderPrimitive(GLcontext
*ctx
, GLenum prim
)
572 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
573 rmesa
->radeon
.swtcl
.render_primitive
= prim
;
574 radeon_print(RADEON_SWRENDER
, RADEON_TRACE
, "%s\n", __func__
);
576 if ((prim
== GL_TRIANGLES
) && (ctx
->_TriangleCaps
& DD_TRI_UNFILLED
))
579 r300RasterPrimitive( ctx
, reduced_prim
[prim
] );
582 void r300ResetLineStipple(GLcontext
*ctx
)
584 if (RADEON_DEBUG
& RADEON_VERTS
)
585 fprintf(stderr
, "%s\n", __func__
);
588 void r300InitSwtcl(GLcontext
*ctx
)
590 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
591 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
592 static int firsttime
= 1;
593 radeon_print(RADEON_SWRENDER
, RADEON_NORMAL
, "%s\n", __func__
);
599 rmesa
->radeon
.swtcl
.emit_prediction
= 0;
601 tnl
->Driver
.Render
.Start
= r300RenderStart
;
602 tnl
->Driver
.Render
.Finish
= r300RenderFinish
;
603 tnl
->Driver
.Render
.PrimitiveNotify
= r300RenderPrimitive
;
604 tnl
->Driver
.Render
.ResetLineStipple
= r300ResetLineStipple
;
605 tnl
->Driver
.Render
.BuildVertices
= _tnl_build_vertices
;
606 tnl
->Driver
.Render
.CopyPV
= _tnl_copy_pv
;
607 tnl
->Driver
.Render
.Interp
= _tnl_interp
;
609 /* FIXME: what are these numbers? */
610 _tnl_init_vertices( ctx
, ctx
->Const
.MaxArrayLockSize
+ 12,
611 48 * sizeof(GLfloat
) );
613 rmesa
->radeon
.swtcl
.verts
= (GLubyte
*)tnl
->clipspace
.vertex_buf
;
614 rmesa
->radeon
.swtcl
.RenderIndex
= ~0;
615 rmesa
->radeon
.swtcl
.render_primitive
= GL_TRIANGLES
;
616 rmesa
->radeon
.swtcl
.hw_primitive
= 0;
618 _tnl_invalidate_vertex_state( ctx
, ~0 );
619 _tnl_invalidate_vertices( ctx
, ~0 );
621 _tnl_need_projected_coords( ctx
, GL_FALSE
);
624 void r300DestroySwtcl(GLcontext
*ctx
)
628 static void r300EmitVertexAOS(r300ContextPtr rmesa
, GLuint vertex_size
, struct radeon_bo
*bo
, GLuint offset
)
630 BATCH_LOCALS(&rmesa
->radeon
);
632 radeon_print(RADEON_SWRENDER
, RADEON_TRACE
,
633 "%s: vertex_size %d, offset 0x%x \n",
634 __FUNCTION__
, vertex_size
, offset
);
637 OUT_BATCH_PACKET3(R300_PACKET3_3D_LOAD_VBPNTR
, 2);
639 OUT_BATCH(vertex_size
| (vertex_size
<< 8));
640 OUT_BATCH_RELOC(offset
, bo
, offset
, RADEON_GEM_DOMAIN_GTT
, 0, 0);
644 static void r300EmitVbufPrim(r300ContextPtr rmesa
, GLuint primitive
, GLuint vertex_nr
)
646 BATCH_LOCALS(&rmesa
->radeon
);
648 if (RADEON_DEBUG
& RADEON_VERTS
)
649 fprintf(stderr
, "%s\n", __func__
);
651 type
= r300PrimitiveType(rmesa
, primitive
);
652 num_verts
= r300NumVerts(rmesa
, vertex_nr
, primitive
);
655 OUT_BATCH_PACKET3(R300_PACKET3_3D_DRAW_VBUF_2
, 0);
656 OUT_BATCH(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST
| (num_verts
<< 16) | type
);
660 void r300_swtcl_flush(GLcontext
*ctx
, uint32_t current_offset
)
662 radeon_print(RADEON_SWRENDER
, RADEON_TRACE
, "%s\n", __func__
);
663 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
665 r300EmitCacheFlush(rmesa
);
667 radeonEmitState(&rmesa
->radeon
);
668 r300_emit_scissor(ctx
);
669 r300EmitVertexAOS(rmesa
,
670 rmesa
->radeon
.swtcl
.vertex_size
,
671 rmesa
->radeon
.swtcl
.bo
,
674 r300EmitVbufPrim(rmesa
,
675 rmesa
->radeon
.swtcl
.hw_primitive
,
676 rmesa
->radeon
.swtcl
.numverts
);
677 r300EmitCacheFlush(rmesa
);
678 if ( rmesa
->radeon
.swtcl
.emit_prediction
< rmesa
->radeon
.cmdbuf
.cs
->cdw
)
679 WARN_ONCE("Rendering was %d commands larger than predicted size."
680 " We might overflow command buffer.\n",
681 rmesa
->radeon
.cmdbuf
.cs
->cdw
- rmesa
->radeon
.swtcl
.emit_prediction
);
682 rmesa
->radeon
.swtcl
.emit_prediction
= 0;