diff options
Diffstat (limited to 'src/gallium/winsys')
77 files changed, 6215 insertions, 1978 deletions
diff --git a/src/gallium/winsys/drm/SConscript b/src/gallium/winsys/drm/SConscript index a9e9f2682a..9f7b383d2d 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/intel/dri/Makefile b/src/gallium/winsys/drm/intel/dri/Makefile index 5e212b62a4..c0ecd9680e 100644 --- a/src/gallium/winsys/drm/intel/dri/Makefile +++ b/src/gallium/winsys/drm/intel/dri/Makefile @@ -9,7 +9,7 @@ PIPE_DRIVERS = \ $(TOP)/src/gallium/drivers/trace/libtrace.a \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ $(TOP)/src/gallium/drivers/identity/libidentity.a \ - $(TOP)/src/gallium/drivers/i915simple/libi915simple.a + $(TOP)/src/gallium/drivers/i915/libi915.a DRIVER_SOURCES = diff --git a/src/gallium/winsys/drm/intel/dri/SConscript b/src/gallium/winsys/drm/intel/dri/SConscript index f973811072..b1b654d9f8 100644 --- a/src/gallium/winsys/drm/intel/dri/SConscript +++ b/src/gallium/winsys/drm/intel/dri/SConscript @@ -8,7 +8,7 @@ drivers = [ st_dri, inteldrm, softpipe, - i915simple, + i915, trace, ] diff --git a/src/gallium/winsys/drm/intel/egl/Makefile b/src/gallium/winsys/drm/intel/egl/Makefile index 490baded66..1397e9f729 100644 --- a/src/gallium/winsys/drm/intel/egl/Makefile +++ b/src/gallium/winsys/drm/intel/egl/Makefile @@ -9,7 +9,7 @@ PIPE_DRIVERS = \ $(GALLIUMDIR)/winsys/drm/intel/gem/libinteldrm.a \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ $(TOP)/src/gallium/drivers/trace/libtrace.a \ - $(TOP)/src/gallium/drivers/i915simple/libi915simple.a + $(TOP)/src/gallium/drivers/i915/libi915.a DRIVER_SOURCES = diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_api.c b/src/gallium/winsys/drm/intel/gem/intel_drm_api.c index 4c5a1d2ea8..9ed570ff6e 100644 --- a/src/gallium/winsys/drm/intel/gem/intel_drm_api.c +++ b/src/gallium/winsys/drm/intel/gem/intel_drm_api.c @@ -4,9 +4,10 @@ #include "intel_drm_winsys.h" #include "util/u_memory.h" -#include "i915simple/i915_context.h" -#include "i915simple/i915_screen.h" +#include "i915/i915_context.h" +#include "i915/i915_screen.h" +#include "trace/tr_drm.h" /* * Helper functions @@ -40,6 +41,7 @@ intel_drm_buffer_from_handle(struct intel_drm_winsys *idws, const char* name, unsigned handle) { struct intel_drm_buffer *buf = CALLOC_STRUCT(intel_drm_buffer); + uint32_t tile = 0, swizzle = 0; if (!buf) return NULL; @@ -52,6 +54,10 @@ intel_drm_buffer_from_handle(struct intel_drm_winsys *idws, if (!buf->bo) goto err; + drm_intel_bo_get_tiling(buf->bo, &tile, &swizzle); + if (tile != INTEL_TILE_NONE) + buf->map_gtt = TRUE; + return (struct intel_buffer *)buf; err: @@ -166,6 +172,7 @@ intel_drm_create_screen(struct drm_api *api, int drmFD, idws->base.destroy = intel_drm_winsys_destroy; idws->pools.gem = drm_intel_bufmgr_gem_init(idws->fd, idws->max_batch_size); + drm_intel_bufmgr_gem_enable_reuse(idws->pools.gem); idws->softpipe = FALSE; idws->dump_cmd = debug_get_bool_option("INTEL_DUMP_CMD", FALSE); @@ -198,5 +205,5 @@ struct drm_api intel_drm_api = struct drm_api * drm_api_create() { - return &intel_drm_api; + return trace_drm_create(&intel_drm_api); } diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_batchbuffer.c b/src/gallium/winsys/drm/intel/gem/intel_drm_batchbuffer.c index ebd1b607b7..5b4dafc8e4 100644 --- a/src/gallium/winsys/drm/intel/gem/intel_drm_batchbuffer.c +++ b/src/gallium/winsys/drm/intel/gem/intel_drm_batchbuffer.c @@ -14,6 +14,8 @@ #undef INTEL_RUN_SYNC #undef INTEL_MAP_BATCHBUFFER +#undef INTEL_MAP_GTT +#define INTEL_ALWAYS_FLUSH struct intel_drm_batchbuffer { @@ -34,6 +36,7 @@ static void intel_drm_batchbuffer_reset(struct intel_drm_batchbuffer *batch) { struct intel_drm_winsys *idws = intel_drm_winsys(batch->base.iws); + int ret; if (batch->bo) drm_intel_bo_unreference(batch->bo); @@ -43,8 +46,15 @@ intel_drm_batchbuffer_reset(struct intel_drm_batchbuffer *batch) 4096); #ifdef INTEL_MAP_BATCHBUFFER - drm_intel_bo_map(batch->bo, TRUE); +#ifdef INTEL_MAP_GTT + ret = drm_intel_gem_bo_map_gtt(batch->bo); +#else + ret = drm_intel_bo_map(batch->bo, TRUE); +#endif + assert(ret == 0); batch->base.map = batch->bo->virtual; +#else + (void)ret; #endif memset(batch->base.map, 0, batch->actual_size); @@ -148,24 +158,29 @@ intel_drm_batchbuffer_flush(struct intel_batchbuffer *ibatch, used = batch->base.ptr - batch->base.map; assert((used & 3) == 0); - if (used & 4) { - // MI_FLUSH | FLUSH_MAP_CACHE; - intel_batchbuffer_dword(ibatch, (0x0<<29)|(0x4<<23)|(1<<0)); - // MI_NOOP - intel_batchbuffer_dword(ibatch, (0x0<<29)|(0x0<<23)); - // MI_BATCH_BUFFER_END; - intel_batchbuffer_dword(ibatch, (0x0<<29)|(0xA<<23)); - } else { - //MI_FLUSH | FLUSH_MAP_CACHE; - intel_batchbuffer_dword(ibatch, (0x0<<29)|(0x4<<23)|(1<<0)); - // MI_BATCH_BUFFER_END; - intel_batchbuffer_dword(ibatch, (0x0<<29)|(0xA<<23)); + +#ifdef INTEL_ALWAYS_FLUSH + /* MI_FLUSH | FLUSH_MAP_CACHE */ + intel_batchbuffer_dword(ibatch, (0x4<<23)|(1<<0)); + used += 4; +#endif + + if ((used & 4) == 0) { + /* MI_NOOP */ + intel_batchbuffer_dword(ibatch, 0); } + /* MI_BATCH_BUFFER_END */ + intel_batchbuffer_dword(ibatch, (0xA<<23)); used = batch->base.ptr - batch->base.map; + assert((used & 4) == 0); #ifdef INTEL_MAP_BATCHBUFFER +#ifdef INTEL_MAP_GTT + drm_intel_gem_bo_unmap_gtt(batch->bo); +#else drm_intel_bo_unmap(batch->bo); +#endif #else drm_intel_bo_subdata(batch->bo, 0, used, batch->base.map); #endif diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_buffer.c b/src/gallium/winsys/drm/intel/gem/intel_drm_buffer.c index 0030f915a3..ac4dd6e00e 100644 --- a/src/gallium/winsys/drm/intel/gem/intel_drm_buffer.c +++ b/src/gallium/winsys/drm/intel/gem/intel_drm_buffer.c @@ -58,11 +58,17 @@ intel_drm_buffer_set_fence_reg(struct intel_winsys *iws, unsigned stride, enum intel_buffer_tile tile) { + struct intel_drm_buffer *buf = intel_drm_buffer(buffer); assert(I915_TILING_NONE == INTEL_TILE_NONE); assert(I915_TILING_X == INTEL_TILE_X); assert(I915_TILING_Y == INTEL_TILE_Y); - return drm_intel_bo_set_tiling(intel_bo(buffer), &tile, stride); + if (tile != INTEL_TILE_NONE) { + assert(buf->map_count == 0); + buf->map_gtt = TRUE; + } + + return drm_intel_bo_set_tiling(buf->bo, &tile, stride); } static void * @@ -113,9 +119,9 @@ intel_drm_buffer_unmap(struct intel_winsys *iws, static int intel_drm_buffer_write(struct intel_winsys *iws, struct intel_buffer *buffer, - const void *data, + size_t offset, size_t size, - size_t offset) + const void *data) { struct intel_drm_buffer *buf = intel_drm_buffer(buffer); diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_fence.c b/src/gallium/winsys/drm/intel/gem/intel_drm_fence.c index e70bfe7b44..e8b58742ab 100644 --- a/src/gallium/winsys/drm/intel/gem/intel_drm_fence.c +++ b/src/gallium/winsys/drm/intel/gem/intel_drm_fence.c @@ -39,11 +39,12 @@ intel_drm_fence_reference(struct intel_winsys *iws, struct intel_drm_fence *old = (struct intel_drm_fence *)*ptr; struct intel_drm_fence *f = (struct intel_drm_fence *)fence; - if (pipe_reference((struct pipe_reference**)ptr, &f->reference)) { + if (pipe_reference(&((struct intel_drm_fence *)(*ptr))->reference, &f->reference)) { if (old->bo) drm_intel_bo_unreference(old->bo); FREE(old); } + *ptr = fence; } static int diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_winsys.h b/src/gallium/winsys/drm/intel/gem/intel_drm_winsys.h index 415c45feea..b4a60563ef 100644 --- a/src/gallium/winsys/drm/intel/gem/intel_drm_winsys.h +++ b/src/gallium/winsys/drm/intel/gem/intel_drm_winsys.h @@ -2,7 +2,7 @@ #ifndef INTEL_DRM_WINSYS_H #define INTEL_DRM_WINSYS_H -#include "i915simple/intel_batchbuffer.h" +#include "i915/intel_batchbuffer.h" #include "drm.h" #include "intel_bufmgr.h" diff --git a/src/gallium/winsys/drm/intel/xorg/Makefile b/src/gallium/winsys/drm/intel/xorg/Makefile index 9e56853b02..14c2462524 100644 --- a/src/gallium/winsys/drm/intel/xorg/Makefile +++ b/src/gallium/winsys/drm/intel/xorg/Makefile @@ -18,7 +18,7 @@ INCLUDES = \ LIBS = \ $(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \ $(TOP)/src/gallium/winsys/drm/intel/gem/libinteldrm.a \ - $(TOP)/src/gallium/drivers/i915simple/libi915simple.a \ + $(TOP)/src/gallium/drivers/i915/libi915.a \ $(TOP)/src/gallium/drivers/trace/libtrace.a \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ $(GALLIUM_AUXILIARIES) 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 091cbbcfed..8d95826c9a 100644 --- a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c +++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c @@ -21,15 +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; - pf_get_block(tmpl.format, &tmpl.block); + tmpl.width0 = width; + tmpl.height0 = height; pt = api->texture_from_shared_handle(api, pscreen, &tmpl, "front buffer", pitch, handle); @@ -112,7 +110,7 @@ nouveau_drm_create_screen(struct drm_api *api, int fd, return NULL; } - if (arg->mode == DRM_CREATE_DRI1) { + if (arg && arg->mode == DRM_CREATE_DRI1) { struct nouveau_dri *nvdri = dri1->ddx_info; enum pipe_format format; @@ -197,6 +195,7 @@ nouveau_drm_pt_from_name(struct drm_api *api, struct pipe_screen *pscreen, unsigned stride, unsigned handle) { struct nouveau_device *dev = nouveau_screen(pscreen)->device; + struct pipe_texture *pt; struct pipe_buffer *pb; int ret; @@ -218,7 +217,9 @@ nouveau_drm_pt_from_name(struct drm_api *api, struct pipe_screen *pscreen, pb->usage = PIPE_BUFFER_USAGE_GPU_READ_WRITE | PIPE_BUFFER_USAGE_CPU_READ_WRITE; pb->size = nouveau_bo(pb)->size; - return pscreen->texture_blanket(pscreen, templ, &stride, pb); + pt = pscreen->texture_blanket(pscreen, templ, &stride, pb); + pipe_buffer_reference(&pb, NULL); + return pt; } static boolean @@ -245,6 +246,7 @@ nouveau_drm_handle_from_pt(struct drm_api *api, struct pipe_screen *pscreen, return false; *handle = mt->bo->handle; + *stride = pf_get_stride(mt->base.format, mt->base.width0); return true; } diff --git a/src/gallium/winsys/drm/nouveau/xorg/Makefile b/src/gallium/winsys/drm/nouveau/xorg/Makefile new file mode 100644 index 0000000000..f0d3b337e8 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/xorg/Makefile @@ -0,0 +1,61 @@ +TARGET = modesetting_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../gem \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/src/gallium/auxiliary \ + -I$(TOP)/src/mesa \ + -I$(TOP)/include \ + -I$(TOP)/src/egl/main + +LIBS = \ + $(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \ + $(TOP)/src/gallium/winsys/drm/nouveau/drm/libnouveaudrm.a \ + $(TOP)/src/gallium/drivers/nv04/libnv04.a \ + $(TOP)/src/gallium/drivers/nv10/libnv10.a \ + $(TOP)/src/gallium/drivers/nv20/libnv20.a \ + $(TOP)/src/gallium/drivers/nv30/libnv30.a \ + $(TOP)/src/gallium/drivers/nv40/libnv40.a \ + $(TOP)/src/gallium/drivers/nv50/libnv50.a \ + $(TOP)/src/gallium/drivers/nouveau/libnouveau.a \ + $(GALLIUM_AUXILIARIES) + +DRIVER_DEFINES = \ + -DHAVE_CONFIG_H + + +############################################# + + + +all default: $(TARGET) + +$(TARGET): $(OBJECTS) Makefile $(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a $(LIBS) + $(TOP)/bin/mklib -noprefix -o $@ \ + $(OBJECTS) $(LIBS) $(shell pkg-config --libs libdrm) -ldrm_nouveau + +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/nouveau/xorg/nouveau_xorg.c b/src/gallium/winsys/drm/nouveau/xorg/nouveau_xorg.c new file mode 100644 index 0000000000..a669b3080a --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/xorg/nouveau_xorg.c @@ -0,0 +1,149 @@ +/* + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * + * Author: Alan Hourihane <alanh@tungstengraphics.com> + * Author: Jakob Bornecrantz <wallbraker@gmail.com> + * + */ + +#include "../../../../state_trackers/xorg/xorg_winsys.h" + +static void nouveau_xorg_identify(int flags); +static Bool nouveau_xorg_pci_probe(DriverPtr driver, int entity_num, + struct pci_device *device, + intptr_t match_data); + +static const struct pci_id_match nouveau_xorg_device_match[] = { + { 0x10de, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, + 0x00030000, 0x00ffffff, 0 }, + { 0x12d2, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, + 0x00030000, 0x00ffffff, 0 }, + {0, 0, 0}, +}; + +static SymTabRec nouveau_xorg_chipsets[] = { + {PCI_MATCH_ANY, "NVIDIA Graphics Device"}, + {-1, NULL} +}; + +static PciChipsets nouveau_xorg_pci_devices[] = { + {PCI_MATCH_ANY, PCI_MATCH_ANY, NULL}, + {-1, -1, NULL} +}; + +static XF86ModuleVersionInfo nouveau_xorg_version = { + "modesetting", + 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 modesetting = { + 1, + "modesetting", + nouveau_xorg_identify, + NULL, + xorg_tracker_available_options, + NULL, + 0, + NULL, + nouveau_xorg_device_match, + nouveau_xorg_pci_probe +}; + +static MODULESETUPPROTO(nouveau_xorg_setup); + +_X_EXPORT XF86ModuleData modesettingModuleData = { + &nouveau_xorg_version, + nouveau_xorg_setup, + NULL +}; + +/* + * Xorg driver functions + */ + +static pointer +nouveau_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(&modesetting, 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 +nouveau_xorg_identify(int flags) +{ + xf86PrintChipsets("modesetting", "Driver for Modesetting Kernel Drivers", + nouveau_xorg_chipsets); +} + +static Bool +nouveau_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, nouveau_xorg_pci_devices, + NULL, NULL, NULL, NULL, NULL); + if (scrn != NULL) { + scrn->driverVersion = 1; + scrn->driverName = "i915"; + scrn->name = "modesetting"; + scrn->Probe = NULL; + + entity = xf86GetEntityInfo(entity_num); + + /* Use all the functions from the xorg tracker */ + xorg_tracker_set_functions(scrn); + } + return scrn != NULL; +} diff --git a/src/gallium/winsys/drm/radeon/core/Makefile b/src/gallium/winsys/drm/radeon/core/Makefile index 42a6f4abc2..860cbb6dbf 100644 --- a/src/gallium/winsys/drm/radeon/core/Makefile +++ b/src/gallium/winsys/drm/radeon/core/Makefile @@ -7,8 +7,7 @@ LIBNAME = radeonwinsys C_SOURCES = \ radeon_buffer.c \ radeon_drm.c \ - radeon_r300.c \ - radeon_winsys_softpipe.c + radeon_r300.c LIBRARY_INCLUDES = -I$(TOP)/src/gallium/drivers/r300 \ $(shell pkg-config libdrm --cflags-only-I) diff --git a/src/gallium/winsys/drm/radeon/core/SConscript b/src/gallium/winsys/drm/radeon/core/SConscript index 2ad68e403f..f4e9c397bd 100644 --- a/src/gallium/winsys/drm/radeon/core/SConscript +++ b/src/gallium/winsys/drm/radeon/core/SConscript @@ -6,7 +6,6 @@ radeon_sources = [ 'radeon_buffer.c', 'radeon_drm.c', 'radeon_r300.c', - 'radeon_winsys_softpipe.c', ] env.Append(CPPPATH = '#/src/gallium/drivers/r300') diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c index 7bf23cba23..2a8daed051 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c @@ -33,6 +33,17 @@ #include "radeon_buffer.h" #include "radeon_bo_gem.h" +#include "softpipe/sp_texture.h" +#include "r300_context.h" +#include "util/u_math.h" +#include <X11/Xutil.h> + +struct radeon_vl_context +{ + Display *display; + int screen; + Drawable drawable; +}; static const char *radeon_get_name(struct pipe_winsys *ws) { @@ -104,17 +115,13 @@ static struct pipe_buffer *radeon_surface_buffer_create(struct pipe_winsys *ws, unsigned tex_usage, unsigned *stride) { - struct pipe_format_block block; - unsigned nblocksx, nblocksy, size; - - pf_get_block(format, &block); - - nblocksx = pf_get_nblocksx(&block, width); - nblocksy = pf_get_nblocksy(&block, height); - /* Radeons enjoy things in multiples of 32. */ /* XXX this can be 32 when POT */ - *stride = (nblocksx * block.size + 63) & ~63; + const unsigned alignment = 64; + unsigned nblocksy, size; + + nblocksy = pf_get_nblocksy(format, height); + *stride = align(pf_get_stride(format, width), alignment); size = *stride * nblocksy; return radeon_buffer_create(ws, 64, usage, size); @@ -133,10 +140,15 @@ static void *radeon_buffer_map(struct pipe_winsys *ws, struct pipe_buffer *buffer, unsigned flags) { + struct radeon_winsys_priv *priv = ((struct radeon_winsys *)ws)->priv; struct radeon_pipe_buffer *radeon_buffer = (struct radeon_pipe_buffer*)buffer; int write = 0; + if (radeon_bo_is_referenced_by_cs(radeon_buffer->bo, priv->cs)) { + priv->cs->space_flush_fn(priv->cs->space_flush_data); + } + if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) { uint32_t domain; @@ -183,11 +195,53 @@ static int radeon_fence_finish(struct pipe_winsys *ws, return 0; } +static void radeon_display_surface(struct pipe_winsys *pws, + struct pipe_surface *psurf, + struct radeon_vl_context *rvl_ctx) +{ + struct r300_texture *r300tex = (struct r300_texture *)(psurf->texture); + XImage *ximage; + void *data; + + ximage = XCreateImage(rvl_ctx->display, + XDefaultVisual(rvl_ctx->display, rvl_ctx->screen), + XDefaultDepth(rvl_ctx->display, rvl_ctx->screen), + ZPixmap, 0, /* format, offset */ + NULL, /* data */ + 0, 0, /* size */ + 32, /* bitmap_pad */ + 0); /* bytes_per_line */ + + assert(ximage->format); + assert(ximage->bitmap_unit); + + data = pws->buffer_map(pws, r300tex->buffer, 0); + + /* update XImage's fields */ + ximage->data = data; + ximage->width = psurf->width; + ximage->height = psurf->height; + 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), + ximage, 0, 0, 0, 0, psurf->width, psurf->height); + + XSync(rvl_ctx->display, 0); + + ximage->data = NULL; + XDestroyImage(ximage); + + pws->buffer_unmap(pws, r300tex->buffer); +} + static void radeon_flush_frontbuffer(struct pipe_winsys *pipe_winsys, struct pipe_surface *pipe_surface, void *context_private) { - /* XXX TODO: call dri2CopyRegion */ + struct radeon_vl_context *rvl_ctx; + rvl_ctx = (struct radeon_vl_context *) context_private; + radeon_display_surface(pipe_winsys, pipe_surface, rvl_ctx); } struct radeon_winsys* radeon_pipe_winsys(int fd) @@ -266,13 +320,10 @@ 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); - tmpl.nblocksy[0] = pf_get_nblocksy(&tmpl.block, h); pt = pipe_screen->texture_blanket(pipe_screen, &tmpl, &pitch, pb); if (pt == NULL) { diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h index f5153b06af..bfe2221d1e 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h +++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h @@ -45,6 +45,8 @@ #include "radeon_drm.h" +#include "radeon_winsys.h" + struct radeon_pipe_buffer { struct pipe_buffer base; struct radeon_bo *bo; @@ -68,14 +70,6 @@ struct radeon_winsys_priv { struct radeon_cs* cs; }; -struct radeon_winsys { - /* Parent class. */ - struct pipe_winsys base; - - /* This corresponds to void* radeon_winsys in r300_winsys. */ - struct radeon_winsys_priv* priv; -}; - struct radeon_winsys* radeon_pipe_winsys(int fb); #if 0 struct pipe_surface *radeon_surface_from_handle(struct radeon_context *radeon_context, diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.c b/src/gallium/winsys/drm/radeon/core/radeon_drm.c index a4011db0b8..dec7c06503 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_drm.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.c @@ -29,21 +29,95 @@ * Joakim Sindholt <opensource@zhasha.com> */ +#include "softpipe/sp_winsys.h" + #include "radeon_drm.h" +/* Helper function to do the ioctls needed for setup and init. */ +static void do_ioctls(int fd, struct radeon_winsys* winsys) +{ + struct drm_radeon_gem_info gem_info = {0}; + struct drm_radeon_info info = {0}; + int target = 0; + int retval; + + info.value = (unsigned long)⌖ + + /* We do things in a specific order here. + * + * First, the PCI ID. This is essential and should return usable numbers + * for all Radeons. If this fails, we probably got handed an FD for some + * non-Radeon card. + * + * The GB and Z pipe requests should always succeed, but they might not + * return sensical values for all chipsets, but that's alright because + * the pipe drivers already know that. + * + * The GEM info is actually bogus on the kernel side, as well as our side + * (see radeon_gem_info_ioctl in radeon_gem.c) but that's alright because + * we don't actually use the info for anything yet. + * XXX update the above when we can safely use vram_size instead of vram_visible */ + info.request = RADEON_INFO_DEVICE_ID; + retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)); + if (retval) { + fprintf(stderr, "%s: Failed to get PCI ID, " + "error number %d\n", __FUNCTION__, retval); + exit(1); + } + winsys->pci_id = target; + + info.request = RADEON_INFO_NUM_GB_PIPES; + retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)); + if (retval) { + fprintf(stderr, "%s: Failed to get GB pipe count, " + "error number %d\n", __FUNCTION__, retval); + exit(1); + } + winsys->gb_pipes = target; + + info.request = RADEON_INFO_NUM_Z_PIPES; + retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)); + if (retval) { + fprintf(stderr, "%s: Failed to get Z pipe count, " + "error number %d\n", __FUNCTION__, retval); + exit(1); + } + winsys->z_pipes = target; + + retval = drmCommandWriteRead(fd, DRM_RADEON_GEM_INFO, + &gem_info, sizeof(gem_info)); + if (retval) { + fprintf(stderr, "%s: Failed to get MM info, error number %d\n", + __FUNCTION__, retval); + exit(1); + } + winsys->gart_size = gem_info.gart_size; + /* XXX */ + winsys->vram_size = gem_info.vram_visible; +} + +/* Guess at whether this chipset should use r300g. + * + * I believe that this check is valid, but I haven't been exhaustive. */ +static boolean is_r3xx(int pciid) +{ + return (pciid > 0x3150) && (pciid < 0x796f); +} + /* Create a pipe_screen. */ struct pipe_screen* radeon_create_screen(struct drm_api* api, int drmFB, struct drm_create_screen_arg *arg) { - struct radeon_winsys* winsys = radeon_pipe_winsys(drmFB); + struct radeon_winsys* rwinsys = radeon_pipe_winsys(drmFB); + do_ioctls(drmFB, rwinsys); - if (getenv("RADEON_SOFTPIPE")) { - return softpipe_create_screen((struct pipe_winsys*)winsys); + if (!is_r3xx(rwinsys->pci_id) || + debug_get_bool_option("RADEON_SOFTPIPE", FALSE)) { + return softpipe_create_screen((struct pipe_winsys*)rwinsys); } else { - struct r300_winsys* r300 = radeon_create_r300_winsys(drmFB, winsys); - FREE(winsys); - return r300_create_screen(r300); + radeon_setup_winsys(drmFB, rwinsys); + return r300_create_screen(rwinsys); } } @@ -51,11 +125,13 @@ struct pipe_screen* radeon_create_screen(struct drm_api* api, struct pipe_context* radeon_create_context(struct drm_api* api, struct pipe_screen* screen) { - if (getenv("RADEON_SOFTPIPE")) { - return radeon_create_softpipe(screen->winsys); + struct radeon_winsys* rwinsys = (struct radeon_winsys*)screen->winsys; + + if (!is_r3xx(rwinsys->pci_id) || + debug_get_bool_option("RADEON_SOFTPIPE", FALSE)) { + return softpipe_create(screen); } else { - return r300_create_context(screen, - (struct r300_winsys*)screen->winsys); + return r300_create_context(screen, rwinsys); } } @@ -107,13 +183,18 @@ radeon_texture_from_shared_handle(struct drm_api *api, unsigned handle) { struct pipe_buffer *buffer; + struct pipe_texture *blanket; buffer = radeon_buffer_from_handle(api, screen, name, handle); if (!buffer) { return NULL; } - return screen->texture_blanket(screen, templ, &stride, buffer); + blanket = screen->texture_blanket(screen, templ, &stride, buffer); + + pipe_buffer_reference(&buffer, NULL); + + return blanket; } static boolean radeon_shared_handle_from_texture(struct drm_api *api, diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.h b/src/gallium/winsys/drm/radeon/core/radeon_drm.h index 88a5c82b28..bf0e78138d 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_drm.h +++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.h @@ -37,13 +37,13 @@ #include "pipe/p_screen.h" #include "trace/tr_drm.h" +#include "util/u_debug.h" #include "util/u_memory.h" #include "state_tracker/drm_api.h" #include "radeon_buffer.h" #include "radeon_r300.h" -#include "radeon_winsys_softpipe.h" /* XXX */ #include "r300_screen.h" diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.c b/src/gallium/winsys/drm/radeon/core/radeon_r300.c index d2d84f1a8f..ba0596c30d 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_r300.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.c @@ -22,25 +22,27 @@ #include "radeon_r300.h" -static boolean radeon_r300_add_buffer(struct r300_winsys* winsys, - struct pipe_buffer* pbuffer, - uint32_t rd, - uint32_t wd) +static void radeon_set_flush_cb(struct radeon_winsys *winsys, + void (*flush_cb)(void *), + void *data) +{ + radeon_cs_space_set_flush(winsys->priv->cs, flush_cb, data); +} + +static boolean radeon_add_buffer(struct radeon_winsys* winsys, + struct pipe_buffer* pbuffer, + uint32_t rd, + uint32_t wd) { - struct radeon_winsys_priv* priv = - (struct radeon_winsys_priv*)winsys->radeon_winsys; struct radeon_bo* bo = ((struct radeon_pipe_buffer*)pbuffer)->bo; - radeon_cs_space_add_persistent_bo(priv->cs, bo, rd, wd); + radeon_cs_space_add_persistent_bo(winsys->priv->cs, bo, rd, wd); return TRUE; } -static boolean radeon_r300_validate(struct r300_winsys* winsys) +static boolean radeon_validate(struct radeon_winsys* winsys) { - struct radeon_winsys_priv* priv = - (struct radeon_winsys_priv*)winsys->radeon_winsys; - - if (radeon_cs_space_check(priv->cs) < 0) { + if (radeon_cs_space_check(winsys->priv->cs) < 0) { return FALSE; } @@ -48,45 +50,37 @@ static boolean radeon_r300_validate(struct r300_winsys* winsys) return TRUE; } -static boolean radeon_r300_check_cs(struct r300_winsys* winsys, int size) +static boolean radeon_check_cs(struct radeon_winsys* winsys, int size) { - /* XXX check size here, lazy ass! */ - /* XXX also validate buffers */ - return TRUE; + struct radeon_cs* cs = winsys->priv->cs; + + return radeon_validate(winsys) && cs->cdw + size <= cs->ndw; } -static void radeon_r300_begin_cs(struct r300_winsys* winsys, - int size, - const char* file, - const char* function, - int line) +static void radeon_begin_cs(struct radeon_winsys* winsys, + int size, + const char* file, + const char* function, + int line) { - struct radeon_winsys_priv* priv = - (struct radeon_winsys_priv*)winsys->radeon_winsys; - - radeon_cs_begin(priv->cs, size, file, function, line); + radeon_cs_begin(winsys->priv->cs, size, file, function, line); } -static void radeon_r300_write_cs_dword(struct r300_winsys* winsys, - uint32_t dword) +static void radeon_write_cs_dword(struct radeon_winsys* winsys, + uint32_t dword) { - struct radeon_winsys_priv* priv = - (struct radeon_winsys_priv*)winsys->radeon_winsys; - - radeon_cs_write_dword(priv->cs, dword); + radeon_cs_write_dword(winsys->priv->cs, dword); } -static void radeon_r300_write_cs_reloc(struct r300_winsys* winsys, - struct pipe_buffer* pbuffer, - uint32_t rd, - uint32_t wd, - uint32_t flags) +static void radeon_write_cs_reloc(struct radeon_winsys* winsys, + struct pipe_buffer* pbuffer, + uint32_t rd, + uint32_t wd, + uint32_t flags) { - struct radeon_winsys_priv* priv = - (struct radeon_winsys_priv*)winsys->radeon_winsys; int retval = 0; - retval = radeon_cs_write_reloc(priv->cs, + retval = radeon_cs_write_reloc(winsys->priv->cs, ((struct radeon_pipe_buffer*)pbuffer)->bo, rd, wd, flags); if (retval) { @@ -95,116 +89,60 @@ static void radeon_r300_write_cs_reloc(struct r300_winsys* winsys, } } -static void radeon_r300_end_cs(struct r300_winsys* winsys, - const char* file, - const char* function, - int line) +static void radeon_reset_bos(struct radeon_winsys *winsys) { - struct radeon_winsys_priv* priv = - (struct radeon_winsys_priv*)winsys->radeon_winsys; + radeon_cs_space_reset_bos(winsys->priv->cs); +} - radeon_cs_end(priv->cs, file, function, line); +static void radeon_end_cs(struct radeon_winsys* winsys, + const char* file, + const char* function, + int line) +{ + radeon_cs_end(winsys->priv->cs, file, function, line); } -static void radeon_r300_flush_cs(struct r300_winsys* winsys) +static void radeon_flush_cs(struct radeon_winsys* winsys) { - struct radeon_winsys_priv* priv = - (struct radeon_winsys_priv*)winsys->radeon_winsys; int retval; /* Emit the CS. */ - retval = radeon_cs_emit(priv->cs); + retval = radeon_cs_emit(winsys->priv->cs); if (retval) { debug_printf("radeon: Bad CS, dumping...\n"); - radeon_cs_print(priv->cs, stderr); + radeon_cs_print(winsys->priv->cs, stderr); } - /* Clean out BOs. */ - radeon_cs_space_reset_bos(priv->cs); - /* Reset CS. * Someday, when we care about performance, we should really find a way * to rotate between two or three CS objects so that the GPU can be * spinning through one CS while another one is being filled. */ - radeon_cs_erase(priv->cs); -} - -/* Helper function to do the ioctls needed for setup and init. */ -static void do_ioctls(struct r300_winsys* winsys, int fd) -{ - struct drm_radeon_gem_info gem_info = {0}; - struct drm_radeon_info info = {0}; - int target = 0; - int retval; - - info.value = (unsigned long)⌖ - - /* First, get the number of pixel pipes */ - info.request = RADEON_INFO_NUM_GB_PIPES; - retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)); - if (retval) { - fprintf(stderr, "%s: Failed to get GB pipe count, " - "error number %d\n", __FUNCTION__, retval); - exit(1); - } - winsys->gb_pipes = target; - - /* Then, get PCI ID */ - info.request = RADEON_INFO_DEVICE_ID; - retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)); - if (retval) { - fprintf(stderr, "%s: Failed to get PCI ID, " - "error number %d\n", __FUNCTION__, retval); - exit(1); - } - winsys->pci_id = target; - - /* Finally, retrieve MM info */ - retval = drmCommandWriteRead(fd, DRM_RADEON_GEM_INFO, - &gem_info, sizeof(gem_info)); - if (retval) { - fprintf(stderr, "%s: Failed to get MM info, error number %d\n", - __FUNCTION__, retval); - exit(1); - } - winsys->gart_size = gem_info.gart_size; - /* XXX */ - winsys->vram_size = gem_info.vram_visible; + radeon_cs_erase(winsys->priv->cs); } -struct r300_winsys* -radeon_create_r300_winsys(int fd, struct radeon_winsys* old_winsys) +void +radeon_setup_winsys(int fd, struct radeon_winsys* winsys) { - struct r300_winsys* winsys = CALLOC_STRUCT(r300_winsys); - struct radeon_winsys_priv* priv; - - if (winsys == NULL) { - return NULL; - } - - priv = old_winsys->priv; - - do_ioctls(winsys, fd); + struct radeon_winsys_priv* priv = winsys->priv; priv->csm = radeon_cs_manager_gem_ctor(fd); + /* Size limit on IBs is 64 kibibytes. */ priv->cs = radeon_cs_create(priv->csm, 1024 * 64 / 4); radeon_cs_set_limit(priv->cs, RADEON_GEM_DOMAIN_GTT, winsys->gart_size); radeon_cs_set_limit(priv->cs, RADEON_GEM_DOMAIN_VRAM, winsys->vram_size); - winsys->add_buffer = radeon_r300_add_buffer; - winsys->validate = radeon_r300_validate; - - winsys->check_cs = radeon_r300_check_cs; - winsys->begin_cs = radeon_r300_begin_cs; - winsys->write_cs_dword = radeon_r300_write_cs_dword; - winsys->write_cs_reloc = radeon_r300_write_cs_reloc; - winsys->end_cs = radeon_r300_end_cs; - winsys->flush_cs = radeon_r300_flush_cs; - - memcpy(winsys, old_winsys, sizeof(struct radeon_winsys)); - - return winsys; + winsys->add_buffer = radeon_add_buffer; + winsys->validate = radeon_validate; + + winsys->check_cs = radeon_check_cs; + winsys->begin_cs = radeon_begin_cs; + winsys->write_cs_dword = radeon_write_cs_dword; + winsys->write_cs_reloc = radeon_write_cs_reloc; + winsys->end_cs = radeon_end_cs; + winsys->flush_cs = radeon_flush_cs; + winsys->reset_bos = radeon_reset_bos; + winsys->set_flush_cb = radeon_set_flush_cb; } diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.h b/src/gallium/winsys/drm/radeon/core/radeon_r300.h index 775d7937fd..cfbdb30266 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_r300.h +++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.h @@ -34,9 +34,6 @@ #include "radeon_buffer.h" -struct radeon_winsys; - -struct r300_winsys* -radeon_create_r300_winsys(int fd, struct radeon_winsys* old_winsys); +void radeon_setup_winsys(int fd, struct radeon_winsys* winsys); #endif /* RADEON_R300_H */ diff --git a/src/gallium/winsys/drm/radeon/core/radeon_winsys.h b/src/gallium/winsys/drm/radeon/core/radeon_winsys.h new file mode 100644 index 0000000000..9edc9e038c --- /dev/null +++ b/src/gallium/winsys/drm/radeon/core/radeon_winsys.h @@ -0,0 +1,105 @@ +/* + * Copyright © 2009 Corbin Simpson + * 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 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ +/* + * Authors: + * Corbin Simpson <MostAwesomeDude@gmail.com> + */ +#ifndef RADEON_WINSYS_H +#define RADEON_WINSYS_H + +#include "pipe/internal/p_winsys_screen.h" + +struct radeon_winsys_priv; + +struct radeon_winsys { + /* Parent class. */ + struct pipe_winsys base; + + /* Winsys private */ + struct radeon_winsys_priv* priv; + + /* PCI ID */ + uint32_t pci_id; + + /* GB pipe count */ + uint32_t gb_pipes; + + /* Z pipe count (rv530 only) */ + uint32_t z_pipes; + + /* GART size. */ + uint32_t gart_size; + + /* VRAM size. */ + uint32_t vram_size; + + /* Add a pipe_buffer to the list of buffer objects to validate. */ + boolean (*add_buffer)(struct radeon_winsys* winsys, + struct pipe_buffer* pbuffer, + uint32_t rd, + uint32_t wd); + + /* Revalidate all currently setup pipe_buffers. + * Returns TRUE if a flush is required. */ + boolean (*validate)(struct radeon_winsys* winsys); + + /* Check to see if there's room for commands. */ + boolean (*check_cs)(struct radeon_winsys* winsys, int size); + + /* Start a command emit. */ + void (*begin_cs)(struct radeon_winsys* winsys, + int size, + const char* file, + const char* function, + int line); + + /* Write a dword to the command buffer. */ + void (*write_cs_dword)(struct radeon_winsys* winsys, uint32_t dword); + + /* Write a relocated dword to the command buffer. */ + void (*write_cs_reloc)(struct radeon_winsys* winsys, + struct pipe_buffer* bo, + uint32_t rd, + uint32_t wd, + uint32_t flags); + + /* Finish a command emit. */ + void (*end_cs)(struct radeon_winsys* winsys, + const char* file, + const char* function, + int line); + + /* Flush the CS. */ + void (*flush_cs)(struct radeon_winsys* winsys); + + /* winsys flush - callback from winsys when flush required */ + void (*set_flush_cb)(struct radeon_winsys *winsys, + void (*flush_cb)(void *), void *data); + + void (*reset_bos)(struct radeon_winsys *winsys); +}; + +#endif diff --git a/src/gallium/winsys/drm/radeon/core/radeon_winsys_softpipe.c b/src/gallium/winsys/drm/radeon/core/radeon_winsys_softpipe.c deleted file mode 100644 index f038bfa40e..0000000000 --- a/src/gallium/winsys/drm/radeon/core/radeon_winsys_softpipe.c +++ /dev/null @@ -1,41 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., 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 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. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Keith Whitwell <keithw-at-tungstengraphics-dot-com> - */ - -#include "radeon_winsys_softpipe.h" - -struct pipe_context *radeon_create_softpipe(struct pipe_winsys* winsys) -{ - struct pipe_screen *pipe_screen; - - pipe_screen = softpipe_create_screen(winsys); - - return softpipe_create(pipe_screen); -} diff --git a/src/gallium/winsys/drm/radeon/core/radeon_winsys_softpipe.h b/src/gallium/winsys/drm/radeon/core/radeon_winsys_softpipe.h deleted file mode 100644 index 04740e41a5..0000000000 --- a/src/gallium/winsys/drm/radeon/core/radeon_winsys_softpipe.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright © 2008 Jérôme Glisse - * 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 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. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - */ -/* - * Authors: - * Jérôme Glisse <glisse@freedesktop.org> - */ -#ifndef RADEON_WINSYS_SOFTPIPE_H -#define RADEON_WINSYS_SOFTPIPE_H - -#include <stdio.h> - -#include "pipe/p_defines.h" -#include "pipe/p_format.h" - -#include "softpipe/sp_winsys.h" - -#include "util/u_memory.h" - -struct pipe_context *radeon_create_softpipe(struct pipe_winsys* winsys); - -#endif diff --git a/src/gallium/winsys/drm/radeon/xorg/Makefile b/src/gallium/winsys/drm/radeon/xorg/Makefile index 0241625f69..9fa16dab24 100644 --- a/src/gallium/winsys/drm/radeon/xorg/Makefile +++ b/src/gallium/winsys/drm/radeon/xorg/Makefile @@ -20,6 +20,8 @@ LIBS = \ $(GALLIUMDIR)/state_trackers/xorg/libxorgtracker.a \ $(GALLIUMDIR)/winsys/drm/radeon/core/libradeonwinsys.a \ $(TOP)/src/gallium/drivers/r300/libr300.a \ + $(TOP)/src/gallium/drivers/trace/libtrace.a \ + $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ $(GALLIUM_AUXILIARIES) ############################################# diff --git a/src/gallium/winsys/drm/vmware/Makefile b/src/gallium/winsys/drm/vmware/Makefile new file mode 100644 index 0000000000..2ae6dead5c --- /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 0000000000..06e6d5be9c --- /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 0000000000..a52957c1a5 --- /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 0000000000..edaf9458be --- /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 0000000000..b812fb59d3 --- /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 <jfonseca@vmware.com> + */ + + +#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 0000000000..634bdcabd2 --- /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 0000000000..b6997588de --- /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 0000000000..305ce9b5be --- /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 <jfonseca@vmware.com> + */ + + +#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 0000000000..873dd51166 --- /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 0000000000..5357b4f61d --- /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 0000000000..911eec5e25 --- /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 0000000000..a875107370 --- /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 <jfonseca@vmware.com> + */ + + +#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 0000000000..5995eee34b --- /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 0000000000..51e455f925 --- /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 0000000000..b1c24b0cb6 --- /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 0000000000..d7d008859b --- /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 0000000000..5f1b9ad577 --- /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 0000000000..340cc1532e --- /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 <jfonseca@vmware.com> + */ + + +#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 0000000000..89bbf17ce9 --- /dev/null +++ b/src/gallium/winsys/drm/vmware/core/vmwgfx_drm.h @@ -0,0 +1,540 @@ +/************************************************************************** + * + * 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 +#define DRM_VMW_OVERLAY 13 +#define DRM_VMW_CURSOR_BYPASS 14 + +/*************************************************************************/ +/** + * DRM_VMW_GET_PARAM - get device information. + * + * 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. + * + * DRM_VMW_PARAM_OVERLAY_IOCTL: + * Does the driver support the overlay ioctl. + */ + +#define DRM_VMW_PARAM_FIFO_OFFSET 0 +#define DRM_VMW_PARAM_OVERLAY_IOCTL 1 + +/** + * 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; +}; + +/*************************************************************************/ +/** + * DRM_VMW_OVERLAY - Control overlays. + * + * This IOCTL controls the overlay units of the svga device. + * The SVGA overlay units does not work like regular hardware units in + * that they do not automaticaly read back the contents of the given dma + * buffer. But instead only read back for each call to this ioctl, and + * at any point between this call being made and a following call that + * either changes the buffer or disables the stream. + */ + +/** + * struct drm_vmw_rect + * + * Defines a rectangle. Used in the overlay ioctl to define + * source and destination rectangle. + */ + +struct drm_vmw_rect { + int32_t x; + int32_t y; + uint32_t w; + uint32_t h; +}; + +/** + * struct drm_vmw_overlay_arg + * + * @stream_id: Stearm to control + * @enabled: If false all following arguments are ignored. + * @handle: Handle to buffer for getting data from. + * @format: Format of the overlay as understood by the host. + * @width: Width of the overlay. + * @height: Height of the overlay. + * @size: Size of the overlay in bytes. + * @pitch: Array of pitches, the two last are only used for YUV12 formats. + * @offset: Offset from start of dma buffer to overlay. + * @src: Source rect, must be within the defined area above. + * @dst: Destination rect, x and y may be negative. + * + * Argument to the DRM_VMW_OVERLAY Ioctl. + */ + +struct drm_vmw_overlay_arg { + uint32_t stream_id; + uint32_t enabled; + + uint32_t flags; + uint32_t color_key; + + uint32_t handle; + uint32_t offset; + int32_t format; + uint32_t size; + uint32_t width; + uint32_t height; + uint32_t pitch[3]; + + uint32_t pad64; + struct drm_vmw_rect src; + struct drm_vmw_rect dst; +}; + +/*************************************************************************/ +/** + * DRM_VMW_CURSOR_BYPASS - Give extra information about cursor bypass. + * + */ + +#define DRM_VMW_CURSOR_BYPASS_ALL (1 << 0) +#define DRM_VMW_CURSOR_BYPASS_FLAGS (1) + +/** + * struct drm_vmw_cursor_bypass_arg + * + * @flags: Flags. + * @crtc_id: Crtc id, only used if DMR_CURSOR_BYPASS_ALL isn't passed. + * @xpos: X position of cursor. + * @ypos: Y position of cursor. + * @xhot: X hotspot. + * @yhot: Y hotspot. + * + * Argument to the DRM_VMW_CURSOR_BYPASS Ioctl. + */ + +struct drm_vmw_cursor_bypass_arg { + uint32_t flags; + uint32_t crtc_id; + int32_t xpos; + int32_t ypos; + int32_t xhot; + int32_t yhot; +}; + +#endif diff --git a/src/gallium/winsys/drm/vmware/dri/Makefile b/src/gallium/winsys/drm/vmware/dri/Makefile new file mode 100644 index 0000000000..8a39e23da6 --- /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 0000000000..1019f577a5 --- /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 0000000000..8e2980c318 --- /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 0000000000..49e28ae17f --- /dev/null +++ b/src/gallium/winsys/drm/vmware/xorg/Makefile @@ -0,0 +1,71 @@ +TOP = ../../../../../.. + +include $(TOP)/configs/current + +TARGET = vmwgfx_drv.so + +CFILES = \ + vmw_xorg.c \ + vmw_video.c \ + vmw_ioctl.c \ + vmw_screen.c + +OBJECTS = $(patsubst %.c,%.o,$(CFILES)) + +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 = \ + -std=gnu99 \ + -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 0000000000..b8968e7137 --- /dev/null +++ b/src/gallium/winsys/drm/vmware/xorg/SConscript @@ -0,0 +1,56 @@ +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_ioctl.c', + 'vmw_screen.c', + '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_driver.h b/src/gallium/winsys/drm/vmware/xorg/vmw_driver.h new file mode 100644 index 0000000000..7265f767a5 --- /dev/null +++ b/src/gallium/winsys/drm/vmware/xorg/vmw_driver.h @@ -0,0 +1,94 @@ +/********************************************************** + * 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 + * Contains the shared resources for VMware Xorg driver + * that sits ontop of the Xorg State Traker. + * + * It is initialized in vmw_screen.c. + * + * @author Jakob Bornecrantz <jakob@vmware.com> + */ + +#ifndef VMW_DRIVER_H_ +#define VMW_DRIVER_H_ + +#include "state_trackers/xorg/xorg_tracker.h" + +struct vmw_dma_buffer; + +struct vmw_driver +{ + int fd; + + void *cursor_priv; + + /* vmw_video.c */ + void *video_priv; +}; + +static INLINE struct vmw_driver * +vmw_driver(ScrnInfoPtr pScrn) +{ + modesettingPtr ms = modesettingPTR(pScrn); + return ms ? (struct vmw_driver *)ms->winsys_priv : NULL; +} + + +/*********************************************************************** + * vmw_video.c + */ + +Bool vmw_video_init(ScrnInfoPtr pScrn, struct vmw_driver *vmw); + +Bool vmw_video_close(ScrnInfoPtr pScrn, struct vmw_driver *vmw); + +void vmw_video_stop_all(ScrnInfoPtr pScrn, struct vmw_driver *vmw); + + +/*********************************************************************** + * vmw_ioctl.c + */ + +int vmw_ioctl_supports_overlay(struct vmw_driver *vmw); + +int vmw_ioctl_cursor_bypass(struct vmw_driver *vmw, int xhot, int yhot); + +struct vmw_dma_buffer * vmw_ioctl_buffer_create(struct vmw_driver *vmw, + uint32_t size, + unsigned *handle); + +void * vmw_ioctl_buffer_map(struct vmw_driver *vmw, + struct vmw_dma_buffer *buf); + +void vmw_ioctl_buffer_unmap(struct vmw_driver *vmw, + struct vmw_dma_buffer *buf); + +void vmw_ioctl_buffer_destroy(struct vmw_driver *vmw, + struct vmw_dma_buffer *buf); + + +#endif diff --git a/src/gallium/winsys/drm/vmware/xorg/vmw_hook.h b/src/gallium/winsys/drm/vmware/xorg/vmw_hook.h new file mode 100644 index 0000000000..224a2d9299 --- /dev/null +++ b/src/gallium/winsys/drm/vmware/xorg/vmw_hook.h @@ -0,0 +1,39 @@ +/********************************************************** + * 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_HOOK_H_ +#define VMW_HOOK_H_ + +#include "state_trackers/xorg/xorg_winsys.h" + + +/*********************************************************************** + * vmw_screen.c + */ + +void vmw_screen_set_functions(ScrnInfoPtr pScrn); + + +#endif diff --git a/src/gallium/winsys/drm/vmware/xorg/vmw_ioctl.c b/src/gallium/winsys/drm/vmware/xorg/vmw_ioctl.c new file mode 100644 index 0000000000..0d1a0fcee6 --- /dev/null +++ b/src/gallium/winsys/drm/vmware/xorg/vmw_ioctl.c @@ -0,0 +1,190 @@ +/********************************************************** + * 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 + * Contains the functions for creating dma buffers by calling + * the kernel via driver specific ioctls. + * + * @author Jakob Bornecrantz <jakob@vmware.com> + */ + +#ifndef HAVE_STDINT_H +#define HAVE_STDINT_H 1 +#endif +#define _FILE_OFFSET_BITS 64 + +#include <errno.h> +#include <stdlib.h> +#include <string.h> + +#include <sys/mman.h> +#include "xf86drm.h" +#include "../core/vmwgfx_drm.h" + +#include "vmw_driver.h" +#include "util/u_debug.h" + +struct vmw_dma_buffer +{ + void *data; + unsigned handle; + uint64_t map_handle; + unsigned map_count; + uint32_t size; +}; + +static int +vmw_ioctl_get_param(struct vmw_driver *vmw, uint32_t param, uint64_t *out) +{ + struct drm_vmw_getparam_arg gp_arg; + int ret; + + memset(&gp_arg, 0, sizeof(gp_arg)); + gp_arg.param = param; + ret = drmCommandWriteRead(vmw->fd, DRM_VMW_GET_PARAM, + &gp_arg, sizeof(gp_arg)); + + if (ret == 0) { + *out = gp_arg.value; + } + + return ret; +} + +int +vmw_ioctl_supports_overlay(struct vmw_driver *vmw) +{ + uint64_t value; + int ret; + + ret = vmw_ioctl_get_param(vmw, DRM_VMW_PARAM_OVERLAY_IOCTL, &value); + if (ret) + return ret; + + return value ? 0 : -ENOSYS; +} + +int +vmw_ioctl_cursor_bypass(struct vmw_driver *vmw, int xhot, int yhot) +{ + struct drm_vmw_cursor_bypass_arg arg; + int ret; + + memset(&arg, 0, sizeof(arg)); + arg.flags = DRM_VMW_CURSOR_BYPASS_ALL; + arg.xhot = xhot; + arg.yhot = yhot; + + ret = drmCommandWrite(vmw->fd, DRM_VMW_CURSOR_BYPASS, + &arg, sizeof(arg)); + + return ret; +} + +struct vmw_dma_buffer * +vmw_ioctl_buffer_create(struct vmw_driver *vmw, uint32_t size, unsigned *handle) +{ + struct vmw_dma_buffer *buf; + 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; + + buf = xcalloc(1, sizeof(*buf)); + if (!buf) + goto err; + + memset(&arg, 0, sizeof(arg)); + req->size = size; + do { + ret = drmCommandWriteRead(vmw->fd, DRM_VMW_ALLOC_DMABUF, &arg, sizeof(arg)); + } while (ret == -ERESTART); + + if (ret) { + debug_printf("IOCTL failed %d: %s\n", ret, strerror(-ret)); + goto err_free; + } + + + buf->data = NULL; + buf->handle = rep->handle; + buf->map_handle = rep->map_handle; + buf->map_count = 0; + buf->size = size; + + *handle = rep->handle; + + return buf; + +err_free: + xfree(buf); +err: + return NULL; +} + +void +vmw_ioctl_buffer_destroy(struct vmw_driver *vmw, struct vmw_dma_buffer *buf) +{ + struct drm_vmw_unref_dmabuf_arg arg; + + if (buf->data) { + munmap(buf->data, buf->size); + buf->data = NULL; + } + + memset(&arg, 0, sizeof(arg)); + arg.handle = buf->handle; + drmCommandWrite(vmw->fd, DRM_VMW_UNREF_DMABUF, &arg, sizeof(arg)); + + xfree(buf); +} + +void * +vmw_ioctl_buffer_map(struct vmw_driver *vmw, struct vmw_dma_buffer *buf) +{ + void *map; + + if (buf->data == NULL) { + map = mmap(NULL, buf->size, PROT_READ | PROT_WRITE, MAP_SHARED, + vmw->fd, buf->map_handle); + if (map == MAP_FAILED) { + debug_printf("%s: Map failed.\n", __FUNCTION__); + return NULL; + } + + buf->data = map; + } + + ++buf->map_count; + + return buf->data; +} + +void +vmw_ioctl_buffer_unmap(struct vmw_driver *vmw, struct vmw_dma_buffer *buf) +{ + --buf->map_count; +} diff --git a/src/gallium/winsys/drm/vmware/xorg/vmw_screen.c b/src/gallium/winsys/drm/vmware/xorg/vmw_screen.c new file mode 100644 index 0000000000..7c9757cce9 --- /dev/null +++ b/src/gallium/winsys/drm/vmware/xorg/vmw_screen.c @@ -0,0 +1,178 @@ +/********************************************************** + * 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 + * Contains the init code for the VMware Xorg driver. + * + * @author Jakob Bornecrantz <jakob@vmware.com> + */ + +#include "vmw_hook.h" +#include "vmw_driver.h" + +#include "cursorstr.h" + +/* modified version of crtc functions */ +xf86CrtcFuncsRec vmw_screen_crtc_funcs; + +static void +vmw_screen_cursor_load_argb(xf86CrtcPtr crtc, CARD32 *image) +{ + struct vmw_driver *vmw = modesettingPTR(crtc->scrn)->winsys_priv; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn); + xf86CrtcFuncsPtr funcs = vmw->cursor_priv; + CursorPtr c = config->cursor; + + /* Run the ioctl before uploading the image */ + vmw_ioctl_cursor_bypass(vmw, c->bits->xhot, c->bits->yhot); + + funcs->load_cursor_argb(crtc, image); +} + +static void +vmw_screen_cursor_init(ScrnInfoPtr pScrn, struct vmw_driver *vmw) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + int i; + + /* XXX assume that all crtc's have the same function struct */ + + /* Save old struct need to call the old functions as well */ + vmw->cursor_priv = (void*)(config->crtc[0]->funcs); + memcpy(&vmw_screen_crtc_funcs, vmw->cursor_priv, sizeof(xf86CrtcFuncsRec)); + vmw_screen_crtc_funcs.load_cursor_argb = vmw_screen_cursor_load_argb; + + for (i = 0; i < config->num_crtc; i++) + config->crtc[i]->funcs = &vmw_screen_crtc_funcs; +} + +static void +vmw_screen_cursor_close(ScrnInfoPtr pScrn, struct vmw_driver *vmw) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + int i; + + vmw_ioctl_cursor_bypass(vmw, 0, 0); + + for (i = 0; i < config->num_crtc; i++) + config->crtc[i]->funcs = vmw->cursor_priv; +} + +static Bool +vmw_screen_init(ScrnInfoPtr pScrn) +{ + modesettingPtr ms = modesettingPTR(pScrn); + struct vmw_driver *vmw; + + vmw = xnfcalloc(sizeof(*vmw), 1); + if (!vmw) + return FALSE; + + vmw->fd = ms->fd; + ms->winsys_priv = vmw; + + vmw_screen_cursor_init(pScrn, vmw); + + /* if gallium is used then we don't need to do anything more. */ + if (ms->screen) + return TRUE; + + vmw_video_init(pScrn, vmw); + + return TRUE; +} + +static Bool +vmw_screen_close(ScrnInfoPtr pScrn) +{ + modesettingPtr ms = modesettingPTR(pScrn); + struct vmw_driver *vmw = vmw_driver(pScrn); + + if (!vmw) + return TRUE; + + vmw_screen_cursor_close(pScrn, vmw); + + vmw_video_close(pScrn, vmw); + + ms->winsys_priv = NULL; + xfree(vmw); + + return TRUE; +} + +static Bool +vmw_screen_enter_vt(ScrnInfoPtr pScrn) +{ + debug_printf("%s: enter\n", __func__); + + return TRUE; +} + +static Bool +vmw_screen_leave_vt(ScrnInfoPtr pScrn) +{ + struct vmw_driver *vmw = vmw_driver(pScrn); + + debug_printf("%s: enter\n", __func__); + + vmw_video_stop_all(pScrn, vmw); + + return TRUE; +} + +/* + * Functions for setting up hooks into the xorg state tracker + */ + +static Bool (*vmw_screen_pre_init_saved)(ScrnInfoPtr pScrn, int flags) = NULL; + +static Bool +vmw_screen_pre_init(ScrnInfoPtr pScrn, int flags) +{ + modesettingPtr ms; + + pScrn->PreInit = vmw_screen_pre_init_saved; + if (!pScrn->PreInit(pScrn, flags)) + return FALSE; + + ms = modesettingPTR(pScrn); + ms->winsys_screen_init = vmw_screen_init; + ms->winsys_screen_close = vmw_screen_close; + ms->winsys_enter_vt = vmw_screen_enter_vt; + ms->winsys_leave_vt = vmw_screen_leave_vt; + + return TRUE; +} + +void +vmw_screen_set_functions(ScrnInfoPtr pScrn) +{ + assert(!vmw_screen_pre_init_saved); + + vmw_screen_pre_init_saved = pScrn->PreInit; + pScrn->PreInit = vmw_screen_pre_init; +} diff --git a/src/gallium/winsys/drm/vmware/xorg/vmw_video.c b/src/gallium/winsys/drm/vmware/xorg/vmw_video.c new file mode 100644 index 0000000000..5674e4f352 --- /dev/null +++ b/src/gallium/winsys/drm/vmware/xorg/vmw_video.c @@ -0,0 +1,1061 @@ +/* + * Copyright 2007 by VMware, Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Except as contained in this notice, the name of the copyright holder(s) + * and author(s) shall not be used in advertising or otherwise to promote + * the sale, use or other dealings in this Software without prior written + * authorization from the copyright holder(s) and author(s). + */ + +/* + * vmwarevideo.c -- + * + * Xv extension support. + * See http://www.xfree86.org/current/DESIGN16.html + * + */ + + +#include "xf86xv.h" +#include "fourcc.h" + +#include "pipe/p_compiler.h" +/* + * We can't incude svga_types.h due to conflicting types for Bool. + */ +typedef int64_t int64; +typedef uint64_t uint64; + +typedef int32_t int32; +typedef uint32_t uint32; + +typedef int16_t int16; +typedef uint16_t uint16; + +typedef int8_t int8; +typedef uint8_t uint8; + +#include "svga/include/svga_reg.h" +#include "svga/include/svga_escape.h" +#include "svga/include/svga_overlay.h" + +#include "vmw_driver.h" + +#include <X11/extensions/Xv.h> + +#include "xf86drm.h" +#include "../core/vmwgfx_drm.h" + +#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) + +/* + * Number of videos that can be played simultaneously + */ +#define VMWARE_VID_NUM_PORTS 1 + +/* + * Using a dark shade as the default colorKey + */ +#define VMWARE_VIDEO_COLORKEY 0x100701 + +/* + * Maximum dimensions + */ +#define VMWARE_VID_MAX_WIDTH 2048 +#define VMWARE_VID_MAX_HEIGHT 2048 + +#define VMWARE_VID_NUM_ENCODINGS 1 +static XF86VideoEncodingRec vmwareVideoEncodings[] = +{ + { + 0, + "XV_IMAGE", + VMWARE_VID_MAX_WIDTH, VMWARE_VID_MAX_HEIGHT, + {1, 1} + } +}; + +#define VMWARE_VID_NUM_FORMATS 2 +static XF86VideoFormatRec vmwareVideoFormats[] = +{ + { 16, TrueColor}, + { 24, TrueColor} +}; + +#define VMWARE_VID_NUM_IMAGES 3 +static XF86ImageRec vmwareVideoImages[] = +{ + XVIMAGE_YV12, + XVIMAGE_YUY2, + XVIMAGE_UYVY +}; + +#define VMWARE_VID_NUM_ATTRIBUTES 2 +static XF86AttributeRec vmwareVideoAttributes[] = +{ + { + XvGettable | XvSettable, + 0x000000, + 0xffffff, + "XV_COLORKEY" + }, + { + XvGettable | XvSettable, + 0, + 1, + "XV_AUTOPAINT_COLORKEY" + } +}; + +/* + * Video frames are stored in a circular list of buffers. + * Must be power or two, See vmw_video_port_play. + */ +#define VMWARE_VID_NUM_BUFFERS 1 + +/* + * Defines the structure used to hold and pass video data to the host + */ +struct vmw_video_buffer +{ + unsigned handle; + int size; + void *data; + void *extra_data; + struct vmw_dma_buffer *buf; +}; + + +/** + * Structure representing a single video stream, aka port. + * + * Ports maps one to one to a SVGA stream. Port is just + * what Xv calls a SVGA stream. + */ +struct vmw_video_port +{ + /* + * Function prototype same as XvPutImage. + * + * This is either set to vmw_video_port_init or vmw_video_port_play. + * At init this function is set to port_init. In port_init we set it + * to port_play and call it, after initializing the struct. + */ + int (*play)(ScrnInfoPtr, struct vmw_video_port *, + short, short, short, short, short, + short, short, short, int, unsigned char*, + short, short, RegionPtr); + + /* values to go into the SVGAOverlayUnit */ + uint32 streamId; + uint32 colorKey; + uint32 flags; + + /* round robin of buffers */ + unsigned currBuf; + struct vmw_video_buffer bufs[VMWARE_VID_NUM_BUFFERS]; + + /* properties that applies to all buffers */ + int size; + int pitches[3]; + int offsets[3]; + + /* things for X */ + RegionRec clipBoxes; + Bool isAutoPaintColorkey; +}; + + +/** + * Structure holding all the infromation for video. + */ +struct vmw_video_private +{ + int fd; + + /** ports */ + struct vmw_video_port port[VMWARE_VID_NUM_PORTS]; + + /** Used to store port pointers pointers */ + DevUnion port_ptr[VMWARE_VID_NUM_PORTS]; +}; + + +/* + * Callback functions exported to Xv, prefixed with vmw_xv_*. + */ +static int vmw_xv_put_image(ScrnInfoPtr pScrn, short src_x, short src_y, + short drw_x, short drw_y, short src_w, short src_h, + short drw_w, short drw_h, int image, + unsigned char *buf, short width, short height, + Bool sync, RegionPtr clipBoxes, pointer data, + DrawablePtr dst); +static void vmw_xv_stop_video(ScrnInfoPtr pScrn, pointer data, Bool Cleanup); +static int vmw_xv_query_image_attributes(ScrnInfoPtr pScrn, int format, + unsigned short *width, + unsigned short *height, int *pitches, + int *offsets); +static int vmw_xv_set_port_attribute(ScrnInfoPtr pScrn, Atom attribute, + INT32 value, pointer data); +static int vmw_xv_get_port_attribute(ScrnInfoPtr pScrn, Atom attribute, + INT32 *value, pointer data); +static void vmw_xv_query_best_size(ScrnInfoPtr pScrn, Bool motion, + short vid_w, short vid_h, short drw_w, + short drw_h, unsigned int *p_w, + unsigned int *p_h, pointer data); + + +/* + * Local functions. + */ +static XF86VideoAdaptorPtr vmw_video_init_adaptor(ScrnInfoPtr pScrn, struct vmw_driver *vmw); + +static int vmw_video_port_init(ScrnInfoPtr pScrn, + struct vmw_video_port *port, + short src_x, short src_y, short drw_x, + short drw_y, short src_w, short src_h, + short drw_w, short drw_h, int format, + unsigned char *buf, short width, + short height, RegionPtr clipBoxes); +static int vmw_video_port_play(ScrnInfoPtr pScrn, struct vmw_video_port *port, + short src_x, short src_y, short drw_x, + short drw_y, short src_w, short src_h, + short drw_w, short drw_h, int format, + unsigned char *buf, short width, + short height, RegionPtr clipBoxes); +static void vmw_video_port_cleanup(ScrnInfoPtr pScrn, struct vmw_video_port *port); + +static int vmw_video_buffer_alloc(struct vmw_driver *vmw, int size, + struct vmw_video_buffer *out); +static int vmw_video_buffer_free(struct vmw_driver *vmw, + struct vmw_video_buffer *out); + + +/* + *----------------------------------------------------------------------------- + * + * vmw_video_init -- + * + * Initializes Xv support. + * + * Results: + * TRUE on success, FALSE on error. + * + * Side effects: + * Xv support is initialized. Memory is allocated for all supported + * video streams. + * + *----------------------------------------------------------------------------- + */ + +Bool +vmw_video_init(ScrnInfoPtr pScrn, struct vmw_driver *vmw) +{ + ScreenPtr pScreen = pScrn->pScreen; + XF86VideoAdaptorPtr *overlayAdaptors, *newAdaptors = NULL; + XF86VideoAdaptorPtr newAdaptor = NULL; + int numAdaptors; + + debug_printf("%s: enter\n", __func__); + + if (vmw_ioctl_supports_overlay(vmw) != 0) { + debug_printf("No overlay ioctl support\n"); + return FALSE; + } + + numAdaptors = xf86XVListGenericAdaptors(pScrn, &overlayAdaptors); + + newAdaptor = vmw_video_init_adaptor(pScrn, vmw); + if (!newAdaptor) { + debug_printf("Failed to initialize Xv extension\n"); + return FALSE; + } + + if (!numAdaptors) { + numAdaptors = 1; + overlayAdaptors = &newAdaptor; + } else { + newAdaptors = xalloc((numAdaptors + 1) * + sizeof(XF86VideoAdaptorPtr*)); + if (!newAdaptors) { + xf86XVFreeVideoAdaptorRec(newAdaptor); + return FALSE; + } + + memcpy(newAdaptors, overlayAdaptors, + numAdaptors * sizeof(XF86VideoAdaptorPtr)); + newAdaptors[numAdaptors++] = newAdaptor; + overlayAdaptors = newAdaptors; + } + + if (!xf86XVScreenInit(pScreen, overlayAdaptors, numAdaptors)) { + debug_printf("Failed to initialize Xv extension\n"); + xf86XVFreeVideoAdaptorRec(newAdaptor); + return FALSE; + } + + if (newAdaptors) { + xfree(newAdaptors); + } + + debug_printf("Initialized VMware Xv extension successfully\n"); + + return TRUE; +} + + +/* + *----------------------------------------------------------------------------- + * + * vmw_video_close -- + * + * Unitializes video. + * + * Results: + * TRUE. + * + * Side effects: + * vmw->video_priv = NULL + * + *----------------------------------------------------------------------------- + */ + +Bool +vmw_video_close(ScrnInfoPtr pScrn, struct vmw_driver *vmw) +{ + struct vmw_video_private *video; + int i; + + debug_printf("%s: enter\n", __func__); + + video = vmw->video_priv; + if (!video) + return TRUE; + + for (i = 0; i < VMWARE_VID_NUM_PORTS; ++i) { + /* make sure the port is stoped as well */ + vmw_xv_stop_video(pScrn, &video->port[i], TRUE); + } + + /* XXX: I'm sure this function is missing code for turning off Xv */ + + free(vmw->video_priv); + vmw->video_priv = NULL; + + return TRUE; +} + + +/* + *----------------------------------------------------------------------------- + * + * vmw_video_stop_all -- + * + * Stop all video streams from playing. + * + * Results: + * None. + * + * Side effects: + * All buffers are freed. + * + *----------------------------------------------------------------------------- + */ + +void vmw_video_stop_all(ScrnInfoPtr pScrn, struct vmw_driver *vmw) +{ + struct vmw_video_private *video = vmw->video_priv; + int i; + + debug_printf("%s: enter\n", __func__); + + if (!video) + return; + + for (i = 0; i < VMWARE_VID_NUM_PORTS; ++i) { + vmw_xv_stop_video(pScrn, &video->port[i], TRUE); + } +} + + +/* + *----------------------------------------------------------------------------- + * + * vmw_video_init_adaptor -- + * + * Initializes a XF86VideoAdaptor structure with the capabilities and + * functions supported by this video driver. + * + * Results: + * On success initialized XF86VideoAdaptor struct or NULL on error + * + * Side effects: + * None. + * + *----------------------------------------------------------------------------- + */ + +static XF86VideoAdaptorPtr +vmw_video_init_adaptor(ScrnInfoPtr pScrn, struct vmw_driver *vmw) +{ + XF86VideoAdaptorPtr adaptor; + struct vmw_video_private *video; + int i; + + debug_printf("%s: enter \n", __func__); + + adaptor = xf86XVAllocateVideoAdaptorRec(pScrn); + if (!adaptor) { + debug_printf("Not enough memory\n"); + return NULL; + } + + video = xcalloc(1, sizeof(*video)); + if (!video) { + debug_printf("Not enough memory.\n"); + xf86XVFreeVideoAdaptorRec(adaptor); + return NULL; + } + + vmw->video_priv = video; + + adaptor->type = XvInputMask | XvImageMask | XvWindowMask; + adaptor->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; + adaptor->name = "VMware Video Engine"; + adaptor->nEncodings = VMWARE_VID_NUM_ENCODINGS; + adaptor->pEncodings = vmwareVideoEncodings; + adaptor->nFormats = VMWARE_VID_NUM_FORMATS; + adaptor->pFormats = vmwareVideoFormats; + adaptor->nPorts = VMWARE_VID_NUM_PORTS; + adaptor->pPortPrivates = video->port_ptr; + + for (i = 0; i < VMWARE_VID_NUM_PORTS; ++i) { + video->port[i].streamId = i; + video->port[i].play = vmw_video_port_init; + video->port[i].flags = SVGA_VIDEO_FLAG_COLORKEY; + video->port[i].colorKey = VMWARE_VIDEO_COLORKEY; + video->port[i].isAutoPaintColorkey = TRUE; + adaptor->pPortPrivates[i].ptr = &video->port[i]; + } + + adaptor->nAttributes = VMWARE_VID_NUM_ATTRIBUTES; + adaptor->pAttributes = vmwareVideoAttributes; + + adaptor->nImages = VMWARE_VID_NUM_IMAGES; + adaptor->pImages = vmwareVideoImages; + + adaptor->PutVideo = NULL; + adaptor->PutStill = NULL; + adaptor->GetVideo = NULL; + adaptor->GetStill = NULL; + adaptor->StopVideo = vmw_xv_stop_video; + adaptor->SetPortAttribute = vmw_xv_set_port_attribute; + adaptor->GetPortAttribute = vmw_xv_get_port_attribute; + adaptor->QueryBestSize = vmw_xv_query_best_size; + adaptor->PutImage = vmw_xv_put_image; + adaptor->QueryImageAttributes = vmw_xv_query_image_attributes; + + debug_printf("%s: done %p\n", __func__, adaptor); + + return adaptor; +} + + +/* + *----------------------------------------------------------------------------- + * + * vmw_video_port_init -- + * + * Initializes a video stream in response to the first PutImage() on a + * video stream. The process goes as follows: + * - Figure out characteristics according to format + * - Allocate offscreen memory + * - Pass on video to Play() functions + * + * Results: + * Success or XvBadAlloc on failure. + * + * Side effects: + * Video stream is initialized and its first frame sent to the host + * (done by VideoPlay() function called at the end) + * + *----------------------------------------------------------------------------- + */ + +static int +vmw_video_port_init(ScrnInfoPtr pScrn, struct vmw_video_port *port, + short src_x, short src_y, short drw_x, + short drw_y, short src_w, short src_h, + short drw_w, short drw_h, int format, + unsigned char *buf, short width, + short height, RegionPtr clipBoxes) +{ + struct vmw_driver *vmw = vmw_driver(pScrn); + unsigned short w, h; + int i, ret; + + debug_printf("\t%s: id %d, format %d\n", __func__, port->streamId, format); + + w = width; + h = height; + /* init all the format attributes, used for buffers */ + port->size = vmw_xv_query_image_attributes(pScrn, format, &w, &h, + port->pitches, port->offsets); + + if (port->size == -1) + return XvBadAlloc; + + port->play = vmw_video_port_play; + + for (i = 0; i < VMWARE_VID_NUM_BUFFERS; ++i) { + ret = vmw_video_buffer_alloc(vmw, port->size, &port->bufs[i]); + if (ret != Success) + break; + } + + /* Free all allocated buffers on failure */ + if (ret != Success) { + for (--i; i >= 0; --i) { + vmw_video_buffer_free(vmw, &port->bufs[i]); + } + return ret; + } + + port->currBuf = 0; + + REGION_COPY(pScrn->pScreen, &port->clipBoxes, clipBoxes); + + if (port->isAutoPaintColorkey) + xf86XVFillKeyHelper(pScrn->pScreen, port->colorKey, clipBoxes); + + return port->play(pScrn, port, src_x, src_y, drw_x, drw_y, src_w, src_h, + drw_w, drw_h, format, buf, width, height, clipBoxes); +} + + +/* + *----------------------------------------------------------------------------- + * + * vmw_video_port_play -- + * + * Sends all the attributes associated with the video frame using the + * FIFO ESCAPE mechanism to the host. + * + * Results: + * Always returns Success. + * + * Side effects: + * None. + * + *----------------------------------------------------------------------------- + */ + +static int +vmw_video_port_play(ScrnInfoPtr pScrn, struct vmw_video_port *port, + short src_x, short src_y, short drw_x, + short drw_y, short src_w, short src_h, + short drw_w, short drw_h, int format, + unsigned char *buf, short width, + short height, RegionPtr clipBoxes) +{ + struct vmw_driver *vmw = vmw_driver(pScrn); + struct drm_vmw_overlay_arg arg; + unsigned short w, h; + int size; + int ret; + + debug_printf("\t%s: enter\n", __func__); + + w = width; + h = height; + + /* we don't update the ports size */ + size = vmw_xv_query_image_attributes(pScrn, format, &w, &h, + port->pitches, port->offsets); + + if (size > port->size) { + debug_printf("\t%s: Increase in size of Xv video frame streamId:%d.\n", + __func__, port->streamId); + vmw_xv_stop_video(pScrn, port, TRUE); + return port->play(pScrn, port, src_x, src_y, drw_x, drw_y, src_w, + src_h, drw_w, drw_h, format, buf, width, height, + clipBoxes); + } + + memcpy(port->bufs[port->currBuf].data, buf, port->size); + + memset(&arg, 0, sizeof(arg)); + + arg.stream_id = port->streamId; + arg.enabled = TRUE; + arg.flags = port->flags; + arg.color_key = port->colorKey; + arg.handle = port->bufs[port->currBuf].handle; + arg.format = format; + arg.size = port->size; + arg.width = w; + arg.height = h; + arg.src.x = src_x; + arg.src.y = src_y; + arg.src.w = src_w; + arg.src.h = src_h; + arg.dst.x = drw_x; + arg.dst.y = drw_y; + arg.dst.w = drw_w; + arg.dst.h = drw_h; + arg.pitch[0] = port->pitches[0]; + arg.pitch[1] = port->pitches[1]; + arg.pitch[2] = port->pitches[2]; + arg.offset = 0; + + /* + * Update the clipList and paint the colorkey, if required. + */ + if (!REGION_EQUAL(pScrn->pScreen, &port->clipBoxes, clipBoxes)) { + REGION_COPY(pScrn->pScreen, &port->clipBoxes, clipBoxes); + if (port->isAutoPaintColorkey) { + xf86XVFillKeyHelper(pScrn->pScreen, port->colorKey, clipBoxes); + } + } + + ret = drmCommandWrite(vmw->fd, DRM_VMW_OVERLAY, &arg, sizeof(arg)); + if (ret) { + vmw_video_port_cleanup(pScrn, port); + return XvBadAlloc; + } + + port->currBuf = ++port->currBuf & (VMWARE_VID_NUM_BUFFERS - 1); + + return Success; +} + + +/* + *----------------------------------------------------------------------------- + * + * vmw_video_port_cleanup -- + * + * Frees up all resources (if any) taken by a video stream. + * + * Results: + * None. + * + * Side effects: + * Same as above. + * + *----------------------------------------------------------------------------- + */ + +static void +vmw_video_port_cleanup(ScrnInfoPtr pScrn, struct vmw_video_port *port) +{ + struct vmw_driver *vmw = vmw_driver(pScrn); + uint32 id, colorKey, flags; + Bool isAutoPaintColorkey; + int i; + + debug_printf("\t%s: enter\n", __func__); + + for (i = 0; i < VMWARE_VID_NUM_BUFFERS; i++) { + vmw_video_buffer_free(vmw, &port->bufs[i]); + } + + /* + * reset stream for next video + */ + id = port->streamId; + colorKey = port->colorKey; + flags = port->flags; + isAutoPaintColorkey = port->isAutoPaintColorkey; + + memset(port, 0, sizeof(*port)); + + port->streamId = id; + port->play = vmw_video_port_init; + port->colorKey = colorKey; + port->flags = flags; + port->isAutoPaintColorkey = isAutoPaintColorkey; +} + + +/* + *----------------------------------------------------------------------------- + * + * vmw_video_buffer_alloc -- + * + * Allocates and map a kernel buffer to be used as data storage. + * + * Results: + * XvBadAlloc on failure, otherwise Success. + * + * Side effects: + * Calls into the kernel, sets members of out. + * + *----------------------------------------------------------------------------- + */ + +static int +vmw_video_buffer_alloc(struct vmw_driver *vmw, int size, + struct vmw_video_buffer *out) +{ + out->buf = vmw_ioctl_buffer_create(vmw, size, &out->handle); + if (!out->buf) + return XvBadAlloc; + + out->data = vmw_ioctl_buffer_map(vmw, out->buf); + if (!out->data) { + vmw_ioctl_buffer_destroy(vmw, out->buf); + + out->handle = 0; + out->buf = NULL; + + return XvBadAlloc; + } + + out->size = size; + out->extra_data = xcalloc(1, size); + + debug_printf("\t\t%s: allocated buffer %p of size %i\n", __func__, out, size); + + return Success; +} + + +/* + *----------------------------------------------------------------------------- + * + * vmw_video_buffer_free -- + * + * Frees and unmaps an allocated kernel buffer. + * + * Results: + * Success. + * + * Side effects: + * Calls into the kernel, sets members of out to 0. + * + *----------------------------------------------------------------------------- + */ + +static int +vmw_video_buffer_free(struct vmw_driver *vmw, + struct vmw_video_buffer *out) +{ + if (out->size == 0) + return Success; + + xfree(out->extra_data); + vmw_ioctl_buffer_unmap(vmw, out->buf); + vmw_ioctl_buffer_destroy(vmw, out->buf); + + out->buf = NULL; + out->data = NULL; + out->handle = 0; + out->size = 0; + + debug_printf("\t\t%s: freed buffer %p\n", __func__, out); + + return Success; +} + + +/* + *----------------------------------------------------------------------------- + * + * vmw_xv_put_image -- + * + * Main video playback function. It copies the passed data which is in + * the specified format (e.g. FOURCC_YV12) into the overlay. + * + * If sync is TRUE the driver should not return from this + * function until it is through reading the data from buf. + * + * Results: + * Success or XvBadAlloc on failure + * + * Side effects: + * Video port will be played(initialized if 1st frame) on success + * or will fail on error. + * + *----------------------------------------------------------------------------- + */ + +static int +vmw_xv_put_image(ScrnInfoPtr pScrn, short src_x, short src_y, + short drw_x, short drw_y, short src_w, short src_h, + short drw_w, short drw_h, int format, + unsigned char *buf, short width, short height, + Bool sync, RegionPtr clipBoxes, pointer data, + DrawablePtr dst) +{ + struct vmw_driver *vmw = vmw_driver(pScrn); + struct vmw_video_port *port = data; + + debug_printf("%s: enter (%u, %u) (%ux%u) (%u, %u) (%ux%u) (%ux%u)\n", __func__, + src_x, src_y, src_w, src_h, + drw_x, drw_y, drw_w, drw_h, + width, height); + + if (!vmw->video_priv) + return XvBadAlloc; + + return port->play(pScrn, port, src_x, src_y, drw_x, drw_y, src_w, src_h, + drw_w, drw_h, format, buf, width, height, clipBoxes); +} + + +/* + *----------------------------------------------------------------------------- + * + * vmw_xv_stop_video -- + * + * Called when we should stop playing video for a particular stream. If + * Cleanup is FALSE, the "stop" operation is only temporary, and thus we + * don't do anything. If Cleanup is TRUE we kill the video port by + * sending a message to the host and freeing up the stream. + * + * Results: + * None. + * + * Side effects: + * See above. + * + *----------------------------------------------------------------------------- + */ + +static void +vmw_xv_stop_video(ScrnInfoPtr pScrn, pointer data, Bool cleanup) +{ + struct vmw_driver *vmw = vmw_driver(pScrn); + struct vmw_video_port *port = data; + struct drm_vmw_overlay_arg arg; + int ret; + + debug_printf("%s: cleanup is %s\n", __func__, cleanup ? "TRUE" : "FALSE"); + + if (!vmw->video_priv) + return; + + if (!cleanup) + return; + + + memset(&arg, 0, sizeof(arg)); + arg.stream_id = port->streamId; + arg.enabled = FALSE; + + ret = drmCommandWrite(vmw->fd, DRM_VMW_OVERLAY, &arg, sizeof(arg)); + assert(ret == 0); + + vmw_video_port_cleanup(pScrn, port); +} + + +/* + *----------------------------------------------------------------------------- + * + * vmw_xv_query_image_attributes -- + * + * From the spec: This function is called to let the driver specify how data + * for a particular image of size width by height should be stored. + * Sometimes only the size and corrected width and height are needed. In + * that case pitches and offsets are NULL. + * + * Results: + * The size of the memory required for the image, or -1 on error. + * + * Side effects: + * None. + * + *----------------------------------------------------------------------------- + */ + +static int +vmw_xv_query_image_attributes(ScrnInfoPtr pScrn, int format, + unsigned short *width, unsigned short *height, + int *pitches, int *offsets) +{ + INT32 size, tmp; + + if (*width > VMWARE_VID_MAX_WIDTH) { + *width = VMWARE_VID_MAX_WIDTH; + } + if (*height > VMWARE_VID_MAX_HEIGHT) { + *height = VMWARE_VID_MAX_HEIGHT; + } + + *width = (*width + 1) & ~1; + if (offsets != NULL) { + offsets[0] = 0; + } + + switch (format) { + case FOURCC_YV12: + *height = (*height + 1) & ~1; + size = (*width + 3) & ~3; + if (pitches) { + pitches[0] = size; + } + size *= *height; + if (offsets) { + offsets[1] = size; + } + tmp = ((*width >> 1) + 3) & ~3; + if (pitches) { + pitches[1] = pitches[2] = tmp; + } + tmp *= (*height >> 1); + size += tmp; + if (offsets) { + offsets[2] = size; + } + size += tmp; + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + size = *width * 2; + if (pitches) { + pitches[0] = size; + } + size *= *height; + break; + default: + debug_printf("Query for invalid video format %d\n", format); + return -1; + } + return size; +} + + +/* + *----------------------------------------------------------------------------- + * + * vmw_xv_set_port_attribute -- + * + * From the spec: A port may have particular attributes such as colorKey, hue, + * saturation, brightness or contrast. Xv clients set these + * attribute values by sending attribute strings (Atoms) to the server. + * + * Results: + * Success if the attribute exists and XvBadAlloc otherwise. + * + * Side effects: + * The respective attribute gets the new value. + * + *----------------------------------------------------------------------------- + */ + +static int +vmw_xv_set_port_attribute(ScrnInfoPtr pScrn, Atom attribute, + INT32 value, pointer data) +{ + struct vmw_video_port *port = data; + Atom xvColorKey = MAKE_ATOM("XV_COLORKEY"); + Atom xvAutoPaint = MAKE_ATOM("XV_AUTOPAINT_COLORKEY"); + + if (attribute == xvColorKey) { + debug_printf("%s: Set colorkey:0x%x\n", __func__, (unsigned)value); + port->colorKey = value; + } else if (attribute == xvAutoPaint) { + debug_printf("%s: Set autoPaint: %s\n", __func__, value? "TRUE": "FALSE"); + port->isAutoPaintColorkey = value; + } else { + return XvBadAlloc; + } + + return Success; +} + + +/* + *----------------------------------------------------------------------------- + * + * vmw_xv_get_port_attribute -- + * + * From the spec: A port may have particular attributes such as hue, + * saturation, brightness or contrast. Xv clients get these + * attribute values by sending attribute strings (Atoms) to the server + * + * Results: + * Success if the attribute exists and XvBadAlloc otherwise. + * + * Side effects: + * "value" contains the requested attribute on success. + * + *----------------------------------------------------------------------------- + */ + +static int +vmw_xv_get_port_attribute(ScrnInfoPtr pScrn, Atom attribute, + INT32 *value, pointer data) +{ + struct vmw_video_port *port = data; + Atom xvColorKey = MAKE_ATOM("XV_COLORKEY"); + Atom xvAutoPaint = MAKE_ATOM("XV_AUTOPAINT_COLORKEY"); + + if (attribute == xvColorKey) { + *value = port->colorKey; + } else if (attribute == xvAutoPaint) { + *value = port->isAutoPaintColorkey; + } else { + return XvBadAlloc; + } + + return Success; +} + + +/* + *----------------------------------------------------------------------------- + * + * vmw_xv_query_best_size -- + * + * From the spec: QueryBestSize provides the client with a way to query what + * the destination dimensions would end up being if they were to request + * that an area vid_w by vid_h from the video stream be scaled to rectangle + * of drw_w by drw_h on the screen. Since it is not expected that all + * hardware will be able to get the target dimensions exactly, it is + * important that the driver provide this function. + * + * This function seems to never be called, but to be on the safe side + * we apply the same logic that QueryImageAttributes has for width + * and height. + * + * Results: + * None. + * + * Side effects: + * None. + * + *----------------------------------------------------------------------------- + */ + +static void +vmw_xv_query_best_size(ScrnInfoPtr pScrn, Bool motion, + short vid_w, short vid_h, short drw_w, + short drw_h, unsigned int *p_w, + unsigned int *p_h, pointer data) +{ + *p_w = (drw_w + 1) & ~1; + *p_h = drw_h; + + return; +} 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 0000000000..4b208719ca --- /dev/null +++ b/src/gallium/winsys/drm/vmware/xorg/vmw_xorg.c @@ -0,0 +1,152 @@ +/********************************************************** + * 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 <alanh@tungstengraphics.com> + * @author Jakob Bornecrantz <wallbraker@gmail.com> + */ + +#include "vmw_hook.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); + + vmw_screen_set_functions(scrn); + } + return scrn != NULL; +} diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index d02f825047..599973ce12 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -41,6 +41,7 @@ #include "pipe/p_state.h" #include "pipe/internal/p_winsys_screen.h" #include "util/u_memory.h" +#include "util/u_math.h" #include "softpipe/sp_winsys.h" #include "softpipe/sp_texture.h" @@ -138,17 +139,6 @@ lookup_context(_EGLContext *ctx) } -static unsigned int -bitcount(unsigned int n) -{ - unsigned int bits; - for (bits = 0; n > 0; n = n >> 1) { - bits += (n & 1); - } - return bits; -} - - /** * Create the EGLConfigs. (one per X visual) */ @@ -174,9 +164,9 @@ create_configs(struct xlib_egl_display *xdpy, _EGLDisplay *disp) for (i = 0; i < num_visuals; i++) { _EGLConfig *config = calloc(1, sizeof(_EGLConfig)); int id = i + 1; - int rbits = bitcount(visInfo[i].red_mask); - int gbits = bitcount(visInfo[i].green_mask); - int bbits = bitcount(visInfo[i].blue_mask); + int rbits = util_bitcount(visInfo[i].red_mask); + int gbits = util_bitcount(visInfo[i].green_mask); + int bbits = util_bitcount(visInfo[i].blue_mask); int abits = bbits == 8 ? 8 : 0; int zbits = 24; int sbits = 8; diff --git a/src/gallium/winsys/egl_xlib/sw_winsys.c b/src/gallium/winsys/egl_xlib/sw_winsys.c index 79ff2cc985..d5644c161f 100644 --- a/src/gallium/winsys/egl_xlib/sw_winsys.c +++ b/src/gallium/winsys/egl_xlib/sw_winsys.c @@ -71,16 +71,6 @@ sw_pipe_buffer(struct pipe_buffer *b) } -/** - * Round n up to next multiple. - */ -static INLINE unsigned -round_up(unsigned n, unsigned multiple) -{ - return (n + multiple - 1) & ~(multiple - 1); -} - - static const char * get_name(struct pipe_winsys *pws) { @@ -170,13 +160,10 @@ surface_buffer_create(struct pipe_winsys *winsys, unsigned *stride) { const unsigned alignment = 64; - struct pipe_format_block block; - unsigned nblocksx, nblocksy; + unsigned nblocksy; - pf_get_block(format, &block); - nblocksx = pf_get_nblocksx(&block, width); - nblocksy = pf_get_nblocksy(&block, height); - *stride = round_up(nblocksx * block.size, alignment); + nblocksy = pf_get_nblocksy(format, height); + *stride = align(pf_get_stride(format, width), alignment); return winsys->buffer_create(winsys, alignment, usage, diff --git a/src/gallium/winsys/g3dvl/Makefile b/src/gallium/winsys/g3dvl/Makefile new file mode 100644 index 0000000000..424ddea87a --- /dev/null +++ b/src/gallium/winsys/g3dvl/Makefile @@ -0,0 +1,11 @@ +TOP = ../../../.. +include $(TOP)/configs/current + +SUBDIRS = $(GALLIUM_WINSYS_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/g3dvl/vl_winsys.h b/src/gallium/winsys/g3dvl/vl_winsys.h index c83db28dd9..b4fa0d67a1 100644 --- a/src/gallium/winsys/g3dvl/vl_winsys.h +++ b/src/gallium/winsys/g3dvl/vl_winsys.h @@ -1,14 +1,51 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + #ifndef vl_winsys_h #define vl_winsys_h #include <X11/Xlib.h> +#include <pipe/p_defines.h> +#include <pipe/p_format.h> -struct pipe_context; +struct pipe_screen; +struct pipe_video_context; -struct pipe_context* create_pipe_context(Display *display, int screen); -int destroy_pipe_context(struct pipe_context *pipe); -int bind_pipe_drawable(struct pipe_context *pipe, Drawable drawable); -int unbind_pipe_drawable(struct pipe_context *pipe); +struct pipe_screen* +vl_screen_create(Display *display, int screen); -#endif +struct pipe_video_context* +vl_video_create(Display *display, int screen, + struct pipe_screen *p_screen, + enum pipe_video_profile profile, + enum pipe_video_chroma_format chroma_format, + unsigned width, unsigned height); +Drawable +vl_video_bind_drawable(struct pipe_video_context *vpipe, Drawable drawable); + +#endif diff --git a/src/gallium/winsys/g3dvl/xlib/Makefile b/src/gallium/winsys/g3dvl/xlib/Makefile new file mode 100644 index 0000000000..cf765ef51a --- /dev/null +++ b/src/gallium/winsys/g3dvl/xlib/Makefile @@ -0,0 +1,74 @@ +# This makefile produces a "stand-alone" libXvMCg3dvl.so which is +# based on Xlib (no DRI HW acceleration) + +TOP = ../../../../.. +include $(TOP)/configs/current + +XVMC_MAJOR = 1 +XVMC_MINOR = 0 +XVMC_LIB = XvMCg3dvl +XVMC_LIB_NAME = lib$(XVMC_LIB).so +XVMC_LIB_DEPS = $(EXTRA_LIB_PATH) -lXvMC -lXv -lX11 -lm + +INCLUDES = -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/auxiliary \ + -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/src/gallium/winsys/g3dvl + +DEFINES += -DGALLIUM_SOFTPIPE \ + -DGALLIUM_TRACE + +SOURCES = xsp_winsys.c + +# XXX: Hack, if we include libxvmctracker.a in LIBS none of the symbols are +# pulled in by the linker because xsp_winsys.c doesn't refer to them +OBJECTS = $(SOURCES:.c=.o) $(TOP)/src/gallium/state_trackers/xorg/xvmc/*.o + +LIBS = $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ + $(TOP)/src/gallium/auxiliary/vl/libvl.a \ + $(TOP)/src/gallium/auxiliary/tgsi/libtgsi.a \ + $(TOP)/src/gallium/auxiliary/draw/libdraw.a \ + $(TOP)/src/gallium/auxiliary/translate/libtranslate.a \ + $(TOP)/src/gallium/auxiliary/cso_cache/libcso_cache.a \ + $(TOP)/src/gallium/auxiliary/rtasm/librtasm.a \ + $(TOP)/src/gallium/auxiliary/util/libutil.a + +.c.o: + $(CC) -c $(INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@ + +.S.o: + $(CC) -c $(INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@ + +.PHONY: default $(TOP)/$(LIB_DIR)/gallium clean + +default: depend $(TOP)/$(LIB_DIR)/gallium $(TOP)/$(LIB_DIR)/gallium/$(XVMC_LIB_NAME) + +$(TOP)/$(LIB_DIR)/gallium: + @mkdir -p $(TOP)/$(LIB_DIR)/gallium + +# Make the libXvMCg3dvl.so library +$(TOP)/$(LIB_DIR)/gallium/$(XVMC_LIB_NAME): $(OBJECTS) $(LIBS) Makefile + $(MKLIB) -o $(XVMC_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \ + -major $(XVMC_MAJOR) -minor $(XVMC_MINOR) $(MKLIB_OPTIONS) \ + -install $(TOP)/$(LIB_DIR)/gallium -id $(INSTALL_LIB_DIR)/lib$(XVMC_LIB).1.dylib \ + $(XVMC_LIB_DEPS) $(OBJECTS) $(LIBS) + +depend: $(SOURCES) Makefile + $(RM) depend + touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDES) $(SOURCES) + +#install: default +# $(INSTALL) -d $(INSTALL_DIR)/include/GL +# $(INSTALL) -d $(INSTALL_DIR)/$(LIB_DIR) +# $(INSTALL) -m 644 $(TOP)/include/GL/*.h $(INSTALL_DIR)/include/GL +# @if [ -e $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) ]; then \ +# $(INSTALL) $(TOP)/$(LIB_DIR)/libGL* $(INSTALL_DIR)/$(LIB_DIR); \ +# fi + +clean: Makefile + $(RM) $(TOP)/$(LIB_DIR)/gallium/$(XVMC_LIB_NAME) + $(RM) *.o *~ + $(RM) depend depend.bak + +-include depend diff --git a/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c b/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c new file mode 100644 index 0000000000..b8c8502d7b --- /dev/null +++ b/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c @@ -0,0 +1,329 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include <vl_winsys.h> +#include <X11/Xutil.h> +#include <pipe/internal/p_winsys_screen.h> +#include <pipe/p_state.h> +#include <pipe/p_inlines.h> +#include <util/u_memory.h> +#include <util/u_math.h> +#include <softpipe/sp_winsys.h> +#include <softpipe/sp_video_context.h> +#include <softpipe/sp_texture.h> + +/* pipe_winsys implementation */ + +struct xsp_pipe_winsys +{ + struct pipe_winsys base; + Display *display; + int screen; + XImage *fbimage; +}; + +struct xsp_context +{ + Drawable drawable; + + void (*pipe_destroy)(struct pipe_video_context *vpipe); +}; + +struct xsp_buffer +{ + struct pipe_buffer base; + boolean is_user_buffer; + void *data; + void *mapped_data; +}; + +static struct pipe_buffer* xsp_buffer_create(struct pipe_winsys *pws, unsigned alignment, unsigned usage, unsigned size) +{ + struct xsp_buffer *buffer; + + assert(pws); + + buffer = calloc(1, sizeof(struct xsp_buffer)); + pipe_reference_init(&buffer->base.reference, 1); + buffer->base.alignment = alignment; + buffer->base.usage = usage; + buffer->base.size = size; + buffer->data = align_malloc(size, alignment); + + return (struct pipe_buffer*)buffer; +} + +static struct pipe_buffer* xsp_user_buffer_create(struct pipe_winsys *pws, void *data, unsigned size) +{ + struct xsp_buffer *buffer; + + assert(pws); + + buffer = calloc(1, sizeof(struct xsp_buffer)); + pipe_reference_init(&buffer->base.reference, 1); + buffer->base.size = size; + buffer->is_user_buffer = TRUE; + buffer->data = data; + + return (struct pipe_buffer*)buffer; +} + +static void* xsp_buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buffer, unsigned flags) +{ + struct xsp_buffer *xsp_buf = (struct xsp_buffer*)buffer; + + assert(pws); + assert(buffer); + + xsp_buf->mapped_data = xsp_buf->data; + + return xsp_buf->mapped_data; +} + +static void xsp_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buffer) +{ + struct xsp_buffer *xsp_buf = (struct xsp_buffer*)buffer; + + assert(pws); + assert(buffer); + + xsp_buf->mapped_data = NULL; +} + +static void xsp_buffer_destroy(struct pipe_buffer *buffer) +{ + struct xsp_buffer *xsp_buf = (struct xsp_buffer*)buffer; + + assert(buffer); + + if (!xsp_buf->is_user_buffer) + align_free(xsp_buf->data); + + free(xsp_buf); +} + +static struct pipe_buffer* xsp_surface_buffer_create +( + struct pipe_winsys *pws, + unsigned width, + unsigned height, + enum pipe_format format, + unsigned usage, + unsigned tex_usage, + unsigned *stride +) +{ + const unsigned int ALIGNMENT = 1; + unsigned nblocksy; + + nblocksy = pf_get_nblocksy(format, height); + *stride = align(pf_get_stride(format, width), ALIGNMENT); + + return pws->buffer_create(pws, ALIGNMENT, usage, + *stride * nblocksy); +} + +static void xsp_fence_reference(struct pipe_winsys *pws, struct pipe_fence_handle **ptr, struct pipe_fence_handle *fence) +{ + assert(pws); + assert(ptr); + assert(fence); +} + +static int xsp_fence_signalled(struct pipe_winsys *pws, struct pipe_fence_handle *fence, unsigned flag) +{ + assert(pws); + assert(fence); + + return 0; +} + +static int xsp_fence_finish(struct pipe_winsys *pws, struct pipe_fence_handle *fence, unsigned flag) +{ + assert(pws); + assert(fence); + + return 0; +} + +static void xsp_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surface, void *context_private) +{ + struct xsp_pipe_winsys *xsp_winsys; + struct xsp_context *xsp_context; + + assert(pws); + assert(surface); + assert(context_private); + + xsp_winsys = (struct xsp_pipe_winsys*)pws; + xsp_context = (struct xsp_context*)context_private; + xsp_winsys->fbimage->width = surface->width; + xsp_winsys->fbimage->height = surface->height; + xsp_winsys->fbimage->bytes_per_line = surface->width * (xsp_winsys->fbimage->bits_per_pixel >> 3); + xsp_winsys->fbimage->data = (char*)((struct xsp_buffer *)softpipe_texture(surface->texture)->buffer)->data + surface->offset; + + XPutImage + ( + xsp_winsys->display, xsp_context->drawable, + XDefaultGC(xsp_winsys->display, xsp_winsys->screen), + xsp_winsys->fbimage, 0, 0, 0, 0, + surface->width, surface->height + ); + XFlush(xsp_winsys->display); +} + +static const char* xsp_get_name(struct pipe_winsys *pws) +{ + assert(pws); + return "X11 SoftPipe"; +} + +static void xsp_destroy(struct pipe_winsys *pws) +{ + struct xsp_pipe_winsys *xsp_winsys = (struct xsp_pipe_winsys*)pws; + + assert(pws); + + /* XDestroyImage() wants to free the data as well */ + xsp_winsys->fbimage->data = NULL; + + XDestroyImage(xsp_winsys->fbimage); + FREE(xsp_winsys); +} + +/* Called through pipe_video_context::destroy() */ +static void xsp_pipe_destroy(struct pipe_video_context *vpipe) +{ + struct xsp_context *xsp_context; + + assert(vpipe); + + xsp_context = vpipe->priv; + + /* Call the original destroy */ + xsp_context->pipe_destroy(vpipe); + + FREE(xsp_context); +} + +/* Show starts here */ + +Drawable +vl_video_bind_drawable(struct pipe_video_context *vpipe, Drawable drawable) +{ + struct xsp_context *xsp_context; + Drawable old_drawable; + + assert(vpipe); + + xsp_context = vpipe->priv; + old_drawable = xsp_context->drawable; + xsp_context->drawable = drawable; + + return old_drawable; +} + +struct pipe_screen* +vl_screen_create(Display *display, int screen) +{ + struct xsp_pipe_winsys *xsp_winsys; + + assert(display); + + xsp_winsys = CALLOC_STRUCT(xsp_pipe_winsys); + if (!xsp_winsys) + return NULL; + + xsp_winsys->base.buffer_create = xsp_buffer_create; + xsp_winsys->base.user_buffer_create = xsp_user_buffer_create; + xsp_winsys->base.buffer_map = xsp_buffer_map; + xsp_winsys->base.buffer_unmap = xsp_buffer_unmap; + xsp_winsys->base.buffer_destroy = xsp_buffer_destroy; + xsp_winsys->base.surface_buffer_create = xsp_surface_buffer_create; + xsp_winsys->base.fence_reference = xsp_fence_reference; + xsp_winsys->base.fence_signalled = xsp_fence_signalled; + xsp_winsys->base.fence_finish = xsp_fence_finish; + xsp_winsys->base.flush_frontbuffer = xsp_flush_frontbuffer; + xsp_winsys->base.get_name = xsp_get_name; + xsp_winsys->base.destroy = xsp_destroy; + xsp_winsys->display = display; + xsp_winsys->screen = screen; + xsp_winsys->fbimage = XCreateImage + ( + display, + XDefaultVisual(display, screen), + XDefaultDepth(display, screen), + ZPixmap, + 0, + NULL, + 0, /* Don't know the width and height until flush_frontbuffer */ + 0, + 32, + 0 + ); + + if (!xsp_winsys->fbimage) { + FREE(xsp_winsys); + return NULL; + } + + XInitImage(xsp_winsys->fbimage); + + return softpipe_create_screen(&xsp_winsys->base); +} + +struct pipe_video_context* +vl_video_create(Display *display, int screen, + struct pipe_screen *p_screen, + enum pipe_video_profile profile, + enum pipe_video_chroma_format chroma_format, + unsigned width, unsigned height) +{ + struct pipe_video_context *vpipe; + struct xsp_context *xsp_context; + + assert(p_screen); + assert(width && height); + + vpipe = sp_video_create(p_screen, profile, chroma_format, width, height); + if (!vpipe) + return NULL; + + xsp_context = CALLOC_STRUCT(xsp_context); + if (!xsp_context) { + vpipe->destroy(vpipe); + return NULL; + } + + /* Override this so we can free our xsp_context when the pipe is freed */ + xsp_context->pipe_destroy = vpipe->destroy; + vpipe->destroy = xsp_pipe_destroy; + + vpipe->priv = xsp_context; + + return vpipe; +} diff --git a/src/gallium/winsys/g3dvl/xsp_winsys.c b/src/gallium/winsys/g3dvl/xsp_winsys.c deleted file mode 100644 index 37d60ce540..0000000000 --- a/src/gallium/winsys/g3dvl/xsp_winsys.c +++ /dev/null @@ -1,291 +0,0 @@ -#include "vl_winsys.h" -#include <X11/Xutil.h> -#include <pipe/internal/p_winsys_screen.h> -#include <pipe/p_state.h> -#include <pipe/p_inlines.h> -#include <util/u_memory.h> -#include <util/u_math.h> -#include <softpipe/sp_winsys.h> -#include <softpipe/sp_texture.h> - -/* pipe_winsys implementation */ - -struct xsp_pipe_winsys -{ - struct pipe_winsys base; - XImage fbimage; -}; - -struct xsp_context -{ - Display *display; - int screen; - Drawable drawable; - int drawable_bound; -}; - -struct xsp_buffer -{ - struct pipe_buffer base; - boolean is_user_buffer; - void *data; - void *mapped_data; -}; - -static struct pipe_buffer* xsp_buffer_create(struct pipe_winsys *pws, unsigned alignment, unsigned usage, unsigned size) -{ - struct xsp_buffer *buffer; - - assert(pws); - - buffer = calloc(1, sizeof(struct xsp_buffer)); - pipe_reference_init(&buffer->base.reference, 1); - buffer->base.alignment = alignment; - buffer->base.usage = usage; - buffer->base.size = size; - buffer->data = align_malloc(size, alignment); - - return (struct pipe_buffer*)buffer; -} - -static struct pipe_buffer* xsp_user_buffer_create(struct pipe_winsys *pws, void *data, unsigned size) -{ - struct xsp_buffer *buffer; - - assert(pws); - - buffer = calloc(1, sizeof(struct xsp_buffer)); - pipe_reference_init(&buffer->base.reference, 1); - buffer->base.size = size; - buffer->is_user_buffer = TRUE; - buffer->data = data; - - return (struct pipe_buffer*)buffer; -} - -static void* xsp_buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buffer, unsigned flags) -{ - struct xsp_buffer *xsp_buf = (struct xsp_buffer*)buffer; - - assert(pws); - assert(buffer); - - xsp_buf->mapped_data = xsp_buf->data; - - return xsp_buf->mapped_data; -} - -static void xsp_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buffer) -{ - struct xsp_buffer *xsp_buf = (struct xsp_buffer*)buffer; - - assert(pws); - assert(buffer); - - xsp_buf->mapped_data = NULL; -} - -static void xsp_buffer_destroy(struct pipe_winsys *pws, struct pipe_buffer *buffer) -{ - struct xsp_buffer *xsp_buf = (struct xsp_buffer*)buffer; - - assert(pws); - assert(buffer); - - if (!xsp_buf->is_user_buffer) - align_free(xsp_buf->data); - - free(xsp_buf); -} - -static struct pipe_buffer* xsp_surface_buffer_create -( - struct pipe_winsys *pws, - unsigned width, - unsigned height, - enum pipe_format format, - unsigned usage, - unsigned tex_usage, - unsigned *stride -) -{ - const unsigned int ALIGNMENT = 1; - struct pipe_format_block block; - unsigned nblocksx, nblocksy; - - pf_get_block(format, &block); - nblocksx = pf_get_nblocksx(&block, width); - nblocksy = pf_get_nblocksy(&block, height); - *stride = align(nblocksx * block.size, ALIGNMENT); - - return pws->buffer_create(pws, ALIGNMENT, - usage, - *stride * nblocksy); -} - -static void xsp_fence_reference(struct pipe_winsys *pws, struct pipe_fence_handle **ptr, struct pipe_fence_handle *fence) -{ - assert(pws); - assert(ptr); - assert(fence); -} - -static int xsp_fence_signalled(struct pipe_winsys *pws, struct pipe_fence_handle *fence, unsigned flag) -{ - assert(pws); - assert(fence); - - return 0; -} - -static int xsp_fence_finish(struct pipe_winsys *pws, struct pipe_fence_handle *fence, unsigned flag) -{ - assert(pws); - assert(fence); - - return 0; -} - -static void xsp_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surface, void *context_private) -{ - struct xsp_pipe_winsys *xsp_winsys; - struct xsp_context *xsp_context; - - assert(pws); - assert(surface); - assert(context_private); - - xsp_winsys = (struct xsp_pipe_winsys*)pws; - xsp_context = (struct xsp_context*)context_private; - - if (!xsp_context->drawable_bound) - return; - - xsp_winsys->fbimage.width = surface->width; - xsp_winsys->fbimage.height = surface->height; - xsp_winsys->fbimage.bytes_per_line = surface->width * (xsp_winsys->fbimage.bits_per_pixel >> 3); - xsp_winsys->fbimage.data = ((struct xsp_buffer *)softpipe_texture(surface->texture)->buffer)->data + surface->offset; - - XPutImage - ( - xsp_context->display, - xsp_context->drawable, - XDefaultGC(xsp_context->display, xsp_context->screen), - &xsp_winsys->fbimage, - 0, - 0, - 0, - 0, - surface->width, - surface->height - ); - XFlush(xsp_context->display); -} - -static const char* xsp_get_name(struct pipe_winsys *pws) -{ - assert(pws); - return "X11 SoftPipe"; -} - -/* Show starts here */ - -int bind_pipe_drawable(struct pipe_context *pipe, Drawable drawable) -{ - struct xsp_context *xsp_context; - - assert(pipe); - - xsp_context = pipe->priv; - xsp_context->drawable = drawable; - xsp_context->drawable_bound = 1; - - return 0; -} - -int unbind_pipe_drawable(struct pipe_context *pipe) -{ - struct xsp_context *xsp_context; - - assert(pipe); - - xsp_context = pipe->priv; - xsp_context->drawable_bound = 0; - - return 0; -} - -struct pipe_context* create_pipe_context(Display *display, int screen) -{ - struct xsp_pipe_winsys *xsp_winsys; - struct xsp_context *xsp_context; - struct pipe_screen *sp_screen; - struct pipe_context *sp_pipe; - - assert(display); - - xsp_winsys = calloc(1, sizeof(struct xsp_pipe_winsys)); - xsp_winsys->base.buffer_create = xsp_buffer_create; - xsp_winsys->base.user_buffer_create = xsp_user_buffer_create; - xsp_winsys->base.buffer_map = xsp_buffer_map; - xsp_winsys->base.buffer_unmap = xsp_buffer_unmap; - xsp_winsys->base.buffer_destroy = xsp_buffer_destroy; - xsp_winsys->base.surface_buffer_create = xsp_surface_buffer_create; - xsp_winsys->base.fence_reference = xsp_fence_reference; - xsp_winsys->base.fence_signalled = xsp_fence_signalled; - xsp_winsys->base.fence_finish = xsp_fence_finish; - xsp_winsys->base.flush_frontbuffer = xsp_flush_frontbuffer; - xsp_winsys->base.get_name = xsp_get_name; - - { - /* XXX: Can't use the returned XImage* directly, - since we don't have control over winsys destruction - and we wouldn't be able to free it */ - XImage *template = XCreateImage - ( - display, - XDefaultVisual(display, XDefaultScreen(display)), - XDefaultDepth(display, XDefaultScreen(display)), - ZPixmap, - 0, - NULL, - 0, /* Don't know the width and height until flush_frontbuffer */ - 0, - 32, - 0 - ); - - memcpy(&xsp_winsys->fbimage, template, sizeof(XImage)); - XInitImage(&xsp_winsys->fbimage); - - XDestroyImage(template); - } - - sp_screen = softpipe_create_screen((struct pipe_winsys*)xsp_winsys); - sp_pipe = softpipe_create(sp_screen); - - xsp_context = calloc(1, sizeof(struct xsp_context)); - xsp_context->display = display; - xsp_context->screen = screen; - - sp_pipe->priv = xsp_context; - - return sp_pipe; -} - -int destroy_pipe_context(struct pipe_context *pipe) -{ - struct pipe_screen *screen; - struct pipe_winsys *winsys; - - assert(pipe); - - screen = pipe->screen; - winsys = pipe->winsys; - free(pipe->priv); - pipe->destroy(pipe); - screen->destroy(screen); - free(winsys); - - return 0; -} diff --git a/src/gallium/winsys/gdi/SConscript b/src/gallium/winsys/gdi/SConscript index 9fbe9e800c..74f6b2fd47 100644 --- a/src/gallium/winsys/gdi/SConscript +++ b/src/gallium/winsys/gdi/SConscript @@ -18,14 +18,20 @@ if env['platform'] == 'windows': 'ws2_32', ]) - if 'llvmpipe' in env['drivers']: - sources = ['gdi_llvmpipe_winsys.c'] - drivers = [llvmpipe] - env.Tool('llvm') - elif 'softpipe' in env['drivers']: + sources = [] + drivers = [] + + if 'softpipe' in env['drivers']: sources = ['gdi_softpipe_winsys.c'] drivers = [softpipe] - else: + + if 'llvmpipe' in env['drivers']: + env.Tool('llvm') + if 'LLVM_VERSION' in env: + sources = ['gdi_llvmpipe_winsys.c'] + drivers = [llvmpipe] + + if not sources or not drivers: print 'warning: softpipe or llvmpipe not selected, gdi winsys disabled' Return() diff --git a/src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c b/src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c index c0c33b45d5..81c46c0a96 100644 --- a/src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c +++ b/src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c @@ -43,13 +43,12 @@ #include "util/u_memory.h" #include "llvmpipe/lp_winsys.h" #include "llvmpipe/lp_texture.h" -#include "shared/stw_winsys.h" +#include "stw_winsys.h" struct gdi_llvmpipe_displaytarget { enum pipe_format format; - struct pipe_format_block block; unsigned width; unsigned height; unsigned stride; @@ -118,16 +117,6 @@ gdi_llvmpipe_displaytarget_destroy(struct llvmpipe_winsys *winsys, } -/** - * Round n up to next multiple. - */ -static INLINE unsigned -round_up(unsigned n, unsigned multiple) -{ - return (n + multiple - 1) & ~(multiple - 1); -} - - static struct llvmpipe_displaytarget * gdi_llvmpipe_displaytarget_create(struct llvmpipe_winsys *winsys, enum pipe_format format, @@ -147,10 +136,10 @@ gdi_llvmpipe_displaytarget_create(struct llvmpipe_winsys *winsys, gdt->width = width; gdt->height = height; - bpp = pf_get_bits(format); - cpp = pf_get_size(format); + bpp = pf_get_blocksizebits(format); + cpp = pf_get_blocksize(format); - gdt->stride = round_up(width * cpp, alignment); + gdt->stride = align(width * cpp, alignment); gdt->size = gdt->stride * height; gdt->data = align_malloc(gdt->size, alignment); @@ -234,9 +223,9 @@ gdi_llvmpipe_context_create(struct pipe_screen *screen) static void -gdi_llvmpipe_flush_frontbuffer(struct pipe_screen *screen, - struct pipe_surface *surface, - HDC hDC) +gdi_llvmpipe_present(struct pipe_screen *screen, + struct pipe_surface *surface, + HDC hDC) { struct llvmpipe_texture *texture; struct gdi_llvmpipe_displaytarget *gdt; @@ -254,7 +243,11 @@ gdi_llvmpipe_flush_frontbuffer(struct pipe_screen *screen, static const struct stw_winsys stw_winsys = { &gdi_llvmpipe_screen_create, &gdi_llvmpipe_context_create, - &gdi_llvmpipe_flush_frontbuffer + &gdi_llvmpipe_present, + NULL, /* get_adapter_luid */ + NULL, /* shared_surface_open */ + NULL, /* shared_surface_close */ + NULL /* compose */ }; diff --git a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c index 66120a6a98..173fa5b6fe 100644 --- a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c +++ b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c @@ -46,7 +46,7 @@ #include "util/u_memory.h" #include "softpipe/sp_winsys.h" #include "softpipe/sp_texture.h" -#include "shared/stw_winsys.h" +#include "stw_winsys.h" struct gdi_softpipe_buffer @@ -151,16 +151,6 @@ gdi_softpipe_user_buffer_create(struct pipe_winsys *winsys, } -/** - * Round n up to next multiple. - */ -static INLINE unsigned -round_up(unsigned n, unsigned multiple) -{ - return (n + multiple - 1) & ~(multiple - 1); -} - - static struct pipe_buffer * gdi_softpipe_surface_buffer_create(struct pipe_winsys *winsys, unsigned width, unsigned height, @@ -170,13 +160,10 @@ gdi_softpipe_surface_buffer_create(struct pipe_winsys *winsys, unsigned *stride) { const unsigned alignment = 64; - struct pipe_format_block block; - unsigned nblocksx, nblocksy; + unsigned nblocksy; - pf_get_block(format, &block); - nblocksx = pf_get_nblocksx(&block, width); - nblocksy = pf_get_nblocksy(&block, height); - *stride = round_up(nblocksx * block.size, alignment); + nblocksy = pf_get_nblocksy(format, height); + *stride = align(pf_get_stride(format, width), alignment); return winsys->buffer_create(winsys, alignment, usage, @@ -269,9 +256,9 @@ gdi_softpipe_context_create(struct pipe_screen *screen) static void -gdi_softpipe_flush_frontbuffer(struct pipe_screen *screen, - struct pipe_surface *surface, - HDC hDC) +gdi_softpipe_present(struct pipe_screen *screen, + struct pipe_surface *surface, + HDC hDC) { struct softpipe_texture *texture; struct gdi_softpipe_buffer *buffer; @@ -283,10 +270,10 @@ gdi_softpipe_flush_frontbuffer(struct pipe_screen *screen, memset(&bmi, 0, sizeof(BITMAPINFO)); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bmi.bmiHeader.biWidth = texture->stride[surface->level] / pf_get_size(surface->format); + bmi.bmiHeader.biWidth = texture->stride[surface->level] / pf_get_blocksize(surface->format); bmi.bmiHeader.biHeight= -(long)surface->height; bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biBitCount = pf_get_bits(surface->format); + bmi.bmiHeader.biBitCount = pf_get_blocksizebits(surface->format); bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biSizeImage = 0; bmi.bmiHeader.biXPelsPerMeter = 0; @@ -304,7 +291,11 @@ gdi_softpipe_flush_frontbuffer(struct pipe_screen *screen, static const struct stw_winsys stw_winsys = { &gdi_softpipe_screen_create, &gdi_softpipe_context_create, - &gdi_softpipe_flush_frontbuffer + &gdi_softpipe_present, + NULL, /* get_adapter_luid */ + NULL, /* shared_surface_open */ + NULL, /* shared_surface_close */ + NULL /* compose */ }; diff --git a/src/gallium/winsys/xlib/Makefile b/src/gallium/winsys/xlib/Makefile index 3a1945d92c..3dc38a78e4 100644 --- a/src/gallium/winsys/xlib/Makefile +++ b/src/gallium/winsys/xlib/Makefile @@ -31,9 +31,6 @@ DEFINES += \ XLIB_WINSYS_SOURCES = \ xlib.c \ xlib_cell.c \ - xlib_brw_aub.c \ - xlib_brw_context.c \ - xlib_brw_screen.c \ xlib_llvmpipe.c \ xlib_softpipe.c \ xlib_trace.c diff --git a/src/gallium/winsys/xlib/SConscript b/src/gallium/winsys/xlib/SConscript index 467d595d33..dfe550f733 100644 --- a/src/gallium/winsys/xlib/SConscript +++ b/src/gallium/winsys/xlib/SConscript @@ -5,7 +5,7 @@ Import('*') if env['platform'] == 'linux' \ and 'mesa' in env['statetrackers'] \ - and set(('softpipe', 'llvmpipe', 'i915simple', 'trace')).intersection(env['drivers']) \ + and set(('softpipe', 'llvmpipe', 'i915', 'trace')).intersection(env['drivers']) \ and not env['dri']: env = env.Clone() @@ -36,15 +36,6 @@ if env['platform'] == 'linux' \ env.Tool('udis86') sources += ['xlib_llvmpipe.c'] drivers += [llvmpipe] - - if 'i965simple' in env['drivers']: - env.Append(CPPDEFINES = 'GALLIUM_I965SIMPLE') - sources += [ - 'xlib_brw_aub.c', - 'xlib_brw_context.c', - 'xlib_brw_screen.c', - ] - drivers += [i965simple] if 'cell' in env['drivers']: env.Append(CPPDEFINES = 'GALLIUM_CELL') diff --git a/src/gallium/winsys/xlib/xlib.c b/src/gallium/winsys/xlib/xlib.c index 4b71cf7ec3..163cc8863c 100644 --- a/src/gallium/winsys/xlib/xlib.c +++ b/src/gallium/winsys/xlib/xlib.c @@ -43,7 +43,6 @@ enum mode { MODE_TRACE, - MODE_BRW, MODE_CELL, MODE_LLVMPIPE, MODE_SOFTPIPE @@ -55,9 +54,6 @@ static enum mode get_mode() if (getenv("XMESA_TRACE")) return MODE_TRACE; - if (getenv("XMESA_BRW")) - return MODE_BRW; - #ifdef GALLIUM_CELL if (!getenv("GALLIUM_NOCELL")) return MODE_CELL; @@ -82,11 +78,6 @@ static void _init( void ) xmesa_set_driver( &xlib_trace_driver ); #endif break; - case MODE_BRW: -#if defined(GALLIUM_BRW) - xmesa_set_driver( &xlib_brw_driver ); -#endif - break; case MODE_CELL: #if defined(GALLIUM_CELL) xmesa_set_driver( &xlib_cell_driver ); diff --git a/src/gallium/winsys/xlib/xlib.h b/src/gallium/winsys/xlib/xlib.h index 347d45f4d6..f0855035f7 100644 --- a/src/gallium/winsys/xlib/xlib.h +++ b/src/gallium/winsys/xlib/xlib.h @@ -9,7 +9,6 @@ extern struct xm_driver xlib_trace_driver; extern struct xm_driver xlib_softpipe_driver; extern struct xm_driver xlib_llvmpipe_driver; extern struct xm_driver xlib_cell_driver; -extern struct xm_driver xlib_brw_driver; #endif diff --git a/src/gallium/winsys/xlib/xlib_brw.h b/src/gallium/winsys/xlib/xlib_brw.h deleted file mode 100644 index be2dd147db..0000000000 --- a/src/gallium/winsys/xlib/xlib_brw.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef XLIB_BRW_H -#define XLIB_BRW_H - -struct pipe_winsys; -struct pipe_buffer; -struct pipe_surface; -struct xmesa_buffer; - -unsigned xlib_brw_get_buffer_offset( struct pipe_winsys *pws, - struct pipe_buffer *buf, - unsigned access_flags ); - -void xlib_brw_buffer_subdata_typed( struct pipe_winsys *pws, - struct pipe_buffer *buf, - unsigned long offset, - unsigned long size, - const void *data, - unsigned data_type ); - - - -void xlib_brw_commands_aub(struct pipe_winsys *winsys, - unsigned *cmds, - unsigned nr_dwords); - -struct pipe_context * -xlib_create_brw_context( struct pipe_screen *screen, - void *unused ); - -#endif diff --git a/src/gallium/winsys/xlib/xlib_brw_aub.c b/src/gallium/winsys/xlib/xlib_brw_aub.c deleted file mode 100644 index b6bd849ef2..0000000000 --- a/src/gallium/winsys/xlib/xlib_brw_aub.c +++ /dev/null @@ -1,399 +0,0 @@ -/* - Copyright (C) Intel Corp. 2006. All Rights Reserved. - Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to - develop this 3D driver. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice (including the - next paragraph) shall be included in all copies or substantial - portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. - - **********************************************************************/ - /* - * Authors: - * Keith Whitwell <keith@tungstengraphics.com> - */ - -#include <stdio.h> -#include <stdlib.h> -#include "xlib_brw_aub.h" -#include "pipe/p_context.h" -#include "pipe/p_state.h" -#include "util/u_debug.h" -#include "util/u_memory.h" -#include "softpipe/sp_texture.h" - - -struct brw_aubfile { - FILE *file; - unsigned next_free_page; -}; - - -extern char *__progname; - - -struct aub_file_header { - unsigned int instruction_type; - unsigned int pad0:16; - unsigned int minor:8; - unsigned int major:8; - unsigned char application[8*4]; - unsigned int day:8; - unsigned int month:8; - unsigned int year:16; - unsigned int timezone:8; - unsigned int second:8; - unsigned int minute:8; - unsigned int hour:8; - unsigned int comment_length:16; - unsigned int pad1:16; -}; - -struct aub_block_header { - unsigned int instruction_type; - unsigned int operation:8; - unsigned int type:8; - unsigned int address_space:8; - unsigned int pad0:8; - unsigned int general_state_type:8; - unsigned int surface_state_type:8; - unsigned int pad1:16; - unsigned int address; - unsigned int length; -}; - -struct aub_dump_bmp { - unsigned int instruction_type; - unsigned int xmin:16; - unsigned int ymin:16; - unsigned int pitch:16; - unsigned int bpp:8; - unsigned int format:8; - unsigned int xsize:16; - unsigned int ysize:16; - unsigned int addr; - unsigned int unknown; -}; - -enum bh_operation { - BH_COMMENT, - BH_DATA_WRITE, - BH_COMMAND_WRITE, - BH_MMI0_WRITE32, - BH_END_SCENE, - BH_CONFIG_MEMORY_MAP, - BH_MAX_OPERATION -}; - -enum command_write_type { - CW_HWB_RING = 1, - CW_PRIMARY_RING_A, - CW_PRIMARY_RING_B, /* XXX - disagreement with listaub! */ - CW_PRIMARY_RING_C, - CW_MAX_TYPE -}; - -enum memory_map_type { - MM_DEFAULT, - MM_DYNAMIC, - MM_MAX_TYPE -}; - -enum address_space { - ADDR_GTT, - ADDR_LOCAL, - ADDR_MAIN, - ADDR_MAX -}; - - -#define AUB_FILE_HEADER 0xe085000b -#define AUB_BLOCK_HEADER 0xe0c10003 -#define AUB_DUMP_BMP 0xe09e0004 - -/* Registers to control page table - */ -#define PGETBL_CTL 0x2020 -#define PGETBL_ENABLED 0x1 - -#define NR_GTT_ENTRIES 65536 /* 256 mb */ - -#define FAIL \ -do { \ - fprintf(stderr, "failed to write aub data at %s/%d\n", __FUNCTION__, __LINE__); \ - exit(1); \ -} while (0) - - -/* Emit the headers at the top of each aubfile. Initialize the GTT. - */ -static void init_aubfile( FILE *aub_file ) -{ - struct aub_file_header fh; - struct aub_block_header bh; - unsigned int data; - - static int nr; - - nr++; - - /* Emit the aub header: - */ - memset(&fh, 0, sizeof(fh)); - - fh.instruction_type = AUB_FILE_HEADER; - fh.minor = 0x0; - fh.major = 0x7; - memcpy(fh.application, __progname, sizeof(fh.application)); - fh.day = (nr>>24) & 0xff; - fh.month = 0x0; - fh.year = 0x0; - fh.timezone = 0x0; - fh.second = nr & 0xff; - fh.minute = (nr>>8) & 0xff; - fh.hour = (nr>>16) & 0xff; - fh.comment_length = 0x0; - - if (fwrite(&fh, sizeof(fh), 1, aub_file) < 0) - FAIL; - - /* Setup the GTT starting at main memory address zero (!): - */ - memset(&bh, 0, sizeof(bh)); - - bh.instruction_type = AUB_BLOCK_HEADER; - bh.operation = BH_MMI0_WRITE32; - bh.type = 0x0; - bh.address_space = ADDR_GTT; /* ??? */ - bh.general_state_type = 0x0; - bh.surface_state_type = 0x0; - bh.address = PGETBL_CTL; - bh.length = 0x4; - - if (fwrite(&bh, sizeof(bh), 1, aub_file) < 0) - FAIL; - - data = 0x0 | PGETBL_ENABLED; - - if (fwrite(&data, sizeof(data), 1, aub_file) < 0) - FAIL; -} - - -static void init_aub_gtt( struct brw_aubfile *aubfile, - unsigned start_offset, - unsigned size ) -{ - FILE *aub_file = aubfile->file; - struct aub_block_header bh; - unsigned int i; - - assert(start_offset + size < NR_GTT_ENTRIES * 4096); - - - memset(&bh, 0, sizeof(bh)); - - bh.instruction_type = AUB_BLOCK_HEADER; - bh.operation = BH_DATA_WRITE; - bh.type = 0x0; - bh.address_space = ADDR_MAIN; - bh.general_state_type = 0x0; - bh.surface_state_type = 0x0; - bh.address = start_offset / 4096 * 4; - bh.length = size / 4096 * 4; - - if (fwrite(&bh, sizeof(bh), 1, aub_file) < 0) - FAIL; - - for (i = 0; i < size / 4096; i++) { - unsigned data = aubfile->next_free_page | 1; - - aubfile->next_free_page += 4096; - - if (fwrite(&data, sizeof(data), 1, aub_file) < 0) - FAIL; - } - -} - -static void write_block_header( FILE *aub_file, - struct aub_block_header *bh, - const unsigned *data, - unsigned sz ) -{ - sz = (sz + 3) & ~3; - - if (fwrite(bh, sizeof(*bh), 1, aub_file) < 0) - FAIL; - - if (fwrite(data, sz, 1, aub_file) < 0) - FAIL; - - fflush(aub_file); -} - - -static void write_dump_bmp( FILE *aub_file, - struct aub_dump_bmp *db ) -{ - if (fwrite(db, sizeof(*db), 1, aub_file) < 0) - FAIL; - - fflush(aub_file); -} - - - -void brw_aub_gtt_data( struct brw_aubfile *aubfile, - unsigned offset, - const void *data, - unsigned sz, - unsigned type, - unsigned state_type ) -{ - struct aub_block_header bh; - - bh.instruction_type = AUB_BLOCK_HEADER; - bh.operation = BH_DATA_WRITE; - bh.type = type; - bh.address_space = ADDR_GTT; - bh.pad0 = 0; - - if (type == DW_GENERAL_STATE) { - bh.general_state_type = state_type; - bh.surface_state_type = 0; - } - else { - bh.general_state_type = 0; - bh.surface_state_type = state_type; - } - - bh.pad1 = 0; - bh.address = offset; - bh.length = sz; - - write_block_header(aubfile->file, &bh, data, sz); -} - - - -void brw_aub_gtt_cmds( struct brw_aubfile *aubfile, - unsigned offset, - const void *data, - unsigned sz ) -{ - struct aub_block_header bh; - unsigned type = CW_PRIMARY_RING_A; - - - bh.instruction_type = AUB_BLOCK_HEADER; - bh.operation = BH_COMMAND_WRITE; - bh.type = type; - bh.address_space = ADDR_GTT; - bh.pad0 = 0; - bh.general_state_type = 0; - bh.surface_state_type = 0; - bh.pad1 = 0; - bh.address = offset; - bh.length = sz; - - write_block_header(aubfile->file, &bh, data, sz); -} - -void brw_aub_dump_bmp( struct brw_aubfile *aubfile, - struct pipe_surface *surface, - unsigned gtt_offset ) -{ - struct aub_dump_bmp db; - unsigned format; - - assert(surface->texture->block.width == 1); - assert(surface->texture->block.height == 1); - - if (surface->texture->block.size == 4) - format = 0x7; - else - format = 0x3; - - db.instruction_type = AUB_DUMP_BMP; - db.xmin = 0; - db.ymin = 0; - db.format = format; - db.bpp = surface->texture->block.size * 8; - db.pitch = softpipe_texture(surface->texture)->stride[surface->level] / - surface->texture->block.size; - db.xsize = surface->width; - db.ysize = surface->height; - db.addr = gtt_offset; - db.unknown = /* surface->tiled ? 0x4 : */ 0x0; - - write_dump_bmp(aubfile->file, &db); -} - - - -struct brw_aubfile *brw_aubfile_create( void ) -{ - struct brw_aubfile *aubfile = CALLOC_STRUCT(brw_aubfile); - char filename[80]; - int val; - static int i = 0; - - i++; - - if (getenv("INTEL_AUBFILE")) { - val = snprintf(filename, sizeof(filename), "%s%d.aub", getenv("INTEL_AUBFILE"), i%4); - debug_printf("--> Aub file: %s\n", filename); - aubfile->file = fopen(filename, "w"); - } - else { - val = snprintf(filename, sizeof(filename), "%s.aub", __progname); - if (val < 0 || val > sizeof(filename)) - strcpy(filename, "default.aub"); - - debug_printf("--> Aub file: %s\n", filename); - aubfile->file = fopen(filename, "w"); - } - - if (!aubfile->file) { - debug_printf("couldn't open aubfile\n"); - exit(1); - } - - init_aubfile(aubfile->file); - - /* The GTT is located starting address zero in main memory. Pages - * to populate the gtt start after this point. - */ - aubfile->next_free_page = (NR_GTT_ENTRIES * 4 + 4095) & ~4095; - - /* More or less correspond with all the agp regions mapped by the - * driver: - */ - init_aub_gtt(aubfile, 0, 4096*4); - init_aub_gtt(aubfile, AUB_BUF_START, AUB_BUF_SIZE); - - return aubfile; -} - -void brw_aub_destroy( struct brw_aubfile *aubfile ) -{ - fclose(aubfile->file); - FREE(aubfile); -} diff --git a/src/gallium/winsys/xlib/xlib_brw_aub.h b/src/gallium/winsys/xlib/xlib_brw_aub.h deleted file mode 100644 index f5c60c7be2..0000000000 --- a/src/gallium/winsys/xlib/xlib_brw_aub.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - Copyright (C) Intel Corp. 2006. All Rights Reserved. - Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to - develop this 3D driver. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice (including the - next paragraph) shall be included in all copies or substantial - portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. - - **********************************************************************/ - /* - * Authors: - * Keith Whitwell <keith@tungstengraphics.com> - */ - -#ifndef BRW_AUB_H -#define BRW_AUB_H - -/* We set up this region, buffers may be allocated here: - */ -#define AUB_BUF_START (4096*4) -#define AUB_BUF_SIZE (8*1024*1024) - -struct intel_context; -struct pipe_surface; - -struct brw_aubfile *brw_aubfile_create( void ); - -void brw_aub_destroy( struct brw_aubfile *aubfile ); - -void brw_aub_gtt_data( struct brw_aubfile *aubfile, - unsigned offset, - const void *data, - unsigned sz, - unsigned type, - unsigned state_type ); - -void brw_aub_gtt_cmds( struct brw_aubfile *aubfile, - unsigned offset, - const void *data, - unsigned sz ); - -void brw_aub_dump_bmp( struct brw_aubfile *aubfile, - struct pipe_surface *surface, - unsigned gtt_offset ); - - -enum data_write_type { - DW_NOTYPE, - DW_BATCH_BUFFER, - DW_BIN_BUFFER, - DW_BIN_POINTER_LIST, - DW_SLOW_STATE_BUFFER, - DW_VERTEX_BUFFER, - DW_2D_MAP, - DW_CUBE_MAP, - DW_INDIRECT_STATE_BUFFER, - DW_VOLUME_MAP, - DW_1D_MAP, - DW_CONSTANT_BUFFER, - DW_CONSTANT_URB_ENTRY, - DW_INDEX_BUFFER, - DW_GENERAL_STATE, - DW_SURFACE_STATE, - DW_MEDIA_OBJECT_INDIRECT_DATA, - DW_MAX_TYPE -}; - -enum data_write_general_state_type { - DWGS_NOTYPE, - DWGS_VERTEX_SHADER_STATE, - DWGS_GEOMETRY_SHADER_STATE , - DWGS_CLIPPER_STATE, - DWGS_STRIPS_FANS_STATE, - DWGS_WINDOWER_IZ_STATE, - DWGS_COLOR_CALC_STATE, - DWGS_CLIPPER_VIEWPORT_STATE, /* was 0x7 */ - DWGS_STRIPS_FANS_VIEWPORT_STATE, - DWGS_COLOR_CALC_VIEWPORT_STATE, /* was 0x9 */ - DWGS_SAMPLER_STATE, - DWGS_KERNEL_INSTRUCTIONS, - DWGS_SCRATCH_SPACE, - DWGS_SAMPLER_DEFAULT_COLOR, - DWGS_INTERFACE_DESCRIPTOR, - DWGS_VLD_STATE, - DWGS_VFE_STATE, - DWGS_MAX_TYPE -}; - -enum data_write_surface_state_type { - DWSS_NOTYPE, - DWSS_BINDING_TABLE_STATE, - DWSS_SURFACE_STATE, - DWSS_MAX_TYPE -}; - - -#endif diff --git a/src/gallium/winsys/xlib/xlib_brw_context.c b/src/gallium/winsys/xlib/xlib_brw_context.c deleted file mode 100644 index 09599507f4..0000000000 --- a/src/gallium/winsys/xlib/xlib_brw_context.c +++ /dev/null @@ -1,209 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., 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 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. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ - -/* - * Authors: - * Keith Whitwell - * Brian Paul - */ - - -//#include "glxheader.h" -//#include "xmesaP.h" - -#include "pipe/internal/p_winsys_screen.h" -#include "pipe/p_inlines.h" -#include "util/u_math.h" -#include "util/u_memory.h" -#include "i965simple/brw_winsys.h" -#include "xlib_brw_aub.h" -#include "xlib_brw.h" - - - - -#define XBCWS_BATCHBUFFER_SIZE 1024 - - -/* The backend to the brw driver (ie struct brw_winsys) is actually a - * per-context entity. - */ -struct xlib_brw_context_winsys { - struct brw_winsys brw_context_winsys; /**< batch buffer funcs */ - struct aub_context *aub; - - struct pipe_winsys *pipe_winsys; - - unsigned batch_data[XBCWS_BATCHBUFFER_SIZE]; - unsigned batch_nr; - unsigned batch_size; - unsigned batch_alloc; -}; - - -/* Turn a brw_winsys into an xlib_brw_context_winsys: - */ -static inline struct xlib_brw_context_winsys * -xlib_brw_context_winsys( struct brw_winsys *sws ) -{ - return (struct xlib_brw_context_winsys *)sws; -} - - -/* Simple batchbuffer interface: - */ - -static unsigned *xbcws_batch_start( struct brw_winsys *sws, - unsigned dwords, - unsigned relocs ) -{ - struct xlib_brw_context_winsys *xbcws = xlib_brw_context_winsys(sws); - - if (xbcws->batch_size < xbcws->batch_nr + dwords) - return NULL; - - xbcws->batch_alloc = xbcws->batch_nr + dwords; - return (void *)1; /* not a valid pointer! */ -} - -static void xbcws_batch_dword( struct brw_winsys *sws, - unsigned dword ) -{ - struct xlib_brw_context_winsys *xbcws = xlib_brw_context_winsys(sws); - - assert(xbcws->batch_nr < xbcws->batch_alloc); - xbcws->batch_data[xbcws->batch_nr++] = dword; -} - -static void xbcws_batch_reloc( struct brw_winsys *sws, - struct pipe_buffer *buf, - unsigned access_flags, - unsigned delta ) -{ - struct xlib_brw_context_winsys *xbcws = xlib_brw_context_winsys(sws); - - assert(xbcws->batch_nr < xbcws->batch_alloc); - xbcws->batch_data[xbcws->batch_nr++] = - ( xlib_brw_get_buffer_offset( NULL, buf, access_flags ) + - delta ); -} - -static void xbcws_batch_end( struct brw_winsys *sws ) -{ - struct xlib_brw_context_winsys *xbcws = xlib_brw_context_winsys(sws); - - assert(xbcws->batch_nr <= xbcws->batch_alloc); - xbcws->batch_alloc = 0; -} - -static void xbcws_batch_flush( struct brw_winsys *sws, - struct pipe_fence_handle **fence ) -{ - struct xlib_brw_context_winsys *xbcws = xlib_brw_context_winsys(sws); - assert(xbcws->batch_nr <= xbcws->batch_size); - - if (xbcws->batch_nr) { - xlib_brw_commands_aub( xbcws->pipe_winsys, - xbcws->batch_data, - xbcws->batch_nr ); - } - - xbcws->batch_nr = 0; -} - - - -/* Really a per-device function, just pass through: - */ -static unsigned xbcws_get_buffer_offset( struct brw_winsys *sws, - struct pipe_buffer *buf, - unsigned access_flags ) -{ - struct xlib_brw_context_winsys *xbcws = xlib_brw_context_winsys(sws); - - return xlib_brw_get_buffer_offset( xbcws->pipe_winsys, - buf, - access_flags ); -} - - -/* Really a per-device function, just pass through: - */ -static void xbcws_buffer_subdata_typed( struct brw_winsys *sws, - struct pipe_buffer *buf, - unsigned long offset, - unsigned long size, - const void *data, - unsigned data_type ) -{ - struct xlib_brw_context_winsys *xbcws = xlib_brw_context_winsys(sws); - - xlib_brw_buffer_subdata_typed( xbcws->pipe_winsys, - buf, - offset, - size, - data, - data_type ); -} - - -/** - * Create i965 hardware rendering context, but plugged into a - * dump-to-aubfile backend. - */ -struct pipe_context * -xlib_create_brw_context( struct pipe_screen *screen, - void *unused ) -{ - struct xlib_brw_context_winsys *xbcws = CALLOC_STRUCT( xlib_brw_context_winsys ); - - /* Fill in this struct with callbacks that i965simple will need to - * communicate with the window system, buffer manager, etc. - */ - xbcws->brw_context_winsys.batch_start = xbcws_batch_start; - xbcws->brw_context_winsys.batch_dword = xbcws_batch_dword; - xbcws->brw_context_winsys.batch_reloc = xbcws_batch_reloc; - xbcws->brw_context_winsys.batch_end = xbcws_batch_end; - xbcws->brw_context_winsys.batch_flush = xbcws_batch_flush; - xbcws->brw_context_winsys.buffer_subdata_typed = xbcws_buffer_subdata_typed; - xbcws->brw_context_winsys.get_buffer_offset = xbcws_get_buffer_offset; - - xbcws->pipe_winsys = screen->winsys; /* redundant */ - - xbcws->batch_size = XBCWS_BATCHBUFFER_SIZE; - - /* Create the i965simple context: - */ -#ifdef GALLIUM_CELL - return NULL; -#else - return brw_create( screen, - &xbcws->brw_context_winsys, - 0 ); -#endif -} diff --git a/src/gallium/winsys/xlib/xlib_brw_screen.c b/src/gallium/winsys/xlib/xlib_brw_screen.c deleted file mode 100644 index ef545796f3..0000000000 --- a/src/gallium/winsys/xlib/xlib_brw_screen.c +++ /dev/null @@ -1,469 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., 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 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. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ - -/* - * Authors: - * Keith Whitwell - * Brian Paul - */ - - -//#include "state_trackers/xlib/glxheader.h" -//#include "state_trackers/xlib/xmesaP.h" - -#include "pipe/internal/p_winsys_screen.h" -#include "util/u_math.h" -#include "util/u_memory.h" -#include "i965simple/brw_winsys.h" -#include "i965simple/brw_screen.h" -#include "i965simple/brw_context.h" - - -#include "xlib_brw_aub.h" -#include "xlib_brw.h" -#include "xlib.h" - -static struct pipe_buffer * -buffer_from_surface(struct pipe_surface *surface) -{ - struct brw_texture *texture = (struct brw_texture *)surface; - return texture->buffer; -} - -struct aub_buffer { - struct pipe_reference reference; - char *data; - unsigned offset; - unsigned size; - unsigned map_count; - boolean dump_on_unmap; -}; - - - -struct aub_pipe_winsys { - struct pipe_winsys winsys; - - struct brw_aubfile *aubfile; - - /* This is simple, isn't it: - */ - char *pool; - unsigned size; - unsigned used; -}; - - -/* Turn a pipe winsys into an aub/pipe winsys: - */ -static inline struct aub_pipe_winsys * -aub_pipe_winsys( struct pipe_winsys *winsys ) -{ - return (struct aub_pipe_winsys *)winsys; -} - - - -static INLINE struct aub_buffer * -aub_bo( struct pipe_buffer *bo ) -{ - return (struct aub_buffer *)bo; -} - -static INLINE struct pipe_buffer * -pipe_bo( struct aub_buffer *bo ) -{ - return (struct pipe_buffer *)bo; -} - - - - -static void *aub_buffer_map(struct pipe_winsys *winsys, - struct pipe_buffer *buf, - unsigned flags ) -{ - struct aub_buffer *sbo = aub_bo(buf); - - assert(sbo->data); - - if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) - sbo->dump_on_unmap = 1; - - sbo->map_count++; - return sbo->data; -} - -static void aub_buffer_unmap(struct pipe_winsys *winsys, - struct pipe_buffer *buf) -{ - struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys); - struct aub_buffer *sbo = aub_bo(buf); - - sbo->map_count--; - - if (sbo->map_count == 0 && - sbo->dump_on_unmap) { - - sbo->dump_on_unmap = 0; - - brw_aub_gtt_data( iws->aubfile, - sbo->offset, - sbo->data, - sbo->size, - 0, - 0); - } -} - - -static void -aub_buffer_destroy(struct pipe_buffer *buf) -{ - free(buf); -} - - - -void xlib_brw_commands_aub(struct pipe_winsys *winsys, - unsigned *cmds, - unsigned nr_dwords) -{ - struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys); - unsigned size = nr_dwords * 4; - - assert(iws->used + size < iws->size); - - brw_aub_gtt_cmds( iws->aubfile, - AUB_BUF_START + iws->used, - cmds, - nr_dwords * sizeof(int) ); - - iws->used += align(size, 4096); -} - - -/* XXX: fix me: - */ -static struct aub_pipe_winsys *global_winsys = NULL; - - - - -/* Pipe has no concept of pools. We choose the tex/region pool - * for all buffers. - */ -static struct pipe_buffer * -aub_buffer_create(struct pipe_winsys *winsys, - unsigned alignment, - unsigned usage, - unsigned size) -{ - struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys); - struct aub_buffer *sbo = CALLOC_STRUCT(aub_buffer); - - pipe_reference_init(&sbo->reference, 1); - - /* Could reuse buffers that are not referenced in current - * batchbuffer. Can't do that atm, so always reallocate: - */ - assert(iws->used + size < iws->size); - sbo->data = iws->pool + iws->used; - sbo->offset = AUB_BUF_START + iws->used; - iws->used += align(size, 4096); - - sbo->size = size; - - return pipe_bo(sbo); -} - - -static struct pipe_buffer * -aub_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes) -{ - struct aub_buffer *sbo; - - /* Lets hope this is meant for upload, not as a result! - */ - sbo = aub_bo(aub_buffer_create( winsys, 0, 0, 0 )); - - sbo->data = ptr; - sbo->size = bytes; - - return pipe_bo(sbo); -} - - -/* The state tracker (should!) keep track of whether the fake - * frontbuffer has been touched by any rendering since the last time - * we copied its contents to the real frontbuffer. Our task is easy: - */ -static void -aub_flush_frontbuffer( struct pipe_winsys *winsys, - struct pipe_surface *surface, - void *context_private) -{ -// struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys); - brw_aub_dump_bmp( global_winsys->aubfile, - surface, - aub_bo(buffer_from_surface(surface))->offset ); -} - - -/** - * Round n up to next multiple. - */ -static INLINE unsigned -round_up(unsigned n, unsigned multiple) -{ - return (n + multiple - 1) & ~(multiple - 1); -} - -static struct pipe_buffer * -aub_i915_surface_buffer_create(struct pipe_winsys *winsys, - unsigned width, unsigned height, - enum pipe_format format, - unsigned usage, - unsigned tex_usage, - unsigned *stride) -{ - const unsigned alignment = 64; - struct pipe_format_block block; - unsigned nblocksx, nblocksy; - - pf_get_block(format, &block); - nblocksx = pf_get_nblocksx(&block, width); - nblocksy = pf_get_nblocksy(&block, height); - *stride = round_up(nblocksx * block.size, alignment); - - return winsys->buffer_create(winsys, alignment, - usage, - *stride * nblocksy); -} - - -static const char * -aub_get_name( struct pipe_winsys *winsys ) -{ - return "Aub/xlib"; -} - -static void -xlib_brw_destroy_pipe_winsys_aub( struct pipe_winsys *winsys ) - -{ - struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys); - brw_aub_destroy(iws->aubfile); - free(iws->pool); - free(iws); -} - - - -static struct pipe_winsys * -xlib_create_brw_winsys( void ) -{ - struct aub_pipe_winsys *iws = CALLOC_STRUCT( aub_pipe_winsys ); - - /* Fill in this struct with callbacks that pipe will need to - * communicate with the window system, buffer manager, etc. - * - * Pipe would be happy with a malloc based memory manager, but - * the SwapBuffers implementation in this winsys driver requires - * that rendering be done to an appropriate _DriBufferObject. - */ - iws->winsys.buffer_create = aub_buffer_create; - iws->winsys.user_buffer_create = aub_user_buffer_create; - iws->winsys.buffer_map = aub_buffer_map; - iws->winsys.buffer_unmap = aub_buffer_unmap; - iws->winsys.buffer_destroy = aub_buffer_destroy; - iws->winsys.flush_frontbuffer = aub_flush_frontbuffer; - iws->winsys.get_name = aub_get_name; - iws->winsys.destroy = xlib_brw_destroy_pipe_winsys_aub; - - iws->winsys.surface_buffer_create = aub_i915_surface_buffer_create; - - iws->aubfile = brw_aubfile_create(); - iws->size = AUB_BUF_SIZE; - iws->pool = malloc(AUB_BUF_SIZE); - - /* HACK: static copy of this pointer: - */ - assert(global_winsys == NULL); - global_winsys = iws; - - return &iws->winsys; -} - - -static struct pipe_screen * -xlib_create_brw_screen( void ) -{ -#ifndef GALLIUM_CELL - struct pipe_winsys *winsys; - struct pipe_screen *screen; - - winsys = xlib_create_brw_winsys(); - if (winsys == NULL) - return NULL; - - screen = brw_create_screen(winsys, 0/* XXX pci_id */); - if (screen == NULL) - goto fail; - - return screen; - -fail: - if (winsys) - winsys->destroy( winsys ); - -#endif - return NULL; -} - - -/* These per-screen functions are acually made available to the driver - * through the brw_winsys (per-context) entity. - */ -unsigned xlib_brw_get_buffer_offset( struct pipe_winsys *pws, - struct pipe_buffer *buf, - unsigned access_flags ) -{ - return aub_bo(buf)->offset; -} - -void xlib_brw_buffer_subdata_typed( struct pipe_winsys *pws, - struct pipe_buffer *buf, - unsigned long offset, - unsigned long size, - const void *data, - unsigned data_type ) -{ - unsigned aub_type = DW_GENERAL_STATE; - unsigned aub_sub_type = 0; - - switch (data_type) { - case BRW_CC_VP: - aub_sub_type = DWGS_COLOR_CALC_VIEWPORT_STATE; - break; - case BRW_CC_UNIT: - aub_sub_type = DWGS_COLOR_CALC_STATE; - break; - case BRW_WM_PROG: - aub_sub_type = DWGS_KERNEL_INSTRUCTIONS; - break; - case BRW_SAMPLER_DEFAULT_COLOR: - aub_sub_type = DWGS_SAMPLER_DEFAULT_COLOR; - break; - case BRW_SAMPLER: - aub_sub_type = DWGS_SAMPLER_STATE; - break; - case BRW_WM_UNIT: - aub_sub_type = DWGS_WINDOWER_IZ_STATE; - break; - case BRW_SF_PROG: - aub_sub_type = DWGS_KERNEL_INSTRUCTIONS; - break; - case BRW_SF_VP: - aub_sub_type = DWGS_STRIPS_FANS_VIEWPORT_STATE; - break; - case BRW_SF_UNIT: - aub_sub_type = DWGS_STRIPS_FANS_STATE; - break; - case BRW_VS_UNIT: - aub_sub_type = DWGS_VERTEX_SHADER_STATE; - break; - case BRW_VS_PROG: - aub_sub_type = DWGS_KERNEL_INSTRUCTIONS; - break; - case BRW_GS_UNIT: - aub_sub_type = DWGS_GEOMETRY_SHADER_STATE; - break; - case BRW_GS_PROG: - aub_sub_type = DWGS_KERNEL_INSTRUCTIONS; - break; - case BRW_CLIP_VP: - aub_sub_type = DWGS_CLIPPER_VIEWPORT_STATE; - break; - case BRW_CLIP_UNIT: - aub_sub_type = DWGS_CLIPPER_STATE; - break; - case BRW_CLIP_PROG: - aub_sub_type = DWGS_KERNEL_INSTRUCTIONS; - break; - case BRW_SS_SURFACE: - aub_type = DW_SURFACE_STATE; - aub_sub_type = DWSS_SURFACE_STATE; - break; - case BRW_SS_SURF_BIND: - aub_type = DW_SURFACE_STATE; - aub_sub_type = DWSS_BINDING_TABLE_STATE; - break; - case BRW_CONSTANT_BUFFER: - aub_type = DW_CONSTANT_URB_ENTRY; - aub_sub_type = 0; - break; - - default: - assert(0); - break; - } - - { - struct aub_pipe_winsys *iws = aub_pipe_winsys(pws); - struct aub_buffer *sbo = aub_bo(buf); - - assert(sbo->size > offset + size); - memcpy(sbo->data + offset, data, size); - - brw_aub_gtt_data( iws->aubfile, - sbo->offset + offset, - sbo->data + offset, - size, - aub_type, - aub_sub_type ); - } -} - - -static void -xlib_brw_display_surface(struct xmesa_buffer *b, - struct pipe_surface *surf) -{ - brw_aub_dump_bmp( global_winsys->aubfile, - surf, - aub_bo(buffer_from_surface(surf))->offset ); -} - - -struct xm_driver xlib_brw_driver = -{ - .create_pipe_screen = xlib_create_brw_screen, - .create_pipe_context = xlib_create_brw_context, - .display_surface = xlib_brw_display_surface, -}; diff --git a/src/gallium/winsys/xlib/xlib_cell.c b/src/gallium/winsys/xlib/xlib_cell.c index 13e609f58f..b078de23b7 100644 --- a/src/gallium/winsys/xlib/xlib_cell.c +++ b/src/gallium/winsys/xlib/xlib_cell.c @@ -277,35 +277,24 @@ xm_user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes) -/** - * Round n up to next multiple. - */ -static INLINE unsigned -round_up(unsigned n, unsigned multiple) -{ - return (n + multiple - 1) & ~(multiple - 1); -} - static struct pipe_buffer * xm_surface_buffer_create(struct pipe_winsys *winsys, unsigned width, unsigned height, enum pipe_format format, unsigned usage, + unsigned tex_usage, unsigned *stride) { const unsigned alignment = 64; - struct pipe_format_block block; - unsigned nblocksx, nblocksy; + unsigned nblocksy; - pf_get_block(format, &block); - nblocksx = pf_get_nblocksx(&block, width); - nblocksy = pf_get_nblocksy(&block, height); - *stride = round_up(nblocksx * block.size, alignment); + nblocksy = pf_get_nblocksy(format, height); + *stride = align(pf_get_stride(format, width), alignment); return winsys->buffer_create(winsys, alignment, usage, /* XXX a bit of a hack */ - *stride * round_up(nblocksy, TILE_SIZE)); + *stride * align(nblocksy, TILE_SIZE)); } diff --git a/src/gallium/winsys/xlib/xlib_llvmpipe.c b/src/gallium/winsys/xlib/xlib_llvmpipe.c index 3dd15e099b..41f3e248e8 100644 --- a/src/gallium/winsys/xlib/xlib_llvmpipe.c +++ b/src/gallium/winsys/xlib/xlib_llvmpipe.c @@ -58,7 +58,6 @@ struct xm_displaytarget { enum pipe_format format; - struct pipe_format_block block; unsigned width; unsigned height; unsigned stride; @@ -262,10 +261,10 @@ xm_llvmpipe_display(struct xmesa_buffer *xm_buffer, { if (xm_dt->tempImage == NULL) { - assert(xm_dt->block.width == 1); - assert(xm_dt->block.height == 1); + assert(pf_get_blockwidth(xm_dt->format) == 1); + assert(pf_get_blockheight(xm_dt->format) == 1); alloc_shm_ximage(xm_dt, xm_buffer, - xm_dt->stride / xm_dt->block.size, + xm_dt->stride / pf_get_blocksize(xm_dt->format), xm_dt->height); } @@ -321,7 +320,7 @@ xm_displaytarget_create(struct llvmpipe_winsys *winsys, unsigned *stride) { struct xm_displaytarget *xm_dt = CALLOC_STRUCT(xm_displaytarget); - unsigned nblocksx, nblocksy, size; + unsigned nblocksy, size; xm_dt = CALLOC_STRUCT(xm_displaytarget); if(!xm_dt) @@ -331,10 +330,8 @@ xm_displaytarget_create(struct llvmpipe_winsys *winsys, xm_dt->width = width; xm_dt->height = height; - pf_get_block(format, &xm_dt->block); - nblocksx = pf_get_nblocksx(&xm_dt->block, width); - nblocksy = pf_get_nblocksy(&xm_dt->block, height); - xm_dt->stride = align(nblocksx * xm_dt->block.size, alignment); + nblocksy = pf_get_nblocksy(format, height); + xm_dt->stride = align(pf_get_stride(format, width), alignment); size = xm_dt->stride * nblocksy; #ifdef USE_XSHM diff --git a/src/gallium/winsys/xlib/xlib_softpipe.c b/src/gallium/winsys/xlib/xlib_softpipe.c index 67fea023a3..69a5dcc2b7 100644 --- a/src/gallium/winsys/xlib/xlib_softpipe.c +++ b/src/gallium/winsys/xlib/xlib_softpipe.c @@ -75,9 +75,6 @@ struct xmesa_pipe_winsys { struct pipe_winsys base; /* struct xmesa_visual *xm_visual; */ -#ifdef USE_XSHM - int shm; -#endif }; @@ -93,11 +90,6 @@ xm_buffer( struct pipe_buffer *buf ) /** * X Shared Memory Image extension code */ -#ifdef USE_XSHM -#define XSHM_ENABLED(b) ((b)->shm) -#else -#define XSHM_ENABLED(b) 0 -#endif #ifdef USE_XSHM @@ -116,23 +108,23 @@ mesaHandleXError(Display *dpy, XErrorEvent *event) } -static GLboolean alloc_shm(struct xm_buffer *buf, unsigned size) +static char *alloc_shm(struct xm_buffer *buf, unsigned size) { XShmSegmentInfo *const shminfo = & buf->shminfo; shminfo->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777); if (shminfo->shmid < 0) { - return GL_FALSE; + return NULL; } shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0); if (shminfo->shmaddr == (char *) -1) { shmctl(shminfo->shmid, IPC_RMID, 0); - return GL_FALSE; + return NULL; } shminfo->readOnly = False; - return GL_TRUE; + return shminfo->shmaddr; } @@ -258,25 +250,30 @@ xlib_softpipe_display_surface(struct xmesa_buffer *b, return; #ifdef USE_XSHM - if (XSHM_ENABLED(xm_buf) && (xm_buf->tempImage == NULL)) { - assert(surf->texture->block.width == 1); - assert(surf->texture->block.height == 1); - alloc_shm_ximage(xm_buf, b, spt->stride[surf->level] / - surf->texture->block.size, surf->height); - } -#endif + if (xm_buf->shm) + { + if (xm_buf->tempImage == NULL) + { + assert(pf_get_blockwidth(surf->texture->format) == 1); + assert(pf_get_blockheight(surf->texture->format) == 1); + alloc_shm_ximage(xm_buf, b, spt->stride[surf->level] / + pf_get_blocksize(surf->texture->format), surf->height); + } - ximage = (XSHM_ENABLED(xm_buf)) ? xm_buf->tempImage : b->tempImage; - ximage->data = xm_buf->data; + ximage = xm_buf->tempImage; + ximage->data = xm_buf->data; - /* display image in Window */ -#ifdef USE_XSHM - if (XSHM_ENABLED(xm_buf)) { + /* _debug_printf("XSHM\n"); */ XShmPutImage(b->xm_visual->display, b->drawable, b->gc, ximage, 0, 0, 0, 0, surf->width, surf->height, False); - } else + } + else #endif { + /* display image in Window */ + ximage = b->tempImage; + ximage->data = xm_buf->data; + /* check that the XImage has been previously initialized */ assert(ximage->format); assert(ximage->bitmap_unit); @@ -286,6 +283,7 @@ xlib_softpipe_display_surface(struct xmesa_buffer *b, ximage->height = surf->height; ximage->bytes_per_line = spt->stride[surf->level]; + /* _debug_printf("XPUT\n"); */ XPutImage(b->xm_visual->display, b->drawable, b->gc, ximage, 0, 0, 0, 0, surf->width, surf->height); } @@ -322,21 +320,6 @@ xm_buffer_create(struct pipe_winsys *pws, unsigned size) { struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer); -#ifdef USE_XSHM - struct xmesa_pipe_winsys *xpws = (struct xmesa_pipe_winsys *) pws; - - buffer->shminfo.shmid = -1; - buffer->shminfo.shmaddr = (char *) -1; - - if (xpws->shm && (usage & PIPE_BUFFER_USAGE_PIXEL) != 0) { - buffer->shm = xpws->shm; - - if (alloc_shm(buffer, size)) { - buffer->data = buffer->shminfo.shmaddr; - buffer->shm = 1; - } - } -#endif pipe_reference_init(&buffer->base.reference, 1); buffer->base.alignment = alignment; @@ -363,9 +346,6 @@ xm_user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes) buffer->base.size = bytes; buffer->userBuffer = TRUE; buffer->data = ptr; -#ifdef USE_XSHM - buffer->shm = 0; -#endif return &buffer->base; } @@ -380,17 +360,42 @@ xm_surface_buffer_create(struct pipe_winsys *winsys, unsigned *stride) { const unsigned alignment = 64; - struct pipe_format_block block; - unsigned nblocksx, nblocksy; + unsigned nblocksy, size; + + nblocksy = pf_get_nblocksy(format, height); + *stride = align(pf_get_stride(format, width), alignment); + size = *stride * nblocksy; - pf_get_block(format, &block); - nblocksx = pf_get_nblocksx(&block, width); - nblocksy = pf_get_nblocksy(&block, height); - *stride = align(nblocksx * block.size, alignment); +#ifdef USE_XSHM + if (!debug_get_bool_option("XLIB_NO_SHM", FALSE)) + { + struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer); + + pipe_reference_init(&buffer->base.reference, 1); + buffer->base.alignment = alignment; + buffer->base.usage = usage; + buffer->base.size = size; + buffer->userBuffer = FALSE; + buffer->shminfo.shmid = -1; + buffer->shminfo.shmaddr = (char *) -1; + buffer->shm = TRUE; + + buffer->data = alloc_shm(buffer, size); + if (!buffer->data) + goto out; + + return &buffer->base; + + out: + if (buffer) + FREE(buffer); + } +#endif + return winsys->buffer_create(winsys, alignment, usage, - *stride * nblocksy); + size); } |