svga: avoid emitting redundant SetShaderResource command
authorCharmaine Lee <charmainel@vmware.com>
Wed, 17 Aug 2016 23:50:23 +0000 (16:50 -0700)
committerBrian Paul <brianp@vmware.com>
Fri, 26 Aug 2016 12:19:52 +0000 (06:19 -0600)
Tested with Lightsmark2008, Heaven, MTT piglit, glretrace, viewperf, conform.

Reviewed-by: Brian Paul <brianp@vmware.com>
src/gallium/drivers/svga/svga_context.c
src/gallium/drivers/svga/svga_context.h
src/gallium/drivers/svga/svga_pipe_sampler.c
src/gallium/drivers/svga/svga_state_sampler.c

index 475b2b53f5eeebd7da5488866c64deff4e947c16..ffecef59eb9e1525f8503af463d6432ab5b3cc6f 100644 (file)
@@ -226,6 +226,8 @@ struct pipe_context *svga_context_create(struct pipe_screen *screen,
       sizeof(svga->state.hw_draw.num_samplers));
    memset(&svga->state.hw_draw.num_sampler_views, 0,
       sizeof(svga->state.hw_draw.num_sampler_views));
+   memset(svga->state.hw_draw.sampler_views, 0,
+          sizeof(svga->state.hw_draw.sampler_views));
    svga->state.hw_draw.num_views = 0;
 
    /* Initialize the shader pointers */
