mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2025-12-30 17:50:17 +01:00
OS support for radeon pageflipping.
This commit is contained in:
parent
9c2285a4d1
commit
4b7d1a99ce
9 changed files with 97 additions and 79 deletions
|
|
@ -51,6 +51,8 @@
|
|||
* - Increase MAX_TEXTURE_LEVELS (brian)
|
||||
* 1.3 - Add cmdbuf ioctl (keith)
|
||||
* - Add support for new radeon packets (keith)
|
||||
* - Add getparam ioctl (keith)
|
||||
* - Add flip-buffers ioctl, deprecate fullscreen foo (keith).
|
||||
*/
|
||||
#define DRIVER_IOCTLS \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { radeon_cp_buffers, 1, 0 }, \
|
||||
|
|
@ -70,7 +72,8 @@
|
|||
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDIRECT)] = { radeon_cp_indirect, 1, 1 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX2)] = { radeon_cp_vertex2, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CMDBUF)] = { radeon_cp_cmdbuf, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_GETPARAM)] = { radeon_cp_getparam, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_GETPARAM)] = { radeon_cp_getparam, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_FLIP)] = { radeon_cp_flip, 1, 0 },
|
||||
|
||||
|
||||
#include "drm_agpsupport.h"
|
||||
|
|
|
|||
|
|
@ -492,6 +492,7 @@ typedef struct drm_scatter_gather {
|
|||
#define DRM_IOCTL_RADEON_VERTEX2 DRM_IOW( 0x4f, drm_radeon_vertex_t)
|
||||
#define DRM_IOCTL_RADEON_CMDBUF DRM_IOW( 0x50, drm_radeon_cmd_buffer_t)
|
||||
#define DRM_IOCTL_RADEON_GETPARAM DRM_IOWR(0x51, drm_radeon_getparam_t)
|
||||
#define DRM_IOCTL_RADEON_FLIP DRM_IO( 0x52)
|
||||
|
||||
/* Gamma specific ioctls */
|
||||
#define DRM_IOCTL_GAMMA_INIT DRM_IOW( 0x40, drm_gamma_init_t)
|
||||
|
|
|
|||
|
|
@ -1144,60 +1144,12 @@ int radeon_engine_reset( struct inode *inode, struct file *filp,
|
|||
* Fullscreen mode
|
||||
*/
|
||||
|
||||
static int radeon_do_init_pageflip( drm_device_t *dev )
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
dev_priv->crtc_offset = RADEON_READ( RADEON_CRTC_OFFSET );
|
||||
dev_priv->crtc_offset_cntl = RADEON_READ( RADEON_CRTC_OFFSET_CNTL );
|
||||
|
||||
RADEON_WRITE( RADEON_CRTC_OFFSET, dev_priv->front_offset );
|
||||
RADEON_WRITE( RADEON_CRTC_OFFSET_CNTL,
|
||||
dev_priv->crtc_offset_cntl |
|
||||
RADEON_CRTC_OFFSET_FLIP_CNTL );
|
||||
|
||||
dev_priv->page_flipping = 1;
|
||||
dev_priv->current_page = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int radeon_do_cleanup_pageflip( drm_device_t *dev )
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
RADEON_WRITE( RADEON_CRTC_OFFSET, dev_priv->crtc_offset );
|
||||
RADEON_WRITE( RADEON_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl );
|
||||
|
||||
dev_priv->page_flipping = 0;
|
||||
dev_priv->current_page = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* KW: Deprecated to say the least:
|
||||
*/
|
||||
int radeon_fullscreen( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg )
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_radeon_fullscreen_t fs;
|
||||
|
||||
LOCK_TEST_WITH_RETURN( dev );
|
||||
|
||||
if ( copy_from_user( &fs, (drm_radeon_fullscreen_t *)arg,
|
||||
sizeof(fs) ) )
|
||||
return -EFAULT;
|
||||
|
||||
switch ( fs.func ) {
|
||||
case RADEON_INIT_FULLSCREEN:
|
||||
return radeon_do_init_pageflip( dev );
|
||||
case RADEON_CLEANUP_FULLSCREEN:
|
||||
return radeon_do_cleanup_pageflip( dev );
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -291,6 +291,8 @@ typedef struct {
|
|||
drm_radeon_tex_region_t tex_list[RADEON_NR_TEX_HEAPS][RADEON_NR_TEX_REGIONS+1];
|
||||
int tex_age[RADEON_NR_TEX_HEAPS];
|
||||
int ctx_owner;
|
||||
int pfState; /* number of 3d windows (0,1,2ormore) */
|
||||
int pfCurrentPage; /* which buffer is being displayed? */
|
||||
} drm_radeon_sarea_t;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@
|
|||
* - Increase MAX_TEXTURE_LEVELS (brian)
|
||||
* 1.3 - Add cmdbuf ioctl (keith)
|
||||
* - Add support for new radeon packets (keith)
|
||||
* - Add getparam ioctl (keith)
|
||||
* - Add flip-buffers ioctl, deprecate fullscreen foo (keith).
|
||||
*/
|
||||
#define DRIVER_IOCTLS \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { radeon_cp_buffers, 1, 0 }, \
|
||||
|
|
@ -70,7 +72,8 @@
|
|||
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDIRECT)] = { radeon_cp_indirect, 1, 1 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX2)] = { radeon_cp_vertex2, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CMDBUF)] = { radeon_cp_cmdbuf, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_GETPARAM)] = { radeon_cp_getparam, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_GETPARAM)] = { radeon_cp_getparam, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_FLIP)] = { radeon_cp_flip, 1, 0 },
|
||||
|
||||
|
||||
#include "drm_agpsupport.h"
|
||||
|
|
|
|||
|
|
@ -171,6 +171,8 @@ extern int radeon_cp_cmdbuf( struct inode *inode, struct file *filp,
|
|||
unsigned int cmd, unsigned long arg );
|
||||
extern int radeon_cp_getparam( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg );
|
||||
extern int radeon_cp_flip( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg );
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,8 @@ static inline void radeon_emit_clip_rect( drm_radeon_private_t *dev_priv,
|
|||
OUT_RING( CP_PACKET0( RADEON_RE_TOP_LEFT, 0 ) );
|
||||
OUT_RING( (box->y1 << 16) | box->x1 );
|
||||
OUT_RING( CP_PACKET0( RADEON_RE_WIDTH_HEIGHT, 0 ) );
|
||||
OUT_RING( ((box->y2 - 1) << 16) | (box->x2 - 1) );
|
||||
/* OUT_RING( ((box->y2 - 1) << 16) | (box->x2 - 1) );*/
|
||||
OUT_RING( (box->y2 << 16) | box->x2 );
|
||||
ADVANCE_RING();
|
||||
}
|
||||
|
||||
|
|
@ -543,9 +544,17 @@ static void radeon_cp_dispatch_swap( drm_device_t *dev )
|
|||
RADEON_DP_SRC_SOURCE_MEMORY |
|
||||
RADEON_GMC_CLR_CMP_CNTL_DIS |
|
||||
RADEON_GMC_WR_MSK_DIS );
|
||||
|
||||
OUT_RING( dev_priv->back_pitch_offset );
|
||||
OUT_RING( dev_priv->front_pitch_offset );
|
||||
|
||||
/* Make this work even if front & back are flipped:
|
||||
*/
|
||||
if (dev_priv->current_page == 0) {
|
||||
OUT_RING( dev_priv->back_pitch_offset );
|
||||
OUT_RING( dev_priv->front_pitch_offset );
|
||||
}
|
||||
else {
|
||||
OUT_RING( dev_priv->front_pitch_offset );
|
||||
OUT_RING( dev_priv->back_pitch_offset );
|
||||
}
|
||||
|
||||
OUT_RING( (x << 16) | y );
|
||||
OUT_RING( (x << 16) | y );
|
||||
|
|
@ -580,11 +589,12 @@ static void radeon_cp_dispatch_flip( drm_device_t *dev )
|
|||
radeon_cp_performance_boxes( dev_priv );
|
||||
#endif
|
||||
|
||||
BEGIN_RING( 6 );
|
||||
BEGIN_RING( 4 );
|
||||
|
||||
RADEON_WAIT_UNTIL_3D_IDLE();
|
||||
/*
|
||||
RADEON_WAIT_UNTIL_PAGE_FLIPPED();
|
||||
|
||||
*/
|
||||
OUT_RING( CP_PACKET0( RADEON_CRTC_OFFSET, 0 ) );
|
||||
|
||||
if ( dev_priv->current_page == 0 ) {
|
||||
|
|
@ -602,6 +612,7 @@ static void radeon_cp_dispatch_flip( drm_device_t *dev )
|
|||
* performing the swapbuffer ioctl.
|
||||
*/
|
||||
dev_priv->sarea_priv->last_frame++;
|
||||
dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page;
|
||||
|
||||
BEGIN_RING( 2 );
|
||||
|
||||
|
|
@ -1045,25 +1056,71 @@ int radeon_cp_clear( struct inode *inode, struct file *filp,
|
|||
sarea_priv->nbox * sizeof(depth_boxes[0]) ) )
|
||||
return -EFAULT;
|
||||
|
||||
/* Needed for depth clears via triangles???
|
||||
*/
|
||||
if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) {
|
||||
radeon_emit_state( dev_priv,
|
||||
&sarea_priv->context_state,
|
||||
sarea_priv->tex_state,
|
||||
sarea_priv->dirty );
|
||||
|
||||
sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES |
|
||||
RADEON_UPLOAD_TEX1IMAGES |
|
||||
RADEON_UPLOAD_TEX2IMAGES |
|
||||
RADEON_REQUIRE_QUIESCENCE);
|
||||
}
|
||||
|
||||
radeon_cp_dispatch_clear( dev, &clear, depth_boxes );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Not sure why this isn't set all the time:
|
||||
*/
|
||||
static int radeon_do_init_pageflip( drm_device_t *dev )
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
dev_priv->crtc_offset = RADEON_READ( RADEON_CRTC_OFFSET );
|
||||
dev_priv->crtc_offset_cntl = RADEON_READ( RADEON_CRTC_OFFSET_CNTL );
|
||||
|
||||
RADEON_WRITE( RADEON_CRTC_OFFSET, dev_priv->front_offset );
|
||||
RADEON_WRITE( RADEON_CRTC_OFFSET_CNTL,
|
||||
dev_priv->crtc_offset_cntl |
|
||||
RADEON_CRTC_OFFSET_FLIP_CNTL );
|
||||
|
||||
dev_priv->page_flipping = 1;
|
||||
dev_priv->current_page = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int radeon_do_cleanup_pageflip( drm_device_t *dev )
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
RADEON_WRITE( RADEON_CRTC_OFFSET, dev_priv->crtc_offset );
|
||||
RADEON_WRITE( RADEON_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl );
|
||||
|
||||
dev_priv->page_flipping = 0;
|
||||
dev_priv->current_page = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Swapping and flipping are different operations, need different ioctls.
|
||||
* They can & should be intermixed to support multiple 3d windows.
|
||||
*/
|
||||
int radeon_cp_flip( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg )
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
LOCK_TEST_WITH_RETURN( dev );
|
||||
|
||||
RING_SPACE_TEST_WITH_RETURN( dev_priv );
|
||||
|
||||
if (!dev_priv->page_flipping)
|
||||
radeon_do_init_pageflip( dev );
|
||||
|
||||
radeon_cp_dispatch_flip( dev );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int radeon_cp_swap( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg )
|
||||
{
|
||||
|
|
@ -1080,12 +1137,8 @@ int radeon_cp_swap( struct inode *inode, struct file *filp,
|
|||
if ( sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS )
|
||||
sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS;
|
||||
|
||||
if ( !dev_priv->page_flipping ) {
|
||||
radeon_cp_dispatch_swap( dev );
|
||||
dev_priv->sarea_priv->ctx_owner = 0;
|
||||
} else {
|
||||
radeon_cp_dispatch_flip( dev );
|
||||
}
|
||||
radeon_cp_dispatch_swap( dev );
|
||||
dev_priv->sarea_priv->ctx_owner = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -492,6 +492,7 @@ typedef struct drm_scatter_gather {
|
|||
#define DRM_IOCTL_RADEON_VERTEX2 DRM_IOW( 0x4f, drm_radeon_vertex_t)
|
||||
#define DRM_IOCTL_RADEON_CMDBUF DRM_IOW( 0x50, drm_radeon_cmd_buffer_t)
|
||||
#define DRM_IOCTL_RADEON_GETPARAM DRM_IOWR(0x51, drm_radeon_getparam_t)
|
||||
#define DRM_IOCTL_RADEON_FLIP DRM_IO( 0x52)
|
||||
|
||||
/* Gamma specific ioctls */
|
||||
#define DRM_IOCTL_GAMMA_INIT DRM_IOW( 0x40, drm_gamma_init_t)
|
||||
|
|
|
|||
|
|
@ -492,6 +492,7 @@ typedef struct drm_scatter_gather {
|
|||
#define DRM_IOCTL_RADEON_VERTEX2 DRM_IOW( 0x4f, drm_radeon_vertex_t)
|
||||
#define DRM_IOCTL_RADEON_CMDBUF DRM_IOW( 0x50, drm_radeon_cmd_buffer_t)
|
||||
#define DRM_IOCTL_RADEON_GETPARAM DRM_IOWR(0x51, drm_radeon_getparam_t)
|
||||
#define DRM_IOCTL_RADEON_FLIP DRM_IO( 0x52)
|
||||
|
||||
/* Gamma specific ioctls */
|
||||
#define DRM_IOCTL_GAMMA_INIT DRM_IOW( 0x40, drm_gamma_init_t)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue