r200: emit elts into a separate ELT bo
[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
54 #if 0
55 /* Usage:
56 * - from r200_tcl_render
57 * - call r200EmitArrays to ensure uptodate arrays in dma
58 * - emit primitives (new type?) which reference the data
59 * -- need to use elts for lineloop, quads, quadstrip/flat
60 * -- other primitives are all well-formed (need tristrip-1,fake-poly)
61 *
62 */
63 static void emit_ubyte_rgba3( GLcontext *ctx,
64 struct radeon_dma_region *rvb,
65 char *data,
66 int stride,
67 int count )
68 {
69 int i;
70 r200_color_t *out = (r200_color_t *)(rvb->start + rvb->address);
71
72 if (R200_DEBUG & DEBUG_VERTS)
73 fprintf(stderr, "%s count %d stride %d out %p\n",
74 __FUNCTION__, count, stride, (void *)out);
75
76 for (i = 0; i < count; i++) {
77 out->red = *data;
78 out->green = *(data+1);
79 out->blue = *(data+2);
80 out->alpha = 0xFF;
81 out++;
82 data += stride;
83 }
84 }
85
86 static void emit_ubyte_rgba4( GLcontext *ctx,
87 struct radeon_dma_region *rvb,
88 char *data,
89 int stride,
90 int count )
91 {
92 int i;
93 int *out = (int *)(rvb->address + rvb->start);
94
95 if (R200_DEBUG & DEBUG_VERTS)
96 fprintf(stderr, "%s count %d stride %d\n",
97 __FUNCTION__, count, stride);
98
99 if (stride == 4) {
100 for (i = 0; i < count; i++)
101 ((int *)out)[i] = LE32_TO_CPU(((int *)data)[i]);
102 } else {
103 for (i = 0; i < count; i++) {
104 *(int *)out++ = LE32_TO_CPU(*(int *)data);
105 data += stride;
106 }
107 }
108 }
109
110
111 static void emit_ubyte_rgba( GLcontext *ctx,
112 struct radeon_dma_region *rvb,
113 char *data,
114 int size,
115 int stride,
116 int count )
117 {
118 r200ContextPtr rmesa = R200_CONTEXT(ctx);
119
120 if (R200_DEBUG & DEBUG_VERTS)
121 fprintf(stderr, "%s %d/%d\n", __FUNCTION__, count, size);
122
123 assert (!rvb->buf);
124
125 if (stride == 0) {
126 // r200AllocDmaRegion( rmesa, rvb, 4, 4 );
127 count = 1;
128 rvb->aos_start = GET_START(rvb);
129 rvb->aos_stride = 0;
130 rvb->aos_size = 1;
131 }
132 else {
133 // r200AllocDmaRegion( rmesa, rvb, 4 * count, 4 ); /* alignment? */
134 rvb->aos_start = GET_START(rvb);
135 rvb->aos_stride = 1;
136 rvb->aos_size = 1;
137 }
138
139 /* Emit the data
140 */
141 switch (size) {
142 case 3:
143 emit_ubyte_rgba3( ctx, rvb, data, stride, count );
144 break;
145 case 4:
146 emit_ubyte_rgba4( ctx, rvb, data, stride, count );
147 break;
148 default:
149 assert(0);
150 exit(1);
151 break;
152 }
153 }
154 #endif
155
156
157 #if defined(USE_X86_ASM)
158 #define COPY_DWORDS( dst, src, nr ) \
159 do { \
160 int __tmp; \
161 __asm__ __volatile__( "rep ; movsl" \
162 : "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \
163 : "0" (nr), \
164 "D" ((long)dst), \
165 "S" ((long)src) ); \
166 } while (0)
167 #else
168 #define COPY_DWORDS( dst, src, nr ) \
169 do { \
170 int j; \
171 for ( j = 0 ; j < nr ; j++ ) \
172 dst[j] = ((int *)src)[j]; \
173 dst += nr; \
174 } while (0)
175 #endif
176
177 static void r200_emit_vecfog(GLcontext *ctx, struct radeon_aos *aos,
178 GLvoid *data, int stride, int count)
179 {
180 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
181 uint32_t *out;
182 uint32_t bo_size;
183 int i;
184 int size = 1;
185
186 memset(aos, 0, sizeof(struct radeon_aos));
187 if (stride == 0) {
188 bo_size = size * 4;
189 count = 1;
190 aos->stride = 0;
191 } else {
192 bo_size = size * count * 4;
193 aos->stride = size;
194 }
195 aos->bo = radeon_bo_open(rmesa->radeonScreen->bom,
196 0, bo_size, 32, RADEON_GEM_DOMAIN_GTT, 0);
197 aos->offset = 0;
198 aos->components = size;
199 aos->count = count;
200
201 radeon_bo_map(aos->bo, 1);
202 out = (uint32_t*)((char*)aos->bo->ptr + aos->offset);
203 for (i = 0; i < count; i++) {
204 out[0] = r200ComputeFogBlendFactor( ctx, *(GLfloat *)data );
205 out++;
206 data += stride;
207 }
208 radeon_bo_unmap(aos->bo);
209 }
210
211
212
213 /* Emit any changed arrays to new GART memory, re-emit a packet to
214 * update the arrays.
215 */
216 void r200EmitArrays( GLcontext *ctx, GLubyte *vimap_rev )
217 {
218 r200ContextPtr rmesa = R200_CONTEXT( ctx );
219 struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
220 // struct radeon_dma_region **component = rmesa->tcl.aos_components;
221 GLuint nr = 0;
222 GLuint vfmt0 = 0, vfmt1 = 0;
223 GLuint count = VB->Count;
224 GLuint i, emitsize;
225
226 fprintf(stderr,"emit arrays\n");
227 for ( i = 0; i < 15; i++ ) {
228 GLubyte attrib = vimap_rev[i];
229 if (attrib != 255) {
230 switch (i) {
231 case 0:
232 emitsize = (VB->AttribPtr[attrib]->size);
233 switch (emitsize) {
234 case 4:
235 vfmt0 |= R200_VTX_W0;
236 /* fallthrough */
237 case 3:
238 vfmt0 |= R200_VTX_Z0;
239 break;
240 case 2:
241 break;
242 default: assert(0);
243 }
244 break;
245 case 1:
246 assert(attrib == VERT_ATTRIB_WEIGHT);
247 emitsize = (VB->AttribPtr[attrib]->size);
248 vfmt0 |= emitsize << R200_VTX_WEIGHT_COUNT_SHIFT;
249 break;
250 case 2:
251 assert(attrib == VERT_ATTRIB_NORMAL);
252 emitsize = 3;
253 vfmt0 |= R200_VTX_N0;
254 break;
255 case 3:
256 /* special handling to fix up fog. Will get us into trouble with vbos...*/
257 assert(attrib == VERT_ATTRIB_FOG);
258 if (!rmesa->tcl.vertex_data[i].buf) {
259 if (ctx->VertexProgram._Enabled)
260 rcommon_emit_vector( ctx,
261 &(rmesa->tcl.aos[nr]),
262 (char *)VB->AttribPtr[attrib]->data,
263 1,
264 VB->AttribPtr[attrib]->stride,
265 count);
266 else
267 r200_emit_vecfog( ctx,
268 &(rmesa->tcl.aos[nr]),
269 (char *)VB->AttribPtr[attrib]->data,
270 VB->AttribPtr[attrib]->stride,
271 count);
272 }
273 vfmt0 |= R200_VTX_DISCRETE_FOG;
274 goto after_emit;
275 break;
276 case 4:
277 case 5:
278 case 6:
279 case 7:
280 if (VB->AttribPtr[attrib]->size == 4 &&
281 (VB->AttribPtr[attrib]->stride != 0 ||
282 VB->AttribPtr[attrib]->data[0][3] != 1.0)) emitsize = 4;
283 else emitsize = 3;
284 if (emitsize == 4)
285 vfmt0 |= R200_VTX_FP_RGBA << (R200_VTX_COLOR_0_SHIFT + (i - 4) * 2);
286 else {
287 vfmt0 |= R200_VTX_FP_RGB << (R200_VTX_COLOR_0_SHIFT + (i - 4) * 2);
288 }
289 break;
290 case 8:
291 case 9:
292 case 10:
293 case 11:
294 case 12:
295 case 13:
296 emitsize = VB->AttribPtr[attrib]->size;
297 vfmt1 |= emitsize << (R200_VTX_TEX0_COMP_CNT_SHIFT + (i - 8) * 3);
298 break;
299 case 14:
300 emitsize = VB->AttribPtr[attrib]->size >= 2 ? VB->AttribPtr[attrib]->size : 2;
301 switch (emitsize) {
302 case 2:
303 vfmt0 |= R200_VTX_XY1;
304 /* fallthrough */
305 case 3:
306 vfmt0 |= R200_VTX_Z1;
307 /* fallthrough */
308 case 4:
309 vfmt0 |= R200_VTX_W1;
310 break;
311 }
312 default:
313 assert(0);
314 }
315 if (!rmesa->tcl.vertex_data[i].buf) {
316 rcommon_emit_vector( ctx,
317 &(rmesa->tcl.aos[nr]),
318 (char *)VB->AttribPtr[attrib]->data,
319 emitsize,
320 VB->AttribPtr[attrib]->stride,
321 count );
322 }
323 after_emit:
324 assert(nr < 12);
325 nr++;
326 // component[nr++] = &rmesa->tcl.vertex_data[i];
327 }
328 }
329
330 if (vfmt0 != rmesa->hw.vtx.cmd[VTX_VTXFMT_0] ||
331 vfmt1 != rmesa->hw.vtx.cmd[VTX_VTXFMT_1]) {
332 R200_STATECHANGE( rmesa, vtx );
333 rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = vfmt0;
334 rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = vfmt1;
335 }
336
337 rmesa->tcl.nr_aos_components = nr;
338 }
339
340
341 void r200ReleaseArrays( GLcontext *ctx, GLuint newinputs )
342 {
343 r200ContextPtr rmesa = R200_CONTEXT( ctx );
344 int i;
345 for (i = 0; i < rmesa->tcl.nr_aos_components; i++) {
346 if (rmesa->tcl.aos[i].bo) {
347 rmesa->tcl.aos[i].bo = radeon_bo_unref(rmesa->tcl.aos[i].bo);
348 }
349 }
350 }