r600: fix enabled_rb_mask on eg/cm
authorRoland Scheidegger <sroland@vmware.com>
Tue, 9 Jan 2018 00:38:27 +0000 (01:38 +0100)
committerRoland Scheidegger <sroland@vmware.com>
Wed, 10 Jan 2018 03:59:00 +0000 (04:59 +0100)
For eg/cm, the r600_gb_backend_map will always be 0. This is a bug in
the drm kernel driver, as it just just never fills the information in
(it is now being fixed - the history shows it was being filled in when
the query was brand new but got lost shortly thereafter with backend_map
fixes).
This causes r600_query_hw_prepare_buffer to write the "status bit"
(just the highest bit of the occlusion query result) even for active rbes
(all but the first). This doesn't make much sense, albeit I suppose it's mostly
safe. According to the commit history, it's necessary to set these bits for
inactive rbes since otherwise predication will lock up - presumably the hw just
is waiting for the status bit to appear, which will never happen with inactive
rbes. I'd guess potentially predication could be wrong (due to not waiting for
the actual result if the status bit is already there) if this is set for
active rbes.

Discovered while trying to fix predication lockups on Juniper (needs another
patch).

Reviewed-by: Dave Airlie <airlied@redhat.com>
src/gallium/drivers/r600/r600_query.c

index 0d22bc5216a0a42f6f91488930a860ba94cfe443..8f87c51cca2e64594f4811c7f79403043c4d3fb5 100644 (file)
@@ -1822,8 +1822,15 @@ void r600_query_fix_enabled_rb_mask(struct r600_common_screen *rscreen)
 
        assert(rscreen->chip_class <= CAYMAN);
 
 
        assert(rscreen->chip_class <= CAYMAN);
 
-       /* if backend_map query is supported by the kernel */
-       if (rscreen->info.r600_gb_backend_map_valid) {
+       /*
+        * if backend_map query is supported by the kernel.
+        * Note the kernel drm driver for a long time never filled in the
+        * associated data on eg/cm, only on r600/r700, hence ignore the valid
+        * bit there if the map is zero.
+        * (Albeit some chips with just one active rb can have a valid 0 map.)
+        */ 
+       if (rscreen->info.r600_gb_backend_map_valid &&
+           (ctx->chip_class < EVERGREEN || rscreen->info.r600_gb_backend_map != 0)) {
                unsigned num_tile_pipes = rscreen->info.num_tile_pipes;
                unsigned backend_map = rscreen->info.r600_gb_backend_map;
                unsigned item_width, item_mask;
                unsigned num_tile_pipes = rscreen->info.num_tile_pipes;
                unsigned backend_map = rscreen->info.r600_gb_backend_map;
                unsigned item_width, item_mask;