342c529d42eca4a813458a2d57a2cf67ddbe202f
[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
48 #include "radeon_reg.h"
49 #include "radeon_macros.h"
50 #include "radeon_ioctl.h"
51 #include "radeon_state.h"
52 #include "r300_context.h"
53 #include "r300_ioctl.h"
54 #include "r300_state.h"
55 #include "r300_reg.h"
56 #include "r300_program.h"
57 #include "r300_tex.h"
58
59 #include "r300_emit.h"
60
61 /* Turns out we might not need this after all... */
62 void update_zbias(GLcontext * ctx, int prim)
63 {
64 r300ContextPtr rmesa = R300_CONTEXT(ctx);
65 int enabled = 0;
66 uint32_t values[4];
67 //return ;
68 switch(prim & PRIM_MODE_MASK) {
69 case GL_POINTS:
70 if(ctx->Polygon.OffsetPoint == GL_TRUE)
71 enabled=1;
72 break;
73 case GL_LINES:
74 case GL_LINE_STRIP:
75 case GL_LINE_LOOP:
76 if(ctx->Polygon.OffsetLine == GL_TRUE)
77 enabled=1;
78 break;
79 case GL_TRIANGLES:
80 case GL_TRIANGLE_STRIP:
81 case GL_TRIANGLE_FAN:
82 case GL_QUADS:
83 case GL_QUAD_STRIP:
84 case GL_POLYGON:
85 if(ctx->Polygon.OffsetFill == GL_TRUE)
86 enabled=1;
87 break;
88 default:
89 fprintf(stderr, "%s:%s Do not know how to handle primitive %02x - help me !\n",
90 __FILE__, __FUNCTION__,
91 prim & PRIM_MODE_MASK);
92
93 }
94
95 if(enabled){
96 values[0]=values[2]=r300PackFloat32(ctx->Polygon.OffsetFactor * 12.0);
97 values[1]=values[3]=r300PackFloat32(ctx->Polygon.OffsetUnits * 4.0);
98 }else{
99 values[0]=values[2]=r300PackFloat32(0.0);
100 values[1]=values[3]=r300PackFloat32(0.0);
101 }
102
103 if(values[0] != rmesa->hw.zbs.cmd[R300_ZBS_T_FACTOR] ||
104 values[1] != rmesa->hw.zbs.cmd[R300_ZBS_T_CONSTANT] ||
105 values[2] != rmesa->hw.zbs.cmd[R300_ZBS_W_FACTOR] ||
106 values[3] != rmesa->hw.zbs.cmd[R300_ZBS_W_CONSTANT]){
107
108 R300_STATECHANGE(rmesa, zbs);
109 rmesa->hw.zbs.cmd[R300_ZBS_T_FACTOR] = values[0];
110 rmesa->hw.zbs.cmd[R300_ZBS_T_CONSTANT] = values[1];
111 rmesa->hw.zbs.cmd[R300_ZBS_W_FACTOR] = values[2];
112 rmesa->hw.zbs.cmd[R300_ZBS_W_CONSTANT] = values[3];
113
114 }
115 }
116
117 /**********************************************************************
118 * Hardware rasterization
119 *
120 * When we fell back to software TCL, we still try to use the
121 * rasterization hardware for rendering.
122 **********************************************************************/
123
124 static int r300_get_primitive_type(r300ContextPtr rmesa, GLcontext *ctx, int prim)
125 {
126 TNLcontext *tnl = TNL_CONTEXT(ctx);
127 struct vertex_buffer *VB = &tnl->vb;
128 GLuint i;
129 int type=-1;
130
131 switch (prim & PRIM_MODE_MASK) {
132 case GL_POINTS:
133 type=R300_VAP_VF_CNTL__PRIM_POINTS;
134 break;
135 case GL_LINES:
136 type=R300_VAP_VF_CNTL__PRIM_LINES;
137 break;
138 case GL_LINE_STRIP:
139 type=R300_VAP_VF_CNTL__PRIM_LINE_STRIP;
140 break;
141 case GL_LINE_LOOP:
142 type=R300_VAP_VF_CNTL__PRIM_LINE_LOOP;
143 break;
144 case GL_TRIANGLES:
145 type=R300_VAP_VF_CNTL__PRIM_TRIANGLES;
146 break;
147 case GL_TRIANGLE_STRIP:
148 type=R300_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP;
149 break;
150 case GL_TRIANGLE_FAN:
151 type=R300_VAP_VF_CNTL__PRIM_TRIANGLE_FAN;
152 break;
153 case GL_QUADS:
154 type=R300_VAP_VF_CNTL__PRIM_QUADS;
155 break;
156 case GL_QUAD_STRIP:
157 type=R300_VAP_VF_CNTL__PRIM_QUAD_STRIP;
158 break;
159 case GL_POLYGON:
160 type=R300_VAP_VF_CNTL__PRIM_POLYGON;
161 break;
162 default:
163 fprintf(stderr, "%s:%s Do not know how to handle primitive %02x - help me !\n",
164 __FILE__, __FUNCTION__,
165 prim & PRIM_MODE_MASK);
166 return -1;
167 break;
168 }
169 return type;
170 }
171
172 static int r300_get_num_verts(r300ContextPtr rmesa,
173 GLcontext *ctx,
174 int num_verts,
175 int prim)
176 {
177 TNLcontext *tnl = TNL_CONTEXT(ctx);
178 struct vertex_buffer *VB = &tnl->vb;
179 GLuint i;
180 int type=-1, verts_off=0;
181 char *name="UNKNOWN";
182
183 switch (prim & PRIM_MODE_MASK) {
184 case GL_POINTS:
185 name="P";
186 verts_off = 0;
187 break;
188 case GL_LINES:
189 name="L";
190 verts_off = num_verts % 2;
191 break;
192 case GL_LINE_STRIP:
193 name="LS";
194 if(num_verts < 2)
195 verts_off = num_verts;
196 break;
197 case GL_LINE_LOOP:
198 name="LL";
199 if(num_verts < 2)
200 verts_off = num_verts;
201 break;
202 case GL_TRIANGLES:
203 name="T";
204 verts_off = num_verts % 3;
205 break;
206 case GL_TRIANGLE_STRIP:
207 name="TS";
208 if(num_verts < 3)
209 verts_off = num_verts;
210 break;
211 case GL_TRIANGLE_FAN:
212 name="TF";
213 if(num_verts < 3)
214 verts_off = num_verts;
215 break;
216 case GL_QUADS:
217 name="Q";
218 verts_off = num_verts % 4;
219 break;
220 case GL_QUAD_STRIP:
221 name="QS";
222 if(num_verts < 4)
223 verts_off = num_verts;
224 else
225 verts_off = num_verts % 2;
226 break;
227 case GL_POLYGON:
228 name="P";
229 if(num_verts < 3)
230 verts_off = num_verts;
231 break;
232 default:
233 fprintf(stderr, "%s:%s Do not know how to handle primitive %02x - help me !\n",
234 __FILE__, __FUNCTION__,
235 prim & PRIM_MODE_MASK);
236 return -1;
237 break;
238 }
239
240 if(num_verts - verts_off == 0){
241 WARN_ONCE("user error: Need more than %d vertices to draw primitive %s !\n", num_verts, name);
242 return 0;
243 }
244
245 if(verts_off > 0){
246 WARN_ONCE("user error: %d is not a valid number of vertices for primitive %s !\n", num_verts, name);
247 }
248
249 return num_verts - verts_off;
250 }
251
252 void dump_inputs(GLcontext *ctx, int render_inputs)
253 {
254 int k;
255 fprintf(stderr, "inputs:");
256 if(render_inputs & _TNL_BIT_POS)
257 fprintf(stderr, "_TNL_BIT_POS ");
258 if(render_inputs & _TNL_BIT_NORMAL)
259 fprintf(stderr, "_TNL_BIT_NORMAL ");
260
261 /* color components */
262 if(render_inputs & _TNL_BIT_COLOR0)
263 fprintf(stderr, "_TNL_BIT_COLOR0 ");
264 if(render_inputs & _TNL_BIT_COLOR1)
265 fprintf(stderr, "_TNL_BIT_COLOR1 ");
266
267 if(render_inputs & _TNL_BIT_FOG)
268 fprintf(stderr, "_TNL_BIT_FOG ");
269
270 /* texture coordinates */
271 for(k=0;k < ctx->Const.MaxTextureUnits;k++)
272 if(render_inputs & (_TNL_BIT_TEX0<<k))
273 fprintf(stderr, "_TNL_BIT_TEX%d ", k);
274
275 if(render_inputs & _TNL_BIT_INDEX)
276 fprintf(stderr, "_TNL_BIT_INDEX ");
277 if(render_inputs & _TNL_BIT_POINTSIZE)
278 fprintf(stderr, "_TNL_BIT_POINTSIZE ");
279
280 fprintf(stderr, "\n");
281 }
282
283 /* This function compiles GL context into state registers that
284 describe data routing inside of R300 pipeline.
285
286 In particular, it programs input_route, output_vtx_fmt, texture
287 unit configuration and gb_output_vtx_fmt
288
289 This function encompasses setup_AOS() from r300_lib.c
290 */
291
292
293
294
295 /* Immediate implementation - vertex data is sent via command stream */
296
297 static GLfloat default_vector[4]={0.0, 0.0, 0.0, 1.0};
298
299 #define output_vector(v, i) \
300 { \
301 int _i; \
302 for(_i=0;_i<v->size;_i++){ \
303 efloat(VEC_ELT(v, GLfloat, i)[_i]); \
304 } \
305 for(_i=v->size;_i<4;_i++){ \
306 efloat(default_vector[_i]); \
307 } \
308 }
309
310 /* Immediate implementation - vertex data is sent via command stream */
311
312 static void r300_render_immediate_primitive(r300ContextPtr rmesa,
313 GLcontext *ctx,
314 int start,
315 int end,
316 int prim)
317 {
318 TNLcontext *tnl = TNL_CONTEXT(ctx);
319 struct vertex_buffer *VB = &tnl->vb;
320 GLuint i, render_inputs;
321 int k, type, num_verts;
322 LOCAL_VARS
323
324 type=r300_get_primitive_type(rmesa, ctx, prim);
325 num_verts=r300_get_num_verts(rmesa, ctx, end-start, prim);
326
327 #if 0
328 fprintf(stderr,"ObjPtr: size=%d stride=%d\n",
329 VB->ObjPtr->size, VB->ObjPtr->stride);
330 fprintf(stderr,"ColorPtr[0]: size=%d stride=%d\n",
331 VB->ColorPtr[0]->size, VB->ColorPtr[0]->stride);
332 fprintf(stderr,"TexCoordPtr[0]: size=%d stride=%d\n",
333 VB->TexCoordPtr[0]->size, VB->TexCoordPtr[0]->stride);
334 #endif
335
336 if(type<0 || num_verts <= 0)return;
337
338 if(!VB->ObjPtr){
339 WARN_ONCE("FIXME: Don't know how to handle GL_ARB_vertex_buffer_object correctly\n");
340 return;
341 }
342 /* A packet cannot have more than 16383 data words.. */
343 if((num_verts*4*rmesa->state.aos_count)>16380){
344 WARN_ONCE("Too many vertices to paint. Fix me !\n");
345 return;
346 }
347
348 //fprintf(stderr, "aos_count=%d start=%d end=%d\n", rmesa->state.aos_count, start, end);
349
350 if(rmesa->state.aos_count==0){
351 WARN_ONCE("Aeiee ! aos_count==0, while it shouldn't. Skipping rendering\n");
352 return;
353 }
354
355 render_inputs = rmesa->state.render_inputs;
356
357 if(!render_inputs){
358 WARN_ONCE("Aeiee ! render_inputs==0. Skipping rendering.\n");
359 return;
360 }
361
362 //dump_inputs(ctx, render_inputs); return ;
363
364 start_immediate_packet(num_verts, type, 4*rmesa->state.aos_count);
365
366 for(i=start;i<start+num_verts;i++){
367 #if 0
368 fprintf(stderr, "* (%f %f %f %f) (%f %f %f %f)\n",
369 VEC_ELT(VB->ObjPtr, GLfloat, i)[0],
370 VEC_ELT(VB->ObjPtr, GLfloat, i)[1],
371 VEC_ELT(VB->ObjPtr, GLfloat, i)[2],
372 VEC_ELT(VB->ObjPtr, GLfloat, i)[3],
373
374 VEC_ELT(VB->ColorPtr[0], GLfloat, i)[0],
375 VEC_ELT(VB->ColorPtr[0], GLfloat, i)[1],
376 VEC_ELT(VB->ColorPtr[0], GLfloat, i)[2],
377 VEC_ELT(VB->ColorPtr[0], GLfloat, i)[3]
378 );
379 #endif
380
381
382 /* coordinates */
383 if(render_inputs & _TNL_BIT_POS)
384 output_vector(VB->ObjPtr, i);
385 if(render_inputs & _TNL_BIT_NORMAL)
386 output_vector(VB->NormalPtr, i);
387
388 /* color components */
389 if(render_inputs & _TNL_BIT_COLOR0)
390 output_vector(VB->ColorPtr[0], i);
391 if(render_inputs & _TNL_BIT_COLOR1)
392 output_vector(VB->SecondaryColorPtr[0], i);
393
394 /* if(render_inputs & _TNL_BIT_FOG) // Causes lock ups when immediate mode is on
395 output_vector(VB->FogCoordPtr, i);*/
396
397 /* texture coordinates */
398 for(k=0;k < ctx->Const.MaxTextureUnits;k++)
399 if(render_inputs & (_TNL_BIT_TEX0<<k))
400 output_vector(VB->TexCoordPtr[k], i);
401
402 if(render_inputs & _TNL_BIT_INDEX)
403 output_vector(VB->IndexPtr[0], i);
404 if(render_inputs & _TNL_BIT_POINTSIZE)
405 output_vector(VB->PointSizePtr, i);
406 }
407
408 }
409
410
411 static GLboolean r300_run_immediate_render(GLcontext *ctx,
412 struct tnl_pipeline_stage *stage)
413 {
414 r300ContextPtr rmesa = R300_CONTEXT(ctx);
415 TNLcontext *tnl = TNL_CONTEXT(ctx);
416 struct vertex_buffer *VB = &tnl->vb;
417 GLuint i;
418 /* Only do 2d textures */
419 struct gl_texture_object *to=ctx->Texture.Unit[0].Current2D;
420 r300TexObjPtr t=to->DriverData;
421 LOCAL_VARS
422
423
424 /* Update texture state - needs to be done only when actually changed..
425 All the time for now.. */
426
427
428 if (RADEON_DEBUG == DEBUG_PRIMS)
429 fprintf(stderr, "%s\n", __FUNCTION__);
430
431 #if 1 /* we need this, somehow */
432 /* Flush state - make sure command buffer is nice and large */
433 r300Flush(ctx);
434 /* Make sure we have enough space */
435 #else
436 /* Count is very imprecize, but should be good upper bound */
437 r300EnsureCmdBufSpace(rmesa, rmesa->hw.max_state_size + 4+2+30
438 +VB->PrimitiveCount*(1+8)+VB->Count*4*rmesa->state.texture.tc_count+4, __FUNCTION__);
439 #endif
440
441 /* needed before starting 3d operation .. */
442 reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
443 e32(0x0000000a);
444
445 reg_start(0x4f18,0);
446 e32(0x00000003);
447
448
449 #if 0 /* looks like the Z offset issue got fixed */
450 rmesa->hw.vte.cmd[1] = R300_VPORT_X_SCALE_ENA
451 | R300_VPORT_X_OFFSET_ENA
452 | R300_VPORT_Y_SCALE_ENA
453 | R300_VPORT_Y_OFFSET_ENA
454 | R300_VTX_W0_FMT;
455 R300_STATECHANGE(rmesa, vte);
456 #endif
457
458
459
460 /* Magic register - note it is right after 20b0 */
461
462
463 if(rmesa->state.texture.tc_count>0){
464 reg_start(0x20b4,0);
465 e32(0x0000000c);
466
467 }
468
469 r300EmitState(rmesa);
470
471 #if 0
472 reg_start(R300_RB3D_COLORMASK, 0);
473 e32(0xf);
474
475 vsf_start_fragment(0x406, 4);
476 efloat(0.0);
477 efloat(0.0);
478 efloat(0.0);
479 efloat(1.0);
480
481 vsf_start_fragment(0x400, 4);
482 efloat(0.0);
483 efloat(0.0);
484 efloat(0.0);
485 efloat(1.0);
486 #endif
487
488 /* We need LOAD_VBPNTR to setup AOS_ATTR fields.. the offsets are irrelevant */
489 r300EmitLOAD_VBPNTR(rmesa, 0);
490
491 for(i=0; i < VB->PrimitiveCount; i++){
492 GLuint prim = VB->Primitive[i].mode;
493 GLuint start = VB->Primitive[i].start;
494 GLuint length = VB->Primitive[i].count;
495
496 r300_render_immediate_primitive(rmesa, ctx, start, start + length, prim);
497 }
498
499 /* This sequence is required after any 3d drawing packet
500 I suspect it work arounds a bug (or deficiency) in hardware */
501
502 reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
503 e32(0x0000000a);
504
505 reg_start(0x4f18,0);
506 e32(0x00000003);
507
508 return GL_FALSE;
509 }
510
511
512 /* vertex buffer implementation */
513
514 /* We use the start part of GART texture buffer for vertices */
515
516
517 static void upload_vertex_buffer(r300ContextPtr rmesa, GLcontext *ctx)
518 {
519 TNLcontext *tnl = TNL_CONTEXT(ctx);
520 struct vertex_buffer *VB = &tnl->vb;
521 int idx=0;
522 int i,j,k;
523 radeonScreenPtr rsp=rmesa->radeon.radeonScreen;
524 GLuint render_inputs;
525
526 /* A hack - we don't want to overwrite vertex buffers, so we
527 just use AGP space for them.. Fix me ! */
528 static int offset=0;
529 if(offset>2*1024*1024){
530 //fprintf(stderr, "Wrapping agp vertex buffer offset\n");
531 offset=0;
532 }
533 /* Not the most efficient implementation, but, for now, I just want something that
534 works */
535 /* to do - make single memcpy per column (is it possible ?) */
536 /* to do - use dirty flags to avoid redundant copies */
537 #define UPLOAD_VECTOR(v)\
538 { \
539 /* Is the data dirty ? */ \
540 if (v->flags & ((1<<v->size)-1)) { \
541 /* fprintf(stderr, "size=%d vs stride=%d\n", v->size, v->stride); */ \
542 if(v->size*4==v->stride){\
543 /* fast path */ \
544 memcpy(rsp->gartTextures.map+offset, v->data, v->stride*VB->Count); \
545 } else { \
546 for(i=0;i<VB->Count;i++){ \
547 /* copy one vertex at a time*/ \
548 memcpy(rsp->gartTextures.map+offset+i*v->size*4, VEC_ELT(v, GLfloat, i), v->size*4); \
549 } \
550 } \
551 /* v->flags &= ~((1<<v->size)-1);*/ \
552 } \
553 rmesa->state.aos[idx].offset=rsp->gartTextures.handle+offset; \
554 offset+=v->size*4*VB->Count; \
555 idx++; \
556 }
557
558 render_inputs = rmesa->state.render_inputs;
559
560 if(!render_inputs){
561 WARN_ONCE("Aeiee ! render_inputs==0. Skipping rendering.\n");
562 return;
563 }
564 /* coordinates */
565 if(render_inputs & _TNL_BIT_POS)
566 UPLOAD_VECTOR(VB->ObjPtr);
567 if(render_inputs & _TNL_BIT_NORMAL)
568 UPLOAD_VECTOR(VB->NormalPtr);
569
570 /* color components */
571 if(render_inputs & _TNL_BIT_COLOR0)
572 UPLOAD_VECTOR(VB->ColorPtr[0]);
573 if(render_inputs & _TNL_BIT_COLOR1)
574 UPLOAD_VECTOR(VB->SecondaryColorPtr[0]);
575
576 if(render_inputs & _TNL_BIT_FOG)
577 UPLOAD_VECTOR(VB->FogCoordPtr);
578
579 /* texture coordinates */
580 for(k=0;k < ctx->Const.MaxTextureUnits;k++)
581 if(render_inputs & (_TNL_BIT_TEX0<<k))
582 UPLOAD_VECTOR(VB->TexCoordPtr[k]);
583
584 if(render_inputs & _TNL_BIT_INDEX)
585 UPLOAD_VECTOR(VB->IndexPtr[0]);
586 if(render_inputs & _TNL_BIT_POINTSIZE)
587 UPLOAD_VECTOR(VB->PointSizePtr);
588
589 if(idx>=R300_MAX_AOS_ARRAYS){
590 fprintf(stderr, "Aieee ! Maximum AOS arrays count exceeded.. \n");
591 exit(-1);
592 }
593 //dump_inputs(ctx, render_inputs); return ;
594 }
595
596 static void r300_render_vb_primitive(r300ContextPtr rmesa,
597 GLcontext *ctx,
598 int start,
599 int end,
600 int prim)
601 {
602 int type, num_verts;
603 LOCAL_VARS
604
605 type=r300_get_primitive_type(rmesa, ctx, prim);
606 num_verts=r300_get_num_verts(rmesa, ctx, end-start, prim);
607
608 if(type<0 || num_verts <= 0)return;
609
610
611 fire_AOS(PASS_PREFIX num_verts, type);
612 }
613
614 static GLboolean r300_run_vb_render(GLcontext *ctx,
615 struct tnl_pipeline_stage *stage)
616 {
617 r300ContextPtr rmesa = R300_CONTEXT(ctx);
618 TNLcontext *tnl = TNL_CONTEXT(ctx);
619 struct vertex_buffer *VB = &tnl->vb;
620 int i, j;
621 LOCAL_VARS
622
623 if (RADEON_DEBUG == DEBUG_PRIMS)
624 fprintf(stderr, "%s\n", __FUNCTION__);
625
626
627 reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
628 e32(0x0000000a);
629
630 reg_start(0x4f18,0);
631 e32(0x00000003);
632
633 r300_setup_routing(ctx, GL_FALSE);
634
635 r300EmitState(rmesa);
636
637 /* setup array of structures data */
638 LOCK_HARDWARE(&(rmesa->radeon));
639
640 upload_vertex_buffer(rmesa, ctx);
641 //fprintf(stderr, "Using %d AOS arrays\n", n_arrays);
642
643 for(i=0; i < VB->PrimitiveCount; i++){
644 GLuint prim = VB->Primitive[i].mode;
645 GLuint start = VB->Primitive[i].start;
646 GLuint length = VB->Primitive[i].count;
647
648 /* We need LOAD_VBPNTR to setup AOS_ATTR fields.. */
649 r300EmitLOAD_VBPNTR(rmesa, start);
650
651 r300_render_vb_primitive(rmesa, ctx, start, start + length, prim);
652 }
653
654 /* This sequence is required after any 3d drawing packet
655 I suspect it works around a bug (or deficiency) in hardware */
656
657 reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
658 e32(0x0000000a);
659
660 reg_start(0x4f18,0);
661 e32(0x00000003);
662
663 end_3d(PASS_PREFIX_VOID);
664
665 /* Flush state - we are done drawing.. */
666 r300FlushCmdBufLocked(rmesa, __FUNCTION__);
667 radeonWaitForIdleLocked(&(rmesa->radeon));
668
669 UNLOCK_HARDWARE(&(rmesa->radeon));
670 return GL_FALSE;
671 }
672
673 /**
674 * Called by the pipeline manager to render a batch of primitives.
675 * We can return true to pass on to the next stage (i.e. software
676 * rasterization) or false to indicate that the pipeline has finished
677 * after we render something.
678 */
679 static GLboolean r300_run_render(GLcontext *ctx,
680 struct tnl_pipeline_stage *stage)
681 {
682 r300ContextPtr rmesa = R300_CONTEXT(ctx);
683 TNLcontext *tnl = TNL_CONTEXT(ctx);
684 struct vertex_buffer *VB = &tnl->vb;
685 GLuint i;
686
687 if (RADEON_DEBUG == DEBUG_PRIMS)
688 fprintf(stderr, "%s\n", __FUNCTION__);
689
690
691 #if 1
692
693 #if 0
694 return r300_run_immediate_render(ctx, stage);
695 #else
696 return r300_run_vb_render(ctx, stage);
697 #endif
698 #else
699 return GL_TRUE;
700 #endif
701
702 #if 0
703 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
704 TNLcontext *tnl = TNL_CONTEXT(ctx);
705 struct vertex_buffer *VB = &tnl->vb;
706 GLuint i;
707
708 /* Don't handle clipping or indexed vertices or vertex manipulations.
709 */
710 if (mmesa->RenderIndex != 0 ||
711 !mga_validate_render( ctx, VB )) {
712 return GL_TRUE;
713 }
714
715 tnl->Driver.Render.Start( ctx );
716 mmesa->SetupNewInputs = ~0;
717
718 for (i = 0 ; i < VB->PrimitiveCount ; i++)
719 {
720 GLuint prim = VB->Primitive[i].mode;
721 GLuint start = VB->Primitive[i].start;
722 GLuint length = VB->Primitive[i].count;
723
724 if (!length)
725 continue;
726
727 mga_render_tab_verts[prim & PRIM_MODE_MASK]( ctx, start, start + length,
728 prim);
729 }
730
731 tnl->Driver.Render.Finish( ctx );
732
733 return GL_FALSE; /* finished the pipe */
734 #endif
735 }
736
737
738 /**
739 * Called by the pipeline manager once before rendering.
740 * We check the GL state here to
741 * a) decide whether we can do the current state in hardware and
742 * b) update hardware registers
743 */
744 #define FALLBACK_IF(expr) \
745 do { \
746 if (expr) { \
747 if (1 || RADEON_DEBUG & DEBUG_FALLBACKS) \
748 fprintf(stderr, "%s: fallback:%s\n", \
749 __FUNCTION__, #expr); \
750 stage->active = GL_FALSE; \
751 return; \
752 } \
753 } while(0)
754
755 static void r300_check_render(GLcontext *ctx, struct tnl_pipeline_stage *stage)
756 {
757 r300ContextPtr r300 = R300_CONTEXT(ctx);
758 int i;
759
760 if (RADEON_DEBUG & DEBUG_STATE)
761 fprintf(stderr, "%s\n", __FUNCTION__);
762
763 /* We only support rendering in hardware for now */
764 if (ctx->RenderMode != GL_RENDER) {
765 stage->active = GL_FALSE;
766 return;
767 }
768
769 // I failed to figure out how dither works in hardware,
770 // let's just ignore it for now
771 //FALLBACK_IF(ctx->Color.DitherFlag);
772
773 /* I'm almost certain I forgot something here */
774 #if 0 /* This should work now.. */
775 FALLBACK_IF(ctx->Color.AlphaEnabled); // GL_ALPHA_TEST
776 FALLBACK_IF(ctx->Color.BlendEnabled); // GL_BLEND
777 #endif
778 //FALLBACK_IF(ctx->Fog.Enabled); // GL_FOG disable as swtcl doesnt seem to support this
779 FALLBACK_IF(ctx->Line.SmoothFlag); // GL_LINE_SMOOTH
780 FALLBACK_IF(ctx->Line.StippleFlag); // GL_LINE_STIPPLE
781 FALLBACK_IF(ctx->Point.SmoothFlag); // GL_POINT_SMOOTH
782 if (ctx->Extensions.NV_point_sprite || ctx->Extensions.ARB_point_sprite)
783 FALLBACK_IF(ctx->Point.PointSprite); // GL_POINT_SPRITE_NV
784 //FALLBACK_IF(ctx->Polygon.OffsetPoint); // GL_POLYGON_OFFSET_POINT
785 //FALLBACK_IF(ctx->Polygon.OffsetLine); // GL_POLYGON_OFFSET_LINE
786 //FALLBACK_IF(ctx->Polygon.OffsetFill); // GL_POLYGON_OFFSET_FILL
787 //if(ctx->Polygon.OffsetFill)WARN_ONCE("Polygon.OffsetFill not implemented, ignoring\n");
788 FALLBACK_IF(ctx->Polygon.SmoothFlag); // GL_POLYGON_SMOOTH
789 FALLBACK_IF(ctx->Polygon.StippleFlag); // GL_POLYGON_STIPPLE
790 //FALLBACK_IF(ctx->Stencil.Enabled); // GL_STENCIL_TEST
791 FALLBACK_IF(ctx->Multisample.Enabled); // GL_MULTISAMPLE_ARB
792
793 /* One step at a time - let one texture pass.. */
794 for (i = 1; i < ctx->Const.MaxTextureUnits; i++)
795 FALLBACK_IF(ctx->Texture.Unit[i].Enabled);
796
797 /* let r300_run_render do its job */
798 #if 0
799 stage->active = GL_FALSE;
800 #endif
801 }
802
803
804 static void dtr(struct tnl_pipeline_stage *stage)
805 {
806 (void)stage;
807 }
808
809 const struct tnl_pipeline_stage _r300_render_stage = {
810 "r300 hw rasterize",
811 _NEW_ALL, /* re-check (always re-check for now) */
812 0, /* re-run (always runs) */
813 GL_TRUE, /* active */
814 0, 0, /* inputs (set in check_render), outputs */
815 0, 0, /* changed_inputs, private */
816 dtr, /* destructor */
817 r300_check_render, /* check */
818 r300_run_render /* run */
819 };