r300g: fix mipmapped 3D textures
authorMarek Olšák <maraeo@gmail.com>
Sun, 11 Apr 2010 03:06:27 +0000 (05:06 +0200)
committerMarek Olšák <maraeo@gmail.com>
Sun, 11 Apr 2010 04:40:46 +0000 (06:40 +0200)
This is a bug in the CS checker causing CS being rejected.

src/gallium/drivers/r300/r300_texture.c
src/gallium/drivers/r300/r300_winsys.h
src/gallium/winsys/radeon/drm/radeon_drm.c
src/gallium/winsys/radeon/drm/radeon_r300.c
src/gallium/winsys/radeon/drm/radeon_winsys.h

index 8ed28eb11a6d21b39baa44d18bf7e68093792b31..4439e35d670bc00ff34553810177c2d25b7788a9 100644 (file)
@@ -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);
 
index 80abaef4ba7f3540d25790054c58bf8e34ec1ff3..5ac997c86805e6606b8ca3fc33434abbc7cd6ffd 100644 (file)
@@ -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 {
index 3dfcc5aef07de2f2fdde35ca6d3b47c981147f4b..2809b578626fae117dee5a66e5764c134c701bb8 100644 (file)
@@ -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) {
index 735b93bc7791d18b068da4f1c68ab0c22559cebf..d1e65f87c36ceb960614fdd46cbff2ce326f4829 100644 (file)
@@ -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;
 }
index 4260dbaad725a1016287976530db357a769b246e..396f258c31204f8db1578855aebe5b1e826c5505 100644 (file)
@@ -60,6 +60,9 @@ struct radeon_libdrm_winsys {
     /* Square tiling support. */
     boolean squaretiling;
 
+    /* Square tiling support. */
+    boolean tex3d_mip_bug;
+
     /* DRM FD */
     int fd;