From 8dbb022b8a93e99a6909ef58299f3649de26b854 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Wed, 21 Apr 2021 19:50:23 -0400 Subject: [PATCH] softpipe: fix render condition checking always casting this to a u64 is invalid if the value is just a bool, and it even generates ASAN/valgrind errors about uninitialized reads Fixes: 41450b03a8e ("softpipe: implement conditional rendering") Reviewed-by: Dave Airlie Part-of: --- src/gallium/drivers/softpipe/sp_query.c | 30 ++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/src/gallium/drivers/softpipe/sp_query.c b/src/gallium/drivers/softpipe/sp_query.c index 08017799190..4fc03fc4c4c 100644 --- a/src/gallium/drivers/softpipe/sp_query.c +++ b/src/gallium/drivers/softpipe/sp_query.c @@ -268,6 +268,29 @@ softpipe_get_query_result(struct pipe_context *pipe, return true; } +static bool +is_result_nonzero(struct pipe_query *q, + union pipe_query_result *vresult) +{ + struct softpipe_query *sq = softpipe_query(q); + + switch (sq->type) { + case PIPE_QUERY_TIMESTAMP_DISJOINT: + case PIPE_QUERY_SO_STATISTICS: + case PIPE_QUERY_PIPELINE_STATISTICS: + unreachable("unpossible"); + break; + case PIPE_QUERY_GPU_FINISHED: + case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: + case PIPE_QUERY_SO_OVERFLOW_PREDICATE: + case PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE: + return vresult->b; + default: + return !!vresult->u64; + } + return false; +} /** * Called by rendering function to check rendering is conditional. @@ -278,7 +301,8 @@ softpipe_check_render_cond(struct softpipe_context *sp) { struct pipe_context *pipe = &sp->pipe; boolean b, wait; - uint64_t result; + union pipe_query_result result; + memset(&result, 0, sizeof(union pipe_query_result)); if (!sp->render_cond_query) { return TRUE; /* no query predicate, draw normally */ @@ -288,9 +312,9 @@ softpipe_check_render_cond(struct softpipe_context *sp) sp->render_cond_mode == PIPE_RENDER_COND_BY_REGION_WAIT); b = pipe->get_query_result(pipe, sp->render_cond_query, wait, - (void*)&result); + &result); if (b) - return (!result) == sp->render_cond_cond; + return !is_result_nonzero(sp->render_cond_query, &result) == sp->render_cond_cond; else return TRUE; }