2 /**************************************************************************
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"
46 #include "tnl/t_imm_debug.h"
48 #include "r200_context.h"
49 #include "r200_ioctl.h"
50 #include "r200_state.h"
51 #include "r200_swtcl.h"
52 #include "r200_maos.h"
55 * - from r200_tcl_render
56 * - call r200EmitArrays 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 r200_dma_region
*rvb
,
69 r200_color_t
*out
= (r200_color_t
*)(rvb
->start
+ rvb
->address
);
71 if (R200_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 r200_dma_region
*rvb
,
115 int *out
= (int *)(rvb
->address
+ rvb
->start
);
117 if (R200_DEBUG
& DEBUG_VERTS
)
118 fprintf(stderr
, "%s count %d stride %d\n",
119 __FUNCTION__
, count
, stride
);
122 for (i
= 0; i
< count
; i
++)
123 ((int *)out
)[i
] = LE32_TO_CPU(((int *)data
)[i
]);
125 for (i
= 0; i
< count
; i
++) {
126 *(int *)out
++ = LE32_TO_CPU(*(int *)data
);
133 static void emit_ubyte_rgba( GLcontext
*ctx
,
134 struct r200_dma_region
*rvb
,
140 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
142 if (R200_DEBUG
& DEBUG_VERTS
)
143 fprintf(stderr
, "%s %d/%d\n", __FUNCTION__
, count
, size
);
148 r200AllocDmaRegion( rmesa
, rvb
, 4, 4 );
150 rvb
->aos_start
= GET_START(rvb
);
155 r200AllocDmaRegion( rmesa
, rvb
, 4 * count
, 4 ); /* alignment? */
156 rvb
->aos_start
= GET_START(rvb
);
165 emit_ubyte_rgba3( ctx
, rvb
, data
, stride
, count
);
168 emit_ubyte_rgba4( ctx
, rvb
, data
, stride
, count
);
180 static void emit_vec8( GLcontext
*ctx
,
181 struct r200_dma_region
*rvb
,
187 int *out
= (int *)(rvb
->address
+ rvb
->start
);
189 if (R200_DEBUG
& DEBUG_VERTS
)
190 fprintf(stderr
, "%s count %d stride %d\n",
191 __FUNCTION__
, count
, stride
);
194 COPY_DWORDS( out
, data
, count
*2 );
196 for (i
= 0; i
< count
; i
++) {
197 out
[0] = *(int *)data
;
198 out
[1] = *(int *)(data
+4);
204 static void emit_vec12( GLcontext
*ctx
,
205 struct r200_dma_region
*rvb
,
211 int *out
= (int *)(rvb
->address
+ rvb
->start
);
213 if (R200_DEBUG
& DEBUG_VERTS
)
214 fprintf(stderr
, "%s count %d stride %d out %p data %p\n",
215 __FUNCTION__
, count
, stride
, out
, data
);
218 COPY_DWORDS( out
, data
, count
*3 );
220 for (i
= 0; i
< count
; i
++) {
221 out
[0] = *(int *)data
;
222 out
[1] = *(int *)(data
+4);
223 out
[2] = *(int *)(data
+8);
229 static void emit_vec16( 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\n",
240 __FUNCTION__
, count
, stride
);
243 COPY_DWORDS( out
, data
, count
*4 );
245 for (i
= 0; i
< count
; i
++) {
246 out
[0] = *(int *)data
;
247 out
[1] = *(int *)(data
+4);
248 out
[2] = *(int *)(data
+8);
249 out
[3] = *(int *)(data
+12);
256 static void emit_vector( GLcontext
*ctx
,
257 struct r200_dma_region
*rvb
,
263 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
265 if (R200_DEBUG
& DEBUG_VERTS
)
266 fprintf(stderr
, "%s count %d size %d stride %d\n",
267 __FUNCTION__
, count
, size
, stride
);
272 r200AllocDmaRegion( rmesa
, rvb
, size
* 4, 4 );
274 rvb
->aos_start
= GET_START(rvb
);
276 rvb
->aos_size
= size
;
279 r200AllocDmaRegion( rmesa
, rvb
, size
* count
* 4, 4 ); /* alignment? */
280 rvb
->aos_start
= GET_START(rvb
);
281 rvb
->aos_stride
= size
;
282 rvb
->aos_size
= size
;
289 emit_vec8( ctx
, rvb
, data
, stride
, count
);
292 emit_vec12( ctx
, rvb
, data
, stride
, count
);
295 emit_vec16( ctx
, rvb
, data
, stride
, count
);
307 /* Emit any changed arrays to new agp memory, re-emit a packet to
310 void r200EmitArrays( GLcontext
*ctx
, GLuint inputs
)
312 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
313 struct vertex_buffer
*VB
= &TNL_CONTEXT( ctx
)->vb
;
314 struct r200_dma_region
**component
= rmesa
->tcl
.aos_components
;
316 GLuint vfmt0
= 0, vfmt1
= 0;
317 GLuint count
= VB
->Count
;
319 if (R200_DEBUG
& DEBUG_VERTS
)
320 _tnl_print_vert_flags( __FUNCTION__
, inputs
);
323 if (!rmesa
->tcl
.obj
.buf
)
326 (char *)VB
->ObjPtr
->data
,
331 switch( VB
->ObjPtr
->size
) {
332 case 4: vfmt0
|= R200_VTX_W0
;
333 case 3: vfmt0
|= R200_VTX_Z0
;
338 component
[nr
++] = &rmesa
->tcl
.obj
;
342 if (inputs
& VERT_BIT_NORMAL
) {
343 if (!rmesa
->tcl
.norm
.buf
)
346 (char *)VB
->NormalPtr
->data
,
348 VB
->NormalPtr
->stride
,
351 vfmt0
|= R200_VTX_N0
;
352 component
[nr
++] = &rmesa
->tcl
.norm
;
355 if (inputs
& VERT_BIT_COLOR0
) {
356 if (VB
->ColorPtr
[0]->Type
== GL_UNSIGNED_BYTE
) {
357 if (!rmesa
->tcl
.rgba
.buf
)
358 emit_ubyte_rgba( ctx
,
360 (char *)VB
->ColorPtr
[0]->Ptr
,
361 VB
->ColorPtr
[0]->Size
,
362 VB
->ColorPtr
[0]->StrideB
,
365 vfmt0
|= R200_VTX_PK_RGBA
<< R200_VTX_COLOR_0_SHIFT
;
370 if (VB
->ColorPtr
[0]->Size
== 4 &&
371 (VB
->ColorPtr
[0]->StrideB
!= 0 ||
372 ((GLfloat
*)VB
->ColorPtr
[0]->Ptr
)[3] != 1.0)) {
373 vfmt0
|= R200_VTX_FP_RGBA
<< R200_VTX_COLOR_0_SHIFT
;
377 vfmt0
|= R200_VTX_FP_RGB
<< R200_VTX_COLOR_0_SHIFT
;
381 if (!rmesa
->tcl
.rgba
.buf
)
384 (char *)VB
->ColorPtr
[0]->Ptr
,
386 VB
->ColorPtr
[0]->StrideB
,
390 component
[nr
++] = &rmesa
->tcl
.rgba
;
394 if (inputs
& VERT_BIT_COLOR1
) {
395 if (!rmesa
->tcl
.spec
.buf
) {
396 if (VB
->SecondaryColorPtr
[0]->Type
!= GL_UNSIGNED_BYTE
)
397 r200_import_float_spec_colors( ctx
);
399 emit_ubyte_rgba( ctx
,
401 (char *)VB
->SecondaryColorPtr
[0]->Ptr
,
403 VB
->SecondaryColorPtr
[0]->StrideB
,
407 /* How does this work?
409 vfmt0
|= R200_VTX_PK_RGBA
<< R200_VTX_COLOR_1_SHIFT
;
410 component
[nr
++] = &rmesa
->tcl
.spec
;
413 /* vtx = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] & */
414 /* ~(R200_TCL_VTX_Q0|R200_TCL_VTX_Q1)); */
416 if (inputs
& VERT_BIT_TEX0
) {
417 if (!rmesa
->tcl
.tex
[0].buf
)
419 &(rmesa
->tcl
.tex
[0]),
420 (char *)VB
->TexCoordPtr
[0]->data
,
421 VB
->TexCoordPtr
[0]->size
,
422 VB
->TexCoordPtr
[0]->stride
,
425 vfmt1
|= VB
->TexCoordPtr
[0]->size
<< R200_VTX_TEX0_COMP_CNT_SHIFT
;
426 component
[nr
++] = &rmesa
->tcl
.tex
[0];
429 if (inputs
& VERT_BIT_TEX1
) {
430 if (!rmesa
->tcl
.tex
[1].buf
)
432 &(rmesa
->tcl
.tex
[1]),
433 (char *)VB
->TexCoordPtr
[1]->data
,
434 VB
->TexCoordPtr
[1]->size
,
435 VB
->TexCoordPtr
[1]->stride
,
438 vfmt1
|= VB
->TexCoordPtr
[1]->size
<< R200_VTX_TEX1_COMP_CNT_SHIFT
;
439 component
[nr
++] = &rmesa
->tcl
.tex
[1];
442 if (vfmt0
!= rmesa
->hw
.vtx
.cmd
[VTX_VTXFMT_0
] ||
443 vfmt1
!= rmesa
->hw
.vtx
.cmd
[VTX_VTXFMT_1
]) {
444 R200_STATECHANGE( rmesa
, vtx
);
445 rmesa
->hw
.vtx
.cmd
[VTX_VTXFMT_0
] = vfmt0
;
446 rmesa
->hw
.vtx
.cmd
[VTX_VTXFMT_1
] = vfmt1
;
449 rmesa
->tcl
.nr_aos_components
= nr
;
450 rmesa
->tcl
.vertex_format
= vfmt0
;
454 void r200ReleaseArrays( GLcontext
*ctx
, GLuint newinputs
)
456 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
458 if (R200_DEBUG
& DEBUG_VERTS
)
459 _tnl_print_vert_flags( __FUNCTION__
, newinputs
);
461 if (newinputs
& VERT_BIT_POS
)
462 r200ReleaseDmaRegion( rmesa
, &rmesa
->tcl
.obj
, __FUNCTION__
);
464 if (newinputs
& VERT_BIT_NORMAL
)
465 r200ReleaseDmaRegion( rmesa
, &rmesa
->tcl
.norm
, __FUNCTION__
);
467 if (newinputs
& VERT_BIT_COLOR0
)
468 r200ReleaseDmaRegion( rmesa
, &rmesa
->tcl
.rgba
, __FUNCTION__
);
470 if (newinputs
& VERT_BIT_COLOR1
)
471 r200ReleaseDmaRegion( rmesa
, &rmesa
->tcl
.spec
, __FUNCTION__
);
473 if (newinputs
& VERT_BIT_TEX0
)
474 r200ReleaseDmaRegion( rmesa
, &rmesa
->tcl
.tex
[0], __FUNCTION__
);
476 if (newinputs
& VERT_BIT_TEX1
)
477 r200ReleaseDmaRegion( rmesa
, &rmesa
->tcl
.tex
[1], __FUNCTION__
);