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>
42 #include "swrast_setup/swrast_setup.h"
43 #include "math/m_translate.h"
45 #include "tnl/t_context.h"
46 #include "tnl/t_imm_debug.h"
48 #include "radeon_context.h"
49 #include "radeon_ioctl.h"
50 #include "radeon_state.h"
51 #include "radeon_swtcl.h"
52 #include "radeon_maos.h"
55 * - from radeon_tcl_render
56 * - call radeonEmitArrays to ensure uptodate arrays in dma
57 * - emit primitives (new type?) which reference the data
58 * -- need to use elts for lineloop, quads, quadstrip/flat
59 * -- other primitives are all well-formed (need tristrip-1,fake-poly)
62 static void emit_ubyte_rgba3( GLcontext
*ctx
,
63 struct radeon_dma_region
*rvb
,
69 radeon_color_t
*out
= (radeon_color_t
*)(rvb
->start
+ rvb
->address
);
71 if (RADEON_DEBUG
& DEBUG_VERTS
)
72 fprintf(stderr
, "%s count %d stride %d out %p\n",
73 __FUNCTION__
, count
, stride
, out
);
75 for (i
= 0; i
< count
; i
++) {
77 out
->green
= *(data
+1);
78 out
->blue
= *(data
+2);
86 #if defined(USE_X86_ASM)
87 #define COPY_DWORDS( dst, src, nr ) \
90 __asm__ __volatile__( "rep ; movsl" \
91 : "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \
97 #define COPY_DWORDS( dst, src, nr ) \
100 for ( j = 0 ; j < nr ; j++ ) \
101 dst[j] = ((int *)src)[j]; \
108 static void emit_ubyte_rgba4( GLcontext
*ctx
,
109 struct radeon_dma_region
*rvb
,
115 int *out
= (int *)(rvb
->address
+ rvb
->start
);
117 if (RADEON_DEBUG
& DEBUG_VERTS
)
118 fprintf(stderr
, "%s count %d stride %d\n",
119 __FUNCTION__
, count
, stride
);
122 COPY_DWORDS( out
, data
, count
);
124 for (i
= 0; i
< count
; i
++) {
125 *out
++ = LE32_TO_CPU(*(int *)data
);
131 static void emit_ubyte_rgba( GLcontext
*ctx
,
132 struct radeon_dma_region
*rvb
,
138 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
140 if (RADEON_DEBUG
& DEBUG_VERTS
)
141 fprintf(stderr
, "%s %d/%d\n", __FUNCTION__
, count
, size
);
146 radeonAllocDmaRegion( rmesa
, rvb
, 4, 4 );
148 rvb
->aos_start
= GET_START(rvb
);
153 radeonAllocDmaRegion( rmesa
, rvb
, 4 * count
, 4 ); /* alignment? */
154 rvb
->aos_start
= GET_START(rvb
);
163 emit_ubyte_rgba3( ctx
, rvb
, data
, stride
, count
);
166 emit_ubyte_rgba4( ctx
, rvb
, data
, stride
, count
);
178 static void emit_vec8( GLcontext
*ctx
,
179 struct radeon_dma_region
*rvb
,
185 int *out
= (int *)(rvb
->address
+ rvb
->start
);
187 if (RADEON_DEBUG
& DEBUG_VERTS
)
188 fprintf(stderr
, "%s count %d stride %d\n",
189 __FUNCTION__
, count
, stride
);
192 COPY_DWORDS( out
, data
, count
*2 );
194 for (i
= 0; i
< count
; i
++) {
195 out
[0] = *(int *)data
;
196 out
[1] = *(int *)(data
+4);
202 static void emit_vec12( GLcontext
*ctx
,
203 struct radeon_dma_region
*rvb
,
209 int *out
= (int *)(rvb
->address
+ rvb
->start
);
211 if (RADEON_DEBUG
& DEBUG_VERTS
)
212 fprintf(stderr
, "%s count %d stride %d out %p data %p\n",
213 __FUNCTION__
, count
, stride
, out
, data
);
216 COPY_DWORDS( out
, data
, count
*3 );
218 for (i
= 0; i
< count
; i
++) {
219 out
[0] = *(int *)data
;
220 out
[1] = *(int *)(data
+4);
221 out
[2] = *(int *)(data
+8);
227 static void emit_vec16( GLcontext
*ctx
,
228 struct radeon_dma_region
*rvb
,
234 int *out
= (int *)(rvb
->address
+ rvb
->start
);
236 if (RADEON_DEBUG
& DEBUG_VERTS
)
237 fprintf(stderr
, "%s count %d stride %d\n",
238 __FUNCTION__
, count
, stride
);
241 COPY_DWORDS( out
, data
, count
*4 );
243 for (i
= 0; i
< count
; i
++) {
244 out
[0] = *(int *)data
;
245 out
[1] = *(int *)(data
+4);
246 out
[2] = *(int *)(data
+8);
247 out
[3] = *(int *)(data
+12);
254 static void emit_vector( GLcontext
*ctx
,
255 struct radeon_dma_region
*rvb
,
261 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
263 if (RADEON_DEBUG
& DEBUG_VERTS
)
264 fprintf(stderr
, "%s count %d size %d stride %d\n",
265 __FUNCTION__
, count
, size
, stride
);
270 radeonAllocDmaRegion( rmesa
, rvb
, size
* 4, 4 );
272 rvb
->aos_start
= GET_START(rvb
);
274 rvb
->aos_size
= size
;
277 radeonAllocDmaRegion( rmesa
, rvb
, size
* count
* 4, 4 ); /* alignment? */
278 rvb
->aos_start
= GET_START(rvb
);
279 rvb
->aos_stride
= size
;
280 rvb
->aos_size
= size
;
287 emit_vec8( ctx
, rvb
, data
, stride
, count
);
290 emit_vec12( ctx
, rvb
, data
, stride
, count
);
293 emit_vec16( ctx
, rvb
, data
, stride
, count
);
305 static void emit_s0_vec( GLcontext
*ctx
,
306 struct radeon_dma_region
*rvb
,
312 int *out
= (int *)(rvb
->address
+ rvb
->start
);
314 if (RADEON_DEBUG
& DEBUG_VERTS
)
315 fprintf(stderr
, "%s count %d stride %d\n",
316 __FUNCTION__
, count
, stride
);
318 for (i
= 0; i
< count
; i
++) {
319 out
[0] = *(int *)data
;
326 static void emit_stq_vec( GLcontext
*ctx
,
327 struct radeon_dma_region
*rvb
,
333 int *out
= (int *)(rvb
->address
+ rvb
->start
);
335 if (RADEON_DEBUG
& DEBUG_VERTS
)
336 fprintf(stderr
, "%s count %d stride %d\n",
337 __FUNCTION__
, count
, stride
);
339 for (i
= 0; i
< count
; i
++) {
340 out
[0] = *(int *)data
;
341 out
[1] = *(int *)(data
+4);
342 out
[2] = *(int *)(data
+12);
351 static void emit_tex_vector( GLcontext
*ctx
,
352 struct radeon_dma_region
*rvb
,
358 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
361 if (RADEON_DEBUG
& DEBUG_VERTS
)
362 fprintf(stderr
, "%s %d/%d\n", __FUNCTION__
, count
, size
);
367 case 4: emitsize
= 3; break;
368 default: emitsize
= 2; break;
373 radeonAllocDmaRegion( rmesa
, rvb
, 4 * emitsize
, 4 );
375 rvb
->aos_start
= GET_START(rvb
);
377 rvb
->aos_size
= emitsize
;
380 radeonAllocDmaRegion( rmesa
, rvb
, 4 * emitsize
* count
, 4 );
381 rvb
->aos_start
= GET_START(rvb
);
382 rvb
->aos_stride
= emitsize
;
383 rvb
->aos_size
= emitsize
;
391 emit_s0_vec( ctx
, rvb
, data
, stride
, count
);
394 emit_vec8( ctx
, rvb
, data
, stride
, count
);
397 emit_vec8( ctx
, rvb
, data
, stride
, count
);
400 emit_stq_vec( ctx
, rvb
, data
, stride
, count
);
412 /* Emit any changed arrays to new agp memory, re-emit a packet to
415 void radeonEmitArrays( GLcontext
*ctx
, GLuint inputs
)
417 radeonContextPtr rmesa
= RADEON_CONTEXT( ctx
);
418 struct vertex_buffer
*VB
= &TNL_CONTEXT( ctx
)->vb
;
419 struct radeon_dma_region
**component
= rmesa
->tcl
.aos_components
;
422 GLuint count
= VB
->Count
;
425 if (RADEON_DEBUG
& DEBUG_VERTS
)
426 _tnl_print_vert_flags( __FUNCTION__
, inputs
);
429 if (!rmesa
->tcl
.obj
.buf
)
432 (char *)VB
->ObjPtr
->data
,
437 switch( VB
->ObjPtr
->size
) {
438 case 4: vfmt
|= RADEON_CP_VC_FRMT_W0
;
439 case 3: vfmt
|= RADEON_CP_VC_FRMT_Z
;
440 case 2: vfmt
|= RADEON_CP_VC_FRMT_XY
;
443 component
[nr
++] = &rmesa
->tcl
.obj
;
447 if (inputs
& VERT_BIT_NORMAL
) {
448 if (!rmesa
->tcl
.norm
.buf
)
451 (char *)VB
->NormalPtr
->data
,
453 VB
->NormalPtr
->stride
,
456 vfmt
|= RADEON_CP_VC_FRMT_N0
;
457 component
[nr
++] = &rmesa
->tcl
.norm
;
460 if (inputs
& VERT_BIT_COLOR0
) {
461 if (VB
->ColorPtr
[0]->Type
== GL_UNSIGNED_BYTE
) {
462 if (!rmesa
->tcl
.rgba
.buf
)
463 emit_ubyte_rgba( ctx
,
465 (char *)VB
->ColorPtr
[0]->Ptr
,
466 VB
->ColorPtr
[0]->Size
,
467 VB
->ColorPtr
[0]->StrideB
,
470 vfmt
|= RADEON_CP_VC_FRMT_PKCOLOR
;
475 if (VB
->ColorPtr
[0]->Size
== 4 &&
476 (VB
->ColorPtr
[0]->StrideB
!= 0 ||
477 ((GLfloat
*)VB
->ColorPtr
[0]->Ptr
)[3] != 1.0)) {
478 vfmt
|= RADEON_CP_VC_FRMT_FPCOLOR
| RADEON_CP_VC_FRMT_FPALPHA
;
482 vfmt
|= RADEON_CP_VC_FRMT_FPCOLOR
;
486 if (!rmesa
->tcl
.rgba
.buf
)
489 (char *)VB
->ColorPtr
[0]->Ptr
,
491 VB
->ColorPtr
[0]->StrideB
,
495 component
[nr
++] = &rmesa
->tcl
.rgba
;
499 if (inputs
& VERT_BIT_COLOR1
) {
500 if (!rmesa
->tcl
.spec
.buf
) {
501 if (VB
->SecondaryColorPtr
[0]->Type
!= GL_UNSIGNED_BYTE
)
502 radeon_import_float_spec_colors( ctx
);
504 emit_ubyte_rgba( ctx
,
506 (char *)VB
->SecondaryColorPtr
[0]->Ptr
,
508 VB
->SecondaryColorPtr
[0]->StrideB
,
512 vfmt
|= RADEON_CP_VC_FRMT_PKSPEC
;
513 component
[nr
++] = &rmesa
->tcl
.spec
;
516 vtx
= (rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &
517 ~(RADEON_TCL_VTX_Q0
|RADEON_TCL_VTX_Q1
));
519 if (inputs
& VERT_BIT_TEX0
) {
520 if (!rmesa
->tcl
.tex
[0].buf
)
521 emit_tex_vector( ctx
,
522 &(rmesa
->tcl
.tex
[0]),
523 (char *)VB
->TexCoordPtr
[0]->data
,
524 VB
->TexCoordPtr
[0]->size
,
525 VB
->TexCoordPtr
[0]->stride
,
528 switch( VB
->TexCoordPtr
[0]->size
) {
530 vtx
|= RADEON_TCL_VTX_Q0
;
531 vfmt
|= RADEON_CP_VC_FRMT_Q0
;
533 vfmt
|= RADEON_CP_VC_FRMT_ST0
;
535 component
[nr
++] = &rmesa
->tcl
.tex
[0];
538 if (inputs
& VERT_BIT_TEX1
) {
539 if (!rmesa
->tcl
.tex
[1].buf
)
540 emit_tex_vector( ctx
,
541 &(rmesa
->tcl
.tex
[1]),
542 (char *)VB
->TexCoordPtr
[1]->data
,
543 VB
->TexCoordPtr
[1]->size
,
544 VB
->TexCoordPtr
[1]->stride
,
547 switch( VB
->TexCoordPtr
[1]->size
) {
549 vtx
|= RADEON_TCL_VTX_Q1
;
550 vfmt
|= RADEON_CP_VC_FRMT_Q1
;
552 vfmt
|= RADEON_CP_VC_FRMT_ST1
;
554 component
[nr
++] = &rmesa
->tcl
.tex
[1];
557 if (vtx
!= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
]) {
558 RADEON_STATECHANGE( rmesa
, tcl
);
559 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] = vtx
;
562 rmesa
->tcl
.nr_aos_components
= nr
;
563 rmesa
->tcl
.vertex_format
= vfmt
;
567 void radeonReleaseArrays( GLcontext
*ctx
, GLuint newinputs
)
569 radeonContextPtr rmesa
= RADEON_CONTEXT( ctx
);
571 if (RADEON_DEBUG
& DEBUG_VERTS
)
572 _tnl_print_vert_flags( __FUNCTION__
, newinputs
);
574 if (newinputs
& VERT_BIT_POS
)
575 radeonReleaseDmaRegion( rmesa
, &rmesa
->tcl
.obj
, __FUNCTION__
);
577 if (newinputs
& VERT_BIT_NORMAL
)
578 radeonReleaseDmaRegion( rmesa
, &rmesa
->tcl
.norm
, __FUNCTION__
);
580 if (newinputs
& VERT_BIT_COLOR0
)
581 radeonReleaseDmaRegion( rmesa
, &rmesa
->tcl
.rgba
, __FUNCTION__
);
583 if (newinputs
& VERT_BIT_COLOR1
)
584 radeonReleaseDmaRegion( rmesa
, &rmesa
->tcl
.spec
, __FUNCTION__
);
586 if (newinputs
& VERT_BIT_TEX0
)
587 radeonReleaseDmaRegion( rmesa
, &rmesa
->tcl
.tex
[0], __FUNCTION__
);
589 if (newinputs
& VERT_BIT_TEX1
)
590 radeonReleaseDmaRegion( rmesa
, &rmesa
->tcl
.tex
[1], __FUNCTION__
);