index a5ec78c9093ad9388313b69a0d6f1125f1311084..a635ef1fc9529e14b7519185b4cf2c83c16c5609 100644 (file)
@@ -377,12 +377,15 @@ struct svga_hw_draw_state
    unsigned num_samplers[PIPE_SHADER_TYPES];
    SVGA3dSamplerId samplers[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
 
+   unsigned num_sampler_views[PIPE_SHADER_TYPES];
+   struct pipe_sampler_view
+      *sampler_views[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
+
    unsigned num_rendertargets;
    struct pipe_surface *rtv[SVGA3D_MAX_RENDER_TARGETS];
    struct pipe_surface *dsv;
 
    /* used for rebinding */
-   unsigned num_sampler_views[PIPE_SHADER_TYPES];
    unsigned default_constbuf_size[PIPE_SHADER_TYPES];
 };
 
index ae19b7ee0a6ff499c54480fbc5a5d996ba002122..59609b84e205d5bd72c589ba4888bbb910afe390 100644 (file)
@@ -544,9 +544,20 @@ done:
 void
 svga_cleanup_sampler_state(struct svga_context *svga)
 {
+   unsigned shader;
+
    if (!svga_have_vgpu10(svga))
       return;
 
+   for (shader = 0; shader <= PIPE_SHADER_GEOMETRY; shader++) {
+      unsigned i;
+
+      for (i = 0; i < svga->state.hw_draw.num_sampler_views[shader]; i++) {
+         pipe_sampler_view_release(&svga->pipe,
+                                   &svga->state.hw_draw.sampler_views[shader][i]);
+      }
+   }
+   
    /* free polygon stipple state */
    if (svga->polygon_stipple.sampler) {
       svga->pipe.delete_sampler_state(&svga->pipe, svga->polygon_stipple.sampler);
index 216ab8180fbb246312b0ca9dd290e9a8716fcf2a..420a5667efb0fb929bd1b11fd4829831d4979191 100644 (file)
@@ -205,6 +205,7 @@ update_sampler_resources(struct svga_context *svga, unsigned dirty)
    for (shader = PIPE_SHADER_VERTEX; shader <= PIPE_SHADER_GEOMETRY; shader++) {
       SVGA3dShaderResourceViewId ids[PIPE_MAX_SAMPLERS];
       struct svga_winsys_surface *surfaces[PIPE_MAX_SAMPLERS];
+      struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
       unsigned count;
       unsigned nviews;
       unsigned i;
@@ -213,10 +214,9 @@ update_sampler_resources(struct svga_context *svga, unsigned dirty)
       for (i = 0; i < count; i++) {
          struct svga_pipe_sampler_view *sv =
             svga_pipe_sampler_view(svga->curr.sampler_views[shader][i]);
-         struct svga_winsys_surface *surface;
 
          if (sv) {
-            surface = svga_resource_handle(sv->base.texture);
+            surfaces[i] = svga_resource_handle(sv->base.texture);
 
             ret = svga_validate_pipe_sampler_view(svga, sv);
             if (ret != PIPE_OK)
@@ -224,39 +224,19 @@ update_sampler_resources(struct svga_context *svga, unsigned dirty)
 
             assert(sv->id != SVGA3D_INVALID_ID);
             ids[i] = sv->id;
+            sampler_views[i] = &sv->base;
          }
          else {
-            surface = NULL;
+            surfaces[i] = NULL;
             ids[i] = SVGA3D_INVALID_ID;
+            sampler_views[i] = NULL;
          }
-         surfaces[i] = surface;
       }
 
-      for (; i < ARRAY_SIZE(ids); i++) {
+      for (; i < svga->state.hw_draw.num_sampler_views[shader]; i++) {
          ids[i] = SVGA3D_INVALID_ID;
          surfaces[i] = NULL;
-      }
-
-      if (shader == PIPE_SHADER_FRAGMENT) {
-         /* Handle polygon stipple sampler view */
-         if (svga->curr.rast->templ.poly_stipple_enable) {
-            const unsigned unit = svga->state.hw_draw.fs->pstipple_sampler_unit;
-            struct svga_pipe_sampler_view *sv =
-               svga->polygon_stipple.sampler_view;
-
-            assert(sv);
-            if (!sv) {
-               return PIPE_OK;  /* probably out of memory */
-            }
-
-            ret = svga_validate_pipe_sampler_view(svga, sv);
-            if (ret != PIPE_OK)
-               return ret;
-
-            ids[unit] = sv->id;
-            surfaces[unit] = svga_resource_handle(sv->base.texture);
-            count = MAX2(count, unit+1);
-         }
+         sampler_views[i] = NULL;
       }
 
       /* Number of ShaderResources that need to be modified. This includes
@@ -264,20 +244,53 @@ update_sampler_resources(struct svga_context *svga, unsigned dirty)
        */
       nviews = MAX2(svga->state.hw_draw.num_sampler_views[shader], count);
       if (nviews > 0) {
-         ret = SVGA3D_vgpu10_SetShaderResources(svga->swc,
+         if (count != svga->state.hw_draw.num_sampler_views[shader] ||
+             memcmp(sampler_views, svga->state.hw_draw.sampler_views[shader],
+                    count * sizeof(sampler_views[0])) != 0) {
+            ret = SVGA3D_vgpu10_SetShaderResources(svga->swc,
                                                 svga_shader_type(shader),
                                                 0, /* startView */
                                                 nviews,
                                                 ids,
                                                 surfaces);
-         if (ret != PIPE_OK)
-            return ret;
-      }
+            if (ret != PIPE_OK)
+               return ret;
 
-      /* Number of sampler views enabled in the device */
-      svga->state.hw_draw.num_sampler_views[shader] = count;
+            /* Save referenced sampler views in the hw draw state.  */
+            svga->state.hw_draw.num_sampler_views[shader] = count;
+            for (i = 0; i < nviews; i++) {
+               pipe_sampler_view_reference(
+                  &svga->state.hw_draw.sampler_views[shader][i],
+                  sampler_views[i]);
+            }
+         }
+      }
    }
 
+   /* Handle polygon stipple sampler view */
+   if (svga->curr.rast->templ.poly_stipple_enable) {
+      const unsigned unit = svga->state.hw_draw.fs->pstipple_sampler_unit;
+      struct svga_pipe_sampler_view *sv = svga->polygon_stipple.sampler_view;
+      struct svga_winsys_surface *surface;
+
+      assert(sv);
+      if (!sv) {
+         return PIPE_OK;  /* probably out of memory */
+      }
+
+      ret = svga_validate_pipe_sampler_view(svga, sv);
+      if (ret != PIPE_OK)
+         return ret;
+
+      surface = svga_resource_handle(sv->base.texture);
+      ret = SVGA3D_vgpu10_SetShaderResources(
+               svga->swc,
+               svga_shader_type(PIPE_SHADER_FRAGMENT),
+               unit, /* startView */
+               1,
+               &sv->id,
+               &surface);
+   }
    return ret;
 }