r600: hack up num_render_backends on Juniper to 8
authorRoland Scheidegger <sroland@vmware.com>
Tue, 9 Jan 2018 02:28:45 +0000 (03:28 +0100)
committerRoland Scheidegger <sroland@vmware.com>
Wed, 10 Jan 2018 03:59:00 +0000 (04:59 +0100)
Juniper really has a maximum of 4 RBEs (16 pixels). However, predication
always locks up on my HD 5750, and through experiments it looks like if we're
pretending it has a maximum of 8, with 4 disabled, it works correctly.
My conclusion would be that there's a bug (likely firmware, not hw) which
causes the predication logic to try to read 8 results out of the query buffer
instead of just 4, and since of course noone ever writes the upper 4, the
status bit is never set and hence it will wait for it forever.

Ideally this would be fixed in firmware, but I'd guess chances of that
happening are slim.
This will double the size of (occlusion) query result buffers, write the
status bit for the disabled rbs in these buffers, and will also add 8 results
together instead of just 4 when reading them back. The latter is unnecessary,
but it's probably not worth bothering - luckily num_render_backends isn't
used outside of occlusion queries, so don't need separate value for the
"real" maximum.
Also print out the enabled_rb_mask if it changed from the pre-fixed value
(which is already printed out), just in case there's some more problems
with chips which have some rbs disabled...

This fixes all the lockups with piglit nv_conditional_render tests on my
HD 5750 (all pass).

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

index 8f87c51..b451983 100644 (file)
@@ -1818,7 +1818,19 @@ void r600_query_fix_enabled_rb_mask(struct r600_common_screen *rscreen)
        struct r600_resource *buffer;
        uint32_t *results;
        unsigned i, mask = 0;
-       unsigned max_rbs = ctx->screen->info.num_render_backends;
+       unsigned max_rbs;
+       
+       if (ctx->family == CHIP_JUNIPER) {
+               /*
+                * Fix for predication lockups - the chip can only ever have
+                * 4 RBs, however it looks like the predication logic assumes
+                * there's 8, trying to read results from query buffers never
+                * written to. By increasing this number we'll write the
+                * status bit for these as per the normal disabled rb logic.
+                */
+               ctx->screen->info.num_render_backends = 8;
+       }
+       max_rbs = ctx->screen->info.num_render_backends;
 
        assert(rscreen->chip_class <= CAYMAN);
 
@@ -1890,8 +1902,13 @@ void r600_query_fix_enabled_rb_mask(struct r600_common_screen *rscreen)
 
        r600_resource_reference(&buffer, NULL);
 
-       if (mask)
+       if (mask) {
+               if (rscreen->debug_flags & DBG_INFO &&
+                   mask != rscreen->info.enabled_rb_mask) {
+                       printf("enabled_rb_mask (fixed) = 0x%x\n", mask);
+               }
                rscreen->info.enabled_rb_mask = mask;
+       }
 }
 
 #define XFULL(name_, query_type_, type_, result_type_, group_id_) \