diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gallium/drivers/r300/r300_texture.c | 24 | ||||
-rw-r--r-- | src/gallium/drivers/r300/r300_winsys.h | 3 | ||||
-rw-r--r-- | src/gallium/winsys/radeon/drm/radeon_drm.c | 3 | ||||
-rw-r--r-- | src/gallium/winsys/radeon/drm/radeon_r300.c | 2 | ||||
-rw-r--r-- | src/gallium/winsys/radeon/drm/radeon_winsys.h | 3 |
5 files changed, 34 insertions, 1 deletions
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 8ed28eb11a6..4439e35d670 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -759,6 +759,29 @@ static unsigned r300_texture_get_nblocksy(struct r300_texture* tex, return util_format_get_nblocksy(tex->b.b.format, height); } +static void r300_texture_3d_fix_mipmapping(struct r300_screen *screen, + struct r300_texture *tex) +{ + /* The kernels <= 2.6.34-rc3 compute the size of mipmapped 3D textures + * incorrectly. This is a workaround to prevent CS from being rejected. */ + + unsigned i, size; + + if (screen->rws->get_value(screen->rws, R300_VID_TEX3D_MIP_BUG) && + tex->b.b.target == PIPE_TEXTURE_3D && + tex->b.b.last_level > 0) { + size = 0; + + for (i = 0; i <= tex->b.b.last_level; i++) { + size += r300_texture_get_stride(screen, tex, i) * + r300_texture_get_nblocksy(tex, i); + } + + size *= tex->b.b.depth0; + tex->size = size; + } +} + static void r300_setup_miptree(struct r300_screen* screen, struct r300_texture* tex) { @@ -930,6 +953,7 @@ struct pipe_resource* r300_texture_create(struct pipe_screen* screen, r300_setup_tiling(screen, tex); } r300_setup_miptree(rscreen, tex); + r300_texture_3d_fix_mipmapping(rscreen, tex); r300_texture_setup_immutable_state(rscreen, tex); r300_texture_setup_fb_state(rscreen, tex); diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h index 80abaef4ba7..5ac997c8680 100644 --- a/src/gallium/drivers/r300/r300_winsys.h +++ b/src/gallium/drivers/r300/r300_winsys.h @@ -50,7 +50,8 @@ enum r300_value_id { R300_VID_PCI_ID, R300_VID_GB_PIPES, R300_VID_Z_PIPES, - R300_VID_SQUARE_TILING_SUPPORT + R300_VID_SQUARE_TILING_SUPPORT, + R300_VID_TEX3D_MIP_BUG, }; struct r300_winsys_screen { diff --git a/src/gallium/winsys/radeon/drm/radeon_drm.c b/src/gallium/winsys/radeon/drm/radeon_drm.c index 3dfcc5aef07..2809b578626 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm.c @@ -100,6 +100,9 @@ static void do_ioctls(int fd, struct radeon_libdrm_winsys* winsys) version->version_minor >= 1; #endif + /* XXX */ + winsys->tex3d_mip_bug = TRUE; + info.request = RADEON_INFO_DEVICE_ID; retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)); if (retval) { diff --git a/src/gallium/winsys/radeon/drm/radeon_r300.c b/src/gallium/winsys/radeon/drm/radeon_r300.c index 735b93bc779..d1e65f87c36 100644 --- a/src/gallium/winsys/radeon/drm/radeon_r300.c +++ b/src/gallium/winsys/radeon/drm/radeon_r300.c @@ -264,6 +264,8 @@ static uint32_t radeon_get_value(struct r300_winsys_screen *rws, return ws->z_pipes; case R300_VID_SQUARE_TILING_SUPPORT: return ws->squaretiling; + case R300_VID_TEX3D_MIP_BUG: + return ws->tex3d_mip_bug; } return 0; } diff --git a/src/gallium/winsys/radeon/drm/radeon_winsys.h b/src/gallium/winsys/radeon/drm/radeon_winsys.h index 4260dbaad72..396f258c312 100644 --- a/src/gallium/winsys/radeon/drm/radeon_winsys.h +++ b/src/gallium/winsys/radeon/drm/radeon_winsys.h @@ -60,6 +60,9 @@ struct radeon_libdrm_winsys { /* Square tiling support. */ boolean squaretiling; + /* Square tiling support. */ + boolean tex3d_mip_bug; + /* DRM FD */ int fd; |