svga: remove const qualifier from SVGA3D_vgpu10_GenMips() prototype
[mesa.git] / src / gallium / drivers / svga / svga_state_framebuffer.c
index 9abacc9fa204451f859822a39a4257b9a2e12b8b..b1362a981689ffe0ca183db9ca5a1ea159f0fc5f 100644 (file)
@@ -168,8 +168,9 @@ emit_fb_vgpu10(struct svga_context *svga)
    struct pipe_framebuffer_state *curr = &svga->curr.framebuffer;
    struct pipe_framebuffer_state *hw = &svga->state.hw_clear.framebuffer;
    const unsigned num_color = MAX2(curr->nr_cbufs, hw->nr_cbufs);
+   int last_rtv = -1;
    unsigned i;
-   enum pipe_error ret;
+   enum pipe_error ret = PIPE_OK;
 
    assert(svga_have_vgpu10(svga));
 
@@ -187,6 +188,7 @@ emit_fb_vgpu10(struct svga_context *svga)
          }
 
          assert(svga_surface(rtv[i])->view_id != SVGA3D_INVALID_ID);
+         last_rtv = i;
       }
       else {
          rtv[i] = NULL;
@@ -196,7 +198,7 @@ emit_fb_vgpu10(struct svga_context *svga)
    /* Setup depth stencil view */
    if (curr->zsbuf) {
       dsv = svga_validate_surface_view(svga, svga_surface(curr->zsbuf));
-      if (dsv == NULL) {
+      if (!dsv) {
          return PIPE_ERROR_OUT_OF_MEMORY;
       }
    }
@@ -204,28 +206,41 @@ 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;
+
+      /* number of render targets sent to the device, not including trailing
+       * unbound render targets.
+       */
+      svga->state.hw_draw.num_rendertargets = last_rtv + 1;
+      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;
@@ -278,8 +293,7 @@ svga_reemit_framebuffer_bindings(struct svga_context *svga)
 enum pipe_error
 svga_rebind_framebuffer_bindings(struct svga_context *svga)
 {
-   const struct svga_screen *ss = svga_screen(svga->pipe.screen);
-   struct pipe_framebuffer_state *hw = &svga->state.hw_clear.framebuffer;
+   struct svga_hw_draw_state *hw = &svga->state.hw_draw;
    unsigned i;
    enum pipe_error ret;
 
@@ -288,10 +302,10 @@ svga_rebind_framebuffer_bindings(struct svga_context *svga)
    if (!svga->rebind.flags.rendertargets)
       return PIPE_OK;
 
-   for (i = 0; i < ss->max_color_buffers; i++) {
-      if (hw->cbufs[i]) {
+   for (i = 0; i < hw->num_rendertargets; i++) {
+      if (hw->rtv[i]) {
          ret = svga->swc->resource_rebind(svga->swc,
-                                          svga_surface(hw->cbufs[i])->handle,
+                                          svga_surface(hw->rtv[i])->handle,
                                           NULL,
                                           SVGA_RELOC_WRITE);
          if (ret != PIPE_OK)
@@ -299,9 +313,9 @@ svga_rebind_framebuffer_bindings(struct svga_context *svga)
       }
    }
 
-   if (hw->zsbuf) {
+   if (hw->dsv) {
       ret = svga->swc->resource_rebind(svga->swc,
-                                       svga_surface(hw->zsbuf)->handle,
+                                       svga_surface(hw->dsv)->handle,
                                        NULL,
                                        SVGA_RELOC_WRITE);
       if (ret != PIPE_OK)