Move dimensions from struct pipe_region to struct pipe_surface.
authorMichel Dänzer <michel@tungstengraphics.com>
Wed, 28 Nov 2007 18:04:54 +0000 (19:04 +0100)
committerMichel Dänzer <michel@tungstengraphics.com>
Thu, 29 Nov 2007 15:41:39 +0000 (16:41 +0100)
21 files changed:
src/mesa/drivers/dri/intel_winsys/intel_swapbuffers.c
src/mesa/drivers/dri/intel_winsys/intel_winsys_pipe.c
src/mesa/pipe/failover/fo_context.c
src/mesa/pipe/i915simple/i915_clear.c
src/mesa/pipe/i915simple/i915_regions.c
src/mesa/pipe/i915simple/i915_state_emit.c
src/mesa/pipe/i915simple/i915_surface.c
src/mesa/pipe/p_context.h
src/mesa/pipe/p_state.h
src/mesa/pipe/p_winsys.h
src/mesa/pipe/softpipe/sp_clear.c
src/mesa/pipe/softpipe/sp_region.c
src/mesa/pipe/softpipe/sp_surface.c
src/mesa/pipe/xlib/xm_buffer.c
src/mesa/pipe/xlib/xm_surface.c
src/mesa/pipe/xlib/xm_winsys.c
src/mesa/state_tracker/st_cb_drawpixels.c
src/mesa/state_tracker/st_cb_fbo.c
src/mesa/state_tracker/st_cb_readpixels.c
src/mesa/state_tracker/st_cb_texture.c
src/mesa/state_tracker/st_mipmap_tree.c

index 9fcb2dac27314fb22bb0b4ddb02f5cb8dd483c9e..f96209d1b06ba888a0083236850a3aace38f844e 100644 (file)
@@ -89,15 +89,15 @@ intelDisplaySurface(__DRIdrawablePrivate *dPriv,
       const int pitch = intelScreen->front.pitch / intelScreen->front.cpp;
       const int cpp = intelScreen->front.cpp;
       const struct pipe_region *srcRegion = surf->region;
-      const int srcpitch = srcRegion->pitch;
+      const int srcpitch = surf->pitch;
       int BR13, CMD;
       int i;
 
       ASSERT(srcRegion);
-      ASSERT(srcRegion->cpp == cpp);
+      ASSERT(surf->cpp == cpp);
 
       DBG(SWAP, "screen pitch %d  src surface pitch %d\n",
-         pitch, srcRegion->pitch);
+         pitch, surf->pitch);
 
       if (cpp == 2) {
         BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24);
index ae02f98a783fcd7772e9be7bb69d6008e080443e..7b3aa9948241613abb3bc3eac89bd191ef132e1d 100644 (file)
@@ -173,14 +173,10 @@ intel_flush_frontbuffer( struct pipe_winsys *winsys,
 }
 
 
-static struct pipe_region *
-intel_i915_region_alloc(struct pipe_winsys *winsys,
-                        unsigned cpp, unsigned width,
-                        unsigned height, unsigned flags)
+static unsigned
+intel_i915_surface_pitch(struct pipe_winsys *winsys,
+                        unsigned cpp, unsigned width, unsigned flags)
 {
-   struct pipe_region *region = calloc(sizeof(*region), 1);
-   const unsigned alignment = 64;
-
    /* Choose a pitch to match hardware requirements - requires 64 byte
     * alignment of render targets.  
     *
@@ -188,24 +184,29 @@ intel_i915_region_alloc(struct pipe_winsys *winsys,
     * clearly want to be able to render to textures under some
     * circumstances, but maybe not always a requirement.
     */
-   unsigned pitch;
 
    /* XXX is the pitch different for textures vs. drawables? */
    if (flags & PIPE_SURFACE_FLAG_TEXTURE)  /* or PIPE_SURFACE_FLAG_RENDER? */
-      pitch = ((cpp * width + 63) & ~63) / cpp;
+      return ((cpp * width + 63) & ~63) / cpp;
    else
-      pitch = ((cpp * width + 63) & ~63) / cpp;
+      return ((cpp * width + 63) & ~63) / cpp;
+}
+
+
+static struct pipe_region *
+intel_i915_region_alloc(struct pipe_winsys *winsys,
+                        unsigned size, unsigned flags)
+{
+   struct pipe_region *region = calloc(sizeof(*region), 1);
+   const unsigned alignment = 64;
 
-   region->cpp = cpp;
-   region->pitch = pitch;
-   region->height = height;     /* needed? */
    region->refcount = 1;
 
    region->buffer = winsys->buffer_create( winsys, alignment );
 
    winsys->buffer_data( winsys,
                         region->buffer, 
-                        pitch * cpp * height
+                        size
                         NULL,
                         PIPE_BUFFER_USAGE_PIXEL );
 
@@ -301,6 +302,7 @@ intel_create_pipe_winsys( int fd )
    iws->winsys.get_name = intel_get_name;
    iws->winsys.region_alloc = intel_i915_region_alloc;
    iws->winsys.region_release = intel_i915_region_release;
+   iws->winsys.surface_pitch = intel_i915_surface_pitch;
    iws->winsys.surface_alloc = intel_i915_surface_alloc;
    iws->winsys.surface_release = intel_i915_surface_release;
 
index c5fab73fb137dcfd8a93d1a9f67436c24be7917d..0cc9cab408c99003d4b4babce268449067d895ff 100644 (file)
@@ -142,9 +142,9 @@ struct pipe_context *failover_create( struct pipe_context *hw,
 
    failover->pipe.region_map = hw->region_map;
    failover->pipe.region_unmap = hw->region_unmap;
-   failover->pipe.region_data = hw->region_data;
-   failover->pipe.region_copy = hw->region_copy;
-   failover->pipe.region_fill = hw->region_fill;
+   failover->pipe.surface_data = hw->surface_data;
+   failover->pipe.surface_copy = hw->surface_copy;
+   failover->pipe.surface_fill = hw->surface_fill;
    failover->pipe.mipmap_tree_layout = hw->mipmap_tree_layout;
    failover->pipe.flush = hw->flush;
 
index e8087df5a473c28e210981ba1c7b0cc2736e2e53..cde69daacc08ddd8447e21e7c7fbd8167accd8d3 100644 (file)
@@ -43,12 +43,5 @@ void
 i915_clear(struct pipe_context *pipe, struct pipe_surface *ps,
           unsigned clearValue)
 {
-   int x, y, w, h;
-
-   x = 0;
-   y = 0;
-   w = ps->width;
-   h = ps->height;
-
-   pipe->region_fill(pipe, ps->region, 0, x, y, w, h, clearValue);
+   pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue);
 }
index e8c4c92bc885818035d097177067bc67b14bac0e..82fdec83d095bc4ced8f7d8d9bb81dfcb84aac86 100644 (file)
@@ -34,7 +34,6 @@
 #include "pipe/p_defines.h"
 #include "pipe/p_winsys.h"
 #include "i915_context.h"
-#include "i915_blit.h"
 
 
 
@@ -70,181 +69,10 @@ i915_region_unmap(struct pipe_context *pipe, struct pipe_region *region)
 }
 
 
