Merge branch 'llvm-cliptest-viewport'
[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(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 }