wait commands for cmdbuffer ioctl

This commit is contained in:
Keith Whitwell 2002-09-21 14:20:53 +00:00
parent 698c795d4f
commit 61ed1d2585
7 changed files with 133 additions and 37 deletions

View file

@ -164,8 +164,14 @@ typedef union {
struct {
unsigned char cmd_type, buf_idx, pad0, pad1;
} dma;
struct {
unsigned char cmd_type, flags, pad0, pad1;
} wait;
} drm_radeon_cmd_header_t;
#define RADEON_WAIT_2D 0x1
#define RADEON_WAIT_3D 0x2
#define RADEON_FRONT 0x1
#define RADEON_BACK 0x2

View file

@ -567,6 +567,8 @@ extern int radeon_emit_irq(drm_device_t *dev);
#define RADEON_TXFORMAT_ARGB4444 5
#define RADEON_TXFORMAT_ARGB8888 6
#define RADEON_TXFORMAT_RGBA8888 7
#define RADEON_TXFORMAT_VYUY422 10
#define RADEON_TXFORMAT_YVYU422 11
#define R200_PP_TXCBLEND_0 0x2f00
#define R200_PP_TXCBLEND_1 0x2f10

View file

@ -1087,6 +1087,8 @@ static int radeon_cp_dispatch_texture( drm_device_t *dev,
case RADEON_TXFORMAT_ARGB1555:
case RADEON_TXFORMAT_RGB565:
case RADEON_TXFORMAT_ARGB4444:
case RADEON_TXFORMAT_VYUY422:
case RADEON_TXFORMAT_YVYU422:
format = RADEON_COLOR_FORMAT_RGB565;
tex_width = tex->width * 2;
blit_width = image->width * 2;
@ -1381,7 +1383,7 @@ int radeon_cp_vertex( DRM_IOCTL_ARGS )
LOCK_TEST_WITH_RETURN( dev );
if ( !dev_priv ) {
DRM_ERROR( "%s called with no initialization\n", __func__ );
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
return DRM_ERR(EINVAL);
}
@ -1468,7 +1470,7 @@ int radeon_cp_indices( DRM_IOCTL_ARGS )
LOCK_TEST_WITH_RETURN( dev );
if ( !dev_priv ) {
DRM_ERROR( "%s called with no initialization\n", __func__ );
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
return DRM_ERR(EINVAL);
}
@ -1618,7 +1620,7 @@ int radeon_cp_indirect( DRM_IOCTL_ARGS )
LOCK_TEST_WITH_RETURN( dev );
if ( !dev_priv ) {
DRM_ERROR( "%s called with no initialization\n", __func__ );
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
return DRM_ERR(EINVAL);
}
@ -1695,7 +1697,7 @@ int radeon_cp_vertex2( DRM_IOCTL_ARGS )
LOCK_TEST_WITH_RETURN( dev );
if ( !dev_priv ) {
DRM_ERROR( "%s called with no initialization\n", __func__ );
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
return DRM_ERR(EINVAL);
}
@ -1939,14 +1941,18 @@ static int radeon_emit_packet3_cliprect( drm_device_t *dev,
if ( i < cmdbuf->nbox ) {
if (DRM_COPY_FROM_USER_UNCHECKED( &box, &boxes[i], sizeof(box) ))
return DRM_ERR(EFAULT);
/* FIXME The second and subsequent times round this loop, send a
* WAIT_UNTIL_3D_IDLE before calling emit_clip_rect(). This
* fixes a lockup on fast machines when sending several
* cliprects with a cmdbuf, as when waving a 2D window over
* a 3D window. Something in the commands from user space
* seems to hang the card when they're sent several times
* in a row. That would be the correct place to fix it but
* this works around it until I can figure that out - Tim Smith */
/* FIXME The second and subsequent times round
* this loop, send a WAIT_UNTIL_3D_IDLE before
* calling emit_clip_rect(). This fixes a
* lockup on fast machines when sending
* several cliprects with a cmdbuf, as when
* waving a 2D window over a 3D
* window. Something in the commands from user
* space seems to hang the card when they're
* sent several times in a row. That would be
* the correct place to fix it but this works
* around it until I can figure that out - Tim
* Smith */
if ( i ) {
BEGIN_RING( 2 );
RADEON_WAIT_UNTIL_3D_IDLE();
@ -1970,6 +1976,34 @@ static int radeon_emit_packet3_cliprect( drm_device_t *dev,
}
static int radeon_emit_wait( drm_device_t *dev, int flags )
{
drm_radeon_private_t *dev_priv = dev->dev_private;
RING_LOCALS;
DRM_DEBUG("%s: %x\n", __FUNCTION__, flags);
switch (flags) {
case RADEON_WAIT_2D:
BEGIN_RING( 2 );
RADEON_WAIT_UNTIL_2D_IDLE();
ADVANCE_RING();
break;
case RADEON_WAIT_3D:
BEGIN_RING( 2 );
RADEON_WAIT_UNTIL_3D_IDLE();
ADVANCE_RING();
break;
case RADEON_WAIT_2D|RADEON_WAIT_3D:
BEGIN_RING( 2 );
RADEON_WAIT_UNTIL_IDLE();
ADVANCE_RING();
break;
default:
return DRM_ERR(EINVAL);
}
return 0;
}
int radeon_cp_cmdbuf( DRM_IOCTL_ARGS )
{
@ -1985,14 +2019,13 @@ int radeon_cp_cmdbuf( DRM_IOCTL_ARGS )
LOCK_TEST_WITH_RETURN( dev );
if ( !dev_priv ) {
DRM_ERROR( "%s called with no initialization\n", __func__ );
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
return DRM_ERR(EINVAL);
}
DRM_COPY_FROM_USER_IOCTL( cmdbuf, (drm_radeon_cmd_buffer_t *)data,
sizeof(cmdbuf) );
DRM_DEBUG( "pid=%d\n", DRM_CURRENTPID );
RING_SPACE_TEST_WITH_RETURN( dev_priv );
VB_AGE_TEST_WITH_RETURN( dev_priv );
@ -2083,6 +2116,14 @@ int radeon_cp_cmdbuf( DRM_IOCTL_ARGS )
return DRM_ERR(EINVAL);
}
break;
case RADEON_CMD_WAIT:
DRM_DEBUG("RADEON_CMD_WAIT\n");
if (radeon_emit_wait( dev, header.wait.flags )) {
DRM_ERROR("radeon_emit_wait failed\n");
return DRM_ERR(EINVAL);
}
break;
default:
DRM_ERROR("bad cmd_type %d at %p\n",
header.header.cmd_type,
@ -2107,7 +2148,7 @@ int radeon_cp_getparam( DRM_IOCTL_ARGS )
int value;
if ( !dev_priv ) {
DRM_ERROR( "%s called with no initialization\n", __func__ );
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
return DRM_ERR(EINVAL);
}

View file

@ -149,13 +149,11 @@
RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 ); \
} while (0)
/* #ifdef __linux__ */
/* #define IWH(x) init_waitqueue_head(x) */
/* #else */
/* #define IWH(x) */
/* #endif */
#define IWH(x)
#ifdef __linux__
#define IWH(x) init_waitqueue_head(x)
#else
#define IWH(x)
#endif
#define DRIVER_POSTINSTALL() do { \
drm_radeon_private_t *dev_priv = \

View file

@ -164,8 +164,14 @@ typedef union {
struct {
unsigned char cmd_type, buf_idx, pad0, pad1;
} dma;
struct {
unsigned char cmd_type, flags, pad0, pad1;
} wait;
} drm_radeon_cmd_header_t;
#define RADEON_WAIT_2D 0x1
#define RADEON_WAIT_3D 0x2
#define RADEON_FRONT 0x1
#define RADEON_BACK 0x2

View file

@ -567,6 +567,8 @@ extern int radeon_emit_irq(drm_device_t *dev);
#define RADEON_TXFORMAT_ARGB4444 5
#define RADEON_TXFORMAT_ARGB8888 6
#define RADEON_TXFORMAT_RGBA8888 7
#define RADEON_TXFORMAT_VYUY422 10
#define RADEON_TXFORMAT_YVYU422 11
#define R200_PP_TXCBLEND_0 0x2f00
#define R200_PP_TXCBLEND_1 0x2f10

View file

@ -1087,6 +1087,8 @@ static int radeon_cp_dispatch_texture( drm_device_t *dev,
case RADEON_TXFORMAT_ARGB1555:
case RADEON_TXFORMAT_RGB565:
case RADEON_TXFORMAT_ARGB4444:
case RADEON_TXFORMAT_VYUY422:
case RADEON_TXFORMAT_YVYU422:
format = RADEON_COLOR_FORMAT_RGB565;
tex_width = tex->width * 2;
blit_width = image->width * 2;
@ -1381,7 +1383,7 @@ int radeon_cp_vertex( DRM_IOCTL_ARGS )
LOCK_TEST_WITH_RETURN( dev );
if ( !dev_priv ) {
DRM_ERROR( "%s called with no initialization\n", __func__ );
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
return DRM_ERR(EINVAL);
}
@ -1468,7 +1470,7 @@ int radeon_cp_indices( DRM_IOCTL_ARGS )
LOCK_TEST_WITH_RETURN( dev );
if ( !dev_priv ) {
DRM_ERROR( "%s called with no initialization\n", __func__ );
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
return DRM_ERR(EINVAL);
}
@ -1618,7 +1620,7 @@ int radeon_cp_indirect( DRM_IOCTL_ARGS )
LOCK_TEST_WITH_RETURN( dev );
if ( !dev_priv ) {
DRM_ERROR( "%s called with no initialization\n", __func__ );
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
return DRM_ERR(EINVAL);
}
@ -1695,7 +1697,7 @@ int radeon_cp_vertex2( DRM_IOCTL_ARGS )
LOCK_TEST_WITH_RETURN( dev );
if ( !dev_priv ) {
DRM_ERROR( "%s called with no initialization\n", __func__ );
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
return DRM_ERR(EINVAL);
}
@ -1939,14 +1941,18 @@ static int radeon_emit_packet3_cliprect( drm_device_t *dev,
if ( i < cmdbuf->nbox ) {
if (DRM_COPY_FROM_USER_UNCHECKED( &box, &boxes[i], sizeof(box) ))
return DRM_ERR(EFAULT);
/* FIXME The second and subsequent times round this loop, send a
* WAIT_UNTIL_3D_IDLE before calling emit_clip_rect(). This
* fixes a lockup on fast machines when sending several
* cliprects with a cmdbuf, as when waving a 2D window over
* a 3D window. Something in the commands from user space
* seems to hang the card when they're sent several times
* in a row. That would be the correct place to fix it but
* this works around it until I can figure that out - Tim Smith */
/* FIXME The second and subsequent times round
* this loop, send a WAIT_UNTIL_3D_IDLE before
* calling emit_clip_rect(). This fixes a
* lockup on fast machines when sending
* several cliprects with a cmdbuf, as when
* waving a 2D window over a 3D
* window. Something in the commands from user
* space seems to hang the card when they're
* sent several times in a row. That would be
* the correct place to fix it but this works
* around it until I can figure that out - Tim
* Smith */
if ( i ) {
BEGIN_RING( 2 );
RADEON_WAIT_UNTIL_3D_IDLE();
@ -1970,6 +1976,34 @@ static int radeon_emit_packet3_cliprect( drm_device_t *dev,
}
static int radeon_emit_wait( drm_device_t *dev, int flags )
{
drm_radeon_private_t *dev_priv = dev->dev_private;
RING_LOCALS;
DRM_DEBUG("%s: %x\n", __FUNCTION__, flags);
switch (flags) {
case RADEON_WAIT_2D:
BEGIN_RING( 2 );
RADEON_WAIT_UNTIL_2D_IDLE();
ADVANCE_RING();
break;
case RADEON_WAIT_3D:
BEGIN_RING( 2 );
RADEON_WAIT_UNTIL_3D_IDLE();
ADVANCE_RING();
break;
case RADEON_WAIT_2D|RADEON_WAIT_3D:
BEGIN_RING( 2 );
RADEON_WAIT_UNTIL_IDLE();
ADVANCE_RING();
break;
default:
return DRM_ERR(EINVAL);
}
return 0;
}
int radeon_cp_cmdbuf( DRM_IOCTL_ARGS )
{
@ -1985,14 +2019,13 @@ int radeon_cp_cmdbuf( DRM_IOCTL_ARGS )
LOCK_TEST_WITH_RETURN( dev );
if ( !dev_priv ) {
DRM_ERROR( "%s called with no initialization\n", __func__ );
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
return DRM_ERR(EINVAL);
}
DRM_COPY_FROM_USER_IOCTL( cmdbuf, (drm_radeon_cmd_buffer_t *)data,
sizeof(cmdbuf) );
DRM_DEBUG( "pid=%d\n", DRM_CURRENTPID );
RING_SPACE_TEST_WITH_RETURN( dev_priv );
VB_AGE_TEST_WITH_RETURN( dev_priv );
@ -2083,6 +2116,14 @@ int radeon_cp_cmdbuf( DRM_IOCTL_ARGS )
return DRM_ERR(EINVAL);
}
break;
case RADEON_CMD_WAIT:
DRM_DEBUG("RADEON_CMD_WAIT\n");
if (radeon_emit_wait( dev, header.wait.flags )) {
DRM_ERROR("radeon_emit_wait failed\n");
return DRM_ERR(EINVAL);
}
break;
default:
DRM_ERROR("bad cmd_type %d at %p\n",
header.header.cmd_type,
@ -2107,7 +2148,7 @@ int radeon_cp_getparam( DRM_IOCTL_ARGS )
int value;
if ( !dev_priv ) {
DRM_ERROR( "%s called with no initialization\n", __func__ );
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
return DRM_ERR(EINVAL);
}