diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/r600_cs.c')
| -rw-r--r-- | drivers/gpu/drm/radeon/r600_cs.c | 65 |
1 files changed, 36 insertions, 29 deletions
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index ca87f7afaf23..3dab49cb1d4a 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
| @@ -764,8 +764,10 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) | |||
| 764 | } | 764 | } |
| 765 | 765 | ||
| 766 | /* Check depth buffer */ | 766 | /* Check depth buffer */ |
| 767 | if (track->db_dirty && (G_028800_STENCIL_ENABLE(track->db_depth_control) || | 767 | if (track->db_dirty && |
| 768 | G_028800_Z_ENABLE(track->db_depth_control))) { | 768 | G_028010_FORMAT(track->db_depth_info) != V_028010_DEPTH_INVALID && |
| 769 | (G_028800_STENCIL_ENABLE(track->db_depth_control) || | ||
| 770 | G_028800_Z_ENABLE(track->db_depth_control))) { | ||
| 769 | r = r600_cs_track_validate_db(p); | 771 | r = r600_cs_track_validate_db(p); |
| 770 | if (r) | 772 | if (r) |
| 771 | return r; | 773 | return r; |
| @@ -1557,13 +1559,14 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
| 1557 | u32 tiling_flags) | 1559 | u32 tiling_flags) |
| 1558 | { | 1560 | { |
| 1559 | struct r600_cs_track *track = p->track; | 1561 | struct r600_cs_track *track = p->track; |
| 1560 | u32 nfaces, llevel, blevel, w0, h0, d0; | 1562 | u32 dim, nfaces, llevel, blevel, w0, h0, d0; |
| 1561 | u32 word0, word1, l0_size, mipmap_size, word2, word3; | 1563 | u32 word0, word1, l0_size, mipmap_size, word2, word3, word4, word5; |
| 1562 | u32 height_align, pitch, pitch_align, depth_align; | 1564 | u32 height_align, pitch, pitch_align, depth_align; |
| 1563 | u32 array, barray, larray; | 1565 | u32 barray, larray; |
| 1564 | u64 base_align; | 1566 | u64 base_align; |
| 1565 | struct array_mode_checker array_check; | 1567 | struct array_mode_checker array_check; |
| 1566 | u32 format; | 1568 | u32 format; |
| 1569 | bool is_array; | ||
| 1567 | 1570 | ||
| 1568 | /* on legacy kernel we don't perform advanced check */ | 1571 | /* on legacy kernel we don't perform advanced check */ |
| 1569 | if (p->rdev == NULL) | 1572 | if (p->rdev == NULL) |
| @@ -1581,12 +1584,28 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
| 1581 | word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); | 1584 | word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); |
| 1582 | } | 1585 | } |
| 1583 | word1 = radeon_get_ib_value(p, idx + 1); | 1586 | word1 = radeon_get_ib_value(p, idx + 1); |
| 1587 | word2 = radeon_get_ib_value(p, idx + 2) << 8; | ||
| 1588 | word3 = radeon_get_ib_value(p, idx + 3) << 8; | ||
| 1589 | word4 = radeon_get_ib_value(p, idx + 4); | ||
| 1590 | word5 = radeon_get_ib_value(p, idx + 5); | ||
| 1591 | dim = G_038000_DIM(word0); | ||
| 1584 | w0 = G_038000_TEX_WIDTH(word0) + 1; | 1592 | w0 = G_038000_TEX_WIDTH(word0) + 1; |
| 1593 | pitch = (G_038000_PITCH(word0) + 1) * 8; | ||
| 1585 | h0 = G_038004_TEX_HEIGHT(word1) + 1; | 1594 | h0 = G_038004_TEX_HEIGHT(word1) + 1; |
| 1586 | d0 = G_038004_TEX_DEPTH(word1); | 1595 | d0 = G_038004_TEX_DEPTH(word1); |
| 1596 | format = G_038004_DATA_FORMAT(word1); | ||
| 1597 | blevel = G_038010_BASE_LEVEL(word4); | ||
| 1598 | llevel = G_038014_LAST_LEVEL(word5); | ||
| 1599 | /* pitch in texels */ | ||
| 1600 | array_check.array_mode = G_038000_TILE_MODE(word0); | ||
| 1601 | array_check.group_size = track->group_size; | ||
| 1602 | array_check.nbanks = track->nbanks; | ||
| 1603 | array_check.npipes = track->npipes; | ||
| 1604 | array_check.nsamples = 1; | ||
| 1605 | array_check.blocksize = r600_fmt_get_blocksize(format); | ||
| 1587 | nfaces = 1; | 1606 | nfaces = 1; |
| 1588 | array = 0; | 1607 | is_array = false; |
| 1589 | switch (G_038000_DIM(word0)) { | 1608 | switch (dim) { |
| 1590 | case V_038000_SQ_TEX_DIM_1D: | 1609 | case V_038000_SQ_TEX_DIM_1D: |
| 1591 | case V_038000_SQ_TEX_DIM_2D: | 1610 | case V_038000_SQ_TEX_DIM_2D: |
| 1592 | case V_038000_SQ_TEX_DIM_3D: | 1611 | case V_038000_SQ_TEX_DIM_3D: |
| @@ -1599,29 +1618,25 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
| 1599 | break; | 1618 | break; |
| 1600 | case V_038000_SQ_TEX_DIM_1D_ARRAY: | 1619 | case V_038000_SQ_TEX_DIM_1D_ARRAY: |
| 1601 | case V_038000_SQ_TEX_DIM_2D_ARRAY: | 1620 | case V_038000_SQ_TEX_DIM_2D_ARRAY: |
| 1602 | array = 1; | 1621 | is_array = true; |
| 1603 | break; | 1622 | break; |
| 1604 | case V_038000_SQ_TEX_DIM_2D_MSAA: | ||
| 1605 | case V_038000_SQ_TEX_DIM_2D_ARRAY_MSAA: | 1623 | case V_038000_SQ_TEX_DIM_2D_ARRAY_MSAA: |
| 1624 | is_array = true; | ||
| 1625 | /* fall through */ | ||
| 1626 | case V_038000_SQ_TEX_DIM_2D_MSAA: | ||
| 1627 | array_check.nsamples = 1 << llevel; | ||
| 1628 | llevel = 0; | ||
| 1629 | break; | ||
| 1606 | default: | 1630 | default: |
| 1607 | dev_warn(p->dev, "this kernel doesn't support %d texture dim\n", G_038000_DIM(word0)); | 1631 | dev_warn(p->dev, "this kernel doesn't support %d texture dim\n", G_038000_DIM(word0)); |
| 1608 | return -EINVAL; | 1632 | return -EINVAL; |
| 1609 | } | 1633 | } |
| 1610 | format = G_038004_DATA_FORMAT(word1); | ||
| 1611 | if (!r600_fmt_is_valid_texture(format, p->family)) { | 1634 | if (!r600_fmt_is_valid_texture(format, p->family)) { |
| 1612 | dev_warn(p->dev, "%s:%d texture invalid format %d\n", | 1635 | dev_warn(p->dev, "%s:%d texture invalid format %d\n", |
| 1613 | __func__, __LINE__, format); | 1636 | __func__, __LINE__, format); |
| 1614 | return -EINVAL; | 1637 | return -EINVAL; |
| 1615 | } | 1638 | } |
| 1616 | 1639 | ||
| 1617 | /* pitch in texels */ | ||
| 1618 | pitch = (G_038000_PITCH(word0) + 1) * 8; | ||
| 1619 | array_check.array_mode = G_038000_TILE_MODE(word0); | ||
| 1620 | array_check.group_size = track->group_size; | ||
| 1621 | array_check.nbanks = track->nbanks; | ||
| 1622 | array_check.npipes = track->npipes; | ||
| 1623 | array_check.nsamples = 1; | ||
| 1624 | array_check.blocksize = r600_fmt_get_blocksize(format); | ||
| 1625 | if (r600_get_array_mode_alignment(&array_check, | 1640 | if (r600_get_array_mode_alignment(&array_check, |
| 1626 | &pitch_align, &height_align, &depth_align, &base_align)) { | 1641 | &pitch_align, &height_align, &depth_align, &base_align)) { |
| 1627 | dev_warn(p->dev, "%s:%d tex array mode (%d) invalid\n", | 1642 | dev_warn(p->dev, "%s:%d tex array mode (%d) invalid\n", |
| @@ -1647,20 +1662,13 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
| 1647 | return -EINVAL; | 1662 | return -EINVAL; |
| 1648 | } | 1663 | } |
| 1649 | 1664 | ||
| 1650 | word2 = radeon_get_ib_value(p, idx + 2) << 8; | ||
| 1651 | word3 = radeon_get_ib_value(p, idx + 3) << 8; | ||
| 1652 | |||
| 1653 | word0 = radeon_get_ib_value(p, idx + 4); | ||
| 1654 | word1 = radeon_get_ib_value(p, idx + 5); | ||
| 1655 | blevel = G_038010_BASE_LEVEL(word0); | ||
| 1656 | llevel = G_038014_LAST_LEVEL(word1); | ||
| 1657 | if (blevel > llevel) { | 1665 | if (blevel > llevel) { |
| 1658 | dev_warn(p->dev, "texture blevel %d > llevel %d\n", | 1666 | dev_warn(p->dev, "texture blevel %d > llevel %d\n", |
| 1659 | blevel, llevel); | 1667 | blevel, llevel); |
| 1660 | } | 1668 | } |
| 1661 | if (array == 1) { | 1669 | if (is_array) { |
| 1662 | barray = G_038014_BASE_ARRAY(word1); | 1670 | barray = G_038014_BASE_ARRAY(word5); |
| 1663 | larray = G_038014_LAST_ARRAY(word1); | 1671 | larray = G_038014_LAST_ARRAY(word5); |
| 1664 | 1672 | ||
| 1665 | nfaces = larray - barray + 1; | 1673 | nfaces = larray - barray + 1; |
| 1666 | } | 1674 | } |
| @@ -1677,7 +1685,6 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
| 1677 | return -EINVAL; | 1685 | return -EINVAL; |
| 1678 | } | 1686 | } |
| 1679 | /* using get ib will give us the offset into the mipmap bo */ | 1687 | /* using get ib will give us the offset into the mipmap bo */ |
| 1680 | word3 = radeon_get_ib_value(p, idx + 3) << 8; | ||
| 1681 | if ((mipmap_size + word3) > radeon_bo_size(mipmap)) { | 1688 | if ((mipmap_size + word3) > radeon_bo_size(mipmap)) { |
| 1682 | /*dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n", | 1689 | /*dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n", |
| 1683 | w0, h0, format, blevel, nlevels, word3, mipmap_size, radeon_bo_size(texture));*/ | 1690 | w0, h0, format, blevel, nlevels, word3, mipmap_size, radeon_bo_size(texture));*/ |
