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(struct gl_context *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(struct gl_context *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( struct gl_context *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
368 #define HAVE_BACK_COLORS 0
369 #define HAVE_HW_FLATSHADE 1
372 #define DEPTH_SCALE 1.0
373 #define UNFILLED_TRI unfilled_tri
374 #define UNFILLED_QUAD unfilled_quad
375 #define VERT_X(_v) _v->v.x
376 #define VERT_Y(_v) _v->v.y
377 #define VERT_Z(_v) _v->v.z
378 #define AREA_IS_CCW( a ) (a < 0)
379 #define GET_VERTEX(e) (rmesa->radeon.swtcl.verts + (e*rmesa->radeon.swtcl.vertex_size*sizeof(int)))
381 #define VERT_SET_RGBA( v, c ) \
383 r300_color_t *color = (r300_color_t *)&((v)->ui[coloroffset]); \
384 UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]); \
385 UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]); \
386 UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]); \
387 UNCLAMPED_FLOAT_TO_UBYTE(color->alpha, (c)[3]); \
390 #define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
392 #define VERT_SET_SPEC( v0, c ) \
395 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.red, (c)[0]); \
396 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.green, (c)[1]); \
397 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.blue, (c)[2]); \
401 #define VERT_COPY_SPEC( v0, v1 ) \
404 v0->v.specular.red = v1->v.specular.red; \
405 v0->v.specular.green = v1->v.specular.green; \
406 v0->v.specular.blue = v1->v.specular.blue; \
410 #define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[coloroffset]
411 #define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx]
412 #define VERT_SAVE_SPEC( idx ) if (specoffset) spec[idx] = v[idx]->ui[specoffset]
413 #define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->ui[specoffset] = spec[idx]
419 #define LOCAL_VARS(n) \
420 r300ContextPtr rmesa = R300_CONTEXT(ctx); \
421 GLuint color[n] = { 0, }, spec[n] = { 0, }; \
422 GLuint coloroffset = rmesa->swtcl.coloroffset; \
423 GLuint specoffset = rmesa->swtcl.specoffset; \
424 (void) color; (void) spec; (void) coloroffset; (void) specoffset;
426 /***********************************************************************
427 * Helpers for rendering unfilled primitives *
428 ***********************************************************************/
430 #define RASTERIZE(x) r300RasterPrimitive( ctx, reduced_prim[x] )
431 #define RENDER_PRIMITIVE rmesa->radeon.swtcl.render_primitive
434 #include "tnl_dd/t_dd_unfilled.h"
438 /***********************************************************************
439 * Generate GL render functions *
440 ***********************************************************************/
445 #include "tnl_dd/t_dd_tritmp.h"
447 #define IND (R300_UNFILLED_BIT)
448 #define TAG(x) x##_unfilled
449 #include "tnl_dd/t_dd_tritmp.h"
452 static void init_rast_tab( void )
458 /**********************************************************************/
459 /* Render unclipped begin/end objects */
460 /**********************************************************************/
462 #define RENDER_POINTS( start, count ) \
463 for ( ; start < count ; start++) \
464 r300_point( rmesa, VERT(start) )
465 #define RENDER_LINE( v0, v1 ) \
466 r300_line( rmesa, VERT(v0), VERT(v1) )
467 #define RENDER_TRI( v0, v1, v2 ) \
468 r300_triangle( rmesa, VERT(v0), VERT(v1), VERT(v2) )
469 #define RENDER_QUAD( v0, v1, v2, v3 ) \
470 r300_quad( rmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) )
471 #define INIT(x) do { \
472 r300RenderPrimitive( ctx, x ); \
476 r300ContextPtr rmesa = R300_CONTEXT(ctx); \
477 const GLuint vertsize = rmesa->radeon.swtcl.vertex_size; \
478 const char *r300verts = (char *)rmesa->radeon.swtcl.verts; \
479 const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
480 const GLboolean stipple = ctx->Line.StippleFlag; \
481 (void) elt; (void) stipple;
482 #define RESET_STIPPLE //if ( stipple ) r200ResetLineStipple( ctx );
483 #define RESET_OCCLUSION
484 #define PRESERVE_VB_DEFS
486 #define TAG(x) r300_##x##_verts
487 #include "tnl/t_vb_rendertmp.h"
490 #define TAG(x) r300_##x##_elts
491 #define ELT(x) elt[x]
492 #include "tnl/t_vb_rendertmp.h"
497 /**********************************************************************/
498 /* Choose render functions */
499 /**********************************************************************/
500 static void r300ChooseRenderState( struct gl_context *ctx )
502 TNLcontext *tnl = TNL_CONTEXT(ctx);
503 r300ContextPtr rmesa = R300_CONTEXT(ctx);
505 GLuint flags = ctx->_TriangleCaps;
506 radeon_print(RADEON_SWRENDER, RADEON_VERBOSE, "%s\n", __func__);
508 if (flags & DD_TRI_UNFILLED) index |= R300_UNFILLED_BIT;
510 if (index != rmesa->radeon.swtcl.RenderIndex) {
511 tnl->Driver.Render.Points = rast_tab[index].points;
512 tnl->Driver.Render.Line = rast_tab[index].line;
513 tnl->Driver.Render.ClippedLine = rast_tab[index].line;
514 tnl->Driver.Render.Triangle = rast_tab[index].triangle;
515 tnl->Driver.Render.Quad = rast_tab[index].quad;
518 tnl->Driver.Render.PrimTabVerts = r300_render_tab_verts;
519 tnl->Driver.Render.PrimTabElts = r300_render_tab_elts;
520 tnl->Driver.Render.ClippedPolygon = r300_fast_clipped_poly;
522 tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
523 tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
524 tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon;
527 rmesa->radeon.swtcl.RenderIndex = index;
531 void r300RenderStart(struct gl_context *ctx)
533 radeon_print(RADEON_SWRENDER, RADEON_VERBOSE, "%s\n", __func__);
534 r300ContextPtr rmesa = R300_CONTEXT( ctx );
536 r300ChooseRenderState(ctx);
538 r300UpdateShaders(rmesa);
540 r300PrepareVertices(ctx);
542 r300ValidateBuffers(ctx);
544 r300UpdateShaderStates(rmesa);
547 /* investigate if we can put back flush optimisation if needed */
548 if (rmesa->radeon.dma.flush != NULL) {
549 rmesa->radeon.dma.flush(ctx);
553 void r300RenderFinish(struct gl_context *ctx)
557 static void r300RasterPrimitive( struct gl_context *ctx, GLuint hwprim )
559 r300ContextPtr rmesa = R300_CONTEXT(ctx);
560 radeon_print(RADEON_SWRENDER, RADEON_TRACE, "%s\n", __func__);
562 if (rmesa->radeon.swtcl.hw_primitive != hwprim) {
563 R300_NEWPRIM( rmesa );
564 rmesa->radeon.swtcl.hw_primitive = hwprim;
568 void r300RenderPrimitive(struct gl_context *ctx, GLenum prim)
571 r300ContextPtr rmesa = R300_CONTEXT(ctx);
572 rmesa->radeon.swtcl.render_primitive = prim;
573 radeon_print(RADEON_SWRENDER, RADEON_TRACE, "%s\n", __func__);
575 if ((prim == GL_TRIANGLES) && (ctx->_TriangleCaps & DD_TRI_UNFILLED))
578 r300RasterPrimitive( ctx, reduced_prim[prim] );
581 void r300ResetLineStipple(struct gl_context *ctx)
583 if (RADEON_DEBUG & RADEON_VERTS)
584 fprintf(stderr, "%s\n", __func__);
587 void r300InitSwtcl(struct gl_context *ctx)
589 TNLcontext *tnl = TNL_CONTEXT(ctx);
590 r300ContextPtr rmesa = R300_CONTEXT(ctx);
591 static int firsttime = 1;
592 radeon_print(RADEON_SWRENDER, RADEON_NORMAL, "%s\n", __func__);
598 rmesa->radeon.swtcl.emit_prediction = 0;
600 tnl->Driver.Render.Start = r300RenderStart;
601 tnl->Driver.Render.Finish = r300RenderFinish;
602 tnl->Driver.Render.PrimitiveNotify = r300RenderPrimitive;
603 tnl->Driver.Render.ResetLineStipple = r300ResetLineStipple;
604 tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
605 tnl->Driver.Render.CopyPV = _tnl_copy_pv;
606 tnl->Driver.Render.Interp = _tnl_interp;
608 /* FIXME: what are these numbers? */
609 _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12,
610 48 * sizeof(GLfloat) );
612 rmesa->radeon.swtcl.verts = (GLubyte *)tnl->clipspace.vertex_buf;
613 rmesa->radeon.swtcl.RenderIndex = ~0;
614 rmesa->radeon.swtcl.render_primitive = GL_TRIANGLES;
615 rmesa->radeon.swtcl.hw_primitive = 0;
617 _tnl_invalidate_vertex_state( ctx, ~0 );
618 _tnl_invalidate_vertices( ctx, ~0 );
620 _tnl_need_projected_coords( ctx, GL_FALSE );
623 void r300DestroySwtcl(struct gl_context *ctx)
627 static void r300EmitVertexAOS(r300ContextPtr rmesa, GLuint vertex_size, struct radeon_bo *bo, GLuint offset)
629 BATCH_LOCALS(&rmesa->radeon);
631 radeon_print(RADEON_SWRENDER, RADEON_TRACE,
632 "%s: vertex_size %d, offset 0x%x \n",
633 __FUNCTION__, vertex_size, offset);
636 OUT_BATCH_PACKET3(R300_PACKET3_3D_LOAD_VBPNTR, 2);
638 OUT_BATCH(vertex_size | (vertex_size << 8));
639 OUT_BATCH_RELOC(offset, bo, offset, RADEON_GEM_DOMAIN_GTT, 0, 0);
643 static void r300EmitVbufPrim(r300ContextPtr rmesa, GLuint primitive, GLuint vertex_nr)
645 BATCH_LOCALS(&rmesa->radeon);
647 if (RADEON_DEBUG & RADEON_VERTS)
648 fprintf(stderr, "%s\n", __func__);
650 type = r300PrimitiveType(rmesa, primitive);
651 num_verts = r300NumVerts(rmesa, vertex_nr, primitive);
654 OUT_BATCH_PACKET3(R300_PACKET3_3D_DRAW_VBUF_2, 0);
655 OUT_BATCH(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (num_verts << 16) | type);
659 void r300_swtcl_flush(struct gl_context *ctx, uint32_t current_offset)
661 radeon_print(RADEON_SWRENDER, RADEON_TRACE, "%s\n", __func__);
662 r300ContextPtr rmesa = R300_CONTEXT(ctx);
664 r300EmitCacheFlush(rmesa);
666 radeonEmitState(&rmesa->radeon);
667 r300_emit_scissor(ctx);
668 r300EmitVertexAOS(rmesa,
669 rmesa->radeon.swtcl.vertex_size,
670 rmesa->radeon.swtcl.bo,
673 r300EmitVbufPrim(rmesa,
674 rmesa->radeon.swtcl.hw_primitive,
675 rmesa->radeon.swtcl.numverts);
676 r300EmitCacheFlush(rmesa);
677 if ( rmesa->radeon.swtcl.emit_prediction < rmesa->radeon.cmdbuf.cs->cdw )
678 WARN_ONCE("Rendering was %d commands larger than predicted size."
679 " We might overflow command buffer.\n",
680 rmesa->radeon.cmdbuf.cs->cdw - rmesa->radeon.swtcl.emit_prediction );
681 rmesa->radeon.swtcl.emit_prediction = 0;