Tizen 2.0 Release
[profile/ivi/osmesa.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(struct gl_context *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(struct gl_context *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( struct gl_context *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_SPEC   1
368 #define HAVE_BACK_COLORS  0
369 #define HAVE_HW_FLATSHADE 1
370 #define TAB rast_tab
371
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)))
380
381 #define VERT_SET_RGBA( v, c ) \
382 do { \
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]); \
388 } while (0)
389
390 #define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
391
392 #define VERT_SET_SPEC( v0, c ) \
393 do { \
394    if (specoffset) { \
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]); \
398    } \
399 } while (0)
400
401 #define VERT_COPY_SPEC( v0, v1 ) \
402 do { \
403    if (specoffset) { \
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; \
407    } \
408 } while (0)
409
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]
414
415 #undef LOCAL_VARS
416 #undef TAG
417 #undef INIT
418
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;
425
426 /***********************************************************************
427  *                Helpers for rendering unfilled primitives            *
428  ***********************************************************************/
429
430 #define RASTERIZE(x) r300RasterPrimitive( ctx, reduced_prim[x] )
431 #define RENDER_PRIMITIVE rmesa->radeon.swtcl.render_primitive
432 #undef TAG
433 #define TAG(x) x
434 #include "tnl_dd/t_dd_unfilled.h"
435 #undef IND
436
437
438 /***********************************************************************
439  *                      Generate GL render functions                   *
440  ***********************************************************************/
441
442
443 #define IND (0)
444 #define TAG(x) x
445 #include "tnl_dd/t_dd_tritmp.h"
446
447 #define IND (R300_UNFILLED_BIT)
448 #define TAG(x) x##_unfilled
449 #include "tnl_dd/t_dd_tritmp.h"
450
451
452 static void init_rast_tab( void )
453 {
454    init();
455    init_unfilled();
456 }
457
458 /**********************************************************************/
459 /*               Render unclipped begin/end objects                   */
460 /**********************************************************************/
461
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 );                       \
473 } while (0)
474 #undef LOCAL_VARS
475 #define LOCAL_VARS                                              \
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
485 #define ELT(x) (x)
486 #define TAG(x) r300_##x##_verts
487 #include "tnl/t_vb_rendertmp.h"
488 #undef ELT
489 #undef TAG
490 #define TAG(x) r300_##x##_elts
491 #define ELT(x) elt[x]
492 #include "tnl/t_vb_rendertmp.h"
493
494
495
496
497 /**********************************************************************/
498 /*                    Choose render functions                         */
499 /**********************************************************************/
500 static void r300ChooseRenderState( struct gl_context *ctx )
501 {
502         TNLcontext *tnl = TNL_CONTEXT(ctx);
503         r300ContextPtr rmesa = R300_CONTEXT(ctx);
504         GLuint index = 0;
505         GLuint flags = ctx->_TriangleCaps;
506         radeon_print(RADEON_SWRENDER, RADEON_VERBOSE, "%s\n", __func__);
507
508         if (flags & DD_TRI_UNFILLED)      index |= R300_UNFILLED_BIT;
509
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;
516
517                 if (index == 0) {
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;
521                 } else {
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;
525                 }
526
527                 rmesa->radeon.swtcl.RenderIndex = index;
528         }
529 }
530
531 void r300RenderStart(struct gl_context *ctx)
532 {
533         radeon_print(RADEON_SWRENDER, RADEON_VERBOSE, "%s\n", __func__);
534         r300ContextPtr rmesa = R300_CONTEXT( ctx );
535
536         r300ChooseRenderState(ctx);
537
538         r300UpdateShaders(rmesa);
539
540         r300PrepareVertices(ctx);
541
542         r300ValidateBuffers(ctx);
543
544         r300UpdateShaderStates(rmesa);
545
546
547         /* investigate if we can put back flush optimisation if needed */
548         if (rmesa->radeon.dma.flush != NULL) {
549                 rmesa->radeon.dma.flush(ctx);
550         }
551 }
552
553 void r300RenderFinish(struct gl_context *ctx)
554 {
555 }
556
557 static void r300RasterPrimitive( struct gl_context *ctx, GLuint hwprim )
558 {
559         r300ContextPtr rmesa = R300_CONTEXT(ctx);
560         radeon_print(RADEON_SWRENDER, RADEON_TRACE, "%s\n", __func__);
561
562         if (rmesa->radeon.swtcl.hw_primitive != hwprim) {
563                 R300_NEWPRIM( rmesa );
564                 rmesa->radeon.swtcl.hw_primitive = hwprim;
565         }
566 }
567
568 void r300RenderPrimitive(struct gl_context *ctx, GLenum prim)
569 {
570
571         r300ContextPtr rmesa = R300_CONTEXT(ctx);
572         rmesa->radeon.swtcl.render_primitive = prim;
573         radeon_print(RADEON_SWRENDER, RADEON_TRACE, "%s\n", __func__);
574
575         if ((prim == GL_TRIANGLES) && (ctx->_TriangleCaps & DD_TRI_UNFILLED))
576                 return;
577
578         r300RasterPrimitive( ctx, reduced_prim[prim] );
579 }
580
581 void r300ResetLineStipple(struct gl_context *ctx)
582 {
583         if (RADEON_DEBUG & RADEON_VERTS)
584                 fprintf(stderr, "%s\n", __func__);
585 }
586
587 void r300InitSwtcl(struct gl_context *ctx)
588 {
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__);
593
594         if (firsttime) {
595                 init_rast_tab();
596                 firsttime = 0;
597         }
598         rmesa->radeon.swtcl.emit_prediction = 0;
599
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;
607
608         /* FIXME: what are these numbers? */
609         _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12,
610                             48 * sizeof(GLfloat) );
611
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;
616
617         _tnl_invalidate_vertex_state( ctx, ~0 );
618         _tnl_invalidate_vertices( ctx, ~0 );
619
620         _tnl_need_projected_coords( ctx, GL_FALSE );
621 }
622
623 void r300DestroySwtcl(struct gl_context *ctx)
624 {
625 }
626
627 static void r300EmitVertexAOS(r300ContextPtr rmesa, GLuint vertex_size, struct radeon_bo *bo, GLuint offset)
628 {
629         BATCH_LOCALS(&rmesa->radeon);
630
631         radeon_print(RADEON_SWRENDER, RADEON_TRACE,
632                 "%s:  vertex_size %d, offset 0x%x \n",
633                         __FUNCTION__, vertex_size, offset);
634
635         BEGIN_BATCH(7);
636         OUT_BATCH_PACKET3(R300_PACKET3_3D_LOAD_VBPNTR, 2);
637         OUT_BATCH(1);
638         OUT_BATCH(vertex_size | (vertex_size << 8));
639         OUT_BATCH_RELOC(offset, bo, offset, RADEON_GEM_DOMAIN_GTT, 0, 0);
640         END_BATCH();
641 }
642
643 static void r300EmitVbufPrim(r300ContextPtr rmesa, GLuint primitive, GLuint vertex_nr)
644 {
645         BATCH_LOCALS(&rmesa->radeon);
646         int type, num_verts;
647         if (RADEON_DEBUG & RADEON_VERTS)
648                 fprintf(stderr, "%s\n", __func__);
649
650         type = r300PrimitiveType(rmesa, primitive);
651         num_verts = r300NumVerts(rmesa, vertex_nr, primitive);
652
653         BEGIN_BATCH(3);
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);
656         END_BATCH();
657 }
658
659 void r300_swtcl_flush(struct gl_context *ctx, uint32_t current_offset)
660 {
661         radeon_print(RADEON_SWRENDER, RADEON_TRACE, "%s\n", __func__);
662         r300ContextPtr rmesa = R300_CONTEXT(ctx);
663
664         r300EmitCacheFlush(rmesa);
665
666         radeonEmitState(&rmesa->radeon);
667         r300_emit_scissor(ctx);
668         r300EmitVertexAOS(rmesa,
669                           rmesa->radeon.swtcl.vertex_size,
670                           rmesa->radeon.swtcl.bo,
671                           current_offset);
672
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;
682         COMMIT_BATCH();
683 }