Fix for buffer overrun caused by ALLOC_STATE not having args surrounded by parenthesi...
[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 #include "r300_maos.h"
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 fprintf(stderr, "%08x ", render_inputs);
257
258 if(render_inputs & _TNL_BIT_POS)
259 fprintf(stderr, "_TNL_BIT_POS ");
260 if(render_inputs & _TNL_BIT_NORMAL)
261 fprintf(stderr, "_TNL_BIT_NORMAL ");
262
263 /* color components */
264 if(render_inputs & _TNL_BIT_COLOR0)
265 fprintf(stderr, "_TNL_BIT_COLOR0 ");
266 if(render_inputs & _TNL_BIT_COLOR1)
267 fprintf(stderr, "_TNL_BIT_COLOR1 ");
268
269 if(render_inputs & _TNL_BIT_FOG)
270 fprintf(stderr, "_TNL_BIT_FOG ");
271
272 /* texture coordinates */
273 for(k=0;k < ctx->Const.MaxTextureUnits;k++)
274 if(render_inputs & (_TNL_BIT_TEX0<<k))
275 fprintf(stderr, "_TNL_BIT_TEX%d ", k);
276
277 if(render_inputs & _TNL_BIT_INDEX)
278 fprintf(stderr, "_TNL_BIT_INDEX ");
279 if(render_inputs & _TNL_BIT_POINTSIZE)
280 fprintf(stderr, "_TNL_BIT_POINTSIZE ");
281
282 fprintf(stderr, "\n");
283 }
284
285 /* This function compiles GL context into state registers that
286 describe data routing inside of R300 pipeline.
287
288 In particular, it programs input_route, output_vtx_fmt, texture
289 unit configuration and gb_output_vtx_fmt
290
291 This function encompasses setup_AOS() from r300_lib.c
292 */
293
294
295
296
297 /* Immediate implementation - vertex data is sent via command stream */
298
299 static GLfloat default_vector[4]={0.0, 0.0, 0.0, 1.0};
300
301 #define output_vector(v, i) \
302 { \
303 int _i; \
304 for(_i=0;_i<v->size;_i++){ \
305 efloat(VEC_ELT(v, GLfloat, i)[_i]); \
306 } \
307 for(_i=v->size;_i<4;_i++){ \
308 efloat(default_vector[_i]); \
309 } \
310 }
311
312 /* Immediate implementation - vertex data is sent via command stream */
313
314 static void r300_render_immediate_primitive(r300ContextPtr rmesa,
315 GLcontext *ctx,
316 int start,
317 int end,
318 int prim)
319 {
320 TNLcontext *tnl = TNL_CONTEXT(ctx);
321 struct vertex_buffer *VB = &tnl->vb;
322 GLuint i, render_inputs;
323 int k, type, num_verts;
324 LOCAL_VARS
325
326 type=r300_get_primitive_type(rmesa, ctx, prim);
327 num_verts=r300_get_num_verts(rmesa, ctx, end-start, prim);
328
329 #if 0
330 fprintf(stderr,"ObjPtr: size=%d stride=%d\n",
331 VB->ObjPtr->size, VB->ObjPtr->stride);
332 fprintf(stderr,"ColorPtr[0]: size=%d stride=%d\n",
333 VB->ColorPtr[0]->size, VB->ColorPtr[0]->stride);
334 fprintf(stderr,"TexCoordPtr[0]: size=%d stride=%d\n",
335 VB->TexCoordPtr[0]->size, VB->TexCoordPtr[0]->stride);
336 #endif
337
338 if(type<0 || num_verts <= 0)return;
339
340 if(!VB->ObjPtr){
341 WARN_ONCE("FIXME: Don't know how to handle GL_ARB_vertex_buffer_object correctly\n");
342 return;
343 }
344 /* A packet cannot have more than 16383 data words.. */
345 if((num_verts*4*rmesa->state.aos_count)>16380){
346 WARN_ONCE("Too many vertices to paint. Fix me !\n");
347 return;
348 }
349
350 //fprintf(stderr, "aos_count=%d start=%d end=%d\n", rmesa->state.aos_count, start, end);
351
352 if(rmesa->state.aos_count==0){
353 WARN_ONCE("Aeiee ! aos_count==0, while it shouldn't. Skipping rendering\n");
354 return;
355 }
356
357 render_inputs = rmesa->state.render_inputs;
358
359 if(!render_inputs){
360 WARN_ONCE("Aeiee ! render_inputs==0. Skipping rendering.\n");
361 return;
362 }
363
364 //dump_inputs(ctx, render_inputs); return ;
365
366 start_immediate_packet(num_verts, type, 4*rmesa->state.aos_count);
367
368 for(i=start;i<start+num_verts;i++){
369 #if 0
370 fprintf(stderr, "* (%f %f %f %f) (%f %f %f %f)\n",
371 VEC_ELT(VB->ObjPtr, GLfloat, i)[0],
372 VEC_ELT(VB->ObjPtr, GLfloat, i)[1],
373 VEC_ELT(VB->ObjPtr, GLfloat, i)[2],
374 VEC_ELT(VB->ObjPtr, GLfloat, i)[3],
375
376 VEC_ELT(VB->ColorPtr[0], GLfloat, i)[0],
377 VEC_ELT(VB->ColorPtr[0], GLfloat, i)[1],
378 VEC_ELT(VB->ColorPtr[0], GLfloat, i)[2],
379 VEC_ELT(VB->ColorPtr[0], GLfloat, i)[3]
380 );
381 #endif
382
383
384 /* coordinates */
385 if(render_inputs & _TNL_BIT_POS)
386 output_vector(VB->ObjPtr, i);
387 if(render_inputs & _TNL_BIT_NORMAL)
388 output_vector(VB->NormalPtr, i);
389
390 /* color components */
391 if(render_inputs & _TNL_BIT_COLOR0)
392 output_vector(VB->ColorPtr[0], i);
393 if(render_inputs & _TNL_BIT_COLOR1)
394 output_vector(VB->SecondaryColorPtr[0], i);
395
396 /* if(render_inputs & _TNL_BIT_FOG) // Causes lock ups when immediate mode is on
397 output_vector(VB->FogCoordPtr, i);*/
398
399 /* texture coordinates */
400 for(k=0;k < ctx->Const.MaxTextureUnits;k++)
401 if(render_inputs & (_TNL_BIT_TEX0<<k))
402 output_vector(VB->TexCoordPtr[k], i);
403
404 if(render_inputs & _TNL_BIT_INDEX)
405 output_vector(VB->IndexPtr[0], i);
406 if(render_inputs & _TNL_BIT_POINTSIZE)
407 output_vector(VB->PointSizePtr, i);
408 }
409
410 }
411
412
413 static GLboolean r300_run_immediate_render(GLcontext *ctx,
414 struct tnl_pipeline_stage *stage)
415 {
416 r300ContextPtr rmesa = R300_CONTEXT(ctx);
417 TNLcontext *tnl = TNL_CONTEXT(ctx);
418 struct vertex_buffer *VB = &tnl->vb;
419 GLuint i;
420 /* Only do 2d textures */
421 struct gl_texture_object *to=ctx->Texture.Unit[0].Current2D;
422 r300TexObjPtr t=to->DriverData;
423 LOCAL_VARS
424
425
426 /* Update texture state - needs to be done only when actually changed..
427 All the time for now.. */
428
429
430 if (RADEON_DEBUG == DEBUG_PRIMS)
431 fprintf(stderr, "%s\n", __FUNCTION__);
432
433 #if 1 /* we need this, somehow */
434 /* Flush state - make sure command buffer is nice and large */
435 r300Flush(ctx);
436 /* Make sure we have enough space */
437 #else
438 /* Count is very imprecize, but should be good upper bound */
439 r300EnsureCmdBufSpace(rmesa, rmesa->hw.max_state_size + 4+2+30
440 +VB->PrimitiveCount*(1+8)+VB->Count*4*rmesa->state.texture.tc_count+4, __FUNCTION__);
441 #endif
442
443 /* needed before starting 3d operation .. */
444 reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
445 e32(0x0000000a);
446
447 reg_start(0x4f18,0);
448 e32(0x00000003);
449
450
451 #if 0 /* looks like the Z offset issue got fixed */
452 rmesa->hw.vte.cmd[1] = R300_VPORT_X_SCALE_ENA
453 | R300_VPORT_X_OFFSET_ENA
454 | R300_VPORT_Y_SCALE_ENA
455 | R300_VPORT_Y_OFFSET_ENA
456 | R300_VTX_W0_FMT;
457 R300_STATECHANGE(rmesa, vte);
458 #endif
459
460
461
462 /* Magic register - note it is right after 20b0 */
463
464
465 if(rmesa->state.texture.tc_count>0){
466 reg_start(0x20b4,0);
467 e32(0x0000000c);
468
469 }
470
471 r300EmitState(rmesa);
472
473 #if 0
474 reg_start(R300_RB3D_COLORMASK, 0);
475 e32(0xf);
476
477 vsf_start_fragment(0x406, 4);
478 efloat(0.0);
479 efloat(0.0);
480 efloat(0.0);
481 efloat(1.0);
482
483 vsf_start_fragment(0x400, 4);
484 efloat(0.0);
485 efloat(0.0);
486 efloat(0.0);
487 efloat(1.0);
488 #endif
489
490 /* Setup INPUT_ROUTE and INPUT_CNTL */
491 r300EmitArrays(ctx, GL_TRUE);
492
493 /* Why do we need this for immediate mode?? Vertex processor needs it to know proper regs */
494 // r300EmitLOAD_VBPNTR(rmesa, 0);
495 /* Okay, it seems I misunderstood something, EmitAOS does the same thing */
496 r300EmitAOS(rmesa, rmesa->state.aos_count, 0);
497
498 for(i=0; i < VB->PrimitiveCount; i++){
499 GLuint prim = VB->Primitive[i].mode;
500 GLuint start = VB->Primitive[i].start;
501 GLuint length = VB->Primitive[i].count;
502
503 r300_render_immediate_primitive(rmesa, ctx, start, start + length, prim);
504 }
505
506 /* This sequence is required after any 3d drawing packet
507 I suspect it work arounds a bug (or deficiency) in hardware */
508
509 reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
510 e32(0x0000000a);
511
512 reg_start(0x4f18,0);
513 e32(0x00000003);
514
515 return GL_FALSE;
516 }
517
518 /* vertex buffer implementation */
519 void emit_elts(GLcontext * ctx, GLuint *elts,
520 unsigned long n_elts, unsigned long n_fake_elts, int align);
521
522 # define R300_EB_UNK1_SHIFT 24
523 # define R300_EB_UNK1 (0x80<<24)
524 # define R300_EB_UNK2 0x0810
525
526 //#define PLAY_WITH_MAGIC_1
527
528 unsigned long get_num_elts(unsigned long count)
529 {
530 #ifdef PLAY_WITH_MAGIC_1
531 return count;
532 #else
533 /* round up elt count so that magic_1 is 0 (divisable by 4)*/
534 return (count+3) & (~3);
535 //return count - (count % 4);
536 #endif
537 }
538
539 int get_align(int vertex_count)
540 {
541 unsigned char magic1_tbl[4]={ 0, 6, 4, 2 };
542
543 return magic1_tbl[vertex_count % 4];
544 }
545
546 static void inline fire_EB(PREFIX unsigned long addr, int vertex_count, int type)
547 {
548 LOCAL_VARS
549 unsigned long magic_1;
550
551 magic_1 = get_align(vertex_count);
552 #ifndef PLAY_WITH_MAGIC_1
553 if(magic_1 != 0){
554 WARN_ONCE("Dont know how to handle this yet!\n");
555 return ;
556 }
557 #endif
558 check_space(6);
559
560 start_packet3(RADEON_CP_PACKET3_3D_DRAW_INDX_2, 0);
561 e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (vertex_count<<16) | type);
562
563 start_packet3(RADEON_CP_PACKET3_INDX_BUFFER, 2);
564 e32(R300_EB_UNK1 | (magic_1 << 16) | R300_EB_UNK2);
565 e32(addr);
566 e32(((vertex_count+1) / 2) + magic_1); /* This still fails once in a while */
567
568 }
569
570 static void r300_render_vb_primitive(r300ContextPtr rmesa,
571 GLcontext *ctx,
572 int start,
573 int end,
574 int prim)
575 {
576 int type, num_verts;
577 radeonScreenPtr rsp=rmesa->radeon.radeonScreen;
578 LOCAL_VARS
579 TNLcontext *tnl = TNL_CONTEXT(ctx);
580 struct vertex_buffer *VB = &tnl->vb;
581 int i;
582
583 type=r300_get_primitive_type(rmesa, ctx, prim);
584 num_verts=r300_get_num_verts(rmesa, ctx, end-start, prim);
585
586 if(type<0 || num_verts <= 0)return;
587
588 if(rmesa->state.Elts){
589 unsigned long elt_count;
590
591 WARN_ONCE("Rendering with elts\n");
592 r300EmitAOS(rmesa, rmesa->state.aos_count, 0);
593 #if 1
594 start_index32_packet(num_verts, type);
595 for(i=0; i < num_verts; i++)
596 e32(rmesa->state.Elts[start+i]); /* start ? */
597 #else
598 elt_count=get_num_elts(num_verts);
599 //emit_elts(ctx, rmesa->state.Elts, VB->Count, get_num_elts(VB->Count));
600 emit_elts(ctx, rmesa->state.Elts+start, num_verts, elt_count, get_align(elt_count));
601 fire_EB(PASS_PREFIX rsp->gartTextures.handle/*rmesa->state.elt_ao.aos_offset*/, elt_count, type);
602 #endif
603 }else{
604 r300EmitAOS(rmesa, rmesa->state.aos_count, start);
605 fire_AOS(PASS_PREFIX num_verts, type);
606 }
607 }
608
609 static GLboolean r300_run_vb_render(GLcontext *ctx,
610 struct tnl_pipeline_stage *stage)
611 {
612 r300ContextPtr rmesa = R300_CONTEXT(ctx);
613 TNLcontext *tnl = TNL_CONTEXT(ctx);
614 struct vertex_buffer *VB = &tnl->vb;
615 int i, j;
616 LOCAL_VARS
617
618 if (RADEON_DEBUG & DEBUG_PRIMS)
619 fprintf(stderr, "%s\n", __FUNCTION__);
620
621
622 r300ReleaseArrays(ctx);
623 r300EmitArrays(ctx, GL_FALSE);
624 //dump_inputs(ctx, rmesa->state.render_inputs);
625 #if 0 /* Cant do this here yet due to magic_1 */
626 if(rmesa->state.Elts)
627 emit_elts(ctx, rmesa->state.Elts, /*600*/VB->Count, get_num_elts(/*600*/VB->Count));
628 #endif
629
630 // LOCK_HARDWARE(&(rmesa->radeon));
631
632 reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
633 e32(0x0000000a);
634
635 reg_start(0x4f18,0);
636 e32(0x00000003);
637 r300EmitState(rmesa);
638
639 rmesa->state.Elts = VB->Elts;
640
641 for(i=0; i < VB->PrimitiveCount; i++){
642 GLuint prim = VB->Primitive[i].mode;
643 GLuint start = VB->Primitive[i].start;
644 GLuint length = VB->Primitive[i].count;
645
646 r300_render_vb_primitive(rmesa, ctx, start, start + length, prim);
647 }
648
649 reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
650 e32(0x0000000a);
651
652 reg_start(0x4f18,0);
653 e32(0x00000003);
654
655 // end_3d(PASS_PREFIX_VOID);
656
657 /* Flush state - we are done drawing.. */
658 // r300FlushCmdBufLocked(rmesa, __FUNCTION__);
659 // radeonWaitForIdleLocked(&(rmesa->radeon));
660
661 // UNLOCK_HARDWARE(&(rmesa->radeon));
662 return GL_FALSE;
663 }
664
665 /**
666 * Called by the pipeline manager to render a batch of primitives.
667 * We can return true to pass on to the next stage (i.e. software
668 * rasterization) or false to indicate that the pipeline has finished
669 * after we render something.
670 */
671 static GLboolean r300_run_render(GLcontext *ctx,
672 struct tnl_pipeline_stage *stage)
673 {
674 r300ContextPtr rmesa = R300_CONTEXT(ctx);
675 TNLcontext *tnl = TNL_CONTEXT(ctx);
676 struct vertex_buffer *VB = &tnl->vb;
677 GLuint i;
678
679 if (RADEON_DEBUG & DEBUG_PRIMS)
680 fprintf(stderr, "%s\n", __FUNCTION__);
681
682
683 #if 1
684
685 #if 1
686 return r300_run_immediate_render(ctx, stage);
687 #else
688 return r300_run_vb_render(ctx, stage);
689 #endif
690 #else
691 return GL_TRUE;
692 #endif
693
694 #if 0
695 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
696 TNLcontext *tnl = TNL_CONTEXT(ctx);
697 struct vertex_buffer *VB = &tnl->vb;
698 GLuint i;
699
700 /* Don't handle clipping or indexed vertices or vertex manipulations.
701 */
702 if (mmesa->RenderIndex != 0 ||
703 !mga_validate_render( ctx, VB )) {
704 return GL_TRUE;
705 }
706
707 tnl->Driver.Render.Start( ctx );
708 mmesa->SetupNewInputs = ~0;
709
710 for (i = 0 ; i < VB->PrimitiveCount ; i++)
711 {
712 GLuint prim = VB->Primitive[i].mode;
713 GLuint start = VB->Primitive[i].start;
714 GLuint length = VB->Primitive[i].count;
715
716 if (!length)
717 continue;
718
719 mga_render_tab_verts[prim & PRIM_MODE_MASK]( ctx, start, start + length,
720 prim);
721 }
722
723 tnl->Driver.Render.Finish( ctx );
724
725 return GL_FALSE; /* finished the pipe */
726 #endif
727 }
728
729
730 /**
731 * Called by the pipeline manager once before rendering.
732 * We check the GL state here to
733 * a) decide whether we can do the current state in hardware and
734 * b) update hardware registers
735 */
736 #define FALLBACK_IF(expr) \
737 do { \
738 if (expr) { \
739 if (1 || RADEON_DEBUG & DEBUG_FALLBACKS) \
740 fprintf(stderr, "%s: fallback:%s\n", \
741 __FUNCTION__, #expr); \
742 stage->active = GL_FALSE; \
743 return; \
744 } \
745 } while(0)
746
747 static void r300_check_render(GLcontext *ctx, struct tnl_pipeline_stage *stage)
748 {
749 r300ContextPtr r300 = R300_CONTEXT(ctx);
750 int i;
751
752 if (RADEON_DEBUG & DEBUG_STATE)
753 fprintf(stderr, "%s\n", __FUNCTION__);
754
755 /* We only support rendering in hardware for now */
756 if (ctx->RenderMode != GL_RENDER) {
757 stage->active = GL_FALSE;
758 return;
759 }
760
761 // I failed to figure out how dither works in hardware,
762 // let's just ignore it for now
763 //FALLBACK_IF(ctx->Color.DitherFlag);
764
765 /* I'm almost certain I forgot something here */
766 #if 0 /* This should work now.. */
767 FALLBACK_IF(ctx->Color.AlphaEnabled); // GL_ALPHA_TEST
768 FALLBACK_IF(ctx->Color.BlendEnabled); // GL_BLEND
769 #endif
770 //FALLBACK_IF(ctx->Fog.Enabled); // GL_FOG disable as swtcl doesnt seem to support this
771 FALLBACK_IF(ctx->Line.SmoothFlag); // GL_LINE_SMOOTH
772 FALLBACK_IF(ctx->Line.StippleFlag); // GL_LINE_STIPPLE
773 FALLBACK_IF(ctx->Point.SmoothFlag); // GL_POINT_SMOOTH
774 if (ctx->Extensions.NV_point_sprite || ctx->Extensions.ARB_point_sprite)
775 FALLBACK_IF(ctx->Point.PointSprite); // GL_POINT_SPRITE_NV
776 //FALLBACK_IF(ctx->Polygon.OffsetPoint); // GL_POLYGON_OFFSET_POINT
777 //FALLBACK_IF(ctx->Polygon.OffsetLine); // GL_POLYGON_OFFSET_LINE
778 //FALLBACK_IF(ctx->Polygon.OffsetFill); // GL_POLYGON_OFFSET_FILL
779 //if(ctx->Polygon.OffsetFill)WARN_ONCE("Polygon.OffsetFill not implemented, ignoring\n");
780 FALLBACK_IF(ctx->Polygon.SmoothFlag); // GL_POLYGON_SMOOTH
781 FALLBACK_IF(ctx->Polygon.StippleFlag); // GL_POLYGON_STIPPLE
782 //FALLBACK_IF(ctx->Stencil.Enabled); // GL_STENCIL_TEST
783 FALLBACK_IF(ctx->Multisample.Enabled); // GL_MULTISAMPLE_ARB
784
785 /* One step at a time - let one texture pass.. */
786 for (i = 1; i < ctx->Const.MaxTextureUnits; i++)
787 FALLBACK_IF(ctx->Texture.Unit[i].Enabled);
788
789 /* let r300_run_render do its job */
790 #if 0
791 stage->active = GL_FALSE;
792 #endif
793 }
794
795
796 static void dtr(struct tnl_pipeline_stage *stage)
797 {
798 (void)stage;
799 }
800
801 const struct tnl_pipeline_stage _r300_render_stage = {
802 "r300 hw rasterize",
803 _NEW_ALL, /* re-check (always re-check for now) */
804 0, /* re-run (always runs) */
805 GL_TRUE, /* active */
806 0, 0, /* inputs (set in check_render), outputs */
807 0, 0, /* changed_inputs, private */
808 dtr, /* destructor */
809 r300_check_render, /* check */
810 r300_run_render /* run */
811 };