tu: Implement fallback linear staging blit for CopyImage
[mesa.git] / src / gallium / state_trackers / dri / drisw.c
index e3fb3f1b9254fa89fec0c14e5b815cdb16e3b2d8..4afa69f891d1e64077af784e7eb1329eda79de5e 100644 (file)
@@ -138,6 +138,9 @@ get_image_shm(__DRIdrawable *dPriv, int x, int y, int width, int height,
    if (!res->screen->resource_get_handle(res->screen, NULL, res, &whandle, PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE))
       return FALSE;
 
+   if (loader->base.version > 5 && loader->getImageShm2)
+      return loader->getImageShm2(dPriv, x, y, width, height, whandle.handle, dPriv->loaderPrivate);
+
    loader->getImageShm(dPriv, x, y, width, height, whandle.handle, dPriv->loaderPrivate);
    return TRUE;
 }
@@ -251,6 +254,13 @@ drisw_swap_buffers(__DRIdrawable *dPriv)
 
       ctx->st->flush(ctx->st, ST_FLUSH_FRONT, NULL, NULL, NULL);
 
+      if (drawable->stvis.samples > 1) {
+         /* Resolve the back buffer. */
+         dri_pipe_blit(ctx->st->pipe,
+                       drawable->textures[ST_ATTACHMENT_BACK_LEFT],
+                       drawable->msaa_textures[ST_ATTACHMENT_BACK_LEFT]);
+      }
+
       drisw_copy_to_front(dPriv, ptex);
    }
 }
@@ -289,6 +299,12 @@ drisw_flush_frontbuffer(struct dri_context *ctx,
    if (!ctx)
       return;
 
+   if (drawable->stvis.samples > 1) {
+      /* Resolve the front buffer. */
+      dri_pipe_blit(ctx->st->pipe,
+                    drawable->textures[ST_ATTACHMENT_FRONT_LEFT],
+                    drawable->msaa_textures[ST_ATTACHMENT_FRONT_LEFT]);
+   }
    ptex = drawable->textures[statt];
 
    if (ptex) {
@@ -324,8 +340,10 @@ drisw_allocate_textures(struct dri_context *stctx,
 
    /* remove outdated textures */
    if (resized) {
-      for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
+      for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
          pipe_resource_reference(&drawable->textures[i], NULL);
+         pipe_resource_reference(&drawable->msaa_textures[i], NULL);
+      }
    }
 
    memset(&templ, 0, sizeof(templ));
@@ -348,13 +366,15 @@ drisw_allocate_textures(struct dri_context *stctx,
 
       /* if we don't do any present, no need for display targets */
       if (statts[i] != ST_ATTACHMENT_DEPTH_STENCIL && !screen->swrast_no_present)
-         bind |= PIPE_BIND_DISPLAY_TARGET;
+         bind |= PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_LINEAR;
 
       if (format == PIPE_FORMAT_NONE)
          continue;
 
       templ.format = format;
       templ.bind = bind;
+      templ.nr_samples = 0;
+      templ.nr_storage_samples = 0;
 
       if (statts[i] == ST_ATTACHMENT_FRONT_LEFT &&
           screen->base.screen->resource_create_front &&
@@ -364,6 +384,19 @@ drisw_allocate_textures(struct dri_context *stctx,
       } else
          drawable->textures[statts[i]] =
             screen->base.screen->resource_create(screen->base.screen, &templ);
+
+      if (drawable->stvis.samples > 1) {
+         templ.bind = templ.bind &
+            ~(PIPE_BIND_SCANOUT | PIPE_BIND_SHARED | PIPE_BIND_DISPLAY_TARGET);
+         templ.nr_samples = drawable->stvis.samples;
+         templ.nr_storage_samples = drawable->stvis.samples;
+         drawable->msaa_textures[statts[i]] =
+            screen->base.screen->resource_create(screen->base.screen, &templ);
+
+         dri_pipe_blit(stctx->st->pipe,
+                       drawable->msaa_textures[statts[i]],
+                       drawable->textures[statts[i]]);
+      }
    }
 
    drawable->old_w = width;