8f74007faa905cec544d6a45fb5f876ac4e6d102
[mesa.git] / src / mesa / drivers / dri / r300 / r300_render.c
1 /**************************************************************************
2
3 Copyright (C) 2004 Nicolai Haehnle.
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 ATI, VA LINUX SYSTEMS AND/OR THEIR 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 * Nicolai Haehnle <prefect_@gmx.net>
31 */
32
33 #include "glheader.h"
34 #include "state.h"
35 #include "imports.h"
36 #include "enums.h"
37 #include "macros.h"
38 #include "context.h"
39 #include "dd.h"
40 #include "simple_list.h"
41
42 #include "api_arrayelt.h"
43 #include "swrast/swrast.h"
44 #include "swrast_setup/swrast_setup.h"
45 #include "array_cache/acache.h"
46 #include "tnl/tnl.h"
47 #include "tnl/t_vp_build.h"
48
49 #include "radeon_reg.h"
50 #include "radeon_macros.h"
51 #include "radeon_ioctl.h"
52 #include "radeon_state.h"
53 #include "r300_context.h"
54 #include "r300_ioctl.h"
55 #include "r300_state.h"
56 #include "r300_reg.h"
57 #include "r300_program.h"
58 #include "r300_tex.h"
59 #include "r300_maos.h"
60 #include "r300_emit.h"
61
62 extern int future_hw_tcl_on;
63
64 /**********************************************************************
65 * Hardware rasterization
66 *
67 * When we fell back to software TCL, we still try to use the
68 * rasterization hardware for rendering.
69 **********************************************************************/
70
71 static int r300_get_primitive_type(r300ContextPtr rmesa, GLcontext *ctx, int prim)
72 {
73 TNLcontext *tnl = TNL_CONTEXT(ctx);
74 struct vertex_buffer *VB = &tnl->vb;
75 GLuint i;
76 int type=-1;
77
78 switch (prim & PRIM_MODE_MASK) {
79 case GL_POINTS:
80 type=R300_VAP_VF_CNTL__PRIM_POINTS;
81 break;
82 case GL_LINES:
83 type=R300_VAP_VF_CNTL__PRIM_LINES;
84 break;
85 case GL_LINE_STRIP:
86 type=R300_VAP_VF_CNTL__PRIM_LINE_STRIP;
87 break;
88 case GL_LINE_LOOP:
89 type=R300_VAP_VF_CNTL__PRIM_LINE_LOOP;
90 break;
91 case GL_TRIANGLES:
92 type=R300_VAP_VF_CNTL__PRIM_TRIANGLES;
93 break;
94 case GL_TRIANGLE_STRIP:
95 type=R300_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP;
96 break;
97 case GL_TRIANGLE_FAN:
98 type=R300_VAP_VF_CNTL__PRIM_TRIANGLE_FAN;
99 break;
100 case GL_QUADS:
101 type=R300_VAP_VF_CNTL__PRIM_QUADS;
102 break;
103 case GL_QUAD_STRIP:
104 type=R300_VAP_VF_CNTL__PRIM_QUAD_STRIP;
105 break;
106 case GL_POLYGON:
107 type=R300_VAP_VF_CNTL__PRIM_POLYGON;
108 break;
109 default:
110 fprintf(stderr, "%s:%s Do not know how to handle primitive %02x - help me !\n",
111 __FILE__, __FUNCTION__,
112 prim & PRIM_MODE_MASK);
113 return -1;
114 break;
115 }
116 return type;
117 }
118
119 static int r300_get_num_verts(r300ContextPtr rmesa,
120 GLcontext *ctx,
121 int num_verts,
122 int prim)
123 {
124 TNLcontext *tnl = TNL_CONTEXT(ctx);
125 struct vertex_buffer *VB = &tnl->vb;
126 GLuint i;
127 int type=-1, verts_off=0;
128 char *name="UNKNOWN";
129
130 switch (prim & PRIM_MODE_MASK) {
131 case GL_POINTS:
132 name="P";
133 verts_off = 0;
134 break;
135 case GL_LINES:
136 name="L";
137 verts_off = num_verts % 2;
138 break;
139 case GL_LINE_STRIP:
140 name="LS";
141 if(num_verts < 2)
142 verts_off = num_verts;
143 break;
144 case GL_LINE_LOOP:
145 name="LL";
146 if(num_verts < 2)
147 verts_off = num_verts;
148 break;
149 case GL_TRIANGLES:
150 name="T";
151 verts_off = num_verts % 3;
152 break;
153 case GL_TRIANGLE_STRIP:
154 name="TS";
155 if(num_verts < 3)
156 verts_off = num_verts;
157 break;
158 case GL_TRIANGLE_FAN:
159 name="TF";
160 if(num_verts < 3)
161 verts_off = num_verts;
162 break;
163 case GL_QUADS:
164 name="Q";
165 verts_off = num_verts % 4;
166 break;
167 case GL_QUAD_STRIP:
168 name="QS";
169 if(num_verts < 4)
170 verts_off = num_verts;
171 else
172 verts_off = num_verts % 2;
173 break;
174 case GL_POLYGON:
175 name="P";
176 if(num_verts < 3)
177 verts_off = num_verts;
178 break;
179 default:
180 fprintf(stderr, "%s:%s Do not know how to handle primitive %02x - help me !\n",
181 __FILE__, __FUNCTION__,
182 prim & PRIM_MODE_MASK);
183 return -1;
184 break;
185 }
186
187 if(num_verts - verts_off == 0){
188 WARN_ONCE("user error: Need more than %d vertices to draw primitive %s !\n", num_verts, name);
189 return 0;
190 }
191
192 if(verts_off > 0){
193 WARN_ONCE("user error: %d is not a valid number of vertices for primitive %s !\n", num_verts, name);
194 }
195
196 return num_verts - verts_off;
197 }
198
199 /* This function compiles GL context into state registers that
200 describe data routing inside of R300 pipeline.
201
202 In particular, it programs input_route, output_vtx_fmt, texture
203 unit configuration and gb_output_vtx_fmt
204
205 This function encompasses setup_AOS() from r300_lib.c
206 */
207
208
209
210
211 /* Immediate implementation - vertex data is sent via command stream */
212
213 static GLfloat default_vector[4]={0.0, 0.0, 0.0, 1.0};
214
215 #define output_vector(v, i) { \
216 int _i; \
217 for(_i=0;_i<v->size;_i++){ \
218 if(VB->Elts){ \
219 efloat(VEC_ELT(v, GLfloat, VB->Elts[i])[_i]); \
220 }else{ \
221 efloat(VEC_ELT(v, GLfloat, i)[_i]); \
222 } \
223 } \
224 for(_i=v->size;_i<4;_i++){ \
225 efloat(default_vector[_i]); \
226 } \
227 }
228
229 /* Immediate implementation - vertex data is sent via command stream */
230
231 static void r300_render_immediate_primitive(r300ContextPtr rmesa,
232 GLcontext *ctx,
233 int start,
234 int end,
235 int prim)
236 {
237 TNLcontext *tnl = TNL_CONTEXT(ctx);
238 struct vertex_buffer *VB = &tnl->vb;
239 GLuint i, render_inputs;
240 int k, type, num_verts;
241 LOCAL_VARS
242
243 type=r300_get_primitive_type(rmesa, ctx, prim);
244 num_verts=r300_get_num_verts(rmesa, ctx, end-start, prim);
245
246 #if 0
247 fprintf(stderr,"ObjPtr: size=%d stride=%d\n",
248 VB->ObjPtr->size, VB->ObjPtr->stride);
249 fprintf(stderr,"ColorPtr[0]: size=%d stride=%d\n",
250 VB->ColorPtr[0]->size, VB->ColorPtr[0]->stride);
251 fprintf(stderr,"TexCoordPtr[0]: size=%d stride=%d\n",
252 VB->TexCoordPtr[0]->size, VB->TexCoordPtr[0]->stride);
253 #endif
254
255 if(type<0 || num_verts <= 0)return;
256
257 if(!VB->ObjPtr){
258 WARN_ONCE("FIXME: Don't know how to handle GL_ARB_vertex_buffer_object correctly\n");
259 return;
260 }
261 /* A packet cannot have more than 16383 data words.. */
262 if((num_verts*4*rmesa->state.aos_count)>16380){
263 WARN_ONCE("Too many vertices to paint. Fix me !\n");
264 return;
265 }
266
267 //fprintf(stderr, "aos_count=%d start=%d end=%d\n", rmesa->state.aos_count, start, end);
268
269 if(rmesa->state.aos_count==0){
270 WARN_ONCE("Aeiee ! aos_count==0, while it shouldn't. Skipping rendering\n");
271 return;
272 }
273
274 render_inputs = rmesa->state.render_inputs;
275
276 if(!render_inputs){
277 WARN_ONCE("Aeiee ! render_inputs==0. Skipping rendering.\n");
278 return;
279 }
280
281
282 start_immediate_packet(num_verts, type, 4*rmesa->state.aos_count);
283
284 for(i=start;i<start+num_verts;i++){
285 #if 0
286 fprintf(stderr, "* (%f %f %f %f) (%f %f %f %f)\n",
287 VEC_ELT(VB->ObjPtr, GLfloat, i)[0],
288 VEC_ELT(VB->ObjPtr, GLfloat, i)[1],
289 VEC_ELT(VB->ObjPtr, GLfloat, i)[2],
290 VEC_ELT(VB->ObjPtr, GLfloat, i)[3],
291
292 VEC_ELT(VB->ColorPtr[0], GLfloat, i)[0],
293 VEC_ELT(VB->ColorPtr[0], GLfloat, i)[1],
294 VEC_ELT(VB->ColorPtr[0], GLfloat, i)[2],
295 VEC_ELT(VB->ColorPtr[0], GLfloat, i)[3]
296 );
297 #endif
298
299
300 /* coordinates */
301 if(render_inputs & _TNL_BIT_POS)
302 output_vector(VB->ObjPtr, i);
303 if(render_inputs & _TNL_BIT_NORMAL)
304 output_vector(VB->NormalPtr, i);
305
306 /* color components */
307 if(render_inputs & _TNL_BIT_COLOR0)
308 output_vector(VB->ColorPtr[0], i);
309 if(render_inputs & _TNL_BIT_COLOR1)
310 output_vector(VB->SecondaryColorPtr[0], i);
311
312 /* if(render_inputs & _TNL_BIT_FOG) // Causes lock ups when immediate mode is on
313 output_vector(VB->FogCoordPtr, i);*/
314
315 /* texture coordinates */
316 for(k=0;k < ctx->Const.MaxTextureUnits;k++)
317 if(render_inputs & (_TNL_BIT_TEX0<<k))
318 output_vector(VB->TexCoordPtr[k], i);
319
320 if(render_inputs & _TNL_BIT_INDEX)
321 output_vector(VB->IndexPtr[0], i);
322 if(render_inputs & _TNL_BIT_POINTSIZE)
323 output_vector(VB->PointSizePtr, i);
324 }
325
326 }
327
328
329 static GLboolean r300_run_immediate_render(GLcontext *ctx,
330 struct tnl_pipeline_stage *stage)
331 {
332 r300ContextPtr rmesa = R300_CONTEXT(ctx);
333 TNLcontext *tnl = TNL_CONTEXT(ctx);
334 struct vertex_buffer *VB = &tnl->vb;
335 GLuint i;
336 /* Only do 2d textures */
337 struct gl_texture_object *to=ctx->Texture.Unit[0].Current2D;
338 r300TexObjPtr t=to->DriverData;
339 LOCAL_VARS
340
341
342 /* Update texture state - needs to be done only when actually changed..
343 All the time for now.. */
344
345
346 if (RADEON_DEBUG == DEBUG_PRIMS)
347 fprintf(stderr, "%s\n", __FUNCTION__);
348
349 #if 1 /* we need this, somehow */
350 /* Flush state - make sure command buffer is nice and large */
351 r300Flush(ctx);
352 /* Make sure we have enough space */
353 #else
354 /* Count is very imprecize, but should be good upper bound */
355 r300EnsureCmdBufSpace(rmesa, rmesa->hw.max_state_size + 4+2+30
356 +VB->PrimitiveCount*(1+8)+VB->Count*4*rmesa->state.texture.tc_count+4, __FUNCTION__);
357 #endif
358
359 /* needed before starting 3d operation .. */
360 reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
361 e32(0x0000000a);
362
363 reg_start(0x4f18,0);
364 e32(0x00000003);
365
366
367 #if 0 /* looks like the Z offset issue got fixed */
368 rmesa->hw.vte.cmd[1] = R300_VPORT_X_SCALE_ENA
369 | R300_VPORT_X_OFFSET_ENA
370 | R300_VPORT_Y_SCALE_ENA
371 | R300_VPORT_Y_OFFSET_ENA
372 | R300_VTX_W0_FMT;
373 R300_STATECHANGE(rmesa, vte);
374 #endif
375
376
377
378 /* Magic register - note it is right after 20b0 */
379
380
381 if(rmesa->state.texture.tc_count>0){
382 reg_start(0x20b4,0);
383 e32(0x0000000c);
384
385 }
386
387 r300EmitState(rmesa);
388
389 /* Setup INPUT_ROUTE and INPUT_CNTL */
390 r300EmitArrays(ctx, GL_TRUE);
391
392 /* Why do we need this for immediate mode?? Vertex processor needs it to know proper regs */
393 // r300EmitLOAD_VBPNTR(rmesa, 0);
394 /* Okay, it seems I misunderstood something, EmitAOS does the same thing */
395 r300EmitAOS(rmesa, rmesa->state.aos_count, 0);
396
397 for(i=0; i < VB->PrimitiveCount; i++){
398 GLuint prim = VB->Primitive[i].mode;
399 GLuint start = VB->Primitive[i].start;
400 GLuint length = VB->Primitive[i].count;
401
402 r300_render_immediate_primitive(rmesa, ctx, start, start + length, prim);
403 }
404
405 /* This sequence is required after any 3d drawing packet
406 I suspect it work arounds a bug (or deficiency) in hardware */
407
408 reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
409 e32(0x0000000a);
410
411 reg_start(0x4f18,0);
412 e32(0x00000003);
413
414 return GL_FALSE;
415 }
416
417
418 /* vertex buffer implementation */
419
420 static void inline fire_EB(PREFIX unsigned long addr, int vertex_count, int type, int elt_size)
421 {
422 LOCAL_VARS
423 unsigned long addr_a;
424 unsigned long t_addr;
425 unsigned long magic_1, magic_2;
426 GLcontext *ctx;
427 ctx = rmesa->radeon.glCtx;
428
429 assert(elt_size == 2 || elt_size == 4);
430
431 if(addr & (elt_size-1)){
432 WARN_ONCE("Badly aligned buffer\n");
433 return ;
434 }
435 #ifdef OPTIMIZE_ELTS
436 addr_a = 0;
437
438 magic_1 = (addr % 32) / 4;
439 t_addr = addr & (~0x1d);
440 magic_2 = (vertex_count + 1 + (t_addr & 0x2)) / 2 + magic_1;
441
442 check_space(6);
443
444 start_packet3(RADEON_CP_PACKET3_3D_DRAW_INDX_2, 0);
445 if(elt_size == 4){
446 e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (vertex_count<<16) | type | R300_VAP_VF_CNTL__INDEX_SIZE_32bit);
447 } else {
448 e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (vertex_count<<16) | type);
449 }
450
451 start_packet3(RADEON_CP_PACKET3_INDX_BUFFER, 2);
452 if(elt_size == 4){
453 e32(R300_EB_UNK1 | (0 << 16) | R300_EB_UNK2);
454 e32(addr /*& 0xffffffe3*/);
455 } else {
456 e32(R300_EB_UNK1 | (magic_1 << 16) | R300_EB_UNK2);
457 e32(t_addr);
458 }
459
460 if(elt_size == 4){
461 e32(vertex_count /*+ addr_a/4*/); /* Total number of dwords needed? */
462 } else {
463 e32(magic_2); /* Total number of dwords needed? */
464 }
465 //cp_delay(PASS_PREFIX 1);
466 #if 0
467 fprintf(stderr, "magic_1 %d\n", magic_1);
468 fprintf(stderr, "t_addr %x\n", t_addr);
469 fprintf(stderr, "magic_2 %d\n", magic_2);
470 exit(1);
471 #endif
472 #else
473 addr_a = 0;
474
475 check_space(6);
476
477 start_packet3(RADEON_CP_PACKET3_3D_DRAW_INDX_2, 0);
478 if(elt_size == 4){
479 e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (vertex_count<<16) | type | R300_VAP_VF_CNTL__INDEX_SIZE_32bit);
480 } else {
481 e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (vertex_count<<16) | type);
482 }
483
484 start_packet3(RADEON_CP_PACKET3_INDX_BUFFER, 2);
485 e32(R300_EB_UNK1 | (0 << 16) | R300_EB_UNK2);
486 e32(addr /*& 0xffffffe3*/);
487
488 if(elt_size == 4){
489 e32(vertex_count /*+ addr_a/4*/); /* Total number of dwords needed? */
490 } else {
491 e32((vertex_count+1)/2 /*+ addr_a/4*/); /* Total number of dwords needed? */
492 }
493 //cp_delay(PASS_PREFIX 1);
494 #endif
495 }
496
497 static void r300_render_vb_primitive(r300ContextPtr rmesa,
498 GLcontext *ctx,
499 int start,
500 int end,
501 int prim)
502 {
503 int type, num_verts;
504 radeonScreenPtr rsp=rmesa->radeon.radeonScreen;
505 LOCAL_VARS
506 TNLcontext *tnl = TNL_CONTEXT(ctx);
507 struct vertex_buffer *VB = &tnl->vb;
508 int i;
509
510 type=r300_get_primitive_type(rmesa, ctx, prim);
511 num_verts=r300_get_num_verts(rmesa, ctx, end-start, prim);
512
513 if(type<0 || num_verts <= 0)return;
514
515 if(rmesa->state.Elts){
516 r300EmitAOS(rmesa, rmesa->state.aos_count, 0);
517 #if 0
518 start_index32_packet(num_verts, type);
519 for(i=0; i < num_verts; i++)
520 e32(rmesa->state.Elts[start+i]); /* start ? */
521 #else
522 WARN_ONCE("Rendering with elt buffers\n");
523 if(num_verts == 1){
524 start_index32_packet(num_verts, type);
525 e32(rmesa->state.Elts[start]);
526 return;
527 }
528
529 if(num_verts > 65535){ /* not implemented yet */
530 WARN_ONCE("Too many elts\n");
531 return;
532 }
533 r300EmitElts(ctx, rmesa->state.Elts+start, num_verts, 4);
534 fire_EB(PASS_PREFIX GET_START(&(rmesa->state.elt_dma)), num_verts, type, 4);
535 #endif
536 }else{
537 r300EmitAOS(rmesa, rmesa->state.aos_count, start);
538 fire_AOS(PASS_PREFIX num_verts, type);
539 }
540 }
541
542 static GLboolean r300_run_vb_render(GLcontext *ctx,
543 struct tnl_pipeline_stage *stage)
544 {
545 r300ContextPtr rmesa = R300_CONTEXT(ctx);
546 TNLcontext *tnl = TNL_CONTEXT(ctx);
547 struct vertex_buffer *VB = &tnl->vb;
548 int i, j;
549 LOCAL_VARS
550
551 if (RADEON_DEBUG & DEBUG_PRIMS)
552 fprintf(stderr, "%s\n", __FUNCTION__);
553
554
555 r300ReleaseArrays(ctx);
556 r300EmitArrays(ctx, GL_FALSE);
557
558 // LOCK_HARDWARE(&(rmesa->radeon));
559
560 reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
561 e32(0x0000000a);
562
563 reg_start(0x4f18,0);
564 e32(0x00000003);
565 r300EmitState(rmesa);
566
567 rmesa->state.Elts = VB->Elts;
568
569 for(i=0; i < VB->PrimitiveCount; i++){
570 GLuint prim = VB->Primitive[i].mode;
571 GLuint start = VB->Primitive[i].start;
572 GLuint length = VB->Primitive[i].count;
573
574 r300_render_vb_primitive(rmesa, ctx, start, start + length, prim);
575 }
576
577 reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
578 e32(0x0000000a);
579
580 reg_start(0x4f18,0);
581 e32(0x00000003);
582
583 #ifdef USER_BUFFERS
584 r300UseArrays(ctx);
585 #endif
586 // end_3d(PASS_PREFIX_VOID);
587
588 /* Flush state - we are done drawing.. */
589 // r300FlushCmdBufLocked(rmesa, __FUNCTION__);
590 // radeonWaitForIdleLocked(&(rmesa->radeon));
591
592 // UNLOCK_HARDWARE(&(rmesa->radeon));
593 return GL_FALSE;
594 }
595
596 #ifdef RADEON_VTXFMT_A
597
598 static void r300_render_vb_primitive_vtxfmt_a(r300ContextPtr rmesa,
599 GLcontext *ctx,
600 int start,
601 int end,
602 int prim)
603 {
604 int type, num_verts;
605 radeonScreenPtr rsp=rmesa->radeon.radeonScreen;
606 LOCAL_VARS
607 TNLcontext *tnl = TNL_CONTEXT(ctx);
608 struct vertex_buffer *VB = &tnl->vb;
609 int i;
610
611 type=r300_get_primitive_type(rmesa, ctx, prim);
612 num_verts=r300_get_num_verts(rmesa, ctx, end-start, prim);
613
614 if(type<0 || num_verts <= 0)return;
615
616 if(rmesa->state.VB.Elts){
617 r300EmitAOS(rmesa, rmesa->state.aos_count, /*0*/start);
618 #if 0
619 start_index32_packet(num_verts, type);
620 for(i=0; i < num_verts; i++)
621 e32(((unsigned long *)rmesa->state.VB.Elts)[i]/*rmesa->state.Elts[start+i]*/); /* start ? */
622 #else
623 WARN_ONCE("Rendering with elt buffers\n");
624 if(num_verts == 1){
625 //start_index32_packet(num_verts, type);
626 //e32(rmesa->state.Elts[start]);
627 return;
628 }
629
630 if(num_verts > 65535){ /* not implemented yet */
631 WARN_ONCE("Too many elts\n");
632 return;
633 }
634
635 r300EmitElts(ctx, rmesa->state.VB.Elts, num_verts, rmesa->state.VB.elt_size);
636 fire_EB(PASS_PREFIX rmesa->state.elt_dma.aos_offset, num_verts, type, rmesa->state.VB.elt_size);
637 #endif
638 }else{
639 r300EmitAOS(rmesa, rmesa->state.aos_count, start);
640 fire_AOS(PASS_PREFIX num_verts, type);
641 }
642 }
643
644 void dump_array(struct r300_dma_region *rvb, int count)
645 {
646 int *out = (int *)(rvb->address + rvb->start);
647 int i, ci;
648
649 for (i=0; i < count; i++) {
650 fprintf(stderr, "{");
651 if (rvb->aos_format == AOS_FORMAT_FLOAT)
652 for (ci=0; ci < rvb->aos_size; ci++)
653 fprintf(stderr, "%f ", ((float *)out)[ci]);
654 else
655 for (ci=0; ci < rvb->aos_size; ci++)
656 fprintf(stderr, "%d ", ((unsigned char *)out)[ci]);
657 fprintf(stderr, "}");
658
659 out += rvb->aos_stride;
660 }
661
662 fprintf(stderr, "\n");
663 }
664
665 void dump_dt(struct dt *dt, int count)
666 {
667 int *out = dt->data;
668 int i, ci;
669
670 fprintf(stderr, "base at %p ", out);
671
672 for (i=0; i < count; i++){
673 fprintf(stderr, "{");
674 if (dt->type == GL_FLOAT)
675 for (ci=0; ci < dt->size; ci++)
676 fprintf(stderr, "%f ", ((float *)out)[ci]);
677 else
678 for (ci=0; ci < dt->size; ci++)
679 fprintf(stderr, "%d ", ((unsigned char *)out)[ci]);
680 fprintf(stderr, "}");
681
682 out = (char *)out + dt->stride;
683 }
684
685 fprintf(stderr, "\n");
686 }
687
688 /*static */GLboolean r300_run_vb_render_vtxfmt_a(GLcontext *ctx,
689 struct tnl_pipeline_stage *stage)
690 {
691 r300ContextPtr rmesa = R300_CONTEXT(ctx);
692 //TNLcontext *tnl = TNL_CONTEXT(ctx);
693 struct radeon_vertex_buffer *VB = &rmesa->state.VB; //&tnl->vb;
694 int i, j;
695 LOCAL_VARS
696
697 if (RADEON_DEBUG & DEBUG_PRIMS)
698 fprintf(stderr, "%s\n", __FUNCTION__);
699
700 if (rmesa->state.VB.LockCount == 0) {
701 r300ReleaseArrays(ctx);
702 r300EmitArraysVtx(ctx, GL_FALSE);
703 } else {
704 /* TODO: Figure out why do we need these. */
705 R300_STATECHANGE(rmesa, vir[0]);
706 R300_STATECHANGE(rmesa, vir[1]);
707 R300_STATECHANGE(rmesa, vic);
708 R300_STATECHANGE(rmesa, vof);
709
710 #if 0
711 fprintf(stderr, "dt:\n");
712 for(i=0; i < VERT_ATTRIB_MAX; i++){
713 fprintf(stderr, "dt %d:", i);
714 dump_dt(&rmesa->state.VB.AttribPtr[i], VB->Count);
715 }
716
717 fprintf(stderr, "before:\n");
718 for(i=0; i < rmesa->state.aos_count; i++){
719 fprintf(stderr, "aos %d:", i);
720 dump_array(&rmesa->state.aos[i], VB->Count);
721 }
722 #endif
723 #if 0
724 r300ReleaseArrays(ctx);
725 r300EmitArraysVtx(ctx, GL_FALSE);
726
727 fprintf(stderr, "after:\n");
728 for(i=0; i < rmesa->state.aos_count; i++){
729 fprintf(stderr, "aos %d:", i);
730 dump_array(&rmesa->state.aos[i], VB->Count);
731 }
732 #endif
733 }
734
735 // LOCK_HARDWARE(&(rmesa->radeon));
736
737 reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
738 e32(0x0000000a);
739
740 reg_start(0x4f18,0);
741 e32(0x00000003);
742 #if 0
743 reg_start(R300_VAP_PVS_WAITIDLE,0);
744 e32(0x00000000);
745 #endif
746 r300EmitState(rmesa);
747
748 for(i=0; i < VB->PrimitiveCount; i++){
749 GLuint prim = VB->Primitive[i].mode;
750 GLuint start = VB->Primitive[i].start;
751 GLuint length = VB->Primitive[i].count;
752
753 r300_render_vb_primitive_vtxfmt_a(rmesa, ctx, start, start + length, prim);
754 }
755
756 reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
757 e32(0x0000000a/*0x2*/);
758
759 reg_start(0x4f18,0);
760 e32(0x00000003/*0x1*/);
761
762 #ifdef USER_BUFFERS
763 r300UseArrays(ctx);
764 #endif
765 // end_3d(PASS_PREFIX_VOID);
766
767 /* Flush state - we are done drawing.. */
768 // r300FlushCmdBufLocked(rmesa, __FUNCTION__);
769 // radeonWaitForIdleLocked(&(rmesa->radeon));
770
771 // UNLOCK_HARDWARE(&(rmesa->radeon));
772 return GL_FALSE;
773 }
774 #endif
775
776 /**
777 * Called by the pipeline manager to render a batch of primitives.
778 * We can return true to pass on to the next stage (i.e. software
779 * rasterization) or false to indicate that the pipeline has finished
780 * after we render something.
781 */
782 static GLboolean r300_run_render(GLcontext *ctx,
783 struct tnl_pipeline_stage *stage)
784 {
785 r300ContextPtr rmesa = R300_CONTEXT(ctx);
786 TNLcontext *tnl = TNL_CONTEXT(ctx);
787 struct vertex_buffer *VB = &tnl->vb;
788 GLuint i;
789
790 if (RADEON_DEBUG & DEBUG_PRIMS)
791 fprintf(stderr, "%s\n", __FUNCTION__);
792
793
794 #if 1
795
796 #if 0
797 return r300_run_immediate_render(ctx, stage);
798 #else
799 return r300_run_vb_render(ctx, stage);
800 #endif
801 #else
802 return GL_TRUE;
803 #endif
804 }
805
806
807 /**
808 * Called by the pipeline manager once before rendering.
809 * We check the GL state here to
810 * a) decide whether we can do the current state in hardware and
811 * b) update hardware registers
812 */
813 #define FALLBACK_IF(expr) \
814 do { \
815 if (expr) { \
816 if (1 || RADEON_DEBUG & DEBUG_FALLBACKS) \
817 fprintf(stderr, "%s: fallback:%s\n", \
818 __FUNCTION__, #expr); \
819 /*stage->active = GL_FALSE*/; \
820 return; \
821 } \
822 } while(0)
823
824 static void r300_check_render(GLcontext *ctx, struct tnl_pipeline_stage *stage)
825 {
826 r300ContextPtr r300 = R300_CONTEXT(ctx);
827 int i;
828
829 if (RADEON_DEBUG & DEBUG_STATE)
830 fprintf(stderr, "%s\n", __FUNCTION__);
831
832 /* We only support rendering in hardware for now */
833 if (ctx->RenderMode != GL_RENDER) {
834 //stage->active = GL_FALSE;
835 return;
836 }
837
838
839 /* I'm almost certain I forgot something here */
840 #if 0 /* These should work now.. */
841 FALLBACK_IF(ctx->Color.DitherFlag);
842 FALLBACK_IF(ctx->Color.AlphaEnabled); // GL_ALPHA_TEST
843 FALLBACK_IF(ctx->Color.BlendEnabled); // GL_BLEND
844 FALLBACK_IF(ctx->Polygon.OffsetFill); // GL_POLYGON_OFFSET_FILL
845 #endif
846 //FALLBACK_IF(ctx->Polygon.OffsetPoint); // GL_POLYGON_OFFSET_POINT
847 //FALLBACK_IF(ctx->Polygon.OffsetLine); // GL_POLYGON_OFFSET_LINE
848 //FALLBACK_IF(ctx->Stencil.Enabled); // GL_STENCIL_TEST
849
850 //FALLBACK_IF(ctx->Fog.Enabled); // GL_FOG disable as swtcl doesnt seem to support this
851 //FALLBACK_IF(ctx->Polygon.SmoothFlag); // GL_POLYGON_SMOOTH disabling to get blender going
852 FALLBACK_IF(ctx->Polygon.StippleFlag); // GL_POLYGON_STIPPLE
853 FALLBACK_IF(ctx->Multisample.Enabled); // GL_MULTISAMPLE_ARB
854
855 FALLBACK_IF(ctx->RenderMode != GL_RENDER); // We do not do SELECT or FEEDBACK (yet ?)
856
857 #if 0 /* ut2k3 fails to start if this is on */
858 /* One step at a time - let one texture pass.. */
859 for (i = 1; i < ctx->Const.MaxTextureUnits; i++)
860 FALLBACK_IF(ctx->Texture.Unit[i].Enabled);
861 #endif
862
863 /* Assumed factor reg is found but pattern is still missing */
864 //FALLBACK_IF(ctx->Line.StippleFlag); // GL_LINE_STIPPLE disabling to get blender going
865
866 /* HW doesnt appear to directly support these */
867 //FALLBACK_IF(ctx->Line.SmoothFlag); // GL_LINE_SMOOTH disabling to get blender going
868 FALLBACK_IF(ctx->Point.SmoothFlag); // GL_POINT_SMOOTH
869 /* Rest could be done with vertex fragments */
870 if (ctx->Extensions.NV_point_sprite || ctx->Extensions.ARB_point_sprite)
871 FALLBACK_IF(ctx->Point.PointSprite); // GL_POINT_SPRITE_NV
872 //GL_POINT_DISTANCE_ATTENUATION_ARB
873 //GL_POINT_FADE_THRESHOLD_SIZE_ARB
874
875 /* let r300_run_render do its job */
876 #if 0
877 stage->active = GL_FALSE;
878 #endif
879 }
880
881
882 static void dtr(struct tnl_pipeline_stage *stage)
883 {
884 (void)stage;
885 }
886
887 static GLboolean r300_create_render(GLcontext *ctx,
888 struct tnl_pipeline_stage *stage)
889 {
890 return GL_TRUE;
891 }
892
893
894 const struct tnl_pipeline_stage _r300_render_stage = {
895 "r300 hw rasterize",
896 NULL,
897 r300_create_render,
898 dtr, /* destructor */
899 r300_check_render, /* check */
900 r300_run_render /* run */
901 };
902
903 static GLboolean r300_run_tcl_render(GLcontext *ctx,
904 struct tnl_pipeline_stage *stage)
905 {
906 r300ContextPtr rmesa = R300_CONTEXT(ctx);
907 TNLcontext *tnl = TNL_CONTEXT(ctx);
908 struct vertex_buffer *VB = &tnl->vb;
909 GLuint i;
910 struct r300_vertex_program *vp;
911
912 hw_tcl_on=future_hw_tcl_on;
913
914 if (RADEON_DEBUG & DEBUG_PRIMS)
915 fprintf(stderr, "%s\n", __FUNCTION__);
916 if(hw_tcl_on == GL_FALSE)
917 return GL_TRUE;
918
919 r300UpdateShaderStates(rmesa);
920
921 return r300_run_vb_render(ctx, stage);
922 }
923
924 static void r300_check_tcl_render(GLcontext *ctx, struct tnl_pipeline_stage *stage)
925 {
926 r300ContextPtr r300 = R300_CONTEXT(ctx);
927 int i;
928
929 if (RADEON_DEBUG & DEBUG_STATE)
930 fprintf(stderr, "%s\n", __FUNCTION__);
931
932 /* We only support rendering in hardware for now */
933 if (ctx->RenderMode != GL_RENDER) {
934 //stage->active = GL_FALSE;
935 return;
936 }
937 }
938
939 const struct tnl_pipeline_stage _r300_tcl_stage = {
940 "r300 tcl",
941 NULL,
942 r300_create_render,
943 dtr, /* destructor */
944 r300_check_tcl_render, /* check */
945 r300_run_tcl_render /* run */
946 };