r300: merge r300/r500 fragment program structures
[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_swtcl.h"
38 #include "r300_emit.h"
39 #include "r300_tex.h"
40
41 #define EMIT_ATTR( ATTR, STYLE ) \
42 do { \
43 rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].attrib = (ATTR); \
44 rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].format = (STYLE); \
45 rmesa->radeon.swtcl.vertex_attr_count++; \
46 } while (0)
47
48 #define EMIT_PAD( N ) \
49 do { \
50 rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].attrib = 0; \
51 rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].format = EMIT_PAD; \
52 rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].offset = (N); \
53 rmesa->radeon.swtcl.vertex_attr_count++; \
54 } while (0)
55
56 #define ADD_ATTR(_attr, _format, _dst_loc, _swizzle, _write_mask) \
57 do { \
58 attrs[num_attrs].attr = (_attr); \
59 attrs[num_attrs].format = (_format); \
60 attrs[num_attrs].dst_loc = (_dst_loc); \
61 attrs[num_attrs].swizzle = (_swizzle); \
62 attrs[num_attrs].write_mask = (_write_mask); \
63 ++num_attrs; \
64 } while (0)
65
66 static void r300SwtclVAPSetup(GLcontext *ctx, GLuint InputsRead, GLuint OutputsWritten, GLuint vap_out_fmt_1)
67 {
68 r300ContextPtr rmesa = R300_CONTEXT( ctx );
69 struct vertex_attribute *attrs = rmesa->swtcl.vert_attrs;
70 int i, j, reg_count;
71 uint32_t *vir0 = &rmesa->hw.vir[0].cmd[1];
72 uint32_t *vir1 = &rmesa->hw.vir[1].cmd[1];
73
74 for (i = 0; i < R300_VIR_CMDSIZE-1; ++i)
75 vir0[i] = vir1[i] = 0;
76
77 for (i = 0, j = 0; i < rmesa->radeon.swtcl.vertex_attr_count; ++i) {
78 int tmp, data_format;
79 switch (attrs[i].format) {
80 case EMIT_1F:
81 data_format = R300_DATA_TYPE_FLOAT_1;
82 break;
83 case EMIT_2F:
84 data_format = R300_DATA_TYPE_FLOAT_2;
85 break;
86 case EMIT_3F:
87 data_format = R300_DATA_TYPE_FLOAT_3;
88 break;
89 case EMIT_4F:
90 data_format = R300_DATA_TYPE_FLOAT_4;
91 break;
92 case EMIT_4UB_4F_RGBA:
93 case EMIT_4UB_4F_ABGR:
94 data_format = R300_DATA_TYPE_BYTE | R300_NORMALIZE;
95 break;
96 default:
97 fprintf(stderr, "%s: Invalid data format type", __FUNCTION__);
98 _mesa_exit(-1);
99 break;
100 }
101
102 tmp = data_format | (attrs[i].dst_loc << R300_DST_VEC_LOC_SHIFT);
103 if (i % 2 == 0) {
104 vir0[j] = tmp << R300_DATA_TYPE_0_SHIFT;
105 vir1[j] = attrs[i].swizzle | (attrs[i].write_mask << R300_WRITE_ENA_SHIFT);
106 } else {
107 vir0[j] |= tmp << R300_DATA_TYPE_1_SHIFT;
108 vir1[j] |= (attrs[i].swizzle | (attrs[i].write_mask << R300_WRITE_ENA_SHIFT)) << R300_SWIZZLE1_SHIFT;
109 ++j;
110 }
111 }
112
113 reg_count = (rmesa->radeon.swtcl.vertex_attr_count + 1) >> 1;
114 if (rmesa->radeon.swtcl.vertex_attr_count % 2 != 0) {
115 vir0[reg_count-1] |= R300_LAST_VEC << R300_DATA_TYPE_0_SHIFT;
116 } else {
117 vir0[reg_count-1] |= R300_LAST_VEC << R300_DATA_TYPE_1_SHIFT;
118 }
119
120 R300_STATECHANGE(rmesa, vir[0]);
121 R300_STATECHANGE(rmesa, vir[1]);
122 R300_STATECHANGE(rmesa, vof);
123 R300_STATECHANGE(rmesa, vic);
124
125 if (rmesa->radeon.radeonScreen->kernel_mm) {
126 rmesa->hw.vir[0].cmd[0] &= 0xC000FFFF;
127 rmesa->hw.vir[1].cmd[0] &= 0xC000FFFF;
128 rmesa->hw.vir[0].cmd[0] |= (reg_count & 0x3FFF) << 16;
129 rmesa->hw.vir[1].cmd[0] |= (reg_count & 0x3FFF) << 16;
130 } else {
131 ((drm_r300_cmd_header_t *) rmesa->hw.vir[0].cmd)->packet0.count = reg_count;
132 ((drm_r300_cmd_header_t *) rmesa->hw.vir[1].cmd)->packet0.count = reg_count;
133 }
134
135 rmesa->hw.vic.cmd[R300_VIC_CNTL_0] = r300VAPInputCntl0(ctx, InputsRead);
136 rmesa->hw.vic.cmd[R300_VIC_CNTL_1] = r300VAPInputCntl1(ctx, InputsRead);
137 rmesa->hw.vof.cmd[R300_VOF_CNTL_0] = r300VAPOutputCntl0(ctx, OutputsWritten);
138 /**
139 * Can't use r300VAPOutputCntl1 function because it assumes
140 * that all texture coords have 4 components and that's the case
141 * for HW TCL path, but not for SW TCL.
142 */
143 rmesa->hw.vof.cmd[R300_VOF_CNTL_1] = vap_out_fmt_1;
144 }
145
146
147 static void r300SetVertexFormat( GLcontext *ctx )
148 {
149 r300ContextPtr rmesa = R300_CONTEXT( ctx );
150 TNLcontext *tnl = TNL_CONTEXT(ctx);
151 struct vertex_buffer *VB = &tnl->vb;
152 int first_free_tex = 0, vap_out_fmt_1 = 0;
153 GLuint InputsRead = 0;
154 GLuint OutputsWritten = 0;
155 int num_attrs = 0;
156 struct vertex_attribute *attrs = rmesa->swtcl.vert_attrs;
157
158 rmesa->swtcl.coloroffset = rmesa->swtcl.specoffset = 0;
159 rmesa->radeon.swtcl.vertex_attr_count = 0;
160
161 /* We always want non Ndc coords format */
162 VB->AttribPtr[VERT_ATTRIB_POS] = VB->ClipPtr;
163
164 if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, _TNL_ATTRIB_POS)) {
165 InputsRead |= 1 << VERT_ATTRIB_POS;
166 OutputsWritten |= 1 << VERT_RESULT_HPOS;
167 EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F );
168 ADD_ATTR(VERT_ATTRIB_POS, EMIT_4F, SWTCL_OVM_POS, SWIZZLE_XYZW, MASK_XYZW);
169 rmesa->swtcl.coloroffset = 4;
170 }
171
172 if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, _TNL_ATTRIB_COLOR0)) {
173 InputsRead |= 1 << VERT_ATTRIB_COLOR0;
174 OutputsWritten |= 1 << VERT_RESULT_COL0;
175 #if MESA_LITTLE_ENDIAN
176 EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_RGBA );
177 ADD_ATTR(VERT_ATTRIB_COLOR0, EMIT_4UB_4F_RGBA, SWTCL_OVM_COLOR0, SWIZZLE_XYZW, MASK_XYZW);
178 #else
179 EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_ABGR );
180 ADD_ATTR(VERT_ATTRIB_COLOR0, EMIT_4UB_4F_ABGR, SWTCL_OVM_COLOR0, SWIZZLE_XYZW, MASK_XYZW);
181 #endif
182 }
183
184 if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, _TNL_ATTRIB_COLOR1 )) {
185 GLuint swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE);
186 InputsRead |= 1 << VERT_ATTRIB_COLOR1;
187 OutputsWritten |= 1 << VERT_RESULT_COL1;
188 #if MESA_LITTLE_ENDIAN
189 EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_4UB_4F_RGBA );
190 ADD_ATTR(VERT_ATTRIB_COLOR1, EMIT_4UB_4F_RGBA, SWTCL_OVM_COLOR1, swiz, MASK_XYZW);
191 #else
192 EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_4UB_4F_ABGR );
193 ADD_ATTR(VERT_ATTRIB_COLOR1, EMIT_4UB_4F_ABGR, SWTCL_OVM_COLOR1, swiz, MASK_XYZW);
194 #endif
195 rmesa->swtcl.specoffset = rmesa->swtcl.coloroffset + 1;
196 }
197
198 if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, _TNL_ATTRIB_POINTSIZE )) {
199 GLuint swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO);
200 InputsRead |= 1 << VERT_ATTRIB_POINT_SIZE;
201 OutputsWritten |= 1 << VERT_RESULT_PSIZ;
202 EMIT_ATTR( _TNL_ATTRIB_POINTSIZE, EMIT_1F );
203 ADD_ATTR(VERT_ATTRIB_POINT_SIZE, EMIT_1F, SWTCL_OVM_POINT_SIZE, swiz, MASK_X);
204 }
205
206 if (RENDERINPUTS_TEST_RANGE(tnl->render_inputs_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) {
207 int i, size;
208 GLuint swiz, mask, format;
209 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
210 if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, _TNL_ATTRIB_TEX(i) )) {
211 switch (VB->TexCoordPtr[i]->size) {
212 case 1:
213 case 2:
214 format = EMIT_2F;
215 swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ZERO, SWIZZLE_ZERO);
216 mask = MASK_X | MASK_Y;
217 size = 2;
218 break;
219 case 3:
220 format = EMIT_3F;
221 swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO);
222 mask = MASK_X | MASK_Y | MASK_Z;
223 size = 3;
224 break;
225 case 4:
226 format = EMIT_4F;
227 swiz = SWIZZLE_XYZW;
228 mask = MASK_XYZW;
229 size = 4;
230 break;
231 default:
232 continue;
233 }
234 InputsRead |= 1 << (VERT_ATTRIB_TEX0 + i);
235 OutputsWritten |= 1 << (VERT_RESULT_TEX0 + i);
236 EMIT_ATTR(_TNL_ATTRIB_TEX(i), format);
237 ADD_ATTR(VERT_ATTRIB_TEX0 + i, format, SWTCL_OVM_TEX(i), swiz, mask);
238 vap_out_fmt_1 |= size << (i * 3);
239 ++first_free_tex;
240 }
241 }
242 }
243
244 /* RS can't put fragment position on the pixel stack, so stuff it in texcoord if needed */
245 if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, _TNL_ATTRIB_POS) && (ctx->FragmentProgram._Current->Base.InputsRead & FRAG_BIT_WPOS)) {
246 if (first_free_tex >= ctx->Const.MaxTextureUnits) {
247 fprintf(stderr, "\tout of free texcoords to write w pos\n");
248 _mesa_exit(-1);
249 }
250
251 InputsRead |= 1 << (VERT_ATTRIB_TEX0 + first_free_tex);
252 OutputsWritten |= 1 << (VERT_RESULT_TEX0 + first_free_tex);
253 EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F );
254 ADD_ATTR(VERT_ATTRIB_POS, EMIT_4F, SWTCL_OVM_TEX(first_free_tex), SWIZZLE_XYZW, MASK_XYZW);
255 vap_out_fmt_1 |= 4 << (first_free_tex * 3);
256 ++first_free_tex;
257 }
258
259 if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, _TNL_ATTRIB_FOG)) {
260 if (first_free_tex >= ctx->Const.MaxTextureUnits) {
261 fprintf(stderr, "\tout of free texcoords to write fog coordinate\n");
262 _mesa_exit(-1);
263 }
264
265 InputsRead |= 1 << VERT_ATTRIB_FOG;
266 OutputsWritten |= 1 << VERT_RESULT_FOGC;
267 GLuint swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO);
268 EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1F );
269 ADD_ATTR(VERT_ATTRIB_FOG, EMIT_1F, SWTCL_OVM_TEX(first_free_tex), swiz, MASK_X);
270 vap_out_fmt_1 |= 1 << (first_free_tex * 3);
271 }
272
273 R300_NEWPRIM(rmesa);
274 r300SwtclVAPSetup(ctx, InputsRead, OutputsWritten, vap_out_fmt_1);
275
276 rmesa->radeon.swtcl.vertex_size =
277 _tnl_install_attrs( ctx,
278 rmesa->radeon.swtcl.vertex_attrs,
279 rmesa->radeon.swtcl.vertex_attr_count,
280 NULL, 0 );
281
282 rmesa->radeon.swtcl.vertex_size /= 4;
283
284 RENDERINPUTS_COPY(rmesa->render_inputs_bitset, tnl->render_inputs_bitset);
285 }
286
287
288 static GLuint reduced_prim[] = {
289 GL_POINTS,
290 GL_LINES,
291 GL_LINES,
292 GL_LINES,
293 GL_TRIANGLES,
294 GL_TRIANGLES,
295 GL_TRIANGLES,
296 GL_TRIANGLES,
297 GL_TRIANGLES,
298 GL_TRIANGLES,
299 };
300
301 static void r300RasterPrimitive( GLcontext *ctx, GLuint prim );
302 static void r300RenderPrimitive( GLcontext *ctx, GLenum prim );
303
304 /***********************************************************************
305 * Emit primitives as inline vertices *
306 ***********************************************************************/
307
308
309 #define HAVE_POINTS 1
310 #define HAVE_LINES 1
311 #define HAVE_LINE_STRIPS 1
312 #define HAVE_TRIANGLES 1
313 #define HAVE_TRI_STRIPS 1
314 #define HAVE_TRI_STRIP_1 0
315 #define HAVE_TRI_FANS 1
316 #define HAVE_QUADS 0
317 #define HAVE_QUAD_STRIPS 0
318 #define HAVE_POLYGONS 1
319 #define HAVE_ELTS 1
320
321 #undef LOCAL_VARS
322 #undef ALLOC_VERTS
323 #define CTX_ARG r300ContextPtr rmesa
324 #define GET_VERTEX_DWORDS() rmesa->radeon.swtcl.vertex_size
325 #define ALLOC_VERTS( n, size ) rcommonAllocDmaLowVerts( &rmesa->radeon, n, size * 4 )
326 #define LOCAL_VARS \
327 r300ContextPtr rmesa = R300_CONTEXT(ctx); \
328 const char *r300verts = (char *)rmesa->radeon.swtcl.verts;
329 #define VERT(x) (r300Vertex *)(r300verts + ((x) * vertsize * sizeof(int)))
330 #define VERTEX r300Vertex
331 #undef TAG
332 #define TAG(x) r300_##x
333 #include "tnl_dd/t_dd_triemit.h"
334
335
336
337 /***********************************************************************
338 * Macros for t_dd_tritmp.h to draw basic primitives *
339 ***********************************************************************/
340
341 #define QUAD( a, b, c, d ) r300_quad( rmesa, a, b, c, d )
342 #define TRI( a, b, c ) r300_triangle( rmesa, a, b, c )
343 #define LINE( a, b ) r300_line( rmesa, a, b )
344 #define POINT( a ) r300_point( rmesa, a )
345
346 /***********************************************************************
347 * Build render functions from dd templates *
348 ***********************************************************************/
349
350 #define R300_TWOSIDE_BIT 0x01
351 #define R300_UNFILLED_BIT 0x02
352 #define R300_MAX_TRIFUNC 0x04
353
354 static struct {
355 tnl_points_func points;
356 tnl_line_func line;
357 tnl_triangle_func triangle;
358 tnl_quad_func quad;
359 } rast_tab[R300_MAX_TRIFUNC];
360
361 #define DO_FALLBACK 0
362 #define DO_UNFILLED (IND & R300_UNFILLED_BIT)
363 #define DO_TWOSIDE (IND & R300_TWOSIDE_BIT)
364 #define DO_FLAT 0
365 #define DO_OFFSET 0
366 #define DO_TRI 1
367 #define DO_QUAD 1
368 #define DO_LINE 1
369 #define DO_POINTS 1
370 #define DO_FULL_QUAD 1
371
372 #define HAVE_RGBA 1
373 #define HAVE_SPEC 1
374 #define HAVE_BACK_COLORS 0
375 #define HAVE_HW_FLATSHADE 1
376 #define TAB rast_tab
377
378 #define DEPTH_SCALE 1.0
379 #define UNFILLED_TRI unfilled_tri
380 #define UNFILLED_QUAD unfilled_quad
381 #define VERT_X(_v) _v->v.x
382 #define VERT_Y(_v) _v->v.y
383 #define VERT_Z(_v) _v->v.z
384 #define AREA_IS_CCW( a ) (a < 0)
385 #define GET_VERTEX(e) (rmesa->radeon.swtcl.verts + (e*rmesa->radeon.swtcl.vertex_size*sizeof(int)))
386
387 #define VERT_SET_RGBA( v, c ) \
388 do { \
389 r300_color_t *color = (r300_color_t *)&((v)->ui[coloroffset]); \
390 UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]); \
391 UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]); \
392 UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]); \
393 UNCLAMPED_FLOAT_TO_UBYTE(color->alpha, (c)[3]); \
394 } while (0)
395
396 #define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
397
398 #define VERT_SET_SPEC( v0, c ) \
399 do { \
400 if (specoffset) { \
401 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.red, (c)[0]); \
402 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.green, (c)[1]); \
403 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.blue, (c)[2]); \
404 } \
405 } while (0)
406
407 #define VERT_COPY_SPEC( v0, v1 ) \
408 do { \
409 if (specoffset) { \
410 v0->v.specular.red = v1->v.specular.red; \
411 v0->v.specular.green = v1->v.specular.green; \
412 v0->v.specular.blue = v1->v.specular.blue; \
413 } \
414 } while (0)
415
416 #define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[coloroffset]
417 #define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx]
418 #define VERT_SAVE_SPEC( idx ) if (specoffset) spec[idx] = v[idx]->ui[specoffset]
419 #define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->ui[specoffset] = spec[idx]
420
421 #undef LOCAL_VARS
422 #undef TAG
423 #undef INIT
424
425 #define LOCAL_VARS(n) \
426 r300ContextPtr rmesa = R300_CONTEXT(ctx); \
427 GLuint color[n] = { 0, }, spec[n] = { 0, }; \
428 GLuint coloroffset = rmesa->swtcl.coloroffset; \
429 GLuint specoffset = rmesa->swtcl.specoffset; \
430 (void) color; (void) spec; (void) coloroffset; (void) specoffset;
431
432 /***********************************************************************
433 * Helpers for rendering unfilled primitives *
434 ***********************************************************************/
435
436 #define RASTERIZE(x) r300RasterPrimitive( ctx, reduced_prim[x] )
437 #define RENDER_PRIMITIVE rmesa->radeon.swtcl.render_primitive
438 #undef TAG
439 #define TAG(x) x
440 #include "tnl_dd/t_dd_unfilled.h"
441 #undef IND
442
443
444 /***********************************************************************
445 * Generate GL render functions *
446 ***********************************************************************/
447
448
449 #define IND (0)
450 #define TAG(x) x
451 #include "tnl_dd/t_dd_tritmp.h"
452
453 #define IND (R300_TWOSIDE_BIT)
454 #define TAG(x) x##_twoside
455 #include "tnl_dd/t_dd_tritmp.h"
456
457 #define IND (R300_UNFILLED_BIT)
458 #define TAG(x) x##_unfilled
459 #include "tnl_dd/t_dd_tritmp.h"
460
461 #define IND (R300_TWOSIDE_BIT|R300_UNFILLED_BIT)
462 #define TAG(x) x##_twoside_unfilled
463 #include "tnl_dd/t_dd_tritmp.h"
464
465
466
467 static void init_rast_tab( void )
468 {
469 init();
470 init_twoside();
471 init_unfilled();
472 init_twoside_unfilled();
473 }
474
475 /**********************************************************************/
476 /* Render unclipped begin/end objects */
477 /**********************************************************************/
478
479 #define RENDER_POINTS( start, count ) \
480 for ( ; start < count ; start++) \
481 r300_point( rmesa, VERT(start) )
482 #define RENDER_LINE( v0, v1 ) \
483 r300_line( rmesa, VERT(v0), VERT(v1) )
484 #define RENDER_TRI( v0, v1, v2 ) \
485 r300_triangle( rmesa, VERT(v0), VERT(v1), VERT(v2) )
486 #define RENDER_QUAD( v0, v1, v2, v3 ) \
487 r300_quad( rmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) )
488 #define INIT(x) do { \
489 r300RenderPrimitive( ctx, x ); \
490 } while (0)
491 #undef LOCAL_VARS
492 #define LOCAL_VARS \
493 r300ContextPtr rmesa = R300_CONTEXT(ctx); \
494 const GLuint vertsize = rmesa->radeon.swtcl.vertex_size; \
495 const char *r300verts = (char *)rmesa->radeon.swtcl.verts; \
496 const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
497 const GLboolean stipple = ctx->Line.StippleFlag; \
498 (void) elt; (void) stipple;
499 #define RESET_STIPPLE //if ( stipple ) r200ResetLineStipple( ctx );
500 #define RESET_OCCLUSION
501 #define PRESERVE_VB_DEFS
502 #define ELT(x) (x)
503 #define TAG(x) r300_##x##_verts
504 #include "tnl/t_vb_rendertmp.h"
505 #undef ELT
506 #undef TAG
507 #define TAG(x) r300_##x##_elts
508 #define ELT(x) elt[x]
509 #include "tnl/t_vb_rendertmp.h"
510
511
512
513
514 /**********************************************************************/
515 /* Choose render functions */
516 /**********************************************************************/
517 static void r300ChooseRenderState( GLcontext *ctx )
518 {
519 TNLcontext *tnl = TNL_CONTEXT(ctx);
520 r300ContextPtr rmesa = R300_CONTEXT(ctx);
521 GLuint index = 0;
522 GLuint flags = ctx->_TriangleCaps;
523
524 if (flags & DD_TRI_LIGHT_TWOSIDE) index |= R300_TWOSIDE_BIT;
525 if (flags & DD_TRI_UNFILLED) index |= R300_UNFILLED_BIT;
526
527 if (index != rmesa->radeon.swtcl.RenderIndex) {
528 tnl->Driver.Render.Points = rast_tab[index].points;
529 tnl->Driver.Render.Line = rast_tab[index].line;
530 tnl->Driver.Render.ClippedLine = rast_tab[index].line;
531 tnl->Driver.Render.Triangle = rast_tab[index].triangle;
532 tnl->Driver.Render.Quad = rast_tab[index].quad;
533
534 if (index == 0) {
535 tnl->Driver.Render.PrimTabVerts = r300_render_tab_verts;
536 tnl->Driver.Render.PrimTabElts = r300_render_tab_elts;
537 tnl->Driver.Render.ClippedPolygon = r300_fast_clipped_poly;
538 } else {
539 tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
540 tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
541 tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon;
542 }
543
544 rmesa->radeon.swtcl.RenderIndex = index;
545 }
546 }
547
548
549 static void r300RenderStart(GLcontext *ctx)
550 {
551 r300ContextPtr rmesa = R300_CONTEXT( ctx );
552
553 r300ChooseRenderState(ctx);
554 r300SetVertexFormat(ctx);
555
556 r300ValidateBuffers(ctx);
557
558 r300UpdateShaders(rmesa);
559 r300UpdateShaderStates(rmesa);
560
561 r300EmitCacheFlush(rmesa);
562
563 /* investigate if we can put back flush optimisation if needed */
564 if (rmesa->radeon.dma.flush != NULL) {
565 rmesa->radeon.dma.flush(ctx);
566 }
567 }
568
569 static void r300RenderFinish(GLcontext *ctx)
570 {
571 }
572
573 static void r300RasterPrimitive( GLcontext *ctx, GLuint hwprim )
574 {
575 r300ContextPtr rmesa = R300_CONTEXT(ctx);
576
577 if (rmesa->radeon.swtcl.hw_primitive != hwprim) {
578 R300_NEWPRIM( rmesa );
579 rmesa->radeon.swtcl.hw_primitive = hwprim;
580 }
581 }
582
583 static void r300RenderPrimitive(GLcontext *ctx, GLenum prim)
584 {
585
586 r300ContextPtr rmesa = R300_CONTEXT(ctx);
587 rmesa->radeon.swtcl.render_primitive = prim;
588
589 if ((prim == GL_TRIANGLES) && (ctx->_TriangleCaps & DD_TRI_UNFILLED))
590 return;
591
592 r300RasterPrimitive( ctx, reduced_prim[prim] );
593 }
594
595 static void r300ResetLineStipple(GLcontext *ctx)
596 {
597 }
598
599 void r300InitSwtcl(GLcontext *ctx)
600 {
601 TNLcontext *tnl = TNL_CONTEXT(ctx);
602 r300ContextPtr rmesa = R300_CONTEXT(ctx);
603 static int firsttime = 1;
604
605 if (firsttime) {
606 init_rast_tab();
607 firsttime = 0;
608 }
609
610 tnl->Driver.Render.Start = r300RenderStart;
611 tnl->Driver.Render.Finish = r300RenderFinish;
612 tnl->Driver.Render.PrimitiveNotify = r300RenderPrimitive;
613 tnl->Driver.Render.ResetLineStipple = r300ResetLineStipple;
614 tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
615 tnl->Driver.Render.CopyPV = _tnl_copy_pv;
616 tnl->Driver.Render.Interp = _tnl_interp;
617
618 /* FIXME: what are these numbers? */
619 _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12,
620 48 * sizeof(GLfloat) );
621
622 rmesa->radeon.swtcl.verts = (GLubyte *)tnl->clipspace.vertex_buf;
623 rmesa->radeon.swtcl.RenderIndex = ~0;
624 rmesa->radeon.swtcl.render_primitive = GL_TRIANGLES;
625 rmesa->radeon.swtcl.hw_primitive = 0;
626
627 _tnl_invalidate_vertex_state( ctx, ~0 );
628 _tnl_invalidate_vertices( ctx, ~0 );
629
630 _tnl_need_projected_coords( ctx, GL_FALSE );
631 r300ChooseRenderState(ctx);
632 }
633
634 void r300DestroySwtcl(GLcontext *ctx)
635 {
636 }
637
638 static void r300EmitVertexAOS(r300ContextPtr rmesa, GLuint vertex_size, struct radeon_bo *bo, GLuint offset)
639 {
640 BATCH_LOCALS(&rmesa->radeon);
641
642 if (RADEON_DEBUG & DEBUG_VERTS)
643 fprintf(stderr, "%s: vertex_size %d, offset 0x%x \n",
644 __FUNCTION__, vertex_size, offset);
645
646 BEGIN_BATCH(7);
647 OUT_BATCH_PACKET3(R300_PACKET3_3D_LOAD_VBPNTR, 2);
648 OUT_BATCH(1);
649 OUT_BATCH(vertex_size | (vertex_size << 8));
650 OUT_BATCH_RELOC(offset, bo, offset, RADEON_GEM_DOMAIN_GTT, 0, 0);
651 END_BATCH();
652 }
653
654 static void r300EmitVbufPrim(r300ContextPtr rmesa, GLuint primitive, GLuint vertex_nr)
655 {
656 BATCH_LOCALS(&rmesa->radeon);
657 int type, num_verts;
658
659 type = r300PrimitiveType(rmesa, primitive);
660 num_verts = r300NumVerts(rmesa, vertex_nr, primitive);
661
662 BEGIN_BATCH(3);
663 OUT_BATCH_PACKET3(R300_PACKET3_3D_DRAW_VBUF_2, 0);
664 OUT_BATCH(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (num_verts << 16) | type);
665 END_BATCH();
666 }
667
668 void r300_swtcl_flush(GLcontext *ctx, uint32_t current_offset)
669 {
670 r300ContextPtr rmesa = R300_CONTEXT(ctx);
671
672 rcommonEnsureCmdBufSpace(&rmesa->radeon,
673 rmesa->radeon.hw.max_state_size + (12*sizeof(int)),
674 __FUNCTION__);
675 radeonEmitState(&rmesa->radeon);
676 r300EmitVertexAOS(rmesa,
677 rmesa->radeon.swtcl.vertex_size,
678 rmesa->radeon.dma.current,
679 current_offset);
680
681 r300EmitVbufPrim(rmesa,
682 rmesa->radeon.swtcl.hw_primitive,
683 rmesa->radeon.swtcl.numverts);
684 r300EmitCacheFlush(rmesa);
685 COMMIT_BATCH();
686 }