-/*
- * XXX Move this into core Mesa?
- */
-static void
-_mesa_copy_rect(ubyte * dst,
-                unsigned cpp,
-                unsigned dst_pitch,
-                unsigned dst_x,
-                unsigned dst_y,
-                unsigned width,
-                unsigned height,
-                const ubyte * src,
-                unsigned src_pitch,
-               unsigned src_x, 
-               unsigned src_y)
-{
-   unsigned i;
-
-   dst_pitch *= cpp;
-   src_pitch *= cpp;
-   dst += dst_x * cpp;
-   src += src_x * cpp;
-   dst += dst_y * dst_pitch;
-   src += src_y * dst_pitch;
-   width *= cpp;
-
-   if (width == dst_pitch && width == src_pitch)
-      memcpy(dst, src, height * width);
-   else {
-      for (i = 0; i < height; i++) {
-         memcpy(dst, src, width);
-         dst += dst_pitch;
-         src += src_pitch;
-      }
-   }
-}
-
-
-/* Upload data to a rectangular sub-region.  Lots of choices how to do this:
- *
- * - memcpy by span to current destination
- * - upload data as new buffer and blit
- *
- * Currently always memcpy.
- */
-static void
-i915_region_data(struct pipe_context *pipe,
-              struct pipe_region *dst,
-              unsigned dst_offset,
-              unsigned dstx, unsigned dsty,
-              const void *src, unsigned src_pitch,
-              unsigned srcx, unsigned srcy, unsigned width, unsigned height)
-{
-   _mesa_copy_rect(pipe->region_map(pipe, dst) + dst_offset,
-                   dst->cpp,
-                   dst->pitch,
-                   dstx, dsty, width, height, src, src_pitch, srcx, srcy);
-
-   pipe->region_unmap(pipe, dst);
-}
-
-
-/* Assumes all values are within bounds -- no checking at this level -
- * do it higher up if required.
- */
-static void
-i915_region_copy(struct pipe_context *pipe,
-              struct pipe_region *dst,
-              unsigned dst_offset,
-              unsigned dstx, unsigned dsty,
-              struct pipe_region *src,
-              unsigned src_offset,
-              unsigned srcx, unsigned srcy, unsigned width, unsigned height)
-{
-   assert( dst != src );
-   assert( dst->cpp == src->cpp );
-
-   if (0) {
-      _mesa_copy_rect(pipe->region_map(pipe, dst) + dst_offset,
-                     dst->cpp,
-                     dst->pitch,
-                     dstx, dsty, 
-                     width, height, 
-                     pipe->region_map(pipe, src) + src_offset, 
-                     src->pitch, 
-                     srcx, srcy);
-
-      pipe->region_unmap(pipe, src);
-      pipe->region_unmap(pipe, dst);
-   }
-   else {
-      i915_copy_blit( i915_context(pipe),
-                     dst->cpp,
-                     (short) src->pitch, src->buffer, src_offset,
-                     (short) dst->pitch, dst->buffer, dst_offset,
-                     (short) srcx, (short) srcy, (short) dstx, (short) dsty, (short) width, (short) height );
-   }
-}
-
-/* Fill a rectangular sub-region.  Need better logic about when to
- * push buffers into AGP - will currently do so whenever possible.
- */
-static ubyte *
-get_pointer(struct pipe_region *dst, unsigned x, unsigned y)
-{
-   return dst->map + (y * dst->pitch + x) * dst->cpp;
-}
-
-
-static void
-i915_region_fill(struct pipe_context *pipe,
-               struct pipe_region *dst,
-               unsigned dst_offset,
-               unsigned dstx, unsigned dsty,
-               unsigned width, unsigned height, unsigned value)
-{
-   if (0) {
-      unsigned i, j;
-
-      (void)pipe->region_map(pipe, dst);
-
-      switch (dst->cpp) {
-      case 1: {
-        ubyte *row = get_pointer(dst, dstx, dsty);
-        for (i = 0; i < height; i++) {
-           memset(row, value, width);
-           row += dst->pitch;
-        }
-      }
-        break;
-      case 2: {
-        ushort *row = (ushort *) get_pointer(dst, dstx, dsty);
-        for (i = 0; i < height; i++) {
-           for (j = 0; j < width; j++)
-              row[j] = (ushort) value;
-           row += dst->pitch;
-        }
-      }
-        break;
-      case 4: {
-        unsigned *row = (unsigned *) get_pointer(dst, dstx, dsty);
-        for (i = 0; i < height; i++) {
-           for (j = 0; j < width; j++)
-              row[j] = value;
-           row += dst->pitch;
-        }
-      }
-        break;
-      default:
-        assert(0);
-        break;
-      }
-   }
-   else {
-      i915_fill_blit( i915_context(pipe),
-                     dst->cpp,
-                     (short) dst->pitch, 
-                     dst->buffer, dst_offset,
-                     (short) dstx, (short) dsty, 
-                     (short) width, (short) height, 
-                     value );
-   }
-}
-
-
-
-
-
 void
 i915_init_region_functions(struct i915_context *i915)
 {
    i915->pipe.region_map = i915_region_map;
    i915->pipe.region_unmap = i915_region_unmap;
-   i915->pipe.region_data = i915_region_data;
-   i915->pipe.region_copy = i915_region_copy;
-   i915->pipe.region_fill = i915_region_fill;
 }
 
