svga: flush our command buffer after the 8th distinct render target
authorKeith Whitwell <keithw@vmware.com>
Fri, 27 Nov 2009 12:19:28 +0000 (12:19 +0000)
committerKeith Whitwell <keithw@vmware.com>
Fri, 27 Nov 2009 12:24:57 +0000 (12:24 +0000)
This helps improve the surface cache behaviour in the face of the
large number of single-use render targets generated by EXA and the xorg
state tracker.  Without this we can reference hundreds of individual
render targets from a command buffer, which leaves little scope for
sharing or reuse of those targets.

Flushing early means we can start reusing textures much sooner.

This shouldn't have much effect on normal 3d rendering as it's pretty
rare to have a command buffer with >8 different render targets in that
world.

src/gallium/drivers/svga/svga_context.c
src/gallium/drivers/svga/svga_context.h
src/gallium/drivers/svga/svga_state_framebuffer.c

index 73233957f36eff30e1c572625cf4d77fbb02f3e2..c3de12b4a39861f93739840b8d6b5a64ace33b11 100644 (file)
@@ -230,7 +230,9 @@ void svga_context_flush( struct svga_context *svga,
                          struct pipe_fence_handle **pfence )
 {
    struct svga_screen *svgascreen = svga_screen(svga->pipe.screen);
-   
+
+   svga->curr.nr_fbs = 0;
+
    /* Unmap upload manager buffers: 
     */
    u_upload_flush(svga->upload_vb);
index 9a3e92fd8d132d41e27429ec489614d0e3a1fab5..e650a251d1975a134754702c5302f58fd56c1603 100644 (file)
@@ -191,6 +191,11 @@ struct svga_state
    struct pipe_framebuffer_state framebuffer;
    float depthscale;
 
+   /* Hack to limit the number of different render targets between
+    * flushes.  Helps avoid blowing out our surface cache in EXA.
+    */
+   int nr_fbs;
+
    struct pipe_poly_stipple poly_stipple;
    struct pipe_scissor_state scissor;
    struct pipe_blend_color blend_color;
index 7d7f93d8e3c373407f7f620ac0072f3d072425ce..cfdcae4ee4a0d37ead162a15a975239740eaec9a 100644 (file)
@@ -54,6 +54,9 @@ static int emit_framebuffer( struct svga_context *svga,
    
    for(i = 0; i < PIPE_MAX_COLOR_BUFS; ++i) {
       if (curr->cbufs[i] != hw->cbufs[i]) {
+         if (svga->curr.nr_fbs++ > 8)
+            return PIPE_ERROR_OUT_OF_MEMORY;
+
          ret = SVGA3D_SetRenderTarget(svga->swc, SVGA3D_RT_COLOR0 + i, curr->cbufs[i]);
          if (ret != PIPE_OK)
             return ret;