Updates to tnl_dd_dmatmp.h
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_maos_arrays.c
1 /* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_maos_arrays.c,v 1.1 2002/10/30 12:51:55 alanh Exp $ */
2 /**************************************************************************
3
4 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
5 Tungsten Graphics Inc., Cedar Park, Texas.
6
7 All Rights Reserved.
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 "imports.h"
38 #include "mtypes.h"
39 #include "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 #include "tnl/t_imm_debug.h"
46
47 #include "radeon_context.h"
48 #include "radeon_ioctl.h"
49 #include "radeon_state.h"
50 #include "radeon_swtcl.h"
51 #include "radeon_maos.h"
52
53 /* Usage:
54 * - from radeon_tcl_render
55 * - call radeonEmitArrays to ensure uptodate arrays in dma
56 * - emit primitives (new type?) which reference the data
57 * -- need to use elts for lineloop, quads, quadstrip/flat
58 * -- other primitives are all well-formed (need tristrip-1,fake-poly)
59 *
60 */
61 static void emit_ubyte_rgba3( GLcontext *ctx,
62 struct radeon_dma_region *rvb,
63 char *data,
64 int stride,
65 int count )
66 {
67 int i;
68 radeon_color_t *out = (radeon_color_t *)(rvb->start + rvb->address);
69
70 if (RADEON_DEBUG & DEBUG_VERTS)
71 fprintf(stderr, "%s count %d stride %d out %p\n",
72 __FUNCTION__, count, stride, out);
73
74 for (i = 0; i < count; i++) {
75 out->red = *data;
76 out->green = *(data+1);
77 out->blue = *(data+2);
78 out->alpha = 0xFF;
79 out++;
80 data += stride;
81 }
82 }
83
84
85 #if defined(USE_X86_ASM)
86 #define COPY_DWORDS( dst, src, nr ) \
87 do { \
88 int __tmp; \
89 __asm__ __volatile__( "rep ; movsl" \
90 : "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \
91 : "0" (nr), \
92 "D" ((long)dst), \
93 "S" ((long)src) ); \
94 } while (0)
95 #else
96 #define COPY_DWORDS( dst, src, nr ) \
97 do { \
98 int j; \
99 for ( j = 0 ; j < nr ; j++ ) \
100 dst[j] = ((int *)src)[j]; \
101 dst += nr; \
102 } while (0)
103 #endif
104
105
106
107 static void emit_ubyte_rgba4( GLcontext *ctx,
108 struct radeon_dma_region *rvb,
109 char *data,
110 int stride,
111 int count )
112 {
113 int i;
114 int *out = (int *)(rvb->address + rvb->start);
115
116 if (RADEON_DEBUG & DEBUG_VERTS)
117 fprintf(stderr, "%s count %d stride %d\n",
118 __FUNCTION__, count, stride);
119
120 if (stride == 4)
121 COPY_DWORDS( out, data, count );
122 else
123 for (i = 0; i < count; i++) {
124 *out++ = LE32_TO_CPU(*(int *)data);
125 data += stride;
126 }
127 }
128
129
130 static void emit_ubyte_rgba( GLcontext *ctx,
131 struct radeon_dma_region *rvb,
132 char *data,
133 int size,
134 int stride,
135 int count )
136 {
137 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
138
139 if (RADEON_DEBUG & DEBUG_VERTS)
140 fprintf(stderr, "%s %d/%d\n", __FUNCTION__, count, size);
141
142 assert (!rvb->buf);
143
144 if (stride == 0) {
145 radeonAllocDmaRegion( rmesa, rvb, 4, 4 );
146 count = 1;
147 rvb->aos_start = GET_START(rvb);
148 rvb->aos_stride = 0;
149 rvb->aos_size = 1;
150 }
151 else {
152 radeonAllocDmaRegion( rmesa, rvb, 4 * count, 4 ); /* alignment? */
153 rvb->aos_start = GET_START(rvb);
154 rvb->aos_stride = 1;
155 rvb->aos_size = 1;
156 }
157
158 /* Emit the data
159 */
160 switch (size) {
161 case 3:
162 emit_ubyte_rgba3( ctx, rvb, data, stride, count );
163 break;
164 case 4:
165 emit_ubyte_rgba4( ctx, rvb, data, stride, count );
166 break;
167 default:
168 assert(0);
169 exit(1);
170 break;
171 }
172 }
173
174
175
176
177 static void emit_vec8( GLcontext *ctx,
178 struct radeon_dma_region *rvb,
179 char *data,
180 int stride,
181 int count )
182 {
183 int i;
184 int *out = (int *)(rvb->address + rvb->start);
185
186 if (RADEON_DEBUG & DEBUG_VERTS)
187 fprintf(stderr, "%s count %d stride %d\n",
188 __FUNCTION__, count, stride);
189
190 if (stride == 8)
191 COPY_DWORDS( out, data, count*2 );
192 else
193 for (i = 0; i < count; i++) {
194 out[0] = *(int *)data;
195 out[1] = *(int *)(data+4);
196 out += 2;
197 data += stride;
198 }
199 }
200
201 static void emit_vec12( GLcontext *ctx,
202 struct radeon_dma_region *rvb,
203 char *data,
204 int stride,
205 int count )
206 {
207 int i;
208 int *out = (int *)(rvb->address + rvb->start);
209
210 if (RADEON_DEBUG & DEBUG_VERTS)
211 fprintf(stderr, "%s count %d stride %d out %p data %p\n",
212 __FUNCTION__, count, stride, out, data);
213
214 if (stride == 12)
215 COPY_DWORDS( out, data, count*3 );
216 else
217 for (i = 0; i < count; i++) {
218 out[0] = *(int *)data;
219 out[1] = *(int *)(data+4);
220 out[2] = *(int *)(data+8);
221 out += 3;
222 data += stride;
223 }
224 }
225
226 static void emit_vec16( GLcontext *ctx,
227 struct radeon_dma_region *rvb,
228 char *data,
229 int stride,
230 int count )
231 {
232 int i;
233 int *out = (int *)(rvb->address + rvb->start);
234
235 if (RADEON_DEBUG & DEBUG_VERTS)
236 fprintf(stderr, "%s count %d stride %d\n",
237 __FUNCTION__, count, stride);
238
239 if (stride == 16)
240 COPY_DWORDS( out, data, count*4 );
241 else
242 for (i = 0; i < count; i++) {
243 out[0] = *(int *)data;
244 out[1] = *(int *)(data+4);
245 out[2] = *(int *)(data+8);
246 out[3] = *(int *)(data+12);
247 out += 4;
248 data += stride;
249 }
250 }
251
252
253 static void emit_vector( GLcontext *ctx,
254 struct radeon_dma_region *rvb,
255 char *data,
256 int size,
257 int stride,
258 int count )
259 {
260 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
261
262 if (RADEON_DEBUG & DEBUG_VERTS)
263 fprintf(stderr, "%s count %d size %d stride %d\n",
264 __FUNCTION__, count, size, stride);
265
266 assert (!rvb->buf);
267
268 if (stride == 0) {
269 radeonAllocDmaRegion( rmesa, rvb, size * 4, 4 );
270 count = 1;
271 rvb->aos_start = GET_START(rvb);
272 rvb->aos_stride = 0;
273 rvb->aos_size = size;
274 }
275 else {
276 radeonAllocDmaRegion( rmesa, rvb, size * count * 4, 4 ); /* alignment? */
277 rvb->aos_start = GET_START(rvb);
278 rvb->aos_stride = size;
279 rvb->aos_size = size;
280 }
281
282 /* Emit the data
283 */
284 switch (size) {
285 case 2:
286 emit_vec8( ctx, rvb, data, stride, count );
287 break;
288 case 3:
289 emit_vec12( ctx, rvb, data, stride, count );
290 break;
291 case 4:
292 emit_vec16( ctx, rvb, data, stride, count );
293 break;
294 default:
295 assert(0);
296 exit(1);
297 break;
298 }
299
300 }
301
302
303
304 static void emit_s0_vec( GLcontext *ctx,
305 struct radeon_dma_region *rvb,
306 char *data,
307 int stride,
308 int count )
309 {
310 int i;
311 int *out = (int *)(rvb->address + rvb->start);
312
313 if (RADEON_DEBUG & DEBUG_VERTS)
314 fprintf(stderr, "%s count %d stride %d\n",
315 __FUNCTION__, count, stride);
316
317 for (i = 0; i < count; i++) {
318 out[0] = *(int *)data;
319 out[1] = 0;
320 out += 2;
321 data += stride;
322 }
323 }
324
325 static void emit_stq_vec( GLcontext *ctx,
326 struct radeon_dma_region *rvb,
327 char *data,
328 int stride,
329 int count )
330 {
331 int i;
332 int *out = (int *)(rvb->address + rvb->start);
333
334 if (RADEON_DEBUG & DEBUG_VERTS)
335 fprintf(stderr, "%s count %d stride %d\n",
336 __FUNCTION__, count, stride);
337
338 for (i = 0; i < count; i++) {
339 out[0] = *(int *)data;
340 out[1] = *(int *)(data+4);
341 out[2] = *(int *)(data+12);
342 out += 3;
343 data += stride;
344 }
345 }
346
347
348
349
350 static void emit_tex_vector( GLcontext *ctx,
351 struct radeon_dma_region *rvb,
352 char *data,
353 int size,
354 int stride,
355 int count )
356 {
357 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
358 int emitsize;
359
360 if (RADEON_DEBUG & DEBUG_VERTS)
361 fprintf(stderr, "%s %d/%d\n", __FUNCTION__, count, size);
362
363 assert (!rvb->buf);
364
365 switch (size) {
366 case 4: emitsize = 3; break;
367 default: emitsize = 2; break;
368 }
369
370
371 if (stride == 0) {
372 radeonAllocDmaRegion( rmesa, rvb, 4 * emitsize, 4 );
373 count = 1;
374 rvb->aos_start = GET_START(rvb);
375 rvb->aos_stride = 0;
376 rvb->aos_size = emitsize;
377 }
378 else {
379 radeonAllocDmaRegion( rmesa, rvb, 4 * emitsize * count, 4 );
380 rvb->aos_start = GET_START(rvb);
381 rvb->aos_stride = emitsize;
382 rvb->aos_size = emitsize;
383 }
384
385
386 /* Emit the data
387 */
388 switch (size) {
389 case 1:
390 emit_s0_vec( ctx, rvb, data, stride, count );
391 break;
392 case 2:
393 emit_vec8( ctx, rvb, data, stride, count );
394 break;
395 case 3:
396 emit_vec8( ctx, rvb, data, stride, count );
397 break;
398 case 4:
399 emit_stq_vec( ctx, rvb, data, stride, count );
400 break;
401 default:
402 assert(0);
403 exit(1);
404 break;
405 }
406 }
407
408
409
410
411 /* Emit any changed arrays to new GART memory, re-emit a packet to
412 * update the arrays.
413 */
414 void radeonEmitArrays( GLcontext *ctx, GLuint inputs )
415 {
416 radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
417 struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
418 struct radeon_dma_region **component = rmesa->tcl.aos_components;
419 GLuint nr = 0;
420 GLuint vfmt = 0;
421 GLuint count = VB->Count;
422 GLuint vtx;
423
424 #if 0
425 if (RADEON_DEBUG & DEBUG_VERTS)
426 _tnl_print_vert_flags( __FUNCTION__, inputs );
427 #endif
428
429 if (1) {
430 if (!rmesa->tcl.obj.buf)
431 emit_vector( ctx,
432 &rmesa->tcl.obj,
433 (char *)VB->ObjPtr->data,
434 VB->ObjPtr->size,
435 VB->ObjPtr->stride,
436 count);
437
438 switch( VB->ObjPtr->size ) {
439 case 4: vfmt |= RADEON_CP_VC_FRMT_W0;
440 case 3: vfmt |= RADEON_CP_VC_FRMT_Z;
441 case 2: vfmt |= RADEON_CP_VC_FRMT_XY;
442 default:
443 }
444 component[nr++] = &rmesa->tcl.obj;
445 }
446
447
448 if (inputs & VERT_BIT_NORMAL) {
449 if (!rmesa->tcl.norm.buf)
450 emit_vector( ctx,
451 &(rmesa->tcl.norm),
452 (char *)VB->NormalPtr->data,
453 3,
454 VB->NormalPtr->stride,
455 count);
456
457 vfmt |= RADEON_CP_VC_FRMT_N0;
458 component[nr++] = &rmesa->tcl.norm;
459 }
460
461 if (inputs & VERT_BIT_COLOR0) {
462 if (VB->ColorPtr[0]->Type == GL_UNSIGNED_BYTE) {
463 if (!rmesa->tcl.rgba.buf)
464 emit_ubyte_rgba( ctx,
465 &rmesa->tcl.rgba,
466 (char *)VB->ColorPtr[0]->Ptr,
467 VB->ColorPtr[0]->Size,
468 VB->ColorPtr[0]->StrideB,
469 count);
470
471 vfmt |= RADEON_CP_VC_FRMT_PKCOLOR;
472 }
473 else {
474 int emitsize;
475
476 if (VB->ColorPtr[0]->Size == 4 &&
477 (VB->ColorPtr[0]->StrideB != 0 ||
478 ((GLfloat *)VB->ColorPtr[0]->Ptr)[3] != 1.0)) {
479 vfmt |= RADEON_CP_VC_FRMT_FPCOLOR | RADEON_CP_VC_FRMT_FPALPHA;
480 emitsize = 4;
481 }
482 else {
483 vfmt |= RADEON_CP_VC_FRMT_FPCOLOR;
484 emitsize = 3;
485 }
486
487 if (!rmesa->tcl.rgba.buf)
488 emit_vector( ctx,
489 &(rmesa->tcl.rgba),
490 (char *)VB->ColorPtr[0]->Ptr,
491 emitsize,
492 VB->ColorPtr[0]->StrideB,
493 count);
494 }
495
496 component[nr++] = &rmesa->tcl.rgba;
497 }
498
499
500 if (inputs & VERT_BIT_COLOR1) {
501 if (!rmesa->tcl.spec.buf) {
502
503 emit_ubyte_rgba( ctx,
504 &rmesa->tcl.spec,
505 (char *)VB->SecondaryColorPtr[0]->Ptr,
506 3,
507 VB->SecondaryColorPtr[0]->StrideB,
508 count);
509 }
510
511 vfmt |= RADEON_CP_VC_FRMT_PKSPEC;
512 component[nr++] = &rmesa->tcl.spec;
513 }
514
515 vtx = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &
516 ~(RADEON_TCL_VTX_Q0|RADEON_TCL_VTX_Q1));
517
518 if (inputs & VERT_BIT_TEX0) {
519 if (!rmesa->tcl.tex[0].buf)
520 emit_tex_vector( ctx,
521 &(rmesa->tcl.tex[0]),
522 (char *)VB->TexCoordPtr[0]->data,
523 VB->TexCoordPtr[0]->size,
524 VB->TexCoordPtr[0]->stride,
525 count );
526
527 switch( VB->TexCoordPtr[0]->size ) {
528 case 4:
529 vtx |= RADEON_TCL_VTX_Q0;
530 vfmt |= RADEON_CP_VC_FRMT_Q0;
531 default:
532 vfmt |= RADEON_CP_VC_FRMT_ST0;
533 }
534 component[nr++] = &rmesa->tcl.tex[0];
535 }
536
537 if (inputs & VERT_BIT_TEX1) {
538 if (!rmesa->tcl.tex[1].buf)
539 emit_tex_vector( ctx,
540 &(rmesa->tcl.tex[1]),
541 (char *)VB->TexCoordPtr[1]->data,
542 VB->TexCoordPtr[1]->size,
543 VB->TexCoordPtr[1]->stride,
544 count );
545
546 switch( VB->TexCoordPtr[1]->size ) {
547 case 4:
548 vtx |= RADEON_TCL_VTX_Q1;
549 vfmt |= RADEON_CP_VC_FRMT_Q1;
550 default:
551 vfmt |= RADEON_CP_VC_FRMT_ST1;
552 }
553 component[nr++] = &rmesa->tcl.tex[1];
554 }
555
556 if (vtx != rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT]) {
557 RADEON_STATECHANGE( rmesa, tcl );
558 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] = vtx;
559 }
560
561 rmesa->tcl.nr_aos_components = nr;
562 rmesa->tcl.vertex_format = vfmt;
563 }
564
565
566 void radeonReleaseArrays( GLcontext *ctx, GLuint newinputs )
567 {
568 radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
569
570 #if 0
571 if (RADEON_DEBUG & DEBUG_VERTS)
572 _tnl_print_vert_flags( __FUNCTION__, newinputs );
573 #endif
574
575 if (newinputs & VERT_BIT_POS)
576 radeonReleaseDmaRegion( rmesa, &rmesa->tcl.obj, __FUNCTION__ );
577
578 if (newinputs & VERT_BIT_NORMAL)
579 radeonReleaseDmaRegion( rmesa, &rmesa->tcl.norm, __FUNCTION__ );
580
581 if (newinputs & VERT_BIT_COLOR0)
582 radeonReleaseDmaRegion( rmesa, &rmesa->tcl.rgba, __FUNCTION__ );
583
584 if (newinputs & VERT_BIT_COLOR1)
585 radeonReleaseDmaRegion( rmesa, &rmesa->tcl.spec, __FUNCTION__ );
586
587 if (newinputs & VERT_BIT_TEX0)
588 radeonReleaseDmaRegion( rmesa, &rmesa->tcl.tex[0], __FUNCTION__ );
589
590 if (newinputs & VERT_BIT_TEX1)
591 radeonReleaseDmaRegion( rmesa, &rmesa->tcl.tex[1], __FUNCTION__ );
592 }