diff options
author | Younes Manton <[email protected]> | 2009-11-02 20:32:58 -0500 |
---|---|---|
committer | Younes Manton <[email protected]> | 2009-11-02 20:32:58 -0500 |
commit | e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9fe (patch) | |
tree | 7b703c5e05ed7faee397a6062f77eb5fbfd6b7da /src/gallium/winsys | |
parent | 87d7c1aa15a944d64e43b217e18553256f9fb681 (diff) |
g3dvl: DRM winsys changes.
Diffstat (limited to 'src/gallium/winsys')
-rw-r--r-- | src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c | 53 | ||||
-rw-r--r-- | src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h | 2 | ||||
-rw-r--r-- | src/gallium/winsys/g3dvl/nouveau/Makefile | 148 | ||||
-rw-r--r-- | src/gallium/winsys/g3dvl/nouveau/drm_nouveau_winsys.c | 393 | ||||
-rw-r--r-- | src/gallium/winsys/g3dvl/vl_winsys.h | 35 | ||||
-rw-r--r-- | src/gallium/winsys/g3dvl/xlib/xsp_winsys.c | 103 |
6 files changed, 630 insertions, 104 deletions
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 317dc44d22f..47e53936749 100644 --- a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c +++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c @@ -45,9 +45,9 @@ dri_surface_from_handle(struct drm_api *api, struct pipe_screen *pscreen, } static struct pipe_surface * -nouveau_dri1_front_surface(struct pipe_context *pipe) +nouveau_dri1_front_surface(struct pipe_screen *screen) { - return nouveau_winsys_screen(pipe->screen)->front; + return nouveau_winsys_screen(screen)->front; } static struct dri1_api nouveau_dri1_api = { @@ -190,6 +190,54 @@ nouveau_drm_create_context(struct drm_api *api, struct pipe_screen *pscreen) return nvws->pctx[i]; } +typedef struct pipe_video_context* (*nouveau_video_create)(struct pipe_context *pipe, + enum pipe_video_profile profile, + enum pipe_video_chroma_format chroma_format, + unsigned width, unsigned height, + unsigned pvctx); + +static struct pipe_video_context * +nouveau_drm_create_video_context(struct drm_api *api, struct pipe_screen *pscreen, + enum pipe_video_profile profile, + enum pipe_video_chroma_format chroma_format, + unsigned width, unsigned height) +{ + struct nouveau_winsys *nvws = nouveau_winsys_screen(pscreen); + nouveau_video_create init; + unsigned chipset = nouveau_screen(pscreen)->device->chipset; + struct pipe_context *pipe; + int i; + + switch (chipset & 0xf0) { + case 0x40: + case 0x60: + init = nv40_video_create; + break; + default: + debug_printf("%s: unknown chipset nv%02x\n", __func__, chipset); + return NULL; + } + + /* Find a free slot for a pipe video context, allocate a new one if needed */ + for (i = 0; i < nvws->nr_pvctx; i++) { + if (nvws->pvctx[i] == NULL) + break; + } + + if (i == nvws->nr_pvctx) { + nvws->nr_pvctx++; + nvws->pvctx = realloc(nvws->pvctx, + sizeof(*nvws->pvctx) * nvws->nr_pvctx); + } + + pipe = nouveau_drm_create_context(api, pscreen); + if (!pipe) + return NULL; + + nvws->pvctx[i] = init(pipe, profile, chroma_format, width, height, i); + return nvws->pvctx[i]; +} + static struct pipe_texture * nouveau_drm_pt_from_name(struct drm_api *api, struct pipe_screen *pscreen, struct pipe_texture *templ, const char *name, @@ -254,6 +302,7 @@ nouveau_drm_handle_from_pt(struct drm_api *api, struct pipe_screen *pscreen, struct drm_api drm_api_hooks = { .create_screen = nouveau_drm_create_screen, .create_context = nouveau_drm_create_context, + .create_video_context = nouveau_drm_create_video_context, .texture_from_shared_handle = nouveau_drm_pt_from_name, .shared_handle_from_texture = nouveau_drm_name_from_pt, .local_handle_from_texture = nouveau_drm_handle_from_pt, diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h index e61e0e0957a..fa4e821e60c 100644 --- a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h +++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h @@ -15,6 +15,8 @@ struct nouveau_winsys { unsigned nr_pctx; struct pipe_context **pctx; + unsigned nr_pvctx; + struct pipe_video_context **pvctx; struct pipe_surface *front; }; diff --git a/src/gallium/winsys/g3dvl/nouveau/Makefile b/src/gallium/winsys/g3dvl/nouveau/Makefile index 2997f6b79ce..4eba18a0d5c 100644 --- a/src/gallium/winsys/g3dvl/nouveau/Makefile +++ b/src/gallium/winsys/g3dvl/nouveau/Makefile @@ -1,50 +1,98 @@ -TARGET = libnouveau_dri.so -GALLIUMDIR = ../../.. -DRMDIR ?= /usr -DRIDIR = ../../../../driclient - -OBJECTS = nouveau_screen_vl.o nouveau_context_vl.o nouveau_swapbuffers.o - -CFLAGS += -g -Wall -Werror=implicit-function-declaration -fPIC \ - -I${GALLIUMDIR}/include \ - -I${GALLIUMDIR}/winsys/g3dvl \ - -I${GALLIUMDIR}/winsys/drm/nouveau \ - -I${DRMDIR}/include \ - -I${DRMDIR}/include/drm \ - -I${DRMDIR}/include/nouveau \ - -I${GALLIUMDIR}/drivers \ - -I${GALLIUMDIR}/auxiliary \ - -I${DRIDIR}/include - -LDFLAGS += -L${DRMDIR}/lib \ - -L${DRIDIR}/lib \ - -L${GALLIUMDIR}/winsys/drm/nouveau/common \ - -L${GALLIUMDIR}/auxiliary/draw \ - -L${GALLIUMDIR}/auxiliary/tgsi \ - -L${GALLIUMDIR}/auxiliary/translate \ - -L${GALLIUMDIR}/auxiliary/rtasm \ - -L${GALLIUMDIR}/auxiliary/cso_cache \ - -L${GALLIUMDIR}/drivers/nv04 \ - -L${GALLIUMDIR}/drivers/nv10 \ - -L${GALLIUMDIR}/drivers/nv20 \ - -L${GALLIUMDIR}/drivers/nv30 \ - -L${GALLIUMDIR}/drivers/nv40 \ - -L${GALLIUMDIR}/drivers/nv50 - -LIBS += -lnouveaudrm -ldriclient -ldrm_nouveau -ldrm -lnv04 -lnv10 -lnv20 -lnv30 -lnv40 -lnv50 -ldraw -ltgsi -ltranslate -lrtasm -lcso_cache -lm - -############################################# - -.PHONY = all clean libdriclient - -all: ${TARGET} - -${TARGET}: ${OBJECTS} libdriclient - $(CC) ${LDFLAGS} -shared -o $@ ${OBJECTS} ${LIBS} - -libdriclient: - cd ${DRIDIR}/src; ${MAKE} - -clean: - cd ${DRIDIR}/src; ${MAKE} clean - rm -rf ${OBJECTS} ${TARGET} +# This makefile produces a libXvMCg3dvl.so which is +# based on DRM/DRI + +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 + +SOURCES = drm_nouveau_winsys.c + +DRIVER_INCLUDES = $(shell pkg-config libdrm libdrm_nouveau --cflags-only-I) \ + -I$(TOP)/src/gallium/winsys/drm/nouveau \ + -I$(TOP)/src/driclient/include +DRIVER_DEFINES = $(shell pkg-config libdrm libdrm_nouveau --cflags-only-other) + +PIPE_DRIVERS = \ + $(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 + +DRI_LIB_DEPS += $(shell pkg-config libdrm_nouveau --libs) + +############################################################### + +INCLUDES = $(DRIVER_INCLUDES) \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/auxiliary \ + -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/src/gallium/winsys/g3dvl \ + -I$(TOP)/src/driclient/include + +DEFINES += $(DRIVER_DEFINES) \ + -DGALLIUM_SOFTPIPE \ + -DGALLIUM_TRACE + +# 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 = $(PIPE_DRIVERS) \ + $(TOP)/src/driclient/lib/libdriclient.a \ + $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ + $(TOP)/src/gallium/auxiliary/vl/libvl.a \ + $(TOP)/src/gallium/auxiliary/draw/libdraw.a \ + $(TOP)/src/gallium/auxiliary/tgsi/libtgsi.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) $(DRI_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/nouveau/drm_nouveau_winsys.c b/src/gallium/winsys/g3dvl/nouveau/drm_nouveau_winsys.c new file mode 100644 index 00000000000..257aa0a1201 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/drm_nouveau_winsys.c @@ -0,0 +1,393 @@ +/************************************************************************** + * + * 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 <driclient.h> +#include <state_tracker/dri1_api.h> +#include <pipe/p_video_context.h> +#include <pipe/p_state.h> +#include <util/u_memory.h> + +struct vl_dri_screen +{ + struct vl_screen base; + Visual *visual; + struct drm_api *api; + dri_screen_t *dri_screen; + dri_framebuffer_t dri_framebuf; + struct dri1_api *api_hooks; +}; + +struct vl_dri_context +{ + struct vl_context base; + boolean is_locked; + boolean lost_lock; + drmLock *lock; + dri_context_t *dri_context; + int fd; + struct pipe_video_context *vpipe; + dri_drawable_t *drawable; +}; + +static void +vl_dri_lock(void *priv) +{ + struct vl_dri_context *vl_dri_ctx = priv; + drm_context_t hw_context; + char ret = 0; + + assert(priv); + + hw_context = vl_dri_ctx->dri_context->drm_context; + + DRM_CAS(vl_dri_ctx->lock, hw_context, DRM_LOCK_HELD | hw_context, ret); + if (ret) { + drmGetLock(vl_dri_ctx->fd, hw_context, 0); + vl_dri_ctx->lost_lock = TRUE; + } + vl_dri_ctx->is_locked = TRUE; +} + +static void +vl_dri_unlock(void *priv) +{ + struct vl_dri_context *vl_dri_ctx = priv; + drm_context_t hw_context; + + assert(priv); + + hw_context = vl_dri_ctx->dri_context->drm_context; + + vl_dri_ctx->is_locked = FALSE; + DRM_UNLOCK(vl_dri_ctx->fd, vl_dri_ctx->lock, hw_context); +} + +static boolean +vl_dri_is_locked(void *priv) +{ + struct vl_dri_context *vl_dri_ctx = priv; + + assert(priv); + + return vl_dri_ctx->is_locked; +} + +static boolean +vl_dri_lost_lock(void *priv) +{ + struct vl_dri_context *vl_dri_ctx = priv; + + assert(priv); + + return vl_dri_ctx->lost_lock; +} + +static void +vl_dri_clear_lost_lock(void *priv) +{ + struct vl_dri_context *vl_dri_ctx = priv; + + assert(priv); + + vl_dri_ctx->lost_lock = FALSE; +} + +struct dri1_api_lock_funcs dri1_lf = +{ + .lock = vl_dri_lock, + .unlock = vl_dri_unlock, + .is_locked = vl_dri_is_locked, + .is_lock_lost = vl_dri_lost_lock, + .clear_lost_lock = vl_dri_clear_lost_lock +}; + +static void +vl_dri_copy_version(struct dri1_api_version *dst, dri_version_t *src) +{ + assert(src); + assert(dst); + dst->major = src->major; + dst->minor = src->minor; + dst->patch_level = src->patch; +} + +static boolean +vl_dri_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; + + assert(dst); + assert(src); + assert(bbox); + + 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; +} + +static void +vl_clip_copy(struct vl_dri_context *vl_dri_ctx, + struct pipe_surface *dst, + struct pipe_surface *src, + const struct drm_clip_rect *src_bbox) +{ + struct pipe_video_context *vpipe = vl_dri_ctx->base.vpipe; + struct drm_clip_rect clip; + struct drm_clip_rect *cur; + int i; + + assert(vl_dri_ctx); + assert(dst); + assert(src); + assert(src_bbox); + + assert(vl_dri_ctx->drawable->cliprects); + assert(vl_dri_ctx->drawable->num_cliprects > 0); + + cur = vl_dri_ctx->drawable->cliprects; + + for (i = 0; i < vl_dri_ctx->drawable->num_cliprects; ++i) { + if (vl_dri_intersect_src_bbox(&clip, vl_dri_ctx->drawable->x, vl_dri_ctx->drawable->y, cur++, src_bbox)) + vpipe->surface_copy + ( + vpipe, dst, clip.x1, clip.y1, src, + (int)clip.x1 - vl_dri_ctx->drawable->x, + (int)clip.y1 - vl_dri_ctx->drawable->y, + clip.x2 - clip.x1, clip.y2 - clip.y1 + ); + } +} + +static void +vl_dri_update_drawables_locked(struct vl_dri_context *vl_dri_ctx) +{ + struct vl_dri_screen *vl_dri_scrn; + + assert(vl_dri_ctx); + + vl_dri_scrn = (struct vl_dri_screen*)vl_dri_ctx->base.vscreen; + + if (vl_dri_ctx->lost_lock) { + vl_dri_ctx->lost_lock = FALSE; + DRI_VALIDATE_DRAWABLE_INFO(vl_dri_scrn->dri_screen, vl_dri_ctx->drawable); + } +} + +static void +vl_dri_flush_frontbuffer(struct pipe_screen *screen, + struct pipe_surface *surf, void *context_private) +{ + struct vl_dri_context *vl_dri_ctx = (struct vl_dri_context*)context_private; + struct vl_dri_screen *vl_dri_scrn; + struct drm_clip_rect src_bbox; + boolean save_lost_lock = FALSE; + + assert(screen); + assert(surf); + assert(context_private); + + vl_dri_scrn = (struct vl_dri_screen*)vl_dri_ctx->base.vscreen; + + vl_dri_lock(vl_dri_ctx); + + save_lost_lock = vl_dri_ctx->lost_lock; + + vl_dri_update_drawables_locked(vl_dri_ctx); + + src_bbox.x1 = 0; + src_bbox.x2 = vl_dri_ctx->drawable->w; + src_bbox.y1 = 0; + src_bbox.y2 = vl_dri_ctx->drawable->h; + +#if 0 + if (vl_dri_scrn->_api_hooks->present_locked) + vl_dri_scrn->api_hooks->present_locked(pipe, surf, + vl_dri_ctx->drawable->cliprects, + vl_dri_ctx->drawable->num_cliprects, + vl_dri_ctx->drawable->x, vl_dri_drawable->y, + &bbox, NULL /*fence*/); + else +#endif + if (vl_dri_scrn->api_hooks->front_srf_locked) { + struct pipe_surface *front = vl_dri_scrn->api_hooks->front_srf_locked(screen); + + if (front) + vl_clip_copy(vl_dri_ctx, front, surf, &src_bbox); + + //st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, fence); + } + + vl_dri_ctx->lost_lock = save_lost_lock; + + vl_dri_unlock(vl_dri_ctx); +} + +Drawable +vl_video_bind_drawable(struct vl_context *vctx, Drawable drawable) +{ + struct vl_dri_context *vl_dri_ctx = (struct vl_dri_context*)vctx; + struct vl_dri_screen *vl_dri_scrn; + dri_drawable_t *dri_drawable; + Drawable old_drawable = None; + + assert(vctx); + + if (vl_dri_ctx->drawable) + old_drawable = vl_dri_ctx->drawable->x_drawable; + + vl_dri_scrn = (struct vl_dri_screen*)vl_dri_ctx->base.vscreen; + driCreateDrawable(vl_dri_scrn->dri_screen, drawable, &dri_drawable); + vl_dri_ctx->drawable = dri_drawable; + + return old_drawable; +} + +struct vl_screen* +vl_screen_create(Display *display, int screen) +{ + struct vl_dri_screen *vl_dri_scrn; + struct dri1_create_screen_arg arg; + + assert(display); + + vl_dri_scrn = CALLOC_STRUCT(vl_dri_screen); + if (!vl_dri_scrn) + return NULL; + + driCreateScreen(display, screen, &vl_dri_scrn->dri_screen, &vl_dri_scrn->dri_framebuf); + vl_dri_scrn->api = drm_api_create(); + + arg.base.mode = DRM_CREATE_DRI1; + arg.lf = &dri1_lf; + arg.ddx_info = vl_dri_scrn->dri_framebuf.private; + arg.ddx_info_size = vl_dri_scrn->dri_framebuf.private_size; + arg.sarea = vl_dri_scrn->dri_screen->sarea; + vl_dri_copy_version(&arg.ddx_version, &vl_dri_scrn->dri_screen->ddx); + vl_dri_copy_version(&arg.dri_version, &vl_dri_scrn->dri_screen->dri); + vl_dri_copy_version(&arg.drm_version, &vl_dri_scrn->dri_screen->drm); + arg.api = NULL; + + vl_dri_scrn->base.pscreen = vl_dri_scrn->api->create_screen(vl_dri_scrn->api, + vl_dri_scrn->dri_screen->fd, + &arg.base); + + if (!vl_dri_scrn->base.pscreen) { + FREE(vl_dri_scrn); + return NULL; + } + + vl_dri_scrn->visual = XDefaultVisual(display, screen); + vl_dri_scrn->api_hooks = arg.api; + vl_dri_scrn->base.pscreen->flush_frontbuffer = vl_dri_flush_frontbuffer; + /* XXX: Safe to call this while unlocked? */ + vl_dri_scrn->base.format = vl_dri_scrn->api_hooks->front_srf_locked(vl_dri_scrn->base.pscreen)->format; + + return &vl_dri_scrn->base; +} + +void vl_screen_destroy(struct vl_screen *vscreen) +{ + struct vl_dri_screen *vl_dri_scrn = (struct vl_dri_screen*)vscreen; + + assert(vscreen); + + vl_dri_scrn->base.pscreen->destroy(vl_dri_scrn->base.pscreen); + driDestroyScreen(vl_dri_scrn->dri_screen); + FREE(vl_dri_scrn); +} + +struct vl_context* +vl_video_create(struct vl_screen *vscreen, + enum pipe_video_profile profile, + enum pipe_video_chroma_format chroma_format, + unsigned width, unsigned height) +{ + struct vl_dri_screen *vl_dri_scrn = (struct vl_dri_screen*)vscreen; + struct vl_dri_context *vl_dri_ctx; + + vl_dri_ctx = CALLOC_STRUCT(vl_dri_context); + if (!vl_dri_ctx) + return NULL; + + /* XXX: Is default visual correct/sufficient here? */ + driCreateContext(vl_dri_scrn->dri_screen, vl_dri_scrn->visual, &vl_dri_ctx->dri_context); + + if (!vl_dri_scrn->api->create_video_context) { + debug_printf("[G3DVL] No video support found on %s/%s.\n", + vl_dri_scrn->base.pscreen->get_vendor(vl_dri_scrn->base.pscreen), + vl_dri_scrn->base.pscreen->get_name(vl_dri_scrn->base.pscreen)); + FREE(vl_dri_ctx); + return NULL; + } + + vl_dri_ctx->base.vpipe = vl_dri_scrn->api->create_video_context(vl_dri_scrn->api, + vscreen->pscreen, + profile, chroma_format, + width, height); + + if (!vl_dri_ctx->base.vpipe) { + FREE(vl_dri_ctx); + return NULL; + } + + vl_dri_ctx->base.vpipe->priv = vl_dri_ctx; + vl_dri_ctx->base.vscreen = vscreen; + vl_dri_ctx->fd = vl_dri_scrn->dri_screen->fd; + vl_dri_ctx->lock = (drmLock*)&vl_dri_scrn->dri_screen->sarea->lock; + + return &vl_dri_ctx->base; +} + +void vl_video_destroy(struct vl_context *vctx) +{ + struct vl_dri_context *vl_dri_ctx = (struct vl_dri_context*)vctx; + + assert(vctx); + + vl_dri_ctx->base.vpipe->destroy(vl_dri_ctx->base.vpipe); + FREE(vl_dri_ctx); +} diff --git a/src/gallium/winsys/g3dvl/vl_winsys.h b/src/gallium/winsys/g3dvl/vl_winsys.h index b4fa0d67a1b..d95e9c58335 100644 --- a/src/gallium/winsys/g3dvl/vl_winsys.h +++ b/src/gallium/winsys/g3dvl/vl_winsys.h @@ -1,8 +1,8 @@ /************************************************************************** - * + * * 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 @@ -10,11 +10,11 @@ * 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. @@ -22,7 +22,7 @@ * 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 @@ -35,17 +35,32 @@ struct pipe_screen; struct pipe_video_context; -struct pipe_screen* +struct vl_screen +{ + enum pipe_format format; + struct pipe_screen *pscreen; +}; + +struct vl_context +{ + struct vl_screen *vscreen; + struct pipe_video_context *vpipe; +}; + +struct vl_screen* vl_screen_create(Display *display, int screen); -struct pipe_video_context* -vl_video_create(Display *display, int screen, - struct pipe_screen *p_screen, +void vl_screen_destroy(struct vl_screen *vscreen); + +struct vl_context* +vl_video_create(struct vl_screen *vscreen, enum pipe_video_profile profile, enum pipe_video_chroma_format chroma_format, unsigned width, unsigned height); +void vl_video_destroy(struct vl_context *vctx); + Drawable -vl_video_bind_drawable(struct pipe_video_context *vpipe, Drawable drawable); +vl_video_bind_drawable(struct vl_context *vctx, Drawable drawable); #endif diff --git a/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c b/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c index 08067aad64c..2b32f07c9e8 100644 --- a/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c +++ b/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c @@ -1,8 +1,8 @@ /************************************************************************** - * + * * 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 @@ -10,11 +10,11 @@ * 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. @@ -22,7 +22,7 @@ * 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> @@ -36,7 +36,12 @@ #include <softpipe/sp_video_context.h> #include <softpipe/sp_texture.h> -/* pipe_winsys implementation */ +/* TODO: Find a good way to calculate this */ +static enum pipe_format VisualToPipe(Visual *visual) +{ + assert(visual); + return PIPE_FORMAT_X8R8G8B8_UNORM; +} struct xsp_pipe_winsys { @@ -48,9 +53,9 @@ struct xsp_pipe_winsys struct xsp_context { - Drawable drawable; + struct vl_context base; - void (*pipe_destroy)(struct pipe_video_context *vpipe); + Drawable drawable; }; struct xsp_buffer @@ -218,48 +223,37 @@ static void xsp_destroy(struct pipe_winsys *pws) 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) +vl_video_bind_drawable(struct vl_context *vctx, Drawable drawable) { - struct xsp_context *xsp_context; + struct xsp_context *xsp_context = (struct xsp_context*)vctx; Drawable old_drawable; - assert(vpipe); + assert(vctx); - xsp_context = vpipe->priv; old_drawable = xsp_context->drawable; xsp_context->drawable = drawable; return old_drawable; } -struct pipe_screen* +struct vl_screen* vl_screen_create(Display *display, int screen) { + struct vl_screen *vscreen; struct xsp_pipe_winsys *xsp_winsys; assert(display); + vscreen = CALLOC_STRUCT(vl_screen); + if (!vscreen) + return NULL; + xsp_winsys = CALLOC_STRUCT(xsp_pipe_winsys); - if (!xsp_winsys) + if (!xsp_winsys) { + FREE(vscreen); return NULL; + } xsp_winsys->base.buffer_create = xsp_buffer_create; xsp_winsys->base.user_buffer_create = xsp_user_buffer_create; @@ -291,17 +285,36 @@ vl_screen_create(Display *display, int screen) if (!xsp_winsys->fbimage) { FREE(xsp_winsys); + FREE(vscreen); return NULL; } XInitImage(xsp_winsys->fbimage); - return softpipe_create_screen(&xsp_winsys->base); + vscreen->pscreen = softpipe_create_screen(&xsp_winsys->base); + + if (!vscreen->pscreen) { + FREE(vscreen); + XDestroyImage(xsp_winsys->fbimage); + FREE(xsp_winsys); + return NULL; + } + + vscreen->format = VisualToPipe(XDefaultVisual(display, screen)); + + return vscreen; +} + +void vl_screen_destroy(struct vl_screen *vscreen) +{ + assert(vscreen); + + vscreen->pscreen->destroy(vscreen->pscreen); + FREE(vscreen); } -struct pipe_video_context* -vl_video_create(Display *display, int screen, - struct pipe_screen *p_screen, +struct vl_context* +vl_video_create(struct vl_screen *vscreen, enum pipe_video_profile profile, enum pipe_video_chroma_format chroma_format, unsigned width, unsigned height) @@ -309,10 +322,10 @@ vl_video_create(Display *display, int screen, struct pipe_video_context *vpipe; struct xsp_context *xsp_context; - assert(p_screen); + assert(vscreen); assert(width && height); - vpipe = sp_video_create(p_screen, profile, chroma_format, width, height); + vpipe = sp_video_create(vscreen->pscreen, profile, chroma_format, width, height); if (!vpipe) return NULL; @@ -322,11 +335,17 @@ vl_video_create(Display *display, int screen, 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; + xsp_context->base.vpipe = vpipe; + xsp_context->base.vscreen = vscreen; + + return &xsp_context->base; +} + +void vl_video_destroy(struct vl_context *vctx) +{ + assert(vctx); - return vpipe; + vctx->vpipe->destroy(vctx->vpipe); + FREE(vctx); } |