summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Olšák <marek.olsak@amd.com>2013-09-19 14:19:02 +0200
committerMarek Olšák <marek.olsak@amd.com>2013-09-29 14:44:23 +0200
commit75f747b919e1b1cd852eeaa8e662e72273189fb2 (patch)
treee99a603c418b14c964c74c52cc718c4ebf37e6fb
parentbf4a7cd4b2456d4dc93a86bbcc51eba4ae73390a (diff)
radeon: fix pitch alignment for non-power-of-two mipmaps on SI
This fixes VM protection faults. I have a new piglit test which can iterate over all possible widths, heights, and depths (including NPOT) and tests mipmapping with various texture targets. After this is committed, I'll make a new release of libdrm and bump the libdrm version requirement in Mesa.
-rw-r--r--radeon/radeon_surface.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/radeon/radeon_surface.c b/radeon/radeon_surface.c
index 1710e344..d5c45c4e 100644
--- a/radeon/radeon_surface.c
+++ b/radeon/radeon_surface.c
@@ -1412,7 +1412,11 @@ static void si_surf_minify(struct radeon_surface *surf,
uint32_t xalign, uint32_t yalign, uint32_t zalign,
uint32_t slice_align, unsigned offset)
{
- surflevel->npix_x = mip_minify(surf->npix_x, level);
+ if (level == 0) {
+ surflevel->npix_x = surf->npix_x;
+ } else {
+ surflevel->npix_x = mip_minify(next_power_of_two(surf->npix_x), level);
+ }
surflevel->npix_y = mip_minify(surf->npix_y, level);
surflevel->npix_z = mip_minify(surf->npix_z, level);
@@ -1434,7 +1438,7 @@ static void si_surf_minify(struct radeon_surface *surf,
if (level == 0 && surf->last_level == 0)
/* Non-mipmap pitch padded to slice alignment */
xalign = MAX2(xalign, slice_align / surf->bpe);
- else
+ else if (surflevel->mode == RADEON_SURF_MODE_LINEAR_ALIGNED)
/* Small rows evenly distributed across slice */
xalign = MAX2(xalign, slice_align / surf->bpe / surflevel->nblk_y);
@@ -1456,7 +1460,11 @@ static void si_surf_minify_2d(struct radeon_surface *surf,
{
unsigned mtile_pr, mtile_ps;
- surflevel->npix_x = mip_minify(surf->npix_x, level);
+ if (level == 0) {
+ surflevel->npix_x = surf->npix_x;
+ } else {
+ surflevel->npix_x = mip_minify(next_power_of_two(surf->npix_x), level);
+ }
surflevel->npix_y = mip_minify(surf->npix_y, level);
surflevel->npix_z = mip_minify(surf->npix_z, level);