1 /* radeon_state.c -- State support for Radeon -*- linux-c -*-
3 * Copyright 2000 VA Linux Systems, Inc., Fremont, California.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
26 * Gareth Hughes <gareth@valinux.com>
27 * Kevin E. Martin <martin@valinux.com>
33 #include "drm_sarea.h"
34 #include "radeon_drm.h"
35 #include "radeon_drv.h"
36 #include "drm_os_linux.h"
38 /* ================================================================
39 * CP hardware state programming functions
42 static inline void radeon_emit_clip_rect( drm_radeon_private_t
*dev_priv
,
43 drm_clip_rect_t
*box
)
47 DRM_DEBUG( " box: x1=%d y1=%d x2=%d y2=%d\n",
48 box
->x1
, box
->y1
, box
->x2
, box
->y2
);
51 OUT_RING( CP_PACKET0( RADEON_RE_TOP_LEFT
, 0 ) );
52 OUT_RING( (box
->y1
<< 16) | box
->x1
);
53 OUT_RING( CP_PACKET0( RADEON_RE_WIDTH_HEIGHT
, 0 ) );
54 OUT_RING( ((box
->y2
- 1) << 16) | (box
->x2
- 1) );
60 static void radeon_emit_state( drm_radeon_private_t
*dev_priv
,
61 drm_radeon_context_regs_t
*ctx
,
62 drm_radeon_texture_regs_t
*tex
,
66 DRM_DEBUG( "dirty=0x%08x\n", dirty
);
68 if ( dirty
& RADEON_UPLOAD_CONTEXT
) {
70 OUT_RING( CP_PACKET0( RADEON_PP_MISC
, 6 ) );
71 OUT_RING( ctx
->pp_misc
);
72 OUT_RING( ctx
->pp_fog_color
);
73 OUT_RING( ctx
->re_solid_color
);
74 OUT_RING( ctx
->rb3d_blendcntl
);
75 OUT_RING( ctx
->rb3d_depthoffset
);
76 OUT_RING( ctx
->rb3d_depthpitch
);
77 OUT_RING( ctx
->rb3d_zstencilcntl
);
78 OUT_RING( CP_PACKET0( RADEON_PP_CNTL
, 2 ) );
79 OUT_RING( ctx
->pp_cntl
);
80 OUT_RING( ctx
->rb3d_cntl
);
81 OUT_RING( ctx
->rb3d_coloroffset
);
82 OUT_RING( CP_PACKET0( RADEON_RB3D_COLORPITCH
, 0 ) );
83 OUT_RING( ctx
->rb3d_colorpitch
);
87 if ( dirty
& RADEON_UPLOAD_VERTFMT
) {
89 OUT_RING( CP_PACKET0( RADEON_SE_COORD_FMT
, 0 ) );
90 OUT_RING( ctx
->se_coord_fmt
);
94 if ( dirty
& RADEON_UPLOAD_LINE
) {
96 OUT_RING( CP_PACKET0( RADEON_RE_LINE_PATTERN
, 1 ) );
97 OUT_RING( ctx
->re_line_pattern
);
98 OUT_RING( ctx
->re_line_state
);
99 OUT_RING( CP_PACKET0( RADEON_SE_LINE_WIDTH
, 0 ) );
100 OUT_RING( ctx
->se_line_width
);
104 if ( dirty
& RADEON_UPLOAD_BUMPMAP
) {
106 OUT_RING( CP_PACKET0( RADEON_PP_LUM_MATRIX
, 0 ) );
107 OUT_RING( ctx
->pp_lum_matrix
);
108 OUT_RING( CP_PACKET0( RADEON_PP_ROT_MATRIX_0
, 1 ) );
109 OUT_RING( ctx
->pp_rot_matrix_0
);
110 OUT_RING( ctx
->pp_rot_matrix_1
);
114 if ( dirty
& RADEON_UPLOAD_MASKS
) {
116 OUT_RING( CP_PACKET0( RADEON_RB3D_STENCILREFMASK
, 2 ) );
117 OUT_RING( ctx
->rb3d_stencilrefmask
);
118 OUT_RING( ctx
->rb3d_ropcntl
);
119 OUT_RING( ctx
->rb3d_planemask
);
123 if ( dirty
& RADEON_UPLOAD_VIEWPORT
) {
125 OUT_RING( CP_PACKET0( RADEON_SE_VPORT_XSCALE
, 5 ) );
126 OUT_RING( ctx
->se_vport_xscale
);
127 OUT_RING( ctx
->se_vport_xoffset
);
128 OUT_RING( ctx
->se_vport_yscale
);
129 OUT_RING( ctx
->se_vport_yoffset
);
130 OUT_RING( ctx
->se_vport_zscale
);
131 OUT_RING( ctx
->se_vport_zoffset
);
135 if ( dirty
& RADEON_UPLOAD_SETUP
) {
137 OUT_RING( CP_PACKET0( RADEON_SE_CNTL
, 0 ) );
138 OUT_RING( ctx
->se_cntl
);
139 OUT_RING( CP_PACKET0( RADEON_SE_CNTL_STATUS
, 0 ) );
140 OUT_RING( ctx
->se_cntl_status
);
144 if ( dirty
& RADEON_UPLOAD_MISC
) {
146 OUT_RING( CP_PACKET0( RADEON_RE_MISC
, 0 ) );
147 OUT_RING( ctx
->re_misc
);
151 if ( dirty
& RADEON_UPLOAD_TEX0
) {
153 OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_0
, 5 ) );
154 OUT_RING( tex
[0].pp_txfilter
);
155 OUT_RING( tex
[0].pp_txformat
);
156 OUT_RING( tex
[0].pp_txoffset
);
157 OUT_RING( tex
[0].pp_txcblend
);
158 OUT_RING( tex
[0].pp_txablend
);
159 OUT_RING( tex
[0].pp_tfactor
);
160 OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_0
, 0 ) );
161 OUT_RING( tex
[0].pp_border_color
);
165 if ( dirty
& RADEON_UPLOAD_TEX1
) {
167 OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_1
, 5 ) );
168 OUT_RING( tex
[1].pp_txfilter
);
169 OUT_RING( tex
[1].pp_txformat
);
170 OUT_RING( tex
[1].pp_txoffset
);
171 OUT_RING( tex
[1].pp_txcblend
);
172 OUT_RING( tex
[1].pp_txablend
);
173 OUT_RING( tex
[1].pp_tfactor
);
174 OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_1
, 0 ) );
175 OUT_RING( tex
[1].pp_border_color
);
179 if ( dirty
& RADEON_UPLOAD_TEX2
) {
181 OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_2
, 5 ) );
182 OUT_RING( tex
[2].pp_txfilter
);
183 OUT_RING( tex
[2].pp_txformat
);
184 OUT_RING( tex
[2].pp_txoffset
);
185 OUT_RING( tex
[2].pp_txcblend
);
186 OUT_RING( tex
[2].pp_txablend
);
187 OUT_RING( tex
[2].pp_tfactor
);
188 OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_2
, 0 ) );
189 OUT_RING( tex
[2].pp_border_color
);
196 static void radeon_emit_state2( drm_radeon_private_t
*dev_priv
,
197 drm_radeon_state_t
*state
)
201 if (state
->dirty
& RADEON_UPLOAD_ZBIAS
) {
203 OUT_RING( CP_PACKET0( RADEON_SE_ZBIAS_FACTOR
, 1 ) );
204 OUT_RING( state
->context2
.se_zbias_factor
);
205 OUT_RING( state
->context2
.se_zbias_constant
);
209 radeon_emit_state( dev_priv
, &state
->context
,
210 state
->tex
, state
->dirty
);
213 /* New (1.3) state mechanism. 3 commands (packet, scalar, vector) in
214 * 1.3 cmdbuffers allow all previous state to be updated as well as
215 * the tcl scalar and vector areas.
221 } packet
[RADEON_MAX_STATE_PACKETS
] = {
222 { RADEON_PP_MISC
,7,"RADEON_PP_MISC" },
223 { RADEON_PP_CNTL
,3,"RADEON_PP_CNTL" },
224 { RADEON_RB3D_COLORPITCH
,1,"RADEON_RB3D_COLORPITCH" },
225 { RADEON_RE_LINE_PATTERN
,2,"RADEON_RE_LINE_PATTERN" },
226 { RADEON_SE_LINE_WIDTH
,1,"RADEON_SE_LINE_WIDTH" },
227 { RADEON_PP_LUM_MATRIX
,1,"RADEON_PP_LUM_MATRIX" },
228 { RADEON_PP_ROT_MATRIX_0
,2,"RADEON_PP_ROT_MATRIX_0" },
229 { RADEON_RB3D_STENCILREFMASK
,3,"RADEON_RB3D_STENCILREFMASK" },
230 { RADEON_SE_VPORT_XSCALE
,6,"RADEON_SE_VPORT_XSCALE" },
231 { RADEON_SE_CNTL
,2,"RADEON_SE_CNTL" },
232 { RADEON_SE_CNTL_STATUS
,1,"RADEON_SE_CNTL_STATUS" },
233 { RADEON_RE_MISC
,1,"RADEON_RE_MISC" },
234 { RADEON_PP_TXFILTER_0
,6,"RADEON_PP_TXFILTER_0" },
235 { RADEON_PP_BORDER_COLOR_0
,1,"RADEON_PP_BORDER_COLOR_0" },
236 { RADEON_PP_TXFILTER_1
,6,"RADEON_PP_TXFILTER_1" },
237 { RADEON_PP_BORDER_COLOR_1
,1,"RADEON_PP_BORDER_COLOR_1" },
238 { RADEON_PP_TXFILTER_2
,6,"RADEON_PP_TXFILTER_2" },
239 { RADEON_PP_BORDER_COLOR_2
,1,"RADEON_PP_BORDER_COLOR_2" },
240 { RADEON_SE_ZBIAS_FACTOR
,2,"RADEON_SE_ZBIAS_FACTOR" },
241 { RADEON_SE_TCL_OUTPUT_VTX_FMT
,11,"RADEON_SE_TCL_OUTPUT_VTX_FMT" },
242 { RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED
,17,"RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED" },
243 { R200_PP_TXCBLEND_0
, 4, "R200_PP_TXCBLEND_0" },
244 { R200_PP_TXCBLEND_1
, 4, "R200_PP_TXCBLEND_1" },
245 { R200_PP_TXCBLEND_2
, 4, "R200_PP_TXCBLEND_2" },
246 { R200_PP_TXCBLEND_3
, 4, "R200_PP_TXCBLEND_3" },
247 { R200_PP_TXCBLEND_4
, 4, "R200_PP_TXCBLEND_4" },
248 { R200_PP_TXCBLEND_5
, 4, "R200_PP_TXCBLEND_5" },
249 { R200_PP_TXCBLEND_6
, 4, "R200_PP_TXCBLEND_6" },
250 { R200_PP_TXCBLEND_7
, 4, "R200_PP_TXCBLEND_7" },
251 { R200_SE_TCL_LIGHT_MODEL_CTL_0
, 6, "R200_SE_TCL_LIGHT_MODEL_CTL_0" },
252 { R200_PP_TFACTOR_0
, 6, "R200_PP_TFACTOR_0" },
253 { R200_SE_VTX_FMT_0
, 4, "R200_SE_VTX_FMT_0" },
254 { R200_SE_VAP_CNTL
, 1, "R200_SE_VAP_CNTL" },
255 { R200_SE_TCL_MATRIX_SEL_0
, 5, "R200_SE_TCL_MATRIX_SEL_0" },
256 { R200_SE_TCL_TEX_PROC_CTL_2
, 5, "R200_SE_TCL_TEX_PROC_CTL_2" },
257 { R200_SE_TCL_UCP_VERT_BLEND_CTL
, 1, "R200_SE_TCL_UCP_VERT_BLEND_CTL" },
258 { R200_PP_TXFILTER_0
, 6, "R200_PP_TXFILTER_0" },
259 { R200_PP_TXFILTER_1
, 6, "R200_PP_TXFILTER_1" },
260 { R200_PP_TXFILTER_2
, 6, "R200_PP_TXFILTER_2" },
261 { R200_PP_TXFILTER_3
, 6, "R200_PP_TXFILTER_3" },
262 { R200_PP_TXFILTER_4
, 6, "R200_PP_TXFILTER_4" },
263 { R200_PP_TXFILTER_5
, 6, "R200_PP_TXFILTER_5" },
264 { R200_PP_TXOFFSET_0
, 1, "R200_PP_TXOFFSET_0" },
265 { R200_PP_TXOFFSET_1
, 1, "R200_PP_TXOFFSET_1" },
266 { R200_PP_TXOFFSET_2
, 1, "R200_PP_TXOFFSET_2" },
267 { R200_PP_TXOFFSET_3
, 1, "R200_PP_TXOFFSET_3" },
268 { R200_PP_TXOFFSET_4
, 1, "R200_PP_TXOFFSET_4" },
269 { R200_PP_TXOFFSET_5
, 1, "R200_PP_TXOFFSET_5" },
270 { R200_SE_VTE_CNTL
, 1, "R200_SE_VTE_CNTL" },
271 { R200_SE_TCL_OUTPUT_VTX_COMP_SEL
, 1, "R200_SE_TCL_OUTPUT_VTX_COMP_SEL" },
272 { R200_PP_TAM_DEBUG3
, 1, "R200_PP_TAM_DEBUG3" },
273 { R200_PP_CNTL_X
, 1, "R200_PP_CNTL_X" },
274 { R200_RB3D_DEPTHXY_OFFSET
, 1, "R200_RB3D_DEPTHXY_OFFSET" },
275 { R200_RE_AUX_SCISSOR_CNTL
, 1, "R200_RE_AUX_SCISSOR_CNTL" },
276 { R200_RE_SCISSOR_TL_0
, 2, "R200_RE_SCISSOR_TL_0" },
277 { R200_RE_SCISSOR_TL_1
, 2, "R200_RE_SCISSOR_TL_1" },
278 { R200_RE_SCISSOR_TL_2
, 2, "R200_RE_SCISSOR_TL_2" },
279 { R200_SE_VAP_CNTL_STATUS
, 1, "R200_SE_VAP_CNTL_STATUS" },
280 { R200_SE_VTX_STATE_CNTL
, 1, "R200_SE_VTX_STATE_CNTL" },
281 { R200_RE_POINTSIZE
, 1, "R200_RE_POINTSIZE" },
282 { R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0
, 4, "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0" },
283 { R200_PP_CUBIC_FACES_0
, 1, "R200_PP_CUBIC_FACES_0" }, /* 61 */
284 { R200_PP_CUBIC_OFFSET_F1_0
, 5, "R200_PP_CUBIC_OFFSET_F1_0" }, /* 62 */
285 { R200_PP_CUBIC_FACES_1
, 1, "R200_PP_CUBIC_FACES_1" },
286 { R200_PP_CUBIC_OFFSET_F1_1
, 5, "R200_PP_CUBIC_OFFSET_F1_1" },
287 { R200_PP_CUBIC_FACES_2
, 1, "R200_PP_CUBIC_FACES_2" },
288 { R200_PP_CUBIC_OFFSET_F1_2
, 5, "R200_PP_CUBIC_OFFSET_F1_2" },
289 { R200_PP_CUBIC_FACES_3
, 1, "R200_PP_CUBIC_FACES_3" },
290 { R200_PP_CUBIC_OFFSET_F1_3
, 5, "R200_PP_CUBIC_OFFSET_F1_3" },
291 { R200_PP_CUBIC_FACES_4
, 1, "R200_PP_CUBIC_FACES_4" },
292 { R200_PP_CUBIC_OFFSET_F1_4
, 5, "R200_PP_CUBIC_OFFSET_F1_4" },
293 { R200_PP_CUBIC_FACES_5
, 1, "R200_PP_CUBIC_FACES_5" },
294 { R200_PP_CUBIC_OFFSET_F1_5
, 5, "R200_PP_CUBIC_OFFSET_F1_5" },
299 /* ================================================================
300 * Performance monitoring functions
303 static void radeon_clear_box( drm_radeon_private_t
*dev_priv
,
304 int x
, int y
, int w
, int h
,
305 int r
, int g
, int b
)
310 x
+= dev_priv
->sarea_priv
->boxes
[0].x1
;
311 y
+= dev_priv
->sarea_priv
->boxes
[0].y1
;
313 switch ( dev_priv
->color_fmt
) {
314 case RADEON_COLOR_FORMAT_RGB565
:
315 color
= (((r
& 0xf8) << 8) |
319 case RADEON_COLOR_FORMAT_ARGB8888
:
321 color
= (((0xff) << 24) | (r
<< 16) | (g
<< 8) | b
);
326 RADEON_WAIT_UNTIL_3D_IDLE();
327 OUT_RING( CP_PACKET0( RADEON_DP_WRITE_MASK
, 0 ) );
328 OUT_RING( 0xffffffff );
333 OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI
, 4 ) );
334 OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL
|
335 RADEON_GMC_BRUSH_SOLID_COLOR
|
336 (dev_priv
->color_fmt
<< 8) |
337 RADEON_GMC_SRC_DATATYPE_COLOR
|
339 RADEON_GMC_CLR_CMP_CNTL_DIS
);
341 if ( dev_priv
->page_flipping
&& dev_priv
->current_page
== 1 ) {
342 OUT_RING( dev_priv
->front_pitch_offset
);
344 OUT_RING( dev_priv
->back_pitch_offset
);
349 OUT_RING( (x
<< 16) | y
);
350 OUT_RING( (w
<< 16) | h
);
355 static void radeon_cp_performance_boxes( drm_radeon_private_t
*dev_priv
)
357 /* Collapse various things into a wait flag -- trying to
358 * guess if userspase slept -- better just to have them tell us.
360 if (dev_priv
->stats
.last_frame_reads
> 1 ||
361 dev_priv
->stats
.last_clear_reads
> dev_priv
->stats
.clears
) {
362 dev_priv
->stats
.boxes
|= RADEON_BOX_WAIT_IDLE
;
365 if (dev_priv
->stats
.freelist_loops
) {
366 dev_priv
->stats
.boxes
|= RADEON_BOX_WAIT_IDLE
;
369 /* Purple box for page flipping
371 if ( dev_priv
->stats
.boxes
& RADEON_BOX_FLIP
)
372 radeon_clear_box( dev_priv
, 4, 4, 8, 8, 255, 0, 255 );
374 /* Red box if we have to wait for idle at any point
376 if ( dev_priv
->stats
.boxes
& RADEON_BOX_WAIT_IDLE
)
377 radeon_clear_box( dev_priv
, 16, 4, 8, 8, 255, 0, 0 );
379 /* Blue box: lost context?
382 /* Yellow box for texture swaps
384 if ( dev_priv
->stats
.boxes
& RADEON_BOX_TEXTURE_LOAD
)
385 radeon_clear_box( dev_priv
, 40, 4, 8, 8, 255, 255, 0 );
387 /* Green box if hardware never idles (as far as we can tell)
389 if ( !(dev_priv
->stats
.boxes
& RADEON_BOX_DMA_IDLE
) )
390 radeon_clear_box( dev_priv
, 64, 4, 8, 8, 0, 255, 0 );
393 /* Draw bars indicating number of buffers allocated
394 * (not a great measure, easily confused)
396 if (dev_priv
->stats
.requested_bufs
) {
397 if (dev_priv
->stats
.requested_bufs
> 100)
398 dev_priv
->stats
.requested_bufs
= 100;
400 radeon_clear_box( dev_priv
, 4, 16,
401 dev_priv
->stats
.requested_bufs
, 4,
405 memset( &dev_priv
->stats
, 0, sizeof(dev_priv
->stats
) );
408 /* ================================================================
409 * CP command dispatch functions
412 static void radeon_cp_dispatch_clear( drm_device_t
*dev
,
413 drm_radeon_clear_t
*clear
,
414 drm_radeon_clear_rect_t
*depth_boxes
)
416 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
417 drm_radeon_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
418 drm_radeon_depth_clear_t
*depth_clear
= &dev_priv
->depth_clear
;
419 int nbox
= sarea_priv
->nbox
;
420 drm_clip_rect_t
*pbox
= sarea_priv
->boxes
;
421 unsigned int flags
= clear
->flags
;
422 u32 rb3d_cntl
= 0, rb3d_stencilrefmask
= 0;
425 DRM_DEBUG( "flags = 0x%x\n", flags
);
427 dev_priv
->stats
.clears
++;
429 if ( dev_priv
->page_flipping
&& dev_priv
->current_page
== 1 ) {
430 unsigned int tmp
= flags
;
432 flags
&= ~(RADEON_FRONT
| RADEON_BACK
);
433 if ( tmp
& RADEON_FRONT
) flags
|= RADEON_BACK
;
434 if ( tmp
& RADEON_BACK
) flags
|= RADEON_FRONT
;
437 if ( flags
& (RADEON_FRONT
| RADEON_BACK
) ) {
441 /* Ensure the 3D stream is idle before doing a
442 * 2D fill to clear the front or back buffer.
444 RADEON_WAIT_UNTIL_3D_IDLE();
446 OUT_RING( CP_PACKET0( RADEON_DP_WRITE_MASK
, 0 ) );
447 OUT_RING( clear
->color_mask
);
451 /* Make sure we restore the 3D state next time.
453 dev_priv
->sarea_priv
->ctx_owner
= 0;
455 for ( i
= 0 ; i
< nbox
; i
++ ) {
458 int w
= pbox
[i
].x2
- x
;
459 int h
= pbox
[i
].y2
- y
;
461 DRM_DEBUG( "dispatch clear %d,%d-%d,%d flags 0x%x\n",
464 if ( flags
& RADEON_FRONT
) {
467 OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI
, 4 ) );
468 OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL
|
469 RADEON_GMC_BRUSH_SOLID_COLOR
|
470 (dev_priv
->color_fmt
<< 8) |
471 RADEON_GMC_SRC_DATATYPE_COLOR
|
473 RADEON_GMC_CLR_CMP_CNTL_DIS
);
475 OUT_RING( dev_priv
->front_pitch_offset
);
476 OUT_RING( clear
->clear_color
);
478 OUT_RING( (x
<< 16) | y
);
479 OUT_RING( (w
<< 16) | h
);
484 if ( flags
& RADEON_BACK
) {
487 OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI
, 4 ) );
488 OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL
|
489 RADEON_GMC_BRUSH_SOLID_COLOR
|
490 (dev_priv
->color_fmt
<< 8) |
491 RADEON_GMC_SRC_DATATYPE_COLOR
|
493 RADEON_GMC_CLR_CMP_CNTL_DIS
);
495 OUT_RING( dev_priv
->back_pitch_offset
);
496 OUT_RING( clear
->clear_color
);
498 OUT_RING( (x
<< 16) | y
);
499 OUT_RING( (w
<< 16) | h
);
506 /* We have to clear the depth and/or stencil buffers by
507 * rendering a quad into just those buffers. Thus, we have to
508 * make sure the 3D engine is configured correctly.
510 if ( dev_priv
->is_r200
&&
511 (flags
& (RADEON_DEPTH
| RADEON_STENCIL
)) ) {
516 int tempRB3D_ZSTENCILCNTL
;
517 int tempRB3D_STENCILREFMASK
;
518 int tempRB3D_PLANEMASK
;
521 int tempSE_VTX_FMT_0
;
522 int tempSE_VTX_FMT_1
;
524 int tempRE_AUX_SCISSOR_CNTL
;
529 tempRB3D_CNTL
= depth_clear
->rb3d_cntl
;
530 tempRB3D_CNTL
&= ~(1<<15); /* unset radeon magic flag */
532 tempRB3D_ZSTENCILCNTL
= depth_clear
->rb3d_zstencilcntl
;
533 tempRB3D_STENCILREFMASK
= 0x0;
535 tempSE_CNTL
= depth_clear
->se_cntl
;
541 tempSE_VAP_CNTL
= (/* SE_VAP_CNTL__FORCE_W_TO_ONE_MASK | */
542 (0x9 << SE_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT
));
544 tempRB3D_PLANEMASK
= 0x0;
546 tempRE_AUX_SCISSOR_CNTL
= 0x0;
549 SE_VTE_CNTL__VTX_XY_FMT_MASK
|
550 SE_VTE_CNTL__VTX_Z_FMT_MASK
;
552 /* Vertex format (X, Y, Z, W)*/
554 SE_VTX_FMT_0__VTX_Z0_PRESENT_MASK
|
555 SE_VTX_FMT_0__VTX_W0_PRESENT_MASK
;
556 tempSE_VTX_FMT_1
= 0x0;
560 * Depth buffer specific enables
562 if (flags
& RADEON_DEPTH
) {
563 /* Enable depth buffer */
564 tempRB3D_CNTL
|= RADEON_Z_ENABLE
;
566 /* Disable depth buffer */
567 tempRB3D_CNTL
&= ~RADEON_Z_ENABLE
;
571 * Stencil buffer specific enables
573 if ( flags
& RADEON_STENCIL
) {
574 tempRB3D_CNTL
|= RADEON_STENCIL_ENABLE
;
575 tempRB3D_STENCILREFMASK
= clear
->depth_mask
;
577 tempRB3D_CNTL
&= ~RADEON_STENCIL_ENABLE
;
578 tempRB3D_STENCILREFMASK
= 0x00000000;
582 RADEON_WAIT_UNTIL_2D_IDLE();
584 OUT_RING_REG( RADEON_PP_CNTL
, tempPP_CNTL
);
585 OUT_RING_REG( R200_RE_CNTL
, tempRE_CNTL
);
586 OUT_RING_REG( RADEON_RB3D_CNTL
, tempRB3D_CNTL
);
587 OUT_RING_REG( RADEON_RB3D_ZSTENCILCNTL
,
588 tempRB3D_ZSTENCILCNTL
);
589 OUT_RING_REG( RADEON_RB3D_STENCILREFMASK
,
590 tempRB3D_STENCILREFMASK
);
591 OUT_RING_REG( RADEON_RB3D_PLANEMASK
, tempRB3D_PLANEMASK
);
592 OUT_RING_REG( RADEON_SE_CNTL
, tempSE_CNTL
);
593 OUT_RING_REG( R200_SE_VTE_CNTL
, tempSE_VTE_CNTL
);
594 OUT_RING_REG( R200_SE_VTX_FMT_0
, tempSE_VTX_FMT_0
);
595 OUT_RING_REG( R200_SE_VTX_FMT_1
, tempSE_VTX_FMT_1
);
596 OUT_RING_REG( R200_SE_VAP_CNTL
, tempSE_VAP_CNTL
);
597 OUT_RING_REG( R200_RE_AUX_SCISSOR_CNTL
,
598 tempRE_AUX_SCISSOR_CNTL
);
601 /* Make sure we restore the 3D state next time.
603 dev_priv
->sarea_priv
->ctx_owner
= 0;
605 for ( i
= 0 ; i
< nbox
; i
++ ) {
607 /* Funny that this should be required --
610 radeon_emit_clip_rect( dev_priv
,
611 &sarea_priv
->boxes
[i
] );
614 OUT_RING( CP_PACKET3( R200_3D_DRAW_IMMD_2
, 12 ) );
615 OUT_RING( (RADEON_PRIM_TYPE_RECT_LIST
|
616 RADEON_PRIM_WALK_RING
|
617 (3 << RADEON_NUM_VERTICES_SHIFT
)) );
618 OUT_RING( depth_boxes
[i
].ui
[CLEAR_X1
] );
619 OUT_RING( depth_boxes
[i
].ui
[CLEAR_Y1
] );
620 OUT_RING( depth_boxes
[i
].ui
[CLEAR_DEPTH
] );
621 OUT_RING( 0x3f800000 );
622 OUT_RING( depth_boxes
[i
].ui
[CLEAR_X1
] );
623 OUT_RING( depth_boxes
[i
].ui
[CLEAR_Y2
] );
624 OUT_RING( depth_boxes
[i
].ui
[CLEAR_DEPTH
] );
625 OUT_RING( 0x3f800000 );
626 OUT_RING( depth_boxes
[i
].ui
[CLEAR_X2
] );
627 OUT_RING( depth_boxes
[i
].ui
[CLEAR_Y2
] );
628 OUT_RING( depth_boxes
[i
].ui
[CLEAR_DEPTH
] );
629 OUT_RING( 0x3f800000 );
633 else if ( (flags
& (RADEON_DEPTH
| RADEON_STENCIL
)) ) {
635 rb3d_cntl
= depth_clear
->rb3d_cntl
;
637 if ( flags
& RADEON_DEPTH
) {
638 rb3d_cntl
|= RADEON_Z_ENABLE
;
640 rb3d_cntl
&= ~RADEON_Z_ENABLE
;
643 if ( flags
& RADEON_STENCIL
) {
644 rb3d_cntl
|= RADEON_STENCIL_ENABLE
;
645 rb3d_stencilrefmask
= clear
->depth_mask
; /* misnamed field */
647 rb3d_cntl
&= ~RADEON_STENCIL_ENABLE
;
648 rb3d_stencilrefmask
= 0x00000000;
652 RADEON_WAIT_UNTIL_2D_IDLE();
654 OUT_RING( CP_PACKET0( RADEON_PP_CNTL
, 1 ) );
655 OUT_RING( 0x00000000 );
656 OUT_RING( rb3d_cntl
);
658 OUT_RING_REG( RADEON_RB3D_ZSTENCILCNTL
,
659 depth_clear
->rb3d_zstencilcntl
);
660 OUT_RING_REG( RADEON_RB3D_STENCILREFMASK
,
661 rb3d_stencilrefmask
);
662 OUT_RING_REG( RADEON_RB3D_PLANEMASK
,
664 OUT_RING_REG( RADEON_SE_CNTL
,
665 depth_clear
->se_cntl
);
668 /* Make sure we restore the 3D state next time.
670 dev_priv
->sarea_priv
->ctx_owner
= 0;
672 for ( i
= 0 ; i
< nbox
; i
++ ) {
674 /* Funny that this should be required --
677 radeon_emit_clip_rect( dev_priv
,
678 &sarea_priv
->boxes
[i
] );
682 OUT_RING( CP_PACKET3( RADEON_3D_DRAW_IMMD
, 13 ) );
683 OUT_RING( RADEON_VTX_Z_PRESENT
|
684 RADEON_VTX_PKCOLOR_PRESENT
);
685 OUT_RING( (RADEON_PRIM_TYPE_RECT_LIST
|
686 RADEON_PRIM_WALK_RING
|
688 RADEON_VTX_FMT_RADEON_MODE
|
689 (3 << RADEON_NUM_VERTICES_SHIFT
)) );
692 OUT_RING( depth_boxes
[i
].ui
[CLEAR_X1
] );
693 OUT_RING( depth_boxes
[i
].ui
[CLEAR_Y1
] );
694 OUT_RING( depth_boxes
[i
].ui
[CLEAR_DEPTH
] );
697 OUT_RING( depth_boxes
[i
].ui
[CLEAR_X1
] );
698 OUT_RING( depth_boxes
[i
].ui
[CLEAR_Y2
] );
699 OUT_RING( depth_boxes
[i
].ui
[CLEAR_DEPTH
] );
702 OUT_RING( depth_boxes
[i
].ui
[CLEAR_X2
] );
703 OUT_RING( depth_boxes
[i
].ui
[CLEAR_Y2
] );
704 OUT_RING( depth_boxes
[i
].ui
[CLEAR_DEPTH
] );
711 /* Increment the clear counter. The client-side 3D driver must
712 * wait on this value before performing the clear ioctl. We
713 * need this because the card's so damned fast...
715 dev_priv
->sarea_priv
->last_clear
++;
719 RADEON_CLEAR_AGE( dev_priv
->sarea_priv
->last_clear
);
720 RADEON_WAIT_UNTIL_IDLE();
725 static void radeon_cp_dispatch_swap( drm_device_t
*dev
)
727 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
728 drm_radeon_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
729 int nbox
= sarea_priv
->nbox
;
730 drm_clip_rect_t
*pbox
= sarea_priv
->boxes
;
735 /* Do some trivial performance monitoring...
737 if (dev_priv
->do_boxes
)
738 radeon_cp_performance_boxes( dev_priv
);
741 /* Wait for the 3D stream to idle before dispatching the bitblt.
742 * This will prevent data corruption between the two streams.
746 RADEON_WAIT_UNTIL_3D_IDLE();
750 for ( i
= 0 ; i
< nbox
; i
++ ) {
753 int w
= pbox
[i
].x2
- x
;
754 int h
= pbox
[i
].y2
- y
;
756 DRM_DEBUG( "dispatch swap %d,%d-%d,%d\n",
761 OUT_RING( CP_PACKET3( RADEON_CNTL_BITBLT_MULTI
, 5 ) );
762 OUT_RING( RADEON_GMC_SRC_PITCH_OFFSET_CNTL
|
763 RADEON_GMC_DST_PITCH_OFFSET_CNTL
|
764 RADEON_GMC_BRUSH_NONE
|
765 (dev_priv
->color_fmt
<< 8) |
766 RADEON_GMC_SRC_DATATYPE_COLOR
|
768 RADEON_DP_SRC_SOURCE_MEMORY
|
769 RADEON_GMC_CLR_CMP_CNTL_DIS
|
770 RADEON_GMC_WR_MSK_DIS
);
772 /* Make this work even if front & back are flipped:
774 if (dev_priv
->current_page
== 0) {
775 OUT_RING( dev_priv
->back_pitch_offset
);
776 OUT_RING( dev_priv
->front_pitch_offset
);
779 OUT_RING( dev_priv
->front_pitch_offset
);
780 OUT_RING( dev_priv
->back_pitch_offset
);
783 OUT_RING( (x
<< 16) | y
);
784 OUT_RING( (x
<< 16) | y
);
785 OUT_RING( (w
<< 16) | h
);
790 /* Increment the frame counter. The client-side 3D driver must
791 * throttle the framerate by waiting for this value before
792 * performing the swapbuffer ioctl.
794 dev_priv
->sarea_priv
->last_frame
++;
798 RADEON_FRAME_AGE( dev_priv
->sarea_priv
->last_frame
);
799 RADEON_WAIT_UNTIL_2D_IDLE();
804 static void radeon_cp_dispatch_flip( drm_device_t
*dev
)
806 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
807 drm_sarea_t
*sarea
= (drm_sarea_t
*)dev_priv
->sarea
->handle
;
808 int offset
= (dev_priv
->current_page
== 1)
809 ? dev_priv
->front_offset
: dev_priv
->back_offset
;
811 DRM_DEBUG( "%s: page=%d pfCurrentPage=%d\n",
813 dev_priv
->current_page
,
814 dev_priv
->sarea_priv
->pfCurrentPage
);
816 /* Do some trivial performance monitoring...
818 if (dev_priv
->do_boxes
) {
819 dev_priv
->stats
.boxes
|= RADEON_BOX_FLIP
;
820 radeon_cp_performance_boxes( dev_priv
);
823 /* Update the frame offsets for both CRTCs
827 RADEON_WAIT_UNTIL_3D_IDLE();
828 OUT_RING_REG( RADEON_CRTC_OFFSET
, ( ( sarea
->frame
.y
* dev_priv
->front_pitch
830 * ( dev_priv
->color_fmt
- 2 ) ) & ~7 )
832 OUT_RING_REG( RADEON_CRTC2_OFFSET
, dev_priv
->sarea_priv
->crtc2_base
837 /* Increment the frame counter. The client-side 3D driver must
838 * throttle the framerate by waiting for this value before
839 * performing the swapbuffer ioctl.
841 dev_priv
->sarea_priv
->last_frame
++;
842 dev_priv
->sarea_priv
->pfCurrentPage
= dev_priv
->current_page
=
843 1 - dev_priv
->current_page
;
847 RADEON_FRAME_AGE( dev_priv
->sarea_priv
->last_frame
);
852 static int bad_prim_vertex_nr( int primitive
, int nr
)
854 switch (primitive
& RADEON_PRIM_TYPE_MASK
) {
855 case RADEON_PRIM_TYPE_NONE
:
856 case RADEON_PRIM_TYPE_POINT
:
858 case RADEON_PRIM_TYPE_LINE
:
859 return (nr
& 1) || nr
== 0;
860 case RADEON_PRIM_TYPE_LINE_STRIP
:
862 case RADEON_PRIM_TYPE_TRI_LIST
:
863 case RADEON_PRIM_TYPE_3VRT_POINT_LIST
:
864 case RADEON_PRIM_TYPE_3VRT_LINE_LIST
:
865 case RADEON_PRIM_TYPE_RECT_LIST
:
866 return nr
% 3 || nr
== 0;
867 case RADEON_PRIM_TYPE_TRI_FAN
:
868 case RADEON_PRIM_TYPE_TRI_STRIP
:
881 unsigned int numverts
;
883 unsigned int vc_format
;
884 } drm_radeon_tcl_prim_t
;
886 static void radeon_cp_dispatch_vertex( drm_device_t
*dev
,
888 drm_radeon_tcl_prim_t
*prim
,
889 drm_clip_rect_t
*boxes
,
893 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
895 int offset
= dev_priv
->agp_buffers_offset
+ buf
->offset
+ prim
->start
;
896 int numverts
= (int)prim
->numverts
;
900 DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d %d verts\n",
907 if (bad_prim_vertex_nr( prim
->prim
, prim
->numverts
)) {
908 DRM_ERROR( "bad prim %x numverts %d\n",
909 prim
->prim
, prim
->numverts
);
914 /* Emit the next cliprect */
916 if (__copy_from_user( &box
, &boxes
[i
], sizeof(box
) ))
919 radeon_emit_clip_rect( dev_priv
, &box
);
922 /* Emit the vertex buffer rendering commands */
925 OUT_RING( CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM
, 3 ) );
927 OUT_RING( numverts
);
928 OUT_RING( prim
->vc_format
);
929 OUT_RING( prim
->prim
| RADEON_PRIM_WALK_LIST
|
930 RADEON_COLOR_ORDER_RGBA
|
931 RADEON_VTX_FMT_RADEON_MODE
|
932 (numverts
<< RADEON_NUM_VERTICES_SHIFT
) );
937 } while ( i
< nbox
);
942 static void radeon_cp_discard_buffer( drm_device_t
*dev
, drm_buf_t
*buf
)
944 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
945 drm_radeon_buf_priv_t
*buf_priv
= buf
->dev_private
;
948 buf_priv
->age
= ++dev_priv
->sarea_priv
->last_dispatch
;
950 /* Emit the vertex buffer age */
952 RADEON_DISPATCH_AGE( buf_priv
->age
);
959 static void radeon_cp_dispatch_indirect( drm_device_t
*dev
,
963 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
965 DRM_DEBUG( "indirect: buf=%d s=0x%x e=0x%x\n",
966 buf
->idx
, start
, end
);
968 if ( start
!= end
) {
969 int offset
= (dev_priv
->agp_buffers_offset
970 + buf
->offset
+ start
);
971 int dwords
= (end
- start
+ 3) / sizeof(u32
);
973 /* Indirect buffer data must be an even number of
974 * dwords, so if we've been given an odd number we must
975 * pad the data with a Type-2 CP packet.
979 ((char *)dev_priv
->buffers
->handle
980 + buf
->offset
+ start
);
981 data
[dwords
++] = RADEON_CP_PACKET2
;
984 /* Fire off the indirect buffer */
987 OUT_RING( CP_PACKET0( RADEON_CP_IB_BASE
, 1 ) );
996 static void radeon_cp_dispatch_indices( drm_device_t
*dev
,
998 drm_radeon_tcl_prim_t
*prim
,
999 drm_clip_rect_t
*boxes
,
1002 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1003 drm_clip_rect_t box
;
1004 int offset
= dev_priv
->agp_buffers_offset
+ prim
->offset
;
1008 int start
= prim
->start
+ RADEON_INDEX_PRIM_OFFSET
;
1009 int count
= (prim
->finish
- start
) / sizeof(u16
);
1011 DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d offset: %x nr %d\n",
1019 if (bad_prim_vertex_nr( prim
->prim
, count
)) {
1020 DRM_ERROR( "bad prim %x count %d\n",
1021 prim
->prim
, count
);
1026 if ( start
>= prim
->finish
||
1027 (prim
->start
& 0x7) ) {
1028 DRM_ERROR( "buffer prim %d\n", prim
->prim
);
1032 dwords
= (prim
->finish
- prim
->start
+ 3) / sizeof(u32
);
1034 data
= (u32
*)((char *)dev_priv
->buffers
->handle
+
1035 elt_buf
->offset
+ prim
->start
);
1037 data
[0] = CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM
, dwords
-2 );
1039 data
[2] = prim
->numverts
;
1040 data
[3] = prim
->vc_format
;
1041 data
[4] = (prim
->prim
|
1042 RADEON_PRIM_WALK_IND
|
1043 RADEON_COLOR_ORDER_RGBA
|
1044 RADEON_VTX_FMT_RADEON_MODE
|
1045 (count
<< RADEON_NUM_VERTICES_SHIFT
) );
1049 if (__copy_from_user( &box
, &boxes
[i
], sizeof(box
) ))
1052 radeon_emit_clip_rect( dev_priv
, &box
);
1055 radeon_cp_dispatch_indirect( dev
, elt_buf
,
1060 } while ( i
< nbox
);
1064 #define RADEON_MAX_TEXTURE_SIZE (RADEON_BUFFER_SIZE - 8 * sizeof(u32))
1066 static int radeon_cp_dispatch_texture( drm_device_t
*dev
,
1067 drm_radeon_texture_t
*tex
,
1068 drm_radeon_tex_image_t
*image
)
1070 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1075 int size
, dwords
, tex_width
, blit_width
;
1080 dev_priv
->stats
.boxes
|= RADEON_BOX_TEXTURE_LOAD
;
1082 /* Flush the pixel cache. This ensures no pixel data gets mixed
1083 * up with the texture data from the host data blit, otherwise
1084 * part of the texture image may be corrupted.
1087 RADEON_FLUSH_CACHE();
1088 RADEON_WAIT_UNTIL_IDLE();
1092 /* The Mesa texture functions provide the data in little endian as the
1093 * chip wants it, but we need to compensate for the fact that the CP
1094 * ring gets byte-swapped
1097 OUT_RING_REG( RADEON_RBBM_GUICNTL
, RADEON_HOST_DATA_SWAP_32BIT
);
1102 /* The compiler won't optimize away a division by a variable,
1103 * even if the only legal values are powers of two. Thus, we'll
1104 * use a shift instead.
1106 switch ( tex
->format
) {
1107 case RADEON_TXFORMAT_ARGB8888
:
1108 case RADEON_TXFORMAT_RGBA8888
:
1109 format
= RADEON_COLOR_FORMAT_ARGB8888
;
1110 tex_width
= tex
->width
* 4;
1111 blit_width
= image
->width
* 4;
1113 case RADEON_TXFORMAT_AI88
:
1114 case RADEON_TXFORMAT_ARGB1555
:
1115 case RADEON_TXFORMAT_RGB565
:
1116 case RADEON_TXFORMAT_ARGB4444
:
1117 case RADEON_TXFORMAT_VYUY422
:
1118 case RADEON_TXFORMAT_YVYU422
:
1119 format
= RADEON_COLOR_FORMAT_RGB565
;
1120 tex_width
= tex
->width
* 2;
1121 blit_width
= image
->width
* 2;
1123 case RADEON_TXFORMAT_I8
:
1124 case RADEON_TXFORMAT_RGB332
:
1125 format
= RADEON_COLOR_FORMAT_CI8
;
1126 tex_width
= tex
->width
* 1;
1127 blit_width
= image
->width
* 1;
1130 DRM_ERROR( "invalid texture format %d\n", tex
->format
);
1134 DRM_DEBUG("tex=%dx%d blit=%d\n", tex_width
, tex
->height
, blit_width
);
1137 DRM_DEBUG( "tex: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n",
1138 tex
->offset
>> 10, tex
->pitch
, tex
->format
,
1139 image
->x
, image
->y
, image
->width
, image
->height
);
1141 /* Make a copy of some parameters in case we have to
1142 * update them for a multi-pass texture blit.
1144 height
= image
->height
;
1145 data
= (const u8
*)image
->data
;
1147 size
= height
* blit_width
;
1149 if ( size
> RADEON_MAX_TEXTURE_SIZE
) {
1150 height
= RADEON_MAX_TEXTURE_SIZE
/ blit_width
;
1151 size
= height
* blit_width
;
1152 } else if ( size
< 4 && size
> 0 ) {
1154 } else if ( size
== 0 ) {
1158 buf
= radeon_freelist_get( dev
);
1160 radeon_do_cp_idle( dev_priv
);
1161 buf
= radeon_freelist_get( dev
);
1164 DRM_DEBUG("radeon_cp_dispatch_texture: EAGAIN\n");
1165 copy_to_user( tex
->image
, image
, sizeof(*image
) );
1170 /* Dispatch the indirect buffer.
1172 buffer
= (u32
*)((char*)dev_priv
->buffers
->handle
+ buf
->offset
);
1174 buffer
[0] = CP_PACKET3( RADEON_CNTL_HOSTDATA_BLT
, dwords
+ 6 );
1175 buffer
[1] = (RADEON_GMC_DST_PITCH_OFFSET_CNTL
|
1176 RADEON_GMC_BRUSH_NONE
|
1178 RADEON_GMC_SRC_DATATYPE_COLOR
|
1180 RADEON_DP_SRC_SOURCE_HOST_DATA
|
1181 RADEON_GMC_CLR_CMP_CNTL_DIS
|
1182 RADEON_GMC_WR_MSK_DIS
);
1184 buffer
[2] = (tex
->pitch
<< 22) | (tex
->offset
>> 10);
1185 buffer
[3] = 0xffffffff;
1186 buffer
[4] = 0xffffffff;
1187 buffer
[5] = (image
->y
<< 16) | image
->x
;
1188 buffer
[6] = (height
<< 16) | image
->width
;
1193 if ( tex_width
>= 32 ) {
1194 /* Texture image width is larger than the minimum, so we
1195 * can upload it directly.
1197 if ( copy_from_user( buffer
, data
, dwords
* sizeof(u32
) ) ) {
1198 DRM_ERROR( "EFAULT on data, %d dwords\n", dwords
);
1202 /* Texture image width is less than the minimum, so we
1203 * need to pad out each image scanline to the minimum
1206 for ( i
= 0 ; i
< tex
->height
; i
++ ) {
1207 if ( copy_from_user( buffer
, data
, tex_width
) ) {
1208 DRM_ERROR( "EFAULT on pad, %d bytes\n",
1217 buf
->pid
= current
->pid
;
1218 buf
->used
= (dwords
+ 8) * sizeof(u32
);
1220 radeon_cp_dispatch_indirect( dev
, buf
, 0, buf
->used
);
1221 radeon_cp_discard_buffer( dev
, buf
);
1223 /* Update the input parameters for next time */
1225 image
->height
-= height
;
1226 image
->data
= (const u8
*)image
->data
+ size
;
1227 } while (image
->height
> 0);
1229 /* Flush the pixel cache after the blit completes. This ensures
1230 * the texture data is written out to memory before rendering
1234 RADEON_FLUSH_CACHE();
1235 RADEON_WAIT_UNTIL_2D_IDLE();
1241 static void radeon_cp_dispatch_stipple( drm_device_t
*dev
, u32
*stipple
)
1243 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1250 OUT_RING( CP_PACKET0( RADEON_RE_STIPPLE_ADDR
, 0 ) );
1251 OUT_RING( 0x00000000 );
1253 OUT_RING( CP_PACKET0_TABLE( RADEON_RE_STIPPLE_DATA
, 31 ) );
1254 for ( i
= 0 ; i
< 32 ; i
++ ) {
1255 OUT_RING( stipple
[i
] );
1262 /* ================================================================
1266 int radeon_cp_clear( struct inode
*inode
, struct file
*filp
,
1267 unsigned int cmd
, unsigned long arg
)
1269 drm_file_t
*priv
= filp
->private_data
;
1270 drm_device_t
*dev
= priv
->dev
;
1271 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1272 drm_radeon_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
1273 drm_radeon_clear_t clear
;
1274 drm_radeon_clear_rect_t depth_boxes
[RADEON_NR_SAREA_CLIPRECTS
];
1277 LOCK_TEST_WITH_RETURN( dev
);
1279 if ( copy_from_user( &clear
, (drm_radeon_clear_t
*)arg
,
1283 RING_SPACE_TEST_WITH_RETURN( dev_priv
);
1285 if ( sarea_priv
->nbox
> RADEON_NR_SAREA_CLIPRECTS
)
1286 sarea_priv
->nbox
= RADEON_NR_SAREA_CLIPRECTS
;
1288 if ( copy_from_user( &depth_boxes
, clear
.depth_boxes
,
1289 sarea_priv
->nbox
* sizeof(depth_boxes
[0]) ) )
1292 radeon_cp_dispatch_clear( dev
, &clear
, depth_boxes
);
1299 /* Not sure why this isn't set all the time:
1301 static int radeon_do_init_pageflip( drm_device_t
*dev
)
1303 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1309 RADEON_WAIT_UNTIL_3D_IDLE();
1310 OUT_RING( CP_PACKET0( RADEON_CRTC_OFFSET_CNTL
, 0 ) );
1311 OUT_RING( RADEON_READ( RADEON_CRTC_OFFSET_CNTL
) | RADEON_CRTC_OFFSET_FLIP_CNTL
);
1312 OUT_RING( CP_PACKET0( RADEON_CRTC2_OFFSET_CNTL
, 0 ) );
1313 OUT_RING( RADEON_READ( RADEON_CRTC2_OFFSET_CNTL
) | RADEON_CRTC_OFFSET_FLIP_CNTL
);
1316 dev_priv
->page_flipping
= 1;
1317 dev_priv
->current_page
= 0;
1318 dev_priv
->sarea_priv
->pfCurrentPage
= dev_priv
->current_page
;
1323 /* Called whenever a client dies, from DRM(release).
1324 * NOTE: Lock isn't necessarily held when this is called!
1326 int radeon_do_cleanup_pageflip( drm_device_t
*dev
)
1328 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1331 if (dev_priv
->current_page
!= 0)
1332 radeon_cp_dispatch_flip( dev
);
1334 dev_priv
->page_flipping
= 0;
1338 /* Swapping and flipping are different operations, need different ioctls.
1339 * They can & should be intermixed to support multiple 3d windows.
1341 int radeon_cp_flip(struct inode
*inode
, struct file
*filp
, unsigned int cmd
, unsigned long data
)
1343 drm_file_t
*priv
= filp
->private_data
;
1344 drm_device_t
*dev
= priv
->dev
;
1345 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1348 LOCK_TEST_WITH_RETURN( dev
);
1350 RING_SPACE_TEST_WITH_RETURN( dev_priv
);
1352 if (!dev_priv
->page_flipping
)
1353 radeon_do_init_pageflip( dev
);
1355 radeon_cp_dispatch_flip( dev
);
1361 int radeon_cp_swap( struct inode
*inode
, struct file
*filp
,
1362 unsigned int cmd
, unsigned long arg
)
1364 drm_file_t
*priv
= filp
->private_data
;
1365 drm_device_t
*dev
= priv
->dev
;
1366 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1367 drm_radeon_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
1370 LOCK_TEST_WITH_RETURN( dev
);
1372 RING_SPACE_TEST_WITH_RETURN( dev_priv
);
1374 if ( sarea_priv
->nbox
> RADEON_NR_SAREA_CLIPRECTS
)
1375 sarea_priv
->nbox
= RADEON_NR_SAREA_CLIPRECTS
;
1377 radeon_cp_dispatch_swap( dev
);
1378 dev_priv
->sarea_priv
->ctx_owner
= 0;
1384 int radeon_cp_vertex( struct inode
*inode
, struct file
*filp
,
1385 unsigned int cmd
, unsigned long arg
)
1387 drm_file_t
*priv
= filp
->private_data
;
1388 drm_device_t
*dev
= priv
->dev
;
1389 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1390 drm_radeon_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
1391 drm_device_dma_t
*dma
= dev
->dma
;
1393 drm_radeon_vertex_t vertex
;
1394 drm_radeon_tcl_prim_t prim
;
1396 LOCK_TEST_WITH_RETURN( dev
);
1399 DRM_ERROR( "%s called with no initialization\n", __FUNCTION__
);
1403 if ( copy_from_user( &vertex
, (drm_radeon_vertex_t
*)arg
,
1407 DRM_DEBUG( "pid=%d index=%d count=%d discard=%d\n",
1409 vertex
.idx
, vertex
.count
, vertex
.discard
);
1411 if ( vertex
.idx
< 0 || vertex
.idx
>= dma
->buf_count
) {
1412 DRM_ERROR( "buffer index %d (of %d max)\n",
1413 vertex
.idx
, dma
->buf_count
- 1 );
1416 if ( vertex
.prim
< 0 ||
1417 vertex
.prim
> RADEON_PRIM_TYPE_3VRT_LINE_LIST
) {
1418 DRM_ERROR( "buffer prim %d\n", vertex
.prim
);
1422 RING_SPACE_TEST_WITH_RETURN( dev_priv
);
1423 VB_AGE_TEST_WITH_RETURN( dev_priv
);
1425 buf
= dma
->buflist
[vertex
.idx
];
1427 if ( buf
->pid
!= current
->pid
) {
1428 DRM_ERROR( "process %d using buffer owned by %d\n",
1429 current
->pid
, buf
->pid
);
1432 if ( buf
->pending
) {
1433 DRM_ERROR( "sending pending buffer %d\n", vertex
.idx
);
1437 /* Build up a prim_t record:
1440 buf
->used
= vertex
.count
; /* not used? */
1442 if ( sarea_priv
->dirty
& ~RADEON_UPLOAD_CLIPRECTS
) {
1443 radeon_emit_state( dev_priv
,
1444 &sarea_priv
->context_state
,
1445 sarea_priv
->tex_state
,
1446 sarea_priv
->dirty
);
1448 sarea_priv
->dirty
&= ~(RADEON_UPLOAD_TEX0IMAGES
|
1449 RADEON_UPLOAD_TEX1IMAGES
|
1450 RADEON_UPLOAD_TEX2IMAGES
|
1451 RADEON_REQUIRE_QUIESCENCE
);
1455 prim
.finish
= vertex
.count
; /* unused */
1456 prim
.prim
= vertex
.prim
;
1457 prim
.numverts
= vertex
.count
;
1458 prim
.vc_format
= dev_priv
->sarea_priv
->vc_format
;
1460 radeon_cp_dispatch_vertex( dev
, buf
, &prim
,
1461 dev_priv
->sarea_priv
->boxes
,
1462 dev_priv
->sarea_priv
->nbox
);
1465 if (vertex
.discard
) {
1466 radeon_cp_discard_buffer( dev
, buf
);
1473 int radeon_cp_indices( struct inode
*inode
, struct file
*filp
,
1474 unsigned int cmd
, unsigned long arg
)
1476 drm_file_t
*priv
= filp
->private_data
;
1477 drm_device_t
*dev
= priv
->dev
;
1478 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1479 drm_radeon_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
1480 drm_device_dma_t
*dma
= dev
->dma
;
1482 drm_radeon_indices_t elts
;
1483 drm_radeon_tcl_prim_t prim
;
1486 LOCK_TEST_WITH_RETURN( dev
);
1489 DRM_ERROR( "%s called with no initialization\n", __FUNCTION__
);
1493 if ( copy_from_user( &elts
, (drm_radeon_indices_t
*)arg
,
1497 DRM_DEBUG( "%s: pid=%d index=%d start=%d end=%d discard=%d\n",
1498 __FUNCTION__
, current
->pid
,
1499 elts
.idx
, elts
.start
, elts
.end
, elts
.discard
);
1501 if ( elts
.idx
< 0 || elts
.idx
>= dma
->buf_count
) {
1502 DRM_ERROR( "buffer index %d (of %d max)\n",
1503 elts
.idx
, dma
->buf_count
- 1 );
1506 if ( elts
.prim
< 0 ||
1507 elts
.prim
> RADEON_PRIM_TYPE_3VRT_LINE_LIST
) {
1508 DRM_ERROR( "buffer prim %d\n", elts
.prim
);
1512 RING_SPACE_TEST_WITH_RETURN( dev_priv
);
1513 VB_AGE_TEST_WITH_RETURN( dev_priv
);
1515 buf
= dma
->buflist
[elts
.idx
];
1517 if ( buf
->pid
!= current
->pid
) {
1518 DRM_ERROR( "process %d using buffer owned by %d\n",
1519 current
->pid
, buf
->pid
);
1522 if ( buf
->pending
) {
1523 DRM_ERROR( "sending pending buffer %d\n", elts
.idx
);
1527 count
= (elts
.end
- elts
.start
) / sizeof(u16
);
1528 elts
.start
-= RADEON_INDEX_PRIM_OFFSET
;
1530 if ( elts
.start
& 0x7 ) {
1531 DRM_ERROR( "misaligned buffer 0x%x\n", elts
.start
);
1534 if ( elts
.start
< buf
->used
) {
1535 DRM_ERROR( "no header 0x%x - 0x%x\n", elts
.start
, buf
->used
);
1539 buf
->used
= elts
.end
;
1541 if ( sarea_priv
->dirty
& ~RADEON_UPLOAD_CLIPRECTS
) {
1542 radeon_emit_state( dev_priv
,
1543 &sarea_priv
->context_state
,
1544 sarea_priv
->tex_state
,
1545 sarea_priv
->dirty
);
1547 sarea_priv
->dirty
&= ~(RADEON_UPLOAD_TEX0IMAGES
|
1548 RADEON_UPLOAD_TEX1IMAGES
|
1549 RADEON_UPLOAD_TEX2IMAGES
|
1550 RADEON_REQUIRE_QUIESCENCE
);
1554 /* Build up a prim_t record:
1556 prim
.start
= elts
.start
;
1557 prim
.finish
= elts
.end
;
1558 prim
.prim
= elts
.prim
;
1559 prim
.offset
= 0; /* offset from start of dma buffers */
1560 prim
.numverts
= RADEON_MAX_VB_VERTS
; /* duh */
1561 prim
.vc_format
= dev_priv
->sarea_priv
->vc_format
;
1563 radeon_cp_dispatch_indices( dev
, buf
, &prim
,
1564 dev_priv
->sarea_priv
->boxes
,
1565 dev_priv
->sarea_priv
->nbox
);
1567 radeon_cp_discard_buffer( dev
, buf
);
1574 int radeon_cp_texture( struct inode
*inode
, struct file
*filp
,
1575 unsigned int cmd
, unsigned long arg
)
1577 drm_file_t
*priv
= filp
->private_data
;
1578 drm_device_t
*dev
= priv
->dev
;
1579 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1580 drm_radeon_texture_t tex
;
1581 drm_radeon_tex_image_t image
;
1584 LOCK_TEST_WITH_RETURN( dev
);
1586 if ( copy_from_user( &tex
, (drm_radeon_texture_t
*)arg
, sizeof(tex
) ) )
1589 if ( tex
.image
== NULL
) {
1590 DRM_ERROR( "null texture image!\n" );
1594 if ( copy_from_user( &image
,
1595 (drm_radeon_tex_image_t
*)tex
.image
,
1599 RING_SPACE_TEST_WITH_RETURN( dev_priv
);
1600 VB_AGE_TEST_WITH_RETURN( dev_priv
);
1602 ret
= radeon_cp_dispatch_texture( dev
, &tex
, &image
);
1608 int radeon_cp_stipple( struct inode
*inode
, struct file
*filp
,
1609 unsigned int cmd
, unsigned long arg
)
1611 drm_file_t
*priv
= filp
->private_data
;
1612 drm_device_t
*dev
= priv
->dev
;
1613 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1614 drm_radeon_stipple_t stipple
;
1617 LOCK_TEST_WITH_RETURN( dev
);
1619 if ( copy_from_user( &stipple
, (drm_radeon_stipple_t
*)arg
,
1623 if ( copy_from_user( &mask
, stipple
.mask
, 32 * sizeof(u32
) ) )
1626 RING_SPACE_TEST_WITH_RETURN( dev_priv
);
1628 radeon_cp_dispatch_stipple( dev
, mask
);
1634 int radeon_cp_indirect( struct inode
*inode
, struct file
*filp
,
1635 unsigned int cmd
, unsigned long arg
)
1637 drm_file_t
*priv
= filp
->private_data
;
1638 drm_device_t
*dev
= priv
->dev
;
1639 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1640 drm_device_dma_t
*dma
= dev
->dma
;
1642 drm_radeon_indirect_t indirect
;
1645 LOCK_TEST_WITH_RETURN( dev
);
1648 DRM_ERROR( "%s called with no initialization\n", __FUNCTION__
);
1652 if ( copy_from_user( &indirect
, (drm_radeon_indirect_t
*)arg
,
1653 sizeof(indirect
) ) )
1656 DRM_DEBUG( "indirect: idx=%d s=%d e=%d d=%d\n",
1657 indirect
.idx
, indirect
.start
,
1658 indirect
.end
, indirect
.discard
);
1660 if ( indirect
.idx
< 0 || indirect
.idx
>= dma
->buf_count
) {
1661 DRM_ERROR( "buffer index %d (of %d max)\n",
1662 indirect
.idx
, dma
->buf_count
- 1 );
1666 buf
= dma
->buflist
[indirect
.idx
];
1668 if ( buf
->pid
!= current
->pid
) {
1669 DRM_ERROR( "process %d using buffer owned by %d\n",
1670 current
->pid
, buf
->pid
);
1673 if ( buf
->pending
) {
1674 DRM_ERROR( "sending pending buffer %d\n", indirect
.idx
);
1678 if ( indirect
.start
< buf
->used
) {
1679 DRM_ERROR( "reusing indirect: start=0x%x actual=0x%x\n",
1680 indirect
.start
, buf
->used
);
1684 RING_SPACE_TEST_WITH_RETURN( dev_priv
);
1685 VB_AGE_TEST_WITH_RETURN( dev_priv
);
1687 buf
->used
= indirect
.end
;
1689 /* Wait for the 3D stream to idle before the indirect buffer
1690 * containing 2D acceleration commands is processed.
1694 RADEON_WAIT_UNTIL_3D_IDLE();
1698 /* Dispatch the indirect buffer full of commands from the
1699 * X server. This is insecure and is thus only available to
1700 * privileged clients.
1702 radeon_cp_dispatch_indirect( dev
, buf
, indirect
.start
, indirect
.end
);
1703 if (indirect
.discard
) {
1704 radeon_cp_discard_buffer( dev
, buf
);
1712 int radeon_cp_vertex2(struct inode
*inode
, struct file
*filp
, unsigned int cmd
, unsigned long data
)
1714 drm_file_t
*priv
= filp
->private_data
;
1715 drm_device_t
*dev
= priv
->dev
;
1716 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1717 drm_radeon_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
1718 drm_device_dma_t
*dma
= dev
->dma
;
1720 drm_radeon_vertex2_t vertex
;
1722 unsigned char laststate
;
1724 LOCK_TEST_WITH_RETURN( dev
);
1727 DRM_ERROR( "%s called with no initialization\n", __FUNCTION__
);
1731 DRM_COPY_FROM_USER_IOCTL( vertex
, (drm_radeon_vertex2_t
*)data
,
1734 DRM_DEBUG( "pid=%d index=%d discard=%d\n",
1736 vertex
.idx
, vertex
.discard
);
1738 if ( vertex
.idx
< 0 || vertex
.idx
>= dma
->buf_count
) {
1739 DRM_ERROR( "buffer index %d (of %d max)\n",
1740 vertex
.idx
, dma
->buf_count
- 1 );
1744 RING_SPACE_TEST_WITH_RETURN( dev_priv
);
1745 VB_AGE_TEST_WITH_RETURN( dev_priv
);
1747 buf
= dma
->buflist
[vertex
.idx
];
1749 if ( buf
->pid
!= current
->pid
) {
1750 DRM_ERROR( "process %d using buffer owned by %d\n",
1751 current
->pid
, buf
->pid
);
1755 if ( buf
->pending
) {
1756 DRM_ERROR( "sending pending buffer %d\n", vertex
.idx
);
1760 if (sarea_priv
->nbox
> RADEON_NR_SAREA_CLIPRECTS
)
1763 for (laststate
= 0xff, i
= 0 ; i
< vertex
.nr_prims
; i
++) {
1764 drm_radeon_prim_t prim
;
1765 drm_radeon_tcl_prim_t tclprim
;
1767 if ( copy_from_user( &prim
, &vertex
.prim
[i
], sizeof(prim
) ) )
1770 if ( prim
.stateidx
!= laststate
) {
1771 drm_radeon_state_t state
;
1773 if ( copy_from_user( &state
,
1774 &vertex
.state
[prim
.stateidx
],
1778 radeon_emit_state2( dev_priv
, &state
);
1780 laststate
= prim
.stateidx
;
1783 tclprim
.start
= prim
.start
;
1784 tclprim
.finish
= prim
.finish
;
1785 tclprim
.prim
= prim
.prim
;
1786 tclprim
.vc_format
= prim
.vc_format
;
1788 if ( prim
.prim
& RADEON_PRIM_WALK_IND
) {
1789 tclprim
.offset
= prim
.numverts
* 64;
1790 tclprim
.numverts
= RADEON_MAX_VB_VERTS
; /* duh */
1792 radeon_cp_dispatch_indices( dev
, buf
, &tclprim
,
1796 tclprim
.numverts
= prim
.numverts
;
1797 tclprim
.offset
= 0; /* not used */
1799 radeon_cp_dispatch_vertex( dev
, buf
, &tclprim
,
1804 if (sarea_priv
->nbox
== 1)
1805 sarea_priv
->nbox
= 0;
1808 if ( vertex
.discard
) {
1809 radeon_cp_discard_buffer( dev
, buf
);
1817 static int radeon_emit_packets(
1818 drm_radeon_private_t
*dev_priv
,
1819 drm_radeon_cmd_header_t header
,
1820 drm_radeon_cmd_buffer_t
*cmdbuf
)
1822 int id
= (int)header
.packet
.packet_id
;
1824 int *data
= (int *)cmdbuf
->buf
;
1827 if (id
>= RADEON_MAX_STATE_PACKETS
)
1830 sz
= packet
[id
].len
;
1831 reg
= packet
[id
].start
;
1833 if (sz
* sizeof(int) > cmdbuf
->bufsz
)
1837 OUT_RING( CP_PACKET0( reg
, (sz
-1) ) );
1838 OUT_RING_USER_TABLE( data
, sz
);
1841 cmdbuf
->buf
+= sz
* sizeof(int);
1842 cmdbuf
->bufsz
-= sz
* sizeof(int);
1846 static __inline__
int radeon_emit_scalars(
1847 drm_radeon_private_t
*dev_priv
,
1848 drm_radeon_cmd_header_t header
,
1849 drm_radeon_cmd_buffer_t
*cmdbuf
)
1851 int sz
= header
.scalars
.count
;
1852 int *data
= (int *)cmdbuf
->buf
;
1853 int start
= header
.scalars
.offset
;
1854 int stride
= header
.scalars
.stride
;
1858 OUT_RING( CP_PACKET0( RADEON_SE_TCL_SCALAR_INDX_REG
, 0 ) );
1859 OUT_RING( start
| (stride
<< RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT
));
1860 OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_SCALAR_DATA_REG
, sz
-1 ) );
1861 OUT_RING_USER_TABLE( data
, sz
);
1863 cmdbuf
->buf
+= sz
* sizeof(int);
1864 cmdbuf
->bufsz
-= sz
* sizeof(int);
1870 static __inline__
int radeon_emit_scalars2(
1871 drm_radeon_private_t
*dev_priv
,
1872 drm_radeon_cmd_header_t header
,
1873 drm_radeon_cmd_buffer_t
*cmdbuf
)
1875 int sz
= header
.scalars
.count
;
1876 int *data
= (int *)cmdbuf
->buf
;
1877 int start
= ((unsigned int)header
.scalars
.offset
) + 0x100;
1878 int stride
= header
.scalars
.stride
;
1882 OUT_RING( CP_PACKET0( RADEON_SE_TCL_SCALAR_INDX_REG
, 0 ) );
1883 OUT_RING( start
| (stride
<< RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT
));
1884 OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_SCALAR_DATA_REG
, sz
-1 ) );
1885 OUT_RING_USER_TABLE( data
, sz
);
1887 cmdbuf
->buf
+= sz
* sizeof(int);
1888 cmdbuf
->bufsz
-= sz
* sizeof(int);
1892 static __inline__
int radeon_emit_vectors(
1893 drm_radeon_private_t
*dev_priv
,
1894 drm_radeon_cmd_header_t header
,
1895 drm_radeon_cmd_buffer_t
*cmdbuf
)
1897 int sz
= header
.vectors
.count
;
1898 int *data
= (int *)cmdbuf
->buf
;
1899 int start
= header
.vectors
.offset
;
1900 int stride
= header
.vectors
.stride
;
1904 OUT_RING( CP_PACKET0( RADEON_SE_TCL_VECTOR_INDX_REG
, 0 ) );
1905 OUT_RING( start
| (stride
<< RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT
));
1906 OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_VECTOR_DATA_REG
, (sz
-1) ) );
1907 OUT_RING_USER_TABLE( data
, sz
);
1910 cmdbuf
->buf
+= sz
* sizeof(int);
1911 cmdbuf
->bufsz
-= sz
* sizeof(int);
1916 static int radeon_emit_packet3( drm_device_t
*dev
,
1917 drm_radeon_cmd_buffer_t
*cmdbuf
)
1919 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1921 int *cmd
= (int *)cmdbuf
->buf
;
1927 if (__get_user( tmp
, &cmd
[0]))
1930 cmdsz
= 2 + ((tmp
& RADEON_CP_PACKET_COUNT_MASK
) >> 16);
1932 if ((tmp
& 0xc0000000) != RADEON_CP_PACKET3
||
1933 cmdsz
* 4 > cmdbuf
->bufsz
)
1936 BEGIN_RING( cmdsz
);
1937 OUT_RING_USER_TABLE( cmd
, cmdsz
);
1940 cmdbuf
->buf
+= cmdsz
* 4;
1941 cmdbuf
->bufsz
-= cmdsz
* 4;
1946 static int radeon_emit_packet3_cliprect( drm_device_t
*dev
,
1947 drm_radeon_cmd_buffer_t
*cmdbuf
,
1950 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1951 drm_clip_rect_t box
;
1953 int *cmd
= (int *)cmdbuf
->buf
;
1954 drm_clip_rect_t
*boxes
= cmdbuf
->boxes
;
1960 if (__get_user( tmp
, &cmd
[0]))
1963 cmdsz
= 2 + ((tmp
& RADEON_CP_PACKET_COUNT_MASK
) >> 16);
1965 if ((tmp
& 0xc0000000) != RADEON_CP_PACKET3
||
1966 cmdsz
* 4 > cmdbuf
->bufsz
)
1973 if ( i
< cmdbuf
->nbox
) {
1974 if (__copy_from_user( &box
, &boxes
[i
], sizeof(box
) ))
1976 /* FIXME The second and subsequent times round
1977 * this loop, send a WAIT_UNTIL_3D_IDLE before
1978 * calling emit_clip_rect(). This fixes a
1979 * lockup on fast machines when sending
1980 * several cliprects with a cmdbuf, as when
1981 * waving a 2D window over a 3D
1982 * window. Something in the commands from user
1983 * space seems to hang the card when they're
1984 * sent several times in a row. That would be
1985 * the correct place to fix it but this works
1986 * around it until I can figure that out - Tim
1990 RADEON_WAIT_UNTIL_3D_IDLE();
1993 radeon_emit_clip_rect( dev_priv
, &box
);
1996 BEGIN_RING( cmdsz
);
1997 OUT_RING_USER_TABLE( cmd
, cmdsz
);
2000 } while ( ++i
< cmdbuf
->nbox
);
2001 if (cmdbuf
->nbox
== 1)
2005 cmdbuf
->buf
+= cmdsz
* 4;
2006 cmdbuf
->bufsz
-= cmdsz
* 4;
2011 static int radeon_emit_wait( drm_device_t
*dev
, int flags
)
2013 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2016 DRM_DEBUG("%s: %x\n", __FUNCTION__
, flags
);
2018 case RADEON_WAIT_2D
:
2020 RADEON_WAIT_UNTIL_2D_IDLE();
2023 case RADEON_WAIT_3D
:
2025 RADEON_WAIT_UNTIL_3D_IDLE();
2028 case RADEON_WAIT_2D
|RADEON_WAIT_3D
:
2030 RADEON_WAIT_UNTIL_IDLE();
2040 int radeon_cp_cmdbuf(struct inode
*inode
, struct file
*filp
, unsigned int cmd
, unsigned long data
)
2042 drm_file_t
*priv
= filp
->private_data
;
2043 drm_device_t
*dev
= priv
->dev
;
2044 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2045 drm_device_dma_t
*dma
= dev
->dma
;
2048 drm_radeon_cmd_buffer_t cmdbuf
;
2049 drm_radeon_cmd_header_t header
;
2052 LOCK_TEST_WITH_RETURN( dev
);
2055 DRM_ERROR( "%s called with no initialization\n", __FUNCTION__
);
2059 DRM_COPY_FROM_USER_IOCTL( cmdbuf
, (drm_radeon_cmd_buffer_t
*)data
,
2062 RING_SPACE_TEST_WITH_RETURN( dev_priv
);
2063 VB_AGE_TEST_WITH_RETURN( dev_priv
);
2066 if (verify_area( VERIFY_READ
, cmdbuf
.buf
, cmdbuf
.bufsz
))
2070 verify_area( VERIFY_READ
, cmdbuf
.boxes
,
2071 cmdbuf
.nbox
* sizeof(drm_clip_rect_t
)))
2074 orig_nbox
= cmdbuf
.nbox
;
2076 while ( cmdbuf
.bufsz
>= sizeof(header
) ) {
2078 if (__get_user( header
.i
, (int *)cmdbuf
.buf
)) {
2079 DRM_ERROR("__get_user %p\n", cmdbuf
.buf
);
2083 cmdbuf
.buf
+= sizeof(header
);
2084 cmdbuf
.bufsz
-= sizeof(header
);
2086 switch (header
.header
.cmd_type
) {
2087 case RADEON_CMD_PACKET
:
2088 DRM_DEBUG("RADEON_CMD_PACKET\n");
2089 if (radeon_emit_packets( dev_priv
, header
, &cmdbuf
)) {
2090 DRM_ERROR("radeon_emit_packets failed\n");
2095 case RADEON_CMD_SCALARS
:
2096 DRM_DEBUG("RADEON_CMD_SCALARS\n");
2097 if (radeon_emit_scalars( dev_priv
, header
, &cmdbuf
)) {
2098 DRM_ERROR("radeon_emit_scalars failed\n");
2103 case RADEON_CMD_VECTORS
:
2104 DRM_DEBUG("RADEON_CMD_VECTORS\n");
2105 if (radeon_emit_vectors( dev_priv
, header
, &cmdbuf
)) {
2106 DRM_ERROR("radeon_emit_vectors failed\n");
2111 case RADEON_CMD_DMA_DISCARD
:
2112 DRM_DEBUG("RADEON_CMD_DMA_DISCARD\n");
2113 idx
= header
.dma
.buf_idx
;
2114 if ( idx
< 0 || idx
>= dma
->buf_count
) {
2115 DRM_ERROR( "buffer index %d (of %d max)\n",
2116 idx
, dma
->buf_count
- 1 );
2120 buf
= dma
->buflist
[idx
];
2121 if ( buf
->pid
!= current
->pid
|| buf
->pending
) {
2122 DRM_ERROR( "bad buffer\n" );
2126 radeon_cp_discard_buffer( dev
, buf
);
2129 case RADEON_CMD_PACKET3
:
2130 DRM_DEBUG("RADEON_CMD_PACKET3\n");
2131 if (radeon_emit_packet3( dev
, &cmdbuf
)) {
2132 DRM_ERROR("radeon_emit_packet3 failed\n");
2137 case RADEON_CMD_PACKET3_CLIP
:
2138 DRM_DEBUG("RADEON_CMD_PACKET3_CLIP\n");
2139 if (radeon_emit_packet3_cliprect( dev
, &cmdbuf
, orig_nbox
)) {
2140 DRM_ERROR("radeon_emit_packet3_clip failed\n");
2145 case RADEON_CMD_SCALARS2
:
2146 DRM_DEBUG("RADEON_CMD_SCALARS2\n");
2147 if (radeon_emit_scalars2( dev_priv
, header
, &cmdbuf
)) {
2148 DRM_ERROR("radeon_emit_scalars2 failed\n");
2153 case RADEON_CMD_WAIT
:
2154 DRM_DEBUG("RADEON_CMD_WAIT\n");
2155 if (radeon_emit_wait( dev
, header
.wait
.flags
)) {
2156 DRM_ERROR("radeon_emit_wait failed\n");
2161 DRM_ERROR("bad cmd_type %d at %p\n",
2162 header
.header
.cmd_type
,
2163 cmdbuf
.buf
- sizeof(header
));
2169 DRM_DEBUG("DONE\n");
2176 int radeon_cp_getparam(struct inode
*inode
, struct file
*filp
, unsigned int cmd
, unsigned long data
)
2178 drm_file_t
*priv
= filp
->private_data
;
2179 drm_device_t
*dev
= priv
->dev
;
2180 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2181 drm_radeon_getparam_t param
;
2185 DRM_ERROR( "%s called with no initialization\n", __FUNCTION__
);
2189 DRM_COPY_FROM_USER_IOCTL( param
, (drm_radeon_getparam_t
*)data
,
2192 DRM_DEBUG( "pid=%d\n", current
->pid
);
2194 switch( param
.param
) {
2195 case RADEON_PARAM_AGP_BUFFER_OFFSET
:
2196 value
= dev_priv
->agp_buffers_offset
;
2198 case RADEON_PARAM_LAST_FRAME
:
2199 dev_priv
->stats
.last_frame_reads
++;
2200 value
= GET_SCRATCH( 0 );
2202 case RADEON_PARAM_LAST_DISPATCH
:
2203 value
= GET_SCRATCH( 1 );
2205 case RADEON_PARAM_LAST_CLEAR
:
2206 dev_priv
->stats
.last_clear_reads
++;
2207 value
= GET_SCRATCH( 2 );
2209 case RADEON_PARAM_IRQ_NR
:
2212 case RADEON_PARAM_AGP_BASE
:
2213 value
= dev_priv
->agp_vm_start
;
2219 if ( copy_to_user( param
.value
, &value
, sizeof(int) ) ) {
2220 DRM_ERROR( "copy_to_user\n" );