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"
57 * - from r200_tcl_render
58 * - call r200EmitArrays to ensure uptodate arrays in dma
59 * - emit primitives (new type?) which reference the data
60 * -- need to use elts for lineloop, quads, quadstrip/flat
61 * -- other primitives are all well-formed (need tristrip-1,fake-poly)
64 static void emit_ubyte_rgba3( GLcontext
*ctx
,
65 struct r200_dma_region
*rvb
,
71 r200_color_t
*out
= (r200_color_t
*)(rvb
->start
+ rvb
->address
);
73 if (R200_DEBUG
& DEBUG_VERTS
)
74 fprintf(stderr
, "%s count %d stride %d out %p\n",
75 __FUNCTION__
, count
, stride
, (void *)out
);
77 for (i
= 0; i
< count
; i
++) {
79 out
->green
= *(data
+1);
80 out
->blue
= *(data
+2);
87 static void emit_ubyte_rgba4( GLcontext
*ctx
,
88 struct r200_dma_region
*rvb
,
94 int *out
= (int *)(rvb
->address
+ rvb
->start
);
96 if (R200_DEBUG
& DEBUG_VERTS
)
97 fprintf(stderr
, "%s count %d stride %d\n",
98 __FUNCTION__
, count
, stride
);
101 for (i
= 0; i
< count
; i
++)
102 ((int *)out
)[i
] = LE32_TO_CPU(((int *)data
)[i
]);
104 for (i
= 0; i
< count
; i
++) {
105 *(int *)out
++ = LE32_TO_CPU(*(int *)data
);
112 static void emit_ubyte_rgba( GLcontext
*ctx
,
113 struct r200_dma_region
*rvb
,
119 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
121 if (R200_DEBUG
& DEBUG_VERTS
)
122 fprintf(stderr
, "%s %d/%d\n", __FUNCTION__
, count
, size
);
127 r200AllocDmaRegion( rmesa
, rvb
, 4, 4 );
129 rvb
->aos_start
= GET_START(rvb
);
134 r200AllocDmaRegion( rmesa
, rvb
, 4 * count
, 4 ); /* alignment? */
135 rvb
->aos_start
= GET_START(rvb
);
144 emit_ubyte_rgba3( ctx
, rvb
, data
, stride
, count
);
147 emit_ubyte_rgba4( ctx
, rvb
, data
, stride
, count
);
158 #if defined(USE_X86_ASM)
159 #define COPY_DWORDS( dst, src, nr ) \
162 __asm__ __volatile__( "rep ; movsl" \
163 : "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \
169 #define COPY_DWORDS( dst, src, nr ) \
172 for ( j = 0 ; j < nr ; j++ ) \
173 dst[j] = ((int *)src)[j]; \
179 static void emit_vecfog( GLcontext
*ctx
,
180 struct r200_dma_region
*rvb
,
188 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
190 if (R200_DEBUG
& DEBUG_VERTS
)
191 fprintf(stderr
, "%s count %d stride %d\n",
192 __FUNCTION__
, count
, stride
);
197 r200AllocDmaRegion( rmesa
, rvb
, 4, 4 );
199 rvb
->aos_start
= GET_START(rvb
);
204 r200AllocDmaRegion( rmesa
, rvb
, count
* 4, 4 ); /* alignment? */
205 rvb
->aos_start
= GET_START(rvb
);
212 out
= (GLfloat
*)(rvb
->address
+ rvb
->start
);
213 for (i
= 0; i
< count
; i
++) {
214 out
[0] = r200ComputeFogBlendFactor( ctx
, *(GLfloat
*)data
);
222 static void emit_vec4( GLcontext
*ctx
,
223 struct r200_dma_region
*rvb
,
229 int *out
= (int *)(rvb
->address
+ rvb
->start
);
231 if (R200_DEBUG
& DEBUG_VERTS
)
232 fprintf(stderr
, "%s count %d stride %d\n",
233 __FUNCTION__
, count
, stride
);
236 COPY_DWORDS( out
, data
, count
);
238 for (i
= 0; i
< count
; i
++) {
239 out
[0] = *(int *)data
;
246 static void emit_vec8( GLcontext
*ctx
,
247 struct r200_dma_region
*rvb
,
253 int *out
= (int *)(rvb
->address
+ rvb
->start
);
255 if (R200_DEBUG
& DEBUG_VERTS
)
256 fprintf(stderr
, "%s count %d stride %d\n",
257 __FUNCTION__
, count
, stride
);
260 COPY_DWORDS( out
, data
, count
*2 );
262 for (i
= 0; i
< count
; i
++) {
263 out
[0] = *(int *)data
;
264 out
[1] = *(int *)(data
+4);
270 static void emit_vec12( GLcontext
*ctx
,
271 struct r200_dma_region
*rvb
,
277 int *out
= (int *)(rvb
->address
+ rvb
->start
);
279 if (R200_DEBUG
& DEBUG_VERTS
)
280 fprintf(stderr
, "%s count %d stride %d out %p data %p\n",
281 __FUNCTION__
, count
, stride
, (void *)out
, (void *)data
);
284 COPY_DWORDS( out
, data
, count
*3 );
286 for (i
= 0; i
< count
; i
++) {
287 out
[0] = *(int *)data
;
288 out
[1] = *(int *)(data
+4);
289 out
[2] = *(int *)(data
+8);
295 static void emit_vec16( GLcontext
*ctx
,
296 struct r200_dma_region
*rvb
,
302 int *out
= (int *)(rvb
->address
+ rvb
->start
);
304 if (R200_DEBUG
& DEBUG_VERTS
)
305 fprintf(stderr
, "%s count %d stride %d\n",
306 __FUNCTION__
, count
, stride
);
309 COPY_DWORDS( out
, data
, count
*4 );
311 for (i
= 0; i
< count
; i
++) {
312 out
[0] = *(int *)data
;
313 out
[1] = *(int *)(data
+4);
314 out
[2] = *(int *)(data
+8);
315 out
[3] = *(int *)(data
+12);
322 static void emit_vector( GLcontext
*ctx
,
323 struct r200_dma_region
*rvb
,
329 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
331 if (R200_DEBUG
& DEBUG_VERTS
)
332 fprintf(stderr
, "%s count %d size %d stride %d\n",
333 __FUNCTION__
, count
, size
, stride
);
338 r200AllocDmaRegion( rmesa
, rvb
, size
* 4, 4 );
340 rvb
->aos_start
= GET_START(rvb
);
342 rvb
->aos_size
= size
;
345 r200AllocDmaRegion( rmesa
, rvb
, size
* count
* 4, 4 ); /* alignment? */
346 rvb
->aos_start
= GET_START(rvb
);
347 rvb
->aos_stride
= size
;
348 rvb
->aos_size
= size
;
355 emit_vec4( ctx
, rvb
, data
, stride
, count
);
358 emit_vec8( ctx
, rvb
, data
, stride
, count
);
361 emit_vec12( ctx
, rvb
, data
, stride
, count
);
364 emit_vec16( ctx
, rvb
, data
, stride
, count
);
376 /* Emit any changed arrays to new GART memory, re-emit a packet to
379 void r200EmitArrays( GLcontext
*ctx
, GLuint inputs
)
381 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
382 struct vertex_buffer
*VB
= &TNL_CONTEXT( ctx
)->vb
;
383 struct r200_dma_region
**component
= rmesa
->tcl
.aos_components
;
385 GLuint vfmt0
= 0, vfmt1
= 0;
386 GLuint count
= VB
->Count
;
388 GLuint generic_in_mapped
= 0;
389 struct r200_vertex_program
*vp
= NULL
;
391 /* this looks way more complicated than necessary... */
392 if (ctx
->VertexProgram
._Enabled
) {
393 vp
= rmesa
->curr_vp_hw
;
394 generic_in_mapped
= vp
->gen_inputs_mapped
;
397 if (inputs
& VERT_BIT_POS
) {
398 if (!rmesa
->tcl
.obj
.buf
)
401 (char *)VB
->ObjPtr
->data
,
406 switch( VB
->ObjPtr
->size
) {
407 case 4: vfmt0
|= R200_VTX_W0
;
408 case 3: vfmt0
|= R200_VTX_Z0
;
413 component
[nr
++] = &rmesa
->tcl
.obj
;
415 else if (generic_in_mapped
& (1 << 0)) {
416 int geninput
= vp
->rev_inputs
[0] - VERT_ATTRIB_GENERIC0
;
417 if (!rmesa
->tcl
.generic
[geninput
].buf
) {
419 &(rmesa
->tcl
.generic
[geninput
]),
420 (char *)VB
->AttribPtr
[geninput
+ VERT_ATTRIB_GENERIC0
]->data
,
422 VB
->AttribPtr
[geninput
+ VERT_ATTRIB_GENERIC0
]->stride
,
425 component
[nr
++] = &rmesa
->tcl
.generic
[geninput
];
426 vfmt0
|= R200_VTX_W0
| R200_VTX_Z0
;
429 if (inputs
& VERT_BIT_WEIGHT
) {
430 if (!rmesa
->tcl
.weight
.buf
)
433 (char *)VB
->AttribPtr
[VERT_ATTRIB_WEIGHT
]->data
,
434 VB
->AttribPtr
[VERT_ATTRIB_WEIGHT
]->size
,
435 VB
->AttribPtr
[VERT_ATTRIB_WEIGHT
]->stride
,
438 assert(VB
->AttribPtr
[VERT_ATTRIB_WEIGHT
]->size
<= 4);
439 vfmt0
|= VB
->AttribPtr
[VERT_ATTRIB_WEIGHT
]->size
<< R200_VTX_WEIGHT_COUNT_SHIFT
;
440 component
[nr
++] = &rmesa
->tcl
.weight
;
443 if (inputs
& VERT_BIT_NORMAL
) {
444 if (!rmesa
->tcl
.norm
.buf
)
447 (char *)VB
->NormalPtr
->data
,
449 VB
->NormalPtr
->stride
,
452 vfmt0
|= R200_VTX_N0
;
453 component
[nr
++] = &rmesa
->tcl
.norm
;
456 if (inputs
& VERT_BIT_FOG
) {
457 if (!rmesa
->tcl
.fog
.buf
) {
458 if (ctx
->VertexProgram
._Enabled
)
461 (char *)VB
->FogCoordPtr
->data
,
463 VB
->FogCoordPtr
->stride
,
468 (char *)VB
->FogCoordPtr
->data
,
469 VB
->FogCoordPtr
->stride
,
473 vfmt0
|= R200_VTX_DISCRETE_FOG
;
474 component
[nr
++] = &rmesa
->tcl
.fog
;
477 if (inputs
& VERT_BIT_COLOR0
) {
480 if (VB
->ColorPtr
[0]->size
== 4 &&
481 (VB
->ColorPtr
[0]->stride
!= 0 ||
482 VB
->ColorPtr
[0]->data
[0][3] != 1.0)) {
483 vfmt0
|= R200_VTX_FP_RGBA
<< R200_VTX_COLOR_0_SHIFT
;
487 vfmt0
|= R200_VTX_FP_RGB
<< R200_VTX_COLOR_0_SHIFT
;
491 if (!rmesa
->tcl
.rgba
.buf
)
494 (char *)VB
->ColorPtr
[0]->data
,
496 VB
->ColorPtr
[0]->stride
,
499 component
[nr
++] = &rmesa
->tcl
.rgba
;
501 /* vfmt0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT;
502 emit_ubyte_rgba( ctx, &rmesa->tcl.rgba,
503 (char *)VB->ColorPtr[0]->data, 4,
504 VB->ColorPtr[0]->stride, count);*/
505 else if (generic_in_mapped
& (1 << 2)) {
506 int geninput
= vp
->rev_inputs
[2] - VERT_ATTRIB_GENERIC0
;
507 if (!rmesa
->tcl
.generic
[geninput
].buf
) {
509 &(rmesa
->tcl
.generic
[geninput
]),
510 (char *)VB
->AttribPtr
[geninput
+ VERT_ATTRIB_GENERIC0
]->data
,
512 VB
->AttribPtr
[geninput
+ VERT_ATTRIB_GENERIC0
]->stride
,
515 component
[nr
++] = &rmesa
->tcl
.generic
[geninput
];
516 vfmt0
|= R200_VTX_FP_RGBA
<< R200_VTX_COLOR_0_SHIFT
;
520 if (inputs
& VERT_BIT_COLOR1
) {
521 if (!rmesa
->tcl
.spec
.buf
) {
524 (char *)VB
->SecondaryColorPtr
[0]->data
,
526 VB
->SecondaryColorPtr
[0]->stride
,
530 /* How does this work?
532 vfmt0
|= R200_VTX_FP_RGB
<< R200_VTX_COLOR_1_SHIFT
;
533 component
[nr
++] = &rmesa
->tcl
.spec
;
535 else if (generic_in_mapped
& (1 << 3)) {
536 int geninput
= vp
->rev_inputs
[3] - VERT_ATTRIB_GENERIC0
;
537 if (!rmesa
->tcl
.generic
[geninput
].buf
) {
539 &(rmesa
->tcl
.generic
[geninput
]),
540 (char *)VB
->AttribPtr
[geninput
+ VERT_ATTRIB_GENERIC0
]->data
,
542 VB
->AttribPtr
[geninput
+ VERT_ATTRIB_GENERIC0
]->stride
,
545 component
[nr
++] = &rmesa
->tcl
.generic
[geninput
];
546 vfmt0
|= R200_VTX_FP_RGBA
<< R200_VTX_COLOR_1_SHIFT
;
549 if (generic_in_mapped
& (1 << 4)) {
550 int geninput
= vp
->rev_inputs
[4] - VERT_ATTRIB_GENERIC0
;
551 if (!rmesa
->tcl
.generic
[geninput
].buf
) {
553 &(rmesa
->tcl
.generic
[geninput
]),
554 (char *)VB
->AttribPtr
[geninput
+ VERT_ATTRIB_GENERIC0
]->data
,
556 VB
->AttribPtr
[geninput
+ VERT_ATTRIB_GENERIC0
]->stride
,
559 component
[nr
++] = &rmesa
->tcl
.generic
[geninput
];
560 vfmt0
|= R200_VTX_FP_RGBA
<< R200_VTX_COLOR_2_SHIFT
;
563 if (generic_in_mapped
& (1 << 5)) {
564 int geninput
= vp
->rev_inputs
[5] - VERT_ATTRIB_GENERIC0
;
565 if (!rmesa
->tcl
.generic
[geninput
].buf
) {
567 &(rmesa
->tcl
.generic
[geninput
]),
568 (char *)VB
->AttribPtr
[geninput
+ VERT_ATTRIB_GENERIC0
]->data
,
570 VB
->AttribPtr
[geninput
+ VERT_ATTRIB_GENERIC0
]->stride
,
573 component
[nr
++] = &rmesa
->tcl
.generic
[geninput
];
574 vfmt0
|= R200_VTX_FP_RGBA
<< R200_VTX_COLOR_3_SHIFT
;
577 for ( i
= 0 ; i
< 6 ; i
++ ) {
578 if (inputs
& (VERT_BIT_TEX0
<< i
)) {
579 if (!rmesa
->tcl
.tex
[i
].buf
)
581 &(rmesa
->tcl
.tex
[i
]),
582 (char *)VB
->TexCoordPtr
[i
]->data
,
583 VB
->TexCoordPtr
[i
]->size
,
584 VB
->TexCoordPtr
[i
]->stride
,
587 vfmt1
|= VB
->TexCoordPtr
[i
]->size
<< (i
* 3);
588 component
[nr
++] = &rmesa
->tcl
.tex
[i
];
590 else if (generic_in_mapped
& (1 << (i
+ 6))) {
591 int geninput
= vp
->rev_inputs
[i
+ 6] - VERT_ATTRIB_GENERIC0
;
592 if (!rmesa
->tcl
.generic
[geninput
].buf
) {
594 &(rmesa
->tcl
.generic
[geninput
]),
595 (char *)VB
->AttribPtr
[geninput
+ VERT_ATTRIB_GENERIC0
]->data
,
597 VB
->AttribPtr
[geninput
+ VERT_ATTRIB_GENERIC0
]->stride
,
600 component
[nr
++] = &rmesa
->tcl
.generic
[geninput
];
601 vfmt1
|= 4 << (R200_VTX_TEX0_COMP_CNT_SHIFT
+ (i
* 3));
605 if (generic_in_mapped
& (1 << 13)) {
606 int geninput
= vp
->rev_inputs
[13] - VERT_ATTRIB_GENERIC0
;
607 if (!rmesa
->tcl
.generic
[geninput
].buf
) {
609 &(rmesa
->tcl
.generic
[geninput
]),
610 (char *)VB
->AttribPtr
[geninput
+ VERT_ATTRIB_GENERIC0
]->data
,
612 VB
->AttribPtr
[geninput
+ VERT_ATTRIB_GENERIC0
]->stride
,
615 component
[nr
++] = &rmesa
->tcl
.generic
[geninput
];
616 vfmt0
|= R200_VTX_XY1
| R200_VTX_Z1
| R200_VTX_W1
;
619 /* doesn't work. Wrong order with mixed generic & conventional! */
621 if (ctx->VertexProgram._Enabled) {
622 int *vp_inputs = rmesa->curr_vp_hw->inputs;
623 for ( i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++ ) {
624 if (inputs & (1 << i)) {
625 int geninput = i - VERT_ATTRIB_GENERIC0;
626 if (!rmesa->tcl.generic[geninput].buf) {
628 &(rmesa->tcl.generic[geninput]),
629 (char *)VB->AttribPtr[i]->data,
631 VB->AttribPtr[i]->stride,
634 component[nr++] = &rmesa->tcl.generic[geninput];
635 switch (vp_inputs[i]) {
637 vfmt0 |= R200_VTX_W0 | R200_VTX_Z0;
643 vfmt0 |= R200_VTX_FP_RGBA << (R200_VTX_COLOR_0_SHIFT + (vp_inputs[i] - 2) * 2);
651 vfmt1 |= 4 << (R200_VTX_TEX0_COMP_CNT_SHIFT + (vp_inputs[i] - 6) * 3);
654 vfmt0 |= R200_VTX_XY1 | R200_VTX_Z1 | R200_VTX_W1;
666 if (vfmt0
!= rmesa
->hw
.vtx
.cmd
[VTX_VTXFMT_0
] ||
667 vfmt1
!= rmesa
->hw
.vtx
.cmd
[VTX_VTXFMT_1
]) {
668 R200_STATECHANGE( rmesa
, vtx
);
669 rmesa
->hw
.vtx
.cmd
[VTX_VTXFMT_0
] = vfmt0
;
670 rmesa
->hw
.vtx
.cmd
[VTX_VTXFMT_1
] = vfmt1
;
673 rmesa
->tcl
.nr_aos_components
= nr
;
674 rmesa
->tcl
.vertex_format
= vfmt0
;
678 void r200ReleaseArrays( GLcontext
*ctx
, GLuint newinputs
)
681 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
683 /* if (R200_DEBUG & DEBUG_VERTS) */
684 /* _tnl_print_vert_flags( __FUNCTION__, newinputs ); */
686 if (newinputs
& VERT_BIT_POS
)
687 r200ReleaseDmaRegion( rmesa
, &rmesa
->tcl
.obj
, __FUNCTION__
);
689 if (newinputs
& VERT_BIT_WEIGHT
)
690 r200ReleaseDmaRegion( rmesa
, &rmesa
->tcl
.weight
, __FUNCTION__
);
692 if (newinputs
& VERT_BIT_NORMAL
)
693 r200ReleaseDmaRegion( rmesa
, &rmesa
->tcl
.norm
, __FUNCTION__
);
695 if (newinputs
& VERT_BIT_FOG
)
696 r200ReleaseDmaRegion( rmesa
, &rmesa
->tcl
.fog
, __FUNCTION__
);
698 if (newinputs
& VERT_BIT_COLOR0
)
699 r200ReleaseDmaRegion( rmesa
, &rmesa
->tcl
.rgba
, __FUNCTION__
);
701 if (newinputs
& VERT_BIT_COLOR1
)
702 r200ReleaseDmaRegion( rmesa
, &rmesa
->tcl
.spec
, __FUNCTION__
);
704 for (unit
= 0 ; unit
< ctx
->Const
.MaxTextureUnits
; unit
++) {
705 if (newinputs
& VERT_BIT_TEX(unit
))
706 r200ReleaseDmaRegion( rmesa
, &rmesa
->tcl
.tex
[unit
], __FUNCTION__
);
709 if (ctx
->VertexProgram
._Enabled
) {
711 for (i
= VERT_ATTRIB_GENERIC0
; i
< VERT_ATTRIB_MAX
; i
++) {
712 if (newinputs
& (1 << i
))
713 r200ReleaseDmaRegion( rmesa
,
714 &rmesa
->tcl
.generic
[i
- VERT_ATTRIB_GENERIC0
], __FUNCTION__
);