From 76baf997371dc8678cbea51fe5d4651aa59af741 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Tue, 9 Jan 2018 03:28:45 +0100 Subject: r600: hack up num_render_backends on Juniper to 8 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 --- src/gallium/drivers/r600/r600_query.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/r600/r600_query.c b/src/gallium/drivers/r600/r600_query.c index 8f87c51cca2..b4519830cc4 100644 --- a/src/gallium/drivers/r600/r600_query.c +++ b/src/gallium/drivers/r600/r600_query.c @@ -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_) \ -- cgit v1.2.3