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 rmesa
->swtcl
.coloroffset
= rmesa
->swtcl
.specoffset
= 0;
84 rmesa
->radeon
.swtcl
.vertex_attr_count
= 0;
86 if (RADEON_DEBUG
& DEBUG_VERTS
)
87 fprintf(stderr
, "%s\n", __func__
);
89 /* We always want non Ndc coords format */
90 VB
->AttribPtr
[VERT_ATTRIB_POS
] = VB
->ClipPtr
;
92 /* Always write position vector */
93 InputsRead
|= 1 << VERT_ATTRIB_POS
;
94 OutputsWritten
|= 1 << VERT_RESULT_HPOS
;
95 EMIT_ATTR( _TNL_ATTRIB_POS
, EMIT_4F
);
96 ADD_ATTR(VERT_ATTRIB_POS
, R300_DATA_TYPE_FLOAT_4
, SWTCL_OVM_POS
, SWIZZLE_XYZW
, MASK_XYZW
, 0);
97 rmesa
->swtcl
.coloroffset
= 4;
99 if (fp_reads
& FRAG_BIT_COL0
) {
100 InputsRead
|= 1 << VERT_ATTRIB_COLOR0
;
101 OutputsWritten
|= 1 << VERT_RESULT_COL0
;
102 #if MESA_LITTLE_ENDIAN
103 EMIT_ATTR( _TNL_ATTRIB_COLOR0
, EMIT_4UB_4F_RGBA
);
104 ADD_ATTR(VERT_ATTRIB_COLOR0
, R300_DATA_TYPE_BYTE
, SWTCL_OVM_COLOR0
, SWIZZLE_XYZW
, MASK_XYZW
, 1);
106 EMIT_ATTR( _TNL_ATTRIB_COLOR0
, EMIT_4UB_4F_ABGR
);
107 ADD_ATTR(VERT_ATTRIB_COLOR0
, R300_DATA_TYPE_BYTE
, SWTCL_OVM_COLOR0
, SWIZZLE_XYZW
, MASK_XYZW
, 1);
111 if (fp_reads
& FRAG_BIT_COL1
) {
112 GLuint swiz
= MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_Y
, SWIZZLE_Z
, SWIZZLE_ONE
);
113 InputsRead
|= 1 << VERT_ATTRIB_COLOR1
;
114 OutputsWritten
|= 1 << VERT_RESULT_COL1
;
115 #if MESA_LITTLE_ENDIAN
116 EMIT_ATTR( _TNL_ATTRIB_COLOR1
, EMIT_4UB_4F_RGBA
);
117 ADD_ATTR(VERT_ATTRIB_COLOR1
, R300_DATA_TYPE_BYTE
, SWTCL_OVM_COLOR1
, swiz
, MASK_XYZW
, 1);
119 EMIT_ATTR( _TNL_ATTRIB_COLOR1
, EMIT_4UB_4F_ABGR
);
120 ADD_ATTR(VERT_ATTRIB_COLOR1
, R300_DATA_TYPE_BYTE
, SWTCL_OVM_COLOR1
, swiz
, MASK_XYZW
, 1);
122 rmesa
->swtcl
.specoffset
= rmesa
->swtcl
.coloroffset
+ 1;
125 if (ctx
->Light
.Enabled
&& ctx
->Light
.Model
.TwoSide
) {
126 VB
->AttribPtr
[VERT_ATTRIB_GENERIC0
] = VB
->ColorPtr
[1];
127 OutputsWritten
|= 1 << VERT_RESULT_BFC0
;
128 #if MESA_LITTLE_ENDIAN
129 EMIT_ATTR( _TNL_ATTRIB_GENERIC0
, EMIT_4UB_4F_RGBA
);
130 ADD_ATTR(VERT_ATTRIB_GENERIC0
, R300_DATA_TYPE_BYTE
, SWTCL_OVM_COLOR2
, SWIZZLE_XYZW
, MASK_XYZW
, 1);
132 EMIT_ATTR( _TNL_ATTRIB_GENERIC0
, EMIT_4UB_4F_ABGR
);
133 ADD_ATTR(VERT_ATTRIB_GENERIC0
, R300_DATA_TYPE_BYTE
, SWTCL_OVM_COLOR2
, SWIZZLE_XYZW
, MASK_XYZW
, 1);
135 if (fp_reads
& FRAG_BIT_COL1
) {
136 VB
->AttribPtr
[VERT_ATTRIB_GENERIC1
] = VB
->SecondaryColorPtr
[1];
137 GLuint swiz
= MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_Y
, SWIZZLE_Z
, SWIZZLE_ONE
);
138 OutputsWritten
|= 1 << VERT_RESULT_BFC1
;
139 #if MESA_LITTLE_ENDIAN
140 EMIT_ATTR( _TNL_ATTRIB_GENERIC1
, EMIT_4UB_4F_RGBA
);
141 ADD_ATTR(VERT_ATTRIB_GENERIC1
, R300_DATA_TYPE_BYTE
, SWTCL_OVM_COLOR3
, swiz
, MASK_XYZW
, 1);
143 EMIT_ATTR( _TNL_ATTRIB_GENERIC1
, EMIT_4UB_4F_ABGR
);
144 ADD_ATTR(VERT_ATTRIB_GENERIC1
, R300_DATA_TYPE_BYTE
, SWTCL_OVM_COLOR3
, swiz
, MASK_XYZW
, 1);
149 if (RENDERINPUTS_TEST(tnl
->render_inputs_bitset
, _TNL_ATTRIB_POINTSIZE
)) {
150 GLuint swiz
= MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_ZERO
, SWIZZLE_ZERO
, SWIZZLE_ZERO
);
151 InputsRead
|= 1 << VERT_ATTRIB_POINT_SIZE
;
152 OutputsWritten
|= 1 << VERT_RESULT_PSIZ
;
153 EMIT_ATTR( _TNL_ATTRIB_POINTSIZE
, EMIT_1F
);
154 ADD_ATTR(VERT_ATTRIB_POINT_SIZE
, R300_DATA_TYPE_FLOAT_1
, SWTCL_OVM_POINT_SIZE
, swiz
, MASK_X
, 0);
157 if (rmesa
->selected_fp
->wpos_attr
!= FRAG_ATTRIB_MAX
) {
158 int tex_id
= rmesa
->selected_fp
->wpos_attr
- FRAG_ATTRIB_TEX0
;
160 VB
->AttribPtr
[VERT_ATTRIB_TEX0
+ tex_id
] = VB
->AttribPtr
[VERT_ATTRIB_POS
];
161 VB
->TexCoordPtr
[tex_id
] = VB
->AttribPtr
[VERT_ATTRIB_POS
];
162 RENDERINPUTS_SET(tnl
->render_inputs_bitset
, _TNL_ATTRIB_TEX0
+ tex_id
);
165 if (rmesa
->selected_fp
->fog_attr
!= FRAG_ATTRIB_MAX
) {
166 int tex_id
= rmesa
->selected_fp
->fog_attr
- FRAG_ATTRIB_TEX0
;
168 VB
->AttribPtr
[VERT_ATTRIB_TEX0
+ tex_id
] = VB
->AttribPtr
[VERT_ATTRIB_FOG
];
169 VB
->TexCoordPtr
[tex_id
] = VB
->AttribPtr
[VERT_ATTRIB_FOG
];
170 RENDERINPUTS_SET(tnl
->render_inputs_bitset
, _TNL_ATTRIB_TEX0
+ tex_id
);
174 * Sending only one texcoord component may lead to lock up,
175 * so for all textures always output 4 texcoord components to RS.
179 GLuint swiz
, format
, hw_format
;
180 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
181 if (fp_reads
& FRAG_BIT_TEX(i
)) {
182 switch (VB
->TexCoordPtr
[i
]->size
) {
185 hw_format
= R300_DATA_TYPE_FLOAT_1
;
186 swiz
= MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_ZERO
, SWIZZLE_ZERO
, SWIZZLE_ONE
);
190 hw_format
= R300_DATA_TYPE_FLOAT_2
;
191 swiz
= MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_Y
, SWIZZLE_ZERO
, SWIZZLE_ONE
);
195 hw_format
= R300_DATA_TYPE_FLOAT_3
;
196 swiz
= MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_Y
, SWIZZLE_Z
, SWIZZLE_ONE
);
200 hw_format
= R300_DATA_TYPE_FLOAT_4
;
206 InputsRead
|= 1 << (VERT_ATTRIB_TEX0
+ i
);
207 OutputsWritten
|= 1 << (VERT_RESULT_TEX0
+ i
);
208 EMIT_ATTR(_TNL_ATTRIB_TEX(i
), format
);
209 ADD_ATTR(VERT_ATTRIB_TEX0
+ i
, hw_format
, SWTCL_OVM_TEX(first_free_tex
), swiz
, MASK_XYZW
, 0);
215 if (first_free_tex
>= ctx
->Const
.MaxTextureUnits
) {
216 fprintf(stderr
, "\tout of free texcoords to write fog coordinate\n");
221 rmesa
->vbuf
.num_attribs
= num_attrs
;
222 *_InputsRead
= InputsRead
;
223 *_OutputsWritten
= OutputsWritten
;
225 RENDERINPUTS_COPY(rmesa
->render_inputs_bitset
, tnl
->render_inputs_bitset
);
228 static void r300PrepareVertices(GLcontext
*ctx
)
230 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
231 GLuint InputsRead
, OutputsWritten
;
233 r300ChooseSwtclVertexFormat(ctx
, &InputsRead
, &OutputsWritten
);
234 r300SetupVAP(ctx
, InputsRead
, OutputsWritten
);
236 rmesa
->radeon
.swtcl
.vertex_size
=
237 _tnl_install_attrs( ctx
,
238 rmesa
->radeon
.swtcl
.vertex_attrs
,
239 rmesa
->radeon
.swtcl
.vertex_attr_count
,
242 rmesa
->radeon
.swtcl
.vertex_size
/= 4;
245 static void r300_predict_emit_size( r300ContextPtr rmesa
)
247 if (!rmesa
->radeon
.swtcl
.emit_prediction
) {
248 const int vertex_size
= 7;
249 const int prim_size
= 3;
250 const int cache_flush_size
= 4;
251 const int pre_emit_state
= 4;
252 const int scissor_size
= 3;
253 const int state_size
= radeonCountStateEmitSize(&rmesa
->radeon
);
255 if (rcommonEnsureCmdBufSpace(&rmesa
->radeon
,
256 state_size
+ pre_emit_state
+ scissor_size
257 + vertex_size
+ prim_size
+ cache_flush_size
* 2,
259 rmesa
->radeon
.swtcl
.emit_prediction
= radeonCountStateEmitSize(&rmesa
->radeon
);
261 rmesa
->radeon
.swtcl
.emit_prediction
= state_size
;
263 rmesa
->radeon
.swtcl
.emit_prediction
+= rmesa
->radeon
.cmdbuf
.cs
->cdw
264 + vertex_size
+ scissor_size
+ prim_size
+ cache_flush_size
* 2 + pre_emit_state
;
269 static GLuint reduced_prim
[] = {
282 static void r300RasterPrimitive( GLcontext
*ctx
, GLuint prim
);
284 /***********************************************************************
285 * Emit primitives as inline vertices *
286 ***********************************************************************/
289 #define HAVE_POINTS 1
291 #define HAVE_LINE_STRIPS 1
292 #define HAVE_TRIANGLES 1
293 #define HAVE_TRI_STRIPS 1
294 #define HAVE_TRI_STRIP_1 0
295 #define HAVE_TRI_FANS 1
297 #define HAVE_QUAD_STRIPS 0
298 #define HAVE_POLYGONS 1
301 static void* r300_alloc_verts(r300ContextPtr rmesa
, GLuint n
, GLuint size
)
305 r300_predict_emit_size( rmesa
);
306 rv
= rcommonAllocDmaLowVerts( &rmesa
->radeon
, n
, size
* 4 );
313 #define CTX_ARG r300ContextPtr rmesa
314 #define GET_VERTEX_DWORDS() rmesa->radeon.swtcl.vertex_size
315 #define ALLOC_VERTS( n, size ) r300_alloc_verts(rmesa, n, size);
317 r300ContextPtr rmesa = R300_CONTEXT(ctx); \
318 const char *r300verts = (char *)rmesa->radeon.swtcl.verts;
319 #define VERT(x) (r300Vertex *)(r300verts + ((x) * vertsize * sizeof(int)))
320 #define VERTEX r300Vertex
322 #define TAG(x) r300_##x
323 #include "tnl_dd/t_dd_triemit.h"
327 /***********************************************************************
328 * Macros for t_dd_tritmp.h to draw basic primitives *
329 ***********************************************************************/
331 #define QUAD( a, b, c, d ) r300_quad( rmesa, a, b, c, d )
332 #define TRI( a, b, c ) r300_triangle( rmesa, a, b, c )
333 #define LINE( a, b ) r300_line( rmesa, a, b )
334 #define POINT( a ) r300_point( rmesa, a )
336 /***********************************************************************
337 * Build render functions from dd templates *
338 ***********************************************************************/
340 #define R300_UNFILLED_BIT 0x01
341 #define R300_MAX_TRIFUNC 0x02
344 tnl_points_func points
;
346 tnl_triangle_func triangle
;
348 } rast_tab
[R300_MAX_TRIFUNC
];
350 #define DO_FALLBACK 0
351 #define DO_UNFILLED (IND & R300_UNFILLED_BIT)
359 #define DO_FULL_QUAD 1
363 #define HAVE_BACK_COLORS 0
364 #define HAVE_HW_FLATSHADE 1
367 #define DEPTH_SCALE 1.0
368 #define UNFILLED_TRI unfilled_tri
369 #define UNFILLED_QUAD unfilled_quad
370 #define VERT_X(_v) _v->v.x
371 #define VERT_Y(_v) _v->v.y
372 #define VERT_Z(_v) _v->v.z
373 #define AREA_IS_CCW( a ) (a < 0)
374 #define GET_VERTEX(e) (rmesa->radeon.swtcl.verts + (e*rmesa->radeon.swtcl.vertex_size*sizeof(int)))
376 #define VERT_SET_RGBA( v, c ) \
378 r300_color_t *color = (r300_color_t *)&((v)->ui[coloroffset]); \
379 UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]); \
380 UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]); \
381 UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]); \
382 UNCLAMPED_FLOAT_TO_UBYTE(color->alpha, (c)[3]); \
385 #define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
387 #define VERT_SET_SPEC( v0, c ) \
390 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.red, (c)[0]); \
391 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.green, (c)[1]); \
392 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.blue, (c)[2]); \
396 #define VERT_COPY_SPEC( v0, v1 ) \
399 v0->v.specular.red = v1->v.specular.red; \
400 v0->v.specular.green = v1->v.specular.green; \
401 v0->v.specular.blue = v1->v.specular.blue; \
405 #define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[coloroffset]
406 #define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx]
407 #define VERT_SAVE_SPEC( idx ) if (specoffset) spec[idx] = v[idx]->ui[specoffset]
408 #define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->ui[specoffset] = spec[idx]
414 #define LOCAL_VARS(n) \
415 r300ContextPtr rmesa = R300_CONTEXT(ctx); \
416 GLuint color[n] = { 0, }, spec[n] = { 0, }; \
417 GLuint coloroffset = rmesa->swtcl.coloroffset; \
418 GLuint specoffset = rmesa->swtcl.specoffset; \
419 (void) color; (void) spec; (void) coloroffset; (void) specoffset;
421 /***********************************************************************
422 * Helpers for rendering unfilled primitives *
423 ***********************************************************************/
425 #define RASTERIZE(x) r300RasterPrimitive( ctx, reduced_prim[x] )
426 #define RENDER_PRIMITIVE rmesa->radeon.swtcl.render_primitive
429 #include "tnl_dd/t_dd_unfilled.h"
433 /***********************************************************************
434 * Generate GL render functions *
435 ***********************************************************************/
440 #include "tnl_dd/t_dd_tritmp.h"
442 #define IND (R300_UNFILLED_BIT)
443 #define TAG(x) x##_unfilled
444 #include "tnl_dd/t_dd_tritmp.h"
447 static void init_rast_tab( void )
453 /**********************************************************************/
454 /* Render unclipped begin/end objects */
455 /**********************************************************************/
457 #define RENDER_POINTS( start, count ) \
458 for ( ; start < count ; start++) \
459 r300_point( rmesa, VERT(start) )
460 #define RENDER_LINE( v0, v1 ) \
461 r300_line( rmesa, VERT(v0), VERT(v1) )
462 #define RENDER_TRI( v0, v1, v2 ) \
463 r300_triangle( rmesa, VERT(v0), VERT(v1), VERT(v2) )
464 #define RENDER_QUAD( v0, v1, v2, v3 ) \
465 r300_quad( rmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) )
466 #define INIT(x) do { \
467 r300RenderPrimitive( ctx, x ); \
471 r300ContextPtr rmesa = R300_CONTEXT(ctx); \
472 const GLuint vertsize = rmesa->radeon.swtcl.vertex_size; \
473 const char *r300verts = (char *)rmesa->radeon.swtcl.verts; \
474 const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
475 const GLboolean stipple = ctx->Line.StippleFlag; \
476 (void) elt; (void) stipple;
477 #define RESET_STIPPLE //if ( stipple ) r200ResetLineStipple( ctx );
478 #define RESET_OCCLUSION
479 #define PRESERVE_VB_DEFS
481 #define TAG(x) r300_##x##_verts
482 #include "tnl/t_vb_rendertmp.h"
485 #define TAG(x) r300_##x##_elts
486 #define ELT(x) elt[x]
487 #include "tnl/t_vb_rendertmp.h"
492 /**********************************************************************/
493 /* Choose render functions */
494 /**********************************************************************/
495 static void r300ChooseRenderState( GLcontext
*ctx
)
497 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
498 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
500 GLuint flags
= ctx
->_TriangleCaps
;
501 if (RADEON_DEBUG
& DEBUG_VERTS
)
502 fprintf(stderr
, "%s\n", __func__
);
504 if (flags
& DD_TRI_UNFILLED
) index
|= R300_UNFILLED_BIT
;
506 if (index
!= rmesa
->radeon
.swtcl
.RenderIndex
) {
507 tnl
->Driver
.Render
.Points
= rast_tab
[index
].points
;
508 tnl
->Driver
.Render
.Line
= rast_tab
[index
].line
;
509 tnl
->Driver
.Render
.ClippedLine
= rast_tab
[index
].line
;
510 tnl
->Driver
.Render
.Triangle
= rast_tab
[index
].triangle
;
511 tnl
->Driver
.Render
.Quad
= rast_tab
[index
].quad
;
514 tnl
->Driver
.Render
.PrimTabVerts
= r300_render_tab_verts
;
515 tnl
->Driver
.Render
.PrimTabElts
= r300_render_tab_elts
;
516 tnl
->Driver
.Render
.ClippedPolygon
= r300_fast_clipped_poly
;
518 tnl
->Driver
.Render
.PrimTabVerts
= _tnl_render_tab_verts
;
519 tnl
->Driver
.Render
.PrimTabElts
= _tnl_render_tab_elts
;
520 tnl
->Driver
.Render
.ClippedPolygon
= _tnl_RenderClippedPolygon
;
523 rmesa
->radeon
.swtcl
.RenderIndex
= index
;
527 void r300RenderStart(GLcontext
*ctx
)
529 if (RADEON_DEBUG
& DEBUG_VERTS
)
530 fprintf(stderr
, "%s\n", __func__
);
531 r300ContextPtr rmesa
= R300_CONTEXT( ctx
);
533 r300ChooseRenderState(ctx
);
535 r300UpdateShaders(rmesa
);
537 r300PrepareVertices(ctx
);
539 r300ValidateBuffers(ctx
);
541 r300UpdateShaderStates(rmesa
);
544 /* investigate if we can put back flush optimisation if needed */
545 if (rmesa
->radeon
.dma
.flush
!= NULL
) {
546 rmesa
->radeon
.dma
.flush(ctx
);
550 void r300RenderFinish(GLcontext
*ctx
)
554 static void r300RasterPrimitive( GLcontext
*ctx
, GLuint hwprim
)
556 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
557 if (RADEON_DEBUG
& DEBUG_VERTS
)
558 fprintf(stderr
, "%s\n", __func__
);
560 if (rmesa
->radeon
.swtcl
.hw_primitive
!= hwprim
) {
561 R300_NEWPRIM( rmesa
);
562 rmesa
->radeon
.swtcl
.hw_primitive
= hwprim
;
566 void r300RenderPrimitive(GLcontext
*ctx
, GLenum prim
)
569 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
570 rmesa
->radeon
.swtcl
.render_primitive
= prim
;
571 if (RADEON_DEBUG
& DEBUG_VERTS
)
572 fprintf(stderr
, "%s\n", __func__
);
574 if ((prim
== GL_TRIANGLES
) && (ctx
->_TriangleCaps
& DD_TRI_UNFILLED
))
577 r300RasterPrimitive( ctx
, reduced_prim
[prim
] );
580 void r300ResetLineStipple(GLcontext
*ctx
)
582 if (RADEON_DEBUG
& DEBUG_VERTS
)
583 fprintf(stderr
, "%s\n", __func__
);
586 void r300InitSwtcl(GLcontext
*ctx
)
588 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
589 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
590 static int firsttime
= 1;
591 if (RADEON_DEBUG
& DEBUG_VERTS
)
592 fprintf(stderr
, "%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(GLcontext
*ctx
)
627 static void r300EmitVertexAOS(r300ContextPtr rmesa
, GLuint vertex_size
, struct radeon_bo
*bo
, GLuint offset
)
629 BATCH_LOCALS(&rmesa
->radeon
);
631 if (RADEON_DEBUG
& DEBUG_VERTS
)
632 fprintf(stderr
, "%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
& DEBUG_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(GLcontext
*ctx
, uint32_t current_offset
)
661 if (RADEON_DEBUG
& DEBUG_VERTS
)
662 fprintf(stderr
, "%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 first_elem(&rmesa
->radeon
.dma
.reserved
)->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;