2 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
4 The Weather Channel (TM) funded Tungsten Graphics to develop the
5 initial release of the Radeon 8500 driver under the XFree86 license.
6 This notice must be preserved.
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/mtypes.h"
37 #include "main/colormac.h"
38 #include "main/imports.h"
39 #include "main/macros.h"
41 #include "swrast_setup/swrast_setup.h"
42 #include "math/m_translate.h"
44 #include "tnl/t_context.h"
46 #include "r200_context.h"
47 #include "r200_ioctl.h"
48 #include "r200_state.h"
49 #include "r200_swtcl.h"
50 #include "r200_maos.h"
56 * - from r200_tcl_render
57 * - call r200EmitArrays to ensure uptodate arrays in dma
58 * - emit primitives (new type?) which reference the data
59 * -- need to use elts for lineloop, quads, quadstrip/flat
60 * -- other primitives are all well-formed (need tristrip-1,fake-poly)
63 static void emit_ubyte_rgba3( GLcontext
*ctx
,
64 struct r200_dma_region
*rvb
,
70 r200_color_t
*out
= (r200_color_t
*)(rvb
->start
+ rvb
->address
);
72 if (R200_DEBUG
& DEBUG_VERTS
)
73 fprintf(stderr
, "%s count %d stride %d out %p\n",
74 __FUNCTION__
, count
, stride
, (void *)out
);
76 for (i
= 0; i
< count
; i
++) {
78 out
->green
= *(data
+1);
79 out
->blue
= *(data
+2);
86 static void emit_ubyte_rgba4( GLcontext
*ctx
,
87 struct r200_dma_region
*rvb
,
93 int *out
= (int *)(rvb
->address
+ rvb
->start
);
95 if (R200_DEBUG
& DEBUG_VERTS
)
96 fprintf(stderr
, "%s count %d stride %d\n",
97 __FUNCTION__
, count
, stride
);
100 for (i
= 0; i
< count
; i
++)
101 ((int *)out
)[i
] = LE32_TO_CPU(((int *)data
)[i
]);
103 for (i
= 0; i
< count
; i
++) {
104 *(int *)out
++ = LE32_TO_CPU(*(int *)data
);
111 static void emit_ubyte_rgba( GLcontext
*ctx
,
112 struct r200_dma_region
*rvb
,
118 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
120 if (R200_DEBUG
& DEBUG_VERTS
)
121 fprintf(stderr
, "%s %d/%d\n", __FUNCTION__
, count
, size
);
126 r200AllocDmaRegion( rmesa
, rvb
, 4, 4 );
128 rvb
->aos_start
= GET_START(rvb
);
133 r200AllocDmaRegion( rmesa
, rvb
, 4 * count
, 4 ); /* alignment? */
134 rvb
->aos_start
= GET_START(rvb
);
143 emit_ubyte_rgba3( ctx
, rvb
, data
, stride
, count
);
146 emit_ubyte_rgba4( ctx
, rvb
, data
, stride
, count
);
157 #if defined(USE_X86_ASM)
158 #define COPY_DWORDS( dst, src, nr ) \
161 __asm__ __volatile__( "rep ; movsl" \
162 : "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \
168 #define COPY_DWORDS( dst, src, nr ) \
171 for ( j = 0 ; j < nr ; j++ ) \
172 dst[j] = ((int *)src)[j]; \
178 static void emit_vecfog( GLcontext
*ctx
,
179 struct r200_dma_region
*rvb
,
187 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
189 if (R200_DEBUG
& DEBUG_VERTS
)
190 fprintf(stderr
, "%s count %d stride %d\n",
191 __FUNCTION__
, count
, stride
);
196 r200AllocDmaRegion( rmesa
, rvb
, 4, 4 );
198 rvb
->aos_start
= GET_START(rvb
);
203 r200AllocDmaRegion( rmesa
, rvb
, count
* 4, 4 ); /* alignment? */
204 rvb
->aos_start
= GET_START(rvb
);
211 out
= (GLfloat
*)(rvb
->address
+ rvb
->start
);
212 for (i
= 0; i
< count
; i
++) {
213 out
[0] = r200ComputeFogBlendFactor( ctx
, *(GLfloat
*)data
);
221 static void emit_vec4( GLcontext
*ctx
,
222 struct r200_dma_region
*rvb
,
228 int *out
= (int *)(rvb
->address
+ rvb
->start
);
230 if (R200_DEBUG
& DEBUG_VERTS
)
231 fprintf(stderr
, "%s count %d stride %d\n",
232 __FUNCTION__
, count
, stride
);
235 COPY_DWORDS( out
, data
, count
);
237 for (i
= 0; i
< count
; i
++) {
238 out
[0] = *(int *)data
;
245 static void emit_vec8( GLcontext
*ctx
,
246 struct r200_dma_region
*rvb
,
252 int *out
= (int *)(rvb
->address
+ rvb
->start
);
254 if (R200_DEBUG
& DEBUG_VERTS
)
255 fprintf(stderr
, "%s count %d stride %d\n",
256 __FUNCTION__
, count
, stride
);
259 COPY_DWORDS( out
, data
, count
*2 );
261 for (i
= 0; i
< count
; i
++) {
262 out
[0] = *(int *)data
;
263 out
[1] = *(int *)(data
+4);
269 static void emit_vec12( GLcontext
*ctx
,
270 struct r200_dma_region
*rvb
,
276 int *out
= (int *)(rvb
->address
+ rvb
->start
);
278 if (R200_DEBUG
& DEBUG_VERTS
)
279 fprintf(stderr
, "%s count %d stride %d out %p data %p\n",
280 __FUNCTION__
, count
, stride
, (void *)out
, (void *)data
);
283 COPY_DWORDS( out
, data
, count
*3 );
285 for (i
= 0; i
< count
; i
++) {
286 out
[0] = *(int *)data
;
287 out
[1] = *(int *)(data
+4);
288 out
[2] = *(int *)(data
+8);
294 static void emit_vec16( GLcontext
*ctx
,
295 struct r200_dma_region
*rvb
,
301 int *out
= (int *)(rvb
->address
+ rvb
->start
);
303 if (R200_DEBUG
& DEBUG_VERTS
)
304 fprintf(stderr
, "%s count %d stride %d\n",
305 __FUNCTION__
, count
, stride
);
308 COPY_DWORDS( out
, data
, count
*4 );
310 for (i
= 0; i
< count
; i
++) {
311 out
[0] = *(int *)data
;
312 out
[1] = *(int *)(data
+4);
313 out
[2] = *(int *)(data
+8);
314 out
[3] = *(int *)(data
+12);
321 static void emit_vector( GLcontext
*ctx
,
322 struct r200_dma_region
*rvb
,
328 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
330 if (R200_DEBUG
& DEBUG_VERTS
)
331 fprintf(stderr
, "%s count %d size %d stride %d\n",
332 __FUNCTION__
, count
, size
, stride
);
337 r200AllocDmaRegion( rmesa
, rvb
, size
* 4, 4 );
339 rvb
->aos_start
= GET_START(rvb
);
341 rvb
->aos_size
= size
;
344 r200AllocDmaRegion( rmesa
, rvb
, size
* count
* 4, 4 ); /* alignment? */
345 rvb
->aos_start
= GET_START(rvb
);
346 rvb
->aos_stride
= size
;
347 rvb
->aos_size
= size
;
354 emit_vec4( ctx
, rvb
, data
, stride
, count
);
357 emit_vec8( ctx
, rvb
, data
, stride
, count
);
360 emit_vec12( ctx
, rvb
, data
, stride
, count
);
363 emit_vec16( ctx
, rvb
, data
, stride
, count
);
375 /* Emit any changed arrays to new GART memory, re-emit a packet to
378 void r200EmitArrays( GLcontext
*ctx
, GLubyte
*vimap_rev
)
380 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
381 struct vertex_buffer
*VB
= &TNL_CONTEXT( ctx
)->vb
;
382 struct r200_dma_region
**component
= rmesa
->tcl
.aos_components
;
384 GLuint vfmt0
= 0, vfmt1
= 0;
385 GLuint count
= VB
->Count
;
388 for ( i
= 0; i
< 15; i
++ ) {
389 GLubyte attrib
= vimap_rev
[i
];
393 emitsize
= (VB
->AttribPtr
[attrib
]->size
);
396 vfmt0
|= R200_VTX_W0
;
399 vfmt0
|= R200_VTX_Z0
;
407 assert(attrib
== VERT_ATTRIB_WEIGHT
);
408 emitsize
= (VB
->AttribPtr
[attrib
]->size
);
409 vfmt0
|= emitsize
<< R200_VTX_WEIGHT_COUNT_SHIFT
;
412 assert(attrib
== VERT_ATTRIB_NORMAL
);
414 vfmt0
|= R200_VTX_N0
;
417 /* special handling to fix up fog. Will get us into trouble with vbos...*/
418 assert(attrib
== VERT_ATTRIB_FOG
);
419 if (!rmesa
->tcl
.vertex_data
[i
].buf
) {
420 if (ctx
->VertexProgram
._Enabled
)
422 &(rmesa
->tcl
.vertex_data
[i
]),
423 (char *)VB
->AttribPtr
[attrib
]->data
,
425 VB
->AttribPtr
[attrib
]->stride
,
429 &(rmesa
->tcl
.vertex_data
[i
]),
430 (char *)VB
->AttribPtr
[attrib
]->data
,
431 VB
->AttribPtr
[attrib
]->stride
,
434 vfmt0
|= R200_VTX_DISCRETE_FOG
;
441 if (VB
->AttribPtr
[attrib
]->size
== 4 &&
442 (VB
->AttribPtr
[attrib
]->stride
!= 0 ||
443 VB
->AttribPtr
[attrib
]->data
[0][3] != 1.0)) emitsize
= 4;
446 vfmt0
|= R200_VTX_FP_RGBA
<< (R200_VTX_COLOR_0_SHIFT
+ (i
- 4) * 2);
448 vfmt0
|= R200_VTX_FP_RGB
<< (R200_VTX_COLOR_0_SHIFT
+ (i
- 4) * 2);
457 emitsize
= VB
->AttribPtr
[attrib
]->size
;
458 vfmt1
|= emitsize
<< (R200_VTX_TEX0_COMP_CNT_SHIFT
+ (i
- 8) * 3);
461 emitsize
= VB
->AttribPtr
[attrib
]->size
>= 2 ? VB
->AttribPtr
[attrib
]->size
: 2;
464 vfmt0
|= R200_VTX_XY1
;
467 vfmt0
|= R200_VTX_Z1
;
470 vfmt0
|= R200_VTX_W1
;
476 if (!rmesa
->tcl
.vertex_data
[i
].buf
) {
478 &(rmesa
->tcl
.vertex_data
[i
]),
479 (char *)VB
->AttribPtr
[attrib
]->data
,
481 VB
->AttribPtr
[attrib
]->stride
,
486 component
[nr
++] = &rmesa
->tcl
.vertex_data
[i
];
490 if (vfmt0
!= rmesa
->hw
.vtx
.cmd
[VTX_VTXFMT_0
] ||
491 vfmt1
!= rmesa
->hw
.vtx
.cmd
[VTX_VTXFMT_1
]) {
492 R200_STATECHANGE( rmesa
, vtx
);
493 rmesa
->hw
.vtx
.cmd
[VTX_VTXFMT_0
] = vfmt0
;
494 rmesa
->hw
.vtx
.cmd
[VTX_VTXFMT_1
] = vfmt1
;
497 rmesa
->tcl
.nr_aos_components
= nr
;
501 void r200ReleaseArrays( GLcontext
*ctx
, GLuint newinputs
)
503 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
505 /* only do it for changed inputs ? */
507 for (i
= 0; i
< 15; i
++) {
508 if (newinputs
& (1 << i
))
509 r200ReleaseDmaRegion( rmesa
,
510 &rmesa
->tcl
.vertex_data
[i
], __FUNCTION__
);