svga: avoid emitting redundant DXSetRenderTargets command
authorCharmaine Lee <charmainel@vmware.com>
Tue, 28 Jun 2016 23:09:59 +0000 (16:09 -0700)
committerBrian Paul <brianp@vmware.com>
Tue, 5 Jul 2016 22:58:29 +0000 (16:58 -0600)
Tested with Lightsmark2008, MTT piglit, glretrace, conform.

Reviewed-by: Sinclair Yeh <syeh@vmware.com>
Reviewed-by: Brian Paul <brianp@vmware.com>
src/gallium/drivers/svga/svga_context.h
src/gallium/drivers/svga/svga_state_framebuffer.c

index 4f1c07ec4b1af21f50ccab61a04c99f123b4b999..49c6030325f4f51ace47a3063397db1387b09d79 100644 (file)
@@ -368,6 +368,10 @@ struct svga_hw_draw_state
    unsigned num_samplers[PIPE_SHADER_TYPES];
    SVGA3dSamplerId samplers[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 4b0400bf80a13ff197abcd3a2d39fa778265f052..12efc4960d5b04ebae86eb1ffd62eb384898d03f 100644 (file)
@@ -169,7 +169,7 @@ emit_fb_vgpu10(struct svga_context *svga)
    struct pipe_framebuffer_state *hw = &svga->state.hw_clear.framebuffer;
    const unsigned num_color = MAX2(curr->nr_cbufs, hw->nr_cbufs);
    unsigned i;
-   enum pipe_error ret;
+   enum pipe_error ret = PIPE_OK;
 
    assert(svga_have_vgpu10(svga));
 
@@ -204,28 +204,38 @@ emit_fb_vgpu10(struct svga_context *svga)
       dsv = NULL;
    }
 
-   ret = SVGA3D_vgpu10_SetRenderTargets(svga->swc, num_color, rtv, dsv);
-   if (ret != PIPE_OK)
-      return ret;
+   /* avoid emitting redundant SetRenderTargets command */
+   if ((num_color != svga->state.hw_draw.num_rendertargets) ||
+       (dsv != svga->state.hw_draw.dsv) ||
+       memcmp(rtv, svga->state.hw_draw.rtv, num_color * sizeof(rtv[0]))) {
 
-   for (i = 0; i < ss->max_color_buffers; i++) {
-      if (hw->cbufs[i] != curr->cbufs[i]) {
-         /* propagate the backed view surface before unbinding it */
-         if (hw->cbufs[i] && svga_surface(hw->cbufs[i])->backed) {
-            svga_propagate_surface(svga,
-                                   &svga_surface(hw->cbufs[i])->backed->base);
+      ret = SVGA3D_vgpu10_SetRenderTargets(svga->swc, num_color, rtv, dsv);
+      if (ret != PIPE_OK)
+         return ret;
+
+      svga->state.hw_draw.num_rendertargets = num_color;
+      svga->state.hw_draw.dsv = dsv;
+      memcpy(svga->state.hw_draw.rtv, rtv, num_color * sizeof(rtv[0]));
+    
+      for (i = 0; i < ss->max_color_buffers; i++) {
+         if (hw->cbufs[i] != curr->cbufs[i]) {
+            /* propagate the backed view surface before unbinding it */
+            if (hw->cbufs[i] && svga_surface(hw->cbufs[i])->backed) {
+               svga_propagate_surface(svga,
+                                      &svga_surface(hw->cbufs[i])->backed->base);
+            }
+            pipe_surface_reference(&hw->cbufs[i], curr->cbufs[i]);
          }
-         pipe_surface_reference(&hw->cbufs[i], curr->cbufs[i]);
       }
-   }
-   hw->nr_cbufs = curr->nr_cbufs;
+      hw->nr_cbufs = curr->nr_cbufs;
 
-   if (hw->zsbuf != curr->zsbuf) {
-      /* propagate the backed view surface before unbinding it */
-      if (hw->zsbuf && svga_surface(hw->zsbuf)->backed) {
-         svga_propagate_surface(svga, &svga_surface(hw->zsbuf)->backed->base);
+      if (hw->zsbuf != curr->zsbuf) {
+         /* propagate the backed view surface before unbinding it */
+         if (hw->zsbuf && svga_surface(hw->zsbuf)->backed) {
+            svga_propagate_surface(svga, &svga_surface(hw->zsbuf)->backed->base);
+         }
+         pipe_surface_reference(&hw->zsbuf, curr->zsbuf);
       }
-      pipe_surface_reference(&hw->zsbuf, curr->zsbuf);
    }
 
    return ret;