1 /**************************************************************************
3 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
4 Tungsten Graphics Inc., Cedar Park, Texas.
8 Permission is hereby granted, free of charge, to any person obtaining
9 a copy of this software and associated documentation files (the
10 "Software"), to deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify, merge, publish,
12 distribute, sublicense, and/or sell copies of the Software, and to
13 permit persons to whom the Software is furnished to do so, subject to
14 the following conditions:
16 The above copyright notice and this permission notice (including the
17 next paragraph) shall be included in all copies or substantial
18 portions of the Software.
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
24 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 **************************************************************************/
32 * Keith Whitwell <keith@tungstengraphics.com>
35 #include "main/glheader.h"
36 #include "main/imports.h"
37 #include "main/mtypes.h"
38 #include "main/macros.h"
40 #include "swrast_setup/swrast_setup.h"
41 #include "math/m_translate.h"
44 #include "radeon_context.h"
45 #include "radeon_ioctl.h"
46 #include "radeon_state.h"
47 #include "radeon_swtcl.h"
48 #include "radeon_maos.h"
49 #include "radeon_tcl.h"
51 static void emit_vecfog(struct gl_context
*ctx
, struct radeon_aos
*aos
,
52 GLvoid
*data
, int stride
, int count
)
57 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
59 if (RADEON_DEBUG
& RADEON_VERTS
)
60 fprintf(stderr
, "%s count %d stride %d\n",
61 __FUNCTION__
, count
, stride
);
64 radeonAllocDmaRegion( rmesa
, &aos
->bo
, &aos
->offset
, size
* 4, 32 );
69 radeonAllocDmaRegion(rmesa
, &aos
->bo
, &aos
->offset
, size
* 4, 32);
73 aos
->components
= size
;
79 radeon_bo_map(aos
->bo
, 1);
80 out
= (uint32_t*)((char*)aos
->bo
->ptr
+ aos
->offset
);
81 for (i
= 0; i
< count
; i
++) {
82 out
[0] = radeonComputeFogBlendFactor( ctx
, *(GLfloat
*)data
);
86 radeon_bo_unmap(aos
->bo
);
89 static void emit_s0_vec(uint32_t *out
, GLvoid
*data
, int stride
, int count
)
92 if (RADEON_DEBUG
& RADEON_VERTS
)
93 fprintf(stderr
, "%s count %d stride %d\n",
94 __FUNCTION__
, count
, stride
);
96 for (i
= 0; i
< count
; i
++) {
97 out
[0] = *(int *)data
;
104 static void emit_stq_vec(uint32_t *out
, GLvoid
*data
, int stride
, int count
)
108 if (RADEON_DEBUG
& RADEON_VERTS
)
109 fprintf(stderr
, "%s count %d stride %d\n",
110 __FUNCTION__
, count
, stride
);
112 for (i
= 0; i
< count
; i
++) {
113 out
[0] = *(int *)data
;
114 out
[1] = *(int *)(data
+4);
115 out
[2] = *(int *)(data
+12);
124 static void emit_tex_vector(struct gl_context
*ctx
, struct radeon_aos
*aos
,
125 GLvoid
*data
, int size
, int stride
, int count
)
127 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
131 if (RADEON_DEBUG
& RADEON_VERTS
)
132 fprintf(stderr
, "%s %d/%d\n", __FUNCTION__
, count
, size
);
135 case 4: emitsize
= 3; break;
136 case 3: emitsize
= 3; break;
137 default: emitsize
= 2; break;
142 radeonAllocDmaRegion(rmesa
, &aos
->bo
, &aos
->offset
, emitsize
* 4, 32);
147 radeonAllocDmaRegion(rmesa
, &aos
->bo
, &aos
->offset
, emitsize
* count
* 4, 32);
148 aos
->stride
= emitsize
;
151 aos
->components
= emitsize
;
156 radeon_bo_map(aos
->bo
, 1);
157 out
= (uint32_t*)((char*)aos
->bo
->ptr
+ aos
->offset
);
160 emit_s0_vec( out
, data
, stride
, count
);
163 radeonEmitVec8( out
, data
, stride
, count
);
166 radeonEmitVec12( out
, data
, stride
, count
);
169 emit_stq_vec( out
, data
, stride
, count
);
176 radeon_bo_unmap(aos
->bo
);
182 /* Emit any changed arrays to new GART memory, re-emit a packet to
185 void radeonEmitArrays( struct gl_context
*ctx
, GLuint inputs
)
187 r100ContextPtr rmesa
= R100_CONTEXT( ctx
);
188 struct vertex_buffer
*VB
= &TNL_CONTEXT( ctx
)->vb
;
191 GLuint count
= VB
->Count
;
195 if (RADEON_DEBUG
& RADEON_VERTS
)
196 _tnl_print_vert_flags( __FUNCTION__
, inputs
);
200 if (!rmesa
->tcl
.obj
.buf
)
201 rcommon_emit_vector( ctx
,
202 &(rmesa
->tcl
.aos
[nr
]),
203 (char *)VB
->AttribPtr
[_TNL_ATTRIB_POS
]->data
,
204 VB
->AttribPtr
[_TNL_ATTRIB_POS
]->size
,
205 VB
->AttribPtr
[_TNL_ATTRIB_POS
]->stride
,
208 switch( VB
->AttribPtr
[_TNL_ATTRIB_POS
]->size
) {
209 case 4: vfmt
|= RADEON_CP_VC_FRMT_W0
;
210 case 3: vfmt
|= RADEON_CP_VC_FRMT_Z
;
211 case 2: vfmt
|= RADEON_CP_VC_FRMT_XY
;
219 if (inputs
& VERT_BIT_NORMAL
) {
220 if (!rmesa
->tcl
.norm
.buf
)
221 rcommon_emit_vector( ctx
,
222 &(rmesa
->tcl
.aos
[nr
]),
223 (char *)VB
->AttribPtr
[_TNL_ATTRIB_NORMAL
]->data
,
225 VB
->AttribPtr
[_TNL_ATTRIB_NORMAL
]->stride
,
228 vfmt
|= RADEON_CP_VC_FRMT_N0
;
232 if (inputs
& VERT_BIT_COLOR0
) {
234 if (VB
->AttribPtr
[_TNL_ATTRIB_COLOR0
]->size
== 4 &&
235 (VB
->AttribPtr
[_TNL_ATTRIB_COLOR0
]->stride
!= 0 ||
236 VB
->AttribPtr
[_TNL_ATTRIB_COLOR0
]->data
[0][3] != 1.0)) {
237 vfmt
|= RADEON_CP_VC_FRMT_FPCOLOR
| RADEON_CP_VC_FRMT_FPALPHA
;
242 vfmt
|= RADEON_CP_VC_FRMT_FPCOLOR
;
246 if (!rmesa
->tcl
.rgba
.buf
)
247 rcommon_emit_vector( ctx
,
248 &(rmesa
->tcl
.aos
[nr
]),
249 (char *)VB
->AttribPtr
[_TNL_ATTRIB_COLOR0
]->data
,
251 VB
->AttribPtr
[_TNL_ATTRIB_COLOR0
]->stride
,
258 if (inputs
& VERT_BIT_COLOR1
) {
259 if (!rmesa
->tcl
.spec
.buf
) {
261 rcommon_emit_vector( ctx
,
262 &(rmesa
->tcl
.aos
[nr
]),
263 (char *)VB
->AttribPtr
[_TNL_ATTRIB_COLOR1
]->data
,
265 VB
->AttribPtr
[_TNL_ATTRIB_COLOR1
]->stride
,
269 vfmt
|= RADEON_CP_VC_FRMT_FPSPEC
;
273 /* FIXME: not sure if this is correct. May need to stitch this together with
274 secondary color. It seems odd that for primary color color and alpha values
275 are emitted together but for secondary color not. */
276 if (inputs
& VERT_BIT_FOG
) {
277 if (!rmesa
->tcl
.fog
.buf
)
279 &(rmesa
->tcl
.aos
[nr
]),
280 (char *)VB
->AttribPtr
[_TNL_ATTRIB_FOG
]->data
,
281 VB
->AttribPtr
[_TNL_ATTRIB_FOG
]->stride
,
284 vfmt
|= RADEON_CP_VC_FRMT_FPFOG
;
289 vtx
= (rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &
290 ~(RADEON_TCL_VTX_Q0
|RADEON_TCL_VTX_Q1
|RADEON_TCL_VTX_Q2
));
292 for (unit
= 0; unit
< ctx
->Const
.MaxTextureUnits
; unit
++) {
293 if (inputs
& VERT_BIT_TEX(unit
)) {
294 if (!rmesa
->tcl
.tex
[unit
].buf
)
295 emit_tex_vector( ctx
,
296 &(rmesa
->tcl
.aos
[nr
]),
297 (char *)VB
->AttribPtr
[_TNL_ATTRIB_TEX0
+ unit
]->data
,
298 VB
->AttribPtr
[_TNL_ATTRIB_TEX0
+ unit
]->size
,
299 VB
->AttribPtr
[_TNL_ATTRIB_TEX0
+ unit
]->stride
,
303 vfmt
|= RADEON_ST_BIT(unit
);
304 /* assume we need the 3rd coord if texgen is active for r/q OR at least
305 3 coords are submitted. This may not be 100% correct */
306 if (VB
->AttribPtr
[_TNL_ATTRIB_TEX0
+ unit
]->size
>= 3) {
307 vtx
|= RADEON_Q_BIT(unit
);
308 vfmt
|= RADEON_Q_BIT(unit
);
310 if ( (ctx
->Texture
.Unit
[unit
].TexGenEnabled
& (R_BIT
| Q_BIT
)) )
311 vtx
|= RADEON_Q_BIT(unit
);
312 else if ((VB
->AttribPtr
[_TNL_ATTRIB_TEX0
+ unit
]->size
>= 3) &&
313 ((ctx
->Texture
.Unit
[unit
]._ReallyEnabled
& (TEXTURE_CUBE_BIT
)) == 0)) {
314 GLuint swaptexmatcol
= (VB
->AttribPtr
[_TNL_ATTRIB_TEX0
+ unit
]->size
- 3);
315 if (((rmesa
->NeedTexMatrix
>> unit
) & 1) &&
316 (swaptexmatcol
!= ((rmesa
->TexMatColSwap
>> unit
) & 1)))
317 radeonUploadTexMatrix( rmesa
, unit
, swaptexmatcol
) ;
322 if (vtx
!= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
]) {
323 RADEON_STATECHANGE( rmesa
, tcl
);
324 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] = vtx
;
327 rmesa
->tcl
.nr_aos_components
= nr
;
328 rmesa
->tcl
.vertex_format
= vfmt
;