diff options
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/drivers/dri/i915pipe/Makefile | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915pipe/intel_context.c | 10 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915pipe/intel_context.h | 7 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915pipe/intel_regions.c | 298 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915pipe/intel_regions.h | 36 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915pipe/intel_softpipe.c | 182 | ||||
-rw-r--r-- | src/mesa/pipe/p_context.h | 12 | ||||
-rw-r--r-- | src/mesa/pipe/p_state.h | 5 | ||||
-rw-r--r-- | src/mesa/pipe/softpipe/sp_clear.c | 2 | ||||
-rw-r--r-- | src/mesa/pipe/softpipe/sp_context.c | 5 | ||||
-rw-r--r-- | src/mesa/pipe/softpipe/sp_context.h | 4 | ||||
-rw-r--r-- | src/mesa/pipe/softpipe/sp_region.c | 287 | ||||
-rw-r--r-- | src/mesa/pipe/softpipe/sp_winsys.h | 100 |
13 files changed, 493 insertions, 457 deletions
diff --git a/src/mesa/drivers/dri/i915pipe/Makefile b/src/mesa/drivers/dri/i915pipe/Makefile index 617b2c7bce7..4e8d0201962 100644 --- a/src/mesa/drivers/dri/i915pipe/Makefile +++ b/src/mesa/drivers/dri/i915pipe/Makefile @@ -10,7 +10,7 @@ PIPE_DRIVERS = \ $(TOP)/src/mesa/pipe/softpipe/libsoftpipe.a DRIVER_SOURCES = \ - intel_regions.c \ + intel_softpipe.c \ intel_buffer_objects.c \ intel_batchbuffer.c \ intel_mipmap_tree.c \ diff --git a/src/mesa/drivers/dri/i915pipe/intel_context.c b/src/mesa/drivers/dri/i915pipe/intel_context.c index ac04d4e8c22..d43b7841120 100644 --- a/src/mesa/drivers/dri/i915pipe/intel_context.c +++ b/src/mesa/drivers/dri/i915pipe/intel_context.c @@ -54,11 +54,9 @@ #include "intel_buffer_objects.h" #include "intel_fbo.h" -#include "pipe/softpipe/sp_context.h" #include "state_tracker/st_public.h" #include "state_tracker/st_context.h" - #include "drirenderbuffer.h" #include "vblank.h" #include "utils.h" @@ -366,7 +364,7 @@ intelCreateContext(const __GLcontextModes * mesaVis, * Pipe-related setup */ st_create_context( &intel->ctx, - softpipe_create() ); + intel_create_softpipe( intel ) ); /* KW: Not sure I like this - we should only be talking to the * state_tracker. The pipe code will need some way of talking to @@ -375,9 +373,9 @@ intelCreateContext(const __GLcontextModes * mesaVis, * BP: Yes, a temporary hack so we can make jumps between old/new code. */ intel->pipe = intel->ctx.st->pipe; - intel->pipe->screen = intelScreen; - intel->pipe->glctx = ctx; - intel_init_region_functions(intel->pipe); +// intel->pipe->screen = intelScreen; +// intel->pipe->glctx = ctx; +// intel_init_region_functions(intel->pipe); /* * memory pools diff --git a/src/mesa/drivers/dri/i915pipe/intel_context.h b/src/mesa/drivers/dri/i915pipe/intel_context.h index 6c728dfe735..ad55e7eef24 100644 --- a/src/mesa/drivers/dri/i915pipe/intel_context.h +++ b/src/mesa/drivers/dri/i915pipe/intel_context.h @@ -196,6 +196,13 @@ extern void intelFlush(GLcontext * ctx); extern void intelInitDriverFunctions(struct dd_function_table *functions); +/* ================================================================ + * intel_softpipe.c: + */ + +struct pipe_context * +intel_create_softpipe( struct intel_context *intel ); + #define MI_BATCH_BUFFER_END (0xA<<23) diff --git a/src/mesa/drivers/dri/i915pipe/intel_regions.c b/src/mesa/drivers/dri/i915pipe/intel_regions.c deleted file mode 100644 index 75ba1f9cdb0..00000000000 --- a/src/mesa/drivers/dri/i915pipe/intel_regions.c +++ /dev/null @@ -1,298 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 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. - * - **************************************************************************/ - -/* Provide additional functionality on top of bufmgr buffers: - * - 2d semantics and blit operations - * - refcounting of buffers for multiple images in a buffer. - * - refcounting of buffer mappings. - * - some logic for moving the buffers to the best memory pools for - * given operations. - * - * Most of this is to make it easier to implement the fixed-layout - * mipmap tree required by intel hardware in the face of GL's - * programming interface where each image can be specifed in random - * order and it isn't clear what layout the tree should have until the - * last moment. - */ - -#include "pipe/p_state.h" -#include "pipe/p_context.h" - -#include "intel_context.h" -#include "intel_blit.h" -#include "intel_buffer_objects.h" -#include "dri_bufmgr.h" -#include "intel_batchbuffer.h" - - -#define FILE_DEBUG_FLAG DEBUG_REGION - - -/** XXX temporary helper */ -static intelScreenPrivate * -pipe_screen(struct pipe_context *pipe) -{ - return (intelScreenPrivate *) pipe->screen; -} - - -static void -intel_region_idle(struct pipe_context *pipe, struct pipe_region *region) -{ - DBG("%s\n", __FUNCTION__); - if (region && region->buffer) - driBOWaitIdle(region->buffer, GL_FALSE); -} - -/* XXX: Thread safety? - */ -static GLubyte * -intel_region_map(struct pipe_context *pipe, struct pipe_region *region) -{ - DBG("%s\n", __FUNCTION__); - if (!region->map_refcount++) { - region->map = driBOMap(region->buffer, - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0); - } - - return region->map; -} - -static void -intel_region_unmap(struct pipe_context *pipe, struct pipe_region *region) -{ - DBG("%s\n", __FUNCTION__); - if (!--region->map_refcount) { - driBOUnmap(region->buffer); - region->map = NULL; - } -} - -static struct pipe_region * -intel_region_alloc(struct pipe_context *pipe, - GLuint cpp, GLuint pitch, GLuint height) -{ - intelScreenPrivate *intelScreen = pipe_screen(pipe); - struct pipe_region *region = calloc(sizeof(*region), 1); - struct intel_context *intel = intelScreenContext(intelScreen); - - DBG("%s\n", __FUNCTION__); - - region->cpp = cpp; - region->pitch = pitch; - region->height = height; /* needed? */ - region->refcount = 1; - - driGenBuffers(intelScreen->regionPool, - "region", 1, ®ion->buffer, 64, - 0, - 0); - - LOCK_HARDWARE(intel); - driBOData(region->buffer, pitch * cpp * height, NULL, 0); - UNLOCK_HARDWARE(intel); - return region; -} - -static void -intel_region_release(struct pipe_context *pipe, struct pipe_region **region) -{ - if (!*region) - return; - - DBG("%s %d\n", __FUNCTION__, (*region)->refcount - 1); - - ASSERT((*region)->refcount > 0); - (*region)->refcount--; - - if ((*region)->refcount == 0) { - assert((*region)->map_refcount == 0); - - driBOUnReference((*region)->buffer); - free(*region); - } - *region = NULL; -} - - - - - - - -/* - * XXX Move this into core Mesa? - */ -static void -_mesa_copy_rect(GLubyte * dst, - GLuint cpp, - GLuint dst_pitch, - GLuint dst_x, - GLuint dst_y, - GLuint width, - GLuint height, - const GLubyte * src, - GLuint src_pitch, GLuint src_x, GLuint src_y) -{ - GLuint i; - - dst_pitch *= cpp; - src_pitch *= cpp; - dst += dst_x * cpp; - src += src_x * cpp; - dst += dst_y * dst_pitch; - src += src_y * dst_pitch; - width *= cpp; - - if (width == dst_pitch && width == src_pitch) - memcpy(dst, src, height * width); - else { - for (i = 0; i < height; i++) { - memcpy(dst, src, width); - dst += dst_pitch; - src += src_pitch; - } - } -} - - -/* Upload data to a rectangular sub-region. Lots of choices how to do this: - * - * - memcpy by span to current destination - * - upload data as new buffer and blit - * - * Currently always memcpy. - */ -static void -intel_region_data(struct pipe_context *pipe, - struct pipe_region *dst, - GLuint dst_offset, - GLuint dstx, GLuint dsty, - const void *src, GLuint src_pitch, - GLuint srcx, GLuint srcy, GLuint width, GLuint height) -{ - intelScreenPrivate *intelScreen = pipe_screen(pipe); - struct intel_context *intel = intelScreenContext(intelScreen); - - DBG("%s\n", __FUNCTION__); - - if (intel == NULL) - return; - - LOCK_HARDWARE(intel); - - _mesa_copy_rect(pipe->region_map(pipe, dst) + dst_offset, - dst->cpp, - dst->pitch, - dstx, dsty, width, height, src, src_pitch, srcx, srcy); - - pipe->region_unmap(pipe, dst); - - UNLOCK_HARDWARE(intel); - -} - -/* Copy rectangular sub-regions. Need better logic about when to - * push buffers into AGP - will currently do so whenever possible. - */ -static void -intel_region_copy(struct pipe_context *pipe, - struct pipe_region *dst, - GLuint dst_offset, - GLuint dstx, GLuint dsty, - const struct pipe_region *src, - GLuint src_offset, - GLuint srcx, GLuint srcy, GLuint width, GLuint height) -{ - intelScreenPrivate *intelScreen = pipe_screen(pipe); - struct intel_context *intel = intelScreenContext(intelScreen); - - DBG("%s\n", __FUNCTION__); - - if (intel == NULL) - return; - - assert(src->cpp == dst->cpp); - - intelEmitCopyBlit(intel, - dst->cpp, - src->pitch, src->buffer, src_offset, - dst->pitch, dst->buffer, dst_offset, - srcx, srcy, dstx, dsty, width, height, - GL_COPY); -} - -/* Fill a rectangular sub-region. Need better logic about when to - * push buffers into AGP - will currently do so whenever possible. - */ -static void -intel_region_fill(struct pipe_context *pipe, - struct pipe_region *dst, - GLuint dst_offset, - GLuint dstx, GLuint dsty, - GLuint width, GLuint height, - GLuint value, GLuint mask) -{ - intelScreenPrivate *intelScreen = pipe_screen(pipe); - struct intel_context *intel = intelScreenContext(intelScreen); - - DBG("%s\n", __FUNCTION__); - - if (intel == NULL) - return; - - intelEmitFillBlit(intel, - dst->cpp, - dst->pitch, dst->buffer, dst_offset, - dstx, dsty, width, height, value, mask); -} - - - -static struct _DriBufferObject * -intel_region_buffer(struct pipe_context *pipe, - struct pipe_region *region, GLuint flag) -{ - return region->buffer; -} - - - -void -intel_init_region_functions(struct pipe_context *pipe) -{ - pipe->region_idle = intel_region_idle; - pipe->region_map = intel_region_map; - pipe->region_unmap = intel_region_unmap; - pipe->region_alloc = intel_region_alloc; - pipe->region_release = intel_region_release; - pipe->region_data = intel_region_data; - pipe->region_copy = intel_region_copy; - pipe->region_fill = intel_region_fill; - pipe->region_buffer = intel_region_buffer; -} - diff --git a/src/mesa/drivers/dri/i915pipe/intel_regions.h b/src/mesa/drivers/dri/i915pipe/intel_regions.h deleted file mode 100644 index 2a3b5b4025c..00000000000 --- a/src/mesa/drivers/dri/i915pipe/intel_regions.h +++ /dev/null @@ -1,36 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 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. - * - **************************************************************************/ - -#ifndef INTEL_REGIONS_H -#define INTEL_REGIONS_H - -#include "mtypes.h" -#include "intel_screen.h" - - - -#endif diff --git a/src/mesa/drivers/dri/i915pipe/intel_softpipe.c b/src/mesa/drivers/dri/i915pipe/intel_softpipe.c new file mode 100644 index 00000000000..4591730a02e --- /dev/null +++ b/src/mesa/drivers/dri/i915pipe/intel_softpipe.c @@ -0,0 +1,182 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * THE COPYRIGHT HOLDERS, AUTHORS 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Keith Whitwell <keithw-at-tungstengraphics-dot-com> + */ + +#include <stdlib.h> +#include <xf86drm.h> +#include "dri_bufpool.h" +#include "dri_bufmgr.h" + +/* #include "errno.h" */ +/* #include "string.h" */ +/* #include "imports.h" */ + +#include "intel_context.h" + +#include "pipe/softpipe/sp_winsys.h" + + +struct intel_softpipe_winsys { + struct softpipe_winsys sws; + struct intel_context *intel; +}; + + + +/* Turn the softpipe opaque buffer pointer into a dri_bufmgr opaque + * buffer pointer... + */ +static inline struct _DriBufferObject * +dri_bo( struct softpipe_buffer_handle *bo ) +{ + return (struct _DriBufferObject *)bo; +} + +static inline struct softpipe_buffer_handle * +pipe_bo( struct _DriBufferObject *bo ) +{ + return (struct softpipe_buffer_handle *)bo; +} + +/* Turn a softpipe winsys into an intel/softpipe winsys: + */ +static inline struct intel_softpipe_winsys * +intel_softpipe_winsys( struct softpipe_winsys *sws ) +{ + return (struct intel_softpipe_winsys *)sws; +} + + +/* Most callbacks map direcly onto dri_bufmgr operations: + */ +static void *intel_buffer_map(struct softpipe_winsys *sws, + struct softpipe_buffer_handle *buf ) +{ + return driBOMap( dri_bo(buf), + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0 ); +} + +static void intel_buffer_unmap(struct softpipe_winsys *sws, + struct softpipe_buffer_handle *buf) +{ + driBOUnmap( dri_bo(buf) ); +} + + +static struct softpipe_buffer_handle * +intel_buffer_reference(struct softpipe_winsys *sws, + struct softpipe_buffer_handle *buf) +{ + return pipe_bo( driBOReference( dri_bo(buf) ) ); +} + +static void intel_buffer_unreference(struct softpipe_winsys *sws, + struct softpipe_buffer_handle *buf) +{ + driBOUnReference( dri_bo(buf) ); +} + +/* Grabs the hardware lock! + */ +static void intel_buffer_data(struct softpipe_winsys *sws, + struct softpipe_buffer_handle *buf, + unsigned size, const void *data ) +{ + struct intel_context *intel = intel_softpipe_winsys(sws)->intel; + + LOCK_HARDWARE( intel ); + driBOData( dri_bo(buf), size, data, 0 ); + UNLOCK_HARDWARE( intel ); +} + +static void intel_buffer_subdata(struct softpipe_winsys *sws, + struct softpipe_buffer_handle *buf, + unsigned long offset, + unsigned long size, + const void *data) +{ + driBOSubData( dri_bo(buf), offset, size, data ); +} + +static void intel_buffer_get_subdata(struct softpipe_winsys *sws, + struct softpipe_buffer_handle *buf, + unsigned long offset, + unsigned long size, + void *data) +{ + driBOGetSubData( dri_bo(buf), offset, size, data ); +} + +/* Softpipe has no concept of pools. We choose the tex/region pool + * for all buffers. + */ +static struct softpipe_buffer_handle * +intel_create_buffer(struct softpipe_winsys *sws, + const char *name, + unsigned alignment) +{ + struct intel_context *intel = intel_softpipe_winsys(sws)->intel; + struct _DriBufferObject *buffer; + + LOCK_HARDWARE( intel ); + driGenBuffers( intel->intelScreen->regionPool, + name, 1, &buffer, alignment, 0, 0 ); + UNLOCK_HARDWARE( intel ); + + return pipe_bo(buffer); +} + + +struct pipe_context * +intel_create_softpipe( struct intel_context *intel ) +{ + struct intel_softpipe_winsys *isws = CALLOC_STRUCT( intel_softpipe_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 _DriBufferObject. + */ + isws->sws.create_buffer = intel_create_buffer; + isws->sws.buffer_map = intel_buffer_map; + isws->sws.buffer_unmap = intel_buffer_unmap; + isws->sws.buffer_reference = intel_buffer_reference; + isws->sws.buffer_unreference = intel_buffer_unreference; + isws->sws.buffer_data = intel_buffer_data; + isws->sws.buffer_subdata = intel_buffer_subdata; + isws->sws.buffer_get_subdata = intel_buffer_get_subdata; + isws->intel = intel; + + /* Create the softpipe context: + */ + return softpipe_create( &isws->sws ); +} diff --git a/src/mesa/pipe/p_context.h b/src/mesa/pipe/p_context.h index ac6567f009b..92670c77337 100644 --- a/src/mesa/pipe/p_context.h +++ b/src/mesa/pipe/p_context.h @@ -32,10 +32,6 @@ #include "p_state.h" -/* Kludge: - */ -extern struct pipe_context *softpipe_create( void ); - /* Drawing currently kludged up via the existing tnl/ module. */ struct vertex_buffer; @@ -161,7 +157,8 @@ struct pipe_context { struct pipe_region *dest, GLuint dest_offset, GLuint destx, GLuint desty, - const struct pipe_region *src, + struct pipe_region *src, /* don't make this const - + need to map/unmap */ GLuint src_offset, GLuint srcx, GLuint srcy, GLuint width, GLuint height); @@ -170,14 +167,11 @@ struct pipe_context { GLuint dst_offset, GLuint dstx, GLuint dsty, GLuint width, GLuint height, - GLuint value, GLuint mask); + GLuint value); struct _DriBufferObject *(*region_buffer)(struct pipe_context *pipe, struct pipe_region *region, GLuint flag); - - void *screen; /**< temporary */ - void *glctx; /**< temporary */ }; diff --git a/src/mesa/pipe/p_state.h b/src/mesa/pipe/p_state.h index 699efd5877a..3be1010007a 100644 --- a/src/mesa/pipe/p_state.h +++ b/src/mesa/pipe/p_state.h @@ -235,12 +235,9 @@ struct pipe_sampler_state *** Resource Objects ***/ - -struct _DriBufferObject; - struct pipe_region { - struct _DriBufferObject *buffer; /**< buffer manager's buffer ID */ + void *buffer; /**< driver private buffer handle */ GLuint refcount; /**< Reference count for region */ GLuint cpp; /**< bytes per pixel */ diff --git a/src/mesa/pipe/softpipe/sp_clear.c b/src/mesa/pipe/softpipe/sp_clear.c index d7684d20445..2d69b6e0dca 100644 --- a/src/mesa/pipe/softpipe/sp_clear.c +++ b/src/mesa/pipe/softpipe/sp_clear.c @@ -56,5 +56,5 @@ softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps, w = softpipe->framebuffer.cbufs[0]->width; h = softpipe->framebuffer.cbufs[0]->height; - pipe->region_fill(pipe, ps->region, 0, x, y, w, h, clearValue, ~0); + pipe->region_fill(pipe, ps->region, 0, x, y, w, h, clearValue); } diff --git a/src/mesa/pipe/softpipe/sp_context.c b/src/mesa/pipe/softpipe/sp_context.c index fe7f2f351a4..22928f7bd64 100644 --- a/src/mesa/pipe/softpipe/sp_context.c +++ b/src/mesa/pipe/softpipe/sp_context.c @@ -39,6 +39,7 @@ #include "sp_state.h" #include "sp_surface.h" #include "sp_prim_setup.h" +#include "sp_winsys.h" @@ -168,7 +169,7 @@ static GLuint softpipe_get_occlusion_counter(struct pipe_context *pipe) } -struct pipe_context *softpipe_create( void ) +struct pipe_context *softpipe_create( struct softpipe_winsys *sws ) { struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context); @@ -209,6 +210,8 @@ struct pipe_context *softpipe_create( void ) softpipe->quad.colormask = sp_quad_colormask_stage(softpipe); softpipe->quad.output = sp_quad_output_stage(softpipe); + softpipe->winsys = sws; + /* * Create drawing context and plug our rendering stage into it. */ diff --git a/src/mesa/pipe/softpipe/sp_context.h b/src/mesa/pipe/softpipe/sp_context.h index 3c379c9091a..43fa8acd763 100644 --- a/src/mesa/pipe/softpipe/sp_context.h +++ b/src/mesa/pipe/softpipe/sp_context.h @@ -38,8 +38,8 @@ #include "sp_quad.h" - struct softpipe_surface; +struct softpipe_winsys; struct draw_context; struct draw_stage; @@ -68,6 +68,8 @@ enum interp_mode { struct softpipe_context { struct pipe_context pipe; /**< base class */ + struct softpipe_winsys *winsys; /**< window system interface */ + /* The most recent drawing state as set by the driver: */ diff --git a/src/mesa/pipe/softpipe/sp_region.c b/src/mesa/pipe/softpipe/sp_region.c index 1dbd1609e37..78a0919ad50 100644 --- a/src/mesa/pipe/softpipe/sp_region.c +++ b/src/mesa/pipe/softpipe/sp_region.c @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -25,74 +25,185 @@ * **************************************************************************/ -/** - * Software-based region allocation and management. - * A hardware driver would override these functions. +/* Provide additional functionality on top of bufmgr buffers: + * - 2d semantics and blit operations (XXX: remove/simplify blits??) + * - refcounting of buffers for multiple images in a buffer. + * - refcounting of buffer mappings. */ - #include "sp_context.h" +#include "sp_winsys.h" #include "sp_region.h" -#include "sp_surface.h" -#include "main/imports.h" +static void +sp_region_idle(struct pipe_context *pipe, struct pipe_region *region) +{ + +} + + +static GLubyte * +sp_region_map(struct pipe_context *pipe, struct pipe_region *region) +{ + struct softpipe_context *sp = softpipe_context( pipe ); + + if (!region->map_refcount++) { + region->map = sp->winsys->buffer_map( sp->winsys, + region->buffer ); + } + + return region->map; +} + +static void +sp_region_unmap(struct pipe_context *pipe, struct pipe_region *region) +{ + struct softpipe_context *sp = softpipe_context( pipe ); + + if (!--region->map_refcount) { + sp->winsys->buffer_unmap( sp->winsys, + region->buffer ); + region->map = NULL; + } +} + static struct pipe_region * sp_region_alloc(struct pipe_context *pipe, - GLuint cpp, GLuint pitch, GLuint height) + GLuint cpp, GLuint pitch, GLuint height) { - struct pipe_region *region = CALLOC_STRUCT(pipe_region); - if (!region) - return NULL; + struct softpipe_context *sp = softpipe_context( pipe ); + struct pipe_region *region = calloc(sizeof(*region), 1); - region->refcount = 1; region->cpp = cpp; region->pitch = pitch; - region->height = height; - region->map = malloc(cpp * pitch * height); + region->height = height; /* needed? */ + region->refcount = 1; + + region->buffer = sp->winsys->create_buffer(sp->winsys, "region", 64 ); + + sp->winsys->buffer_data( sp->winsys, + region->buffer, + pitch * cpp * height, + NULL ); return region; } - static void sp_region_release(struct pipe_context *pipe, struct pipe_region **region) { - assert((*region)->refcount > 0); + struct softpipe_context *sp = softpipe_context( pipe ); + + if (!*region) + return; + + ASSERT((*region)->refcount > 0); (*region)->refcount--; if ((*region)->refcount == 0) { assert((*region)->map_refcount == 0); -#if 0 - if ((*region)->pbo) - (*region)->pbo->region = NULL; - (*region)->pbo = NULL; -#endif - + sp->winsys->buffer_unreference( sp->winsys, + (*region)->buffer ); free(*region); } *region = NULL; } - -static GLubyte * -sp_region_map(struct pipe_context *pipe, struct pipe_region *region) +/* + * XXX Move this into core Mesa? + */ +static void +_mesa_copy_rect(GLubyte * dst, + GLuint cpp, + GLuint dst_pitch, + GLuint dst_x, + GLuint dst_y, + GLuint width, + GLuint height, + const GLubyte * src, + GLuint src_pitch, + GLuint src_x, + GLuint src_y) { - region->map_refcount++; - return region->map; + GLuint i; + + dst_pitch *= cpp; + src_pitch *= cpp; + dst += dst_x * cpp; + src += src_x * cpp; + dst += dst_y * dst_pitch; + src += src_y * dst_pitch; + width *= cpp; + + if (width == dst_pitch && width == src_pitch) + memcpy(dst, src, height * width); + else { + for (i = 0; i < height; i++) { + memcpy(dst, src, width); + dst += dst_pitch; + src += src_pitch; + } + } } +/* Upload data to a rectangular sub-region. Lots of choices how to do this: + * + * - memcpy by span to current destination + * - upload data as new buffer and blit + * + * Currently always memcpy. + */ static void -sp_region_unmap(struct pipe_context *pipe, struct pipe_region *region) +sp_region_data(struct pipe_context *pipe, + struct pipe_region *dst, + GLuint dst_offset, + GLuint dstx, GLuint dsty, + const void *src, GLuint src_pitch, + GLuint srcx, GLuint srcy, GLuint width, GLuint height) { - region->map_refcount--; + _mesa_copy_rect(pipe->region_map(pipe, dst) + dst_offset, + dst->cpp, + dst->pitch, + dstx, dsty, width, height, src, src_pitch, srcx, srcy); + + pipe->region_unmap(pipe, dst); } +/* Assumes all values are within bounds -- no checking at this level - + * do it higher up if required. + */ +static void +sp_region_copy(struct pipe_context *pipe, + struct pipe_region *dst, + GLuint dst_offset, + GLuint dstx, GLuint dsty, + struct pipe_region *src, + GLuint src_offset, + GLuint srcx, GLuint srcy, GLuint width, GLuint height) +{ + assert( dst != src ); + assert( dst->cpp == src->cpp ); + _mesa_copy_rect(pipe->region_map(pipe, dst) + dst_offset, + dst->cpp, + dst->pitch, + dstx, dsty, + width, height, + pipe->region_map(pipe, src) + src_offset, + src->pitch, + srcx, srcy); + pipe->region_unmap(pipe, src); + pipe->region_unmap(pipe, dst); +} + +/* Fill a rectangular sub-region. Need better logic about when to + * push buffers into AGP - will currently do so whenever possible. + */ static GLubyte * get_pointer(struct pipe_region *dst, GLuint x, GLuint y) { @@ -105,93 +216,69 @@ sp_region_fill(struct pipe_context *pipe, struct pipe_region *dst, GLuint dst_offset, GLuint dstx, GLuint dsty, - GLuint width, GLuint height, GLuint value, GLuint mask) + GLuint width, GLuint height, GLuint value) { GLuint i, j; + + (void)pipe->region_map(pipe, dst); + switch (dst->cpp) { - case 1: - { - GLubyte *row = get_pointer(dst, dstx, dsty); - if ((mask & 0xff) == 0xff) { - /* no masking */ - for (i = 0; i < height; i++) { - memset(row, value, width); - row += dst->pitch; - } - } - else { - value &= mask; - mask = ~mask; - for (i = 0; i < height; i++) { - for (j = 0; j < width; j++) { - row[j] = (row[j] & mask) | value; - } - row += dst->pitch; - } - } + case 1: { + GLubyte *row = get_pointer(dst, dstx, dsty); + for (i = 0; i < height; i++) { + memset(row, value, width); + row += dst->pitch; } - break; - case 2: - { - GLushort *row = (GLushort *) get_pointer(dst, dstx, dsty); - if ((mask & 0xffff) == 0xffff) { - /* no masking */ - for (i = 0; i < height; i++) { - for (j = 0; j < width; j++) - row[j] = value; - row += dst->pitch; - } - } - else { - value &= mask; - mask = ~mask; - for (i = 0; i < height; i++) { - for (j = 0; j < width; j++) - row[j] = (row[j] & mask) | value; - row += dst->pitch; - } - } + } + break; + case 2: { + GLushort *row = (GLushort *) get_pointer(dst, dstx, dsty); + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) + row[j] = value; + row += dst->pitch; } - break; - case 4: - { - GLuint *row = (GLuint *) get_pointer(dst, dstx, dsty); - if (mask == 0xffffffff) { - /* no masking */ - for (i = 0; i < height; i++) { - for (j = 0; j < width; j++) - row[j] = value; - row += dst->pitch; - } - } - else { - value &= mask; - mask = ~mask; - for (i = 0; i < height; i++) { - for (j = 0; j < width; j++) - row[j] = (row[j] & mask) | value; - row += dst->pitch; - } - } + } + break; + case 4: { + GLuint *row = (GLuint *) get_pointer(dst, dstx, dsty); + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) + row[j] = value; + row += dst->pitch; } - break; + } + break; default: assert(0); - + break; } + + pipe->region_unmap( pipe, dst ); +} + + + +static struct _DriBufferObject * +sp_region_buffer(struct pipe_context *pipe, + struct pipe_region *region, GLuint flag) +{ + return region->buffer; } + void sp_init_region_functions(struct softpipe_context *sp) { - sp->pipe.region_alloc = sp_region_alloc; - sp->pipe.region_release = sp_region_release; - + sp->pipe.region_idle = sp_region_idle; sp->pipe.region_map = sp_region_map; sp->pipe.region_unmap = sp_region_unmap; - + sp->pipe.region_alloc = sp_region_alloc; + sp->pipe.region_release = sp_region_release; + sp->pipe.region_data = sp_region_data; + sp->pipe.region_copy = sp_region_copy; sp->pipe.region_fill = sp_region_fill; - - /* XXX lots of other region functions needed... */ + sp->pipe.region_buffer = sp_region_buffer; } + diff --git a/src/mesa/pipe/softpipe/sp_winsys.h b/src/mesa/pipe/softpipe/sp_winsys.h new file mode 100644 index 00000000000..43953c648ba --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_winsys.h @@ -0,0 +1,100 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +#ifndef SP_WINSYS_H +#define SP_WINSYS_H + +#include "main/mtypes.h" + +/* This is the interface that softpipe requires any window system + * hosting it to implement. This is the only include file in softpipe + * which is public. + */ + + +/* Pipe drivers are (meant to be!) independent of both GL and the + * window system. The window system provides a buffer manager and a + * set of additional hooks for things like command buffer submission, + * etc. + * + * There clearly has to be some agreement between the window system + * driver and the hardware driver about the format of command buffers, + * etc. + */ + +struct softpipe_buffer_handle; + +struct softpipe_winsys { + + + /* The buffer manager is modeled after the dri_bugmgr interface, + * but this is the subset that softpipe cares about. Remember that + * softpipe gets to choose the interface it needs, and the window + * systems must then implement that interface (rather than the + * other way around...). + * + * Softpipe only really wants to make system memory allocations, + * right?? + */ + struct softpipe_buffer_handle *(*create_buffer)(struct softpipe_winsys *sws, + const char *name, + unsigned alignment ); + + void *(*buffer_map)( struct softpipe_winsys *sws, + struct softpipe_buffer_handle *buf ); + + void (*buffer_unmap)( struct softpipe_winsys *sws, + struct softpipe_buffer_handle *buf ); + + struct softpipe_buffer_handle *(*buffer_reference)( struct softpipe_winsys *sws, + struct softpipe_buffer_handle *buf ); + + void (*buffer_unreference)( struct softpipe_winsys *sws, + struct softpipe_buffer_handle *buf ); + + void (*buffer_data)(struct softpipe_winsys *sws, + struct softpipe_buffer_handle *buf, + unsigned size, const void *data ); + + void (*buffer_subdata)(struct softpipe_winsys *sws, + struct softpipe_buffer_handle *buf, + unsigned long offset, + unsigned long size, + const void *data); + + void (*buffer_get_subdata)(struct softpipe_winsys *sws, + struct softpipe_buffer_handle *buf, + unsigned long offset, + unsigned long size, + void *data); +}; + + +struct pipe_context *softpipe_create( struct softpipe_winsys * ); + + +#endif /* SP_WINSYS_H */ |