svga: fix backed surface view regression
authorCharmaine Lee <charmainel@vmware.com>
Thu, 13 Aug 2015 22:08:22 +0000 (15:08 -0700)
committerBrian Paul <brianp@vmware.com>
Wed, 2 Sep 2015 19:22:42 +0000 (13:22 -0600)
Commit b9ba8492 removes an unneeded pipe_surface_release() from
st_render_texture() and exposes a bug in the backed surface view
creation.  Currently a backed surface view for a conflicted surface view
is created at framebuffer emit time. But if shader sampler views are changed
but framebuffer surface views remain unchanged, emit_framebuffer() will not
be called and conflicted surface views will not be detected.

To fix this, also check for conflicted surface views when setting sampler
views. If there is any conflicted surface views, enable the
framebuffer dirty bit so that the framebuffer emit code has a chance to
create a backed surface view for the conflicted surface view.

Fix cinebench-r11-test regression.

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

index bb18f5a8247f62cc871e686d1cc6dbe3e81ebef7..ab84ed396024566d2a5b7b5c7caaddc24aa443a4 100644 (file)
@@ -35,6 +35,8 @@
 #include "svga_cmd.h"
 #include "svga_debug.h"
 #include "svga_resource_texture.h"
+#include "svga_surface.h"
+#include "svga_sampler_view.h"
 
 
 static inline unsigned
@@ -445,7 +447,31 @@ svga_set_sampler_views(struct pipe_context *pipe,
       svga->dirty |= SVGA_NEW_TEXTURE_FLAGS;
       svga->curr.tex_flags.flag_1d = flag_1d;
       svga->curr.tex_flags.flag_srgb = flag_srgb;
-   }  
+   }
+
+   /* Check if any of the sampler view resources collide with the framebuffer
+    * color buffers or depth stencil resource. If so, enable the NEW_FRAME_BUFFER
+    * dirty bit so that emit_framebuffer can be invoked to create backed view
+    * for the conflicted surface view.
+    */
+   for (i = 0; i < svga->curr.framebuffer.nr_cbufs; i++) {
+      struct svga_surface *s = svga_surface(svga->curr.framebuffer.cbufs[i]);
+      if (s) {
+         if (svga_check_sampler_view_resource_collision(svga, s->handle, shader)) {
+            svga->dirty |= SVGA_NEW_FRAME_BUFFER;
+            break;
+         }
+      }
+   }
+
+   if (svga->curr.framebuffer.zsbuf) {
+      struct svga_surface *s = svga_surface(svga->curr.framebuffer.zsbuf);
+      if (s) {
+         if (svga_check_sampler_view_resource_collision(svga, s->handle, shader)) {
+            svga->dirty |= SVGA_NEW_FRAME_BUFFER;
+         }
+      }
+   }
 }
 
 
index acd7ae0ca24d582a99b1ae0b73b11e3fd064c08b..4ca7fb781a999fa87dd556f6f3437befb1a8f7d0 100644 (file)
@@ -100,6 +100,6 @@ svga_sampler_view_reference(struct svga_sampler_view **ptr, struct svga_sampler_
 
 boolean
 svga_check_sampler_view_resource_collision(struct svga_context *svga,
-                                           struct svga_winsys_surface *res);
-
+                                           struct svga_winsys_surface *res,
+                                           unsigned shader);
 #endif
index 1c6913e4a2666fb5b6531bea226413ec5a5e426b..611d2c6102f9158aa06b339f3d06fee09023383d 100644 (file)
@@ -63,23 +63,22 @@ svga_resource_handle(struct pipe_resource *res)
  */
 boolean
 svga_check_sampler_view_resource_collision(struct svga_context *svga,
-                                           struct svga_winsys_surface *res)
+                                           struct svga_winsys_surface *res,
+                                           unsigned shader)
 {
    struct pipe_screen *screen = svga->pipe.screen;
-   unsigned shader, i;
+   unsigned i;
 
    if (svga_screen(screen)->debug.no_surface_view) {
       return FALSE;
    }
 
-   for (shader = PIPE_SHADER_VERTEX; shader <= PIPE_SHADER_GEOMETRY; shader++) {
-      for (i = 0; i < svga->curr.num_sampler_views[shader]; i++) {
-         struct svga_pipe_sampler_view *sv =
-            svga_pipe_sampler_view(svga->curr.sampler_views[shader][i]);
+   for (i = 0; i < svga->curr.num_sampler_views[shader]; i++) {
+      struct svga_pipe_sampler_view *sv =
+         svga_pipe_sampler_view(svga->curr.sampler_views[shader][i]);
 
-         if (sv && res == svga_resource_handle(sv->base.texture)) {
-            return TRUE;
-         }
+      if (sv && res == svga_resource_handle(sv->base.texture)) {
+         return TRUE;
       }
    }
 
index 79981dcf5ff1b95723437bf57d8ddb24f2219e66..4b0f9417c3273c06723906642aeaa3ef907e4ce3 100644 (file)
@@ -377,6 +377,7 @@ svga_validate_surface_view(struct svga_context *svga, struct svga_surface *s)
 {
    enum pipe_error ret = PIPE_OK;
    int try;
+   unsigned shader;
 
    assert(svga_have_vgpu10(svga));
 
@@ -388,11 +389,14 @@ svga_validate_surface_view(struct svga_context *svga, struct svga_surface *s)
     * associated resource. We will then use the cloned surface view for
     * render target.
     */
-   if (svga_check_sampler_view_resource_collision(svga, s->handle)) {
-      SVGA_DBG(DEBUG_VIEWS,
-               "same resource used in shaderResource and renderTarget 0x%x\n",
-               s->handle);
-      s = create_backed_surface_view(svga, s);
+   for (shader = PIPE_SHADER_VERTEX; shader <= PIPE_SHADER_GEOMETRY; shader++) {
+      if (svga_check_sampler_view_resource_collision(svga, s->handle, shader)) {
+         SVGA_DBG(DEBUG_VIEWS,
+                  "same resource used in shaderResource and renderTarget 0x%x\n",
+                  s->handle);
+         s = create_backed_surface_view(svga, s);
+         break;
+      }
    }
 
    if (s->view_id == SVGA3D_INVALID_ID) {