b3793e28d58f2e6f33ef2a70d1f1217711a29891
[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 rmesa->swtcl.coloroffset = rmesa->swtcl.specoffset = 0;
84 rmesa->radeon.swtcl.vertex_attr_count = 0;
85
86 if (RADEON_DEBUG & DEBUG_VERTS)
87 fprintf(stderr, "%s\n", __func__);
88
89 /* We always want non Ndc coords format */
90 VB->AttribPtr[VERT_ATTRIB_POS] = VB->ClipPtr;
91
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;
98
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);
105 #else
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);
108 #endif
109 }
110
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);
118 #else
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);
121 #endif
122 rmesa->swtcl.specoffset = rmesa->swtcl.coloroffset + 1;
123 }
124
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);
131 #else
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);
134 #endif
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);
142 #else
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);
145 #endif
146 }
147 }
148
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);
155 }
156
157 if (rmesa->selected_fp->wpos_attr != FRAG_ATTRIB_MAX) {
158 int tex_id = rmesa->selected_fp->wpos_attr - FRAG_ATTRIB_TEX0;
159
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);
163 }
164
165 if (rmesa->selected_fp->fog_attr != FRAG_ATTRIB_MAX) {
166 int tex_id = rmesa->selected_fp->fog_attr - FRAG_ATTRIB_TEX0;
167
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);
171 }
172
173 /**
174 * Sending only one texcoord component may lead to lock up,
175 * so for all textures always output 4 texcoord components to RS.
176 */
177 {
178 int i;
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) {
183 case 1:
184 format = EMIT_1F;
185 hw_format = R300_DATA_TYPE_FLOAT_1;
186 swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ONE);
187 break;
188 case 2:
189 format = EMIT_2F;
190 hw_format = R300_DATA_TYPE_FLOAT_2;
191 swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ZERO, SWIZZLE_ONE);
192 break;
193 case 3:
194 format = EMIT_3F;
195 hw_format = R300_DATA_TYPE_FLOAT_3;
196 swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE);
197 break;
198 case 4:
199 format = EMIT_4F;
200 hw_format = R300_DATA_TYPE_FLOAT_4;
201 swiz = SWIZZLE_XYZW;
202 break;
203 default:
204 continue;
205 }
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);
210 ++first_free_tex;
211 }
212 }
213 }
214
215 if (first_free_tex >= ctx->Const.MaxTextureUnits) {
216 fprintf(stderr, "\tout of free texcoords to write fog coordinate\n");
217 _mesa_exit(-1);
218 }
219
220 R300_NEWPRIM(rmesa);
221 rmesa->vbuf.num_attribs = num_attrs;
222 *_InputsRead = InputsRead;
223 *_OutputsWritten = OutputsWritten;
224
225 RENDERINPUTS_COPY(rmesa->render_inputs_bitset, tnl->render_inputs_bitset);
226 }
227
228 static void r300PrepareVertices(GLcontext *ctx)
229 {
230 r300ContextPtr rmesa = R300_CONTEXT(ctx);
231 GLuint InputsRead, OutputsWritten;
232
233 r300ChooseSwtclVertexFormat(ctx, &InputsRead, &OutputsWritten);
234 r300SetupVAP(ctx, InputsRead, OutputsWritten);
235
236 rmesa->radeon.swtcl.vertex_size =
237 _tnl_install_attrs( ctx,
238 rmesa->radeon.swtcl.vertex_attrs,
239 rmesa->radeon.swtcl.vertex_attr_count,
240 NULL, 0 );
241
242 rmesa->radeon.swtcl.vertex_size /= 4;
243 }
244
245 static void r300_predict_emit_size( r300ContextPtr rmesa )
246 {
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);
254
255 if (rcommonEnsureCmdBufSpace(&rmesa->radeon,
256 state_size + pre_emit_state + scissor_size
257 + vertex_size + prim_size + cache_flush_size * 2,
258 __FUNCTION__))
259 rmesa->radeon.swtcl.emit_prediction = radeonCountStateEmitSize(&rmesa->radeon);
260 else
261 rmesa->radeon.swtcl.emit_prediction = state_size;
262
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;
265 }
266 }
267
268
269 static GLuint reduced_prim[] = {
270 GL_POINTS,
271 GL_LINES,
272 GL_LINES,
273 GL_LINES,
274 GL_TRIANGLES,
275 GL_TRIANGLES,
276 GL_TRIANGLES,
277 GL_TRIANGLES,
278 GL_TRIANGLES,
279 GL_TRIANGLES,
280 };
281
282 static void r300RasterPrimitive( GLcontext *ctx, GLuint prim );
283
284 /***********************************************************************
285 * Emit primitives as inline vertices *
286 ***********************************************************************/
287
288
289 #define HAVE_POINTS 1
290 #define HAVE_LINES 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
296 #define HAVE_QUADS 0
297 #define HAVE_QUAD_STRIPS 0
298 #define HAVE_POLYGONS 1
299 #define HAVE_ELTS 1
300
301 static void* r300_alloc_verts(r300ContextPtr rmesa, GLuint n, GLuint size)
302 {
303 void *rv;
304 do {
305 r300_predict_emit_size( rmesa );
306 rv = rcommonAllocDmaLowVerts( &rmesa->radeon, n, size * 4 );
307 } while (!rv);
308 return rv;
309 }
310
311 #undef LOCAL_VARS
312 #undef ALLOC_VERTS
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);
316 #define LOCAL_VARS \
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
321 #undef TAG
322 #define TAG(x) r300_##x
323 #include "tnl_dd/t_dd_triemit.h"
324
325
326
327 /***********************************************************************
328 * Macros for t_dd_tritmp.h to draw basic primitives *
329 ***********************************************************************/
330
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 )
335
336 /***********************************************************************
337 * Build render functions from dd templates *
338 ***********************************************************************/
339
340 #define R300_UNFILLED_BIT 0x01
341 #define R300_MAX_TRIFUNC 0x02
342
343 static struct {
344 tnl_points_func points;
345 tnl_line_func line;
346 tnl_triangle_func triangle;
347 tnl_quad_func quad;
348 } rast_tab[R300_MAX_TRIFUNC];
349
350 #define DO_FALLBACK 0
351 #define DO_UNFILLED (IND & R300_UNFILLED_BIT)
352 #define DO_TWOSIDE 0
353 #define DO_FLAT 0
354 #define DO_OFFSET 0
355 #define DO_TRI 1
356 #define DO_QUAD 1
357 #define DO_LINE 1
358 #define DO_POINTS 1
359 #define DO_FULL_QUAD 1
360
361 #define HAVE_RGBA 1
362 #define HAVE_SPEC 1
363 #define HAVE_BACK_COLORS 0
364 #define HAVE_HW_FLATSHADE 1
365 #define TAB rast_tab
366
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)))
375
376 #define VERT_SET_RGBA( v, c ) \
377 do { \
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]); \
383 } while (0)
384
385 #define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
386
387 #define VERT_SET_SPEC( v0, c ) \
388 do { \
389 if (specoffset) { \
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]); \
393 } \
394 } while (0)
395
396 #define VERT_COPY_SPEC( v0, v1 ) \
397 do { \
398 if (specoffset) { \
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; \
402 } \
403 } while (0)
404
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]
409
410 #undef LOCAL_VARS
411 #undef TAG
412 #undef INIT
413
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;
420
421 /***********************************************************************
422 * Helpers for rendering unfilled primitives *
423 ***********************************************************************/
424
425 #define RASTERIZE(x) r300RasterPrimitive( ctx, reduced_prim[x] )
426 #define RENDER_PRIMITIVE rmesa->radeon.swtcl.render_primitive
427 #undef TAG
428 #define TAG(x) x
429 #include "tnl_dd/t_dd_unfilled.h"
430 #undef IND
431
432
433 /***********************************************************************
434 * Generate GL render functions *
435 ***********************************************************************/
436
437
438 #define IND (0)
439 #define TAG(x) x
440 #include "tnl_dd/t_dd_tritmp.h"
441
442 #define IND (R300_UNFILLED_BIT)
443 #define TAG(x) x##_unfilled
444 #include "tnl_dd/t_dd_tritmp.h"
445
446
447 static void init_rast_tab( void )
448 {
449 init();
450 init_unfilled();
451 }
452
453 /**********************************************************************/
454 /* Render unclipped begin/end objects */
455 /**********************************************************************/
456
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 ); \
468 } while (0)
469 #undef LOCAL_VARS
470 #define LOCAL_VARS \
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
480 #define ELT(x) (x)
481 #define TAG(x) r300_##x##_verts
482 #include "tnl/t_vb_rendertmp.h"
483 #undef ELT
484 #undef TAG
485 #define TAG(x) r300_##x##_elts
486 #define ELT(x) elt[x]
487 #include "tnl/t_vb_rendertmp.h"
488
489
490
491
492 /**********************************************************************/
493 /* Choose render functions */
494 /**********************************************************************/
495 static void r300ChooseRenderState( GLcontext *ctx )
496 {
497 TNLcontext *tnl = TNL_CONTEXT(ctx);
498 r300ContextPtr rmesa = R300_CONTEXT(ctx);
499 GLuint index = 0;
500 GLuint flags = ctx->_TriangleCaps;
501 if (RADEON_DEBUG & DEBUG_VERTS)
502 fprintf(stderr, "%s\n", __func__);
503
504 if (flags & DD_TRI_UNFILLED) index |= R300_UNFILLED_BIT;
505
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;
512
513 if (index == 0) {
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;
517 } else {
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;
521 }
522
523 rmesa->radeon.swtcl.RenderIndex = index;
524 }
525 }
526
527 void r300RenderStart(GLcontext *ctx)
528 {
529 if (RADEON_DEBUG & DEBUG_VERTS)
530 fprintf(stderr, "%s\n", __func__);
531 r300ContextPtr rmesa = R300_CONTEXT( ctx );
532
533 r300ChooseRenderState(ctx);
534
535 r300UpdateShaders(rmesa);
536
537 r300PrepareVertices(ctx);
538
539 r300ValidateBuffers(ctx);
540
541 r300UpdateShaderStates(rmesa);
542
543
544 /* investigate if we can put back flush optimisation if needed */
545 if (rmesa->radeon.dma.flush != NULL) {
546 rmesa->radeon.dma.flush(ctx);
547 }
548 }
549
550 void r300RenderFinish(GLcontext *ctx)
551 {
552 }
553
554 static void r300RasterPrimitive( GLcontext *ctx, GLuint hwprim )
555 {
556 r300ContextPtr rmesa = R300_CONTEXT(ctx);
557 if (RADEON_DEBUG & DEBUG_VERTS)
558 fprintf(stderr, "%s\n", __func__);
559
560 if (rmesa->radeon.swtcl.hw_primitive != hwprim) {
561 R300_NEWPRIM( rmesa );
562 rmesa->radeon.swtcl.hw_primitive = hwprim;
563 }
564 }
565
566 void r300RenderPrimitive(GLcontext *ctx, GLenum prim)
567 {
568
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__);
573
574 if ((prim == GL_TRIANGLES) && (ctx->_TriangleCaps & DD_TRI_UNFILLED))
575 return;
576
577 r300RasterPrimitive( ctx, reduced_prim[prim] );
578 }
579
580 void r300ResetLineStipple(GLcontext *ctx)
581 {
582 if (RADEON_DEBUG & DEBUG_VERTS)
583 fprintf(stderr, "%s\n", __func__);
584 }
585
586 void r300InitSwtcl(GLcontext *ctx)
587 {
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__);
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(GLcontext *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 if (RADEON_DEBUG & DEBUG_VERTS)
632 fprintf(stderr, "%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 & DEBUG_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(GLcontext *ctx, uint32_t current_offset)
660 {
661 if (RADEON_DEBUG & DEBUG_VERTS)
662 fprintf(stderr, "%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 first_elem(&rmesa->radeon.dma.reserved)->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 }