OSDN Git Service

dee730351062418bb4acceabe2e294b1e7118e34
[android-x86/external-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 #if defined(USE_X86_ASM)
54 #define COPY_DWORDS( dst, src, nr )                                     \
55 do {                                                                    \
56         int __tmp;                                                      \
57         __asm__ __volatile__( "rep ; movsl"                             \
58                               : "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \
59                               : "0" (nr),                               \
60                                 "D" ((long)dst),                        \
61                                 "S" ((long)src) );                      \
62 } while (0)
63 #else
64 #define COPY_DWORDS( dst, src, nr )             \
65 do {                                            \
66    int j;                                       \
67    for ( j = 0 ; j < nr ; j++ )                 \
68       dst[j] = ((int *)src)[j];                 \
69    dst += nr;                                   \
70 } while (0)
71 #endif
72
73 static void r200_emit_vecfog(struct gl_context *ctx, struct radeon_aos *aos,
74                              GLvoid *data, int stride, int count)
75 {
76         radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
77         GLfloat *out;
78         int i;
79         int size = 1;
80
81         if (stride == 0) {
82                 radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * 4, 32);
83                 count = 1;
84                 aos->stride = 0;
85         } else {
86                 radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * count * 4, 32);
87                 aos->stride = size;
88         }
89
90         aos->components = size;
91         aos->count = count;
92
93         radeon_bo_map(aos->bo, 1);
94         out = (GLfloat*)((char*)aos->bo->ptr + aos->offset);
95         for (i = 0; i < count; i++) {
96           out[0] = r200ComputeFogBlendFactor( ctx, *(GLfloat *)data );
97           out++;
98           data += stride;
99         }
100         radeon_bo_unmap(aos->bo);
101 }
102
103 /* Emit any changed arrays to new GART memory, re-emit a packet to
104  * update the arrays.  
105  */
106 void r200EmitArrays( struct gl_context *ctx, GLubyte *vimap_rev )
107 {
108    r200ContextPtr rmesa = R200_CONTEXT( ctx );
109    struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
110    GLuint nr = 0;
111    GLuint vfmt0 = 0, vfmt1 = 0;
112    GLuint count = VB->Count;
113    GLuint i, emitsize;
114
115    //   fprintf(stderr,"emit arrays\n");
116    for ( i = 0; i < 15; i++ ) {
117       GLubyte attrib = vimap_rev[i];
118       if (attrib != 255) {
119          switch (i) {
120          case 0:
121             emitsize = (VB->AttribPtr[attrib]->size);
122             switch (emitsize) {
123             case 4:
124                vfmt0 |= R200_VTX_W0;
125                /* fallthrough */
126             case 3:
127                vfmt0 |= R200_VTX_Z0;
128                break;
129             case 2:
130                break;
131             default: assert(0);
132             }
133             break;
134          case 1:
135             assert(attrib == VERT_ATTRIB_WEIGHT);
136             emitsize = (VB->AttribPtr[attrib]->size);
137             vfmt0 |= emitsize << R200_VTX_WEIGHT_COUNT_SHIFT;
138             break;
139          case 2:
140             assert(attrib == VERT_ATTRIB_NORMAL);
141             emitsize = 3;
142             vfmt0 |= R200_VTX_N0;
143             break;
144          case 3:
145             /* special handling to fix up fog. Will get us into trouble with vbos...*/
146             assert(attrib == VERT_ATTRIB_FOG);
147             if (!rmesa->radeon.tcl.aos[i].bo) {
148                if (ctx->VertexProgram._Enabled)
149                   rcommon_emit_vector( ctx,
150                                        &(rmesa->radeon.tcl.aos[nr]),
151                                        (char *)VB->AttribPtr[attrib]->data,
152                                        1,
153                                        VB->AttribPtr[attrib]->stride,
154                                        count);
155                else
156                  r200_emit_vecfog( ctx,
157                                    &(rmesa->radeon.tcl.aos[nr]),
158                                    (char *)VB->AttribPtr[attrib]->data,
159                                    VB->AttribPtr[attrib]->stride,
160                                    count);
161             }
162             vfmt0 |= R200_VTX_DISCRETE_FOG;
163             goto after_emit;
164             break;
165          case 4:
166          case 5:
167          case 6:
168          case 7:
169             if (VB->AttribPtr[attrib]->size == 4 &&
170                (VB->AttribPtr[attrib]->stride != 0 ||
171                 VB->AttribPtr[attrib]->data[0][3] != 1.0)) emitsize = 4;
172             else emitsize = 3;
173             if (emitsize == 4)
174                vfmt0 |= R200_VTX_FP_RGBA << (R200_VTX_COLOR_0_SHIFT + (i - 4) * 2);
175             else {
176                vfmt0 |= R200_VTX_FP_RGB << (R200_VTX_COLOR_0_SHIFT + (i - 4) * 2);
177             }
178             break;
179          case 8:
180          case 9:
181          case 10:
182          case 11:
183          case 12:
184          case 13:
185             emitsize = VB->AttribPtr[attrib]->size;
186             vfmt1 |= emitsize << (R200_VTX_TEX0_COMP_CNT_SHIFT + (i - 8) * 3);
187             break;
188          case 14:
189             emitsize = VB->AttribPtr[attrib]->size >= 2 ? VB->AttribPtr[attrib]->size : 2;
190             switch (emitsize) {
191             case 2:
192                vfmt0 |= R200_VTX_XY1;
193                /* fallthrough */
194             case 3:
195                vfmt0 |= R200_VTX_Z1;
196                /* fallthrough */
197             case 4:
198                vfmt0 |= R200_VTX_W1;
199             break;
200             }
201          default:
202             assert(0);
203             emitsize = 0;
204          }
205          if (!rmesa->radeon.tcl.aos[nr].bo) {
206            rcommon_emit_vector( ctx,
207                                 &(rmesa->radeon.tcl.aos[nr]),
208                                 (char *)VB->AttribPtr[attrib]->data,
209                                 emitsize,
210                                 VB->AttribPtr[attrib]->stride,
211                                 count );
212          }
213 after_emit:
214          assert(nr < 12);
215          nr++;
216       }
217    }
218
219    if (vfmt0 != rmesa->hw.vtx.cmd[VTX_VTXFMT_0] ||
220        vfmt1 != rmesa->hw.vtx.cmd[VTX_VTXFMT_1]) {
221       R200_STATECHANGE( rmesa, vtx );
222       rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = vfmt0;
223       rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = vfmt1;
224    }
225
226    rmesa->radeon.tcl.aos_count = nr;
227 }
228