Merge branch '7.8'
[mesa.git] / src / gallium / auxiliary / util / u_rect.c
index fe81a685be114b5be1dade934b92e459f98582ed..e73797f1b7e62d64a7837619a777472d9c0d0f71 100644 (file)
 #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"
 
 
 /**
  * Copy 2D rect from one place to another.
  * Position and sizes are in pixels.
- * src_pitch may be negative to do vertical flip of pixels from source.
+ * src_stride 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,
@@ -53,31 +54,30 @@ pipe_copy_rect(ubyte * dst,
                const ubyte * src,
                int src_stride,
                unsigned src_x, 
-               int src_y)
+               unsigned src_y)
 {
    unsigned i;
    int src_stride_pos = src_stride < 0 ? -src_stride : src_stride;
-
-   assert(block->size > 0);
-   assert(block->width > 0);
-   assert(block->height > 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;
+   int blocksize = util_format_get_blocksize(format);
+   int blockwidth = util_format_get_blockwidth(format);
+   int blockheight = util_format_get_blockheight(format);
+
+   assert(blocksize > 0);
+   assert(blockwidth > 0);
+   assert(blockheight > 0);
+
+   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 +91,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 +102,24 @@ pipe_fill_rect(ubyte * dst,
 {
    unsigned i, j;
    unsigned width_size;
-
-   assert(block->size > 0);
-   assert(block->width > 0);
-   assert(block->height > 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;
+   int blocksize = util_format_get_blocksize(format);
+   int blockwidth = util_format_get_blockwidth(format);
+   int blockheight = util_format_get_blockheight(format);
+
+   assert(blocksize > 0);
+   assert(blockwidth > 0);
+   assert(blockheight > 0);
+
+   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);
@@ -168,84 +169,66 @@ util_surface_copy(struct pipe_context *pipe,
                   unsigned src_x, unsigned src_y, 
                   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(src->texture && dst->texture);
+   if (!src->texture || !dst->texture)
+      return;
 
-   assert(dst->block.size == src->block.size);
-   assert(dst->block.width == src->block.width);
-   assert(dst->block.height == src->block.height);
+   src_format = src->texture->format;
+   dst_format = dst->texture->format;
 
-   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_trans = pipe->get_tex_transfer(pipe,
                                         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 = pipe->get_tex_transfer(pipe,
                                         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);
+
+   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->surface_map(screen,
-                                       src, PIPE_BUFFER_USAGE_CPU_READ);
-   dst_map = pipe->screen->surface_map(screen,
-                                       dst, PIPE_BUFFER_USAGE_CPU_WRITE);
+   src_map = pipe->transfer_map(pipe, src_trans);
+   dst_map = pipe->transfer_map(pipe, 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 ? src_y + h - 1 : 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->transfer_unmap(pipe, src_trans);
+   pipe->transfer_unmap(pipe, dst_trans);
 
-   if (new_src)
-      screen->tex_surface_release(screen, &new_src);
-   if (new_dst)
-      screen->tex_surface_release(screen, &new_dst);
+   pipe->tex_transfer_destroy(pipe, src_trans);
+   pipe->tex_transfer_destroy(pipe, 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))
 
 
@@ -259,43 +242,38 @@ util_surface_fill(struct pipe_context *pipe,
                   unsigned dstx, unsigned dsty,
                   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 = pipe->get_tex_transfer(pipe,
                                         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->transfer_map(pipe, 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 +290,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 +300,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->transfer_unmap(pipe, dst_trans);
+   pipe->tex_transfer_destroy(pipe, dst_trans);
 }