1/*
2Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
3
4The Weather Channel (TM) funded Tungsten Graphics to develop the
5initial release of the Radeon 8500 driver under the XFree86 license.
6This notice must be preserved.
7
8Permission is hereby granted, free of charge, to any person obtaining
9a copy of this software and associated documentation files (the
10"Software"), to deal in the Software without restriction, including
11without limitation the rights to use, copy, modify, merge, publish,
12distribute, sublicense, and/or sell copies of the Software, and to
13permit persons to whom the Software is furnished to do so, subject to
14the following conditions:
15
16The above copyright notice and this permission notice (including the
17next paragraph) shall be included in all copies or substantial
18portions of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
24LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28**************************************************************************/
29
30/*
31 * Authors:
32 *   Keith Whitwell <keith@tungstengraphics.com>
33 */
34
35#include "main/glheader.h"
36#include "main/mtypes.h"
37#include "main/colormac.h"
38#include "main/imports.h"
39#include "main/macros.h"
40
41#include "swrast_setup/swrast_setup.h"
42#include "math/m_translate.h"
43#include "tnl/tnl.h"
44#include "tnl/t_context.h"
45
46#include "r200_context.h"
47#include "r200_ioctl.h"
48#include "r200_state.h"
49#include "r200_swtcl.h"
50#include "r200_maos.h"
51#include "r200_tcl.h"
52
53#if defined(USE_X86_ASM)
54#define COPY_DWORDS( dst, src, nr )					\
55do {									\
56	int __tmp;							\
57	__asm__ __volatile__( "rep ; movsl"				\
58			      : "=%c" (__tmp), "=D" (dst), "=S" (__tmp)	\
59			      : "0" (nr),				\
60			        "D" ((long)dst),			\
61			        "S" ((long)src) );			\
62} while (0)
63#else
64#define COPY_DWORDS( dst, src, nr )		\
65do {						\
66   int j;					\
67   for ( j = 0 ; j < nr ; j++ )			\
68      dst[j] = ((int *)src)[j];			\
69   dst += nr;					\
70} while (0)
71#endif
72
73/* Emit any changed arrays to new GART memory, re-emit a packet to
74 * update the arrays.
75 */
76void r200EmitArrays( struct gl_context *ctx, GLubyte *vimap_rev )
77{
78   r200ContextPtr rmesa = R200_CONTEXT( ctx );
79   struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
80   GLuint nr = 0;
81   GLuint vfmt0 = 0, vfmt1 = 0;
82   GLuint count = VB->Count;
83   GLuint i, emitsize;
84
85   //   fprintf(stderr,"emit arrays\n");
86   for ( i = 0; i < 15; i++ ) {
87      GLubyte attrib = vimap_rev[i];
88      if (attrib != 255) {
89	 switch (i) {
90	 case 0:
91	    emitsize = (VB->AttribPtr[attrib]->size);
92	    switch (emitsize) {
93	    case 4:
94	       vfmt0 |= R200_VTX_W0;
95	       /* fallthrough */
96	    case 3:
97	       vfmt0 |= R200_VTX_Z0;
98	       break;
99	    case 2:
100	       break;
101	    default: assert(0);
102	    }
103	    break;
104	 case 1:
105	    assert(attrib == VERT_ATTRIB_WEIGHT);
106	    emitsize = (VB->AttribPtr[attrib]->size);
107	    vfmt0 |= emitsize << R200_VTX_WEIGHT_COUNT_SHIFT;
108	    break;
109	 case 2:
110	    assert(attrib == VERT_ATTRIB_NORMAL);
111	    emitsize = 3;
112	    vfmt0 |= R200_VTX_N0;
113	    break;
114	 case 3:
115	    /* special handling to fix up fog. Will get us into trouble with vbos...*/
116	    assert(attrib == VERT_ATTRIB_FOG);
117	    if (!rmesa->radeon.tcl.aos[i].bo) {
118	       if (ctx->VertexProgram._Enabled)
119		  rcommon_emit_vector( ctx,
120				       &(rmesa->radeon.tcl.aos[nr]),
121				       (char *)VB->AttribPtr[attrib]->data,
122				       1,
123				       VB->AttribPtr[attrib]->stride,
124				       count);
125	       else
126		 rcommon_emit_vecfog( ctx,
127				      &(rmesa->radeon.tcl.aos[nr]),
128				      (char *)VB->AttribPtr[attrib]->data,
129				      VB->AttribPtr[attrib]->stride,
130				      count);
131	    }
132	    vfmt0 |= R200_VTX_DISCRETE_FOG;
133	    goto after_emit;
134	    break;
135	 case 4:
136	 case 5:
137	 case 6:
138	 case 7:
139	    if (VB->AttribPtr[attrib]->size == 4 &&
140	       (VB->AttribPtr[attrib]->stride != 0 ||
141		VB->AttribPtr[attrib]->data[0][3] != 1.0)) emitsize = 4;
142	    else emitsize = 3;
143	    if (emitsize == 4)
144	       vfmt0 |= R200_VTX_FP_RGBA << (R200_VTX_COLOR_0_SHIFT + (i - 4) * 2);
145	    else {
146	       vfmt0 |= R200_VTX_FP_RGB << (R200_VTX_COLOR_0_SHIFT + (i - 4) * 2);
147	    }
148	    break;
149	 case 8:
150	 case 9:
151	 case 10:
152	 case 11:
153	 case 12:
154	 case 13:
155	    emitsize = VB->AttribPtr[attrib]->size;
156	    vfmt1 |= emitsize << (R200_VTX_TEX0_COMP_CNT_SHIFT + (i - 8) * 3);
157	    break;
158	 case 14:
159	    emitsize = VB->AttribPtr[attrib]->size >= 2 ? VB->AttribPtr[attrib]->size : 2;
160	    switch (emitsize) {
161	    case 2:
162	       vfmt0 |= R200_VTX_XY1;
163	       /* fallthrough */
164	    case 3:
165	       vfmt0 |= R200_VTX_Z1;
166	       /* fallthrough */
167	    case 4:
168	       vfmt0 |= R200_VTX_W1;
169	       /* fallthrough */
170	    }
171	    break;
172	 default:
173	    assert(0);
174	    emitsize = 0;
175	 }
176	 if (!rmesa->radeon.tcl.aos[nr].bo) {
177	   rcommon_emit_vector( ctx,
178				&(rmesa->radeon.tcl.aos[nr]),
179				(char *)VB->AttribPtr[attrib]->data,
180				emitsize,
181				VB->AttribPtr[attrib]->stride,
182				count );
183	 }
184after_emit:
185	 assert(nr < 12);
186	 nr++;
187      }
188   }
189
190   if (vfmt0 != rmesa->hw.vtx.cmd[VTX_VTXFMT_0] ||
191       vfmt1 != rmesa->hw.vtx.cmd[VTX_VTXFMT_1]) {
192      R200_STATECHANGE( rmesa, vtx );
193      rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = vfmt0;
194      rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = vfmt1;
195   }
196
197   rmesa->radeon.tcl.aos_count = nr;
198}
199
200