summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Levy <alevy@redhat.com>2011-08-02 11:51:24 +0300
committerAlon Levy <alevy@redhat.com>2011-08-26 16:22:13 +0300
commitb465dc803102392f885f383edf2a2420c3538fb1 (patch)
tree47850f1c14128c5dcd2d543b8c3dc7cbd0fe6c72
parent718d2b5b5be22cf827121a541163f65fddc75a7a (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.c4
-rw-r--r--src/gallium/drivers/remote/remote_messages.h7
-rw-r--r--src/gallium/drivers/remote/remote_screen.c121
-rw-r--r--src/gallium/drivers/remote/remote_screen.h3
-rw-r--r--src/gallium/drivers/remote/remote_state.h2
-rw-r--r--src/gallium/drivers/remote/remote_util.h2
-rw-r--r--src/gallium/winsys/sw/remote_xlib/remote_xlib_sw_winsys.c82
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;