8e2663f39bdc47affa8540ea04e57a1fd7ef91c3
[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_ioctl.h"
49 #include "radeon_state.h"
50 #include "r300_context.h"
51 #include "r300_ioctl.h"
52 #include "r300_state.h"
53 #include "r300_reg.h"
54 #include "r300_program.h"
55
56 #include "r300_lib.h"
57
58
59 /**********************************************************************
60 * Hardware rasterization
61 *
62 * When we fell back to software TCL, we still try to use the
63 * rasterization hardware for rendering.
64 **********************************************************************/
65
66 static int r300_get_primitive_type(r300ContextPtr rmesa,
67 GLcontext *ctx,
68 int start,
69 int end,
70 int prim)
71 {
72 TNLcontext *tnl = TNL_CONTEXT(ctx);
73 struct vertex_buffer *VB = &tnl->vb;
74 GLuint i;
75 int type=-1, min_vertices=0;
76 char *name="UNKNOWN";
77
78 if(end<=start)return -1; /* do we need to watch for this ? */
79
80 switch (prim & PRIM_MODE_MASK) {
81 case GL_POINTS:
82 name="P";
83 type=R300_VAP_VF_CNTL__PRIM_POINTS;
84 min_vertices=1;
85 break;
86 case GL_LINES:
87 name="L";
88 type=R300_VAP_VF_CNTL__PRIM_LINES;
89 min_vertices=2;
90 break;
91 case GL_LINE_STRIP:
92 name="LS";
93 type=R300_VAP_VF_CNTL__PRIM_LINE_STRIP;
94 min_vertices=2;
95 break;
96 case GL_LINE_LOOP:
97 name="LL";
98 min_vertices=2;
99 return -1;
100 break;
101 case GL_TRIANGLES:
102 name="T";
103 type=R300_VAP_VF_CNTL__PRIM_TRIANGLES;
104 min_vertices=3;
105 break;
106 case GL_TRIANGLE_STRIP:
107 name="TS";
108 type=R300_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP;
109 min_vertices=3;
110 break;
111 case GL_TRIANGLE_FAN:
112 name="TF";
113 type=R300_VAP_VF_CNTL__PRIM_TRIANGLE_FAN;
114 min_vertices=3;
115 break;
116 case GL_QUADS:
117 name="Q";
118 type=R300_VAP_VF_CNTL__PRIM_QUADS;
119 min_vertices=4;
120 break;
121 case GL_QUAD_STRIP:
122 name="QS";
123 type=R300_VAP_VF_CNTL__PRIM_QUAD_STRIP;
124 min_vertices=4;
125 break;
126 default:
127 fprintf(stderr, "Cannot handle primitive %02x ", prim & PRIM_MODE_MASK);
128 return -1;
129 break;
130 }
131 #if 1
132 fprintf(stderr, "[%d-%d]%s ", start, end, name);
133 #endif
134 if(start+min_vertices>=end){
135 fprintf(stderr, "Not enough vertices\n");
136 return -1;
137 }
138 return type;
139 }
140
141
142
143 /* Immediate implementation - vertex data is sent via command stream */
144
145 static GLfloat default_vector[4]={0.0, 0.0, 0.0, 1.0};
146
147 #define output_vector(v, i) \
148 { \
149 int _i; \
150 for(_i=0;_i<v->size;_i++){ \
151 efloat(VEC_ELT(v, GLfloat, i)[_i]); \
152 } \
153 for(_i=v->size;_i<4;_i++){ \
154 efloat(default_vector[_i]); \
155 } \
156 }
157
158 static void r300_render_flat_primitive(r300ContextPtr rmesa,
159 GLcontext *ctx,
160 int start,
161 int end,
162 int prim)
163 {
164 TNLcontext *tnl = TNL_CONTEXT(ctx);
165 struct vertex_buffer *VB = &tnl->vb;
166 GLuint i;
167 int k, type;
168 LOCAL_VARS
169
170 type=r300_get_primitive_type(rmesa, ctx, start, end, prim);
171
172 fprintf(stderr,"ObjPtr: size=%d stride=%d\n",
173 VB->ObjPtr->size, VB->ObjPtr->stride);
174 fprintf(stderr,"ColorPtr[0]: size=%d stride=%d\n",
175 VB->ColorPtr[0]->size, VB->ColorPtr[0]->stride);
176
177 if(type<0)return;
178
179
180 start_immediate_packet(end-start, type, 8);
181
182 for(i=start;i<end;i++){
183 #if 0
184 fprintf(stderr, "* (%f %f %f %f) (%f %f %f %f)\n",
185 VEC_ELT(VB->ObjPtr, GLfloat, i)[0],
186 VEC_ELT(VB->ObjPtr, GLfloat, i)[1],
187 VEC_ELT(VB->ObjPtr, GLfloat, i)[2],
188 VEC_ELT(VB->ObjPtr, GLfloat, i)[3],
189
190 VEC_ELT(VB->ColorPtr[0], GLfloat, i)[0],
191 VEC_ELT(VB->ColorPtr[0], GLfloat, i)[1],
192 VEC_ELT(VB->ColorPtr[0], GLfloat, i)[2],
193 VEC_ELT(VB->ColorPtr[0], GLfloat, i)[3]
194 );
195 #endif
196
197
198 /* coordinates */
199 output_vector(VB->ObjPtr, i);
200
201 /* color components */
202 output_vector(VB->ColorPtr[0], i);
203 }
204
205 }
206
207 static GLboolean r300_run_flat_render(GLcontext *ctx,
208 struct tnl_pipeline_stage *stage)
209 {
210 r300ContextPtr rmesa = R300_CONTEXT(ctx);
211 TNLcontext *tnl = TNL_CONTEXT(ctx);
212 struct vertex_buffer *VB = &tnl->vb;
213 GLuint i;
214 AOS_DATA vb_arrays[2];
215 LOCAL_VARS
216
217 if (RADEON_DEBUG == DEBUG_PRIMS)
218 fprintf(stderr, "%s\n", __FUNCTION__);
219
220 /* setup array of structures data */
221
222 /* Note: immediate vertex data includes all coordinates.
223 To save bandwidth use either VBUF or state-based vertex generation */
224 /* xyz */
225 vb_arrays[0].element_size=4;
226 vb_arrays[0].stride=4;
227 vb_arrays[0].offset=0; /* Not used */
228 vb_arrays[0].format=AOS_FORMAT_FLOAT;
229 vb_arrays[0].ncomponents=4;
230 vb_arrays[0].reg=REG_COORDS;
231
232 /* color */
233 vb_arrays[1].element_size=4;
234 vb_arrays[1].stride=4;
235 vb_arrays[1].offset=0; /* Not used */
236 vb_arrays[1].format=AOS_FORMAT_FLOAT_COLOR;
237 vb_arrays[1].ncomponents=4;
238 vb_arrays[1].reg=REG_COLOR0;
239
240
241 /* needed before starting 3d operation .. */
242 reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
243 e32(0x0000000a);
244
245 reg_start(0x4f18,0);
246 e32(0x00000003);
247
248 rmesa->hw.vte.cmd[1] = R300_VPORT_X_SCALE_ENA
249 | R300_VPORT_X_OFFSET_ENA
250 | R300_VPORT_Y_SCALE_ENA
251 | R300_VPORT_Y_OFFSET_ENA
252 | R300_VTX_W0_FMT;
253 R300_STATECHANGE(rmesa, vte);
254
255 r300EmitState(rmesa);
256
257 FLAT_COLOR_PIPELINE.vertex_shader.matrix[0].length=16;
258 memcpy(FLAT_COLOR_PIPELINE.vertex_shader.matrix[0].body.f, ctx->_ModelProjectMatrix.m, 16*4);
259
260 FLAT_COLOR_PIPELINE.vertex_shader.unknown2.length=4;
261 FLAT_COLOR_PIPELINE.vertex_shader.unknown2.body.f[0]=0.0;
262 FLAT_COLOR_PIPELINE.vertex_shader.unknown2.body.f[1]=0.0;
263 FLAT_COLOR_PIPELINE.vertex_shader.unknown2.body.f[2]=1.0;
264 FLAT_COLOR_PIPELINE.vertex_shader.unknown2.body.f[3]=0.0;
265
266 program_pipeline(PASS_PREFIX &FLAT_COLOR_PIPELINE);
267
268 /* We need LOAD_VBPNTR to setup AOS_ATTR fields.. the offsets are irrelevant */
269 setup_AOS(PASS_PREFIX vb_arrays, 2);
270
271 for(i=0; i < VB->PrimitiveCount; i++){
272 GLuint prim = VB->Primitive[i].mode;
273 GLuint start = VB->Primitive[i].start;
274 GLuint length = VB->Primitive[i].count;
275 r300_render_flat_primitive(rmesa, ctx, start, start + length, prim);
276 }
277
278 end_3d(PASS_PREFIX_VOID);
279
280 fprintf(stderr, "\n");
281 return GL_FALSE;
282 }
283
284 /* vertex buffer implementation */
285
286 /* We use the start part of GART texture buffer for vertices */
287
288 /* 8 is somewhat bogus... it is probably something like 24 */
289 #define R300_MAX_AOS_ARRAYS 8
290
291 static void upload_vertex_buffer(r300ContextPtr rmesa,
292 GLcontext *ctx, AOS_DATA *array, int *n_arrays)
293 {
294 TNLcontext *tnl = TNL_CONTEXT(ctx);
295 struct vertex_buffer *VB = &tnl->vb;
296 int offset=0, idx=0;
297 int i,j;
298 radeonScreenPtr rsp=rmesa->radeon.radeonScreen;
299 /* Not the most efficient implementation, but, for now, I just want something that
300 works */
301 /* to do - make single memcpy per column (is it possible ?) */
302 /* to do - use dirty flags to avoid redundant copies */
303 #define UPLOAD_VECTOR(v, r, f)\
304 { \
305 /* Is the data dirty ? */ \
306 if (v->flags & ((1<<v->size)-1)) { \
307 fprintf(stderr, "size=%d vs stride=%d\n", v->size, v->stride); \
308 if(v->size*4==v->stride){\
309 /* fast path */ \
310 memcpy(rsp->gartTextures.map+offset, v->data, v->stride*VB->Count); \
311 } else { \
312 for(i=0;i<VB->Count;i++){ \
313 /* copy one vertex at a time*/ \
314 memcpy(rsp->gartTextures.map+offset+i*v->size*4, VEC_ELT(v, GLfloat, i), v->size*4); \
315 } \
316 } \
317 /* v->flags &= ~((1<<v->size)-1);*/ \
318 } \
319 array[idx].element_size=v->size; \
320 array[idx].stride=v->size; \
321 array[idx].format=(f); \
322 array[idx].ncomponents=v->size; \
323 array[idx].offset=rsp->gartTextures.handle+offset; \
324 array[idx].reg=r; \
325 offset+=v->size*4*VB->Count; \
326 idx++; \
327 }
328
329 UPLOAD_VECTOR(VB->ObjPtr, REG_COORDS, AOS_FORMAT_FLOAT);
330 UPLOAD_VECTOR(VB->ColorPtr[0], REG_COLOR0, AOS_FORMAT_FLOAT_COLOR);
331
332 *n_arrays=idx;
333 if(idx>=R300_MAX_AOS_ARRAYS){
334 fprintf(stderr, "Aieee ! Maximum AOS arrays count exceeded.. \n");
335 exit(-1);
336 }
337 }
338
339 static void r300_render_vb_flat_primitive(r300ContextPtr rmesa,
340 GLcontext *ctx,
341 int start,
342 int end,
343 int prim)
344 {
345 TNLcontext *tnl = TNL_CONTEXT(ctx);
346 struct vertex_buffer *VB = &tnl->vb;
347 GLuint i;
348 int k, type, n_arrays;
349 LOCAL_VARS
350
351 if(end<=start)return; /* do we need to watch for this ? */
352
353 type=r300_get_primitive_type(rmesa, ctx, start, end, prim);
354 if(type<0)return;
355
356 fire_AOS(PASS_PREFIX end-start, type);
357 }
358
359 static VERTEX_SHADER_FRAGMENT default_vector_vsf={
360 length: 4,
361 body: {
362 f: {0.0, 0.0, 0.0, 1.0}
363 }
364 };
365
366 static GLboolean r300_run_vb_flat_render(GLcontext *ctx,
367 struct tnl_pipeline_stage *stage)
368 {
369 r300ContextPtr rmesa = R300_CONTEXT(ctx);
370 TNLcontext *tnl = TNL_CONTEXT(ctx);
371 struct vertex_buffer *VB = &tnl->vb;
372 int i, j, n_arrays;
373 AOS_DATA vb_arrays[R300_MAX_AOS_ARRAYS];
374 AOS_DATA vb_arrays2[R300_MAX_AOS_ARRAYS];
375 LOCAL_VARS
376
377 if (RADEON_DEBUG == DEBUG_PRIMS)
378 fprintf(stderr, "%s\n", __FUNCTION__);
379
380 /* setup array of structures data */
381
382 upload_vertex_buffer(rmesa, ctx, vb_arrays, &n_arrays);
383 fprintf(stderr, "Using %d AOS arrays\n", n_arrays);
384
385 reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
386 e32(0x0000000a);
387
388 reg_start(0x4f18,0);
389 e32(0x00000003);
390
391 r300EmitState(rmesa);
392
393 FLAT_COLOR_PIPELINE.vertex_shader.matrix[0].length=16;
394 memcpy(FLAT_COLOR_PIPELINE.vertex_shader.matrix[0].body.f, ctx->_ModelProjectMatrix.m, 16*4);
395
396 FLAT_COLOR_PIPELINE.vertex_shader.unknown2.length=4;
397 FLAT_COLOR_PIPELINE.vertex_shader.unknown2.body.f[0]=0.0;
398 FLAT_COLOR_PIPELINE.vertex_shader.unknown2.body.f[1]=0.0;
399 FLAT_COLOR_PIPELINE.vertex_shader.unknown2.body.f[2]=1.0;
400 FLAT_COLOR_PIPELINE.vertex_shader.unknown2.body.f[3]=0.0;
401
402 program_pipeline(PASS_PREFIX &FLAT_COLOR_PIPELINE);
403
404 set_quad0(PASS_PREFIX 1.0,1.0,1.0,1.0);
405 set_init21(PASS_PREFIX 0.0,1.0);
406
407 for(i=0; i < VB->PrimitiveCount; i++){
408 GLuint prim = VB->Primitive[i].mode;
409 GLuint start = VB->Primitive[i].start;
410 GLuint length = VB->Primitive[i].count;
411
412 /* copy arrays */
413 memcpy(vb_arrays2, vb_arrays, sizeof(AOS_DATA)*n_arrays);
414 for(j=0;j<n_arrays;j++){
415 vb_arrays2[j].offset+=vb_arrays2[j].stride*start*4;
416 }
417
418 setup_AOS(PASS_PREFIX vb_arrays2, n_arrays);
419
420 r300_render_vb_flat_primitive(rmesa, ctx, start, start + length, prim);
421 }
422
423 end_3d(PASS_PREFIX_VOID);
424
425 /* Flush state - we are done drawing.. */
426 r300Flush(ctx);
427 fprintf(stderr, "\n");
428 return GL_FALSE;
429 }
430
431 /* Textures... */
432
433 /* Immediate implementation - vertex data is sent via command stream */
434
435 static void r300_render_tex_primitive(r300ContextPtr rmesa,
436 GLcontext *ctx,
437 int start,
438 int end,
439 int prim)
440 {
441 TNLcontext *tnl = TNL_CONTEXT(ctx);
442 struct vertex_buffer *VB = &tnl->vb;
443 GLuint i;
444 int k, type;
445 LOCAL_VARS
446
447 type=r300_get_primitive_type(rmesa, ctx, start, end, prim);
448
449 fprintf(stderr,"ObjPtr: size=%d stride=%d\n",
450 VB->ObjPtr->size, VB->ObjPtr->stride);
451 fprintf(stderr,"ColorPtr[0]: size=%d stride=%d\n",
452 VB->ColorPtr[0]->size, VB->ColorPtr[0]->stride);
453
454 if(type<0)return;
455
456
457 start_immediate_packet(end-start, type, 8);
458
459 for(i=start;i<end;i++){
460 #if 0
461 fprintf(stderr, "* (%f %f %f %f) (%f %f %f %f)\n",
462 VEC_ELT(VB->ObjPtr, GLfloat, i)[0],
463 VEC_ELT(VB->ObjPtr, GLfloat, i)[1],
464 VEC_ELT(VB->ObjPtr, GLfloat, i)[2],
465 VEC_ELT(VB->ObjPtr, GLfloat, i)[3],
466
467 VEC_ELT(VB->ColorPtr[0], GLfloat, i)[0],
468 VEC_ELT(VB->ColorPtr[0], GLfloat, i)[1],
469 VEC_ELT(VB->ColorPtr[0], GLfloat, i)[2],
470 VEC_ELT(VB->ColorPtr[0], GLfloat, i)[3]
471 );
472 #endif
473
474
475 /* coordinates */
476 output_vector(VB->ObjPtr, i);
477
478 /* color components */
479 output_vector(VB->TexCoordPtr[0], i);
480 }
481
482 }
483
484 static GLboolean r300_run_tex_render(GLcontext *ctx,
485 struct tnl_pipeline_stage *stage)
486 {
487 r300ContextPtr rmesa = R300_CONTEXT(ctx);
488 TNLcontext *tnl = TNL_CONTEXT(ctx);
489 struct vertex_buffer *VB = &tnl->vb;
490 GLuint i;
491 AOS_DATA vb_arrays[2];
492 /* Only do 2d textures */
493 struct gl_texture_object *to=ctx->Texture.Unit[0].Current2D;
494 radeonScreenPtr rsp=rmesa->radeon.radeonScreen;
495 LOCAL_VARS
496
497
498 fprintf(stderr, "%s Fixme ! I am broken\n", __FUNCTION__);
499 return GL_TRUE;
500
501 if (RADEON_DEBUG == DEBUG_PRIMS)
502 fprintf(stderr, "%s\n", __FUNCTION__);
503
504 /* setup array of structures data */
505
506 /* Note: immediate vertex data includes all coordinates.
507 To save bandwidth use either VBUF or state-based vertex generation */
508 /* xyz */
509 vb_arrays[0].element_size=4;
510 vb_arrays[0].stride=4;
511 vb_arrays[0].offset=0; /* Not used */
512 vb_arrays[0].format=AOS_FORMAT_FLOAT;
513 vb_arrays[0].ncomponents=4;
514 vb_arrays[0].reg=REG_COORDS;
515
516 /* color */
517 vb_arrays[1].element_size=4;
518 vb_arrays[1].stride=4;
519 vb_arrays[1].offset=0; /* Not used */
520 vb_arrays[1].format=AOS_FORMAT_FLOAT;
521 vb_arrays[1].ncomponents=4;
522 vb_arrays[1].reg=REG_TEX0;
523
524
525 /* needed before starting 3d operation .. */
526 reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
527 e32(0x0000000a);
528
529 reg_start(0x4f18,0);
530 e32(0x00000003);
531
532
533 r300EmitState(rmesa);
534
535 SINGLE_TEXTURE_PIPELINE.vertex_shader.matrix[0].length=16;
536 memcpy(SINGLE_TEXTURE_PIPELINE.vertex_shader.matrix[0].body.f, ctx->_ModelProjectMatrix.m, 16*4);
537
538 SINGLE_TEXTURE_PIPELINE.vertex_shader.unknown2.length=4;
539 SINGLE_TEXTURE_PIPELINE.vertex_shader.unknown2.body.f[0]=0.0;
540 SINGLE_TEXTURE_PIPELINE.vertex_shader.unknown2.body.f[1]=0.0;
541 SINGLE_TEXTURE_PIPELINE.vertex_shader.unknown2.body.f[2]=1.0;
542 SINGLE_TEXTURE_PIPELINE.vertex_shader.unknown2.body.f[3]=0.0;
543
544 /* Put it in the beginning of texture memory */
545 SINGLE_TEXTURE_PIPELINE.texture_unit[0].offset=rsp->gartTextures.handle;
546
547 /* Upload texture, a hack, really we can do a lot better */
548 #if 0
549 memcpy(rsp->gartTextures.map, to->Image[0][0]->Data, to->Image[0][0]->RowStride*to->Image[0][0]->Height*4);
550 #endif
551
552 reg_start(0x4e0c,0);
553 e32(0x0000000f);
554
555 reg_start(0x427c,1);
556 /* XG_427c(427c) */
557 e32(0x00000000);
558 /* XG_4280(4280) */
559 e32(0x00000000);
560
561 reg_start(0x4e04,1);
562 /* XG_4e04(4e04) */
563 e32(0x20220000);
564 /* XG_4e08(4e08) */
565 e32(0x00000000);
566
567 reg_start(0x4f14,0);
568 e32(0x00000001);
569
570 reg_start(0x4f1c,0);
571 e32(0x00000000);
572
573 /* gap */
574 sync_VAP(PASS_PREFIX_VOID);
575
576 reg_start(R300_RS_CNTL_0,1);
577 /* R300_RS_CNTL_0(4300) */
578 e32(0x00040084);
579 /* RS_INST_COUNT(4304) */
580 e32(0x000000c0);
581
582 reg_start(R300_RS_ROUTE_0,0);
583 e32(0x00024008);
584
585 reg_start(R300_RS_INTERP_0,7);
586 /* X_MEM0_0(4310) */
587 e32(0x00d10000);
588 /* X_MEM0_1(4314) */
589 e32(0x00d10044);
590 /* X_MEM0_2(4318) */
591 e32(0x00d10084);
592 /* X_MEM0_3(431c) */
593 e32(0x00d100c4);
594 /* X_MEM0_4(4320) */
595 e32(0x00d10004);
596 /* X_MEM0_5(4324) */
597 e32(0x00d10004);
598 /* X_MEM0_6(4328) */
599 e32(0x00d10004);
600 /* X_MEM0_7(432c) */
601 e32(0x00d10004);
602
603 reg_start(0x221c,0);
604 e32(0x00000000);
605
606 reg_start(0x20b0,0);
607 e32(0x0000043f);
608
609 reg_start(0x4bd8,0);
610 e32(0x00000000);
611
612 reg_start(0x4e04,0);
613 e32(0x20220000);
614
615 reg_start(0x20b4,0);
616 e32(0x0000000c);
617
618 reg_start(0x4288,0);
619 e32(0x00000000);
620
621 reg_start(0x4e0c,0);
622 e32(0x0000000f);
623
624 reg_start(R300_RS_CNTL_0,0);
625 e32(0x00040084);
626
627 program_pipeline(PASS_PREFIX &SINGLE_TEXTURE_PIPELINE);
628
629 /* We need LOAD_VBPNTR to setup AOS_ATTR fields.. the offsets are irrelevant */
630 setup_AOS(PASS_PREFIX vb_arrays, 2);
631
632 for(i=0; i < VB->PrimitiveCount; i++){
633 GLuint prim = VB->Primitive[i].mode;
634 GLuint start = VB->Primitive[i].start;
635 GLuint length = VB->Primitive[i].count;
636 r300_render_tex_primitive(rmesa, ctx, start, start + length, prim);
637 }
638
639 end_3d(PASS_PREFIX_VOID);
640
641 fprintf(stderr, "\n");
642 return GL_FALSE;
643 }
644
645
646 /**
647 * Called by the pipeline manager to render a batch of primitives.
648 * We can return true to pass on to the next stage (i.e. software
649 * rasterization) or false to indicate that the pipeline has finished
650 * after we render something.
651 */
652 static GLboolean r300_run_render(GLcontext *ctx,
653 struct tnl_pipeline_stage *stage)
654 {
655 r300ContextPtr rmesa = R300_CONTEXT(ctx);
656 TNLcontext *tnl = TNL_CONTEXT(ctx);
657 struct vertex_buffer *VB = &tnl->vb;
658 GLuint i;
659
660 if (RADEON_DEBUG == DEBUG_PRIMS)
661 fprintf(stderr, "%s\n", __FUNCTION__);
662
663 #if 1
664 /* Just switch between pipelines.. We could possibly do better.. (?) */
665 if(ctx->Texture.Unit[0].Enabled)
666 return r300_run_tex_render(ctx, stage);
667 else
668 return r300_run_flat_render(ctx, stage);
669 #else
670 return GL_TRUE;
671 #endif
672
673 #if 0
674 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
675 TNLcontext *tnl = TNL_CONTEXT(ctx);
676 struct vertex_buffer *VB = &tnl->vb;
677 GLuint i;
678
679 /* Don't handle clipping or indexed vertices or vertex manipulations.
680 */
681 if (mmesa->RenderIndex != 0 ||
682 !mga_validate_render( ctx, VB )) {
683 return GL_TRUE;
684 }
685
686 tnl->Driver.Render.Start( ctx );
687 mmesa->SetupNewInputs = ~0;
688
689 for (i = 0 ; i < VB->PrimitiveCount ; i++)
690 {
691 GLuint prim = VB->Primitive[i].mode;
692 GLuint start = VB->Primitive[i].start;
693 GLuint length = VB->Primitive[i].count;
694
695 if (!length)
696 continue;
697
698 mga_render_tab_verts[prim & PRIM_MODE_MASK]( ctx, start, start + length,
699 prim);
700 }
701
702 tnl->Driver.Render.Finish( ctx );
703
704 return GL_FALSE; /* finished the pipe */
705 #endif
706 }
707
708
709 /**
710 * Called by the pipeline manager once before rendering.
711 * We check the GL state here to
712 * a) decide whether we can do the current state in hardware and
713 * b) update hardware registers
714 */
715 #define FALLBACK_IF(expr) \
716 do { \
717 if (expr) { \
718 if (RADEON_DEBUG & DEBUG_FALLBACKS) \
719 fprintf(stderr, "%s: fallback:%s\n", \
720 __FUNCTION__, #expr); \
721 stage->active = GL_FALSE; \
722 return; \
723 } \
724 } while(0)
725
726 static void r300_check_render(GLcontext *ctx, struct tnl_pipeline_stage *stage)
727 {
728 r300ContextPtr r300 = R300_CONTEXT(ctx);
729 int i;
730
731 if (RADEON_DEBUG & DEBUG_STATE)
732 fprintf(stderr, "%s\n", __FUNCTION__);
733
734 /* We only support rendering in hardware for now */
735 if (ctx->RenderMode != GL_RENDER) {
736 stage->active = GL_FALSE;
737 return;
738 }
739
740 // I failed to figure out how dither works in hardware,
741 // let's just ignore it for now
742 //FALLBACK_IF(ctx->Color.DitherFlag);
743
744 /* I'm almost certain I forgot something here */
745 FALLBACK_IF(ctx->Color.AlphaEnabled); // GL_ALPHA_TEST
746 FALLBACK_IF(ctx->Color.BlendEnabled); // GL_BLEND
747 FALLBACK_IF(ctx->Fog.Enabled); // GL_FOG
748 FALLBACK_IF(ctx->Line.SmoothFlag); // GL_LINE_SMOOTH
749 FALLBACK_IF(ctx->Line.StippleFlag); // GL_LINE_STIPPLE
750 FALLBACK_IF(ctx->Point.SmoothFlag); // GL_POINT_SMOOTH
751 if (ctx->Extensions.NV_point_sprite || ctx->Extensions.ARB_point_sprite)
752 FALLBACK_IF(ctx->Point.PointSprite); // GL_POINT_SPRITE_NV
753 FALLBACK_IF(ctx->Polygon.OffsetPoint); // GL_POLYGON_OFFSET_POINT
754 FALLBACK_IF(ctx->Polygon.OffsetLine); // GL_POLYGON_OFFSET_LINE
755 FALLBACK_IF(ctx->Polygon.OffsetFill); // GL_POLYGON_OFFSET_FILL
756 FALLBACK_IF(ctx->Polygon.SmoothFlag); // GL_POLYGON_SMOOTH
757 FALLBACK_IF(ctx->Polygon.StippleFlag); // GL_POLYGON_STIPPLE
758 FALLBACK_IF(ctx->Stencil.Enabled); // GL_STENCIL_TEST
759 FALLBACK_IF(ctx->Multisample.Enabled); // GL_MULTISAMPLE_ARB
760
761 /* One step at a time - let one texture pass.. */
762 for (i = 1; i < ctx->Const.MaxTextureUnits; i++)
763 FALLBACK_IF(ctx->Texture.Unit[i].Enabled);
764
765
766 /* let r300_run_render do its job */
767 #if 0
768 stage->active = GL_FALSE;
769 #endif
770 }
771
772
773 static void dtr(struct tnl_pipeline_stage *stage)
774 {
775 (void)stage;
776 }
777
778 const struct tnl_pipeline_stage _r300_render_stage = {
779 "r300 hw rasterize",
780 _NEW_ALL, /* re-check (always re-check for now) */
781 0, /* re-run (always runs) */
782 GL_TRUE, /* active */
783 0, 0, /* inputs (set in check_render), outputs */
784 0, 0, /* changed_inputs, private */
785 dtr, /* destructor */
786 r300_check_render, /* check */
787 r300_run_render /* run */
788 };