vl: Drop DRI1, clean up DRI2 bits.

This commit is contained in:
Younes Manton 2010-06-06 11:48:47 -04:00
parent 156fbb9fc5
commit 6414952efe
10 changed files with 249 additions and 388 deletions

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;

View File

@ -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

View File

@ -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;
goto no_struct;
/* 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;
}
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);
}

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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;
}
struct vl_screen base;
Display *display;
int screen;
Visual visual;
struct xlib_drawable xdraw;
struct pipe_surface *drawable_surface;
};
/* 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 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(vscreen->display, drawable, &root, &x, &y, &width, &height, &border_width, &depth) == BadDrawable)
if (XGetGeometry(xsp_screen->display, drawable, &root, &x, &y, &width, &height, &border_width, &depth) == BadDrawable)
return NULL;
if (width_out) *width_out = width;
if (height_out) *height_out = height;
xsp_screen->xdraw.drawable = drawable;
xdraw.depth = depth;
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);
}
return &xdraw;
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 (!xsp_screen->drawable_surface)
return NULL;
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;
assert(vctx);
assert(drawable_surface);
assert(xsp_screen->drawable_surface == drawable_surface);
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);
}