svga: fix cubemap array rendering with backed surface view
authorCharmaine Lee <charmainel@vmware.com>
Thu, 19 Oct 2017 23:03:44 +0000 (16:03 -0700)
committerBrian Paul <brianp@vmware.com>
Mon, 10 Sep 2018 19:07:30 +0000 (13:07 -0600)
This patch fixes the layer index when rendering to a
backed surface view of a cubemap array.

Fixes piglit test fbo-generatemipmap-cubemap array.

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

index 45badae6ce823904d848039450bec7242c6a5f95..cf2d12d02e2a57adef73dff6faba869bac658dd7 100644 (file)
 
 static void svga_mark_surface_dirty(struct pipe_surface *surf);
 
+void
+svga_texture_copy_region(struct svga_context *svga,
+                         struct svga_winsys_surface *src_handle,
+                         unsigned srcSubResource,
+                         unsigned src_x, unsigned src_y, unsigned src_z,
+                         struct svga_winsys_surface *dst_handle,
+                         unsigned dstSubResource,
+                         unsigned dst_x, unsigned dst_y, unsigned dst_z,
+                         unsigned width, unsigned height, unsigned depth)
+{
+   enum pipe_error ret;
+   SVGA3dCopyBox box;
+
+   assert(svga_have_vgpu10(svga));
+
+   box.x = dst_x;
+   box.y = dst_y;
+   box.z = dst_z;
+   box.w = width;
+   box.h = height;
+   box.d = depth;
+   box.srcx = src_x;
+   box.srcy = src_y;
+   box.srcz = src_z;
+
+   ret = SVGA3D_vgpu10_PredCopyRegion(svga->swc,
+                                      dst_handle, dstSubResource,
+                                      src_handle, srcSubResource, &box);
+   if (ret != PIPE_OK) {
+      svga_context_flush(svga, NULL);
+      ret = SVGA3D_vgpu10_PredCopyRegion(svga->swc,
+                                         dst_handle, dstSubResource,
+                                         src_handle, srcSubResource, &box);
+      assert(ret = PIPE_OK);
+   }
+}
+
+
 void
 svga_texture_copy_handle(struct svga_context *svga,
                          struct svga_winsys_surface *src_handle,
@@ -350,7 +388,8 @@ svga_create_surface_view(struct pipe_context *pipe,
                flags |= SVGA3D_SURFACE_CUBEMAP;
             break;
          case PIPE_TEXTURE_CUBE_ARRAY:
-            flags |= SVGA3D_SURFACE_CUBEMAP | SVGA3D_SURFACE_ARRAY;
+            if (nlayers % 6 == 0)
+               flags |= SVGA3D_SURFACE_CUBEMAP | SVGA3D_SURFACE_ARRAY;
             break;   
          default:
             break;
@@ -467,6 +506,7 @@ create_backed_surface_view(struct svga_context *svga, struct svga_surface *s)
 
       switch (tex->b.b.target) {
       case PIPE_TEXTURE_CUBE:
+      case PIPE_TEXTURE_CUBE_ARRAY:
       case PIPE_TEXTURE_1D_ARRAY:
       case PIPE_TEXTURE_2D_ARRAY:
          layer = s->base.u.tex.first_layer;
@@ -756,13 +796,19 @@ svga_propagate_surface(struct svga_context *svga, struct pipe_surface *surf,
       unsigned zslice, layer;
       unsigned nlayers = 1;
       unsigned i;
+      unsigned numMipLevels = tex->b.b.last_level + 1;
+      unsigned srcLevel = s->real_level;
+      unsigned dstLevel = surf->u.tex.level;
+      unsigned width = u_minify(tex->b.b.width0, dstLevel);
+      unsigned height = u_minify(tex->b.b.height0, dstLevel);
 
       if (surf->texture->target == PIPE_TEXTURE_CUBE) {
          zslice = 0;
          layer = surf->u.tex.first_layer;
       }
       else if (surf->texture->target == PIPE_TEXTURE_1D_ARRAY ||
-               surf->texture->target == PIPE_TEXTURE_2D_ARRAY) {
+               surf->texture->target == PIPE_TEXTURE_2D_ARRAY ||
+               surf->texture->target == PIPE_TEXTURE_CUBE_ARRAY) {
          zslice = 0;
          layer = surf->u.tex.first_layer;
          nlayers = surf->u.tex.last_layer - surf->u.tex.first_layer + 1;
@@ -775,16 +821,32 @@ svga_propagate_surface(struct svga_context *svga, struct pipe_surface *surf,
       SVGA_DBG(DEBUG_VIEWS,
                "Propagate surface %p to resource %p, level %u\n",
                surf, tex, surf->u.tex.level);
-      for (i = 0; i < nlayers; i++) {
-         svga_texture_copy_handle(svga,
-                                  s->handle, 0, 0, 0, s->real_level,
-                                  s->real_layer + i,
-                                  tex->handle, 0, 0, zslice, surf->u.tex.level,
-                                  layer + i,
-                                  u_minify(tex->b.b.width0, surf->u.tex.level),
-                                  u_minify(tex->b.b.height0, surf->u.tex.level),
-                                  1);
-         svga_define_texture_level(tex, layer + i, surf->u.tex.level);
+
+      if (svga_have_vgpu10(svga)) {
+         unsigned srcSubResource, dstSubResource;
+
+         for (i = 0; i < nlayers; i++) {
+            srcSubResource = (s->real_layer + i) * numMipLevels + srcLevel;
+            dstSubResource = (layer + i) * numMipLevels + dstLevel;
+
+            svga_texture_copy_region(svga,
+                                     s->handle, srcSubResource, 0, 0, 0,
+                                     tex->handle, dstSubResource, 0, 0, zslice,
+                                     width, height, 1);
+            svga_define_texture_level(tex, layer + i, dstLevel);
+         }
+      }
+      else {
+         for (i = 0; i < nlayers; i++) {
+            svga_texture_copy_handle(svga,
+                                     s->handle, 0, 0, 0, srcLevel,
+                                     s->real_layer + i,
+                                     tex->handle, 0, 0, zslice, dstLevel,
+                                     layer + i,
+                                     width, height, 1);
+        
+            svga_define_texture_level(tex, layer + i, dstLevel);
+         }
       }
 
       /* Sync the surface view age with the texture age */
index b1a7728084df477d4bbb668792d9ec195e1e4a17..587632d0eb6d63f1f988054f242bdf5cb2779df5 100644 (file)
@@ -105,6 +105,15 @@ svga_texture_view_surface(struct svga_context *svga,
                           boolean cacheable,
                           struct svga_host_surface_cache_key *key); /* OUT */
 
+void
+svga_texture_copy_region(struct svga_context *svga,
+                         struct svga_winsys_surface *src_handle,
+                         unsigned srcSubResource,
+                         unsigned src_x, unsigned src_y, unsigned src_z,
+                         struct svga_winsys_surface *dst_handle,
+                         unsigned dstSubResource,
+                         unsigned dst_x, unsigned dst_y, unsigned dst_z,
+                         unsigned width, unsigned height, unsigned depth);
 
 void
 svga_texture_copy_handle(struct svga_context *svga,