index d793e92a14d8d935e08f2349d2f183bfa0ff5b8f..900a91d8963fb562099d12800211e433af003ffd 100644 (file)
@@ -208,10 +208,11 @@ i915_emit_hardware_state(struct i915_context *i915 )
    /* 8 dwords, 2 relocs */
    if (i915->hardware_dirty & I915_HW_STATIC)
    {
-      if (i915->framebuffer.cbufs[0]) {
-        struct pipe_region *cbuf_region = i915->framebuffer.cbufs[0]->region;
-        unsigned pitch = (cbuf_region->pitch *
-                          cbuf_region->cpp);
+      struct pipe_surface *cbuf_surface = i915->framebuffer.cbufs[0];
+      struct pipe_surface *depth_surface = i915->framebuffer.zbuf;
+
+      if (cbuf_surface) {
+        unsigned pitch = (cbuf_surface->pitch * cbuf_surface->cpp);
 
         OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
 
@@ -219,17 +220,15 @@ i915_emit_hardware_state(struct i915_context *i915 )
                   BUF_3D_PITCH(pitch) |  /* pitch in bytes */
                   BUF_3D_USE_FENCE);
 
-        OUT_RELOC(cbuf_region->buffer,
+        OUT_RELOC(cbuf_surface->region->buffer,
                   I915_BUFFER_ACCESS_WRITE,
                   0);
       }
 
       /* What happens if no zbuf??
        */
-      if (i915->framebuffer.zbuf) {
-        struct pipe_region *depth_region = i915->framebuffer.zbuf->region;
-        unsigned zpitch = (depth_region->pitch *
-                           depth_region->cpp);
+      if (depth_surface) {
+        unsigned zpitch = (depth_surface->pitch * depth_surface->cpp);
                         
         OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
 
@@ -237,7 +236,7 @@ i915_emit_hardware_state(struct i915_context *i915 )
                   BUF_3D_PITCH(zpitch) |  /* pitch in bytes */
                   BUF_3D_USE_FENCE);
 
-        OUT_RELOC(depth_region->buffer,
+        OUT_RELOC(depth_surface->region->buffer,
                   I915_BUFFER_ACCESS_WRITE,
                   0);
       }
@@ -245,13 +244,13 @@ i915_emit_hardware_state(struct i915_context *i915 )
       {
         unsigned cformat, zformat = 0;
       
-        if (i915->framebuffer.cbufs[0])
-            cformat = i915->framebuffer.cbufs[0]->format;
+        if (cbuf_surface)
+            cformat = cbuf_surface->format;
          else
             cformat = PIPE_FORMAT_U_A8_R8_G8_B8; /* arbitrary */
          cformat = translate_format(cformat);
 
-        if (i915->framebuffer.zbuf
+        if (depth_surface
            zformat = translate_depth_format( i915->framebuffer.zbuf->format );
 
         OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD);
index bec7ddb731924b2a3eab3a1940c6c232b5cd48e2..e4a5de00d776049493ca51a81322dce4dbb4ada9 100644 (file)
@@ -26,6 +26,7 @@
  **************************************************************************/
 
 #include "i915_context.h"
+#include "i915_blit.h"
 #include "i915_state.h"
 #include "pipe/p_defines.h"
 #include "pipe/p_util.h"
@@ -57,7 +58,7 @@ i915_get_tile_rgba(struct pipe_context *pipe,
 {
    const unsigned *src
       = ((const unsigned *) (ps->region->map + ps->offset))
-      + y * ps->region->pitch + x;
+      + y * ps->pitch + x;
    unsigned i, j;
    unsigned w0 = w;
 
@@ -75,7 +76,7 @@ i915_get_tile_rgba(struct pipe_context *pipe,
             pRow[3] = UBYTE_TO_FLOAT((pixel >> 24) & 0xff);
             pRow += 4;
          }
-         src += ps->region->pitch;
+         src += ps->pitch;
          p += w0 * 4;
       }
       break;
@@ -92,7 +93,7 @@ i915_get_tile_rgba(struct pipe_context *pipe,
                pRow[3] = (pixel & 0xffffff) * scale;
                pRow += 4;
             }
-            src += ps->region->pitch;
+            src += ps->pitch;
             p += w0 * 4;
          }
       }
@@ -122,7 +123,7 @@ i915_get_tile(struct pipe_context *pipe,
               uint x, uint y, uint w, uint h,
               void *p, int dst_stride)
 {
-   const uint cpp = ps->region->cpp;
+   const uint cpp = ps->cpp;
    const uint w0 = w;
    const ubyte *pSrc;
    ubyte *pDest;
@@ -136,13 +137,13 @@ i915_get_tile(struct pipe_context *pipe,
       dst_stride = w0 * cpp;
    }
 
-   pSrc = ps->region->map + ps->offset + (y * ps->region->pitch + x) * cpp;
+   pSrc = ps->region->map + ps->offset + (y * ps->pitch + x) * cpp;
    pDest = (ubyte *) p;
 
    for (i = 0; i < h; i++) {
       memcpy(pDest, pSrc, w0 * cpp);
       pDest += dst_stride;
-      pSrc += ps->region->pitch * cpp;
+      pSrc += ps->pitch * cpp;
    }
 }
 
@@ -156,7 +157,7 @@ i915_put_tile(struct pipe_context *pipe,
               uint x, uint y, uint w, uint h,
               const void *p, int src_stride)
 {
-   const uint cpp = ps->region->cpp;
+   const uint cpp = ps->cpp;
    const uint w0 = w;
    const ubyte *pSrc;
    ubyte *pDest;
@@ -171,11 +172,11 @@ i915_put_tile(struct pipe_context *pipe,
    }
 
    pSrc = (const ubyte *) p;
-   pDest = ps->region->map + ps->offset + (y * ps->region->pitch + x) * cpp;
+   pDest = ps->region->map + ps->offset + (y * ps->pitch + x) * cpp;
 
    for (i = 0; i < h; i++) {
       memcpy(pDest, pSrc, w0 * cpp);
-      pDest += ps->region->pitch * cpp;
+      pDest += ps->pitch * cpp;
       pSrc += src_stride;
    }
 }
@@ -210,14 +211,177 @@ i915_get_tex_surface(struct pipe_context *pipe,
       assert(ps->format);
       assert(ps->refcount);
       pipe_region_reference(&ps->region, mt->region);
+      ps->cpp = mt->cpp;
       ps->width = mt->level[level].width;
       ps->height = mt->level[level].height;
+      ps->pitch = mt->pitch;
       ps->offset = offset;
    }
    return ps;
 }
 
 
+/*
+ * XXX Move this into core Mesa?
+ */
+static void
+_mesa_copy_rect(ubyte * dst,
+                unsigned cpp,
+                unsigned dst_pitch,
+                unsigned dst_x,
+                unsigned dst_y,
+                unsigned width,
+                unsigned height,
+                const ubyte * src,
+                unsigned src_pitch,
+               unsigned src_x, 
+               unsigned src_y)
+{
+   unsigned i;
+
+   dst_pitch *= cpp;
+   src_pitch *= cpp;
+   dst += dst_x * cpp;
+   src += src_x * cpp;
+   dst += dst_y * dst_pitch;
+   src += src_y * dst_pitch;
+   width *= cpp;
+
+   if (width == dst_pitch && width == src_pitch)
+      memcpy(dst, src, height * width);
+   else {
+      for (i = 0; i < height; i++) {
+         memcpy(dst, src, width);
+         dst += dst_pitch;
+         src += src_pitch;
+      }
+   }
+}
+
+
+/* Upload data to a rectangular sub-region.  Lots of choices how to do this:
+ *
+ * - memcpy by span to current destination
+ * - upload data as new buffer and blit
+ *
+ * Currently always memcpy.
+ */
+static void
+i915_surface_data(struct pipe_context *pipe,
+                 struct pipe_surface *dst,
+                 unsigned dstx, unsigned dsty,
+                 const void *src, unsigned src_pitch,
+                 unsigned srcx, unsigned srcy, unsigned width, unsigned height)
+{
+   _mesa_copy_rect(pipe->region_map(pipe, dst->region) + dst->offset,
+                   dst->cpp,
+                   dst->pitch,
+                   dstx, dsty, width, height, src, src_pitch, srcx, srcy);
+
+   pipe->region_unmap(pipe, dst->region);
+}
+
+
+/* Assumes all values are within bounds -- no checking at this level -
+ * do it higher up if required.
+ */
+static void
+i915_surface_copy(struct pipe_context *pipe,
+                 struct pipe_surface *dst,
+                 unsigned dstx, unsigned dsty,
+                 struct pipe_surface *src,
+                 unsigned srcx, unsigned srcy, unsigned width, unsigned height)
+{
+   assert( dst != src );
+   assert( dst->cpp == src->cpp );
+
+   if (0) {
+      _mesa_copy_rect(pipe->region_map(pipe, dst->region) + dst->offset,
+                     dst->cpp,
+                     dst->pitch,
+                     dstx, dsty, 
+                     width, height, 
+                     pipe->region_map(pipe, src->region) + src->offset, 
+                     src->pitch, 
+                     srcx, srcy);
+
+      pipe->region_unmap(pipe, src->region);
+      pipe->region_unmap(pipe, dst->region);
+   }
+   else {
+      i915_copy_blit( i915_context(pipe),
+                     dst->cpp,
+                     (short) src->pitch, src->region->buffer, src->offset,
+                     (short) dst->pitch, dst->region->buffer, dst->offset,
+                     (short) srcx, (short) srcy, (short) dstx, (short) dsty, (short) width, (short) height );
+   }
+}
+
+/* Fill a rectangular sub-region.  Need better logic about when to
+ * push buffers into AGP - will currently do so whenever possible.
+ */
+static ubyte *
+get_pointer(struct pipe_surface *dst, unsigned x, unsigned y)
+{
+   return dst->region->map + (y * dst->pitch + x) * dst->cpp;
+}
+
+
+static void
+i915_surface_fill(struct pipe_context *pipe,
+                 struct pipe_surface *dst,
+                 unsigned dstx, unsigned dsty,
+                 unsigned width, unsigned height, unsigned value)
+{
+   if (0) {
+      unsigned i, j;
+
+      (void)pipe->region_map(pipe, dst->region);
+
+      switch (dst->cpp) {
+      case 1: {
+        ubyte *row = get_pointer(dst, dstx, dsty);
+        for (i = 0; i < height; i++) {
+           memset(row, value, width);
+           row += dst->pitch;
+        }
+      }
+        break;
+      case 2: {
+        ushort *row = (ushort *) get_pointer(dst, dstx, dsty);
+        for (i = 0; i < height; i++) {
+           for (j = 0; j < width; j++)
+              row[j] = (ushort) value;
+           row += dst->pitch;
+        }
+      }
+        break;
+      case 4: {
+        unsigned *row = (unsigned *) get_pointer(dst, dstx, dsty);
+        for (i = 0; i < height; i++) {
+           for (j = 0; j < width; j++)
+              row[j] = value;
+           row += dst->pitch;
+        }
+      }
+        break;
+      default:
+        assert(0);
+        break;
+      }
+   }
+   else {
+      i915_fill_blit( i915_context(pipe),
+                     dst->cpp,
+                     (short) dst->pitch, 
+                     dst->region->buffer, dst->offset,
+                     (short) dstx, (short) dsty, 
+                     (short) width, (short) height, 
+                     value );
+   }
+}
+
+
 void
 i915_init_surface_functions(struct i915_context *i915)
 {
@@ -226,4 +390,7 @@ i915_init_surface_functions(struct i915_context *i915)
    i915->pipe.put_tile = i915_put_tile;
    i915->pipe.get_tile_rgba = i915_get_tile_rgba;
    i915->pipe.put_tile_rgba = i915_put_tile_rgba;
+   i915->pipe.surface_data = i915_surface_data;
+   i915->pipe.surface_copy = i915_surface_copy;
+   i915->pipe.surface_fill = i915_surface_fill;
 }
index 8bed958feb38fd5e1f422ef6ff3e393d0fd3fd41..e145b22f2ff6641591fad16e6fbed3d2131fdf22 100644 (file)
@@ -208,30 +208,30 @@ struct pipe_context {
 
    void (*region_unmap)(struct pipe_context *pipe, struct pipe_region *r);
 
-   void (*region_data)(struct pipe_context *pipe,
-                       struct pipe_region *dest,
-                       unsigned dest_offset,
-                       unsigned destx, unsigned desty,
-                       const void *src, unsigned src_stride,
-                       unsigned srcx, unsigned srcy,
-                       unsigned width, unsigned height);
-
-   void (*region_copy)(struct pipe_context *pipe,
-                       struct pipe_region *dest,
-                       unsigned dest_offset,
-                       unsigned destx, unsigned desty,
-                       struct pipe_region *src,        /* don't make this const - 
-                                                  need to map/unmap */
-                       unsigned src_offset,
-                       unsigned srcx, unsigned srcy,
-                       unsigned width, unsigned height);
-
-   void (*region_fill)(struct pipe_context *pipe,
-                       struct pipe_region *dst,
-                       unsigned dst_offset,
-                       unsigned dstx, unsigned dsty,
-                       unsigned width, unsigned height,
-                       unsigned value);
+
+   /*
+    * Surface functions
+    */
+   void (*surface_data)(struct pipe_context *pipe,
+                       struct pipe_surface *dest,
+                       unsigned destx, unsigned desty,
+                       const void *src, unsigned src_stride,
+                       unsigned srcx, unsigned srcy,
+                       unsigned width, unsigned height);
+
+   void (*surface_copy)(struct pipe_context *pipe,
+                       struct pipe_surface *dest,
+                       unsigned destx, unsigned desty,
+                       struct pipe_surface *src, /* don't make this const - 
+                                                    need to map/unmap */
+                       unsigned srcx, unsigned srcy,
+                       unsigned width, unsigned height);
+
+   void (*surface_fill)(struct pipe_context *pipe,
+                       struct pipe_surface *dst,
+                       unsigned dstx, unsigned dsty,
+                       unsigned width, unsigned height,
+                       unsigned value);
 
 
    /*
index 570f44e24ed2a866b2b430c661d1c0904ef232ea..642734aeb807ac5bbc25c558f00d1d37ba8abb1f 100644 (file)
@@ -265,9 +265,6 @@ struct pipe_region
    struct pipe_buffer_handle *buffer; /**< driver private buffer handle */
 
    unsigned refcount; /**< Reference count for region */
-   unsigned cpp;      /**< bytes per pixel */
-   unsigned pitch;    /**< in pixels */
-   unsigned height;   /**< in pixels */
    ubyte *map;    /**< only non-NULL when region is actually mapped */
    unsigned map_refcount;  /**< Reference count for mapping */
 };
@@ -281,7 +278,9 @@ struct pipe_surface
 {
    struct pipe_region *region;
    unsigned format;              /**< PIPE_FORMAT_x */
+   unsigned cpp;                 /**< bytes per pixel */
    unsigned width, height;
+   unsigned pitch;               /**< in pixels */
    unsigned offset;              /**< offset from start of region, in bytes */
    unsigned refcount;
    struct pipe_winsys *winsys;   /**< winsys which owns/created the surface */
index 41d522e11ea047c53ea5e09b9d268c356a8d9da4..5adca1d6fd616e488601441d2f970ad63b1604ff 100644 (file)
@@ -80,12 +80,14 @@ struct pipe_winsys
     * flags is bitmask of PIPE_SURFACE_FLAG_RENDER, PIPE_SURFACE_FLAG_TEXTURE
     */
    struct pipe_region *(*region_alloc)(struct pipe_winsys *ws,
-                                       unsigned cpp, unsigned width,
-                                       unsigned height, unsigned flags);
+                                       unsigned size, unsigned flags);
 
    void (*region_release)(struct pipe_winsys *ws, struct pipe_region **r);
 
 
+   unsigned (*surface_pitch)(struct pipe_winsys *ws, unsigned cpp,
+                            unsigned with, unsigned flags);
+
    /** allocate a new surface (no context dependency) */
    struct pipe_surface *(*surface_alloc)(struct pipe_winsys *ws,
                                          unsigned format);
index 87f850b6fd9a6697a9a851985f6794cf3dd6b8b6..a4276362b99b0b1b60db51b0b8f5feae8d38a99c 100644 (file)
@@ -47,23 +47,9 @@ softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps,
                unsigned clearValue)
 {
    struct softpipe_context *softpipe = softpipe_context(pipe);
-   unsigned x, y, w, h;
 
    softpipe_update_derived(softpipe); /* not needed?? */
 
-   /* Use the X coord to trick region_fill() into filling at an offset
-    * from the start of the region.  Perhaps pipe_region should have the
-    * 'offset' field, not pipe_surface???
-    */
-   assert(ps->offset % ps->region->cpp == 0);
-   x = ps->offset / ps->region->cpp;
-   y = 0;
-   w = ps->width;
-   h = ps->height;
-
-   assert(w <= ps->region->pitch);
-   assert(h <= ps->region->height);
-
    if (ps == sp_tile_cache_get_surface(softpipe->zbuf_cache)) {
       float clear[4];
       clear[0] = 1.0; /* XXX hack */
@@ -78,7 +64,7 @@ softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps,
       sp_tile_cache_clear(softpipe->cbuf_cache[0], clear);
    }
 
-   pipe->region_fill(pipe, ps->region, 0, x, y, w, h, clearValue);
+   pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue);
 
 
 #if 0
index fef63ef2f6d4ae76f3e7dea867f5f81d636f0669..58dc6bb96e448e9f9a8a4d91a7ea878902c73749 100644 (file)
@@ -70,196 +70,10 @@ sp_region_unmap(struct pipe_context *pipe, struct pipe_region *region)
 }
 
 
-
-/**
- * Copy 2D rect from one place to another.
- * Position and sizes are in pixels.
- */
-static void
-copy_rect(ubyte * dst,
-          unsigned cpp,
-          unsigned dst_pitch,
-          unsigned dst_x,
-          unsigned dst_y,
-          unsigned width,
-          unsigned height,
-          const ubyte * src,
-          unsigned src_pitch,
-          unsigned src_x, 
-          unsigned src_y)
-{
-   unsigned i;
-
-   dst_pitch *= cpp;
-   src_pitch *= cpp;
-   dst += dst_x * cpp;
-   src += src_x * cpp;
-   dst += dst_y * dst_pitch;
-   src += src_y * src_pitch;
-   width *= cpp;
-
-   if (width == dst_pitch && width == src_pitch)
-      memcpy(dst, src, height * width);
-   else {
-      for (i = 0; i < height; i++) {
-         memcpy(dst, src, width);
-         dst += dst_pitch;
-         src += src_pitch;
-      }
-   }
-}
-
-
-/* Upload data to a rectangular sub-region.  Lots of choices how to do this:
- *
- * - memcpy by span to current destination
- * - upload data as new buffer and blit
- *
- * Currently always memcpy.
- */
-static void
-sp_region_data(struct pipe_context *pipe,
-              struct pipe_region *dst,
-              unsigned dst_offset,
-              unsigned dstx, unsigned dsty,
-              const void *src, unsigned src_pitch,
-              unsigned srcx, unsigned srcy, unsigned width, unsigned height)
-{
-   copy_rect(pipe->region_map(pipe, dst) + dst_offset,
-             dst->cpp,
-             dst->pitch,
-             dstx, dsty, width, height, src, src_pitch, srcx, srcy);
-
-   pipe->region_unmap(pipe, dst);
-}
-
-/* Assumes all values are within bounds -- no checking at this level -
- * do it higher up if required.
- */
-static void
-sp_region_copy(struct pipe_context *pipe,
-              struct pipe_region *dst,
-              unsigned dst_offset,
-              unsigned dstx, unsigned dsty,
-              struct pipe_region *src,
-              unsigned src_offset,
-              unsigned srcx, unsigned srcy, unsigned width, unsigned height)
-{
-   ubyte *src_map, *dst_map;
-   assert( dst->cpp == src->cpp );
-
-   dst_map = pipe->region_map(pipe, dst);
-   src_map = pipe->region_map(pipe, src);
-   copy_rect(dst_map + dst_offset,
-             dst->cpp,
-             dst->pitch,
-             dstx, dsty,
-             width, height,
-             src_map + src_offset,
-             src->pitch,
-             srcx, srcy);
-
-   pipe->region_unmap(pipe, src);
-   pipe->region_unmap(pipe, dst);
-}
-
-
-static ubyte *
-get_pointer(struct pipe_region *dst, unsigned x, unsigned y)
-{
-   return dst->map + (y * dst->pitch + x) * dst->cpp;
-}
-
-
-#define UBYTE_TO_USHORT(B) ((B) | ((B) << 8))
-
-
-/**
- * Fill a rectangular sub-region.  Need better logic about when to
- * push buffers into AGP - will currently do so whenever possible.
- */
-static void
-sp_region_fill(struct pipe_context *pipe,
-               struct pipe_region *dst,
-               unsigned dst_offset,
-               unsigned dstx, unsigned dsty,
-               unsigned width, unsigned height, unsigned value)
-{
-   unsigned i, j;
-
-   assert(dst->pitch > 0);
-   assert(width <= dst->pitch);
-
-   (void)pipe->region_map(pipe, dst);
-
-   switch (dst->cpp) {
-   case 1:
-      {
-         ubyte *row = get_pointer(dst, dstx, dsty);
-         for (i = 0; i < height; i++) {
-            memset(row, value, width);
-        row += dst->pitch;
-         }
-      }
-      break;
-   case 2:
-      {
-         ushort *row = (ushort *) get_pointer(dst, dstx, dsty);
-         for (i = 0; i < height; i++) {
-            for (j = 0; j < width; j++)
-               row[j] = (ushort) value;
-            row += dst->pitch;
-         }
-      }
-      break;
-   case 4:
-      {
-         unsigned *row = (unsigned *) get_pointer(dst, dstx, dsty);
-         for (i = 0; i < height; i++) {
-            for (j = 0; j < width; j++)
-               row[j] = value;
-            row += dst->pitch;
-         }
-      }
-      break;
-   case 8:
-      {
-         /* expand the 4-byte clear value to an 8-byte value */
-         ushort *row = (ushort *) get_pointer(dst, dstx, dsty);
-         ushort val0 = UBYTE_TO_USHORT((value >>  0) & 0xff);
-         ushort val1 = UBYTE_TO_USHORT((value >>  8) & 0xff);
-         ushort val2 = UBYTE_TO_USHORT((value >> 16) & 0xff);
-         ushort val3 = UBYTE_TO_USHORT((value >> 24) & 0xff);
-         for (i = 0; i < height; i++) {
-            for (j = 0; j < width; j++) {
-               row[j*4+0] = val0;
-               row[j*4+1] = val1;
-               row[j*4+2] = val2;
-               row[j*4+3] = val3;
-            }
-            row += dst->pitch * 4;
-         }
-      }
-      break;
-   default:
-      assert(0);
-      break;
-   }
-
-   pipe->region_unmap( pipe, dst );
-}
-
-
-
-
-
 void
 sp_init_region_functions(struct softpipe_context *sp)
 {
    sp->pipe.region_map = sp_region_map;
    sp->pipe.region_unmap = sp_region_unmap;
-   sp->pipe.region_data = sp_region_data;
-   sp->pipe.region_copy = sp_region_copy;
-   sp->pipe.region_fill = sp_region_fill;
 }
 
index b7c9d4f0045ffcd1ced174683b6f401ff74a395c..2ddf3ab99c2eff971f45dab16664c3c98e263db8 100644 (file)
@@ -77,7 +77,7 @@ a8r8g8b8_get_tile(struct pipe_surface *ps,
 {
    const unsigned *src
       = ((const unsigned *) (ps->region->map + ps->offset))
-      + y * ps->region->pitch + x;
+      + y * ps->pitch + x;
    unsigned i, j;
    unsigned w0 = w;
 
@@ -95,7 +95,7 @@ a8r8g8b8_get_tile(struct pipe_surface *ps,
          pRow[3] = UBYTE_TO_FLOAT((pixel >> 24) & 0xff);
          pRow += 4;
       }
-      src += ps->region->pitch;
+      src += ps->pitch;
       p += w0 * 4;
    }
 }
@@ -108,7 +108,7 @@ a8r8g8b8_put_tile(struct pipe_surface *ps,
 {
    unsigned *dst
       = ((unsigned *) (ps->region->map + ps->offset))
-      + y * ps->region->pitch + x;
+      + y * ps->pitch + x;
    unsigned i, j;
    unsigned w0 = w;
 
@@ -127,7 +127,7 @@ a8r8g8b8_put_tile(struct pipe_surface *ps,
          dst[j] = (a << 24) | (r << 16) | (g << 8) | b;
          pRow += 4;
       }
-      dst += ps->region->pitch;
+      dst += ps->pitch;
       p += w0 * 4;
    }
 }
@@ -141,7 +141,7 @@ a1r5g5b5_get_tile(struct pipe_surface *ps,
 {
    const ushort *src
       = ((const ushort *) (ps->region->map + ps->offset))
-      + y * ps->region->pitch + x;
+      + y * ps->pitch + x;
    unsigned i, j;
 
    assert(ps->format == PIPE_FORMAT_U_A1_R5_G5_B5);
@@ -155,7 +155,7 @@ a1r5g5b5_get_tile(struct pipe_surface *ps,
          p[3] = ((pixel >> 15)       ) * 1.0f;
          p += 4;
       }
-      src += ps->region->pitch;
+      src += ps->pitch;
    }
 }
 
@@ -172,7 +172,7 @@ z16_get_tile(struct pipe_surface *ps,
 {
    const ushort *src
       = ((const ushort *) (ps->region->map + ps->offset))
-      + y * ps->region->pitch + x;
+      + y * ps->pitch + x;
    const float scale = 1.0f / 65535.0f;
    unsigned i, j;
    unsigned w0 = w;
@@ -189,7 +189,7 @@ z16_get_tile(struct pipe_surface *ps,
          pRow[j * 4 + 2] =
          pRow[j * 4 + 3] = src[j] * scale;
       }
-      src += ps->region->pitch;
+      src += ps->pitch;
       p += 4 * w0;
    }
 }
@@ -205,7 +205,7 @@ l8_get_tile(struct pipe_surface *ps,
 {
    const ubyte *src
       = ((const ubyte *) (ps->region->map + ps->offset))
-      + y * ps->region->pitch + x;
+      + y * ps->pitch + x;
    unsigned i, j;
    unsigned w0 = w;
 
@@ -222,7 +222,7 @@ l8_get_tile(struct pipe_surface *ps,
          pRow[3] = 1.0;
          pRow += 4;
       }
-      src += ps->region->pitch;
+      src += ps->pitch;
       p += w0 * 4;
    }
 }
@@ -236,7 +236,7 @@ a8_get_tile(struct pipe_surface *ps,
 {
    const ubyte *src
       = ((const ubyte *) (ps->region->map + ps->offset))
-      + y * ps->region->pitch + x;
+      + y * ps->pitch + x;
    unsigned i, j;
    unsigned w0 = w;
 
@@ -253,7 +253,7 @@ a8_get_tile(struct pipe_surface *ps,
          pRow[3] = UBYTE_TO_FLOAT(src[j]);
          pRow += 4;
       }
-      src += ps->region->pitch;
+      src += ps->pitch;
       p += w0 * 4;
    }
 }
@@ -267,7 +267,7 @@ r16g16b16a16_get_tile(struct pipe_surface *ps,
 {
    const short *src
       = ((const short *) (ps->region->map + ps->offset))
-      + (y * ps->region->pitch + x) * 4;
+      + (y * ps->pitch + x) * 4;
    unsigned i, j;
    unsigned w0 = w;
 
@@ -286,7 +286,7 @@ r16g16b16a16_get_tile(struct pipe_surface *ps,
          pRow += 4;
          pixel += 4;
       }
-      src += ps->region->pitch * 4;
+      src += ps->pitch * 4;
       p += w0 * 4;
    }
 }
@@ -299,7 +299,7 @@ r16g16b16a16_put_tile(struct pipe_surface *ps,
 {
    short *dst
       = ((short *) (ps->region->map + ps->offset))
-      + (y * ps->region->pitch + x) * 4;
+      + (y * ps->pitch + x) * 4;
    unsigned i, j;
    unsigned w0 = w;
 
@@ -321,7 +321,7 @@ r16g16b16a16_put_tile(struct pipe_surface *ps,
          dst[j*4+3] = a;
          pRow += 4;
       }
-      dst += ps->region->pitch * 4;
+      dst += ps->pitch * 4;
       p += w0 * 4;
    }
 }
@@ -336,7 +336,7 @@ i8_get_tile(struct pipe_surface *ps,
 {
    const ubyte *src
       = ((const ubyte *) (ps->region->map + ps->offset))
-      + y * ps->region->pitch + x;
+      + y * ps->pitch + x;
    unsigned i, j;
    unsigned w0 = w;
 
@@ -353,7 +353,7 @@ i8_get_tile(struct pipe_surface *ps,
          pRow[3] = UBYTE_TO_FLOAT(src[j]);
          pRow += 4;
       }
-      src += ps->region->pitch;
+      src += ps->pitch;
       p += w0 * 4;
    }
 }
@@ -367,7 +367,7 @@ a8_l8_get_tile(struct pipe_surface *ps,
 {
    const ushort *src
       = ((const ushort *) (ps->region->map + ps->offset))
-      + y * ps->region->pitch + x;
+      + y * ps->pitch + x;
    unsigned i, j;
    unsigned w0 = w;
 
@@ -385,7 +385,7 @@ a8_l8_get_tile(struct pipe_surface *ps,
          pRow[3] = UBYTE_TO_FLOAT(p >> 8);
          pRow += 4;
       }
-      src += ps->region->pitch;
+      src += ps->pitch;
       p += w0 * 4;
    }
 }
@@ -404,7 +404,7 @@ z32_get_tile(struct pipe_surface *ps,
 {
    const uint *src
       = ((const uint *) (ps->region->map + ps->offset))
-      + y * ps->region->pitch + x;
+      + y * ps->pitch + x;
    const double scale = 1.0 / (double) 0xffffffff;
    unsigned i, j;
    unsigned w0 = w;
@@ -421,7 +421,7 @@ z32_get_tile(struct pipe_surface *ps,
          pRow[j * 4 + 2] =
          pRow[j * 4 + 3] = (float) (scale * src[j]);
       }
-      src += ps->region->pitch;
+      src += ps->pitch;
       p += 4 * w0;
    }
 }
@@ -438,7 +438,7 @@ s8z24_get_tile(struct pipe_surface *ps,
 {
    const uint *src
       = ((const uint *) (ps->region->map + ps->offset))
-      + y * ps->region->pitch + x;
+      + y * ps->pitch + x;
    const double scale = 1.0 / ((1 << 24) - 1);
    unsigned i, j;
    unsigned w0 = w;
@@ -455,7 +455,7 @@ s8z24_get_tile(struct pipe_surface *ps,
          pRow[j * 4 + 2] =
          pRow[j * 4 + 3] = (float) (scale * (src[j] & 0xffffff));
       }
-      src += ps->region->pitch;
+      src += ps->pitch;
       p += 4 * w0;
    }
 }
@@ -472,7 +472,7 @@ z24s8_get_tile(struct pipe_surface *ps,
 {
    const uint *src
       = ((const uint *) (ps->region->map + ps->offset))
-      + y * ps->region->pitch + x;
+      + y * ps->pitch + x;
    const double scale = 1.0 / ((1 << 24) - 1);
    unsigned i, j;
    unsigned w0 = w;
@@ -489,7 +489,7 @@ z24s8_get_tile(struct pipe_surface *ps,
          pRow[j * 4 + 2] =
          pRow[j * 4 + 3] = (float) (scale * (src[j] >> 8));
       }
-      src += ps->region->pitch;
+      src += ps->pitch;
       p += 4 * w0;
    }
 }
@@ -525,8 +525,10 @@ softpipe_get_tex_surface(struct pipe_context *pipe,
       assert(ps->format);
       assert(ps->refcount);
       pipe_region_reference(&ps->region, mt->region);
+      ps->cpp = mt->cpp;
       ps->width = mt->level[level].width;
       ps->height = mt->level[level].height;
+      ps->pitch = mt->pitch;
       ps->offset = offset;
    }
    return ps;
@@ -541,7 +543,7 @@ softpipe_get_tile(struct pipe_context *pipe, struct pipe_surface *ps,
                   uint x, uint y, uint w, uint h,
                   void *p, int dst_stride)
 {
-   const uint cpp = ps->region->cpp;
+   const uint cpp = ps->cpp;
    const ubyte *pSrc;
    ubyte *pDest;
    uint i;
@@ -554,13 +556,13 @@ softpipe_get_tile(struct pipe_context *pipe, struct pipe_surface *ps,
 
    CLIP_TILE;
 
-   pSrc = ps->region->map + ps->offset + (y * ps->region->pitch + x) * cpp;
+   pSrc = ps->region->map + ps->offset + (y * ps->pitch + x) * cpp;
    pDest = (ubyte *) p;
 
    for (i = 0; i < h; i++) {
       memcpy(pDest, pSrc, w * cpp);
       pDest += dst_stride;
-      pSrc += ps->region->pitch * cpp;
+      pSrc += ps->pitch * cpp;
    }
 }
 
@@ -573,7 +575,7 @@ softpipe_put_tile(struct pipe_context *pipe, struct pipe_surface *ps,
                   uint x, uint y, uint w, uint h,
                   const void *p, int src_stride)
 {
-   const uint cpp = ps->region->cpp;
+   const uint cpp = ps->cpp;
    const ubyte *pSrc;
    ubyte *pDest;
    uint i;
@@ -587,11 +589,11 @@ softpipe_put_tile(struct pipe_context *pipe, struct pipe_surface *ps,
    CLIP_TILE;
 
    pSrc = (const ubyte *) p;
-   pDest = ps->region->map + ps->offset + (y * ps->region->pitch + x) * cpp;
+   pDest = ps->region->map + ps->offset + (y * ps->pitch + x) * cpp;
 
    for (i = 0; i < h; i++) {
       memcpy(pDest, pSrc, w * cpp);
-      pDest += ps->region->pitch * cpp;
+      pDest += ps->pitch * cpp;
       pSrc += src_stride;
    }
 }
@@ -691,6 +693,180 @@ softpipe_put_tile_rgba(struct pipe_context *pipe,
 }
 
 
+/**
+ * Copy 2D rect from one place to another.
+ * Position and sizes are in pixels.
+ */
+static void
+copy_rect(ubyte * dst,
+          unsigned cpp,
+          unsigned dst_pitch,
+          unsigned dst_x,
+          unsigned dst_y,
+          unsigned width,
+          unsigned height,
+          const ubyte * src,
+          unsigned src_pitch,
+          unsigned src_x, 
+          unsigned src_y)
+{
+   unsigned i;
+
+   dst_pitch *= cpp;
+   src_pitch *= cpp;
+   dst += dst_x * cpp;
+   src += src_x * cpp;
+   dst += dst_y * dst_pitch;
+   src += src_y * src_pitch;
+   width *= cpp;
+
+   if (width == dst_pitch && width == src_pitch)
+      memcpy(dst, src, height * width);
+   else {
+      for (i = 0; i < height; i++) {
+         memcpy(dst, src, width);
+         dst += dst_pitch;
+         src += src_pitch;
+      }
+   }
+}
+
+
+/* Upload data to a rectangular sub-region.  Lots of choices how to do this:
+ *
+ * - memcpy by span to current destination
+ * - upload data as new buffer and blit
+ *
+ * Currently always memcpy.
+ */
+static void
+sp_surface_data(struct pipe_context *pipe,
+               struct pipe_surface *dst,
+               unsigned dstx, unsigned dsty,
+               const void *src, unsigned src_pitch,
+               unsigned srcx, unsigned srcy, unsigned width, unsigned height)
+{
+   copy_rect(pipe->region_map(pipe, dst->region) + dst->offset,
+             dst->cpp,
+             dst->pitch,
+             dstx, dsty, width, height, src, src_pitch, srcx, srcy);
+
+   pipe->region_unmap(pipe, dst->region);
+}
+
+/* Assumes all values are within bounds -- no checking at this level -
+ * do it higher up if required.
+ */
+static void
+sp_surface_copy(struct pipe_context *pipe,
+               struct pipe_surface *dst,
+               unsigned dstx, unsigned dsty,
+               struct pipe_surface *src,
+               unsigned srcx, unsigned srcy, unsigned width, unsigned height)
+{
+   ubyte *src_map, *dst_map;
+   assert( dst->cpp == src->cpp );
+
+   dst_map = pipe->region_map(pipe, dst->region);
+   src_map = pipe->region_map(pipe, src->region);
+   copy_rect(dst_map + dst->offset,
+             dst->cpp,
+             dst->pitch,
+             dstx, dsty,
+             width, height,
+             src_map + src->offset,
+             src->pitch,
+             srcx, srcy);
+
+   pipe->region_unmap(pipe, src->region);
+   pipe->region_unmap(pipe, dst->region);
+}
+
+
+static ubyte *
+get_pointer(struct pipe_surface *dst, unsigned x, unsigned y)
+{
+   return dst->region->map + (y * dst->pitch + x) * dst->cpp;
+}
+
+
+#define UBYTE_TO_USHORT(B) ((B) | ((B) << 8))
+
+
+/**
+ * Fill a rectangular sub-region.  Need better logic about when to
+ * push buffers into AGP - will currently do so whenever possible.
+ */
+static void
+sp_surface_fill(struct pipe_context *pipe,
+               struct pipe_surface *dst,
+               unsigned dstx, unsigned dsty,
+               unsigned width, unsigned height, unsigned value)
+{
+   unsigned i, j;
+
+   assert(dst->pitch > 0);
+   assert(width <= dst->pitch);
+
+   (void)pipe->region_map(pipe, dst->region);
+
+   switch (dst->cpp) {
+   case 1:
+      {
+         ubyte *row = get_pointer(dst, dstx, dsty);
+         for (i = 0; i < height; i++) {
+            memset(row, value, width);
+        row += dst->pitch;
+         }
+      }
+      break;
+   case 2:
+      {
+         ushort *row = (ushort *) get_pointer(dst, dstx, dsty);
+         for (i = 0; i < height; i++) {
+            for (j = 0; j < width; j++)
+               row[j] = (ushort) value;
+            row += dst->pitch;
+         }
+      }
+      break;
+   case 4:
+      {
+         unsigned *row = (unsigned *) get_pointer(dst, dstx, dsty);
+         for (i = 0; i < height; i++) {
+            for (j = 0; j < width; j++)
+               row[j] = value;
+            row += dst->pitch;
+         }
+      }
+      break;
+   case 8:
+      {
+         /* expand the 4-byte clear value to an 8-byte value */
+         ushort *row = (ushort *) get_pointer(dst, dstx, dsty);
+         ushort val0 = UBYTE_TO_USHORT((value >>  0) & 0xff);
+         ushort val1 = UBYTE_TO_USHORT((value >>  8) & 0xff);
+         ushort val2 = UBYTE_TO_USHORT((value >> 16) & 0xff);
+         ushort val3 = UBYTE_TO_USHORT((value >> 24) & 0xff);
+         for (i = 0; i < height; i++) {
+            for (j = 0; j < width; j++) {
+               row[j*4+0] = val0;
+               row[j*4+1] = val1;
+               row[j*4+2] = val2;
+               row[j*4+3] = val3;
+            }
+            row += dst->pitch * 4;
+         }
+      }
+      break;
+   default:
+      assert(0);
+      break;
+   }
+
+   pipe->region_unmap( pipe, dst->region );
+}
+
 
 void
 sp_init_surface_functions(struct softpipe_context *sp)
@@ -700,4 +876,8 @@ sp_init_surface_functions(struct softpipe_context *sp)
 
    sp->pipe.get_tile_rgba = softpipe_get_tile_rgba;
    sp->pipe.put_tile_rgba = softpipe_put_tile_rgba;
+
+   sp->pipe.surface_data = sp_surface_data;
+   sp->pipe.surface_copy = sp_surface_copy;
+   sp->pipe.surface_fill = sp_surface_fill;
 }
index 7dc85bf2ebe5dd1710320f33575fe7cfc14e8411..71a2003e6df4f19b29bf337b17002cfe3b264517 100644 (file)
@@ -260,9 +260,8 @@ finish_surface_init(GLcontext *ctx, struct xmesa_renderbuffer *xrb)
 {
    struct pipe_context *pipe = ctx->st->pipe;
    if (!xrb->St.surface->region) {
-      int w = 1, h = 1;
-      xrb->St.surface->region = pipe->winsys->region_alloc(pipe->winsys,
-                                                           1, w, h, 0x0);
+      xrb->St.surface->region = pipe->winsys->region_alloc(pipe->winsys, 1,
+                                                          0x0);
    }
 }
 
index 43e505074769f44a3a470dc443b151c147527cd9..23945630959c40b2511e497d16f2f260988bc08d 100644 (file)
@@ -624,7 +624,7 @@ xmesa_new_color_surface(struct pipe_winsys *winsys, GLuint pipeFormat)
     * The region's size will get set in the xmesa_alloc_front/back_storage()
     * functions.
     */
-   xms->surface.region = winsys->region_alloc(winsys, 1, 1, 1, 0x0);
+   xms->surface.region = winsys->region_alloc(winsys, 1, 0x0);
 
    return &xms->surface;
 }
index b842cf766e3976a3ad724ada21d407230c2e1e4f..99816a811d6e7ef1c310f402baf79cabfbe4669f 100644 (file)
@@ -220,27 +220,30 @@ round_up(unsigned n, unsigned multiple)
 }
 
 
