vl: Drop DRI1, clean up DRI2 bits.
This commit is contained in:
parent
156fbb9fc5
commit
6414952efe
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue