diff options
-rw-r--r-- | src/gallium/drivers/nvfx/nvfx_video_context.c | 3 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_video_context.c | 18 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_video_context.h | 7 | ||||
-rw-r--r-- | src/gallium/state_trackers/xorg/xvmc/surface.c | 26 | ||||
-rw-r--r-- | src/gallium/targets/xvmc-nouveau/Makefile | 2 | ||||
-rw-r--r-- | src/gallium/winsys/g3dvl/dri/dri_winsys.c | 443 | ||||
-rw-r--r-- | src/gallium/winsys/g3dvl/dri/driclient.c | 19 | ||||
-rw-r--r-- | src/gallium/winsys/g3dvl/dri/driclient.h | 1 | ||||
-rw-r--r-- | src/gallium/winsys/g3dvl/vl_winsys.h | 9 | ||||
-rw-r--r-- | src/gallium/winsys/g3dvl/xlib/xsp_winsys.c | 115 |
10 files changed, 252 insertions, 391 deletions
diff --git a/src/gallium/drivers/nvfx/nvfx_video_context.c b/src/gallium/drivers/nvfx/nvfx_video_context.c index 5b85b29e29b..4e21f35f40d 100644 --- a/src/gallium/drivers/nvfx/nvfx_video_context.c +++ b/src/gallium/drivers/nvfx/nvfx_video_context.c @@ -44,5 +44,6 @@ nvfx_video_create(struct pipe_screen *screen, enum pipe_video_profile profile, return sp_video_create_ex(pipe, profile, chroma_format, width, height, VL_MPEG12_MC_RENDERER_BUFFER_PICTURE, VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE, - true); + true, + PIPE_FORMAT_VUYA); } diff --git a/src/gallium/drivers/softpipe/sp_video_context.c b/src/gallium/drivers/softpipe/sp_video_context.c index fcee9b66823..9aec8a8c4fe 100644 --- a/src/gallium/drivers/softpipe/sp_video_context.c +++ b/src/gallium/drivers/softpipe/sp_video_context.c @@ -74,8 +74,7 @@ sp_mpeg12_get_param(struct pipe_video_context *vpipe, int param) #endif return FALSE; case PIPE_CAP_DECODE_TARGET_PREFERRED_FORMAT: - //return PIPE_FORMAT_AYUV; - return PIPE_FORMAT_VUYA; + return ctx->decode_format; default: { debug_printf("Softpipe: Unknown PIPE_CAP %d\n", param); @@ -322,7 +321,8 @@ sp_mpeg12_create(struct pipe_context *pipe, enum pipe_video_profile profile, unsigned width, unsigned height, enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode, enum VL_MPEG12_MC_RENDERER_EMPTY_BLOCK eb_handling, - bool pot_buffers) + bool pot_buffers, + enum pipe_format decode_format) { struct sp_mpeg12_context *ctx; @@ -352,6 +352,7 @@ sp_mpeg12_create(struct pipe_context *pipe, enum pipe_video_profile profile, ctx->base.set_csc_matrix = sp_mpeg12_set_csc_matrix; ctx->pipe = pipe; + ctx->decode_format = decode_format; if (!vl_mpeg12_mc_renderer_init(&ctx->mc_renderer, ctx->pipe, width, height, chroma_format, @@ -382,7 +383,7 @@ sp_mpeg12_create(struct pipe_context *pipe, enum pipe_video_profile profile, struct pipe_video_context * sp_video_create(struct pipe_screen *screen, enum pipe_video_profile profile, enum pipe_video_chroma_format chroma_format, - unsigned width, unsigned height) + unsigned width, unsigned height, void *priv) { struct pipe_context *pipe; @@ -400,7 +401,8 @@ sp_video_create(struct pipe_screen *screen, enum pipe_video_profile profile, width, height, VL_MPEG12_MC_RENDERER_BUFFER_PICTURE, VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE, - true); + true, + PIPE_FORMAT_AYUV); } struct pipe_video_context * @@ -409,7 +411,8 @@ sp_video_create_ex(struct pipe_context *pipe, enum pipe_video_profile profile, unsigned width, unsigned height, enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode, enum VL_MPEG12_MC_RENDERER_EMPTY_BLOCK eb_handling, - bool pot_buffers) + bool pot_buffers, + enum pipe_format decode_format) { assert(pipe); assert(width && height); @@ -420,7 +423,8 @@ sp_video_create_ex(struct pipe_context *pipe, enum pipe_video_profile profile, chroma_format, width, height, bufmode, eb_handling, - pot_buffers); + pot_buffers, + decode_format); default: return NULL; } diff --git a/src/gallium/drivers/softpipe/sp_video_context.h b/src/gallium/drivers/softpipe/sp_video_context.h index bc5daa05ac6..0fe48d7a872 100644 --- a/src/gallium/drivers/softpipe/sp_video_context.h +++ b/src/gallium/drivers/softpipe/sp_video_context.h @@ -46,12 +46,14 @@ struct sp_mpeg12_context void *rast; void *dsa; void *blend; + + enum pipe_format decode_format; }; struct pipe_video_context * sp_video_create(struct pipe_screen *screen, enum pipe_video_profile profile, enum pipe_video_chroma_format chroma_format, - unsigned width, unsigned height); + unsigned width, unsigned height, void *priv); /* Other drivers can call this function in their pipe_video_context constructors and pass it an accelerated pipe_context along with suitable buffering modes, etc */ @@ -61,6 +63,7 @@ sp_video_create_ex(struct pipe_context *pipe, enum pipe_video_profile profile, unsigned width, unsigned height, enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode, enum VL_MPEG12_MC_RENDERER_EMPTY_BLOCK eb_handling, - bool pot_buffers); + bool pot_buffers, + enum pipe_format decode_format); #endif /* SP_VIDEO_CONTEXT_H */ diff --git a/src/gallium/state_trackers/xorg/xvmc/surface.c b/src/gallium/state_trackers/xorg/xvmc/surface.c index 985cc1a97a6..ea1f648e7fc 100644 --- a/src/gallium/state_trackers/xorg/xvmc/surface.c +++ b/src/gallium/state_trackers/xorg/xvmc/surface.c @@ -94,6 +94,7 @@ static enum pipe_mpeg12_motion_type MotionToPipe(int xvmc_motion_type, int xvmc_ return -1; } +#if 0 static bool CreateOrResizeBackBuffer(struct vl_context *vctx, unsigned int width, unsigned int height, struct pipe_surface **backbuffer) @@ -141,6 +142,7 @@ CreateOrResizeBackBuffer(struct vl_context *vctx, unsigned int width, unsigned i return true; } +#endif static void MacroBlocksToPipe(struct pipe_screen *screen, @@ -280,7 +282,6 @@ Status XvMCRenderSurface(Display *dpy, XvMCContext *context, unsigned int pictur XvMCSurfacePrivate *past_surface_priv; XvMCSurfacePrivate *future_surface_priv; struct pipe_mpeg12_macroblock pipe_macroblocks[num_macroblocks]; - unsigned int i; XVMC_MSG(XVMC_TRACE, "[XvMC] Rendering to surface %p.\n", target_surface); @@ -331,7 +332,7 @@ Status XvMCRenderSurface(Display *dpy, XvMCContext *context, unsigned int pictur vpipe->set_decode_target(vpipe, t_vsfc); vpipe->decode_macroblocks(vpipe, p_vsfc, f_vsfc, num_macroblocks, - &pipe_macroblocks->base, target_surface_priv->render_fence); + &pipe_macroblocks->base, &target_surface_priv->render_fence); XVMC_MSG(XVMC_TRACE, "[XvMC] Submitted surface %p for rendering.\n", target_surface); @@ -373,8 +374,7 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable, XvMCContext *context; struct pipe_video_rect src_rect = {srcx, srcy, srcw, srch}; struct pipe_video_rect dst_rect = {destx, desty, destw, desth}; - void *displaytarget; - unsigned width, height; + struct pipe_surface *drawable_surface; XVMC_MSG(XVMC_TRACE, "[XvMC] Displaying surface %p.\n", surface); @@ -387,8 +387,8 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable, context = surface_priv->context; context_priv = context->privData; - displaytarget = vl_displaytarget_get(context_priv->vctx->vscreen, drawable, &width, &height); - if (!displaytarget) + drawable_surface = vl_drawable_surface_get(context_priv->vctx->vscreen, drawable); + if (!drawable_surface) return BadDrawable; assert(flags == XVMC_TOP_FIELD || flags == XVMC_BOTTOM_FIELD || flags == XVMC_FRAME_PICTURE); @@ -402,15 +402,17 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable, * until the app updates destw and desth. */ /* - assert(destx + destw - 1 < width); - assert(desty + desth - 1 < height); + assert(destx + destw - 1 < drawable_surface->width); + assert(desty + desth - 1 < drawable_surface->height); */ subpicture_priv = surface_priv->subpicture ? surface_priv->subpicture->privData : NULL; vpipe = context_priv->vctx->vpipe; +#if 0 if (!CreateOrResizeBackBuffer(context_priv->vctx, width, height, &context_priv->backbuffer)) return BadAlloc; +#endif if (subpicture_priv) { struct pipe_video_rect src_rect = {surface_priv->subx, surface_priv->suby, surface_priv->subw, surface_priv->subh}; @@ -430,17 +432,19 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable, vpipe->set_picture_layers(vpipe, NULL, NULL, NULL, 0); vpipe->render_picture(vpipe, surface_priv->pipe_vsfc, PictureToPipe(flags), &src_rect, - context_priv->backbuffer, &dst_rect, surface_priv->disp_fence); + drawable_surface, &dst_rect, surface_priv->disp_fence); XVMC_MSG(XVMC_TRACE, "[XvMC] Submitted surface %p for display. Pushing to front buffer.\n", surface); vpipe->screen->flush_frontbuffer ( vpipe->screen, - context_priv->backbuffer, - displaytarget + drawable_surface, + vl_contextprivate_get(context_priv->vctx, drawable_surface) ); + pipe_surface_reference(&drawable_surface, NULL); + XVMC_MSG(XVMC_TRACE, "[XvMC] Pushed surface %p to front buffer.\n", surface); return Success; diff --git a/src/gallium/targets/xvmc-nouveau/Makefile b/src/gallium/targets/xvmc-nouveau/Makefile index 045dbcbf97b..fe418b07681 100644 --- a/src/gallium/targets/xvmc-nouveau/Makefile +++ b/src/gallium/targets/xvmc-nouveau/Makefile @@ -16,7 +16,7 @@ C_SOURCES = \ $(COMMON_GALLIUM_SOURCES) \ $(DRIVER_SOURCES) -DRIVER_LIBS = $(shell pkg-config libdrm_nouveau --libs) +DRIVER_LIBS = $(shell pkg-config libdrm_nouveau --libs) -lXfixes include ../Makefile.xvmc diff --git a/src/gallium/winsys/g3dvl/dri/dri_winsys.c b/src/gallium/winsys/g3dvl/dri/dri_winsys.c index 892f93df470..06631840f78 100644 --- a/src/gallium/winsys/g3dvl/dri/dri_winsys.c +++ b/src/gallium/winsys/g3dvl/dri/dri_winsys.c @@ -27,251 +27,29 @@ #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> +#include <util/u_hash.h> +#include <util/u_hash_table.h> +#include <state_tracker/drm_api.h> +#include <X11/Xlibint.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; - boolean dri2; + struct util_hash_table *drawable_table; + Drawable last_seen_drawable; }; 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; - struct pipe_surface *dri2_front; }; -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; - struct drm_clip_rect clip; - struct drm_clip_rect *cur; - int i; - - assert(vl_dri_ctx); - assert(dst); - assert(src); - assert(src_bbox); - - vpipe = vl_dri_ctx->base.vpipe; - - 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); - - if (vl_dri_ctx->drawable->cliprects) { - 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); -} - static struct pipe_surface* vl_dri2_get_front(struct vl_dri_screen *vl_dri_scrn, Drawable drawable) { @@ -286,6 +64,9 @@ vl_dri2_get_front(struct vl_dri_screen *vl_dri_scrn, Drawable drawable) dri2_front = DRI2GetBuffers(vl_dri_scrn->dri_screen->display, drawable, &w, &h, attachments, 1, &count); + + assert(count == 1); + if (dri2_front) { struct winsys_handle dri2_front_handle = { @@ -297,7 +78,7 @@ vl_dri2_get_front(struct vl_dri_screen *vl_dri_scrn, Drawable drawable) memset(&template, 0, sizeof(struct pipe_resource)); template.target = PIPE_TEXTURE_2D; - template.format = vl_dri_scrn->base.format; + template.format = PIPE_FORMAT_B8G8R8X8_UNORM; template.last_level = 0; template.width0 = w; template.height0 = h; @@ -310,8 +91,9 @@ vl_dri2_get_front(struct vl_dri_screen *vl_dri_scrn, Drawable drawable) if (front_tex) front_surf = vl_dri_scrn->base.pscreen->get_tex_surface(vl_dri_scrn->base.pscreen, front_tex, 0, 0, 0, - /*PIPE_BIND_RENDER_TARGET*/ PIPE_BIND_BLIT_DESTINATION); + PIPE_BIND_RENDER_TARGET); pipe_resource_reference(&front_tex, NULL); + Xfree(dri2_front); } return front_surf; @@ -322,119 +104,121 @@ vl_dri2_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 pipe_video_context *vpipe; + struct vl_dri_screen *vl_dri_scrn = (struct vl_dri_screen*)vl_dri_ctx->base.vscreen; assert(screen); assert(surf); assert(context_private); - assert(vl_dri_ctx->dri2_front); - - vl_dri_scrn = (struct vl_dri_screen*)vl_dri_ctx->base.vscreen; - vpipe = vl_dri_ctx->base.vpipe; - /* XXX: Why not just render to fake front? */ - vpipe->surface_copy(vpipe, vl_dri_ctx->dri2_front, 0, 0, surf, 0, 0, surf->width, surf->height); - - //st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, fence); + dri2CopyDrawable(vl_dri_scrn->dri_screen, vl_dri_scrn->last_seen_drawable, + DRI_BUFFER_FRONT_LEFT, DRI_BUFFER_FAKE_FRONT_LEFT); } -/* XXX: Kill with fire */ -struct vl_dri_context *_vl_dri_ctx = NULL; - -void* -vl_displaytarget_get(struct vl_screen *vscreen, Drawable drawable, - unsigned *width, unsigned *height) +struct pipe_surface* +vl_drawable_surface_get(struct vl_screen *vscreen, Drawable drawable) { struct vl_dri_screen *vl_dri_scrn = (struct vl_dri_screen*)vscreen; assert(vscreen); - assert(width); - assert(height); - - if (vl_dri_scrn->dri2 && _vl_dri_ctx) { - if (!_vl_dri_ctx->dri2_front) { - _vl_dri_ctx->dri2_front = vl_dri2_get_front((struct vl_dri_screen*)vscreen, drawable); - if (!_vl_dri_ctx->dri2_front) - return NULL; - *width = _vl_dri_ctx->dri2_front->width; - *height = _vl_dri_ctx->dri2_front->height; + + if (vl_dri_scrn->last_seen_drawable != drawable) { + /* Hash table business depends on this equality */ + assert(None == NULL); + Drawable lookup_drawable = (Drawable)util_hash_table_get(vl_dri_scrn->drawable_table, (void*)drawable); + if (lookup_drawable == None) { + dri2CreateDrawable(vl_dri_scrn->dri_screen, drawable); + util_hash_table_set(vl_dri_scrn->drawable_table, (void*)drawable, (void*)drawable); } - return _vl_dri_ctx; + vl_dri_scrn->last_seen_drawable = drawable; } - else - return NULL; + + return vl_dri2_get_front(vl_dri_scrn, drawable); +} + +void* +vl_contextprivate_get(struct vl_context *vctx, struct pipe_surface *displaytarget) +{ + return vctx; +} + +static unsigned drawable_hash(void *key) +{ + Drawable drawable = (Drawable)key; + assert(drawable != None); + return util_hash_crc32(&drawable, sizeof(Drawable)); +} + +static int drawable_cmp(void *key1, void *key2) +{ + Drawable d1 = (Drawable)key1; + Drawable d2 = (Drawable)key2; + assert(d1 != None); + assert(d2 != None); + return d1 != d2; +} + +static enum pipe_error +drawable_destroy(void *key, void *value, void *data) +{ + Drawable drawable = (Drawable)key; + struct vl_dri_screen *vl_dri_scrn = (struct vl_dri_screen*)data; + + assert(drawable != None); + assert(value); + assert(data); + + dri2DestroyDrawable(vl_dri_scrn->dri_screen, drawable); + + return PIPE_OK; } struct vl_screen* vl_screen_create(Display *display, int screen) { struct vl_dri_screen *vl_dri_scrn; - struct dri1_create_screen_arg arg; + struct drm_create_screen_arg arg; assert(display); vl_dri_scrn = CALLOC_STRUCT(vl_dri_screen); if (!vl_dri_scrn) - return NULL; - - /* Try DRI2 first */ - if (dri2CreateScreen(display, screen, &vl_dri_scrn->dri_screen)) { - /* If not, try DRI */ - if (driCreateScreen(display, screen, &vl_dri_scrn->dri_screen, &vl_dri_scrn->dri_framebuf)) { - /* Now what? */ - FREE(vl_dri_scrn); - return NULL; - } - else { - /* Got DRI */ - 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->dri2 = FALSE; - } - } - else { - /* Got DRI2 */ - arg.base.mode = DRM_CREATE_NORMAL; - vl_dri_scrn->dri2 = TRUE; - } + goto no_struct; + + if (dri2CreateScreen(display, screen, &vl_dri_scrn->dri_screen)) + goto no_dri2screen; vl_dri_scrn->api = drm_api_create(); - if (!vl_dri_scrn->api) { - FREE(vl_dri_scrn); - return NULL; - } + if (!vl_dri_scrn->api) + goto no_drmapi; + + arg.mode = DRM_CREATE_NORMAL; vl_dri_scrn->base.pscreen = vl_dri_scrn->api->create_screen(vl_dri_scrn->api, vl_dri_scrn->dri_screen->fd, - &arg.base); + &arg); - if (!vl_dri_scrn->base.pscreen) { - FREE(vl_dri_scrn); - return NULL; - } + if (!vl_dri_scrn->base.pscreen) + goto no_pscreen; - if (!vl_dri_scrn->dri2) { - vl_dri_scrn->visual = XDefaultVisual(display, screen); - vl_dri_scrn->api_hooks = arg.api; - vl_dri_scrn->base.format = vl_dri_scrn->api_hooks->front_srf_locked(vl_dri_scrn->base.pscreen)->format; - vl_dri_scrn->base.pscreen->flush_frontbuffer = vl_dri_flush_frontbuffer; - } - else { - /* XXX: Fuuuuu... Can't possibly get this right with current code. - * Need to rethink this in st/xvmc and winsys dri/xlib winsyses */ - vl_dri_scrn->base.format = PIPE_FORMAT_B8G8R8X8_UNORM; - vl_dri_scrn->base.pscreen->flush_frontbuffer = vl_dri2_flush_frontbuffer; - } + vl_dri_scrn->drawable_table = util_hash_table_create(&drawable_hash, &drawable_cmp); + if (!vl_dri_scrn->drawable_table) + goto no_hash; + + vl_dri_scrn->last_seen_drawable = None; + vl_dri_scrn->base.pscreen->flush_frontbuffer = vl_dri2_flush_frontbuffer; return &vl_dri_scrn->base; + +no_hash: + vl_dri_scrn->base.pscreen->destroy(vl_dri_scrn->base.pscreen); +no_pscreen: + vl_dri_scrn->api->destroy(vl_dri_scrn->api); +no_drmapi: + dri2DestroyScreen(vl_dri_scrn->dri_screen); +no_dri2screen: + FREE(vl_dri_scrn); +no_struct: + return NULL; } void vl_screen_destroy(struct vl_screen *vscreen) @@ -443,11 +227,12 @@ void vl_screen_destroy(struct vl_screen *vscreen) assert(vscreen); + util_hash_table_foreach(vl_dri_scrn->drawable_table, drawable_destroy, vl_dri_scrn); + util_hash_table_destroy(vl_dri_scrn->drawable_table); vl_dri_scrn->base.pscreen->destroy(vl_dri_scrn->base.pscreen); - if (vl_dri_scrn->dri2) - dri2DestroyScreen(vl_dri_scrn->dri_screen); - else - driDestroyScreen(vl_dri_scrn->dri_screen); + if (vl_dri_scrn->api->destroy) + vl_dri_scrn->api->destroy(vl_dri_scrn->api); + dri2DestroyScreen(vl_dri_scrn->dri_screen); FREE(vl_dri_scrn); } @@ -462,39 +247,33 @@ vl_video_create(struct vl_screen *vscreen, vl_dri_ctx = CALLOC_STRUCT(vl_dri_context); if (!vl_dri_ctx) - return NULL; - - /* XXX: Is default visual correct/sufficient here? */ - if (!vl_dri_scrn->dri2) - driCreateContext(vl_dri_scrn->dri_screen, vl_dri_scrn->visual, &vl_dri_ctx->dri_context); + goto no_struct; if (!vscreen->pscreen->video_context_create) { debug_printf("[G3DVL] No video support found on %s/%s.\n", vscreen->pscreen->get_vendor(vscreen->pscreen), vscreen->pscreen->get_name(vscreen->pscreen)); - FREE(vl_dri_ctx); - return NULL; + goto no_vpipe; } vl_dri_ctx->base.vpipe = vscreen->pscreen->video_context_create(vscreen->pscreen, profile, chroma_format, width, height, - vl_dri_ctx->dri_context); + vl_dri_ctx); - if (!vl_dri_ctx->base.vpipe) { - FREE(vl_dri_ctx); - return NULL; - } + if (!vl_dri_ctx->base.vpipe) + goto no_vpipe; 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; - if (!vl_dri_scrn->dri2) - vl_dri_ctx->lock = (drmLock*)&vl_dri_scrn->dri_screen->sarea->lock; - else - _vl_dri_ctx = vl_dri_ctx; return &vl_dri_ctx->base; + +no_vpipe: + FREE(vl_dri_ctx); +no_struct: + return NULL; } void vl_video_destroy(struct vl_context *vctx) @@ -504,9 +283,5 @@ void vl_video_destroy(struct vl_context *vctx) assert(vctx); vl_dri_ctx->base.vpipe->destroy(vl_dri_ctx->base.vpipe); - if (vl_dri_ctx->dri2_front) - pipe_surface_reference(&vl_dri_ctx->dri2_front, NULL); - if (!((struct vl_dri_screen *)vctx->vscreen)->dri2) - driDestroyContext(vl_dri_ctx->dri_context); FREE(vl_dri_ctx); } diff --git a/src/gallium/winsys/g3dvl/dri/driclient.c b/src/gallium/winsys/g3dvl/dri/driclient.c index 7a2469c0d66..90e48a7cb28 100644 --- a/src/gallium/winsys/g3dvl/dri/driclient.c +++ b/src/gallium/winsys/g3dvl/dri/driclient.c @@ -353,17 +353,36 @@ free_screen: int dri2DestroyScreen(dri_screen_t *dri_screen) { /* Not much to do here apparently... */ + assert(dri_screen); + free(dri_screen); return 0; } int dri2CreateDrawable(dri_screen_t *dri_screen, XID drawable) { + assert(dri_screen); DRI2CreateDrawable(dri_screen->display, drawable); return 0; } int dri2DestroyDrawable(dri_screen_t *dri_screen, XID drawable) { + assert(dri_screen); DRI2DestroyDrawable(dri_screen->display, drawable); return 0; } + +int dri2CopyDrawable(dri_screen_t *dri_screen, XID drawable, int dest, int src) +{ + XserverRegion region; + + assert(dri_screen); + assert(dest >= DRI_BUFFER_FRONT_LEFT && dest <= DRI_BUFFER_DEPTH_STENCIL); + assert(src >= DRI_BUFFER_FRONT_LEFT && src <= DRI_BUFFER_DEPTH_STENCIL); + + region = XFixesCreateRegionFromWindow(dri_screen->display, drawable, WindowRegionBounding); + DRI2CopyRegion(dri_screen->display, drawable, region, dest, src); + XFixesDestroyRegion(dri_screen->display, region); + + return 0; +} diff --git a/src/gallium/winsys/g3dvl/dri/driclient.h b/src/gallium/winsys/g3dvl/dri/driclient.h index c71b6c2c831..4e4fd362395 100644 --- a/src/gallium/winsys/g3dvl/dri/driclient.h +++ b/src/gallium/winsys/g3dvl/dri/driclient.h @@ -100,6 +100,7 @@ int dri2CreateScreen(Display *display, int screen, dri_screen_t **dri_screen); int dri2DestroyScreen(dri_screen_t *dri_screen); int dri2CreateDrawable(dri_screen_t *dri_screen, XID drawable); int dri2DestroyDrawable(dri_screen_t *dri_screen, XID drawable); +int dri2CopyDrawable(dri_screen_t *dri_screen, XID drawable, int dest, int src); #define DRI_BUFFER_FRONT_LEFT 0 #define DRI_BUFFER_BACK_LEFT 1 diff --git a/src/gallium/winsys/g3dvl/vl_winsys.h b/src/gallium/winsys/g3dvl/vl_winsys.h index c75ff9f32f5..381478637a8 100644 --- a/src/gallium/winsys/g3dvl/vl_winsys.h +++ b/src/gallium/winsys/g3dvl/vl_winsys.h @@ -34,11 +34,10 @@ struct pipe_screen; struct pipe_video_context; +struct pipe_surface; struct vl_screen { - Display *display; - enum pipe_format format; struct pipe_screen *pscreen; }; @@ -61,8 +60,10 @@ vl_video_create(struct vl_screen *vscreen, void vl_video_destroy(struct vl_context *vctx); +struct pipe_surface* +vl_drawable_surface_get(struct vl_screen *vscreen, Drawable drawable); + void* -vl_displaytarget_get(struct vl_screen *vscreen, Drawable drawable, - unsigned *width, unsigned *height); +vl_contextprivate_get(struct vl_context *vctx, struct pipe_surface *drawable_surface); #endif diff --git a/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c b/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c index 95c2af1e73c..0a7f324a77c 100644 --- a/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c +++ b/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c @@ -26,81 +26,136 @@ **************************************************************************/ #include <vl_winsys.h> +#include <X11/Xlibint.h> #include <state_tracker/xlib_sw_winsys.h> #include <util/u_memory.h> +#include <util/u_format.h> #include <softpipe/sp_public.h> #include <softpipe/sp_video_context.h> -/* TODO: Find a good way to calculate this */ -static enum pipe_format VisualToPipe(Visual *visual) +struct vl_xsp_screen { - assert(visual); - return PIPE_FORMAT_B8G8R8X8_UNORM; -} - -/* XXX: Not thread-safe */ -static struct xlib_drawable xdraw; - -void* -vl_displaytarget_get(struct vl_screen *vscreen, Drawable drawable, - unsigned *width_out, unsigned *height_out) + struct vl_screen base; + Display *display; + int screen; + Visual visual; + struct xlib_drawable xdraw; + struct pipe_surface *drawable_surface; +}; + +struct pipe_surface* +vl_drawable_surface_get(struct vl_screen *vscreen, Drawable drawable) { + struct vl_xsp_screen *xsp_screen = (struct vl_xsp_screen*)vscreen; Window root; int x, y; unsigned int width, height; unsigned int border_width; unsigned int depth; + struct pipe_resource templat, *drawable_tex; + struct pipe_surface *drawable_surface = NULL; assert(vscreen); + assert(drawable != None); + + if (XGetGeometry(xsp_screen->display, drawable, &root, &x, &y, &width, &height, &border_width, &depth) == BadDrawable) + return NULL; + + xsp_screen->xdraw.drawable = drawable; + + if (xsp_screen->drawable_surface) { + if (xsp_screen->drawable_surface->width == width && + xsp_screen->drawable_surface->height == height) { + pipe_surface_reference(&drawable_surface, xsp_screen->drawable_surface); + return drawable_surface; + } + else + pipe_surface_reference(&xsp_screen->drawable_surface, NULL); + } + + memset(&templat, 0, sizeof(struct pipe_resource)); + templat.target = PIPE_TEXTURE_2D; + /* XXX: Need to figure out drawable's format */ + templat.format = PIPE_FORMAT_B8G8R8X8_UNORM; + templat.last_level = 0; + templat.width0 = width; + templat.height0 = height; + templat.depth0 = 1; + templat.usage = PIPE_USAGE_DEFAULT; + templat.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_BLIT_SOURCE; + templat.flags = 0; + + drawable_tex = vscreen->pscreen->resource_create(vscreen->pscreen, &templat); + if (!drawable_tex) + return NULL; + + xsp_screen->drawable_surface = vscreen->pscreen->get_tex_surface(vscreen->pscreen, drawable_tex, + 0, 0, 0, + templat.bind); + pipe_resource_reference(&drawable_tex, NULL); - if (XGetGeometry(vscreen->display, drawable, &root, &x, &y, &width, &height, &border_width, &depth) == BadDrawable) + if (!xsp_screen->drawable_surface) return NULL; - if (width_out) *width_out = width; - if (height_out) *height_out = height; + pipe_surface_reference(&drawable_surface, xsp_screen->drawable_surface); + + xsp_screen->xdraw.depth = 24/*util_format_get_blocksizebits(templat.format) / + util_format_get_blockwidth(templat.format)*/; + + return drawable_surface; +} + +void* +vl_contextprivate_get(struct vl_context *vctx, struct pipe_surface *drawable_surface) +{ + struct vl_xsp_screen *xsp_screen = (struct vl_xsp_screen*)vctx->vscreen; - xdraw.depth = depth; - xdraw.drawable = drawable; + assert(vctx); + assert(drawable_surface); + assert(xsp_screen->drawable_surface == drawable_surface); - return &xdraw; + return &xsp_screen->xdraw; } struct vl_screen* vl_screen_create(Display *display, int screen) { - struct vl_screen *vscreen; + struct vl_xsp_screen *xsp_screen; struct sw_winsys *winsys; assert(display); - vscreen = CALLOC_STRUCT(vl_screen); - if (!vscreen) + xsp_screen = CALLOC_STRUCT(vl_xsp_screen); + if (!xsp_screen) return NULL; winsys = xlib_create_sw_winsys(display); if (!winsys) { - FREE(vscreen); + FREE(xsp_screen); return NULL; } - vscreen->pscreen = softpipe_create_screen(winsys); - if (!vscreen->pscreen) { + xsp_screen->base.pscreen = softpipe_create_screen(winsys); + if (!xsp_screen->base.pscreen) { winsys->destroy(winsys); - FREE(vscreen); + FREE(xsp_screen); return NULL; } - vscreen->display = display; - xdraw.visual = XDefaultVisual(display, screen); - vscreen->format = VisualToPipe(xdraw.visual); + xsp_screen->display = display; + xsp_screen->screen = screen; + xsp_screen->xdraw.visual = XDefaultVisual(display, screen); - return vscreen; + return &xsp_screen->base; } void vl_screen_destroy(struct vl_screen *vscreen) { + struct vl_xsp_screen *xsp_screen = (struct vl_xsp_screen*)vscreen; + assert(vscreen); + pipe_surface_reference(&xsp_screen->drawable_surface, NULL); vscreen->pscreen->destroy(vscreen->pscreen); FREE(vscreen); } @@ -142,8 +197,6 @@ void vl_video_destroy(struct vl_context *vctx) { assert(vctx); -#if 1 vctx->vpipe->destroy(vctx->vpipe); -#endif FREE(vctx); } |