r300_select_vertex_shader4:
[mesa.git] / src / mesa / drivers / dri / r300 / r300_maos.c
1 /* $XFree86: xc/lib/GL/mesa/src/drv/r300/r300_maos_arrays.c,v 1.3 2003/02/23 23:59:01 dawes Exp $ */
2 /*
3 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
4
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.
8
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:
16
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.
20
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.
28
29 **************************************************************************/
30
31 /*
32 * Authors:
33 * Keith Whitwell <keith@tungstengraphics.com>
34 */
35
36 #include "glheader.h"
37 #include "mtypes.h"
38 #include "colormac.h"
39 #include "imports.h"
40 #include "macros.h"
41 #include "image.h"
42
43 #include "swrast_setup/swrast_setup.h"
44 #include "math/m_translate.h"
45 #include "tnl/tnl.h"
46 #include "tnl/t_context.h"
47
48 #include "r300_context.h"
49 #include "radeon_ioctl.h"
50 #include "r300_state.h"
51 #include "r300_maos.h"
52 #include "r300_ioctl.h"
53
54 #ifdef USER_BUFFERS
55 #include "radeon_mm.h"
56 #endif
57
58 #if SWIZZLE_X != R300_INPUT_ROUTE_SELECT_X || \
59 SWIZZLE_Y != R300_INPUT_ROUTE_SELECT_Y || \
60 SWIZZLE_Z != R300_INPUT_ROUTE_SELECT_Z || \
61 SWIZZLE_W != R300_INPUT_ROUTE_SELECT_W || \
62 SWIZZLE_ZERO != R300_INPUT_ROUTE_SELECT_ZERO || \
63 SWIZZLE_ONE != R300_INPUT_ROUTE_SELECT_ONE
64 #error Cannot change these!
65 #endif
66
67 #define DEBUG_ALL DEBUG_VERTS
68
69
70 #if defined(USE_X86_ASM)
71 #define COPY_DWORDS( dst, src, nr ) \
72 do { \
73 int __tmp; \
74 __asm__ __volatile__( "rep ; movsl" \
75 : "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \
76 : "0" (nr), \
77 "D" ((long)dst), \
78 "S" ((long)src) ); \
79 } while (0)
80 #else
81 #define COPY_DWORDS( dst, src, nr ) \
82 do { \
83 int j; \
84 for ( j = 0 ; j < nr ; j++ ) \
85 dst[j] = ((int *)src)[j]; \
86 dst += nr; \
87 } while (0)
88 #endif
89
90 static void emit_vec4(GLcontext * ctx,
91 struct r300_dma_region *rvb,
92 GLvoid *data, int stride, int count)
93 {
94 int i;
95 int *out = (int *)(rvb->address + rvb->start);
96
97 if (RADEON_DEBUG & DEBUG_VERTS)
98 fprintf(stderr, "%s count %d stride %d\n",
99 __FUNCTION__, count, stride);
100
101 if (stride == 4)
102 COPY_DWORDS(out, data, count);
103 else
104 for (i = 0; i < count; i++) {
105 out[0] = *(int *)data;
106 out++;
107 data += stride;
108 }
109 }
110
111 static void emit_vec8(GLcontext * ctx,
112 struct r300_dma_region *rvb,
113 GLvoid *data, int stride, int count)
114 {
115 int i;
116 int *out = (int *)(rvb->address + rvb->start);
117
118 if (RADEON_DEBUG & DEBUG_VERTS)
119 fprintf(stderr, "%s count %d stride %d\n",
120 __FUNCTION__, count, stride);
121
122 if (stride == 8)
123 COPY_DWORDS(out, data, count * 2);
124 else
125 for (i = 0; i < count; i++) {
126 out[0] = *(int *)data;
127 out[1] = *(int *)(data + 4);
128 out += 2;
129 data += stride;
130 }
131 }
132
133 static void emit_vec12(GLcontext * ctx,
134 struct r300_dma_region *rvb,
135 GLvoid *data, int stride, int count)
136 {
137 int i;
138 int *out = (int *)(rvb->address + rvb->start);
139
140 if (RADEON_DEBUG & DEBUG_VERTS)
141 fprintf(stderr, "%s count %d stride %d out %p data %p\n",
142 __FUNCTION__, count, stride, (void *)out, (void *)data);
143
144 if (stride == 12)
145 COPY_DWORDS(out, data, count * 3);
146 else
147 for (i = 0; i < count; i++) {
148 out[0] = *(int *)data;
149 out[1] = *(int *)(data + 4);
150 out[2] = *(int *)(data + 8);
151 out += 3;
152 data += stride;
153 }
154 }
155
156 static void emit_vec16(GLcontext * ctx,
157 struct r300_dma_region *rvb,
158 GLvoid *data, int stride, int count)
159 {
160 int i;
161 int *out = (int *)(rvb->address + rvb->start);
162
163 if (RADEON_DEBUG & DEBUG_VERTS)
164 fprintf(stderr, "%s count %d stride %d\n",
165 __FUNCTION__, count, stride);
166
167 if (stride == 16)
168 COPY_DWORDS(out, data, count * 4);
169 else
170 for (i = 0; i < count; i++) {
171 out[0] = *(int *)data;
172 out[1] = *(int *)(data + 4);
173 out[2] = *(int *)(data + 8);
174 out[3] = *(int *)(data + 12);
175 out += 4;
176 data += stride;
177 }
178 }
179
180 static void emit_vector(GLcontext * ctx,
181 struct r300_dma_region *rvb,
182 GLvoid *data, int size, int stride, int count)
183 {
184 r300ContextPtr rmesa = R300_CONTEXT(ctx);
185
186 if (RADEON_DEBUG & DEBUG_VERTS)
187 fprintf(stderr, "%s count %d size %d stride %d\n",
188 __FUNCTION__, count, size, stride);
189
190 /* Gets triggered when playing with future_hw_tcl_on ...*/
191 //assert(!rvb->buf);
192
193 if (stride == 0) {
194 r300AllocDmaRegion(rmesa, rvb, size * 4, 4);
195 count = 1;
196 rvb->aos_offset = GET_START(rvb);
197 rvb->aos_stride = 0;
198 } else {
199 r300AllocDmaRegion(rmesa, rvb, size * count * 4, 4); /* alignment? */
200 rvb->aos_offset = GET_START(rvb);
201 rvb->aos_stride = size;
202 }
203
204 /* Emit the data
205 */
206 switch (size) {
207 case 1:
208 emit_vec4(ctx, rvb, data, stride, count);
209 break;
210 case 2:
211 emit_vec8(ctx, rvb, data, stride, count);
212 break;
213 case 3:
214 emit_vec12(ctx, rvb, data, stride, count);
215 break;
216 case 4:
217 emit_vec16(ctx, rvb, data, stride, count);
218 break;
219 default:
220 assert(0);
221 exit(1);
222 break;
223 }
224
225 }
226
227 void r300EmitElts(GLcontext * ctx, void *elts, unsigned long n_elts, int elt_size)
228 {
229 r300ContextPtr rmesa = R300_CONTEXT(ctx);
230 struct r300_dma_region *rvb=&rmesa->state.elt_dma;
231 void *out;
232
233 assert(elt_size == 2 || elt_size == 4);
234
235 if(r300IsGartMemory(rmesa, elts, n_elts * elt_size)){
236 rvb->address = rmesa->radeon.radeonScreen->gartTextures.map;
237 rvb->start = ((char *)elts) - rvb->address;
238 rvb->aos_offset = rmesa->radeon.radeonScreen->gart_texture_offset + rvb->start;
239
240 return ;
241 }else if(r300IsGartMemory(rmesa, elts, 1)){
242 WARN_ONCE("Pointer not within GART memory!\n");
243 exit(1);
244 }
245
246 r300AllocDmaRegion(rmesa, rvb, n_elts * elt_size, elt_size);
247 rvb->aos_offset = GET_START(rvb);
248
249 out = rvb->address + rvb->start;
250 memcpy(out, elts, n_elts * elt_size);
251 }
252
253 static GLuint t_type(struct dt *dt)
254 {
255 switch (dt->type) {
256 case GL_UNSIGNED_BYTE:
257 return AOS_FORMAT_UBYTE;
258
259 case GL_SHORT:
260 return AOS_FORMAT_USHORT;
261
262 case GL_FLOAT:
263 return AOS_FORMAT_FLOAT;
264
265 default:
266 assert(0);
267 break;
268 }
269
270 return AOS_FORMAT_FLOAT;
271 }
272
273 static GLuint t_vir0_size(struct dt *dt)
274 {
275 switch (dt->type) {
276 case GL_UNSIGNED_BYTE:
277 return 4;
278
279 case GL_SHORT:
280 return 7;
281
282 case GL_FLOAT:
283 return dt->size - 1;
284
285 default:
286 assert(0);
287 break;
288 }
289
290 return 0;
291 }
292
293 static GLuint t_aos_size(struct dt *dt)
294 {
295 switch (dt->type) {
296 case GL_UNSIGNED_BYTE:
297 return 1;
298
299 case GL_SHORT:
300 return 2;
301
302 case GL_FLOAT:
303 return dt->size;
304
305 default:
306 assert(0);
307 break;
308 }
309
310 return 0;
311 }
312
313 static GLuint t_vir0(uint32_t *dst, struct dt *dt, int *inputs, GLint *tab, GLuint nr)
314 {
315 GLuint i, dw;
316
317 for (i = 0; i + 1 < nr; i += 2){
318 dw = t_vir0_size(&dt[tab[i]]) | (inputs[tab[i]] << 8) | (t_type(&dt[tab[i]]) << 14);
319 dw |= (t_vir0_size(&dt[tab[i + 1]]) | (inputs[tab[i + 1]] << 8) | (t_type(&dt[tab[i + 1]]) << 14)) << 16;
320
321 if (i + 2 == nr) {
322 dw |= (1 << (13 + 16));
323 }
324 dst[i >> 1] = dw;
325 }
326
327 if (nr & 1) {
328 dw = t_vir0_size(&dt[tab[nr - 1]]) | (inputs[tab[nr - 1]] << 8) | (t_type(&dt[tab[nr - 1]]) << 14);
329 dw |= 1 << 13;
330
331 dst[nr >> 1] = dw;
332 }
333
334 return (nr + 1) >> 1;
335 }
336
337 static GLuint t_swizzle(int swizzle[4])
338 {
339 return (swizzle[0] << R300_INPUT_ROUTE_X_SHIFT) |
340 (swizzle[1] << R300_INPUT_ROUTE_Y_SHIFT) |
341 (swizzle[2] << R300_INPUT_ROUTE_Z_SHIFT) |
342 (swizzle[3] << R300_INPUT_ROUTE_W_SHIFT);
343 }
344
345 static GLuint t_vir1(uint32_t *dst, int swizzle[][4], GLuint nr)
346 {
347 GLuint i;
348
349 for (i = 0; i + 1 < nr; i += 2) {
350 dst[i >> 1] = t_swizzle(swizzle[i]) | R300_INPUT_ROUTE_ENABLE;
351 dst[i >> 1] |= (t_swizzle(swizzle[i + 1]) | R300_INPUT_ROUTE_ENABLE) << 16;
352 }
353
354 if (nr & 1)
355 dst[nr >> 1] = t_swizzle(swizzle[nr - 1]) | R300_INPUT_ROUTE_ENABLE;
356
357 return (nr + 1) >> 1;
358 }
359
360 static GLuint t_emit_size(struct dt *dt)
361 {
362 return dt->size;
363 }
364
365 static GLuint t_vic(GLcontext * ctx, GLuint InputsRead)
366 {
367 r300ContextPtr r300 = R300_CONTEXT(ctx);
368 GLuint i, vic_1 = 0;
369
370 if (InputsRead & (1 << VERT_ATTRIB_POS))
371 vic_1 |= R300_INPUT_CNTL_POS;
372
373 if (InputsRead & (1 << VERT_ATTRIB_NORMAL))
374 vic_1 |= R300_INPUT_CNTL_NORMAL;
375
376 if (InputsRead & (1 << VERT_ATTRIB_COLOR0))
377 vic_1 |= R300_INPUT_CNTL_COLOR;
378
379 r300->state.texture.tc_count = 0;
380 for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
381 if (InputsRead & (1 << (VERT_ATTRIB_TEX0 + i))) {
382 r300->state.texture.tc_count++;
383 vic_1 |= R300_INPUT_CNTL_TC0 << i;
384 }
385
386 return vic_1;
387 }
388
389 /* Emit vertex data to GART memory
390 * Route inputs to the vertex processor
391 * This function should never return R300_FALLBACK_TCL when using software tcl.
392 */
393
394 int r300EmitArrays(GLcontext *ctx)
395 {
396 r300ContextPtr rmesa = R300_CONTEXT(ctx);
397 r300ContextPtr r300 = rmesa;
398 struct radeon_vertex_buffer *VB = &rmesa->state.VB;
399 GLuint nr;
400 GLuint count = VB->Count;
401 GLuint i;
402 GLuint InputsRead = 0, OutputsWritten = 0;
403 int *inputs = NULL;
404 GLint tab[VERT_ATTRIB_MAX];
405 int swizzle[VERT_ATTRIB_MAX][4];
406
407 if (hw_tcl_on) {
408 struct r300_vertex_program *prog=(struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx);
409 inputs = prog->inputs;
410 InputsRead = CURRENT_VERTEX_SHADER(ctx)->key.InputsRead;
411 OutputsWritten = CURRENT_VERTEX_SHADER(ctx)->key.OutputsWritten;
412 } else {
413 DECLARE_RENDERINPUTS(inputs_bitset);
414 inputs = r300->state.sw_tcl_inputs;
415
416 RENDERINPUTS_COPY( inputs_bitset, TNL_CONTEXT(ctx)->render_inputs_bitset );
417
418 assert(RENDERINPUTS_TEST( inputs_bitset, _TNL_ATTRIB_POS ));
419 InputsRead |= 1 << VERT_ATTRIB_POS;
420 OutputsWritten |= 1 << VERT_RESULT_HPOS;
421
422 assert(RENDERINPUTS_TEST( inputs_bitset, _TNL_ATTRIB_NORMAL ) == 0);
423
424 assert(RENDERINPUTS_TEST( inputs_bitset, _TNL_ATTRIB_COLOR0 ));
425 InputsRead |= 1 << VERT_ATTRIB_COLOR0;
426 OutputsWritten |= 1 << VERT_RESULT_COL0;
427
428 if (RENDERINPUTS_TEST( inputs_bitset, _TNL_ATTRIB_COLOR1 )) {
429 InputsRead |= 1 << VERT_ATTRIB_COLOR1;
430 OutputsWritten |= 1 << VERT_RESULT_COL1;
431 }
432
433 for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
434 if (RENDERINPUTS_TEST( inputs_bitset, _TNL_ATTRIB_TEX(i) )) {
435 InputsRead |= 1 << (VERT_ATTRIB_TEX0 + i);
436 OutputsWritten |= 1 << (VERT_RESULT_TEX0 + i);
437 }
438
439 for (i = 0, nr = 0; i < VERT_ATTRIB_MAX; i++)
440 if (InputsRead & (1 << i))
441 inputs[i] = nr++;
442 else
443 inputs[i] = -1;
444
445 RENDERINPUTS_COPY( rmesa->state.render_inputs_bitset, inputs_bitset );
446 }
447 assert(InputsRead);
448 assert(OutputsWritten);
449
450 for (i = 0, nr = 0; i < VERT_ATTRIB_MAX; i++)
451 if (InputsRead & (1 << i))
452 tab[nr++] = i;
453
454 if (nr > R300_MAX_AOS_ARRAYS)
455 return R300_FALLBACK_TCL;
456
457 for (i = 0; i < nr; i++) {
458 int ci;
459 int comp_size, fix, found = 0;
460
461 swizzle[i][0] = SWIZZLE_ZERO;
462 swizzle[i][1] = SWIZZLE_ZERO;
463 swizzle[i][2] = SWIZZLE_ZERO;
464 swizzle[i][3] = SWIZZLE_ONE;
465
466 for (ci = 0; ci < VB->AttribPtr[tab[i]].size; ci++)
467 swizzle[i][ci] = ci;
468
469 #if MESA_BIG_ENDIAN
470 #define SWAP_INT(a, b) do { \
471 int __temp; \
472 __temp = a;\
473 a = b; \
474 b = __temp; \
475 } while (0)
476
477 if (VB->AttribPtr[tab[i]].type == GL_UNSIGNED_BYTE) {
478 SWAP_INT(swizzle[i][0], swizzle[i][3]);
479 SWAP_INT(swizzle[i][1], swizzle[i][2]);
480 }
481 #endif /* MESA_BIG_ENDIAN */
482
483 if (r300IsGartMemory(rmesa, VB->AttribPtr[tab[i]].data, /*(count-1)*stride */ 4)) {
484 if (VB->AttribPtr[tab[i]].stride % 4)
485 return R300_FALLBACK_TCL;
486
487 rmesa->state.aos[i].address = VB->AttribPtr[tab[i]].data;
488 rmesa->state.aos[i].start = 0;
489 rmesa->state.aos[i].aos_offset = r300GartOffsetFromVirtual(rmesa, VB->AttribPtr[tab[i]].data);
490 rmesa->state.aos[i].aos_stride = VB->AttribPtr[tab[i]].stride / 4;
491
492 rmesa->state.aos[i].aos_size = t_emit_size(&VB->AttribPtr[tab[i]]);
493 } else {
494 /* TODO: emit_vector can only handle 4 byte vectors */
495 if (VB->AttribPtr[tab[i]].type != GL_FLOAT)
496 return R300_FALLBACK_TCL;
497
498 emit_vector(ctx, &rmesa->state.aos[i], VB->AttribPtr[tab[i]].data,
499 t_emit_size(&VB->AttribPtr[tab[i]]), VB->AttribPtr[tab[i]].stride, count);
500 }
501
502 rmesa->state.aos[i].aos_size = t_aos_size(&VB->AttribPtr[tab[i]]);
503
504 comp_size = _mesa_sizeof_type(VB->AttribPtr[tab[i]].type);
505
506 for (fix = 0; fix <= 4 - VB->AttribPtr[tab[i]].size; fix++) {
507 if ((rmesa->state.aos[i].aos_offset - comp_size * fix) % 4)
508 continue;
509
510 found = 1;
511 break;
512 }
513
514 if (found) {
515 if (fix > 0) {
516 WARN_ONCE("Feeling lucky?\n");
517 }
518
519 rmesa->state.aos[i].aos_offset -= comp_size * fix;
520
521 for (ci = 0; ci < VB->AttribPtr[tab[i]].size; ci++)
522 swizzle[i][ci] += fix;
523 } else {
524 WARN_ONCE("Cannot handle offset %x with stride %d, comp %d\n",
525 rmesa->state.aos[i].aos_offset, rmesa->state.aos[i].aos_stride, VB->AttribPtr[tab[i]].size);
526 return R300_FALLBACK_TCL;
527 }
528 }
529
530 /* setup INPUT_ROUTE */
531 R300_STATECHANGE(r300, vir[0]);
532 ((drm_r300_cmd_header_t*)r300->hw.vir[0].cmd)->packet0.count =
533 t_vir0(&r300->hw.vir[0].cmd[R300_VIR_CNTL_0], VB->AttribPtr, inputs, tab, nr);
534
535 R300_STATECHANGE(r300, vir[1]);
536 ((drm_r300_cmd_header_t*)r300->hw.vir[1].cmd)->packet0.count =
537 t_vir1(&r300->hw.vir[1].cmd[R300_VIR_CNTL_0], swizzle, nr);
538
539 /* Set up input_cntl */
540 /* I don't think this is needed for vertex buffers, but it doesn't hurt anything */
541 R300_STATECHANGE(r300, vic);
542 r300->hw.vic.cmd[R300_VIC_CNTL_0] = 0x5555; /* Hard coded value, no idea what it means */
543 r300->hw.vic.cmd[R300_VIC_CNTL_1] = t_vic(ctx, InputsRead);
544
545 /* Stage 3: VAP output */
546
547 R300_STATECHANGE(r300, vof);
548
549 r300->hw.vof.cmd[R300_VOF_CNTL_0]=0;
550 r300->hw.vof.cmd[R300_VOF_CNTL_1]=0;
551
552 if (OutputsWritten & (1 << VERT_RESULT_HPOS))
553 r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
554
555 if (OutputsWritten & (1 << VERT_RESULT_COL0))
556 r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT;
557
558 if (OutputsWritten & (1 << VERT_RESULT_COL1))
559 r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT;
560
561 /*if(OutputsWritten & (1 << VERT_RESULT_BFC0))
562 r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT;
563
564 if(OutputsWritten & (1 << VERT_RESULT_BFC1))
565 r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT;*/
566 //if(OutputsWritten & (1 << VERT_RESULT_FOGC))
567
568 if (OutputsWritten & (1 << VERT_RESULT_PSIZ))
569 r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT;
570
571 for(i=0;i < ctx->Const.MaxTextureUnits;i++)
572 if(OutputsWritten & (1 << (VERT_RESULT_TEX0 + i)))
573 r300->hw.vof.cmd[R300_VOF_CNTL_1] |= (4 << (3 * i));
574
575 rmesa->state.aos_count = nr;
576
577 return R300_FALLBACK_NONE;
578 }
579
580 #ifdef USER_BUFFERS
581 void r300UseArrays(GLcontext * ctx)
582 {
583 r300ContextPtr rmesa = R300_CONTEXT(ctx);
584 int i;
585
586 if(rmesa->state.elt_dma.buf)
587 radeon_mm_use(rmesa, rmesa->state.elt_dma.buf->id);
588
589 for (i=0; i < rmesa->state.aos_count;i++) {
590 if (rmesa->state.aos[i].buf)
591 radeon_mm_use(rmesa, rmesa->state.aos[i].buf->id);
592 }
593
594 #ifdef HW_VBOS
595
596 #define USE_VBO(a) \
597 do { \
598 if (ctx->Array.ArrayObj->a.BufferObj->Name \
599 && ctx->Array.ArrayObj->a.Enabled) \
600 radeon_mm_use(rmesa, ((struct r300_buffer_object *)ctx->Array.ArrayObj->a.BufferObj)->id); \
601 } while(0)
602
603 if (ctx->Array.ElementArrayBufferObj->Name && ctx->Array.ElementArrayBufferObj->OnCard)
604 radeon_mm_use(rmesa, ((struct r300_buffer_object *)ctx->Array.ElementArrayBufferObj)->id);
605
606 USE_VBO(Vertex);
607 USE_VBO(Normal);
608 USE_VBO(Color);
609 USE_VBO(SecondaryColor);
610 USE_VBO(FogCoord);
611
612 for (i=0; i < MAX_TEXTURE_COORD_UNITS; i++)
613 USE_VBO(TexCoord[i]);
614 #endif
615
616 }
617 #endif
618
619 void r300ReleaseArrays(GLcontext * ctx)
620 {
621 r300ContextPtr rmesa = R300_CONTEXT(ctx);
622 int i;
623
624 r300ReleaseDmaRegion(rmesa, &rmesa->state.elt_dma, __FUNCTION__);
625 for (i=0;i<rmesa->state.aos_count;i++) {
626 r300ReleaseDmaRegion(rmesa, &rmesa->state.aos[i], __FUNCTION__);
627 }
628 }