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 GLvoid
*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 GLvoid
*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 GLvoid
*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 GLvoid
*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 GLvoid
*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
);
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
);
184 rvb
->aos_stride
= stride
/ 4;
186 rvb
->aos_size
= size
;
190 /* Gets triggered when playing with future_hw_tcl_on ...*/
194 r300AllocDmaRegion(rmesa
, rvb
, size
* 4, 4);
196 rvb
->aos_offset
= GET_START(rvb
);
198 rvb
->aos_size
= size
;
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
;
210 emit_vec4(ctx
, rvb
, data
, stride
, count
);
213 emit_vec8(ctx
, rvb
, data
, stride
, count
);
216 emit_vec12(ctx
, rvb
, data
, stride
, count
);
219 emit_vec16(ctx
, rvb
, data
, stride
, count
);
229 void r300EmitElts(GLcontext
* ctx
, GLuint
*elts
, unsigned long n_elts
)
231 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
232 struct r300_dma_region
*rvb
=&rmesa
->state
.elt_dma
;
233 unsigned short int *out
;
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
;
243 r300AllocDmaRegion(rmesa
, rvb
, n_elts
*sizeof(unsigned short int), 2);
245 out
= (unsigned short int *)(rvb
->address
+ rvb
->start
);
247 for(i
=0; i
< n_elts
; i
++)
248 out
[i
]=(unsigned short int)elts
[i
];
251 /* Emit vertex data to GART memory (unless immediate mode)
252 * Route inputs to the vertex processor
254 void r300EmitArrays(GLcontext
* ctx
, GLboolean immd
)
256 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
257 r300ContextPtr r300
= rmesa
;
258 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
260 GLuint count
= VB
->Count
;
262 GLuint vic_1
= 0; /* R300_VAP_INPUT_CNTL_1 */
263 GLuint aa_vap_reg
= 0; /* VAP register assignment */
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"); \
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; \
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; \
285 &rmesa->state.aos[nr-1], \
290 rmesa->state.vap_reg.r=rmesa->state.aos[nr-1].aos_reg; \
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
];
301 if (InputsRead
& (1<<VERT_ATTRIB_NORMAL
)) {
302 inputs
|= _TNL_BIT_NORMAL
;
303 rmesa
->state
.aos
[nr
++].aos_reg
= prog
->inputs
[VERT_ATTRIB_NORMAL
];
305 if (InputsRead
& (1<<VERT_ATTRIB_COLOR0
)) {
306 inputs
|= _TNL_BIT_COLOR0
;
307 rmesa
->state
.aos
[nr
++].aos_reg
= prog
->inputs
[VERT_ATTRIB_COLOR0
];
309 if (InputsRead
& (1<<VERT_ATTRIB_COLOR1
)) {
310 inputs
|= _TNL_BIT_COLOR1
;
311 rmesa
->state
.aos
[nr
++].aos_reg
= prog
->inputs
[VERT_ATTRIB_COLOR1
];
313 if (InputsRead
& (1<<VERT_ATTRIB_FOG
)) {
314 inputs
|= _TNL_BIT_FOG
;
315 rmesa
->state
.aos
[nr
++].aos_reg
= prog
->inputs
[VERT_ATTRIB_FOG
];
317 if(ctx
->Const
.MaxTextureUnits
> 8) { /* Not sure if this can even happen... */
318 fprintf(stderr
, "%s: Cant handle that many inputs\n", __FUNCTION__
);
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
];
329 inputs
= TNL_CONTEXT(ctx
)->render_inputs
;
331 rmesa
->state
.render_inputs
= inputs
;
333 if (inputs
& _TNL_BIT_POS
) {
334 CONFIGURE_AOS(i_coords
, AOS_FORMAT_FLOAT
,
336 immd
? 4 : VB
->ObjPtr
->size
,
339 vic_1
|= R300_INPUT_CNTL_POS
;
342 if (inputs
& _TNL_BIT_NORMAL
) {
343 CONFIGURE_AOS(i_normal
, AOS_FORMAT_FLOAT
,
345 immd
? 4 : VB
->NormalPtr
->size
,
348 vic_1
|= R300_INPUT_CNTL_NORMAL
;
351 if (inputs
& _TNL_BIT_COLOR0
) {
355 if (VB
->ColorPtr
[0]->size
== 4 &&
356 (VB
->ColorPtr
[0]->stride
!= 0 ||
357 VB
->ColorPtr
[0]->data
[0][3] != 1.0)) {
364 CONFIGURE_AOS(i_color
[0], AOS_FORMAT_FLOAT_COLOR
,
369 vic_1
|= R300_INPUT_CNTL_COLOR
;
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
,
380 if (inputs
& _TNL_BIT_FOG
) {
381 CONFIGURE_AOS( AOS_FORMAT_FLOAT
,
383 immd
? 4 : VB
->FogCoordPtr
->size
,
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
,
393 immd
? 4 : VB
->TexCoordPtr
[i
]->size
,
396 vic_1
|= R300_INPUT_CNTL_TC0
<< i
;
397 r300
->state
.texture
.tc_count
++;
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", \
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); \
413 /* setup INPUT_ROUTE */
414 R300_STATECHANGE(r300
, vir
[0]);
415 for(i
=0;i
+1<nr
;i
+=2){
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);
428 r300
->hw
.vir
[0].cmd
[R300_VIR_CNTL_0
+(i
>>1)]=dw
;
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)
436 r300
->hw
.vir
[0].cmd
[R300_VIR_CNTL_0
+(nr
>>1)]=dw
;
437 //fprintf(stderr, "vir0 dw=%08x\n", dw);
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;
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))
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))
455 R300_STATECHANGE(r300
, vir
[1]);
457 for(i
=0;i
+1<nr
;i
+=2){
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
;
465 mask
=(1<<(r300
->state
.aos
[i
+1].aos_size
*3))-1;
467 (ALL_COMPONENTS
& mask
)
468 | (ALL_DEFAULT
& ~mask
)
469 | R300_INPUT_ROUTE_ENABLE
472 r300
->hw
.vir
[1].cmd
[R300_VIR_CNTL_0
+(i
>>1)]=dw
;
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);
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;
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
;
493 r300
->hw
.vic
.cmd
[R300_VIC_CNTL_1
]=0;
495 if(r300
->state
.render_inputs
& _TNL_BIT_POS
)
496 r300
->hw
.vic
.cmd
[R300_VIC_CNTL_1
]|=R300_INPUT_CNTL_POS
;
498 if(r300
->state
.render_inputs
& _TNL_BIT_NORMAL
)
499 r300
->hw
.vic
.cmd
[R300_VIC_CNTL_1
]|=R300_INPUT_CNTL_NORMAL
;
501 if(r300
->state
.render_inputs
& _TNL_BIT_COLOR0
)
502 r300
->hw
.vic
.cmd
[R300_VIC_CNTL_1
]|=R300_INPUT_CNTL_COLOR
;
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
);
509 /* Stage 3: VAP output */
511 R300_STATECHANGE(r300
, vof
);
513 r300
->hw
.vof
.cmd
[R300_VOF_CNTL_0
]=0;
514 r300
->hw
.vof
.cmd
[R300_VOF_CNTL_1
]=0;
516 GLuint OutputsWritten
= CURRENT_VERTEX_SHADER(ctx
)->OutputsWritten
;
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))
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
;
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
));
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
;
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
));
549 rmesa
->state
.aos_count
= nr
;
552 void r300ReleaseArrays(GLcontext
* ctx
)
554 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
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__
);