summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mesa/drivers/dri/intel_winsys/intel_swapbuffers.c6
-rw-r--r--src/mesa/drivers/dri/intel_winsys/intel_winsys_pipe.c30
-rw-r--r--src/mesa/pipe/failover/fo_context.c6
-rw-r--r--src/mesa/pipe/i915simple/i915_clear.c9
-rw-r--r--src/mesa/pipe/i915simple/i915_regions.c172
-rw-r--r--src/mesa/pipe/i915simple/i915_state_emit.c25
-rw-r--r--src/mesa/pipe/i915simple/i915_surface.c185
-rw-r--r--src/mesa/pipe/p_context.h48
-rw-r--r--src/mesa/pipe/p_state.h5
-rw-r--r--src/mesa/pipe/p_winsys.h6
-rw-r--r--src/mesa/pipe/softpipe/sp_clear.c16
-rw-r--r--src/mesa/pipe/softpipe/sp_region.c186
-rw-r--r--src/mesa/pipe/softpipe/sp_surface.c244
-rw-r--r--src/mesa/pipe/xlib/xm_buffer.c5
-rw-r--r--src/mesa/pipe/xlib/xm_surface.c2
-rw-r--r--src/mesa/pipe/xlib/xm_winsys.c22
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.c50
-rw-r--r--src/mesa/state_tracker/st_cb_fbo.c8
-rw-r--r--src/mesa/state_tracker/st_cb_readpixels.c6
-rw-r--r--src/mesa/state_tracker/st_cb_texture.c35
-rw-r--r--src/mesa/state_tracker/st_mipmap_tree.c54
21 files changed, 550 insertions, 570 deletions
diff --git a/src/mesa/drivers/dri/intel_winsys/intel_swapbuffers.c b/src/mesa/drivers/dri/intel_winsys/intel_swapbuffers.c
index 9fcb2dac273..f96209d1b06 100644
--- a/src/mesa/drivers/dri/intel_winsys/intel_swapbuffers.c
+++ b/src/mesa/drivers/dri/intel_winsys/intel_swapbuffers.c
@@ -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);
diff --git a/src/mesa/drivers/dri/intel_winsys/intel_winsys_pipe.c b/src/mesa/drivers/dri/intel_winsys/intel_winsys_pipe.c
index ae02f98a783..7b3aa994824 100644
--- a/src/mesa/drivers/dri/intel_winsys/intel_winsys_pipe.c
+++ b/src/mesa/drivers/dri/intel_winsys/intel_winsys_pipe.c
@@ -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;
diff --git a/src/mesa/pipe/failover/fo_context.c b/src/mesa/pipe/failover/fo_context.c
index c5fab73fb13..0cc9cab408c 100644
--- a/src/mesa/pipe/failover/fo_context.c
+++ b/src/mesa/pipe/failover/fo_context.c
@@ -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;
diff --git a/src/mesa/pipe/i915simple/i915_clear.c b/src/mesa/pipe/i915simple/i915_clear.c
index e8087df5a47..cde69daacc0 100644
--- a/src/mesa/pipe/i915simple/i915_clear.c
+++ b/src/mesa/pipe/i915simple/i915_clear.c
@@ -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);
}
diff --git a/src/mesa/pipe/i915simple/i915_regions.c b/src/mesa/pipe/i915simple/i915_regions.c
index e8c4c92bc88..82fdec83d09 100644
--- a/src/mesa/pipe/i915simple/i915_regions.c
+++ b/src/mesa/pipe/i915simple/i915_regions.c
@@ -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;
}
diff --git a/src/mesa/pipe/i915simple/i915_state_emit.c b/src/mesa/pipe/i915simple/i915_state_emit.c
index d793e92a14d..900a91d8963 100644
--- a/src/mesa/pipe/i915simple/i915_state_emit.c
+++ b/src/mesa/pipe/i915simple/i915_state_emit.c
@@ -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);
diff --git a/src/mesa/pipe/i915simple/i915_surface.c b/src/mesa/pipe/i915simple/i915_surface.c
index bec7ddb7319..e4a5de00d77 100644
--- a/src/mesa/pipe/i915simple/i915_surface.c
+++ b/src/mesa/pipe/i915simple/i915_surface.c
@@ -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;
}
diff --git a/src/mesa/pipe/p_context.h b/src/mesa/pipe/p_context.h
index 8bed958feb3..e145b22f2ff 100644
--- a/src/mesa/pipe/p_context.h
+++ b/src/mesa/pipe/p_context.h
@@ -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);
/*
diff --git a/src/mesa/pipe/p_state.h b/src/mesa/pipe/p_state.h
index 570f44e24ed..642734aeb80 100644
--- a/src/mesa/pipe/p_state.h
+++ b/src/mesa/pipe/p_state.h
@@ -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 */
diff --git a/src/mesa/pipe/p_winsys.h b/src/mesa/pipe/p_winsys.h
index 41d522e11ea..5adca1d6fd6 100644
--- a/src/mesa/pipe/p_winsys.h
+++ b/src/mesa/pipe/p_winsys.h
@@ -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);
diff --git a/src/mesa/pipe/softpipe/sp_clear.c b/src/mesa/pipe/softpipe/sp_clear.c
index 87f850b6fd9..a4276362b99 100644
--- a/src/mesa/pipe/softpipe/sp_clear.c
+++ b/src/mesa/pipe/softpipe/sp_clear.c
@@ -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
diff --git a/src/mesa/pipe/softpipe/sp_region.c b/src/mesa/pipe/softpipe/sp_region.c
index fef63ef2f6d..58dc6bb96e4 100644
--- a/src/mesa/pipe/softpipe/sp_region.c
+++ b/src/mesa/pipe/softpipe/sp_region.c
@@ -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;
}
diff --git a/src/mesa/pipe/softpipe/sp_surface.c b/src/mesa/pipe/softpipe/sp_surface.c
index b7c9d4f0045..2ddf3ab99c2 100644
--- a/src/mesa/pipe/softpipe/sp_surface.c
+++ b/src/mesa/pipe/softpipe/sp_surface.c
@@ -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;
}
diff --git a/src/mesa/pipe/xlib/xm_buffer.c b/src/mesa/pipe/xlib/xm_buffer.c
index 7dc85bf2ebe..71a2003e6df 100644
--- a/src/mesa/pipe/xlib/xm_buffer.c
+++ b/src/mesa/pipe/xlib/xm_buffer.c
@@ -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);
}
}
diff --git a/src/mesa/pipe/xlib/xm_surface.c b/src/mesa/pipe/xlib/xm_surface.c
index 43e50507476..23945630959 100644
--- a/src/mesa/pipe/xlib/xm_surface.c
+++ b/src/mesa/pipe/xlib/xm_surface.c
@@ -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;
}
diff --git a/src/mesa/pipe/xlib/xm_winsys.c b/src/mesa/pipe/xlib/xm_winsys.c
index b842cf766e3..99816a811d6 100644
--- a/src/mesa/pipe/xlib/xm_winsys.c
+++ b/src/mesa/pipe/xlib/xm_winsys.c
@@ -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;
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index df41d5ce5b2..39c0cf6b327 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -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);
}
diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c
index f58d532b2a7..80c92e8b7a1 100644
--- a/src/mesa/state_tracker/st_cb_fbo.c
+++ b/src/mesa/state_tracker/st_cb_fbo.c
@@ -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? */
diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c
index 2e7c01672a1..83fe480af85 100644
--- a/src/mesa/state_tracker/st_cb_readpixels.c
+++ b/src/mesa/state_tracker/st_cb_readpixels.c
@@ -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;
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index 4e6d4857f48..461705119fa 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -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,
diff --git a/src/mesa/state_tracker/st_mipmap_tree.c b/src/mesa/state_tracker/st_mipmap_tree.c
index d1db590bee4..6ccf33105f1 100644
--- a/src/mesa/state_tracker/st_mipmap_tree.c
+++ b/src/mesa/state_tracker/st_mipmap_tree.c
@@ -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);
}
}