From 27cedd8aecccea808a35ef297477cac5fe87e476 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Tue, 13 Aug 2013 01:42:37 -0400 Subject: [PATCH] llvmpipe: fix pipeline statistics with a null ps If the fragment shader is null then pixel shader invocations have to be equal to zero. And if we're running a null ps then clipper invocations and primitives should be equal to zero but only if both stancil and depth testing are disabled. Signed-off-by: Zack Rusin Reviewed-by: Roland Scheidegger --- src/gallium/drivers/llvmpipe/lp_rast.c | 3 ++- src/gallium/drivers/llvmpipe/lp_rast_priv.h | 3 ++- src/gallium/drivers/llvmpipe/lp_setup_line.c | 3 ++- src/gallium/drivers/llvmpipe/lp_setup_point.c | 3 ++- src/gallium/drivers/llvmpipe/lp_setup_tri.c | 3 ++- src/gallium/drivers/llvmpipe/lp_setup_vbuf.c | 8 +++++-- src/gallium/drivers/llvmpipe/lp_state_fs.c | 24 ++++++++++++++++++- src/gallium/drivers/llvmpipe/lp_state_fs.h | 4 ++++ 8 files changed, 43 insertions(+), 8 deletions(-) diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 49cdbfeff8e..af661e929f0 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -35,6 +35,7 @@ #include "os/os_time.h" #include "lp_scene_queue.h" +#include "lp_context.h" #include "lp_debug.h" #include "lp_fence.h" #include "lp_perf.h" @@ -459,7 +460,7 @@ lp_rast_shade_quads_mask(struct lp_rasterizer_task *task, if ((x % TILE_SIZE) < task->width && (y % TILE_SIZE) < task->height) { /* not very accurate would need a popcount on the mask */ /* always count this not worth bothering? */ - task->ps_invocations++; + task->ps_invocations += 1 * variant->ps_inv_multiplier; /* run shader on 4x4 block */ BEGIN_JIT_CALL(state, task); diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h index b8bc99c1939..41fe097e27e 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h @@ -100,6 +100,7 @@ struct lp_rasterizer_task /* occlude counter for visible pixels */ struct lp_jit_thread_data thread_data; uint64_t ps_invocations; + uint8_t ps_inv_multiplier; pipe_semaphore work_ready; pipe_semaphore work_done; @@ -308,7 +309,7 @@ lp_rast_shade_quads_all( struct lp_rasterizer_task *task, if ((x % TILE_SIZE) < task->width && (y % TILE_SIZE) < task->height) { /* not very accurate would need a popcount on the mask */ /* always count this not worth bothering? */ - task->ps_invocations++; + task->ps_invocations += 1 * variant->ps_inv_multiplier; /* run shader on 4x4 block */ BEGIN_JIT_CALL(state, task); diff --git a/src/gallium/drivers/llvmpipe/lp_setup_line.c b/src/gallium/drivers/llvmpipe/lp_setup_line.c index a25a6b02f8d..e1686eaabf6 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_line.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_line.c @@ -600,7 +600,8 @@ try_setup_line( struct lp_setup_context *setup, LP_COUNT(nr_tris); - if (lp_context->active_statistics_queries) { + if (lp_context->active_statistics_queries && + !llvmpipe_rasterization_disabled(lp_context)) { lp_context->pipeline_statistics.c_primitives++; } diff --git a/src/gallium/drivers/llvmpipe/lp_setup_point.c b/src/gallium/drivers/llvmpipe/lp_setup_point.c index cbcc8d4f2f3..45068ec6df3 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_point.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_point.c @@ -384,7 +384,8 @@ try_setup_point( struct lp_setup_context *setup, LP_COUNT(nr_tris); - if (lp_context->active_statistics_queries) { + if (lp_context->active_statistics_queries && + !llvmpipe_rasterization_disabled(lp_context)) { lp_context->pipeline_statistics.c_primitives++; } diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index 579f35126a5..23bc6e2a4f9 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -340,7 +340,8 @@ do_triangle_ccw(struct lp_setup_context *setup, LP_COUNT(nr_tris); - if (lp_context->active_statistics_queries) { + if (lp_context->active_statistics_queries && + !llvmpipe_rasterization_disabled(lp_context)) { lp_context->pipeline_statistics.c_primitives++; } diff --git a/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c b/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c index 8173994e5c1..1ea6bcf5b00 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c @@ -565,8 +565,12 @@ lp_setup_pipeline_statistics( stats->gs_invocations; llvmpipe->pipeline_statistics.gs_primitives += stats->gs_primitives; - llvmpipe->pipeline_statistics.c_invocations += - stats->c_invocations; + if (!llvmpipe_rasterization_disabled(llvmpipe)) { + llvmpipe->pipeline_statistics.c_invocations += + stats->c_invocations; + } else { + llvmpipe->pipeline_statistics.c_invocations = 0; + } } /** diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 373994186e7..07e6685a304 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -2361,7 +2361,14 @@ generate_variant(struct llvmpipe_context *lp, !key->alpha.enabled && !key->depth.enabled && !shader->info.base.uses_kill - ? TRUE : FALSE; + ? TRUE : FALSE; + + if ((!shader || shader->info.base.num_tokens <= 1) && + !key->depth.enabled && !key->stencil[0].enabled) { + variant->ps_inv_multiplier = 0; + } else { + variant->ps_inv_multiplier = 1; + } if ((LP_DEBUG & DEBUG_FS) || (gallivm_debug & GALLIVM_DEBUG_IR)) { lp_debug_fs_variant(variant); @@ -2940,3 +2947,18 @@ llvmpipe_init_fs_funcs(struct llvmpipe_context *llvmpipe) llvmpipe->pipe.set_constant_buffer = llvmpipe_set_constant_buffer; } + +/* + * Rasterization is disabled if there is no pixel shader and + * both depth and stencil testing are disabled: + * http://msdn.microsoft.com/en-us/library/windows/desktop/bb205125 + */ +boolean +llvmpipe_rasterization_disabled(struct llvmpipe_context *lp) +{ + boolean null_fs = !lp->fs || lp->fs->info.base.num_tokens <= 1; + + return (null_fs && + !lp->depth_stencil->depth.enabled && + !lp->depth_stencil->stencil[0].enabled); +} diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.h b/src/gallium/drivers/llvmpipe/lp_state_fs.h index 33140901c18..aac45266017 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.h +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.h @@ -97,6 +97,7 @@ struct lp_fragment_shader_variant struct lp_fragment_shader_variant_key key; boolean opaque; + uint8_t ps_inv_multiplier; struct gallivm_state *gallivm; @@ -148,5 +149,8 @@ void llvmpipe_remove_shader_variant(struct llvmpipe_context *lp, struct lp_fragment_shader_variant *variant); +boolean +llvmpipe_rasterization_disabled(struct llvmpipe_context *lp); + #endif /* LP_STATE_FS_H_ */ -- 2.30.2