summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/r300/r300_texture.c24
-rw-r--r--src/gallium/drivers/r300/r300_winsys.h3
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_drm.c3
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_r300.c2
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_winsys.h3
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;