aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/r600_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/r600_cs.c')
-rw-r--r--drivers/gpu/drm/radeon/r600_cs.c65
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));*/