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"
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"
56 #include "r300_program.h"
58 #include "r300_maos.h"
59 #include "r300_emit.h"
61 /**********************************************************************
62 * Hardware rasterization
64 * When we fell back to software TCL, we still try to use the
65 * rasterization hardware for rendering.
66 **********************************************************************/
68 static int r300_get_primitive_type(r300ContextPtr rmesa
, GLcontext
*ctx
, int prim
)
70 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
71 struct vertex_buffer
*VB
= &tnl
->vb
;
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
,
121 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
122 struct vertex_buffer
*VB
= &tnl
->vb
;
124 int type
=-1, verts_off
=0;
125 char *name
="UNKNOWN";
127 switch (prim
& PRIM_MODE_MASK
) {
134 verts_off
= num_verts
% 2;
139 verts_off
= num_verts
;
144 verts_off
= num_verts
;
148 verts_off
= num_verts
% 3;
150 case GL_TRIANGLE_STRIP
:
153 verts_off
= num_verts
;
155 case GL_TRIANGLE_FAN
:
158 verts_off
= num_verts
;
162 verts_off
= num_verts
% 4;
167 verts_off
= num_verts
;
169 verts_off
= num_verts
% 2;
174 verts_off
= num_verts
;
177 fprintf(stderr
, "%s:%s Do not know how to handle primitive %02x - help me !\n",
178 __FILE__
, __FUNCTION__
,
179 prim
& PRIM_MODE_MASK
);
184 if(num_verts
- verts_off
== 0){
185 WARN_ONCE("user error: Need more than %d vertices to draw primitive %s !\n", num_verts
, name
);
190 WARN_ONCE("user error: %d is not a valid number of vertices for primitive %s !\n", num_verts
, name
);
193 return num_verts
- verts_off
;
196 void dump_inputs(GLcontext
*ctx
, int render_inputs
)
199 fprintf(stderr
, "inputs:");
200 fprintf(stderr
, "%08x ", render_inputs
);
202 if(render_inputs
& _TNL_BIT_POS
)
203 fprintf(stderr
, "_TNL_BIT_POS ");
204 if(render_inputs
& _TNL_BIT_NORMAL
)
205 fprintf(stderr
, "_TNL_BIT_NORMAL ");
207 /* color components */
208 if(render_inputs
& _TNL_BIT_COLOR0
)
209 fprintf(stderr
, "_TNL_BIT_COLOR0 ");
210 if(render_inputs
& _TNL_BIT_COLOR1
)
211 fprintf(stderr
, "_TNL_BIT_COLOR1 ");
213 if(render_inputs
& _TNL_BIT_FOG
)
214 fprintf(stderr
, "_TNL_BIT_FOG ");
216 /* texture coordinates */
217 for(k
=0;k
< ctx
->Const
.MaxTextureUnits
;k
++)
218 if(render_inputs
& (_TNL_BIT_TEX0
<<k
))
219 fprintf(stderr
, "_TNL_BIT_TEX%d ", k
);
221 if(render_inputs
& _TNL_BIT_INDEX
)
222 fprintf(stderr
, "_TNL_BIT_INDEX ");
223 if(render_inputs
& _TNL_BIT_POINTSIZE
)
224 fprintf(stderr
, "_TNL_BIT_POINTSIZE ");
226 fprintf(stderr
, "\n");
229 /* This function compiles GL context into state registers that
230 describe data routing inside of R300 pipeline.
232 In particular, it programs input_route, output_vtx_fmt, texture
233 unit configuration and gb_output_vtx_fmt
235 This function encompasses setup_AOS() from r300_lib.c
241 /* Immediate implementation - vertex data is sent via command stream */
243 static GLfloat default_vector
[4]={0.0, 0.0, 0.0, 1.0};
245 #define output_vector(v, i) \
248 for(_i=0;_i<v->size;_i++){ \
249 efloat(VEC_ELT(v, GLfloat, i)[_i]); \
251 for(_i=v->size;_i<4;_i++){ \
252 efloat(default_vector[_i]); \
256 /* Immediate implementation - vertex data is sent via command stream */
258 static void r300_render_immediate_primitive(r300ContextPtr rmesa
,
264 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
265 struct vertex_buffer
*VB
= &tnl
->vb
;
266 GLuint i
, render_inputs
;
267 int k
, type
, num_verts
;
270 type
=r300_get_primitive_type(rmesa
, ctx
, prim
);
271 num_verts
=r300_get_num_verts(rmesa
, ctx
, end
-start
, prim
);
274 fprintf(stderr
,"ObjPtr: size=%d stride=%d\n",
275 VB
->ObjPtr
->size
, VB
->ObjPtr
->stride
);
276 fprintf(stderr
,"ColorPtr[0]: size=%d stride=%d\n",
277 VB
->ColorPtr
[0]->size
, VB
->ColorPtr
[0]->stride
);
278 fprintf(stderr
,"TexCoordPtr[0]: size=%d stride=%d\n",
279 VB
->TexCoordPtr
[0]->size
, VB
->TexCoordPtr
[0]->stride
);
282 if(type
<0 || num_verts
<= 0)return;
285 WARN_ONCE("FIXME: Don't know how to handle GL_ARB_vertex_buffer_object correctly\n");
288 /* A packet cannot have more than 16383 data words.. */
289 if((num_verts
*4*rmesa
->state
.aos_count
)>16380){
290 WARN_ONCE("Too many vertices to paint. Fix me !\n");
294 //fprintf(stderr, "aos_count=%d start=%d end=%d\n", rmesa->state.aos_count, start, end);
296 if(rmesa
->state
.aos_count
==0){
297 WARN_ONCE("Aeiee ! aos_count==0, while it shouldn't. Skipping rendering\n");
301 render_inputs
= rmesa
->state
.render_inputs
;
304 WARN_ONCE("Aeiee ! render_inputs==0. Skipping rendering.\n");
308 //dump_inputs(ctx, render_inputs); return ;
310 start_immediate_packet(num_verts
, type
, 4*rmesa
->state
.aos_count
);
312 for(i
=start
;i
<start
+num_verts
;i
++){
314 fprintf(stderr
, "* (%f %f %f %f) (%f %f %f %f)\n",
315 VEC_ELT(VB
->ObjPtr
, GLfloat
, i
)[0],
316 VEC_ELT(VB
->ObjPtr
, GLfloat
, i
)[1],
317 VEC_ELT(VB
->ObjPtr
, GLfloat
, i
)[2],
318 VEC_ELT(VB
->ObjPtr
, GLfloat
, i
)[3],
320 VEC_ELT(VB
->ColorPtr
[0], GLfloat
, i
)[0],
321 VEC_ELT(VB
->ColorPtr
[0], GLfloat
, i
)[1],
322 VEC_ELT(VB
->ColorPtr
[0], GLfloat
, i
)[2],
323 VEC_ELT(VB
->ColorPtr
[0], GLfloat
, i
)[3]
329 if(render_inputs
& _TNL_BIT_POS
)
330 output_vector(VB
->ObjPtr
, i
);
331 if(render_inputs
& _TNL_BIT_NORMAL
)
332 output_vector(VB
->NormalPtr
, i
);
334 /* color components */
335 if(render_inputs
& _TNL_BIT_COLOR0
)
336 output_vector(VB
->ColorPtr
[0], i
);
337 if(render_inputs
& _TNL_BIT_COLOR1
)
338 output_vector(VB
->SecondaryColorPtr
[0], i
);
340 /* if(render_inputs & _TNL_BIT_FOG) // Causes lock ups when immediate mode is on
341 output_vector(VB->FogCoordPtr, i);*/
343 /* texture coordinates */
344 for(k
=0;k
< ctx
->Const
.MaxTextureUnits
;k
++)
345 if(render_inputs
& (_TNL_BIT_TEX0
<<k
))
346 output_vector(VB
->TexCoordPtr
[k
], i
);
348 if(render_inputs
& _TNL_BIT_INDEX
)
349 output_vector(VB
->IndexPtr
[0], i
);
350 if(render_inputs
& _TNL_BIT_POINTSIZE
)
351 output_vector(VB
->PointSizePtr
, i
);
357 static GLboolean
r300_run_immediate_render(GLcontext
*ctx
,
358 struct tnl_pipeline_stage
*stage
)
360 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
361 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
362 struct vertex_buffer
*VB
= &tnl
->vb
;
364 /* Only do 2d textures */
365 struct gl_texture_object
*to
=ctx
->Texture
.Unit
[0].Current2D
;
366 r300TexObjPtr t
=to
->DriverData
;
370 /* Update texture state - needs to be done only when actually changed..
371 All the time for now.. */
374 if (RADEON_DEBUG
== DEBUG_PRIMS
)
375 fprintf(stderr
, "%s\n", __FUNCTION__
);
377 #if 1 /* we need this, somehow */
378 /* Flush state - make sure command buffer is nice and large */
380 /* Make sure we have enough space */
382 /* Count is very imprecize, but should be good upper bound */
383 r300EnsureCmdBufSpace(rmesa
, rmesa
->hw
.max_state_size
+ 4+2+30
384 +VB
->PrimitiveCount
*(1+8)+VB
->Count
*4*rmesa
->state
.texture
.tc_count
+4, __FUNCTION__
);
387 /* needed before starting 3d operation .. */
388 reg_start(R300_RB3D_DSTCACHE_CTLSTAT
,0);
395 #if 0 /* looks like the Z offset issue got fixed */
396 rmesa
->hw
.vte
.cmd
[1] = R300_VPORT_X_SCALE_ENA
397 | R300_VPORT_X_OFFSET_ENA
398 | R300_VPORT_Y_SCALE_ENA
399 | R300_VPORT_Y_OFFSET_ENA
401 R300_STATECHANGE(rmesa
, vte
);
406 /* Magic register - note it is right after 20b0 */
409 if(rmesa
->state
.texture
.tc_count
>0){
415 r300EmitState(rmesa
);
418 reg_start(R300_RB3D_COLORMASK
, 0);
421 vsf_start_fragment(0x406, 4);
427 vsf_start_fragment(0x400, 4);
434 /* Setup INPUT_ROUTE and INPUT_CNTL */
435 r300EmitArrays(ctx
, GL_TRUE
);
437 /* Why do we need this for immediate mode?? Vertex processor needs it to know proper regs */
438 // r300EmitLOAD_VBPNTR(rmesa, 0);
439 /* Okay, it seems I misunderstood something, EmitAOS does the same thing */
440 r300EmitAOS(rmesa
, rmesa
->state
.aos_count
, 0);
442 for(i
=0; i
< VB
->PrimitiveCount
; i
++){
443 GLuint prim
= VB
->Primitive
[i
].mode
;
444 GLuint start
= VB
->Primitive
[i
].start
;
445 GLuint length
= VB
->Primitive
[i
].count
;
447 r300_render_immediate_primitive(rmesa
, ctx
, start
, start
+ length
, prim
);
450 /* This sequence is required after any 3d drawing packet
451 I suspect it work arounds a bug (or deficiency) in hardware */
453 reg_start(R300_RB3D_DSTCACHE_CTLSTAT
,0);
462 /* vertex buffer implementation */
464 static void inline fire_EB(PREFIX
unsigned long addr
, int vertex_count
, int type
)
467 unsigned long addr_a
;
469 addr_a
= addr
& 0x1c;
473 start_packet3(RADEON_CP_PACKET3_3D_DRAW_INDX_2
, 0);
474 /* TODO: Check if R300_VAP_VF_CNTL__INDEX_SIZE_32bit works. */
475 e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES
| (vertex_count
<<16) | type
);
477 start_packet3(RADEON_CP_PACKET3_INDX_BUFFER
, 2);
478 e32(R300_EB_UNK1
| (addr_a
<< 16) | R300_EB_UNK2
);
479 e32(addr
& 0xffffffe3);
480 e32((vertex_count
+1)/2 + addr_a
/4);
483 static void r300_render_vb_primitive(r300ContextPtr rmesa
,
490 radeonScreenPtr rsp
=rmesa
->radeon
.radeonScreen
;
492 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
493 struct vertex_buffer
*VB
= &tnl
->vb
;
496 type
=r300_get_primitive_type(rmesa
, ctx
, prim
);
497 num_verts
=r300_get_num_verts(rmesa
, ctx
, end
-start
, prim
);
499 if(type
<0 || num_verts
<= 0)return;
501 if(rmesa
->state
.Elts
){
502 r300EmitAOS(rmesa
, rmesa
->state
.aos_count
, 0);
504 start_index32_packet(num_verts
, type
);
505 for(i
=0; i
< num_verts
; i
++)
506 e32(rmesa
->state
.Elts
[start
+i
]); /* start ? */
508 WARN_ONCE("Rendering with elt buffers\n");
510 start_index32_packet(num_verts
, type
);
511 e32(rmesa
->state
.Elts
[start
]);
515 if(num_verts
> 65535){ /* not implemented yet */
518 r300EmitElts(ctx
, rmesa
->state
.Elts
+start
, num_verts
);
519 fire_EB(PASS_PREFIX
GET_START(&(rmesa
->state
.elt_dma
)), num_verts
, type
);
522 r300EmitAOS(rmesa
, rmesa
->state
.aos_count
, start
);
523 fire_AOS(PASS_PREFIX num_verts
, type
);
527 static GLboolean
r300_run_vb_render(GLcontext
*ctx
,
528 struct tnl_pipeline_stage
*stage
)
530 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
531 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
532 struct vertex_buffer
*VB
= &tnl
->vb
;
536 if (RADEON_DEBUG
& DEBUG_PRIMS
)
537 fprintf(stderr
, "%s\n", __FUNCTION__
);
540 r300ReleaseArrays(ctx
);
541 r300EmitArrays(ctx
, GL_FALSE
);
542 //dump_inputs(ctx, rmesa->state.render_inputs);
544 // LOCK_HARDWARE(&(rmesa->radeon));
546 reg_start(R300_RB3D_DSTCACHE_CTLSTAT
,0);
551 r300EmitState(rmesa
);
553 rmesa
->state
.Elts
= VB
->Elts
;
555 for(i
=0; i
< VB
->PrimitiveCount
; i
++){
556 GLuint prim
= VB
->Primitive
[i
].mode
;
557 GLuint start
= VB
->Primitive
[i
].start
;
558 GLuint length
= VB
->Primitive
[i
].count
;
560 r300_render_vb_primitive(rmesa
, ctx
, start
, start
+ length
, prim
);
563 reg_start(R300_RB3D_DSTCACHE_CTLSTAT
,0);
569 // end_3d(PASS_PREFIX_VOID);
571 /* Flush state - we are done drawing.. */
572 // r300FlushCmdBufLocked(rmesa, __FUNCTION__);
573 // radeonWaitForIdleLocked(&(rmesa->radeon));
575 // UNLOCK_HARDWARE(&(rmesa->radeon));
580 * Called by the pipeline manager to render a batch of primitives.
581 * We can return true to pass on to the next stage (i.e. software
582 * rasterization) or false to indicate that the pipeline has finished
583 * after we render something.
585 static GLboolean
r300_run_render(GLcontext
*ctx
,
586 struct tnl_pipeline_stage
*stage
)
588 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
589 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
590 struct vertex_buffer
*VB
= &tnl
->vb
;
593 if (RADEON_DEBUG
& DEBUG_PRIMS
)
594 fprintf(stderr
, "%s\n", __FUNCTION__
);
600 return r300_run_immediate_render(ctx
, stage
);
602 return r300_run_vb_render(ctx
, stage
);
609 mgaContextPtr mmesa
= MGA_CONTEXT(ctx
);
610 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
611 struct vertex_buffer
*VB
= &tnl
->vb
;
614 /* Don't handle clipping or indexed vertices or vertex manipulations.
616 if (mmesa
->RenderIndex
!= 0 ||
617 !mga_validate_render( ctx
, VB
)) {
621 tnl
->Driver
.Render
.Start( ctx
);
622 mmesa
->SetupNewInputs
= ~0;
624 for (i
= 0 ; i
< VB
->PrimitiveCount
; i
++)
626 GLuint prim
= VB
->Primitive
[i
].mode
;
627 GLuint start
= VB
->Primitive
[i
].start
;
628 GLuint length
= VB
->Primitive
[i
].count
;
633 mga_render_tab_verts
[prim
& PRIM_MODE_MASK
]( ctx
, start
, start
+ length
,
637 tnl
->Driver
.Render
.Finish( ctx
);
639 return GL_FALSE
; /* finished the pipe */
645 * Called by the pipeline manager once before rendering.
646 * We check the GL state here to
647 * a) decide whether we can do the current state in hardware and
648 * b) update hardware registers
650 #define FALLBACK_IF(expr) \
653 if (1 || RADEON_DEBUG & DEBUG_FALLBACKS) \
654 fprintf(stderr, "%s: fallback:%s\n", \
655 __FUNCTION__, #expr); \
656 stage->active = GL_FALSE; \
661 static void r300_check_render(GLcontext
*ctx
, struct tnl_pipeline_stage
*stage
)
663 r300ContextPtr r300
= R300_CONTEXT(ctx
);
666 if (RADEON_DEBUG
& DEBUG_STATE
)
667 fprintf(stderr
, "%s\n", __FUNCTION__
);
669 /* We only support rendering in hardware for now */
670 if (ctx
->RenderMode
!= GL_RENDER
) {
671 stage
->active
= GL_FALSE
;
676 /* I'm almost certain I forgot something here */
677 #if 0 /* These should work now.. */
678 FALLBACK_IF(ctx
->Color
.DitherFlag
);
679 FALLBACK_IF(ctx
->Color
.AlphaEnabled
); // GL_ALPHA_TEST
680 FALLBACK_IF(ctx
->Color
.BlendEnabled
); // GL_BLEND
681 FALLBACK_IF(ctx
->Polygon
.OffsetFill
); // GL_POLYGON_OFFSET_FILL
683 //FALLBACK_IF(ctx->Polygon.OffsetPoint); // GL_POLYGON_OFFSET_POINT
684 //FALLBACK_IF(ctx->Polygon.OffsetLine); // GL_POLYGON_OFFSET_LINE
685 //FALLBACK_IF(ctx->Stencil.Enabled); // GL_STENCIL_TEST
687 //FALLBACK_IF(ctx->Fog.Enabled); // GL_FOG disable as swtcl doesnt seem to support this
688 //FALLBACK_IF(ctx->Polygon.SmoothFlag); // GL_POLYGON_SMOOTH disabling to get blender going
689 FALLBACK_IF(ctx
->Polygon
.StippleFlag
); // GL_POLYGON_STIPPLE
690 FALLBACK_IF(ctx
->Multisample
.Enabled
); // GL_MULTISAMPLE_ARB
692 #if 0 /* ut2k3 fails to start if this is on */
693 /* One step at a time - let one texture pass.. */
694 for (i
= 1; i
< ctx
->Const
.MaxTextureUnits
; i
++)
695 FALLBACK_IF(ctx
->Texture
.Unit
[i
].Enabled
);
698 /* Assumed factor reg is found but pattern is still missing */
699 //FALLBACK_IF(ctx->Line.StippleFlag); // GL_LINE_STIPPLE disabling to get blender going
701 /* HW doesnt appear to directly support these */
702 //FALLBACK_IF(ctx->Line.SmoothFlag); // GL_LINE_SMOOTH disabling to get blender going
703 FALLBACK_IF(ctx
->Point
.SmoothFlag
); // GL_POINT_SMOOTH
704 /* Rest could be done with vertex fragments */
705 if (ctx
->Extensions
.NV_point_sprite
|| ctx
->Extensions
.ARB_point_sprite
)
706 FALLBACK_IF(ctx
->Point
.PointSprite
); // GL_POINT_SPRITE_NV
707 //GL_POINT_DISTANCE_ATTENUATION_ARB
708 //GL_POINT_FADE_THRESHOLD_SIZE_ARB
710 /* let r300_run_render do its job */
712 stage
->active
= GL_FALSE
;
717 static void dtr(struct tnl_pipeline_stage
*stage
)
722 const struct tnl_pipeline_stage _r300_render_stage
= {
724 _NEW_ALL
, /* re-check (always re-check for now) */
725 0, /* re-run (always runs) */
726 GL_TRUE
, /* active */
727 0, 0, /* inputs (set in check_render), outputs */
728 0, 0, /* changed_inputs, private */
729 dtr
, /* destructor */
730 r300_check_render
, /* check */
731 r300_run_render
/* run */