[Mesa-dev] [PATCH] llvmpipe: improve rasterization discard logic

Roland Scheidegger sroland at vmware.com
Tue May 22 15:06:27 UTC 2018


Am 22.05.2018 um 05:01 schrieb Brian Paul:
> On 05/21/2018 07:34 PM, sroland at vmware.com wrote:
>> From: Roland Scheidegger <sroland at vmware.com>
>>
>> This unifies the explicit rasterization dicard as well as the implicit
> 
> "discard"
Right.

> 
> Looks OK to me.  Minor nits below.
> 
> Reviewed-by: Brian Paul <brianp at vmware.com>
> 
> 
>> rasterization disabled logic (which we need for another state tracker),
>> which really should do the exact same thing.
>> We'll now toss out the prims early on in setup with (implicit or
>> explicit) discard, rather than do setup and binning with them, which
>> was entirely pointless.
>> (We should eventually get rid of implicit discard, which should also
>> enable us to discard stuff already in draw, hence draw would be
>> able to skip the pointless clip and fallback stages in this case.)
>> We still need separate logic for only null ps - this is not the same
>> as rasterization discard. But simplify the logic there and don't count
>> primitives simply when there's an empty fs, regardless of depth/stencil
>> tests, which seems perfectly acceptable by d3d10.
>> While here, also fix statistics for primitives if face culling is
>> enabled.
>> No piglit changes.
>> ---
>>   src/gallium/drivers/llvmpipe/lp_context.h       |  1 -
>>   src/gallium/drivers/llvmpipe/lp_jit.c           |  1 +
>>   src/gallium/drivers/llvmpipe/lp_jit.h           |  5 +++
>>   src/gallium/drivers/llvmpipe/lp_rast.c          | 12 +++-----
>>   src/gallium/drivers/llvmpipe/lp_rast_priv.h     |  6 ----
>>   src/gallium/drivers/llvmpipe/lp_scene.c         |  5 ++-
>>   src/gallium/drivers/llvmpipe/lp_scene.h         | 10 +++---
>>   src/gallium/drivers/llvmpipe/lp_setup.c         | 18 ++++++-----
>>   src/gallium/drivers/llvmpipe/lp_setup_line.c    | 27 ++++++++++------
>>   src/gallium/drivers/llvmpipe/lp_setup_point.c   | 21 +++++++++----
>>   src/gallium/drivers/llvmpipe/lp_setup_tri.c     | 29 ++++++++++++-----
>>   src/gallium/drivers/llvmpipe/lp_setup_vbuf.c    |  2 +-
>>   src/gallium/drivers/llvmpipe/lp_state_derived.c | 22 ++++++++++---
>>   src/gallium/drivers/llvmpipe/lp_state_fs.c      | 41
>> ++++++++++++-------------
>>   src/gallium/drivers/llvmpipe/lp_state_fs.h      |  5 ---
>>   15 files changed, 118 insertions(+), 87 deletions(-)
>>
>> diff --git a/src/gallium/drivers/llvmpipe/lp_context.h
>> b/src/gallium/drivers/llvmpipe/lp_context.h
>> index 54d98fd..7a2f253 100644
>> --- a/src/gallium/drivers/llvmpipe/lp_context.h
>> +++ b/src/gallium/drivers/llvmpipe/lp_context.h
>> @@ -136,7 +136,6 @@ struct llvmpipe_context {
>>      struct blitter_context *blitter;
>>        unsigned tex_timestamp;
>> -   boolean no_rast;
>>        /** List of all fragment shader variants */
>>      struct lp_fs_variant_list_item fs_variants_list;
>> diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c
>> b/src/gallium/drivers/llvmpipe/lp_jit.c
>> index a2762f3..e2309f4 100644
>> --- a/src/gallium/drivers/llvmpipe/lp_jit.c
>> +++ b/src/gallium/drivers/llvmpipe/lp_jit.c
>> @@ -212,6 +212,7 @@ lp_jit_create_types(struct
>> lp_fragment_shader_variant *lp)
>>         elem_types[LP_JIT_THREAD_DATA_CACHE] =
>>               LLVMPointerType(lp_build_format_cache_type(gallivm), 0);
>>         elem_types[LP_JIT_THREAD_DATA_COUNTER] =
>> LLVMInt64TypeInContext(lc);
>> +      elem_types[LP_JIT_THREAD_DATA_INVOCATIONS] =
>> LLVMInt64TypeInContext(lc);
>>         elem_types[LP_JIT_THREAD_DATA_RASTER_STATE_VIEWPORT_INDEX] =
>>               LLVMInt32TypeInContext(lc);
>>   diff --git a/src/gallium/drivers/llvmpipe/lp_jit.h
>> b/src/gallium/drivers/llvmpipe/lp_jit.h
>> index 9db26f2..312d1a1 100644
>> --- a/src/gallium/drivers/llvmpipe/lp_jit.h
>> +++ b/src/gallium/drivers/llvmpipe/lp_jit.h
>> @@ -192,6 +192,7 @@ struct lp_jit_thread_data
>>   {
>>      struct lp_build_format_cache *cache;
>>      uint64_t vis_counter;
>> +   uint64_t ps_invocations;
>>        /*
>>       * Non-interpolated rasterizer state passed through to the
>> fragment shader.
>> @@ -205,6 +206,7 @@ struct lp_jit_thread_data
>>   enum {
>>      LP_JIT_THREAD_DATA_CACHE = 0,
>>      LP_JIT_THREAD_DATA_COUNTER,
>> +   LP_JIT_THREAD_DATA_INVOCATIONS,
>>      LP_JIT_THREAD_DATA_RASTER_STATE_VIEWPORT_INDEX,
>>      LP_JIT_THREAD_DATA_COUNT
>>   };
>> @@ -216,6 +218,9 @@ enum {
>>   #define lp_jit_thread_data_counter(_gallivm, _ptr) \
>>      lp_build_struct_get_ptr(_gallivm, _ptr,
>> LP_JIT_THREAD_DATA_COUNTER, "counter")
>>   +#define lp_jit_thread_data_invocations(_gallivm, _ptr) \
>> +   lp_build_struct_get_ptr(_gallivm, _ptr,
>> LP_JIT_THREAD_DATA_INVOCATIONS, "invocs")
>> +
>>   #define lp_jit_thread_data_raster_state_viewport_index(_gallivm,
>> _ptr) \
>>      lp_build_struct_get(_gallivm, _ptr, \
>>                         
>> LP_JIT_THREAD_DATA_RASTER_STATE_VIEWPORT_INDEX, \
>> diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c
>> b/src/gallium/drivers/llvmpipe/lp_rast.c
>> index 939944a..9d4f9f8 100644
>> --- a/src/gallium/drivers/llvmpipe/lp_rast.c
>> +++ b/src/gallium/drivers/llvmpipe/lp_rast.c
>> @@ -107,7 +107,7 @@ lp_rast_tile_begin(struct lp_rasterizer_task *task,
>>                       task->scene->fb.height - y * TILE_SIZE : TILE_SIZE;
>>        task->thread_data.vis_counter = 0;
>> -   task->ps_invocations = 0;
>> +   task->thread_data.ps_invocations = 0;
>>        for (i = 0; i < task->scene->fb.nr_cbufs; i++) {
>>         if (task->scene->fb.cbufs[i]) {
>> @@ -446,10 +446,6 @@ lp_rast_shade_quads_mask(struct
>> lp_rasterizer_task *task,
>>       * allocated 4x4 blocks hence need to filter them out here.
>>       */
>>      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 += 1 * variant->ps_inv_multiplier;
>> -
>>         /* Propagate non-interpolated raster state. */
>>         task->thread_data.raster_state.viewport_index =
>> inputs->viewport_index;
>>   @@ -491,7 +487,7 @@ lp_rast_begin_query(struct lp_rasterizer_task
>> *task,
>>         pq->start[task->thread_index] = task->thread_data.vis_counter;
>>         break;
>>      case PIPE_QUERY_PIPELINE_STATISTICS:
>> -      pq->start[task->thread_index] = task->ps_invocations;
>> +      pq->start[task->thread_index] = task->thread_data.ps_invocations;
>>         break;
>>      default:
>>         assert(0);
>> @@ -524,7 +520,7 @@ lp_rast_end_query(struct lp_rasterizer_task *task,
>>         break;
>>      case PIPE_QUERY_PIPELINE_STATISTICS:
>>         pq->end[task->thread_index] +=
>> -         task->ps_invocations - pq->start[task->thread_index];
>> +         task->thread_data.ps_invocations -
>> pq->start[task->thread_index];
>>         pq->start[task->thread_index] = 0;
>>         break;
>>      default:
>> @@ -679,7 +675,7 @@ rasterize_scene(struct lp_rasterizer_task *task,
>>   #endif
>>   #endif
>>   -   if (!task->rast->no_rast && !scene->discard) {
>> +   if (!task->rast->no_rast) {
>>         /* loop over scene bins, rasterize each */
>>         {
>>            struct cmd_bin *bin;
>> diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h
>> b/src/gallium/drivers/llvmpipe/lp_rast_priv.h
>> index fe078d5..59d3a2d 100644
>> --- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h
>> +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h
>> @@ -99,8 +99,6 @@ struct lp_rasterizer_task
>>        /** Non-interpolated passthru state and 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;
>> @@ -259,10 +257,6 @@ lp_rast_shade_quads_all( struct
>> lp_rasterizer_task *task,
>>       * allocated 4x4 blocks hence need to filter them out here.
>>       */
>>      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 += 1 * variant->ps_inv_multiplier;
>> -
>>         /* Propagate non-interpolated raster state. */
>>         task->thread_data.raster_state.viewport_index =
>> inputs->viewport_index;
>>   diff --git a/src/gallium/drivers/llvmpipe/lp_scene.c
>> b/src/gallium/drivers/llvmpipe/lp_scene.c
>> index dfad9fa..ef0136c 100644
>> --- a/src/gallium/drivers/llvmpipe/lp_scene.c
>> +++ b/src/gallium/drivers/llvmpipe/lp_scene.c
>> @@ -507,15 +507,14 @@ end:
>>   }
>>     -void lp_scene_begin_binning( struct lp_scene *scene,
>> -                             struct pipe_framebuffer_state *fb,
>> boolean discard )
>> +void lp_scene_begin_binning(struct lp_scene *scene,
>> +                            struct pipe_framebuffer_state *fb)
>>   {
>>      int i;
>>      unsigned max_layer = ~0;
>>        assert(lp_scene_is_empty(scene));
>>   -   scene->discard = discard;
>>      util_copy_framebuffer_state(&scene->fb, fb);
>>        scene->tiles_x = align(fb->width, TILE_SIZE) / TILE_SIZE;
>> diff --git a/src/gallium/drivers/llvmpipe/lp_scene.h
>> b/src/gallium/drivers/llvmpipe/lp_scene.h
>> index da29057..b4ed881 100644
>> --- a/src/gallium/drivers/llvmpipe/lp_scene.h
>> +++ b/src/gallium/drivers/llvmpipe/lp_scene.h
>> @@ -166,7 +166,6 @@ struct lp_scene {
>>      unsigned resource_reference_size;
>>        boolean alloc_failed;
>> -   boolean discard;
>>      /**
>>       * Number of active tiles in each dimension.
>>       * This basically the framebuffer size divided by tile size
>> @@ -389,12 +388,11 @@ lp_scene_bin_iter_next( struct lp_scene *scene,
>> int *x, int *y );
>>   /* Begin/end binning of a scene
>>    */
>>   void
>> -lp_scene_begin_binning( struct lp_scene *scene,
>> -                        struct pipe_framebuffer_state *fb,
>> -                        boolean discard );
>> +lp_scene_begin_binning(struct lp_scene *scene,
>> +                       struct pipe_framebuffer_state *fb);
>>     void
>> -lp_scene_end_binning( struct lp_scene *scene );
>> +lp_scene_end_binning(struct lp_scene *scene);
>>       /* Begin/end rasterization of a scene
>> @@ -403,7 +401,7 @@ void
>>   lp_scene_begin_rasterization(struct lp_scene *scene);
>>     void
>> -lp_scene_end_rasterization(struct lp_scene *scene );
>> +lp_scene_end_rasterization(struct lp_scene *scene);
>>       diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c
>> b/src/gallium/drivers/llvmpipe/lp_setup.c
>> index c157323..b087369 100644
>> --- a/src/gallium/drivers/llvmpipe/lp_setup.c
>> +++ b/src/gallium/drivers/llvmpipe/lp_setup.c
>> @@ -82,7 +82,7 @@ lp_setup_get_empty_scene(struct lp_setup_context
>> *setup)
>>         lp_fence_wait(setup->scene->fence);
>>      }
>>   -   lp_scene_begin_binning(setup->scene, &setup->fb,
>> setup->rasterizer_discard);
>> +   lp_scene_begin_binning(setup->scene, &setup->fb);
>>     }
>>   @@ -724,25 +724,27 @@ lp_setup_set_scissors( struct lp_setup_context
>> *setup,
>>       void
>> -lp_setup_set_flatshade_first( struct lp_setup_context *setup,
>> -                              boolean flatshade_first )
>> +lp_setup_set_flatshade_first(struct lp_setup_context *setup,
>> +                             boolean flatshade_first)
>>   {
>>      setup->flatshade_first = flatshade_first;
>>   }
>>     void
>> -lp_setup_set_rasterizer_discard( struct lp_setup_context *setup,
>> -                                 boolean rasterizer_discard )
>> +lp_setup_set_rasterizer_discard(struct lp_setup_context *setup,
>> +                                boolean rasterizer_discard)
>>   {
>>      if (setup->rasterizer_discard != rasterizer_discard) {
>>         setup->rasterizer_discard = rasterizer_discard;
>> -      set_scene_state( setup, SETUP_FLUSHED, __FUNCTION__ );
>> +      setup->line = first_line;
>> +      setup->point = first_point;
>> +      setup->triangle = first_triangle;
>>      }
>>   }
>>     void
>> -lp_setup_set_vertex_info( struct lp_setup_context *setup,
>> -                          struct vertex_info *vertex_info )
>> +lp_setup_set_vertex_info(struct lp_setup_context *setup,
>> +                         struct vertex_info *vertex_info)
>>   {
>>      /* XXX: just silently holding onto the pointer:
>>       */
>> diff --git a/src/gallium/drivers/llvmpipe/lp_setup_line.c
>> b/src/gallium/drivers/llvmpipe/lp_setup_line.c
>> index d0bac5e..56b62d8 100644
>> --- a/src/gallium/drivers/llvmpipe/lp_setup_line.c
>> +++ b/src/gallium/drivers/llvmpipe/lp_setup_line.c
>> @@ -616,8 +616,7 @@ try_setup_line( struct lp_setup_context *setup,
>>        LP_COUNT(nr_tris);
>>   -   if (lp_context->active_statistics_queries &&
>> -       !llvmpipe_rasterization_disabled(lp_context)) {
>> +   if (lp_context->active_statistics_queries) {
>>         lp_context->pipeline_statistics.c_primitives++;
>>      }
>>   @@ -759,24 +758,34 @@ try_setup_line( struct lp_setup_context *setup,
>>   }
>>     -static void lp_setup_line( struct lp_setup_context *setup,
>> -                           const float (*v0)[4],
>> -                           const float (*v1)[4] )
>> +static void lp_setup_line_discard(struct lp_setup_context *setup,
>> +                                  const float (*v0)[4],
>> +                                  const float (*v1)[4])
>>   {
>> -   if (!try_setup_line( setup, v0, v1 ))
>> +}
>> +
>> +static void lp_setup_line(struct lp_setup_context *setup,
>> +                          const float (*v0)[4],
>> +                          const float (*v1)[4])
>> +{
>> +   if (!try_setup_line(setup, v0, v1))
>>      {
> 
> Brace on same line as the if.
Ah I only fixed up formatting partly :-).

> 
> 
>>         if (!lp_setup_flush_and_restart(setup))
>>            return;
>>   -      if (!try_setup_line( setup, v0, v1 ))
>> +      if (!try_setup_line(setup, v0, v1))
>>            return;
>>      }
>>   }
>>     -void lp_setup_choose_line( struct lp_setup_context *setup )
>> +void lp_setup_choose_line(struct lp_setup_context *setup)
>>   {
>> -   setup->line = lp_setup_line;
>> +   if (setup->rasterizer_discard) {
>> +      setup->line = lp_setup_line_discard;
>> +   } else {
>> +      setup->line = lp_setup_line;
>> +   }
>>   }
>>     diff --git a/src/gallium/drivers/llvmpipe/lp_setup_point.c
>> b/src/gallium/drivers/llvmpipe/lp_setup_point.c
>> index 8cb6b83..e559c20 100644
>> --- a/src/gallium/drivers/llvmpipe/lp_setup_point.c
>> +++ b/src/gallium/drivers/llvmpipe/lp_setup_point.c
>> @@ -458,8 +458,7 @@ try_setup_point( struct lp_setup_context *setup,
>>        LP_COUNT(nr_tris);
>>   -   if (lp_context->active_statistics_queries &&
>> -       !llvmpipe_rasterization_disabled(lp_context)) {
>> +   if (lp_context->active_statistics_queries) {
>>         lp_context->pipeline_statistics.c_primitives++;
>>      }
>>   @@ -518,24 +517,34 @@ try_setup_point( struct lp_setup_context *setup,
>>       static void
>> +lp_setup_point_discard(struct lp_setup_context *setup,
>> +                       const float (*v0)[4])
>> +{
>> +}
>> +
>> +static void
>>   lp_setup_point(struct lp_setup_context *setup,
>>                  const float (*v0)[4])
>>   {
>> -   if (!try_setup_point( setup, v0 ))
>> +   if (!try_setup_point(setup, v0))
>>      {
> 
> Brace on same line as the if.
> 
> 
>>         if (!lp_setup_flush_and_restart(setup))
>>            return;
>>   -      if (!try_setup_point( setup, v0 ))
>> +      if (!try_setup_point(setup, v0))
>>            return;
>>      }
>>   }
>>       void
>> -lp_setup_choose_point( struct lp_setup_context *setup )
>> +lp_setup_choose_point(struct lp_setup_context *setup)
>>   {
>> -   setup->point = lp_setup_point;
>> +   if (setup->rasterizer_discard) {
>> +      setup->point = lp_setup_point_discard;
>> +   } else {
>> +      setup->point = lp_setup_point;
>> +   }
>>   }
>>     diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c
>> b/src/gallium/drivers/llvmpipe/lp_setup_tri.c
>> index 39755d6..cec6198 100644
>> --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c
>> +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c
>> @@ -1127,6 +1127,11 @@ static void triangle_cw(struct lp_setup_context
>> *setup,
>>                           const float (*v2)[4])
>>   {
>>      PIPE_ALIGN_VAR(16) struct fixed_position position;
>> +   struct llvmpipe_context *lp_context = (struct llvmpipe_context
>> *)setup->pipe;
>> +
>> +   if (lp_context->active_statistics_queries) {
>> +      lp_context->pipeline_statistics.c_primitives++;
>> +   }
>>        calc_fixed_position(setup, &position, v0, v1, v2);
>>   @@ -1148,6 +1153,11 @@ static void triangle_ccw(struct
>> lp_setup_context *setup,
>>                            const float (*v2)[4])
>>   {
>>      PIPE_ALIGN_VAR(16) struct fixed_position position;
>> +   struct llvmpipe_context *lp_context = (struct llvmpipe_context
>> *)setup->pipe;
>> +
>> +   if (lp_context->active_statistics_queries) {
>> +      lp_context->pipeline_statistics.c_primitives++;
>> +   }
>>        calc_fixed_position(setup, &position, v0, v1, v2);
>>   @@ -1166,8 +1176,7 @@ static void triangle_both(struct
>> lp_setup_context *setup,
>>      PIPE_ALIGN_VAR(16) struct fixed_position position;
>>      struct llvmpipe_context *lp_context = (struct llvmpipe_context
>> *)setup->pipe;
>>   -   if (lp_context->active_statistics_queries &&
>> -       !llvmpipe_rasterization_disabled(lp_context)) {
>> +   if (lp_context->active_statistics_queries) {
>>         lp_context->pipeline_statistics.c_primitives++;
>>      }
>>   @@ -1196,17 +1205,21 @@ static void triangle_both(struct
>> lp_setup_context *setup,
>>   }
>>     -static void triangle_nop( struct lp_setup_context *setup,
>> -              const float (*v0)[4],
>> -              const float (*v1)[4],
>> -              const float (*v2)[4] )
>> +static void triangle_noop(struct lp_setup_context *setup,
>> +                          const float (*v0)[4],
>> +                          const float (*v1)[4],
>> +                          const float (*v2)[4])
>>   {
>>   }
>>       void
>> -lp_setup_choose_triangle( struct lp_setup_context *setup )
>> +lp_setup_choose_triangle(struct lp_setup_context *setup)
>>   {
>> +   if (setup->rasterizer_discard) {
>> +      setup->triangle = triangle_noop;
>> +      return;
>> +   }
>>      switch (setup->cullmode) {
>>      case PIPE_FACE_NONE:
>>         setup->triangle = triangle_both;
>> @@ -1218,7 +1231,7 @@ lp_setup_choose_triangle( struct
>> lp_setup_context *setup )
>>         setup->triangle = setup->ccw_is_frontface ? triangle_cw :
>> triangle_ccw;
>>         break;
>>      default:
>> -      setup->triangle = triangle_nop;
>> +      setup->triangle = triangle_noop;
>>         break;
>>      }
>>   }
>> diff --git a/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c
>> b/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c
>> index 28a48d4..6675b20 100644
>> --- a/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c
>> +++ b/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c
>> @@ -571,7 +571,7 @@ lp_setup_pipeline_statistics(
>>         stats->gs_invocations;
>>      llvmpipe->pipeline_statistics.gs_primitives +=
>>         stats->gs_primitives;
>> -   if (!llvmpipe_rasterization_disabled(llvmpipe)) {
>> +   if (!setup->rasterizer_discard) {
>>         llvmpipe->pipeline_statistics.c_invocations +=
>>            stats->c_invocations;
>>      } else {
>> diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c
>> b/src/gallium/drivers/llvmpipe/lp_state_derived.c
>> index 3e75d44..4bcca90 100644
>> --- a/src/gallium/drivers/llvmpipe/lp_state_derived.c
>> +++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c
>> @@ -207,13 +207,27 @@ void llvmpipe_update_derived( struct
>> llvmpipe_context *llvmpipe )
>>                             LP_NEW_SAMPLER |
>>                             LP_NEW_SAMPLER_VIEW |
>>                             LP_NEW_OCCLUSION_QUERY))
>> -      llvmpipe_update_fs( llvmpipe );
>> +      llvmpipe_update_fs(llvmpipe);
>>   -   if (llvmpipe->dirty & (LP_NEW_RASTERIZER)) {
>> +   if (llvmpipe->dirty & (LP_NEW_FS |
>> +                          LP_NEW_FRAMEBUFFER |
>> +                          LP_NEW_RASTERIZER |
>> +                          LP_NEW_DEPTH_STENCIL_ALPHA)) {
>> +
>> +      /*
>> +       * 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
>> +       * FIXME: set rasterizer_discard in state tracker instead.
>> +       */
>> +      boolean null_fs = !llvmpipe->fs ||
>> +                        llvmpipe->fs->info.base.num_instructions <= 1;
>>         boolean discard =
>>            (llvmpipe->sample_mask & 1) == 0 ||
>> -         (llvmpipe->rasterizer ?
>> llvmpipe->rasterizer->rasterizer_discard : FALSE);
>> -
>> +         (llvmpipe->rasterizer ?
>> llvmpipe->rasterizer->rasterizer_discard : FALSE) ||
>> +         (null_fs &&
>> +          !llvmpipe->depth_stencil->depth.enabled &&
>> +          !llvmpipe->depth_stencil->stencil[0].enabled);
> 
> I like to put complex conditionals like this into a helper function
> where it can be broken up into a bunch of simpler if statements.  What
> do you think?
I like compact code :-).
That said, the plan is to get rid of most of it in the near future
anyway (by using explicit discard).

Roland

> 
> 
>>         lp_setup_set_rasterizer_discard(llvmpipe->setup, discard);
>>      }
>>   diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c
>> b/src/gallium/drivers/llvmpipe/lp_state_fs.c
>> index 91b68e7..b7e16f9 100644
>> --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
>> +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
>> @@ -2554,6 +2554,25 @@ generate_fragment(struct llvmpipe_context *lp,
>>      assert(builder);
>>      LLVMPositionBuilderAtEnd(builder, block);
>>   +   /*
>> +    * Must not count ps invocations if there's a null shader.
>> +    * (It would be ok to count with null shader if there's d/s tests,
>> +    * but only if there's d/s buffers too, which is different
>> +    * to implicit rasterization disable which must not depend
>> +    * on the d/s buffers.)
>> +    * Could use popcount on mask, but pixel accuracy is not required.
>> +    * Could disable if there's no stats query, but maybe not worth it.
>> +    */
>> +   if (shader->info.base.num_instructions > 1) {
>> +      LLVMValueRef invocs, val;
>> +      invocs = lp_jit_thread_data_invocations(gallivm, thread_data_ptr);
>> +      val = LLVMBuildLoad(builder, invocs, "");
>> +      val = LLVMBuildAdd(builder, val,
>> +                        
>> LLVMConstInt(LLVMInt64TypeInContext(gallivm->context), 1, 0),
>> +                         "invoc_count");
>> +      LLVMBuildStore(builder, val, invocs);
>> +   }
>> +
>>      /* code generated texture sampling */
>>      sampler = lp_llvm_sampler_soa_create(key->state);
>>   @@ -2843,14 +2862,6 @@ generate_variant(struct llvmpipe_context *lp,
>>            !shader->info.base.writes_samplemask
>>         ? TRUE : FALSE;
>>   -   /* if num_instructions == 1, it's a nop shader with only an END
>> instruction */
>> -   if ((shader->info.base.num_instructions <= 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);
>>      }
>> @@ -3471,18 +3482,4 @@ 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)
>> -{
>> -   /* if num_instructions == 1, it's a nop shader with only an END
>> instruction */
>> -   boolean null_fs = !lp->fs || lp->fs->info.base.num_instructions <= 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 2ddd851..28eccde 100644
>> --- a/src/gallium/drivers/llvmpipe/lp_state_fs.h
>> +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.h
>> @@ -98,7 +98,6 @@ struct lp_fragment_shader_variant
>>      struct lp_fragment_shader_variant_key key;
>>        boolean opaque;
>> -   uint8_t ps_inv_multiplier;
>>        struct gallivm_state *gallivm;
>>   @@ -150,8 +149,4 @@ 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_ */
>>
> 



More information about the mesa-dev mailing list