1 /**************************************************************************
3 Copyright (C) 2004 Nicolai Haehnle.
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:
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
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.
26 **************************************************************************/
30 * Nicolai Haehnle <prefect_@gmx.net>
40 #include "simple_list.h"
42 #include "api_arrayelt.h"
43 #include "swrast/swrast.h"
44 #include "swrast_setup/swrast_setup.h"
45 #include "array_cache/acache.h"
47 #include "tnl/t_vp_build.h"
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"
57 #include "r300_program.h"
59 #include "r300_maos.h"
60 #include "r300_emit.h"
62 extern int future_hw_tcl_on
;
64 /**********************************************************************
65 * Hardware rasterization
67 * When we fell back to software TCL, we still try to use the
68 * rasterization hardware for rendering.
69 **********************************************************************/
71 static int r300_get_primitive_type(r300ContextPtr rmesa
, GLcontext
*ctx
, int prim
)
75 switch (prim
& PRIM_MODE_MASK
) {
77 type
=R300_VAP_VF_CNTL__PRIM_POINTS
;
80 type
=R300_VAP_VF_CNTL__PRIM_LINES
;
83 type
=R300_VAP_VF_CNTL__PRIM_LINE_STRIP
;
86 type
=R300_VAP_VF_CNTL__PRIM_LINE_LOOP
;
89 type
=R300_VAP_VF_CNTL__PRIM_TRIANGLES
;
91 case GL_TRIANGLE_STRIP
:
92 type
=R300_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP
;
95 type
=R300_VAP_VF_CNTL__PRIM_TRIANGLE_FAN
;
98 type
=R300_VAP_VF_CNTL__PRIM_QUADS
;
101 type
=R300_VAP_VF_CNTL__PRIM_QUAD_STRIP
;
104 type
=R300_VAP_VF_CNTL__PRIM_POLYGON
;
107 fprintf(stderr
, "%s:%s Do not know how to handle primitive %02x - help me !\n",
108 __FILE__
, __FUNCTION__
,
109 prim
& PRIM_MODE_MASK
);
116 static int r300_get_num_verts(r300ContextPtr rmesa
,
122 char *name
="UNKNOWN";
124 switch (prim
& PRIM_MODE_MASK
) {
131 verts_off
= num_verts
% 2;
136 verts_off
= num_verts
;
141 verts_off
= num_verts
;
145 verts_off
= num_verts
% 3;
147 case GL_TRIANGLE_STRIP
:
150 verts_off
= num_verts
;
152 case GL_TRIANGLE_FAN
:
155 verts_off
= num_verts
;
159 verts_off
= num_verts
% 4;
164 verts_off
= num_verts
;
166 verts_off
= num_verts
% 2;
171 verts_off
= num_verts
;
174 fprintf(stderr
, "%s:%s Do not know how to handle primitive %02x - help me !\n",
175 __FILE__
, __FUNCTION__
,
176 prim
& PRIM_MODE_MASK
);
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
);
188 WARN_ONCE("user error: %d is not a valid number of vertices for primitive %s !\n", num_verts
, name
);
192 return num_verts
- verts_off
;
195 /* Immediate implementation has been removed from CVS. */
197 /* vertex buffer implementation */
199 static void inline fire_EB(PREFIX
unsigned long addr
, int vertex_count
, int type
, int elt_size
)
202 unsigned long addr_a
;
203 unsigned long t_addr
;
204 unsigned long magic_1
, magic_2
;
206 ctx
= rmesa
->radeon
.glCtx
;
208 assert(elt_size
== 2 || elt_size
== 4);
210 if(addr
& (elt_size
-1)){
211 WARN_ONCE("Badly aligned buffer\n");
217 magic_1
= (addr
% 32) / 4;
218 t_addr
= addr
& (~0x1d);
219 magic_2
= (vertex_count
+ 1 + (t_addr
& 0x2)) / 2 + magic_1
;
223 start_packet3(RADEON_CP_PACKET3_3D_DRAW_INDX_2
, 0);
225 e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES
| (vertex_count
<<16) | type
| R300_VAP_VF_CNTL__INDEX_SIZE_32bit
);
227 e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES
| (vertex_count
<<16) | type
);
230 start_packet3(RADEON_CP_PACKET3_INDX_BUFFER
, 2);
232 e32(R300_EB_UNK1
| (0 << 16) | R300_EB_UNK2
);
233 e32(addr
/*& 0xffffffe3*/);
235 e32(R300_EB_UNK1
| (magic_1
<< 16) | R300_EB_UNK2
);
240 e32(vertex_count
/*+ addr_a/4*/); /* Total number of dwords needed? */
242 e32(magic_2
); /* Total number of dwords needed? */
244 //cp_delay(PASS_PREFIX 1);
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
);
252 (void)magic_2
, (void)magic_1
, (void)t_addr
;
258 start_packet3(RADEON_CP_PACKET3_3D_DRAW_INDX_2
, 0);
260 e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES
| (vertex_count
<<16) | type
| R300_VAP_VF_CNTL__INDEX_SIZE_32bit
);
262 e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES
| (vertex_count
<<16) | type
);
265 start_packet3(RADEON_CP_PACKET3_INDX_BUFFER
, 2);
266 e32(R300_EB_UNK1
| (0 << 16) | R300_EB_UNK2
);
267 e32(addr
/*& 0xffffffe3*/);
270 e32(vertex_count
/*+ addr_a/4*/); /* Total number of dwords needed? */
272 e32((vertex_count
+1)/2 /*+ addr_a/4*/); /* Total number of dwords needed? */
274 //cp_delay(PASS_PREFIX 1);
278 static void r300_render_vb_primitive(r300ContextPtr rmesa
,
287 type
=r300_get_primitive_type(rmesa
, ctx
, prim
);
288 num_verts
=r300_get_num_verts(rmesa
, ctx
, end
-start
, prim
);
290 if(type
<0 || num_verts
<= 0)return;
292 if(rmesa
->state
.Elts
){
293 r300EmitAOS(rmesa
, rmesa
->state
.aos_count
, 0);
296 start_index32_packet(num_verts
, type
);
297 for(i
=0; i
< num_verts
; i
++)
298 e32(rmesa
->state
.Elts
[start
+i
]); /* start ? */
301 start_index32_packet(num_verts
, type
);
302 e32(rmesa
->state
.Elts
[start
]);
306 if(num_verts
> 65535){ /* not implemented yet */
307 WARN_ONCE("Too many elts\n");
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);
314 r300EmitAOS(rmesa
, rmesa
->state
.aos_count
, start
);
315 fire_AOS(PASS_PREFIX num_verts
, type
);
319 static GLboolean
r300_run_vb_render(GLcontext
*ctx
,
320 struct tnl_pipeline_stage
*stage
)
322 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
323 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
324 struct vertex_buffer
*VB
= &tnl
->vb
;
328 if (RADEON_DEBUG
& DEBUG_PRIMS
)
329 fprintf(stderr
, "%s\n", __FUNCTION__
);
332 //r300UpdateShaders(rmesa);
334 r300ReleaseArrays(ctx
);
335 r300EmitArrays(ctx
, GL_FALSE
);
337 r300UpdateShaderStates(rmesa
);
339 reg_start(R300_RB3D_DSTCACHE_CTLSTAT
,0);
344 r300EmitState(rmesa
);
346 rmesa
->state
.Elts
= VB
->Elts
;
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
;
353 r300_render_vb_primitive(rmesa
, ctx
, start
, start
+ length
, prim
);
356 reg_start(R300_RB3D_DSTCACHE_CTLSTAT
,0);
369 #ifdef RADEON_VTXFMT_A
371 static void r300_render_vb_primitive_vtxfmt_a(r300ContextPtr rmesa
,
379 type
=r300_get_primitive_type(rmesa
, ctx
, prim
);
380 num_verts
=r300_get_num_verts(rmesa
, ctx
, end
-start
, prim
);
382 if(type
<0 || num_verts
<= 0)return;
384 if(rmesa
->state
.VB
.Elts
){
385 r300EmitAOS(rmesa
, rmesa
->state
.aos_count
, /*0*/start
);
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 ? */
394 //start_index32_packet(num_verts, type);
395 //e32(rmesa->state.Elts[start]);
399 if(num_verts
> 65535){ /* not implemented yet */
400 WARN_ONCE("Too many elts\n");
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
);
408 r300EmitAOS(rmesa
, rmesa
->state
.aos_count
, start
);
409 fire_AOS(PASS_PREFIX num_verts
, type
);
414 void dump_array(struct r300_dma_region
*rvb
, int count
)
416 int *out
= (int *)(rvb
->address
+ rvb
->start
);
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
]);
425 for (ci
=0; ci
< rvb
->aos_size
; ci
++)
426 fprintf(stderr
, "%d ", ((unsigned char *)out
)[ci
]);
427 fprintf(stderr
, "}");
429 out
+= rvb
->aos_stride
;
432 fprintf(stderr
, "\n");
435 void dump_dt(struct dt
*dt
, int count
)
440 fprintf(stderr
, "base at %p ", out
);
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
]);
448 for (ci
=0; ci
< dt
->size
; ci
++)
449 fprintf(stderr
, "%d ", ((unsigned char *)out
)[ci
]);
450 fprintf(stderr
, "}");
452 out
= (int *)((char *)out
+ dt
->stride
);
455 fprintf(stderr
, "\n");
459 /*static */GLboolean
r300_run_vb_render_vtxfmt_a(GLcontext
*ctx
,
460 struct tnl_pipeline_stage
*stage
)
462 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
463 //TNLcontext *tnl = TNL_CONTEXT(ctx);
464 struct radeon_vertex_buffer
*VB
= &rmesa
->state
.VB
; //&tnl->vb;
468 if (RADEON_DEBUG
& DEBUG_PRIMS
)
469 fprintf(stderr
, "%s\n", __FUNCTION__
);
471 r300UpdateShaders(rmesa
);
472 if (rmesa
->state
.VB
.LockCount
== 0 || 1) {
473 r300ReleaseArrays(ctx
);
474 r300EmitArraysVtx(ctx
, GL_FALSE
);
476 r300UpdateShaderStates(rmesa
);
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
);
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
);
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
);
498 r300ReleaseArrays(ctx
);
499 r300EmitArraysVtx(ctx
, GL_FALSE
);
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
);
509 reg_start(R300_RB3D_DSTCACHE_CTLSTAT
,0);
515 reg_start(R300_VAP_PVS_WAITIDLE
,0);
518 r300EmitState(rmesa
);
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
;
525 r300_render_vb_primitive_vtxfmt_a(rmesa
, ctx
, start
, start
+ length
, prim
);
528 reg_start(R300_RB3D_DSTCACHE_CTLSTAT
,0);
529 e32(0x0000000a/*0x2*/);
532 e32(0x00000003/*0x1*/);
541 #define FALLBACK_IF(expr) \
544 if (1 || RADEON_DEBUG & DEBUG_FALLBACKS) \
545 WARN_ONCE("fallback:%s\n", #expr); \
550 GLboolean
r300Fallback(GLcontext
*ctx
)
553 //FALLBACK_IF(ctx->RenderMode != GL_RENDER); // We do not do SELECT or FEEDBACK (yet ?)
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
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
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
571 FALLBACK_IF(ctx
->Line
.StippleFlag
);
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
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.
589 static GLboolean
r300_run_render(GLcontext
*ctx
,
590 struct tnl_pipeline_stage
*stage
)
593 if (RADEON_DEBUG
& DEBUG_PRIMS
)
594 fprintf(stderr
, "%s\n", __FUNCTION__
);
596 if (r300Fallback(ctx
))
599 return r300_run_vb_render(ctx
, stage
);
602 const struct tnl_pipeline_stage _r300_render_stage
= {
608 r300_run_render
/* run */
611 static GLboolean
r300_run_tcl_render(GLcontext
*ctx
,
612 struct tnl_pipeline_stage
*stage
)
614 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
615 struct r300_vertex_program
*vp
;
618 hw_tcl_on
=future_hw_tcl_on
;
620 if (RADEON_DEBUG
& DEBUG_PRIMS
)
621 fprintf(stderr
, "%s\n", __FUNCTION__
);
622 if(hw_tcl_on
== GL_FALSE
)
625 if (r300Fallback(ctx
)) {
626 hw_tcl_on
= GL_FALSE
;
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
;
636 r300UpdateShaders(rmesa
);
638 vp
= (struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
);
639 #if 0 /* Draw every second request with software arb vp */
642 //vp->native = GL_FALSE;
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
;
650 cache
= tnl
->vp_cache
;
651 c
= cache
->items
[0xc000cc0e % cache
->size
];
653 if(c
&& c
->data
== vp
)
654 vp
->native
= GL_FALSE
;
658 vp
->native
= GL_FALSE
;
660 if (vp
->native
== GL_FALSE
) {
661 hw_tcl_on
= GL_FALSE
;
664 //r300UpdateShaderStates(rmesa);
666 return r300_run_vb_render(ctx
, stage
);
669 const struct tnl_pipeline_stage _r300_tcl_stage
= {
675 r300_run_tcl_render
/* run */
678 /* R300 texture rectangle expects coords in 0..1 range, not 0..dimension
679 * as in the extension spec. Need to translate here.
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)
684 struct texrect_stage_data
{
685 GLvector4f texcoord
[MAX_TEXTURE_UNITS
];
688 #define TEXRECT_STAGE_DATA(stage) ((struct texrect_stage_data *)stage->privatePtr)
691 static GLboolean
run_texrect_stage( GLcontext
*ctx
,
692 struct tnl_pipeline_stage
*stage
)
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
;
700 if (rmesa
->radeon
.Fallback
)
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
;
714 store
->texcoord
[i
].size
= VB
->TexCoordPtr
[i
]->size
;
715 for (j
= 0 ; j
< VB
->Count
; j
++) {
716 switch (VB
->TexCoordPtr
[i
]->size
) {
724 out
[j
][0] = in
[0] * iw
;
725 out
[j
][1] = in
[1] * ih
;
727 in
= (GLfloat
*)((GLubyte
*)in
+ instride
);
730 VB
->AttribPtr
[VERT_ATTRIB_TEX0
+i
] = VB
->TexCoordPtr
[i
] = &store
->texcoord
[i
];
738 /* Called the first time stage->run() is invoked.
740 static GLboolean
alloc_texrect_data( GLcontext
*ctx
,
741 struct tnl_pipeline_stage
*stage
)
743 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
744 struct texrect_stage_data
*store
;
747 stage
->privatePtr
= CALLOC(sizeof(*store
));
748 store
= TEXRECT_STAGE_DATA(stage
);
752 for (i
= 0 ; i
< ctx
->Const
.MaxTextureUnits
; i
++)
753 _mesa_vector4f_alloc( &store
->texcoord
[i
], 0, VB
->Size
, 32 );
758 static void free_texrect_data( struct tnl_pipeline_stage
*stage
)
760 struct texrect_stage_data
*store
= TEXRECT_STAGE_DATA(stage
);
764 for (i
= 0 ; i
< MAX_TEXTURE_UNITS
; i
++)
765 if (store
->texcoord
[i
].data
)
766 _mesa_vector4f_free( &store
->texcoord
[i
] );
768 stage
->privatePtr
= NULL
;
772 const struct tnl_pipeline_stage _r300_texrect_stage
=
774 "r300 texrect stage", /* name */