diff options
author | Alon Levy <alevy@redhat.com> | 2011-07-14 06:09:38 +0300 |
---|---|---|
committer | Alon Levy <alevy@redhat.com> | 2011-08-26 16:22:13 +0300 |
commit | 558dde17202f9d546c6b33462807451593ec4efd (patch) | |
tree | 29aa52d18f69708c6f66b35e3628bcff557f6704 /src | |
parent | 9f95af6c4997fc947e9dbdaa4efcbb999e9a48de (diff) |
s/g/winsys/sw/remote_xlib: adding, broken - uses 2 years old api
Minus all the files that are copies plus tweaks from sw/xlib. Maybe
possible to do without it with the sw_winsys.
Diffstat (limited to 'src')
-rw-r--r-- | src/gallium/winsys/sw/remote_xlib/Makefile | 16 | ||||
-rw-r--r-- | src/gallium/winsys/sw/remote_xlib/SConscript | 45 | ||||
-rw-r--r-- | src/gallium/winsys/sw/remote_xlib/remote_xlib_sw_winsys.c | 503 |
3 files changed, 564 insertions, 0 deletions
diff --git a/src/gallium/winsys/sw/remote_xlib/Makefile b/src/gallium/winsys/sw/remote_xlib/Makefile new file mode 100644 index 0000000000..7f49e3aba4 --- /dev/null +++ b/src/gallium/winsys/sw/remote_xlib/Makefile @@ -0,0 +1,16 @@ +TOP = ../../../../.. +include $(TOP)/configs/current + +LIBNAME = ws_xlib + +LIBRARY_INCLUDES = \ + -I$(TOP)/src/gallium/drivers/remote \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/src/gallium/auxiliary \ + $(X11_CFLAGS) + +C_SOURCES = \ + remote_xlib_sw_winsys.c + +include ../../../Makefile.template diff --git a/src/gallium/winsys/sw/remote_xlib/SConscript b/src/gallium/winsys/sw/remote_xlib/SConscript new file mode 100644 index 0000000000..32523dcd5c --- /dev/null +++ b/src/gallium/winsys/sw/remote_xlib/SConscript @@ -0,0 +1,45 @@ +####################################################################### +# SConscript for remote-xlib winsys + +Import('*') + +if env['platform'] == 'linux' \ + and 'mesa' in env['statetrackers'] \ + and 'remote' in env['drivers'] \ + and not env['dri']: + + env = env.Clone() + + env.Append(CPPPATH = [ + '.', + '#/src/mesa', + '#/src/mesa/main', + '../../drivers/remote', + '/usr/include/X11', + '/usr/include/X11/extensions' + ]) + + env.Append(CFLAGS = [ '-std=c99' ]) + + sources = [ + 'glxapi.c', + 'fakeglx.c', + 'xfonts.c', + 'xm_api.c', + 'tr_winsys.c', + 'ext.c' + ] + + drivers = [ + remote, + ] + + # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions + libgl = env.SharedLibrary( + target ='GL', + source = sources, + LIBS = glapi + mesa + drivers + auxiliaries + env['LIBS'], + ) + + env.InstallSharedLibrary(libgl, version=(1, 5)) +
\ No newline at end of file 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 new file mode 100644 index 0000000000..82ffb12d8a --- /dev/null +++ b/src/gallium/winsys/sw/remote_xlib/remote_xlib_sw_winsys.c @@ -0,0 +1,503 @@ +/************************************************************************** + * + * Copyright 2008 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. + * + **************************************************************************/ + +#include "util/u_memory.h" +#include "util/u_hash_table.h" + +#include "remote_state.h" +#include "remote_screen.h" +#include "remote_util.h" +#include "remote_messages.h" +#include "remote_comms.h" +#include "remote_debug.h" +#include "remote_winsys.h" +#include "remote_context.h" + +extern int analyse_waits; + +struct remote_winsys* singleton_winsys = 0; +struct remote_screen* singleton_screen = 0; + +struct pipe_context * +xmesa_create_pipe_context(XMesaContext xmesa, uint pixelformat) +{ + struct pipe_context *pipe; + + DBG("Creating a new xmesa_context\n"); + + if(!singleton_winsys) { + DBG("Found no winsys; creating\n"); + singleton_winsys = (struct remote_winsys*)remote_winsys_create(); + } + + if(!singleton_screen) { + DBG("Found no screen; creating\n"); + singleton_screen = (struct remote_screen*)remote_screen_create((struct pipe_winsys*)singleton_winsys); + if(!singleton_screen) { + DBG("remote_screen_create returned NULL\n"); + exit(1); + } + if(complete_screen_creation(singleton_screen)) { + singleton_winsys->screen = (struct remote_screen*)singleton_screen; + } + else { + DBG("Complete_screen_creation failed\n"); + exit(1); + } + } + + pipe = remote_context_create((struct pipe_screen*)singleton_screen); + + if (pipe) + pipe->priv = xmesa; + + return pipe; +} + + +static const char * +winsys_get_name(struct pipe_winsys *_winsys) +{ + + return "Xen virtualised 3D (GLX)\n"; + +} + + +static void +winsys_flush_frontbuffer(struct pipe_winsys *_winsys, + struct pipe_surface *surface, + void *context_private) +{ + + // Ignore the context_private pointer, as I can't know where this came from# + // or how to serialise it correctly. + + DBG("Flush frontbuffer\n"); + + ALLOC_OUT_MESSAGE(flush_frontbuffer, message); + + message->base.opcode = REMREQ_FLUSH_FRONTBUFFER; + message->screen = WINSYS_HANDLE(_winsys); + message->surface = SURFACE_HANDLE(surface); + + enqueue_message(message); + +} + + +// The following two methods stubbed, since all our surfaces are remote and these never get called +// from the Mesa state tracker. Of course, should some other ST do so, these need implementing. + +static struct pipe_surface * +winsys_surface_alloc(struct pipe_winsys *_winsys) +{ + + printf("SURFACE_ALLOC NOT IMPLEMENTED!\n"); + exit(1); + + return NULL; + +} + + +static int +winsys_surface_alloc_storage(struct pipe_winsys *_winsys, + struct pipe_surface *surface, + unsigned width, unsigned height, + enum pipe_format format, + unsigned flags, + unsigned tex_usage) +{ + + printf("SURFACE_ALLOC_STORAGE NOT IMPLEMENTED!\n"); + exit(1); + + return 0; +} + +// Stubbed as I don't have any surfaces which do not correspond to textures + +static void +winsys_surface_release(struct pipe_winsys *_winsys, + struct pipe_surface **psurface) +{ + + printf("SURFACE_RELEASE NOT IMPLEMENTED!\n"); + 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, + unsigned usage, + unsigned size) +{ + + struct remote_winsys* rwinsys = + (struct remote_winsys*)_winsys; + + uint32_t handle = get_fresh_buffer_handle((struct pipe_screen*)rwinsys->screen); + + DBG("New buffer %u (size %u)\n", handle, size); + + ALLOC_OUT_MESSAGE(buffer_create, message); + + message->base.opcode = REMREQ_BUFFER_CREATE; + message->screen = WINSYS_HANDLE(_winsys); + message->alignment = alignment; + message->usage = usage; + message->size = size; + message->handle = handle; + + enqueue_message(message); + + struct remote_buffer* rembuf = CALLOC_STRUCT(remote_buffer); + + rembuf->base.alignment = alignment; + rembuf->base.usage = usage; + rembuf->base.size = size; + rembuf->base.refcount = 1; + rembuf->handle = handle; + 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_user_buffer_create(struct pipe_winsys *_winsys, + void *data, + unsigned size) +{ + + struct remote_winsys* rwinsys = + (struct remote_winsys*)_winsys; + + uint32_t handle = get_fresh_buffer_handle((struct pipe_screen*)rwinsys->screen); + + DBG("User buffer create: %u (size %u)\n", handle, size); + + struct remreq_user_buffer_create* header = + (struct remreq_user_buffer_create*) + allocate_message_memory(sizeof(struct remreq_user_buffer_create) + size); + + header->base.opcode = REMREQ_USER_BUFFER_CREATE; + header->screen = WINSYS_HANDLE(_winsys); + header->size = size; + header->handle = handle; + + void* copydest = ((char*)header + sizeof(struct remreq_user_buffer_create)); + + memcpy(copydest, data, size); + + enqueue_message(header); + + struct remote_buffer* rembuf = CALLOC_STRUCT(remote_buffer); + + rembuf->base.alignment = 1; + rembuf->base.size = size; + rembuf->base.refcount = 1; + rembuf->handle = handle; + rembuf->nmaps = 0; + rembuf->is_user = 1; + rembuf->map = data; + rembuf->remote_dirty = 0; + rembuf->local_dirty = 0; + + return (struct pipe_buffer*)rembuf; + +} + + +void +winsys_user_buffer_update(struct pipe_winsys *_winsys, + struct pipe_buffer *buffer) +{ + + // For now, copy the whole damn thing again. + // In the long run, shared memory is the answer. + + DBG("Update user buffer %u\n", BUFFER_HANDLE(buffer)); + + struct remreq_user_buffer_update* header = + (struct remreq_user_buffer_update*) + malloc(sizeof(struct remreq_user_buffer_update) + buffer->size); + + header->base.opcode = REMREQ_USER_BUFFER_UPDATE; + header->screen = WINSYS_HANDLE(_winsys); + header->buffer = BUFFER_HANDLE(buffer); + + void* copydest = ((char*)header + sizeof(struct remreq_user_buffer_create)); + + void* copysrc = ((struct remote_buffer*)buffer)->map; + + memcpy(copydest, copysrc, buffer->size); + + enqueue_message(header); + +} + + +static void * +winsys_buffer_map(struct pipe_winsys *_winsys, + struct pipe_buffer *buffer, + unsigned usage) +{ + + struct remote_buffer* rembuf = (struct remote_buffer*)buffer; + + if(usage & (PIPE_BUFFER_USAGE_CPU_WRITE)) + DBG("Map buffer %u for writing\n", BUFFER_HANDLE(buffer)); + else + DBG("Map buffer %u for reading\n", BUFFER_HANDLE(buffer)); + + if(rembuf->remote_dirty) + DBG("Buffer is out of date: must update\n"); + + if(rembuf->remote_dirty) { + + rembuf->remote_dirty = 0; + // i.e., our local copy no longer lags the remote + + if(rembuf->nmaps > 1) + printf("WARNING: Buffer was dirty, but already mapped locally.\n"); + + ALLOC_OUT_MESSAGE(buffer_get_data, message); + + message->base.opcode = REMREQ_BUFFER_GET_DATA; + message->winsys = WINSYS_HANDLE(_winsys); + message->buffer = BUFFER_HANDLE(buffer); + + if(analyse_waits) + printf("Might wait: buffer_get_data (getting %d bytes...)\n", (int)rembuf->base.size); + QUEUE_AND_WAIT(message, buffer_get_data, reply); + + if(analyse_waits) + printf("buffer_get_data completed\n"); + + if(!reply->success) { + DBG("Remote side reported failure\n"); + free_message(reply); + return NULL; + } + + memcpy(rembuf->map, ((char*)reply) + sizeof(struct remrep_buffer_get_data), rembuf->base.size); + DBG("Copied in %u bytes\n", buffer->size); + + free_message(reply); + + } + + if(usage & (PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_GPU_WRITE)) + rembuf->local_dirty = 1; + + rembuf->nmaps++; + + return rembuf->map; + +} + + +static void +winsys_buffer_unmap(struct pipe_winsys *_winsys, + struct pipe_buffer *buffer) +{ + + struct remote_buffer* rembuf = (struct remote_buffer*)buffer; + + DBG("Buffer unmap: buffer %u, currently mapped %u times\n", BUFFER_HANDLE(buffer), rembuf->nmaps); + if(rembuf->local_dirty) { + DBG("Remote is out of date: must update\n"); + } + + if((!(--(rembuf->nmaps))) && rembuf->local_dirty) { + + DBG("Local refcount hit zero: freeing map\n"); + + if(analyse_waits) + printf("Set data (might cause waits): %d bytes\n", (int)buffer->size); + + struct remreq_buffer_set_data* header = + (struct remreq_buffer_set_data*) + allocate_message_memory(sizeof(struct remreq_buffer_set_data) + + buffer->size); + + header->base.opcode = REMREQ_BUFFER_SET_DATA; + header->winsys = WINSYS_HANDLE(_winsys); + header->buffer = BUFFER_HANDLE(buffer); + + char* copydest = ((char*)header + sizeof(struct remreq_buffer_set_data)); + memcpy(copydest, rembuf->map, buffer->size); + + enqueue_message(header); + + if(analyse_waits) + printf("Set data completed\n"); + + rembuf->local_dirty = 0; + + } + +} + + +static void +winsys_buffer_destroy(struct pipe_winsys *_winsys, + struct pipe_buffer *buffer) +{ + + struct remote_buffer* rbuf = (struct remote_buffer*)buffer; + + if(rbuf->handle) { + + DBG("Destroy buffer %u\n", BUFFER_HANDLE(buffer)); + + ALLOC_OUT_MESSAGE(buffer_destroy, message); + + message->base.opcode = REMREQ_BUFFER_DESTROY; + message->screen = WINSYS_HANDLE(_winsys); + message->buffer = BUFFER_HANDLE(buffer); + + enqueue_message(message); + + } + else { + DBG("Destroy anonymous buffer\n"); + } + + if(!rbuf->is_user) + free(rbuf->map); + + free(rbuf); + +} + +// Stubbed, as it doesn't appear the state tracker uses these + +static void +winsys_fence_reference(struct pipe_winsys *_winsys, + struct pipe_fence_handle **pdst, + struct pipe_fence_handle *src) +{ + + DBG("FENCE FUNCTIONS NOT IMPLEMENTED\n"); + +} + + +static int +winsys_fence_signalled(struct pipe_winsys *_winsys, + struct pipe_fence_handle *fence, + unsigned flag) +{ + + DBG("FENCE FUNCTIONS NOT IMPLEMENTED\n"); + return 0; + +} + + +static int +winsys_fence_finish(struct pipe_winsys *_winsys, + struct pipe_fence_handle *fence, + unsigned flag) +{ + + DBG("FENCE FUNCTIONS NOT IMPLEMENTED\n"); + return 0; + +} + + +static void +winsys_destroy(struct pipe_winsys *_winsys) +{ + struct remote_winsys *tr_ws = (struct remote_winsys*)_winsys; + + DBG("Destroy winsys for screen %u\n", WINSYS_HANDLE(_winsys)); + + FREE(tr_ws); +} + + +struct pipe_winsys * remote_winsys_create() +{ + struct remote_winsys *tr_ws; + + DBG("Creating winsys\n"); + + tr_ws = CALLOC_STRUCT(remote_winsys); + if(!tr_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; + +error1: + return NULL; + +} |