diff options
author | Alon Levy <alevy@redhat.com> | 2011-08-02 11:51:24 +0300 |
---|---|---|
committer | Alon Levy <alevy@redhat.com> | 2011-08-26 16:22:13 +0300 |
commit | b465dc803102392f885f383edf2a2420c3538fb1 (patch) | |
tree | 47850f1c14128c5dcd2d543b8c3dc7cbd0fe6c72 | |
parent | 718d2b5b5be22cf827121a541163f65fddc75a7a (diff) |
remote: more in progress - moving some winsys to driver
resource_create and user_buffer_create implemented previously in winsys
and when resource_create was still called buffer_create and didn't receive
a template. Changed the affected REMREQ_* messages, hoping that my guess
that the template would be a previously created remote resource (actually,
where does this start? oh well) so passing both handles and screens.
-rw-r--r-- | src/gallium/drivers/remote/remote_context.c | 4 | ||||
-rw-r--r-- | src/gallium/drivers/remote/remote_messages.h | 7 | ||||
-rw-r--r-- | src/gallium/drivers/remote/remote_screen.c | 121 | ||||
-rw-r--r-- | src/gallium/drivers/remote/remote_screen.h | 3 | ||||
-rw-r--r-- | src/gallium/drivers/remote/remote_state.h | 2 | ||||
-rw-r--r-- | src/gallium/drivers/remote/remote_util.h | 2 | ||||
-rw-r--r-- | src/gallium/winsys/sw/remote_xlib/remote_xlib_sw_winsys.c | 82 |
7 files changed, 154 insertions, 67 deletions
diff --git a/src/gallium/drivers/remote/remote_context.c b/src/gallium/drivers/remote/remote_context.c index 765da14bc2..4df3bd1e65 100644 --- a/src/gallium/drivers/remote/remote_context.c +++ b/src/gallium/drivers/remote/remote_context.c @@ -80,8 +80,8 @@ static INLINE void mark_surface_dirty(struct pipe_surface* surf) { debug_printf("!!! Surface with no texture encountered\n"); } else { - struct remote_buffer* rbuf = (struct remote_buffer*)rtex->backing_buffer; - rbuf->remote_dirty = 1; + struct remote_resource* rres = (struct remote_resource*)rtex->backing_buffer; + rres->remote_dirty = 1; } } diff --git a/src/gallium/drivers/remote/remote_messages.h b/src/gallium/drivers/remote/remote_messages.h index 588c0e05f6..8ae1e790c2 100644 --- a/src/gallium/drivers/remote/remote_messages.h +++ b/src/gallium/drivers/remote/remote_messages.h @@ -772,16 +772,17 @@ struct remreq_flush_frontbuffer { #define REMREQ_FLUSH_FRONTBUFFER 66 -struct remreq_buffer_create { +struct remreq_resource_create { struct message_header base; uint32_t screen; - unsigned alignment, size, usage; uint32_t handle; + uint32_t templat_screen; + uint32_t templat_handle; }; -#define REMREQ_BUFFER_CREATE 67 +#define REMREQ_RESOURCE_CREATE 67 struct remreq_user_buffer_create { diff --git a/src/gallium/drivers/remote/remote_screen.c b/src/gallium/drivers/remote/remote_screen.c index 3bf5f4e130..5afef8ff95 100644 --- a/src/gallium/drivers/remote/remote_screen.c +++ b/src/gallium/drivers/remote/remote_screen.c @@ -42,6 +42,7 @@ #include "util/u_inlines.h" #include "pipe/p_defines.h" #include "util/u_memory.h" +#include "util/u_format.h" #include "remote_state.h" #include "remote_util.h" @@ -187,7 +188,7 @@ remote_screen_is_format_supported(struct pipe_screen *_screen, } -static int get_or_alloc_buffer_handle(struct remote_buffer* rbuf, +static int get_or_alloc_buffer_handle(struct remote_resource* rbuf, struct pipe_screen* screen, uint32_t* handle) { @@ -240,10 +241,51 @@ static struct pipe_resource * remote_screen_resource_create(struct pipe_screen *_screen, const struct pipe_resource *templat) { - struct pipe_resource *result = NULL; + struct remote_resource *remres_templat = (struct remote_resource*)templat; - DBG("%s: unimplemented\n", __FUNCTION__); - return result; + uint32_t handle = get_fresh_buffer_handle(_screen); + + DBG("New resource %u from template %p\n", handle, templat); + + ALLOC_OUT_MESSAGE(resource_create, message); + + message->base.opcode = REMREQ_RESOURCE_CREATE; + message->screen = SCREEN_HANDLE(_screen); + message->templat_screen = SCREEN_HANDLE(templat->screen); + // assume that we also created this resource? stands to reason - is it + // even possible to share resources between different drivers? + message->templat_handle = remres_templat->handle; + message->handle = handle; + + enqueue_message(message); + + struct remote_resource* remres = CALLOC_STRUCT(remote_resource); + + remres->base = *templat; + remres->base.screen = _screen; + pipe_reference_init(&remres->base.reference, 1); + remres->handle = handle; + remres->nmaps = 0; + remres->is_user = 0; + remres->remote_dirty = 0; + remres->local_dirty = 0; + // XXX llvmpipe has different storage for different buffer typess - textures + // are tiled, everything else is just a straight malloc. let's just do + // a malloc. nothing is going to be done with this except copying + // over the wire / accessed by the host. Of course, possibly we do + // want to do some rendering in the guest? or avoid copy in the host? Later. + { + const enum pipe_format format = templat->format; + const uint w = templat->width0 / util_format_get_blockheight(format); + /* XXX buffers should only have one dimension, those values should be 1 */ + const uint h = templat->height0 / util_format_get_blockwidth(format); + const uint d = templat->depth0; + const uint bpp = util_format_get_blocksize(format); + const uint bytes = w * h * d * bpp; + remres->map = malloc(bytes); + } + + return (struct pipe_resource*)remres; } static struct pipe_resource * @@ -277,14 +319,59 @@ remote_screen_resource_destroy(struct pipe_screen *_screen, * buffer */ +/* TODO: the header documentation of pipe_screen->user_buffer_create + * says this is deferred usually, sometimes doesn't happen - so why + * do we send a message immediately? perhaps better to send it much later + * if at all. */ static struct pipe_resource * remote_screen_user_buffer_create(struct pipe_screen *_screen, void *data, - unsigned size, - unsigned usage) + unsigned bytes, + unsigned bind_flags) { - DBG("%s: unimplemented\n", __FUNCTION__); - return NULL; + struct remote_screen *remote_screen = (struct remote_screen*)_screen; // CONTAINER_OF? + uint32_t handle = get_fresh_buffer_handle(_screen); + + DBG("User buffer create: %u (bytes %u)\n", handle, bytes); + + struct remreq_user_buffer_create* header = + (struct remreq_user_buffer_create*) + allocate_message_memory(sizeof(struct remreq_user_buffer_create) + bytes); + + header->base.opcode = REMREQ_USER_BUFFER_CREATE; + header->screen = remote_screen->remote_handle; + header->size = bytes; + header->handle = handle; + + void* copydest = ((char*)header + sizeof(struct remreq_user_buffer_create)); + + memcpy(copydest, data, bytes); + + enqueue_message(header); + + struct remote_resource* remres = CALLOC_STRUCT(remote_resource); + + if (!remres) { + return NULL; + } + pipe_reference_init(&remres->base.reference, 1); + remres->base.bind = bind_flags; + /* these parameters are copied from llvmpipe (lp_texture.c, llvmpipe_user_buffer_create)) */ + remres->base.usage = PIPE_USAGE_IMMUTABLE; + remres->base.flags = 0; + remres->base.width0 = bytes; + remres->base.height0 = 1; + remres->base.depth0 = 1; + remres->base.array_size = 1; + remres->handle = handle; + remres->nmaps = 0; + remres->is_user = 1; + remres->map = data; + remres->remote_dirty = 0; + remres->local_dirty = 0; + + return (struct pipe_resource*)remres; + } @@ -579,15 +666,6 @@ int complete_screen_creation(struct remote_screen* screen) { } - -struct remote_screen * -remote_screen(struct pipe_screen *screen) -{ - assert(screen); - assert(screen->destroy == remote_screen_destroy); - return (struct remote_screen *)screen; -} - // Handle generation functions. Currently these just assign sequential numbers. // If a 32-bit space for e.g. buffers becomes a problem will need to expand that. @@ -660,4 +738,13 @@ uint32_t get_fresh_buffer_handle(struct pipe_screen* screen) { return remscr->last_buffer_handle++; } + +struct remote_screen * +remote_screen(struct pipe_screen *screen) +{ + assert(screen); + assert(screen->destroy == remote_screen_destroy); + return (struct remote_screen *)screen; +} + /* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/drivers/remote/remote_screen.h b/src/gallium/drivers/remote/remote_screen.h index 704312ad5b..1e388cc22f 100644 --- a/src/gallium/drivers/remote/remote_screen.h +++ b/src/gallium/drivers/remote/remote_screen.h @@ -28,6 +28,8 @@ #ifndef TR_SCREEN_H_ #define TR_SCREEN_H_ +#include "pipe/p_defines.h" +#include "util/u_debug.h" #include "pipe/p_screen.h" #ifdef __cplusplus @@ -68,7 +70,6 @@ struct remote_screen }; - struct remote_screen * remote_screen(struct pipe_screen *screen); diff --git a/src/gallium/drivers/remote/remote_state.h b/src/gallium/drivers/remote/remote_state.h index 5ebca9d3d1..cb884a4ab8 100644 --- a/src/gallium/drivers/remote/remote_state.h +++ b/src/gallium/drivers/remote/remote_state.h @@ -16,7 +16,7 @@ TRIVIAL_REMOTE(opaque_remote_vs) #undef TRIVIAL_REMOTE -struct remote_buffer { +struct remote_resource { struct pipe_resource base; unsigned is_user; diff --git a/src/gallium/drivers/remote/remote_util.h b/src/gallium/drivers/remote/remote_util.h index 35b1a4b866..68d7c30dfa 100644 --- a/src/gallium/drivers/remote/remote_util.h +++ b/src/gallium/drivers/remote/remote_util.h @@ -27,4 +27,4 @@ #define SURFACE_HANDLE(s) (s ? ((struct remote_surface*)s)->handle : 0) -#define BUFFER_HANDLE(buf) (buf ? ((struct remote_buffer*)buf)->handle : 0) +#define BUFFER_HANDLE(res) (res ? ((struct remote_resource*)res)->handle : 0) diff --git a/src/gallium/winsys/sw/remote_xlib/remote_xlib_sw_winsys.c b/src/gallium/winsys/sw/remote_xlib/remote_xlib_sw_winsys.c index 2c5e508b3d..978b9db8ad 100644 --- a/src/gallium/winsys/sw/remote_xlib/remote_xlib_sw_winsys.c +++ b/src/gallium/winsys/sw/remote_xlib/remote_xlib_sw_winsys.c @@ -25,9 +25,12 @@ * **************************************************************************/ +#include <stdio.h> + #include "util/u_memory.h" #include "util/u_hash_table.h" +#include "remote_screen.h" #include "remote_state.h" #include "remote_screen.h" #include "remote_util.h" @@ -36,16 +39,18 @@ #include "remote_debug.h" #include "remote_context.h" +#include "remote_winsys.h" + extern int analyse_waits; struct remote_winsys* singleton_winsys = 0; struct remote_screen* singleton_screen = 0; +struct pipe_winsys * remote_winsys_create(); + static void remote_create_singletons(void) { - struct pipe_context *pipe; - if(!singleton_winsys) { DBG("Found no winsys; creating\n"); singleton_winsys = (struct remote_winsys*)remote_winsys_create(); @@ -59,7 +64,7 @@ remote_create_singletons(void) exit(1); } if(complete_screen_creation(singleton_screen)) { - singleton_winsys->screen = (struct remote_screen*)singleton_screen; + singleton_winsys->screen = (struct remote_screen*)singleton_screen; } else { DBG("Complete_screen_creation failed\n"); @@ -141,26 +146,7 @@ winsys_surface_release(struct pipe_winsys *_winsys, exit(1); } - -struct pipe_buffer* create_anon_buffer(unsigned size) { - - struct remote_buffer* rembuf = CALLOC_STRUCT(remote_buffer); - - rembuf->base.alignment = 1; - rembuf->base.usage = PIPE_BUFFER_USAGE_CPU_READ | PIPE_BUFFER_USAGE_CPU_WRITE; - rembuf->base.size = size; - rembuf->base.refcount = 1; - rembuf->handle = 0; - rembuf->nmaps = 0; - rembuf->is_user = 0; - rembuf->map = malloc(size); - rembuf->remote_dirty = 0; - rembuf->local_dirty = 0; - - return (struct pipe_buffer*)rembuf; - -} - + static struct pipe_buffer * winsys_buffer_create(struct pipe_winsys *_winsys, unsigned alignment, @@ -462,30 +448,42 @@ winsys_destroy(struct pipe_winsys *_winsys) struct pipe_winsys * remote_winsys_create() { - struct remote_winsys *tr_ws; + struct remote_winsys *rem_ws; DBG("Creating winsys\n"); - tr_ws = CALLOC_STRUCT(remote_winsys); - if(!tr_ws) + rem_ws = CALLOC_STRUCT(remote_winsys); + if (!rem_ws) goto error1; - tr_ws->base.destroy = winsys_destroy; - tr_ws->base.get_name = winsys_get_name; - tr_ws->base.flush_frontbuffer = winsys_flush_frontbuffer; - tr_ws->base.surface_alloc = winsys_surface_alloc; - tr_ws->base.surface_alloc_storage = winsys_surface_alloc_storage; - tr_ws->base.surface_release = winsys_surface_release; - tr_ws->base.buffer_create = winsys_buffer_create; - tr_ws->base.user_buffer_create = winsys_user_buffer_create; - tr_ws->base.buffer_map = winsys_buffer_map; - tr_ws->base.buffer_unmap = winsys_buffer_unmap; - tr_ws->base.buffer_destroy = winsys_buffer_destroy; - tr_ws->base.fence_reference = winsys_fence_reference; - tr_ws->base.fence_signalled = winsys_fence_signalled; - tr_ws->base.fence_finish = winsys_fence_finish; - - return &tr_ws->base; + rem_ws->base.destroy = winsys_destroy; + rem_ws->base.get_name = winsys_get_name; + rem_ws->base.flush_frontbuffer = winsys_flush_frontbuffer; + rem_ws->base.surface_alloc = winsys_surface_alloc; + rem_ws->base.surface_alloc_storage = winsys_surface_alloc_storage; + rem_ws->base.surface_release = winsys_surface_release; + rem_ws->base.buffer_create = winsys_buffer_create; + rem_ws->base.user_buffer_create = winsys_user_buffer_create; + rem_ws->base.buffer_map = winsys_buffer_map; + rem_ws->base.buffer_unmap = winsys_buffer_unmap; + rem_ws->base.buffer_destroy = winsys_buffer_destroy; + rem_ws->base.fence_reference = winsys_fence_reference; + rem_ws->base.fence_signalled = winsys_fence_signalled; + rem_ws->base.fence_finish = winsys_fence_finish; + + rem_ws->base.is_displaytarget_format_supported = remote_is_displaytarget_format_supported; + + rem_ws->base.displaytarget_create = remote_displaytarget_create; + rem_ws->base.displaytarget_from_handle = remote_displaytarget_from_handle; + rem_ws->base.displaytarget_get_handle = remote_displaytarget_get_handle; + rem_ws->base.displaytarget_map = remote_displaytarget_map; + rem_ws->base.displaytarget_unmap = remote_displaytarget_unmap; + rem_ws->base.displaytarget_destroy = remote_displaytarget_destroy; + + rem_ws->base.displaytarget_display = remote_displaytarget_display; + + + return &rem_ws->base; error1: return NULL; |