Mesa (master): st/mesa: make generic CopyPixels path work with MSAA visuals

Marek Olšák mareko at kemper.freedesktop.org
Thu Jun 13 01:56:17 UTC 2013


Module: Mesa
Branch: master
Commit: 526ebfa278554f167ba02377a3da672551d58b25
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=526ebfa278554f167ba02377a3da672551d58b25

Author: Marek Olšák <maraeo at gmail.com>
Date:   Fri May 31 20:26:39 2013 +0200

st/mesa: make generic CopyPixels path work with MSAA visuals

We have to use pipe->blit, not resource_copy_region, so that the read buffer
is resolved if it's multisampled. I also removed the CPU-based copying,
which just did format conversion (obsoleted by the blit).

Also, the layer/slice/face of the read buffer is taken into account (this was
ignored).

Last but not least, the format choosing is improved to take float and integer
read buffers into account.

Reviewed-by: Brian Paul <brianp at vmware.com>

---

 src/mesa/state_tracker/st_cb_drawpixels.c |  162 +++++++++++++----------------
 1 files changed, 70 insertions(+), 92 deletions(-)

diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index eb75500..1c26315 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -1474,10 +1474,9 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
    struct pipe_sampler_view *sv[2];
    int num_sampler_view = 1;
    GLfloat *color;
-   enum pipe_format srcFormat, texFormat;
+   enum pipe_format srcFormat;
    GLboolean invertTex = GL_FALSE;
    GLint readX, readY, readW, readH;
-   GLuint sample_count;
    struct gl_pixelstore_attrib pack = ctx->DefaultPacking;
    struct st_fp_variant *fpv;
 
@@ -1539,35 +1538,51 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
    /* update fragment program constants */
    st_upload_constants(st, fpv->parameters, PIPE_SHADER_FRAGMENT);
 
-   sample_count = rbRead->texture->nr_samples;
-   /* I believe this would be legal, presumably would need to do a resolve
-      for color, and for depth/stencil spec says to just use one of the
-      depth/stencil samples per pixel? Need some transfer clarifications. */
-   assert(sample_count < 2);
-
+   /* Choose the format for the temporary texture. */
    srcFormat = rbRead->texture->format;
 
-   if (screen->is_format_supported(screen, srcFormat, st->internal_target,
-                                   sample_count,
-                                   PIPE_BIND_SAMPLER_VIEW)) {
-      texFormat = srcFormat;
-   }
-   else {
-      /* srcFormat can't be used as a texture format */
+   if (!screen->is_format_supported(screen, srcFormat, st->internal_target, 0,
+                                    PIPE_BIND_SAMPLER_VIEW |
+                                    (type == GL_COLOR ? PIPE_BIND_RENDER_TARGET
+                                     : PIPE_BIND_DEPTH_STENCIL))) {
       if (type == GL_DEPTH) {
-         texFormat = st_choose_format(st, GL_DEPTH_COMPONENT,
-                                      GL_NONE, GL_NONE, st->internal_target,
-                                      sample_count, PIPE_BIND_DEPTH_STENCIL,
-                                      FALSE);
-         assert(texFormat != PIPE_FORMAT_NONE);
+         srcFormat = st_choose_format(st, GL_DEPTH_COMPONENT, GL_NONE,
+                                      GL_NONE, st->internal_target, 0,
+                                      PIPE_BIND_SAMPLER_VIEW |
+                                      PIPE_BIND_DEPTH_STENCIL, FALSE);
       }
       else {
-         /* default color format */
-         texFormat = st_choose_format(st, GL_RGBA,
-                                      GL_NONE, GL_NONE, st->internal_target,
-                                      sample_count, PIPE_BIND_SAMPLER_VIEW,
-                                      FALSE);
-         assert(texFormat != PIPE_FORMAT_NONE);
+         assert(type == GL_COLOR);
+
+         if (util_format_is_float(srcFormat)) {
+            srcFormat = st_choose_format(st, GL_RGBA32F, GL_NONE,
+                                         GL_NONE, st->internal_target, 0,
+                                         PIPE_BIND_SAMPLER_VIEW |
+                                         PIPE_BIND_RENDER_TARGET, FALSE);
+         }
+         else if (util_format_is_pure_sint(srcFormat)) {
+            srcFormat = st_choose_format(st, GL_RGBA32I, GL_NONE,
+                                         GL_NONE, st->internal_target, 0,
+                                         PIPE_BIND_SAMPLER_VIEW |
+                                         PIPE_BIND_RENDER_TARGET, FALSE);
+         }
+         else if (util_format_is_pure_uint(srcFormat)) {
+            srcFormat = st_choose_format(st, GL_RGBA32UI, GL_NONE,
+                                         GL_NONE, st->internal_target, 0,
+                                         PIPE_BIND_SAMPLER_VIEW |
+                                         PIPE_BIND_RENDER_TARGET, FALSE);
+         }
+         else {
+            srcFormat = st_choose_format(st, GL_RGBA, GL_NONE,
+                                         GL_NONE, st->internal_target, 0,
+                                         PIPE_BIND_SAMPLER_VIEW |
+                                         PIPE_BIND_RENDER_TARGET, FALSE);
+         }
+      }
+
+      if (srcFormat == PIPE_FORMAT_NONE) {
+         assert(0 && "cannot choose a format for src of CopyPixels");
+         return;
       }
    }
 
@@ -1599,8 +1614,8 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
    readW = MAX2(0, readW);
    readH = MAX2(0, readH);
 
-   /* alloc temporary texture */
-   pt = alloc_texture(st, width, height, texFormat);
+   /* Allocate the temporary texture. */
+   pt = alloc_texture(st, width, height, srcFormat);
    if (!pt)
       return;
 
@@ -1610,70 +1625,33 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
       return;
    }
 
