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