From f684120417c6b3ca9e7486ffeb24fe88e428834d Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 25 Oct 2007 19:27:29 -0600 Subject: Move region_alloc() and region_release() to pipe_winsys. This allows regions to be allocated w/out a rendering context. --- .../drivers/dri/intel_winsys/intel_winsys_i915.c | 61 ++++++++++++++++ src/mesa/drivers/x11/xm_buffer.c | 4 +- src/mesa/drivers/x11/xm_surface.c | 4 +- src/mesa/drivers/x11/xm_winsys.c | 83 ++++++++++++++++------ 4 files changed, 130 insertions(+), 22 deletions(-) (limited to 'src/mesa/drivers') diff --git a/src/mesa/drivers/dri/intel_winsys/intel_winsys_i915.c b/src/mesa/drivers/dri/intel_winsys/intel_winsys_i915.c index f6eb050152..c481495309 100644 --- a/src/mesa/drivers/dri/intel_winsys/intel_winsys_i915.c +++ b/src/mesa/drivers/dri/intel_winsys/intel_winsys_i915.c @@ -120,6 +120,64 @@ static void intel_i915_batch_flush( struct i915_winsys *sws ) +static struct pipe_region * +intel_i915_region_alloc(struct pipe_winsys *winsys, + unsigned cpp, unsigned width, + unsigned height, 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. + * + * XXX: is this ok for textures?? + * 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; + else + pitch = ((cpp * width + 63) & ~63) / cpp; + + 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, + NULL ); + + return region; +} + +static void +intel_i915_region_release(struct pipe_winsys *winsys, + struct pipe_region **region) +{ + if (!*region) + return; + + assert((*region)->refcount > 0); + (*region)->refcount--; + + if ((*region)->refcount == 0) { + assert((*region)->map_refcount == 0); + + winsys->buffer_reference( winsys, + &((*region)->buffer), NULL ); + free(*region); + } + *region = NULL; +} + struct pipe_context * intel_create_i915simple( struct intel_context *intel ) @@ -135,6 +193,9 @@ intel_create_i915simple( struct intel_context *intel ) iws->winsys.batch_flush = intel_i915_batch_flush; iws->intel = intel; + iws->winsys.region_alloc = intel_i915_region_alloc; + iws->winsys.region_release = intel_i915_region_release; + /* Create the i915simple context: */ return i915_create( intel_create_pipe_winsys(intel), diff --git a/src/mesa/drivers/x11/xm_buffer.c b/src/mesa/drivers/x11/xm_buffer.c index b8d3df1379..09356c7329 100644 --- a/src/mesa/drivers/x11/xm_buffer.c +++ b/src/mesa/drivers/x11/xm_buffer.c @@ -37,6 +37,7 @@ #include "renderbuffer.h" #include "pipe/p_state.h" #include "pipe/p_defines.h" +#include "pipe/p_winsys.h" #include "state_tracker/st_context.h" @@ -254,7 +255,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->region_alloc(pipe, 1, w, h, 0x0); + xrb->St.surface->region = pipe->winsys->region_alloc(pipe->winsys, + 1, w, h, 0x0); } } diff --git a/src/mesa/drivers/x11/xm_surface.c b/src/mesa/drivers/x11/xm_surface.c index 340f796bc8..337033f8ad 100644 --- a/src/mesa/drivers/x11/xm_surface.c +++ b/src/mesa/drivers/x11/xm_surface.c @@ -44,6 +44,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" +#include "pipe/p_winsys.h" #include "pipe/softpipe/sp_context.h" #include "pipe/softpipe/sp_clear.h" #include "pipe/softpipe/sp_tile_cache.h" @@ -163,7 +164,8 @@ xmesa_new_color_surface(struct pipe_context *pipe, GLuint pipeFormat) * functions. */ if (pipe) - xms->surface.surface.region = pipe->region_alloc(pipe, 1, 0, 0, 0x0); + xms->surface.surface.region = pipe->winsys->region_alloc(pipe->winsys, + 1, 0, 0, 0x0); return &xms->surface.surface; } diff --git a/src/mesa/drivers/x11/xm_winsys.c b/src/mesa/drivers/x11/xm_winsys.c index 7e29580b50..624d28dd01 100644 --- a/src/mesa/drivers/x11/xm_winsys.c +++ b/src/mesa/drivers/x11/xm_winsys.c @@ -233,6 +233,63 @@ xm_user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes) } + +/** + * Round n up to next multiple. + */ +static INLINE unsigned +round_up(unsigned n, unsigned multiple) +{ + return (n + multiple - 1) & ~(multiple - 1); +} + + +static struct pipe_region * +xm_region_alloc(struct pipe_winsys *winsys, + unsigned cpp, unsigned width, unsigned height, 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); + + region->buffer = winsys->buffer_create( winsys, alignment ) +; + + /* NULL data --> just allocate the space */ + winsys->buffer_data( winsys, + region->buffer, + region->pitch * cpp * height, + NULL ); + return region; +} + + +static void +xm_region_release(struct pipe_winsys *winsys, struct pipe_region **region) +{ + if (!*region) + return; + + assert((*region)->refcount > 0); + (*region)->refcount--; + + if ((*region)->refcount == 0) { + assert((*region)->map_refcount == 0); + + winsys->buffer_reference( winsys, &((*region)->buffer), NULL ); + free(*region); + } + *region = NULL; +} + + + struct xmesa_pipe_winsys { struct pipe_winsys winsys; @@ -259,6 +316,10 @@ xmesa_create_pipe_winsys( XMesaContext xmesa ) xws->winsys.buffer_data = xm_buffer_data; xws->winsys.buffer_subdata = xm_buffer_subdata; xws->winsys.buffer_get_subdata = xm_buffer_get_subdata; + + xws->winsys.region_alloc = xm_region_alloc; + xws->winsys.region_release = xm_region_release; + xws->winsys.flush_frontbuffer = xm_flush_frontbuffer; xws->winsys.wait_idle = xm_wait_idle; xws->winsys.printf = xm_printf; @@ -272,27 +333,9 @@ xmesa_create_pipe_winsys( XMesaContext xmesa ) struct pipe_context * xmesa_create_softpipe(XMesaContext xmesa) { - struct xm_winsys *isws = CALLOC_STRUCT( xm_winsys ); + struct xm_winsys *xm_ws = CALLOC_STRUCT( xm_winsys ); - /* Fill in this struct with callbacks that softpipe will need to - * communicate with the window system, buffer manager, etc. - * - * Softpipe would be happy with a malloc based memory manager, but - * the SwapBuffers implementation in this winsys driver requires - * that rendering be done to an appropriate xm_buffer. - */ -#if 0 - isws->sws.create_buffer = xm_create_buffer; - isws->sws.buffer_map = xm_buffer_map; - isws->sws.buffer_unmap = xm_buffer_unmap; - isws->sws.buffer_reference = xm_buffer_reference; - isws->sws.buffer_unreference = xm_buffer_unreference; - isws->sws.buffer_data = xm_buffer_data; - isws->sws.buffer_subdata = xm_buffer_subdata; - isws->sws.buffer_get_subdata = xm_buffer_get_subdata; -#endif - /* Create the softpipe context: */ - return softpipe_create( xmesa_create_pipe_winsys(xmesa), &isws->sws ); + return softpipe_create( xmesa_create_pipe_winsys(xmesa), &xm_ws->sws ); } -- cgit v1.2.3