diff options
author | Brian <[email protected]> | 2007-10-26 10:45:42 -0600 |
---|---|---|
committer | Brian <[email protected]> | 2007-10-26 10:45:42 -0600 |
commit | e4f6f0ec02133e9297c3f2db787dee14bf0ae6e1 (patch) | |
tree | a5706d83a96964b2cf63cd66ca25ed63641b4a56 /src/mesa/pipe/i915simple | |
parent | f7be1b419aab80c4e011183611964eb4d7c023c2 (diff) |
surface_alloc() is now a winsys function.
This allows surfaces to be allocated without a rendering context.
A few loose ends to resolve, but in working condition.
Diffstat (limited to 'src/mesa/pipe/i915simple')
-rw-r--r-- | src/mesa/pipe/i915simple/i915_surface.c | 189 |
1 files changed, 149 insertions, 40 deletions
diff --git a/src/mesa/pipe/i915simple/i915_surface.c b/src/mesa/pipe/i915simple/i915_surface.c index a07a21c13b1..b4b5bd1ce57 100644 --- a/src/mesa/pipe/i915simple/i915_surface.c +++ b/src/mesa/pipe/i915simple/i915_surface.c @@ -29,13 +29,20 @@ #include "i915_state.h" #include "pipe/p_defines.h" #include "pipe/p_util.h" +#include "pipe/p_winsys.h" -struct i915_surface -{ - struct pipe_surface surface; - /* anything else? */ -}; +#define CLIP_TILE \ + do { \ + if (x >= ps->width) \ + return; \ + if (y >= ps->height) \ + return; \ + if (x + w > ps->width) \ + w = ps->width - x; \ + if (y + h > ps->height) \ + h = ps->height -y; \ + } while(0) /** @@ -53,30 +60,44 @@ i915_get_tile_rgba(struct pipe_context *pipe, unsigned i, j; unsigned w0 = w; - assert(ps->format == PIPE_FORMAT_U_A8_R8_G8_B8); - -#if 0 - assert(x + w <= ps->width); - assert(y + h <= ps->height); -#else - /* temp clipping hack */ - if (x + w > ps->width) - w = ps->width - x; - if (y + h > ps->height) - h = ps->height -y; -#endif - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++) { - const unsigned pixel = src[j]; - pRow[0] = UBYTE_TO_FLOAT((pixel >> 16) & 0xff); - pRow[1] = UBYTE_TO_FLOAT((pixel >> 8) & 0xff); - pRow[2] = UBYTE_TO_FLOAT((pixel >> 0) & 0xff); - pRow[3] = UBYTE_TO_FLOAT((pixel >> 24) & 0xff); - pRow += 4; + CLIP_TILE; + + switch (ps->format) { + case PIPE_FORMAT_U_A8_R8_G8_B8: + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++) { + const unsigned pixel = src[j]; + pRow[0] = UBYTE_TO_FLOAT((pixel >> 16) & 0xff); + pRow[1] = UBYTE_TO_FLOAT((pixel >> 8) & 0xff); + pRow[2] = UBYTE_TO_FLOAT((pixel >> 0) & 0xff); + pRow[3] = UBYTE_TO_FLOAT((pixel >> 24) & 0xff); + pRow += 4; + } + src += ps->region->pitch; + p += w0 * 4; + } + break; + case PIPE_FORMAT_S8_Z24: + { + const float scale = 1.0 / (float) 0xffffff; + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++) { + const unsigned pixel = src[j]; + pRow[0] = + pRow[1] = + pRow[2] = + pRow[3] = (pixel & 0xffffff) * scale; + pRow += 4; + } + src += ps->region->pitch; + p += w0 * 4; + } } - src += ps->region->pitch; - p += w0 * 4; + break; + default: + assert(0); } } @@ -86,34 +107,122 @@ i915_put_tile_rgba(struct pipe_context *pipe, struct pipe_surface *ps, uint x, uint y, uint w, uint h, const float *p) { - /* any need to put tiles into i915 surfaces? */ + /* TODO */ assert(0); } +/* + * XXX note: same as code in sp_surface.c + */ +static void +i915_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 w0 = w; + const ubyte *pSrc; + ubyte *pDest; + uint i; -static struct pipe_surface * -i915_surface_alloc(struct pipe_context *pipe, unsigned format) + assert(ps->region->map); + + CLIP_TILE; + + if (dst_stride == 0) { + dst_stride = w0 * cpp; + } + + pSrc = ps->region->map + ps->offset + (y * ps->region->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; + } +} + + +/* + * XXX note: same as code in sp_surface.c + */ +static void +i915_put_tile(struct pipe_context *pipe, + struct pipe_surface *ps, + uint x, uint y, uint w, uint h, + const void *p, int src_stride) { - struct i915_surface *surf = CALLOC_STRUCT(i915_surface); + const uint cpp = ps->region->cpp; + const uint w0 = w; + const ubyte *pSrc; + ubyte *pDest; + uint i; + + assert(ps->region->map); + + CLIP_TILE; + + if (src_stride == 0) { + src_stride = w0 * cpp; + } + + pSrc = (const ubyte *) p; + pDest = ps->region->map + ps->offset + (y * ps->region->pitch + x) * cpp; + + for (i = 0; i < h; i++) { + memcpy(pDest, pSrc, w0 * cpp); + pDest += ps->region->pitch * cpp; + pSrc += src_stride; + } +} - if (!surf) - return NULL; - surf->surface.format = format; - surf->surface.refcount = 1; +/* + * XXX note: same as code in sp_surface.c + */ +static struct pipe_surface * +i915_get_tex_surface(struct pipe_context *pipe, + struct pipe_mipmap_tree *mt, + unsigned face, unsigned level, unsigned zslice) +{ + struct pipe_surface *ps; + unsigned offset; /* in bytes */ - // surf->surface.get_tile = i915_get_tile; - // surf->surface.put_tile = i915_put_tile; + offset = mt->level[level].level_offset; - return &surf->surface; + if (mt->target == PIPE_TEXTURE_CUBE) { + offset += mt->level[level].image_offset[face] * mt->cpp; + } + else if (mt->target == PIPE_TEXTURE_3D) { + offset += mt->level[level].image_offset[zslice] * mt->cpp; + } + else { + assert(face == 0); + assert(zslice == 0); + } + + ps = pipe->winsys->surface_alloc(pipe->winsys, mt->format); + if (ps) { + assert(ps->format); + assert(ps->refcount); + pipe_region_reference(&ps->region, mt->region); + ps->width = mt->level[level].width; + ps->height = mt->level[level].height; + ps->offset = offset; + } + return ps; } void i915_init_surface_functions(struct i915_context *i915) { - i915->pipe.surface_alloc = i915_surface_alloc; + i915->pipe.get_tex_surface = i915_get_tex_surface; + i915->pipe.get_tile = i915_get_tile; + 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; } |