slang: initialize the context
[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 */
32
33 /* derived from r200 swtcl path */
34
35
36
37 #include "main/glheader.h"
38 #include "main/mtypes.h"
39 #include "main/colormac.h"
40 #include "main/enums.h"
41 #include "main/image.h"
42 #include "main/imports.h"
43 #include "main/light.h"
44 #include "main/macros.h"
45
46 #include "swrast/s_context.h"
47 #include "swrast/s_fog.h"
48 #include "swrast_setup/swrast_setup.h"
49 #include "math/m_translate.h"
50 #include "tnl/tnl.h"
51 #include "tnl/t_context.h"
52 #include "tnl/t_pipeline.h"
53
54 #include "r300_context.h"
55 #include "r300_swtcl.h"
56 #include "r300_state.h"
57 #include "r300_ioctl.h"
58 #include "r300_emit.h"
59 #include "r300_mem.h"
60
61 static void flush_last_swtcl_prim( r300ContextPtr rmesa );
62
63
64 void r300EmitVertexAOS(r300ContextPtr rmesa, GLuint vertex_size, GLuint offset);
65 void r300EmitVbufPrim(r300ContextPtr rmesa, GLuint primitive, GLuint vertex_nr);
66 #define EMIT_ATTR( ATTR, STYLE ) \
67 do { \
68 rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].attrib = (ATTR); \
69 rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].format = (STYLE); \
70 rmesa->swtcl.vertex_attr_count++; \
71 } while (0)
72
73 #define EMIT_PAD( N ) \
74 do { \
75 rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].attrib = 0; \
76 rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].format = EMIT_PAD; \
77 rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].offset = (N); \
78 rmesa->swtcl.vertex_attr_count++; \
79 } while (0)
80
81 static void r300SetVertexFormat( GLcontext *ctx )
82 {
83 r300ContextPtr rmesa = R300_CONTEXT( ctx );
84 TNLcontext *tnl = TNL_CONTEXT(ctx);
85 struct vertex_buffer *VB = &tnl->vb;
86 DECLARE_RENDERINPUTS(index_bitset);
87 GLuint InputsRead = 0, OutputsWritten = 0;
88 int vap_fmt_1 = 0;
89 int offset = 0;
90 int vte = 0;
91 int fog_id;
92 GLint inputs[VERT_ATTRIB_MAX];
93 GLint tab[VERT_ATTRIB_MAX];
94 int swizzle[VERT_ATTRIB_MAX][4];
95 GLuint i, nr;
96 GLuint sz;
97
98 DECLARE_RENDERINPUTS(render_inputs_bitset);
99 RENDERINPUTS_COPY(render_inputs_bitset, tnl->render_inputs_bitset);
100 RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset );
101 RENDERINPUTS_COPY(rmesa->state.render_inputs_bitset, render_inputs_bitset);
102
103 vte = rmesa->hw.vte.cmd[1];
104 vte &= ~(R300_VTX_XY_FMT | R300_VTX_Z_FMT | R300_VTX_W0_FMT);
105 /* Important:
106 */
107 if ( VB->NdcPtr != NULL ) {
108 VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
109 vte |= R300_VTX_XY_FMT | R300_VTX_Z_FMT;
110 }
111 else {
112 VB->AttribPtr[VERT_ATTRIB_POS] = VB->ClipPtr;
113 vte |= R300_VTX_W0_FMT;
114 }
115
116 assert( VB->AttribPtr[VERT_ATTRIB_POS] != NULL );
117 rmesa->swtcl.vertex_attr_count = 0;
118
119 /* EMIT_ATTR's must be in order as they tell t_vertex.c how to
120 * build up a hardware vertex.
121 */
122 if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_POS)) {
123 sz = VB->AttribPtr[VERT_ATTRIB_POS]->size;
124 InputsRead |= 1 << VERT_ATTRIB_POS;
125 OutputsWritten |= 1 << VERT_RESULT_HPOS;
126 EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_1F + sz - 1 );
127 offset = sz;
128 } else {
129 offset = 4;
130 EMIT_PAD(4 * sizeof(float));
131 }
132 /*
133 if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_POINTSIZE )) {
134 EMIT_ATTR( _TNL_ATTRIB_POINTSIZE, EMIT_1F );
135 offset += 1;
136 }
137 */
138 if (RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_COLOR0)) {
139 sz = VB->AttribPtr[VERT_ATTRIB_COLOR0]->size;
140 rmesa->swtcl.coloroffset = offset;
141 InputsRead |= 1 << VERT_ATTRIB_COLOR0;
142 OutputsWritten |= 1 << VERT_RESULT_COL0;
143 EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_1F + sz - 1 );
144 offset += sz;
145 }
146
147 rmesa->swtcl.specoffset = 0;
148 if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) {
149 sz = VB->AttribPtr[VERT_ATTRIB_COLOR1]->size;
150 rmesa->swtcl.specoffset = offset;
151 EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_1F + sz - 1 );
152 InputsRead |= 1 << VERT_ATTRIB_COLOR1;
153 OutputsWritten |= 1 << VERT_RESULT_COL1;
154 }
155
156 fog_id = -1;
157 if (RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_FOG)) {
158 /* find first free tex coord slot */
159 if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) {
160 int i;
161 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
162 if (!RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX(i) )) {
163 fog_id = i;
164 break;
165 }
166 }
167 } else {
168 fog_id = 0;
169 }
170
171 if (fog_id == -1) {
172 fprintf(stderr, "\tout of free texcoords to do fog\n");
173 _mesa_exit(-1);
174 }
175
176 sz = VB->AttribPtr[VERT_ATTRIB_FOG]->size;
177 EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1F + sz - 1);
178 InputsRead |= 1 << VERT_ATTRIB_FOG;
179 OutputsWritten |= 1 << VERT_RESULT_FOGC;
180 vap_fmt_1 |= sz << (3 * fog_id);
181 }
182
183 if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) {
184 int i;
185
186 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
187 if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX(i) )) {
188 sz = VB->TexCoordPtr[i]->size;
189 InputsRead |= 1 << (VERT_ATTRIB_TEX0 + i);
190 OutputsWritten |= 1 << (VERT_RESULT_TEX0 + i);
191 EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_1F + sz - 1 );
192 vap_fmt_1 |= sz << (3 * i);
193 }
194 }
195 }
196
197 /* RS can't put fragment position on the pixel stack, so stuff it in texcoord if needed */
198 if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_POS) && (ctx->FragmentProgram._Current->Base.InputsRead & FRAG_BIT_WPOS)) {
199 int first_free_tex = -1;
200 if (fog_id >= 0) {
201 first_free_tex = fog_id+1;
202 } else {
203 if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) {
204 int i;
205 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
206 if (!RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX(i) )) {
207 first_free_tex = i;
208 break;
209 }
210 }
211 } else {
212 first_free_tex = 0;
213 }
214 }
215
216 if (first_free_tex == -1) {
217 fprintf(stderr, "\tout of free texcoords to write w pos\n");
218 _mesa_exit(-1);
219 }
220
221 sz = VB->AttribPtr[VERT_ATTRIB_POS]->size;
222 InputsRead |= 1 << (VERT_ATTRIB_TEX0 + first_free_tex);
223 OutputsWritten |= 1 << (VERT_RESULT_TEX0 + first_free_tex);
224 EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_1F + sz - 1 );
225 vap_fmt_1 |= sz << (3 * first_free_tex);
226 }
227
228 for (i = 0, nr = 0; i < VERT_ATTRIB_MAX; i++) {
229 if (InputsRead & (1 << i)) {
230 inputs[i] = nr++;
231 } else {
232 inputs[i] = -1;
233 }
234 }
235
236 /* Fixed, apply to vir0 only */
237 if (InputsRead & (1 << VERT_ATTRIB_POS))
238 inputs[VERT_ATTRIB_POS] = 0;
239 if (InputsRead & (1 << VERT_ATTRIB_COLOR0))
240 inputs[VERT_ATTRIB_COLOR0] = 2;
241 if (InputsRead & (1 << VERT_ATTRIB_COLOR1))
242 inputs[VERT_ATTRIB_COLOR1] = 3;
243 if (InputsRead & (1 << VERT_ATTRIB_FOG))
244 inputs[VERT_ATTRIB_FOG] = 6 + fog_id;
245 for (i = VERT_ATTRIB_TEX0; i <= VERT_ATTRIB_TEX7; i++)
246 if (InputsRead & (1 << i))
247 inputs[i] = 6 + (i - VERT_ATTRIB_TEX0);
248
249 for (i = 0, nr = 0; i < VERT_ATTRIB_MAX; i++) {
250 if (InputsRead & (1 << i)) {
251 tab[nr++] = i;
252 }
253 }
254
255 for (i = 0; i < nr; i++) {
256 int ci;
257
258 swizzle[i][0] = SWIZZLE_ZERO;
259 swizzle[i][1] = SWIZZLE_ZERO;
260 swizzle[i][2] = SWIZZLE_ZERO;
261 swizzle[i][3] = SWIZZLE_ONE;
262
263 for (ci = 0; ci < VB->AttribPtr[tab[i]]->size; ci++) {
264 swizzle[i][ci] = ci;
265 }
266 }
267
268 R300_NEWPRIM(rmesa);
269 R300_STATECHANGE(rmesa, vir[0]);
270 ((drm_r300_cmd_header_t *) rmesa->hw.vir[0].cmd)->packet0.count =
271 r300VAPInputRoute0(&rmesa->hw.vir[0].cmd[R300_VIR_CNTL_0],
272 VB->AttribPtr, inputs, tab, nr);
273 R300_STATECHANGE(rmesa, vir[1]);
274 ((drm_r300_cmd_header_t *) rmesa->hw.vir[1].cmd)->packet0.count =
275 r300VAPInputRoute1(&rmesa->hw.vir[1].cmd[R300_VIR_CNTL_0], swizzle,
276 nr);
277
278 R300_STATECHANGE(rmesa, vic);
279 rmesa->hw.vic.cmd[R300_VIC_CNTL_0] = r300VAPInputCntl0(ctx, InputsRead);
280 rmesa->hw.vic.cmd[R300_VIC_CNTL_1] = r300VAPInputCntl1(ctx, InputsRead);
281
282 R300_STATECHANGE(rmesa, vof);
283 rmesa->hw.vof.cmd[R300_VOF_CNTL_0] = r300VAPOutputCntl0(ctx, OutputsWritten);
284 rmesa->hw.vof.cmd[R300_VOF_CNTL_1] = vap_fmt_1;
285
286 rmesa->swtcl.vertex_size =
287 _tnl_install_attrs( ctx,
288 rmesa->swtcl.vertex_attrs,
289 rmesa->swtcl.vertex_attr_count,
290 NULL, 0 );
291
292 rmesa->swtcl.vertex_size /= 4;
293
294 RENDERINPUTS_COPY( rmesa->tnl_index_bitset, index_bitset );
295
296
297 R300_STATECHANGE(rmesa, vte);
298 rmesa->hw.vte.cmd[1] = vte;
299 rmesa->hw.vte.cmd[2] = rmesa->swtcl.vertex_size;
300 }
301
302
303 /* Flush vertices in the current dma region.
304 */
305 static void flush_last_swtcl_prim( r300ContextPtr rmesa )
306 {
307 if (RADEON_DEBUG & DEBUG_IOCTL)
308 fprintf(stderr, "%s\n", __FUNCTION__);
309
310 rmesa->dma.flush = NULL;
311
312 if (rmesa->dma.current.buf) {
313 struct r300_dma_region *current = &rmesa->dma.current;
314 GLuint current_offset = GET_START(current);
315
316 assert (current->start +
317 rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 ==
318 current->ptr);
319
320 if (rmesa->dma.current.start != rmesa->dma.current.ptr) {
321
322 r300EnsureCmdBufSpace( rmesa, rmesa->hw.max_state_size + (12*sizeof(int)), __FUNCTION__);
323
324 r300EmitState(rmesa);
325
326 r300EmitVertexAOS( rmesa,
327 rmesa->swtcl.vertex_size,
328 current_offset);
329
330 r300EmitVbufPrim( rmesa,
331 rmesa->swtcl.hw_primitive,
332 rmesa->swtcl.numverts);
333
334 r300EmitCacheFlush(rmesa);
335 }
336
337 rmesa->swtcl.numverts = 0;
338 current->start = current->ptr;
339 }
340 }
341
342 /* Alloc space in the current dma region.
343 */
344 static void *
345 r300AllocDmaLowVerts( r300ContextPtr rmesa, int nverts, int vsize )
346 {
347 GLuint bytes = vsize * nverts;
348
349 if ( rmesa->dma.current.ptr + bytes > rmesa->dma.current.end )
350 r300RefillCurrentDmaRegion( rmesa, bytes);
351
352 if (!rmesa->dma.flush) {
353 rmesa->radeon.glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
354 rmesa->dma.flush = flush_last_swtcl_prim;
355 }
356
357 ASSERT( vsize == rmesa->swtcl.vertex_size * 4 );
358 ASSERT( rmesa->dma.flush == flush_last_swtcl_prim );
359 ASSERT( rmesa->dma.current.start +
360 rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 ==
361 rmesa->dma.current.ptr );
362
363 {
364 GLubyte *head = (GLubyte *) (rmesa->dma.current.address + rmesa->dma.current.ptr);
365 rmesa->dma.current.ptr += bytes;
366 rmesa->swtcl.numverts += nverts;
367 return head;
368 }
369 }
370
371 static GLuint reduced_prim[] = {
372 GL_POINTS,
373 GL_LINES,
374 GL_LINES,
375 GL_LINES,
376 GL_TRIANGLES,
377 GL_TRIANGLES,
378 GL_TRIANGLES,
379 GL_TRIANGLES,
380 GL_TRIANGLES,
381 GL_TRIANGLES,
382 };
383
384 static void r300RasterPrimitive( GLcontext *ctx, GLuint prim );
385 static void r300RenderPrimitive( GLcontext *ctx, GLenum prim );
386 //static void r300ResetLineStipple( GLcontext *ctx );
387
388 /***********************************************************************
389 * Emit primitives as inline vertices *
390 ***********************************************************************/
391
392
393 #define HAVE_POINTS 1
394 #define HAVE_LINES 1
395 #define HAVE_LINE_STRIPS 1
396 #define HAVE_TRIANGLES 1
397 #define HAVE_TRI_STRIPS 1
398 #define HAVE_TRI_STRIP_1 0
399 #define HAVE_TRI_FANS 1
400 #define HAVE_QUADS 0
401 #define HAVE_QUAD_STRIPS 0
402 #define HAVE_POLYGONS 1
403 #define HAVE_ELTS 1
404
405 #undef LOCAL_VARS
406 #undef ALLOC_VERTS
407 #define CTX_ARG r300ContextPtr rmesa
408 #define GET_VERTEX_DWORDS() rmesa->swtcl.vertex_size
409 #define ALLOC_VERTS( n, size ) r300AllocDmaLowVerts( rmesa, n, size * 4 )
410 #define LOCAL_VARS \
411 r300ContextPtr rmesa = R300_CONTEXT(ctx); \
412 const char *r300verts = (char *)rmesa->swtcl.verts;
413 #define VERT(x) (r300Vertex *)(r300verts + ((x) * vertsize * sizeof(int)))
414 #define VERTEX r300Vertex
415 #define DO_DEBUG_VERTS (1 && (RADEON_DEBUG & DEBUG_VERTS))
416 #define PRINT_VERTEX(x)
417 #undef TAG
418 #define TAG(x) r300_##x
419 #include "tnl_dd/t_dd_triemit.h"
420
421
422
423 /***********************************************************************
424 * Macros for t_dd_tritmp.h to draw basic primitives *
425 ***********************************************************************/
426
427 #define QUAD( a, b, c, d ) r300_quad( rmesa, a, b, c, d )
428 #define TRI( a, b, c ) r300_triangle( rmesa, a, b, c )
429 #define LINE( a, b ) r300_line( rmesa, a, b )
430 #define POINT( a ) r300_point( rmesa, a )
431
432 /***********************************************************************
433 * Build render functions from dd templates *
434 ***********************************************************************/
435
436 #define R300_TWOSIDE_BIT 0x01
437 #define R300_UNFILLED_BIT 0x02
438 #define R300_MAX_TRIFUNC 0x04
439
440 static struct {
441 tnl_points_func points;
442 tnl_line_func line;
443 tnl_triangle_func triangle;
444 tnl_quad_func quad;
445 } rast_tab[R300_MAX_TRIFUNC];
446
447 #define DO_FALLBACK 0
448 #define DO_UNFILLED (IND & R300_UNFILLED_BIT)
449 #define DO_TWOSIDE (IND & R300_TWOSIDE_BIT)
450 #define DO_FLAT 0
451 #define DO_OFFSET 0
452 #define DO_TRI 1
453 #define DO_QUAD 1
454 #define DO_LINE 1
455 #define DO_POINTS 1
456 #define DO_FULL_QUAD 1
457
458 #define HAVE_RGBA 1
459 #define HAVE_SPEC 1
460 #define HAVE_BACK_COLORS 0
461 #define HAVE_HW_FLATSHADE 1
462 #define TAB rast_tab
463
464 #define DEPTH_SCALE 1.0
465 #define UNFILLED_TRI unfilled_tri
466 #define UNFILLED_QUAD unfilled_quad
467 #define VERT_X(_v) _v->v.x
468 #define VERT_Y(_v) _v->v.y
469 #define VERT_Z(_v) _v->v.z
470 #define AREA_IS_CCW( a ) (a < 0)
471 #define GET_VERTEX(e) (rmesa->swtcl.verts + (e*rmesa->swtcl.vertex_size*sizeof(int)))
472
473 /* Only used to pull back colors into vertices (ie, we know color is
474 * floating point).
475 */
476 #define R300_COLOR( dst, src ) \
477 do { \
478 UNCLAMPED_FLOAT_TO_UBYTE((dst)[0], (src)[2]); \
479 UNCLAMPED_FLOAT_TO_UBYTE((dst)[1], (src)[1]); \
480 UNCLAMPED_FLOAT_TO_UBYTE((dst)[2], (src)[0]); \
481 UNCLAMPED_FLOAT_TO_UBYTE((dst)[3], (src)[3]); \
482 } while (0)
483
484 #define VERT_SET_RGBA( v, c ) if (coloroffset) R300_COLOR( v->ub4[coloroffset], c )
485 #define VERT_COPY_RGBA( v0, v1 ) if (coloroffset) v0->ui[coloroffset] = v1->ui[coloroffset]
486 #define VERT_SAVE_RGBA( idx ) if (coloroffset) color[idx] = v[idx]->ui[coloroffset]
487 #define VERT_RESTORE_RGBA( idx ) if (coloroffset) v[idx]->ui[coloroffset] = color[idx]
488
489 #define R300_SPEC( dst, src ) \
490 do { \
491 UNCLAMPED_FLOAT_TO_UBYTE((dst)[0], (src)[2]); \
492 UNCLAMPED_FLOAT_TO_UBYTE((dst)[1], (src)[1]); \
493 UNCLAMPED_FLOAT_TO_UBYTE((dst)[2], (src)[0]); \
494 } while (0)
495
496 #define VERT_SET_SPEC( v, c ) if (specoffset) R300_SPEC( v->ub4[specoffset], c )
497 #define VERT_COPY_SPEC( v0, v1 ) if (specoffset) COPY_3V(v0->ub4[specoffset], v1->ub4[specoffset])
498 #define VERT_SAVE_SPEC( idx ) if (specoffset) spec[idx] = v[idx]->ui[specoffset]
499 #define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->ui[specoffset] = spec[idx]
500
501 #undef LOCAL_VARS
502 #undef TAG
503 #undef INIT
504
505 #define LOCAL_VARS(n) \
506 r300ContextPtr rmesa = R300_CONTEXT(ctx); \
507 GLuint color[n], spec[n]; \
508 GLuint coloroffset = rmesa->swtcl.coloroffset; \
509 GLuint specoffset = rmesa->swtcl.specoffset; \
510 (void) color; (void) spec; (void) coloroffset; (void) specoffset;
511
512 /***********************************************************************
513 * Helpers for rendering unfilled primitives *
514 ***********************************************************************/
515
516 #define RASTERIZE(x) r300RasterPrimitive( ctx, reduced_prim[x] )
517 #define RENDER_PRIMITIVE rmesa->swtcl.render_primitive
518 #undef TAG
519 #define TAG(x) x
520 #include "tnl_dd/t_dd_unfilled.h"
521 #undef IND
522
523
524 /***********************************************************************
525 * Generate GL render functions *
526 ***********************************************************************/
527
528
529 #define IND (0)
530 #define TAG(x) x
531 #include "tnl_dd/t_dd_tritmp.h"
532
533 #define IND (R300_TWOSIDE_BIT)
534 #define TAG(x) x##_twoside
535 #include "tnl_dd/t_dd_tritmp.h"
536
537 #define IND (R300_UNFILLED_BIT)
538 #define TAG(x) x##_unfilled
539 #include "tnl_dd/t_dd_tritmp.h"
540
541 #define IND (R300_TWOSIDE_BIT|R300_UNFILLED_BIT)
542 #define TAG(x) x##_twoside_unfilled
543 #include "tnl_dd/t_dd_tritmp.h"
544
545
546
547 static void init_rast_tab( void )
548 {
549 init();
550 init_twoside();
551 init_unfilled();
552 init_twoside_unfilled();
553 }
554
555 /**********************************************************************/
556 /* Render unclipped begin/end objects */
557 /**********************************************************************/
558
559 #define RENDER_POINTS( start, count ) \
560 for ( ; start < count ; start++) \
561 r300_point( rmesa, VERT(start) )
562 #define RENDER_LINE( v0, v1 ) \
563 r300_line( rmesa, VERT(v0), VERT(v1) )
564 #define RENDER_TRI( v0, v1, v2 ) \
565 r300_triangle( rmesa, VERT(v0), VERT(v1), VERT(v2) )
566 #define RENDER_QUAD( v0, v1, v2, v3 ) \
567 r300_quad( rmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) )
568 #define INIT(x) do { \
569 r300RenderPrimitive( ctx, x ); \
570 } while (0)
571 #undef LOCAL_VARS
572 #define LOCAL_VARS \
573 r300ContextPtr rmesa = R300_CONTEXT(ctx); \
574 const GLuint vertsize = rmesa->swtcl.vertex_size; \
575 const char *r300verts = (char *)rmesa->swtcl.verts; \
576 const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
577 const GLboolean stipple = ctx->Line.StippleFlag; \
578 (void) elt; (void) stipple;
579 #define RESET_STIPPLE //if ( stipple ) r200ResetLineStipple( ctx );
580 #define RESET_OCCLUSION
581 #define PRESERVE_VB_DEFS
582 #define ELT(x) (x)
583 #define TAG(x) r300_##x##_verts
584 #include "tnl/t_vb_rendertmp.h"
585 #undef ELT
586 #undef TAG
587 #define TAG(x) r300_##x##_elts
588 #define ELT(x) elt[x]
589 #include "tnl/t_vb_rendertmp.h"
590
591
592
593
594 /**********************************************************************/
595 /* Choose render functions */
596 /**********************************************************************/
597 static void r300ChooseRenderState( GLcontext *ctx )
598 {
599 TNLcontext *tnl = TNL_CONTEXT(ctx);
600 r300ContextPtr rmesa = R300_CONTEXT(ctx);
601 GLuint index = 0;
602 GLuint flags = ctx->_TriangleCaps;
603
604 if (flags & DD_TRI_LIGHT_TWOSIDE) index |= R300_TWOSIDE_BIT;
605 if (flags & DD_TRI_UNFILLED) index |= R300_UNFILLED_BIT;
606
607 if (index != rmesa->swtcl.RenderIndex) {
608 tnl->Driver.Render.Points = rast_tab[index].points;
609 tnl->Driver.Render.Line = rast_tab[index].line;
610 tnl->Driver.Render.ClippedLine = rast_tab[index].line;
611 tnl->Driver.Render.Triangle = rast_tab[index].triangle;
612 tnl->Driver.Render.Quad = rast_tab[index].quad;
613
614 if (index == 0) {
615 tnl->Driver.Render.PrimTabVerts = r300_render_tab_verts;
616 tnl->Driver.Render.PrimTabElts = r300_render_tab_elts;
617 tnl->Driver.Render.ClippedPolygon = r300_fast_clipped_poly;
618 } else {
619 tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
620 tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
621 tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon;
622 }
623
624 rmesa->swtcl.RenderIndex = index;
625 }
626 }
627
628
629 static void r300RenderStart(GLcontext *ctx)
630 {
631 r300ContextPtr rmesa = R300_CONTEXT( ctx );
632 // fprintf(stderr, "%s\n", __FUNCTION__);
633
634 r300ChooseRenderState(ctx);
635 r300SetVertexFormat(ctx);
636
637 r300UpdateShaders(rmesa);
638 r300UpdateShaderStates(rmesa);
639
640 r300EmitCacheFlush(rmesa);
641
642 if (rmesa->dma.flush != 0 &&
643 rmesa->dma.flush != flush_last_swtcl_prim)
644 rmesa->dma.flush( rmesa );
645
646 }
647
648 static void r300RenderFinish(GLcontext *ctx)
649 {
650 }
651
652 static void r300RasterPrimitive( GLcontext *ctx, GLuint hwprim )
653 {
654 r300ContextPtr rmesa = R300_CONTEXT(ctx);
655
656 if (rmesa->swtcl.hw_primitive != hwprim) {
657 R300_NEWPRIM( rmesa );
658 rmesa->swtcl.hw_primitive = hwprim;
659 }
660 }
661
662 static void r300RenderPrimitive(GLcontext *ctx, GLenum prim)
663 {
664
665 r300ContextPtr rmesa = R300_CONTEXT(ctx);
666 rmesa->swtcl.render_primitive = prim;
667
668 if ((prim == GL_TRIANGLES) && (ctx->_TriangleCaps & DD_TRI_UNFILLED))
669 return;
670
671 r300RasterPrimitive( ctx, reduced_prim[prim] );
672 // fprintf(stderr, "%s\n", __FUNCTION__);
673
674 }
675
676 static void r300ResetLineStipple(GLcontext *ctx)
677 {
678
679
680 }
681
682 void r300InitSwtcl(GLcontext *ctx)
683 {
684 TNLcontext *tnl = TNL_CONTEXT(ctx);
685 r300ContextPtr rmesa = R300_CONTEXT(ctx);
686 static int firsttime = 1;
687
688 if (firsttime) {
689 init_rast_tab();
690 firsttime = 0;
691 }
692
693 tnl->Driver.Render.Start = r300RenderStart;
694 tnl->Driver.Render.Finish = r300RenderFinish;
695 tnl->Driver.Render.PrimitiveNotify = r300RenderPrimitive;
696 tnl->Driver.Render.ResetLineStipple = r300ResetLineStipple;
697 tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
698 tnl->Driver.Render.CopyPV = _tnl_copy_pv;
699 tnl->Driver.Render.Interp = _tnl_interp;
700
701 /* FIXME: what are these numbers? */
702 _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12,
703 48 * sizeof(GLfloat) );
704
705 rmesa->swtcl.verts = (GLubyte *)tnl->clipspace.vertex_buf;
706 rmesa->swtcl.RenderIndex = ~0;
707 rmesa->swtcl.render_primitive = GL_TRIANGLES;
708 rmesa->swtcl.hw_primitive = 0;
709
710 _tnl_invalidate_vertex_state( ctx, ~0 );
711 _tnl_invalidate_vertices( ctx, ~0 );
712 RENDERINPUTS_ZERO( rmesa->tnl_index_bitset );
713
714 _tnl_need_projected_coords( ctx, GL_FALSE );
715 r300ChooseRenderState(ctx);
716
717 _mesa_validate_all_lighting_tables( ctx );
718
719 tnl->Driver.NotifyMaterialChange =
720 _mesa_validate_all_lighting_tables;
721 }
722
723 void r300DestroySwtcl(GLcontext *ctx)
724 {
725 }
726
727 void r300EmitVertexAOS(r300ContextPtr rmesa, GLuint vertex_size, GLuint offset)
728 {
729 int cmd_reserved = 0;
730 int cmd_written = 0;
731
732 drm_radeon_cmd_header_t *cmd = NULL;
733 if (RADEON_DEBUG & DEBUG_VERTS)
734 fprintf(stderr, "%s: vertex_size %d, offset 0x%x \n",
735 __FUNCTION__, vertex_size, offset);
736
737 start_packet3(CP_PACKET3(R300_PACKET3_3D_LOAD_VBPNTR, 2), 2);
738 e32(1);
739 e32(vertex_size | (vertex_size << 8));
740 e32(offset);
741 }
742
743 void r300EmitVbufPrim(r300ContextPtr rmesa, GLuint primitive, GLuint vertex_nr)
744 {
745
746 int cmd_reserved = 0;
747 int cmd_written = 0;
748 int type, num_verts;
749 drm_radeon_cmd_header_t *cmd = NULL;
750
751 type = r300PrimitiveType(rmesa, primitive);
752 num_verts = r300NumVerts(rmesa, vertex_nr, primitive);
753
754 start_packet3(CP_PACKET3(R300_PACKET3_3D_DRAW_VBUF_2, 0), 0);
755 e32(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (num_verts << 16) | type);
756 }