Merge branch 'mesa_7_7_branch'
[mesa.git] / src / mesa / drivers / dri / r200 / r200_maos_arrays.c
1 /*
2 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
3
4 The Weather Channel (TM) funded Tungsten Graphics to develop the
5 initial release of the Radeon 8500 driver under the XFree86 license.
6 This notice must be preserved.
7
8 Permission is hereby granted, free of charge, to any person obtaining
9 a copy of this software and associated documentation files (the
10 "Software"), to deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify, merge, publish,
12 distribute, sublicense, and/or sell copies of the Software, and to
13 permit persons to whom the Software is furnished to do so, subject to
14 the following conditions:
15
16 The above copyright notice and this permission notice (including the
17 next paragraph) shall be included in all copies or substantial
18 portions of the Software.
19
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
24 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 WITH 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 ) \
55 do { \
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 ) \
65 do { \
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 static void r200_emit_vecfog(GLcontext *ctx, struct radeon_aos *aos,
74 GLvoid *data, int stride, int count)
75 {
76 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
77 uint32_t *out;
78 int i;
79 int size = 1;
80
81 if (stride == 0) {
82 radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * 4, 32);
83 count = 1;
84 aos->stride = 0;
85 } else {
86 radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * 4, 32);
87 aos->stride = size;
88 }
89
90 aos->components = size;
91 aos->count = count;
92
93 radeon_bo_map(aos->bo, 1);
94 out = (uint32_t*)((char*)aos->bo->ptr + aos->offset);
95 for (i = 0; i < count; i++) {
96 out[0] = r200ComputeFogBlendFactor( ctx, *(GLfloat *)data );
97 out++;
98 data += stride;
99 }
100 radeon_bo_unmap(aos->bo);
101 }
102
103 /* Emit any changed arrays to new GART memory, re-emit a packet to
104 * update the arrays.
105 */
106 void r200EmitArrays( GLcontext *ctx, GLubyte *vimap_rev )
107 {
108 r200ContextPtr rmesa = R200_CONTEXT( ctx );
109 struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
110 GLuint nr = 0;
111 GLuint vfmt0 = 0, vfmt1 = 0;
112 GLuint count = VB->Count;
113 GLuint i, emitsize;
114
115 // fprintf(stderr,"emit arrays\n");
116 for ( i = 0; i < 15; i++ ) {
117 GLubyte attrib = vimap_rev[i];
118 if (attrib != 255) {
119 switch (i) {
120 case 0:
121 emitsize = (VB->AttribPtr[attrib]->size);
122 switch (emitsize) {
123 case 4:
124 vfmt0 |= R200_VTX_W0;
125 /* fallthrough */
126 case 3:
127 vfmt0 |= R200_VTX_Z0;
128 break;
129 case 2:
130 break;
131 default: assert(0);
132 }
133 break;
134 case 1:
135 assert(attrib == VERT_ATTRIB_WEIGHT);
136 emitsize = (VB->AttribPtr[attrib]->size);
137 vfmt0 |= emitsize << R200_VTX_WEIGHT_COUNT_SHIFT;
138 break;
139 case 2:
140 assert(attrib == VERT_ATTRIB_NORMAL);
141 emitsize = 3;
142 vfmt0 |= R200_VTX_N0;
143 break;
144 case 3:
145 /* special handling to fix up fog. Will get us into trouble with vbos...*/
146 assert(attrib == VERT_ATTRIB_FOG);
147 if (!rmesa->radeon.tcl.aos[i].bo) {
148 if (ctx->VertexProgram._Enabled)
149 rcommon_emit_vector( ctx,
150 &(rmesa->radeon.tcl.aos[nr]),
151 (char *)VB->AttribPtr[attrib]->data,
152 1,
153 VB->AttribPtr[attrib]->stride,
154 count);
155 else
156 r200_emit_vecfog( ctx,
157 &(rmesa->radeon.tcl.aos[nr]),
158 (char *)VB->AttribPtr[attrib]->data,
159 VB->AttribPtr[attrib]->stride,
160 count);
161 }
162 vfmt0 |= R200_VTX_DISCRETE_FOG;
163 goto after_emit;
164 break;
165 case 4:
166 case 5:
167 case 6:
168 case 7:
169 if (VB->AttribPtr[attrib]->size == 4 &&
170 (VB->AttribPtr[attrib]->stride != 0 ||
171 VB->AttribPtr[attrib]->data[0][3] != 1.0)) emitsize = 4;
172 else emitsize = 3;
173 if (emitsize == 4)
174 vfmt0 |= R200_VTX_FP_RGBA << (R200_VTX_COLOR_0_SHIFT + (i - 4) * 2);
175 else {
176 vfmt0 |= R200_VTX_FP_RGB << (R200_VTX_COLOR_0_SHIFT + (i - 4) * 2);
177 }
178 break;
179 case 8:
180 case 9:
181 case 10:
182 case 11:
183 case 12:
184 case 13:
185 emitsize = VB->AttribPtr[attrib]->size;
186 vfmt1 |= emitsize << (R200_VTX_TEX0_COMP_CNT_SHIFT + (i - 8) * 3);
187 break;
188 case 14:
189 emitsize = VB->AttribPtr[attrib]->size >= 2 ? VB->AttribPtr[attrib]->size : 2;
190 switch (emitsize) {
191 case 2:
192 vfmt0 |= R200_VTX_XY1;
193 /* fallthrough */
194 case 3:
195 vfmt0 |= R200_VTX_Z1;
196 /* fallthrough */
197 case 4:
198 vfmt0 |= R200_VTX_W1;
199 break;
200 }
201 default:
202 assert(0);
203 }
204 if (!rmesa->radeon.tcl.aos[nr].bo) {
205 rcommon_emit_vector( ctx,
206 &(rmesa->radeon.tcl.aos[nr]),
207 (char *)VB->AttribPtr[attrib]->data,
208 emitsize,
209 VB->AttribPtr[attrib]->stride,
210 count );
211 }
212 after_emit:
213 assert(nr < 12);
214 nr++;
215 }
216 }
217
218 if (vfmt0 != rmesa->hw.vtx.cmd[VTX_VTXFMT_0] ||
219 vfmt1 != rmesa->hw.vtx.cmd[VTX_VTXFMT_1]) {
220 R200_STATECHANGE( rmesa, vtx );
221 rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = vfmt0;
222 rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = vfmt1;
223 }
224
225 rmesa->radeon.tcl.aos_count = nr;
226 }
227