gallium: Make sure we flush before some texture / buffer operations.
[mesa.git] / src / mesa / state_tracker / st_cb_drawpixels.c
index 5b24b9f06874cf0c6eaeb63213f7511bf30f8bde..c67b026413eebbf232c047c118c98c76b89dca20 100644 (file)
@@ -75,7 +75,7 @@ is_passthrough_program(const struct gl_fragment_program *prog)
       if (inst[0].Opcode == OPCODE_MOV &&
           inst[1].Opcode == OPCODE_END &&
           inst[0].DstReg.File == PROGRAM_OUTPUT &&
-          inst[0].DstReg.Index == FRAG_RESULT_COLR &&
+          inst[0].DstReg.Index == FRAG_RESULT_COLOR &&
           inst[0].DstReg.WriteMask == WRITEMASK_XYZW &&
           inst[0].SrcReg[0].File == PROGRAM_INPUT &&
           inst[0].SrcReg[0].Index == FRAG_ATTRIB_COL0 &&
@@ -158,7 +158,7 @@ combined_drawpix_fragment_program(GLcontext *ctx)
 
 /**
  * Create fragment shader that does a TEX() instruction to get a Z
- * value, then writes to FRAG_RESULT_DEPR.
+ * value, then writes to FRAG_RESULT_DEPTH.
  * Pass fragment color through as-is.
  */
 static struct st_fragment_program *
@@ -191,7 +191,7 @@ make_fragment_shader_z(struct st_context *st)
    /* TEX result.depth, fragment.texcoord[0], texture[0], 2D; */
    p->Instructions[ic].Opcode = OPCODE_TEX;
    p->Instructions[ic].DstReg.File = PROGRAM_OUTPUT;
-   p->Instructions[ic].DstReg.Index = FRAG_RESULT_DEPR;
+   p->Instructions[ic].DstReg.Index = FRAG_RESULT_DEPTH;
    p->Instructions[ic].DstReg.WriteMask = WRITEMASK_Z;
    p->Instructions[ic].SrcReg[0].File = PROGRAM_INPUT;
    p->Instructions[ic].SrcReg[0].Index = FRAG_ATTRIB_TEX0;
@@ -202,7 +202,7 @@ make_fragment_shader_z(struct st_context *st)
    /* MOV result.color, fragment.color */
    p->Instructions[ic].Opcode = OPCODE_MOV;
    p->Instructions[ic].DstReg.File = PROGRAM_OUTPUT;
-   p->Instructions[ic].DstReg.Index = FRAG_RESULT_COLR;
+   p->Instructions[ic].DstReg.Index = FRAG_RESULT_COLOR;
    p->Instructions[ic].SrcReg[0].File = PROGRAM_INPUT;
    p->Instructions[ic].SrcReg[0].Index = FRAG_ATTRIB_COL0;
    ic++;
@@ -213,7 +213,7 @@ make_fragment_shader_z(struct st_context *st)
    assert(ic == p->NumInstructions);
 
    p->InputsRead = FRAG_BIT_TEX0 | FRAG_BIT_COL0;
-   p->OutputsWritten = (1 << FRAG_RESULT_COLR) | (1 << FRAG_RESULT_DEPR);
+   p->OutputsWritten = (1 << FRAG_RESULT_COLOR) | (1 << FRAG_RESULT_DEPTH);
    p->SamplersUsed = 0x1;  /* sampler 0 (bit 0) is used */
 
    st->drawpix.z_shader = (struct st_fragment_program *) p;
@@ -309,6 +309,8 @@ _mesa_base_format(GLenum format)
    switch (format) {
    case GL_DEPTH_COMPONENT:
       return GL_DEPTH_COMPONENT;
+   case GL_DEPTH_STENCIL:
+      return GL_DEPTH_STENCIL;
    case GL_STENCIL_INDEX:
       return GL_STENCIL_INDEX;
    default:
@@ -349,8 +351,7 @@ make_texture(struct st_context *st,
    if (!pixels)
       return NULL;
 
-   pt = st_texture_create(st, PIPE_TEXTURE_2D, pipeFormat, 0, width, height,
-                         1, 0,
+   pt = st_texture_create(st, PIPE_TEXTURE_2D, pipeFormat, 0, width, height, 1,
                           PIPE_TEXTURE_USAGE_SAMPLER);
    if (!pt) {
       _mesa_unmap_drawpix_pbo(ctx, unpack);
@@ -358,7 +359,7 @@ make_texture(struct st_context *st,
    }
 
    {
-      struct pipe_surface *surface;
+      struct pipe_transfer *transfer;
       static const GLuint dstImageOffsets = 0;
       GLboolean success;
       GLubyte *dest;
@@ -367,14 +368,14 @@ make_texture(struct st_context *st,
       /* we'll do pixel transfer in a fragment shader */
       ctx->_ImageTransferState = 0x0;
 
-      surface = screen->get_tex_surface(screen, pt, 0, 0, 0,
-                                        PIPE_BUFFER_USAGE_CPU_WRITE);
+      transfer = screen->get_tex_transfer(screen, pt, 0, 0, 0,
+                                          PIPE_TRANSFER_WRITE, 0, 0,
+                                          width, height);
 
-      /* map texture surface */
-      dest = screen->surface_map(screen, surface,
-                                 PIPE_BUFFER_USAGE_CPU_WRITE);
+      /* map texture transfer */
+      dest = screen->transfer_map(screen, transfer);
 
-      /* Put image into texture surface.
+      /* Put image into texture transfer.
        * Note that the image is actually going to be upside down in
        * the texture.  We deal with that with texcoords.
        */
@@ -383,7 +384,7 @@ make_texture(struct st_context *st,
                                     mformat,          /* gl_texture_format */
                                     dest,             /* dest */
                                     0, 0, 0,          /* dstX/Y/Zoffset */
-                                    surface->stride,  /* dstRowStride, bytes */
+                                    transfer->stride, /* dstRowStride, bytes */
                                     &dstImageOffsets, /* dstImageOffsets */
                                     width, height, 1, /* size */
                                     format, type,     /* src format/type */
@@ -391,8 +392,8 @@ make_texture(struct st_context *st,
                                     unpack);
 
       /* unmap */
-      screen->surface_unmap(screen, surface);
-      pipe_surface_reference(&surface, NULL);
+      screen->transfer_unmap(screen, transfer);
+      screen->tex_transfer_destroy(transfer);
 
       assert(success);
 
@@ -485,20 +486,17 @@ draw_quad(GLcontext *ctx, GLfloat x0, GLfloat y0, GLfloat z,
 
    {
       struct pipe_buffer *buf;
-      ubyte *map;
 
       /* allocate/load buffer object with vertex data */
       buf = pipe_buffer_create(pipe->screen, 32, PIPE_BUFFER_USAGE_VERTEX,
                                sizeof(verts));
-      map = pipe_buffer_map(pipe->screen, buf, PIPE_BUFFER_USAGE_CPU_WRITE);
-      memcpy(map, verts, sizeof(verts));
-      pipe_buffer_unmap(pipe->screen, buf);
+      pipe_buffer_write(pipe->screen, buf, 0, sizeof(verts), verts);
 
-      util_draw_vertex_buffer(pipe, buf,
+      util_draw_vertex_buffer(pipe, buf, 0,
                               PIPE_PRIM_QUADS,
                               4,  /* verts */
                               3); /* attribs/vert */
-      pipe_buffer_reference(pipe->screen, &buf, NULL);
+      pipe_buffer_reference(&buf, NULL);
    }
 }
 
@@ -605,10 +603,9 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
    x1 = x + width * ctx->Pixel.ZoomX;
    y0 = (GLfloat) y;
    y1 = y + height * ctx->Pixel.ZoomY;
-   //if(!color)
+
    draw_quad(ctx, x0, y0, z, x1, y1, color, invertTex);
-   //else
-   //printf("skip draw quad\n");
+
    /* restore state */
    cso_restore_rasterizer(cso);
    cso_restore_viewport(cso);
@@ -619,120 +616,9 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
 }
 
 
-/**
- * Check if a GL format/type combination is a match to the given pipe format.
- * XXX probably move this to a re-usable place.
- */
-static GLboolean
-compatible_formats(GLenum format, GLenum type, enum pipe_format pipeFormat)
-{
-   static const GLuint one = 1;
-   GLubyte littleEndian = *((GLubyte *) &one);
-
-   if (pipeFormat == PIPE_FORMAT_R8G8B8A8_UNORM &&
-       format == GL_RGBA &&
-       type == GL_UNSIGNED_BYTE &&
-       !littleEndian) {
-      return GL_TRUE;
-   }
-   else if (pipeFormat == PIPE_FORMAT_R8G8B8A8_UNORM &&
-            format == GL_ABGR_EXT &&
-            type == GL_UNSIGNED_BYTE &&
-            littleEndian) {
-      return GL_TRUE;
-   }
-   else if (pipeFormat == PIPE_FORMAT_A8R8G8B8_UNORM &&
-            format == GL_BGRA &&
-            type == GL_UNSIGNED_BYTE &&
-            littleEndian) {
-      return GL_TRUE;
-   }
-   else if (pipeFormat == PIPE_FORMAT_R5G6B5_UNORM &&
-            format == GL_RGB &&
-            type == GL_UNSIGNED_SHORT_5_6_5) {
-      /* endian don't care */
-      return GL_TRUE;
-   }
-   else if (pipeFormat == PIPE_FORMAT_R5G6B5_UNORM &&
-            format == GL_BGR &&
-            type == GL_UNSIGNED_SHORT_5_6_5_REV) {
-      /* endian don't care */
-      return GL_TRUE;
-   }
-   else if (pipeFormat == PIPE_FORMAT_S8_UNORM &&
-            format == GL_STENCIL_INDEX &&
-            type == GL_UNSIGNED_BYTE) {
-      return GL_TRUE;
-   }
-   else if (pipeFormat == PIPE_FORMAT_Z32_UNORM &&
-            format == GL_DEPTH_COMPONENT &&
-            type == GL_UNSIGNED_INT) {
-      return GL_TRUE;
-   }
-   /* XXX add more cases */
-   else {
-      return GL_FALSE;
-   }
-}
-
-
-/**
- * Check if any per-fragment ops are enabled.
- * XXX probably move this to a re-usable place.
- */
-static GLboolean
-any_fragment_ops(const struct st_context *st)
-{
-   if (st->state.depth_stencil.alpha.enabled ||
-       st->state.depth_stencil.depth.enabled ||
-       st->state.blend.blend_enable ||
-       st->state.blend.logicop_enable)
-      /* XXX more checks */
-      return GL_TRUE;
-   else
-      return GL_FALSE;
-}
-
-
-/**
- * Check if any pixel transfer ops are enabled.
- * XXX probably move this to a re-usable place.
- */
-static GLboolean
-any_pixel_transfer_ops(const struct st_context *st)
-{
-   if (st->ctx->Pixel.RedScale != 1.0 ||
-       st->ctx->Pixel.RedBias != 0.0 ||
-       st->ctx->Pixel.GreenScale != 1.0 ||
-       st->ctx->Pixel.GreenBias != 0.0 ||
-       st->ctx->Pixel.BlueScale != 1.0 ||
-       st->ctx->Pixel.BlueBias != 0.0 ||
-       st->ctx->Pixel.AlphaScale != 1.0 ||
-       st->ctx->Pixel.AlphaBias != 0.0 ||
-       st->ctx->Pixel.MapColorFlag)
-      /* XXX more checks */
-      return GL_TRUE;
-   else
-      return GL_FALSE;
-}
-
-
-/**
- * Draw image with a blit, or other non-textured quad method.
- */
-static void
-draw_blit(struct st_context *st,
-          GLsizei width, GLsizei height,
-          GLenum format, GLenum type, const GLvoid *pixels)
-{
-
-
-}
-
-
 static void
 draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
-                    GLsizei width, GLsizei height, GLenum type,
+                    GLsizei width, GLsizei height, GLenum format, GLenum type,
                     const struct gl_pixelstore_attrib *unpack,
                     const GLvoid *pixels)
 {
@@ -740,65 +626,105 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
    struct pipe_context *pipe = st->pipe;
    struct pipe_screen *screen = pipe->screen;
    struct st_renderbuffer *strb;
-   struct pipe_surface *ps;
+   struct pipe_transfer *pt;
    const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
    GLint skipPixels;
    ubyte *stmap;
 
-   pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
-
    strb = st_renderbuffer(ctx->DrawBuffer->
                           Attachment[BUFFER_STENCIL].Renderbuffer);
-   ps = screen->get_tex_surface(screen, strb->texture, 0, 0, 0,
-                                PIPE_BUFFER_USAGE_CPU_WRITE);
 
-   /* map the stencil buffer */
-   stmap = screen->surface_map(screen, ps, 
-                               PIPE_BUFFER_USAGE_CPU_WRITE);
+   if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
+      y = ctx->DrawBuffer->Height - y - height;
+   }
+
+   st_teximage_flush_before_map(ctx->st, strb->texture, 0, 0,
+                               PIPE_TRANSFER_WRITE);
+
+   pt = screen->get_tex_transfer(screen, strb->texture, 0, 0, 0,
+                                 PIPE_TRANSFER_WRITE, x, y,
+                                 width, height);
+
+   stmap = screen->transfer_map(screen, pt);
+
+   pixels = _mesa_map_drawpix_pbo(ctx, unpack, pixels);
+   assert(pixels);
 
    /* if width > MAX_WIDTH, have to process image in chunks */
    skipPixels = 0;
    while (skipPixels < width) {
-      const GLint spanX = x + skipPixels;
+      const GLint spanX = skipPixels;
       const GLint spanWidth = MIN2(width - skipPixels, MAX_WIDTH);
       GLint row;
       for (row = 0; row < height; row++) {
-         GLint spanY = y + row;
-         GLubyte values[MAX_WIDTH];
+         GLubyte sValues[MAX_WIDTH];
+         GLuint zValues[MAX_WIDTH];
          GLenum destType = GL_UNSIGNED_BYTE;
          const GLvoid *source = _mesa_image_address2d(unpack, pixels,
                                                       width, height,
-                                                      GL_COLOR_INDEX, type,
+                                                      format, type,
                                                       row, skipPixels);
-         _mesa_unpack_stencil_span(ctx, spanWidth, destType, values,
+         _mesa_unpack_stencil_span(ctx, spanWidth, destType, sValues,
                                    type, source, unpack,
                                    ctx->_ImageTransferState);
+
+         if (format == GL_DEPTH_STENCIL) {
+            _mesa_unpack_depth_span(ctx, spanWidth, GL_UNSIGNED_INT, zValues,
+                                    (1 << 24) - 1, type, source, unpack);
+         }
+
          if (zoom) {
-            /*
-            _swrast_write_zoomed_stencil_span(ctx, x, y, spanWidth,
-                                              spanX, spanY, values);
-            */
+            _mesa_problem(ctx, "Gallium glDrawPixels(GL_STENCIL) with "
+                          "zoom not complete");
          }
-         else {
+
+         {
+            GLint spanY;
+
             if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
-               spanY = ctx->DrawBuffer->Height - spanY - 1;
+               spanY = height - row - 1;
+            }
+            else {
+               spanY = row;
             }
 
-            switch (ps->format) {
+            /* now pack the stencil (and Z) values in the dest format */
+            switch (pt->format) {
             case PIPE_FORMAT_S8_UNORM:
                {
-                  ubyte *dest = stmap + spanY * ps->stride + spanX;
-                  memcpy(dest, values, spanWidth);
+                  ubyte *dest = stmap + spanY * pt->stride + spanX;
+                  memcpy(dest, sValues, spanWidth);
                }
                break;
             case PIPE_FORMAT_S8Z24_UNORM:
-               {
-                  uint *dest = (uint *) (stmap + spanY * ps->stride + spanX*4);
+               if (format == GL_DEPTH_STENCIL) {
+                  uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4);
                   GLint k;
                   for (k = 0; k < spanWidth; k++) {
-                     uint p = dest[k];
-                     p = (p & 0xffffff) | (values[k] << 24);
-                     dest[k] = p;
+                     dest[k] = zValues[k] | (sValues[k] << 24);
+                  }
+               }
+               else {
+                  uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4);
+                  GLint k;
+                  for (k = 0; k < spanWidth; k++) {
+                     dest[k] = (dest[k] & 0xffffff) | (sValues[k] << 24);
+                  }
+               }
+               break;
+            case PIPE_FORMAT_Z24S8_UNORM:
+               if (format == GL_DEPTH_STENCIL) {
+                  uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4);
+                  GLint k;
+                  for (k = 0; k < spanWidth; k++) {
+                     dest[k] = zValues[k] | (sValues[k] << 24);
+                  }
+               }
+               else {
+                  uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4);
+                  GLint k;
+                  for (k = 0; k < spanWidth; k++) {
+                     dest[k] = (dest[k] & 0xffffff00) | (sValues[k] & 0xff);
                   }
                }
                break;
@@ -810,9 +736,11 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
       skipPixels += spanWidth;
    }
 
+   _mesa_unmap_drawpix_pbo(ctx, unpack);
+
    /* unmap the stencil buffer */
-   screen->surface_unmap(screen, ps);
-   pipe_surface_reference(&ps, NULL);
+   screen->transfer_unmap(screen, pt);
+   screen->tex_transfer_destroy(pt);
 }
 
 
@@ -831,8 +759,10 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
    GLuint bufferFormat;
    const GLfloat *color;
 
-   if (format == GL_STENCIL_INDEX) {
-      draw_stencil_pixels(ctx, x, y, width, height, type, unpack, pixels);
+   if (format == GL_STENCIL_INDEX ||
+       format == GL_DEPTH_STENCIL) {
+      draw_stencil_pixels(ctx, x, y, width, height, format, type,
+                          unpack, pixels);
       return;
    }
 
@@ -847,11 +777,6 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
       stvp = st_make_passthrough_vertex_shader(ctx->st, GL_TRUE);
       color = ctx->Current.RasterColor;
    }
-   else if (format == GL_STENCIL_INDEX) {
-      ps = st->state.framebuffer.zsbuf;
-      /* XXX special case - can't use texture map */
-      color = NULL;
-   }
    else {
       ps = st->state.framebuffer.cbufs[0];
       stfp = combined_drawpix_fragment_program(ctx);
@@ -861,10 +786,8 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
 
    bufferFormat = ps->format;
 
-   if (1/*any_fragment_ops(st) ||
-       any_pixel_transfer_ops(st) ||
-       !compatible_formats(format, type, ps->format)*/) {
-      /* textured quad */
+   /* draw with textured quad */
+   {
       struct pipe_texture *pt
          = make_texture(ctx->st, width, height, format, type, unpack, pixels);
       if (pt) {
@@ -874,10 +797,6 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
          pipe_texture_reference(&pt, NULL);
       }
    }
-   else {
-      /* blit */
-      draw_blit(st, width, height, format, type, pixels);
-   }
 
    _mesa_set_vp_override( ctx, FALSE );
 }
@@ -891,29 +810,34 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
 {
    struct st_renderbuffer *rbDraw = st_renderbuffer(ctx->DrawBuffer->_StencilBuffer);
    struct pipe_screen *screen = ctx->st->pipe->screen;
-   struct pipe_surface *psDraw;
+   struct pipe_transfer *ptDraw;
    ubyte *drawMap;
    ubyte *buffer;
    int i;
 
-   buffer = malloc(width * height * sizeof(ubyte));
+   buffer = _mesa_malloc(width * height * sizeof(ubyte));
    if (!buffer) {
       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels(stencil)");
       return;
    }
 
    /* this will do stencil pixel transfer ops */
-   st_read_stencil_pixels(ctx, srcx, srcy, width, height, GL_UNSIGNED_BYTE,
+   st_read_stencil_pixels(ctx, srcx, srcy, width, height,
+                          GL_STENCIL_INDEX, GL_UNSIGNED_BYTE,
                           &ctx->DefaultPacking, buffer);
 
-   psDraw = screen->get_tex_surface(screen, rbDraw->texture, 0, 0, 0,
-                                    PIPE_BUFFER_USAGE_CPU_WRITE);
+   st_teximage_flush_before_map(ctx->st, rbDraw->texture, 0, 0,
+                               PIPE_TRANSFER_WRITE);
 
-   assert(psDraw->block.width == 1);
-   assert(psDraw->block.height == 1);
+   ptDraw = screen->get_tex_transfer(screen, rbDraw->texture, 0, 0, 0,
+                                     PIPE_TRANSFER_WRITE, dstx, dsty,
+                                     width, height);
+
+   assert(ptDraw->block.width == 1);
+   assert(ptDraw->block.height == 1);
    
    /* map the stencil buffer */
-   drawMap = screen->surface_map(screen, psDraw, PIPE_BUFFER_USAGE_CPU_WRITE);
+   drawMap = screen->transfer_map(screen, ptDraw);
 
    /* draw */
    /* XXX PixelZoom not handled yet */
@@ -922,16 +846,16 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
       const ubyte *src;
       int y;
 
-      y = dsty + i;
+      y = i;
 
       if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
-         y = ctx->DrawBuffer->Height - y - 1;
+         y = height - y - 1;
       }
 
-      dst = drawMap + y * psDraw->stride + dstx * psDraw->block.size;
+      dst = drawMap + y * ptDraw->stride;
       src = buffer + i * width;
 
-      switch (psDraw->format) {
+      switch (ptDraw->format) {
       case PIPE_FORMAT_S8Z24_UNORM:
          {
             uint *dst4 = (uint *) dst;
@@ -942,6 +866,16 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
             }
          }
          break;
+      case PIPE_FORMAT_Z24S8_UNORM:
+         {
+            uint *dst4 = (uint *) dst;
+            int j;
+            for (j = 0; j < width; j++) {
+               *dst4 = (*dst4 & 0xffffff00) | (src[j] & 0xff);
+               dst4++;
+            }
+         }
+         break;
       case PIPE_FORMAT_S8_UNORM:
          memcpy(dst, src, width);
          break;
@@ -950,11 +884,11 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
       }
    }
 
-   free(buffer);
+   _mesa_free(buffer);
 
    /* unmap the stencil buffer */
-   screen->surface_unmap(screen, psDraw);
-   pipe_surface_reference(&psDraw, NULL);
+   screen->transfer_unmap(screen, ptDraw);
+   screen->tex_transfer_destroy(ptDraw);
 }
 
 
@@ -969,7 +903,6 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
    struct st_renderbuffer *rbRead;
    struct st_vertex_program *stvp;
    struct st_fragment_program *stfp;
-   struct pipe_surface *psTex;
    struct pipe_texture *pt;
    GLfloat *color;
    enum pipe_format srcFormat, texFormat;
@@ -1021,7 +954,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
    }
 
    pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, texFormat, 0,
-                          width, height, 1, 0,
+                          width, height, 1,
                           PIPE_TEXTURE_USAGE_SAMPLER);
    if (!pt)
       return;
@@ -1035,45 +968,47 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
       struct pipe_surface *psRead = screen->get_tex_surface(screen,
                                        rbRead->texture, 0, 0, 0,
                                        PIPE_BUFFER_USAGE_GPU_READ);
-      psTex = screen->get_tex_surface(screen, pt, 0, 0, 0, 
+      struct pipe_surface *psTex = screen->get_tex_surface(screen, pt, 0, 0, 0, 
                                       PIPE_BUFFER_USAGE_GPU_WRITE );
       pipe->surface_copy(pipe,
-                         FALSE,
                         psTex, /* dest */
                         0, 0, /* destx/y */
                         psRead,
                         srcx, srcy, width, height);
-      pipe_surface_reference(&psRead, NULL);
+      pipe_surface_reference(&psRead, NULL); 
+      pipe_surface_reference(&psTex, NULL);
    }
    else {
       /* CPU-based fallback/conversion */
-      struct pipe_surface *psRead = screen->get_tex_surface(screen,
-                                       rbRead->texture, 0, 0, 0,
-                                       PIPE_BUFFER_USAGE_CPU_READ);
+      struct pipe_transfer *ptRead =
+         screen->get_tex_transfer(screen, rbRead->texture, 0, 0, 0,
+                                  PIPE_TRANSFER_READ, srcx, srcy, width,
+                                  height);
 
-      psTex = screen->get_tex_surface(screen, pt, 0, 0, 0, 
-                                      PIPE_BUFFER_USAGE_CPU_WRITE );
+      struct pipe_transfer *ptTex =
+         screen->get_tex_transfer(screen, pt, 0, 0, 0, PIPE_TRANSFER_WRITE,
+                                  0, 0, width, height);
 
       if (type == GL_COLOR) {
          /* alternate path using get/put_tile() */
-         GLfloat *buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
+         GLfloat *buf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
 
-         pipe_get_tile_rgba(psRead, srcx, srcy, width, height, buf);
-         pipe_put_tile_rgba(psTex, 0, 0, width, height, buf);
+         pipe_get_tile_rgba(ptRead, 0, 0, width, height, buf);
+         pipe_put_tile_rgba(ptTex, 0, 0, width, height, buf);
 
-         free(buf);
+         _mesa_free(buf);
       }
       else {
          /* GL_DEPTH */
-         GLuint *buf = (GLuint *) malloc(width * height * sizeof(GLuint));
-         pipe_get_tile_z(psRead, srcx, srcy, width, height, buf);
-         pipe_put_tile_z(psTex, 0, 0, width, height, buf);
-         free(buf);
+         GLuint *buf = (GLuint *) _mesa_malloc(width * height * sizeof(GLuint));
+         pipe_get_tile_z(ptRead, 0, 0, width, height, buf);
+         pipe_put_tile_z(ptTex, 0, 0, width, height, buf);
+         _mesa_free(buf);
       }
-      pipe_surface_reference(&psRead, NULL);
-   }
 
-   pipe_surface_reference(&psTex, NULL);
+      screen->tex_transfer_destroy(ptRead);
+      screen->tex_transfer_destroy(ptTex);
+   }
 
    /* draw textured quad */
    draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2],
@@ -1100,5 +1035,3 @@ st_destroy_drawpix(struct st_context *st)
    st_reference_vertprog(st, &st->drawpix.vert_shaders[0], NULL);
    st_reference_vertprog(st, &st->drawpix.vert_shaders[1], NULL);
 }
-
-