Merge branch 'mesa_7_7_branch'
[mesa.git] / src / gallium / auxiliary / util / u_rect.c
index 30f32413d79217949ccc0751d7cd0795ea92cfbf..298fbacecbae7c09411cf6b32e9bd55ab856cb2f 100644 (file)
@@ -34,6 +34,7 @@
 #include "pipe/p_format.h"
 #include "pipe/p_context.h"
 #include "pipe/p_screen.h"
+#include "util/u_format.h"
 #include "util/u_rect.h"
 
 
@@ -43,8 +44,8 @@
  * src_pitch may be negative to do vertical flip of pixels from source.
  */
 void
-pipe_copy_rect(ubyte * dst,
-               const struct pipe_format_block *block,
+util_copy_rect(ubyte * dst,
+               enum pipe_format format,
                unsigned dst_stride,
                unsigned dst_x,
                unsigned dst_y,
@@ -57,27 +58,30 @@ pipe_copy_rect(ubyte * dst,
 {
    unsigned i;
    int src_stride_pos = src_stride < 0 ? -src_stride : src_stride;
+   int blocksize = util_format_get_blocksize(format);
+   int blockwidth = util_format_get_blockwidth(format);
+   int blockheight = util_format_get_blockheight(format);
 
-   assert(block->size > 0);
-   assert(block->width > 0);
-   assert(block->height > 0);
+   assert(blocksize > 0);
+   assert(blockwidth > 0);
+   assert(blockheight > 0);
    assert(src_x >= 0);
    assert(src_y >= 0);
    assert(dst_x >= 0);
    assert(dst_y >= 0);
 
-   dst_x /= block->width;
-   dst_y /= block->height;
-   width = (width + block->width - 1)/block->width;
-   height = (height + block->height - 1)/block->height;
-   src_x /= block->width;
-   src_y /= block->height;
+   dst_x /= blockwidth;
+   dst_y /= blockheight;
+   width = (width + blockwidth - 1)/blockwidth;
+   height = (height + blockheight - 1)/blockheight;
+   src_x /= blockwidth;
+   src_y /= blockheight;
    
-   dst += dst_x * block->size;
-   src += src_x * block->size;
+   dst += dst_x * blocksize;
+   src += src_x * blocksize;
    dst += dst_y * dst_stride;
    src += src_y * src_stride_pos;
-   width *= block->size;
+   width *= blocksize;
 
    if (width == dst_stride && width == src_stride)
       memcpy(dst, src, height * width);
@@ -91,8 +95,8 @@ pipe_copy_rect(ubyte * dst,
 }
 
 void
-pipe_fill_rect(ubyte * dst,
-               const struct pipe_format_block *block,
+util_fill_rect(ubyte * dst,
+               enum pipe_format format,
                unsigned dst_stride,
                unsigned dst_x,
                unsigned dst_y,
@@ -102,23 +106,26 @@ pipe_fill_rect(ubyte * dst,
 {
    unsigned i, j;
    unsigned width_size;
+   int blocksize = util_format_get_blocksize(format);
+   int blockwidth = util_format_get_blockwidth(format);
+   int blockheight = util_format_get_blockheight(format);
 
-   assert(block->size > 0);
-   assert(block->width > 0);
-   assert(block->height > 0);
+   assert(blocksize > 0);
+   assert(blockwidth > 0);
+   assert(blockheight > 0);
    assert(dst_x >= 0);
    assert(dst_y >= 0);
 
-   dst_x /= block->width;
-   dst_y /= block->height;
-   width = (width + block->width - 1)/block->width;
-   height = (height + block->height - 1)/block->height;
+   dst_x /= blockwidth;
+   dst_y /= blockheight;
+   width = (width + blockwidth - 1)/blockwidth;
+   height = (height + blockheight - 1)/blockheight;
    
-   dst += dst_x * block->size;
+   dst += dst_x * blocksize;
    dst += dst_y * dst_stride;
-   width_size = width * block->size;
+   width_size = width * blocksize;
    
-   switch (block->size) {
+   switch (blocksize) {
    case 1:
       if(dst_stride == width_size)
         memset(dst, (ubyte) value, height * width_size);
@@ -169,83 +176,66 @@ util_surface_copy(struct pipe_context *pipe,
                   unsigned w, unsigned h)
 {
    struct pipe_screen *screen = pipe->screen;
-   struct pipe_surface *new_src = NULL, *new_dst = NULL;
+   struct pipe_transfer *src_trans, *dst_trans;
    void *dst_map;
    const void *src_map;
+   enum pipe_format src_format, dst_format;
 
-   assert(dst->block.size == src->block.size);
-   assert(dst->block.width == src->block.width);
-   assert(dst->block.height == src->block.height);
+   assert(src->texture && dst->texture);
+   if (!src->texture || !dst->texture)
+      return;
 
-   if ((src->usage & PIPE_BUFFER_USAGE_CPU_READ) == 0) {
-      /* Need to create new src surface which is CPU readable */
-      assert(src->texture);
-      if (!src->texture)
-         return;
-      new_src = screen->get_tex_surface(screen,
+   src_format = src->texture->format;
+   dst_format = dst->texture->format;
+
+   src_trans = screen->get_tex_transfer(screen,
                                         src->texture,
                                         src->face,
                                         src->level,
                                         src->zslice,
-                                        PIPE_BUFFER_USAGE_CPU_READ);
-      src = new_src;
-   }
+                                        PIPE_TRANSFER_READ,
+                                        src_x, src_y, w, h);
 
-   if ((dst->usage & PIPE_BUFFER_USAGE_CPU_WRITE) == 0) {
-      /* Need to create new dst surface which is CPU writable */
-      assert(dst->texture);
-      if (!dst->texture)
-         return;
-      new_dst = screen->get_tex_surface(screen,
+   dst_trans = screen->get_tex_transfer(screen,
                                         dst->texture,
                                         dst->face,
                                         dst->level,
                                         dst->zslice,
-                                        PIPE_BUFFER_USAGE_CPU_WRITE);
-      dst = new_dst;
-   }
+                                        PIPE_TRANSFER_WRITE,
+                                        dst_x, dst_y, w, h);
 
-   src_map = pipe->screen->surface_map(screen,
-                                       src, PIPE_BUFFER_USAGE_CPU_READ);
-   dst_map = pipe->screen->surface_map(screen,
-                                       dst, PIPE_BUFFER_USAGE_CPU_WRITE);
+   assert(util_format_get_blocksize(dst_format) == util_format_get_blocksize(src_format));
+   assert(util_format_get_blockwidth(dst_format) == util_format_get_blockwidth(src_format));
+   assert(util_format_get_blockheight(dst_format) == util_format_get_blockheight(src_format));
+
+   src_map = pipe->screen->transfer_map(screen, src_trans);
+   dst_map = pipe->screen->transfer_map(screen, dst_trans);
 
    assert(src_map);
    assert(dst_map);
 
    if (src_map && dst_map) {
       /* If do_flip, invert src_y position and pass negative src stride */
-      pipe_copy_rect(dst_map,
-                     &dst->block,
-                     dst->stride,
-                     dst_x, dst_y,
+      util_copy_rect(dst_map,
+                     dst_format,
+                     dst_trans->stride,
+                     0, 0,
                      w, h,
                      src_map,
-                     do_flip ? -(int) src->stride : src->stride,
-                     src_x,
-                     do_flip ? w - src_y : src_y);
+                     do_flip ? -(int) src_trans->stride : src_trans->stride,
+                     0,
+                     do_flip ? h - 1 : 0);
    }
 
-   pipe->screen->surface_unmap(pipe->screen, src);
-   pipe->screen->surface_unmap(pipe->screen, dst);
+   pipe->screen->transfer_unmap(pipe->screen, src_trans);
+   pipe->screen->transfer_unmap(pipe->screen, dst_trans);
 
-   if (new_src)
-      screen->tex_surface_release(screen, &new_src);
-   if (new_dst)
-      screen->tex_surface_release(screen, &new_dst);
+   screen->tex_transfer_destroy(src_trans);
+   screen->tex_transfer_destroy(dst_trans);
 }
 
 
 
-static void *
-get_pointer(struct pipe_surface *dst, void *dst_map, unsigned x, unsigned y)
-{
-   return (char *)dst_map
-      + y / dst->block.height * dst->stride
-      + x / dst->block.width * dst->block.size;
-}
-
-
 #define UBYTE_TO_USHORT(B) ((B) | ((B) << 8))
 
 
@@ -260,42 +250,38 @@ util_surface_fill(struct pipe_context *pipe,
                   unsigned width, unsigned height, unsigned value)
 {
    struct pipe_screen *screen = pipe->screen;
-   struct pipe_surface *new_dst = NULL;
+   struct pipe_transfer *dst_trans;
    void *dst_map;
 
-   if ((dst->usage & PIPE_BUFFER_USAGE_CPU_WRITE) == 0) {
-      /* Need to create new dst surface which is CPU writable */
-      assert(dst->texture);
-      if (!dst->texture)
-         return;
-      new_dst = screen->get_tex_surface(screen,
+   assert(dst->texture);
+   if (!dst->texture)
+      return;
+   dst_trans = screen->get_tex_transfer(screen,
                                         dst->texture,
                                         dst->face,
                                         dst->level,
                                         dst->zslice,
-                                        PIPE_BUFFER_USAGE_CPU_WRITE);
-      dst = new_dst;
-   }
+                                        PIPE_TRANSFER_WRITE,
+                                        dstx, dsty, width, height);
 
-   dst_map = pipe->screen->surface_map(screen,
-                                       dst, PIPE_BUFFER_USAGE_CPU_WRITE);
+   dst_map = pipe->screen->transfer_map(screen, dst_trans);
 
    assert(dst_map);
 
    if (dst_map) {
-      assert(dst->stride > 0);
+      assert(dst_trans->stride > 0);
 
-      switch (dst->block.size) {
+      switch (util_format_get_blocksize(dst_trans->texture->format)) {
       case 1:
       case 2:
       case 4:
-         pipe_fill_rect(dst_map, &dst->block, dst->stride,
-                        dstx, dsty, width, height, value);
+         util_fill_rect(dst_map, dst_trans->texture->format, dst_trans->stride,
+                        0, 0, width, height, value);
          break;
       case 8:
          {
             /* expand the 4-byte clear value to an 8-byte value */
-            ushort *row = (ushort *) get_pointer(dst, dst_map, dstx, dsty);
+            ushort *row = (ushort *) dst_map;
             ushort val0 = UBYTE_TO_USHORT((value >>  0) & 0xff);
             ushort val1 = UBYTE_TO_USHORT((value >>  8) & 0xff);
             ushort val2 = UBYTE_TO_USHORT((value >> 16) & 0xff);
@@ -312,7 +298,7 @@ util_surface_fill(struct pipe_context *pipe,
                   row[j*4+2] = val2;
                   row[j*4+3] = val3;
                }
-               row += dst->stride/2;
+               row += dst_trans->stride/2;
             }
          }
          break;
@@ -322,8 +308,6 @@ util_surface_fill(struct pipe_context *pipe,
       }
    }
 
-   pipe->screen->surface_unmap(pipe->screen, dst);
-
-   if (new_dst)
-      screen->tex_surface_release(screen, &new_dst);
+   pipe->screen->transfer_unmap(pipe->screen, dst_trans);
+   screen->tex_transfer_destroy(dst_trans);
 }