1 /* $XFree86: xc/lib/GL/mesa/src/drv/r300/r300_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.
29 **************************************************************************/
33 * Keith Whitwell <keith@tungstengraphics.com>
42 #include "swrast_setup/swrast_setup.h"
43 #include "math/m_translate.h"
45 #include "tnl/t_context.h"
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"
53 #define DEBUG_ALL DEBUG_VERTS
56 #if defined(USE_X86_ASM)
57 #define COPY_DWORDS( dst, src, nr ) \
60 __asm__ __volatile__( "rep ; movsl" \
61 : "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \
67 #define COPY_DWORDS( dst, src, nr ) \
70 for ( j = 0 ; j < nr ; j++ ) \
71 dst[j] = ((int *)src)[j]; \
76 static void emit_vec4(GLcontext
* ctx
,
77 struct r300_dma_region
*rvb
,
78 char *data
, int stride
, int count
)
81 int *out
= (int *)(rvb
->address
+ rvb
->start
);
83 if (RADEON_DEBUG
& DEBUG_VERTS
)
84 fprintf(stderr
, "%s count %d stride %d\n",
85 __FUNCTION__
, count
, stride
);
88 COPY_DWORDS(out
, data
, count
);
90 for (i
= 0; i
< count
; i
++) {
91 out
[0] = *(int *)data
;
97 static void emit_vec8(GLcontext
* ctx
,
98 struct r300_dma_region
*rvb
,
99 char *data
, int stride
, int count
)
102 int *out
= (int *)(rvb
->address
+ rvb
->start
);
104 if (RADEON_DEBUG
& DEBUG_VERTS
)
105 fprintf(stderr
, "%s count %d stride %d\n",
106 __FUNCTION__
, count
, stride
);
109 COPY_DWORDS(out
, data
, count
* 2);
111 for (i
= 0; i
< count
; i
++) {
112 out
[0] = *(int *)data
;
113 out
[1] = *(int *)(data
+ 4);
119 static void emit_vec12(GLcontext
* ctx
,
120 struct r300_dma_region
*rvb
,
121 char *data
, int stride
, int count
)
124 int *out
= (int *)(rvb
->address
+ rvb
->start
);
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
);
131 COPY_DWORDS(out
, data
, count
* 3);
133 for (i
= 0; i
< count
; i
++) {
134 out
[0] = *(int *)data
;
135 out
[1] = *(int *)(data
+ 4);
136 out
[2] = *(int *)(data
+ 8);
142 static void emit_vec16(GLcontext
* ctx
,
143 struct r300_dma_region
*rvb
,
144 char *data
, int stride
, int count
)
147 int *out
= (int *)(rvb
->address
+ rvb
->start
);
149 if (RADEON_DEBUG
& DEBUG_VERTS
)
150 fprintf(stderr
, "%s count %d stride %d\n",
151 __FUNCTION__
, count
, stride
);
154 COPY_DWORDS(out
, data
, count
* 4);
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);
166 static void emit_vector(GLcontext
* ctx
,
167 struct r300_dma_region
*rvb
,
168 char *data
, int size
, int stride
, int count
)
170 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
172 if (RADEON_DEBUG
& DEBUG_VERTS
)
173 fprintf(stderr
, "%s count %d size %d stride %d\n",
174 __FUNCTION__
, count
, size
, stride
);
179 r300AllocDmaRegion(rmesa
, rvb
, size
* 4, 4);
181 rvb
->aos_offset
= GET_START(rvb
);
183 rvb
->aos_size
= size
;
185 r300AllocDmaRegion(rmesa
, rvb
, size
* count
* 4, 4); /* alignment? */
186 rvb
->aos_offset
= GET_START(rvb
);
187 rvb
->aos_stride
= size
;
188 rvb
->aos_size
= size
;
195 emit_vec4(ctx
, rvb
, data
, stride
, count
);
198 emit_vec8(ctx
, rvb
, data
, stride
, count
);
201 emit_vec12(ctx
, rvb
, data
, stride
, count
);
204 emit_vec16(ctx
, rvb
, data
, stride
, count
);
214 void r300EmitElts(GLcontext
* ctx
, GLuint
*elts
, unsigned long n_elts
)
216 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
217 struct r300_dma_region
*rvb
=&rmesa
->state
.elt_dma
;
218 unsigned short int *out
;
221 r300AllocDmaRegion(rmesa
, rvb
, (n_elts
+1)*2 , 0x20);
223 out
= (unsigned short int *)(rvb
->address
+ rvb
->start
);
225 for(i
=0; i
< n_elts
; i
++)
226 out
[i
]=(unsigned short int)elts
[i
];
232 /* Emit vertex data to GART memory (unless immediate mode)
233 * Route inputs to the vertex processor
235 void r300EmitArrays(GLcontext
* ctx
, GLboolean immd
)
237 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
238 r300ContextPtr r300
= rmesa
;
239 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
241 GLuint count
= VB
->Count
;
243 GLuint vic_1
= 0; /* R300_VAP_INPUT_CNTL_1 */
244 GLuint aa_vap_reg
= 0; /* VAP register assignment */
249 #define CONFIGURE_AOS(r, f, v, sz, cn) { \
250 if (RADEON_DEBUG & DEBUG_STATE) \
251 fprintf(stderr, "Enabling "#v "\n"); \
252 if (++nr >= R300_MAX_AOS_ARRAYS) { \
253 fprintf(stderr, "Aieee! AOS array count exceeded!\n"); \
257 if (rmesa->current_vp == NULL) \
258 rmesa->state.aos[nr-1].aos_reg = aa_vap_reg++; \
259 rmesa->state.aos[nr-1].aos_format = f; \
261 rmesa->state.aos[nr-1].aos_size = 4; \
262 rmesa->state.aos[nr-1].aos_stride = 4; \
263 rmesa->state.aos[nr-1].aos_offset = 0; \
266 &rmesa->state.aos[nr-1], \
271 rmesa->state.vap_reg.r=rmesa->state.aos[nr-1].aos_reg; \
275 if (rmesa
->current_vp
!= NULL
) {
276 if (rmesa
->current_vp
->inputs
[VERT_ATTRIB_POS
] != -1) {
277 inputs
|= _TNL_BIT_POS
;
278 rmesa
->state
.aos
[nr
++].aos_reg
= rmesa
->current_vp
->inputs
[VERT_ATTRIB_POS
];
280 if (rmesa
->current_vp
->inputs
[VERT_ATTRIB_NORMAL
] != -1) {
281 inputs
|= _TNL_BIT_NORMAL
;
282 rmesa
->state
.aos
[nr
++].aos_reg
= rmesa
->current_vp
->inputs
[VERT_ATTRIB_NORMAL
];
284 if (rmesa
->current_vp
->inputs
[VERT_ATTRIB_COLOR0
] != -1) {
285 inputs
|= _TNL_BIT_COLOR0
;
286 rmesa
->state
.aos
[nr
++].aos_reg
= rmesa
->current_vp
->inputs
[VERT_ATTRIB_COLOR0
];
288 if (rmesa
->current_vp
->inputs
[VERT_ATTRIB_COLOR1
] != -1) {
289 inputs
|= _TNL_BIT_COLOR1
;
290 rmesa
->state
.aos
[nr
++].aos_reg
= rmesa
->current_vp
->inputs
[VERT_ATTRIB_COLOR1
];
292 if (rmesa
->current_vp
->inputs
[VERT_ATTRIB_FOG
] != -1) {
293 inputs
|= _TNL_BIT_FOG
;
294 rmesa
->state
.aos
[nr
++].aos_reg
= rmesa
->current_vp
->inputs
[VERT_ATTRIB_FOG
];
296 if(ctx
->Const
.MaxTextureUnits
> 8) { /* Not sure if this can even happen... */
297 fprintf(stderr
, "%s: Cant handle that many inputs\n", __FUNCTION__
);
300 for (i
=0;i
<ctx
->Const
.MaxTextureUnits
;i
++) {
301 if (rmesa
->current_vp
->inputs
[VERT_ATTRIB_TEX0
+i
] != -1) {
302 inputs
|= _TNL_BIT_TEX0
<<i
;
303 rmesa
->state
.aos
[nr
++].aos_reg
= rmesa
->current_vp
->inputs
[VERT_ATTRIB_TEX0
+i
];
308 inputs
= TNL_CONTEXT(ctx
)->render_inputs
;
310 rmesa
->state
.render_inputs
= inputs
;
312 if (inputs
& _TNL_BIT_POS
) {
313 CONFIGURE_AOS(i_coords
, AOS_FORMAT_FLOAT
,
315 immd
? 4 : VB
->ObjPtr
->size
,
318 vic_1
|= R300_INPUT_CNTL_POS
;
321 if (inputs
& _TNL_BIT_NORMAL
) {
322 CONFIGURE_AOS(i_normal
, AOS_FORMAT_FLOAT
,
324 immd
? 4 : VB
->NormalPtr
->size
,
327 vic_1
|= R300_INPUT_CNTL_NORMAL
;
330 if (inputs
& _TNL_BIT_COLOR0
) {
334 if (VB
->ColorPtr
[0]->size
== 4 &&
335 (VB
->ColorPtr
[0]->stride
!= 0 ||
336 VB
->ColorPtr
[0]->data
[0][3] != 1.0)) {
343 CONFIGURE_AOS(i_color
[0], AOS_FORMAT_FLOAT_COLOR
,
348 vic_1
|= R300_INPUT_CNTL_COLOR
;
351 if (inputs
& _TNL_BIT_COLOR1
) {
352 CONFIGURE_AOS(i_color
[1], AOS_FORMAT_FLOAT_COLOR
,
353 VB
->SecondaryColorPtr
[0],
354 immd
? 4 : VB
->SecondaryColorPtr
[0]->size
,
359 if (inputs
& _TNL_BIT_FOG
) {
360 CONFIGURE_AOS( AOS_FORMAT_FLOAT
,
362 immd
? 4 : VB
->FogCoordPtr
->size
,
367 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
368 if (inputs
& (_TNL_BIT_TEX0
<< i
)) {
369 CONFIGURE_AOS(i_tex
[i
], AOS_FORMAT_FLOAT
,
371 immd
? 4 : VB
->TexCoordPtr
[i
]->size
,
374 vic_1
|= R300_INPUT_CNTL_TC0
<< i
;
381 drm_radeon_cmd_header_t
*cmd
= NULL
;
383 #define SHOW_INFO(n) do { \
384 if (RADEON_DEBUG & DEBUG_ALL) { \
385 fprintf(stderr, "RR[%d] - sz=%d, reg=%d, fmt=%d -- st=%d, of=0x%08x\n", \
387 r300->state.aos[n].aos_size, \
388 r300->state.aos[n].aos_reg, \
389 r300->state.aos[n].aos_format, \
390 r300->state.aos[n].aos_stride, \
391 r300->state.aos[n].aos_offset); \
395 /* setup INPUT_ROUTE */
396 R300_STATECHANGE(r300
, vir
[0]);
397 for(i
=0;i
+1<nr
;i
+=2){
400 dw
=(r300
->state
.aos
[i
].aos_size
-1)
401 | ((r300
->state
.aos
[i
].aos_reg
)<<8)
402 | (r300
->state
.aos
[i
].aos_format
<<14)
403 | (((r300
->state
.aos
[i
+1].aos_size
-1)
404 | ((r300
->state
.aos
[i
+1].aos_reg
)<<8)
405 | (r300
->state
.aos
[i
+1].aos_format
<<14))<<16);
410 r300
->hw
.vir
[0].cmd
[R300_VIR_CNTL_0
+(i
>>1)]=dw
;
414 dw
=(r300
->state
.aos
[nr
-1].aos_size
-1)
415 | (r300
->state
.aos
[nr
-1].aos_format
<<14)
416 | ((r300
->state
.aos
[nr
-1].aos_reg
)<<8)
418 r300
->hw
.vir
[0].cmd
[R300_VIR_CNTL_0
+(nr
>>1)]=dw
;
419 //fprintf(stderr, "vir0 dw=%08x\n", dw);
421 /* Set the rest of INPUT_ROUTE_0 to 0 */
422 //for(i=((count+1)>>1); i<8; i++)r300->hw.vir[0].cmd[R300_VIR_CNTL_0+i]=(0x0);
423 ((drm_r300_cmd_header_t
*)r300
->hw
.vir
[0].cmd
)->unchecked_state
.count
= (nr
+1)>>1;
426 /* Mesa assumes that all missing components are from (0, 0, 0, 1) */
427 #define ALL_COMPONENTS ((R300_INPUT_ROUTE_SELECT_X<<R300_INPUT_ROUTE_X_SHIFT) \
428 | (R300_INPUT_ROUTE_SELECT_Y<<R300_INPUT_ROUTE_Y_SHIFT) \
429 | (R300_INPUT_ROUTE_SELECT_Z<<R300_INPUT_ROUTE_Z_SHIFT) \
430 | (R300_INPUT_ROUTE_SELECT_W<<R300_INPUT_ROUTE_W_SHIFT))
432 #define ALL_DEFAULT ((R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_X_SHIFT) \
433 | (R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_Y_SHIFT) \
434 | (R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_Z_SHIFT) \
435 | (R300_INPUT_ROUTE_SELECT_ONE<<R300_INPUT_ROUTE_W_SHIFT))
437 R300_STATECHANGE(r300
, vir
[1]);
439 for(i
=0;i
+1<nr
;i
+=2){
441 mask
=(1<<(r300
->state
.aos
[i
].aos_size
*3))-1;
442 dw
=(ALL_COMPONENTS
& mask
)
443 | (ALL_DEFAULT
& ~mask
)
444 | R300_INPUT_ROUTE_ENABLE
;
447 mask
=(1<<(r300
->state
.aos
[i
+1].aos_size
*3))-1;
449 (ALL_COMPONENTS
& mask
)
450 | (ALL_DEFAULT
& ~mask
)
451 | R300_INPUT_ROUTE_ENABLE
454 r300
->hw
.vir
[1].cmd
[R300_VIR_CNTL_0
+(i
>>1)]=dw
;
457 mask
=(1<<(r300
->state
.aos
[nr
-1].aos_size
*3))-1;
458 dw
=(ALL_COMPONENTS
& mask
)
459 | (ALL_DEFAULT
& ~mask
)
460 | R300_INPUT_ROUTE_ENABLE
;
461 r300
->hw
.vir
[1].cmd
[R300_VIR_CNTL_0
+(nr
>>1)]=dw
;
462 //fprintf(stderr, "vir1 dw=%08x\n", dw);
464 /* Set the rest of INPUT_ROUTE_1 to 0 */
465 //for(i=((count+1)>>1); i<8; i++)r300->hw.vir[1].cmd[R300_VIR_CNTL_0+i]=0x0;
466 ((drm_r300_cmd_header_t
*)r300
->hw
.vir
[1].cmd
)->unchecked_state
.count
= (nr
+1)>>1;
468 /* Set up input_cntl */
469 /* I don't think this is needed for vertex buffers, but it doesn't hurt anything */
470 R300_STATECHANGE(r300
, vic
);
471 r300
->hw
.vic
.cmd
[R300_VIC_CNTL_0
]=0x5555; /* Hard coded value, no idea what it means */
472 r300
->hw
.vic
.cmd
[R300_VIC_CNTL_1
]=vic_1
;
475 r300
->hw
.vic
.cmd
[R300_VIC_CNTL_1
]=0;
477 if(r300
->state
.render_inputs
& _TNL_BIT_POS
)
478 r300
->hw
.vic
.cmd
[R300_VIC_CNTL_1
]|=R300_INPUT_CNTL_POS
;
480 if(r300
->state
.render_inputs
& _TNL_BIT_NORMAL
)
481 r300
->hw
.vic
.cmd
[R300_VIC_CNTL_1
]|=R300_INPUT_CNTL_NORMAL
;
483 if(r300
->state
.render_inputs
& _TNL_BIT_COLOR0
)
484 r300
->hw
.vic
.cmd
[R300_VIC_CNTL_1
]|=R300_INPUT_CNTL_COLOR
;
486 for(i
=0;i
< ctx
->Const
.MaxTextureUnits
;i
++)
487 if(r300
->state
.render_inputs
& (_TNL_BIT_TEX0
<<i
))
488 r300
->hw
.vic
.cmd
[R300_VIC_CNTL_1
]|=(R300_INPUT_CNTL_TC0
<<i
);
491 /* Stage 3: VAP output */
492 R300_STATECHANGE(r300
, vof
);
493 r300
->hw
.vof
.cmd
[R300_VOF_CNTL_0
]=R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
494 | R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT
;
496 r300
->hw
.vof
.cmd
[R300_VOF_CNTL_1
]=0;
497 for(i
=0;i
< ctx
->Const
.MaxTextureUnits
;i
++)
498 if(r300
->state
.render_inputs
& (_TNL_BIT_TEX0
<<i
))
499 r300
->hw
.vof
.cmd
[R300_VOF_CNTL_1
]|=(4<<(3*i
));
501 rmesa
->state
.aos_count
= nr
;
504 void r300ReleaseArrays(GLcontext
* ctx
)
506 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
509 r300ReleaseDmaRegion(rmesa
, &rmesa
->state
.elt_dma
, __FUNCTION__
);
510 for (i
=0;i
<rmesa
->state
.aos_count
;i
++) {
511 r300ReleaseDmaRegion(rmesa
, &rmesa
->state
.aos
[i
], __FUNCTION__
);