diff options
Diffstat (limited to 'src')
41 files changed, 955 insertions, 396 deletions
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index eef898f486..5d626b7cdc 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -769,8 +769,7 @@ void cso_restore_vertex_shader(struct cso_context *ctx) enum pipe_error cso_set_framebuffer(struct cso_context *ctx, const struct pipe_framebuffer_state *fb) { - /* XXX this memcmp() fails to detect buffer size changes */ - if (1/*memcmp(&ctx->fb, fb, sizeof(*fb))*/) { + if (memcmp(&ctx->fb, fb, sizeof(*fb)) != 0) { ctx->fb = *fb; ctx->pipe->set_framebuffer_state(ctx->pipe, fb); } diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index f501b2aed4..6dc20f2c90 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -415,8 +415,11 @@ aaline_create_texture(struct aaline_stage *aaline) assert(aaline->texture->width[level] == aaline->texture->height[level]); - surface = screen->get_tex_surface(screen, aaline->texture, 0, level, 0); - data = pipe_surface_map(surface); + /* This texture is new, no need to flush. + */ + surface = screen->get_tex_surface(screen, aaline->texture, 0, level, 0, + PIPE_BUFFER_USAGE_CPU_WRITE); + data = screen->surface_map(screen, surface, PIPE_BUFFER_USAGE_CPU_WRITE); if (data == NULL) return FALSE; @@ -440,9 +443,8 @@ aaline_create_texture(struct aaline_stage *aaline) } /* unmap */ - pipe_surface_unmap(surface); - pipe_surface_reference(&surface, NULL); - pipe->texture_update(pipe, aaline->texture, 0, (1 << level)); + screen->surface_unmap(screen, surface); + screen->tex_surface_release(screen, &surface); } return TRUE; } diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c index 73ee419858..4bca92ff11 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -376,8 +376,14 @@ pstip_update_texture(struct pstip_stage *pstip) uint i, j; ubyte *data; - surface = screen->get_tex_surface(screen, pstip->texture, 0, 0, 0); - data = pipe_surface_map(surface); + /* XXX: want to avoid flushing just because we use stipple: + */ + pipe->flush( pipe, PIPE_FLUSH_TEXTURE_CACHE, NULL ); + + surface = screen->get_tex_surface(screen, pstip->texture, 0, 0, 0, + PIPE_BUFFER_USAGE_CPU_WRITE); + data = screen->surface_map(screen, surface, + PIPE_BUFFER_USAGE_CPU_WRITE); /* * Load alpha texture. @@ -399,9 +405,8 @@ pstip_update_texture(struct pstip_stage *pstip) } /* unmap */ - pipe_surface_unmap(surface); - pipe_surface_reference(&surface, NULL); - pipe->texture_update(pipe, pstip->texture, 0, 0x1); + screen->surface_unmap(screen, surface); + screen->tex_surface_release(screen, &surface); } diff --git a/src/gallium/auxiliary/util/p_tile.c b/src/gallium/auxiliary/util/p_tile.c index 63e1cc6013..5728757d2f 100644 --- a/src/gallium/auxiliary/util/p_tile.c +++ b/src/gallium/auxiliary/util/p_tile.c @@ -50,6 +50,7 @@ pipe_get_tile_raw(struct pipe_context *pipe, uint x, uint y, uint w, uint h, void *p, int dst_stride) { + struct pipe_screen *screen = pipe->screen; const uint cpp = ps->cpp; const ubyte *pSrc; const uint src_stride = ps->pitch * cpp; @@ -63,7 +64,11 @@ pipe_get_tile_raw(struct pipe_context *pipe, if (pipe_clip_tile(x, y, &w, &h, ps)) return; - pSrc = (const ubyte *) pipe_surface_map(ps) + (y * ps->pitch + x) * cpp; + pSrc = (const ubyte *) screen->surface_map(screen, ps, + PIPE_BUFFER_USAGE_CPU_READ); + assert(pSrc); /* XXX: proper error handling! */ + + pSrc += (y * ps->pitch + x) * cpp; pDest = (ubyte *) p; for (i = 0; i < h; i++) { @@ -72,7 +77,7 @@ pipe_get_tile_raw(struct pipe_context *pipe, pSrc += src_stride; } - pipe_surface_unmap(ps); + screen->surface_unmap(screen, ps); } @@ -86,6 +91,7 @@ pipe_put_tile_raw(struct pipe_context *pipe, uint x, uint y, uint w, uint h, const void *p, int src_stride) { + struct pipe_screen *screen = pipe->screen; const uint cpp = ps->cpp; const ubyte *pSrc; const uint dst_stride = ps->pitch * cpp; @@ -100,7 +106,11 @@ pipe_put_tile_raw(struct pipe_context *pipe, return; pSrc = (const ubyte *) p; - pDest = (ubyte *) pipe_surface_map(ps) + (y * ps->pitch + x) * cpp; + + pDest = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_WRITE); + assert(pDest); /* XXX: proper error handling */ + + pDest += (y * ps->pitch + x) * cpp; for (i = 0; i < h; i++) { memcpy(pDest, pSrc, w * cpp); @@ -108,7 +118,7 @@ pipe_put_tile_raw(struct pipe_context *pipe, pSrc += src_stride; } - pipe_surface_unmap(ps); + screen->surface_unmap(screen, ps); } @@ -834,18 +844,26 @@ pipe_get_tile_z(struct pipe_context *pipe, uint x, uint y, uint w, uint h, uint *z) { + struct pipe_screen *screen = pipe->screen; const uint dstStride = w; + void *map; uint *pDest = z; uint i, j; if (pipe_clip_tile(x, y, &w, &h, ps)) return; + map = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_READ); + if (!map) { + assert(0); + return; + } + switch (ps->format) { case PIPE_FORMAT_Z32_UNORM: { const uint *pSrc - = (const uint *) pipe_surface_map(ps) + (y * ps->pitch + x); + = (const uint *)map + (y * ps->pitch + x); for (i = 0; i < h; i++) { memcpy(pDest, pSrc, 4 * w); pDest += dstStride; @@ -857,7 +875,7 @@ pipe_get_tile_z(struct pipe_context *pipe, case PIPE_FORMAT_X8Z24_UNORM: { const uint *pSrc - = (const uint *) pipe_surface_map(ps) + (y * ps->pitch + x); + = (const uint *)map + (y * ps->pitch + x); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { /* convert 24-bit Z to 32-bit Z */ @@ -871,7 +889,7 @@ pipe_get_tile_z(struct pipe_context *pipe, case PIPE_FORMAT_Z16_UNORM: { const ushort *pSrc - = (const ushort *) pipe_surface_map(ps) + (y * ps->pitch + x); + = (const ushort *)map + (y * ps->pitch + x); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { /* convert 16-bit Z to 32-bit Z */ @@ -886,7 +904,7 @@ pipe_get_tile_z(struct pipe_context *pipe, assert(0); } - pipe_surface_unmap(ps); + screen->surface_unmap(screen, ps); } @@ -896,17 +914,25 @@ pipe_put_tile_z(struct pipe_context *pipe, uint x, uint y, uint w, uint h, const uint *zSrc) { + struct pipe_screen *screen = pipe->screen; const uint srcStride = w; const uint *pSrc = zSrc; + void *map; uint i, j; if (pipe_clip_tile(x, y, &w, &h, ps)) return; + map = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_WRITE); + if (!map) { + assert(0); + return; + } + switch (ps->format) { case PIPE_FORMAT_Z32_UNORM: { - uint *pDest = (uint *) pipe_surface_map(ps) + (y * ps->pitch + x); + uint *pDest = (uint *) map + (y * ps->pitch + x); for (i = 0; i < h; i++) { memcpy(pDest, pSrc, 4 * w); pDest += ps->pitch; @@ -917,7 +943,7 @@ pipe_put_tile_z(struct pipe_context *pipe, case PIPE_FORMAT_S8Z24_UNORM: case PIPE_FORMAT_X8Z24_UNORM: { - uint *pDest = (uint *) pipe_surface_map(ps) + (y * ps->pitch + x); + uint *pDest = (uint *) map + (y * ps->pitch + x); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { /* convert 32-bit Z to 24-bit Z (0 stencil) */ @@ -930,7 +956,7 @@ pipe_put_tile_z(struct pipe_context *pipe, break; case PIPE_FORMAT_Z16_UNORM: { - ushort *pDest = (ushort *) pipe_surface_map(ps) + (y * ps->pitch + x); + ushort *pDest = (ushort *) map + (y * ps->pitch + x); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { /* convert 32-bit Z to 16-bit Z */ @@ -945,7 +971,7 @@ pipe_put_tile_z(struct pipe_context *pipe, assert(0); } - pipe_surface_unmap(ps); + screen->surface_unmap(screen, ps); } diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index 568d62ced1..999a3e5099 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -287,7 +287,8 @@ util_blit_pixels(struct blit_state *ctx, if (!tex) return; - texSurf = screen->get_tex_surface(screen, tex, 0, 0, 0); + texSurf = screen->get_tex_surface(screen, tex, 0, 0, 0, + PIPE_BUFFER_USAGE_GPU_WRITE); /* load temp texture */ pipe->surface_copy(pipe, FALSE, @@ -295,7 +296,9 @@ util_blit_pixels(struct blit_state *ctx, src, srcLeft, srcTop, /* src */ srcW, srcH); /* size */ - pipe->texture_update(pipe, tex, 0, 1 << 0); + /* free the surface, update the texture if necessary. + */ + screen->tex_surface_release(screen, &texSurf); /* save state (restored below) */ cso_save_blend(ctx->cso); @@ -356,8 +359,6 @@ util_blit_pixels(struct blit_state *ctx, cso_restore_vertex_shader(ctx->cso); cso_restore_viewport(ctx->cso); - /* free the texture */ - pipe_surface_reference(&texSurf, NULL); screen->texture_release(screen, &tex); } diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index c53c512268..7d71aefda9 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -589,8 +589,11 @@ make_1d_mipmap(struct gen_mipmap_state *ctx, struct pipe_surface *srcSurf, *dstSurf; void *srcMap, *dstMap; - srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice); - dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice); + srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice, + PIPE_BUFFER_USAGE_CPU_READ); + + dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice, + PIPE_BUFFER_USAGE_CPU_WRITE); srcMap = ((ubyte *) winsys->buffer_map(winsys, srcSurf->buffer, PIPE_BUFFER_USAGE_CPU_READ) @@ -629,8 +632,10 @@ make_2d_mipmap(struct gen_mipmap_state *ctx, struct pipe_surface *srcSurf, *dstSurf; ubyte *srcMap, *dstMap; - srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice); - dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice); + srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice, + PIPE_BUFFER_USAGE_CPU_READ); + dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice, + PIPE_BUFFER_USAGE_CPU_WRITE); srcMap = ((ubyte *) winsys->buffer_map(winsys, srcSurf->buffer, PIPE_BUFFER_USAGE_CPU_READ) @@ -891,10 +896,14 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) { const uint srcLevel = dstLevel - 1; + struct pipe_surface *surf = + screen->get_tex_surface(screen, pt, face, dstLevel, zslice, + PIPE_BUFFER_USAGE_GPU_WRITE); + /* * Setup framebuffer / dest surface */ - fb.cbufs[0] = screen->get_tex_surface(screen, pt, face, dstLevel, zslice); + fb.cbufs[0] = surf; fb.width = pt->width[dstLevel]; fb.height = pt->height[dstLevel]; cso_set_framebuffer(ctx->cso, &fb); @@ -925,7 +934,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); /* need to signal that the texture has changed _after_ rendering to it */ - pipe->texture_update(pipe, pt, face, (1 << dstLevel)); + pipe_surface_reference( &surf, NULL ); } /* restore state we changed */ diff --git a/src/gallium/auxiliary/util/u_string.h b/src/gallium/auxiliary/util/u_string.h index b99d4e8021..2fede229d9 100644 --- a/src/gallium/auxiliary/util/u_string.h +++ b/src/gallium/auxiliary/util/u_string.h @@ -41,6 +41,8 @@ #include <stddef.h> #include <stdarg.h> +#include "pipe/p_compiler.h" + #ifdef __cplusplus extern "C" { @@ -48,11 +50,121 @@ extern "C" { #ifdef WIN32 + int util_vsnprintf(char *, size_t, const char *, va_list); int util_snprintf(char *str, size_t size, const char *format, ...); + +static INLINE void +util_sprintf(char *str, const char *format, ...) +{ + va_list ap; + va_start(ap, format); + util_vsnprintf(str, (size_t)-1, format, ap); + va_end(ap); +} + +static INLINE char * +util_strchr(const char *s, char c) +{ + while(*s) { + if(*s == c) + return (char *)s; + ++s; + } + return NULL; +} + +static INLINE char* +util_strncat(char *dst, const char *src, size_t n) +{ + char *p = dst + strlen(dst); + const char *q = src; + size_t i; + + for (i = 0; i < n && *q != '\0'; ++i) + *p++ = *q++; + *p = '\0'; + + return dst; +} + +static INLINE int +util_strcmp(const char *s1, const char *s2) +{ + unsigned char u1, u2; + + while (1) { + u1 = (unsigned char) *s1++; + u2 = (unsigned char) *s2++; + if (u1 != u2) + return u1 - u2; + if (u1 == '\0') + return 0; + } + return 0; +} + +static INLINE int +util_strncmp(const char *s1, const char *s2, size_t n) +{ + unsigned char u1, u2; + + while (n-- > 0) { + u1 = (unsigned char) *s1++; + u2 = (unsigned char) *s2++; + if (u1 != u2) + return u1 - u2; + if (u1 == '\0') + return 0; + } + return 0; +} + +static INLINE char * +util_strstr(const char *haystack, const char *needle) +{ + const char *p = haystack; + int len = strlen(needle); + + for (; (p = util_strchr(p, *needle)) != 0; p++) { + if (util_strncmp(p, needle, len) == 0) { + return (char *)p; + } + } + return NULL; +} + +static INLINE void * +util_memmove(void *dest, const void *src, size_t n) +{ + char *p = (char *)dest; + const char *q = (const char *)src; + if (dest < src) { + while (n--) + *p++ = *q++; + } + else + { + p += n; + q += n; + while (n--) + *--p = *--q; + } + return dest; +} + + #else + #define util_vsnprintf vsnprintf #define util_snprintf snprintf +#define util_strchr strchr +#define util_strcmp strcmp +#define util_strncmp strncmp +#define util_strncat strncat +#define util_strstr strstr +#define util_memmove memmove + #endif diff --git a/src/gallium/drivers/failover/fo_context.c b/src/gallium/drivers/failover/fo_context.c index cb95ba516f..014a3e31d5 100644 --- a/src/gallium/drivers/failover/fo_context.c +++ b/src/gallium/drivers/failover/fo_context.c @@ -147,8 +147,8 @@ struct pipe_context *failover_create( struct pipe_context *hw, failover->pipe.texture_create = hw->texture_create; failover->pipe.texture_release = hw->texture_release; failover->pipe.get_tex_surface = hw->get_tex_surface; -#endif failover->pipe.texture_update = hw->texture_update; +#endif failover->pipe.flush = hw->flush; diff --git a/src/gallium/drivers/i915simple/i915_screen.c b/src/gallium/drivers/i915simple/i915_screen.c index 646cfd921d..ba8f183bdf 100644 --- a/src/gallium/drivers/i915simple/i915_screen.c +++ b/src/gallium/drivers/i915simple/i915_screen.c @@ -201,6 +201,35 @@ i915_destroy_screen( struct pipe_screen *screen ) } +static void * +i915_surface_map( struct pipe_screen *screen, + struct pipe_surface *surface, + unsigned flags ) +{ + char *map = screen->winsys->buffer_map( screen->winsys, surface->buffer, flags ); + if (map == NULL) + return NULL; + + if (surface->texture && + (flags & PIPE_BUFFER_USAGE_CPU_WRITE)) + { + /* Do something to notify contexts of a texture change. + */ + /* i915_screen(screen)->timestamp++; */ + } + + return map + surface->offset; +} + +static void +i915_surface_unmap(struct pipe_screen *screen, + struct pipe_surface *surface) +{ + screen->winsys->buffer_unmap( screen->winsys, surface->buffer ); +} + + + /** * Create a new i915_screen object */ @@ -244,6 +273,8 @@ i915_create_screen(struct pipe_winsys *winsys, uint pci_id) i915screen->screen.get_param = i915_get_param; i915screen->screen.get_paramf = i915_get_paramf; i915screen->screen.is_format_supported = i915_is_format_supported; + i915screen->screen.surface_map = i915_surface_map; + i915screen->screen.surface_unmap = i915_surface_unmap; i915_init_screen_texture_functions(&i915screen->screen); diff --git a/src/gallium/drivers/i915simple/i915_surface.c b/src/gallium/drivers/i915simple/i915_surface.c index f4fbedbe9b..98367ac073 100644 --- a/src/gallium/drivers/i915simple/i915_surface.c +++ b/src/gallium/drivers/i915simple/i915_surface.c @@ -51,17 +51,25 @@ i915_surface_copy(struct pipe_context *pipe, assert( dst->cpp == src->cpp ); if (0) { - pipe_copy_rect(pipe_surface_map(dst), + void *dst_map = pipe->screen->surface_map( pipe->screen, + dst, + PIPE_BUFFER_USAGE_CPU_WRITE ); + + const void *src_map = pipe->screen->surface_map( pipe->screen, + src, + PIPE_BUFFER_USAGE_CPU_READ ); + + pipe_copy_rect(dst_map, dst->cpp, dst->pitch, dstx, dsty, width, height, - pipe_surface_map(src), + src_map, do_flip ? -(int) src->pitch : src->pitch, srcx, do_flip ? 1 - srcy - height : srcy); - pipe_surface_unmap(src); - pipe_surface_unmap(dst); + pipe->screen->surface_unmap(pipe->screen, src); + pipe->screen->surface_unmap(pipe->screen, dst); } else { i915_copy_blit( i915_context(pipe), @@ -92,7 +100,10 @@ i915_surface_fill(struct pipe_context *pipe, { if (0) { unsigned i, j; - void *dst_map = pipe_surface_map(dst); + void *dst_map = pipe->screen->surface_map( pipe->screen, + dst, + PIPE_BUFFER_USAGE_CPU_WRITE ); + switch (dst->cpp) { case 1: { @@ -126,7 +137,7 @@ i915_surface_fill(struct pipe_context *pipe, break; } - pipe_surface_unmap( dst ); + pipe->screen->surface_unmap(pipe->screen, dst); } else { i915_fill_blit( i915_context(pipe), diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index c39e747705..f668e2e7d7 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -105,6 +105,50 @@ i915_miptree_set_image_offset(struct i915_texture *tex, } +/* Hack it up to use the old winsys->surface_alloc_storage() + * method for now: + */ +static boolean +i915_displaytarget_layout(struct pipe_screen *screen, + struct i915_texture *tex) +{ + struct pipe_winsys *ws = screen->winsys; + struct pipe_surface surf; + unsigned flags = (PIPE_BUFFER_USAGE_CPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE | + PIPE_BUFFER_USAGE_GPU_READ | + PIPE_BUFFER_USAGE_GPU_WRITE); + + + memset(&surf, 0, sizeof(surf)); + + ws->surface_alloc_storage( ws, + &surf, + tex->base.width[0], + tex->base.height[0], + tex->base.format, + flags); + + /* Now extract the goodies: + */ + i915_miptree_set_image_offset( tex, 0, 0, 0, 0 ); + i915_miptree_set_level_info( tex, 0, 0, 0, 0, + tex->base.width[0], + tex->base.height[0], + 1 ); + + tex->buffer = surf.buffer; + tex->pitch = surf.pitch; + tex->total_height = 0; + + + return tex->buffer != NULL; +} + + + + + static void i945_miptree_layout_2d( struct i915_texture *tex ) { @@ -483,30 +527,45 @@ static struct pipe_texture * i915_texture_create_screen(struct pipe_screen *screen, const struct pipe_texture *templat) { + struct i915_screen *i915screen = i915_screen(screen); + struct pipe_winsys *ws = screen->winsys; struct i915_texture *tex = CALLOC_STRUCT(i915_texture); - if (tex) { - struct i915_screen *i915screen = i915_screen(screen); - struct pipe_winsys *ws = screen->winsys; - - tex->base = *templat; - tex->base.refcount = 1; - tex->base.screen = screen; + if (!tex) + return NULL; - if (i915screen->is_i945 ? i945_miptree_layout(tex) : - i915_miptree_layout(tex)) - tex->buffer = ws->buffer_create(ws, 64, - PIPE_BUFFER_USAGE_PIXEL, - tex->pitch * tex->base.cpp * - tex->total_height); + tex->base = *templat; + tex->base.refcount = 1; + tex->base.screen = screen; - if (!tex->buffer) { - FREE(tex); - return NULL; + if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) { + if (!i915_displaytarget_layout(screen, tex)) + goto fail; + } + else { + if (i915screen->is_i945) { + if (!i945_miptree_layout(tex)) + goto fail; + } + else { + if (!i915_miptree_layout(tex)) + goto fail; } + + tex->buffer = ws->buffer_create(ws, 64, + PIPE_BUFFER_USAGE_PIXEL, + tex->pitch * tex->base.cpp * + tex->total_height); + + if (!tex->buffer) + goto fail; } return &tex->base; + + fail: + FREE(tex); + return NULL; } @@ -541,13 +600,6 @@ i915_texture_release_screen(struct pipe_screen *screen, } -static void -i915_texture_update(struct pipe_context *pipe, struct pipe_texture *texture, - uint face, uint levelsMask) -{ - /* no-op? */ -} - /* * XXX note: same as code in sp_surface.c @@ -555,7 +607,8 @@ i915_texture_update(struct pipe_context *pipe, struct pipe_texture *texture, static struct pipe_surface * i915_get_tex_surface_screen(struct pipe_screen *screen, struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice) + unsigned face, unsigned level, unsigned zslice, + unsigned flags) { struct i915_texture *tex = (struct i915_texture *)pt; struct pipe_winsys *ws = screen->winsys; @@ -586,6 +639,7 @@ i915_get_tex_surface_screen(struct pipe_screen *screen, ps->height = pt->height[level]; ps->pitch = tex->pitch; ps->offset = offset; + ps->usage = flags; } return ps; } @@ -594,7 +648,7 @@ i915_get_tex_surface_screen(struct pipe_screen *screen, void i915_init_texture_functions(struct i915_context *i915) { - i915->pipe.texture_update = i915_texture_update; +// i915->pipe.texture_update = i915_texture_update; } diff --git a/src/gallium/drivers/i965simple/brw_surface.c b/src/gallium/drivers/i965simple/brw_surface.c index c99a91dcf7..3e3736b280 100644 --- a/src/gallium/drivers/i965simple/brw_surface.c +++ b/src/gallium/drivers/i965simple/brw_surface.c @@ -35,27 +35,6 @@ #include "util/p_tile.h" -/* 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 -brw_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) -{ - pipe_copy_rect(pipe_surface_map(dst) + dst->offset, - dst->cpp, dst->pitch, - dstx, dsty, width, height, src, src_pitch, srcx, srcy); - - pipe_surface_unmap(dst); -} - /* Assumes all values are within bounds -- no checking at this level - * do it higher up if required. @@ -72,17 +51,25 @@ brw_surface_copy(struct pipe_context *pipe, assert(dst->cpp == src->cpp); if (0) { - pipe_copy_rect(pipe_surface_map(dst) + dst->offset, + void *dst_map = pipe->screen->surface_map( pipe->screen, + dst, + PIPE_BUFFER_USAGE_CPU_WRITE ); + + const void *src_map = pipe->screen->surface_map( pipe->screen, + src, + PIPE_BUFFER_USAGE_CPU_READ ); + + pipe_copy_rect(dst_map, dst->cpp, dst->pitch, - dstx, dsty, - width, height, - pipe_surface_map(src) + src->offset, - do_flip ? -src->pitch : src->pitch, + dstx, dsty, + width, height, + src_map, + do_flip ? -(int) src->pitch : src->pitch, srcx, do_flip ? 1 - srcy - height : srcy); - pipe_surface_unmap(src); - pipe_surface_unmap(dst); + pipe->screen->surface_unmap(pipe->screen, src); + pipe->screen->surface_unmap(pipe->screen, dst); } else { brw_copy_blit(brw_context(pipe), @@ -113,7 +100,10 @@ brw_surface_fill(struct pipe_context *pipe, { if (0) { unsigned i, j; - void *dst_map = pipe_surface_map(dst); + void *dst_map = pipe->screen->surface_map( pipe->screen, + dst, + PIPE_BUFFER_USAGE_CPU_WRITE ); + switch (dst->cpp) { case 1: { @@ -147,7 +137,7 @@ brw_surface_fill(struct pipe_context *pipe, break; } - pipe_surface_unmap( dst ); + pipe->screen->surface_unmap(pipe->screen, dst); } else { brw_fill_blit(brw_context(pipe), @@ -164,7 +154,6 @@ brw_surface_fill(struct pipe_context *pipe, void brw_init_surface_functions(struct brw_context *brw) { - (void) brw_surface_data; /* silence warning */ brw->pipe.surface_copy = brw_surface_copy; brw->pipe.surface_fill = brw_surface_fill; } diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.c b/src/gallium/drivers/i965simple/brw_tex_layout.c index b580f98204..78ae0b1223 100644 --- a/src/gallium/drivers/i965simple/brw_tex_layout.c +++ b/src/gallium/drivers/i965simple/brw_tex_layout.c @@ -357,14 +357,6 @@ brw_texture_release_screen(struct pipe_screen *screen, } -static void -brw_texture_update(struct pipe_context *pipe, struct pipe_texture *texture, - uint face, uint levelsMask) -{ - /* no-op? */ -} - - static struct pipe_surface * brw_get_tex_surface_screen(struct pipe_screen *screen, struct pipe_texture *pt, @@ -407,7 +399,7 @@ brw_get_tex_surface_screen(struct pipe_screen *screen, void brw_init_texture_functions(struct brw_context *brw) { - brw->pipe.texture_update = brw_texture_update; +// brw->pipe.texture_update = brw_texture_update; } diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index fe9cd8375e..2af0db3714 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -192,11 +192,11 @@ softpipe_create( struct pipe_screen *screen, * Must be before quad stage setup! */ for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) - softpipe->cbuf_cache[i] = sp_create_tile_cache(); - softpipe->zsbuf_cache = sp_create_tile_cache(); + softpipe->cbuf_cache[i] = sp_create_tile_cache( screen ); + softpipe->zsbuf_cache = sp_create_tile_cache( screen ); for (i = 0; i < PIPE_MAX_SAMPLERS; i++) - softpipe->tex_cache[i] = sp_create_tile_cache(); + softpipe->tex_cache[i] = sp_create_tile_cache( screen ); /* setup quad rendering stages */ diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c index 0625b69099..e03994b63b 100644 --- a/src/gallium/drivers/softpipe/sp_flush.c +++ b/src/gallium/drivers/softpipe/sp_flush.c @@ -50,25 +50,28 @@ softpipe_flush( struct pipe_context *pipe, draw_flush(softpipe->draw); - /* - flush the quad pipeline - * - flush the texture cache - * - flush the render cache - */ + if (flags & PIPE_FLUSH_TEXTURE_CACHE) { + for (i = 0; i < softpipe->num_textures; i++) { + sp_flush_tile_cache(softpipe, softpipe->tex_cache[i]); + } + } - for (i = 0; i < softpipe->framebuffer.num_cbufs; i++) - if (softpipe->cbuf_cache[i]) - sp_flush_tile_cache(softpipe, softpipe->cbuf_cache[i]); + if (flags & PIPE_FLUSH_RENDER_CACHE) { + for (i = 0; i < softpipe->framebuffer.num_cbufs; i++) + if (softpipe->cbuf_cache[i]) + sp_flush_tile_cache(softpipe, softpipe->cbuf_cache[i]); - if (softpipe->zsbuf_cache) - sp_flush_tile_cache(softpipe, softpipe->zsbuf_cache); + if (softpipe->zsbuf_cache) + sp_flush_tile_cache(softpipe, softpipe->zsbuf_cache); - /* Need this call for hardware buffers before swapbuffers. - * - * there should probably be another/different flush-type function - * that's called before swapbuffers because we don't always want - * to unmap surfaces when flushing. - */ - softpipe_unmap_surfaces(softpipe); + /* Need this call for hardware buffers before swapbuffers. + * + * there should probably be another/different flush-type function + * that's called before swapbuffers because we don't always want + * to unmap surfaces when flushing. + */ + softpipe_unmap_surfaces(softpipe); + } if (fence) *fence = NULL; diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index 7dacb1c461..e9926bf41f 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -33,6 +33,7 @@ #include "sp_texture.h" #include "sp_winsys.h" +#include "sp_screen.h" static const char * @@ -137,6 +138,7 @@ softpipe_destroy_screen( struct pipe_screen *screen ) } + /** * Create a new pipe_screen object * Note: we're not presently subclassing pipe_screen (no softpipe_screen). @@ -144,22 +146,22 @@ softpipe_destroy_screen( struct pipe_screen *screen ) struct pipe_screen * softpipe_create_screen(struct pipe_winsys *winsys) { - struct pipe_screen *screen = CALLOC_STRUCT(pipe_screen); + struct softpipe_screen *screen = CALLOC_STRUCT(softpipe_screen); if (!screen) return NULL; - screen->winsys = winsys; + screen->base.winsys = winsys; - screen->destroy = softpipe_destroy_screen; + screen->base.destroy = softpipe_destroy_screen; - screen->get_name = softpipe_get_name; - screen->get_vendor = softpipe_get_vendor; - screen->get_param = softpipe_get_param; - screen->get_paramf = softpipe_get_paramf; - screen->is_format_supported = softpipe_is_format_supported; + screen->base.get_name = softpipe_get_name; + screen->base.get_vendor = softpipe_get_vendor; + screen->base.get_param = softpipe_get_param; + screen->base.get_paramf = softpipe_get_paramf; + screen->base.is_format_supported = softpipe_is_format_supported; - softpipe_init_screen_texture_funcs(screen); + softpipe_init_screen_texture_funcs(&screen->base); - return screen; + return &screen->base; } diff --git a/src/gallium/drivers/softpipe/sp_screen.h b/src/gallium/drivers/softpipe/sp_screen.h new file mode 100644 index 0000000000..3d4bfd3e84 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_screen.h @@ -0,0 +1,58 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell <keith@tungstengraphics.com> + */ + +#ifndef SP_SCREEN_H +#define SP_SCREEN_H + +#include "pipe/p_screen.h" +#include "pipe/p_defines.h" + + + +struct softpipe_screen { + struct pipe_screen base; + + /* Increments whenever textures are modified. Contexts can track + * this. + */ + unsigned timestamp; +}; + + + + +static INLINE struct softpipe_screen * +softpipe_screen( struct pipe_screen *pipe ) +{ + return (struct softpipe_screen *)pipe; +} + + +#endif /* SP_SCREEN_H */ diff --git a/src/gallium/drivers/softpipe/sp_surface.c b/src/gallium/drivers/softpipe/sp_surface.c index 653449c4f1..29a1e92416 100644 --- a/src/gallium/drivers/softpipe/sp_surface.c +++ b/src/gallium/drivers/softpipe/sp_surface.c @@ -46,19 +46,28 @@ sp_surface_copy(struct pipe_context *pipe, struct pipe_surface *src, unsigned srcx, unsigned srcy, unsigned width, unsigned height) { + void *dst_map = pipe->screen->surface_map( pipe->screen, + dst, + PIPE_BUFFER_USAGE_CPU_WRITE ); + + const void *src_map = pipe->screen->surface_map( pipe->screen, + src, + PIPE_BUFFER_USAGE_CPU_READ ); + assert( dst->cpp == src->cpp ); + assert(src_map && dst_map); - pipe_copy_rect(pipe_surface_map(dst), + pipe_copy_rect(dst_map, dst->cpp, dst->pitch, dstx, dsty, width, height, - pipe_surface_map(src), + src_map, do_flip ? -(int) src->pitch : src->pitch, srcx, do_flip ? 1 - srcy - height : srcy); - pipe_surface_unmap(src); - pipe_surface_unmap(dst); + pipe->screen->surface_unmap(pipe->screen, src); + pipe->screen->surface_unmap(pipe->screen, dst); } @@ -83,7 +92,9 @@ sp_surface_fill(struct pipe_context *pipe, unsigned width, unsigned height, unsigned value) { unsigned i, j; - void *dst_map = pipe_surface_map(dst); + void *dst_map = pipe->screen->surface_map( pipe->screen, + dst, + PIPE_BUFFER_USAGE_CPU_WRITE ); assert(dst->pitch > 0); assert(width <= dst->pitch); @@ -147,7 +158,7 @@ sp_surface_fill(struct pipe_context *pipe, break; } - pipe_surface_unmap( dst ); + pipe->screen->surface_unmap(pipe->screen, dst); } diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 256586ec88..599ff2ac45 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -40,6 +40,7 @@ #include "sp_state.h" #include "sp_texture.h" #include "sp_tile_cache.h" +#include "sp_screen.h" /* Simple, maximally packed layout. @@ -51,40 +52,87 @@ static unsigned minify( unsigned d ) } -static void -softpipe_texture_layout(struct softpipe_texture * spt) +/* Conventional allocation path for non-display textures: + */ +static boolean +softpipe_texture_layout(struct pipe_screen *screen, + struct softpipe_texture * spt) { + struct pipe_winsys *ws = screen->winsys; struct pipe_texture *pt = &spt->base; unsigned level; unsigned width = pt->width[0]; unsigned height = pt->height[0]; unsigned depth = pt->depth[0]; - spt->buffer_size = 0; + unsigned buffer_size = 0; for (level = 0; level <= pt->last_level; level++) { pt->width[level] = width; pt->height[level] = height; pt->depth[level] = depth; + spt->pitch[level] = width; - spt->level_offset[level] = spt->buffer_size; + spt->level_offset[level] = buffer_size; - spt->buffer_size += ((pt->compressed) ? MAX2(1, height/4) : height) * - ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) * - width * pt->cpp; + buffer_size += (((pt->compressed) ? MAX2(1, height/4) : height) * + ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) * + width * pt->cpp); width = minify(width); height = minify(height); depth = minify(depth); } + + spt->buffer = ws->buffer_create(ws, 32, + PIPE_BUFFER_USAGE_PIXEL, + buffer_size); + + return spt->buffer != NULL; +} + + + +/* Hack it up to use the old winsys->surface_alloc_storage() + * method for now: + */ +static boolean +softpipe_displaytarget_layout(struct pipe_screen *screen, + struct softpipe_texture * spt) +{ + struct pipe_winsys *ws = screen->winsys; + struct pipe_surface surf; + unsigned flags = (PIPE_BUFFER_USAGE_CPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE | + PIPE_BUFFER_USAGE_GPU_READ | + PIPE_BUFFER_USAGE_GPU_WRITE); + + + memset(&surf, 0, sizeof(surf)); + + ws->surface_alloc_storage( ws, + &surf, + spt->base.width[0], + spt->base.height[0], + spt->base.format, + flags); + + /* Now extract the goodies: + */ + spt->buffer = surf.buffer; + spt->pitch[0] = surf.pitch; + + return spt->buffer != NULL; } + + + static struct pipe_texture * softpipe_texture_create(struct pipe_screen *screen, const struct pipe_texture *templat) { - struct pipe_winsys *ws = screen->winsys; struct softpipe_texture *spt = CALLOC_STRUCT(softpipe_texture); if (!spt) return NULL; @@ -93,19 +141,21 @@ softpipe_texture_create(struct pipe_screen *screen, spt->base.refcount = 1; spt->base.screen = screen; - softpipe_texture_layout(spt); - - spt->buffer = ws->buffer_create(ws, 32, - PIPE_BUFFER_USAGE_PIXEL, - spt->buffer_size); - if (!spt->buffer) { - FREE(spt); - return NULL; + if (spt->base.tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) { + if (!softpipe_displaytarget_layout(screen, spt)) + goto fail; } - + else { + if (!softpipe_texture_layout(screen, spt)) + goto fail; + } + assert(spt->base.refcount == 1); - return &spt->base; + + fail: + FREE(spt); + return NULL; } @@ -116,19 +166,10 @@ softpipe_texture_release(struct pipe_screen *screen, if (!*pt) return; - /* - DBG("%s %p refcount will be %d\n", - __FUNCTION__, (void *) *pt, (*pt)->refcount - 1); - */ if (--(*pt)->refcount <= 0) { struct softpipe_texture *spt = softpipe_texture(*pt); - /* - DBG("%s deleting %p\n", __FUNCTION__, (void *) spt); - */ - pipe_buffer_reference(screen->winsys, &spt->buffer, NULL); - FREE(spt); } *pt = NULL; @@ -138,7 +179,8 @@ softpipe_texture_release(struct pipe_screen *screen, static struct pipe_surface * softpipe_get_tex_surface(struct pipe_screen *screen, struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice) + unsigned face, unsigned level, unsigned zslice, + unsigned usage) { struct pipe_winsys *ws = screen->winsys; struct softpipe_texture *spt = softpipe_texture(pt); @@ -157,6 +199,24 @@ softpipe_get_tex_surface(struct pipe_screen *screen, ps->height = pt->height[level]; ps->pitch = ps->width; ps->offset = spt->level_offset[level]; + ps->usage = usage; + + /* Because we are softpipe, anything that the state tracker + * thought was going to be done with the GPU will actually get + * done with the CPU. Let's adjust the flags to take that into + * account. + */ + if (ps->usage & PIPE_BUFFER_USAGE_GPU_WRITE) + ps->usage |= PIPE_BUFFER_USAGE_CPU_WRITE; + + if (ps->usage & PIPE_BUFFER_USAGE_GPU_READ) + ps->usage |= PIPE_BUFFER_USAGE_CPU_READ; + + + pipe_texture_reference(&ps->texture, pt); + ps->face = face; + ps->level = level; + ps->zslice = zslice; if (pt->target == PIPE_TEXTURE_CUBE || pt->target == PIPE_TEXTURE_3D) { ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) * @@ -172,25 +232,64 @@ softpipe_get_tex_surface(struct pipe_screen *screen, } -static void -softpipe_texture_update(struct pipe_context *pipe, - struct pipe_texture *texture, - uint face, uint levelsMask) +static void +softpipe_tex_surface_release(struct pipe_screen *screen, + struct pipe_surface **s) { - struct softpipe_context *softpipe = softpipe_context(pipe); - uint unit; - for (unit = 0; unit < softpipe->num_textures; unit++) { - if (softpipe->texture[unit] == texture) { - sp_flush_tile_cache(softpipe, softpipe->tex_cache[unit]); - } + /* Effectively do the texture_update work here - if texture images + * needed post-processing to put them into hardware layout, this is + * where it would happen. For softpipe, nothing to do. + */ + assert ((*s)->texture); + pipe_texture_reference(&(*s)->texture, NULL); + + screen->winsys->surface_release(screen->winsys, s); +} + + +static void * +softpipe_surface_map( struct pipe_screen *screen, + struct pipe_surface *surface, + unsigned flags ) +{ + ubyte *map; + + if (flags & ~surface->usage) { + assert(0); + return NULL; + } + + map = screen->winsys->buffer_map( screen->winsys, surface->buffer, flags ); + if (map == NULL) + return NULL; + + /* May want to different things here depending on read/write nature + * of the map: + */ + if (surface->texture && + (flags & PIPE_BUFFER_USAGE_CPU_WRITE)) + { + /* Do something to notify sharing contexts of a texture change. + * In softpipe, that would mean flushing the texture cache. + */ + softpipe_screen(screen)->timestamp++; } + + return map + surface->offset; +} + + +static void +softpipe_surface_unmap(struct pipe_screen *screen, + struct pipe_surface *surface) +{ + screen->winsys->buffer_unmap( screen->winsys, surface->buffer ); } void -softpipe_init_texture_funcs( struct softpipe_context *softpipe ) +softpipe_init_texture_funcs(struct softpipe_context *sp) { - softpipe->pipe.texture_update = softpipe_texture_update; } @@ -199,5 +298,10 @@ softpipe_init_screen_texture_funcs(struct pipe_screen *screen) { screen->texture_create = softpipe_texture_create; screen->texture_release = softpipe_texture_release; + screen->get_tex_surface = softpipe_get_tex_surface; + screen->tex_surface_release = softpipe_tex_surface_release; + + screen->surface_map = softpipe_surface_map; + screen->surface_unmap = softpipe_surface_unmap; } diff --git a/src/gallium/drivers/softpipe/sp_texture.h b/src/gallium/drivers/softpipe/sp_texture.h index a7322144e6..779a9d8fc9 100644 --- a/src/gallium/drivers/softpipe/sp_texture.h +++ b/src/gallium/drivers/softpipe/sp_texture.h @@ -42,11 +42,11 @@ struct softpipe_texture struct pipe_texture base; unsigned long level_offset[PIPE_MAX_TEXTURE_LEVELS]; + unsigned long pitch[PIPE_MAX_TEXTURE_LEVELS]; /* The data is held here: */ struct pipe_buffer *buffer; - unsigned long buffer_size; }; @@ -61,7 +61,6 @@ softpipe_texture(struct pipe_texture *pt) extern void softpipe_init_texture_funcs( struct softpipe_context *softpipe ); - extern void softpipe_init_screen_texture_funcs(struct pipe_screen *screen); diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index 1117c0ad4c..28c29da87c 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -49,6 +49,7 @@ struct softpipe_tile_cache { + struct pipe_screen *screen; struct pipe_surface *surface; /**< the surface we're caching */ void *surface_map; struct pipe_texture *texture; /**< if caching a texture */ @@ -109,13 +110,14 @@ clear_clear_flag(uint *bitvec, int x, int y) struct softpipe_tile_cache * -sp_create_tile_cache(void) +sp_create_tile_cache( struct pipe_screen *screen ) { struct softpipe_tile_cache *tc; uint pos; tc = CALLOC_STRUCT( softpipe_tile_cache ); if (tc) { + tc->screen = screen; for (pos = 0; pos < NUM_ENTRIES; pos++) { tc->entries[pos].x = tc->entries[pos].y = -1; @@ -154,16 +156,17 @@ sp_tile_cache_set_surface(struct softpipe_tile_cache *tc, assert(!tc->texture); if (tc->surface_map) { - /*assert(tc->surface != ps);*/ - pipe_surface_unmap(tc->surface); + tc->screen->surface_unmap(tc->screen, tc->surface); tc->surface_map = NULL; } pipe_surface_reference(&tc->surface, ps); - if (ps) { - if (tc->surface_map) - tc->surface_map = pipe_surface_map(ps); + if (tc->surface) { + if (tc->surface_map) /* XXX: this is always NULL!? */ + tc->surface_map = tc->screen->surface_map(tc->screen, tc->surface, + PIPE_BUFFER_USAGE_CPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE); tc->depth_stencil = (ps->format == PIPE_FORMAT_S8Z24_UNORM || ps->format == PIPE_FORMAT_Z16_UNORM || @@ -187,10 +190,13 @@ void sp_tile_cache_map_surfaces(struct softpipe_tile_cache *tc) { if (tc->surface && !tc->surface_map) - tc->surface_map = pipe_surface_map(tc->surface); + tc->surface_map = tc->screen->surface_map(tc->screen, tc->surface, + PIPE_BUFFER_USAGE_CPU_WRITE | + PIPE_BUFFER_USAGE_CPU_READ); if (tc->tex_surf && !tc->tex_surf_map) - tc->tex_surf_map = pipe_surface_map(tc->tex_surf); + tc->tex_surf_map = tc->screen->surface_map(tc->screen, tc->tex_surf, + PIPE_BUFFER_USAGE_CPU_READ); } @@ -198,12 +204,12 @@ void sp_tile_cache_unmap_surfaces(struct softpipe_tile_cache *tc) { if (tc->surface_map) { - pipe_surface_unmap(tc->surface); + tc->screen->surface_unmap(tc->screen, tc->surface); tc->surface_map = NULL; } if (tc->tex_surf_map) { - pipe_surface_unmap(tc->tex_surf); + tc->screen->surface_unmap(tc->screen, tc->tex_surf); tc->tex_surf_map = NULL; } } @@ -224,7 +230,7 @@ sp_tile_cache_set_texture(struct pipe_context *pipe, pipe_texture_reference(&tc->texture, texture); if (tc->tex_surf_map) { - pipe_surface_unmap(tc->tex_surf); + tc->screen->surface_unmap(tc->screen, tc->tex_surf); tc->tex_surf_map = NULL; } pipe_surface_reference(&tc->tex_surf, NULL); @@ -514,10 +520,12 @@ sp_get_cached_tile_tex(struct pipe_context *pipe, /* get new surface (view into texture) */ if (tc->tex_surf_map) - pipe_surface_unmap(tc->tex_surf); + tc->screen->surface_unmap(tc->screen, tc->tex_surf); - tc->tex_surf = screen->get_tex_surface(screen, tc->texture, face, level, z); - tc->tex_surf_map = pipe_surface_map(tc->tex_surf); + tc->tex_surf = screen->get_tex_surface(screen, tc->texture, face, level, z, + PIPE_BUFFER_USAGE_CPU_READ); + tc->tex_surf_map = screen->surface_map(screen, tc->tex_surf, + PIPE_BUFFER_USAGE_CPU_READ); tc->tex_face = face; tc->tex_level = level; diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.h b/src/gallium/drivers/softpipe/sp_tile_cache.h index 2631e29a3a..bc96c941f6 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.h +++ b/src/gallium/drivers/softpipe/sp_tile_cache.h @@ -61,7 +61,7 @@ struct softpipe_cached_tile extern struct softpipe_tile_cache * -sp_create_tile_cache(void); +sp_create_tile_cache( struct pipe_screen *screen ); extern void sp_destroy_tile_cache(struct softpipe_tile_cache *tc); diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index f3a9c2cd8b..0f68f592f7 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -198,12 +198,6 @@ struct pipe_context { /*@}*/ - /** Called when texture data is changed */ - void (*texture_update)(struct pipe_context *pipe, - struct pipe_texture *texture, - uint face, uint dirtyLevelsMask); - - /** Flush rendering (flags = bitmask of PIPE_FLUSH_x tokens) */ void (*flush)( struct pipe_context *pipe, unsigned flags, diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 46a355daa2..83330ef22f 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -174,6 +174,12 @@ enum pipe_texture_target { /** + * Surface layout + */ +#define PIPE_SURFACE_LAYOUT_LINEAR 0 + + +/** * Surface status */ #define PIPE_SURFACE_STATUS_UNDEFINED 0 diff --git a/src/gallium/include/pipe/p_inlines.h b/src/gallium/include/pipe/p_inlines.h index 8eb604e73f..1e4b98edb4 100644 --- a/src/gallium/include/pipe/p_inlines.h +++ b/src/gallium/include/pipe/p_inlines.h @@ -39,21 +39,40 @@ extern "C" { #endif +/* XXX: these are a kludge. will fix when all surfaces are views into + * textures, and free-floating winsys surfaces go away. + */ static INLINE void * -pipe_surface_map(struct pipe_surface *surface) +pipe_surface_map( struct pipe_surface *surf, unsigned flags ) { - return (char *)surface->winsys->buffer_map( surface->winsys, surface->buffer, - PIPE_BUFFER_USAGE_CPU_WRITE | - PIPE_BUFFER_USAGE_CPU_READ ) - + surface->offset; + if (surf->texture) { + struct pipe_screen *screen = surf->texture->screen; + return surf->texture->screen->surface_map( screen, surf, flags ); + } + else { + struct pipe_winsys *winsys = surf->winsys; + char *map = (char *)winsys->buffer_map( winsys, surf->buffer, flags ); + if (map == NULL) + return NULL; + return (void *)(map + surf->offset); + } } static INLINE void -pipe_surface_unmap(struct pipe_surface *surface) +pipe_surface_unmap( struct pipe_surface *surf ) { - surface->winsys->buffer_unmap( surface->winsys, surface->buffer ); + if (surf->texture) { + struct pipe_screen *screen = surf->texture->screen; + surf->texture->screen->surface_unmap( screen, surf ); + } + else { + struct pipe_winsys *winsys = surf->winsys; + winsys->buffer_unmap( winsys, surf->buffer ); + } } + + /** * Set 'ptr' to point to 'surf' and update reference counting. * The old thing pointed to, if any, will be unreferenced first. @@ -66,9 +85,20 @@ pipe_surface_reference(struct pipe_surface **ptr, struct pipe_surface *surf) if (surf) surf->refcount++; - if (*ptr /* && --(*ptr)->refcount == 0 */) { - struct pipe_winsys *winsys = (*ptr)->winsys; - winsys->surface_release(winsys, ptr); + if (*ptr) { + + /* There are currently two sorts of surfaces... This needs to be + * fixed so that all surfaces are views into a texture. + */ + if ((*ptr)->texture) { + struct pipe_screen *screen = (*ptr)->texture->screen; + screen->tex_surface_release( screen, ptr ); + } + else { + struct pipe_winsys *winsys = (*ptr)->winsys; + winsys->surface_release(winsys, ptr); + } + assert(!*ptr); } diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h index 26ac99d287..cc8430dae1 100644 --- a/src/gallium/include/pipe/p_screen.h +++ b/src/gallium/include/pipe/p_screen.h @@ -89,6 +89,18 @@ struct pipe_screen { struct pipe_texture * (*texture_create)(struct pipe_screen *, const struct pipe_texture *templat); + /** + * Create a new texture object, using the given template info, but on top of + * existing memory. + * + * It is assumed that the buffer data is layed out according to the expected + * by the hardware. NULL will be returned if any inconsistency is found. + */ + struct pipe_texture * (*texture_blanket)(struct pipe_screen *, + const struct pipe_texture *templat, + const unsigned *pitch, + struct pipe_buffer *buffer); + void (*texture_release)(struct pipe_screen *, struct pipe_texture **pt); @@ -96,7 +108,22 @@ struct pipe_screen { struct pipe_surface *(*get_tex_surface)(struct pipe_screen *, struct pipe_texture *texture, unsigned face, unsigned level, - unsigned zslice); + unsigned zslice, + unsigned usage ); + + /* Surfaces allocated by the above must be released here: + */ + void (*tex_surface_release)( struct pipe_screen *, + struct pipe_surface ** ); + + + void *(*surface_map)( struct pipe_screen *, + struct pipe_surface *surface, + unsigned flags ); + + void (*surface_unmap)( struct pipe_screen *, + struct pipe_surface *surface ); + }; diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 912d84e7b9..571ea8c6e1 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -271,12 +271,25 @@ struct pipe_surface unsigned width; unsigned height; unsigned pitch; /**< in pixels */ + unsigned layout; /**< PIPE_SURFACE_LAYOUT_x */ unsigned offset; /**< offset from start of buffer, in bytes */ unsigned refcount; + unsigned usage; /**< PIPE_BUFFER_USAGE_* */ + struct pipe_winsys *winsys; /**< winsys which owns/created the surface */ + + struct pipe_texture *texture; /**< optional texture into which this is a view */ + unsigned face; + unsigned level; + unsigned zslice; }; +#define PIPE_TEXTURE_USAGE_RENDER_TARGET 0x1 +#define PIPE_TEXTURE_USAGE_DISPLAY_TARGET 0x2 /* ie a backbuffer */ +#define PIPE_TEXTURE_USAGE_DEPTH_STENCIL 0x4 +#define PIPE_TEXTURE_USAGE_SAMPLER 0x8 + /** * Texture object. */ @@ -292,6 +305,8 @@ struct pipe_texture unsigned cpp:8; unsigned last_level:8; /**< Index of last mipmap level present/defined */ unsigned compressed:1; + + unsigned tex_usage; /* PIPE_TEXTURE_USAGE_* */ /* These are also refcounted: */ diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index 0e7e246666..0d8ed167b2 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -204,7 +204,10 @@ mem_dup(const void *src, uint size) #define MIN2( A, B ) ( (A)<(B) ? (A) : (B) ) #define MAX2( A, B ) ( (A)>(B) ? (A) : (B) ) +#ifndef Elements #define Elements(x) (sizeof(x)/sizeof((x)[0])) +#endif + #define Offset(TYPE, MEMBER) ((unsigned)&(((TYPE *)NULL)->MEMBER)) /** diff --git a/src/gallium/include/pipe/p_winsys.h b/src/gallium/include/pipe/p_winsys.h index 3005ec2d94..87a66b66d7 100644 --- a/src/gallium/include/pipe/p_winsys.h +++ b/src/gallium/include/pipe/p_winsys.h @@ -90,7 +90,7 @@ struct pipe_winsys void (*surface_release)(struct pipe_winsys *ws, struct pipe_surface **s); - + /** * Buffer management. Buffer attributes are mostly fixed over its lifetime. * diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 14c3892559..a70752428a 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -498,6 +498,7 @@ xm_surface_alloc_storage(struct pipe_winsys *winsys, surf->format = format; surf->cpp = pf_get_size(format); surf->pitch = round_up(width, alignment / surf->cpp); + surf->usage = flags; #ifdef GALLIUM_CELL /* XXX a bit of a hack */ height = round_up(height, TILE_SIZE); @@ -551,6 +552,7 @@ static void xm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) { struct pipe_surface *surf = *s; + assert(!surf->texture); surf->refcount--; if (surf->refcount == 0) { if (surf->buffer) diff --git a/src/mesa/state_tracker/st_atom_pixeltransfer.c b/src/mesa/state_tracker/st_atom_pixeltransfer.c index 999c148449..e500ac8684 100644 --- a/src/mesa/state_tracker/st_atom_pixeltransfer.c +++ b/src/mesa/state_tracker/st_atom_pixeltransfer.c @@ -126,7 +126,8 @@ create_color_map_texture(GLcontext *ctx) /* create texture for color map/table */ pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, format, 0, - texSize, texSize, 1, 0); + texSize, texSize, 1, 0, + PIPE_TEXTURE_USAGE_SAMPLER); return pt; } @@ -148,8 +149,10 @@ load_color_map_texture(GLcontext *ctx, struct pipe_texture *pt) uint *dest; uint i, j; - surface = screen->get_tex_surface(screen, pt, 0, 0, 0); - dest = (uint *) pipe_surface_map(surface); + surface = screen->get_tex_surface(screen, pt, 0, 0, 0, + PIPE_BUFFER_USAGE_CPU_WRITE); + dest = (uint *) screen->surface_map(screen, surface, + PIPE_BUFFER_USAGE_CPU_WRITE); /* Pack four 1D maps into a 2D texture: * R map is placed horizontally, indexed by S, in channel 0 @@ -168,9 +171,8 @@ load_color_map_texture(GLcontext *ctx, struct pipe_texture *pt) } } - pipe_surface_unmap(surface); + screen->surface_unmap(screen, surface); pipe_surface_reference(&surface, NULL); - pipe->texture_update(pipe, pt, 0, 0x1); } diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c index 10283d31a1..4ce7c41e90 100644 --- a/src/mesa/state_tracker/st_atom_sampler.c +++ b/src/mesa/state_tracker/st_atom_sampler.c @@ -150,7 +150,7 @@ update_samplers(struct st_context *st) sampler->normalized_coords = 1; sampler->lod_bias = st->ctx->Texture.Unit[su].LodBias; - sampler->min_lod = MAX2(0.0f, texobj->MinLod); + sampler->min_lod = MAX2(0.0f, texobj->MinLod - texobj->BaseLevel); sampler->max_lod = MIN2(texobj->MaxLevel - texobj->BaseLevel, texobj->MaxLod); diff --git a/src/mesa/state_tracker/st_cb_accum.c b/src/mesa/state_tracker/st_cb_accum.c index 1636bed91a..e4ef3e16b7 100644 --- a/src/mesa/state_tracker/st_cb_accum.c +++ b/src/mesa/state_tracker/st_cb_accum.c @@ -106,13 +106,15 @@ st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) { struct st_renderbuffer *acc_strb = st_renderbuffer(rb); struct pipe_surface *acc_ps = acc_strb->surface; + struct pipe_screen *screen = ctx->st->pipe->screen; const GLint xpos = ctx->DrawBuffer->_Xmin; const GLint ypos = ctx->DrawBuffer->_Ymin; const GLint width = ctx->DrawBuffer->_Xmax - xpos; const GLint height = ctx->DrawBuffer->_Ymax - ypos; GLvoid *map; - map = pipe_surface_map(acc_ps); + map = screen->surface_map(screen, acc_ps, + PIPE_BUFFER_USAGE_CPU_WRITE); /* note acc_strb->format might not equal acc_ps->format */ switch (acc_strb->format) { @@ -140,7 +142,7 @@ st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) _mesa_problem(ctx, "unexpected format in st_clear_accum_buffer()"); } - pipe_surface_unmap(acc_ps); + screen->surface_unmap(screen, acc_ps); } @@ -150,10 +152,12 @@ accum_mad(GLcontext *ctx, GLfloat scale, GLfloat bias, GLint xpos, GLint ypos, GLint width, GLint height, struct st_renderbuffer *acc_strb) { + struct pipe_screen *screen = ctx->st->pipe->screen; struct pipe_surface *acc_ps = acc_strb->surface; GLvoid *map; - map = pipe_surface_map(acc_ps); + map = screen->surface_map(screen, acc_ps, + PIPE_BUFFER_USAGE_CPU_WRITE); /* note acc_strb->format might not equal acc_ps->format */ switch (acc_strb->format) { @@ -174,7 +178,7 @@ accum_mad(GLcontext *ctx, GLfloat scale, GLfloat bias, _mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()"); } - pipe_surface_unmap(acc_ps); + screen->surface_unmap(screen, acc_ps); } diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index ce8fefe703..f816e59104 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -321,16 +321,18 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height, * Create texture to hold bitmap pattern. */ pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, ctx->st->bitmap.tex_format, - 0, width, height, 1, 0); + 0, width, height, 1, 0, + PIPE_TEXTURE_USAGE_SAMPLER); if (!pt) { _mesa_unmap_bitmap_pbo(ctx, unpack); return NULL; } - surface = screen->get_tex_surface(screen, pt, 0, 0, 0); + surface = screen->get_tex_surface(screen, pt, 0, 0, 0, + PIPE_BUFFER_USAGE_CPU_WRITE); /* map texture surface */ - dest = pipe_surface_map(surface); + dest = screen->surface_map(screen, surface, PIPE_BUFFER_USAGE_CPU_WRITE); /* Put image into texture surface */ memset(dest, 0xff, height * surface->pitch); @@ -340,9 +342,8 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height, _mesa_unmap_bitmap_pbo(ctx, unpack); /* Release surface */ - pipe_surface_unmap(surface); + screen->surface_unmap(screen, surface); pipe_surface_reference(&surface, NULL); - pipe->texture_update(pipe, pt, 0, 0x1); return pt; } @@ -539,13 +540,16 @@ reset_cache(struct st_context *st) cache->texture = st_texture_create(st, PIPE_TEXTURE_2D, st->bitmap.tex_format, 0, BITMAP_CACHE_WIDTH, BITMAP_CACHE_HEIGHT, - 1, 0); + 1, 0, + PIPE_TEXTURE_USAGE_SAMPLER); /* Map the texture surface. * Subsequent glBitmap calls will write into the texture image. */ - cache->surf = screen->get_tex_surface(screen, cache->texture, 0, 0, 0); - cache->buffer = pipe_surface_map(cache->surf); + cache->surf = screen->get_tex_surface(screen, cache->texture, 0, 0, 0, + PIPE_BUFFER_USAGE_CPU_WRITE); + cache->buffer = screen->surface_map(screen, cache->surf, + PIPE_BUFFER_USAGE_CPU_WRITE); /* init image to all 0xff */ memset(cache->buffer, 0xff, BITMAP_CACHE_WIDTH * BITMAP_CACHE_HEIGHT); @@ -562,6 +566,7 @@ st_flush_bitmap_cache(struct st_context *st) if (st->ctx->DrawBuffer) { struct bitmap_cache *cache = st->bitmap.cache; struct pipe_context *pipe = st->pipe; + struct pipe_screen *screen = pipe->screen; assert(cache->xmin <= cache->xmax); /* @@ -574,12 +579,18 @@ st_flush_bitmap_cache(struct st_context *st) /* The texture surface has been mapped until now. * So unmap and release the texture surface before drawing. */ +#if 0 pipe_surface_unmap(cache->surf); pipe_surface_reference(&cache->surf, NULL); +#else + screen->surface_unmap(screen, cache->surf); + screen->tex_surface_release(screen, &cache->surf); +#endif +#if 0 /* XXX is this needed? */ pipe->texture_update(pipe, cache->texture, 0, 0x1); - +#endif draw_bitmap_quad(st->ctx, cache->xpos, cache->ypos, diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 65bfd6cfcc..8c775ad886 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -346,7 +346,8 @@ make_texture(struct st_context *st, return NULL; pt = st_texture_create(st, PIPE_TEXTURE_2D, pipeFormat, 0, width, height, - 1, 0); + 1, 0, + PIPE_TEXTURE_USAGE_SAMPLER); if (!pt) { _mesa_unmap_drawpix_pbo(ctx, unpack); return NULL; @@ -362,10 +363,12 @@ make_texture(struct st_context *st, /* we'll do pixel transfer in a fragment shader */ ctx->_ImageTransferState = 0x0; - surface = screen->get_tex_surface(screen, pt, 0, 0, 0); + surface = screen->get_tex_surface(screen, pt, 0, 0, 0, + PIPE_BUFFER_USAGE_CPU_WRITE); /* map texture surface */ - dest = pipe_surface_map(surface); + dest = screen->surface_map(screen, surface, + PIPE_BUFFER_USAGE_CPU_WRITE); /* Put image into texture surface. * Note that the image is actually going to be upside down in @@ -384,9 +387,8 @@ make_texture(struct st_context *st, unpack); /* unmap */ - pipe_surface_unmap(surface); + screen->surface_unmap(screen, surface); pipe_surface_reference(&surface, NULL); - pipe->texture_update(pipe, pt, 0, 0x1); assert(success); @@ -731,6 +733,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, { struct st_context *st = ctx->st; struct pipe_context *pipe = st->pipe; + struct pipe_screen *screen = pipe->screen; struct pipe_surface *ps = st->state.framebuffer.zsbuf; const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0; GLint skipPixels; @@ -739,7 +742,8 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); /* map the stencil buffer */ - stmap = pipe_surface_map(ps); + stmap = screen->surface_map(screen, ps, + PIPE_BUFFER_USAGE_CPU_WRITE); /* if width > MAX_WIDTH, have to process image in chunks */ skipPixels = 0; @@ -796,7 +800,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, } /* unmap the stencil buffer */ - pipe_surface_unmap(ps); + screen->surface_unmap(screen, ps); } @@ -869,6 +873,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, GLint dstx, GLint dsty) { struct st_renderbuffer *rbDraw = st_renderbuffer(ctx->DrawBuffer->_StencilBuffer); + struct pipe_screen *screen = ctx->st->pipe->screen; struct pipe_surface *psDraw = rbDraw->surface; ubyte *drawMap; ubyte *buffer; @@ -885,7 +890,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, &ctx->DefaultPacking, buffer); /* map the stencil buffer */ - drawMap = pipe_surface_map(psDraw); + drawMap = screen->surface_map(screen, psDraw, PIPE_BUFFER_USAGE_CPU_WRITE); /* draw */ /* XXX PixelZoom not handled yet */ @@ -925,7 +930,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, free(buffer); /* unmap the stencil buffer */ - pipe_surface_unmap(psDraw); + screen->surface_unmap(screen, psDraw); } @@ -990,17 +995,19 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, } pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, texFormat, 0, - width, height, 1, 0); + width, height, 1, 0, + PIPE_TEXTURE_USAGE_SAMPLER); if (!pt) return; - psTex = screen->get_tex_surface(screen, pt, 0, 0, 0); - if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { srcy = ctx->DrawBuffer->Height - srcy - height; } if (srcFormat == texFormat) { + psTex = screen->get_tex_surface(screen, pt, 0, 0, 0, + PIPE_BUFFER_USAGE_GPU_WRITE ); + /* copy source framebuffer surface into mipmap/texture */ pipe->surface_copy(pipe, FALSE, @@ -1009,21 +1016,26 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, psRead, srcx, srcy, width, height); } - else if (type == GL_COLOR) { - /* alternate path using get/put_tile() */ - GLfloat *buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); + else { + psTex = screen->get_tex_surface(screen, pt, 0, 0, 0, + PIPE_BUFFER_USAGE_CPU_WRITE ); - pipe_get_tile_rgba(pipe, psRead, srcx, srcy, width, height, buf); - pipe_put_tile_rgba(pipe, psTex, 0, 0, width, height, buf); + if (type == GL_COLOR) { + /* alternate path using get/put_tile() */ + GLfloat *buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); - free(buf); - } - else { - /* GL_DEPTH */ - GLuint *buf = (GLuint *) malloc(width * height * sizeof(GLuint)); - pipe_get_tile_z(pipe, psRead, srcx, srcy, width, height, buf); - pipe_put_tile_z(pipe, psTex, 0, 0, width, height, buf); - free(buf); + pipe_get_tile_rgba(pipe, psRead, srcx, srcy, width, height, buf); + pipe_put_tile_rgba(pipe, psTex, 0, 0, width, height, buf); + + free(buf); + } + else { + /* GL_DEPTH */ + GLuint *buf = (GLuint *) malloc(width * height * sizeof(GLuint)); + pipe_get_tile_z(pipe, psRead, srcx, srcy, width, height, buf); + pipe_put_tile_z(pipe, psTex, 0, 0, width, height, buf); + free(buf); + } } /* draw textured quad */ diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index fc8a5ea7f6..1fa82b07e6 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -77,6 +77,11 @@ init_renderbuffer_bits(struct st_renderbuffer *strb, return info.size; } +static INLINE GLboolean pf_is_depth_stencil( enum pipe_format format ) +{ + return (pf_get_component_bits( format, PIPE_FORMAT_COMP_Z ) + + pf_get_component_bits( format, PIPE_FORMAT_COMP_S )) != 0; +} /** * gl_renderbuffer::AllocStorage() @@ -90,80 +95,94 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, { struct pipe_context *pipe = ctx->st->pipe; struct st_renderbuffer *strb = st_renderbuffer(rb); - enum pipe_format pipeFormat; - GLbitfield flags = 0x0; /* XXX needed? */ - int ret; - - if (!strb->surface) { - /* first time surface creation */ - strb->surface = pipe->winsys->surface_alloc(pipe->winsys); - assert(strb->surface); - assert(strb->surface->refcount); - assert(strb->surface->winsys); - if (!strb->surface) - return GL_FALSE; + struct pipe_texture template, *texture; + unsigned surface_usage; + + /* Free the old surface (and texture if we hold the last + * reference): + */ + pipe_surface_reference( &strb->surface, NULL ); + + memset(&template, 0, sizeof(template)); + + if (strb->format != PIPE_FORMAT_NONE) { + template.format = strb->format; } - else if (strb->surface->buffer) { - /* release/discard the old surface buffer */ - pipe_reference_buffer(pipe, &strb->surface->buffer, NULL); + else { + template.format = st_choose_renderbuffer_format(pipe, internalFormat); } - /* Determine surface format here */ - if (strb->format != PIPE_FORMAT_NONE) { - assert(strb->format != 0); - /* we'll hit this for front/back color bufs */ - pipeFormat = strb->format; + strb->Base.Width = width; + strb->Base.Height = height; + init_renderbuffer_bits(strb, template.format); + + template.target = PIPE_TEXTURE_2D; + template.compressed = 0; + template.cpp = pf_get_size(template.format); + template.width[0] = width; + template.height[0] = height; + template.depth[0] = 1; + template.last_level = 0; + + if (pf_is_depth_stencil(template.format)) { + template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL; } else { - pipeFormat = st_choose_renderbuffer_format(pipe, internalFormat); + template.tex_usage = (PIPE_TEXTURE_USAGE_DISPLAY_TARGET | + PIPE_TEXTURE_USAGE_RENDER_TARGET); } - init_renderbuffer_bits(strb, pipeFormat); - - ret = pipe->winsys->surface_alloc_storage(pipe->winsys, - strb->surface, - width, - height, - pipeFormat, - flags); - if (ret || !strb->surface->buffer) { - if (pipeFormat == DEFAULT_ACCUM_PIPE_FORMAT) { - /* Accum buffer. Try a different surface format. Since accum - * buffers are s/w only for now, the surface pixel format doesn't - * really matter, only that the buffer is large enough. - */ - int sz, mult; - enum pipe_format accum_format; - - /* allocate a buffer of (typically) double height to get 64bpp */ - accum_format = st_choose_renderbuffer_format(pipe, GL_RGBA); - sz = pf_get_size(accum_format); - mult = pf_get_size(DEFAULT_ACCUM_PIPE_FORMAT) / sz; - - ret = pipe->winsys->surface_alloc_storage(pipe->winsys, - strb->surface, - width, height * mult, - accum_format, flags); - if (ret) - return GL_FALSE; /* we've _really_ failed */ - - } - else { - return GL_FALSE; /* out of memory, try s/w buffer? */ - } + + /* Probably need dedicated flags for surface usage too: + */ + surface_usage = (PIPE_BUFFER_USAGE_GPU_READ | + PIPE_BUFFER_USAGE_GPU_WRITE | + PIPE_BUFFER_USAGE_CPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE); + + texture = pipe->screen->texture_create( pipe->screen, + &template ); + + /* Special path for accum buffers. + * + * Try a different surface format. Since accum buffers are s/w + * only for now, the surface pixel format doesn't really matter, + * only that the buffer is large enough. + */ + if (!texture && template.format == DEFAULT_ACCUM_PIPE_FORMAT) + { + /* Actually, just setting this usage value should be sufficient + * to tell the driver to go ahead and allocate the buffer, even + * if HW doesn't support the format. + */ + template.tex_usage = 0; + surface_usage = (PIPE_BUFFER_USAGE_CPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE); + + texture = pipe->screen->texture_create( pipe->screen, + &template ); + } - ASSERT(strb->surface->buffer); - ASSERT(strb->surface->format); - ASSERT(strb->surface->cpp); - ASSERT(strb->surface->width == width); - /*ASSERT(strb->surface->height == height);*/ - ASSERT(strb->surface->pitch); + if (!texture) + return FALSE; - strb->Base.Width = width; - strb->Base.Height = height; + strb->surface = pipe->screen->get_tex_surface( pipe->screen, + texture, + 0, 0, 0, + surface_usage ); + + pipe_texture_reference( &texture, NULL ); - return GL_TRUE; + assert(strb->surface->buffer); + assert(strb->surface->format); + assert(strb->surface->cpp); + assert(strb->surface->width == width); + assert(strb->surface->height == height); + assert(strb->surface->pitch); + + + return strb->surface != NULL; } @@ -175,10 +194,7 @@ st_renderbuffer_delete(struct gl_renderbuffer *rb) { struct st_renderbuffer *strb = st_renderbuffer(rb); ASSERT(strb); - if (strb->surface) { - struct pipe_winsys *ws = strb->surface->winsys; - ws->surface_release(ws, &strb->surface); - } + pipe_surface_reference(&strb->surface, NULL); free(strb); } @@ -368,7 +384,11 @@ st_render_texture(GLcontext *ctx, strb->surface = screen->get_tex_surface(screen, pt, att->CubeMapFace, att->TextureLevel, - att->Zoffset); + att->Zoffset, + PIPE_BUFFER_USAGE_CPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE | + PIPE_BUFFER_USAGE_GPU_READ | + PIPE_BUFFER_USAGE_GPU_WRITE); assert(strb->surface); assert(screen->is_format_supported(screen, strb->surface->format, PIPE_TEXTURE)); assert(screen->is_format_supported(screen, strb->surface->format, PIPE_SURFACE)); @@ -396,22 +416,19 @@ static void st_finish_render_texture(GLcontext *ctx, struct gl_renderbuffer_attachment *att) { + struct pipe_screen *screen = ctx->st->pipe->screen; struct st_renderbuffer *strb = st_renderbuffer(att->Renderbuffer); assert(strb); ctx->st->pipe->flush(ctx->st->pipe, PIPE_FLUSH_RENDER_CACHE, NULL); - ctx->st->pipe->texture_update(ctx->st->pipe, - st_get_texobj_texture(att->Texture), - att->CubeMapFace, 1 << att->TextureLevel); + screen->tex_surface_release( screen, &strb->surface ); /* printf("FINISH RENDER TO TEXTURE surf=%p\n", strb->surface); */ - pipe_surface_reference(&strb->surface, NULL); - _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); /* restore previous framebuffer state */ diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c index ddbe36106c..e242195e7a 100644 --- a/src/mesa/state_tracker/st_cb_readpixels.c +++ b/src/mesa/state_tracker/st_cb_readpixels.c @@ -61,13 +61,14 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y, GLvoid *pixels) { struct gl_framebuffer *fb = ctx->ReadBuffer; + struct pipe_screen *screen = ctx->st->pipe->screen; struct st_renderbuffer *strb = st_renderbuffer(fb->_StencilBuffer); struct pipe_surface *ps = strb->surface; ubyte *stmap; GLint j; /* map the stencil buffer */ - stmap = pipe_surface_map(ps); + stmap = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_READ); /* width should never be > MAX_WIDTH since we did clipping earlier */ ASSERT(width <= MAX_WIDTH); @@ -124,7 +125,7 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y, /* unmap the stencil buffer */ - pipe_surface_unmap(ps); + screen->surface_unmap(screen, ps); } diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 02ef961e4d..c877e4382d 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -333,7 +333,9 @@ guess_and_alloc_texture(struct st_context *st, width, height, depth, - comp_byte); + comp_byte, + ( PIPE_TEXTURE_USAGE_RENDER_TARGET | + PIPE_TEXTURE_USAGE_SAMPLER )); DBG("%s - success\n", __FUNCTION__); } @@ -478,7 +480,6 @@ st_TexImage(GLcontext * ctx, struct gl_texture_image *texImage, GLsizei imageSize, int compressed) { - struct pipe_context *pipe = ctx->st->pipe; struct st_texture_object *stObj = st_texture_object(texObj); struct st_texture_image *stImage = st_texture_image(texImage); GLint postConvWidth, postConvHeight; @@ -637,7 +638,8 @@ st_TexImage(GLcontext * ctx, return; if (stImage->pt) { - texImage->Data = st_texture_image_map(ctx->st, stImage, 0); + texImage->Data = st_texture_image_map(ctx->st, stImage, 0, + PIPE_BUFFER_USAGE_CPU_WRITE); dstRowStride = stImage->surface->pitch * stImage->surface->cpp; } else { @@ -686,8 +688,9 @@ st_TexImage(GLcontext * ctx, } if (stImage->pt && i < depth) { - st_texture_image_unmap(stImage); - texImage->Data = st_texture_image_map(ctx->st, stImage, i); + st_texture_image_unmap(ctx->st, stImage); + texImage->Data = st_texture_image_map(ctx->st, stImage, i, + PIPE_BUFFER_USAGE_CPU_WRITE); src += srcImageStride; } } @@ -696,13 +699,10 @@ st_TexImage(GLcontext * ctx, _mesa_unmap_teximage_pbo(ctx, unpack); if (stImage->pt) { - st_texture_image_unmap(stImage); + st_texture_image_unmap(ctx->st, stImage); texImage->Data = NULL; } - if (stObj->pt) - pipe->texture_update(pipe, stObj->pt, stImage->face, (1 << level)); - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { ctx->Driver.GenerateMipmap(ctx, target, texObj); } @@ -795,7 +795,8 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level, /* Image is stored in hardware format in a buffer managed by the * kernel. Need to explicitly map and unmap it. */ - texImage->Data = st_texture_image_map(ctx->st, stImage, 0); + texImage->Data = st_texture_image_map(ctx->st, stImage, 0, + PIPE_BUFFER_USAGE_CPU_READ); texImage->RowStride = stImage->surface->pitch; } else { @@ -825,8 +826,9 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level, } if (stImage->pt && i < depth) { - st_texture_image_unmap(stImage); - texImage->Data = st_texture_image_map(ctx->st, stImage, i); + st_texture_image_unmap(ctx->st, stImage); + texImage->Data = st_texture_image_map(ctx->st, stImage, i, + PIPE_BUFFER_USAGE_CPU_READ); dest += dstImageStride; } } @@ -835,7 +837,7 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level, /* Unmap */ if (stImage->pt) { - st_texture_image_unmap(stImage); + st_texture_image_unmap(ctx->st, stImage); texImage->Data = NULL; } } @@ -876,8 +878,6 @@ st_TexSubimage(GLcontext * ctx, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - struct pipe_context *pipe = ctx->st->pipe; - struct st_texture_object *stObj = st_texture_object(texObj); struct st_texture_image *stImage = st_texture_image(texImage); GLuint dstRowStride; GLuint srcImageStride = _mesa_image_image_stride(packing, width, height, @@ -899,7 +899,8 @@ st_TexSubimage(GLcontext * ctx, * from uploading the buffer under us. */ if (stImage->pt) { - texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset); + texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset, + PIPE_BUFFER_USAGE_CPU_WRITE); dstRowStride = stImage->surface->pitch * stImage->surface->cpp; } @@ -924,8 +925,9 @@ st_TexSubimage(GLcontext * ctx, if (stImage->pt && i < depth) { /* map next slice of 3D texture */ - st_texture_image_unmap(stImage); - texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset + i); + st_texture_image_unmap(ctx->st, stImage); + texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset + i, + PIPE_BUFFER_USAGE_CPU_WRITE); src += srcImageStride; } } @@ -937,11 +939,9 @@ st_TexSubimage(GLcontext * ctx, _mesa_unmap_teximage_pbo(ctx, packing); if (stImage->pt) { - st_texture_image_unmap(stImage); + st_texture_image_unmap(ctx->st, stImage); texImage->Data = NULL; } - - pipe->texture_update(pipe, stObj->pt, stImage->face, (1 << level)); } @@ -1060,7 +1060,8 @@ fallback_copy_texsubimage(GLcontext *ctx, src_surf = strb->surface; - dest_surf = screen->get_tex_surface(screen, pt, face, level, destZ); + dest_surf = screen->get_tex_surface(screen, pt, face, level, destZ, + PIPE_BUFFER_USAGE_CPU_WRITE); assert(width <= MAX_WIDTH); @@ -1121,7 +1122,6 @@ do_copy_texsubimage(GLcontext *ctx, struct gl_texture_image *texImage = _mesa_select_tex_image(ctx, texObj, target, level); struct st_texture_image *stImage = st_texture_image(texImage); - struct st_texture_object *stObj = st_texture_object(texObj); GLenum baseFormat = texImage->InternalFormat; struct gl_framebuffer *fb = ctx->ReadBuffer; struct st_renderbuffer *strb; @@ -1159,7 +1159,8 @@ do_copy_texsubimage(GLcontext *ctx, dest_format = stImage->pt->format; dest_surface = screen->get_tex_surface(screen, stImage->pt, stImage->face, - stImage->level, destZ); + stImage->level, destZ, + PIPE_BUFFER_USAGE_CPU_WRITE); if (ctx->_ImageTransferState == 0x0 && strb->surface->buffer && @@ -1225,8 +1226,6 @@ do_copy_texsubimage(GLcontext *ctx, pipe_surface_reference(&dest_surface, NULL); - pipe->texture_update(pipe, stObj->pt, stImage->face, (1 << level)); - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { ctx->Driver.GenerateMipmap(ctx, target, texObj); } @@ -1366,7 +1365,7 @@ calculate_first_last_level(struct st_texture_object *stObj) } else { firstLevel = 0; - lastLevel = MIN2(tObj->MaxLevel, tObj->Image[0][0]->WidthLog2); + lastLevel = MIN2(tObj->MaxLevel, tObj->Image[0][tObj->BaseLevel]->WidthLog2); } break; case GL_TEXTURE_RECTANGLE_NV: @@ -1474,19 +1473,17 @@ st_finalize_texture(GLcontext *ctx, /* If we already have a gallium texture, check that it matches the texture * object's format, target, size, num_levels, etc. */ - if (stObj->pt) { - const enum pipe_format fmt = - st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat); - if (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) || - stObj->pt->format != fmt || - stObj->pt->last_level < stObj->lastLevel || - stObj->pt->width[0] != firstImage->base.Width2 || - stObj->pt->height[0] != firstImage->base.Height2 || - stObj->pt->depth[0] != firstImage->base.Depth2 || - stObj->pt->cpp != cpp || - stObj->pt->compressed != firstImage->base.IsCompressed) { - pipe_texture_release(&stObj->pt); - } + if (stObj->pt && + (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) || + stObj->pt->format != + st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat) || + stObj->pt->last_level < stObj->lastLevel || + stObj->pt->cpp != cpp || + stObj->pt->width[0] != firstImage->base.Width2 || + stObj->pt->height[0] != firstImage->base.Height2 || + stObj->pt->depth[0] != firstImage->base.Depth2 || + stObj->pt->compressed != firstImage->base.IsCompressed)) { + pipe_texture_release(&stObj->pt); } /* May need to create a new gallium texture: @@ -1499,7 +1496,11 @@ st_finalize_texture(GLcontext *ctx, firstImage->base.Width2, firstImage->base.Height2, firstImage->base.Depth2, - comp_byte); + comp_byte, + + ( PIPE_TEXTURE_USAGE_RENDER_TARGET | + PIPE_TEXTURE_USAGE_SAMPLER )); + if (!stObj->pt) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); return GL_FALSE; @@ -1519,7 +1520,6 @@ st_finalize_texture(GLcontext *ctx, if (stImage && stObj->pt != stImage->pt) { copy_image_data_to_texture(ctx->st, stObj, level, stImage); *needFlush = GL_TRUE; - pipe->texture_update(pipe, stObj->pt, face, (1 << level)); } } } diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c index 1a0e19c2f9..cfacfdd04c 100644 --- a/src/mesa/state_tracker/st_gen_mipmap.c +++ b/src/mesa/state_tracker/st_gen_mipmap.c @@ -123,8 +123,10 @@ fallback_generate_mipmap(GLcontext *ctx, GLenum target, const ubyte *srcData; ubyte *dstData; - srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice); - dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice); + srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice, + PIPE_BUFFER_USAGE_CPU_READ); + dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice, + PIPE_BUFFER_USAGE_CPU_WRITE); srcData = (ubyte *) pipe_buffer_map(pipe, srcSurf->buffer, PIPE_BUFFER_USAGE_CPU_READ) diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c index f68bef1207..2b3742d4e5 100644 --- a/src/mesa/state_tracker/st_texture.c +++ b/src/mesa/state_tracker/st_texture.c @@ -75,7 +75,8 @@ st_texture_create(struct st_context *st, GLuint width0, GLuint height0, GLuint depth0, - GLuint compress_byte) + GLuint compress_byte, + GLuint usage ) { struct pipe_texture pt, *newtex; struct pipe_screen *screen = st->pipe->screen; @@ -98,6 +99,7 @@ st_texture_create(struct st_context *st, pt.depth[0] = depth0; pt.compressed = compress_byte ? 1 : 0; pt.cpp = pt.compressed ? compress_byte : st_sizeof_format(format); + pt.tex_usage = usage; newtex = screen->texture_create(screen, &pt); @@ -184,25 +186,30 @@ st_texture_image_offset(const struct pipe_texture * pt, */ GLubyte * st_texture_image_map(struct st_context *st, struct st_texture_image *stImage, - GLuint zoffset) + GLuint zoffset, + GLuint flags ) { struct pipe_screen *screen = st->pipe->screen; struct pipe_texture *pt = stImage->pt; DBG("%s \n", __FUNCTION__); stImage->surface = screen->get_tex_surface(screen, pt, stImage->face, - stImage->level, zoffset); + stImage->level, zoffset, + flags); - return pipe_surface_map(stImage->surface); + return screen->surface_map(screen, stImage->surface, flags); } void -st_texture_image_unmap(struct st_texture_image *stImage) +st_texture_image_unmap(struct st_context *st, + struct st_texture_image *stImage) { + struct pipe_screen *screen = st->pipe->screen; + DBG("%s\n", __FUNCTION__); - pipe_surface_unmap(stImage->surface); + screen->surface_unmap(screen, stImage->surface); pipe_surface_reference(&stImage->surface, NULL); } @@ -224,12 +231,15 @@ st_surface_data(struct pipe_context *pipe, const void *src, unsigned src_pitch, unsigned srcx, unsigned srcy, unsigned width, unsigned height) { - pipe_copy_rect(pipe_surface_map(dst), + struct pipe_screen *screen = pipe->screen; + void *map = screen->surface_map(screen, dst, PIPE_BUFFER_USAGE_CPU_WRITE); + + pipe_copy_rect(map, dst->cpp, dst->pitch, dstx, dsty, width, height, src, src_pitch, srcx, srcy); - pipe_surface_unmap(dst); + screen->surface_unmap(screen, dst); } @@ -256,7 +266,8 @@ st_texture_image_data(struct pipe_context *pipe, if(dst->compressed) height /= 4; - dst_surface = screen->get_tex_surface(screen, dst, face, level, i); + dst_surface = screen->get_tex_surface(screen, dst, face, level, i, + PIPE_BUFFER_USAGE_CPU_WRITE); st_surface_data(pipe, dst_surface, 0, 0, /* dstx, dsty */ @@ -265,7 +276,7 @@ st_texture_image_data(struct pipe_context *pipe, 0, 0, /* source x, y */ dst->width[level], height); /* width, height */ - pipe_surface_reference(&dst_surface, NULL); + screen->tex_surface_release(screen, &dst_surface); srcUB += src_image_pitch * dst->cpp; } @@ -304,8 +315,11 @@ st_texture_image_copy(struct pipe_context *pipe, assert(src->width[srcLevel] == width); assert(src->height[srcLevel] == height); - dst_surface = screen->get_tex_surface(screen, dst, face, dstLevel, i); - src_surface = screen->get_tex_surface(screen, src, face, srcLevel, i); + dst_surface = screen->get_tex_surface(screen, dst, face, dstLevel, i, + PIPE_BUFFER_USAGE_GPU_WRITE); + + src_surface = screen->get_tex_surface(screen, src, face, srcLevel, i, + PIPE_BUFFER_USAGE_GPU_READ); pipe->surface_copy(pipe, FALSE, @@ -315,7 +329,7 @@ st_texture_image_copy(struct pipe_context *pipe, 0, 0, /* srcX, Y */ width, copyHeight); - pipe_surface_reference(&dst_surface, NULL); - pipe_surface_reference(&src_surface, NULL); + screen->tex_surface_release(screen, &src_surface); + screen->tex_surface_release(screen, &dst_surface); } } diff --git a/src/mesa/state_tracker/st_texture.h b/src/mesa/state_tracker/st_texture.h index b05762113c..55d1a367b5 100644 --- a/src/mesa/state_tracker/st_texture.h +++ b/src/mesa/state_tracker/st_texture.h @@ -103,7 +103,8 @@ st_texture_create(struct st_context *st, GLuint width0, GLuint height0, GLuint depth0, - GLuint compress_byte); + GLuint compress_byte, + GLuint tex_usage ); /* Check if an image fits into an existing texture object. @@ -119,10 +120,12 @@ st_texture_match_image(const struct pipe_texture *pt, extern GLubyte * st_texture_image_map(struct st_context *st, struct st_texture_image *stImage, - GLuint zoffset); + GLuint zoffset, + GLuint flags); extern void -st_texture_image_unmap(struct st_texture_image *stImage); +st_texture_image_unmap(struct st_context *st, + struct st_texture_image *stImage); /* Return pointers to each 2d slice within an image. Indexed by depth |