diff options
author | Jakob Bornecrantz <wallbraker@gmail.com> | 2010-02-15 01:52:29 +0000 |
---|---|---|
committer | Jakob Bornecrantz <wallbraker@gmail.com> | 2010-02-15 01:52:29 +0000 |
commit | 6ad834b39d6c2ae9ead2e2b00908ad2fa6914897 (patch) | |
tree | c500a30f49ed1c5b0d413b9d0dfbc7d591aeaa0c | |
parent | 0a03371a0b4c85d1272aeb8a6b680c069395e6d5 (diff) |
drm/sw: Wip drm winsys
This winsys wraps a drm_api in order abstract away the different
memory manager. It also needs help from a pipe screen wrapper.
That wrapper is included in the same file but could be moved out
into a generic file.
-rw-r--r-- | src/gallium/include/state_tracker/xm_winsys.h | 8 | ||||
-rw-r--r-- | src/gallium/winsys/drm/sw/Makefile | 13 | ||||
-rw-r--r-- | src/gallium/winsys/drm/sw/sw_drm_api.c | 287 |
3 files changed, 308 insertions, 0 deletions
diff --git a/src/gallium/include/state_tracker/xm_winsys.h b/src/gallium/include/state_tracker/xm_winsys.h index c928be0ba3..5e2b5ee8be 100644 --- a/src/gallium/include/state_tracker/xm_winsys.h +++ b/src/gallium/include/state_tracker/xm_winsys.h @@ -131,6 +131,14 @@ struct sw_driver { struct pipe_screen *(*create_screen)( struct sw_driver *driver, struct sw_callbacks *callbacks ); + struct pipe_texture *(*wrap_displaytarget)( struct sw_driver *driver, + struct pipe_screen *screen, + struct pipe_texture *templ, + struct sw_displaytarget *dt ); + + struct sw_displaytarget *(*get_displaytarget)( struct sw_driver *driver, + struct pipe_texture *tex ); + /* No call to wrap a display target and create a texture. Hope * that the callback mechanism is sufficient for now. */ diff --git a/src/gallium/winsys/drm/sw/Makefile b/src/gallium/winsys/drm/sw/Makefile new file mode 100644 index 0000000000..2add161a62 --- /dev/null +++ b/src/gallium/winsys/drm/sw/Makefile @@ -0,0 +1,13 @@ +TOP = ../../../../.. +include $(TOP)/configs/current + +LIBNAME = swdrm + +C_SOURCES = \ + sw_drm_api.c + +LIBRARY_INCLUDES = + +LIBRARY_DEFINES = + +include ../../../Makefile.template diff --git a/src/gallium/winsys/drm/sw/sw_drm_api.c b/src/gallium/winsys/drm/sw/sw_drm_api.c new file mode 100644 index 0000000000..21f44a2a62 --- /dev/null +++ b/src/gallium/winsys/drm/sw/sw_drm_api.c @@ -0,0 +1,287 @@ +/************************************************************************** + * + * Copyright © 2010 Jakob Bornecrantz + * + * 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, sublicense, + * 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + **************************************************************************/ + + +#include "pipe/p_format.h" +#include "pipe/p_state.h" + +#include "state_tracker/drm_api.h" +#include "state_tracker/xm_winsys.h" + +#include "util/u_memory.h" +#include "util/u_inlines.h" + +#include "trace/tr_drm.h" + +/* + * XXX The sw_pipe_* code is generic and should be move out. + * + * This code wraps a pipe_screen and exposes a sw_callbacks interface + * for use in software resterizers. This code is used by the DRM based + * winsys to allow access to the drm driver. + * + * We must borrow the whole stack because only the pipe screen knows how + * to decode the content of a buffer. Or how to create a buffer that + * can still be used by drivers using real hardware (as the case is + * with software st/xorg but hw st/dri). + */ + +struct sw_pipe_callbacks +{ + struct sw_callbacks base; + struct pipe_screen *screen; +}; + +struct sw_pipe_displatarget +{ + struct pipe_texture *tex; + struct pipe_transfer *transfer; +}; + +static INLINE struct sw_pipe_callbacks * +sw_pipe_callbacks(struct sw_callbacks *swc) +{ + return (struct sw_pipe_callbacks *)swc; +} + +static INLINE struct pipe_texture * +sw_pipe_dt_get_texture(struct sw_displaytarget *dt) +{ + struct sw_pipe_displatarget *swpdt = (struct sw_pipe_displatarget *)dt; + return swpdt->tex; +} + +static INLINE struct sw_displaytarget * +sw_pipe_dt_wrap_texture(struct pipe_texture *tex) +{ + struct sw_pipe_displatarget *swpdt = CALLOC_STRUCT(sw_pipe_displatarget); + swpdt->tex = tex; + return (struct sw_displaytarget *)swpdt; +} + +static struct sw_displaytarget * +swpc_dt_create(struct sw_callbacks *swc, + enum pipe_format format, + unsigned width, unsigned height, + unsigned alignment, + unsigned *stride) +{ + struct sw_pipe_callbacks *swpc = sw_pipe_callbacks(swc); + struct pipe_texture templ; + struct pipe_texture *tex; + memset(&templ, 0, sizeof(templ)); + + templ->width0 = width; + templ->height0 = height; + templ->format = format; + /* + * XXX How do we tell the difference between displaytargets and primary (scanout)? + * Aslo should all be rendertargets? + * What about depthstencil? + * XXX we pretty much need get usage passed down, maybe even the template. + */ + templ->usage = 0; + /* XXX alignment isn't needed for DRM platform */ + /* XXX stride isn't needed for DRM platform */ + + tex = swpc->screen->texture_create(swpc->screen, &templ); + + return sw_pipe_dt_wrap_texture(tex); +} + +static void * +swpc_dt_map(struct sw_callbacks *ws, + struct sw_displaytarget *dt, + unsigned flags) +{ + /* XXX use transfer */ + return NULL; +} + +static void +swpc_dt_unmap(struct sw_callbacks *ws, + struct sw_displaytarget *dt) +{ + /* XXX unmap transfer */ +} + +static void +swpc_dt_destroy(struct sw_callbacks *ws, + struct sw_displaytarget *dt) +{ + struct sw_pipe_displatarget *swpdt = (struct sw_pipe_displatarget *)dt; + + pipe_texture_reference(&swpdt->tex, NULL); + + FREE(swpdt); +} + +static void +swpc_destroy(struct sw_callbacks *swc) +{ + struct sw_pipe_callbacks *swpc = sw_pipe_callbacks(swc); + + swpc->screen->destroy(swpc->screen); + + FREE(swpc); +} + +static struct sw_callbacks * +sw_callbacks_warp_pipe_screen(struct pipe_screen *pipe) +{ + struct sw_pipe_callbacks *swpc = CALLOC_STRUCT(sw_pipe_callbacks); + + swpc->base.displaytarget_create = swpc_dt_create; + swpc->base.displaytarget_map = swpc_dt_map; + swpc->base.displaytarget_unmap = swpc_dt_unmap; + swpc->base.displaytarget_destroy = swpc_dt_destroy; + swpc->base.destroy = swpc_destroy; + + return &swpc->base; +} + + +/* + * XXX Should be moved out into header file. + */ + +struct drm_api * sw_drm_api_create(struct drm_api *api); + + +/* + * Defines + */ + +struct sw_drm_api +{ + struct drm_api base; + struct drm_api *api; + struct sw_driver *sw; +}; + +static INLINE struct sw_drm_api * +sw_drm_api(struct drm_api *api) +{ + return (struct sw_drm_api *)api; +} + + +/* + * Exported functions + */ + +static struct pipe_texture * +sw_drm_texture_from_shared_handle(struct drm_api *_api, + struct pipe_screen *_screen, + struct pipe_texture *templ, + const char* name, + unsigned pitch, + unsigned handle) +{ + struct sw_drm_api *swapi = sw_drm_api(_api); + struct drm_api *api = swapi->api; + struct pipe_screen *screen = NULL/* XXX GET? */; + struct sw_displaytarget *dt; + struct pipe_texture *tex; + + tex = api->texture_from_shared_handle(api, screen, templ, name, pitch, handle); + dt = sw_pipe_dt_wrap_texture(tex); + + return swapi->sw->wrap_displaytarget(swapi->sw, _screen, templ, dt); +} + +static boolean +sw_drm_shared_handle_from_texture(struct drm_api *_api, + struct pipe_screen *_screen, + struct pipe_texture *_tex, + unsigned *pitch, + unsigned *handle) +{ + struct sw_drm_api *swapi = sw_drm_api(_api); + struct drm_api *api = swapi->api; + struct sw_displaytarget *dt = swapi->sw->get_displaytarget(swapi->sw, _tex); + struct pipe_texture *tex = sw_pipe_dt_get_texture(dt); + struct pipe_screen *screen = tex->screen; + + return api->shared_handle_from_texture(api, screen, tex, pitch, handle); +} + +static boolean +sw_drm_local_handle_from_texture(struct drm_api *_api, + struct pipe_screen *_screen, + struct pipe_texture *_tex, + unsigned *pitch, + unsigned *handle) +{ + struct sw_drm_api *swapi = sw_drm_api(_api); + struct drm_api *api = swapi->api; + struct sw_displaytarget *dt = swapi->sw->get_displaytarget(swapi->sw, _tex); + struct pipe_texture *tex = sw_pipe_dt_get_texture(dt); + struct pipe_screen *screen = tex->screen; + + return api->local_handle_from_texture(api, screen, tex, pitch, handle); +} + +static struct pipe_screen * +sw_drm_create_screen(struct drm_api *_api, int drmFD, + struct drm_create_screen_arg *arg) +{ + struct sw_drm_api *swapi = sw_drm_api(_api); + struct drm_api *api = swapi->api; + struct sw_callbacks *swc; + struct pipe_screen *screen; + + screen = api->create_screen(api, drmFD, arg); + + swc = sw_callbacks_warp_pipe_screen(screen); + + return swapi->sw->create_screen(swapi->sw, swc); +} + +static void +sw_drm_destroy(struct drm_api *api) +{ + struct sw_drm_api *swapi = sw_drm_api(api); + if (swapi->api->destroy) + swapi->api->destroy(swapi->api); + + FREE(swapi); +} + +struct drm_api * +sw_drm_api_create(struct drm_api *api) +{ + struct sw_drm_api *swapi = CALLOC_STRUCT(sw_drm_api); + + swapi->base.name = "sw"; + swapi->base.driver_name = api->driver_name; + swapi->base.create_screen = sw_drm_create_screen; + swapi->base.texture_from_shared_handle = sw_drm_texture_from_shared_handle; + swapi->base.shared_handle_from_texture = sw_drm_shared_handle_from_texture; + swapi->base.local_handle_from_texture = sw_drm_local_handle_from_texture; + swapi->base.destroy = sw_drm_destroy; + + return trace_drm_create(&swapi->base); +} |