+static unsigned
+xm_surface_pitch(struct pipe_winsys *winsys, unsigned cpp, unsigned width,
+                unsigned flags)
+{
+   return round_up(width, 64 / cpp);
+}
+
+
 static struct pipe_region *
-xm_region_alloc(struct pipe_winsys *winsys,
-                unsigned cpp, unsigned width, unsigned height, unsigned flags)
+xm_region_alloc(struct pipe_winsys *winsys, unsigned size, unsigned flags)
 {
    struct pipe_region *region = CALLOC_STRUCT(pipe_region);
    const unsigned alignment = 64;
 
-   region->cpp = cpp;
-   region->pitch = round_up(width, alignment / cpp);
-   region->height = height;
    region->refcount = 1;
 
-   assert(region->pitch > 0);
+   assert(size > 0);
 
-   region->buffer = winsys->buffer_create( winsys, alignment )
-;
+   region->buffer = winsys->buffer_create( winsys, alignment );
 
    /* NULL data --> just allocate the space */
    winsys->buffer_data( winsys,
                         region->buffer, 
-                        region->pitch * cpp * height
+                        size
                         NULL,
                         PIPE_BUFFER_USAGE_PIXEL );
    return region;
@@ -335,6 +338,7 @@ xmesa_get_pipe_winsys(void)
       ws->region_alloc = xm_region_alloc;
       ws->region_release = xm_region_release;
 
+      ws->surface_pitch = xm_surface_pitch;
       ws->surface_alloc = xm_surface_alloc;
       ws->surface_release = xm_surface_release;
 
index df41d5ce5b26a7c781b4b6bb536644a9ef050740..39c0cf6b327c1e67807053a2334fac6025e8eef9 100644 (file)
@@ -455,10 +455,6 @@ alloc_mipmap_tree(struct st_context *st,
 
    cpp = st_sizeof_format(pipeFormat);
 
-   /* allocate texture region/storage */
-   mt->region = st->pipe->winsys->region_alloc(st->pipe->winsys,
-                                               cpp, width, height, flags);
-
    mt->target = PIPE_TEXTURE_2D;
    mt->internal_format = GL_RGBA;
    mt->format = pipeFormat;
@@ -469,7 +465,10 @@ alloc_mipmap_tree(struct st_context *st,
    mt->depth0 = 1;
    mt->cpp = cpp;
    mt->compressed = 0;
-   mt->pitch = mt->region->pitch;
+   mt->pitch = st->pipe->winsys->surface_pitch(st->pipe->winsys, cpp, width,
+                                              flags);
+   mt->region = st->pipe->winsys->region_alloc(st->pipe->winsys,
+                                               mt->pitch * cpp * height, flags);
    mt->depth_pitch = 0;
    mt->total_height = height;
    mt->level[0].level_offset = 0;
@@ -524,7 +523,7 @@ make_mipmap_tree(struct st_context *st,
    {
       static const GLuint dstImageOffsets = 0;
       GLboolean success;
-      GLuint pitch = mt->region->pitch;
+      GLuint pitch = mt->pitch;
       GLubyte *dest;
       const GLbitfield imageTransferStateSave = ctx->_ImageTransferState;
 
@@ -569,7 +568,7 @@ make_mipmap_tree(struct st_context *st,
    mt->depth0 = 1;
    mt->cpp = cpp;
    mt->compressed = 0;
-   mt->pitch = mt->region->pitch;
+   mt->pitch = mt->pitch;
    mt->depth_pitch = 0;
    mt->total_height = height;
    mt->level[0].level_offset = 0;
@@ -952,13 +951,13 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
             switch (ps->format) {
             case PIPE_FORMAT_U_S8:
                {
-                  ubyte *dest = stmap + spanY * ps->region->pitch + spanX;
+                  ubyte *dest = stmap + spanY * ps->pitch + spanX;
                   memcpy(dest, values, spanWidth);
                }
                break;
             case PIPE_FORMAT_S8_Z24:
                {
-                  uint *dest = (uint *) stmap + spanY * ps->region->pitch + spanX;
+                  uint *dest = (uint *) stmap + spanY * ps->pitch + spanX;
                   GLint k;
                   for (k = 0; k < spanWidth; k++) {
                      uint p = dest[k];
@@ -1054,7 +1053,7 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height,
 {
    struct pipe_context *pipe = ctx->st->pipe;
    const uint flags = PIPE_SURFACE_FLAG_TEXTURE;
-   uint format = 0, cpp, comp, pitch;
+   uint format = 0, cpp, comp;
    ubyte *dest;
    struct pipe_mipmap_tree *mt;
    int row, col;
@@ -1091,9 +1090,9 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height,
 
 
    /* allocate texture region/storage */
+   mt->pitch = pipe->winsys->surface_pitch(pipe->winsys, cpp, width, flags);
    mt->region = pipe->winsys->region_alloc(pipe->winsys,
-                                           cpp, width, height, flags);
-   pitch = mt->region->pitch;
+                                          mt->pitch * cpp * height, flags);
 
    /* map texture region */
    dest = pipe->region_map(pipe, mt->region);
@@ -1110,7 +1109,7 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height,
    for (row = 0; row < height; row++) {
       const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack,
                  bitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0);
-      ubyte *destRow = dest + row * pitch * cpp;
+      ubyte *destRow = dest + row * mt->pitch * cpp;
 
       if (unpack->LsbFirst) {
          /* Lsb first */
@@ -1172,7 +1171,6 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height,
    mt->depth0 = 1;
    mt->cpp = cpp;
    mt->compressed = 0;
-   mt->pitch = mt->region->pitch;
    mt->depth_pitch = 0;
    mt->total_height = height;
    mt->level[0].level_offset = 0;
@@ -1256,7 +1254,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
          y = ctx->DrawBuffer->Height - y - 1;
       }
 
-      dst = drawMap + (y * psDraw->region->pitch + dstx) * psDraw->region->cpp;
+      dst = drawMap + (y * psDraw->pitch + dstx) * psDraw->cpp;
       src = buffer + i * width;
 
       switch (psDraw->format) {
@@ -1297,6 +1295,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
    struct st_vertex_program *stvp;
    struct st_fragment_program *stfp;
    struct pipe_surface *psRead;
+   struct pipe_surface *psTex;
    struct pipe_mipmap_tree *mt;
    GLfloat *color;
    uint format;
@@ -1332,6 +1331,8 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
    if (!mt)
       return;
 
+   psTex = pipe->get_tex_surface(pipe, mt, 0, 0, 0);
+
    if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
       srcy = ctx->DrawBuffer->Height - srcy - height;
    }
@@ -1342,21 +1343,16 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
     */
    if (st->haveFramebufferRegions) {
       /* copy source framebuffer region into mipmap/texture */
-      pipe->region_copy(pipe,
-                        mt->region, /* dest */
-                        0, /* dest_offset */
-                        0, 0, /* destx/y */
-                        psRead->region,
-                        0, /* src_offset */
-                        srcx, srcy, width, height);
+      pipe->surface_copy(pipe,
+                        psTex, /* dest */
+                        0, 0, /* destx/y */
+                        psRead,
+                        srcx, srcy, width, height);
    }
    else {
       /* alternate path using get/put_tile() */
-      struct pipe_surface *psTex;
       GLfloat *buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
 
-      psTex = pipe->get_tex_surface(pipe, mt, 0, 0, 0);
-
       (void) pipe->region_map(pipe, psRead->region);
       (void) pipe->region_map(pipe, psTex->region);
 
@@ -1366,17 +1362,15 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
       pipe->region_unmap(pipe, psRead->region);
       pipe->region_unmap(pipe, psTex->region);
 
-      pipe_surface_reference(&psTex, NULL);
-
       free(buf);
    }
 
-
    /* draw textured quad */
    draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2],
                       width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
                       mt, stvp, stfp, color, GL_TRUE);
 
+   pipe_surface_reference(&psTex, NULL);
    free_mipmap_tree(st->pipe, mt);
 }
 
index f58d532b2a77aa3f205f945bc198f34f1c8374dd..80c92e8b7a1fa08c31fe5f7fc28d1a642b4d67e2 100644 (file)
@@ -104,6 +104,9 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
       assert(strb->surface);
       if (!strb->surface)
          return GL_FALSE;
+      strb->surface->cpp = cpp;
+      strb->surface->pitch = pipe->winsys->surface_pitch(pipe->winsys, cpp,
+                                                        width, flags);
    }
 
    /* free old region */
@@ -115,8 +118,9 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
       pipe->winsys->region_release(pipe->winsys, &strb->surface->region);
    }
 
-   strb->surface->region = pipe->winsys->region_alloc(pipe->winsys, cpp,
-                                                      width, height, flags);
+   strb->surface->region = pipe->winsys->region_alloc(pipe->winsys,
+                                                     strb->surface->pitch *
+                                                     cpp * height, flags);
    if (!strb->surface->region)
       return GL_FALSE; /* out of memory, try s/w buffer? */
 
index 2e7c01672a180561507792480f93938aec247896..83fe480af8504389b4d93c45903b3b4c2c734019 100644 (file)
@@ -87,13 +87,13 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
       switch (ps->format) {
       case PIPE_FORMAT_U_S8:
          {
-            const ubyte *src = stmap + srcY * ps->region->pitch + x;
+            const ubyte *src = stmap + srcY * ps->pitch + x;
             memcpy(values, src, width);
          }
          break;
       case PIPE_FORMAT_S8_Z24:
          {
-            const uint *src = (uint *) stmap + srcY * ps->region->pitch + x;
+            const uint *src = (uint *) stmap + srcY * ps->pitch + x;
             GLint k;
             for (k = 0; k < width; k++) {
                values[k] = src[k] >> 24;
@@ -102,7 +102,7 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
          break;
       case PIPE_FORMAT_Z24_S8:
          {
-            const uint *src = (uint *) stmap + srcY * ps->region->pitch + x;
+            const uint *src = (uint *) stmap + srcY * ps->pitch + x;
             GLint k;
             for (k = 0; k < width; k++) {
                values[k] = src[k] & 0xff;
index 4e6d4857f4860cae2d5f502922d05d62b66cff11..461705119fae9bc323e5e6344d5a41d56a048ae9 100644 (file)
@@ -44,6 +44,7 @@
 
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
+#include "pipe/p_inlines.h"
 
 
 #define DBG if (0) printf
@@ -1150,7 +1151,6 @@ do_copy_texsubimage(GLcontext *ctx,
    struct st_renderbuffer *strb;
    struct pipe_context *pipe = ctx->st->pipe;
    struct pipe_region *src_region, *dest_region;
-   uint dest_offset, src_offset;
    uint dest_format, src_format;
 
    (void) texImage;
@@ -1185,12 +1185,13 @@ do_copy_texsubimage(GLcontext *ctx,
        ctx->_ImageTransferState == 0x0 &&
        src_region &&
        dest_region &&
-       src_region->cpp == dest_region->cpp) {
+       strb->surface->cpp == stImage->mt->cpp) {
       /* do blit-style copy */
-      src_offset = 0;
-      dest_offset = st_miptree_image_offset(stImage->mt,
-                                            stImage->face,
-                                            stImage->level);
+      struct pipe_surface *dest_surface = pipe->get_tex_surface(pipe,
+                                                               stImage->mt,
+                                                               stImage->face,
+                                                               stImage->level,
+                                                               destZ);
 
       /* XXX may need to invert image depending on window
        * vs. user-created FBO
@@ -1213,18 +1214,18 @@ do_copy_texsubimage(GLcontext *ctx,
                         GL_COPY); /* ? */
 #else
 
-      pipe->region_copy(pipe,
-                        /* dest */
-                        dest_region,
-                        dest_offset,
-                        destX, destY,
-                        /* src */
-                        src_region,
-                        src_offset,
-                        srcX, srcY,
-                        /* size */
-                        width, height);
+      pipe->surface_copy(pipe,
+                        /* dest */
+                        dest_surface,
+                        destX, destY,
+                        /* src */
+                        strb->surface,
+                        srcX, srcY,
+                        /* size */
+                        width, height);
 #endif
+
+      pipe_surface_reference(&dest_surface, NULL);
    }
    else {
       fallback_copy_texsubimage(ctx, target, level,
index d1db590bee461aaf5d10380b7cf19afd9cea28f4..6ccf33105f1fc94433f2f52d776a38bbb93cca5d 100644 (file)
@@ -31,6 +31,8 @@
 #include "pipe/p_state.h"
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
+#include "pipe/p_util.h"
+#include "pipe/p_inlines.h"
 #include "pipe/p_winsys.h"
 
 
@@ -87,10 +89,9 @@ st_miptree_create(struct pipe_context *pipe,
 
    ok = pipe->mipmap_tree_layout(pipe, mt);
    if (ok) {
-      /* note: it's OK to pass 'pitch' as 'width' here: */
-      mt->region = pipe->winsys->region_alloc(pipe->winsys, mt->cpp, mt->pitch,
-                                              mt->total_height, flags);
-      mt->pitch = mt->region->pitch; /*XXX NEW */
+      mt->region = pipe->winsys->region_alloc(pipe->winsys,
+                                             mt->pitch * mt->cpp *
+                                             mt->total_height, flags);
    }
 
    if (!mt->region) {
@@ -266,24 +267,27 @@ st_miptree_image_data(struct pipe_context *pipe,
                       GLuint src_row_pitch, GLuint src_image_pitch)
 {
    GLuint depth = dst->level[level].depth;
-   GLuint dst_offset = st_miptree_image_offset(dst, face, level);
-   const GLuint *dst_depth_offset = st_miptree_depth_offsets(dst, level);
    GLuint i;
    GLuint height = 0;
    const GLubyte *srcUB = src;
+   struct pipe_surface *dst_surface;
 
    DBG("%s\n", __FUNCTION__);
    for (i = 0; i < depth; i++) {
       height = dst->level[level].height;
       if(dst->compressed)
         height /= 4;
-      pipe->region_data(pipe, dst->region,
-                        dst_offset + dst_depth_offset[i], /* dst_offset */
-                        0, 0,                             /* dstx, dsty */
-                        srcUB,
-                        src_row_pitch,
-                        0, 0,                             /* source x, y */
-                        dst->level[level].width, height); /* width, height */
+
+      dst_surface = pipe->get_tex_surface(pipe, dst, face, level, i);
+
+      pipe->surface_data(pipe, dst_surface,
+                        0, 0,                             /* dstx, dsty */
+                        srcUB,
+                        src_row_pitch,
+                        0, 0,                             /* source x, y */
+                        dst->level[level].width, height); /* width, height */
+
+      pipe_surface_reference(&dst_surface, NULL);
 
       srcUB += src_image_pitch * dst->cpp;
    }
@@ -300,21 +304,25 @@ st_miptree_image_copy(struct pipe_context *pipe,
    GLuint width = src->level[level].width;
    GLuint height = src->level[level].height;
    GLuint depth = src->level[level].depth;
-   GLuint dst_offset = st_miptree_image_offset(dst, face, level);
-   GLuint src_offset = st_miptree_image_offset(src, face, level);
-   const GLuint *dst_depth_offset = st_miptree_depth_offsets(dst, level);
-   const GLuint *src_depth_offset = st_miptree_depth_offsets(src, level);
+   struct pipe_surface *src_surface;
+   struct pipe_surface *dst_surface;
    GLuint i;
 
    if (dst->compressed)
       height /= 4;
    for (i = 0; i < depth; i++) {
-      pipe->region_copy(pipe,
-                        dst->region, dst_offset + dst_depth_offset[i],
-                        0, 0, /* destX, Y */
-                        src->region, src_offset + src_depth_offset[i],
-                        0, 0, /* srcX, Y */
-                        width, height);
+      dst_surface = pipe->get_tex_surface(pipe, dst, face, level, i);
+      src_surface = pipe->get_tex_surface(pipe, src, face, level, i);
+
+      pipe->surface_copy(pipe,
+                        dst_surface,
+                        0, 0, /* destX, Y */
+                        src_surface,
+                        0, 0, /* srcX, Y */
+                        width, height);
+
+      pipe_surface_reference(&dst_surface, NULL);
+      pipe_surface_reference(&src_surface, NULL);
    }
 
 }