radeon_state.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:38k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /* radeon_state.c -- State support for Radeon -*- linux-c -*-
  2.  *
  3.  * Copyright 2000 VA Linux Systems, Inc., Fremont, California.
  4.  * All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the "Software"),
  8.  * to deal in the Software without restriction, including without limitation
  9.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10.  * and/or sell copies of the Software, and to permit persons to whom the
  11.  * Software is furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice (including the next
  14.  * paragraph) shall be included in all copies or substantial portions of the
  15.  * Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  20.  * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  21.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  22.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  23.  * DEALINGS IN THE SOFTWARE.
  24.  *
  25.  * Authors:
  26.  *    Kevin E. Martin <martin@valinux.com>
  27.  *    Gareth Hughes <gareth@valinux.com>
  28.  *
  29.  */
  30. #define __NO_VERSION__
  31. #include "drmP.h"
  32. #include "radeon_drv.h"
  33. #include "drm.h"
  34. #include <linux/delay.h>
  35. /* ================================================================
  36.  * CP hardware state programming functions
  37.  */
  38. static inline void radeon_emit_clip_rect( drm_radeon_private_t *dev_priv,
  39.   drm_clip_rect_t *box )
  40. {
  41. RING_LOCALS;
  42. DRM_DEBUG( "   box:  x1=%d y1=%d  x2=%d y2=%dn",
  43.    box->x1, box->y1, box->x2, box->y2 );
  44. BEGIN_RING( 4 );
  45. OUT_RING( CP_PACKET0( RADEON_RE_TOP_LEFT, 0 ) );
  46. OUT_RING( (box->y1 << 16) | box->x1 );
  47. OUT_RING( CP_PACKET0( RADEON_RE_WIDTH_HEIGHT, 0 ) );
  48. OUT_RING( ((box->y2 - 1) << 16) | (box->x2 - 1) );
  49. ADVANCE_RING();
  50. }
  51. static inline void radeon_emit_context( drm_radeon_private_t *dev_priv )
  52. {
  53. drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
  54. drm_radeon_context_regs_t *ctx = &sarea_priv->context_state;
  55. RING_LOCALS;
  56. DRM_DEBUG( "    %sn", __FUNCTION__ );
  57. BEGIN_RING( 14 );
  58. OUT_RING( CP_PACKET0( RADEON_PP_MISC, 6 ) );
  59. OUT_RING( ctx->pp_misc );
  60. OUT_RING( ctx->pp_fog_color );
  61. OUT_RING( ctx->re_solid_color );
  62. OUT_RING( ctx->rb3d_blendcntl );
  63. OUT_RING( ctx->rb3d_depthoffset );
  64. OUT_RING( ctx->rb3d_depthpitch );
  65. OUT_RING( ctx->rb3d_zstencilcntl );
  66. OUT_RING( CP_PACKET0( RADEON_PP_CNTL, 2 ) );
  67. OUT_RING( ctx->pp_cntl );
  68. OUT_RING( ctx->rb3d_cntl );
  69. OUT_RING( ctx->rb3d_coloroffset );
  70. OUT_RING( CP_PACKET0( RADEON_RB3D_COLORPITCH, 0 ) );
  71. OUT_RING( ctx->rb3d_colorpitch );
  72. ADVANCE_RING();
  73. }
  74. static inline void radeon_emit_vertfmt( drm_radeon_private_t *dev_priv )
  75. {
  76. drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
  77. drm_radeon_context_regs_t *ctx = &sarea_priv->context_state;
  78. RING_LOCALS;
  79. DRM_DEBUG( "    %sn", __FUNCTION__ );
  80. BEGIN_RING( 2 );
  81. OUT_RING( CP_PACKET0( RADEON_SE_COORD_FMT, 0 ) );
  82. OUT_RING( ctx->se_coord_fmt );
  83. ADVANCE_RING();
  84. }
  85. static inline void radeon_emit_line( drm_radeon_private_t *dev_priv )
  86. {
  87. drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
  88. drm_radeon_context_regs_t *ctx = &sarea_priv->context_state;
  89. RING_LOCALS;
  90. DRM_DEBUG( "    %sn", __FUNCTION__ );
  91. BEGIN_RING( 5 );
  92. OUT_RING( CP_PACKET0( RADEON_RE_LINE_PATTERN, 1 ) );
  93. OUT_RING( ctx->re_line_pattern );
  94. OUT_RING( ctx->re_line_state );
  95. OUT_RING( CP_PACKET0( RADEON_SE_LINE_WIDTH, 0 ) );
  96. OUT_RING( ctx->se_line_width );
  97. ADVANCE_RING();
  98. }
  99. static inline void radeon_emit_bumpmap( drm_radeon_private_t *dev_priv )
  100. {
  101. drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
  102. drm_radeon_context_regs_t *ctx = &sarea_priv->context_state;
  103. RING_LOCALS;
  104. DRM_DEBUG( "    %sn", __FUNCTION__ );
  105. BEGIN_RING( 5 );
  106. OUT_RING( CP_PACKET0( RADEON_PP_LUM_MATRIX, 0 ) );
  107. OUT_RING( ctx->pp_lum_matrix );
  108. OUT_RING( CP_PACKET0( RADEON_PP_ROT_MATRIX_0, 1 ) );
  109. OUT_RING( ctx->pp_rot_matrix_0 );
  110. OUT_RING( ctx->pp_rot_matrix_1 );
  111. ADVANCE_RING();
  112. }
  113. static inline void radeon_emit_masks( drm_radeon_private_t *dev_priv )
  114. {
  115. drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
  116. drm_radeon_context_regs_t *ctx = &sarea_priv->context_state;
  117. RING_LOCALS;
  118. DRM_DEBUG( "    %sn", __FUNCTION__ );
  119. BEGIN_RING( 4 );
  120. OUT_RING( CP_PACKET0( RADEON_RB3D_STENCILREFMASK, 2 ) );
  121. OUT_RING( ctx->rb3d_stencilrefmask );
  122. OUT_RING( ctx->rb3d_ropcntl );
  123. OUT_RING( ctx->rb3d_planemask );
  124. ADVANCE_RING();
  125. }
  126. static inline void radeon_emit_viewport( drm_radeon_private_t *dev_priv )
  127. {
  128. drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
  129. drm_radeon_context_regs_t *ctx = &sarea_priv->context_state;
  130. RING_LOCALS;
  131. DRM_DEBUG( "    %sn", __FUNCTION__ );
  132. BEGIN_RING( 7 );
  133. OUT_RING( CP_PACKET0( RADEON_SE_VPORT_XSCALE, 5 ) );
  134. OUT_RING( ctx->se_vport_xscale );
  135. OUT_RING( ctx->se_vport_xoffset );
  136. OUT_RING( ctx->se_vport_yscale );
  137. OUT_RING( ctx->se_vport_yoffset );
  138. OUT_RING( ctx->se_vport_zscale );
  139. OUT_RING( ctx->se_vport_zoffset );
  140. ADVANCE_RING();
  141. }
  142. static inline void radeon_emit_setup( drm_radeon_private_t *dev_priv )
  143. {
  144. drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
  145. drm_radeon_context_regs_t *ctx = &sarea_priv->context_state;
  146. RING_LOCALS;
  147. DRM_DEBUG( "    %sn", __FUNCTION__ );
  148. BEGIN_RING( 4 );
  149. OUT_RING( CP_PACKET0( RADEON_SE_CNTL, 0 ) );
  150. OUT_RING( ctx->se_cntl );
  151. OUT_RING( CP_PACKET0( RADEON_SE_CNTL_STATUS, 0 ) );
  152. OUT_RING( ctx->se_cntl_status );
  153. ADVANCE_RING();
  154. }
  155. static inline void radeon_emit_tcl( drm_radeon_private_t *dev_priv )
  156. {
  157. #ifdef TCL_ENABLE
  158. drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
  159. drm_radeon_context_regs_t *ctx = &sarea_priv->context_state;
  160. RING_LOCALS;
  161. DRM_DEBUG( "    %sn", __FUNCTION__ );
  162. BEGIN_RING( 29 );
  163. OUT_RING( CP_PACKET0( RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED, 27 ) );
  164. OUT_RING( ctx->se_tcl_material_emmissive.red );
  165. OUT_RING( ctx->se_tcl_material_emmissive.green );
  166. OUT_RING( ctx->se_tcl_material_emmissive.blue );
  167. OUT_RING( ctx->se_tcl_material_emmissive.alpha );
  168. OUT_RING( ctx->se_tcl_material_ambient.red );
  169. OUT_RING( ctx->se_tcl_material_ambient.green );
  170. OUT_RING( ctx->se_tcl_material_ambient.blue );
  171. OUT_RING( ctx->se_tcl_material_ambient.alpha );
  172. OUT_RING( ctx->se_tcl_material_diffuse.red );
  173. OUT_RING( ctx->se_tcl_material_diffuse.green );
  174. OUT_RING( ctx->se_tcl_material_diffuse.blue );
  175. OUT_RING( ctx->se_tcl_material_diffuse.alpha );
  176. OUT_RING( ctx->se_tcl_material_specular.red );
  177. OUT_RING( ctx->se_tcl_material_specular.green );
  178. OUT_RING( ctx->se_tcl_material_specular.blue );
  179. OUT_RING( ctx->se_tcl_material_specular.alpha );
  180. OUT_RING( ctx->se_tcl_shininess );
  181. OUT_RING( ctx->se_tcl_output_vtx_fmt );
  182. OUT_RING( ctx->se_tcl_output_vtx_sel );
  183. OUT_RING( ctx->se_tcl_matrix_select_0 );
  184. OUT_RING( ctx->se_tcl_matrix_select_1 );
  185. OUT_RING( ctx->se_tcl_ucp_vert_blend_ctl );
  186. OUT_RING( ctx->se_tcl_texture_proc_ctl );
  187. OUT_RING( ctx->se_tcl_light_model_ctl );
  188. for ( i = 0 ; i < 4 ; i++ ) {
  189. OUT_RING( ctx->se_tcl_per_light_ctl[i] );
  190. }
  191. ADVANCE_RING();
  192. #else
  193. DRM_ERROR( "TCL not enabled!n" );
  194. #endif
  195. }
  196. static inline void radeon_emit_misc( drm_radeon_private_t *dev_priv )
  197. {
  198. drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
  199. drm_radeon_context_regs_t *ctx = &sarea_priv->context_state;
  200. RING_LOCALS;
  201. DRM_DEBUG( "    %sn", __FUNCTION__ );
  202. BEGIN_RING( 2 );
  203. OUT_RING( CP_PACKET0( RADEON_RE_MISC, 0 ) );
  204. OUT_RING( ctx->re_misc );
  205. ADVANCE_RING();
  206. }
  207. static inline void radeon_emit_tex0( drm_radeon_private_t *dev_priv )
  208. {
  209. drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
  210. drm_radeon_texture_regs_t *tex = &sarea_priv->tex_state[0];
  211. RING_LOCALS;
  212. DRM_DEBUG( "    %s: offset=0x%xn", __FUNCTION__, tex->pp_txoffset );
  213. BEGIN_RING( 9 );
  214. OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_0, 5 ) );
  215. OUT_RING( tex->pp_txfilter );
  216. OUT_RING( tex->pp_txformat );
  217. OUT_RING( tex->pp_txoffset );
  218. OUT_RING( tex->pp_txcblend );
  219. OUT_RING( tex->pp_txablend );
  220. OUT_RING( tex->pp_tfactor );
  221. OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_0, 0 ) );
  222. OUT_RING( tex->pp_border_color );
  223. ADVANCE_RING();
  224. }
  225. static inline void radeon_emit_tex1( drm_radeon_private_t *dev_priv )
  226. {
  227. drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
  228. drm_radeon_texture_regs_t *tex = &sarea_priv->tex_state[1];
  229. RING_LOCALS;
  230. DRM_DEBUG( "    %s: offset=0x%xn", __FUNCTION__, tex->pp_txoffset );
  231. BEGIN_RING( 9 );
  232. OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_1, 5 ) );
  233. OUT_RING( tex->pp_txfilter );
  234. OUT_RING( tex->pp_txformat );
  235. OUT_RING( tex->pp_txoffset );
  236. OUT_RING( tex->pp_txcblend );
  237. OUT_RING( tex->pp_txablend );
  238. OUT_RING( tex->pp_tfactor );
  239. OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_1, 0 ) );
  240. OUT_RING( tex->pp_border_color );
  241. ADVANCE_RING();
  242. }
  243. static inline void radeon_emit_tex2( drm_radeon_private_t *dev_priv )
  244. {
  245. drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
  246. drm_radeon_texture_regs_t *tex = &sarea_priv->tex_state[2];
  247. RING_LOCALS;
  248. DRM_DEBUG( "    %sn", __FUNCTION__ );
  249. BEGIN_RING( 9 );
  250. OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_2, 5 ) );
  251. OUT_RING( tex->pp_txfilter );
  252. OUT_RING( tex->pp_txformat );
  253. OUT_RING( tex->pp_txoffset );
  254. OUT_RING( tex->pp_txcblend );
  255. OUT_RING( tex->pp_txablend );
  256. OUT_RING( tex->pp_tfactor );
  257. OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_2, 0 ) );
  258. OUT_RING( tex->pp_border_color );
  259. ADVANCE_RING();
  260. }
  261. static inline void radeon_emit_state( drm_radeon_private_t *dev_priv )
  262. {
  263. drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
  264. unsigned int dirty = sarea_priv->dirty;
  265. DRM_DEBUG( "%s: dirty=0x%08xn", __FUNCTION__, dirty );
  266. if ( dirty & RADEON_UPLOAD_CONTEXT ) {
  267. radeon_emit_context( dev_priv );
  268. sarea_priv->dirty &= ~RADEON_UPLOAD_CONTEXT;
  269. }
  270. if ( dirty & RADEON_UPLOAD_VERTFMT ) {
  271. radeon_emit_vertfmt( dev_priv );
  272. sarea_priv->dirty &= ~RADEON_UPLOAD_VERTFMT;
  273. }
  274. if ( dirty & RADEON_UPLOAD_LINE ) {
  275. radeon_emit_line( dev_priv );
  276. sarea_priv->dirty &= ~RADEON_UPLOAD_LINE;
  277. }
  278. if ( dirty & RADEON_UPLOAD_BUMPMAP ) {
  279. radeon_emit_bumpmap( dev_priv );
  280. sarea_priv->dirty &= ~RADEON_UPLOAD_BUMPMAP;
  281. }
  282. if ( dirty & RADEON_UPLOAD_MASKS ) {
  283. radeon_emit_masks( dev_priv );
  284. sarea_priv->dirty &= ~RADEON_UPLOAD_MASKS;
  285. }
  286. if ( dirty & RADEON_UPLOAD_VIEWPORT ) {
  287. radeon_emit_viewport( dev_priv );
  288. sarea_priv->dirty &= ~RADEON_UPLOAD_VIEWPORT;
  289. }
  290. if ( dirty & RADEON_UPLOAD_SETUP ) {
  291. radeon_emit_setup( dev_priv );
  292. sarea_priv->dirty &= ~RADEON_UPLOAD_SETUP;
  293. }
  294. if ( dirty & RADEON_UPLOAD_TCL ) {
  295. #ifdef TCL_ENABLE
  296. radeon_emit_tcl( dev_priv );
  297. #endif
  298. sarea_priv->dirty &= ~RADEON_UPLOAD_TCL;
  299. }
  300. if ( dirty & RADEON_UPLOAD_MISC ) {
  301. radeon_emit_misc( dev_priv );
  302. sarea_priv->dirty &= ~RADEON_UPLOAD_MISC;
  303. }
  304. if ( dirty & RADEON_UPLOAD_TEX0 ) {
  305. radeon_emit_tex0( dev_priv );
  306. sarea_priv->dirty &= ~RADEON_UPLOAD_TEX0;
  307. }
  308. if ( dirty & RADEON_UPLOAD_TEX1 ) {
  309. radeon_emit_tex1( dev_priv );
  310. sarea_priv->dirty &= ~RADEON_UPLOAD_TEX1;
  311. }
  312. if ( dirty & RADEON_UPLOAD_TEX2 ) {
  313. #if 0
  314. radeon_emit_tex2( dev_priv );
  315. #endif
  316. sarea_priv->dirty &= ~RADEON_UPLOAD_TEX2;
  317. }
  318. sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES |
  319.        RADEON_UPLOAD_TEX1IMAGES |
  320.        RADEON_UPLOAD_TEX2IMAGES |
  321.        RADEON_REQUIRE_QUIESCENCE);
  322. }
  323. #if RADEON_PERFORMANCE_BOXES
  324. /* ================================================================
  325.  * Performance monitoring functions
  326.  */
  327. static void radeon_clear_box( drm_radeon_private_t *dev_priv,
  328.       int x, int y, int w, int h,
  329.       int r, int g, int b )
  330. {
  331. u32 pitch, offset;
  332. u32 color;
  333. RING_LOCALS;
  334. switch ( dev_priv->color_fmt ) {
  335. case RADEON_COLOR_FORMAT_RGB565:
  336. color = (((r & 0xf8) << 8) |
  337.  ((g & 0xfc) << 3) |
  338.  ((b & 0xf8) >> 3));
  339. break;
  340. case RADEON_COLOR_FORMAT_ARGB8888:
  341. default:
  342. color = (((0xff) << 24) | (r << 16) | (g <<  8) | b);
  343. break;
  344. }
  345. offset = dev_priv->back_offset;
  346. pitch = dev_priv->back_pitch >> 3;
  347. BEGIN_RING( 6 );
  348. OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) );
  349. OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL |
  350.   RADEON_GMC_BRUSH_SOLID_COLOR |
  351.   (dev_priv->color_fmt << 8) |
  352.   RADEON_GMC_SRC_DATATYPE_COLOR |
  353.   RADEON_ROP3_P |
  354.   RADEON_GMC_CLR_CMP_CNTL_DIS );
  355. OUT_RING( (pitch << 22) | (offset >> 5) );
  356. OUT_RING( color );
  357. OUT_RING( (x << 16) | y );
  358. OUT_RING( (w << 16) | h );
  359. ADVANCE_RING();
  360. }
  361. static void radeon_cp_performance_boxes( drm_radeon_private_t *dev_priv )
  362. {
  363. if ( atomic_read( &dev_priv->idle_count ) == 0 ) {
  364. radeon_clear_box( dev_priv, 64, 4, 8, 8, 0, 255, 0 );
  365. } else {
  366. atomic_set( &dev_priv->idle_count, 0 );
  367. }
  368. }
  369. #endif
  370. /* ================================================================
  371.  * CP command dispatch functions
  372.  */
  373. static void radeon_print_dirty( const char *msg, unsigned int flags )
  374. {
  375. DRM_DEBUG( "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%sn",
  376.    msg,
  377.    flags,
  378.    (flags & RADEON_UPLOAD_CONTEXT)     ? "context, " : "",
  379.    (flags & RADEON_UPLOAD_VERTFMT)     ? "vertfmt, " : "",
  380.    (flags & RADEON_UPLOAD_LINE)        ? "line, " : "",
  381.    (flags & RADEON_UPLOAD_BUMPMAP)     ? "bumpmap, " : "",
  382.    (flags & RADEON_UPLOAD_MASKS)       ? "masks, " : "",
  383.    (flags & RADEON_UPLOAD_VIEWPORT)    ? "viewport, " : "",
  384.    (flags & RADEON_UPLOAD_SETUP)       ? "setup, " : "",
  385.    (flags & RADEON_UPLOAD_TCL)         ? "tcl, " : "",
  386.    (flags & RADEON_UPLOAD_MISC)        ? "misc, " : "",
  387.    (flags & RADEON_UPLOAD_TEX0)        ? "tex0, " : "",
  388.    (flags & RADEON_UPLOAD_TEX1)        ? "tex1, " : "",
  389.    (flags & RADEON_UPLOAD_TEX2)        ? "tex2, " : "",
  390.    (flags & RADEON_UPLOAD_CLIPRECTS)   ? "cliprects, " : "",
  391.    (flags & RADEON_REQUIRE_QUIESCENCE) ? "quiescence, " : "" );
  392. }
  393. static void radeon_cp_dispatch_clear( drm_device_t *dev,
  394.       drm_radeon_clear_t *clear )
  395. {
  396. drm_radeon_private_t *dev_priv = dev->dev_private;
  397. drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
  398. int nbox = sarea_priv->nbox;
  399. drm_clip_rect_t *pbox = sarea_priv->boxes;
  400. unsigned int flags = clear->flags;
  401. int i;
  402. RING_LOCALS;
  403. DRM_DEBUG( "%sn", __FUNCTION__ );
  404. radeon_update_ring_snapshot( dev_priv );
  405. if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) {
  406. unsigned int tmp = flags;
  407. flags &= ~(RADEON_FRONT | RADEON_BACK);
  408. if ( tmp & RADEON_FRONT ) flags |= RADEON_BACK;
  409. if ( tmp & RADEON_BACK )  flags |= RADEON_FRONT;
  410. }
  411. for ( i = 0 ; i < nbox ; i++ ) {
  412. int x = pbox[i].x1;
  413. int y = pbox[i].y1;
  414. int w = pbox[i].x2 - x;
  415. int h = pbox[i].y2 - y;
  416. DRM_DEBUG( "dispatch clear %d,%d-%d,%d flags 0x%xn",
  417.    x, y, w, h, flags );
  418. if ( flags & (RADEON_FRONT | RADEON_BACK) ) {
  419. BEGIN_RING( 4 );
  420. /* Ensure the 3D stream is idle before doing a
  421.  * 2D fill to clear the front or back buffer.
  422.  */
  423. RADEON_WAIT_UNTIL_3D_IDLE();
  424. OUT_RING( CP_PACKET0( RADEON_DP_WRITE_MASK, 0 ) );
  425. OUT_RING( sarea_priv->context_state.rb3d_planemask );
  426. ADVANCE_RING();
  427. /* Make sure we restore the 3D state next time.
  428.  */
  429. dev_priv->sarea_priv->dirty |= (RADEON_UPLOAD_CONTEXT |
  430. RADEON_UPLOAD_MASKS);
  431. }
  432. if ( flags & RADEON_FRONT ) {
  433. BEGIN_RING( 6 );
  434. OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) );
  435. OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL |
  436.   RADEON_GMC_BRUSH_SOLID_COLOR |
  437.   (dev_priv->color_fmt << 8) |
  438.   RADEON_GMC_SRC_DATATYPE_COLOR |
  439.   RADEON_ROP3_P |
  440.   RADEON_GMC_CLR_CMP_CNTL_DIS );
  441. OUT_RING( dev_priv->front_pitch_offset );
  442. OUT_RING( clear->clear_color );
  443. OUT_RING( (x << 16) | y );
  444. OUT_RING( (w << 16) | h );
  445. ADVANCE_RING();
  446. }
  447. if ( flags & RADEON_BACK ) {
  448. BEGIN_RING( 6 );
  449. OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) );
  450. OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL |
  451.   RADEON_GMC_BRUSH_SOLID_COLOR |
  452.   (dev_priv->color_fmt << 8) |
  453.   RADEON_GMC_SRC_DATATYPE_COLOR |
  454.   RADEON_ROP3_P |
  455.   RADEON_GMC_CLR_CMP_CNTL_DIS );
  456. OUT_RING( dev_priv->back_pitch_offset );
  457. OUT_RING( clear->clear_color );
  458. OUT_RING( (x << 16) | y );
  459. OUT_RING( (w << 16) | h );
  460. ADVANCE_RING();
  461. }
  462. if ( flags & RADEON_DEPTH ) {
  463. drm_radeon_depth_clear_t *depth_clear =
  464.    &dev_priv->depth_clear;
  465. if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) {
  466. radeon_emit_state( dev_priv );
  467. }
  468. /* FIXME: Render a rectangle to clear the depth
  469.  * buffer.  So much for those "fast Z clears"...
  470.  */
  471. BEGIN_RING( 23 );
  472. RADEON_WAIT_UNTIL_2D_IDLE();
  473. OUT_RING( CP_PACKET0( RADEON_PP_CNTL, 1 ) );
  474. OUT_RING( 0x00000000 );
  475. OUT_RING( depth_clear->rb3d_cntl );
  476. OUT_RING( CP_PACKET0( RADEON_RB3D_ZSTENCILCNTL, 0 ) );
  477. OUT_RING( depth_clear->rb3d_zstencilcntl );
  478. OUT_RING( CP_PACKET0( RADEON_RB3D_PLANEMASK, 0 ) );
  479. OUT_RING( 0x00000000 );
  480. OUT_RING( CP_PACKET0( RADEON_SE_CNTL, 0 ) );
  481. OUT_RING( depth_clear->se_cntl );
  482. OUT_RING( CP_PACKET3( RADEON_3D_DRAW_IMMD, 10 ) );
  483. OUT_RING( RADEON_VTX_Z_PRESENT );
  484. OUT_RING( (RADEON_PRIM_TYPE_RECT_LIST |
  485.    RADEON_PRIM_WALK_RING |
  486.    RADEON_MAOS_ENABLE |
  487.    RADEON_VTX_FMT_RADEON_MODE |
  488.    (3 << RADEON_NUM_VERTICES_SHIFT)) );
  489. OUT_RING( clear->rect.ui[CLEAR_X1] );
  490. OUT_RING( clear->rect.ui[CLEAR_Y1] );
  491. OUT_RING( clear->rect.ui[CLEAR_DEPTH] );
  492. OUT_RING( clear->rect.ui[CLEAR_X1] );
  493. OUT_RING( clear->rect.ui[CLEAR_Y2] );
  494. OUT_RING( clear->rect.ui[CLEAR_DEPTH] );
  495. OUT_RING( clear->rect.ui[CLEAR_X2] );
  496. OUT_RING( clear->rect.ui[CLEAR_Y2] );
  497. OUT_RING( clear->rect.ui[CLEAR_DEPTH] );
  498. ADVANCE_RING();
  499. /* Make sure we restore the 3D state next time.
  500.  */
  501. dev_priv->sarea_priv->dirty |= (RADEON_UPLOAD_CONTEXT |
  502. RADEON_UPLOAD_SETUP |
  503. RADEON_UPLOAD_MASKS);
  504. }
  505. }
  506. /* Increment the clear counter.  The client-side 3D driver must
  507.  * wait on this value before performing the clear ioctl.  We
  508.  * need this because the card's so damned fast...
  509.  */
  510. dev_priv->sarea_priv->last_clear++;
  511. BEGIN_RING( 4 );
  512. RADEON_CLEAR_AGE( dev_priv->sarea_priv->last_clear );
  513. RADEON_WAIT_UNTIL_IDLE();
  514. ADVANCE_RING();
  515. }
  516. static void radeon_cp_dispatch_swap( drm_device_t *dev )
  517. {
  518. drm_radeon_private_t *dev_priv = dev->dev_private;
  519. drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
  520. int nbox = sarea_priv->nbox;
  521. drm_clip_rect_t *pbox = sarea_priv->boxes;
  522. int i;
  523. RING_LOCALS;
  524. DRM_DEBUG( "%sn", __FUNCTION__ );
  525. radeon_update_ring_snapshot( dev_priv );
  526. #if RADEON_PERFORMANCE_BOXES
  527. /* Do some trivial performance monitoring...
  528.  */
  529. radeon_cp_performance_boxes( dev_priv );
  530. #endif
  531. /* Wait for the 3D stream to idle before dispatching the bitblt.
  532.  * This will prevent data corruption between the two streams.
  533.  */
  534. BEGIN_RING( 2 );
  535. RADEON_WAIT_UNTIL_3D_IDLE();
  536. ADVANCE_RING();
  537. for ( i = 0 ; i < nbox ; i++ ) {
  538. int x = pbox[i].x1;
  539. int y = pbox[i].y1;
  540. int w = pbox[i].x2 - x;
  541. int h = pbox[i].y2 - y;
  542. DRM_DEBUG( "dispatch swap %d,%d-%d,%dn",
  543.    x, y, w, h );
  544. BEGIN_RING( 7 );
  545. OUT_RING( CP_PACKET3( RADEON_CNTL_BITBLT_MULTI, 5 ) );
  546. OUT_RING( RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
  547.   RADEON_GMC_DST_PITCH_OFFSET_CNTL |
  548.   RADEON_GMC_BRUSH_NONE |
  549.   (dev_priv->color_fmt << 8) |
  550.   RADEON_GMC_SRC_DATATYPE_COLOR |
  551.   RADEON_ROP3_S |
  552.   RADEON_DP_SRC_SOURCE_MEMORY |
  553.   RADEON_GMC_CLR_CMP_CNTL_DIS |
  554.   RADEON_GMC_WR_MSK_DIS );
  555. OUT_RING( dev_priv->back_pitch_offset );
  556. OUT_RING( dev_priv->front_pitch_offset );
  557. OUT_RING( (x << 16) | y );
  558. OUT_RING( (x << 16) | y );
  559. OUT_RING( (w << 16) | h );
  560. ADVANCE_RING();
  561. }
  562. /* Increment the frame counter.  The client-side 3D driver must
  563.  * throttle the framerate by waiting for this value before
  564.  * performing the swapbuffer ioctl.
  565.  */
  566. dev_priv->sarea_priv->last_frame++;
  567. BEGIN_RING( 4 );
  568. RADEON_FRAME_AGE( dev_priv->sarea_priv->last_frame );
  569. RADEON_WAIT_UNTIL_2D_IDLE();
  570. ADVANCE_RING();
  571. }
  572. static void radeon_cp_dispatch_flip( drm_device_t *dev )
  573. {
  574. drm_radeon_private_t *dev_priv = dev->dev_private;
  575. RING_LOCALS;
  576. DRM_DEBUG( "%s: page=%dn", __FUNCTION__, dev_priv->current_page );
  577. radeon_update_ring_snapshot( dev_priv );
  578. #if RADEON_PERFORMANCE_BOXES
  579. /* Do some trivial performance monitoring...
  580.  */
  581. radeon_cp_performance_boxes( dev_priv );
  582. #endif
  583. BEGIN_RING( 6 );
  584. RADEON_WAIT_UNTIL_3D_IDLE();
  585. RADEON_WAIT_UNTIL_PAGE_FLIPPED();
  586. OUT_RING( CP_PACKET0( RADEON_CRTC_OFFSET, 0 ) );
  587. if ( dev_priv->current_page == 0 ) {
  588. OUT_RING( dev_priv->back_offset );
  589. dev_priv->current_page = 1;
  590. } else {
  591. OUT_RING( dev_priv->front_offset );
  592. dev_priv->current_page = 0;
  593. }
  594. ADVANCE_RING();
  595. /* Increment the frame counter.  The client-side 3D driver must
  596.  * throttle the framerate by waiting for this value before
  597.  * performing the swapbuffer ioctl.
  598.  */
  599. dev_priv->sarea_priv->last_frame++;
  600. BEGIN_RING( 2 );
  601. RADEON_FRAME_AGE( dev_priv->sarea_priv->last_frame );
  602. ADVANCE_RING();
  603. }
  604. static void radeon_cp_dispatch_vertex( drm_device_t *dev,
  605.        drm_buf_t *buf )
  606. {
  607. drm_radeon_private_t *dev_priv = dev->dev_private;
  608. drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
  609. drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
  610. int format = sarea_priv->vc_format;
  611. int offset = dev_priv->agp_buffers_offset + buf->offset;
  612. int size = buf->used;
  613. int prim = buf_priv->prim;
  614. int i = 0;
  615. RING_LOCALS;
  616. DRM_DEBUG( "%s: nbox=%dn", __FUNCTION__, sarea_priv->nbox );
  617. radeon_update_ring_snapshot( dev_priv );
  618. if ( 0 )
  619. radeon_print_dirty( "dispatch_vertex", sarea_priv->dirty );
  620. if ( buf->used ) {
  621. buf_priv->dispatched = 1;
  622. if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) {
  623. radeon_emit_state( dev_priv );
  624. }
  625. do {
  626. /* Emit the next set of up to three cliprects */
  627. if ( i < sarea_priv->nbox ) {
  628. radeon_emit_clip_rect( dev_priv,
  629.        &sarea_priv->boxes[i] );
  630. }
  631. /* Emit the vertex buffer rendering commands */
  632. BEGIN_RING( 5 );
  633. OUT_RING( CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, 3 ) );
  634. OUT_RING( offset );
  635. OUT_RING( size );
  636. OUT_RING( format );
  637. OUT_RING( prim | RADEON_PRIM_WALK_LIST |
  638.   RADEON_COLOR_ORDER_RGBA |
  639.   RADEON_VTX_FMT_RADEON_MODE |
  640.   (size << RADEON_NUM_VERTICES_SHIFT) );
  641. ADVANCE_RING();
  642. i++;
  643. } while ( i < sarea_priv->nbox );
  644. }
  645. if ( buf_priv->discard ) {
  646. buf_priv->age = dev_priv->sarea_priv->last_dispatch;
  647. /* Emit the vertex buffer age */
  648. BEGIN_RING( 2 );
  649. RADEON_DISPATCH_AGE( buf_priv->age );
  650. ADVANCE_RING();
  651. buf->pending = 1;
  652. buf->used = 0;
  653. /* FIXME: Check dispatched field */
  654. buf_priv->dispatched = 0;
  655. }
  656. dev_priv->sarea_priv->last_dispatch++;
  657. sarea_priv->dirty &= ~RADEON_UPLOAD_CLIPRECTS;
  658. sarea_priv->nbox = 0;
  659. }
  660. static void radeon_cp_dispatch_indirect( drm_device_t *dev,
  661.  drm_buf_t *buf,
  662.  int start, int end )
  663. {
  664. drm_radeon_private_t *dev_priv = dev->dev_private;
  665. drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
  666. RING_LOCALS;
  667. DRM_DEBUG( "indirect: buf=%d s=0x%x e=0x%xn",
  668.    buf->idx, start, end );
  669. radeon_update_ring_snapshot( dev_priv );
  670. if ( start != end ) {
  671. int offset = (dev_priv->agp_buffers_offset
  672.       + buf->offset + start);
  673. int dwords = (end - start + 3) / sizeof(u32);
  674. /* Indirect buffer data must be an even number of
  675.  * dwords, so if we've been given an odd number we must
  676.  * pad the data with a Type-2 CP packet.
  677.  */
  678. if ( dwords & 1 ) {
  679. u32 *data = (u32 *)
  680. ((char *)dev_priv->buffers->handle
  681.  + buf->offset + start);
  682. data[dwords++] = RADEON_CP_PACKET2;
  683. }
  684. buf_priv->dispatched = 1;
  685. /* Fire off the indirect buffer */
  686. BEGIN_RING( 3 );
  687. OUT_RING( CP_PACKET0( RADEON_CP_IB_BASE, 1 ) );
  688. OUT_RING( offset );
  689. OUT_RING( dwords );
  690. ADVANCE_RING();
  691. }
  692. if ( buf_priv->discard ) {
  693. buf_priv->age = dev_priv->sarea_priv->last_dispatch;
  694. /* Emit the indirect buffer age */
  695. BEGIN_RING( 2 );
  696. RADEON_DISPATCH_AGE( buf_priv->age );
  697. ADVANCE_RING();
  698. buf->pending = 1;
  699. buf->used = 0;
  700. /* FIXME: Check dispatched field */
  701. buf_priv->dispatched = 0;
  702. }
  703. dev_priv->sarea_priv->last_dispatch++;
  704. }
  705. static void radeon_cp_dispatch_indices( drm_device_t *dev,
  706. drm_buf_t *buf,
  707. int start, int end,
  708. int count )
  709. {
  710. drm_radeon_private_t *dev_priv = dev->dev_private;
  711. drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
  712. drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
  713. int format = sarea_priv->vc_format;
  714. int offset = dev_priv->agp_buffers_offset;
  715. int prim = buf_priv->prim;
  716. u32 *data;
  717. int dwords;
  718. int i = 0;
  719. RING_LOCALS;
  720. DRM_DEBUG( "indices: s=%d e=%d c=%dn", start, end, count );
  721. radeon_update_ring_snapshot( dev_priv );
  722. if ( 0 )
  723. radeon_print_dirty( "dispatch_indices", sarea_priv->dirty );
  724. if ( start != end ) {
  725. buf_priv->dispatched = 1;
  726. if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) {
  727. radeon_emit_state( dev_priv );
  728. }
  729. dwords = (end - start + 3) / sizeof(u32);
  730. data = (u32 *)((char *)dev_priv->buffers->handle
  731.        + buf->offset + start);
  732. data[0] = CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, dwords-2 );
  733. data[1] = offset;
  734. data[2] = RADEON_MAX_VB_VERTS;
  735. data[3] = format;
  736. data[4] = (prim | RADEON_PRIM_WALK_IND |
  737.    RADEON_COLOR_ORDER_RGBA |
  738.    RADEON_VTX_FMT_RADEON_MODE |
  739.    (count << RADEON_NUM_VERTICES_SHIFT) );
  740. if ( count & 0x1 ) {
  741. data[dwords-1] &= 0x0000ffff;
  742. }
  743. do {
  744. /* Emit the next set of up to three cliprects */
  745. if ( i < sarea_priv->nbox ) {
  746. radeon_emit_clip_rect( dev_priv,
  747.        &sarea_priv->boxes[i] );
  748. }
  749. radeon_cp_dispatch_indirect( dev, buf, start, end );
  750. i++;
  751. } while ( i < sarea_priv->nbox );
  752. }
  753. if ( buf_priv->discard ) {
  754. buf_priv->age = dev_priv->sarea_priv->last_dispatch;
  755. /* Emit the vertex buffer age */
  756. BEGIN_RING( 2 );
  757. RADEON_DISPATCH_AGE( buf_priv->age );
  758. ADVANCE_RING();
  759. buf->pending = 1;
  760. /* FIXME: Check dispatched field */
  761. buf_priv->dispatched = 0;
  762. }
  763. dev_priv->sarea_priv->last_dispatch++;
  764. sarea_priv->dirty &= ~RADEON_UPLOAD_CLIPRECTS;
  765. sarea_priv->nbox = 0;
  766. }
  767. static int radeon_cp_dispatch_blit( drm_device_t *dev,
  768.     drm_radeon_blit_t *blit )
  769. {
  770. drm_radeon_private_t *dev_priv = dev->dev_private;
  771. drm_device_dma_t *dma = dev->dma;
  772. drm_buf_t *buf;
  773. drm_radeon_buf_priv_t *buf_priv;
  774. u32 format;
  775. u32 *data;
  776. int dword_shift, dwords;
  777. RING_LOCALS;
  778. DRM_DEBUG( "blit: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hdn",
  779.    blit->offset >> 10, blit->pitch, blit->format,
  780.    blit->x, blit->y, blit->width, blit->height );
  781. radeon_update_ring_snapshot( dev_priv );
  782. /* The compiler won't optimize away a division by a variable,
  783.  * even if the only legal values are powers of two.  Thus, we'll
  784.  * use a shift instead.
  785.  */
  786. switch ( blit->format ) {
  787. case RADEON_TXF_32BPP_ARGB8888:
  788. case RADEON_TXF_32BPP_RGBA8888:
  789. format = RADEON_COLOR_FORMAT_ARGB8888;
  790. dword_shift = 0;
  791. break;
  792. case RADEON_TXF_16BPP_AI88:
  793. case RADEON_TXF_16BPP_ARGB1555:
  794. case RADEON_TXF_16BPP_RGB565:
  795. case RADEON_TXF_16BPP_ARGB4444:
  796. format = RADEON_COLOR_FORMAT_RGB565;
  797. dword_shift = 1;
  798. break;
  799. case RADEON_TXF_8BPP_I:
  800. case RADEON_TXF_8BPP_RGB332:
  801. format = RADEON_COLOR_FORMAT_CI8;
  802. dword_shift = 2;
  803. break;
  804. default:
  805. DRM_ERROR( "invalid blit format %dn", blit->format );
  806. return -EINVAL;
  807. }
  808. /* Flush the pixel cache.  This ensures no pixel data gets mixed
  809.  * up with the texture data from the host data blit, otherwise
  810.  * part of the texture image may be corrupted.
  811.  */
  812. BEGIN_RING( 4 );
  813. RADEON_FLUSH_CACHE();
  814. RADEON_WAIT_UNTIL_IDLE();
  815. ADVANCE_RING();
  816. /* Dispatch the indirect buffer.
  817.  */
  818. buf = dma->buflist[blit->idx];
  819. buf_priv = buf->dev_private;
  820. if ( buf->pid != current->pid ) {
  821. DRM_ERROR( "process %d using buffer owned by %dn",
  822.    current->pid, buf->pid );
  823. return -EINVAL;
  824. }
  825. if ( buf->pending ) {
  826. DRM_ERROR( "sending pending buffer %dn", blit->idx );
  827. return -EINVAL;
  828. }
  829. buf_priv->discard = 1;
  830. dwords = (blit->width * blit->height) >> dword_shift;
  831. if ( !dwords ) dwords = 1;
  832. data = (u32 *)((char *)dev_priv->buffers->handle + buf->offset);
  833. data[0] = CP_PACKET3( RADEON_CNTL_HOSTDATA_BLT, dwords + 6 );
  834. data[1] = (RADEON_GMC_DST_PITCH_OFFSET_CNTL |
  835.    RADEON_GMC_BRUSH_NONE |
  836.    (format << 8) |
  837.    RADEON_GMC_SRC_DATATYPE_COLOR |
  838.    RADEON_ROP3_S |
  839.    RADEON_DP_SRC_SOURCE_HOST_DATA |
  840.    RADEON_GMC_CLR_CMP_CNTL_DIS |
  841.    RADEON_GMC_WR_MSK_DIS);
  842. data[2] = (blit->pitch << 22) | (blit->offset >> 10);
  843. data[3] = 0xffffffff;
  844. data[4] = 0xffffffff;
  845. data[5] = (blit->y << 16) | blit->x;
  846. data[6] = (blit->height << 16) | blit->width;
  847. data[7] = dwords;
  848. buf->used = (dwords + 8) * sizeof(u32);
  849. radeon_cp_dispatch_indirect( dev, buf, 0, buf->used );
  850. /* Flush the pixel cache after the blit completes.  This ensures
  851.  * the texture data is written out to memory before rendering
  852.  * continues.
  853.  */
  854. BEGIN_RING( 4 );
  855. RADEON_FLUSH_CACHE();
  856. RADEON_WAIT_UNTIL_2D_IDLE();
  857. ADVANCE_RING();
  858. return 0;
  859. }
  860. static void radeon_cp_dispatch_stipple( drm_device_t *dev, u32 *stipple )
  861. {
  862. drm_radeon_private_t *dev_priv = dev->dev_private;
  863. int i;
  864. RING_LOCALS;
  865. DRM_DEBUG( "%sn", __FUNCTION__ );
  866. radeon_update_ring_snapshot( dev_priv );
  867. BEGIN_RING( 35 );
  868. OUT_RING( CP_PACKET0( RADEON_RE_STIPPLE_ADDR, 0 ) );
  869. OUT_RING( 0x00000000 );
  870. OUT_RING( CP_PACKET0_TABLE( RADEON_RE_STIPPLE_DATA, 31 ) );
  871. for ( i = 0 ; i < 32 ; i++ ) {
  872. OUT_RING( stipple[i] );
  873. }
  874. ADVANCE_RING();
  875. }
  876. /* ================================================================
  877.  * IOCTL functions
  878.  */
  879. int radeon_cp_clear( struct inode *inode, struct file *filp,
  880.      unsigned int cmd, unsigned long arg )
  881. {
  882. drm_file_t *priv = filp->private_data;
  883. drm_device_t *dev = priv->dev;
  884. drm_radeon_private_t *dev_priv = dev->dev_private;
  885. drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
  886. drm_radeon_clear_t clear;
  887. DRM_DEBUG( "%sn", __FUNCTION__ );
  888. if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
  889.      dev->lock.pid != current->pid ) {
  890. DRM_ERROR( "%s called without lock heldn", __FUNCTION__ );
  891. return -EINVAL;
  892. }
  893. if ( copy_from_user( &clear, (drm_radeon_clear_t *) arg,
  894.      sizeof(clear) ) )
  895. return -EFAULT;
  896. if ( sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS )
  897. sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS;
  898. radeon_cp_dispatch_clear( dev, &clear );
  899. return 0;
  900. }
  901. int radeon_cp_swap( struct inode *inode, struct file *filp,
  902.     unsigned int cmd, unsigned long arg )
  903. {
  904. drm_file_t *priv = filp->private_data;
  905. drm_device_t *dev = priv->dev;
  906. drm_radeon_private_t *dev_priv = dev->dev_private;
  907. drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
  908. DRM_DEBUG( "%sn", __FUNCTION__ );
  909. if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
  910.      dev->lock.pid != current->pid ) {
  911. DRM_ERROR( "%s called without lock heldn", __FUNCTION__ );
  912. return -EINVAL;
  913. }
  914. if ( sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS )
  915. sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS;
  916. if ( !dev_priv->page_flipping ) {
  917. radeon_cp_dispatch_swap( dev );
  918. dev_priv->sarea_priv->dirty |= (RADEON_UPLOAD_CONTEXT |
  919. RADEON_UPLOAD_MASKS);
  920. } else {
  921. radeon_cp_dispatch_flip( dev );
  922. }
  923. return 0;
  924. }
  925. int radeon_cp_vertex( struct inode *inode, struct file *filp,
  926.       unsigned int cmd, unsigned long arg )
  927. {
  928. drm_file_t *priv = filp->private_data;
  929. drm_device_t *dev = priv->dev;
  930. drm_radeon_private_t *dev_priv = dev->dev_private;
  931. drm_device_dma_t *dma = dev->dma;
  932. drm_buf_t *buf;
  933. drm_radeon_buf_priv_t *buf_priv;
  934. drm_radeon_vertex_t vertex;
  935. if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
  936.      dev->lock.pid != current->pid ) {
  937. DRM_ERROR( "%s called without lock heldn", __FUNCTION__ );
  938. return -EINVAL;
  939. }
  940. if ( !dev_priv || dev_priv->is_pci ) {
  941. DRM_ERROR( "%s called with a PCI cardn", __FUNCTION__ );
  942. return -EINVAL;
  943. }
  944. if ( copy_from_user( &vertex, (drm_radeon_vertex_t *)arg,
  945.      sizeof(vertex) ) )
  946. return -EFAULT;
  947. DRM_DEBUG( "%s: pid=%d index=%d count=%d discard=%dn",
  948.    __FUNCTION__, current->pid,
  949.    vertex.idx, vertex.count, vertex.discard );
  950. if ( vertex.idx < 0 || vertex.idx >= dma->buf_count ) {
  951. DRM_ERROR( "buffer index %d (of %d max)n",
  952.    vertex.idx, dma->buf_count - 1 );
  953. return -EINVAL;
  954. }
  955. if ( vertex.prim < 0 ||
  956.      vertex.prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST ) {
  957. DRM_ERROR( "buffer prim %dn", vertex.prim );
  958. return -EINVAL;
  959. }
  960. VB_AGE_CHECK_WITH_RET( dev_priv );
  961. buf = dma->buflist[vertex.idx];
  962. buf_priv = buf->dev_private;
  963. if ( buf->pid != current->pid ) {
  964. DRM_ERROR( "process %d using buffer owned by %dn",
  965.    current->pid, buf->pid );
  966. return -EINVAL;
  967. }
  968. if ( buf->pending ) {
  969. DRM_ERROR( "sending pending buffer %dn", vertex.idx );
  970. return -EINVAL;
  971. }
  972. buf->used = vertex.count;
  973. buf_priv->prim = vertex.prim;
  974. buf_priv->discard = vertex.discard;
  975. radeon_cp_dispatch_vertex( dev, buf );
  976. return 0;
  977. }
  978. int radeon_cp_indices( struct inode *inode, struct file *filp,
  979.        unsigned int cmd, unsigned long arg )
  980. {
  981. drm_file_t *priv = filp->private_data;
  982. drm_device_t *dev = priv->dev;
  983. drm_radeon_private_t *dev_priv = dev->dev_private;
  984. drm_device_dma_t *dma = dev->dma;
  985. drm_buf_t *buf;
  986. drm_radeon_buf_priv_t *buf_priv;
  987. drm_radeon_indices_t elts;
  988. int count;
  989. if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
  990.      dev->lock.pid != current->pid ) {
  991. DRM_ERROR( "%s called without lock heldn", __FUNCTION__ );
  992. return -EINVAL;
  993. }
  994. if ( !dev_priv || dev_priv->is_pci ) {
  995. DRM_ERROR( "%s called with a PCI cardn", __FUNCTION__ );
  996. return -EINVAL;
  997. }
  998. if ( copy_from_user( &elts, (drm_radeon_indices_t *)arg,
  999.      sizeof(elts) ) )
  1000. return -EFAULT;
  1001. DRM_DEBUG( "%s: pid=%d index=%d start=%d end=%d discard=%dn",
  1002.    __FUNCTION__, current->pid,
  1003.    elts.idx, elts.start, elts.end, elts.discard );
  1004. if ( elts.idx < 0 || elts.idx >= dma->buf_count ) {
  1005. DRM_ERROR( "buffer index %d (of %d max)n",
  1006.    elts.idx, dma->buf_count - 1 );
  1007. return -EINVAL;
  1008. }
  1009. if ( elts.prim < 0 ||
  1010.      elts.prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST ) {
  1011. DRM_ERROR( "buffer prim %dn", elts.prim );
  1012. return -EINVAL;
  1013. }
  1014. VB_AGE_CHECK_WITH_RET( dev_priv );
  1015. buf = dma->buflist[elts.idx];
  1016. buf_priv = buf->dev_private;
  1017. if ( buf->pid != current->pid ) {
  1018. DRM_ERROR( "process %d using buffer owned by %dn",
  1019.    current->pid, buf->pid );
  1020. return -EINVAL;
  1021. }
  1022. if ( buf->pending ) {
  1023. DRM_ERROR( "sending pending buffer %dn", elts.idx );
  1024. return -EINVAL;
  1025. }
  1026. count = (elts.end - elts.start) / sizeof(u16);
  1027. elts.start -= RADEON_INDEX_PRIM_OFFSET;
  1028. if ( elts.start & 0x7 ) {
  1029. DRM_ERROR( "misaligned buffer 0x%xn", elts.start );
  1030. return -EINVAL;
  1031. }
  1032. if ( elts.start < buf->used ) {
  1033. DRM_ERROR( "no header 0x%x - 0x%xn", elts.start, buf->used );
  1034. return -EINVAL;
  1035. }
  1036. buf->used = elts.end;
  1037. buf_priv->prim = elts.prim;
  1038. buf_priv->discard = elts.discard;
  1039. radeon_cp_dispatch_indices( dev, buf, elts.start, elts.end, count );
  1040. return 0;
  1041. }
  1042. int radeon_cp_blit( struct inode *inode, struct file *filp,
  1043.     unsigned int cmd, unsigned long arg )
  1044. {
  1045. drm_file_t *priv = filp->private_data;
  1046. drm_device_t *dev = priv->dev;
  1047. drm_radeon_private_t *dev_priv = dev->dev_private;
  1048. drm_device_dma_t *dma = dev->dma;
  1049. drm_radeon_blit_t blit;
  1050. if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
  1051.      dev->lock.pid != current->pid ) {
  1052. DRM_ERROR( "%s called without lock heldn", __FUNCTION__ );
  1053. return -EINVAL;
  1054. }
  1055. if ( copy_from_user( &blit, (drm_radeon_blit_t *)arg,
  1056.      sizeof(blit) ) )
  1057. return -EFAULT;
  1058. DRM_DEBUG( "%s: pid=%d index=%dn",
  1059.    __FUNCTION__, current->pid, blit.idx );
  1060. if ( blit.idx < 0 || blit.idx > dma->buf_count ) {
  1061. DRM_ERROR( "sending %d buffers (of %d max)n",
  1062.    blit.idx, dma->buf_count );
  1063. return -EINVAL;
  1064. }
  1065. VB_AGE_CHECK_WITH_RET( dev_priv );
  1066. return radeon_cp_dispatch_blit( dev, &blit );
  1067. }
  1068. int radeon_cp_stipple( struct inode *inode, struct file *filp,
  1069.        unsigned int cmd, unsigned long arg )
  1070. {
  1071. drm_file_t *priv = filp->private_data;
  1072. drm_device_t *dev = priv->dev;
  1073. drm_radeon_stipple_t stipple;
  1074. u32 mask[32];
  1075. if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
  1076.      dev->lock.pid != current->pid ) {
  1077. DRM_ERROR( "%s called without lock heldn", __FUNCTION__ );
  1078. return -EINVAL;
  1079. }
  1080. if ( copy_from_user( &stipple, (drm_radeon_stipple_t *)arg,
  1081.      sizeof(stipple) ) )
  1082. return -EFAULT;
  1083. if ( copy_from_user( &mask, stipple.mask,
  1084.      32 * sizeof(u32) ) )
  1085. return -EFAULT;
  1086. radeon_cp_dispatch_stipple( dev, mask );
  1087. return 0;
  1088. }
  1089. int radeon_cp_indirect( struct inode *inode, struct file *filp,
  1090. unsigned int cmd, unsigned long arg )
  1091. {
  1092. drm_file_t *priv = filp->private_data;
  1093. drm_device_t *dev = priv->dev;
  1094. drm_radeon_private_t *dev_priv = dev->dev_private;
  1095. drm_device_dma_t *dma = dev->dma;
  1096. drm_buf_t *buf;
  1097. drm_radeon_buf_priv_t *buf_priv;
  1098. drm_radeon_indirect_t indirect;
  1099. RING_LOCALS;
  1100. if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
  1101.      dev->lock.pid != current->pid ) {
  1102. DRM_ERROR( "%s called without lock heldn", __FUNCTION__ );
  1103. return -EINVAL;
  1104. }
  1105. if ( !dev_priv || dev_priv->is_pci ) {
  1106. DRM_ERROR( "%s called with a PCI cardn", __FUNCTION__ );
  1107. return -EINVAL;
  1108. }
  1109. if ( copy_from_user( &indirect, (drm_radeon_indirect_t *)arg,
  1110.      sizeof(indirect) ) )
  1111. return -EFAULT;
  1112. DRM_DEBUG( "indirect: idx=%d s=%d e=%d d=%dn",
  1113.    indirect.idx, indirect.start,
  1114.    indirect.end, indirect.discard );
  1115. if ( indirect.idx < 0 || indirect.idx >= dma->buf_count ) {
  1116. DRM_ERROR( "buffer index %d (of %d max)n",
  1117.    indirect.idx, dma->buf_count - 1 );
  1118. return -EINVAL;
  1119. }
  1120. buf = dma->buflist[indirect.idx];
  1121. buf_priv = buf->dev_private;
  1122. if ( buf->pid != current->pid ) {
  1123. DRM_ERROR( "process %d using buffer owned by %dn",
  1124.    current->pid, buf->pid );
  1125. return -EINVAL;
  1126. }
  1127. if ( buf->pending ) {
  1128. DRM_ERROR( "sending pending buffer %dn", indirect.idx );
  1129. return -EINVAL;
  1130. }
  1131. if ( indirect.start < buf->used ) {
  1132. DRM_ERROR( "reusing indirect: start=0x%x actual=0x%xn",
  1133.    indirect.start, buf->used );
  1134. return -EINVAL;
  1135. }
  1136. VB_AGE_CHECK_WITH_RET( dev_priv );
  1137. buf->used = indirect.end;
  1138. buf_priv->discard = indirect.discard;
  1139. /* Wait for the 3D stream to idle before the indirect buffer
  1140.  * containing 2D acceleration commands is processed.
  1141.  */
  1142. BEGIN_RING( 2 );
  1143. RADEON_WAIT_UNTIL_3D_IDLE();
  1144. ADVANCE_RING();
  1145. /* Dispatch the indirect buffer full of commands from the
  1146.  * X server.  This is insecure and is thus only available to
  1147.  * privileged clients.
  1148.  */
  1149. radeon_cp_dispatch_indirect( dev, buf, indirect.start, indirect.end );
  1150. return 0;
  1151. }