Merge branch 'mesa_7_5_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 out = (uint32_t*)((char*)aos->bo->ptr + aos->offset);
94 for (i = 0; i < count; i++) {
95 out[0] = r200ComputeFogBlendFactor( ctx, *(GLfloat *)data );
96 out++;
97 data += stride;
98 }
99 }
100
101 /* Emit any changed arrays to new GART memory, re-emit a packet to
102 * update the arrays.
103 */
104 void r200EmitArrays( GLcontext *ctx, GLubyte *vimap_rev )
105 {
106 r200ContextPtr rmesa = R200_CONTEXT( ctx );
107 struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
108 GLuint nr = 0;
109 GLuint vfmt0 = 0, vfmt1 = 0;
110 GLuint count = VB->Count;
111 GLuint i, emitsize;
112
113 // fprintf(stderr,"emit arrays\n");
114 for ( i = 0; i < 15; i++ ) {
115 GLubyte attrib = vimap_rev[i];
116 if (attrib != 255) {
117 switch (i) {
118 case 0:
119 emitsize = (VB->AttribPtr[attrib]->size);
120 switch (emitsize) {
121 case 4:
122 vfmt0 |= R200_VTX_W0;
123 /* fallthrough */
124 case 3:
125 vfmt0 |= R200_VTX_Z0;
126 break;
127 case 2:
128 break;
129 default: assert(0);
130 }
131 break;
132 case 1:
133 assert(attrib == VERT_ATTRIB_WEIGHT);
134 emitsize = (VB->AttribPtr[attrib]->size);
135 vfmt0 |= emitsize << R200_VTX_WEIGHT_COUNT_SHIFT;
136 break;
137 case 2:
138 assert(attrib == VERT_ATTRIB_NORMAL);
139 emitsize = 3;
140 vfmt0 |= R200_VTX_N0;
141 break;
142 case 3:
143 /* special handling to fix up fog. Will get us into trouble with vbos...*/
144 assert(attrib == VERT_ATTRIB_FOG);
145 if (!rmesa->radeon.tcl.aos[i].bo) {
146 if (ctx->VertexProgram._Enabled)
147 rcommon_emit_vector( ctx,
148 &(rmesa->radeon.tcl.aos[nr]),
149 (char *)VB->AttribPtr[attrib]->data,
150 1,
151 VB->AttribPtr[attrib]->stride,
152 count);
153 else
154 r200_emit_vecfog( ctx,
155 &(rmesa->radeon.tcl.aos[nr]),
156 (char *)VB->AttribPtr[attrib]->data,
157 VB->AttribPtr[attrib]->stride,
158 count);
159 }
160 vfmt0 |= R200_VTX_DISCRETE_FOG;
161 goto after_emit;
162 break;
163 case 4:
164 case 5:
165 case 6:
166 case 7:
167 if (VB->AttribPtr[attrib]->size == 4 &&
168 (VB->AttribPtr[attrib]->stride != 0 ||
169 VB->AttribPtr[attrib]->data[0][3] != 1.0)) emitsize = 4;
170 else emitsize = 3;
171 if (emitsize == 4)
172 vfmt0 |= R200_VTX_FP_RGBA << (R200_VTX_COLOR_0_SHIFT + (i - 4) * 2);
173 else {
174 vfmt0 |= R200_VTX_FP_RGB << (R200_VTX_COLOR_0_SHIFT + (i - 4) * 2);
175 }
176 break;
177 case 8:
178 case 9:
179 case 10:
180 case 11:
181 case 12:
182 case 13:
183 emitsize = VB->AttribPtr[attrib]->size;
184 vfmt1 |= emitsize << (R200_VTX_TEX0_COMP_CNT_SHIFT + (i - 8) * 3);
185 break;
186 case 14:
187 emitsize = VB->AttribPtr[attrib]->size >= 2 ? VB->AttribPtr[attrib]->size : 2;
188 switch (emitsize) {
189 case 2:
190 vfmt0 |= R200_VTX_XY1;
191 /* fallthrough */
192 case 3:
193 vfmt0 |= R200_VTX_Z1;
194 /* fallthrough */
195 case 4:
196 vfmt0 |= R200_VTX_W1;
197 break;
198 }
199 default:
200 assert(0);
201 }
202 if (!rmesa->radeon.tcl.aos[nr].bo) {
203 rcommon_emit_vector( ctx,
204 &(rmesa->radeon.tcl.aos[nr]),
205 (char *)VB->AttribPtr[attrib]->data,
206 emitsize,
207 VB->AttribPtr[attrib]->stride,
208 count );
209 }
210 after_emit:
211 assert(nr < 12);
212 nr++;
213 }
214 }
215
216 if (vfmt0 != rmesa->hw.vtx.cmd[VTX_VTXFMT_0] ||
217 vfmt1 != rmesa->hw.vtx.cmd[VTX_VTXFMT_1]) {
218 R200_STATECHANGE( rmesa, vtx );
219 rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = vfmt0;
220 rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = vfmt1;
221 }
222
223 rmesa->radeon.tcl.aos_count = nr;
224 }
225