ee24f14f6158d019f3c25f1d8812b841ab9aa0e3
[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 int type=-1;
74
75 switch (prim & PRIM_MODE_MASK) {
76 case GL_POINTS:
77 type=R300_VAP_VF_CNTL__PRIM_POINTS;
78 break;
79 case GL_LINES:
80 type=R300_VAP_VF_CNTL__PRIM_LINES;
81 break;
82 case GL_LINE_STRIP:
83 type=R300_VAP_VF_CNTL__PRIM_LINE_STRIP;
84 break;
85 case GL_LINE_LOOP:
86 type=R300_VAP_VF_CNTL__PRIM_LINE_LOOP;
87 break;
88 case GL_TRIANGLES:
89 type=R300_VAP_VF_CNTL__PRIM_TRIANGLES;
90 break;
91 case GL_TRIANGLE_STRIP:
92 type=R300_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP;
93 break;
94 case GL_TRIANGLE_FAN:
95 type=R300_VAP_VF_CNTL__PRIM_TRIANGLE_FAN;
96 break;
97 case GL_QUADS:
98 type=R300_VAP_VF_CNTL__PRIM_QUADS;
99 break;
100 case GL_QUAD_STRIP:
101 type=R300_VAP_VF_CNTL__PRIM_QUAD_STRIP;
102 break;
103 case GL_POLYGON:
104 type=R300_VAP_VF_CNTL__PRIM_POLYGON;
105 break;
106 default:
107 fprintf(stderr, "%s:%s Do not know how to handle primitive %02x - help me !\n",
108 __FILE__, __FUNCTION__,
109 prim & PRIM_MODE_MASK);
110 return -1;
111 break;
112 }
113 return type;
114 }
115
116 static int r300_get_num_verts(r300ContextPtr rmesa,
117 GLcontext *ctx,
118 int num_verts,
119 int prim)
120 {
121 int verts_off=0;
122 char *name="UNKNOWN";
123
124 switch (prim & PRIM_MODE_MASK) {
125 case GL_POINTS:
126 name="P";
127 verts_off = 0;
128 break;
129 case GL_LINES:
130 name="L";
131 verts_off = num_verts % 2;
132 break;
133 case GL_LINE_STRIP:
134 name="LS";
135 if(num_verts < 2)
136 verts_off = num_verts;
137 break;
138 case GL_LINE_LOOP:
139 name="LL";
140 if(num_verts < 2)
141 verts_off = num_verts;
142 break;
143 case GL_TRIANGLES:
144 name="T";
145 verts_off = num_verts % 3;
146 break;
147 case GL_TRIANGLE_STRIP:
148 name="TS";
149 if(num_verts < 3)
150 verts_off = num_verts;
151 break;
152 case GL_TRIANGLE_FAN:
153 name="TF";
154 if(num_verts < 3)
155 verts_off = num_verts;
156 break;
157 case GL_QUADS:
158 name="Q";
159 verts_off = num_verts % 4;
160 break;
161 case GL_QUAD_STRIP:
162 name="QS";
163 if(num_verts < 4)
164 verts_off = num_verts;
165 else
166 verts_off = num_verts % 2;
167 break;
168 case GL_POLYGON:
169 name="P";
170 if(num_verts < 3)
171 verts_off = num_verts;
172 break;
173 default:
174 fprintf(stderr, "%s:%s Do not know how to handle primitive %02x - help me !\n",
175 __FILE__, __FUNCTION__,
176 prim & PRIM_MODE_MASK);
177 return -1;
178 break;
179 }
180
181 if (RADEON_DEBUG & DEBUG_VERTS) {
182 if (num_verts - verts_off == 0) {
183 WARN_ONCE("user error: Need more than %d vertices to draw primitive %s !\n", num_verts, name);
184 return 0;
185 }
186
187 if (verts_off > 0) {
188 WARN_ONCE("user error: %d is not a valid number of vertices for primitive %s !\n", num_verts, name);
189 }
190 }
191
192 return num_verts - verts_off;
193 }
194
195 /* Immediate implementation has been removed from CVS. */
196
197 /* vertex buffer implementation */
198
199 static void inline fire_EB(PREFIX unsigned long addr, int vertex_count, int type, int elt_size)
200 {
201 LOCAL_VARS
202 unsigned long addr_a;
203 unsigned long t_addr;
204 unsigned long magic_1, magic_2;
205 GLcontext *ctx;
206 ctx = rmesa->radeon.glCtx;
207
208 assert(elt_size == 2 || elt_size == 4);
209
210 if(addr & (elt_size-1)){
211 WARN_ONCE("Badly aligned buffer\n");
212 return ;
213 }
214 #ifdef OPTIMIZE_ELTS
215 addr_a = 0;
216
217 magic_1 = (addr % 32) / 4;
218 t_addr = addr & (~0x1d);
219 magic_2 = (vertex_count + 1 + (t_addr & 0x2)) / 2 + magic_1;
220
221 check_space(6);
222
223 start_packet3(RADEON_CP_PACKET3_3D_DRAW_INDX_2, 0);
224 if(elt_size == 4){
225 e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (vertex_count<<16) | type | R300_VAP_VF_CNTL__INDEX_SIZE_32bit);
226 } else {
227 e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (vertex_count<<16) | type);
228 }
229
230 start_packet3(RADEON_CP_PACKET3_INDX_BUFFER, 2);
231 if(elt_size == 4){
232 e32(R300_EB_UNK1 | (0 << 16) | R300_EB_UNK2);
233 e32(addr /*& 0xffffffe3*/);
234 } else {
235 e32(R300_EB_UNK1 | (magic_1 << 16) | R300_EB_UNK2);
236 e32(t_addr);
237 }
238
239 if(elt_size == 4){
240 e32(vertex_count /*+ addr_a/4*/); /* Total number of dwords needed? */
241 } else {
242 e32(magic_2); /* Total number of dwords needed? */
243 }
244 //cp_delay(PASS_PREFIX 1);
245 #if 0
246 fprintf(stderr, "magic_1 %d\n", magic_1);
247 fprintf(stderr, "t_addr %x\n", t_addr);
248 fprintf(stderr, "magic_2 %d\n", magic_2);
249 exit(1);
250 #endif
251 #else
252 (void)magic_2, (void)magic_1, (void)t_addr;
253
254 addr_a = 0;
255
256 check_space(6);
257
258 start_packet3(RADEON_CP_PACKET3_3D_DRAW_INDX_2, 0);
259 if(elt_size == 4){
260 e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (vertex_count<<16) | type | R300_VAP_VF_CNTL__INDEX_SIZE_32bit);
261 } else {
262 e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (vertex_count<<16) | type);
263 }
264
265 start_packet3(RADEON_CP_PACKET3_INDX_BUFFER, 2);
266 e32(R300_EB_UNK1 | (0 << 16) | R300_EB_UNK2);
267 e32(addr /*& 0xffffffe3*/);
268
269 if(elt_size == 4){
270 e32(vertex_count /*+ addr_a/4*/); /* Total number of dwords needed? */
271 } else {
272 e32((vertex_count+1)/2 /*+ addr_a/4*/); /* Total number of dwords needed? */
273 }
274 //cp_delay(PASS_PREFIX 1);
275 #endif
276 }
277
278 static void r300_render_vb_primitive(r300ContextPtr rmesa,
279 GLcontext *ctx,
280 int start,
281 int end,
282 int prim)
283 {
284 int type, num_verts;
285 LOCAL_VARS
286
287 type=r300_get_primitive_type(rmesa, ctx, prim);
288 num_verts=r300_get_num_verts(rmesa, ctx, end-start, prim);
289
290 if(type<0 || num_verts <= 0)return;
291
292 if(rmesa->state.Elts){
293 r300EmitAOS(rmesa, rmesa->state.aos_count, 0);
294 #if 0
295 int i;
296 start_index32_packet(num_verts, type);
297 for(i=0; i < num_verts; i++)
298 e32(rmesa->state.Elts[start+i]); /* start ? */
299 #else
300 if(num_verts == 1){
301 start_index32_packet(num_verts, type);
302 e32(rmesa->state.Elts[start]);
303 return;
304 }
305
306 if(num_verts > 65535){ /* not implemented yet */
307 WARN_ONCE("Too many elts\n");
308 return;
309 }
310 r300EmitElts(ctx, rmesa->state.Elts+start, num_verts, 4);
311 fire_EB(PASS_PREFIX GET_START(&(rmesa->state.elt_dma)), num_verts, type, 4);
312 #endif
313 }else{
314 r300EmitAOS(rmesa, rmesa->state.aos_count, start);
315 fire_AOS(PASS_PREFIX num_verts, type);
316 }
317 }
318
319 static GLboolean r300_run_vb_render(GLcontext *ctx,
320 struct tnl_pipeline_stage *stage)
321 {
322 r300ContextPtr rmesa = R300_CONTEXT(ctx);
323 TNLcontext *tnl = TNL_CONTEXT(ctx);
324 struct vertex_buffer *VB = &tnl->vb;
325 int i;
326 LOCAL_VARS
327
328 if (RADEON_DEBUG & DEBUG_PRIMS)
329 fprintf(stderr, "%s\n", __FUNCTION__);
330
331
332 //r300UpdateShaders(rmesa);
333
334 r300ReleaseArrays(ctx);
335 r300EmitArrays(ctx, GL_FALSE);
336
337 r300UpdateShaderStates(rmesa);
338
339 reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
340 e32(0x0000000a);
341
342 reg_start(0x4f18,0);
343 e32(0x00000003);
344 r300EmitState(rmesa);
345
346 rmesa->state.Elts = VB->Elts;
347
348 for(i=0; i < VB->PrimitiveCount; i++){
349 GLuint prim = VB->Primitive[i].mode;
350 GLuint start = VB->Primitive[i].start;
351 GLuint length = VB->Primitive[i].count;
352
353 r300_render_vb_primitive(rmesa, ctx, start, start + length, prim);
354 }
355
356 reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
357 e32(0x0000000a);
358
359 reg_start(0x4f18,0);
360 e32(0x00000003);
361
362 #ifdef USER_BUFFERS
363 r300UseArrays(ctx);
364 #endif
365
366 return GL_FALSE;
367 }
368
369 #ifdef RADEON_VTXFMT_A
370
371 static void r300_render_vb_primitive_vtxfmt_a(r300ContextPtr rmesa,
372 GLcontext *ctx,
373 int start,
374 int end,
375 int prim)
376 {
377 int type, num_verts;
378
379 type=r300_get_primitive_type(rmesa, ctx, prim);
380 num_verts=r300_get_num_verts(rmesa, ctx, end-start, prim);
381
382 if(type<0 || num_verts <= 0)return;
383
384 if(rmesa->state.VB.Elts){
385 r300EmitAOS(rmesa, rmesa->state.aos_count, /*0*/start);
386 #if 0
387 LOCAL_VARS
388 int i;
389 start_index32_packet(num_verts, type);
390 for(i=0; i < num_verts; i++)
391 e32(((unsigned long *)rmesa->state.VB.Elts)[i]/*rmesa->state.Elts[start+i]*/); /* start ? */
392 #else
393 if(num_verts == 1){
394 //start_index32_packet(num_verts, type);
395 //e32(rmesa->state.Elts[start]);
396 return;
397 }
398
399 if(num_verts > 65535){ /* not implemented yet */
400 WARN_ONCE("Too many elts\n");
401 return;
402 }
403
404 r300EmitElts(ctx, rmesa->state.VB.Elts, num_verts, rmesa->state.VB.elt_size);
405 fire_EB(PASS_PREFIX rmesa->state.elt_dma.aos_offset, num_verts, type, rmesa->state.VB.elt_size);
406 #endif
407 }else{
408 r300EmitAOS(rmesa, rmesa->state.aos_count, start);
409 fire_AOS(PASS_PREFIX num_verts, type);
410 }
411 }
412
413 #if 0
414 void dump_array(struct r300_dma_region *rvb, int count)
415 {
416 int *out = (int *)(rvb->address + rvb->start);
417 int i, ci;
418
419 for (i=0; i < count; i++) {
420 fprintf(stderr, "{");
421 if (rvb->aos_format == AOS_FORMAT_FLOAT)
422 for (ci=0; ci < rvb->aos_size; ci++)
423 fprintf(stderr, "%f ", ((float *)out)[ci]);
424 else
425 for (ci=0; ci < rvb->aos_size; ci++)
426 fprintf(stderr, "%d ", ((unsigned char *)out)[ci]);
427 fprintf(stderr, "}");
428
429 out += rvb->aos_stride;
430 }
431
432 fprintf(stderr, "\n");
433 }
434
435 void dump_dt(struct dt *dt, int count)
436 {
437 int *out = dt->data;
438 int i, ci;
439
440 fprintf(stderr, "base at %p ", out);
441
442 for (i=0; i < count; i++){
443 fprintf(stderr, "{");
444 if (dt->type == GL_FLOAT)
445 for (ci=0; ci < dt->size; ci++)
446 fprintf(stderr, "%f ", ((float *)out)[ci]);
447 else
448 for (ci=0; ci < dt->size; ci++)
449 fprintf(stderr, "%d ", ((unsigned char *)out)[ci]);
450 fprintf(stderr, "}");
451
452 out = (int *)((char *)out + dt->stride);
453 }
454
455 fprintf(stderr, "\n");
456 }
457 #endif
458
459 /*static */GLboolean r300_run_vb_render_vtxfmt_a(GLcontext *ctx,
460 struct tnl_pipeline_stage *stage)
461 {
462 r300ContextPtr rmesa = R300_CONTEXT(ctx);
463 //TNLcontext *tnl = TNL_CONTEXT(ctx);
464 struct radeon_vertex_buffer *VB = &rmesa->state.VB; //&tnl->vb;
465 int i;
466 LOCAL_VARS
467
468 if (RADEON_DEBUG & DEBUG_PRIMS)
469 fprintf(stderr, "%s\n", __FUNCTION__);
470
471 r300UpdateShaders(rmesa);
472 if (rmesa->state.VB.LockCount == 0 || 1) {
473 r300ReleaseArrays(ctx);
474 r300EmitArraysVtx(ctx, GL_FALSE);
475
476 r300UpdateShaderStates(rmesa);
477 } else {
478 /* TODO: Figure out why do we need these. */
479 R300_STATECHANGE(rmesa, vir[0]);
480 R300_STATECHANGE(rmesa, vir[1]);
481 R300_STATECHANGE(rmesa, vic);
482 R300_STATECHANGE(rmesa, vof);
483
484 #if 0
485 fprintf(stderr, "dt:\n");
486 for(i=0; i < VERT_ATTRIB_MAX; i++){
487 fprintf(stderr, "dt %d:", i);
488 dump_dt(&rmesa->state.VB.AttribPtr[i], VB->Count);
489 }
490
491 fprintf(stderr, "before:\n");
492 for(i=0; i < rmesa->state.aos_count; i++){
493 fprintf(stderr, "aos %d:", i);
494 dump_array(&rmesa->state.aos[i], VB->Count);
495 }
496 #endif
497 #if 0
498 r300ReleaseArrays(ctx);
499 r300EmitArraysVtx(ctx, GL_FALSE);
500
501 fprintf(stderr, "after:\n");
502 for(i=0; i < rmesa->state.aos_count; i++){
503 fprintf(stderr, "aos %d:", i);
504 dump_array(&rmesa->state.aos[i], VB->Count);
505 }
506 #endif
507 }
508
509 reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
510 e32(0x0000000a);
511
512 reg_start(0x4f18,0);
513 e32(0x00000003);
514 #if 0
515 reg_start(R300_VAP_PVS_WAITIDLE,0);
516 e32(0x00000000);
517 #endif
518 r300EmitState(rmesa);
519
520 for(i=0; i < VB->PrimitiveCount; i++){
521 GLuint prim = VB->Primitive[i].mode;
522 GLuint start = VB->Primitive[i].start;
523 GLuint length = VB->Primitive[i].count;
524
525 r300_render_vb_primitive_vtxfmt_a(rmesa, ctx, start, start + length, prim);
526 }
527
528 reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
529 e32(0x0000000a/*0x2*/);
530
531 reg_start(0x4f18,0);
532 e32(0x00000003/*0x1*/);
533
534 #ifdef USER_BUFFERS
535 r300UseArrays(ctx);
536 #endif
537 return GL_FALSE;
538 }
539 #endif
540
541 #define FALLBACK_IF(expr) \
542 do { \
543 if (expr) { \
544 if (1 || RADEON_DEBUG & DEBUG_FALLBACKS) \
545 WARN_ONCE("fallback:%s\n", #expr); \
546 return GL_TRUE; \
547 } \
548 } while(0)
549
550 GLboolean r300Fallback(GLcontext *ctx)
551 {
552
553 //FALLBACK_IF(ctx->RenderMode != GL_RENDER); // We do not do SELECT or FEEDBACK (yet ?)
554
555 #if 0 /* These should work now.. */
556 FALLBACK_IF(ctx->Color.DitherFlag);
557 FALLBACK_IF(ctx->Color.AlphaEnabled); // GL_ALPHA_TEST
558 FALLBACK_IF(ctx->Color.BlendEnabled); // GL_BLEND
559 FALLBACK_IF(ctx->Polygon.OffsetFill); // GL_POLYGON_OFFSET_FILL
560 #endif
561 FALLBACK_IF(ctx->Polygon.OffsetPoint); // GL_POLYGON_OFFSET_POINT
562 FALLBACK_IF(ctx->Polygon.OffsetLine); // GL_POLYGON_OFFSET_LINE
563 //FALLBACK_IF(ctx->Stencil.Enabled); // GL_STENCIL_TEST
564
565 //FALLBACK_IF(ctx->Fog.Enabled); // GL_FOG disable as swtcl doesnt seem to support this
566 //FALLBACK_IF(ctx->Polygon.SmoothFlag); // GL_POLYGON_SMOOTH disabling to get blender going
567 FALLBACK_IF(ctx->Polygon.StippleFlag); // GL_POLYGON_STIPPLE
568 FALLBACK_IF(ctx->Multisample.Enabled); // GL_MULTISAMPLE_ARB
569
570
571 FALLBACK_IF(ctx->Line.StippleFlag);
572
573 /* HW doesnt appear to directly support these */
574 FALLBACK_IF(ctx->Line.SmoothFlag); // GL_LINE_SMOOTH
575 FALLBACK_IF(ctx->Point.SmoothFlag); // GL_POINT_SMOOTH
576 /* Rest could be done with vertex fragments */
577 if (ctx->Extensions.NV_point_sprite || ctx->Extensions.ARB_point_sprite)
578 FALLBACK_IF(ctx->Point.PointSprite); // GL_POINT_SPRITE_NV
579
580 return GL_FALSE;
581 }
582
583 /**
584 * Called by the pipeline manager to render a batch of primitives.
585 * We can return true to pass on to the next stage (i.e. software
586 * rasterization) or false to indicate that the pipeline has finished
587 * after we render something.
588 */
589 static GLboolean r300_run_render(GLcontext *ctx,
590 struct tnl_pipeline_stage *stage)
591 {
592
593 if (RADEON_DEBUG & DEBUG_PRIMS)
594 fprintf(stderr, "%s\n", __FUNCTION__);
595
596 if (r300Fallback(ctx))
597 return GL_TRUE;
598
599 return r300_run_vb_render(ctx, stage);
600 }
601
602 const struct tnl_pipeline_stage _r300_render_stage = {
603 "r300 hw rasterize",
604 NULL,
605 NULL,
606 NULL,
607 NULL,
608 r300_run_render /* run */
609 };
610
611 static GLboolean r300_run_tcl_render(GLcontext *ctx,
612 struct tnl_pipeline_stage *stage)
613 {
614 r300ContextPtr rmesa = R300_CONTEXT(ctx);
615 struct r300_vertex_program *vp;
616 int i;
617
618 hw_tcl_on=future_hw_tcl_on;
619
620 if (RADEON_DEBUG & DEBUG_PRIMS)
621 fprintf(stderr, "%s\n", __FUNCTION__);
622 if(hw_tcl_on == GL_FALSE)
623 return GL_TRUE;
624
625 if (r300Fallback(ctx)) {
626 hw_tcl_on = GL_FALSE;
627 return GL_TRUE;
628 }
629
630 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) /* XXX: Needs to be part of r300Fallback */
631 if (ctx->Texture.Unit[i]._ReallyEnabled & TEXTURE_RECT_BIT) {
632 hw_tcl_on = GL_FALSE;
633 return GL_TRUE;
634 }
635
636 r300UpdateShaders(rmesa);
637
638 vp = (struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx);
639 #if 0 /* Draw every second request with software arb vp */
640 vp->native++;
641 vp->native &= 1;
642 //vp->native = GL_FALSE;
643 #endif
644
645 #if 0 /* You dont want to know what this does... */
646 TNLcontext *tnl = TNL_CONTEXT(ctx);
647 struct tnl_cache *cache;
648 struct tnl_cache_item *c;
649
650 cache = tnl->vp_cache;
651 c = cache->items[0xc000cc0e % cache->size];
652
653 if(c && c->data == vp)
654 vp->native = GL_FALSE;
655
656 #endif
657 #if 0
658 vp->native = GL_FALSE;
659 #endif
660 if (vp->native == GL_FALSE) {
661 hw_tcl_on = GL_FALSE;
662 return GL_TRUE;
663 }
664 //r300UpdateShaderStates(rmesa);
665
666 return r300_run_vb_render(ctx, stage);
667 }
668
669 const struct tnl_pipeline_stage _r300_tcl_stage = {
670 "r300 tcl",
671 NULL,
672 NULL,
673 NULL,
674 NULL,
675 r300_run_tcl_render /* run */
676 };
677
678 /* R300 texture rectangle expects coords in 0..1 range, not 0..dimension
679 * as in the extension spec. Need to translate here.
680 *
681 * Note that swrast expects 0..dimension, so if a fallback is active,
682 * don't do anything. (Maybe need to configure swrast to match hw)
683 */
684 struct texrect_stage_data {
685 GLvector4f texcoord[MAX_TEXTURE_UNITS];
686 };
687
688 #define TEXRECT_STAGE_DATA(stage) ((struct texrect_stage_data *)stage->privatePtr)
689
690
691 static GLboolean run_texrect_stage( GLcontext *ctx,
692 struct tnl_pipeline_stage *stage )
693 {
694 struct texrect_stage_data *store = TEXRECT_STAGE_DATA(stage);
695 r300ContextPtr rmesa = R300_CONTEXT(ctx);
696 TNLcontext *tnl = TNL_CONTEXT(ctx);
697 struct vertex_buffer *VB = &tnl->vb;
698 GLuint i;
699
700 if (rmesa->radeon.Fallback)
701 return GL_TRUE;
702
703 for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) {
704 if (ctx->Texture.Unit[i]._ReallyEnabled & TEXTURE_RECT_BIT) {
705 struct gl_texture_object *texObj = ctx->Texture.Unit[i].CurrentRect;
706 struct gl_texture_image *texImage = texObj->Image[0][texObj->BaseLevel];
707 const GLfloat iw = 1.0/texImage->Width;
708 const GLfloat ih = 1.0/texImage->Height;
709 GLfloat *in = (GLfloat *)VB->TexCoordPtr[i]->data;
710 GLint instride = VB->TexCoordPtr[i]->stride;
711 GLfloat (*out)[4] = store->texcoord[i].data;
712 GLint j;
713
714 store->texcoord[i].size = VB->TexCoordPtr[i]->size;
715 for (j = 0 ; j < VB->Count ; j++) {
716 switch (VB->TexCoordPtr[i]->size) {
717 case 4:
718 out[j][3] = in[3];
719 /* fallthrough */
720 case 3:
721 out[j][2] = in[2];
722 /* fallthrough */
723 default:
724 out[j][0] = in[0] * iw;
725 out[j][1] = in[1] * ih;
726 }
727 in = (GLfloat *)((GLubyte *)in + instride);
728 }
729
730 VB->AttribPtr[VERT_ATTRIB_TEX0+i] = VB->TexCoordPtr[i] = &store->texcoord[i];
731 }
732 }
733
734 return GL_TRUE;
735 }
736
737
738 /* Called the first time stage->run() is invoked.
739 */
740 static GLboolean alloc_texrect_data( GLcontext *ctx,
741 struct tnl_pipeline_stage *stage )
742 {
743 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
744 struct texrect_stage_data *store;
745 GLuint i;
746
747 stage->privatePtr = CALLOC(sizeof(*store));
748 store = TEXRECT_STAGE_DATA(stage);
749 if (!store)
750 return GL_FALSE;
751
752 for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++)
753 _mesa_vector4f_alloc( &store->texcoord[i], 0, VB->Size, 32 );
754
755 return GL_TRUE;
756 }
757
758 static void free_texrect_data( struct tnl_pipeline_stage *stage )
759 {
760 struct texrect_stage_data *store = TEXRECT_STAGE_DATA(stage);
761 GLuint i;
762
763 if (store) {
764 for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++)
765 if (store->texcoord[i].data)
766 _mesa_vector4f_free( &store->texcoord[i] );
767 FREE( store );
768 stage->privatePtr = NULL;
769 }
770 }
771
772 const struct tnl_pipeline_stage _r300_texrect_stage =
773 {
774 "r300 texrect stage", /* name */
775 NULL,
776 alloc_texrect_data,
777 free_texrect_data,
778 NULL,
779 run_texrect_stage
780 };
781