diff options
Diffstat (limited to 'drivers/char/drm/radeon_state.c')
-rw-r--r-- | drivers/char/drm/radeon_state.c | 75 |
1 files changed, 40 insertions, 35 deletions
diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c index 1f79e249146c..64a3e3a406ef 100644 --- a/drivers/char/drm/radeon_state.c +++ b/drivers/char/drm/radeon_state.c | |||
@@ -1493,7 +1493,7 @@ static void radeon_cp_dispatch_indices( drm_device_t *dev, | |||
1493 | 1493 | ||
1494 | } | 1494 | } |
1495 | 1495 | ||
1496 | #define RADEON_MAX_TEXTURE_SIZE (RADEON_BUFFER_SIZE - 8 * sizeof(u32)) | 1496 | #define RADEON_MAX_TEXTURE_SIZE RADEON_BUFFER_SIZE |
1497 | 1497 | ||
1498 | static int radeon_cp_dispatch_texture( DRMFILE filp, | 1498 | static int radeon_cp_dispatch_texture( DRMFILE filp, |
1499 | drm_device_t *dev, | 1499 | drm_device_t *dev, |
@@ -1506,10 +1506,11 @@ static int radeon_cp_dispatch_texture( DRMFILE filp, | |||
1506 | u32 format; | 1506 | u32 format; |
1507 | u32 *buffer; | 1507 | u32 *buffer; |
1508 | const u8 __user *data; | 1508 | const u8 __user *data; |
1509 | int size, dwords, tex_width, blit_width; | 1509 | int size, dwords, tex_width, blit_width, spitch; |
1510 | u32 height; | 1510 | u32 height; |
1511 | int i; | 1511 | int i; |
1512 | u32 texpitch, microtile; | 1512 | u32 texpitch, microtile; |
1513 | u32 offset; | ||
1513 | RING_LOCALS; | 1514 | RING_LOCALS; |
1514 | 1515 | ||
1515 | DRM_GET_PRIV_WITH_RETURN( filp_priv, filp ); | 1516 | DRM_GET_PRIV_WITH_RETURN( filp_priv, filp ); |
@@ -1530,17 +1531,6 @@ static int radeon_cp_dispatch_texture( DRMFILE filp, | |||
1530 | RADEON_WAIT_UNTIL_IDLE(); | 1531 | RADEON_WAIT_UNTIL_IDLE(); |
1531 | ADVANCE_RING(); | 1532 | ADVANCE_RING(); |
1532 | 1533 | ||
1533 | #ifdef __BIG_ENDIAN | ||
1534 | /* The Mesa texture functions provide the data in little endian as the | ||
1535 | * chip wants it, but we need to compensate for the fact that the CP | ||
1536 | * ring gets byte-swapped | ||
1537 | */ | ||
1538 | BEGIN_RING( 2 ); | ||
1539 | OUT_RING_REG( RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_32BIT ); | ||
1540 | ADVANCE_RING(); | ||
1541 | #endif | ||
1542 | |||
1543 | |||
1544 | /* The compiler won't optimize away a division by a variable, | 1534 | /* The compiler won't optimize away a division by a variable, |
1545 | * even if the only legal values are powers of two. Thus, we'll | 1535 | * even if the only legal values are powers of two. Thus, we'll |
1546 | * use a shift instead. | 1536 | * use a shift instead. |
@@ -1572,6 +1562,10 @@ static int radeon_cp_dispatch_texture( DRMFILE filp, | |||
1572 | DRM_ERROR( "invalid texture format %d\n", tex->format ); | 1562 | DRM_ERROR( "invalid texture format %d\n", tex->format ); |
1573 | return DRM_ERR(EINVAL); | 1563 | return DRM_ERR(EINVAL); |
1574 | } | 1564 | } |
1565 | spitch = blit_width >> 6; | ||
1566 | if (spitch == 0 && image->height > 1) | ||
1567 | return DRM_ERR(EINVAL); | ||
1568 | |||
1575 | texpitch = tex->pitch; | 1569 | texpitch = tex->pitch; |
1576 | if ((texpitch << 22) & RADEON_DST_TILE_MICRO) { | 1570 | if ((texpitch << 22) & RADEON_DST_TILE_MICRO) { |
1577 | microtile = 1; | 1571 | microtile = 1; |
@@ -1624,25 +1618,6 @@ static int radeon_cp_dispatch_texture( DRMFILE filp, | |||
1624 | */ | 1618 | */ |
1625 | buffer = (u32*)((char*)dev->agp_buffer_map->handle + buf->offset); | 1619 | buffer = (u32*)((char*)dev->agp_buffer_map->handle + buf->offset); |
1626 | dwords = size / 4; | 1620 | dwords = size / 4; |
1627 | buffer[0] = CP_PACKET3( RADEON_CNTL_HOSTDATA_BLT, dwords + 6 ); | ||
1628 | buffer[1] = (RADEON_GMC_DST_PITCH_OFFSET_CNTL | | ||
1629 | RADEON_GMC_BRUSH_NONE | | ||
1630 | (format << 8) | | ||
1631 | RADEON_GMC_SRC_DATATYPE_COLOR | | ||
1632 | RADEON_ROP3_S | | ||
1633 | RADEON_DP_SRC_SOURCE_HOST_DATA | | ||
1634 | RADEON_GMC_CLR_CMP_CNTL_DIS | | ||
1635 | RADEON_GMC_WR_MSK_DIS); | ||
1636 | |||
1637 | buffer[2] = (texpitch << 22) | (tex->offset >> 10); | ||
1638 | buffer[3] = 0xffffffff; | ||
1639 | buffer[4] = 0xffffffff; | ||
1640 | buffer[5] = (image->y << 16) | image->x; | ||
1641 | buffer[6] = (height << 16) | image->width; | ||
1642 | buffer[7] = dwords; | ||
1643 | buffer += 8; | ||
1644 | |||
1645 | |||
1646 | 1621 | ||
1647 | if (microtile) { | 1622 | if (microtile) { |
1648 | /* texture micro tiling in use, minimum texture width is thus 16 bytes. | 1623 | /* texture micro tiling in use, minimum texture width is thus 16 bytes. |
@@ -1750,9 +1725,28 @@ static int radeon_cp_dispatch_texture( DRMFILE filp, | |||
1750 | } | 1725 | } |
1751 | 1726 | ||
1752 | buf->filp = filp; | 1727 | buf->filp = filp; |
1753 | buf->used = (dwords + 8) * sizeof(u32); | 1728 | buf->used = size; |
1754 | radeon_cp_dispatch_indirect( dev, buf, 0, buf->used ); | 1729 | offset = dev_priv->gart_buffers_offset + buf->offset; |
1755 | radeon_cp_discard_buffer( dev, buf ); | 1730 | BEGIN_RING(9); |
1731 | OUT_RING(CP_PACKET3(RADEON_CNTL_BITBLT_MULTI, 5)); | ||
1732 | OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL | | ||
1733 | RADEON_GMC_DST_PITCH_OFFSET_CNTL | | ||
1734 | RADEON_GMC_BRUSH_NONE | | ||
1735 | (format << 8) | | ||
1736 | RADEON_GMC_SRC_DATATYPE_COLOR | | ||
1737 | RADEON_ROP3_S | | ||
1738 | RADEON_DP_SRC_SOURCE_MEMORY | | ||
1739 | RADEON_GMC_CLR_CMP_CNTL_DIS | | ||
1740 | RADEON_GMC_WR_MSK_DIS ); | ||
1741 | OUT_RING((spitch << 22) | (offset >> 10)); | ||
1742 | OUT_RING((texpitch << 22) | (tex->offset >> 10)); | ||
1743 | OUT_RING(0); | ||
1744 | OUT_RING((image->x << 16) | image->y); | ||
1745 | OUT_RING((image->width << 16) | height); | ||
1746 | RADEON_WAIT_UNTIL_2D_IDLE(); | ||
1747 | ADVANCE_RING(); | ||
1748 | |||
1749 | radeon_cp_discard_buffer(dev, buf); | ||
1756 | 1750 | ||
1757 | /* Update the input parameters for next time */ | 1751 | /* Update the input parameters for next time */ |
1758 | image->y += height; | 1752 | image->y += height; |
@@ -2797,6 +2791,17 @@ static int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ) | |||
2797 | 2791 | ||
2798 | orig_nbox = cmdbuf.nbox; | 2792 | orig_nbox = cmdbuf.nbox; |
2799 | 2793 | ||
2794 | if(dev_priv->microcode_version == UCODE_R300) { | ||
2795 | int temp; | ||
2796 | temp=r300_do_cp_cmdbuf(dev, filp, filp_priv, &cmdbuf); | ||
2797 | |||
2798 | if (orig_bufsz != 0) | ||
2799 | drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER); | ||
2800 | |||
2801 | return temp; | ||
2802 | } | ||
2803 | |||
2804 | /* microcode_version != r300 */ | ||
2800 | while ( cmdbuf.bufsz >= sizeof(header) ) { | 2805 | while ( cmdbuf.bufsz >= sizeof(header) ) { |
2801 | 2806 | ||
2802 | header.i = *(int *)cmdbuf.buf; | 2807 | header.i = *(int *)cmdbuf.buf; |