mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2026-05-08 17:29:02 +02:00
wait commands for cmdbuffer ioctl
This commit is contained in:
parent
698c795d4f
commit
61ed1d2585
7 changed files with 133 additions and 37 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 = \
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue