Merge branch '7.8'
authorBrian Paul <brianp@vmware.com>
Wed, 17 Mar 2010 16:13:51 +0000 (10:13 -0600)
committerBrian Paul <brianp@vmware.com>
Wed, 17 Mar 2010 16:13:51 +0000 (10:13 -0600)
Conflicts:

src/mesa/state_tracker/st_cb_drawpixels.c

1  2 
src/mesa/state_tracker/st_cb_drawpixels.c

index 75be79fd4b01ecade82b77f36baa42c8f31d2275,7c611cb4ec965802b984c71434f9c2e858e2d252..72a2ddb379ba37ba85f37c7b0647caf78aaaaf4a
@@@ -292,51 -292,6 +292,51 @@@ base_format(GLenum format
  }
  
  
 +/**
 + * Create a temporary texture to hold an image of the given size.
 + * If width, height are not POT and the driver only handles POT textures,
 + * allocate the next larger size of texture that is POT.
 + */
 +static struct pipe_texture *
 +alloc_texture(struct st_context *st, GLsizei width, GLsizei height,
 +              enum pipe_format texFormat)
 +{
 +   struct pipe_context *pipe = st->pipe;
 +   struct pipe_screen *screen = pipe->screen;
 +   struct pipe_texture *pt;
 +   int ptw, pth;
 +
 +   ptw = width;
 +   pth = height;
 +
 +   /* Need to use POT texture? */
 +   if (!screen->get_param(screen, PIPE_CAP_NPOT_TEXTURES)) {
 +      int l2pt, maxSize;
 +
 +      l2pt = util_logbase2(width);
 +      if (1 << l2pt != width) {
 +         ptw = 1 << (l2pt + 1);
 +      }
 +
 +      l2pt = util_logbase2(height);
 +      if (1 << l2pt != height) {
 +         pth = 1 << (l2pt + 1);
 +      }
 +
 +      /* Check against maximum texture size */
 +      maxSize = 1 << (pipe->screen->get_param(pipe->screen,
 +                               PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1);
 +      assert(ptw <= maxSize);
 +      assert(pth <= maxSize);
 +   }
 +
 +   pt = st_texture_create(st, PIPE_TEXTURE_2D, texFormat, 0,
 +                          ptw, pth, 1, PIPE_TEXTURE_USAGE_SAMPLER);
 +
 +   return pt;
 +}
 +
 +
  /**
   * Make texture containing an image for glDrawPixels image.
   * If 'pixels' is NULL, leave the texture image data undefined.
@@@ -349,11 -304,13 +349,11 @@@ make_texture(struct st_context *st
  {
     GLcontext *ctx = st->ctx;
     struct pipe_context *pipe = st->pipe;
 -   struct pipe_screen *screen = pipe->screen;
     gl_format mformat;
     struct pipe_texture *pt;
     enum pipe_format pipeFormat;
     GLuint cpp;
     GLenum baseFormat;
 -   int ptw, pth;
  
     baseFormat = base_format(format);
  
     if (!pixels)
        return NULL;
  
 -   /* Need to use POT texture? */
 -   ptw = width;
 -   pth = height;
 -   if (!screen->get_param(screen, PIPE_CAP_NPOT_TEXTURES)) {
 -      int l2pt, maxSize;
 -
 -      l2pt = util_logbase2(width);
 -      if (1<<l2pt != width) {
 -         ptw = 1<<(l2pt+1);
 -      }
 -      l2pt = util_logbase2(height);
 -      if (1<<l2pt != height) {
 -         pth = 1<<(l2pt+1);
 -      }
 -
 -      /* Check against maximum texture size */
 -      maxSize = 1 << (pipe->screen->get_param(pipe->screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1);
 -      assert(ptw <= maxSize);
 -      assert(pth <= maxSize);
 -   }
 -
 -   pt = st_texture_create(st, PIPE_TEXTURE_2D, pipeFormat, 0, ptw, pth, 1,
 -                          PIPE_TEXTURE_USAGE_SAMPLER);
 +   /* alloc temporary texture */
 +   pt = alloc_texture(st, width, height, pipeFormat);
     if (!pt) {
        _mesa_unmap_pbo_source(ctx, unpack);
        return NULL;
                                              width, height);
  
        /* map texture transfer */
 -      dest = screen->transfer_map(screen, transfer);
 +      dest = pipe->transfer_map(pipe, transfer);
  
  
        /* Put image into texture transfer.
                                 unpack);
  
        /* unmap */
 -      screen->transfer_unmap(screen, transfer);
 -      screen->tex_transfer_destroy(transfer);
 +      pipe->transfer_unmap(pipe, transfer);
 +      pipe->tex_transfer_destroy(pipe, transfer);
  
        assert(success);
  
@@@ -525,7 -503,7 +525,7 @@@ static voi
  draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
                     GLsizei width, GLsizei height,
                     GLfloat zoomX, GLfloat zoomY,
 -                   struct pipe_texture *pt,
 +                   struct pipe_sampler_view *sv,
                     void *driver_vp,
                     void *driver_fp,
                     const GLfloat *color,
     cso_save_rasterizer(cso);
     cso_save_viewport(cso);
     cso_save_samplers(cso);
 -   cso_save_sampler_textures(cso);
 +   cso_save_fragment_sampler_views(cso);
     cso_save_fragment_shader(cso);
     cso_save_vertex_shader(cso);
 +   cso_save_vertex_elements(cso);
  
     /* rasterizer state: just scissor */
     {
        cso_set_viewport(cso, &vp);
     }
  
 +   cso_set_vertex_elements(cso, 3, st->velems_util_draw);
 +
     /* texture state: */
     if (st->pixel_xfer.pixelmap_enabled) {
 -      struct pipe_texture *textures[2];
 -      textures[0] = pt;
 -      textures[1] = st->pixel_xfer.pixelmap_texture;
 -      pipe->set_fragment_sampler_textures(pipe, 2, textures);
 +      struct pipe_sampler_view *sampler_views[2];
 +      sampler_views[0] = sv;
 +      sampler_views[1] = st->pixel_xfer.pixelmap_sampler_view;
 +      cso_set_fragment_sampler_views(cso, 2, sampler_views);
     }
     else {
 -      pipe->set_fragment_sampler_textures(pipe, 1, &pt);
 +      cso_set_fragment_sampler_views(cso, 1, &sv);
     }
  
     /* Compute Gallium window coords (y=0=top) with pixel zoom.
     z = z * 2.0 - 1.0;
  
     draw_quad(ctx, x0, y0, z, x1, y1, color, invertTex,
 -           (GLfloat) width / pt->width0,
 -           (GLfloat) height / pt->height0);
 +             (GLfloat) width / sv->texture->width0,
 +             (GLfloat) height / sv->texture->height0);
  
     /* restore state */
     cso_restore_rasterizer(cso);
     cso_restore_viewport(cso);
     cso_restore_samplers(cso);
 -   cso_restore_sampler_textures(cso);
 +   cso_restore_fragment_sampler_views(cso);
     cso_restore_fragment_shader(cso);
     cso_restore_vertex_shader(cso);
 +   cso_restore_vertex_elements(cso);
  }
  
  
@@@ -657,6 -631,7 +657,6 @@@ draw_stencil_pixels(GLcontext *ctx, GLi
  {
     struct st_context *st = st_context(ctx);
     struct pipe_context *pipe = st->pipe;
 -   struct pipe_screen *screen = pipe->screen;
     struct st_renderbuffer *strb;
     enum pipe_transfer_usage usage;
     struct pipe_transfer *pt;
                                       usage, x, y,
                                       width, height);
  
 -   stmap = screen->transfer_map(screen, pt);
 +   stmap = pipe->transfer_map(pipe, pt);
  
     pixels = _mesa_map_pbo_source(ctx, &clippedUnpack, pixels);
     assert(pixels);
     _mesa_unmap_pbo_source(ctx, &clippedUnpack);
  
     /* unmap the stencil buffer */
 -   screen->transfer_unmap(screen, pt);
 -   screen->tex_transfer_destroy(pt);
 +   pipe->transfer_unmap(pipe, pt);
 +   pipe->tex_transfer_destroy(pipe, pt);
  }
  
  
@@@ -835,17 -810,12 +835,17 @@@ st_DrawPixels(GLcontext *ctx, GLint x, 
        struct pipe_texture *pt
           = make_texture(st, width, height, format, type, unpack, pixels);
        if (pt) {
 -         draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2],
 -                            width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
 -                            pt, 
 -                            driver_vp, 
 -                            driver_fp,
 -                            color, GL_FALSE);
 +         struct pipe_sampler_view *sv = st_sampler_view_from_texture(st->pipe, pt);
 +
 +         if (sv) {
 +            draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2],
 +                               width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
 +                               sv,
 +                               driver_vp, 
 +                               driver_fp,
 +                               color, GL_FALSE);
 +            pipe_sampler_view_reference(&sv, NULL);
 +         }
           pipe_texture_reference(&pt, NULL);
        }
     }
@@@ -859,7 -829,7 +859,7 @@@ copy_stencil_pixels(GLcontext *ctx, GLi
                      GLint dstx, GLint dsty)
  {
     struct st_renderbuffer *rbDraw = st_renderbuffer(ctx->DrawBuffer->_StencilBuffer);
 -   struct pipe_screen *screen = ctx->st->pipe->screen;
 +   struct pipe_context *pipe = ctx->st->pipe;
     enum pipe_transfer_usage usage;
     struct pipe_transfer *ptDraw;
     ubyte *drawMap;
     assert(util_format_get_blockheight(ptDraw->texture->format) == 1);
  
     /* map the stencil buffer */
 -   drawMap = screen->transfer_map(screen, ptDraw);
 +   drawMap = pipe->transfer_map(pipe, ptDraw);
  
     /* draw */
     /* XXX PixelZoom not handled yet */
     free(buffer);
  
     /* unmap the stencil buffer */
 -   screen->transfer_unmap(screen, ptDraw);
 -   screen->tex_transfer_destroy(ptDraw);
 +   pipe->transfer_unmap(pipe, ptDraw);
 +   pipe->tex_transfer_destroy(pipe, ptDraw);
  }
  
  
@@@ -964,43 -934,17 +964,17 @@@ st_CopyPixels(GLcontext *ctx, GLint src
     struct st_renderbuffer *rbRead;
     void *driver_vp, *driver_fp;
     struct pipe_texture *pt;
 +   struct pipe_sampler_view *sv;
     GLfloat *color;
     enum pipe_format srcFormat, texFormat;
 -   int ptw, pth;
     GLboolean invertTex = GL_FALSE;
+    GLint readX, readY, readW, readH;
+    struct gl_pixelstore_attrib unpack = ctx->DefaultPacking;
  
     pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
  
     st_validate_state(st);
  
-    if (srcx < 0) {
-       width -= -srcx;
-       dstx += -srcx;
-       srcx = 0;
-    }
-    if (srcy < 0) {
-       height -= -srcy;
-       dsty += -srcy;
-       srcy = 0;
-    }
-    if (dstx < 0) {
-       width -= -dstx;
-       srcx += -dstx;
-       dstx = 0;
-    }
-    if (dsty < 0) {
-       height -= -dsty;
-       srcy += -dsty;
-       dsty = 0;
-    }
-    if (width < 0 || height < 0)
-       return;
     if (type == GL_STENCIL) {
        /* can't use texturing to do stencil */
        copy_stencil_pixels(ctx, srcx, srcy, width, height, dstx, dsty);
           texFormat = st_choose_format(screen, GL_DEPTH_COMPONENT,
                                        PIPE_TEXTURE_2D, 
                                        PIPE_TEXTURE_USAGE_DEPTH_STENCIL);
-          assert(texFormat != PIPE_FORMAT_NONE); /* XXX no depth texture formats??? */
+          assert(texFormat != PIPE_FORMAT_NONE);
        }
        else {
           /* default color format */
        }
     }
  
+    /* Invert src region if needed */
     if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
        srcy = ctx->ReadBuffer->Height - srcy - height;
-       if (srcy < 0) {
-          height -= -srcy;
-          srcy = 0;
-       }
-       if (height < 0)
-          return;
        invertTex = !invertTex;
     }
  
 -   /* Need to use POT texture? */
 -   ptw = width;
 -   pth = height;
 -   if (!screen->get_param(screen, PIPE_CAP_NPOT_TEXTURES)) {
 -      int l2pt, maxSize;
 -
 -      l2pt = util_logbase2(width);
 -      if (1<<l2pt != width) {
 -         ptw = 1<<(l2pt+1);
 -      }
 -      l2pt = util_logbase2(height);
 -      if (1<<l2pt != height) {
 -         pth = 1<<(l2pt+1);
 -      }
 -
 -      /* Check against maximum texture size */
 -      maxSize = 1 << (pipe->screen->get_param(pipe->screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1);
 -      assert(ptw <= maxSize);
 -      assert(pth <= maxSize);
 -   }
 -
 -   pt = st_texture_create(st, PIPE_TEXTURE_2D, texFormat, 0,
 -                          ptw, pth, 1,
 -                          PIPE_TEXTURE_USAGE_SAMPLER);
+    /* Clip the read region against the src buffer bounds.
+     * We'll still allocate a temporary buffer/texture for the original
+     * src region size but we'll only read the region which is on-screen.
+     * This may mean that we draw garbage pixels into the dest region, but
+     * that's expected.
+     */
+    readX = srcx;
+    readY = srcy;
+    readW = width;
+    readH = height;
+    _mesa_clip_readpixels(ctx, &readX, &readY, &readW, &readH, &unpack);
+    readW = MAX2(0, readW);
+    readH = MAX2(0, readH);
 +   /* alloc temporary texture */
 +   pt = alloc_texture(st, width, height, texFormat);
     if (!pt)
        return;
  
 +   sv = st_sampler_view_from_texture(st->pipe, pt);
 +   if (!sv) {
 +      pipe_texture_reference(&pt, NULL);
 +      return;
 +   }
 +
     /* Make temporary texture which is a copy of the src region.
-     * We'll draw a quad with this texture to draw the dest image.
      */
     if (srcFormat == texFormat) {
        /* copy source framebuffer surface into mipmap/texture */
                                        PIPE_BUFFER_USAGE_GPU_WRITE );
        if (pipe->surface_copy) {
           pipe->surface_copy(pipe,
-                             psTex, /* dest */
-                             0, 0, /* destx/y */
-                             psRead,
-                             srcx, srcy, width, height);
+                             psTex,                               /* dest surf */
+                             unpack.SkipPixels, unpack.SkipRows,  /* dest pos */
+                             psRead,                              /* src surf */
+                             readX, readY, readW, readH);         /* src region */
        } else {
           util_surface_copy(pipe, FALSE,
                             psTex,
-                            0, 0,
+                            unpack.SkipPixels, unpack.SkipRows,
                             psRead,
-                            srcx, srcy, width, height);
+                            readX, readY, readW, readH);
        }
  
        if (0) {
           /* debug */
 -         debug_dump_surface("copypixsrcsurf", psRead);
 -         debug_dump_surface("copypixtemptex", psTex);
 +         debug_dump_surface(pipe, "copypixsrcsurf", psRead);
 +         debug_dump_surface(pipe, "copypixtemptex", psTex);
        }
  
        pipe_surface_reference(&psRead, NULL); 
        /* CPU-based fallback/conversion */
        struct pipe_transfer *ptRead =
           st_cond_flush_get_tex_transfer(st, rbRead->texture, 0, 0, 0,
-                                       PIPE_TRANSFER_READ, srcx, srcy, width,
-                                       height);
+                                         PIPE_TRANSFER_READ,
+                                         readX, readY, readW, readH);
        struct pipe_transfer *ptTex;
        enum pipe_transfer_usage transfer_usage;
  
        ptTex = st_cond_flush_get_tex_transfer(st, pt, 0, 0, 0, transfer_usage,
                                               0, 0, width, height);
  