-   /* Make temporary texture which is a copy of the src region.
-    */
-   if (srcFormat == texFormat) {
-      struct pipe_box src_box;
-      u_box_2d(readX, readY, readW, readH, &src_box);
-      /* copy source framebuffer surface into mipmap/texture */
-      pipe->resource_copy_region(pipe,
-                                 pt,                                /* dest tex */
-                                 0,                                 /* dest lvl */
-                                 pack.SkipPixels, pack.SkipRows, 0, /* dest pos */
-                                 rbRead->texture,                   /* src tex */
-                                 rbRead->rtt_level,                 /* src lvl */
-                                 &src_box);
-
-   }
-   else {
-      /* CPU-based fallback/conversion */
-      struct pipe_transfer *ptRead;
-      void *mapRead =
-         pipe_transfer_map(st->pipe, rbRead->texture,
-                           rbRead->rtt_level,
-                           rbRead->rtt_face + rbRead->rtt_slice,
-                           PIPE_TRANSFER_READ,
-                           readX, readY, readW, readH, &ptRead);
-      struct pipe_transfer *ptTex;
-      void *mapTex;
-      enum pipe_transfer_usage transfer_usage;
-
-      if (ST_DEBUG & DEBUG_FALLBACK)
-         debug_printf("%s: fallback processing\n", __FUNCTION__);
-
-      if (type == GL_DEPTH && util_format_is_depth_and_stencil(pt->format))
-         transfer_usage = PIPE_TRANSFER_READ_WRITE;
-      else
-         transfer_usage = PIPE_TRANSFER_WRITE;
-
-      mapTex = pipe_transfer_map(st->pipe, pt, 0, 0, transfer_usage,
-                                 0, 0, width, height, &ptTex);
-
-      /* copy image from ptRead surface to ptTex surface */
-      if (type == GL_COLOR) {
-         /* alternate path using get/put_tile() */
-         GLfloat *buf = malloc(width * height * 4 * sizeof(GLfloat));
-         enum pipe_format readFormat, drawFormat;
-         readFormat = util_format_linear(rbRead->texture->format);
-         drawFormat = util_format_linear(pt->format);
-         pipe_get_tile_rgba_format(ptRead, mapRead, 0, 0, readW, readH,
-                                   readFormat, buf);
-         pipe_put_tile_rgba_format(ptTex, mapTex, pack.SkipPixels,
-                                   pack.SkipRows,
-                                   readW, readH, drawFormat, buf);
-         free(buf);
-      }
-      else {
-         /* GL_DEPTH */
-         GLuint *buf = malloc(width * height * sizeof(GLuint));
-         pipe_get_tile_z(ptRead, mapRead, 0, 0, readW, readH, buf);
-         pipe_put_tile_z(ptTex, mapTex, pack.SkipPixels, pack.SkipRows,
-                         readW, readH, buf);
-         free(buf);
-      }
-
-      pipe->transfer_unmap(pipe, ptRead);
-      pipe->transfer_unmap(pipe, ptTex);
+   /* Copy the src region to the temporary texture. */
+   {
+      struct pipe_blit_info blit;
+
+      memset(&blit, 0, sizeof(blit));
+      blit.src.resource = rbRead->texture;
+      blit.src.level = rbRead->rtt_level;
+      blit.src.format = rbRead->texture->format;
+      blit.src.box.x = readX;
+      blit.src.box.y = readY;
+      blit.src.box.z = rbRead->rtt_face + rbRead->rtt_slice;
+      blit.src.box.width = readW;
+      blit.src.box.height = readH;
+      blit.src.box.depth = 1;
+      blit.dst.resource = pt;
+      blit.dst.level = 0;
+      blit.dst.format = pt->format;
+      blit.dst.box.x = pack.SkipPixels;
+      blit.dst.box.y = pack.SkipRows;
+      blit.dst.box.z = 0;
+      blit.dst.box.width = readW;
+      blit.dst.box.height = readH;
+      blit.dst.box.depth = 1;
+      blit.mask = util_format_get_mask(pt->format) & ~PIPE_MASK_S;
+      blit.filter = PIPE_TEX_FILTER_NEAREST;
+
+      pipe->blit(pipe, &blit);
    }
 
    /* OK, the texture 'pt' contains the src image/pixels.  Now draw a




More information about the mesa-commit mailing list