1 /* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_maos_arrays.c,v 1.3 2003/02/23 23:59:01 dawes Exp $ */
3 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
5 The Weather Channel (TM) funded Tungsten Graphics to develop the
6 initial release of the Radeon 8500 driver under the XFree86 license.
7 This notice must be preserved.
9 Permission is hereby granted, free of charge, to any person obtaining
10 a copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sublicense, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial
19 portions of the Software.
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
25 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 **************************************************************************/
33 * Keith Whitwell <keith@tungstengraphics.com>
42 #include "swrast_setup/swrast_setup.h"
43 #include "math/m_translate.h"
45 #include "tnl/t_context.h"
47 #include "r200_context.h"
48 #include "r200_ioctl.h"
49 #include "r200_state.h"
50 #include "r200_swtcl.h"
51 #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]; \
181 static void emit_vec4( GLcontext
*ctx
,
182 struct r200_dma_region
*rvb
,
188 int *out
= (int *)(rvb
->address
+ rvb
->start
);
190 if (R200_DEBUG
& DEBUG_VERTS
)
191 fprintf(stderr
, "%s count %d stride %d\n",
192 __FUNCTION__
, count
, stride
);
195 COPY_DWORDS( out
, data
, count
);
197 for (i
= 0; i
< count
; i
++) {
198 out
[0] = *(int *)data
;
205 static void emit_vec8( GLcontext
*ctx
,
206 struct r200_dma_region
*rvb
,
212 int *out
= (int *)(rvb
->address
+ rvb
->start
);
214 if (R200_DEBUG
& DEBUG_VERTS
)
215 fprintf(stderr
, "%s count %d stride %d\n",
216 __FUNCTION__
, count
, stride
);
219 COPY_DWORDS( out
, data
, count
*2 );
221 for (i
= 0; i
< count
; i
++) {
222 out
[0] = *(int *)data
;
223 out
[1] = *(int *)(data
+4);
229 static void emit_vec12( GLcontext
*ctx
,
230 struct r200_dma_region
*rvb
,
236 int *out
= (int *)(rvb
->address
+ rvb
->start
);
238 if (R200_DEBUG
& DEBUG_VERTS
)
239 fprintf(stderr
, "%s count %d stride %d out %p data %p\n",
240 __FUNCTION__
, count
, stride
, (void *)out
, (void *)data
);
243 COPY_DWORDS( out
, data
, count
*3 );
245 for (i
= 0; i
< count
; i
++) {
246 out
[0] = *(int *)data
;
247 out
[1] = *(int *)(data
+4);
248 out
[2] = *(int *)(data
+8);
254 static void emit_vec16( GLcontext
*ctx
,
255 struct r200_dma_region
*rvb
,
261 int *out
= (int *)(rvb
->address
+ rvb
->start
);
263 if (R200_DEBUG
& DEBUG_VERTS
)
264 fprintf(stderr
, "%s count %d stride %d\n",
265 __FUNCTION__
, count
, stride
);
268 COPY_DWORDS( out
, data
, count
*4 );
270 for (i
= 0; i
< count
; i
++) {
271 out
[0] = *(int *)data
;
272 out
[1] = *(int *)(data
+4);
273 out
[2] = *(int *)(data
+8);
274 out
[3] = *(int *)(data
+12);
281 static void emit_vector( GLcontext
*ctx
,
282 struct r200_dma_region
*rvb
,
288 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
290 if (R200_DEBUG
& DEBUG_VERTS
)
291 fprintf(stderr
, "%s count %d size %d stride %d\n",
292 __FUNCTION__
, count
, size
, stride
);
297 r200AllocDmaRegion( rmesa
, rvb
, size
* 4, 4 );
299 rvb
->aos_start
= GET_START(rvb
);
301 rvb
->aos_size
= size
;
304 r200AllocDmaRegion( rmesa
, rvb
, size
* count
* 4, 4 ); /* alignment? */
305 rvb
->aos_start
= GET_START(rvb
);
306 rvb
->aos_stride
= size
;
307 rvb
->aos_size
= size
;
314 emit_vec4( ctx
, rvb
, data
, stride
, count
);
317 emit_vec8( ctx
, rvb
, data
, stride
, count
);
320 emit_vec12( ctx
, rvb
, data
, stride
, count
);
323 emit_vec16( ctx
, rvb
, data
, stride
, count
);
335 /* Emit any changed arrays to new GART memory, re-emit a packet to
338 void r200EmitArrays( GLcontext
*ctx
, GLuint inputs
)
340 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
341 struct vertex_buffer
*VB
= &TNL_CONTEXT( ctx
)->vb
;
342 struct r200_dma_region
**component
= rmesa
->tcl
.aos_components
;
344 GLuint vfmt0
= 0, vfmt1
= 0;
345 GLuint count
= VB
->Count
;
350 if (!rmesa
->tcl
.obj
.buf
)
353 (char *)VB
->ObjPtr
->data
,
358 switch( VB
->ObjPtr
->size
) {
359 case 4: vfmt0
|= R200_VTX_W0
;
360 case 3: vfmt0
|= R200_VTX_Z0
;
365 component
[nr
++] = &rmesa
->tcl
.obj
;
369 if (inputs
& VERT_BIT_NORMAL
) {
370 if (!rmesa
->tcl
.norm
.buf
)
373 (char *)VB
->NormalPtr
->data
,
375 VB
->NormalPtr
->stride
,
378 vfmt0
|= R200_VTX_N0
;
379 component
[nr
++] = &rmesa
->tcl
.norm
;
382 if (inputs
& VERT_BIT_COLOR0
) {
385 if (VB
->ColorPtr
[0]->size
== 4 &&
386 (VB
->ColorPtr
[0]->stride
!= 0 ||
387 VB
->ColorPtr
[0]->data
[0][3] != 1.0)) {
388 vfmt0
|= R200_VTX_FP_RGBA
<< R200_VTX_COLOR_0_SHIFT
;
392 vfmt0
|= R200_VTX_FP_RGB
<< R200_VTX_COLOR_0_SHIFT
;
396 if (!rmesa
->tcl
.rgba
.buf
)
399 (char *)VB
->ColorPtr
[0]->data
,
401 VB
->ColorPtr
[0]->stride
,
404 component
[nr
++] = &rmesa
->tcl
.rgba
;
408 if (inputs
& VERT_BIT_COLOR1
) {
409 if (!rmesa
->tcl
.spec
.buf
) {
412 (char *)VB
->SecondaryColorPtr
[0]->data
,
414 VB
->SecondaryColorPtr
[0]->stride
,
418 /* How does this work?
420 vfmt0
|= R200_VTX_FP_RGB
<< R200_VTX_COLOR_1_SHIFT
;
421 component
[nr
++] = &rmesa
->tcl
.spec
;
424 /* vtx = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] & */
425 /* ~(R200_TCL_VTX_Q0|R200_TCL_VTX_Q1|R200_TCL_VTX_Q2|R200_TCL_VTX_Q3|R200_TCL_VTX_Q4|R200_TCL_VTX_Q5)); */
427 re_cntl
= rmesa
->hw
.set
.cmd
[SET_RE_CNTL
] & ~(R200_VTX_STQ0_D3D
|
433 for ( i
= 0 ; i
< ctx
->Const
.MaxTextureUnits
; i
++ ) {
434 if (inputs
& (VERT_BIT_TEX0
<< i
)) {
435 if (!rmesa
->tcl
.tex
[i
].buf
)
437 &(rmesa
->tcl
.tex
[i
]),
438 (char *)VB
->TexCoordPtr
[i
]->data
,
439 VB
->TexCoordPtr
[i
]->size
,
440 VB
->TexCoordPtr
[i
]->stride
,
443 if ( ctx
->Texture
.Unit
[i
]._ReallyEnabled
== TEXTURE_CUBE_BIT
) {
444 re_cntl
|= R200_VTX_STQ0_D3D
<< (2 * i
);
447 vfmt1
|= VB
->TexCoordPtr
[i
]->size
<< (i
* 3);
448 component
[nr
++] = &rmesa
->tcl
.tex
[i
];
452 if ( re_cntl
!= rmesa
->hw
.set
.cmd
[SET_RE_CNTL
] ) {
453 R200_STATECHANGE( rmesa
, set
);
454 rmesa
->hw
.set
.cmd
[SET_RE_CNTL
] = re_cntl
;
457 if (vfmt0
!= rmesa
->hw
.vtx
.cmd
[VTX_VTXFMT_0
] ||
458 vfmt1
!= rmesa
->hw
.vtx
.cmd
[VTX_VTXFMT_1
]) {
459 R200_STATECHANGE( rmesa
, vtx
);
460 rmesa
->hw
.vtx
.cmd
[VTX_VTXFMT_0
] = vfmt0
;
461 rmesa
->hw
.vtx
.cmd
[VTX_VTXFMT_1
] = vfmt1
;
464 rmesa
->tcl
.nr_aos_components
= nr
;
465 rmesa
->tcl
.vertex_format
= vfmt0
;
469 void r200ReleaseArrays( GLcontext
*ctx
, GLuint newinputs
)
472 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
474 /* if (R200_DEBUG & DEBUG_VERTS) */
475 /* _tnl_print_vert_flags( __FUNCTION__, newinputs ); */
477 if (newinputs
& VERT_BIT_POS
)
478 r200ReleaseDmaRegion( rmesa
, &rmesa
->tcl
.obj
, __FUNCTION__
);
480 if (newinputs
& VERT_BIT_NORMAL
)
481 r200ReleaseDmaRegion( rmesa
, &rmesa
->tcl
.norm
, __FUNCTION__
);
483 if (newinputs
& VERT_BIT_COLOR0
)
484 r200ReleaseDmaRegion( rmesa
, &rmesa
->tcl
.rgba
, __FUNCTION__
);
486 if (newinputs
& VERT_BIT_COLOR1
)
487 r200ReleaseDmaRegion( rmesa
, &rmesa
->tcl
.spec
, __FUNCTION__
);
489 for (unit
= 0 ; unit
< ctx
->Const
.MaxTextureUnits
; unit
++) {
490 if (newinputs
& VERT_BIT_TEX(unit
))
491 r200ReleaseDmaRegion( rmesa
, &rmesa
->tcl
.tex
[unit
], __FUNCTION__
);