llvmpipe: fix pipeline statistics with a null ps
authorZack Rusin <zackr@vmware.com>
Tue, 13 Aug 2013 05:42:37 +0000 (01:42 -0400)
committerZack Rusin <zackr@vmware.com>
Wed, 14 Aug 2013 22:23:36 +0000 (18:23 -0400)
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 <zackr@vmware.com>
Reviewed-by: Roland Scheidegger <sroland@vmware.com>
src/gallium/drivers/llvmpipe/lp_rast.c
src/gallium/drivers/llvmpipe/lp_rast_priv.h
src/gallium/drivers/llvmpipe/lp_setup_line.c
src/gallium/drivers/llvmpipe/lp_setup_point.c
src/gallium/drivers/llvmpipe/lp_setup_tri.c
src/gallium/drivers/llvmpipe/lp_setup_vbuf.c
src/gallium/drivers/llvmpipe/lp_state_fs.c
src/gallium/drivers/llvmpipe/lp_state_fs.h

index 49cdbfeff8e6df32386c544f4dd1a56742d3ce74..af661e929f097fb20a1abcfbd7dc1631ca3c5955 100644 (file)
@@ -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);
index b8bc99c19397506fbfa94777f64fd3c15110c7d4..41fe097e27e0f0181f9e068576ae7251617f7416 100644 (file)
@@ -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);
index a25a6b02f8d74f3731022a10127310f0000e1af3..e1686eaabf66596e1fd77c97eb54234c79e495a6 100644 (file)
@@ -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++;
    }
 
index cbcc8d4f2f3b407a11257949a735369bf1b5da01..45068ec6df3e09043d567041791126d6bae6d975 100644 (file)
@@ -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++;
    }
 
index 579f35126a543449aec33590eec06cf060a5aa54..23bc6e2a4f98051805a4c3f269a733bd8e4e69d1 100644 (file)
@@ -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++;
    }
 
index 8173994e5c1e31e4f7fa55a6df1143d734c0edff..1ea6bcf5b005adcbb869655d2cbd5ccd7dbac1ae 100644 (file)
@@ -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;
+   }
 }
 
 /**
index 373994186e7aaa0f6568c69b7a31431266219472..07e6685a30483db9ff033788bd03ccc7eec90968 100644 (file)
@@ -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);
+}
index 33140901c184d1ac2ad62d4f4e22af1c62c690d5..aac4526601796be4523d1e700705948f530a9c69 100644 (file)
@@ -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_ */