30 */ 31 32#include "dev/drm/radeon.h" 33#include "dev/drm/drmP.h" 34#include "dev/drm/drm.h" 35#include "dev/drm/drm_sarea.h" 36#include "dev/drm/radeon_drm.h" 37#include "dev/drm/radeon_drv.h" 38 39 40/* ================================================================ 41 * CP hardware state programming functions 42 */ 43 44static __inline__ void radeon_emit_clip_rect( drm_radeon_private_t *dev_priv, 45 drm_clip_rect_t *box ) 46{ 47 RING_LOCALS; 48 49 DRM_DEBUG( " box: x1=%d y1=%d x2=%d y2=%d\n", 50 box->x1, box->y1, box->x2, box->y2 ); 51 52 BEGIN_RING( 4 ); 53 OUT_RING( CP_PACKET0( RADEON_RE_TOP_LEFT, 0 ) ); 54 OUT_RING( (box->y1 << 16) | box->x1 ); 55 OUT_RING( CP_PACKET0( RADEON_RE_WIDTH_HEIGHT, 0 ) ); 56 OUT_RING( ((box->y2 - 1) << 16) | (box->x2 - 1) ); 57 ADVANCE_RING(); 58} 59 60/* Emit 1.1 state 61 */ 62static void radeon_emit_state( drm_radeon_private_t *dev_priv, 63 drm_radeon_context_regs_t *ctx, 64 drm_radeon_texture_regs_t *tex, 65 unsigned int dirty ) 66{ 67 RING_LOCALS; 68 DRM_DEBUG( "dirty=0x%08x\n", dirty ); 69 70 if ( dirty & RADEON_UPLOAD_CONTEXT ) { 71 BEGIN_RING( 14 ); 72 OUT_RING( CP_PACKET0( RADEON_PP_MISC, 6 ) ); 73 OUT_RING( ctx->pp_misc ); 74 OUT_RING( ctx->pp_fog_color ); 75 OUT_RING( ctx->re_solid_color ); 76 OUT_RING( ctx->rb3d_blendcntl ); 77 OUT_RING( ctx->rb3d_depthoffset ); 78 OUT_RING( ctx->rb3d_depthpitch ); 79 OUT_RING( ctx->rb3d_zstencilcntl ); 80 OUT_RING( CP_PACKET0( RADEON_PP_CNTL, 2 ) ); 81 OUT_RING( ctx->pp_cntl ); 82 OUT_RING( ctx->rb3d_cntl ); 83 OUT_RING( ctx->rb3d_coloroffset ); 84 OUT_RING( CP_PACKET0( RADEON_RB3D_COLORPITCH, 0 ) ); 85 OUT_RING( ctx->rb3d_colorpitch ); 86 ADVANCE_RING(); 87 } 88 89 if ( dirty & RADEON_UPLOAD_VERTFMT ) { 90 BEGIN_RING( 2 ); 91 OUT_RING( CP_PACKET0( RADEON_SE_COORD_FMT, 0 ) ); 92 OUT_RING( ctx->se_coord_fmt ); 93 ADVANCE_RING(); 94 } 95 96 if ( dirty & RADEON_UPLOAD_LINE ) { 97 BEGIN_RING( 5 ); 98 OUT_RING( CP_PACKET0( RADEON_RE_LINE_PATTERN, 1 ) ); 99 OUT_RING( ctx->re_line_pattern ); 100 OUT_RING( ctx->re_line_state ); 101 OUT_RING( CP_PACKET0( RADEON_SE_LINE_WIDTH, 0 ) ); 102 OUT_RING( ctx->se_line_width ); 103 ADVANCE_RING(); 104 } 105 106 if ( dirty & RADEON_UPLOAD_BUMPMAP ) { 107 BEGIN_RING( 5 ); 108 OUT_RING( CP_PACKET0( RADEON_PP_LUM_MATRIX, 0 ) ); 109 OUT_RING( ctx->pp_lum_matrix ); 110 OUT_RING( CP_PACKET0( RADEON_PP_ROT_MATRIX_0, 1 ) ); 111 OUT_RING( ctx->pp_rot_matrix_0 ); 112 OUT_RING( ctx->pp_rot_matrix_1 ); 113 ADVANCE_RING(); 114 } 115 116 if ( dirty & RADEON_UPLOAD_MASKS ) { 117 BEGIN_RING( 4 ); 118 OUT_RING( CP_PACKET0( RADEON_RB3D_STENCILREFMASK, 2 ) ); 119 OUT_RING( ctx->rb3d_stencilrefmask ); 120 OUT_RING( ctx->rb3d_ropcntl ); 121 OUT_RING( ctx->rb3d_planemask ); 122 ADVANCE_RING(); 123 } 124 125 if ( dirty & RADEON_UPLOAD_VIEWPORT ) { 126 BEGIN_RING( 7 ); 127 OUT_RING( CP_PACKET0( RADEON_SE_VPORT_XSCALE, 5 ) ); 128 OUT_RING( ctx->se_vport_xscale ); 129 OUT_RING( ctx->se_vport_xoffset ); 130 OUT_RING( ctx->se_vport_yscale ); 131 OUT_RING( ctx->se_vport_yoffset ); 132 OUT_RING( ctx->se_vport_zscale ); 133 OUT_RING( ctx->se_vport_zoffset ); 134 ADVANCE_RING(); 135 } 136 137 if ( dirty & RADEON_UPLOAD_SETUP ) { 138 BEGIN_RING( 4 ); 139 OUT_RING( CP_PACKET0( RADEON_SE_CNTL, 0 ) ); 140 OUT_RING( ctx->se_cntl ); 141 OUT_RING( CP_PACKET0( RADEON_SE_CNTL_STATUS, 0 ) ); 142 OUT_RING( ctx->se_cntl_status ); 143 ADVANCE_RING(); 144 } 145 146 if ( dirty & RADEON_UPLOAD_MISC ) { 147 BEGIN_RING( 2 ); 148 OUT_RING( CP_PACKET0( RADEON_RE_MISC, 0 ) ); 149 OUT_RING( ctx->re_misc ); 150 ADVANCE_RING(); 151 } 152 153 if ( dirty & RADEON_UPLOAD_TEX0 ) { 154 BEGIN_RING( 9 ); 155 OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_0, 5 ) ); 156 OUT_RING( tex[0].pp_txfilter ); 157 OUT_RING( tex[0].pp_txformat ); 158 OUT_RING( tex[0].pp_txoffset ); 159 OUT_RING( tex[0].pp_txcblend ); 160 OUT_RING( tex[0].pp_txablend ); 161 OUT_RING( tex[0].pp_tfactor ); 162 OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_0, 0 ) ); 163 OUT_RING( tex[0].pp_border_color ); 164 ADVANCE_RING(); 165 } 166 167 if ( dirty & RADEON_UPLOAD_TEX1 ) { 168 BEGIN_RING( 9 ); 169 OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_1, 5 ) ); 170 OUT_RING( tex[1].pp_txfilter ); 171 OUT_RING( tex[1].pp_txformat ); 172 OUT_RING( tex[1].pp_txoffset ); 173 OUT_RING( tex[1].pp_txcblend ); 174 OUT_RING( tex[1].pp_txablend ); 175 OUT_RING( tex[1].pp_tfactor ); 176 OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_1, 0 ) ); 177 OUT_RING( tex[1].pp_border_color ); 178 ADVANCE_RING(); 179 } 180 181 if ( dirty & RADEON_UPLOAD_TEX2 ) { 182 BEGIN_RING( 9 ); 183 OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_2, 5 ) ); 184 OUT_RING( tex[2].pp_txfilter ); 185 OUT_RING( tex[2].pp_txformat ); 186 OUT_RING( tex[2].pp_txoffset ); 187 OUT_RING( tex[2].pp_txcblend ); 188 OUT_RING( tex[2].pp_txablend ); 189 OUT_RING( tex[2].pp_tfactor ); 190 OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_2, 0 ) ); 191 OUT_RING( tex[2].pp_border_color ); 192 ADVANCE_RING(); 193 } 194} 195 196/* Emit 1.2 state 197 */ 198static void radeon_emit_state2( drm_radeon_private_t *dev_priv, 199 drm_radeon_state_t *state ) 200{ 201 RING_LOCALS; 202 203 if (state->dirty & RADEON_UPLOAD_ZBIAS) { 204 BEGIN_RING( 3 ); 205 OUT_RING( CP_PACKET0( RADEON_SE_ZBIAS_FACTOR, 1 ) ); 206 OUT_RING( state->context2.se_zbias_factor ); 207 OUT_RING( state->context2.se_zbias_constant ); 208 ADVANCE_RING(); 209 } 210 211 radeon_emit_state( dev_priv, &state->context, 212 state->tex, state->dirty ); 213} 214 215/* New (1.3) state mechanism. 3 commands (packet, scalar, vector) in 216 * 1.3 cmdbuffers allow all previous state to be updated as well as 217 * the tcl scalar and vector areas. 218 */ 219static struct { 220 int start; 221 int len; 222 const char *name; 223} packet[RADEON_MAX_STATE_PACKETS] = { 224 { RADEON_PP_MISC,7,"RADEON_PP_MISC" }, 225 { RADEON_PP_CNTL,3,"RADEON_PP_CNTL" }, 226 { RADEON_RB3D_COLORPITCH,1,"RADEON_RB3D_COLORPITCH" }, 227 { RADEON_RE_LINE_PATTERN,2,"RADEON_RE_LINE_PATTERN" }, 228 { RADEON_SE_LINE_WIDTH,1,"RADEON_SE_LINE_WIDTH" }, 229 { RADEON_PP_LUM_MATRIX,1,"RADEON_PP_LUM_MATRIX" }, 230 { RADEON_PP_ROT_MATRIX_0,2,"RADEON_PP_ROT_MATRIX_0" }, 231 { RADEON_RB3D_STENCILREFMASK,3,"RADEON_RB3D_STENCILREFMASK" }, 232 { RADEON_SE_VPORT_XSCALE,6,"RADEON_SE_VPORT_XSCALE" }, 233 { RADEON_SE_CNTL,2,"RADEON_SE_CNTL" }, 234 { RADEON_SE_CNTL_STATUS,1,"RADEON_SE_CNTL_STATUS" }, 235 { RADEON_RE_MISC,1,"RADEON_RE_MISC" }, 236 { RADEON_PP_TXFILTER_0,6,"RADEON_PP_TXFILTER_0" }, 237 { RADEON_PP_BORDER_COLOR_0,1,"RADEON_PP_BORDER_COLOR_0" }, 238 { RADEON_PP_TXFILTER_1,6,"RADEON_PP_TXFILTER_1" }, 239 { RADEON_PP_BORDER_COLOR_1,1,"RADEON_PP_BORDER_COLOR_1" }, 240 { RADEON_PP_TXFILTER_2,6,"RADEON_PP_TXFILTER_2" }, 241 { RADEON_PP_BORDER_COLOR_2,1,"RADEON_PP_BORDER_COLOR_2" }, 242 { RADEON_SE_ZBIAS_FACTOR,2,"RADEON_SE_ZBIAS_FACTOR" }, 243 { RADEON_SE_TCL_OUTPUT_VTX_FMT,11,"RADEON_SE_TCL_OUTPUT_VTX_FMT" }, 244 { RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED,17,"RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED" }, 245 { R200_PP_TXCBLEND_0, 4, "R200_PP_TXCBLEND_0" }, 246 { R200_PP_TXCBLEND_1, 4, "R200_PP_TXCBLEND_1" }, 247 { R200_PP_TXCBLEND_2, 4, "R200_PP_TXCBLEND_2" }, 248 { R200_PP_TXCBLEND_3, 4, "R200_PP_TXCBLEND_3" }, 249 { R200_PP_TXCBLEND_4, 4, "R200_PP_TXCBLEND_4" }, 250 { R200_PP_TXCBLEND_5, 4, "R200_PP_TXCBLEND_5" }, 251 { R200_PP_TXCBLEND_6, 4, "R200_PP_TXCBLEND_6" }, 252 { R200_PP_TXCBLEND_7, 4, "R200_PP_TXCBLEND_7" }, 253 { R200_SE_TCL_LIGHT_MODEL_CTL_0, 6, "R200_SE_TCL_LIGHT_MODEL_CTL_0" }, 254 { R200_PP_TFACTOR_0, 6, "R200_PP_TFACTOR_0" }, 255 { R200_SE_VTX_FMT_0, 4, "R200_SE_VTX_FMT_0" }, 256 { R200_SE_VAP_CNTL, 1, "R200_SE_VAP_CNTL" }, 257 { R200_SE_TCL_MATRIX_SEL_0, 5, "R200_SE_TCL_MATRIX_SEL_0" }, 258 { R200_SE_TCL_TEX_PROC_CTL_2, 5, "R200_SE_TCL_TEX_PROC_CTL_2" }, 259 { R200_SE_TCL_UCP_VERT_BLEND_CTL, 1, "R200_SE_TCL_UCP_VERT_BLEND_CTL" }, 260 { R200_PP_TXFILTER_0, 6, "R200_PP_TXFILTER_0" }, 261 { R200_PP_TXFILTER_1, 6, "R200_PP_TXFILTER_1" }, 262 { R200_PP_TXFILTER_2, 6, "R200_PP_TXFILTER_2" }, 263 { R200_PP_TXFILTER_3, 6, "R200_PP_TXFILTER_3" }, 264 { R200_PP_TXFILTER_4, 6, "R200_PP_TXFILTER_4" }, 265 { R200_PP_TXFILTER_5, 6, "R200_PP_TXFILTER_5" }, 266 { R200_PP_TXOFFSET_0, 1, "R200_PP_TXOFFSET_0" }, 267 { R200_PP_TXOFFSET_1, 1, "R200_PP_TXOFFSET_1" }, 268 { R200_PP_TXOFFSET_2, 1, "R200_PP_TXOFFSET_2" }, 269 { R200_PP_TXOFFSET_3, 1, "R200_PP_TXOFFSET_3" }, 270 { R200_PP_TXOFFSET_4, 1, "R200_PP_TXOFFSET_4" }, 271 { R200_PP_TXOFFSET_5, 1, "R200_PP_TXOFFSET_5" }, 272 { R200_SE_VTE_CNTL, 1, "R200_SE_VTE_CNTL" }, 273 { R200_SE_TCL_OUTPUT_VTX_COMP_SEL, 1, "R200_SE_TCL_OUTPUT_VTX_COMP_SEL" }, 274 { R200_PP_TAM_DEBUG3, 1, "R200_PP_TAM_DEBUG3" }, 275 { R200_PP_CNTL_X, 1, "R200_PP_CNTL_X" }, 276 { R200_RB3D_DEPTHXY_OFFSET, 1, "R200_RB3D_DEPTHXY_OFFSET" }, 277 { R200_RE_AUX_SCISSOR_CNTL, 1, "R200_RE_AUX_SCISSOR_CNTL" }, 278 { R200_RE_SCISSOR_TL_0, 2, "R200_RE_SCISSOR_TL_0" }, 279 { R200_RE_SCISSOR_TL_1, 2, "R200_RE_SCISSOR_TL_1" }, 280 { R200_RE_SCISSOR_TL_2, 2, "R200_RE_SCISSOR_TL_2" }, 281 { R200_SE_VAP_CNTL_STATUS, 1, "R200_SE_VAP_CNTL_STATUS" }, 282 { R200_SE_VTX_STATE_CNTL, 1, "R200_SE_VTX_STATE_CNTL" }, 283 { R200_RE_POINTSIZE, 1, "R200_RE_POINTSIZE" }, 284 { R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0, 4, "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0" }, 285 { R200_PP_CUBIC_FACES_0, 1, "R200_PP_CUBIC_FACES_0" }, /* 61 */ 286 { R200_PP_CUBIC_OFFSET_F1_0, 5, "R200_PP_CUBIC_OFFSET_F1_0" }, /* 62 */ 287 { R200_PP_CUBIC_FACES_1, 1, "R200_PP_CUBIC_FACES_1" }, 288 { R200_PP_CUBIC_OFFSET_F1_1, 5, "R200_PP_CUBIC_OFFSET_F1_1" }, 289 { R200_PP_CUBIC_FACES_2, 1, "R200_PP_CUBIC_FACES_2" }, 290 { R200_PP_CUBIC_OFFSET_F1_2, 5, "R200_PP_CUBIC_OFFSET_F1_2" }, 291 { R200_PP_CUBIC_FACES_3, 1, "R200_PP_CUBIC_FACES_3" }, 292 { R200_PP_CUBIC_OFFSET_F1_3, 5, "R200_PP_CUBIC_OFFSET_F1_3" }, 293 { R200_PP_CUBIC_FACES_4, 1, "R200_PP_CUBIC_FACES_4" }, 294 { R200_PP_CUBIC_OFFSET_F1_4, 5, "R200_PP_CUBIC_OFFSET_F1_4" }, 295 { R200_PP_CUBIC_FACES_5, 1, "R200_PP_CUBIC_FACES_5" }, 296 { R200_PP_CUBIC_OFFSET_F1_5, 5, "R200_PP_CUBIC_OFFSET_F1_5" }, 297 { RADEON_PP_TEX_SIZE_0, 2, "RADEON_PP_TEX_SIZE_0" }, 298 { RADEON_PP_TEX_SIZE_1, 2, "RADEON_PP_TEX_SIZE_1" }, 299 { RADEON_PP_TEX_SIZE_2, 2, "RADEON_PP_TEX_SIZE_1" }, 300}; 301 302 303 304/* ================================================================ 305 * Performance monitoring functions 306 */ 307 308static void radeon_clear_box( drm_radeon_private_t *dev_priv, 309 int x, int y, int w, int h, 310 int r, int g, int b ) 311{ 312 u32 color; 313 RING_LOCALS; 314 315 x += dev_priv->sarea_priv->boxes[0].x1; 316 y += dev_priv->sarea_priv->boxes[0].y1; 317 318 switch ( dev_priv->color_fmt ) { 319 case RADEON_COLOR_FORMAT_RGB565: 320 color = (((r & 0xf8) << 8) | 321 ((g & 0xfc) << 3) | 322 ((b & 0xf8) >> 3)); 323 break; 324 case RADEON_COLOR_FORMAT_ARGB8888: 325 default: 326 color = (((0xff) << 24) | (r << 16) | (g << 8) | b); 327 break; 328 } 329 330 BEGIN_RING( 4 ); 331 RADEON_WAIT_UNTIL_3D_IDLE(); 332 OUT_RING( CP_PACKET0( RADEON_DP_WRITE_MASK, 0 ) ); 333 OUT_RING( 0xffffffff ); 334 ADVANCE_RING(); 335 336 BEGIN_RING( 6 ); 337 338 OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) ); 339 OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL | 340 RADEON_GMC_BRUSH_SOLID_COLOR | 341 (dev_priv->color_fmt << 8) | 342 RADEON_GMC_SRC_DATATYPE_COLOR | 343 RADEON_ROP3_P | 344 RADEON_GMC_CLR_CMP_CNTL_DIS ); 345 346 if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) { 347 OUT_RING( dev_priv->front_pitch_offset ); 348 } else { 349 OUT_RING( dev_priv->back_pitch_offset ); 350 } 351 352 OUT_RING( color ); 353 354 OUT_RING( (x << 16) | y ); 355 OUT_RING( (w << 16) | h ); 356 357 ADVANCE_RING(); 358} 359 360static void radeon_cp_performance_boxes( drm_radeon_private_t *dev_priv ) 361{ 362 /* Collapse various things into a wait flag -- trying to 363 * guess if userspase slept -- better just to have them tell us. 364 */ 365 if (dev_priv->stats.last_frame_reads > 1 || 366 dev_priv->stats.last_clear_reads > dev_priv->stats.clears) { 367 dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; 368 } 369 370 if (dev_priv->stats.freelist_loops) { 371 dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; 372 } 373 374 /* Purple box for page flipping 375 */ 376 if ( dev_priv->stats.boxes & RADEON_BOX_FLIP ) 377 radeon_clear_box( dev_priv, 4, 4, 8, 8, 255, 0, 255 ); 378 379 /* Red box if we have to wait for idle at any point 380 */ 381 if ( dev_priv->stats.boxes & RADEON_BOX_WAIT_IDLE ) 382 radeon_clear_box( dev_priv, 16, 4, 8, 8, 255, 0, 0 ); 383 384 /* Blue box: lost context? 385 */ 386 387 /* Yellow box for texture swaps 388 */ 389 if ( dev_priv->stats.boxes & RADEON_BOX_TEXTURE_LOAD ) 390 radeon_clear_box( dev_priv, 40, 4, 8, 8, 255, 255, 0 ); 391 392 /* Green box if hardware never idles (as far as we can tell) 393 */ 394 if ( !(dev_priv->stats.boxes & RADEON_BOX_DMA_IDLE) ) 395 radeon_clear_box( dev_priv, 64, 4, 8, 8, 0, 255, 0 ); 396 397 398 /* Draw bars indicating number of buffers allocated 399 * (not a great measure, easily confused) 400 */ 401 if (dev_priv->stats.requested_bufs) { 402 if (dev_priv->stats.requested_bufs > 100) 403 dev_priv->stats.requested_bufs = 100; 404 405 radeon_clear_box( dev_priv, 4, 16, 406 dev_priv->stats.requested_bufs, 4, 407 196, 128, 128 ); 408 } 409 410 memset( &dev_priv->stats, 0, sizeof(dev_priv->stats) ); 411 412} 413/* ================================================================ 414 * CP command dispatch functions 415 */ 416 417static void radeon_cp_dispatch_clear( drm_device_t *dev, 418 drm_radeon_clear_t *clear, 419 drm_radeon_clear_rect_t *depth_boxes ) 420{ 421 drm_radeon_private_t *dev_priv = dev->dev_private; 422 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; 423 drm_radeon_depth_clear_t *depth_clear = &dev_priv->depth_clear; 424 int nbox = sarea_priv->nbox; 425 drm_clip_rect_t *pbox = sarea_priv->boxes; 426 unsigned int flags = clear->flags; 427 u32 rb3d_cntl = 0, rb3d_stencilrefmask= 0; 428 int i; 429 RING_LOCALS; 430 DRM_DEBUG( "flags = 0x%x\n", flags ); 431 432 dev_priv->stats.clears++; 433 434 if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) { 435 unsigned int tmp = flags; 436 437 flags &= ~(RADEON_FRONT | RADEON_BACK); 438 if ( tmp & RADEON_FRONT ) flags |= RADEON_BACK; 439 if ( tmp & RADEON_BACK ) flags |= RADEON_FRONT; 440 } 441 442 if ( flags & (RADEON_FRONT | RADEON_BACK) ) { 443 444 BEGIN_RING( 4 ); 445 446 /* Ensure the 3D stream is idle before doing a 447 * 2D fill to clear the front or back buffer. 448 */ 449 RADEON_WAIT_UNTIL_3D_IDLE(); 450 451 OUT_RING( CP_PACKET0( RADEON_DP_WRITE_MASK, 0 ) ); 452 OUT_RING( clear->color_mask ); 453 454 ADVANCE_RING(); 455 456 /* Make sure we restore the 3D state next time. 457 */ 458 dev_priv->sarea_priv->ctx_owner = 0; 459 460 for ( i = 0 ; i < nbox ; i++ ) { 461 int x = pbox[i].x1; 462 int y = pbox[i].y1; 463 int w = pbox[i].x2 - x; 464 int h = pbox[i].y2 - y; 465 466 DRM_DEBUG( "dispatch clear %d,%d-%d,%d flags 0x%x\n", 467 x, y, w, h, flags ); 468 469 if ( flags & RADEON_FRONT ) { 470 BEGIN_RING( 6 ); 471 472 OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) ); 473 OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL | 474 RADEON_GMC_BRUSH_SOLID_COLOR | 475 (dev_priv->color_fmt << 8) | 476 RADEON_GMC_SRC_DATATYPE_COLOR | 477 RADEON_ROP3_P | 478 RADEON_GMC_CLR_CMP_CNTL_DIS ); 479 480 OUT_RING( dev_priv->front_pitch_offset ); 481 OUT_RING( clear->clear_color ); 482 483 OUT_RING( (x << 16) | y ); 484 OUT_RING( (w << 16) | h ); 485 486 ADVANCE_RING(); 487 } 488 489 if ( flags & RADEON_BACK ) { 490 BEGIN_RING( 6 ); 491 492 OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) ); 493 OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL | 494 RADEON_GMC_BRUSH_SOLID_COLOR | 495 (dev_priv->color_fmt << 8) | 496 RADEON_GMC_SRC_DATATYPE_COLOR | 497 RADEON_ROP3_P | 498 RADEON_GMC_CLR_CMP_CNTL_DIS ); 499 500 OUT_RING( dev_priv->back_pitch_offset ); 501 OUT_RING( clear->clear_color ); 502 503 OUT_RING( (x << 16) | y ); 504 OUT_RING( (w << 16) | h ); 505 506 ADVANCE_RING(); 507 } 508 } 509 } 510 511 /* We have to clear the depth and/or stencil buffers by 512 * rendering a quad into just those buffers. Thus, we have to 513 * make sure the 3D engine is configured correctly. 514 */ 515 if ( dev_priv->is_r200 && 516 (flags & (RADEON_DEPTH | RADEON_STENCIL)) ) { 517 518 int tempPP_CNTL; 519 int tempRE_CNTL; 520 int tempRB3D_CNTL; 521 int tempRB3D_ZSTENCILCNTL; 522 int tempRB3D_STENCILREFMASK; 523 int tempRB3D_PLANEMASK; 524 int tempSE_CNTL; 525 int tempSE_VTE_CNTL; 526 int tempSE_VTX_FMT_0; 527 int tempSE_VTX_FMT_1; 528 int tempSE_VAP_CNTL; 529 int tempRE_AUX_SCISSOR_CNTL; 530 531 tempPP_CNTL = 0; 532 tempRE_CNTL = 0; 533 534 tempRB3D_CNTL = depth_clear->rb3d_cntl; 535 tempRB3D_CNTL &= ~(1<<15); /* unset radeon magic flag */ 536 537 tempRB3D_ZSTENCILCNTL = depth_clear->rb3d_zstencilcntl; 538 tempRB3D_STENCILREFMASK = 0x0; 539 540 tempSE_CNTL = depth_clear->se_cntl; 541 542 543 544 /* Disable TCL */ 545 546 tempSE_VAP_CNTL = (/* SE_VAP_CNTL__FORCE_W_TO_ONE_MASK | */ 547 (0x9 << SE_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT)); 548 549 tempRB3D_PLANEMASK = 0x0; 550 551 tempRE_AUX_SCISSOR_CNTL = 0x0; 552 553 tempSE_VTE_CNTL = 554 SE_VTE_CNTL__VTX_XY_FMT_MASK | 555 SE_VTE_CNTL__VTX_Z_FMT_MASK; 556 557 /* Vertex format (X, Y, Z, W)*/ 558 tempSE_VTX_FMT_0 = 559 SE_VTX_FMT_0__VTX_Z0_PRESENT_MASK | 560 SE_VTX_FMT_0__VTX_W0_PRESENT_MASK; 561 tempSE_VTX_FMT_1 = 0x0; 562 563 564 /* 565 * Depth buffer specific enables 566 */ 567 if (flags & RADEON_DEPTH) { 568 /* Enable depth buffer */ 569 tempRB3D_CNTL |= RADEON_Z_ENABLE; 570 } else { 571 /* Disable depth buffer */ 572 tempRB3D_CNTL &= ~RADEON_Z_ENABLE; 573 } 574 575 /* 576 * Stencil buffer specific enables 577 */ 578 if ( flags & RADEON_STENCIL ) { 579 tempRB3D_CNTL |= RADEON_STENCIL_ENABLE; 580 tempRB3D_STENCILREFMASK = clear->depth_mask; 581 } else { 582 tempRB3D_CNTL &= ~RADEON_STENCIL_ENABLE; 583 tempRB3D_STENCILREFMASK = 0x00000000; 584 } 585 586 BEGIN_RING( 26 ); 587 RADEON_WAIT_UNTIL_2D_IDLE(); 588 589 OUT_RING_REG( RADEON_PP_CNTL, tempPP_CNTL ); 590 OUT_RING_REG( R200_RE_CNTL, tempRE_CNTL ); 591 OUT_RING_REG( RADEON_RB3D_CNTL, tempRB3D_CNTL ); 592 OUT_RING_REG( RADEON_RB3D_ZSTENCILCNTL, 593 tempRB3D_ZSTENCILCNTL ); 594 OUT_RING_REG( RADEON_RB3D_STENCILREFMASK, 595 tempRB3D_STENCILREFMASK ); 596 OUT_RING_REG( RADEON_RB3D_PLANEMASK, tempRB3D_PLANEMASK ); 597 OUT_RING_REG( RADEON_SE_CNTL, tempSE_CNTL ); 598 OUT_RING_REG( R200_SE_VTE_CNTL, tempSE_VTE_CNTL ); 599 OUT_RING_REG( R200_SE_VTX_FMT_0, tempSE_VTX_FMT_0 ); 600 OUT_RING_REG( R200_SE_VTX_FMT_1, tempSE_VTX_FMT_1 ); 601 OUT_RING_REG( R200_SE_VAP_CNTL, tempSE_VAP_CNTL ); 602 OUT_RING_REG( R200_RE_AUX_SCISSOR_CNTL, 603 tempRE_AUX_SCISSOR_CNTL ); 604 ADVANCE_RING(); 605 606 /* Make sure we restore the 3D state next time. 607 */ 608 dev_priv->sarea_priv->ctx_owner = 0; 609 610 for ( i = 0 ; i < nbox ; i++ ) { 611 612 /* Funny that this should be required -- 613 * sets top-left? 614 */ 615 radeon_emit_clip_rect( dev_priv, 616 &sarea_priv->boxes[i] ); 617 618 BEGIN_RING( 14 ); 619 OUT_RING( CP_PACKET3( R200_3D_DRAW_IMMD_2, 12 ) ); 620 OUT_RING( (RADEON_PRIM_TYPE_RECT_LIST | 621 RADEON_PRIM_WALK_RING | 622 (3 << RADEON_NUM_VERTICES_SHIFT)) ); 623 OUT_RING( depth_boxes[i].ui[CLEAR_X1] ); 624 OUT_RING( depth_boxes[i].ui[CLEAR_Y1] ); 625 OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); 626 OUT_RING( 0x3f800000 ); 627 OUT_RING( depth_boxes[i].ui[CLEAR_X1] ); 628 OUT_RING( depth_boxes[i].ui[CLEAR_Y2] ); 629 OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); 630 OUT_RING( 0x3f800000 ); 631 OUT_RING( depth_boxes[i].ui[CLEAR_X2] ); 632 OUT_RING( depth_boxes[i].ui[CLEAR_Y2] ); 633 OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); 634 OUT_RING( 0x3f800000 ); 635 ADVANCE_RING(); 636 } 637 } 638 else if ( (flags & (RADEON_DEPTH | RADEON_STENCIL)) ) { 639 640 rb3d_cntl = depth_clear->rb3d_cntl; 641 642 if ( flags & RADEON_DEPTH ) { 643 rb3d_cntl |= RADEON_Z_ENABLE; 644 } else { 645 rb3d_cntl &= ~RADEON_Z_ENABLE; 646 } 647 648 if ( flags & RADEON_STENCIL ) { 649 rb3d_cntl |= RADEON_STENCIL_ENABLE; 650 rb3d_stencilrefmask = clear->depth_mask; /* misnamed field */ 651 } else { 652 rb3d_cntl &= ~RADEON_STENCIL_ENABLE; 653 rb3d_stencilrefmask = 0x00000000; 654 } 655 656 BEGIN_RING( 13 ); 657 RADEON_WAIT_UNTIL_2D_IDLE(); 658 659 OUT_RING( CP_PACKET0( RADEON_PP_CNTL, 1 ) ); 660 OUT_RING( 0x00000000 ); 661 OUT_RING( rb3d_cntl ); 662 663 OUT_RING_REG( RADEON_RB3D_ZSTENCILCNTL, 664 depth_clear->rb3d_zstencilcntl ); 665 OUT_RING_REG( RADEON_RB3D_STENCILREFMASK, 666 rb3d_stencilrefmask ); 667 OUT_RING_REG( RADEON_RB3D_PLANEMASK, 668 0x00000000 ); 669 OUT_RING_REG( RADEON_SE_CNTL, 670 depth_clear->se_cntl ); 671 ADVANCE_RING(); 672 673 /* Make sure we restore the 3D state next time. 674 */ 675 dev_priv->sarea_priv->ctx_owner = 0; 676 677 for ( i = 0 ; i < nbox ; i++ ) { 678 679 /* Funny that this should be required -- 680 * sets top-left? 681 */ 682 radeon_emit_clip_rect( dev_priv, 683 &sarea_priv->boxes[i] ); 684 685 BEGIN_RING( 15 ); 686 687 OUT_RING( CP_PACKET3( RADEON_3D_DRAW_IMMD, 13 ) ); 688 OUT_RING( RADEON_VTX_Z_PRESENT | 689 RADEON_VTX_PKCOLOR_PRESENT); 690 OUT_RING( (RADEON_PRIM_TYPE_RECT_LIST | 691 RADEON_PRIM_WALK_RING | 692 RADEON_MAOS_ENABLE | 693 RADEON_VTX_FMT_RADEON_MODE | 694 (3 << RADEON_NUM_VERTICES_SHIFT)) ); 695 696 697 OUT_RING( depth_boxes[i].ui[CLEAR_X1] ); 698 OUT_RING( depth_boxes[i].ui[CLEAR_Y1] ); 699 OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); 700 OUT_RING( 0x0 ); 701 702 OUT_RING( depth_boxes[i].ui[CLEAR_X1] ); 703 OUT_RING( depth_boxes[i].ui[CLEAR_Y2] ); 704 OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); 705 OUT_RING( 0x0 ); 706 707 OUT_RING( depth_boxes[i].ui[CLEAR_X2] ); 708 OUT_RING( depth_boxes[i].ui[CLEAR_Y2] ); 709 OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); 710 OUT_RING( 0x0 ); 711 712 ADVANCE_RING(); 713 } 714 } 715 716 /* Increment the clear counter. The client-side 3D driver must 717 * wait on this value before performing the clear ioctl. We 718 * need this because the card's so damned fast... 719 */ 720 dev_priv->sarea_priv->last_clear++; 721 722 BEGIN_RING( 4 ); 723 724 RADEON_CLEAR_AGE( dev_priv->sarea_priv->last_clear ); 725 RADEON_WAIT_UNTIL_IDLE(); 726 727 ADVANCE_RING(); 728} 729 730static void radeon_cp_dispatch_swap( drm_device_t *dev ) 731{ 732 drm_radeon_private_t *dev_priv = dev->dev_private; 733 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; 734 int nbox = sarea_priv->nbox; 735 drm_clip_rect_t *pbox = sarea_priv->boxes; 736 int i; 737 RING_LOCALS; 738 DRM_DEBUG( "\n" ); 739 740 /* Do some trivial performance monitoring... 741 */ 742 if (dev_priv->do_boxes) 743 radeon_cp_performance_boxes( dev_priv ); 744 745 746 /* Wait for the 3D stream to idle before dispatching the bitblt. 747 * This will prevent data corruption between the two streams. 748 */ 749 BEGIN_RING( 2 ); 750 751 RADEON_WAIT_UNTIL_3D_IDLE(); 752 753 ADVANCE_RING(); 754 755 for ( i = 0 ; i < nbox ; i++ ) { 756 int x = pbox[i].x1; 757 int y = pbox[i].y1; 758 int w = pbox[i].x2 - x; 759 int h = pbox[i].y2 - y; 760 761 DRM_DEBUG( "dispatch swap %d,%d-%d,%d\n", 762 x, y, w, h ); 763 764 BEGIN_RING( 7 ); 765 766 OUT_RING( CP_PACKET3( RADEON_CNTL_BITBLT_MULTI, 5 ) ); 767 OUT_RING( RADEON_GMC_SRC_PITCH_OFFSET_CNTL | 768 RADEON_GMC_DST_PITCH_OFFSET_CNTL | 769 RADEON_GMC_BRUSH_NONE | 770 (dev_priv->color_fmt << 8) | 771 RADEON_GMC_SRC_DATATYPE_COLOR | 772 RADEON_ROP3_S | 773 RADEON_DP_SRC_SOURCE_MEMORY | 774 RADEON_GMC_CLR_CMP_CNTL_DIS | 775 RADEON_GMC_WR_MSK_DIS ); 776 777 /* Make this work even if front & back are flipped: 778 */ 779 if (dev_priv->current_page == 0) { 780 OUT_RING( dev_priv->back_pitch_offset ); 781 OUT_RING( dev_priv->front_pitch_offset ); 782 } 783 else { 784 OUT_RING( dev_priv->front_pitch_offset ); 785 OUT_RING( dev_priv->back_pitch_offset ); 786 } 787 788 OUT_RING( (x << 16) | y ); 789 OUT_RING( (x << 16) | y ); 790 OUT_RING( (w << 16) | h ); 791 792 ADVANCE_RING(); 793 } 794 795 /* Increment the frame counter. The client-side 3D driver must 796 * throttle the framerate by waiting for this value before 797 * performing the swapbuffer ioctl. 798 */ 799 dev_priv->sarea_priv->last_frame++; 800 801 BEGIN_RING( 4 ); 802 803 RADEON_FRAME_AGE( dev_priv->sarea_priv->last_frame ); 804 RADEON_WAIT_UNTIL_2D_IDLE(); 805 806 ADVANCE_RING(); 807} 808 809static void radeon_cp_dispatch_flip( drm_device_t *dev ) 810{ 811 drm_radeon_private_t *dev_priv = dev->dev_private; 812 drm_sarea_t *sarea = (drm_sarea_t *)dev_priv->sarea->handle; 813 int offset = (dev_priv->current_page == 1) 814 ? dev_priv->front_offset : dev_priv->back_offset; 815 RING_LOCALS; 816 DRM_DEBUG( "%s: page=%d pfCurrentPage=%d\n", 817 __FUNCTION__, 818 dev_priv->current_page, 819 dev_priv->sarea_priv->pfCurrentPage); 820 821 /* Do some trivial performance monitoring... 822 */ 823 if (dev_priv->do_boxes) { 824 dev_priv->stats.boxes |= RADEON_BOX_FLIP; 825 radeon_cp_performance_boxes( dev_priv ); 826 } 827 828 /* Update the frame offsets for both CRTCs 829 */ 830 BEGIN_RING( 6 ); 831 832 RADEON_WAIT_UNTIL_3D_IDLE(); 833 OUT_RING_REG( RADEON_CRTC_OFFSET, ( ( sarea->frame.y * dev_priv->front_pitch 834 + sarea->frame.x 835 * ( dev_priv->color_fmt - 2 ) ) & ~7 ) 836 + offset ); 837 OUT_RING_REG( RADEON_CRTC2_OFFSET, dev_priv->sarea_priv->crtc2_base 838 + offset ); 839 840 ADVANCE_RING(); 841 842 /* Increment the frame counter. The client-side 3D driver must 843 * throttle the framerate by waiting for this value before 844 * performing the swapbuffer ioctl. 845 */ 846 dev_priv->sarea_priv->last_frame++; 847 dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page = 848 1 - dev_priv->current_page; 849 850 BEGIN_RING( 2 ); 851 852 RADEON_FRAME_AGE( dev_priv->sarea_priv->last_frame ); 853 854 ADVANCE_RING(); 855} 856 857static int bad_prim_vertex_nr( int primitive, int nr ) 858{ 859 switch (primitive & RADEON_PRIM_TYPE_MASK) { 860 case RADEON_PRIM_TYPE_NONE: 861 case RADEON_PRIM_TYPE_POINT: 862 return nr < 1; 863 case RADEON_PRIM_TYPE_LINE: 864 return (nr & 1) || nr == 0; 865 case RADEON_PRIM_TYPE_LINE_STRIP: 866 return nr < 2; 867 case RADEON_PRIM_TYPE_TRI_LIST: 868 case RADEON_PRIM_TYPE_3VRT_POINT_LIST: 869 case RADEON_PRIM_TYPE_3VRT_LINE_LIST: 870 case RADEON_PRIM_TYPE_RECT_LIST: 871 return nr % 3 || nr == 0; 872 case RADEON_PRIM_TYPE_TRI_FAN: 873 case RADEON_PRIM_TYPE_TRI_STRIP: 874 return nr < 3; 875 default: 876 return 1; 877 } 878} 879 880 881 882typedef struct { 883 unsigned int start; 884 unsigned int finish; 885 unsigned int prim; 886 unsigned int numverts; 887 unsigned int offset; 888 unsigned int vc_format; 889} drm_radeon_tcl_prim_t; 890 891static void radeon_cp_dispatch_vertex( drm_device_t *dev, 892 drm_buf_t *buf, 893 drm_radeon_tcl_prim_t *prim ) 894 895{ 896 drm_radeon_private_t *dev_priv = dev->dev_private; 897 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
| 30 */ 31 32#include "dev/drm/radeon.h" 33#include "dev/drm/drmP.h" 34#include "dev/drm/drm.h" 35#include "dev/drm/drm_sarea.h" 36#include "dev/drm/radeon_drm.h" 37#include "dev/drm/radeon_drv.h" 38 39 40/* ================================================================ 41 * CP hardware state programming functions 42 */ 43 44static __inline__ void radeon_emit_clip_rect( drm_radeon_private_t *dev_priv, 45 drm_clip_rect_t *box ) 46{ 47 RING_LOCALS; 48 49 DRM_DEBUG( " box: x1=%d y1=%d x2=%d y2=%d\n", 50 box->x1, box->y1, box->x2, box->y2 ); 51 52 BEGIN_RING( 4 ); 53 OUT_RING( CP_PACKET0( RADEON_RE_TOP_LEFT, 0 ) ); 54 OUT_RING( (box->y1 << 16) | box->x1 ); 55 OUT_RING( CP_PACKET0( RADEON_RE_WIDTH_HEIGHT, 0 ) ); 56 OUT_RING( ((box->y2 - 1) << 16) | (box->x2 - 1) ); 57 ADVANCE_RING(); 58} 59 60/* Emit 1.1 state 61 */ 62static void radeon_emit_state( drm_radeon_private_t *dev_priv, 63 drm_radeon_context_regs_t *ctx, 64 drm_radeon_texture_regs_t *tex, 65 unsigned int dirty ) 66{ 67 RING_LOCALS; 68 DRM_DEBUG( "dirty=0x%08x\n", dirty ); 69 70 if ( dirty & RADEON_UPLOAD_CONTEXT ) { 71 BEGIN_RING( 14 ); 72 OUT_RING( CP_PACKET0( RADEON_PP_MISC, 6 ) ); 73 OUT_RING( ctx->pp_misc ); 74 OUT_RING( ctx->pp_fog_color ); 75 OUT_RING( ctx->re_solid_color ); 76 OUT_RING( ctx->rb3d_blendcntl ); 77 OUT_RING( ctx->rb3d_depthoffset ); 78 OUT_RING( ctx->rb3d_depthpitch ); 79 OUT_RING( ctx->rb3d_zstencilcntl ); 80 OUT_RING( CP_PACKET0( RADEON_PP_CNTL, 2 ) ); 81 OUT_RING( ctx->pp_cntl ); 82 OUT_RING( ctx->rb3d_cntl ); 83 OUT_RING( ctx->rb3d_coloroffset ); 84 OUT_RING( CP_PACKET0( RADEON_RB3D_COLORPITCH, 0 ) ); 85 OUT_RING( ctx->rb3d_colorpitch ); 86 ADVANCE_RING(); 87 } 88 89 if ( dirty & RADEON_UPLOAD_VERTFMT ) { 90 BEGIN_RING( 2 ); 91 OUT_RING( CP_PACKET0( RADEON_SE_COORD_FMT, 0 ) ); 92 OUT_RING( ctx->se_coord_fmt ); 93 ADVANCE_RING(); 94 } 95 96 if ( dirty & RADEON_UPLOAD_LINE ) { 97 BEGIN_RING( 5 ); 98 OUT_RING( CP_PACKET0( RADEON_RE_LINE_PATTERN, 1 ) ); 99 OUT_RING( ctx->re_line_pattern ); 100 OUT_RING( ctx->re_line_state ); 101 OUT_RING( CP_PACKET0( RADEON_SE_LINE_WIDTH, 0 ) ); 102 OUT_RING( ctx->se_line_width ); 103 ADVANCE_RING(); 104 } 105 106 if ( dirty & RADEON_UPLOAD_BUMPMAP ) { 107 BEGIN_RING( 5 ); 108 OUT_RING( CP_PACKET0( RADEON_PP_LUM_MATRIX, 0 ) ); 109 OUT_RING( ctx->pp_lum_matrix ); 110 OUT_RING( CP_PACKET0( RADEON_PP_ROT_MATRIX_0, 1 ) ); 111 OUT_RING( ctx->pp_rot_matrix_0 ); 112 OUT_RING( ctx->pp_rot_matrix_1 ); 113 ADVANCE_RING(); 114 } 115 116 if ( dirty & RADEON_UPLOAD_MASKS ) { 117 BEGIN_RING( 4 ); 118 OUT_RING( CP_PACKET0( RADEON_RB3D_STENCILREFMASK, 2 ) ); 119 OUT_RING( ctx->rb3d_stencilrefmask ); 120 OUT_RING( ctx->rb3d_ropcntl ); 121 OUT_RING( ctx->rb3d_planemask ); 122 ADVANCE_RING(); 123 } 124 125 if ( dirty & RADEON_UPLOAD_VIEWPORT ) { 126 BEGIN_RING( 7 ); 127 OUT_RING( CP_PACKET0( RADEON_SE_VPORT_XSCALE, 5 ) ); 128 OUT_RING( ctx->se_vport_xscale ); 129 OUT_RING( ctx->se_vport_xoffset ); 130 OUT_RING( ctx->se_vport_yscale ); 131 OUT_RING( ctx->se_vport_yoffset ); 132 OUT_RING( ctx->se_vport_zscale ); 133 OUT_RING( ctx->se_vport_zoffset ); 134 ADVANCE_RING(); 135 } 136 137 if ( dirty & RADEON_UPLOAD_SETUP ) { 138 BEGIN_RING( 4 ); 139 OUT_RING( CP_PACKET0( RADEON_SE_CNTL, 0 ) ); 140 OUT_RING( ctx->se_cntl ); 141 OUT_RING( CP_PACKET0( RADEON_SE_CNTL_STATUS, 0 ) ); 142 OUT_RING( ctx->se_cntl_status ); 143 ADVANCE_RING(); 144 } 145 146 if ( dirty & RADEON_UPLOAD_MISC ) { 147 BEGIN_RING( 2 ); 148 OUT_RING( CP_PACKET0( RADEON_RE_MISC, 0 ) ); 149 OUT_RING( ctx->re_misc ); 150 ADVANCE_RING(); 151 } 152 153 if ( dirty & RADEON_UPLOAD_TEX0 ) { 154 BEGIN_RING( 9 ); 155 OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_0, 5 ) ); 156 OUT_RING( tex[0].pp_txfilter ); 157 OUT_RING( tex[0].pp_txformat ); 158 OUT_RING( tex[0].pp_txoffset ); 159 OUT_RING( tex[0].pp_txcblend ); 160 OUT_RING( tex[0].pp_txablend ); 161 OUT_RING( tex[0].pp_tfactor ); 162 OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_0, 0 ) ); 163 OUT_RING( tex[0].pp_border_color ); 164 ADVANCE_RING(); 165 } 166 167 if ( dirty & RADEON_UPLOAD_TEX1 ) { 168 BEGIN_RING( 9 ); 169 OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_1, 5 ) ); 170 OUT_RING( tex[1].pp_txfilter ); 171 OUT_RING( tex[1].pp_txformat ); 172 OUT_RING( tex[1].pp_txoffset ); 173 OUT_RING( tex[1].pp_txcblend ); 174 OUT_RING( tex[1].pp_txablend ); 175 OUT_RING( tex[1].pp_tfactor ); 176 OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_1, 0 ) ); 177 OUT_RING( tex[1].pp_border_color ); 178 ADVANCE_RING(); 179 } 180 181 if ( dirty & RADEON_UPLOAD_TEX2 ) { 182 BEGIN_RING( 9 ); 183 OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_2, 5 ) ); 184 OUT_RING( tex[2].pp_txfilter ); 185 OUT_RING( tex[2].pp_txformat ); 186 OUT_RING( tex[2].pp_txoffset ); 187 OUT_RING( tex[2].pp_txcblend ); 188 OUT_RING( tex[2].pp_txablend ); 189 OUT_RING( tex[2].pp_tfactor ); 190 OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_2, 0 ) ); 191 OUT_RING( tex[2].pp_border_color ); 192 ADVANCE_RING(); 193 } 194} 195 196/* Emit 1.2 state 197 */ 198static void radeon_emit_state2( drm_radeon_private_t *dev_priv, 199 drm_radeon_state_t *state ) 200{ 201 RING_LOCALS; 202 203 if (state->dirty & RADEON_UPLOAD_ZBIAS) { 204 BEGIN_RING( 3 ); 205 OUT_RING( CP_PACKET0( RADEON_SE_ZBIAS_FACTOR, 1 ) ); 206 OUT_RING( state->context2.se_zbias_factor ); 207 OUT_RING( state->context2.se_zbias_constant ); 208 ADVANCE_RING(); 209 } 210 211 radeon_emit_state( dev_priv, &state->context, 212 state->tex, state->dirty ); 213} 214 215/* New (1.3) state mechanism. 3 commands (packet, scalar, vector) in 216 * 1.3 cmdbuffers allow all previous state to be updated as well as 217 * the tcl scalar and vector areas. 218 */ 219static struct { 220 int start; 221 int len; 222 const char *name; 223} packet[RADEON_MAX_STATE_PACKETS] = { 224 { RADEON_PP_MISC,7,"RADEON_PP_MISC" }, 225 { RADEON_PP_CNTL,3,"RADEON_PP_CNTL" }, 226 { RADEON_RB3D_COLORPITCH,1,"RADEON_RB3D_COLORPITCH" }, 227 { RADEON_RE_LINE_PATTERN,2,"RADEON_RE_LINE_PATTERN" }, 228 { RADEON_SE_LINE_WIDTH,1,"RADEON_SE_LINE_WIDTH" }, 229 { RADEON_PP_LUM_MATRIX,1,"RADEON_PP_LUM_MATRIX" }, 230 { RADEON_PP_ROT_MATRIX_0,2,"RADEON_PP_ROT_MATRIX_0" }, 231 { RADEON_RB3D_STENCILREFMASK,3,"RADEON_RB3D_STENCILREFMASK" }, 232 { RADEON_SE_VPORT_XSCALE,6,"RADEON_SE_VPORT_XSCALE" }, 233 { RADEON_SE_CNTL,2,"RADEON_SE_CNTL" }, 234 { RADEON_SE_CNTL_STATUS,1,"RADEON_SE_CNTL_STATUS" }, 235 { RADEON_RE_MISC,1,"RADEON_RE_MISC" }, 236 { RADEON_PP_TXFILTER_0,6,"RADEON_PP_TXFILTER_0" }, 237 { RADEON_PP_BORDER_COLOR_0,1,"RADEON_PP_BORDER_COLOR_0" }, 238 { RADEON_PP_TXFILTER_1,6,"RADEON_PP_TXFILTER_1" }, 239 { RADEON_PP_BORDER_COLOR_1,1,"RADEON_PP_BORDER_COLOR_1" }, 240 { RADEON_PP_TXFILTER_2,6,"RADEON_PP_TXFILTER_2" }, 241 { RADEON_PP_BORDER_COLOR_2,1,"RADEON_PP_BORDER_COLOR_2" }, 242 { RADEON_SE_ZBIAS_FACTOR,2,"RADEON_SE_ZBIAS_FACTOR" }, 243 { RADEON_SE_TCL_OUTPUT_VTX_FMT,11,"RADEON_SE_TCL_OUTPUT_VTX_FMT" }, 244 { RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED,17,"RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED" }, 245 { R200_PP_TXCBLEND_0, 4, "R200_PP_TXCBLEND_0" }, 246 { R200_PP_TXCBLEND_1, 4, "R200_PP_TXCBLEND_1" }, 247 { R200_PP_TXCBLEND_2, 4, "R200_PP_TXCBLEND_2" }, 248 { R200_PP_TXCBLEND_3, 4, "R200_PP_TXCBLEND_3" }, 249 { R200_PP_TXCBLEND_4, 4, "R200_PP_TXCBLEND_4" }, 250 { R200_PP_TXCBLEND_5, 4, "R200_PP_TXCBLEND_5" }, 251 { R200_PP_TXCBLEND_6, 4, "R200_PP_TXCBLEND_6" }, 252 { R200_PP_TXCBLEND_7, 4, "R200_PP_TXCBLEND_7" }, 253 { R200_SE_TCL_LIGHT_MODEL_CTL_0, 6, "R200_SE_TCL_LIGHT_MODEL_CTL_0" }, 254 { R200_PP_TFACTOR_0, 6, "R200_PP_TFACTOR_0" }, 255 { R200_SE_VTX_FMT_0, 4, "R200_SE_VTX_FMT_0" }, 256 { R200_SE_VAP_CNTL, 1, "R200_SE_VAP_CNTL" }, 257 { R200_SE_TCL_MATRIX_SEL_0, 5, "R200_SE_TCL_MATRIX_SEL_0" }, 258 { R200_SE_TCL_TEX_PROC_CTL_2, 5, "R200_SE_TCL_TEX_PROC_CTL_2" }, 259 { R200_SE_TCL_UCP_VERT_BLEND_CTL, 1, "R200_SE_TCL_UCP_VERT_BLEND_CTL" }, 260 { R200_PP_TXFILTER_0, 6, "R200_PP_TXFILTER_0" }, 261 { R200_PP_TXFILTER_1, 6, "R200_PP_TXFILTER_1" }, 262 { R200_PP_TXFILTER_2, 6, "R200_PP_TXFILTER_2" }, 263 { R200_PP_TXFILTER_3, 6, "R200_PP_TXFILTER_3" }, 264 { R200_PP_TXFILTER_4, 6, "R200_PP_TXFILTER_4" }, 265 { R200_PP_TXFILTER_5, 6, "R200_PP_TXFILTER_5" }, 266 { R200_PP_TXOFFSET_0, 1, "R200_PP_TXOFFSET_0" }, 267 { R200_PP_TXOFFSET_1, 1, "R200_PP_TXOFFSET_1" }, 268 { R200_PP_TXOFFSET_2, 1, "R200_PP_TXOFFSET_2" }, 269 { R200_PP_TXOFFSET_3, 1, "R200_PP_TXOFFSET_3" }, 270 { R200_PP_TXOFFSET_4, 1, "R200_PP_TXOFFSET_4" }, 271 { R200_PP_TXOFFSET_5, 1, "R200_PP_TXOFFSET_5" }, 272 { R200_SE_VTE_CNTL, 1, "R200_SE_VTE_CNTL" }, 273 { R200_SE_TCL_OUTPUT_VTX_COMP_SEL, 1, "R200_SE_TCL_OUTPUT_VTX_COMP_SEL" }, 274 { R200_PP_TAM_DEBUG3, 1, "R200_PP_TAM_DEBUG3" }, 275 { R200_PP_CNTL_X, 1, "R200_PP_CNTL_X" }, 276 { R200_RB3D_DEPTHXY_OFFSET, 1, "R200_RB3D_DEPTHXY_OFFSET" }, 277 { R200_RE_AUX_SCISSOR_CNTL, 1, "R200_RE_AUX_SCISSOR_CNTL" }, 278 { R200_RE_SCISSOR_TL_0, 2, "R200_RE_SCISSOR_TL_0" }, 279 { R200_RE_SCISSOR_TL_1, 2, "R200_RE_SCISSOR_TL_1" }, 280 { R200_RE_SCISSOR_TL_2, 2, "R200_RE_SCISSOR_TL_2" }, 281 { R200_SE_VAP_CNTL_STATUS, 1, "R200_SE_VAP_CNTL_STATUS" }, 282 { R200_SE_VTX_STATE_CNTL, 1, "R200_SE_VTX_STATE_CNTL" }, 283 { R200_RE_POINTSIZE, 1, "R200_RE_POINTSIZE" }, 284 { R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0, 4, "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0" }, 285 { R200_PP_CUBIC_FACES_0, 1, "R200_PP_CUBIC_FACES_0" }, /* 61 */ 286 { R200_PP_CUBIC_OFFSET_F1_0, 5, "R200_PP_CUBIC_OFFSET_F1_0" }, /* 62 */ 287 { R200_PP_CUBIC_FACES_1, 1, "R200_PP_CUBIC_FACES_1" }, 288 { R200_PP_CUBIC_OFFSET_F1_1, 5, "R200_PP_CUBIC_OFFSET_F1_1" }, 289 { R200_PP_CUBIC_FACES_2, 1, "R200_PP_CUBIC_FACES_2" }, 290 { R200_PP_CUBIC_OFFSET_F1_2, 5, "R200_PP_CUBIC_OFFSET_F1_2" }, 291 { R200_PP_CUBIC_FACES_3, 1, "R200_PP_CUBIC_FACES_3" }, 292 { R200_PP_CUBIC_OFFSET_F1_3, 5, "R200_PP_CUBIC_OFFSET_F1_3" }, 293 { R200_PP_CUBIC_FACES_4, 1, "R200_PP_CUBIC_FACES_4" }, 294 { R200_PP_CUBIC_OFFSET_F1_4, 5, "R200_PP_CUBIC_OFFSET_F1_4" }, 295 { R200_PP_CUBIC_FACES_5, 1, "R200_PP_CUBIC_FACES_5" }, 296 { R200_PP_CUBIC_OFFSET_F1_5, 5, "R200_PP_CUBIC_OFFSET_F1_5" }, 297 { RADEON_PP_TEX_SIZE_0, 2, "RADEON_PP_TEX_SIZE_0" }, 298 { RADEON_PP_TEX_SIZE_1, 2, "RADEON_PP_TEX_SIZE_1" }, 299 { RADEON_PP_TEX_SIZE_2, 2, "RADEON_PP_TEX_SIZE_1" }, 300}; 301 302 303 304/* ================================================================ 305 * Performance monitoring functions 306 */ 307 308static void radeon_clear_box( drm_radeon_private_t *dev_priv, 309 int x, int y, int w, int h, 310 int r, int g, int b ) 311{ 312 u32 color; 313 RING_LOCALS; 314 315 x += dev_priv->sarea_priv->boxes[0].x1; 316 y += dev_priv->sarea_priv->boxes[0].y1; 317 318 switch ( dev_priv->color_fmt ) { 319 case RADEON_COLOR_FORMAT_RGB565: 320 color = (((r & 0xf8) << 8) | 321 ((g & 0xfc) << 3) | 322 ((b & 0xf8) >> 3)); 323 break; 324 case RADEON_COLOR_FORMAT_ARGB8888: 325 default: 326 color = (((0xff) << 24) | (r << 16) | (g << 8) | b); 327 break; 328 } 329 330 BEGIN_RING( 4 ); 331 RADEON_WAIT_UNTIL_3D_IDLE(); 332 OUT_RING( CP_PACKET0( RADEON_DP_WRITE_MASK, 0 ) ); 333 OUT_RING( 0xffffffff ); 334 ADVANCE_RING(); 335 336 BEGIN_RING( 6 ); 337 338 OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) ); 339 OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL | 340 RADEON_GMC_BRUSH_SOLID_COLOR | 341 (dev_priv->color_fmt << 8) | 342 RADEON_GMC_SRC_DATATYPE_COLOR | 343 RADEON_ROP3_P | 344 RADEON_GMC_CLR_CMP_CNTL_DIS ); 345 346 if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) { 347 OUT_RING( dev_priv->front_pitch_offset ); 348 } else { 349 OUT_RING( dev_priv->back_pitch_offset ); 350 } 351 352 OUT_RING( color ); 353 354 OUT_RING( (x << 16) | y ); 355 OUT_RING( (w << 16) | h ); 356 357 ADVANCE_RING(); 358} 359 360static void radeon_cp_performance_boxes( drm_radeon_private_t *dev_priv ) 361{ 362 /* Collapse various things into a wait flag -- trying to 363 * guess if userspase slept -- better just to have them tell us. 364 */ 365 if (dev_priv->stats.last_frame_reads > 1 || 366 dev_priv->stats.last_clear_reads > dev_priv->stats.clears) { 367 dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; 368 } 369 370 if (dev_priv->stats.freelist_loops) { 371 dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; 372 } 373 374 /* Purple box for page flipping 375 */ 376 if ( dev_priv->stats.boxes & RADEON_BOX_FLIP ) 377 radeon_clear_box( dev_priv, 4, 4, 8, 8, 255, 0, 255 ); 378 379 /* Red box if we have to wait for idle at any point 380 */ 381 if ( dev_priv->stats.boxes & RADEON_BOX_WAIT_IDLE ) 382 radeon_clear_box( dev_priv, 16, 4, 8, 8, 255, 0, 0 ); 383 384 /* Blue box: lost context? 385 */ 386 387 /* Yellow box for texture swaps 388 */ 389 if ( dev_priv->stats.boxes & RADEON_BOX_TEXTURE_LOAD ) 390 radeon_clear_box( dev_priv, 40, 4, 8, 8, 255, 255, 0 ); 391 392 /* Green box if hardware never idles (as far as we can tell) 393 */ 394 if ( !(dev_priv->stats.boxes & RADEON_BOX_DMA_IDLE) ) 395 radeon_clear_box( dev_priv, 64, 4, 8, 8, 0, 255, 0 ); 396 397 398 /* Draw bars indicating number of buffers allocated 399 * (not a great measure, easily confused) 400 */ 401 if (dev_priv->stats.requested_bufs) { 402 if (dev_priv->stats.requested_bufs > 100) 403 dev_priv->stats.requested_bufs = 100; 404 405 radeon_clear_box( dev_priv, 4, 16, 406 dev_priv->stats.requested_bufs, 4, 407 196, 128, 128 ); 408 } 409 410 memset( &dev_priv->stats, 0, sizeof(dev_priv->stats) ); 411 412} 413/* ================================================================ 414 * CP command dispatch functions 415 */ 416 417static void radeon_cp_dispatch_clear( drm_device_t *dev, 418 drm_radeon_clear_t *clear, 419 drm_radeon_clear_rect_t *depth_boxes ) 420{ 421 drm_radeon_private_t *dev_priv = dev->dev_private; 422 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; 423 drm_radeon_depth_clear_t *depth_clear = &dev_priv->depth_clear; 424 int nbox = sarea_priv->nbox; 425 drm_clip_rect_t *pbox = sarea_priv->boxes; 426 unsigned int flags = clear->flags; 427 u32 rb3d_cntl = 0, rb3d_stencilrefmask= 0; 428 int i; 429 RING_LOCALS; 430 DRM_DEBUG( "flags = 0x%x\n", flags ); 431 432 dev_priv->stats.clears++; 433 434 if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) { 435 unsigned int tmp = flags; 436 437 flags &= ~(RADEON_FRONT | RADEON_BACK); 438 if ( tmp & RADEON_FRONT ) flags |= RADEON_BACK; 439 if ( tmp & RADEON_BACK ) flags |= RADEON_FRONT; 440 } 441 442 if ( flags & (RADEON_FRONT | RADEON_BACK) ) { 443 444 BEGIN_RING( 4 ); 445 446 /* Ensure the 3D stream is idle before doing a 447 * 2D fill to clear the front or back buffer. 448 */ 449 RADEON_WAIT_UNTIL_3D_IDLE(); 450 451 OUT_RING( CP_PACKET0( RADEON_DP_WRITE_MASK, 0 ) ); 452 OUT_RING( clear->color_mask ); 453 454 ADVANCE_RING(); 455 456 /* Make sure we restore the 3D state next time. 457 */ 458 dev_priv->sarea_priv->ctx_owner = 0; 459 460 for ( i = 0 ; i < nbox ; i++ ) { 461 int x = pbox[i].x1; 462 int y = pbox[i].y1; 463 int w = pbox[i].x2 - x; 464 int h = pbox[i].y2 - y; 465 466 DRM_DEBUG( "dispatch clear %d,%d-%d,%d flags 0x%x\n", 467 x, y, w, h, flags ); 468 469 if ( flags & RADEON_FRONT ) { 470 BEGIN_RING( 6 ); 471 472 OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) ); 473 OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL | 474 RADEON_GMC_BRUSH_SOLID_COLOR | 475 (dev_priv->color_fmt << 8) | 476 RADEON_GMC_SRC_DATATYPE_COLOR | 477 RADEON_ROP3_P | 478 RADEON_GMC_CLR_CMP_CNTL_DIS ); 479 480 OUT_RING( dev_priv->front_pitch_offset ); 481 OUT_RING( clear->clear_color ); 482 483 OUT_RING( (x << 16) | y ); 484 OUT_RING( (w << 16) | h ); 485 486 ADVANCE_RING(); 487 } 488 489 if ( flags & RADEON_BACK ) { 490 BEGIN_RING( 6 ); 491 492 OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) ); 493 OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL | 494 RADEON_GMC_BRUSH_SOLID_COLOR | 495 (dev_priv->color_fmt << 8) | 496 RADEON_GMC_SRC_DATATYPE_COLOR | 497 RADEON_ROP3_P | 498 RADEON_GMC_CLR_CMP_CNTL_DIS ); 499 500 OUT_RING( dev_priv->back_pitch_offset ); 501 OUT_RING( clear->clear_color ); 502 503 OUT_RING( (x << 16) | y ); 504 OUT_RING( (w << 16) | h ); 505 506 ADVANCE_RING(); 507 } 508 } 509 } 510 511 /* We have to clear the depth and/or stencil buffers by 512 * rendering a quad into just those buffers. Thus, we have to 513 * make sure the 3D engine is configured correctly. 514 */ 515 if ( dev_priv->is_r200 && 516 (flags & (RADEON_DEPTH | RADEON_STENCIL)) ) { 517 518 int tempPP_CNTL; 519 int tempRE_CNTL; 520 int tempRB3D_CNTL; 521 int tempRB3D_ZSTENCILCNTL; 522 int tempRB3D_STENCILREFMASK; 523 int tempRB3D_PLANEMASK; 524 int tempSE_CNTL; 525 int tempSE_VTE_CNTL; 526 int tempSE_VTX_FMT_0; 527 int tempSE_VTX_FMT_1; 528 int tempSE_VAP_CNTL; 529 int tempRE_AUX_SCISSOR_CNTL; 530 531 tempPP_CNTL = 0; 532 tempRE_CNTL = 0; 533 534 tempRB3D_CNTL = depth_clear->rb3d_cntl; 535 tempRB3D_CNTL &= ~(1<<15); /* unset radeon magic flag */ 536 537 tempRB3D_ZSTENCILCNTL = depth_clear->rb3d_zstencilcntl; 538 tempRB3D_STENCILREFMASK = 0x0; 539 540 tempSE_CNTL = depth_clear->se_cntl; 541 542 543 544 /* Disable TCL */ 545 546 tempSE_VAP_CNTL = (/* SE_VAP_CNTL__FORCE_W_TO_ONE_MASK | */ 547 (0x9 << SE_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT)); 548 549 tempRB3D_PLANEMASK = 0x0; 550 551 tempRE_AUX_SCISSOR_CNTL = 0x0; 552 553 tempSE_VTE_CNTL = 554 SE_VTE_CNTL__VTX_XY_FMT_MASK | 555 SE_VTE_CNTL__VTX_Z_FMT_MASK; 556 557 /* Vertex format (X, Y, Z, W)*/ 558 tempSE_VTX_FMT_0 = 559 SE_VTX_FMT_0__VTX_Z0_PRESENT_MASK | 560 SE_VTX_FMT_0__VTX_W0_PRESENT_MASK; 561 tempSE_VTX_FMT_1 = 0x0; 562 563 564 /* 565 * Depth buffer specific enables 566 */ 567 if (flags & RADEON_DEPTH) { 568 /* Enable depth buffer */ 569 tempRB3D_CNTL |= RADEON_Z_ENABLE; 570 } else { 571 /* Disable depth buffer */ 572 tempRB3D_CNTL &= ~RADEON_Z_ENABLE; 573 } 574 575 /* 576 * Stencil buffer specific enables 577 */ 578 if ( flags & RADEON_STENCIL ) { 579 tempRB3D_CNTL |= RADEON_STENCIL_ENABLE; 580 tempRB3D_STENCILREFMASK = clear->depth_mask; 581 } else { 582 tempRB3D_CNTL &= ~RADEON_STENCIL_ENABLE; 583 tempRB3D_STENCILREFMASK = 0x00000000; 584 } 585 586 BEGIN_RING( 26 ); 587 RADEON_WAIT_UNTIL_2D_IDLE(); 588 589 OUT_RING_REG( RADEON_PP_CNTL, tempPP_CNTL ); 590 OUT_RING_REG( R200_RE_CNTL, tempRE_CNTL ); 591 OUT_RING_REG( RADEON_RB3D_CNTL, tempRB3D_CNTL ); 592 OUT_RING_REG( RADEON_RB3D_ZSTENCILCNTL, 593 tempRB3D_ZSTENCILCNTL ); 594 OUT_RING_REG( RADEON_RB3D_STENCILREFMASK, 595 tempRB3D_STENCILREFMASK ); 596 OUT_RING_REG( RADEON_RB3D_PLANEMASK, tempRB3D_PLANEMASK ); 597 OUT_RING_REG( RADEON_SE_CNTL, tempSE_CNTL ); 598 OUT_RING_REG( R200_SE_VTE_CNTL, tempSE_VTE_CNTL ); 599 OUT_RING_REG( R200_SE_VTX_FMT_0, tempSE_VTX_FMT_0 ); 600 OUT_RING_REG( R200_SE_VTX_FMT_1, tempSE_VTX_FMT_1 ); 601 OUT_RING_REG( R200_SE_VAP_CNTL, tempSE_VAP_CNTL ); 602 OUT_RING_REG( R200_RE_AUX_SCISSOR_CNTL, 603 tempRE_AUX_SCISSOR_CNTL ); 604 ADVANCE_RING(); 605 606 /* Make sure we restore the 3D state next time. 607 */ 608 dev_priv->sarea_priv->ctx_owner = 0; 609 610 for ( i = 0 ; i < nbox ; i++ ) { 611 612 /* Funny that this should be required -- 613 * sets top-left? 614 */ 615 radeon_emit_clip_rect( dev_priv, 616 &sarea_priv->boxes[i] ); 617 618 BEGIN_RING( 14 ); 619 OUT_RING( CP_PACKET3( R200_3D_DRAW_IMMD_2, 12 ) ); 620 OUT_RING( (RADEON_PRIM_TYPE_RECT_LIST | 621 RADEON_PRIM_WALK_RING | 622 (3 << RADEON_NUM_VERTICES_SHIFT)) ); 623 OUT_RING( depth_boxes[i].ui[CLEAR_X1] ); 624 OUT_RING( depth_boxes[i].ui[CLEAR_Y1] ); 625 OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); 626 OUT_RING( 0x3f800000 ); 627 OUT_RING( depth_boxes[i].ui[CLEAR_X1] ); 628 OUT_RING( depth_boxes[i].ui[CLEAR_Y2] ); 629 OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); 630 OUT_RING( 0x3f800000 ); 631 OUT_RING( depth_boxes[i].ui[CLEAR_X2] ); 632 OUT_RING( depth_boxes[i].ui[CLEAR_Y2] ); 633 OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); 634 OUT_RING( 0x3f800000 ); 635 ADVANCE_RING(); 636 } 637 } 638 else if ( (flags & (RADEON_DEPTH | RADEON_STENCIL)) ) { 639 640 rb3d_cntl = depth_clear->rb3d_cntl; 641 642 if ( flags & RADEON_DEPTH ) { 643 rb3d_cntl |= RADEON_Z_ENABLE; 644 } else { 645 rb3d_cntl &= ~RADEON_Z_ENABLE; 646 } 647 648 if ( flags & RADEON_STENCIL ) { 649 rb3d_cntl |= RADEON_STENCIL_ENABLE; 650 rb3d_stencilrefmask = clear->depth_mask; /* misnamed field */ 651 } else { 652 rb3d_cntl &= ~RADEON_STENCIL_ENABLE; 653 rb3d_stencilrefmask = 0x00000000; 654 } 655 656 BEGIN_RING( 13 ); 657 RADEON_WAIT_UNTIL_2D_IDLE(); 658 659 OUT_RING( CP_PACKET0( RADEON_PP_CNTL, 1 ) ); 660 OUT_RING( 0x00000000 ); 661 OUT_RING( rb3d_cntl ); 662 663 OUT_RING_REG( RADEON_RB3D_ZSTENCILCNTL, 664 depth_clear->rb3d_zstencilcntl ); 665 OUT_RING_REG( RADEON_RB3D_STENCILREFMASK, 666 rb3d_stencilrefmask ); 667 OUT_RING_REG( RADEON_RB3D_PLANEMASK, 668 0x00000000 ); 669 OUT_RING_REG( RADEON_SE_CNTL, 670 depth_clear->se_cntl ); 671 ADVANCE_RING(); 672 673 /* Make sure we restore the 3D state next time. 674 */ 675 dev_priv->sarea_priv->ctx_owner = 0; 676 677 for ( i = 0 ; i < nbox ; i++ ) { 678 679 /* Funny that this should be required -- 680 * sets top-left? 681 */ 682 radeon_emit_clip_rect( dev_priv, 683 &sarea_priv->boxes[i] ); 684 685 BEGIN_RING( 15 ); 686 687 OUT_RING( CP_PACKET3( RADEON_3D_DRAW_IMMD, 13 ) ); 688 OUT_RING( RADEON_VTX_Z_PRESENT | 689 RADEON_VTX_PKCOLOR_PRESENT); 690 OUT_RING( (RADEON_PRIM_TYPE_RECT_LIST | 691 RADEON_PRIM_WALK_RING | 692 RADEON_MAOS_ENABLE | 693 RADEON_VTX_FMT_RADEON_MODE | 694 (3 << RADEON_NUM_VERTICES_SHIFT)) ); 695 696 697 OUT_RING( depth_boxes[i].ui[CLEAR_X1] ); 698 OUT_RING( depth_boxes[i].ui[CLEAR_Y1] ); 699 OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); 700 OUT_RING( 0x0 ); 701 702 OUT_RING( depth_boxes[i].ui[CLEAR_X1] ); 703 OUT_RING( depth_boxes[i].ui[CLEAR_Y2] ); 704 OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); 705 OUT_RING( 0x0 ); 706 707 OUT_RING( depth_boxes[i].ui[CLEAR_X2] ); 708 OUT_RING( depth_boxes[i].ui[CLEAR_Y2] ); 709 OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); 710 OUT_RING( 0x0 ); 711 712 ADVANCE_RING(); 713 } 714 } 715 716 /* Increment the clear counter. The client-side 3D driver must 717 * wait on this value before performing the clear ioctl. We 718 * need this because the card's so damned fast... 719 */ 720 dev_priv->sarea_priv->last_clear++; 721 722 BEGIN_RING( 4 ); 723 724 RADEON_CLEAR_AGE( dev_priv->sarea_priv->last_clear ); 725 RADEON_WAIT_UNTIL_IDLE(); 726 727 ADVANCE_RING(); 728} 729 730static void radeon_cp_dispatch_swap( drm_device_t *dev ) 731{ 732 drm_radeon_private_t *dev_priv = dev->dev_private; 733 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; 734 int nbox = sarea_priv->nbox; 735 drm_clip_rect_t *pbox = sarea_priv->boxes; 736 int i; 737 RING_LOCALS; 738 DRM_DEBUG( "\n" ); 739 740 /* Do some trivial performance monitoring... 741 */ 742 if (dev_priv->do_boxes) 743 radeon_cp_performance_boxes( dev_priv ); 744 745 746 /* Wait for the 3D stream to idle before dispatching the bitblt. 747 * This will prevent data corruption between the two streams. 748 */ 749 BEGIN_RING( 2 ); 750 751 RADEON_WAIT_UNTIL_3D_IDLE(); 752 753 ADVANCE_RING(); 754 755 for ( i = 0 ; i < nbox ; i++ ) { 756 int x = pbox[i].x1; 757 int y = pbox[i].y1; 758 int w = pbox[i].x2 - x; 759 int h = pbox[i].y2 - y; 760 761 DRM_DEBUG( "dispatch swap %d,%d-%d,%d\n", 762 x, y, w, h ); 763 764 BEGIN_RING( 7 ); 765 766 OUT_RING( CP_PACKET3( RADEON_CNTL_BITBLT_MULTI, 5 ) ); 767 OUT_RING( RADEON_GMC_SRC_PITCH_OFFSET_CNTL | 768 RADEON_GMC_DST_PITCH_OFFSET_CNTL | 769 RADEON_GMC_BRUSH_NONE | 770 (dev_priv->color_fmt << 8) | 771 RADEON_GMC_SRC_DATATYPE_COLOR | 772 RADEON_ROP3_S | 773 RADEON_DP_SRC_SOURCE_MEMORY | 774 RADEON_GMC_CLR_CMP_CNTL_DIS | 775 RADEON_GMC_WR_MSK_DIS ); 776 777 /* Make this work even if front & back are flipped: 778 */ 779 if (dev_priv->current_page == 0) { 780 OUT_RING( dev_priv->back_pitch_offset ); 781 OUT_RING( dev_priv->front_pitch_offset ); 782 } 783 else { 784 OUT_RING( dev_priv->front_pitch_offset ); 785 OUT_RING( dev_priv->back_pitch_offset ); 786 } 787 788 OUT_RING( (x << 16) | y ); 789 OUT_RING( (x << 16) | y ); 790 OUT_RING( (w << 16) | h ); 791 792 ADVANCE_RING(); 793 } 794 795 /* Increment the frame counter. The client-side 3D driver must 796 * throttle the framerate by waiting for this value before 797 * performing the swapbuffer ioctl. 798 */ 799 dev_priv->sarea_priv->last_frame++; 800 801 BEGIN_RING( 4 ); 802 803 RADEON_FRAME_AGE( dev_priv->sarea_priv->last_frame ); 804 RADEON_WAIT_UNTIL_2D_IDLE(); 805 806 ADVANCE_RING(); 807} 808 809static void radeon_cp_dispatch_flip( drm_device_t *dev ) 810{ 811 drm_radeon_private_t *dev_priv = dev->dev_private; 812 drm_sarea_t *sarea = (drm_sarea_t *)dev_priv->sarea->handle; 813 int offset = (dev_priv->current_page == 1) 814 ? dev_priv->front_offset : dev_priv->back_offset; 815 RING_LOCALS; 816 DRM_DEBUG( "%s: page=%d pfCurrentPage=%d\n", 817 __FUNCTION__, 818 dev_priv->current_page, 819 dev_priv->sarea_priv->pfCurrentPage); 820 821 /* Do some trivial performance monitoring... 822 */ 823 if (dev_priv->do_boxes) { 824 dev_priv->stats.boxes |= RADEON_BOX_FLIP; 825 radeon_cp_performance_boxes( dev_priv ); 826 } 827 828 /* Update the frame offsets for both CRTCs 829 */ 830 BEGIN_RING( 6 ); 831 832 RADEON_WAIT_UNTIL_3D_IDLE(); 833 OUT_RING_REG( RADEON_CRTC_OFFSET, ( ( sarea->frame.y * dev_priv->front_pitch 834 + sarea->frame.x 835 * ( dev_priv->color_fmt - 2 ) ) & ~7 ) 836 + offset ); 837 OUT_RING_REG( RADEON_CRTC2_OFFSET, dev_priv->sarea_priv->crtc2_base 838 + offset ); 839 840 ADVANCE_RING(); 841 842 /* Increment the frame counter. The client-side 3D driver must 843 * throttle the framerate by waiting for this value before 844 * performing the swapbuffer ioctl. 845 */ 846 dev_priv->sarea_priv->last_frame++; 847 dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page = 848 1 - dev_priv->current_page; 849 850 BEGIN_RING( 2 ); 851 852 RADEON_FRAME_AGE( dev_priv->sarea_priv->last_frame ); 853 854 ADVANCE_RING(); 855} 856 857static int bad_prim_vertex_nr( int primitive, int nr ) 858{ 859 switch (primitive & RADEON_PRIM_TYPE_MASK) { 860 case RADEON_PRIM_TYPE_NONE: 861 case RADEON_PRIM_TYPE_POINT: 862 return nr < 1; 863 case RADEON_PRIM_TYPE_LINE: 864 return (nr & 1) || nr == 0; 865 case RADEON_PRIM_TYPE_LINE_STRIP: 866 return nr < 2; 867 case RADEON_PRIM_TYPE_TRI_LIST: 868 case RADEON_PRIM_TYPE_3VRT_POINT_LIST: 869 case RADEON_PRIM_TYPE_3VRT_LINE_LIST: 870 case RADEON_PRIM_TYPE_RECT_LIST: 871 return nr % 3 || nr == 0; 872 case RADEON_PRIM_TYPE_TRI_FAN: 873 case RADEON_PRIM_TYPE_TRI_STRIP: 874 return nr < 3; 875 default: 876 return 1; 877 } 878} 879 880 881 882typedef struct { 883 unsigned int start; 884 unsigned int finish; 885 unsigned int prim; 886 unsigned int numverts; 887 unsigned int offset; 888 unsigned int vc_format; 889} drm_radeon_tcl_prim_t; 890 891static void radeon_cp_dispatch_vertex( drm_device_t *dev, 892 drm_buf_t *buf, 893 drm_radeon_tcl_prim_t *prim ) 894 895{ 896 drm_radeon_private_t *dev_priv = dev->dev_private; 897 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
1005 u32 *data; 1006 int dwords; 1007 int i = 0; 1008 int start = prim->start + RADEON_INDEX_PRIM_OFFSET; 1009 int count = (prim->finish - start) / sizeof(u16); 1010 int nbox = sarea_priv->nbox; 1011 1012 DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d offset: %x nr %d\n", 1013 prim->prim, 1014 prim->vc_format, 1015 prim->start, 1016 prim->finish, 1017 prim->offset, 1018 prim->numverts); 1019 1020 if (bad_prim_vertex_nr( prim->prim, count )) { 1021 DRM_ERROR( "bad prim %x count %d\n", 1022 prim->prim, count ); 1023 return; 1024 } 1025 1026 1027 if ( start >= prim->finish || 1028 (prim->start & 0x7) ) { 1029 DRM_ERROR( "buffer prim %d\n", prim->prim ); 1030 return; 1031 } 1032 1033 dwords = (prim->finish - prim->start + 3) / sizeof(u32); 1034 1035 data = (u32 *)((char *)dev_priv->buffers->handle + 1036 elt_buf->offset + prim->start); 1037 1038 data[0] = CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, dwords-2 ); 1039 data[1] = offset; 1040 data[2] = prim->numverts; 1041 data[3] = prim->vc_format; 1042 data[4] = (prim->prim | 1043 RADEON_PRIM_WALK_IND | 1044 RADEON_COLOR_ORDER_RGBA | 1045 RADEON_VTX_FMT_RADEON_MODE | 1046 (count << RADEON_NUM_VERTICES_SHIFT) ); 1047 1048 do { 1049 if ( i < nbox ) 1050 radeon_emit_clip_rect( dev_priv, 1051 &sarea_priv->boxes[i] ); 1052 1053 radeon_cp_dispatch_indirect( dev, elt_buf, 1054 prim->start, 1055 prim->finish ); 1056 1057 i++; 1058 } while ( i < nbox ); 1059 1060} 1061 1062#define RADEON_MAX_TEXTURE_SIZE (RADEON_BUFFER_SIZE - 8 * sizeof(u32)) 1063 1064static int radeon_cp_dispatch_texture( DRMFILE filp, 1065 drm_device_t *dev, 1066 drm_radeon_texture_t *tex, 1067 drm_radeon_tex_image_t *image ) 1068{ 1069 drm_radeon_private_t *dev_priv = dev->dev_private; 1070 drm_buf_t *buf; 1071 u32 format; 1072 u32 *buffer; 1073 const u8 *data; 1074 int size, dwords, tex_width, blit_width; 1075 u32 height; 1076 int i; 1077 RING_LOCALS; 1078 1079 dev_priv->stats.boxes |= RADEON_BOX_TEXTURE_LOAD; 1080 1081 /* Flush the pixel cache. This ensures no pixel data gets mixed 1082 * up with the texture data from the host data blit, otherwise 1083 * part of the texture image may be corrupted. 1084 */ 1085 BEGIN_RING( 4 ); 1086 RADEON_FLUSH_CACHE(); 1087 RADEON_WAIT_UNTIL_IDLE(); 1088 ADVANCE_RING(); 1089 1090#ifdef __BIG_ENDIAN 1091 /* The Mesa texture functions provide the data in little endian as the 1092 * chip wants it, but we need to compensate for the fact that the CP 1093 * ring gets byte-swapped 1094 */ 1095 BEGIN_RING( 2 ); 1096 OUT_RING_REG( RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_32BIT ); 1097 ADVANCE_RING(); 1098#endif 1099 1100 1101 /* The compiler won't optimize away a division by a variable, 1102 * even if the only legal values are powers of two. Thus, we'll 1103 * use a shift instead. 1104 */ 1105 switch ( tex->format ) { 1106 case RADEON_TXFORMAT_ARGB8888: 1107 case RADEON_TXFORMAT_RGBA8888: 1108 format = RADEON_COLOR_FORMAT_ARGB8888; 1109 tex_width = tex->width * 4; 1110 blit_width = image->width * 4; 1111 break; 1112 case RADEON_TXFORMAT_AI88: 1113 case RADEON_TXFORMAT_ARGB1555: 1114 case RADEON_TXFORMAT_RGB565: 1115 case RADEON_TXFORMAT_ARGB4444: 1116 case RADEON_TXFORMAT_VYUY422: 1117 case RADEON_TXFORMAT_YVYU422: 1118 format = RADEON_COLOR_FORMAT_RGB565; 1119 tex_width = tex->width * 2; 1120 blit_width = image->width * 2; 1121 break; 1122 case RADEON_TXFORMAT_I8: 1123 case RADEON_TXFORMAT_RGB332: 1124 format = RADEON_COLOR_FORMAT_CI8; 1125 tex_width = tex->width * 1; 1126 blit_width = image->width * 1; 1127 break; 1128 default: 1129 DRM_ERROR( "invalid texture format %d\n", tex->format ); 1130 return DRM_ERR(EINVAL); 1131 } 1132 1133 DRM_DEBUG("tex=%dx%d blit=%d\n", tex_width, tex->height, blit_width ); 1134 1135 do { 1136 DRM_DEBUG( "tex: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n", 1137 tex->offset >> 10, tex->pitch, tex->format, 1138 image->x, image->y, image->width, image->height ); 1139 1140 /* Make a copy of some parameters in case we have to 1141 * update them for a multi-pass texture blit. 1142 */ 1143 height = image->height; 1144 data = (const u8 *)image->data; 1145 1146 size = height * blit_width; 1147 1148 if ( size > RADEON_MAX_TEXTURE_SIZE ) { 1149 height = RADEON_MAX_TEXTURE_SIZE / blit_width; 1150 size = height * blit_width; 1151 } else if ( size < 4 && size > 0 ) { 1152 size = 4; 1153 } else if ( size == 0 ) { 1154 return 0; 1155 } 1156 1157 buf = radeon_freelist_get( dev ); 1158 if ( 0 && !buf ) { 1159 radeon_do_cp_idle( dev_priv ); 1160 buf = radeon_freelist_get( dev ); 1161 } 1162 if ( !buf ) { 1163 DRM_DEBUG("radeon_cp_dispatch_texture: EAGAIN\n"); 1164 DRM_COPY_TO_USER( tex->image, image, sizeof(*image) ); 1165 return DRM_ERR(EAGAIN); 1166 } 1167 1168 1169 /* Dispatch the indirect buffer. 1170 */ 1171 buffer = (u32*)((char*)dev_priv->buffers->handle + buf->offset); 1172 dwords = size / 4; 1173 buffer[0] = CP_PACKET3( RADEON_CNTL_HOSTDATA_BLT, dwords + 6 ); 1174 buffer[1] = (RADEON_GMC_DST_PITCH_OFFSET_CNTL | 1175 RADEON_GMC_BRUSH_NONE | 1176 (format << 8) | 1177 RADEON_GMC_SRC_DATATYPE_COLOR | 1178 RADEON_ROP3_S | 1179 RADEON_DP_SRC_SOURCE_HOST_DATA | 1180 RADEON_GMC_CLR_CMP_CNTL_DIS | 1181 RADEON_GMC_WR_MSK_DIS); 1182 1183 buffer[2] = (tex->pitch << 22) | (tex->offset >> 10); 1184 buffer[3] = 0xffffffff; 1185 buffer[4] = 0xffffffff; 1186 buffer[5] = (image->y << 16) | image->x; 1187 buffer[6] = (height << 16) | image->width; 1188 buffer[7] = dwords; 1189 buffer += 8; 1190 1191 if ( tex_width >= 32 ) { 1192 /* Texture image width is larger than the minimum, so we 1193 * can upload it directly. 1194 */ 1195 if ( DRM_COPY_FROM_USER( buffer, data, 1196 dwords * sizeof(u32) ) ) { 1197 DRM_ERROR( "EFAULT on data, %d dwords\n", 1198 dwords ); 1199 return DRM_ERR(EFAULT); 1200 } 1201 } else { 1202 /* Texture image width is less than the minimum, so we 1203 * need to pad out each image scanline to the minimum 1204 * width. 1205 */ 1206 for ( i = 0 ; i < tex->height ; i++ ) { 1207 if ( DRM_COPY_FROM_USER( buffer, data, 1208 tex_width ) ) { 1209 DRM_ERROR( "EFAULT on pad, %d bytes\n", 1210 tex_width ); 1211 return DRM_ERR(EFAULT); 1212 } 1213 buffer += 8; 1214 data += tex_width; 1215 } 1216 } 1217 1218 buf->filp = filp; 1219 buf->used = (dwords + 8) * sizeof(u32); 1220 radeon_cp_dispatch_indirect( dev, buf, 0, buf->used ); 1221 radeon_cp_discard_buffer( dev, buf ); 1222 1223 /* Update the input parameters for next time */ 1224 image->y += height; 1225 image->height -= height; 1226 (const u8 *)image->data += size; 1227 } while (image->height > 0); 1228 1229 /* Flush the pixel cache after the blit completes. This ensures 1230 * the texture data is written out to memory before rendering 1231 * continues. 1232 */ 1233 BEGIN_RING( 4 ); 1234 RADEON_FLUSH_CACHE(); 1235 RADEON_WAIT_UNTIL_2D_IDLE(); 1236 ADVANCE_RING(); 1237 return 0; 1238} 1239 1240 1241static void radeon_cp_dispatch_stipple( drm_device_t *dev, u32 *stipple ) 1242{ 1243 drm_radeon_private_t *dev_priv = dev->dev_private; 1244 int i; 1245 RING_LOCALS; 1246 DRM_DEBUG( "\n" ); 1247 1248 BEGIN_RING( 35 ); 1249 1250 OUT_RING( CP_PACKET0( RADEON_RE_STIPPLE_ADDR, 0 ) ); 1251 OUT_RING( 0x00000000 ); 1252 1253 OUT_RING( CP_PACKET0_TABLE( RADEON_RE_STIPPLE_DATA, 31 ) ); 1254 for ( i = 0 ; i < 32 ; i++ ) { 1255 OUT_RING( stipple[i] ); 1256 } 1257 1258 ADVANCE_RING(); 1259} 1260 1261 1262/* ================================================================ 1263 * IOCTL functions 1264 */ 1265 1266int radeon_cp_clear( DRM_IOCTL_ARGS ) 1267{ 1268 DRM_DEVICE; 1269 drm_radeon_private_t *dev_priv = dev->dev_private; 1270 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; 1271 drm_radeon_clear_t clear; 1272 drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS]; 1273 DRM_DEBUG( "\n" ); 1274 1275 LOCK_TEST_WITH_RETURN( dev, filp ); 1276 1277 DRM_COPY_FROM_USER_IOCTL( clear, (drm_radeon_clear_t *)data, 1278 sizeof(clear) ); 1279 1280 RING_SPACE_TEST_WITH_RETURN( dev_priv ); 1281 1282 if ( sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS ) 1283 sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS; 1284 1285 if ( DRM_COPY_FROM_USER( &depth_boxes, clear.depth_boxes, 1286 sarea_priv->nbox * sizeof(depth_boxes[0]) ) ) 1287 return DRM_ERR(EFAULT); 1288 1289 radeon_cp_dispatch_clear( dev, &clear, depth_boxes ); 1290 1291 COMMIT_RING(); 1292 return 0; 1293} 1294 1295 1296/* Not sure why this isn't set all the time: 1297 */ 1298static int radeon_do_init_pageflip( drm_device_t *dev ) 1299{ 1300 drm_radeon_private_t *dev_priv = dev->dev_private; 1301 RING_LOCALS; 1302 1303 DRM_DEBUG( "\n" ); 1304 1305 BEGIN_RING( 6 ); 1306 RADEON_WAIT_UNTIL_3D_IDLE(); 1307 OUT_RING( CP_PACKET0( RADEON_CRTC_OFFSET_CNTL, 0 ) ); 1308 OUT_RING( RADEON_READ( RADEON_CRTC_OFFSET_CNTL ) | RADEON_CRTC_OFFSET_FLIP_CNTL ); 1309 OUT_RING( CP_PACKET0( RADEON_CRTC2_OFFSET_CNTL, 0 ) ); 1310 OUT_RING( RADEON_READ( RADEON_CRTC2_OFFSET_CNTL ) | RADEON_CRTC_OFFSET_FLIP_CNTL ); 1311 ADVANCE_RING(); 1312 1313 dev_priv->page_flipping = 1; 1314 dev_priv->current_page = 0; 1315 dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page; 1316 1317 return 0; 1318} 1319 1320/* Called whenever a client dies, from DRM(release). 1321 * NOTE: Lock isn't necessarily held when this is called! 1322 */ 1323int radeon_do_cleanup_pageflip( drm_device_t *dev ) 1324{ 1325 drm_radeon_private_t *dev_priv = dev->dev_private; 1326 DRM_DEBUG( "\n" ); 1327 1328 if (dev_priv->current_page != 0) 1329 radeon_cp_dispatch_flip( dev ); 1330 1331 dev_priv->page_flipping = 0; 1332 return 0; 1333} 1334 1335/* Swapping and flipping are different operations, need different ioctls. 1336 * They can & should be intermixed to support multiple 3d windows. 1337 */ 1338int radeon_cp_flip( DRM_IOCTL_ARGS ) 1339{ 1340 DRM_DEVICE; 1341 drm_radeon_private_t *dev_priv = dev->dev_private; 1342 DRM_DEBUG( "\n" ); 1343 1344 LOCK_TEST_WITH_RETURN( dev, filp ); 1345 1346 RING_SPACE_TEST_WITH_RETURN( dev_priv ); 1347 1348 if (!dev_priv->page_flipping) 1349 radeon_do_init_pageflip( dev ); 1350 1351 radeon_cp_dispatch_flip( dev ); 1352 1353 COMMIT_RING(); 1354 return 0; 1355} 1356 1357int radeon_cp_swap( DRM_IOCTL_ARGS ) 1358{ 1359 DRM_DEVICE; 1360 drm_radeon_private_t *dev_priv = dev->dev_private; 1361 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; 1362 DRM_DEBUG( "\n" ); 1363 1364 LOCK_TEST_WITH_RETURN( dev, filp ); 1365 1366 RING_SPACE_TEST_WITH_RETURN( dev_priv ); 1367 1368 if ( sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS ) 1369 sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS; 1370 1371 radeon_cp_dispatch_swap( dev ); 1372 dev_priv->sarea_priv->ctx_owner = 0; 1373 1374 COMMIT_RING(); 1375 return 0; 1376} 1377 1378int radeon_cp_vertex( DRM_IOCTL_ARGS ) 1379{ 1380 DRM_DEVICE; 1381 drm_radeon_private_t *dev_priv = dev->dev_private; 1382 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; 1383 drm_device_dma_t *dma = dev->dma; 1384 drm_buf_t *buf; 1385 drm_radeon_vertex_t vertex; 1386 drm_radeon_tcl_prim_t prim; 1387 1388 LOCK_TEST_WITH_RETURN( dev, filp ); 1389 1390 if ( !dev_priv ) { 1391 DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); 1392 return DRM_ERR(EINVAL); 1393 } 1394 1395 DRM_COPY_FROM_USER_IOCTL( vertex, (drm_radeon_vertex_t *)data, 1396 sizeof(vertex) ); 1397 1398 DRM_DEBUG( "pid=%d index=%d count=%d discard=%d\n", 1399 DRM_CURRENTPID, 1400 vertex.idx, vertex.count, vertex.discard ); 1401 1402 if ( vertex.idx < 0 || vertex.idx >= dma->buf_count ) { 1403 DRM_ERROR( "buffer index %d (of %d max)\n", 1404 vertex.idx, dma->buf_count - 1 ); 1405 return DRM_ERR(EINVAL); 1406 } 1407 if ( vertex.prim < 0 || 1408 vertex.prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST ) { 1409 DRM_ERROR( "buffer prim %d\n", vertex.prim ); 1410 return DRM_ERR(EINVAL); 1411 } 1412 1413 RING_SPACE_TEST_WITH_RETURN( dev_priv ); 1414 VB_AGE_TEST_WITH_RETURN( dev_priv ); 1415 1416 buf = dma->buflist[vertex.idx]; 1417 1418 if ( buf->filp != filp ) { 1419 DRM_ERROR( "process %d using buffer owned by %p\n", 1420 DRM_CURRENTPID, buf->filp ); 1421 return DRM_ERR(EINVAL); 1422 } 1423 if ( buf->pending ) { 1424 DRM_ERROR( "sending pending buffer %d\n", vertex.idx ); 1425 return DRM_ERR(EINVAL); 1426 } 1427 1428 /* Build up a prim_t record: 1429 */ 1430 if (vertex.count) { 1431 buf->used = vertex.count; /* not used? */ 1432 1433 if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) { 1434 radeon_emit_state( dev_priv, 1435 &sarea_priv->context_state, 1436 sarea_priv->tex_state, 1437 sarea_priv->dirty ); 1438 1439 sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES | 1440 RADEON_UPLOAD_TEX1IMAGES | 1441 RADEON_UPLOAD_TEX2IMAGES | 1442 RADEON_REQUIRE_QUIESCENCE); 1443 } 1444 1445 prim.start = 0; 1446 prim.finish = vertex.count; /* unused */ 1447 prim.prim = vertex.prim; 1448 prim.numverts = vertex.count; 1449 prim.vc_format = dev_priv->sarea_priv->vc_format; 1450 1451 radeon_cp_dispatch_vertex( dev, buf, &prim ); 1452 } 1453 1454 if (vertex.discard) { 1455 radeon_cp_discard_buffer( dev, buf ); 1456 } 1457 1458 COMMIT_RING(); 1459 return 0; 1460} 1461 1462int radeon_cp_indices( DRM_IOCTL_ARGS ) 1463{ 1464 DRM_DEVICE; 1465 drm_radeon_private_t *dev_priv = dev->dev_private; 1466 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; 1467 drm_device_dma_t *dma = dev->dma; 1468 drm_buf_t *buf; 1469 drm_radeon_indices_t elts; 1470 drm_radeon_tcl_prim_t prim; 1471 int count; 1472 1473 LOCK_TEST_WITH_RETURN( dev, filp ); 1474 1475 if ( !dev_priv ) { 1476 DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); 1477 return DRM_ERR(EINVAL); 1478 } 1479 1480 DRM_COPY_FROM_USER_IOCTL( elts, (drm_radeon_indices_t *)data, 1481 sizeof(elts) ); 1482 1483 DRM_DEBUG( "pid=%d index=%d start=%d end=%d discard=%d\n", 1484 DRM_CURRENTPID, 1485 elts.idx, elts.start, elts.end, elts.discard ); 1486 1487 if ( elts.idx < 0 || elts.idx >= dma->buf_count ) { 1488 DRM_ERROR( "buffer index %d (of %d max)\n", 1489 elts.idx, dma->buf_count - 1 ); 1490 return DRM_ERR(EINVAL); 1491 } 1492 if ( elts.prim < 0 || 1493 elts.prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST ) { 1494 DRM_ERROR( "buffer prim %d\n", elts.prim ); 1495 return DRM_ERR(EINVAL); 1496 } 1497 1498 RING_SPACE_TEST_WITH_RETURN( dev_priv ); 1499 VB_AGE_TEST_WITH_RETURN( dev_priv ); 1500 1501 buf = dma->buflist[elts.idx]; 1502 1503 if ( buf->filp != filp ) { 1504 DRM_ERROR( "process %d using buffer owned by %p\n", 1505 DRM_CURRENTPID, buf->filp ); 1506 return DRM_ERR(EINVAL); 1507 } 1508 if ( buf->pending ) { 1509 DRM_ERROR( "sending pending buffer %d\n", elts.idx ); 1510 return DRM_ERR(EINVAL); 1511 } 1512 1513 count = (elts.end - elts.start) / sizeof(u16); 1514 elts.start -= RADEON_INDEX_PRIM_OFFSET; 1515 1516 if ( elts.start & 0x7 ) { 1517 DRM_ERROR( "misaligned buffer 0x%x\n", elts.start ); 1518 return DRM_ERR(EINVAL); 1519 } 1520 if ( elts.start < buf->used ) { 1521 DRM_ERROR( "no header 0x%x - 0x%x\n", elts.start, buf->used ); 1522 return DRM_ERR(EINVAL); 1523 } 1524 1525 buf->used = elts.end; 1526 1527 if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) { 1528 radeon_emit_state( dev_priv, 1529 &sarea_priv->context_state, 1530 sarea_priv->tex_state, 1531 sarea_priv->dirty ); 1532 1533 sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES | 1534 RADEON_UPLOAD_TEX1IMAGES | 1535 RADEON_UPLOAD_TEX2IMAGES | 1536 RADEON_REQUIRE_QUIESCENCE); 1537 } 1538 1539 1540 /* Build up a prim_t record: 1541 */ 1542 prim.start = elts.start; 1543 prim.finish = elts.end; 1544 prim.prim = elts.prim; 1545 prim.offset = 0; /* offset from start of dma buffers */ 1546 prim.numverts = RADEON_MAX_VB_VERTS; /* duh */ 1547 prim.vc_format = dev_priv->sarea_priv->vc_format; 1548 1549 radeon_cp_dispatch_indices( dev, buf, &prim ); 1550 if (elts.discard) { 1551 radeon_cp_discard_buffer( dev, buf ); 1552 } 1553 1554 COMMIT_RING(); 1555 return 0; 1556} 1557 1558int radeon_cp_texture( DRM_IOCTL_ARGS ) 1559{ 1560 DRM_DEVICE; 1561 drm_radeon_private_t *dev_priv = dev->dev_private; 1562 drm_radeon_texture_t tex; 1563 drm_radeon_tex_image_t image; 1564 int ret; 1565 1566 LOCK_TEST_WITH_RETURN( dev, filp ); 1567 1568 DRM_COPY_FROM_USER_IOCTL( tex, (drm_radeon_texture_t *)data, sizeof(tex) ); 1569 1570 if ( tex.image == NULL ) { 1571 DRM_ERROR( "null texture image!\n" ); 1572 return DRM_ERR(EINVAL); 1573 } 1574 1575 if ( DRM_COPY_FROM_USER( &image, 1576 (drm_radeon_tex_image_t *)tex.image, 1577 sizeof(image) ) ) 1578 return DRM_ERR(EFAULT); 1579 1580 RING_SPACE_TEST_WITH_RETURN( dev_priv ); 1581 VB_AGE_TEST_WITH_RETURN( dev_priv ); 1582 1583 ret = radeon_cp_dispatch_texture( filp, dev, &tex, &image ); 1584 1585 COMMIT_RING(); 1586 return ret; 1587} 1588 1589int radeon_cp_stipple( DRM_IOCTL_ARGS ) 1590{ 1591 DRM_DEVICE; 1592 drm_radeon_private_t *dev_priv = dev->dev_private; 1593 drm_radeon_stipple_t stipple; 1594 u32 mask[32]; 1595 1596 LOCK_TEST_WITH_RETURN( dev, filp ); 1597 1598 DRM_COPY_FROM_USER_IOCTL( stipple, (drm_radeon_stipple_t *)data, 1599 sizeof(stipple) ); 1600 1601 if ( DRM_COPY_FROM_USER( &mask, stipple.mask, 32 * sizeof(u32) ) ) 1602 return DRM_ERR(EFAULT); 1603 1604 RING_SPACE_TEST_WITH_RETURN( dev_priv ); 1605 1606 radeon_cp_dispatch_stipple( dev, mask ); 1607 1608 COMMIT_RING(); 1609 return 0; 1610} 1611 1612int radeon_cp_indirect( DRM_IOCTL_ARGS ) 1613{ 1614 DRM_DEVICE; 1615 drm_radeon_private_t *dev_priv = dev->dev_private; 1616 drm_device_dma_t *dma = dev->dma; 1617 drm_buf_t *buf; 1618 drm_radeon_indirect_t indirect; 1619 RING_LOCALS; 1620 1621 LOCK_TEST_WITH_RETURN( dev, filp ); 1622 1623 if ( !dev_priv ) { 1624 DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); 1625 return DRM_ERR(EINVAL); 1626 } 1627 1628 DRM_COPY_FROM_USER_IOCTL( indirect, (drm_radeon_indirect_t *)data, 1629 sizeof(indirect) ); 1630 1631 DRM_DEBUG( "indirect: idx=%d s=%d e=%d d=%d\n", 1632 indirect.idx, indirect.start, 1633 indirect.end, indirect.discard ); 1634 1635 if ( indirect.idx < 0 || indirect.idx >= dma->buf_count ) { 1636 DRM_ERROR( "buffer index %d (of %d max)\n", 1637 indirect.idx, dma->buf_count - 1 ); 1638 return DRM_ERR(EINVAL); 1639 } 1640 1641 buf = dma->buflist[indirect.idx]; 1642 1643 if ( buf->filp != filp ) { 1644 DRM_ERROR( "process %d using buffer owned by %p\n", 1645 DRM_CURRENTPID, buf->filp ); 1646 return DRM_ERR(EINVAL); 1647 } 1648 if ( buf->pending ) { 1649 DRM_ERROR( "sending pending buffer %d\n", indirect.idx ); 1650 return DRM_ERR(EINVAL); 1651 } 1652 1653 if ( indirect.start < buf->used ) { 1654 DRM_ERROR( "reusing indirect: start=0x%x actual=0x%x\n", 1655 indirect.start, buf->used ); 1656 return DRM_ERR(EINVAL); 1657 } 1658 1659 RING_SPACE_TEST_WITH_RETURN( dev_priv ); 1660 VB_AGE_TEST_WITH_RETURN( dev_priv ); 1661 1662 buf->used = indirect.end; 1663 1664 /* Wait for the 3D stream to idle before the indirect buffer 1665 * containing 2D acceleration commands is processed. 1666 */ 1667 BEGIN_RING( 2 ); 1668 1669 RADEON_WAIT_UNTIL_3D_IDLE(); 1670 1671 ADVANCE_RING(); 1672 1673 /* Dispatch the indirect buffer full of commands from the 1674 * X server. This is insecure and is thus only available to 1675 * privileged clients. 1676 */ 1677 radeon_cp_dispatch_indirect( dev, buf, indirect.start, indirect.end ); 1678 if (indirect.discard) { 1679 radeon_cp_discard_buffer( dev, buf ); 1680 } 1681 1682 1683 COMMIT_RING(); 1684 return 0; 1685} 1686 1687int radeon_cp_vertex2( DRM_IOCTL_ARGS ) 1688{ 1689 DRM_DEVICE; 1690 drm_radeon_private_t *dev_priv = dev->dev_private; 1691 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; 1692 drm_device_dma_t *dma = dev->dma; 1693 drm_buf_t *buf; 1694 drm_radeon_vertex2_t vertex; 1695 int i; 1696 unsigned char laststate; 1697 1698 LOCK_TEST_WITH_RETURN( dev, filp ); 1699 1700 if ( !dev_priv ) { 1701 DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); 1702 return DRM_ERR(EINVAL); 1703 } 1704 1705 DRM_COPY_FROM_USER_IOCTL( vertex, (drm_radeon_vertex2_t *)data, 1706 sizeof(vertex) ); 1707 1708 DRM_DEBUG( "pid=%d index=%d discard=%d\n", 1709 DRM_CURRENTPID, 1710 vertex.idx, vertex.discard ); 1711 1712 if ( vertex.idx < 0 || vertex.idx >= dma->buf_count ) { 1713 DRM_ERROR( "buffer index %d (of %d max)\n", 1714 vertex.idx, dma->buf_count - 1 ); 1715 return DRM_ERR(EINVAL); 1716 } 1717 1718 RING_SPACE_TEST_WITH_RETURN( dev_priv ); 1719 VB_AGE_TEST_WITH_RETURN( dev_priv ); 1720 1721 buf = dma->buflist[vertex.idx]; 1722 1723 if ( buf->filp != filp ) { 1724 DRM_ERROR( "process %d using buffer owned by %p\n", 1725 DRM_CURRENTPID, buf->filp ); 1726 return DRM_ERR(EINVAL); 1727 } 1728 1729 if ( buf->pending ) { 1730 DRM_ERROR( "sending pending buffer %d\n", vertex.idx ); 1731 return DRM_ERR(EINVAL); 1732 } 1733 1734 if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS) 1735 return DRM_ERR(EINVAL); 1736 1737 for (laststate = 0xff, i = 0 ; i < vertex.nr_prims ; i++) { 1738 drm_radeon_prim_t prim; 1739 drm_radeon_tcl_prim_t tclprim; 1740 1741 if ( DRM_COPY_FROM_USER( &prim, &vertex.prim[i], sizeof(prim) ) ) 1742 return DRM_ERR(EFAULT); 1743 1744 if ( prim.stateidx != laststate ) { 1745 drm_radeon_state_t state; 1746 1747 if ( DRM_COPY_FROM_USER( &state, 1748 &vertex.state[prim.stateidx], 1749 sizeof(state) ) ) 1750 return DRM_ERR(EFAULT); 1751 1752 radeon_emit_state2( dev_priv, &state ); 1753 1754 laststate = prim.stateidx; 1755 } 1756 1757 tclprim.start = prim.start; 1758 tclprim.finish = prim.finish; 1759 tclprim.prim = prim.prim; 1760 tclprim.vc_format = prim.vc_format; 1761 1762 if ( prim.prim & RADEON_PRIM_WALK_IND ) { 1763 tclprim.offset = prim.numverts * 64; 1764 tclprim.numverts = RADEON_MAX_VB_VERTS; /* duh */ 1765 1766 radeon_cp_dispatch_indices( dev, buf, &tclprim ); 1767 } else { 1768 tclprim.numverts = prim.numverts; 1769 tclprim.offset = 0; /* not used */ 1770 1771 radeon_cp_dispatch_vertex( dev, buf, &tclprim ); 1772 } 1773 1774 if (sarea_priv->nbox == 1) 1775 sarea_priv->nbox = 0; 1776 } 1777 1778 if ( vertex.discard ) { 1779 radeon_cp_discard_buffer( dev, buf ); 1780 } 1781 1782 COMMIT_RING(); 1783 return 0; 1784} 1785 1786 1787static int radeon_emit_packets( 1788 drm_radeon_private_t *dev_priv, 1789 drm_radeon_cmd_header_t header, 1790 drm_radeon_cmd_buffer_t *cmdbuf ) 1791{ 1792 int id = (int)header.packet.packet_id; 1793 int sz, reg; 1794 int *data = (int *)cmdbuf->buf; 1795 RING_LOCALS; 1796 1797 if (id >= RADEON_MAX_STATE_PACKETS) 1798 return DRM_ERR(EINVAL); 1799 1800 sz = packet[id].len; 1801 reg = packet[id].start; 1802 1803 if (sz * sizeof(int) > cmdbuf->bufsz) 1804 return DRM_ERR(EINVAL); 1805 1806 BEGIN_RING(sz+1); 1807 OUT_RING( CP_PACKET0( reg, (sz-1) ) ); 1808 OUT_RING_USER_TABLE( data, sz ); 1809 ADVANCE_RING(); 1810 1811 cmdbuf->buf += sz * sizeof(int); 1812 cmdbuf->bufsz -= sz * sizeof(int); 1813 return 0; 1814} 1815 1816static __inline__ int radeon_emit_scalars( 1817 drm_radeon_private_t *dev_priv, 1818 drm_radeon_cmd_header_t header, 1819 drm_radeon_cmd_buffer_t *cmdbuf ) 1820{ 1821 int sz = header.scalars.count; 1822 int *data = (int *)cmdbuf->buf; 1823 int start = header.scalars.offset; 1824 int stride = header.scalars.stride; 1825 RING_LOCALS; 1826 1827 BEGIN_RING( 3+sz ); 1828 OUT_RING( CP_PACKET0( RADEON_SE_TCL_SCALAR_INDX_REG, 0 ) ); 1829 OUT_RING( start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT)); 1830 OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_SCALAR_DATA_REG, sz-1 ) ); 1831 OUT_RING_USER_TABLE( data, sz ); 1832 ADVANCE_RING(); 1833 cmdbuf->buf += sz * sizeof(int); 1834 cmdbuf->bufsz -= sz * sizeof(int); 1835 return 0; 1836} 1837 1838/* God this is ugly 1839 */ 1840static __inline__ int radeon_emit_scalars2( 1841 drm_radeon_private_t *dev_priv, 1842 drm_radeon_cmd_header_t header, 1843 drm_radeon_cmd_buffer_t *cmdbuf ) 1844{ 1845 int sz = header.scalars.count; 1846 int *data = (int *)cmdbuf->buf; 1847 int start = ((unsigned int)header.scalars.offset) + 0x100; 1848 int stride = header.scalars.stride; 1849 RING_LOCALS; 1850 1851 BEGIN_RING( 3+sz ); 1852 OUT_RING( CP_PACKET0( RADEON_SE_TCL_SCALAR_INDX_REG, 0 ) ); 1853 OUT_RING( start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT)); 1854 OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_SCALAR_DATA_REG, sz-1 ) ); 1855 OUT_RING_USER_TABLE( data, sz ); 1856 ADVANCE_RING(); 1857 cmdbuf->buf += sz * sizeof(int); 1858 cmdbuf->bufsz -= sz * sizeof(int); 1859 return 0; 1860} 1861 1862static __inline__ int radeon_emit_vectors( 1863 drm_radeon_private_t *dev_priv, 1864 drm_radeon_cmd_header_t header, 1865 drm_radeon_cmd_buffer_t *cmdbuf ) 1866{ 1867 int sz = header.vectors.count; 1868 int *data = (int *)cmdbuf->buf; 1869 int start = header.vectors.offset; 1870 int stride = header.vectors.stride; 1871 RING_LOCALS; 1872 1873 BEGIN_RING( 3+sz ); 1874 OUT_RING( CP_PACKET0( RADEON_SE_TCL_VECTOR_INDX_REG, 0 ) ); 1875 OUT_RING( start | (stride << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT)); 1876 OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_VECTOR_DATA_REG, (sz-1) ) ); 1877 OUT_RING_USER_TABLE( data, sz ); 1878 ADVANCE_RING(); 1879 1880 cmdbuf->buf += sz * sizeof(int); 1881 cmdbuf->bufsz -= sz * sizeof(int); 1882 return 0; 1883} 1884 1885 1886static int radeon_emit_packet3( drm_device_t *dev, 1887 drm_radeon_cmd_buffer_t *cmdbuf ) 1888{ 1889 drm_radeon_private_t *dev_priv = dev->dev_private; 1890 int cmdsz, tmp; 1891 int *cmd = (int *)cmdbuf->buf; 1892 RING_LOCALS; 1893 1894 1895 DRM_DEBUG("\n"); 1896 1897 if (DRM_GET_USER_UNCHECKED( tmp, &cmd[0])) 1898 return DRM_ERR(EFAULT); 1899 1900 cmdsz = 2 + ((tmp & RADEON_CP_PACKET_COUNT_MASK) >> 16); 1901 1902 if ((tmp & 0xc0000000) != RADEON_CP_PACKET3 || 1903 cmdsz * 4 > cmdbuf->bufsz) 1904 return DRM_ERR(EINVAL); 1905 1906 BEGIN_RING( cmdsz ); 1907 OUT_RING_USER_TABLE( cmd, cmdsz ); 1908 ADVANCE_RING(); 1909 1910 cmdbuf->buf += cmdsz * 4; 1911 cmdbuf->bufsz -= cmdsz * 4; 1912 return 0; 1913} 1914 1915 1916static int radeon_emit_packet3_cliprect( drm_device_t *dev, 1917 drm_radeon_cmd_buffer_t *cmdbuf, 1918 int orig_nbox ) 1919{ 1920 drm_radeon_private_t *dev_priv = dev->dev_private; 1921 drm_clip_rect_t box; 1922 int cmdsz, tmp; 1923 int *cmd = (int *)cmdbuf->buf; 1924 drm_clip_rect_t *boxes = cmdbuf->boxes; 1925 int i = 0; 1926 RING_LOCALS; 1927 1928 DRM_DEBUG("\n"); 1929 1930 if (DRM_GET_USER_UNCHECKED( tmp, &cmd[0])) 1931 return DRM_ERR(EFAULT); 1932 1933 cmdsz = 2 + ((tmp & RADEON_CP_PACKET_COUNT_MASK) >> 16); 1934 1935 if ((tmp & 0xc0000000) != RADEON_CP_PACKET3 || 1936 cmdsz * 4 > cmdbuf->bufsz) 1937 return DRM_ERR(EINVAL); 1938 1939 if (!orig_nbox) 1940 goto out; 1941 1942 do { 1943 if ( i < cmdbuf->nbox ) { 1944 if (DRM_COPY_FROM_USER_UNCHECKED( &box, &boxes[i], sizeof(box) )) 1945 return DRM_ERR(EFAULT); 1946 /* FIXME The second and subsequent times round 1947 * this loop, send a WAIT_UNTIL_3D_IDLE before 1948 * calling emit_clip_rect(). This fixes a 1949 * lockup on fast machines when sending 1950 * several cliprects with a cmdbuf, as when 1951 * waving a 2D window over a 3D 1952 * window. Something in the commands from user 1953 * space seems to hang the card when they're 1954 * sent several times in a row. That would be 1955 * the correct place to fix it but this works 1956 * around it until I can figure that out - Tim 1957 * Smith */ 1958 if ( i ) { 1959 BEGIN_RING( 2 ); 1960 RADEON_WAIT_UNTIL_3D_IDLE(); 1961 ADVANCE_RING(); 1962 } 1963 radeon_emit_clip_rect( dev_priv, &box ); 1964 } 1965 1966 BEGIN_RING( cmdsz ); 1967 OUT_RING_USER_TABLE( cmd, cmdsz ); 1968 ADVANCE_RING(); 1969 1970 } while ( ++i < cmdbuf->nbox ); 1971 if (cmdbuf->nbox == 1) 1972 cmdbuf->nbox = 0; 1973 1974 out: 1975 cmdbuf->buf += cmdsz * 4; 1976 cmdbuf->bufsz -= cmdsz * 4; 1977 return 0; 1978} 1979 1980 1981static int radeon_emit_wait( drm_device_t *dev, int flags ) 1982{ 1983 drm_radeon_private_t *dev_priv = dev->dev_private; 1984 RING_LOCALS; 1985 1986 DRM_DEBUG("%s: %x\n", __FUNCTION__, flags); 1987 switch (flags) { 1988 case RADEON_WAIT_2D: 1989 BEGIN_RING( 2 ); 1990 RADEON_WAIT_UNTIL_2D_IDLE(); 1991 ADVANCE_RING(); 1992 break; 1993 case RADEON_WAIT_3D: 1994 BEGIN_RING( 2 ); 1995 RADEON_WAIT_UNTIL_3D_IDLE(); 1996 ADVANCE_RING(); 1997 break; 1998 case RADEON_WAIT_2D|RADEON_WAIT_3D: 1999 BEGIN_RING( 2 ); 2000 RADEON_WAIT_UNTIL_IDLE(); 2001 ADVANCE_RING(); 2002 break; 2003 default: 2004 return DRM_ERR(EINVAL); 2005 } 2006 2007 return 0; 2008} 2009 2010int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ) 2011{ 2012 DRM_DEVICE; 2013 drm_radeon_private_t *dev_priv = dev->dev_private; 2014 drm_device_dma_t *dma = dev->dma; 2015 drm_buf_t *buf = 0; 2016 int idx; 2017 drm_radeon_cmd_buffer_t cmdbuf; 2018 drm_radeon_cmd_header_t header; 2019 int orig_nbox; 2020 2021 LOCK_TEST_WITH_RETURN( dev, filp ); 2022 2023 if ( !dev_priv ) { 2024 DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); 2025 return DRM_ERR(EINVAL); 2026 } 2027 2028 DRM_COPY_FROM_USER_IOCTL( cmdbuf, (drm_radeon_cmd_buffer_t *)data, 2029 sizeof(cmdbuf) ); 2030 2031 RING_SPACE_TEST_WITH_RETURN( dev_priv ); 2032 VB_AGE_TEST_WITH_RETURN( dev_priv ); 2033 2034 2035 if (DRM_VERIFYAREA_READ( cmdbuf.buf, cmdbuf.bufsz )) 2036 return DRM_ERR(EFAULT); 2037 2038 if (cmdbuf.nbox && 2039 DRM_VERIFYAREA_READ(cmdbuf.boxes, 2040 cmdbuf.nbox * sizeof(drm_clip_rect_t))) 2041 return DRM_ERR(EFAULT); 2042 2043 orig_nbox = cmdbuf.nbox; 2044 2045 while ( cmdbuf.bufsz >= sizeof(header) ) { 2046 2047 if (DRM_GET_USER_UNCHECKED( header.i, (int *)cmdbuf.buf )) { 2048 DRM_ERROR("__get_user %p\n", cmdbuf.buf); 2049 return DRM_ERR(EFAULT); 2050 } 2051 2052 cmdbuf.buf += sizeof(header); 2053 cmdbuf.bufsz -= sizeof(header); 2054 2055 switch (header.header.cmd_type) { 2056 case RADEON_CMD_PACKET: 2057 DRM_DEBUG("RADEON_CMD_PACKET\n"); 2058 if (radeon_emit_packets( dev_priv, header, &cmdbuf )) { 2059 DRM_ERROR("radeon_emit_packets failed\n"); 2060 return DRM_ERR(EINVAL); 2061 } 2062 break; 2063 2064 case RADEON_CMD_SCALARS: 2065 DRM_DEBUG("RADEON_CMD_SCALARS\n"); 2066 if (radeon_emit_scalars( dev_priv, header, &cmdbuf )) { 2067 DRM_ERROR("radeon_emit_scalars failed\n"); 2068 return DRM_ERR(EINVAL); 2069 } 2070 break; 2071 2072 case RADEON_CMD_VECTORS: 2073 DRM_DEBUG("RADEON_CMD_VECTORS\n"); 2074 if (radeon_emit_vectors( dev_priv, header, &cmdbuf )) { 2075 DRM_ERROR("radeon_emit_vectors failed\n"); 2076 return DRM_ERR(EINVAL); 2077 } 2078 break; 2079 2080 case RADEON_CMD_DMA_DISCARD: 2081 DRM_DEBUG("RADEON_CMD_DMA_DISCARD\n"); 2082 idx = header.dma.buf_idx; 2083 if ( idx < 0 || idx >= dma->buf_count ) { 2084 DRM_ERROR( "buffer index %d (of %d max)\n", 2085 idx, dma->buf_count - 1 ); 2086 return DRM_ERR(EINVAL); 2087 } 2088 2089 buf = dma->buflist[idx]; 2090 if ( buf->filp != filp || buf->pending ) { 2091 DRM_ERROR( "bad buffer %p %p %d\n", 2092 buf->filp, filp, buf->pending); 2093 return DRM_ERR(EINVAL); 2094 } 2095 2096 radeon_cp_discard_buffer( dev, buf ); 2097 break; 2098 2099 case RADEON_CMD_PACKET3: 2100 DRM_DEBUG("RADEON_CMD_PACKET3\n"); 2101 if (radeon_emit_packet3( dev, &cmdbuf )) { 2102 DRM_ERROR("radeon_emit_packet3 failed\n"); 2103 return DRM_ERR(EINVAL); 2104 } 2105 break; 2106 2107 case RADEON_CMD_PACKET3_CLIP: 2108 DRM_DEBUG("RADEON_CMD_PACKET3_CLIP\n"); 2109 if (radeon_emit_packet3_cliprect( dev, &cmdbuf, orig_nbox )) { 2110 DRM_ERROR("radeon_emit_packet3_clip failed\n"); 2111 return DRM_ERR(EINVAL); 2112 } 2113 break; 2114 2115 case RADEON_CMD_SCALARS2: 2116 DRM_DEBUG("RADEON_CMD_SCALARS2\n"); 2117 if (radeon_emit_scalars2( dev_priv, header, &cmdbuf )) { 2118 DRM_ERROR("radeon_emit_scalars2 failed\n"); 2119 return DRM_ERR(EINVAL); 2120 } 2121 break; 2122 2123 case RADEON_CMD_WAIT: 2124 DRM_DEBUG("RADEON_CMD_WAIT\n"); 2125 if (radeon_emit_wait( dev, header.wait.flags )) { 2126 DRM_ERROR("radeon_emit_wait failed\n"); 2127 return DRM_ERR(EINVAL); 2128 } 2129 break; 2130 default: 2131 DRM_ERROR("bad cmd_type %d at %p\n", 2132 header.header.cmd_type, 2133 cmdbuf.buf - sizeof(header)); 2134 return DRM_ERR(EINVAL); 2135 } 2136 } 2137 2138 2139 DRM_DEBUG("DONE\n"); 2140 COMMIT_RING(); 2141 return 0; 2142} 2143 2144 2145 2146int radeon_cp_getparam( DRM_IOCTL_ARGS ) 2147{ 2148 DRM_DEVICE; 2149 drm_radeon_private_t *dev_priv = dev->dev_private; 2150 drm_radeon_getparam_t param; 2151 int value; 2152 2153 if ( !dev_priv ) { 2154 DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); 2155 return DRM_ERR(EINVAL); 2156 } 2157 2158 DRM_COPY_FROM_USER_IOCTL( param, (drm_radeon_getparam_t *)data, 2159 sizeof(param) ); 2160 2161 DRM_DEBUG( "pid=%d\n", DRM_CURRENTPID ); 2162 2163 switch( param.param ) {
| 1005 u32 *data; 1006 int dwords; 1007 int i = 0; 1008 int start = prim->start + RADEON_INDEX_PRIM_OFFSET; 1009 int count = (prim->finish - start) / sizeof(u16); 1010 int nbox = sarea_priv->nbox; 1011 1012 DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d offset: %x nr %d\n", 1013 prim->prim, 1014 prim->vc_format, 1015 prim->start, 1016 prim->finish, 1017 prim->offset, 1018 prim->numverts); 1019 1020 if (bad_prim_vertex_nr( prim->prim, count )) { 1021 DRM_ERROR( "bad prim %x count %d\n", 1022 prim->prim, count ); 1023 return; 1024 } 1025 1026 1027 if ( start >= prim->finish || 1028 (prim->start & 0x7) ) { 1029 DRM_ERROR( "buffer prim %d\n", prim->prim ); 1030 return; 1031 } 1032 1033 dwords = (prim->finish - prim->start + 3) / sizeof(u32); 1034 1035 data = (u32 *)((char *)dev_priv->buffers->handle + 1036 elt_buf->offset + prim->start); 1037 1038 data[0] = CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, dwords-2 ); 1039 data[1] = offset; 1040 data[2] = prim->numverts; 1041 data[3] = prim->vc_format; 1042 data[4] = (prim->prim | 1043 RADEON_PRIM_WALK_IND | 1044 RADEON_COLOR_ORDER_RGBA | 1045 RADEON_VTX_FMT_RADEON_MODE | 1046 (count << RADEON_NUM_VERTICES_SHIFT) ); 1047 1048 do { 1049 if ( i < nbox ) 1050 radeon_emit_clip_rect( dev_priv, 1051 &sarea_priv->boxes[i] ); 1052 1053 radeon_cp_dispatch_indirect( dev, elt_buf, 1054 prim->start, 1055 prim->finish ); 1056 1057 i++; 1058 } while ( i < nbox ); 1059 1060} 1061 1062#define RADEON_MAX_TEXTURE_SIZE (RADEON_BUFFER_SIZE - 8 * sizeof(u32)) 1063 1064static int radeon_cp_dispatch_texture( DRMFILE filp, 1065 drm_device_t *dev, 1066 drm_radeon_texture_t *tex, 1067 drm_radeon_tex_image_t *image ) 1068{ 1069 drm_radeon_private_t *dev_priv = dev->dev_private; 1070 drm_buf_t *buf; 1071 u32 format; 1072 u32 *buffer; 1073 const u8 *data; 1074 int size, dwords, tex_width, blit_width; 1075 u32 height; 1076 int i; 1077 RING_LOCALS; 1078 1079 dev_priv->stats.boxes |= RADEON_BOX_TEXTURE_LOAD; 1080 1081 /* Flush the pixel cache. This ensures no pixel data gets mixed 1082 * up with the texture data from the host data blit, otherwise 1083 * part of the texture image may be corrupted. 1084 */ 1085 BEGIN_RING( 4 ); 1086 RADEON_FLUSH_CACHE(); 1087 RADEON_WAIT_UNTIL_IDLE(); 1088 ADVANCE_RING(); 1089 1090#ifdef __BIG_ENDIAN 1091 /* The Mesa texture functions provide the data in little endian as the 1092 * chip wants it, but we need to compensate for the fact that the CP 1093 * ring gets byte-swapped 1094 */ 1095 BEGIN_RING( 2 ); 1096 OUT_RING_REG( RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_32BIT ); 1097 ADVANCE_RING(); 1098#endif 1099 1100 1101 /* The compiler won't optimize away a division by a variable, 1102 * even if the only legal values are powers of two. Thus, we'll 1103 * use a shift instead. 1104 */ 1105 switch ( tex->format ) { 1106 case RADEON_TXFORMAT_ARGB8888: 1107 case RADEON_TXFORMAT_RGBA8888: 1108 format = RADEON_COLOR_FORMAT_ARGB8888; 1109 tex_width = tex->width * 4; 1110 blit_width = image->width * 4; 1111 break; 1112 case RADEON_TXFORMAT_AI88: 1113 case RADEON_TXFORMAT_ARGB1555: 1114 case RADEON_TXFORMAT_RGB565: 1115 case RADEON_TXFORMAT_ARGB4444: 1116 case RADEON_TXFORMAT_VYUY422: 1117 case RADEON_TXFORMAT_YVYU422: 1118 format = RADEON_COLOR_FORMAT_RGB565; 1119 tex_width = tex->width * 2; 1120 blit_width = image->width * 2; 1121 break; 1122 case RADEON_TXFORMAT_I8: 1123 case RADEON_TXFORMAT_RGB332: 1124 format = RADEON_COLOR_FORMAT_CI8; 1125 tex_width = tex->width * 1; 1126 blit_width = image->width * 1; 1127 break; 1128 default: 1129 DRM_ERROR( "invalid texture format %d\n", tex->format ); 1130 return DRM_ERR(EINVAL); 1131 } 1132 1133 DRM_DEBUG("tex=%dx%d blit=%d\n", tex_width, tex->height, blit_width ); 1134 1135 do { 1136 DRM_DEBUG( "tex: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n", 1137 tex->offset >> 10, tex->pitch, tex->format, 1138 image->x, image->y, image->width, image->height ); 1139 1140 /* Make a copy of some parameters in case we have to 1141 * update them for a multi-pass texture blit. 1142 */ 1143 height = image->height; 1144 data = (const u8 *)image->data; 1145 1146 size = height * blit_width; 1147 1148 if ( size > RADEON_MAX_TEXTURE_SIZE ) { 1149 height = RADEON_MAX_TEXTURE_SIZE / blit_width; 1150 size = height * blit_width; 1151 } else if ( size < 4 && size > 0 ) { 1152 size = 4; 1153 } else if ( size == 0 ) { 1154 return 0; 1155 } 1156 1157 buf = radeon_freelist_get( dev ); 1158 if ( 0 && !buf ) { 1159 radeon_do_cp_idle( dev_priv ); 1160 buf = radeon_freelist_get( dev ); 1161 } 1162 if ( !buf ) { 1163 DRM_DEBUG("radeon_cp_dispatch_texture: EAGAIN\n"); 1164 DRM_COPY_TO_USER( tex->image, image, sizeof(*image) ); 1165 return DRM_ERR(EAGAIN); 1166 } 1167 1168 1169 /* Dispatch the indirect buffer. 1170 */ 1171 buffer = (u32*)((char*)dev_priv->buffers->handle + buf->offset); 1172 dwords = size / 4; 1173 buffer[0] = CP_PACKET3( RADEON_CNTL_HOSTDATA_BLT, dwords + 6 ); 1174 buffer[1] = (RADEON_GMC_DST_PITCH_OFFSET_CNTL | 1175 RADEON_GMC_BRUSH_NONE | 1176 (format << 8) | 1177 RADEON_GMC_SRC_DATATYPE_COLOR | 1178 RADEON_ROP3_S | 1179 RADEON_DP_SRC_SOURCE_HOST_DATA | 1180 RADEON_GMC_CLR_CMP_CNTL_DIS | 1181 RADEON_GMC_WR_MSK_DIS); 1182 1183 buffer[2] = (tex->pitch << 22) | (tex->offset >> 10); 1184 buffer[3] = 0xffffffff; 1185 buffer[4] = 0xffffffff; 1186 buffer[5] = (image->y << 16) | image->x; 1187 buffer[6] = (height << 16) | image->width; 1188 buffer[7] = dwords; 1189 buffer += 8; 1190 1191 if ( tex_width >= 32 ) { 1192 /* Texture image width is larger than the minimum, so we 1193 * can upload it directly. 1194 */ 1195 if ( DRM_COPY_FROM_USER( buffer, data, 1196 dwords * sizeof(u32) ) ) { 1197 DRM_ERROR( "EFAULT on data, %d dwords\n", 1198 dwords ); 1199 return DRM_ERR(EFAULT); 1200 } 1201 } else { 1202 /* Texture image width is less than the minimum, so we 1203 * need to pad out each image scanline to the minimum 1204 * width. 1205 */ 1206 for ( i = 0 ; i < tex->height ; i++ ) { 1207 if ( DRM_COPY_FROM_USER( buffer, data, 1208 tex_width ) ) { 1209 DRM_ERROR( "EFAULT on pad, %d bytes\n", 1210 tex_width ); 1211 return DRM_ERR(EFAULT); 1212 } 1213 buffer += 8; 1214 data += tex_width; 1215 } 1216 } 1217 1218 buf->filp = filp; 1219 buf->used = (dwords + 8) * sizeof(u32); 1220 radeon_cp_dispatch_indirect( dev, buf, 0, buf->used ); 1221 radeon_cp_discard_buffer( dev, buf ); 1222 1223 /* Update the input parameters for next time */ 1224 image->y += height; 1225 image->height -= height; 1226 (const u8 *)image->data += size; 1227 } while (image->height > 0); 1228 1229 /* Flush the pixel cache after the blit completes. This ensures 1230 * the texture data is written out to memory before rendering 1231 * continues. 1232 */ 1233 BEGIN_RING( 4 ); 1234 RADEON_FLUSH_CACHE(); 1235 RADEON_WAIT_UNTIL_2D_IDLE(); 1236 ADVANCE_RING(); 1237 return 0; 1238} 1239 1240 1241static void radeon_cp_dispatch_stipple( drm_device_t *dev, u32 *stipple ) 1242{ 1243 drm_radeon_private_t *dev_priv = dev->dev_private; 1244 int i; 1245 RING_LOCALS; 1246 DRM_DEBUG( "\n" ); 1247 1248 BEGIN_RING( 35 ); 1249 1250 OUT_RING( CP_PACKET0( RADEON_RE_STIPPLE_ADDR, 0 ) ); 1251 OUT_RING( 0x00000000 ); 1252 1253 OUT_RING( CP_PACKET0_TABLE( RADEON_RE_STIPPLE_DATA, 31 ) ); 1254 for ( i = 0 ; i < 32 ; i++ ) { 1255 OUT_RING( stipple[i] ); 1256 } 1257 1258 ADVANCE_RING(); 1259} 1260 1261 1262/* ================================================================ 1263 * IOCTL functions 1264 */ 1265 1266int radeon_cp_clear( DRM_IOCTL_ARGS ) 1267{ 1268 DRM_DEVICE; 1269 drm_radeon_private_t *dev_priv = dev->dev_private; 1270 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; 1271 drm_radeon_clear_t clear; 1272 drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS]; 1273 DRM_DEBUG( "\n" ); 1274 1275 LOCK_TEST_WITH_RETURN( dev, filp ); 1276 1277 DRM_COPY_FROM_USER_IOCTL( clear, (drm_radeon_clear_t *)data, 1278 sizeof(clear) ); 1279 1280 RING_SPACE_TEST_WITH_RETURN( dev_priv ); 1281 1282 if ( sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS ) 1283 sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS; 1284 1285 if ( DRM_COPY_FROM_USER( &depth_boxes, clear.depth_boxes, 1286 sarea_priv->nbox * sizeof(depth_boxes[0]) ) ) 1287 return DRM_ERR(EFAULT); 1288 1289 radeon_cp_dispatch_clear( dev, &clear, depth_boxes ); 1290 1291 COMMIT_RING(); 1292 return 0; 1293} 1294 1295 1296/* Not sure why this isn't set all the time: 1297 */ 1298static int radeon_do_init_pageflip( drm_device_t *dev ) 1299{ 1300 drm_radeon_private_t *dev_priv = dev->dev_private; 1301 RING_LOCALS; 1302 1303 DRM_DEBUG( "\n" ); 1304 1305 BEGIN_RING( 6 ); 1306 RADEON_WAIT_UNTIL_3D_IDLE(); 1307 OUT_RING( CP_PACKET0( RADEON_CRTC_OFFSET_CNTL, 0 ) ); 1308 OUT_RING( RADEON_READ( RADEON_CRTC_OFFSET_CNTL ) | RADEON_CRTC_OFFSET_FLIP_CNTL ); 1309 OUT_RING( CP_PACKET0( RADEON_CRTC2_OFFSET_CNTL, 0 ) ); 1310 OUT_RING( RADEON_READ( RADEON_CRTC2_OFFSET_CNTL ) | RADEON_CRTC_OFFSET_FLIP_CNTL ); 1311 ADVANCE_RING(); 1312 1313 dev_priv->page_flipping = 1; 1314 dev_priv->current_page = 0; 1315 dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page; 1316 1317 return 0; 1318} 1319 1320/* Called whenever a client dies, from DRM(release). 1321 * NOTE: Lock isn't necessarily held when this is called! 1322 */ 1323int radeon_do_cleanup_pageflip( drm_device_t *dev ) 1324{ 1325 drm_radeon_private_t *dev_priv = dev->dev_private; 1326 DRM_DEBUG( "\n" ); 1327 1328 if (dev_priv->current_page != 0) 1329 radeon_cp_dispatch_flip( dev ); 1330 1331 dev_priv->page_flipping = 0; 1332 return 0; 1333} 1334 1335/* Swapping and flipping are different operations, need different ioctls. 1336 * They can & should be intermixed to support multiple 3d windows. 1337 */ 1338int radeon_cp_flip( DRM_IOCTL_ARGS ) 1339{ 1340 DRM_DEVICE; 1341 drm_radeon_private_t *dev_priv = dev->dev_private; 1342 DRM_DEBUG( "\n" ); 1343 1344 LOCK_TEST_WITH_RETURN( dev, filp ); 1345 1346 RING_SPACE_TEST_WITH_RETURN( dev_priv ); 1347 1348 if (!dev_priv->page_flipping) 1349 radeon_do_init_pageflip( dev ); 1350 1351 radeon_cp_dispatch_flip( dev ); 1352 1353 COMMIT_RING(); 1354 return 0; 1355} 1356 1357int radeon_cp_swap( DRM_IOCTL_ARGS ) 1358{ 1359 DRM_DEVICE; 1360 drm_radeon_private_t *dev_priv = dev->dev_private; 1361 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; 1362 DRM_DEBUG( "\n" ); 1363 1364 LOCK_TEST_WITH_RETURN( dev, filp ); 1365 1366 RING_SPACE_TEST_WITH_RETURN( dev_priv ); 1367 1368 if ( sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS ) 1369 sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS; 1370 1371 radeon_cp_dispatch_swap( dev ); 1372 dev_priv->sarea_priv->ctx_owner = 0; 1373 1374 COMMIT_RING(); 1375 return 0; 1376} 1377 1378int radeon_cp_vertex( DRM_IOCTL_ARGS ) 1379{ 1380 DRM_DEVICE; 1381 drm_radeon_private_t *dev_priv = dev->dev_private; 1382 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; 1383 drm_device_dma_t *dma = dev->dma; 1384 drm_buf_t *buf; 1385 drm_radeon_vertex_t vertex; 1386 drm_radeon_tcl_prim_t prim; 1387 1388 LOCK_TEST_WITH_RETURN( dev, filp ); 1389 1390 if ( !dev_priv ) { 1391 DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); 1392 return DRM_ERR(EINVAL); 1393 } 1394 1395 DRM_COPY_FROM_USER_IOCTL( vertex, (drm_radeon_vertex_t *)data, 1396 sizeof(vertex) ); 1397 1398 DRM_DEBUG( "pid=%d index=%d count=%d discard=%d\n", 1399 DRM_CURRENTPID, 1400 vertex.idx, vertex.count, vertex.discard ); 1401 1402 if ( vertex.idx < 0 || vertex.idx >= dma->buf_count ) { 1403 DRM_ERROR( "buffer index %d (of %d max)\n", 1404 vertex.idx, dma->buf_count - 1 ); 1405 return DRM_ERR(EINVAL); 1406 } 1407 if ( vertex.prim < 0 || 1408 vertex.prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST ) { 1409 DRM_ERROR( "buffer prim %d\n", vertex.prim ); 1410 return DRM_ERR(EINVAL); 1411 } 1412 1413 RING_SPACE_TEST_WITH_RETURN( dev_priv ); 1414 VB_AGE_TEST_WITH_RETURN( dev_priv ); 1415 1416 buf = dma->buflist[vertex.idx]; 1417 1418 if ( buf->filp != filp ) { 1419 DRM_ERROR( "process %d using buffer owned by %p\n", 1420 DRM_CURRENTPID, buf->filp ); 1421 return DRM_ERR(EINVAL); 1422 } 1423 if ( buf->pending ) { 1424 DRM_ERROR( "sending pending buffer %d\n", vertex.idx ); 1425 return DRM_ERR(EINVAL); 1426 } 1427 1428 /* Build up a prim_t record: 1429 */ 1430 if (vertex.count) { 1431 buf->used = vertex.count; /* not used? */ 1432 1433 if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) { 1434 radeon_emit_state( dev_priv, 1435 &sarea_priv->context_state, 1436 sarea_priv->tex_state, 1437 sarea_priv->dirty ); 1438 1439 sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES | 1440 RADEON_UPLOAD_TEX1IMAGES | 1441 RADEON_UPLOAD_TEX2IMAGES | 1442 RADEON_REQUIRE_QUIESCENCE); 1443 } 1444 1445 prim.start = 0; 1446 prim.finish = vertex.count; /* unused */ 1447 prim.prim = vertex.prim; 1448 prim.numverts = vertex.count; 1449 prim.vc_format = dev_priv->sarea_priv->vc_format; 1450 1451 radeon_cp_dispatch_vertex( dev, buf, &prim ); 1452 } 1453 1454 if (vertex.discard) { 1455 radeon_cp_discard_buffer( dev, buf ); 1456 } 1457 1458 COMMIT_RING(); 1459 return 0; 1460} 1461 1462int radeon_cp_indices( DRM_IOCTL_ARGS ) 1463{ 1464 DRM_DEVICE; 1465 drm_radeon_private_t *dev_priv = dev->dev_private; 1466 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; 1467 drm_device_dma_t *dma = dev->dma; 1468 drm_buf_t *buf; 1469 drm_radeon_indices_t elts; 1470 drm_radeon_tcl_prim_t prim; 1471 int count; 1472 1473 LOCK_TEST_WITH_RETURN( dev, filp ); 1474 1475 if ( !dev_priv ) { 1476 DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); 1477 return DRM_ERR(EINVAL); 1478 } 1479 1480 DRM_COPY_FROM_USER_IOCTL( elts, (drm_radeon_indices_t *)data, 1481 sizeof(elts) ); 1482 1483 DRM_DEBUG( "pid=%d index=%d start=%d end=%d discard=%d\n", 1484 DRM_CURRENTPID, 1485 elts.idx, elts.start, elts.end, elts.discard ); 1486 1487 if ( elts.idx < 0 || elts.idx >= dma->buf_count ) { 1488 DRM_ERROR( "buffer index %d (of %d max)\n", 1489 elts.idx, dma->buf_count - 1 ); 1490 return DRM_ERR(EINVAL); 1491 } 1492 if ( elts.prim < 0 || 1493 elts.prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST ) { 1494 DRM_ERROR( "buffer prim %d\n", elts.prim ); 1495 return DRM_ERR(EINVAL); 1496 } 1497 1498 RING_SPACE_TEST_WITH_RETURN( dev_priv ); 1499 VB_AGE_TEST_WITH_RETURN( dev_priv ); 1500 1501 buf = dma->buflist[elts.idx]; 1502 1503 if ( buf->filp != filp ) { 1504 DRM_ERROR( "process %d using buffer owned by %p\n", 1505 DRM_CURRENTPID, buf->filp ); 1506 return DRM_ERR(EINVAL); 1507 } 1508 if ( buf->pending ) { 1509 DRM_ERROR( "sending pending buffer %d\n", elts.idx ); 1510 return DRM_ERR(EINVAL); 1511 } 1512 1513 count = (elts.end - elts.start) / sizeof(u16); 1514 elts.start -= RADEON_INDEX_PRIM_OFFSET; 1515 1516 if ( elts.start & 0x7 ) { 1517 DRM_ERROR( "misaligned buffer 0x%x\n", elts.start ); 1518 return DRM_ERR(EINVAL); 1519 } 1520 if ( elts.start < buf->used ) { 1521 DRM_ERROR( "no header 0x%x - 0x%x\n", elts.start, buf->used ); 1522 return DRM_ERR(EINVAL); 1523 } 1524 1525 buf->used = elts.end; 1526 1527 if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) { 1528 radeon_emit_state( dev_priv, 1529 &sarea_priv->context_state, 1530 sarea_priv->tex_state, 1531 sarea_priv->dirty ); 1532 1533 sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES | 1534 RADEON_UPLOAD_TEX1IMAGES | 1535 RADEON_UPLOAD_TEX2IMAGES | 1536 RADEON_REQUIRE_QUIESCENCE); 1537 } 1538 1539 1540 /* Build up a prim_t record: 1541 */ 1542 prim.start = elts.start; 1543 prim.finish = elts.end; 1544 prim.prim = elts.prim; 1545 prim.offset = 0; /* offset from start of dma buffers */ 1546 prim.numverts = RADEON_MAX_VB_VERTS; /* duh */ 1547 prim.vc_format = dev_priv->sarea_priv->vc_format; 1548 1549 radeon_cp_dispatch_indices( dev, buf, &prim ); 1550 if (elts.discard) { 1551 radeon_cp_discard_buffer( dev, buf ); 1552 } 1553 1554 COMMIT_RING(); 1555 return 0; 1556} 1557 1558int radeon_cp_texture( DRM_IOCTL_ARGS ) 1559{ 1560 DRM_DEVICE; 1561 drm_radeon_private_t *dev_priv = dev->dev_private; 1562 drm_radeon_texture_t tex; 1563 drm_radeon_tex_image_t image; 1564 int ret; 1565 1566 LOCK_TEST_WITH_RETURN( dev, filp ); 1567 1568 DRM_COPY_FROM_USER_IOCTL( tex, (drm_radeon_texture_t *)data, sizeof(tex) ); 1569 1570 if ( tex.image == NULL ) { 1571 DRM_ERROR( "null texture image!\n" ); 1572 return DRM_ERR(EINVAL); 1573 } 1574 1575 if ( DRM_COPY_FROM_USER( &image, 1576 (drm_radeon_tex_image_t *)tex.image, 1577 sizeof(image) ) ) 1578 return DRM_ERR(EFAULT); 1579 1580 RING_SPACE_TEST_WITH_RETURN( dev_priv ); 1581 VB_AGE_TEST_WITH_RETURN( dev_priv ); 1582 1583 ret = radeon_cp_dispatch_texture( filp, dev, &tex, &image ); 1584 1585 COMMIT_RING(); 1586 return ret; 1587} 1588 1589int radeon_cp_stipple( DRM_IOCTL_ARGS ) 1590{ 1591 DRM_DEVICE; 1592 drm_radeon_private_t *dev_priv = dev->dev_private; 1593 drm_radeon_stipple_t stipple; 1594 u32 mask[32]; 1595 1596 LOCK_TEST_WITH_RETURN( dev, filp ); 1597 1598 DRM_COPY_FROM_USER_IOCTL( stipple, (drm_radeon_stipple_t *)data, 1599 sizeof(stipple) ); 1600 1601 if ( DRM_COPY_FROM_USER( &mask, stipple.mask, 32 * sizeof(u32) ) ) 1602 return DRM_ERR(EFAULT); 1603 1604 RING_SPACE_TEST_WITH_RETURN( dev_priv ); 1605 1606 radeon_cp_dispatch_stipple( dev, mask ); 1607 1608 COMMIT_RING(); 1609 return 0; 1610} 1611 1612int radeon_cp_indirect( DRM_IOCTL_ARGS ) 1613{ 1614 DRM_DEVICE; 1615 drm_radeon_private_t *dev_priv = dev->dev_private; 1616 drm_device_dma_t *dma = dev->dma; 1617 drm_buf_t *buf; 1618 drm_radeon_indirect_t indirect; 1619 RING_LOCALS; 1620 1621 LOCK_TEST_WITH_RETURN( dev, filp ); 1622 1623 if ( !dev_priv ) { 1624 DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); 1625 return DRM_ERR(EINVAL); 1626 } 1627 1628 DRM_COPY_FROM_USER_IOCTL( indirect, (drm_radeon_indirect_t *)data, 1629 sizeof(indirect) ); 1630 1631 DRM_DEBUG( "indirect: idx=%d s=%d e=%d d=%d\n", 1632 indirect.idx, indirect.start, 1633 indirect.end, indirect.discard ); 1634 1635 if ( indirect.idx < 0 || indirect.idx >= dma->buf_count ) { 1636 DRM_ERROR( "buffer index %d (of %d max)\n", 1637 indirect.idx, dma->buf_count - 1 ); 1638 return DRM_ERR(EINVAL); 1639 } 1640 1641 buf = dma->buflist[indirect.idx]; 1642 1643 if ( buf->filp != filp ) { 1644 DRM_ERROR( "process %d using buffer owned by %p\n", 1645 DRM_CURRENTPID, buf->filp ); 1646 return DRM_ERR(EINVAL); 1647 } 1648 if ( buf->pending ) { 1649 DRM_ERROR( "sending pending buffer %d\n", indirect.idx ); 1650 return DRM_ERR(EINVAL); 1651 } 1652 1653 if ( indirect.start < buf->used ) { 1654 DRM_ERROR( "reusing indirect: start=0x%x actual=0x%x\n", 1655 indirect.start, buf->used ); 1656 return DRM_ERR(EINVAL); 1657 } 1658 1659 RING_SPACE_TEST_WITH_RETURN( dev_priv ); 1660 VB_AGE_TEST_WITH_RETURN( dev_priv ); 1661 1662 buf->used = indirect.end; 1663 1664 /* Wait for the 3D stream to idle before the indirect buffer 1665 * containing 2D acceleration commands is processed. 1666 */ 1667 BEGIN_RING( 2 ); 1668 1669 RADEON_WAIT_UNTIL_3D_IDLE(); 1670 1671 ADVANCE_RING(); 1672 1673 /* Dispatch the indirect buffer full of commands from the 1674 * X server. This is insecure and is thus only available to 1675 * privileged clients. 1676 */ 1677 radeon_cp_dispatch_indirect( dev, buf, indirect.start, indirect.end ); 1678 if (indirect.discard) { 1679 radeon_cp_discard_buffer( dev, buf ); 1680 } 1681 1682 1683 COMMIT_RING(); 1684 return 0; 1685} 1686 1687int radeon_cp_vertex2( DRM_IOCTL_ARGS ) 1688{ 1689 DRM_DEVICE; 1690 drm_radeon_private_t *dev_priv = dev->dev_private; 1691 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; 1692 drm_device_dma_t *dma = dev->dma; 1693 drm_buf_t *buf; 1694 drm_radeon_vertex2_t vertex; 1695 int i; 1696 unsigned char laststate; 1697 1698 LOCK_TEST_WITH_RETURN( dev, filp ); 1699 1700 if ( !dev_priv ) { 1701 DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); 1702 return DRM_ERR(EINVAL); 1703 } 1704 1705 DRM_COPY_FROM_USER_IOCTL( vertex, (drm_radeon_vertex2_t *)data, 1706 sizeof(vertex) ); 1707 1708 DRM_DEBUG( "pid=%d index=%d discard=%d\n", 1709 DRM_CURRENTPID, 1710 vertex.idx, vertex.discard ); 1711 1712 if ( vertex.idx < 0 || vertex.idx >= dma->buf_count ) { 1713 DRM_ERROR( "buffer index %d (of %d max)\n", 1714 vertex.idx, dma->buf_count - 1 ); 1715 return DRM_ERR(EINVAL); 1716 } 1717 1718 RING_SPACE_TEST_WITH_RETURN( dev_priv ); 1719 VB_AGE_TEST_WITH_RETURN( dev_priv ); 1720 1721 buf = dma->buflist[vertex.idx]; 1722 1723 if ( buf->filp != filp ) { 1724 DRM_ERROR( "process %d using buffer owned by %p\n", 1725 DRM_CURRENTPID, buf->filp ); 1726 return DRM_ERR(EINVAL); 1727 } 1728 1729 if ( buf->pending ) { 1730 DRM_ERROR( "sending pending buffer %d\n", vertex.idx ); 1731 return DRM_ERR(EINVAL); 1732 } 1733 1734 if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS) 1735 return DRM_ERR(EINVAL); 1736 1737 for (laststate = 0xff, i = 0 ; i < vertex.nr_prims ; i++) { 1738 drm_radeon_prim_t prim; 1739 drm_radeon_tcl_prim_t tclprim; 1740 1741 if ( DRM_COPY_FROM_USER( &prim, &vertex.prim[i], sizeof(prim) ) ) 1742 return DRM_ERR(EFAULT); 1743 1744 if ( prim.stateidx != laststate ) { 1745 drm_radeon_state_t state; 1746 1747 if ( DRM_COPY_FROM_USER( &state, 1748 &vertex.state[prim.stateidx], 1749 sizeof(state) ) ) 1750 return DRM_ERR(EFAULT); 1751 1752 radeon_emit_state2( dev_priv, &state ); 1753 1754 laststate = prim.stateidx; 1755 } 1756 1757 tclprim.start = prim.start; 1758 tclprim.finish = prim.finish; 1759 tclprim.prim = prim.prim; 1760 tclprim.vc_format = prim.vc_format; 1761 1762 if ( prim.prim & RADEON_PRIM_WALK_IND ) { 1763 tclprim.offset = prim.numverts * 64; 1764 tclprim.numverts = RADEON_MAX_VB_VERTS; /* duh */ 1765 1766 radeon_cp_dispatch_indices( dev, buf, &tclprim ); 1767 } else { 1768 tclprim.numverts = prim.numverts; 1769 tclprim.offset = 0; /* not used */ 1770 1771 radeon_cp_dispatch_vertex( dev, buf, &tclprim ); 1772 } 1773 1774 if (sarea_priv->nbox == 1) 1775 sarea_priv->nbox = 0; 1776 } 1777 1778 if ( vertex.discard ) { 1779 radeon_cp_discard_buffer( dev, buf ); 1780 } 1781 1782 COMMIT_RING(); 1783 return 0; 1784} 1785 1786 1787static int radeon_emit_packets( 1788 drm_radeon_private_t *dev_priv, 1789 drm_radeon_cmd_header_t header, 1790 drm_radeon_cmd_buffer_t *cmdbuf ) 1791{ 1792 int id = (int)header.packet.packet_id; 1793 int sz, reg; 1794 int *data = (int *)cmdbuf->buf; 1795 RING_LOCALS; 1796 1797 if (id >= RADEON_MAX_STATE_PACKETS) 1798 return DRM_ERR(EINVAL); 1799 1800 sz = packet[id].len; 1801 reg = packet[id].start; 1802 1803 if (sz * sizeof(int) > cmdbuf->bufsz) 1804 return DRM_ERR(EINVAL); 1805 1806 BEGIN_RING(sz+1); 1807 OUT_RING( CP_PACKET0( reg, (sz-1) ) ); 1808 OUT_RING_USER_TABLE( data, sz ); 1809 ADVANCE_RING(); 1810 1811 cmdbuf->buf += sz * sizeof(int); 1812 cmdbuf->bufsz -= sz * sizeof(int); 1813 return 0; 1814} 1815 1816static __inline__ int radeon_emit_scalars( 1817 drm_radeon_private_t *dev_priv, 1818 drm_radeon_cmd_header_t header, 1819 drm_radeon_cmd_buffer_t *cmdbuf ) 1820{ 1821 int sz = header.scalars.count; 1822 int *data = (int *)cmdbuf->buf; 1823 int start = header.scalars.offset; 1824 int stride = header.scalars.stride; 1825 RING_LOCALS; 1826 1827 BEGIN_RING( 3+sz ); 1828 OUT_RING( CP_PACKET0( RADEON_SE_TCL_SCALAR_INDX_REG, 0 ) ); 1829 OUT_RING( start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT)); 1830 OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_SCALAR_DATA_REG, sz-1 ) ); 1831 OUT_RING_USER_TABLE( data, sz ); 1832 ADVANCE_RING(); 1833 cmdbuf->buf += sz * sizeof(int); 1834 cmdbuf->bufsz -= sz * sizeof(int); 1835 return 0; 1836} 1837 1838/* God this is ugly 1839 */ 1840static __inline__ int radeon_emit_scalars2( 1841 drm_radeon_private_t *dev_priv, 1842 drm_radeon_cmd_header_t header, 1843 drm_radeon_cmd_buffer_t *cmdbuf ) 1844{ 1845 int sz = header.scalars.count; 1846 int *data = (int *)cmdbuf->buf; 1847 int start = ((unsigned int)header.scalars.offset) + 0x100; 1848 int stride = header.scalars.stride; 1849 RING_LOCALS; 1850 1851 BEGIN_RING( 3+sz ); 1852 OUT_RING( CP_PACKET0( RADEON_SE_TCL_SCALAR_INDX_REG, 0 ) ); 1853 OUT_RING( start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT)); 1854 OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_SCALAR_DATA_REG, sz-1 ) ); 1855 OUT_RING_USER_TABLE( data, sz ); 1856 ADVANCE_RING(); 1857 cmdbuf->buf += sz * sizeof(int); 1858 cmdbuf->bufsz -= sz * sizeof(int); 1859 return 0; 1860} 1861 1862static __inline__ int radeon_emit_vectors( 1863 drm_radeon_private_t *dev_priv, 1864 drm_radeon_cmd_header_t header, 1865 drm_radeon_cmd_buffer_t *cmdbuf ) 1866{ 1867 int sz = header.vectors.count; 1868 int *data = (int *)cmdbuf->buf; 1869 int start = header.vectors.offset; 1870 int stride = header.vectors.stride; 1871 RING_LOCALS; 1872 1873 BEGIN_RING( 3+sz ); 1874 OUT_RING( CP_PACKET0( RADEON_SE_TCL_VECTOR_INDX_REG, 0 ) ); 1875 OUT_RING( start | (stride << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT)); 1876 OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_VECTOR_DATA_REG, (sz-1) ) ); 1877 OUT_RING_USER_TABLE( data, sz ); 1878 ADVANCE_RING(); 1879 1880 cmdbuf->buf += sz * sizeof(int); 1881 cmdbuf->bufsz -= sz * sizeof(int); 1882 return 0; 1883} 1884 1885 1886static int radeon_emit_packet3( drm_device_t *dev, 1887 drm_radeon_cmd_buffer_t *cmdbuf ) 1888{ 1889 drm_radeon_private_t *dev_priv = dev->dev_private; 1890 int cmdsz, tmp; 1891 int *cmd = (int *)cmdbuf->buf; 1892 RING_LOCALS; 1893 1894 1895 DRM_DEBUG("\n"); 1896 1897 if (DRM_GET_USER_UNCHECKED( tmp, &cmd[0])) 1898 return DRM_ERR(EFAULT); 1899 1900 cmdsz = 2 + ((tmp & RADEON_CP_PACKET_COUNT_MASK) >> 16); 1901 1902 if ((tmp & 0xc0000000) != RADEON_CP_PACKET3 || 1903 cmdsz * 4 > cmdbuf->bufsz) 1904 return DRM_ERR(EINVAL); 1905 1906 BEGIN_RING( cmdsz ); 1907 OUT_RING_USER_TABLE( cmd, cmdsz ); 1908 ADVANCE_RING(); 1909 1910 cmdbuf->buf += cmdsz * 4; 1911 cmdbuf->bufsz -= cmdsz * 4; 1912 return 0; 1913} 1914 1915 1916static int radeon_emit_packet3_cliprect( drm_device_t *dev, 1917 drm_radeon_cmd_buffer_t *cmdbuf, 1918 int orig_nbox ) 1919{ 1920 drm_radeon_private_t *dev_priv = dev->dev_private; 1921 drm_clip_rect_t box; 1922 int cmdsz, tmp; 1923 int *cmd = (int *)cmdbuf->buf; 1924 drm_clip_rect_t *boxes = cmdbuf->boxes; 1925 int i = 0; 1926 RING_LOCALS; 1927 1928 DRM_DEBUG("\n"); 1929 1930 if (DRM_GET_USER_UNCHECKED( tmp, &cmd[0])) 1931 return DRM_ERR(EFAULT); 1932 1933 cmdsz = 2 + ((tmp & RADEON_CP_PACKET_COUNT_MASK) >> 16); 1934 1935 if ((tmp & 0xc0000000) != RADEON_CP_PACKET3 || 1936 cmdsz * 4 > cmdbuf->bufsz) 1937 return DRM_ERR(EINVAL); 1938 1939 if (!orig_nbox) 1940 goto out; 1941 1942 do { 1943 if ( i < cmdbuf->nbox ) { 1944 if (DRM_COPY_FROM_USER_UNCHECKED( &box, &boxes[i], sizeof(box) )) 1945 return DRM_ERR(EFAULT); 1946 /* FIXME The second and subsequent times round 1947 * this loop, send a WAIT_UNTIL_3D_IDLE before 1948 * calling emit_clip_rect(). This fixes a 1949 * lockup on fast machines when sending 1950 * several cliprects with a cmdbuf, as when 1951 * waving a 2D window over a 3D 1952 * window. Something in the commands from user 1953 * space seems to hang the card when they're 1954 * sent several times in a row. That would be 1955 * the correct place to fix it but this works 1956 * around it until I can figure that out - Tim 1957 * Smith */ 1958 if ( i ) { 1959 BEGIN_RING( 2 ); 1960 RADEON_WAIT_UNTIL_3D_IDLE(); 1961 ADVANCE_RING(); 1962 } 1963 radeon_emit_clip_rect( dev_priv, &box ); 1964 } 1965 1966 BEGIN_RING( cmdsz ); 1967 OUT_RING_USER_TABLE( cmd, cmdsz ); 1968 ADVANCE_RING(); 1969 1970 } while ( ++i < cmdbuf->nbox ); 1971 if (cmdbuf->nbox == 1) 1972 cmdbuf->nbox = 0; 1973 1974 out: 1975 cmdbuf->buf += cmdsz * 4; 1976 cmdbuf->bufsz -= cmdsz * 4; 1977 return 0; 1978} 1979 1980 1981static int radeon_emit_wait( drm_device_t *dev, int flags ) 1982{ 1983 drm_radeon_private_t *dev_priv = dev->dev_private; 1984 RING_LOCALS; 1985 1986 DRM_DEBUG("%s: %x\n", __FUNCTION__, flags); 1987 switch (flags) { 1988 case RADEON_WAIT_2D: 1989 BEGIN_RING( 2 ); 1990 RADEON_WAIT_UNTIL_2D_IDLE(); 1991 ADVANCE_RING(); 1992 break; 1993 case RADEON_WAIT_3D: 1994 BEGIN_RING( 2 ); 1995 RADEON_WAIT_UNTIL_3D_IDLE(); 1996 ADVANCE_RING(); 1997 break; 1998 case RADEON_WAIT_2D|RADEON_WAIT_3D: 1999 BEGIN_RING( 2 ); 2000 RADEON_WAIT_UNTIL_IDLE(); 2001 ADVANCE_RING(); 2002 break; 2003 default: 2004 return DRM_ERR(EINVAL); 2005 } 2006 2007 return 0; 2008} 2009 2010int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ) 2011{ 2012 DRM_DEVICE; 2013 drm_radeon_private_t *dev_priv = dev->dev_private; 2014 drm_device_dma_t *dma = dev->dma; 2015 drm_buf_t *buf = 0; 2016 int idx; 2017 drm_radeon_cmd_buffer_t cmdbuf; 2018 drm_radeon_cmd_header_t header; 2019 int orig_nbox; 2020 2021 LOCK_TEST_WITH_RETURN( dev, filp ); 2022 2023 if ( !dev_priv ) { 2024 DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); 2025 return DRM_ERR(EINVAL); 2026 } 2027 2028 DRM_COPY_FROM_USER_IOCTL( cmdbuf, (drm_radeon_cmd_buffer_t *)data, 2029 sizeof(cmdbuf) ); 2030 2031 RING_SPACE_TEST_WITH_RETURN( dev_priv ); 2032 VB_AGE_TEST_WITH_RETURN( dev_priv ); 2033 2034 2035 if (DRM_VERIFYAREA_READ( cmdbuf.buf, cmdbuf.bufsz )) 2036 return DRM_ERR(EFAULT); 2037 2038 if (cmdbuf.nbox && 2039 DRM_VERIFYAREA_READ(cmdbuf.boxes, 2040 cmdbuf.nbox * sizeof(drm_clip_rect_t))) 2041 return DRM_ERR(EFAULT); 2042 2043 orig_nbox = cmdbuf.nbox; 2044 2045 while ( cmdbuf.bufsz >= sizeof(header) ) { 2046 2047 if (DRM_GET_USER_UNCHECKED( header.i, (int *)cmdbuf.buf )) { 2048 DRM_ERROR("__get_user %p\n", cmdbuf.buf); 2049 return DRM_ERR(EFAULT); 2050 } 2051 2052 cmdbuf.buf += sizeof(header); 2053 cmdbuf.bufsz -= sizeof(header); 2054 2055 switch (header.header.cmd_type) { 2056 case RADEON_CMD_PACKET: 2057 DRM_DEBUG("RADEON_CMD_PACKET\n"); 2058 if (radeon_emit_packets( dev_priv, header, &cmdbuf )) { 2059 DRM_ERROR("radeon_emit_packets failed\n"); 2060 return DRM_ERR(EINVAL); 2061 } 2062 break; 2063 2064 case RADEON_CMD_SCALARS: 2065 DRM_DEBUG("RADEON_CMD_SCALARS\n"); 2066 if (radeon_emit_scalars( dev_priv, header, &cmdbuf )) { 2067 DRM_ERROR("radeon_emit_scalars failed\n"); 2068 return DRM_ERR(EINVAL); 2069 } 2070 break; 2071 2072 case RADEON_CMD_VECTORS: 2073 DRM_DEBUG("RADEON_CMD_VECTORS\n"); 2074 if (radeon_emit_vectors( dev_priv, header, &cmdbuf )) { 2075 DRM_ERROR("radeon_emit_vectors failed\n"); 2076 return DRM_ERR(EINVAL); 2077 } 2078 break; 2079 2080 case RADEON_CMD_DMA_DISCARD: 2081 DRM_DEBUG("RADEON_CMD_DMA_DISCARD\n"); 2082 idx = header.dma.buf_idx; 2083 if ( idx < 0 || idx >= dma->buf_count ) { 2084 DRM_ERROR( "buffer index %d (of %d max)\n", 2085 idx, dma->buf_count - 1 ); 2086 return DRM_ERR(EINVAL); 2087 } 2088 2089 buf = dma->buflist[idx]; 2090 if ( buf->filp != filp || buf->pending ) { 2091 DRM_ERROR( "bad buffer %p %p %d\n", 2092 buf->filp, filp, buf->pending); 2093 return DRM_ERR(EINVAL); 2094 } 2095 2096 radeon_cp_discard_buffer( dev, buf ); 2097 break; 2098 2099 case RADEON_CMD_PACKET3: 2100 DRM_DEBUG("RADEON_CMD_PACKET3\n"); 2101 if (radeon_emit_packet3( dev, &cmdbuf )) { 2102 DRM_ERROR("radeon_emit_packet3 failed\n"); 2103 return DRM_ERR(EINVAL); 2104 } 2105 break; 2106 2107 case RADEON_CMD_PACKET3_CLIP: 2108 DRM_DEBUG("RADEON_CMD_PACKET3_CLIP\n"); 2109 if (radeon_emit_packet3_cliprect( dev, &cmdbuf, orig_nbox )) { 2110 DRM_ERROR("radeon_emit_packet3_clip failed\n"); 2111 return DRM_ERR(EINVAL); 2112 } 2113 break; 2114 2115 case RADEON_CMD_SCALARS2: 2116 DRM_DEBUG("RADEON_CMD_SCALARS2\n"); 2117 if (radeon_emit_scalars2( dev_priv, header, &cmdbuf )) { 2118 DRM_ERROR("radeon_emit_scalars2 failed\n"); 2119 return DRM_ERR(EINVAL); 2120 } 2121 break; 2122 2123 case RADEON_CMD_WAIT: 2124 DRM_DEBUG("RADEON_CMD_WAIT\n"); 2125 if (radeon_emit_wait( dev, header.wait.flags )) { 2126 DRM_ERROR("radeon_emit_wait failed\n"); 2127 return DRM_ERR(EINVAL); 2128 } 2129 break; 2130 default: 2131 DRM_ERROR("bad cmd_type %d at %p\n", 2132 header.header.cmd_type, 2133 cmdbuf.buf - sizeof(header)); 2134 return DRM_ERR(EINVAL); 2135 } 2136 } 2137 2138 2139 DRM_DEBUG("DONE\n"); 2140 COMMIT_RING(); 2141 return 0; 2142} 2143 2144 2145 2146int radeon_cp_getparam( DRM_IOCTL_ARGS ) 2147{ 2148 DRM_DEVICE; 2149 drm_radeon_private_t *dev_priv = dev->dev_private; 2150 drm_radeon_getparam_t param; 2151 int value; 2152 2153 if ( !dev_priv ) { 2154 DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); 2155 return DRM_ERR(EINVAL); 2156 } 2157 2158 DRM_COPY_FROM_USER_IOCTL( param, (drm_radeon_getparam_t *)data, 2159 sizeof(param) ); 2160 2161 DRM_DEBUG( "pid=%d\n", DRM_CURRENTPID ); 2162 2163 switch( param.param ) {
|