+       /* copy image from ptRead surface to ptTex surface */
        if (type == GL_COLOR) {
           /* alternate path using get/put_tile() */
           GLfloat *buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
-          pipe_get_tile_rgba(pipe, ptRead, 0, 0, width, height, buf);
-          pipe_put_tile_rgba(pipe, ptTex, 0, 0, width, height, buf);
 -         pipe_get_tile_rgba(ptRead, readX, readY, readW, readH, buf);
 -         pipe_put_tile_rgba(ptTex, unpack.SkipPixels, unpack.SkipRows,
++         pipe_get_tile_rgba(pipe, ptRead, readX, readY, readW, readH, buf);
++         pipe_put_tile_rgba(pipe, ptTex, unpack.SkipPixels, unpack.SkipRows,
+                             readW, readH, buf);
           free(buf);
        }
        else {
           /* GL_DEPTH */
           GLuint *buf = (GLuint *) malloc(width * height * sizeof(GLuint));
-          pipe_get_tile_z(pipe, ptRead, 0, 0, width, height, buf);
-          pipe_put_tile_z(pipe, ptTex, 0, 0, width, height, buf);
 -         pipe_get_tile_z(ptRead, readX, readY, readW, readH, buf);
 -         pipe_put_tile_z(ptTex, unpack.SkipPixels, unpack.SkipRows,
 -                            readW, readH, buf);
++         pipe_get_tile_z(pipe, ptRead, readX, readY, readW, readH, buf);
++         pipe_put_tile_z(pipe, ptTex, unpack.SkipPixels, unpack.SkipRows,
++                         readW, readH, buf);
           free(buf);
        }
  
 -      screen->tex_transfer_destroy(ptRead);
 -      screen->tex_transfer_destroy(ptTex);
 +      pipe->tex_transfer_destroy(pipe, ptRead);
 +      pipe->tex_transfer_destroy(pipe, ptTex);
     }
  
-    /* draw textured quad */
+    /* OK, the texture 'pt' contains the src image/pixels.  Now draw a
+     * textured quad with that texture.
+     */
     draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2],
                        width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
 -                      pt
 +                      sv
                        driver_vp, 
                        driver_fp,
                        color, invertTex);
  
     pipe_texture_reference(&pt, NULL);
 +   pipe_sampler_view_reference(&sv, NULL);
  }