1 /* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_maos_arrays.c,v 1.1 2002/10/30 12:51:55 alanh Exp $ */
2 /**************************************************************************
4 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
5 Tungsten Graphics Inc., Cedar Park, Texas.
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>
41 #include "swrast_setup/swrast_setup.h"
42 #include "math/m_translate.h"
44 #include "tnl/t_context.h"
45 #include "tnl/t_imm_debug.h"
47 #include "radeon_context.h"
48 #include "radeon_ioctl.h"
49 #include "radeon_state.h"
50 #include "radeon_swtcl.h"
51 #include "radeon_maos.h"
54 * - from radeon_tcl_render
55 * - call radeonEmitArrays 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 radeon_dma_region
*rvb
,
68 radeon_color_t
*out
= (radeon_color_t
*)(rvb
->start
+ rvb
->address
);
70 if (RADEON_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 radeon_dma_region
*rvb
,
114 int *out
= (int *)(rvb
->address
+ rvb
->start
);
116 if (RADEON_DEBUG
& DEBUG_VERTS
)
117 fprintf(stderr
, "%s count %d stride %d\n",
118 __FUNCTION__
, count
, stride
);
121 COPY_DWORDS( out
, data
, count
);
123 for (i
= 0; i
< count
; i
++) {
124 *out
++ = LE32_TO_CPU(*(int *)data
);
130 static void emit_ubyte_rgba( GLcontext
*ctx
,
131 struct radeon_dma_region
*rvb
,
137 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
139 if (RADEON_DEBUG
& DEBUG_VERTS
)
140 fprintf(stderr
, "%s %d/%d\n", __FUNCTION__
, count
, size
);
145 radeonAllocDmaRegion( rmesa
, rvb
, 4, 4 );
147 rvb
->aos_start
= GET_START(rvb
);
152 radeonAllocDmaRegion( rmesa
, rvb
, 4 * count
, 4 ); /* alignment? */
153 rvb
->aos_start
= GET_START(rvb
);
162 emit_ubyte_rgba3( ctx
, rvb
, data
, stride
, count
);
165 emit_ubyte_rgba4( ctx
, rvb
, data
, stride
, count
);
177 static void emit_vec8( GLcontext
*ctx
,
178 struct radeon_dma_region
*rvb
,
184 int *out
= (int *)(rvb
->address
+ rvb
->start
);
186 if (RADEON_DEBUG
& DEBUG_VERTS
)
187 fprintf(stderr
, "%s count %d stride %d\n",
188 __FUNCTION__
, count
, stride
);
191 COPY_DWORDS( out
, data
, count
*2 );
193 for (i
= 0; i
< count
; i
++) {
194 out
[0] = *(int *)data
;
195 out
[1] = *(int *)(data
+4);
201 static void emit_vec12( GLcontext
*ctx
,
202 struct radeon_dma_region
*rvb
,
208 int *out
= (int *)(rvb
->address
+ rvb
->start
);
210 if (RADEON_DEBUG
& DEBUG_VERTS
)
211 fprintf(stderr
, "%s count %d stride %d out %p data %p\n",
212 __FUNCTION__
, count
, stride
, out
, data
);
215 COPY_DWORDS( out
, data
, count
*3 );
217 for (i
= 0; i
< count
; i
++) {
218 out
[0] = *(int *)data
;
219 out
[1] = *(int *)(data
+4);
220 out
[2] = *(int *)(data
+8);
226 static void emit_vec16( GLcontext
*ctx
,
227 struct radeon_dma_region
*rvb
,
233 int *out
= (int *)(rvb
->address
+ rvb
->start
);
235 if (RADEON_DEBUG
& DEBUG_VERTS
)
236 fprintf(stderr
, "%s count %d stride %d\n",
237 __FUNCTION__
, count
, stride
);
240 COPY_DWORDS( out
, data
, count
*4 );
242 for (i
= 0; i
< count
; i
++) {
243 out
[0] = *(int *)data
;
244 out
[1] = *(int *)(data
+4);
245 out
[2] = *(int *)(data
+8);
246 out
[3] = *(int *)(data
+12);
253 static void emit_vector( GLcontext
*ctx
,
254 struct radeon_dma_region
*rvb
,
260 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
262 if (RADEON_DEBUG
& DEBUG_VERTS
)
263 fprintf(stderr
, "%s count %d size %d stride %d\n",
264 __FUNCTION__
, count
, size
, stride
);
269 radeonAllocDmaRegion( rmesa
, rvb
, size
* 4, 4 );
271 rvb
->aos_start
= GET_START(rvb
);
273 rvb
->aos_size
= size
;
276 radeonAllocDmaRegion( rmesa
, rvb
, size
* count
* 4, 4 ); /* alignment? */
277 rvb
->aos_start
= GET_START(rvb
);
278 rvb
->aos_stride
= size
;
279 rvb
->aos_size
= size
;
286 emit_vec8( ctx
, rvb
, data
, stride
, count
);
289 emit_vec12( ctx
, rvb
, data
, stride
, count
);
292 emit_vec16( ctx
, rvb
, data
, stride
, count
);
304 static void emit_s0_vec( GLcontext
*ctx
,
305 struct radeon_dma_region
*rvb
,
311 int *out
= (int *)(rvb
->address
+ rvb
->start
);
313 if (RADEON_DEBUG
& DEBUG_VERTS
)
314 fprintf(stderr
, "%s count %d stride %d\n",
315 __FUNCTION__
, count
, stride
);
317 for (i
= 0; i
< count
; i
++) {
318 out
[0] = *(int *)data
;
325 static void emit_stq_vec( GLcontext
*ctx
,
326 struct radeon_dma_region
*rvb
,
332 int *out
= (int *)(rvb
->address
+ rvb
->start
);
334 if (RADEON_DEBUG
& DEBUG_VERTS
)
335 fprintf(stderr
, "%s count %d stride %d\n",
336 __FUNCTION__
, count
, stride
);
338 for (i
= 0; i
< count
; i
++) {
339 out
[0] = *(int *)data
;
340 out
[1] = *(int *)(data
+4);
341 out
[2] = *(int *)(data
+12);
350 static void emit_tex_vector( GLcontext
*ctx
,
351 struct radeon_dma_region
*rvb
,
357 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
360 if (RADEON_DEBUG
& DEBUG_VERTS
)
361 fprintf(stderr
, "%s %d/%d\n", __FUNCTION__
, count
, size
);
366 case 4: emitsize
= 3; break;
367 default: emitsize
= 2; break;
372 radeonAllocDmaRegion( rmesa
, rvb
, 4 * emitsize
, 4 );
374 rvb
->aos_start
= GET_START(rvb
);
376 rvb
->aos_size
= emitsize
;
379 radeonAllocDmaRegion( rmesa
, rvb
, 4 * emitsize
* count
, 4 );
380 rvb
->aos_start
= GET_START(rvb
);
381 rvb
->aos_stride
= emitsize
;
382 rvb
->aos_size
= emitsize
;
390 emit_s0_vec( ctx
, rvb
, data
, stride
, count
);
393 emit_vec8( ctx
, rvb
, data
, stride
, count
);
396 emit_vec8( ctx
, rvb
, data
, stride
, count
);
399 emit_stq_vec( ctx
, rvb
, data
, stride
, count
);
411 /* Emit any changed arrays to new GART memory, re-emit a packet to
414 void radeonEmitArrays( GLcontext
*ctx
, GLuint inputs
)
416 radeonContextPtr rmesa
= RADEON_CONTEXT( ctx
);
417 struct vertex_buffer
*VB
= &TNL_CONTEXT( ctx
)->vb
;
418 struct radeon_dma_region
**component
= rmesa
->tcl
.aos_components
;
421 GLuint count
= VB
->Count
;
425 if (RADEON_DEBUG
& DEBUG_VERTS
)
426 _tnl_print_vert_flags( __FUNCTION__
, inputs
);
430 if (!rmesa
->tcl
.obj
.buf
)
433 (char *)VB
->ObjPtr
->data
,
438 switch( VB
->ObjPtr
->size
) {
439 case 4: vfmt
|= RADEON_CP_VC_FRMT_W0
;
440 case 3: vfmt
|= RADEON_CP_VC_FRMT_Z
;
441 case 2: vfmt
|= RADEON_CP_VC_FRMT_XY
;
444 component
[nr
++] = &rmesa
->tcl
.obj
;
448 if (inputs
& VERT_BIT_NORMAL
) {
449 if (!rmesa
->tcl
.norm
.buf
)
452 (char *)VB
->NormalPtr
->data
,
454 VB
->NormalPtr
->stride
,
457 vfmt
|= RADEON_CP_VC_FRMT_N0
;
458 component
[nr
++] = &rmesa
->tcl
.norm
;
461 if (inputs
& VERT_BIT_COLOR0
) {
462 if (VB
->ColorPtr
[0]->Type
== GL_UNSIGNED_BYTE
) {
463 if (!rmesa
->tcl
.rgba
.buf
)
464 emit_ubyte_rgba( ctx
,
466 (char *)VB
->ColorPtr
[0]->Ptr
,
467 VB
->ColorPtr
[0]->Size
,
468 VB
->ColorPtr
[0]->StrideB
,
471 vfmt
|= RADEON_CP_VC_FRMT_PKCOLOR
;
476 if (VB
->ColorPtr
[0]->Size
== 4 &&
477 (VB
->ColorPtr
[0]->StrideB
!= 0 ||
478 ((GLfloat
*)VB
->ColorPtr
[0]->Ptr
)[3] != 1.0)) {
479 vfmt
|= RADEON_CP_VC_FRMT_FPCOLOR
| RADEON_CP_VC_FRMT_FPALPHA
;
483 vfmt
|= RADEON_CP_VC_FRMT_FPCOLOR
;
487 if (!rmesa
->tcl
.rgba
.buf
)
490 (char *)VB
->ColorPtr
[0]->Ptr
,
492 VB
->ColorPtr
[0]->StrideB
,
496 component
[nr
++] = &rmesa
->tcl
.rgba
;
500 if (inputs
& VERT_BIT_COLOR1
) {
501 if (!rmesa
->tcl
.spec
.buf
) {
503 emit_ubyte_rgba( ctx
,
505 (char *)VB
->SecondaryColorPtr
[0]->Ptr
,
507 VB
->SecondaryColorPtr
[0]->StrideB
,
511 vfmt
|= RADEON_CP_VC_FRMT_PKSPEC
;
512 component
[nr
++] = &rmesa
->tcl
.spec
;
515 vtx
= (rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &
516 ~(RADEON_TCL_VTX_Q0
|RADEON_TCL_VTX_Q1
));
518 if (inputs
& VERT_BIT_TEX0
) {
519 if (!rmesa
->tcl
.tex
[0].buf
)
520 emit_tex_vector( ctx
,
521 &(rmesa
->tcl
.tex
[0]),
522 (char *)VB
->TexCoordPtr
[0]->data
,
523 VB
->TexCoordPtr
[0]->size
,
524 VB
->TexCoordPtr
[0]->stride
,
527 switch( VB
->TexCoordPtr
[0]->size
) {
529 vtx
|= RADEON_TCL_VTX_Q0
;
530 vfmt
|= RADEON_CP_VC_FRMT_Q0
;
532 vfmt
|= RADEON_CP_VC_FRMT_ST0
;
534 component
[nr
++] = &rmesa
->tcl
.tex
[0];
537 if (inputs
& VERT_BIT_TEX1
) {
538 if (!rmesa
->tcl
.tex
[1].buf
)
539 emit_tex_vector( ctx
,
540 &(rmesa
->tcl
.tex
[1]),
541 (char *)VB
->TexCoordPtr
[1]->data
,
542 VB
->TexCoordPtr
[1]->size
,
543 VB
->TexCoordPtr
[1]->stride
,
546 switch( VB
->TexCoordPtr
[1]->size
) {
548 vtx
|= RADEON_TCL_VTX_Q1
;
549 vfmt
|= RADEON_CP_VC_FRMT_Q1
;
551 vfmt
|= RADEON_CP_VC_FRMT_ST1
;
553 component
[nr
++] = &rmesa
->tcl
.tex
[1];
556 if (vtx
!= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
]) {
557 RADEON_STATECHANGE( rmesa
, tcl
);
558 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] = vtx
;
561 rmesa
->tcl
.nr_aos_components
= nr
;
562 rmesa
->tcl
.vertex_format
= vfmt
;
566 void radeonReleaseArrays( GLcontext
*ctx
, GLuint newinputs
)
568 radeonContextPtr rmesa
= RADEON_CONTEXT( ctx
);
571 if (RADEON_DEBUG
& DEBUG_VERTS
)
572 _tnl_print_vert_flags( __FUNCTION__
, newinputs
);
575 if (newinputs
& VERT_BIT_POS
)
576 radeonReleaseDmaRegion( rmesa
, &rmesa
->tcl
.obj
, __FUNCTION__
);
578 if (newinputs
& VERT_BIT_NORMAL
)
579 radeonReleaseDmaRegion( rmesa
, &rmesa
->tcl
.norm
, __FUNCTION__
);
581 if (newinputs
& VERT_BIT_COLOR0
)
582 radeonReleaseDmaRegion( rmesa
, &rmesa
->tcl
.rgba
, __FUNCTION__
);
584 if (newinputs
& VERT_BIT_COLOR1
)
585 radeonReleaseDmaRegion( rmesa
, &rmesa
->tcl
.spec
, __FUNCTION__
);
587 if (newinputs
& VERT_BIT_TEX0
)
588 radeonReleaseDmaRegion( rmesa
, &rmesa
->tcl
.tex
[0], __FUNCTION__
);
590 if (newinputs
& VERT_BIT_TEX1
)
591 radeonReleaseDmaRegion( rmesa
, &rmesa
->tcl
.tex
[1], __FUNCTION__
);