Support 16-bit modes.
[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
42 #include "swrast_setup/swrast_setup.h"
43 #include "math/m_translate.h"
44 #include "tnl/tnl.h"
45 #include "tnl/t_context.h"
46
47 #include "r300_context.h"
48 #include "radeon_ioctl.h"
49 #include "r300_state.h"
50 #include "r300_maos.h"
51 #include "r300_ioctl.h"
52
53 #define DEBUG_ALL DEBUG_VERTS
54
55
56 #if defined(USE_X86_ASM)
57 #define COPY_DWORDS( dst, src, nr ) \
58 do { \
59 int __tmp; \
60 __asm__ __volatile__( "rep ; movsl" \
61 : "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \
62 : "0" (nr), \
63 "D" ((long)dst), \
64 "S" ((long)src) ); \
65 } while (0)
66 #else
67 #define COPY_DWORDS( dst, src, nr ) \
68 do { \
69 int j; \
70 for ( j = 0 ; j < nr ; j++ ) \
71 dst[j] = ((int *)src)[j]; \
72 dst += nr; \
73 } while (0)
74 #endif
75
76 static void emit_vec4(GLcontext * ctx,
77 struct r300_dma_region *rvb,
78 GLvoid *data, int stride, int count)
79 {
80 int i;
81 int *out = (int *)(rvb->address + rvb->start);
82
83 if (RADEON_DEBUG & DEBUG_VERTS)
84 fprintf(stderr, "%s count %d stride %d\n",
85 __FUNCTION__, count, stride);
86
87 if (stride == 4)
88 COPY_DWORDS(out, data, count);
89 else
90 for (i = 0; i < count; i++) {
91 out[0] = *(int *)data;
92 out++;
93 data += stride;
94 }
95 }
96
97 static void emit_vec8(GLcontext * ctx,
98 struct r300_dma_region *rvb,
99 GLvoid *data, int stride, int count)
100 {
101 int i;
102 int *out = (int *)(rvb->address + rvb->start);
103
104 if (RADEON_DEBUG & DEBUG_VERTS)
105 fprintf(stderr, "%s count %d stride %d\n",
106 __FUNCTION__, count, stride);
107
108 if (stride == 8)
109 COPY_DWORDS(out, data, count * 2);
110 else
111 for (i = 0; i < count; i++) {
112 out[0] = *(int *)data;
113 out[1] = *(int *)(data + 4);
114 out += 2;
115 data += stride;
116 }
117 }
118
119 static void emit_vec12(GLcontext * ctx,
120 struct r300_dma_region *rvb,
121 GLvoid *data, int stride, int count)
122 {
123 int i;
124 int *out = (int *)(rvb->address + rvb->start);
125
126 if (RADEON_DEBUG & DEBUG_VERTS)
127 fprintf(stderr, "%s count %d stride %d out %p data %p\n",
128 __FUNCTION__, count, stride, (void *)out, (void *)data);
129
130 if (stride == 12)
131 COPY_DWORDS(out, data, count * 3);
132 else
133 for (i = 0; i < count; i++) {
134 out[0] = *(int *)data;
135 out[1] = *(int *)(data + 4);
136 out[2] = *(int *)(data + 8);
137 out += 3;
138 data += stride;
139 }
140 }
141
142 static void emit_vec16(GLcontext * ctx,
143 struct r300_dma_region *rvb,
144 GLvoid *data, int stride, int count)
145 {
146 int i;
147 int *out = (int *)(rvb->address + rvb->start);
148
149 if (RADEON_DEBUG & DEBUG_VERTS)
150 fprintf(stderr, "%s count %d stride %d\n",
151 __FUNCTION__, count, stride);
152
153 if (stride == 16)
154 COPY_DWORDS(out, data, count * 4);
155 else
156 for (i = 0; i < count; i++) {
157 out[0] = *(int *)data;
158 out[1] = *(int *)(data + 4);
159 out[2] = *(int *)(data + 8);
160 out[3] = *(int *)(data + 12);
161 out += 4;
162 data += stride;
163 }
164 }
165
166 static void emit_vector(GLcontext * ctx,
167 struct r300_dma_region *rvb,
168 GLvoid *data, int size, int stride, int count)
169 {
170 r300ContextPtr rmesa = R300_CONTEXT(ctx);
171
172 if (RADEON_DEBUG & DEBUG_VERTS)
173 fprintf(stderr, "%s count %d size %d stride %d\n",
174 __FUNCTION__, count, size, stride);
175
176 if(r300IsGartMemory(rmesa, data, size*stride)){
177 rvb->address = rmesa->radeon.radeonScreen->gartTextures.map;
178 rvb->start = (char *)data - rvb->address;
179 rvb->aos_offset = r300GartOffsetFromVirtual(rmesa, data);
180
181 if(stride == 0)
182 rvb->aos_stride = 0;
183 else
184 rvb->aos_stride = stride / 4;
185
186 rvb->aos_size = size;
187 return;
188 }
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 rvb->aos_size = size;
199 } else {
200 r300AllocDmaRegion(rmesa, rvb, size * count * 4, 4); /* alignment? */
201 rvb->aos_offset = GET_START(rvb);
202 rvb->aos_stride = size;
203 rvb->aos_size = size;
204 }
205
206 /* Emit the data
207 */
208 switch (size) {
209 case 1:
210 emit_vec4(ctx, rvb, data, stride, count);
211 break;
212 case 2:
213 emit_vec8(ctx, rvb, data, stride, count);
214 break;
215 case 3:
216 emit_vec12(ctx, rvb, data, stride, count);
217 break;
218 case 4:
219 emit_vec16(ctx, rvb, data, stride, count);
220 break;
221 default:
222 assert(0);
223 exit(1);
224 break;
225 }
226
227 }
228
229 void r300EmitElts(GLcontext * ctx, GLuint *elts, unsigned long n_elts)
230 {
231 r300ContextPtr rmesa = R300_CONTEXT(ctx);
232 struct r300_dma_region *rvb=&rmesa->state.elt_dma;
233 unsigned short int *out;
234 int i;
235
236 if(r300IsGartMemory(rmesa, elts, n_elts*sizeof(unsigned short int))){
237 rvb->address = rmesa->radeon.radeonScreen->gartTextures.map;
238 rvb->start = (char *)elts - rvb->address;
239 rvb->aos_offset = rmesa->radeon.radeonScreen->gart_texture_offset + rvb->start;
240 return ;
241 }
242
243 r300AllocDmaRegion(rmesa, rvb, n_elts*sizeof(unsigned short int), 2);
244
245 out = (unsigned short int *)(rvb->address + rvb->start);
246
247 for(i=0; i < n_elts; i++)
248 out[i]=(unsigned short int)elts[i];
249 }
250
251 /* Emit vertex data to GART memory (unless immediate mode)
252 * Route inputs to the vertex processor
253 */
254 void r300EmitArrays(GLcontext * ctx, GLboolean immd)
255 {
256 r300ContextPtr rmesa = R300_CONTEXT(ctx);
257 r300ContextPtr r300 = rmesa;
258 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
259 GLuint nr = 0;
260 GLuint count = VB->Count;
261 GLuint dw,mask;
262 GLuint vic_1 = 0; /* R300_VAP_INPUT_CNTL_1 */
263 GLuint aa_vap_reg = 0; /* VAP register assignment */
264 GLuint i;
265 GLuint inputs = 0;
266
267
268 #define CONFIGURE_AOS(r, f, v, sz, cn) { \
269 if (RADEON_DEBUG & DEBUG_STATE) \
270 fprintf(stderr, "Enabling "#v "\n"); \
271 if (++nr >= R300_MAX_AOS_ARRAYS) { \
272 fprintf(stderr, "Aieee! AOS array count exceeded!\n"); \
273 exit(-1); \
274 } \
275 \
276 if (hw_tcl_on == GL_FALSE) \
277 rmesa->state.aos[nr-1].aos_reg = aa_vap_reg++; \
278 rmesa->state.aos[nr-1].aos_format = f; \
279 if (immd) { \
280 rmesa->state.aos[nr-1].aos_size = 4; \
281 rmesa->state.aos[nr-1].aos_stride = 4; \
282 rmesa->state.aos[nr-1].aos_offset = 0; \
283 } else { \
284 emit_vector(ctx, \
285 &rmesa->state.aos[nr-1], \
286 v->data, \
287 sz, \
288 v->stride, \
289 cn); \
290 rmesa->state.vap_reg.r=rmesa->state.aos[nr-1].aos_reg; \
291 } \
292 }
293
294 if (hw_tcl_on) {
295 GLuint InputsRead = CURRENT_VERTEX_SHADER(ctx)->InputsRead;
296 struct r300_vertex_program *prog=(struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx);
297 if (InputsRead & (1<<VERT_ATTRIB_POS)) {
298 inputs |= _TNL_BIT_POS;
299 rmesa->state.aos[nr++].aos_reg = prog->inputs[VERT_ATTRIB_POS];
300 }
301 if (InputsRead & (1<<VERT_ATTRIB_NORMAL)) {
302 inputs |= _TNL_BIT_NORMAL;
303 rmesa->state.aos[nr++].aos_reg = prog->inputs[VERT_ATTRIB_NORMAL];
304 }
305 if (InputsRead & (1<<VERT_ATTRIB_COLOR0)) {
306 inputs |= _TNL_BIT_COLOR0;
307 rmesa->state.aos[nr++].aos_reg = prog->inputs[VERT_ATTRIB_COLOR0];
308 }
309 if (InputsRead & (1<<VERT_ATTRIB_COLOR1)) {
310 inputs |= _TNL_BIT_COLOR1;
311 rmesa->state.aos[nr++].aos_reg = prog->inputs[VERT_ATTRIB_COLOR1];
312 }
313 if (InputsRead & (1<<VERT_ATTRIB_FOG)) {
314 inputs |= _TNL_BIT_FOG;
315 rmesa->state.aos[nr++].aos_reg = prog->inputs[VERT_ATTRIB_FOG];
316 }
317 if(ctx->Const.MaxTextureUnits > 8) { /* Not sure if this can even happen... */
318 fprintf(stderr, "%s: Cant handle that many inputs\n", __FUNCTION__);
319 exit(-1);
320 }
321 for (i=0;i<ctx->Const.MaxTextureUnits;i++) {
322 if (InputsRead & (1<<(VERT_ATTRIB_TEX0+i))) {
323 inputs |= _TNL_BIT_TEX0<<i;
324 rmesa->state.aos[nr++].aos_reg = prog->inputs[VERT_ATTRIB_TEX0+i];
325 }
326 }
327 nr = 0;
328 } else {
329 inputs = TNL_CONTEXT(ctx)->render_inputs;
330 }
331 rmesa->state.render_inputs = inputs;
332
333 if (inputs & _TNL_BIT_POS) {
334 CONFIGURE_AOS(i_coords, AOS_FORMAT_FLOAT,
335 VB->ObjPtr,
336 immd ? 4 : VB->ObjPtr->size,
337 count);
338
339 vic_1 |= R300_INPUT_CNTL_POS;
340 }
341
342 if (inputs & _TNL_BIT_NORMAL) {
343 CONFIGURE_AOS(i_normal, AOS_FORMAT_FLOAT,
344 VB->NormalPtr,
345 immd ? 4 : VB->NormalPtr->size,
346 count);
347
348 vic_1 |= R300_INPUT_CNTL_NORMAL;
349 }
350
351 if (inputs & _TNL_BIT_COLOR0) {
352 int emitsize=4;
353
354 if (!immd) {
355 if (VB->ColorPtr[0]->size == 4 &&
356 (VB->ColorPtr[0]->stride != 0 ||
357 VB->ColorPtr[0]->data[0][3] != 1.0)) {
358 emitsize = 4;
359 } else {
360 emitsize = 3;
361 }
362 }
363
364 CONFIGURE_AOS(i_color[0], AOS_FORMAT_FLOAT_COLOR,
365 VB->ColorPtr[0],
366 immd ? 4 : emitsize,
367 count);
368
369 vic_1 |= R300_INPUT_CNTL_COLOR;
370 }
371
372 if (inputs & _TNL_BIT_COLOR1) {
373 CONFIGURE_AOS(i_color[1], AOS_FORMAT_FLOAT_COLOR,
374 VB->SecondaryColorPtr[0],
375 immd ? 4 : VB->SecondaryColorPtr[0]->size,
376 count);
377 }
378
379 #if 0
380 if (inputs & _TNL_BIT_FOG) {
381 CONFIGURE_AOS( AOS_FORMAT_FLOAT,
382 VB->FogCoordPtr,
383 immd ? 4 : VB->FogCoordPtr->size,
384 count);
385 }
386 #endif
387
388 r300->state.texture.tc_count = 0;
389 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
390 if (inputs & (_TNL_BIT_TEX0 << i)) {
391 CONFIGURE_AOS(i_tex[i], AOS_FORMAT_FLOAT,
392 VB->TexCoordPtr[i],
393 immd ? 4 : VB->TexCoordPtr[i]->size,
394 count);
395
396 vic_1 |= R300_INPUT_CNTL_TC0 << i;
397 r300->state.texture.tc_count++;
398 }
399 }
400
401 #define SHOW_INFO(n) do { \
402 if (RADEON_DEBUG & DEBUG_ALL) { \
403 fprintf(stderr, "RR[%d] - sz=%d, reg=%d, fmt=%d -- st=%d, of=0x%08x\n", \
404 n, \
405 r300->state.aos[n].aos_size, \
406 r300->state.aos[n].aos_reg, \
407 r300->state.aos[n].aos_format, \
408 r300->state.aos[n].aos_stride, \
409 r300->state.aos[n].aos_offset); \
410 } \
411 } while(0);
412
413 /* setup INPUT_ROUTE */
414 R300_STATECHANGE(r300, vir[0]);
415 for(i=0;i+1<nr;i+=2){
416 SHOW_INFO(i)
417 SHOW_INFO(i+1)
418 dw=(r300->state.aos[i].aos_size-1)
419 | ((r300->state.aos[i].aos_reg)<<8)
420 | (r300->state.aos[i].aos_format<<14)
421 | (((r300->state.aos[i+1].aos_size-1)
422 | ((r300->state.aos[i+1].aos_reg)<<8)
423 | (r300->state.aos[i+1].aos_format<<14))<<16);
424
425 if(i+2==nr){
426 dw|=(1<<(13+16));
427 }
428 r300->hw.vir[0].cmd[R300_VIR_CNTL_0+(i>>1)]=dw;
429 }
430 if(nr & 1){
431 SHOW_INFO(nr-1)
432 dw=(r300->state.aos[nr-1].aos_size-1)
433 | (r300->state.aos[nr-1].aos_format<<14)
434 | ((r300->state.aos[nr-1].aos_reg)<<8)
435 | (1<<13);
436 r300->hw.vir[0].cmd[R300_VIR_CNTL_0+(nr>>1)]=dw;
437 //fprintf(stderr, "vir0 dw=%08x\n", dw);
438 }
439 /* Set the rest of INPUT_ROUTE_0 to 0 */
440 //for(i=((count+1)>>1); i<8; i++)r300->hw.vir[0].cmd[R300_VIR_CNTL_0+i]=(0x0);
441 ((drm_r300_cmd_header_t*)r300->hw.vir[0].cmd)->unchecked_state.count = (nr+1)>>1;
442
443
444 /* Mesa assumes that all missing components are from (0, 0, 0, 1) */
445 #define ALL_COMPONENTS ((R300_INPUT_ROUTE_SELECT_X<<R300_INPUT_ROUTE_X_SHIFT) \
446 | (R300_INPUT_ROUTE_SELECT_Y<<R300_INPUT_ROUTE_Y_SHIFT) \
447 | (R300_INPUT_ROUTE_SELECT_Z<<R300_INPUT_ROUTE_Z_SHIFT) \
448 | (R300_INPUT_ROUTE_SELECT_W<<R300_INPUT_ROUTE_W_SHIFT))
449
450 #define ALL_DEFAULT ((R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_X_SHIFT) \
451 | (R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_Y_SHIFT) \
452 | (R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_Z_SHIFT) \
453 | (R300_INPUT_ROUTE_SELECT_ONE<<R300_INPUT_ROUTE_W_SHIFT))
454
455 R300_STATECHANGE(r300, vir[1]);
456
457 for(i=0;i+1<nr;i+=2){
458 /* do i first.. */
459 mask=(1<<(r300->state.aos[i].aos_size*3))-1;
460 dw=(ALL_COMPONENTS & mask)
461 | (ALL_DEFAULT & ~mask)
462 | R300_INPUT_ROUTE_ENABLE;
463
464 /* i+1 */
465 mask=(1<<(r300->state.aos[i+1].aos_size*3))-1;
466 dw|=(
467 (ALL_COMPONENTS & mask)
468 | (ALL_DEFAULT & ~mask)
469 | R300_INPUT_ROUTE_ENABLE
470 )<<16;
471
472 r300->hw.vir[1].cmd[R300_VIR_CNTL_0+(i>>1)]=dw;
473 }
474 if(nr & 1){
475 mask=(1<<(r300->state.aos[nr-1].aos_size*3))-1;
476 dw=(ALL_COMPONENTS & mask)
477 | (ALL_DEFAULT & ~mask)
478 | R300_INPUT_ROUTE_ENABLE;
479 r300->hw.vir[1].cmd[R300_VIR_CNTL_0+(nr>>1)]=dw;
480 //fprintf(stderr, "vir1 dw=%08x\n", dw);
481 }
482 /* Set the rest of INPUT_ROUTE_1 to 0 */
483 //for(i=((count+1)>>1); i<8; i++)r300->hw.vir[1].cmd[R300_VIR_CNTL_0+i]=0x0;
484 ((drm_r300_cmd_header_t*)r300->hw.vir[1].cmd)->unchecked_state.count = (nr+1)>>1;
485
486 /* Set up input_cntl */
487 /* I don't think this is needed for vertex buffers, but it doesn't hurt anything */
488 R300_STATECHANGE(r300, vic);
489 r300->hw.vic.cmd[R300_VIC_CNTL_0]=0x5555; /* Hard coded value, no idea what it means */
490 r300->hw.vic.cmd[R300_VIC_CNTL_1]=vic_1;
491
492 #if 0
493 r300->hw.vic.cmd[R300_VIC_CNTL_1]=0;
494
495 if(r300->state.render_inputs & _TNL_BIT_POS)
496 r300->hw.vic.cmd[R300_VIC_CNTL_1]|=R300_INPUT_CNTL_POS;
497
498 if(r300->state.render_inputs & _TNL_BIT_NORMAL)
499 r300->hw.vic.cmd[R300_VIC_CNTL_1]|=R300_INPUT_CNTL_NORMAL;
500
501 if(r300->state.render_inputs & _TNL_BIT_COLOR0)
502 r300->hw.vic.cmd[R300_VIC_CNTL_1]|=R300_INPUT_CNTL_COLOR;
503
504 for(i=0;i < ctx->Const.MaxTextureUnits;i++)
505 if(r300->state.render_inputs & (_TNL_BIT_TEX0<<i))
506 r300->hw.vic.cmd[R300_VIC_CNTL_1]|=(R300_INPUT_CNTL_TC0<<i);
507 #endif
508
509 /* Stage 3: VAP output */
510
511 R300_STATECHANGE(r300, vof);
512
513 r300->hw.vof.cmd[R300_VOF_CNTL_0]=0;
514 r300->hw.vof.cmd[R300_VOF_CNTL_1]=0;
515 if (hw_tcl_on){
516 GLuint OutputsWritten = CURRENT_VERTEX_SHADER(ctx)->OutputsWritten;
517
518 if(OutputsWritten & (1<<VERT_RESULT_HPOS))
519 r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
520 if(OutputsWritten & (1<<VERT_RESULT_COL0))
521 r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT;
522 /*if(OutputsWritten & (1<<VERT_RESULT_COL1))
523 r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT;
524 if(OutputsWritten & (1<<VERT_RESULT_BFC0))
525 r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT;
526 if(OutputsWritten & (1<<VERT_RESULT_BFC1))
527 r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT;*/
528 //if(OutputsWritten & (1<<VERT_RESULT_FOGC))
529
530 if(OutputsWritten & (1<<VERT_RESULT_PSIZ))
531 r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT;
532
533 for(i=0;i < ctx->Const.MaxTextureUnits;i++)
534 if(OutputsWritten & (1<<(VERT_RESULT_TEX0+i)))
535 r300->hw.vof.cmd[R300_VOF_CNTL_1] |= (4<<(3*i));
536 } else {
537 if(inputs & _TNL_BIT_POS)
538 r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
539 if(inputs & _TNL_BIT_COLOR0)
540 r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT;
541 if(inputs & _TNL_BIT_COLOR1)
542 r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT;
543
544 for(i=0;i < ctx->Const.MaxTextureUnits;i++)
545 if(inputs & (_TNL_BIT_TEX0<<i))
546 r300->hw.vof.cmd[R300_VOF_CNTL_1]|=(4<<(3*i));
547 }
548
549 rmesa->state.aos_count = nr;
550 }
551
552 void r300ReleaseArrays(GLcontext * ctx)
553 {
554 r300ContextPtr rmesa = R300_CONTEXT(ctx);
555 int i;
556
557 r300ReleaseDmaRegion(rmesa, &rmesa->state.elt_dma, __FUNCTION__);
558 for (i=0;i<rmesa->state.aos_count;i++) {
559 r300ReleaseDmaRegion(rmesa, &rmesa->state.aos[i], __FUNCTION__);
560 }
561 }