2 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
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.
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:
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.
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.
28 **************************************************************************/
33 * \author Keith Whitwell <keith@tungstengraphics.com>
36 #include "main/glheader.h"
37 #include "main/mtypes.h"
38 #include "main/colormac.h"
39 #include "main/imports.h"
40 #include "main/macros.h"
41 #include "main/image.h"
43 #include "swrast_setup/swrast_setup.h"
44 #include "math/m_translate.h"
46 #include "tnl/t_context.h"
48 #include "r300_context.h"
49 #include "radeon_ioctl.h"
50 #include "r300_state.h"
51 #include "r300_emit.h"
52 #include "r300_ioctl.h"
58 #if SWIZZLE_X != R300_INPUT_ROUTE_SELECT_X || \
59 SWIZZLE_Y != R300_INPUT_ROUTE_SELECT_Y || \
60 SWIZZLE_Z != R300_INPUT_ROUTE_SELECT_Z || \
61 SWIZZLE_W != R300_INPUT_ROUTE_SELECT_W || \
62 SWIZZLE_ZERO != R300_INPUT_ROUTE_SELECT_ZERO || \
63 SWIZZLE_ONE != R300_INPUT_ROUTE_SELECT_ONE
64 #error Cannot change these!
67 #define DEBUG_ALL DEBUG_VERTS
69 #if defined(USE_X86_ASM)
70 #define COPY_DWORDS( dst, src, nr ) \
73 __asm__ __volatile__( "rep ; movsl" \
74 : "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \
80 #define COPY_DWORDS( dst, src, nr ) \
83 for ( j = 0 ; j < nr ; j++ ) \
84 dst[j] = ((int *)src)[j]; \
89 static void r300EmitVec4(GLcontext
* ctx
, struct r300_dma_region
*rvb
,
90 GLvoid
* data
, int stride
, int count
)
93 int *out
= (int *)(rvb
->address
+ rvb
->start
);
95 if (RADEON_DEBUG
& DEBUG_VERTS
)
96 fprintf(stderr
, "%s count %d stride %d out %p data %p\n",
97 __FUNCTION__
, count
, stride
, (void *)out
, (void *)data
);
100 COPY_DWORDS(out
, data
, count
);
102 for (i
= 0; i
< count
; i
++) {
103 out
[0] = *(int *)data
;
109 static void r300EmitVec8(GLcontext
* ctx
, struct r300_dma_region
*rvb
,
110 GLvoid
* data
, int stride
, int count
)
113 int *out
= (int *)(rvb
->address
+ rvb
->start
);
115 if (RADEON_DEBUG
& DEBUG_VERTS
)
116 fprintf(stderr
, "%s count %d stride %d out %p data %p\n",
117 __FUNCTION__
, count
, stride
, (void *)out
, (void *)data
);
120 COPY_DWORDS(out
, data
, count
* 2);
122 for (i
= 0; i
< count
; i
++) {
123 out
[0] = *(int *)data
;
124 out
[1] = *(int *)(data
+ 4);
130 static void r300EmitVec12(GLcontext
* ctx
, struct r300_dma_region
*rvb
,
131 GLvoid
* data
, int stride
, int count
)
134 int *out
= (int *)(rvb
->address
+ rvb
->start
);
136 if (RADEON_DEBUG
& DEBUG_VERTS
)
137 fprintf(stderr
, "%s count %d stride %d out %p data %p\n",
138 __FUNCTION__
, count
, stride
, (void *)out
, (void *)data
);
141 COPY_DWORDS(out
, data
, count
* 3);
143 for (i
= 0; i
< count
; i
++) {
144 out
[0] = *(int *)data
;
145 out
[1] = *(int *)(data
+ 4);
146 out
[2] = *(int *)(data
+ 8);
152 static void r300EmitVec16(GLcontext
* ctx
, struct r300_dma_region
*rvb
,
153 GLvoid
* data
, int stride
, int count
)
156 int *out
= (int *)(rvb
->address
+ rvb
->start
);
158 if (RADEON_DEBUG
& DEBUG_VERTS
)
159 fprintf(stderr
, "%s count %d stride %d out %p data %p\n",
160 __FUNCTION__
, count
, stride
, (void *)out
, (void *)data
);
163 COPY_DWORDS(out
, data
, count
* 4);
165 for (i
= 0; i
< count
; i
++) {
166 out
[0] = *(int *)data
;
167 out
[1] = *(int *)(data
+ 4);
168 out
[2] = *(int *)(data
+ 8);
169 out
[3] = *(int *)(data
+ 12);
175 static void r300EmitVec(GLcontext
* ctx
, struct r300_dma_region
*rvb
,
176 GLvoid
* data
, int size
, int stride
, int count
)
178 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
181 r300AllocDmaRegion(rmesa
, rvb
, size
* 4, 4);
183 rvb
->aos_offset
= GET_START(rvb
);
186 r300AllocDmaRegion(rmesa
, rvb
, size
* count
* 4, 4);
187 rvb
->aos_offset
= GET_START(rvb
);
188 rvb
->aos_stride
= size
;
193 r300EmitVec4(ctx
, rvb
, data
, stride
, count
);
196 r300EmitVec8(ctx
, rvb
, data
, stride
, count
);
199 r300EmitVec12(ctx
, rvb
, data
, stride
, count
);
202 r300EmitVec16(ctx
, rvb
, data
, stride
, count
);
210 #define DW_SIZE(x) ((inputs[tab[(x)]] << R300_DST_VEC_LOC_SHIFT) | \
211 (attribptr[tab[(x)]]->size - 1) << R300_DATA_TYPE_0_SHIFT)
213 GLuint
r300VAPInputRoute0(uint32_t * dst
, GLvector4f
** attribptr
,
214 int *inputs
, GLint
* tab
, GLuint nr
)
218 /* type, inputs, stop bit, size */
219 for (i
= 0; i
< nr
; i
+= 2) {
220 /* make sure input is valid, would lockup the gpu */
221 assert(inputs
[tab
[i
]] != -1);
222 dw
= (R300_SIGNED
| DW_SIZE(i
));
224 dw
|= R300_LAST_VEC
<< R300_DATA_TYPE_0_SHIFT
;
226 assert(inputs
[tab
[i
+ 1]] != -1);
228 DW_SIZE(i
+ 1)) << R300_DATA_TYPE_1_SHIFT
;
230 dw
|= R300_LAST_VEC
<< R300_DATA_TYPE_1_SHIFT
;
236 return (nr
+ 1) >> 1;
239 static GLuint
r300VAPInputRoute1Swizzle(int swizzle
[4])
241 return (swizzle
[0] << R300_SWIZZLE_SELECT_X_SHIFT
) |
242 (swizzle
[1] << R300_SWIZZLE_SELECT_Y_SHIFT
) |
243 (swizzle
[2] << R300_SWIZZLE_SELECT_Z_SHIFT
) |
244 (swizzle
[3] << R300_SWIZZLE_SELECT_W_SHIFT
);
247 GLuint
r300VAPInputRoute1(uint32_t * dst
, int swizzle
[][4], GLuint nr
)
251 for (i
= 0; i
< nr
; i
+= 2) {
252 dw
= (r300VAPInputRoute1Swizzle(swizzle
[i
]) |
253 ((R300_WRITE_ENA_X
| R300_WRITE_ENA_Y
|
254 R300_WRITE_ENA_Z
| R300_WRITE_ENA_W
) << R300_WRITE_ENA_SHIFT
)) << R300_SWIZZLE0_SHIFT
;
256 dw
|= (r300VAPInputRoute1Swizzle(swizzle
[i
+ 1]) |
257 ((R300_WRITE_ENA_X
| R300_WRITE_ENA_Y
|
258 R300_WRITE_ENA_Z
| R300_WRITE_ENA_W
) << R300_WRITE_ENA_SHIFT
)) << R300_SWIZZLE1_SHIFT
;
263 return (nr
+ 1) >> 1;
266 GLuint
r300VAPInputCntl0(GLcontext
* ctx
, GLuint InputsRead
)
268 /* No idea what this value means. I have seen other values written to
269 * this register... */
273 GLuint
r300VAPInputCntl1(GLcontext
* ctx
, GLuint InputsRead
)
275 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
278 if (InputsRead
& (1 << VERT_ATTRIB_POS
))
279 vic_1
|= R300_INPUT_CNTL_POS
;
281 if (InputsRead
& (1 << VERT_ATTRIB_NORMAL
))
282 vic_1
|= R300_INPUT_CNTL_NORMAL
;
284 if (InputsRead
& (1 << VERT_ATTRIB_COLOR0
))
285 vic_1
|= R300_INPUT_CNTL_COLOR
;
287 rmesa
->state
.texture
.tc_count
= 0;
288 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++)
289 if (InputsRead
& (1 << (VERT_ATTRIB_TEX0
+ i
))) {
290 rmesa
->state
.texture
.tc_count
++;
291 vic_1
|= R300_INPUT_CNTL_TC0
<< i
;
297 GLuint
r300VAPOutputCntl0(GLcontext
* ctx
, GLuint OutputsWritten
)
301 if (OutputsWritten
& (1 << VERT_RESULT_HPOS
))
302 ret
|= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
;
304 if (OutputsWritten
& (1 << VERT_RESULT_COL0
))
305 ret
|= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT
;
307 if (OutputsWritten
& (1 << VERT_RESULT_COL1
))
308 ret
|= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT
;
310 if (OutputsWritten
& (1 << VERT_RESULT_BFC0
)
311 || OutputsWritten
& (1 << VERT_RESULT_BFC1
))
313 R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT
|
314 R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT
|
315 R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT
;
318 if (OutputsWritten
& (1 << VERT_RESULT_FOGC
)) ;
321 if (OutputsWritten
& (1 << VERT_RESULT_PSIZ
))
322 ret
|= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT
;
327 GLuint
r300VAPOutputCntl1(GLcontext
* ctx
, GLuint OutputsWritten
)
331 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
332 if (OutputsWritten
& (1 << (VERT_RESULT_TEX0
+ i
))) {
333 ret
|= (4 << (3 * i
));
340 /* Emit vertex data to GART memory
341 * Route inputs to the vertex processor
342 * This function should never return R300_FALLBACK_TCL when using software tcl.
344 int r300EmitArrays(GLcontext
* ctx
)
346 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
347 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
348 struct vertex_buffer
*vb
= &tnl
->vb
;
350 GLuint count
= vb
->Count
;
352 GLuint InputsRead
= 0, OutputsWritten
= 0;
354 int vir_inputs
[VERT_ATTRIB_MAX
];
355 GLint tab
[VERT_ATTRIB_MAX
];
356 int swizzle
[VERT_ATTRIB_MAX
][4];
357 struct r300_vertex_program
*prog
=
358 (struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
);
361 inputs
= prog
->inputs
;
362 InputsRead
= prog
->key
.InputsRead
;
363 OutputsWritten
= prog
->key
.OutputsWritten
;
365 inputs
= rmesa
->state
.sw_tcl_inputs
;
367 DECLARE_RENDERINPUTS(render_inputs_bitset
);
368 RENDERINPUTS_COPY(render_inputs_bitset
, tnl
->render_inputs_bitset
);
370 vb
->AttribPtr
[VERT_ATTRIB_POS
] = vb
->ClipPtr
;
372 assert(RENDERINPUTS_TEST(render_inputs_bitset
, _TNL_ATTRIB_POS
));
373 assert(RENDERINPUTS_TEST(render_inputs_bitset
, _TNL_ATTRIB_NORMAL
) == 0);
374 //assert(RENDERINPUTS_TEST(render_inputs_bitset, _TNL_ATTRIB_COLOR0));
376 if (RENDERINPUTS_TEST(render_inputs_bitset
, _TNL_ATTRIB_POS
)) {
377 InputsRead
|= 1 << VERT_ATTRIB_POS
;
378 OutputsWritten
|= 1 << VERT_RESULT_HPOS
;
381 if (RENDERINPUTS_TEST(render_inputs_bitset
, _TNL_ATTRIB_COLOR0
)) {
382 InputsRead
|= 1 << VERT_ATTRIB_COLOR0
;
383 OutputsWritten
|= 1 << VERT_RESULT_COL0
;
386 if (RENDERINPUTS_TEST(render_inputs_bitset
, _TNL_ATTRIB_COLOR1
)) {
387 InputsRead
|= 1 << VERT_ATTRIB_COLOR1
;
388 OutputsWritten
|= 1 << VERT_RESULT_COL1
;
391 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
392 if (RENDERINPUTS_TEST(render_inputs_bitset
, _TNL_ATTRIB_TEX(i
))) {
393 InputsRead
|= 1 << (VERT_ATTRIB_TEX0
+ i
);
394 OutputsWritten
|= 1 << (VERT_RESULT_TEX0
+ i
);
398 for (i
= 0, nr
= 0; i
< VERT_ATTRIB_MAX
; i
++) {
399 if (InputsRead
& (1 << i
)) {
406 /* Fixed, apply to vir0 only */
407 memcpy(vir_inputs
, inputs
, VERT_ATTRIB_MAX
* sizeof(int));
409 if (InputsRead
& VERT_ATTRIB_POS
)
410 inputs
[VERT_ATTRIB_POS
] = 0;
411 if (InputsRead
& (1 << VERT_ATTRIB_COLOR0
))
412 inputs
[VERT_ATTRIB_COLOR0
] = 2;
413 if (InputsRead
& (1 << VERT_ATTRIB_COLOR1
))
414 inputs
[VERT_ATTRIB_COLOR1
] = 3;
415 for (i
= VERT_ATTRIB_TEX0
; i
<= VERT_ATTRIB_TEX7
; i
++)
416 if (InputsRead
& (1 << i
))
417 inputs
[i
] = 6 + (i
- VERT_ATTRIB_TEX0
);
419 RENDERINPUTS_COPY(rmesa
->state
.render_inputs_bitset
, render_inputs_bitset
);
423 assert(OutputsWritten
);
425 for (i
= 0, nr
= 0; i
< VERT_ATTRIB_MAX
; i
++) {
426 if (InputsRead
& (1 << i
)) {
431 if (nr
> R300_MAX_AOS_ARRAYS
) {
432 return R300_FALLBACK_TCL
;
435 for (i
= 0; i
< nr
; i
++) {
436 int ci
, fix
, found
= 0;
438 swizzle
[i
][0] = SWIZZLE_ZERO
;
439 swizzle
[i
][1] = SWIZZLE_ZERO
;
440 swizzle
[i
][2] = SWIZZLE_ZERO
;
441 swizzle
[i
][3] = SWIZZLE_ONE
;
443 for (ci
= 0; ci
< vb
->AttribPtr
[tab
[i
]]->size
; ci
++) {
447 if (r300IsGartMemory(rmesa
, vb
->AttribPtr
[tab
[i
]]->data
, 4)) {
448 if (vb
->AttribPtr
[tab
[i
]]->stride
% 4) {
449 return R300_FALLBACK_TCL
;
451 rmesa
->state
.aos
[i
].address
= (void *)(vb
->AttribPtr
[tab
[i
]]->data
);
452 rmesa
->state
.aos
[i
].start
= 0;
453 rmesa
->state
.aos
[i
].aos_offset
= r300GartOffsetFromVirtual(rmesa
, vb
->AttribPtr
[tab
[i
]]->data
);
454 rmesa
->state
.aos
[i
].aos_stride
= vb
->AttribPtr
[tab
[i
]]->stride
/ 4;
455 rmesa
->state
.aos
[i
].aos_size
= vb
->AttribPtr
[tab
[i
]]->size
;
457 r300EmitVec(ctx
, &rmesa
->state
.aos
[i
],
458 vb
->AttribPtr
[tab
[i
]]->data
,
459 vb
->AttribPtr
[tab
[i
]]->size
,
460 vb
->AttribPtr
[tab
[i
]]->stride
, count
);
463 rmesa
->state
.aos
[i
].aos_size
= vb
->AttribPtr
[tab
[i
]]->size
;
465 for (fix
= 0; fix
<= 4 - vb
->AttribPtr
[tab
[i
]]->size
; fix
++) {
466 if ((rmesa
->state
.aos
[i
].aos_offset
- _mesa_sizeof_type(GL_FLOAT
) * fix
) % 4) {
475 WARN_ONCE("Feeling lucky?\n");
477 rmesa
->state
.aos
[i
].aos_offset
-= _mesa_sizeof_type(GL_FLOAT
) * fix
;
478 for (ci
= 0; ci
< vb
->AttribPtr
[tab
[i
]]->size
; ci
++) {
479 swizzle
[i
][ci
] += fix
;
483 ("Cannot handle offset %x with stride %d, comp %d\n",
484 rmesa
->state
.aos
[i
].aos_offset
,
485 rmesa
->state
.aos
[i
].aos_stride
,
486 vb
->AttribPtr
[tab
[i
]]->size
);
487 return R300_FALLBACK_TCL
;
491 /* Setup INPUT_ROUTE. */
492 R300_STATECHANGE(rmesa
, vir
[0]);
493 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vir
[0].cmd
)->packet0
.count
=
494 r300VAPInputRoute0(&rmesa
->hw
.vir
[0].cmd
[R300_VIR_CNTL_0
],
495 vb
->AttribPtr
, inputs
, tab
, nr
);
496 R300_STATECHANGE(rmesa
, vir
[1]);
497 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vir
[1].cmd
)->packet0
.count
=
498 r300VAPInputRoute1(&rmesa
->hw
.vir
[1].cmd
[R300_VIR_CNTL_0
], swizzle
,
501 /* Setup INPUT_CNTL. */
502 R300_STATECHANGE(rmesa
, vic
);
503 rmesa
->hw
.vic
.cmd
[R300_VIC_CNTL_0
] = r300VAPInputCntl0(ctx
, InputsRead
);
504 rmesa
->hw
.vic
.cmd
[R300_VIC_CNTL_1
] = r300VAPInputCntl1(ctx
, InputsRead
);
506 /* Setup OUTPUT_VTX_FMT. */
507 R300_STATECHANGE(rmesa
, vof
);
508 rmesa
->hw
.vof
.cmd
[R300_VOF_CNTL_0
] =
509 r300VAPOutputCntl0(ctx
, OutputsWritten
);
510 rmesa
->hw
.vof
.cmd
[R300_VOF_CNTL_1
] =
511 r300VAPOutputCntl1(ctx
, OutputsWritten
);
513 rmesa
->state
.aos_count
= nr
;
515 return R300_FALLBACK_NONE
;
519 void r300UseArrays(GLcontext
* ctx
)
521 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
524 if (rmesa
->state
.elt_dma
.buf
)
525 r300_mem_use(rmesa
, rmesa
->state
.elt_dma
.buf
->id
);
527 for (i
= 0; i
< rmesa
->state
.aos_count
; i
++) {
528 if (rmesa
->state
.aos
[i
].buf
)
529 r300_mem_use(rmesa
, rmesa
->state
.aos
[i
].buf
->id
);
534 void r300ReleaseArrays(GLcontext
* ctx
)
536 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
539 r300ReleaseDmaRegion(rmesa
, &rmesa
->state
.elt_dma
, __FUNCTION__
);
540 for (i
= 0; i
< rmesa
->state
.aos_count
; i
++) {
541 r300ReleaseDmaRegion(rmesa
, &rmesa
->state
.aos
[i
], __FUNCTION__
);
545 void r300EmitCacheFlush(r300ContextPtr rmesa
)
547 int cmd_reserved
= 0;
550 drm_radeon_cmd_header_t
*cmd
= NULL
;
552 reg_start(R300_RB3D_DSTCACHE_CTLSTAT
, 0);
553 e32(R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_FREE_3D_TAGS
|
554 R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D
);
556 reg_start(R300_ZB_ZCACHE_CTLSTAT
, 0);
557 e32(R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE
|
558 R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE
);