1
/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_maos_arrays.c,v 1.3 2003/02/23 23:59:01 dawes Exp $ */
3
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
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.
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:
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.
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.
32
* Keith Whitwell <keith@tungstengraphics.com>
42
#include "swrast_setup/swrast_setup.h"
43
#include "math/m_translate.h"
45
#include "tnl/t_context.h"
46
#include "tnl/t_imm_debug.h"
48
#include "r200_context.h"
49
#include "r200_ioctl.h"
50
#include "r200_state.h"
51
#include "r200_swtcl.h"
52
#include "r200_maos.h"
55
* - from r200_tcl_render
56
* - call r200EmitArrays to ensure uptodate arrays in dma
57
* - emit primitives (new type?) which reference the data
58
* -- need to use elts for lineloop, quads, quadstrip/flat
59
* -- other primitives are all well-formed (need tristrip-1,fake-poly)
62
static void emit_ubyte_rgba3( GLcontext *ctx,
63
struct r200_dma_region *rvb,
69
r200_color_t *out = (r200_color_t *)(rvb->start + rvb->address);
71
if (R200_DEBUG & DEBUG_VERTS)
72
fprintf(stderr, "%s count %d stride %d out %p\n",
73
__FUNCTION__, count, stride, out);
75
for (i = 0; i < count; i++) {
77
out->green = *(data+1);
78
out->blue = *(data+2);
86
#if defined(USE_X86_ASM)
87
#define COPY_DWORDS( dst, src, nr ) \
90
__asm__ __volatile__( "rep ; movsl" \
91
: "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \
97
#define COPY_DWORDS( dst, src, nr ) \
100
for ( j = 0 ; j < nr ; j++ ) \
101
dst[j] = ((int *)src)[j]; \
108
static void emit_ubyte_rgba4( GLcontext *ctx,
109
struct r200_dma_region *rvb,
115
int *out = (int *)(rvb->address + rvb->start);
117
if (R200_DEBUG & DEBUG_VERTS)
118
fprintf(stderr, "%s count %d stride %d\n",
119
__FUNCTION__, count, stride);
122
for (i = 0; i < count; i++)
123
((int *)out)[i] = LE32_TO_CPU(((int *)data)[i]);
125
for (i = 0; i < count; i++) {
126
*(int *)out++ = LE32_TO_CPU(*(int *)data);
133
static void emit_ubyte_rgba( GLcontext *ctx,
134
struct r200_dma_region *rvb,
140
r200ContextPtr rmesa = R200_CONTEXT(ctx);
142
if (R200_DEBUG & DEBUG_VERTS)
143
fprintf(stderr, "%s %d/%d\n", __FUNCTION__, count, size);
148
r200AllocDmaRegion( rmesa, rvb, 4, 4 );
150
rvb->aos_start = GET_START(rvb);
155
r200AllocDmaRegion( rmesa, rvb, 4 * count, 4 ); /* alignment? */
156
rvb->aos_start = GET_START(rvb);
165
emit_ubyte_rgba3( ctx, rvb, data, stride, count );
168
emit_ubyte_rgba4( ctx, rvb, data, stride, count );
180
static void emit_vec8( GLcontext *ctx,
181
struct r200_dma_region *rvb,
187
int *out = (int *)(rvb->address + rvb->start);
189
if (R200_DEBUG & DEBUG_VERTS)
190
fprintf(stderr, "%s count %d stride %d\n",
191
__FUNCTION__, count, stride);
194
COPY_DWORDS( out, data, count*2 );
196
for (i = 0; i < count; i++) {
197
out[0] = *(int *)data;
198
out[1] = *(int *)(data+4);
204
static void emit_vec12( GLcontext *ctx,
205
struct r200_dma_region *rvb,
211
int *out = (int *)(rvb->address + rvb->start);
213
if (R200_DEBUG & DEBUG_VERTS)
214
fprintf(stderr, "%s count %d stride %d out %p data %p\n",
215
__FUNCTION__, count, stride, out, data);
218
COPY_DWORDS( out, data, count*3 );
220
for (i = 0; i < count; i++) {
221
out[0] = *(int *)data;
222
out[1] = *(int *)(data+4);
223
out[2] = *(int *)(data+8);
229
static void emit_vec16( GLcontext *ctx,
230
struct r200_dma_region *rvb,
236
int *out = (int *)(rvb->address + rvb->start);
238
if (R200_DEBUG & DEBUG_VERTS)
239
fprintf(stderr, "%s count %d stride %d\n",
240
__FUNCTION__, count, stride);
243
COPY_DWORDS( out, data, count*4 );
245
for (i = 0; i < count; i++) {
246
out[0] = *(int *)data;
247
out[1] = *(int *)(data+4);
248
out[2] = *(int *)(data+8);
249
out[3] = *(int *)(data+12);
256
static void emit_vector( GLcontext *ctx,
257
struct r200_dma_region *rvb,
263
r200ContextPtr rmesa = R200_CONTEXT(ctx);
265
if (R200_DEBUG & DEBUG_VERTS)
266
fprintf(stderr, "%s count %d size %d stride %d\n",
267
__FUNCTION__, count, size, stride);
272
r200AllocDmaRegion( rmesa, rvb, size * 4, 4 );
274
rvb->aos_start = GET_START(rvb);
276
rvb->aos_size = size;
279
r200AllocDmaRegion( rmesa, rvb, size * count * 4, 4 ); /* alignment? */
280
rvb->aos_start = GET_START(rvb);
281
rvb->aos_stride = size;
282
rvb->aos_size = size;
289
emit_vec8( ctx, rvb, data, stride, count );
292
emit_vec12( ctx, rvb, data, stride, count );
295
emit_vec16( ctx, rvb, data, stride, count );
307
/* Emit any changed arrays to new agp memory, re-emit a packet to
310
void r200EmitArrays( GLcontext *ctx, GLuint inputs )
312
r200ContextPtr rmesa = R200_CONTEXT( ctx );
313
struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
314
struct r200_dma_region **component = rmesa->tcl.aos_components;
316
GLuint vfmt0 = 0, vfmt1 = 0;
317
GLuint count = VB->Count;
319
if (R200_DEBUG & DEBUG_VERTS)
320
_tnl_print_vert_flags( __FUNCTION__, inputs );
323
if (!rmesa->tcl.obj.buf)
326
(char *)VB->ObjPtr->data,
331
switch( VB->ObjPtr->size ) {
332
case 4: vfmt0 |= R200_VTX_W0;
333
case 3: vfmt0 |= R200_VTX_Z0;
338
component[nr++] = &rmesa->tcl.obj;
342
if (inputs & VERT_NORM) {
343
if (!rmesa->tcl.norm.buf)
346
(char *)VB->NormalPtr->data,
348
VB->NormalPtr->stride,
351
vfmt0 |= R200_VTX_N0;
352
component[nr++] = &rmesa->tcl.norm;
355
if (inputs & VERT_RGBA) {
356
if (VB->ColorPtr[0]->Type == GL_UNSIGNED_BYTE) {
357
if (!rmesa->tcl.rgba.buf)
358
emit_ubyte_rgba( ctx,
360
(char *)VB->ColorPtr[0]->Ptr,
361
VB->ColorPtr[0]->Size,
362
VB->ColorPtr[0]->StrideB,
365
vfmt0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT;
370
if (VB->ColorPtr[0]->Size == 4 &&
371
(VB->ColorPtr[0]->StrideB != 0 ||
372
((GLfloat *)VB->ColorPtr[0]->Ptr)[3] != 1.0)) {
373
vfmt0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT;
377
vfmt0 |= R200_VTX_FP_RGB << R200_VTX_COLOR_0_SHIFT;
381
if (!rmesa->tcl.rgba.buf)
384
(char *)VB->ColorPtr[0]->Ptr,
386
VB->ColorPtr[0]->StrideB,
390
component[nr++] = &rmesa->tcl.rgba;
394
if (inputs & VERT_SPEC_RGB) {
395
if (!rmesa->tcl.spec.buf) {
396
if (VB->SecondaryColorPtr[0]->Type != GL_UNSIGNED_BYTE)
397
r200_import_float_spec_colors( ctx );
399
emit_ubyte_rgba( ctx,
401
(char *)VB->SecondaryColorPtr[0]->Ptr,
403
VB->SecondaryColorPtr[0]->StrideB,
407
/* How does this work?
409
vfmt0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT;
410
component[nr++] = &rmesa->tcl.spec;
413
/* vtx = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] & */
414
/* ~(R200_TCL_VTX_Q0|R200_TCL_VTX_Q1)); */
416
if (inputs & VERT_TEX0) {
417
if (!rmesa->tcl.tex[0].buf)
419
&(rmesa->tcl.tex[0]),
420
(char *)VB->TexCoordPtr[0]->data,
421
VB->TexCoordPtr[0]->size,
422
VB->TexCoordPtr[0]->stride,
425
vfmt1 |= VB->TexCoordPtr[0]->size << R200_VTX_TEX0_COMP_CNT_SHIFT;
426
component[nr++] = &rmesa->tcl.tex[0];
429
if (inputs & VERT_TEX1) {
430
if (!rmesa->tcl.tex[1].buf)
432
&(rmesa->tcl.tex[1]),
433
(char *)VB->TexCoordPtr[1]->data,
434
VB->TexCoordPtr[1]->size,
435
VB->TexCoordPtr[1]->stride,
438
vfmt1 |= VB->TexCoordPtr[1]->size << R200_VTX_TEX1_COMP_CNT_SHIFT;
439
component[nr++] = &rmesa->tcl.tex[1];
442
if (vfmt0 != rmesa->hw.vtx.cmd[VTX_VTXFMT_0] ||
443
vfmt1 != rmesa->hw.vtx.cmd[VTX_VTXFMT_1]) {
444
R200_STATECHANGE( rmesa, vtx );
445
rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = vfmt0;
446
rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = vfmt1;
450
/* fprintf(stderr, "VTXFMT_0: %x VTXFMT_1: %x\n", vfmt0, vfmt1); */
452
rmesa->tcl.nr_aos_components = nr;
453
rmesa->tcl.vertex_format = vfmt0;
457
void r200ReleaseArrays( GLcontext *ctx, GLuint newinputs )
459
r200ContextPtr rmesa = R200_CONTEXT( ctx );
461
if (R200_DEBUG & DEBUG_VERTS)
462
_tnl_print_vert_flags( __FUNCTION__, newinputs );
464
if (newinputs & VERT_OBJ)
465
r200ReleaseDmaRegion( rmesa, &rmesa->tcl.obj, __FUNCTION__ );
467
if (newinputs & VERT_NORM)
468
r200ReleaseDmaRegion( rmesa, &rmesa->tcl.norm, __FUNCTION__ );
470
if (newinputs & VERT_RGBA)
471
r200ReleaseDmaRegion( rmesa, &rmesa->tcl.rgba, __FUNCTION__ );
473
if (newinputs & VERT_SPEC_RGB)
474
r200ReleaseDmaRegion( rmesa, &rmesa->tcl.spec, __FUNCTION__ );
476
if (newinputs & VERT_TEX0)
477
r200ReleaseDmaRegion( rmesa, &rmesa->tcl.tex[0], __FUNCTION__ );
479
if (newinputs & VERT_TEX1)
480
r200ReleaseDmaRegion( rmesa, &rmesa->tcl.tex[1], __FUNCTION__ );