Merge branch 'mesa_7_7_branch'
[mesa.git] / src / mesa / drivers / dri / r300 / r300_swtcl.c
1 /**************************************************************************
2
3 Copyright (C) 2007 Dave Airlie
4
5 All Rights Reserved.
6
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:
13
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
16 Software.
17
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.
25
26 **************************************************************************/
27
28 /*
29 * Authors:
30 * Dave Airlie <airlied@linux.ie>
31 * Maciej Cencora <m.cencora@gmail.com>
32 */
33
34 #include "tnl/tnl.h"
35 #include "tnl/t_pipeline.h"
36
37 #include "r300_state.h"
38 #include "r300_swtcl.h"
39 #include "r300_emit.h"
40 #include "r300_tex.h"
41 #include "r300_render.h"
42 #include "main/simple_list.h"
43
44 #define EMIT_ATTR( ATTR, STYLE ) \
45 do { \
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++; \
49 } while (0)
50
51 #define EMIT_PAD( N ) \
52 do { \
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++; \
57 } while (0)
58
59 #define ADD_ATTR(_attr, _format, _dst_loc, _swizzle, _write_mask, _normalize) \
60 do { \
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); \
68 ++num_attrs; \
69 } while (0)
70
71 void r300ChooseSwtclVertexFormat(GLcontext *ctx, GLuint *_InputsRead, GLuint *_OutputsWritten)
72 {
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;
79 int num_attrs = 0;
80 GLuint fp_reads = rmesa->selected_fp->InputsRead;
81 struct vertex_attribute *attrs = rmesa->vbuf.attribs;
82
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;
86
87 if (RADEON_DEBUG & RADEON_VERTS)
88 fprintf(stderr, "%s\n", __func__);
89
90 /* We always want non Ndc coords format */
91 VB->AttribPtr[VERT_ATTRIB_POS] = VB->ClipPtr;
92
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;
99
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);
106 #else
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);
109 #endif
110 }
111
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);
119 #else
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);
122 #endif
123 rmesa->swtcl.specoffset = rmesa->swtcl.coloroffset + 1;
124 }
125
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);
132 #else
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);
135 #endif
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);
143 #else
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);
146 #endif
147 }
148 }
149
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);
156 }
157
158 if (rmesa->selected_fp->wpos_attr != FRAG_ATTRIB_MAX) {
159 int tex_id = rmesa->selected_fp->wpos_attr - FRAG_ATTRIB_TEX0;
160
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);
164 }
165
166 if (rmesa->selected_fp->fog_attr != FRAG_ATTRIB_MAX) {
167 int tex_id = rmesa->selected_fp->fog_attr - FRAG_ATTRIB_TEX0;
168
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);
172 }
173
174 /**
175 * Sending only one texcoord component may lead to lock up,
176 * so for all textures always output 4 texcoord components to RS.
177 */
178 {
179 int i;
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) {
184 case 1:
185 format = EMIT_1F;
186 hw_format = R300_DATA_TYPE_FLOAT_1;
187 swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ONE);
188 break;
189 case 2:
190 format = EMIT_2F;
191 hw_format = R300_DATA_TYPE_FLOAT_2;
192 swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ZERO, SWIZZLE_ONE);
193 break;
194 case 3:
195 format = EMIT_3F;
196 hw_format = R300_DATA_TYPE_FLOAT_3;
197 swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE);
198 break;
199 case 4:
200 format = EMIT_4F;
201 hw_format = R300_DATA_TYPE_FLOAT_4;
202 swiz = SWIZZLE_XYZW;
203 break;
204 default:
205 continue;
206 }
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);
211 ++first_free_tex;
212 }
213 }
214 }
215
216 if (first_free_tex >= ctx->Const.MaxTextureUnits) {
217 fprintf(stderr, "\tout of free texcoords to write fog coordinate\n");
218 exit(-1);
219 }
220
221 R300_NEWPRIM(rmesa);
222 rmesa->vbuf.num_attribs = num_attrs;
223 *_InputsRead = InputsRead;
224 *_OutputsWritten = OutputsWritten;
225
226 RENDERINPUTS_COPY(rmesa->render_inputs_bitset, tnl->render_inputs_bitset);
227 }
228
229 static void r300PrepareVertices(GLcontext *ctx)
230 {
231 r300ContextPtr rmesa = R300_CONTEXT(ctx);
232 GLuint InputsRead, OutputsWritten;
233 radeon_print(RADEON_SWRENDER, RADEON_TRACE, "%s\n", __func__);
234
235 r300ChooseSwtclVertexFormat(ctx, &InputsRead, &OutputsWritten);
236 r300SetupVAP(ctx, InputsRead, OutputsWritten);
237
238 rmesa->radeon.swtcl.vertex_size =
239 _tnl_install_attrs( ctx,
240 rmesa->radeon.swtcl.vertex_attrs,
241 rmesa->radeon.swtcl.vertex_attr_count,
242 NULL, 0 );
243
244 rmesa->radeon.swtcl.vertex_size /= 4;
245 }
246
247 static void r300_predict_emit_size( r300ContextPtr rmesa )
248 {
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);
256
257 if (rcommonEnsureCmdBufSpace(&rmesa->radeon,
258 state_size + pre_emit_state + scissor_size
259 + vertex_size + prim_size + cache_flush_size * 2,
260 __FUNCTION__))
261 rmesa->radeon.swtcl.emit_prediction = radeonCountStateEmitSize(&rmesa->radeon);
262 else
263 rmesa->radeon.swtcl.emit_prediction = state_size;
264
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,
268 "%s, size %d\n",
269 __func__, rmesa->radeon.cmdbuf.cs->cdw
270 + vertex_size + scissor_size + prim_size + cache_flush_size * 2 + pre_emit_state);
271 }
272 }
273
274
275 static GLuint reduced_prim[] = {
276 GL_POINTS,
277 GL_LINES,
278 GL_LINES,
279 GL_LINES,
280 GL_TRIANGLES,
281 GL_TRIANGLES,
282 GL_TRIANGLES,
283 GL_TRIANGLES,
284 GL_TRIANGLES,
285 GL_TRIANGLES,
286 };
287
288 static void r300RasterPrimitive( GLcontext *ctx, GLuint prim );
289
290 /***********************************************************************
291 * Emit primitives as inline vertices *
292 ***********************************************************************/
293
294
295 #define HAVE_POINTS 1
296 #define HAVE_LINES 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
302 #define HAVE_QUADS 0
303 #define HAVE_QUAD_STRIPS 0
304 #define HAVE_POLYGONS 1
305 #define HAVE_ELTS 1
306
307 static void* r300_alloc_verts(r300ContextPtr rmesa, GLuint n, GLuint size)
308 {
309 void *rv;
310 do {
311 r300_predict_emit_size( rmesa );
312 rv = rcommonAllocDmaLowVerts( &rmesa->radeon, n, size * 4 );
313 } while (!rv);
314 return rv;
315 }
316
317 #undef LOCAL_VARS
318 #undef ALLOC_VERTS
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);
322 #define LOCAL_VARS \
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
327 #undef TAG
328 #define TAG(x) r300_##x
329 #include "tnl_dd/t_dd_triemit.h"
330
331
332
333 /***********************************************************************
334 * Macros for t_dd_tritmp.h to draw basic primitives *
335 ***********************************************************************/
336
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 )
341
342 /***********************************************************************
343 * Build render functions from dd templates *
344 ***********************************************************************/
345
346 #define R300_UNFILLED_BIT 0x01
347 #define R300_MAX_TRIFUNC 0x02
348
349 static struct {
350 tnl_points_func points;
351 tnl_line_func line;
352 tnl_triangle_func triangle;
353 tnl_quad_func quad;
354 } rast_tab[R300_MAX_TRIFUNC];
355
356 #define DO_FALLBACK 0
357 #define DO_UNFILLED (IND & R300_UNFILLED_BIT)
358 #define DO_TWOSIDE 0
359 #define DO_FLAT 0
360 #define DO_OFFSET 0
361 #define DO_TRI 1
362 #define DO_QUAD 1
363 #define DO_LINE 1
364 #define DO_POINTS 1
365 #define DO_FULL_QUAD 1
366
367 #define HAVE_RGBA 1
368 #define HAVE_SPEC 1
369 #define HAVE_BACK_COLORS 0
370 #define HAVE_HW_FLATSHADE 1
371 #define TAB rast_tab
372
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)))
381
382 #define VERT_SET_RGBA( v, c ) \
383 do { \
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]); \
389 } while (0)
390
391 #define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
392
393 #define VERT_SET_SPEC( v0, c ) \
394 do { \
395 if (specoffset) { \
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]); \
399 } \
400 } while (0)
401
402 #define VERT_COPY_SPEC( v0, v1 ) \
403 do { \
404 if (specoffset) { \
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; \
408 } \
409 } while (0)
410
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]
415
416 #undef LOCAL_VARS
417 #undef TAG
418 #undef INIT
419
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;
426
427 /***********************************************************************
428 * Helpers for rendering unfilled primitives *
429 ***********************************************************************/
430
431 #define RASTERIZE(x) r300RasterPrimitive( ctx, reduced_prim[x] )
432 #define RENDER_PRIMITIVE rmesa->radeon.swtcl.render_primitive
433 #undef TAG
434 #define TAG(x) x
435 #include "tnl_dd/t_dd_unfilled.h"
436 #undef IND
437
438
439 /***********************************************************************
440 * Generate GL render functions *
441 ***********************************************************************/
442
443
444 #define IND (0)
445 #define TAG(x) x
446 #include "tnl_dd/t_dd_tritmp.h"
447
448 #define IND (R300_UNFILLED_BIT)
449 #define TAG(x) x##_unfilled
450 #include "tnl_dd/t_dd_tritmp.h"
451
452
453 static void init_rast_tab( void )
454 {
455 init();
456 init_unfilled();
457 }
458
459 /**********************************************************************/
460 /* Render unclipped begin/end objects */
461 /**********************************************************************/
462
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 ); \
474 } while (0)
475 #undef LOCAL_VARS
476 #define LOCAL_VARS \
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
486 #define ELT(x) (x)
487 #define TAG(x) r300_##x##_verts
488 #include "tnl/t_vb_rendertmp.h"
489 #undef ELT
490 #undef TAG
491 #define TAG(x) r300_##x##_elts
492 #define ELT(x) elt[x]
493 #include "tnl/t_vb_rendertmp.h"
494
495
496
497
498 /**********************************************************************/
499 /* Choose render functions */
500 /**********************************************************************/
501 static void r300ChooseRenderState( GLcontext *ctx )
502 {
503 TNLcontext *tnl = TNL_CONTEXT(ctx);
504 r300ContextPtr rmesa = R300_CONTEXT(ctx);
505 GLuint index = 0;
506 GLuint flags = ctx->_TriangleCaps;
507 radeon_print(RADEON_SWRENDER, RADEON_VERBOSE, "%s\n", __func__);
508
509 if (flags & DD_TRI_UNFILLED) index |= R300_UNFILLED_BIT;
510
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;
517
518 if (index == 0) {
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;
522 } else {
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;
526 }
527
528 rmesa->radeon.swtcl.RenderIndex = index;
529 }
530 }
531
532 void r300RenderStart(GLcontext *ctx)
533 {
534 radeon_print(RADEON_SWRENDER, RADEON_VERBOSE, "%s\n", __func__);
535 r300ContextPtr rmesa = R300_CONTEXT( ctx );
536
537 r300ChooseRenderState(ctx);
538
539 r300UpdateShaders(rmesa);
540
541 r300PrepareVertices(ctx);
542
543 r300ValidateBuffers(ctx);
544
545 r300UpdateShaderStates(rmesa);
546
547
548 /* investigate if we can put back flush optimisation if needed */
549 if (rmesa->radeon.dma.flush != NULL) {
550 rmesa->radeon.dma.flush(ctx);
551 }
552 }
553
554 void r300RenderFinish(GLcontext *ctx)
555 {
556 }
557
558 static void r300RasterPrimitive( GLcontext *ctx, GLuint hwprim )
559 {
560 r300ContextPtr rmesa = R300_CONTEXT(ctx);
561 radeon_print(RADEON_SWRENDER, RADEON_TRACE, "%s\n", __func__);
562
563 if (rmesa->radeon.swtcl.hw_primitive != hwprim) {
564 R300_NEWPRIM( rmesa );
565 rmesa->radeon.swtcl.hw_primitive = hwprim;
566 }
567 }
568
569 void r300RenderPrimitive(GLcontext *ctx, GLenum prim)
570 {
571
572 r300ContextPtr rmesa = R300_CONTEXT(ctx);
573 rmesa->radeon.swtcl.render_primitive = prim;
574 radeon_print(RADEON_SWRENDER, RADEON_TRACE, "%s\n", __func__);
575
576 if ((prim == GL_TRIANGLES) && (ctx->_TriangleCaps & DD_TRI_UNFILLED))
577 return;
578
579 r300RasterPrimitive( ctx, reduced_prim[prim] );
580 }
581
582 void r300ResetLineStipple(GLcontext *ctx)
583 {
584 if (RADEON_DEBUG & RADEON_VERTS)
585 fprintf(stderr, "%s\n", __func__);
586 }
587
588 void r300InitSwtcl(GLcontext *ctx)
589 {
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__);
594
595 if (firsttime) {
596 init_rast_tab();
597 firsttime = 0;
598 }
599 rmesa->radeon.swtcl.emit_prediction = 0;
600
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;
608
609 /* FIXME: what are these numbers? */
610 _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12,
611 48 * sizeof(GLfloat) );
612
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;
617
618 _tnl_invalidate_vertex_state( ctx, ~0 );
619 _tnl_invalidate_vertices( ctx, ~0 );
620
621 _tnl_need_projected_coords( ctx, GL_FALSE );
622 }
623
624 void r300DestroySwtcl(GLcontext *ctx)
625 {
626 }
627
628 static void r300EmitVertexAOS(r300ContextPtr rmesa, GLuint vertex_size, struct radeon_bo *bo, GLuint offset)
629 {
630 BATCH_LOCALS(&rmesa->radeon);
631
632 radeon_print(RADEON_SWRENDER, RADEON_TRACE,
633 "%s: vertex_size %d, offset 0x%x \n",
634 __FUNCTION__, vertex_size, offset);
635
636 BEGIN_BATCH(7);
637 OUT_BATCH_PACKET3(R300_PACKET3_3D_LOAD_VBPNTR, 2);
638 OUT_BATCH(1);
639 OUT_BATCH(vertex_size | (vertex_size << 8));
640 OUT_BATCH_RELOC(offset, bo, offset, RADEON_GEM_DOMAIN_GTT, 0, 0);
641 END_BATCH();
642 }
643
644 static void r300EmitVbufPrim(r300ContextPtr rmesa, GLuint primitive, GLuint vertex_nr)
645 {
646 BATCH_LOCALS(&rmesa->radeon);
647 int type, num_verts;
648 if (RADEON_DEBUG & RADEON_VERTS)
649 fprintf(stderr, "%s\n", __func__);
650
651 type = r300PrimitiveType(rmesa, primitive);
652 num_verts = r300NumVerts(rmesa, vertex_nr, primitive);
653
654 BEGIN_BATCH(3);
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);
657 END_BATCH();
658 }
659
660 void r300_swtcl_flush(GLcontext *ctx, uint32_t current_offset)
661 {
662 radeon_print(RADEON_SWRENDER, RADEON_TRACE, "%s\n", __func__);
663 r300ContextPtr rmesa = R300_CONTEXT(ctx);
664
665 r300EmitCacheFlush(rmesa);
666
667 radeonEmitState(&rmesa->radeon);
668 r300_emit_scissor(ctx);
669 r300EmitVertexAOS(rmesa,
670 rmesa->radeon.swtcl.vertex_size,
671 rmesa->radeon.swtcl.bo,
672 current_offset);
673
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;
683 COMMIT_BATCH();
684 }