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 extern int future_hw_tcl_on
;
63 /**********************************************************************
64 * Hardware rasterization
66 * When we fell back to software TCL, we still try to use the
67 * rasterization hardware for rendering.
68 **********************************************************************/
70 static int r300_get_primitive_type(r300ContextPtr rmesa
, GLcontext
*ctx
, int prim
)
72 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
73 struct vertex_buffer
*VB
= &tnl
->vb
;
77 switch (prim
& PRIM_MODE_MASK
) {
79 type
=R300_VAP_VF_CNTL__PRIM_POINTS
;
82 type
=R300_VAP_VF_CNTL__PRIM_LINES
;
85 type
=R300_VAP_VF_CNTL__PRIM_LINE_STRIP
;
88 type
=R300_VAP_VF_CNTL__PRIM_LINE_LOOP
;
91 type
=R300_VAP_VF_CNTL__PRIM_TRIANGLES
;
93 case GL_TRIANGLE_STRIP
:
94 type
=R300_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP
;
97 type
=R300_VAP_VF_CNTL__PRIM_TRIANGLE_FAN
;
100 type
=R300_VAP_VF_CNTL__PRIM_QUADS
;
103 type
=R300_VAP_VF_CNTL__PRIM_QUAD_STRIP
;
106 type
=R300_VAP_VF_CNTL__PRIM_POLYGON
;
109 fprintf(stderr
, "%s:%s Do not know how to handle primitive %02x - help me !\n",
110 __FILE__
, __FUNCTION__
,
111 prim
& PRIM_MODE_MASK
);
118 static int r300_get_num_verts(r300ContextPtr rmesa
,
123 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
124 struct vertex_buffer
*VB
= &tnl
->vb
;
126 int type
=-1, verts_off
=0;
127 char *name
="UNKNOWN";
129 switch (prim
& PRIM_MODE_MASK
) {
136 verts_off
= num_verts
% 2;
141 verts_off
= num_verts
;
146 verts_off
= num_verts
;
150 verts_off
= num_verts
% 3;
152 case GL_TRIANGLE_STRIP
:
155 verts_off
= num_verts
;
157 case GL_TRIANGLE_FAN
:
160 verts_off
= num_verts
;
164 verts_off
= num_verts
% 4;
169 verts_off
= num_verts
;
171 verts_off
= num_verts
% 2;
176 verts_off
= num_verts
;
179 fprintf(stderr
, "%s:%s Do not know how to handle primitive %02x - help me !\n",
180 __FILE__
, __FUNCTION__
,
181 prim
& PRIM_MODE_MASK
);
186 if(num_verts
- verts_off
== 0){
187 WARN_ONCE("user error: Need more than %d vertices to draw primitive %s !\n", num_verts
, name
);
192 WARN_ONCE("user error: %d is not a valid number of vertices for primitive %s !\n", num_verts
, name
);
195 return num_verts
- verts_off
;
198 /* This function compiles GL context into state registers that
199 describe data routing inside of R300 pipeline.
201 In particular, it programs input_route, output_vtx_fmt, texture
202 unit configuration and gb_output_vtx_fmt
204 This function encompasses setup_AOS() from r300_lib.c
210 /* Immediate implementation - vertex data is sent via command stream */
212 static GLfloat default_vector
[4]={0.0, 0.0, 0.0, 1.0};
214 #define output_vector(v, i) { \
216 for(_i=0;_i<v->size;_i++){ \
218 efloat(VEC_ELT(v, GLfloat, VB->Elts[i])[_i]); \
220 efloat(VEC_ELT(v, GLfloat, i)[_i]); \
223 for(_i=v->size;_i<4;_i++){ \
224 efloat(default_vector[_i]); \
228 /* Immediate implementation - vertex data is sent via command stream */
230 static void r300_render_immediate_primitive(r300ContextPtr rmesa
,
236 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
237 struct vertex_buffer
*VB
= &tnl
->vb
;
238 GLuint i
, render_inputs
;
239 int k
, type
, num_verts
;
242 type
=r300_get_primitive_type(rmesa
, ctx
, prim
);
243 num_verts
=r300_get_num_verts(rmesa
, ctx
, end
-start
, prim
);
246 fprintf(stderr
,"ObjPtr: size=%d stride=%d\n",
247 VB
->ObjPtr
->size
, VB
->ObjPtr
->stride
);
248 fprintf(stderr
,"ColorPtr[0]: size=%d stride=%d\n",
249 VB
->ColorPtr
[0]->size
, VB
->ColorPtr
[0]->stride
);
250 fprintf(stderr
,"TexCoordPtr[0]: size=%d stride=%d\n",
251 VB
->TexCoordPtr
[0]->size
, VB
->TexCoordPtr
[0]->stride
);
254 if(type
<0 || num_verts
<= 0)return;
257 WARN_ONCE("FIXME: Don't know how to handle GL_ARB_vertex_buffer_object correctly\n");
260 /* A packet cannot have more than 16383 data words.. */
261 if((num_verts
*4*rmesa
->state
.aos_count
)>16380){
262 WARN_ONCE("Too many vertices to paint. Fix me !\n");
266 //fprintf(stderr, "aos_count=%d start=%d end=%d\n", rmesa->state.aos_count, start, end);
268 if(rmesa
->state
.aos_count
==0){
269 WARN_ONCE("Aeiee ! aos_count==0, while it shouldn't. Skipping rendering\n");
273 render_inputs
= rmesa
->state
.render_inputs
;
276 WARN_ONCE("Aeiee ! render_inputs==0. Skipping rendering.\n");
281 start_immediate_packet(num_verts
, type
, 4*rmesa
->state
.aos_count
);
283 for(i
=start
;i
<start
+num_verts
;i
++){
285 fprintf(stderr
, "* (%f %f %f %f) (%f %f %f %f)\n",
286 VEC_ELT(VB
->ObjPtr
, GLfloat
, i
)[0],
287 VEC_ELT(VB
->ObjPtr
, GLfloat
, i
)[1],
288 VEC_ELT(VB
->ObjPtr
, GLfloat
, i
)[2],
289 VEC_ELT(VB
->ObjPtr
, GLfloat
, i
)[3],
291 VEC_ELT(VB
->ColorPtr
[0], GLfloat
, i
)[0],
292 VEC_ELT(VB
->ColorPtr
[0], GLfloat
, i
)[1],
293 VEC_ELT(VB
->ColorPtr
[0], GLfloat
, i
)[2],
294 VEC_ELT(VB
->ColorPtr
[0], GLfloat
, i
)[3]
300 if(render_inputs
& _TNL_BIT_POS
)
301 output_vector(VB
->ObjPtr
, i
);
302 if(render_inputs
& _TNL_BIT_NORMAL
)
303 output_vector(VB
->NormalPtr
, i
);
305 /* color components */
306 if(render_inputs
& _TNL_BIT_COLOR0
)
307 output_vector(VB
->ColorPtr
[0], i
);
308 if(render_inputs
& _TNL_BIT_COLOR1
)
309 output_vector(VB
->SecondaryColorPtr
[0], i
);
311 /* if(render_inputs & _TNL_BIT_FOG) // Causes lock ups when immediate mode is on
312 output_vector(VB->FogCoordPtr, i);*/
314 /* texture coordinates */
315 for(k
=0;k
< ctx
->Const
.MaxTextureUnits
;k
++)
316 if(render_inputs
& (_TNL_BIT_TEX0
<<k
))
317 output_vector(VB
->TexCoordPtr
[k
], i
);
319 if(render_inputs
& _TNL_BIT_INDEX
)
320 output_vector(VB
->IndexPtr
[0], i
);
321 if(render_inputs
& _TNL_BIT_POINTSIZE
)
322 output_vector(VB
->PointSizePtr
, i
);
328 static GLboolean
r300_run_immediate_render(GLcontext
*ctx
,
329 struct tnl_pipeline_stage
*stage
)
331 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
332 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
333 struct vertex_buffer
*VB
= &tnl
->vb
;
335 /* Only do 2d textures */
336 struct gl_texture_object
*to
=ctx
->Texture
.Unit
[0].Current2D
;
337 r300TexObjPtr t
=to
->DriverData
;
341 /* Update texture state - needs to be done only when actually changed..
342 All the time for now.. */
345 if (RADEON_DEBUG
== DEBUG_PRIMS
)
346 fprintf(stderr
, "%s\n", __FUNCTION__
);
348 #if 1 /* we need this, somehow */
349 /* Flush state - make sure command buffer is nice and large */
351 /* Make sure we have enough space */
353 /* Count is very imprecize, but should be good upper bound */
354 r300EnsureCmdBufSpace(rmesa
, rmesa
->hw
.max_state_size
+ 4+2+30
355 +VB
->PrimitiveCount
*(1+8)+VB
->Count
*4*rmesa
->state
.texture
.tc_count
+4, __FUNCTION__
);
358 /* needed before starting 3d operation .. */
359 reg_start(R300_RB3D_DSTCACHE_CTLSTAT
,0);
366 #if 0 /* looks like the Z offset issue got fixed */
367 rmesa
->hw
.vte
.cmd
[1] = R300_VPORT_X_SCALE_ENA
368 | R300_VPORT_X_OFFSET_ENA
369 | R300_VPORT_Y_SCALE_ENA
370 | R300_VPORT_Y_OFFSET_ENA
372 R300_STATECHANGE(rmesa
, vte
);
377 /* Magic register - note it is right after 20b0 */
380 if(rmesa
->state
.texture
.tc_count
>0){
386 r300EmitState(rmesa
);
388 /* Setup INPUT_ROUTE and INPUT_CNTL */
389 r300EmitArrays(ctx
, GL_TRUE
);
391 /* Why do we need this for immediate mode?? Vertex processor needs it to know proper regs */
392 // r300EmitLOAD_VBPNTR(rmesa, 0);
393 /* Okay, it seems I misunderstood something, EmitAOS does the same thing */
394 r300EmitAOS(rmesa
, rmesa
->state
.aos_count
, 0);
396 for(i
=0; i
< VB
->PrimitiveCount
; i
++){
397 GLuint prim
= VB
->Primitive
[i
].mode
;
398 GLuint start
= VB
->Primitive
[i
].start
;
399 GLuint length
= VB
->Primitive
[i
].count
;
401 r300_render_immediate_primitive(rmesa
, ctx
, start
, start
+ length
, prim
);
404 /* This sequence is required after any 3d drawing packet
405 I suspect it work arounds a bug (or deficiency) in hardware */
407 reg_start(R300_RB3D_DSTCACHE_CTLSTAT
,0);
417 /* vertex buffer implementation */
419 static void inline fire_EB(PREFIX
unsigned long addr
, int vertex_count
, int type
)
422 unsigned long addr_a
;
425 WARN_ONCE("Badly aligned buffer\n");
428 addr_a
= 0; /*addr & 0x1c;*/
432 start_packet3(RADEON_CP_PACKET3_3D_DRAW_INDX_2
, 0);
433 /* TODO: R300_VAP_VF_CNTL__INDEX_SIZE_32bit . */
434 e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES
| (vertex_count
<<16) | type
);
436 start_packet3(RADEON_CP_PACKET3_INDX_BUFFER
, 2);
437 e32(R300_EB_UNK1
| (addr_a
<< 16) | R300_EB_UNK2
);
438 e32(addr
/*& 0xffffffe3*/);
439 e32((vertex_count
+1)/2 /*+ addr_a/4*/); /* Total number of dwords needed? */
442 static void r300_render_vb_primitive(r300ContextPtr rmesa
,
449 radeonScreenPtr rsp
=rmesa
->radeon
.radeonScreen
;
451 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
452 struct vertex_buffer
*VB
= &tnl
->vb
;
455 type
=r300_get_primitive_type(rmesa
, ctx
, prim
);
456 num_verts
=r300_get_num_verts(rmesa
, ctx
, end
-start
, prim
);
458 if(type
<0 || num_verts
<= 0)return;
460 if(rmesa
->state
.Elts
){
461 r300EmitAOS(rmesa
, rmesa
->state
.aos_count
, 0);
463 start_index32_packet(num_verts
, type
);
464 for(i
=0; i
< num_verts
; i
++)
465 e32(rmesa
->state
.Elts
[start
+i
]); /* start ? */
467 WARN_ONCE("Rendering with elt buffers\n");
469 start_index32_packet(num_verts
, type
);
470 e32(rmesa
->state
.Elts
[start
]);
474 if(num_verts
> 65535){ /* not implemented yet */
475 WARN_ONCE("Too many elts\n");
478 r300EmitElts(ctx
, rmesa
->state
.Elts
+start
, num_verts
);
479 fire_EB(PASS_PREFIX
GET_START(&(rmesa
->state
.elt_dma
)), num_verts
, type
);
482 r300EmitAOS(rmesa
, rmesa
->state
.aos_count
, start
);
483 fire_AOS(PASS_PREFIX num_verts
, type
);
487 static GLboolean
r300_run_vb_render(GLcontext
*ctx
,
488 struct tnl_pipeline_stage
*stage
)
490 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
491 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
492 struct vertex_buffer
*VB
= &tnl
->vb
;
496 if (RADEON_DEBUG
& DEBUG_PRIMS
)
497 fprintf(stderr
, "%s\n", __FUNCTION__
);
500 r300ReleaseArrays(ctx
);
501 r300EmitArrays(ctx
, GL_FALSE
);
503 // LOCK_HARDWARE(&(rmesa->radeon));
505 reg_start(R300_RB3D_DSTCACHE_CTLSTAT
,0);
510 r300EmitState(rmesa
);
512 rmesa
->state
.Elts
= VB
->Elts
;
514 for(i
=0; i
< VB
->PrimitiveCount
; i
++){
515 GLuint prim
= VB
->Primitive
[i
].mode
;
516 GLuint start
= VB
->Primitive
[i
].start
;
517 GLuint length
= VB
->Primitive
[i
].count
;
519 r300_render_vb_primitive(rmesa
, ctx
, start
, start
+ length
, prim
);
522 reg_start(R300_RB3D_DSTCACHE_CTLSTAT
,0);
528 // end_3d(PASS_PREFIX_VOID);
530 /* Flush state - we are done drawing.. */
531 // r300FlushCmdBufLocked(rmesa, __FUNCTION__);
532 // radeonWaitForIdleLocked(&(rmesa->radeon));
534 // UNLOCK_HARDWARE(&(rmesa->radeon));
539 * Called by the pipeline manager to render a batch of primitives.
540 * We can return true to pass on to the next stage (i.e. software
541 * rasterization) or false to indicate that the pipeline has finished
542 * after we render something.
544 static GLboolean
r300_run_render(GLcontext
*ctx
,
545 struct tnl_pipeline_stage
*stage
)
547 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
548 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
549 struct vertex_buffer
*VB
= &tnl
->vb
;
552 if (RADEON_DEBUG
& DEBUG_PRIMS
)
553 fprintf(stderr
, "%s\n", __FUNCTION__
);
559 return r300_run_immediate_render(ctx
, stage
);
561 return r300_run_vb_render(ctx
, stage
);
570 * Called by the pipeline manager once before rendering.
571 * We check the GL state here to
572 * a) decide whether we can do the current state in hardware and
573 * b) update hardware registers
575 #define FALLBACK_IF(expr) \
578 if (1 || RADEON_DEBUG & DEBUG_FALLBACKS) \
579 fprintf(stderr, "%s: fallback:%s\n", \
580 __FUNCTION__, #expr); \
581 /*stage->active = GL_FALSE*/; \
586 static void r300_check_render(GLcontext
*ctx
, struct tnl_pipeline_stage
*stage
)
588 r300ContextPtr r300
= R300_CONTEXT(ctx
);
591 if (RADEON_DEBUG
& DEBUG_STATE
)
592 fprintf(stderr
, "%s\n", __FUNCTION__
);
594 /* We only support rendering in hardware for now */
595 if (ctx
->RenderMode
!= GL_RENDER
) {
596 //stage->active = GL_FALSE;
601 /* I'm almost certain I forgot something here */
602 #if 0 /* These should work now.. */
603 FALLBACK_IF(ctx
->Color
.DitherFlag
);
604 FALLBACK_IF(ctx
->Color
.AlphaEnabled
); // GL_ALPHA_TEST
605 FALLBACK_IF(ctx
->Color
.BlendEnabled
); // GL_BLEND
606 FALLBACK_IF(ctx
->Polygon
.OffsetFill
); // GL_POLYGON_OFFSET_FILL
608 //FALLBACK_IF(ctx->Polygon.OffsetPoint); // GL_POLYGON_OFFSET_POINT
609 //FALLBACK_IF(ctx->Polygon.OffsetLine); // GL_POLYGON_OFFSET_LINE
610 //FALLBACK_IF(ctx->Stencil.Enabled); // GL_STENCIL_TEST
612 //FALLBACK_IF(ctx->Fog.Enabled); // GL_FOG disable as swtcl doesnt seem to support this
613 //FALLBACK_IF(ctx->Polygon.SmoothFlag); // GL_POLYGON_SMOOTH disabling to get blender going
614 FALLBACK_IF(ctx
->Polygon
.StippleFlag
); // GL_POLYGON_STIPPLE
615 FALLBACK_IF(ctx
->Multisample
.Enabled
); // GL_MULTISAMPLE_ARB
617 #if 0 /* ut2k3 fails to start if this is on */
618 /* One step at a time - let one texture pass.. */
619 for (i
= 1; i
< ctx
->Const
.MaxTextureUnits
; i
++)
620 FALLBACK_IF(ctx
->Texture
.Unit
[i
].Enabled
);
623 /* Assumed factor reg is found but pattern is still missing */
624 //FALLBACK_IF(ctx->Line.StippleFlag); // GL_LINE_STIPPLE disabling to get blender going
626 /* HW doesnt appear to directly support these */
627 //FALLBACK_IF(ctx->Line.SmoothFlag); // GL_LINE_SMOOTH disabling to get blender going
628 FALLBACK_IF(ctx
->Point
.SmoothFlag
); // GL_POINT_SMOOTH
629 /* Rest could be done with vertex fragments */
630 if (ctx
->Extensions
.NV_point_sprite
|| ctx
->Extensions
.ARB_point_sprite
)
631 FALLBACK_IF(ctx
->Point
.PointSprite
); // GL_POINT_SPRITE_NV
632 //GL_POINT_DISTANCE_ATTENUATION_ARB
633 //GL_POINT_FADE_THRESHOLD_SIZE_ARB
635 /* let r300_run_render do its job */
637 stage
->active
= GL_FALSE
;
642 static void dtr(struct tnl_pipeline_stage
*stage
)
647 GLboolean
r300_create_render(GLcontext
*ctx
, struct tnl_pipeline_stage
*stage
){
652 const struct tnl_pipeline_stage _r300_render_stage
= {
656 dtr
, /* destructor */
657 r300_check_render
, /* check */
658 r300_run_render
/* run */
661 static GLboolean
r300_run_tcl_render(GLcontext
*ctx
,
662 struct tnl_pipeline_stage
*stage
)
664 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
665 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
666 struct vertex_buffer
*VB
= &tnl
->vb
;
668 struct r300_vertex_program
*vp
;
670 hw_tcl_on
=future_hw_tcl_on
;
672 if (RADEON_DEBUG
& DEBUG_PRIMS
)
673 fprintf(stderr
, "%s\n", __FUNCTION__
);
674 if(hw_tcl_on
== GL_FALSE
)
676 if(ctx
->VertexProgram
._Enabled
== GL_FALSE
){
677 _tnl_UpdateFixedFunctionProgram(ctx
);
679 vp
= CURRENT_VERTEX_SHADER(ctx
);
680 if(vp
->translated
== GL_FALSE
)
681 translate_vertex_shader(vp
);
682 if(vp
->translated
== GL_FALSE
){
683 fprintf(stderr
, "Failing back to sw-tcl\n");
685 hw_tcl_on
=future_hw_tcl_on
=0;
686 r300ResetHwState(rmesa
);
690 r300_setup_textures(ctx
);
691 r300_setup_rs_unit(ctx
);
693 r300SetupVertexShader(rmesa
);
694 r300SetupPixelShader(rmesa
);
696 return r300_run_vb_render(ctx
, stage
);
699 static void r300_check_tcl_render(GLcontext
*ctx
, struct tnl_pipeline_stage
*stage
)
701 r300ContextPtr r300
= R300_CONTEXT(ctx
);
704 if (RADEON_DEBUG
& DEBUG_STATE
)
705 fprintf(stderr
, "%s\n", __FUNCTION__
);
707 /* We only support rendering in hardware for now */
708 if (ctx
->RenderMode
!= GL_RENDER
) {
709 //stage->active = GL_FALSE;
714 const struct tnl_pipeline_stage _r300_tcl_stage
= {
718 dtr
, /* destructor */
719 r300_check_tcl_render
, /* check */
720 r300_run_tcl_render
/* run */