summaryrefslogtreecommitdiffstats
path: root/src/gallium/winsys/drm
diff options
context:
space:
mode:
authorKeith Whitwell <[email protected]>2009-12-21 19:18:41 +0000
committerKeith Whitwell <[email protected]>2009-12-21 19:18:41 +0000
commita5585cb533af3d4e5d5324d5f526447b98597402 (patch)
tree6706dbb8b4f994b919e247647c3e8853d067b45c /src/gallium/winsys/drm
parentd288a30610767f87e3e7c069730d4bc255246568 (diff)
parent574715d8368f99c0a5720a9676385d58d6cfdf30 (diff)
Merge commit 'origin/master' into i965g-restart
Conflicts: SConstruct configs/default configs/linux-dri
Diffstat (limited to 'src/gallium/winsys/drm')
-rw-r--r--src/gallium/winsys/drm/SConscript5
-rw-r--r--src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c9
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_buffer.c8
-rw-r--r--src/gallium/winsys/drm/vmware/Makefile12
-rw-r--r--src/gallium/winsys/drm/vmware/SConscript11
-rw-r--r--src/gallium/winsys/drm/vmware/core/Makefile35
-rw-r--r--src/gallium/winsys/drm/vmware/core/SConscript39
-rw-r--r--src/gallium/winsys/drm/vmware/core/vmw_buffer.c274
-rw-r--r--src/gallium/winsys/drm/vmware/core/vmw_buffer.h65
-rw-r--r--src/gallium/winsys/drm/vmware/core/vmw_context.c297
-rw-r--r--src/gallium/winsys/drm/vmware/core/vmw_context.h59
-rw-r--r--src/gallium/winsys/drm/vmware/core/vmw_fence.c108
-rw-r--r--src/gallium/winsys/drm/vmware/core/vmw_fence.h59
-rw-r--r--src/gallium/winsys/drm/vmware/core/vmw_screen.c74
-rw-r--r--src/gallium/winsys/drm/vmware/core/vmw_screen.h134
-rw-r--r--src/gallium/winsys/drm/vmware/core/vmw_screen_dri.c371
-rw-r--r--src/gallium/winsys/drm/vmware/core/vmw_screen_ioctl.c504
-rw-r--r--src/gallium/winsys/drm/vmware/core/vmw_screen_pools.c79
-rw-r--r--src/gallium/winsys/drm/vmware/core/vmw_screen_svga.c295
-rw-r--r--src/gallium/winsys/drm/vmware/core/vmw_surface.c61
-rw-r--r--src/gallium/winsys/drm/vmware/core/vmw_surface.h79
-rw-r--r--src/gallium/winsys/drm/vmware/core/vmwgfx_drm.h442
-rw-r--r--src/gallium/winsys/drm/vmware/dri/Makefile18
-rw-r--r--src/gallium/winsys/drm/vmware/dri/SConscript62
-rw-r--r--src/gallium/winsys/drm/vmware/egl/Makefile18
-rw-r--r--src/gallium/winsys/drm/vmware/xorg/Makefile63
-rw-r--r--src/gallium/winsys/drm/vmware/xorg/SConscript54
-rw-r--r--src/gallium/winsys/drm/vmware/xorg/vmw_xorg.c150
28 files changed, 3376 insertions, 9 deletions
diff --git a/src/gallium/winsys/drm/SConscript b/src/gallium/winsys/drm/SConscript
index ba389d8ed36..66b73a8bf93 100644
--- a/src/gallium/winsys/drm/SConscript
+++ b/src/gallium/winsys/drm/SConscript
@@ -48,6 +48,11 @@ if env['dri']:
# $(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR)
# $(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR)
+ if 'vmware' in env['winsys']:
+ SConscript([
+ 'vmware/SConscript',
+ ])
+
if 'intel' in env['winsys']:
SConscript([
'intel/SConscript',
diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
index f512c0e5f32..d4978613247 100644
--- a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
+++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
@@ -21,14 +21,13 @@ dri_surface_from_handle(struct drm_api *api, struct pipe_screen *pscreen,
struct pipe_texture tmpl;
memset(&tmpl, 0, sizeof(tmpl));
- tmpl.tex_usage = PIPE_TEXTURE_USAGE_PRIMARY |
- NOUVEAU_TEXTURE_USAGE_LINEAR;
+ tmpl.tex_usage = PIPE_TEXTURE_USAGE_PRIMARY;
tmpl.target = PIPE_TEXTURE_2D;
tmpl.last_level = 0;
- tmpl.depth[0] = 1;
+ tmpl.depth0 = 1;
tmpl.format = format;
- tmpl.width[0] = width;
- tmpl.height[0] = height;
+ tmpl.width0 = width;
+ tmpl.height0 = height;
pf_get_block(tmpl.format, &tmpl.block);
pt = api->texture_from_shared_handle(api, pscreen, &tmpl,
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
index 0a7b5ecb094..74afffc9cfa 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
+++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
@@ -218,7 +218,7 @@ static void radeon_display_surface(struct pipe_winsys *pws,
ximage->data = data;
ximage->width = psurf->width;
ximage->height = psurf->height;
- ximage->bytes_per_line = r300tex->stride_override;
+ ximage->bytes_per_line = psurf->width * (ximage->bits_per_pixel >> 3);
XPutImage(rvl_ctx->display, rvl_ctx->drawable,
XDefaultGC(rvl_ctx->display, rvl_ctx->screen),
@@ -317,9 +317,9 @@ struct pipe_surface *radeon_surface_from_handle(struct radeon_context *radeon_co
memset(&tmpl, 0, sizeof(tmpl));
tmpl.tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
tmpl.target = PIPE_TEXTURE_2D;
- tmpl.width[0] = w;
- tmpl.height[0] = h;
- tmpl.depth[0] = 1;
+ tmpl.width0 = w;
+ tmpl.height0 = h;
+ tmpl.depth0 = 1;
tmpl.format = format;
pf_get_block(tmpl.format, &tmpl.block);
tmpl.nblocksx[0] = pf_get_nblocksx(&tmpl.block, w);
diff --git a/src/gallium/winsys/drm/vmware/Makefile b/src/gallium/winsys/drm/vmware/Makefile
new file mode 100644
index 00000000000..2ae6dead5c1
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/Makefile
@@ -0,0 +1,12 @@
+# src/gallium/winsys/drm/vmware/Makefile
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+SUBDIRS = core $(GALLIUM_STATE_TRACKERS_DIRS)
+
+default install clean:
+ @for dir in $(SUBDIRS) ; do \
+ if [ -d $$dir ] ; then \
+ (cd $$dir && $(MAKE) $@) || exit 1; \
+ fi \
+ done
diff --git a/src/gallium/winsys/drm/vmware/SConscript b/src/gallium/winsys/drm/vmware/SConscript
new file mode 100644
index 00000000000..06e6d5be9ca
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/SConscript
@@ -0,0 +1,11 @@
+Import('*')
+
+SConscript(['core/SConscript',])
+
+if 'mesa' in env['statetrackers']:
+
+ SConscript(['dri/SConscript'])
+
+if 'xorg' in env['statetrackers']:
+
+ SConscript(['xorg/SConscript'])
diff --git a/src/gallium/winsys/drm/vmware/core/Makefile b/src/gallium/winsys/drm/vmware/core/Makefile
new file mode 100644
index 00000000000..a52957c1a5b
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/core/Makefile
@@ -0,0 +1,35 @@
+TOP = ../../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = svgadrm
+
+C_SOURCES = \
+ vmw_buffer.c \
+ vmw_context.c \
+ vmw_fence.c \
+ vmw_screen.c \
+ vmw_screen_dri.c \
+ vmw_screen_ioctl.c \
+ vmw_screen_pools.c \
+ vmw_screen_svga.c \
+ vmw_surface.c
+
+LIBRARY_INCLUDES = \
+ -I$(TOP)/src/gallium/drivers/svga \
+ -I$(TOP)/src/gallium/drivers/svga/include \
+ -I$(GALLIUM)/src/mesa/drivers/dri/common \
+ -I$(GALLIUM)/include \
+ -I$(GALLIUM)/include/GL/internal \
+ -I$(GALLIUM)/src/mesa \
+ -I$(GALLIUM)/src/mesa/main \
+ -I$(GALLIUM)/src/mesa/glapi \
+ -I$(GALLIUM)/src/egl/main \
+ -I$(GALLIUM)/src/egl/drivers/dri \
+ $(shell pkg-config libdrm --cflags-only-I)
+
+LIBRARY_DEFINES = \
+ -std=gnu99 -fvisibility=hidden \
+ -DHAVE_STDINT_H -D_FILE_OFFSET_BITS=64 \
+ $(shell pkg-config libdrm --cflags-only-other)
+
+include ../../../../Makefile.template
diff --git a/src/gallium/winsys/drm/vmware/core/SConscript b/src/gallium/winsys/drm/vmware/core/SConscript
new file mode 100644
index 00000000000..edaf9458bee
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/core/SConscript
@@ -0,0 +1,39 @@
+Import('*')
+
+env = env.Clone()
+
+if env['gcc']:
+ env.Append(CCFLAGS = ['-fvisibility=hidden'])
+ env.Append(CPPDEFINES = [
+ 'HAVE_STDINT_H',
+ 'HAVE_SYS_TYPES_H',
+ '-D_FILE_OFFSET_BITS=64',
+ ])
+
+env.Prepend(CPPPATH = [
+ 'include',
+ '#/src/gallium/drivers/svga',
+ '#/src/gallium/drivers/svga/include',
+])
+
+env.Append(CPPDEFINES = [
+])
+
+sources = [
+ 'vmw_buffer.c',
+ 'vmw_context.c',
+ 'vmw_fence.c',
+ 'vmw_screen.c',
+ 'vmw_screen_dri.c',
+ 'vmw_screen_ioctl.c',
+ 'vmw_screen_pools.c',
+ 'vmw_screen_svga.c',
+ 'vmw_surface.c',
+]
+
+svgadrm = env.ConvenienceLibrary(
+ target = 'svgadrm',
+ source = sources,
+)
+
+Export('svgadrm')
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_buffer.c b/src/gallium/winsys/drm/vmware/core/vmw_buffer.c
new file mode 100644
index 00000000000..b812fb59d39
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/core/vmw_buffer.c
@@ -0,0 +1,274 @@
+/**********************************************************
+ * Copyright 2009 VMware, Inc. 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, 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 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.
+ *
+ **********************************************************/
+
+/**
+ * @file
+ * SVGA buffer manager for Guest Memory Regions (GMRs).
+ *
+ * GMRs are used for pixel and vertex data upload/download to/from the virtual
+ * SVGA hardware. There is a limited number of GMRs available, and
+ * creating/destroying them is also a slow operation so we must suballocate
+ * them.
+ *
+ * This file implements a pipebuffer library's buffer manager, so that we can
+ * use pipepbuffer's suballocation, fencing, and debugging facilities with GMRs.
+ *
+ * @author Jose Fonseca <[email protected]>
+ */
+
+
+#include "svga_cmd.h"
+
+#include "pipe/p_inlines.h"
+#include "util/u_memory.h"
+#include "pipebuffer/pb_buffer.h"
+#include "pipebuffer/pb_bufmgr.h"
+
+#include "svga_winsys.h"
+
+#include "vmw_screen.h"
+#include "vmw_buffer.h"
+
+
+struct vmw_gmr_bufmgr;
+
+
+struct vmw_gmr_buffer
+{
+ struct pb_buffer base;
+
+ struct vmw_gmr_bufmgr *mgr;
+
+ struct vmw_region *region;
+ void *map;
+
+#ifdef DEBUG
+ struct pipe_fence_handle *last_fence;
+#endif
+};
+
+
+extern const struct pb_vtbl vmw_gmr_buffer_vtbl;
+
+
+static INLINE struct vmw_gmr_buffer *
+vmw_gmr_buffer(struct pb_buffer *buf)
+{
+ assert(buf);
+ assert(buf->vtbl == &vmw_gmr_buffer_vtbl);
+ return (struct vmw_gmr_buffer *)buf;
+}
+
+
+struct vmw_gmr_bufmgr
+{
+ struct pb_manager base;
+
+ struct vmw_winsys_screen *vws;
+};
+
+
+static INLINE struct vmw_gmr_bufmgr *
+vmw_gmr_bufmgr(struct pb_manager *mgr)
+{
+ assert(mgr);
+ return (struct vmw_gmr_bufmgr *)mgr;
+}
+
+
+static void
+vmw_gmr_buffer_destroy(struct pb_buffer *_buf)
+{
+ struct vmw_gmr_buffer *buf = vmw_gmr_buffer(_buf);
+
+#ifdef DEBUG
+ if(buf->last_fence) {
+ struct svga_winsys_screen *sws = &buf->mgr->vws->base;
+ assert(sws->fence_signalled(sws, buf->last_fence, 0) == 0);
+ }
+#endif
+
+ vmw_ioctl_region_unmap(buf->region);
+
+ vmw_ioctl_region_destroy(buf->region);
+
+ FREE(buf);
+}
+
+
+static void *
+vmw_gmr_buffer_map(struct pb_buffer *_buf,
+ unsigned flags)
+{
+ struct vmw_gmr_buffer *buf = vmw_gmr_buffer(_buf);
+ return buf->map;
+}
+
+
+static void
+vmw_gmr_buffer_unmap(struct pb_buffer *_buf)
+{
+ /* Do nothing */
+ (void)_buf;
+}
+
+
+static void
+vmw_gmr_buffer_get_base_buffer(struct pb_buffer *buf,
+ struct pb_buffer **base_buf,
+ unsigned *offset)
+{
+ *base_buf = buf;
+ *offset = 0;
+}
+
+
+static enum pipe_error
+vmw_gmr_buffer_validate( struct pb_buffer *_buf,
+ struct pb_validate *vl,
+ unsigned flags )
+{
+ /* Always pinned */
+ return PIPE_OK;
+}
+
+
+static void
+vmw_gmr_buffer_fence( struct pb_buffer *_buf,
+ struct pipe_fence_handle *fence )
+{
+ /* We don't need to do anything, as the pipebuffer library
+ * will take care of delaying the destruction of fenced buffers */
+#ifdef DEBUG
+ struct vmw_gmr_buffer *buf = vmw_gmr_buffer(_buf);
+ if(fence)
+ buf->last_fence = fence;
+#endif
+}
+
+
+const struct pb_vtbl vmw_gmr_buffer_vtbl = {
+ vmw_gmr_buffer_destroy,
+ vmw_gmr_buffer_map,
+ vmw_gmr_buffer_unmap,
+ vmw_gmr_buffer_validate,
+ vmw_gmr_buffer_fence,
+ vmw_gmr_buffer_get_base_buffer
+};
+
+
+static struct pb_buffer *
+vmw_gmr_bufmgr_create_buffer(struct pb_manager *_mgr,
+ pb_size size,
+ const struct pb_desc *desc)
+{
+ struct vmw_gmr_bufmgr *mgr = vmw_gmr_bufmgr(_mgr);
+ struct vmw_winsys_screen *vws = mgr->vws;
+ struct vmw_gmr_buffer *buf;
+
+ buf = CALLOC_STRUCT(vmw_gmr_buffer);
+ if(!buf)
+ goto error1;
+
+ pipe_reference_init(&buf->base.base.reference, 1);
+ buf->base.base.alignment = desc->alignment;
+ buf->base.base.usage = desc->usage;
+ buf->base.base.size = size;
+ buf->base.vtbl = &vmw_gmr_buffer_vtbl;
+ buf->mgr = mgr;
+
+ buf->region = vmw_ioctl_region_create(vws, size);
+ if(!buf->region)
+ goto error2;
+
+ buf->map = vmw_ioctl_region_map(buf->region);
+ if(!buf->map)
+ goto error3;
+
+ return &buf->base;
+
+error3:
+ vmw_ioctl_region_destroy(buf->region);
+error2:
+ FREE(buf);
+error1:
+ return NULL;
+}
+
+
+static void
+vmw_gmr_bufmgr_flush(struct pb_manager *mgr)
+{
+ /* No-op */
+}
+
+
+static void
+vmw_gmr_bufmgr_destroy(struct pb_manager *_mgr)
+{
+ struct vmw_gmr_bufmgr *mgr = vmw_gmr_bufmgr(_mgr);
+ FREE(mgr);
+}
+
+
+struct pb_manager *
+vmw_gmr_bufmgr_create(struct vmw_winsys_screen *vws)
+{
+ struct vmw_gmr_bufmgr *mgr;
+
+ mgr = CALLOC_STRUCT(vmw_gmr_bufmgr);
+ if(!mgr)
+ return NULL;
+
+ mgr->base.destroy = vmw_gmr_bufmgr_destroy;
+ mgr->base.create_buffer = vmw_gmr_bufmgr_create_buffer;
+ mgr->base.flush = vmw_gmr_bufmgr_flush;
+
+ mgr->vws = vws;
+
+ return &mgr->base;
+}
+
+
+boolean
+vmw_gmr_bufmgr_region_ptr(struct pb_buffer *buf,
+ struct SVGAGuestPtr *ptr)
+{
+ struct pb_buffer *base_buf;
+ unsigned offset = 0;
+ struct vmw_gmr_buffer *gmr_buf;
+
+ pb_get_base_buffer( buf, &base_buf, &offset );
+
+ gmr_buf = vmw_gmr_buffer(base_buf);
+ if(!gmr_buf)
+ return FALSE;
+
+ *ptr = vmw_ioctl_region_ptr(gmr_buf->region);
+
+ ptr->offset += offset;
+
+ return TRUE;
+}
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_buffer.h b/src/gallium/winsys/drm/vmware/core/vmw_buffer.h
new file mode 100644
index 00000000000..634bdcabd26
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/core/vmw_buffer.h
@@ -0,0 +1,65 @@
+/**********************************************************
+ * Copyright 2009 VMware, Inc. 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, 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 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.
+ *
+ **********************************************************/
+
+
+#ifndef VMW_BUFFER_H_
+#define VMW_BUFFER_H_
+
+
+#include "pipe/p_compiler.h"
+
+struct SVGAGuestPtr;
+struct pb_buffer;
+struct pb_manager;
+struct svga_winsys_buffer;
+struct svga_winsys_surface;
+struct vmw_winsys_screen;
+
+
+static INLINE struct pb_buffer *
+vmw_pb_buffer(struct svga_winsys_buffer *buffer)
+{
+ assert(buffer);
+ return (struct pb_buffer *)buffer;
+}
+
+
+static INLINE struct svga_winsys_buffer *
+vmw_svga_winsys_buffer(struct pb_buffer *buffer)
+{
+ assert(buffer);
+ return (struct svga_winsys_buffer *)buffer;
+}
+
+
+struct pb_manager *
+vmw_gmr_bufmgr_create(struct vmw_winsys_screen *vws);
+
+boolean
+vmw_gmr_bufmgr_region_ptr(struct pb_buffer *buf,
+ struct SVGAGuestPtr *ptr);
+
+
+#endif /* VMW_BUFFER_H_ */
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_context.c b/src/gallium/winsys/drm/vmware/core/vmw_context.c
new file mode 100644
index 00000000000..b6997588de4
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/core/vmw_context.c
@@ -0,0 +1,297 @@
+/**********************************************************
+ * Copyright 2009 VMware, Inc. 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, 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 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 "svga_cmd.h"
+
+#include "util/u_debug.h"
+#include "util/u_memory.h"
+#include "util/u_debug_stack.h"
+#include "pipebuffer/pb_buffer.h"
+#include "pipebuffer/pb_validate.h"
+
+#include "svga_winsys.h"
+#include "vmw_context.h"
+#include "vmw_screen.h"
+#include "vmw_buffer.h"
+#include "vmw_surface.h"
+#include "vmw_fence.h"
+
+#define VMW_COMMAND_SIZE (64*1024)
+#define VMW_SURFACE_RELOCS (1024)
+
+#define VMW_MUST_FLUSH_STACK 8
+
+struct vmw_svga_winsys_context
+{
+ struct svga_winsys_context base;
+
+ struct vmw_winsys_screen *vws;
+
+#ifdef DEBUG
+ boolean must_flush;
+ struct debug_stack_frame must_flush_stack[VMW_MUST_FLUSH_STACK];
+#endif
+
+ struct {
+ uint8_t buffer[VMW_COMMAND_SIZE];
+ uint32_t size;
+ uint32_t used;
+ uint32_t reserved;
+ } command;
+
+ struct {
+ struct vmw_svga_winsys_surface *handles[VMW_SURFACE_RELOCS];
+ uint32_t size;
+ uint32_t used;
+ uint32_t staged;
+ uint32_t reserved;
+ } surface;
+
+ struct pb_validate *validate;
+
+ uint32_t last_fence;
+};
+
+
+static INLINE struct vmw_svga_winsys_context *
+vmw_svga_winsys_context(struct svga_winsys_context *swc)
+{
+ assert(swc);
+ return (struct vmw_svga_winsys_context *)swc;
+}
+
+
+static enum pipe_error
+vmw_swc_flush(struct svga_winsys_context *swc,
+ struct pipe_fence_handle **pfence)
+{
+ struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
+ struct pipe_fence_handle *fence = NULL;
+ unsigned i;
+ enum pipe_error ret;
+
+ ret = pb_validate_validate(vswc->validate);
+ assert(ret == PIPE_OK);
+ if(ret == PIPE_OK) {
+
+ if (vswc->command.used)
+ vmw_ioctl_command(vswc->vws,
+ vswc->command.buffer,
+ vswc->command.used,
+ &vswc->last_fence);
+
+ fence = vmw_pipe_fence(vswc->last_fence);
+
+ pb_validate_fence(vswc->validate, fence);
+ }
+
+ vswc->command.used = 0;
+ vswc->command.reserved = 0;
+
+ for(i = 0; i < vswc->surface.used + vswc->surface.staged; ++i) {
+ struct vmw_svga_winsys_surface *vsurf =
+ vswc->surface.handles[i];
+ p_atomic_dec(&vsurf->validated);
+ vmw_svga_winsys_surface_reference(&vswc->surface.handles[i], NULL);
+ }
+
+ vswc->surface.used = 0;
+ vswc->surface.reserved = 0;
+
+#ifdef DEBUG
+ vswc->must_flush = FALSE;
+#endif
+
+ if(pfence)
+ *pfence = fence;
+
+ return ret;
+}
+
+
+static void *
+vmw_swc_reserve(struct svga_winsys_context *swc,
+ uint32_t nr_bytes, uint32_t nr_relocs )
+{
+ struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
+
+#ifdef DEBUG
+ /* Check if somebody forgot to check the previous failure */
+ if(vswc->must_flush) {
+ debug_printf("Forgot to flush:\n");
+ debug_backtrace_dump(vswc->must_flush_stack, VMW_MUST_FLUSH_STACK);
+ assert(!vswc->must_flush);
+ }
+#endif
+
+ assert(nr_bytes <= vswc->command.size);
+ if(nr_bytes > vswc->command.size)
+ return NULL;
+
+ if(vswc->command.used + nr_bytes > vswc->command.size ||
+ vswc->surface.used + nr_relocs > vswc->surface.size) {
+#ifdef DEBUG
+ vswc->must_flush = TRUE;
+ debug_backtrace_capture(vswc->must_flush_stack, 1,
+ VMW_MUST_FLUSH_STACK);
+#endif
+ return NULL;
+ }
+
+ assert(vswc->command.used + nr_bytes <= vswc->command.size);
+ assert(vswc->surface.used + nr_relocs <= vswc->surface.size);
+
+ vswc->command.reserved = nr_bytes;
+ vswc->surface.reserved = nr_relocs;
+ vswc->surface.staged = 0;
+
+ return vswc->command.buffer + vswc->command.used;
+}
+
+
+static void
+vmw_swc_surface_relocation(struct svga_winsys_context *swc,
+ uint32 *where,
+ struct svga_winsys_surface *surface,
+ unsigned flags)
+{
+ struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
+ struct vmw_svga_winsys_surface *vsurf;
+
+ if(!surface) {
+ *where = SVGA3D_INVALID_ID;
+ return;
+ }
+
+ assert(vswc->surface.staged < vswc->surface.reserved);
+
+ vsurf = vmw_svga_winsys_surface(surface);
+
+ *where = vsurf->sid;
+
+ vmw_svga_winsys_surface_reference(&vswc->surface.handles[vswc->surface.used + vswc->surface.staged], vsurf);
+ p_atomic_inc(&vsurf->validated);
+ ++vswc->surface.staged;
+}
+
+
+static void
+vmw_swc_region_relocation(struct svga_winsys_context *swc,
+ struct SVGAGuestPtr *where,
+ struct svga_winsys_buffer *buffer,
+ uint32 offset,
+ unsigned flags)
+{
+ struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
+ struct SVGAGuestPtr ptr;
+ struct pb_buffer *buf = vmw_pb_buffer(buffer);
+ enum pipe_error ret;
+
+ if(!vmw_gmr_bufmgr_region_ptr(buf, &ptr))
+ assert(0);
+
+ ptr.offset += offset;
+
+ *where = ptr;
+
+ ret = pb_validate_add_buffer(vswc->validate, buf, flags);
+ /* TODO: Update pipebuffer to reserve buffers and not fail here */
+ assert(ret == PIPE_OK);
+}
+
+
+static void
+vmw_swc_commit(struct svga_winsys_context *swc)
+{
+ struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
+
+ assert(vswc->command.reserved);
+ assert(vswc->command.used + vswc->command.reserved <= vswc->command.size);
+ vswc->command.used += vswc->command.reserved;
+ vswc->command.reserved = 0;
+
+ assert(vswc->surface.staged <= vswc->surface.reserved);
+ assert(vswc->surface.used + vswc->surface.staged <= vswc->surface.size);
+ vswc->surface.used += vswc->surface.staged;
+ vswc->surface.staged = 0;
+ vswc->surface.reserved = 0;
+}
+
+
+static void
+vmw_swc_destroy(struct svga_winsys_context *swc)
+{
+ struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
+ unsigned i;
+ for(i = 0; i < vswc->surface.used; ++i) {
+ p_atomic_dec(&vswc->surface.handles[i]->validated);
+ vmw_svga_winsys_surface_reference(&vswc->surface.handles[i], NULL);
+ }
+ pb_validate_destroy(vswc->validate);
+ vmw_ioctl_context_destroy(vswc->vws, swc->cid);
+ FREE(vswc);
+}
+
+
+struct svga_winsys_context *
+vmw_svga_winsys_context_create(struct svga_winsys_screen *sws)
+{
+ struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
+ struct vmw_svga_winsys_context *vswc;
+
+ vswc = CALLOC_STRUCT(vmw_svga_winsys_context);
+ if(!vswc)
+ return NULL;
+
+ vswc->base.destroy = vmw_swc_destroy;
+ vswc->base.reserve = vmw_swc_reserve;
+ vswc->base.surface_relocation = vmw_swc_surface_relocation;
+ vswc->base.region_relocation = vmw_swc_region_relocation;
+ vswc->base.commit = vmw_swc_commit;
+ vswc->base.flush = vmw_swc_flush;
+
+ vswc->base.cid = vmw_ioctl_context_create(vws);
+
+ vswc->vws = vws;
+
+ vswc->command.size = VMW_COMMAND_SIZE;
+ vswc->surface.size = VMW_SURFACE_RELOCS;
+
+ vswc->validate = pb_validate_create();
+ if(!vswc->validate) {
+ FREE(vswc);
+ return NULL;
+ }
+
+ return &vswc->base;
+}
+
+
+struct pipe_context *
+vmw_svga_context_create(struct pipe_screen *screen)
+{
+ return svga_context_create(screen);
+}
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_context.h b/src/gallium/winsys/drm/vmware/core/vmw_context.h
new file mode 100644
index 00000000000..305ce9b5bec
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/core/vmw_context.h
@@ -0,0 +1,59 @@
+/**********************************************************
+ * Copyright 2009 VMware, Inc. 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, 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 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.
+ *
+ **********************************************************/
+
+/**
+ * @author Jose Fonseca <[email protected]>
+ */
+
+
+#ifndef VMW_CONTEXT_H_
+#define VMW_CONTEXT_H_
+
+#include "pipe/p_compiler.h"
+
+struct svga_winsys_screen;
+struct svga_winsys_context;
+struct pipe_context;
+struct pipe_screen;
+
+#define VMW_DEBUG 0
+
+#if VMW_DEBUG
+#define vmw_printf debug_printf
+#define VMW_FUNC debug_printf("%s\n", __FUNCTION__)
+#else
+#define VMW_FUNC
+#define vmw_printf(...)
+#endif
+
+
+struct svga_winsys_context *
+vmw_svga_winsys_context_create(struct svga_winsys_screen *sws);
+
+struct pipe_context *
+vmw_svga_context_create(struct pipe_screen *screen);
+
+
+#endif /* VMW_CONTEXT_H_ */
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_fence.c b/src/gallium/winsys/drm/vmware/core/vmw_fence.c
new file mode 100644
index 00000000000..873dd51166c
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/core/vmw_fence.c
@@ -0,0 +1,108 @@
+/**********************************************************
+ * Copyright 2009 VMware, Inc. 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, 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 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 "util/u_memory.h"
+#include "pipebuffer/pb_buffer_fenced.h"
+
+#include "vmw_screen.h"
+#include "vmw_fence.h"
+
+
+
+struct vmw_fence_ops
+{
+ struct pb_fence_ops base;
+
+ struct vmw_winsys_screen *vws;
+};
+
+
+static INLINE struct vmw_fence_ops *
+vmw_fence_ops(struct pb_fence_ops *ops)
+{
+ assert(ops);
+ return (struct vmw_fence_ops *)ops;
+}
+
+
+static void
+vmw_fence_ops_fence_reference(struct pb_fence_ops *ops,
+ struct pipe_fence_handle **ptr,
+ struct pipe_fence_handle *fence)
+{
+ *ptr = fence;
+}
+
+
+static int
+vmw_fence_ops_fence_signalled(struct pb_fence_ops *ops,
+ struct pipe_fence_handle *fence,
+ unsigned flag)
+{
+ struct vmw_winsys_screen *vws = vmw_fence_ops(ops)->vws;
+ (void)flag;
+ return vmw_ioctl_fence_signalled(vws, vmw_fence(fence));
+}
+
+
+static int
+vmw_fence_ops_fence_finish(struct pb_fence_ops *ops,
+ struct pipe_fence_handle *fence,
+ unsigned flag)
+{
+ struct vmw_winsys_screen *vws = vmw_fence_ops(ops)->vws;
+ (void)flag;
+ return vmw_ioctl_fence_finish(vws, vmw_fence(fence));
+}
+
+
+static void
+vmw_fence_ops_destroy(struct pb_fence_ops *ops)
+{
+ FREE(ops);
+}
+
+
+struct pb_fence_ops *
+vmw_fence_ops_create(struct vmw_winsys_screen *vws)
+{
+ struct vmw_fence_ops *ops;
+
+ ops = CALLOC_STRUCT(vmw_fence_ops);
+ if(!ops)
+ return NULL;
+
+ ops->base.destroy = &vmw_fence_ops_destroy;
+ ops->base.fence_reference = &vmw_fence_ops_fence_reference;
+ ops->base.fence_signalled = &vmw_fence_ops_fence_signalled;
+ ops->base.fence_finish = &vmw_fence_ops_fence_finish;
+
+ ops->vws = vws;
+
+ return &ops->base;
+}
+
+
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_fence.h b/src/gallium/winsys/drm/vmware/core/vmw_fence.h
new file mode 100644
index 00000000000..5357b4f61de
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/core/vmw_fence.h
@@ -0,0 +1,59 @@
+/**********************************************************
+ * Copyright 2009 VMware, Inc. 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, 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 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.
+ *
+ **********************************************************/
+
+
+#ifndef VMW_FENCE_H_
+#define VMW_FENCE_H_
+
+
+#include "pipe/p_compiler.h"
+
+
+struct pipe_fence_handle;
+struct pb_fence_ops;
+struct vmw_winsys_screen;
+
+
+/** Cast from a pipe_fence_handle pointer into a SVGA fence */
+static INLINE uint32_t
+vmw_fence( struct pipe_fence_handle *fence )
+{
+ return (uint32_t)(uintptr_t)fence;
+}
+
+
+/** Cast from a SVGA fence number to pipe_fence_handle pointer */
+static INLINE struct pipe_fence_handle *
+vmw_pipe_fence( uint32_t fence )
+{
+ return (struct pipe_fence_handle *)(uintptr_t)fence;
+}
+
+
+struct pb_fence_ops *
+vmw_fence_ops_create(struct vmw_winsys_screen *vws);
+
+
+#endif /* VMW_FENCE_H_ */
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_screen.c b/src/gallium/winsys/drm/vmware/core/vmw_screen.c
new file mode 100644
index 00000000000..911eec5e254
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/core/vmw_screen.c
@@ -0,0 +1,74 @@
+/**********************************************************
+ * Copyright 2009 VMware, Inc. 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, 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 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 "vmw_screen.h"
+
+#include "vmw_context.h"
+
+#include "util/u_memory.h"
+#include "pipe/p_compiler.h"
+
+
+/* Called from vmw_drm_create_screen(), creates and initializes the
+ * vmw_winsys_screen structure, which is the main entity in this
+ * module.
+ */
+struct vmw_winsys_screen *
+vmw_winsys_create( int fd )
+{
+ struct vmw_winsys_screen *vws = CALLOC_STRUCT(vmw_winsys_screen);
+ if (!vws)
+ goto out_no_vws;
+
+ vws->ioctl.drm_fd = fd;
+
+ if (!vmw_ioctl_init(vws))
+ goto out_no_ioctl;
+
+ if(!vmw_pools_init(vws))
+ goto out_no_pools;
+
+ if (!vmw_winsys_screen_init_svga(vws))
+ goto out_no_svga;
+
+ return vws;
+out_no_svga:
+ vmw_pools_cleanup(vws);
+out_no_pools:
+ vmw_ioctl_cleanup(vws);
+out_no_ioctl:
+ FREE(vws);
+out_no_vws:
+ return NULL;
+}
+
+void
+vmw_winsys_destroy(struct vmw_winsys_screen *vws)
+{
+ vmw_pools_cleanup(vws);
+ vmw_ioctl_cleanup(vws);
+ FREE(vws);
+}
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_screen.h b/src/gallium/winsys/drm/vmware/core/vmw_screen.h
new file mode 100644
index 00000000000..a875107370c
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/core/vmw_screen.h
@@ -0,0 +1,134 @@
+/**********************************************************
+ * Copyright 2009 VMware, Inc. 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, 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 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.
+ *
+ **********************************************************/
+
+/**
+ * @file
+ * Common definitions for the VMware SVGA winsys.
+ *
+ * @author Jose Fonseca <[email protected]>
+ */
+
+
+#ifndef VMW_SCREEN_H_
+#define VMW_SCREEN_H_
+
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_state.h"
+
+#include "svga_winsys.h"
+
+struct pb_manager;
+struct vmw_region;
+
+
+struct vmw_winsys_screen
+{
+ struct svga_winsys_screen base;
+
+ struct {
+ volatile uint32_t *fifo_map;
+ uint64_t last_fence;
+ int drm_fd;
+ } ioctl;
+
+ struct {
+ struct pb_manager *gmr;
+ struct pb_manager *gmr_mm;
+ struct pb_manager *gmr_fenced;
+ } pools;
+};
+
+
+static INLINE struct vmw_winsys_screen *
+vmw_winsys_screen(struct svga_winsys_screen *base)
+{
+ return (struct vmw_winsys_screen *)base;
+}
+
+/* */
+uint32
+vmw_ioctl_context_create(struct vmw_winsys_screen *vws);
+
+void
+vmw_ioctl_context_destroy(struct vmw_winsys_screen *vws,
+ uint32 cid);
+
+uint32
+vmw_ioctl_surface_create(struct vmw_winsys_screen *vws,
+ SVGA3dSurfaceFlags flags,
+ SVGA3dSurfaceFormat format,
+ SVGA3dSize size,
+ uint32 numFaces,
+ uint32 numMipLevels);
+
+void
+vmw_ioctl_surface_destroy(struct vmw_winsys_screen *vws,
+ uint32 sid);
+
+void
+vmw_ioctl_command(struct vmw_winsys_screen *vws,
+ void *commands,
+ uint32_t size,
+ uint32_t *fence);
+
+struct vmw_region *
+vmw_ioctl_region_create(struct vmw_winsys_screen *vws, uint32_t size);
+
+void
+vmw_ioctl_region_destroy(struct vmw_region *region);
+
+struct SVGAGuestPtr
+vmw_ioctl_region_ptr(struct vmw_region *region);
+
+void *
+vmw_ioctl_region_map(struct vmw_region *region);
+void
+vmw_ioctl_region_unmap(struct vmw_region *region);
+
+
+int
+vmw_ioctl_fence_finish(struct vmw_winsys_screen *vws,
+ uint32_t fence);
+
+int
+vmw_ioctl_fence_signalled(struct vmw_winsys_screen *vws,
+ uint32_t fence);
+
+
+/* Initialize parts of vmw_winsys_screen at startup:
+ */
+boolean vmw_ioctl_init(struct vmw_winsys_screen *vws);
+boolean vmw_pools_init(struct vmw_winsys_screen *vws);
+boolean vmw_winsys_screen_init_svga(struct vmw_winsys_screen *vws);
+
+void vmw_ioctl_cleanup(struct vmw_winsys_screen *vws);
+void vmw_pools_cleanup(struct vmw_winsys_screen *vws);
+
+struct vmw_winsys_screen *vmw_winsys_create(int fd);
+void vmw_winsys_destroy(struct vmw_winsys_screen *sws);
+
+
+#endif /* VMW_SCREEN_H_ */
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_screen_dri.c b/src/gallium/winsys/drm/vmware/core/vmw_screen_dri.c
new file mode 100644
index 00000000000..5995eee34ba
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/core/vmw_screen_dri.c
@@ -0,0 +1,371 @@
+/**********************************************************
+ * Copyright 2009 VMware, Inc. 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, 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 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_compiler.h"
+#include "pipe/p_inlines.h"
+#include "util/u_memory.h"
+#include "vmw_screen.h"
+
+#include "trace/tr_drm.h"
+
+#include "vmw_screen.h"
+#include "vmw_surface.h"
+#include "vmw_fence.h"
+#include "vmw_context.h"
+
+#include <state_tracker/dri1_api.h>
+#include <state_tracker/drm_api.h>
+#include <vmwgfx_drm.h>
+#include <xf86drm.h>
+
+#include <stdio.h>
+
+static struct dri1_api dri1_api_hooks;
+static struct dri1_api_version ddx_required = { 0, 1, 0 };
+static struct dri1_api_version ddx_compat = { 0, 0, 0 };
+static struct dri1_api_version dri_required = { 4, 0, 0 };
+static struct dri1_api_version dri_compat = { 4, 0, 0 };
+static struct dri1_api_version drm_required = { 0, 1, 0 };
+static struct dri1_api_version drm_compat = { 0, 0, 0 };
+
+static boolean
+vmw_dri1_check_version(const struct dri1_api_version *cur,
+ const struct dri1_api_version *required,
+ const struct dri1_api_version *compat,
+ const char component[])
+{
+ if (cur->major > required->major && cur->major <= compat->major)
+ return TRUE;
+ if (cur->major == required->major && cur->minor >= required->minor)
+ return TRUE;
+
+ fprintf(stderr, "%s version failure.\n", component);
+ fprintf(stderr, "%s version is %d.%d.%d and this driver can only work\n"
+ "with versions %d.%d.x through %d.x.x.\n",
+ component,
+ cur->major,
+ cur->minor,
+ cur->patch_level, required->major, required->minor, compat->major);
+ return FALSE;
+}
+
+/* This is actually the entrypoint to the entire driver, called by the
+ * libGL (or EGL, or ...) code via the drm_api_hooks table at the
+ * bottom of the file.
+ */
+static struct pipe_screen *
+vmw_drm_create_screen(struct drm_api *drm_api,
+ int fd,
+ struct drm_create_screen_arg *arg)
+{
+ struct vmw_winsys_screen *vws;
+ struct pipe_screen *screen;
+ struct dri1_create_screen_arg *dri1;
+
+ if (arg != NULL) {
+ switch (arg->mode) {
+ case DRM_CREATE_NORMAL:
+ break;
+ case DRM_CREATE_DRI1:
+ dri1 = (struct dri1_create_screen_arg *)arg;
+ if (!vmw_dri1_check_version(&dri1->ddx_version, &ddx_required,
+ &ddx_compat, "ddx - driver api"))
+ return NULL;
+ if (!vmw_dri1_check_version(&dri1->dri_version, &dri_required,
+ &dri_compat, "dri info"))
+ return NULL;
+ if (!vmw_dri1_check_version(&dri1->drm_version, &drm_required,
+ &drm_compat, "vmwgfx drm driver"))
+ return NULL;
+ dri1->api = &dri1_api_hooks;
+ break;
+ default:
+ return NULL;
+ }
+ }
+
+ vws = vmw_winsys_create( fd );
+ if (!vws)
+ goto out_no_vws;
+
+ screen = svga_screen_create( &vws->base );
+ if (!screen)
+ goto out_no_screen;
+
+ return screen;
+
+ /* Failure cases:
+ */
+out_no_screen:
+ vmw_winsys_destroy( vws );
+
+out_no_vws:
+ return NULL;
+}
+
+static INLINE boolean
+vmw_dri1_intersect_src_bbox(struct drm_clip_rect *dst,
+ int dst_x,
+ int dst_y,
+ const struct drm_clip_rect *src,
+ const struct drm_clip_rect *bbox)
+{
+ int xy1;
+ int xy2;
+
+ xy1 = ((int)src->x1 > (int)bbox->x1 + dst_x) ? src->x1 :
+ (int)bbox->x1 + dst_x;
+ xy2 = ((int)src->x2 < (int)bbox->x2 + dst_x) ? src->x2 :
+ (int)bbox->x2 + dst_x;
+ if (xy1 >= xy2 || xy1 < 0)
+ return FALSE;
+
+ dst->x1 = xy1;
+ dst->x2 = xy2;
+
+ xy1 = ((int)src->y1 > (int)bbox->y1 + dst_y) ? src->y1 :
+ (int)bbox->y1 + dst_y;
+ xy2 = ((int)src->y2 < (int)bbox->y2 + dst_y) ? src->y2 :
+ (int)bbox->y2 + dst_y;
+ if (xy1 >= xy2 || xy1 < 0)
+ return FALSE;
+
+ dst->y1 = xy1;
+ dst->y2 = xy2;
+ return TRUE;
+}
+
+/**
+ * No fancy get-surface-from-sarea stuff here.
+ * Just use the present blit.
+ */
+
+static void
+vmw_dri1_present_locked(struct pipe_context *locked_pipe,
+ struct pipe_surface *surf,
+ const struct drm_clip_rect *rect,
+ unsigned int num_clip,
+ int x_draw, int y_draw,
+ const struct drm_clip_rect *bbox,
+ struct pipe_fence_handle **p_fence)
+{
+ struct svga_winsys_surface *srf =
+ svga_screen_texture_get_winsys_surface(surf->texture);
+ struct vmw_svga_winsys_surface *vsrf = vmw_svga_winsys_surface(srf);
+ struct vmw_winsys_screen *vws =
+ vmw_winsys_screen(svga_winsys_screen(locked_pipe->screen));
+ struct drm_clip_rect clip;
+ int i;
+ struct
+ {
+ SVGA3dCmdHeader header;
+ SVGA3dCmdPresent body;
+ SVGA3dCopyRect rect;
+ } cmd;
+ boolean visible = FALSE;
+ uint32_t fence_seq = 0;
+
+ VMW_FUNC;
+ cmd.header.id = SVGA_3D_CMD_PRESENT;
+ cmd.header.size = sizeof cmd.body + sizeof cmd.rect;
+ cmd.body.sid = vsrf->sid;
+
+ for (i = 0; i < num_clip; ++i) {
+ if (!vmw_dri1_intersect_src_bbox(&clip, x_draw, y_draw, rect++, bbox))
+ continue;
+
+ cmd.rect.x = clip.x1;
+ cmd.rect.y = clip.y1;
+ cmd.rect.w = clip.x2 - clip.x1;
+ cmd.rect.h = clip.y2 - clip.y1;
+ cmd.rect.srcx = (int)clip.x1 - x_draw;
+ cmd.rect.srcy = (int)clip.y1 - y_draw;
+
+ vmw_printf("%s: Clip %d x %d y %d w %d h %d srcx %d srcy %d\n",
+ __FUNCTION__,
+ i,
+ cmd.rect.x,
+ cmd.rect.y,
+ cmd.rect.w, cmd.rect.h, cmd.rect.srcx, cmd.rect.srcy);
+
+ vmw_ioctl_command(vws, &cmd, sizeof cmd.header + cmd.header.size,
+ &fence_seq);
+ visible = TRUE;
+ }
+
+ *p_fence = (visible) ? vmw_pipe_fence(fence_seq) : NULL;
+ vmw_svga_winsys_surface_reference(&vsrf, NULL);
+}
+
+/**
+ * FIXME: We'd probably want to cache these buffers in the
+ * screen, based on handle.
+ */
+
+static struct pipe_buffer *
+vmw_drm_buffer_from_handle(struct drm_api *drm_api,
+ struct pipe_screen *screen,
+ const char *name,
+ unsigned handle)
+{
+ struct vmw_svga_winsys_surface *vsrf;
+ struct svga_winsys_surface *ssrf;
+ struct vmw_winsys_screen *vws =
+ vmw_winsys_screen(svga_winsys_screen(screen));
+ struct pipe_buffer *buf;
+ union drm_vmw_surface_reference_arg arg;
+ struct drm_vmw_surface_arg *req = &arg.req;
+ struct drm_vmw_surface_create_req *rep = &arg.rep;
+ int ret;
+ int i;
+
+ /**
+ * The vmware device specific handle is the hardware SID.
+ * FIXME: We probably want to move this to the ioctl implementations.
+ */
+
+ memset(&arg, 0, sizeof(arg));
+ req->sid = handle;
+
+ ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_REF_SURFACE,
+ &arg, sizeof(arg));
+
+ if (ret) {
+ fprintf(stderr, "Failed referencing shared surface. SID %d.\n"
+ "Error %d (%s).\n",
+ handle, ret, strerror(-ret));
+ return NULL;
+ }
+
+ if (rep->mip_levels[0] != 1) {
+ fprintf(stderr, "Incorrect number of mipmap levels on shared surface."
+ " SID %d, levels %d\n",
+ handle, rep->mip_levels[0]);
+ goto out_mip;
+ }
+
+ for (i=1; i < DRM_VMW_MAX_SURFACE_FACES; ++i) {
+ if (rep->mip_levels[i] != 0) {
+ fprintf(stderr, "Incorrect number of faces levels on shared surface."
+ " SID %d, face %d present.\n",
+ handle, i);
+ goto out_mip;
+ }
+ }
+
+ vsrf = CALLOC_STRUCT(vmw_svga_winsys_surface);
+ if (!vsrf)
+ goto out_mip;
+
+ pipe_reference_init(&vsrf->refcnt, 1);
+ p_atomic_set(&vsrf->validated, 0);
+ vsrf->sid = handle;
+ ssrf = svga_winsys_surface(vsrf);
+ buf = svga_screen_buffer_wrap_surface(screen, rep->format, ssrf);
+ if (!buf)
+ vmw_svga_winsys_surface_reference(&vsrf, NULL);
+
+ return buf;
+ out_mip:
+ vmw_ioctl_surface_destroy(vws, handle);
+ return NULL;
+}
+
+static struct pipe_texture *
+vmw_drm_texture_from_handle(struct drm_api *drm_api,
+ struct pipe_screen *screen,
+ struct pipe_texture *templat,
+ const char *name,
+ unsigned stride,
+ unsigned handle)
+{
+ struct pipe_buffer *buffer;
+ buffer = vmw_drm_buffer_from_handle(drm_api, screen, name, handle);
+
+ if (!buffer)
+ return NULL;
+
+ return screen->texture_blanket(screen, templat, &stride, buffer);
+}
+
+static boolean
+vmw_drm_handle_from_buffer(struct drm_api *drm_api,
+ struct pipe_screen *screen,
+ struct pipe_buffer *buffer,
+ unsigned *handle)
+{
+ struct svga_winsys_surface *surface =
+ svga_screen_buffer_get_winsys_surface(buffer);
+ struct vmw_svga_winsys_surface *vsrf;
+
+ if (!surface)
+ return FALSE;
+
+ vsrf = vmw_svga_winsys_surface(surface);
+ *handle = vsrf->sid;
+ vmw_svga_winsys_surface_reference(&vsrf, NULL);
+ return TRUE;
+}
+
+static boolean
+vmw_drm_handle_from_texture(struct drm_api *drm_api,
+ struct pipe_screen *screen,
+ struct pipe_texture *texture,
+ unsigned *stride,
+ unsigned *handle)
+{
+ struct pipe_buffer *buffer;
+
+ if (!svga_screen_buffer_from_texture(texture, &buffer, stride))
+ return FALSE;
+
+ return vmw_drm_handle_from_buffer(drm_api, screen, buffer, handle);
+}
+
+static struct pipe_context*
+vmw_drm_create_context(struct drm_api *drm_api,
+ struct pipe_screen *screen)
+{
+ return vmw_svga_context_create(screen);
+}
+
+static struct dri1_api dri1_api_hooks = {
+ .front_srf_locked = NULL,
+ .present_locked = vmw_dri1_present_locked
+};
+
+static struct drm_api vmw_drm_api_hooks = {
+ .create_screen = vmw_drm_create_screen,
+ .create_context = vmw_drm_create_context,
+ .texture_from_shared_handle = vmw_drm_texture_from_handle,
+ .shared_handle_from_texture = vmw_drm_handle_from_texture,
+ .local_handle_from_texture = vmw_drm_handle_from_texture,
+};
+
+struct drm_api* drm_api_create()
+{
+ return trace_drm_create(&vmw_drm_api_hooks);
+}
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_screen_ioctl.c b/src/gallium/winsys/drm/vmware/core/vmw_screen_ioctl.c
new file mode 100644
index 00000000000..51e455f9254
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/core/vmw_screen_ioctl.c
@@ -0,0 +1,504 @@
+/**********************************************************
+ * Copyright 2009 VMware, Inc. 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, 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 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.
+ *
+ **********************************************************/
+
+/**
+ * @file
+ *
+ * Wrappers for DRM ioctl functionlaity used by the rest of the vmw
+ * drm winsys.
+ *
+ * Based on svgaicd_escape.c
+ */
+
+
+#include "svga_cmd.h"
+#include "util/u_memory.h"
+#include "util/u_math.h"
+#include "svgadump/svga_dump.h"
+#include "vmw_screen.h"
+#include "vmw_context.h"
+#include "xf86drm.h"
+#include "vmwgfx_drm.h"
+
+#include <sys/mman.h>
+#include <errno.h>
+#include <unistd.h>
+
+struct vmw_region
+{
+ SVGAGuestPtr ptr;
+ uint32_t handle;
+ uint64_t map_handle;
+ void *data;
+ uint32_t map_count;
+ int drm_fd;
+ uint32_t size;
+};
+
+static void
+vmw_check_last_cmd(struct vmw_winsys_screen *vws)
+{
+ static uint32_t buffer[16384];
+ struct drm_vmw_fifo_debug_arg arg;
+ int ret;
+
+ return;
+ memset(&arg, 0, sizeof(arg));
+ arg.debug_buffer = (unsigned long)buffer;
+ arg.debug_buffer_size = 65536;
+
+ ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_FIFO_DEBUG,
+ &arg, sizeof(arg));
+
+ if (ret) {
+ debug_printf("%s Ioctl error: \"%s\".\n", __FUNCTION__, strerror(-ret));
+ return;
+ }
+
+ if (arg.did_not_fit) {
+ debug_printf("%s Command did not fit completely.\n", __FUNCTION__);
+ }
+
+ svga_dump_commands(buffer, arg.used_size);
+}
+
+static void
+vmw_ioctl_fifo_unmap(struct vmw_winsys_screen *vws, void *mapping)
+{
+ VMW_FUNC;
+ (void)munmap(mapping, getpagesize());
+}
+
+
+static void *
+vmw_ioctl_fifo_map(struct vmw_winsys_screen *vws,
+ uint32_t fifo_offset )
+{
+ void *map;
+
+ VMW_FUNC;
+
+ map = mmap(NULL, getpagesize(), PROT_READ, MAP_SHARED,
+ vws->ioctl.drm_fd, fifo_offset);
+
+ if (map == MAP_FAILED) {
+ debug_printf("Map failed %s\n", strerror(errno));
+ return NULL;
+ }
+
+ vmw_printf("Fifo (min) is 0x%08x\n", ((uint32_t *) map)[SVGA_FIFO_MIN]);
+
+ return map;
+}
+
+uint32
+vmw_ioctl_context_create(struct vmw_winsys_screen *vws)
+{
+ struct drm_vmw_context_arg c_arg;
+ int ret;
+
+ VMW_FUNC;
+
+ ret = drmCommandRead(vws->ioctl.drm_fd, DRM_VMW_CREATE_CONTEXT,
+ &c_arg, sizeof(c_arg));
+
+ if (ret)
+ return -1;
+
+ vmw_check_last_cmd(vws);
+ vmw_printf("Context id is %d\n", c_arg.cid);
+
+ return c_arg.cid;
+}
+
+void
+vmw_ioctl_context_destroy(struct vmw_winsys_screen *vws, uint32 cid)
+{
+ struct drm_vmw_context_arg c_arg;
+
+ VMW_FUNC;
+
+ memset(&c_arg, 0, sizeof(c_arg));
+ c_arg.cid = cid;
+
+ (void)drmCommandWrite(vws->ioctl.drm_fd, DRM_VMW_UNREF_CONTEXT,
+ &c_arg, sizeof(c_arg));
+
+ vmw_check_last_cmd(vws);
+}
+
+uint32
+vmw_ioctl_surface_create(struct vmw_winsys_screen *vws,
+ SVGA3dSurfaceFlags flags,
+ SVGA3dSurfaceFormat format,
+ SVGA3dSize size,
+ uint32_t numFaces, uint32_t numMipLevels)
+{
+ union drm_vmw_surface_create_arg s_arg;
+ struct drm_vmw_surface_create_req *req = &s_arg.req;
+ struct drm_vmw_surface_arg *rep = &s_arg.rep;
+ struct drm_vmw_size sizes[DRM_VMW_MAX_SURFACE_FACES*
+ DRM_VMW_MAX_MIP_LEVELS];
+ struct drm_vmw_size *cur_size;
+ uint32_t iFace;
+ uint32_t iMipLevel;
+ int ret;
+
+ vmw_printf("%s flags %d format %d\n", __FUNCTION__, flags, format);
+
+ memset(&s_arg, 0, sizeof(s_arg));
+ req->flags = (uint32_t) flags;
+ req->format = (uint32_t) format;
+ req->shareable = 1;
+
+ assert(numFaces * numMipLevels < DRM_VMW_MAX_SURFACE_FACES*
+ DRM_VMW_MAX_MIP_LEVELS);
+ cur_size = sizes;
+ for (iFace = 0; iFace < numFaces; ++iFace) {
+ SVGA3dSize mipSize = size;
+
+ req->mip_levels[iFace] = numMipLevels;
+ for (iMipLevel = 0; iMipLevel < numMipLevels; ++iMipLevel) {
+ cur_size->width = mipSize.width;
+ cur_size->height = mipSize.height;
+ cur_size->depth = mipSize.depth;
+ mipSize.width = MAX2(mipSize.width >> 1, 1);
+ mipSize.height = MAX2(mipSize.height >> 1, 1);
+ mipSize.depth = MAX2(mipSize.depth >> 1, 1);
+ cur_size++;
+ }
+ }
+ for (iFace = numFaces; iFace < SVGA3D_MAX_SURFACE_FACES; ++iFace) {
+ req->mip_levels[iFace] = 0;
+ }
+
+ req->size_addr = (unsigned long)&sizes;
+
+ ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_CREATE_SURFACE,
+ &s_arg, sizeof(s_arg));
+
+ if (ret)
+ return -1;
+
+ vmw_printf("Surface id is %d\n", rep->sid);
+ vmw_check_last_cmd(vws);
+
+ return rep->sid;
+}
+
+void
+vmw_ioctl_surface_destroy(struct vmw_winsys_screen *vws, uint32 sid)
+{
+ struct drm_vmw_surface_arg s_arg;
+
+ VMW_FUNC;
+
+ memset(&s_arg, 0, sizeof(s_arg));
+ s_arg.sid = sid;
+
+ (void)drmCommandWrite(vws->ioctl.drm_fd, DRM_VMW_UNREF_SURFACE,
+ &s_arg, sizeof(s_arg));
+ vmw_check_last_cmd(vws);
+
+}
+
+void
+vmw_ioctl_command(struct vmw_winsys_screen *vws, void *commands, uint32_t size,
+ uint32_t * pfence)
+{
+ struct drm_vmw_execbuf_arg arg;
+ struct drm_vmw_fence_rep rep;
+ int ret;
+
+#ifdef DEBUG
+ {
+ static boolean firsttime = TRUE;
+ static boolean debug = FALSE;
+ static boolean skip = FALSE;
+ if (firsttime) {
+ debug = debug_get_bool_option("SVGA_DUMP_CMD", FALSE);
+ skip = debug_get_bool_option("SVGA_SKIP_CMD", FALSE);
+ }
+ if (debug) {
+ VMW_FUNC;
+ svga_dump_commands(commands, size);
+ }
+ firsttime = FALSE;
+ if (skip) {
+ size = 0;
+ }
+ }
+#endif
+
+ memset(&arg, 0, sizeof(arg));
+ memset(&rep, 0, sizeof(rep));
+
+ rep.error = -EFAULT;
+ arg.fence_rep = (unsigned long)&rep;
+ arg.commands = (unsigned long)commands;
+ arg.command_size = size;
+
+ do {
+ ret = drmCommandWrite(vws->ioctl.drm_fd, DRM_VMW_EXECBUF, &arg, sizeof(arg));
+ } while(ret == -ERESTART);
+ if (ret) {
+ debug_printf("%s error %s.\n", __FUNCTION__, strerror(-ret));
+ }
+ if (rep.error) {
+
+ /*
+ * Kernel has synced and put the last fence sequence in the FIFO
+ * register.
+ */
+
+ if (rep.error == -EFAULT)
+ rep.fence_seq = vws->ioctl.fifo_map[SVGA_FIFO_FENCE];
+
+ debug_printf("%s Fence error %s.\n", __FUNCTION__,
+ strerror(-rep.error));
+ }
+
+ vws->ioctl.last_fence = rep.fence_seq;
+
+ if (pfence)
+ *pfence = rep.fence_seq;
+ vmw_check_last_cmd(vws);
+
+}
+
+
+struct vmw_region *
+vmw_ioctl_region_create(struct vmw_winsys_screen *vws, uint32_t size)
+{
+ struct vmw_region *region;
+ union drm_vmw_alloc_dmabuf_arg arg;
+ struct drm_vmw_alloc_dmabuf_req *req = &arg.req;
+ struct drm_vmw_dmabuf_rep *rep = &arg.rep;
+ int ret;
+
+ vmw_printf("%s: size = %u\n", __FUNCTION__, size);
+
+ region = CALLOC_STRUCT(vmw_region);
+ if (!region)
+ goto out_err1;
+
+ memset(&arg, 0, sizeof(arg));
+ req->size = size;
+ do {
+ ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_ALLOC_DMABUF, &arg,
+ sizeof(arg));
+ } while (ret == -ERESTART);
+
+ if (ret) {
+ debug_printf("IOCTL failed %d: %s\n", ret, strerror(-ret));
+ goto out_err1;
+ }
+
+ region->ptr.gmrId = rep->cur_gmr_id;
+ region->ptr.offset = rep->cur_gmr_offset;
+ region->data = NULL;
+ region->handle = rep->handle;
+ region->map_handle = rep->map_handle;
+ region->map_count = 0;
+ region->size = size;
+ region->drm_fd = vws->ioctl.drm_fd;
+
+ vmw_printf(" gmrId = %u, offset = %u\n",
+ region->ptr.gmrId, region->ptr.offset);
+
+ return region;
+
+ out_err1:
+ FREE(region);
+ return NULL;
+}
+
+void
+vmw_ioctl_region_destroy(struct vmw_region *region)
+{
+ struct drm_vmw_unref_dmabuf_arg arg;
+
+ vmw_printf("%s: gmrId = %u, offset = %u\n", __FUNCTION__,
+ region->ptr.gmrId, region->ptr.offset);
+
+ if (region->data) {
+ munmap(region->data, region->size);
+ region->data = NULL;
+ }
+
+ memset(&arg, 0, sizeof(arg));
+ arg.handle = region->handle;
+ drmCommandWrite(region->drm_fd, DRM_VMW_UNREF_DMABUF, &arg, sizeof(arg));
+
+ FREE(region);
+}
+
+SVGAGuestPtr
+vmw_ioctl_region_ptr(struct vmw_region *region)
+{
+ return region->ptr;
+}
+
+void *
+vmw_ioctl_region_map(struct vmw_region *region)
+{
+ void *map;
+
+ vmw_printf("%s: gmrId = %u, offset = %u\n", __FUNCTION__,
+ region->ptr.gmrId, region->ptr.offset);
+
+ if (region->data == NULL) {
+ map = mmap(NULL, region->size, PROT_READ | PROT_WRITE, MAP_SHARED,
+ region->drm_fd, region->map_handle);
+ if (map == MAP_FAILED) {
+ debug_printf("%s: Map failed.\n", __FUNCTION__);
+ return NULL;
+ }
+
+ region->data = map;
+ }
+
+ ++region->map_count;
+
+ return region->data;
+}
+
+void
+vmw_ioctl_region_unmap(struct vmw_region *region)
+{
+ vmw_printf("%s: gmrId = %u, offset = %u\n", __FUNCTION__,
+ region->ptr.gmrId, region->ptr.offset);
+ --region->map_count;
+}
+
+
+int
+vmw_ioctl_fence_signalled(struct vmw_winsys_screen *vws,
+ uint32_t fence)
+{
+ uint32_t expected;
+ uint32_t current;
+
+ assert(fence);
+ if(!fence)
+ return 0;
+
+ expected = fence;
+ current = vws->ioctl.fifo_map[SVGA_FIFO_FENCE];
+
+ if ((int32)(current - expected) >= 0)
+ return 0; /* fence passed */
+ else
+ return -1;
+}
+
+
+static void
+vmw_ioctl_sync(struct vmw_winsys_screen *vws,
+ uint32_t fence)
+{
+ uint32_t cur_fence;
+ struct drm_vmw_fence_wait_arg arg;
+ int ret;
+
+ vmw_printf("%s: fence = %lu\n", __FUNCTION__,
+ (unsigned long)fence);
+
+ cur_fence = vws->ioctl.fifo_map[SVGA_FIFO_FENCE];
+ vmw_printf("%s: Fence id read is 0x%08x\n", __FUNCTION__,
+ (unsigned int)cur_fence);
+
+ if ((cur_fence - fence) < (1 << 24))
+ return;
+
+ memset(&arg, 0, sizeof(arg));
+ arg.sequence = fence;
+
+ do {
+ ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_FENCE_WAIT, &arg,
+ sizeof(arg));
+ } while (ret == -ERESTART);
+}
+
+
+int
+vmw_ioctl_fence_finish(struct vmw_winsys_screen *vws,
+ uint32_t fence)
+{
+ assert(fence);
+
+ if(fence) {
+ if(vmw_ioctl_fence_signalled(vws, fence) != 0) {
+ vmw_ioctl_sync(vws, fence);
+ }
+ }
+
+ return 0;
+}
+
+
+boolean
+vmw_ioctl_init(struct vmw_winsys_screen *vws)
+{
+ struct drm_vmw_getparam_arg gp_arg;
+ int ret;
+
+ VMW_FUNC;
+
+ memset(&gp_arg, 0, sizeof(gp_arg));
+ gp_arg.param = DRM_VMW_PARAM_FIFO_OFFSET;
+ ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GET_PARAM,
+ &gp_arg, sizeof(gp_arg));
+
+ if (ret) {
+ debug_printf("GET_PARAM on %d returned %d: %s\n",
+ vws->ioctl.drm_fd, ret, strerror(-ret));
+ goto out_err1;
+ }
+
+ vmw_printf("Offset to map is 0x%08llx\n",
+ (unsigned long long)gp_arg.value);
+
+ vws->ioctl.fifo_map = vmw_ioctl_fifo_map(vws, gp_arg.value);
+ if (vws->ioctl.fifo_map == NULL)
+ goto out_err1;
+
+ vmw_printf("%s OK\n", __FUNCTION__);
+ return TRUE;
+
+ out_err1:
+ debug_printf("%s Failed\n", __FUNCTION__);
+ return FALSE;
+}
+
+
+
+void
+vmw_ioctl_cleanup(struct vmw_winsys_screen *vws)
+{
+ VMW_FUNC;
+
+ vmw_ioctl_fifo_unmap(vws, (void *)vws->ioctl.fifo_map);
+}
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_screen_pools.c b/src/gallium/winsys/drm/vmware/core/vmw_screen_pools.c
new file mode 100644
index 00000000000..b1c24b0cb6a
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/core/vmw_screen_pools.c
@@ -0,0 +1,79 @@
+/**********************************************************
+ * Copyright 2009 VMware, Inc. 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, 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 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 "vmw_screen.h"
+
+#include "vmw_buffer.h"
+#include "vmw_fence.h"
+
+#include "pipebuffer/pb_buffer.h"
+#include "pipebuffer/pb_bufmgr.h"
+
+void
+vmw_pools_cleanup(struct vmw_winsys_screen *vws)
+{
+ if(vws->pools.gmr_fenced)
+ vws->pools.gmr_fenced->destroy(vws->pools.gmr_fenced);
+
+ /* gmr_mm pool is already destroyed above */
+
+ if(vws->pools.gmr)
+ vws->pools.gmr->destroy(vws->pools.gmr);
+}
+
+
+boolean
+vmw_pools_init(struct vmw_winsys_screen *vws)
+{
+ vws->pools.gmr = vmw_gmr_bufmgr_create(vws);
+ if(!vws->pools.gmr)
+ goto error;
+
+ vws->pools.gmr_mm = mm_bufmgr_create(vws->pools.gmr,
+ 16*1024*1024,
+ 12 /* 4096 alignment */);
+ if(!vws->pools.gmr_mm)
+ goto error;
+
+ vws->pools.gmr_fenced = fenced_bufmgr_create(
+ vws->pools.gmr_mm,
+ vmw_fence_ops_create(vws));
+
+#ifdef DEBUG
+ vws->pools.gmr_fenced = pb_debug_manager_create(vws->pools.gmr_fenced,
+ 4096,
+ 4096);
+#endif
+ if(!vws->pools.gmr_fenced)
+ goto error;
+
+ return TRUE;
+
+error:
+ vmw_pools_cleanup(vws);
+ return FALSE;
+}
+
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_screen_svga.c b/src/gallium/winsys/drm/vmware/core/vmw_screen_svga.c
new file mode 100644
index 00000000000..d7d008859b3
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/core/vmw_screen_svga.c
@@ -0,0 +1,295 @@
+/**********************************************************
+ * Copyright 2009 VMware, Inc. 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, 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 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.
+ *
+ **********************************************************/
+
+/**
+ * @file
+ * This file implements the SVGA interface into this winsys, defined
+ * in drivers/svga/svga_winsys.h.
+ *
+ * @author Keith Whitwell
+ * @author Jose Fonseca
+ */
+
+
+#include "svga_cmd.h"
+#include "svga3d_caps.h"
+
+#include "pipe/p_inlines.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+#include "pipebuffer/pb_buffer.h"
+#include "pipebuffer/pb_bufmgr.h"
+#include "svga_winsys.h"
+#include "vmw_context.h"
+#include "vmw_screen.h"
+#include "vmw_surface.h"
+#include "vmw_buffer.h"
+#include "vmw_fence.h"
+
+
+static struct svga_winsys_buffer *
+vmw_svga_winsys_buffer_create(struct svga_winsys_screen *sws,
+ unsigned alignment,
+ unsigned usage,
+ unsigned size)
+{
+ struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
+ struct pb_desc desc;
+ struct pb_manager *provider;
+ struct pb_buffer *buffer;
+
+ memset(&desc, 0, sizeof desc);
+ desc.alignment = alignment;
+ desc.usage = usage;
+
+ provider = vws->pools.gmr_fenced;
+
+ assert(provider);
+ buffer = provider->create_buffer(provider, size, &desc);
+ if(!buffer)
+ return NULL;
+
+ return vmw_svga_winsys_buffer(buffer);
+}
+
+
+static void *
+vmw_svga_winsys_buffer_map(struct svga_winsys_screen *sws,
+ struct svga_winsys_buffer *buf,
+ unsigned flags)
+{
+ (void)sws;
+ return pb_map(vmw_pb_buffer(buf), flags);
+}
+
+
+static void
+vmw_svga_winsys_buffer_unmap(struct svga_winsys_screen *sws,
+ struct svga_winsys_buffer *buf)
+{
+ (void)sws;
+ pb_unmap(vmw_pb_buffer(buf));
+}
+
+
+static void
+vmw_svga_winsys_buffer_destroy(struct svga_winsys_screen *sws,
+ struct svga_winsys_buffer *buf)
+{
+ struct pb_buffer *pbuf = vmw_pb_buffer(buf);
+ (void)sws;
+ pb_reference(&pbuf, NULL);
+}
+
+
+static void
+vmw_svga_winsys_fence_reference(struct svga_winsys_screen *sws,
+ struct pipe_fence_handle **pdst,
+ struct pipe_fence_handle *src)
+{
+ (void)sws;
+ *pdst = src;
+}
+
+
+static int
+vmw_svga_winsys_fence_signalled(struct svga_winsys_screen *sws,
+ struct pipe_fence_handle *fence,
+ unsigned flag)
+{
+ struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
+ (void)flag;
+ return vmw_ioctl_fence_signalled(vws, vmw_fence(fence));
+}
+
+
+static int
+vmw_svga_winsys_fence_finish(struct svga_winsys_screen *sws,
+ struct pipe_fence_handle *fence,
+ unsigned flag)
+{
+ struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
+ (void)flag;
+ return vmw_ioctl_fence_finish(vws, vmw_fence(fence));
+}
+
+
+
+static struct svga_winsys_surface *
+vmw_svga_winsys_surface_create(struct svga_winsys_screen *sws,
+ SVGA3dSurfaceFlags flags,
+ SVGA3dSurfaceFormat format,
+ SVGA3dSize size,
+ uint32 numFaces,
+ uint32 numMipLevels)
+{
+ struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
+ struct vmw_svga_winsys_surface *surface;
+
+ surface = CALLOC_STRUCT(vmw_svga_winsys_surface);
+ if(!surface)
+ goto no_surface;
+
+ pipe_reference_init(&surface->refcnt, 1);
+ p_atomic_set(&surface->validated, 0);
+ surface->screen = vws;
+ surface->sid = vmw_ioctl_surface_create(vws,
+ flags, format, size,
+ numFaces, numMipLevels);
+ if(surface->sid == SVGA3D_INVALID_ID)
+ goto no_sid;
+
+ return svga_winsys_surface(surface);
+
+no_sid:
+ FREE(surface);
+no_surface:
+ return NULL;
+}
+
+
+static boolean
+vmw_svga_winsys_surface_is_flushed(struct svga_winsys_screen *sws,
+ struct svga_winsys_surface *surface)
+{
+ struct vmw_svga_winsys_surface *vsurf = vmw_svga_winsys_surface(surface);
+ return (p_atomic_read(&vsurf->validated) == 0);
+}
+
+
+static void
+vmw_svga_winsys_surface_ref(struct svga_winsys_screen *sws,
+ struct svga_winsys_surface **pDst,
+ struct svga_winsys_surface *src)
+{
+ struct vmw_svga_winsys_surface *d_vsurf = vmw_svga_winsys_surface(*pDst);
+ struct vmw_svga_winsys_surface *s_vsurf = vmw_svga_winsys_surface(src);
+
+ vmw_svga_winsys_surface_reference(&d_vsurf, s_vsurf);
+ *pDst = svga_winsys_surface(d_vsurf);
+}
+
+
+static void
+vmw_svga_winsys_destroy(struct svga_winsys_screen *sws)
+{
+ struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
+
+ vmw_winsys_destroy(vws);
+}
+
+
+static boolean
+vmw_svga_winsys_get_cap(struct svga_winsys_screen *sws,
+ SVGA3dDevCapIndex index,
+ SVGA3dDevCapResult *result)
+{
+ struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
+ const uint32 *capsBlock;
+ const SVGA3dCapsRecord *capsRecord = NULL;
+ uint32 offset;
+ const SVGA3dCapPair *capArray;
+ int numCaps, first, last;
+
+ if(!vws->ioctl.fifo_map)
+ return FALSE;
+
+ if(vws->ioctl.fifo_map[SVGA_FIFO_3D_HWVERSION] < SVGA3D_HWVERSION_WS6_B1)
+ return FALSE;
+
+ /*
+ * Search linearly through the caps block records for the specified type.
+ */
+ capsBlock = (const uint32 *)&vws->ioctl.fifo_map[SVGA_FIFO_3D_CAPS];
+ for (offset = 0; capsBlock[offset] != 0; offset += capsBlock[offset]) {
+ const SVGA3dCapsRecord *record;
+ assert(offset < SVGA_FIFO_3D_CAPS_SIZE);
+ record = (const SVGA3dCapsRecord *) (capsBlock + offset);
+ if ((record->header.type >= SVGA3DCAPS_RECORD_DEVCAPS_MIN) &&
+ (record->header.type <= SVGA3DCAPS_RECORD_DEVCAPS_MAX) &&
+ (!capsRecord || (record->header.type > capsRecord->header.type))) {
+ capsRecord = record;
+ }
+ }
+
+ if(!capsRecord)
+ return FALSE;
+
+ /*
+ * Calculate the number of caps from the size of the record.
+ */
+ capArray = (const SVGA3dCapPair *) capsRecord->data;
+ numCaps = (int) ((capsRecord->header.length * sizeof(uint32) -
+ sizeof capsRecord->header) / (2 * sizeof(uint32)));
+
+ /*
+ * Binary-search for the cap with the specified index.
+ */
+ for (first = 0, last = numCaps - 1; first <= last; ) {
+ int mid = (first + last) / 2;
+
+ if ((SVGA3dDevCapIndex) capArray[mid][0] == index) {
+ /*
+ * Found it.
+ */
+ result->u = capArray[mid][1];
+ return TRUE;
+ }
+
+ /*
+ * Divide and conquer.
+ */
+ if ((SVGA3dDevCapIndex) capArray[mid][0] > index) {
+ last = mid - 1;
+ } else {
+ first = mid + 1;
+ }
+ }
+
+ return FALSE;
+}
+
+
+boolean
+vmw_winsys_screen_init_svga(struct vmw_winsys_screen *vws)
+{
+ vws->base.destroy = vmw_svga_winsys_destroy;
+ vws->base.get_cap = vmw_svga_winsys_get_cap;
+ vws->base.context_create = vmw_svga_winsys_context_create;
+ vws->base.surface_create = vmw_svga_winsys_surface_create;
+ vws->base.surface_is_flushed = vmw_svga_winsys_surface_is_flushed;
+ vws->base.surface_reference = vmw_svga_winsys_surface_ref;
+ vws->base.buffer_create = vmw_svga_winsys_buffer_create;
+ vws->base.buffer_map = vmw_svga_winsys_buffer_map;
+ vws->base.buffer_unmap = vmw_svga_winsys_buffer_unmap;
+ vws->base.buffer_destroy = vmw_svga_winsys_buffer_destroy;
+ vws->base.fence_reference = vmw_svga_winsys_fence_reference;
+ vws->base.fence_signalled = vmw_svga_winsys_fence_signalled;
+ vws->base.fence_finish = vmw_svga_winsys_fence_finish;
+
+ return TRUE;
+}
+
+
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_surface.c b/src/gallium/winsys/drm/vmware/core/vmw_surface.c
new file mode 100644
index 00000000000..64eb32f8b94
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/core/vmw_surface.c
@@ -0,0 +1,61 @@
+/**********************************************************
+ * Copyright 2009 VMware, Inc. 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, 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 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 "svga_cmd.h"
+#include "util/u_debug.h"
+#include "util/u_memory.h"
+
+#include "vmw_surface.h"
+#include "vmw_screen.h"
+
+void
+vmw_svga_winsys_surface_reference(struct vmw_svga_winsys_surface **pdst,
+ struct vmw_svga_winsys_surface *src)
+{
+ struct pipe_reference *src_ref;
+ struct pipe_reference *dst_ref;
+ struct vmw_svga_winsys_surface *dst;
+
+ if(pdst == NULL || *pdst == src)
+ return;
+
+ dst = *pdst;
+
+ src_ref = src ? &src->refcnt : NULL;
+ dst_ref = dst ? &dst->refcnt : NULL;
+
+ if (pipe_reference(&dst_ref, src_ref)) {
+ vmw_ioctl_surface_destroy(dst->screen, dst->sid);
+#ifdef DEBUG
+ /* to detect dangling pointers */
+ assert(p_atomic_read(&dst->validated) == 0);
+ dst->sid = SVGA3D_INVALID_ID;
+#endif
+ FREE(dst);
+ }
+
+ *pdst = src;
+}
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_surface.h b/src/gallium/winsys/drm/vmware/core/vmw_surface.h
new file mode 100644
index 00000000000..340cc1532e0
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/core/vmw_surface.h
@@ -0,0 +1,79 @@
+/**********************************************************
+ * Copyright 2009 VMware, Inc. 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, 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 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.
+ *
+ **********************************************************/
+
+/**
+ * @file
+ * Surfaces for VMware SVGA winsys.
+ *
+ * @author Jose Fonseca <[email protected]>
+ */
+
+
+#ifndef VMW_SURFACE_H_
+#define VMW_SURFACE_H_
+
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_atomic.h"
+#include "pipe/p_refcnt.h"
+
+#define VMW_MAX_PRESENTS 3
+
+
+
+struct vmw_svga_winsys_surface
+{
+ struct pipe_atomic validated;
+ struct pipe_reference refcnt;
+
+ struct vmw_winsys_screen *screen;
+ uint32_t sid;
+
+ /* FIXME: make this thread safe */
+ unsigned next_present_no;
+ uint32_t present_fences[VMW_MAX_PRESENTS];
+};
+
+
+static INLINE struct svga_winsys_surface *
+svga_winsys_surface(struct vmw_svga_winsys_surface *surf)
+{
+ assert(!surf || surf->sid != SVGA3D_INVALID_ID);
+ return (struct svga_winsys_surface *)surf;
+}
+
+
+static INLINE struct vmw_svga_winsys_surface *
+vmw_svga_winsys_surface(struct svga_winsys_surface *surf)
+{
+ return (struct vmw_svga_winsys_surface *)surf;
+}
+
+
+void
+vmw_svga_winsys_surface_reference(struct vmw_svga_winsys_surface **pdst,
+ struct vmw_svga_winsys_surface *src);
+
+#endif /* VMW_SURFACE_H_ */
diff --git a/src/gallium/winsys/drm/vmware/core/vmwgfx_drm.h b/src/gallium/winsys/drm/vmware/core/vmwgfx_drm.h
new file mode 100644
index 00000000000..6705dd42897
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/core/vmwgfx_drm.h
@@ -0,0 +1,442 @@
+/**************************************************************************
+ *
+ * Copyright © 2009 VMware, Inc., Palo Alto, CA., 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 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
+ * 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.
+ *
+ **************************************************************************/
+
+#ifndef _VMWGFX_DRM_H_
+#define _VMWGFX_DRM_H_
+
+#define DRM_VMW_MAX_SURFACE_FACES 6
+#define DRM_VMW_MAX_MIP_LEVELS 24
+
+#define DRM_VMW_EXT_NAME_LEN 128
+
+#define DRM_VMW_GET_PARAM 1
+#define DRM_VMW_EXTENSION 2
+#define DRM_VMW_CREATE_CONTEXT 3
+#define DRM_VMW_UNREF_CONTEXT 4
+#define DRM_VMW_CREATE_SURFACE 5
+#define DRM_VMW_UNREF_SURFACE 6
+#define DRM_VMW_REF_SURFACE 7
+#define DRM_VMW_EXECBUF 8
+#define DRM_VMW_ALLOC_DMABUF 9
+#define DRM_VMW_UNREF_DMABUF 10
+#define DRM_VMW_FIFO_DEBUG 11
+#define DRM_VMW_FENCE_WAIT 12
+
+
+/*************************************************************************/
+/**
+ * DRM_VMW_GET_PARAM - get device information.
+ *
+ * Currently we support only one parameter:
+ *
+ * DRM_VMW_PARAM_FIFO_OFFSET:
+ * Offset to use to map the first page of the FIFO read-only.
+ * The fifo is mapped using the mmap() system call on the drm device.
+ */
+
+#define DRM_VMW_PARAM_FIFO_OFFSET 0
+
+/**
+ * struct drm_vmw_getparam_arg
+ *
+ * @value: Returned value. //Out
+ * @param: Parameter to query. //In.
+ *
+ * Argument to the DRM_VMW_GET_PARAM Ioctl.
+ */
+
+struct drm_vmw_getparam_arg {
+ uint64_t value;
+ uint32_t param;
+ uint32_t pad64;
+};
+
+/*************************************************************************/
+/**
+ * DRM_VMW_EXTENSION - Query device extensions.
+ */
+
+/**
+ * struct drm_vmw_extension_rep
+ *
+ * @exists: The queried extension exists.
+ * @driver_ioctl_offset: Ioctl number of the first ioctl in the extension.
+ * @driver_sarea_offset: Offset to any space in the DRI SAREA
+ * used by the extension.
+ * @major: Major version number of the extension.
+ * @minor: Minor version number of the extension.
+ * @pl: Patch level version number of the extension.
+ *
+ * Output argument to the DRM_VMW_EXTENSION Ioctl.
+ */
+
+struct drm_vmw_extension_rep {
+ int32_t exists;
+ uint32_t driver_ioctl_offset;
+ uint32_t driver_sarea_offset;
+ uint32_t major;
+ uint32_t minor;
+ uint32_t pl;
+ uint32_t pad64;
+};
+
+/**
+ * union drm_vmw_extension_arg
+ *
+ * @extension - Ascii name of the extension to be queried. //In
+ * @rep - Reply as defined above. //Out
+ *
+ * Argument to the DRM_VMW_EXTENSION Ioctl.
+ */
+
+union drm_vmw_extension_arg {
+ char extension[DRM_VMW_EXT_NAME_LEN];
+ struct drm_vmw_extension_rep rep;
+};
+
+/*************************************************************************/
+/**
+ * DRM_VMW_CREATE_CONTEXT - Create a host context.
+ *
+ * Allocates a device unique context id, and queues a create context command
+ * for the host. Does not wait for host completion.
+ */
+
+/**
+ * struct drm_vmw_context_arg
+ *
+ * @cid: Device unique context ID.
+ *
+ * Output argument to the DRM_VMW_CREATE_CONTEXT Ioctl.
+ * Input argument to the DRM_VMW_UNREF_CONTEXT Ioctl.
+ */
+
+struct drm_vmw_context_arg {
+ int32_t cid;
+ uint32_t pad64;
+};
+
+/*************************************************************************/
+/**
+ * DRM_VMW_UNREF_CONTEXT - Create a host context.
+ *
+ * Frees a global context id, and queues a destroy host command for the host.
+ * Does not wait for host completion. The context ID can be used directly
+ * in the command stream and shows up as the same context ID on the host.
+ */
+
+/*************************************************************************/
+/**
+ * DRM_VMW_CREATE_SURFACE - Create a host suface.
+ *
+ * Allocates a device unique surface id, and queues a create surface command
+ * for the host. Does not wait for host completion. The surface ID can be
+ * used directly in the command stream and shows up as the same surface
+ * ID on the host.
+ */
+
+/**
+ * struct drm_wmv_surface_create_req
+ *
+ * @flags: Surface flags as understood by the host.
+ * @format: Surface format as understood by the host.
+ * @mip_levels: Number of mip levels for each face.
+ * An unused face should have 0 encoded.
+ * @size_addr: Address of a user-space array of sruct drm_vmw_size
+ * cast to an uint64_t for 32-64 bit compatibility.
+ * The size of the array should equal the total number of mipmap levels.
+ * @shareable: Boolean whether other clients (as identified by file descriptors)
+ * may reference this surface.
+ *
+ * Input data to the DRM_VMW_CREATE_SURFACE Ioctl.
+ * Output data from the DRM_VMW_REF_SURFACE Ioctl.
+ */
+
+struct drm_vmw_surface_create_req {
+ uint32_t flags;
+ uint32_t format;
+ uint32_t mip_levels[DRM_VMW_MAX_SURFACE_FACES];
+ uint64_t size_addr;
+ int32_t shareable;
+ uint32_t pad64;
+};
+
+/**
+ * struct drm_wmv_surface_arg
+ *
+ * @sid: Surface id of created surface or surface to destroy or reference.
+ *
+ * Output data from the DRM_VMW_CREATE_SURFACE Ioctl.
+ * Input argument to the DRM_VMW_UNREF_SURFACE Ioctl.
+ * Input argument to the DRM_VMW_REF_SURFACE Ioctl.
+ */
+
+struct drm_vmw_surface_arg {
+ int32_t sid;
+ uint32_t pad64;
+};
+
+/**
+ * struct drm_vmw_size ioctl.
+ *
+ * @width - mip level width
+ * @height - mip level height
+ * @depth - mip level depth
+ *
+ * Description of a mip level.
+ * Input data to the DRM_WMW_CREATE_SURFACE Ioctl.
+ */
+
+struct drm_vmw_size {
+ uint32_t width;
+ uint32_t height;
+ uint32_t depth;
+ uint32_t pad64;
+};
+
+/**
+ * union drm_vmw_surface_create_arg
+ *
+ * @rep: Output data as described above.
+ * @req: Input data as described above.
+ *
+ * Argument to the DRM_VMW_CREATE_SURFACE Ioctl.
+ */
+
+union drm_vmw_surface_create_arg {
+ struct drm_vmw_surface_arg rep;
+ struct drm_vmw_surface_create_req req;
+};
+
+/*************************************************************************/
+/**
+ * DRM_VMW_REF_SURFACE - Reference a host surface.
+ *
+ * Puts a reference on a host surface with a give sid, as previously
+ * returned by the DRM_VMW_CREATE_SURFACE ioctl.
+ * A reference will make sure the surface isn't destroyed while we hold
+ * it and will allow the calling client to use the surface ID in the command
+ * stream.
+ *
+ * On successful return, the Ioctl returns the surface information given
+ * in the DRM_VMW_CREATE_SURFACE ioctl.
+ */
+
+/**
+ * union drm_vmw_surface_reference_arg
+ *
+ * @rep: Output data as described above.
+ * @req: Input data as described above.
+ *
+ * Argument to the DRM_VMW_REF_SURFACE Ioctl.
+ */
+
+union drm_vmw_surface_reference_arg {
+ struct drm_vmw_surface_create_req rep;
+ struct drm_vmw_surface_arg req;
+};
+
+/*************************************************************************/
+/**
+ * DRM_VMW_UNREF_SURFACE - Unreference a host surface.
+ *
+ * Clear a reference previously put on a host surface.
+ * When all references are gone, including the one implicitly placed
+ * on creation,
+ * a destroy surface command will be queued for the host.
+ * Does not wait for completion.
+ */
+
+/*************************************************************************/
+/**
+ * DRM_VMW_EXECBUF
+ *
+ * Submit a command buffer for execution on the host, and return a
+ * fence sequence that when signaled, indicates that the command buffer has
+ * executed.
+ */
+
+/**
+ * struct drm_vmw_execbuf_arg
+ *
+ * @commands: User-space address of a command buffer cast to an uint64_t.
+ * @command-size: Size in bytes of the command buffer.
+ * @fence_rep: User-space address of a struct drm_vmw_fence_rep cast to an
+ * uint64_t.
+ *
+ * Argument to the DRM_VMW_EXECBUF Ioctl.
+ */
+
+struct drm_vmw_execbuf_arg {
+ uint64_t commands;
+ uint32_t command_size;
+ uint32_t pad64;
+ uint64_t fence_rep;
+};
+
+/**
+ * struct drm_vmw_fence_rep
+ *
+ * @fence_seq: Fence sequence associated with a command submission.
+ * @error: This member should've been set to -EFAULT on submission.
+ * The following actions should be take on completion:
+ * error == -EFAULT: Fence communication failed. The host is synchronized.
+ * Use the last fence id read from the FIFO fence register.
+ * error != 0 && error != -EFAULT:
+ * Fence submission failed. The host is synchronized. Use the fence_seq member.
+ * error == 0: All is OK, The host may not be synchronized.
+ * Use the fence_seq member.
+ *
+ * Input / Output data to the DRM_VMW_EXECBUF Ioctl.
+ */
+
+struct drm_vmw_fence_rep {
+ uint64_t fence_seq;
+ int32_t error;
+ uint32_t pad64;
+};
+
+/*************************************************************************/
+/**
+ * DRM_VMW_ALLOC_DMABUF
+ *
+ * Allocate a DMA buffer that is visible also to the host.
+ * NOTE: The buffer is
+ * identified by a handle and an offset, which are private to the guest, but
+ * useable in the command stream. The guest kernel may translate these
+ * and patch up the command stream accordingly. In the future, the offset may
+ * be zero at all times, or it may disappear from the interface before it is
+ * fixed.
+ *
+ * The DMA buffer may stay user-space mapped in the guest at all times,
+ * and is thus suitable for sub-allocation.
+ *
+ * DMA buffers are mapped using the mmap() syscall on the drm device.
+ */
+
+/**
+ * struct drm_vmw_alloc_dmabuf_req
+ *
+ * @size: Required minimum size of the buffer.
+ *
+ * Input data to the DRM_VMW_ALLOC_DMABUF Ioctl.
+ */
+
+struct drm_vmw_alloc_dmabuf_req {
+ uint32_t size;
+ uint32_t pad64;
+};
+
+/**
+ * struct drm_vmw_dmabuf_rep
+ *
+ * @map_handle: Offset to use in the mmap() call used to map the buffer.
+ * @handle: Handle unique to this buffer. Used for unreferencing.
+ * @cur_gmr_id: GMR id to use in the command stream when this buffer is
+ * referenced. See not above.
+ * @cur_gmr_offset: Offset to use in the command stream when this buffer is
+ * referenced. See note above.
+ *
+ * Output data from the DRM_VMW_ALLOC_DMABUF Ioctl.
+ */
+
+struct drm_vmw_dmabuf_rep {
+ uint64_t map_handle;
+ uint32_t handle;
+ uint32_t cur_gmr_id;
+ uint32_t cur_gmr_offset;
+ uint32_t pad64;
+};
+
+/**
+ * union drm_vmw_dmabuf_arg
+ *
+ * @req: Input data as described above.
+ * @rep: Output data as described above.
+ *
+ * Argument to the DRM_VMW_ALLOC_DMABUF Ioctl.
+ */
+
+union drm_vmw_alloc_dmabuf_arg {
+ struct drm_vmw_alloc_dmabuf_req req;
+ struct drm_vmw_dmabuf_rep rep;
+};
+
+/*************************************************************************/
+/**
+ * DRM_VMW_UNREF_DMABUF - Free a DMA buffer.
+ *
+ */
+
+/**
+ * struct drm_vmw_unref_dmabuf_arg
+ *
+ * @handle: Handle indicating what buffer to free. Obtained from the
+ * DRM_VMW_ALLOC_DMABUF Ioctl.
+ *
+ * Argument to the DRM_VMW_UNREF_DMABUF Ioctl.
+ */
+
+struct drm_vmw_unref_dmabuf_arg {
+ uint32_t handle;
+ uint32_t pad64;
+};
+
+/*************************************************************************/
+/**
+ * DRM_VMW_FIFO_DEBUG - Get last FIFO submission.
+ *
+ * This IOCTL copies the last FIFO submission directly out of the FIFO buffer.
+ */
+
+/**
+ * struct drm_vmw_fifo_debug_arg
+ *
+ * @debug_buffer: User space address of a debug_buffer cast to an uint64_t //In
+ * @debug_buffer_size: Size in bytes of debug buffer //In
+ * @used_size: Number of bytes copied to the buffer // Out
+ * @did_not_fit: Boolean indicating that the fifo contents did not fit. //Out
+ *
+ * Argument to the DRM_VMW_FIFO_DEBUG Ioctl.
+ */
+
+struct drm_vmw_fifo_debug_arg {
+ uint64_t debug_buffer;
+ uint32_t debug_buffer_size;
+ uint32_t used_size;
+ int32_t did_not_fit;
+ uint32_t pad64;
+};
+
+struct drm_vmw_fence_wait_arg {
+ uint64_t sequence;
+ uint64_t kernel_cookie;
+ int32_t cookie_valid;
+ int32_t pad64;
+};
+
+#endif
diff --git a/src/gallium/winsys/drm/vmware/dri/Makefile b/src/gallium/winsys/drm/vmware/dri/Makefile
new file mode 100644
index 00000000000..8a39e23da6d
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/dri/Makefile
@@ -0,0 +1,18 @@
+
+TOP = ../../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = vmwgfx_dri.so
+
+PIPE_DRIVERS = \
+ $(TOP)/src/gallium/state_trackers/dri/libdridrm.a \
+ $(TOP)/src/gallium/winsys/drm/vmware/core/libsvgadrm.a \
+ $(TOP)/src/gallium/drivers/trace/libtrace.a \
+ $(TOP)/src/gallium/drivers/svga/libsvga.a
+
+C_SOURCES = \
+ $(COMMON_GALLIUM_SOURCES)
+
+include ../../Makefile.template
+
+symlinks:
diff --git a/src/gallium/winsys/drm/vmware/dri/SConscript b/src/gallium/winsys/drm/vmware/dri/SConscript
new file mode 100644
index 00000000000..1019f577a5f
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/dri/SConscript
@@ -0,0 +1,62 @@
+import os
+import os.path
+
+Import('*')
+
+if env['platform'] == 'linux':
+
+ if env['dri']:
+ env = env.Clone()
+
+ sources = [
+ '#/src/mesa/drivers/dri/common/utils.c',
+ '#/src/mesa/drivers/dri/common/vblank.c',
+ '#/src/mesa/drivers/dri/common/dri_util.c',
+ '#/src/mesa/drivers/dri/common/xmlconfig.c',
+ ]
+
+
+ env.ParseConfig('pkg-config --cflags --libs libdrm')
+
+ env.Prepend(CPPPATH = [
+ '#/src/mesa/state_tracker',
+ '#/src/mesa/drivers/dri/common',
+ '#/src/mesa/main',
+ '#/src/mesa/glapi',
+ '#/src/mesa',
+ '#/include',
+ '#/src/gallium/drivers/svga',
+ '#/src/gallium/drivers/svga/include',
+ ])
+
+ env.Append(CPPDEFINES = [
+ 'HAVE_STDINT_H',
+ 'HAVE_SYS_TYPES_H',
+ ])
+
+ env.Append(CFLAGS = [
+ '-std=gnu99',
+ '-D_FILE_OFFSET_BITS=64',
+ ])
+
+ env.Prepend(LIBPATH = [
+ ])
+
+ env.Prepend(LIBS = [
+ trace,
+ st_dri,
+ svgadrm,
+ svga,
+ mesa,
+ auxiliaries,
+ ])
+
+ # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions
+ env.LoadableModule(
+ target ='vmwgfx_dri.so',
+ source = sources,
+ LIBS = env['LIBS'],
+ SHLIBPREFIX = '',
+ )
+
+
diff --git a/src/gallium/winsys/drm/vmware/egl/Makefile b/src/gallium/winsys/drm/vmware/egl/Makefile
new file mode 100644
index 00000000000..8e2980c318c
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/egl/Makefile
@@ -0,0 +1,18 @@
+
+TOP = ../../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = EGL_svga.so
+
+PIPE_DRIVERS = \
+ $(TOP)/src/gallium/state_trackers/egl/libegldrm.a \
+ $(TOP)/src/gallium/winsys/drm/vmware/core/libsvgadrm.a \
+ $(TOP)/src/gallium/drivers/trace/libtrace.a \
+ $(TOP)/src/gallium/drivers/svga/libsvga.a
+
+C_SOURCES = \
+ $(COMMON_GALLIUM_SOURCES)
+
+include ../../Makefile.template
+
+symlinks:
diff --git a/src/gallium/winsys/drm/vmware/xorg/Makefile b/src/gallium/winsys/drm/vmware/xorg/Makefile
new file mode 100644
index 00000000000..48a9b08aa76
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/xorg/Makefile
@@ -0,0 +1,63 @@
+TARGET = vmwgfx_drv.so
+CFILES = $(wildcard ./*.c)
+OBJECTS = $(patsubst ./%.c,./%.o,$(CFILES))
+TOP = ../../../../../..
+
+include $(TOP)/configs/current
+
+INCLUDES = \
+ $(shell pkg-config --cflags-only-I pixman-1 xorg-server libdrm xproto) \
+ -I$(TOP)/src/gallium/include \
+ -I$(TOP)/src/gallium/drivers \
+ -I$(TOP)/src/gallium/auxiliary \
+ -I$(TOP)/src/gallium
+
+LIBS = \
+ $(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \
+ $(TOP)/src/gallium/winsys/drm/vmware/core/libsvgadrm.a \
+ $(TOP)/src/gallium/drivers/trace/libtrace.a \
+ $(TOP)/src/gallium/drivers/svga/libsvga.a \
+ $(GALLIUM_AUXILIARIES)
+
+LINKS = \
+ $(shell pkg-config --libs --silence-errors libkms) \
+ $(shell pkg-config --libs libdrm)
+
+DRIVER_DEFINES = \
+ -DHAVE_CONFIG_H
+
+TARGET_STAGING = $(TOP)/$(LIB_DIR)/gallium/$(TARGET)
+
+#############################################
+
+
+
+all default: $(TARGET) $(TARGET_STAGING)
+
+$(TARGET): $(OBJECTS) Makefile $(LIBS)
+ $(MKLIB) -noprefix -o $@ $(OBJECTS) $(LIBS) $(LINKS)
+
+$(TOP)/$(LIB_DIR)/gallium:
+ mkdir -p $@
+
+$(TARGET_STAGING): $(TARGET) $(TOP)/$(LIB_DIR)/gallium
+ $(INSTALL) $(TARGET) $(TOP)/$(LIB_DIR)/gallium
+
+clean:
+ rm -rf $(OBJECTS) $(TARGET)
+
+install:
+ $(INSTALL) -d $(DESTDIR)/$(XORG_DRIVER_INSTALL_DIR)
+ $(MINSTALL) -m 755 $(TARGET) $(DESTDIR)/$(XORG_DRIVER_INSTALL_DIR)
+
+
+##############################################
+
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCLUDES) $(DRIVER_DEFINES) $< -o $@
+
+
+##############################################
+
+.PHONY = all clean install
diff --git a/src/gallium/winsys/drm/vmware/xorg/SConscript b/src/gallium/winsys/drm/vmware/xorg/SConscript
new file mode 100644
index 00000000000..ff7b2ed34ed
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/xorg/SConscript
@@ -0,0 +1,54 @@
+import os.path
+
+Import('*')
+
+if env['platform'] == 'linux':
+
+ env = env.Clone()
+
+ env.ParseConfig('pkg-config --cflags --libs libdrm xorg-server')
+
+ env.Prepend(CPPPATH = [
+ '#/include',
+ '#/src/gallium',
+ '#/src/mesa',
+ '#/src/gallium/drivers/svga',
+ '#/src/gallium/drivers/svga/include',
+ ])
+
+ env.Append(CPPDEFINES = [
+ ])
+
+ if env['gcc']:
+ env.Append(CPPDEFINES = [
+ 'HAVE_STDINT_H',
+ 'HAVE_SYS_TYPES_H',
+ ])
+
+ env.Append(CFLAGS = [
+ '-std=gnu99',
+ '-D_FILE_OFFSET_BITS=64',
+ ])
+
+ env.Prepend(LIBPATH = [
+ ])
+
+ env.Prepend(LIBS = [
+ trace,
+ st_xorg,
+ svgadrm,
+ svga,
+ auxiliaries,
+ ])
+
+ sources = [
+ 'vmw_xorg.c',
+ ]
+
+ # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions
+ env.LoadableModule(
+ target ='vmwgfx_drv.so',
+ source = sources,
+ LIBS = env['LIBS'],
+ SHLIBPREFIX = '',
+ )
diff --git a/src/gallium/winsys/drm/vmware/xorg/vmw_xorg.c b/src/gallium/winsys/drm/vmware/xorg/vmw_xorg.c
new file mode 100644
index 00000000000..3acc110ae79
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/xorg/vmw_xorg.c
@@ -0,0 +1,150 @@
+/**********************************************************
+ * Copyright 2008-2009 VMware, Inc. 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, 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 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.
+ *
+ **********************************************************/
+
+/**
+ * @file
+ * Glue file for Xorg State Tracker.
+ *
+ * @author Alan Hourihane <[email protected]>
+ * @author Jakob Bornecrantz <[email protected]>
+ */
+
+#include "state_trackers/xorg/xorg_winsys.h"
+
+static void vmw_xorg_identify(int flags);
+static Bool vmw_xorg_pci_probe(DriverPtr driver,
+ int entity_num,
+ struct pci_device *device,
+ intptr_t match_data);
+
+static const struct pci_id_match vmw_xorg_device_match[] = {
+ {0x15ad, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0},
+};
+
+static SymTabRec vmw_xorg_chipsets[] = {
+ {PCI_MATCH_ANY, "VMware SVGA Device"},
+ {-1, NULL}
+};
+
+static PciChipsets vmw_xorg_pci_devices[] = {
+ {PCI_MATCH_ANY, PCI_MATCH_ANY, NULL},
+ {-1, -1, NULL}
+};
+
+static XF86ModuleVersionInfo vmw_xorg_version = {
+ "vmwgfx",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XORG_VERSION_CURRENT,
+ 0, 1, 0, /* major, minor, patch */
+ ABI_CLASS_VIDEODRV,
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0, 0, 0, 0}
+};
+
+/*
+ * Xorg driver exported structures
+ */
+
+_X_EXPORT DriverRec vmwgfx = {
+ 1,
+ "vmwgfx",
+ vmw_xorg_identify,
+ NULL,
+ xorg_tracker_available_options,
+ NULL,
+ 0,
+ NULL,
+ vmw_xorg_device_match,
+ vmw_xorg_pci_probe
+};
+
+static MODULESETUPPROTO(vmw_xorg_setup);
+
+_X_EXPORT XF86ModuleData vmwgfxModuleData = {
+ &vmw_xorg_version,
+ vmw_xorg_setup,
+ NULL
+};
+
+/*
+ * Xorg driver functions
+ */
+
+static pointer
+vmw_xorg_setup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = 0;
+
+ /* This module should be loaded only once, but check to be sure.
+ */
+ if (!setupDone) {
+ setupDone = 1;
+ xf86AddDriver(&vmwgfx, module, HaveDriverFuncs);
+
+ /*
+ * The return value must be non-NULL on success even though there
+ * is no TearDownProc.
+ */
+ return (pointer) 1;
+ } else {
+ if (errmaj)
+ *errmaj = LDR_ONCEONLY;
+ return NULL;
+ }
+}
+
+static void
+vmw_xorg_identify(int flags)
+{
+ xf86PrintChipsets("vmwgfx", "Driver for VMware SVGA device",
+ vmw_xorg_chipsets);
+}
+
+static Bool
+vmw_xorg_pci_probe(DriverPtr driver,
+ int entity_num, struct pci_device *device, intptr_t match_data)
+{
+ ScrnInfoPtr scrn = NULL;
+ EntityInfoPtr entity;
+
+ scrn = xf86ConfigPciEntity(scrn, 0, entity_num, vmw_xorg_pci_devices,
+ NULL, NULL, NULL, NULL, NULL);
+ if (scrn != NULL) {
+ scrn->driverVersion = 1;
+ scrn->driverName = "vmwgfx";
+ scrn->name = "vmwgfx";
+ scrn->Probe = NULL;
+
+ entity = xf86GetEntityInfo(entity_num);
+
+ /* Use all the functions from the xorg tracker */
+ xorg_tracker_set_functions(scrn);
+ }
+ return scrn != NULL;
+}