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"
54 * - from r200_tcl_render
55 * - call r200EmitArrays to ensure uptodate arrays in dma
56 * - emit primitives (new type?) which reference the data
57 * -- need to use elts for lineloop, quads, quadstrip/flat
58 * -- other primitives are all well-formed (need tristrip-1,fake-poly)
61 static void emit_ubyte_rgba3( GLcontext
*ctx
,
62 struct r200_dma_region
*rvb
,
68 r200_color_t
*out
= (r200_color_t
*)(rvb
->start
+ rvb
->address
);
70 if (R200_DEBUG
& DEBUG_VERTS
)
71 fprintf(stderr
, "%s count %d stride %d out %p\n",
72 __FUNCTION__
, count
, stride
, out
);
74 for (i
= 0; i
< count
; i
++) {
76 out
->green
= *(data
+1);
77 out
->blue
= *(data
+2);
85 #if defined(USE_X86_ASM)
86 #define COPY_DWORDS( dst, src, nr ) \
89 __asm__ __volatile__( "rep ; movsl" \
90 : "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \
96 #define COPY_DWORDS( dst, src, nr ) \
99 for ( j = 0 ; j < nr ; j++ ) \
100 dst[j] = ((int *)src)[j]; \
107 static void emit_ubyte_rgba4( GLcontext
*ctx
,
108 struct r200_dma_region
*rvb
,
114 int *out
= (int *)(rvb
->address
+ rvb
->start
);
116 if (R200_DEBUG
& DEBUG_VERTS
)
117 fprintf(stderr
, "%s count %d stride %d\n",
118 __FUNCTION__
, count
, stride
);
121 for (i
= 0; i
< count
; i
++)
122 ((int *)out
)[i
] = LE32_TO_CPU(((int *)data
)[i
]);
124 for (i
= 0; i
< count
; i
++) {
125 *(int *)out
++ = LE32_TO_CPU(*(int *)data
);
132 static void emit_ubyte_rgba( GLcontext
*ctx
,
133 struct r200_dma_region
*rvb
,
139 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
141 if (R200_DEBUG
& DEBUG_VERTS
)
142 fprintf(stderr
, "%s %d/%d\n", __FUNCTION__
, count
, size
);
147 r200AllocDmaRegion( rmesa
, rvb
, 4, 4 );
149 rvb
->aos_start
= GET_START(rvb
);
154 r200AllocDmaRegion( rmesa
, rvb
, 4 * count
, 4 ); /* alignment? */
155 rvb
->aos_start
= GET_START(rvb
);
164 emit_ubyte_rgba3( ctx
, rvb
, data
, stride
, count
);
167 emit_ubyte_rgba4( ctx
, rvb
, data
, stride
, count
);
177 static void emit_vec4( GLcontext
*ctx
,
178 struct r200_dma_region
*rvb
,
184 int *out
= (int *)(rvb
->address
+ rvb
->start
);
186 if (R200_DEBUG
& DEBUG_VERTS
)
187 fprintf(stderr
, "%s count %d stride %d\n",
188 __FUNCTION__
, count
, stride
);
191 COPY_DWORDS( out
, data
, count
);
193 for (i
= 0; i
< count
; i
++) {
194 out
[0] = *(int *)data
;
201 static void emit_vec8( GLcontext
*ctx
,
202 struct r200_dma_region
*rvb
,
208 int *out
= (int *)(rvb
->address
+ rvb
->start
);
210 if (R200_DEBUG
& DEBUG_VERTS
)
211 fprintf(stderr
, "%s count %d stride %d\n",
212 __FUNCTION__
, count
, stride
);
215 COPY_DWORDS( out
, data
, count
*2 );
217 for (i
= 0; i
< count
; i
++) {
218 out
[0] = *(int *)data
;
219 out
[1] = *(int *)(data
+4);
225 static void emit_vec12( GLcontext
*ctx
,
226 struct r200_dma_region
*rvb
,
232 int *out
= (int *)(rvb
->address
+ rvb
->start
);
234 if (R200_DEBUG
& DEBUG_VERTS
)
235 fprintf(stderr
, "%s count %d stride %d out %p data %p\n",
236 __FUNCTION__
, count
, stride
, out
, data
);
239 COPY_DWORDS( out
, data
, count
*3 );
241 for (i
= 0; i
< count
; i
++) {
242 out
[0] = *(int *)data
;
243 out
[1] = *(int *)(data
+4);
244 out
[2] = *(int *)(data
+8);
250 static void emit_vec16( GLcontext
*ctx
,
251 struct r200_dma_region
*rvb
,
257 int *out
= (int *)(rvb
->address
+ rvb
->start
);
259 if (R200_DEBUG
& DEBUG_VERTS
)
260 fprintf(stderr
, "%s count %d stride %d\n",
261 __FUNCTION__
, count
, stride
);
264 COPY_DWORDS( out
, data
, count
*4 );
266 for (i
= 0; i
< count
; i
++) {
267 out
[0] = *(int *)data
;
268 out
[1] = *(int *)(data
+4);
269 out
[2] = *(int *)(data
+8);
270 out
[3] = *(int *)(data
+12);
277 static void emit_vector( GLcontext
*ctx
,
278 struct r200_dma_region
*rvb
,
284 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
286 if (R200_DEBUG
& DEBUG_VERTS
)
287 fprintf(stderr
, "%s count %d size %d stride %d\n",
288 __FUNCTION__
, count
, size
, stride
);
293 r200AllocDmaRegion( rmesa
, rvb
, size
* 4, 4 );
295 rvb
->aos_start
= GET_START(rvb
);
297 rvb
->aos_size
= size
;
300 r200AllocDmaRegion( rmesa
, rvb
, size
* count
* 4, 4 ); /* alignment? */
301 rvb
->aos_start
= GET_START(rvb
);
302 rvb
->aos_stride
= size
;
303 rvb
->aos_size
= size
;
310 emit_vec4( ctx
, rvb
, data
, stride
, count
);
313 emit_vec8( ctx
, rvb
, data
, stride
, count
);
316 emit_vec12( ctx
, rvb
, data
, stride
, count
);
319 emit_vec16( ctx
, rvb
, data
, stride
, count
);
331 /* Emit any changed arrays to new GART memory, re-emit a packet to
334 void r200EmitArrays( GLcontext
*ctx
, GLuint inputs
)
336 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
337 struct vertex_buffer
*VB
= &TNL_CONTEXT( ctx
)->vb
;
338 struct r200_dma_region
**component
= rmesa
->tcl
.aos_components
;
340 GLuint vfmt0
= 0, vfmt1
= 0;
341 GLuint count
= VB
->Count
;
344 if (!rmesa
->tcl
.obj
.buf
)
347 (char *)VB
->ObjPtr
->data
,
352 switch( VB
->ObjPtr
->size
) {
353 case 4: vfmt0
|= R200_VTX_W0
;
354 case 3: vfmt0
|= R200_VTX_Z0
;
359 component
[nr
++] = &rmesa
->tcl
.obj
;
363 if (inputs
& VERT_BIT_NORMAL
) {
364 if (!rmesa
->tcl
.norm
.buf
)
367 (char *)VB
->NormalPtr
->data
,
369 VB
->NormalPtr
->stride
,
372 vfmt0
|= R200_VTX_N0
;
373 component
[nr
++] = &rmesa
->tcl
.norm
;
376 if (inputs
& VERT_BIT_COLOR0
) {
379 if (VB
->ColorPtr
[0]->size
== 4 &&
380 (VB
->ColorPtr
[0]->stride
!= 0 ||
381 VB
->ColorPtr
[0]->data
[0][3] != 1.0)) {
382 vfmt0
|= R200_VTX_FP_RGBA
<< R200_VTX_COLOR_0_SHIFT
;
386 vfmt0
|= R200_VTX_FP_RGB
<< R200_VTX_COLOR_0_SHIFT
;
390 if (!rmesa
->tcl
.rgba
.buf
)
393 (char *)VB
->ColorPtr
[0]->data
,
395 VB
->ColorPtr
[0]->stride
,
398 component
[nr
++] = &rmesa
->tcl
.rgba
;
402 if (inputs
& VERT_BIT_COLOR1
) {
403 if (!rmesa
->tcl
.spec
.buf
) {
406 (char *)VB
->SecondaryColorPtr
[0]->data
,
408 VB
->SecondaryColorPtr
[0]->stride
,
412 /* How does this work?
414 vfmt0
|= R200_VTX_FP_RGB
<< R200_VTX_COLOR_1_SHIFT
;
415 component
[nr
++] = &rmesa
->tcl
.spec
;
418 /* vtx = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] & */
419 /* ~(R200_TCL_VTX_Q0|R200_TCL_VTX_Q1)); */
421 if (inputs
& VERT_BIT_TEX0
) {
422 if (!rmesa
->tcl
.tex
[0].buf
)
424 &(rmesa
->tcl
.tex
[0]),
425 (char *)VB
->TexCoordPtr
[0]->data
,
426 VB
->TexCoordPtr
[0]->size
,
427 VB
->TexCoordPtr
[0]->stride
,
430 vfmt1
|= VB
->TexCoordPtr
[0]->size
<< R200_VTX_TEX0_COMP_CNT_SHIFT
;
431 component
[nr
++] = &rmesa
->tcl
.tex
[0];
434 if (inputs
& VERT_BIT_TEX1
) {
435 if (!rmesa
->tcl
.tex
[1].buf
)
437 &(rmesa
->tcl
.tex
[1]),
438 (char *)VB
->TexCoordPtr
[1]->data
,
439 VB
->TexCoordPtr
[1]->size
,
440 VB
->TexCoordPtr
[1]->stride
,
443 vfmt1
|= VB
->TexCoordPtr
[1]->size
<< R200_VTX_TEX1_COMP_CNT_SHIFT
;
444 component
[nr
++] = &rmesa
->tcl
.tex
[1];
447 if (vfmt0
!= rmesa
->hw
.vtx
.cmd
[VTX_VTXFMT_0
] ||
448 vfmt1
!= rmesa
->hw
.vtx
.cmd
[VTX_VTXFMT_1
]) {
449 R200_STATECHANGE( rmesa
, vtx
);
450 rmesa
->hw
.vtx
.cmd
[VTX_VTXFMT_0
] = vfmt0
;
451 rmesa
->hw
.vtx
.cmd
[VTX_VTXFMT_1
] = vfmt1
;
454 rmesa
->tcl
.nr_aos_components
= nr
;
455 rmesa
->tcl
.vertex_format
= vfmt0
;
459 void r200ReleaseArrays( GLcontext
*ctx
, GLuint newinputs
)
461 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
463 /* if (R200_DEBUG & DEBUG_VERTS) */
464 /* _tnl_print_vert_flags( __FUNCTION__, newinputs ); */
466 if (newinputs
& VERT_BIT_POS
)
467 r200ReleaseDmaRegion( rmesa
, &rmesa
->tcl
.obj
, __FUNCTION__
);
469 if (newinputs
& VERT_BIT_NORMAL
)
470 r200ReleaseDmaRegion( rmesa
, &rmesa
->tcl
.norm
, __FUNCTION__
);
472 if (newinputs
& VERT_BIT_COLOR0
)
473 r200ReleaseDmaRegion( rmesa
, &rmesa
->tcl
.rgba
, __FUNCTION__
);
475 if (newinputs
& VERT_BIT_COLOR1
)
476 r200ReleaseDmaRegion( rmesa
, &rmesa
->tcl
.spec
, __FUNCTION__
);
478 if (newinputs
& VERT_BIT_TEX0
)
479 r200ReleaseDmaRegion( rmesa
, &rmesa
->tcl
.tex
[0], __FUNCTION__
);
481 if (newinputs
& VERT_BIT_TEX1
)
482 r200ReleaseDmaRegion( rmesa
, &rmesa
->tcl
.tex
[1], __FUNCTION__
);