diff options
21 files changed, 957 insertions, 196 deletions
diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h index 42c77e5e778..600a86c795d 100644 --- a/src/gallium/drivers/nouveau/nouveau_winsys.h +++ b/src/gallium/drivers/nouveau/nouveau_winsys.h @@ -53,6 +53,12 @@ nv40_screen_create(struct pipe_winsys *ws, struct nouveau_device *); extern struct pipe_context * nv40_create(struct pipe_screen *, unsigned pctx_id); +extern struct pipe_video_context * +nv40_video_create(struct pipe_context *pipe, enum pipe_video_profile profile, + enum pipe_video_chroma_format chroma_format, + unsigned width, unsigned height, + unsigned pvctx_id); + extern struct pipe_screen * nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *); diff --git a/src/gallium/drivers/nv40/Makefile b/src/gallium/drivers/nv40/Makefile index 0ecae2b4913..09348d98a74 100644 --- a/src/gallium/drivers/nv40/Makefile +++ b/src/gallium/drivers/nv40/Makefile @@ -24,6 +24,7 @@ C_SOURCES = \ nv40_surface.c \ nv40_transfer.c \ nv40_vbo.c \ - nv40_vertprog.c + nv40_vertprog.c \ + nv40_video_context.c include ../../Makefile.template diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index 465dd3b0693..3e742007744 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -204,6 +204,58 @@ nv40_miptree_surface_del(struct pipe_surface *ps) FREE(ps); } +static struct pipe_video_surface* +nv40_video_surface_new(struct pipe_screen *screen, + enum pipe_video_chroma_format chroma_format, + unsigned width, unsigned height) +{ + struct nv40_video_surface *nv40_vsfc; + struct pipe_texture template; + + assert(screen); + assert(width && height); + + nv40_vsfc = CALLOC_STRUCT(nv40_video_surface); + if (!nv40_vsfc) + return NULL; + + pipe_reference_init(&nv40_vsfc->base.reference, 1); + nv40_vsfc->base.screen = screen; + nv40_vsfc->base.chroma_format = chroma_format; + /*nv40_vsfc->base.surface_format = PIPE_VIDEO_SURFACE_FORMAT_VUYA;*/ + nv40_vsfc->base.width = width; + nv40_vsfc->base.height = height; + + memset(&template, 0, sizeof(struct pipe_texture)); + template.target = PIPE_TEXTURE_2D; + template.format = PIPE_FORMAT_X8R8G8B8_UNORM; + template.last_level = 0; + /* vl_mpeg12_mc_renderer expects this when it's initialized with pot_buffers=true */ + template.width[0] = util_next_power_of_two(width); + template.height[0] = util_next_power_of_two(height); + template.depth[0] = 1; + pf_get_block(template.format, &template.block); + template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER | PIPE_TEXTURE_USAGE_RENDER_TARGET; + + nv40_vsfc->tex = screen->texture_create(screen, &template); + if (!nv40_vsfc->tex) { + FREE(nv40_vsfc); + return NULL; + } + + return &nv40_vsfc->base; +} + + +static void +nv40_video_surface_del(struct pipe_video_surface *vsfc) +{ + struct nv40_video_surface *nv40_vsfc = nv40_video_surface(vsfc); + + pipe_texture_reference(&nv40_vsfc->tex, NULL); + FREE(nv40_vsfc); +} + void nv40_screen_init_miptree_functions(struct pipe_screen *pscreen) { @@ -212,5 +264,7 @@ nv40_screen_init_miptree_functions(struct pipe_screen *pscreen) pscreen->texture_destroy = nv40_miptree_destroy; pscreen->get_tex_surface = nv40_miptree_surface_new; pscreen->tex_surface_destroy = nv40_miptree_surface_del; + pscreen->video_surface_create = nv40_video_surface_new; + pscreen->video_surface_destroy = nv40_video_surface_del; } diff --git a/src/gallium/drivers/nv40/nv40_state.h b/src/gallium/drivers/nv40/nv40_state.h index 8a9d8c8fdf6..ae32777f754 100644 --- a/src/gallium/drivers/nv40/nv40_state.h +++ b/src/gallium/drivers/nv40/nv40_state.h @@ -2,6 +2,7 @@ #define __NV40_STATE_H__ #include "pipe/p_state.h" +#include "pipe/p_video_state.h" #include "tgsi/tgsi_scan.h" struct nv40_sampler_state { @@ -85,4 +86,16 @@ struct nv40_miptree { } level[PIPE_MAX_TEXTURE_LEVELS]; }; +struct nv40_video_surface { + struct pipe_video_surface base; + struct pipe_texture *tex; +}; + + +static INLINE struct nv40_video_surface* +nv40_video_surface(struct pipe_video_surface *sfc) +{ + return (struct nv40_video_surface*)sfc; +} + #endif diff --git a/src/gallium/drivers/nv40/nv40_video_context.c b/src/gallium/drivers/nv40/nv40_video_context.c new file mode 100644 index 00000000000..e2985e5a9c8 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_video_context.c @@ -0,0 +1,43 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "nv40_video_context.h" +#include <softpipe/sp_video_context.h> + + +struct pipe_video_context * +nv40_video_create(struct pipe_context *pipe, enum pipe_video_profile profile, + enum pipe_video_chroma_format chroma_format, + unsigned width, unsigned height, + unsigned pvctx_id) +{ + assert(pipe); + 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); +} diff --git a/src/gallium/drivers/nv40/nv40_video_context.h b/src/gallium/drivers/nv40/nv40_video_context.h new file mode 100644 index 00000000000..206a342e35e --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_video_context.h @@ -0,0 +1,41 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef __NV40_VIDEO_CONTEXT_H__ +#define __NV40_VIDEO_CONTEXT_H__ + +#include <pipe/p_video_context.h> + +struct pipe_context; + +struct pipe_video_context* +nv40_video_create(struct pipe_context *pipe, enum pipe_video_profile profile, + enum pipe_video_chroma_format chroma_format, + unsigned width, unsigned height, + unsigned pvctx_id); + +#endif diff --git a/src/gallium/drivers/softpipe/sp_video_context.c b/src/gallium/drivers/softpipe/sp_video_context.c index cae2d3efc58..f4f34e7a905 100644 --- a/src/gallium/drivers/softpipe/sp_video_context.c +++ b/src/gallium/drivers/softpipe/sp_video_context.c @@ -1,8 +1,8 @@ /************************************************************************** - * + * * Copyright 2009 Younes Manton. * All Rights Reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including @@ -10,11 +10,11 @@ * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. @@ -22,12 +22,13 @@ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * **************************************************************************/ #include "sp_video_context.h" #include <pipe/p_inlines.h> #include <util/u_memory.h> +#include <util/u_rect.h> #include "softpipe/sp_winsys.h" #include "softpipe/sp_texture.h" @@ -79,18 +80,40 @@ sp_mpeg12_decode_macroblocks(struct pipe_video_context *vpipe, } static void -sp_mpeg12_clear_surface(struct pipe_video_context *vpipe, - unsigned x, unsigned y, - unsigned width, unsigned height, - unsigned value, - struct pipe_surface *surface) +sp_mpeg12_surface_fill(struct pipe_video_context *vpipe, + struct pipe_surface *dst, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height, + unsigned value) { struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe; assert(vpipe); - assert(surface); + assert(dst); - ctx->pipe->surface_fill(ctx->pipe, surface, x, y, width, height, value); + if (ctx->pipe->surface_fill) + ctx->pipe->surface_fill(ctx->pipe, dst, dstx, dsty, width, height, value); + else + util_surface_fill(ctx->pipe, dst, dstx, dsty, width, height, value); +} + +static void +sp_mpeg12_surface_copy(struct pipe_video_context *vpipe, + struct pipe_surface *dst, + unsigned dstx, unsigned dsty, + struct pipe_surface *src, + unsigned srcx, unsigned srcy, + unsigned width, unsigned height) +{ + struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe; + + assert(vpipe); + assert(dst); + + if (ctx->pipe->surface_copy) + ctx->pipe->surface_copy(ctx->pipe, dst, dstx, dsty, src, srcx, srcy, width, height); + else + util_surface_copy(ctx->pipe, FALSE, dst, dstx, dsty, src, srcx, srcy, width, height); } static void @@ -136,7 +159,8 @@ sp_mpeg12_set_decode_target(struct pipe_video_context *vpipe, pipe_video_surface_reference(&ctx->decode_target, dt); } -static void sp_mpeg12_set_csc_matrix(struct pipe_video_context *vpipe, const float *mat) +static void +sp_mpeg12_set_csc_matrix(struct pipe_video_context *vpipe, const float *mat) { struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe; @@ -181,6 +205,7 @@ init_pipe_state(struct sp_mpeg12_context *ctx) rast.point_size = 1; rast.offset_units = 1; rast.offset_scale = 1; + rast.gl_rasterization_rules = 1; /*rast.sprite_coord_mode[i] = ;*/ ctx->rast = ctx->pipe->create_rasterizer_state(ctx->pipe, &rast); ctx->pipe->bind_rasterizer_state(ctx->pipe, ctx->rast); @@ -223,9 +248,12 @@ init_pipe_state(struct sp_mpeg12_context *ctx) } static struct pipe_video_context * -sp_mpeg12_create(struct pipe_screen *screen, enum pipe_video_profile profile, +sp_mpeg12_create(struct pipe_context *pipe, enum pipe_video_profile profile, enum pipe_video_chroma_format chroma_format, - unsigned width, unsigned height) + unsigned width, unsigned height, + enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode, + enum VL_MPEG12_MC_RENDERER_EMPTY_BLOCK eb_handling, + bool pot_buffers) { struct sp_mpeg12_context *ctx; @@ -241,27 +269,20 @@ sp_mpeg12_create(struct pipe_screen *screen, enum pipe_video_profile profile, ctx->base.width = width; ctx->base.height = height; - ctx->base.screen = screen; + ctx->base.screen = pipe->screen; ctx->base.destroy = sp_mpeg12_destroy; ctx->base.decode_macroblocks = sp_mpeg12_decode_macroblocks; - ctx->base.clear_surface = sp_mpeg12_clear_surface; ctx->base.render_picture = sp_mpeg12_render_picture; + ctx->base.surface_fill = sp_mpeg12_surface_fill; + ctx->base.surface_copy = sp_mpeg12_surface_copy; ctx->base.set_decode_target = sp_mpeg12_set_decode_target; ctx->base.set_csc_matrix = sp_mpeg12_set_csc_matrix; - ctx->pipe = softpipe_create(screen); - if (!ctx->pipe) { - FREE(ctx); - return NULL; - } + ctx->pipe = pipe; - /* TODO: Use slice buffering for softpipe when implemented, no advantage to buffering an entire picture */ if (!vl_mpeg12_mc_renderer_init(&ctx->mc_renderer, ctx->pipe, width, height, chroma_format, - VL_MPEG12_MC_RENDERER_BUFFER_PICTURE, - /* TODO: Use XFER_NONE when implemented */ - VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE, - true)) { + bufmode, eb_handling, pot_buffers)) { ctx->pipe->destroy(ctx->pipe); FREE(ctx); return NULL; @@ -290,14 +311,43 @@ sp_video_create(struct pipe_screen *screen, enum pipe_video_profile profile, enum pipe_video_chroma_format chroma_format, unsigned width, unsigned height) { + struct pipe_context *pipe; + + assert(screen); + assert(width && height); + + pipe = softpipe_create(screen); + if (!pipe) + return NULL; + + /* TODO: Use slice buffering for softpipe when implemented, no advantage to buffering an entire picture with softpipe */ + /* TODO: Use XFER_NONE when implemented */ + 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); +} + +struct pipe_video_context * +sp_video_create_ex(struct pipe_context *pipe, enum pipe_video_profile profile, + enum pipe_video_chroma_format chroma_format, + unsigned width, unsigned height, + enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode, + enum VL_MPEG12_MC_RENDERER_EMPTY_BLOCK eb_handling, + bool pot_buffers) +{ assert(screen); assert(width && height); switch (u_reduce_video_profile(profile)) { case PIPE_VIDEO_CODEC_MPEG12: - return sp_mpeg12_create(screen, profile, + return sp_mpeg12_create(pipe, profile, chroma_format, - width, height); + width, height, + bufmode, eb_handling, + pot_buffers); default: return NULL; } diff --git a/src/gallium/drivers/softpipe/sp_video_context.h b/src/gallium/drivers/softpipe/sp_video_context.h index ccbd1ffe4c8..40743ac423c 100644 --- a/src/gallium/drivers/softpipe/sp_video_context.h +++ b/src/gallium/drivers/softpipe/sp_video_context.h @@ -1,8 +1,8 @@ /************************************************************************** - * + * * Copyright 2009 Younes Manton. * All Rights Reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including @@ -10,11 +10,11 @@ * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. @@ -22,7 +22,7 @@ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * **************************************************************************/ #ifndef SP_VIDEO_CONTEXT_H @@ -54,4 +54,14 @@ sp_video_create(struct pipe_screen *screen, enum pipe_video_profile profile, enum pipe_video_chroma_format chroma_format, unsigned width, unsigned height); +/* 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 */ +struct pipe_video_context * +sp_video_create_ex(struct pipe_context *pipe, enum pipe_video_profile profile, + enum pipe_video_chroma_format chroma_format, + unsigned width, unsigned height, + enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode, + enum VL_MPEG12_MC_RENDERER_EMPTY_BLOCK eb_handling, + bool pot_buffers); + #endif /* SP_VIDEO_CONTEXT_H */ diff --git a/src/gallium/include/pipe/p_video_context.h b/src/gallium/include/pipe/p_video_context.h index 6ae31418fa8..9ae595b224e 100644 --- a/src/gallium/include/pipe/p_video_context.h +++ b/src/gallium/include/pipe/p_video_context.h @@ -72,12 +72,6 @@ struct pipe_video_context struct pipe_macroblock *macroblocks, struct pipe_fence_handle **fence); - void (*clear_surface)(struct pipe_video_context *vpipe, - unsigned x, unsigned y, - unsigned width, unsigned height, - unsigned value, - struct pipe_surface *surface); - void (*render_picture)(struct pipe_video_context *vpipe, /*struct pipe_surface *backround, struct pipe_video_rect *backround_area,*/ @@ -95,6 +89,20 @@ struct pipe_video_context struct pipe_video_rect *layer_src_areas, struct pipe_video_rect *layer_dst_areas,*/ struct pipe_fence_handle **fence); + + void (*surface_fill)(struct pipe_video_context *vpipe, + struct pipe_surface *dst, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height, + unsigned value); + + void (*surface_copy)(struct pipe_video_context *vpipe, + struct pipe_surface *dst, + unsigned dstx, unsigned dsty, + struct pipe_surface *src, + unsigned srcx, unsigned srcy, + unsigned width, unsigned height); + /*@}*/ /** diff --git a/src/gallium/include/state_tracker/dri1_api.h b/src/gallium/include/state_tracker/dri1_api.h index b173ba3683d..603f5d8af83 100644 --- a/src/gallium/include/state_tracker/dri1_api.h +++ b/src/gallium/include/state_tracker/dri1_api.h @@ -29,11 +29,11 @@ struct dri1_api_version struct dri1_api_lock_funcs { - void (*lock) (struct pipe_context * pipe); - void (*unlock) (struct pipe_context * locked_pipe); - boolean(*is_locked) (struct pipe_context * locked_pipe); - boolean(*is_lock_lost) (struct pipe_context * locked_pipe); - void (*clear_lost_lock) (struct pipe_context * locked_pipe); + void (*lock) (void *pipe_priv); + void (*unlock) (void *locked_pipe_priv); + boolean(*is_locked) (void *locked_pipe_priv); + boolean(*is_lock_lost) (void *locked_pipe_priv); + void (*clear_lost_lock) (void *locked_pipe_priv); }; struct dri1_api @@ -46,7 +46,7 @@ struct dri1_api /*@{ */ - struct pipe_surface *(*front_srf_locked) (struct pipe_context * + struct pipe_surface *(*front_srf_locked) (struct pipe_screen * locked_pipe); void (*present_locked) (struct pipe_context * locked_pipe, diff --git a/src/gallium/include/state_tracker/drm_api.h b/src/gallium/include/state_tracker/drm_api.h index 4d1259e1ee7..ea0b91c5813 100644 --- a/src/gallium/include/state_tracker/drm_api.h +++ b/src/gallium/include/state_tracker/drm_api.h @@ -8,6 +8,7 @@ struct pipe_screen; struct pipe_winsys; struct pipe_buffer; struct pipe_context; +struct pipe_video_context; struct pipe_texture; enum drm_create_screen_mode { @@ -36,6 +37,11 @@ struct drm_api struct drm_create_screen_arg *arg); struct pipe_context* (*create_context)(struct drm_api *api, struct pipe_screen *screen); + struct pipe_video_context* (*create_video_context)(struct drm_api *api, + struct pipe_screen *screen, + enum pipe_video_profile profile, + enum pipe_video_chroma_format chroma_format, + unsigned width, unsigned height); /*@}*/ /** diff --git a/src/gallium/state_trackers/dri/dri_context.c b/src/gallium/state_trackers/dri/dri_context.c index 8819936fcaf..3ddff30f883 100644 --- a/src/gallium/state_trackers/dri/dri_context.c +++ b/src/gallium/state_trackers/dri/dri_context.c @@ -175,33 +175,33 @@ dri_make_current(__DRIcontextPrivate * cPriv, } static void -st_dri_lock(struct pipe_context *pipe) +st_dri_lock(void *pipe_priv) { - dri_lock((struct dri_context *)pipe->priv); + dri_lock((struct dri_context *)pipe_priv); } static void -st_dri_unlock(struct pipe_context *pipe) +st_dri_unlock(void *pipe_priv) { - dri_unlock((struct dri_context *)pipe->priv); + dri_unlock((struct dri_context *)pipe_priv); } static boolean -st_dri_is_locked(struct pipe_context *pipe) +st_dri_is_locked(void *pipe_priv) { - return ((struct dri_context *)pipe->priv)->isLocked; + return ((struct dri_context *)pipe_priv)->isLocked; } static boolean -st_dri_lost_lock(struct pipe_context *pipe) +st_dri_lost_lock(void *pipe_priv) { - return ((struct dri_context *)pipe->priv)->wsLostLock; + return ((struct dri_context *)pipe_priv)->wsLostLock; } static void -st_dri_clear_lost_lock(struct pipe_context *pipe) +st_dri_clear_lost_lock(void *pipe_priv) { - ((struct dri_context *)pipe->priv)->wsLostLock = FALSE; + ((struct dri_context *)pipe_priv)->wsLostLock = FALSE; } struct dri1_api_lock_funcs dri1_lf = { diff --git a/src/gallium/state_trackers/xorg/xvmc/context.c b/src/gallium/state_trackers/xorg/xvmc/context.c index c8a389385a8..56003618ada 100644 --- a/src/gallium/state_trackers/xorg/xvmc/context.c +++ b/src/gallium/state_trackers/xorg/xvmc/context.c @@ -1,8 +1,8 @@ /************************************************************************** - * + * * Copyright 2009 Younes Manton. * All Rights Reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including @@ -10,11 +10,11 @@ * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. @@ -22,7 +22,7 @@ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * **************************************************************************/ #include <assert.h> @@ -121,7 +121,7 @@ static enum pipe_video_profile ProfileToPipe(int xvmc_profile) assert(0); if (xvmc_profile & XVMC_MPEG_4) assert(0); - + assert(0); return -1; @@ -152,8 +152,8 @@ Status XvMCCreateContext(Display *dpy, XvPortID port, int surface_type_id, int mc_type; int surface_flags; Status ret; - struct pipe_screen *screen; - struct pipe_video_context *vpipe; + struct vl_screen *vscreen; + struct vl_context *vctx; XvMCContextPrivate *context_priv; float csc[16]; @@ -188,18 +188,18 @@ Status XvMCCreateContext(Display *dpy, XvPortID port, int surface_type_id, return BadAlloc; /* TODO: Reuse screen if process creates another context */ - screen = vl_screen_create(dpy, scrn); + vscreen = vl_screen_create(dpy, scrn); - if (!screen) { + if (!vscreen) { FREE(context_priv); return BadAlloc; } - vpipe = vl_video_create(dpy, scrn, screen, ProfileToPipe(mc_type), - FormatToPipe(chroma_format), width, height); + vctx = vl_video_create(vscreen, ProfileToPipe(mc_type), + FormatToPipe(chroma_format), width, height); - if (!vpipe) { - screen->destroy(screen); + if (!vctx) { + vl_screen_destroy(vscreen); FREE(context_priv); return BadAlloc; } @@ -211,9 +211,9 @@ Status XvMCCreateContext(Display *dpy, XvPortID port, int surface_type_id, VL_CSC_COLOR_STANDARD_IDENTITY : VL_CSC_COLOR_STANDARD_BT_601, NULL, true, csc ); - vpipe->set_csc_matrix(vpipe, csc); + vctx->vpipe->set_csc_matrix(vctx->vpipe, csc); - context_priv->vpipe = vpipe; + context_priv->vctx = vctx; context->context_id = XAllocID(dpy); context->surface_type_id = surface_type_id; @@ -222,7 +222,7 @@ Status XvMCCreateContext(Display *dpy, XvPortID port, int surface_type_id, context->flags = flags; context->port = port; context->privData = context_priv; - + SyncHandle(); return Success; @@ -230,8 +230,8 @@ Status XvMCCreateContext(Display *dpy, XvPortID port, int surface_type_id, Status XvMCDestroyContext(Display *dpy, XvMCContext *context) { - struct pipe_screen *screen; - struct pipe_video_context *vpipe; + struct vl_screen *vscreen; + struct vl_context *vctx; XvMCContextPrivate *context_priv; assert(dpy); @@ -240,11 +240,11 @@ Status XvMCDestroyContext(Display *dpy, XvMCContext *context) return XvMCBadContext; context_priv = context->privData; - vpipe = context_priv->vpipe; + vctx = context_priv->vctx; pipe_surface_reference(&context_priv->backbuffer, NULL); - screen = vpipe->screen; - vpipe->destroy(vpipe); - screen->destroy(screen); + vscreen = vctx->vscreen; + vl_video_destroy(vctx); + vl_screen_destroy(vscreen); FREE(context_priv); context->privData = NULL; diff --git a/src/gallium/state_trackers/xorg/xvmc/surface.c b/src/gallium/state_trackers/xorg/xvmc/surface.c index bf9038f356e..e1779eafa27 100644 --- a/src/gallium/state_trackers/xorg/xvmc/surface.c +++ b/src/gallium/state_trackers/xorg/xvmc/surface.c @@ -27,6 +27,7 @@ #include <assert.h> #include <X11/Xlibint.h> +#include <vl_winsys.h> #include <pipe/p_video_context.h> #include <pipe/p_video_state.h> #include <pipe/p_state.h> @@ -83,13 +84,16 @@ static enum pipe_mpeg12_motion_type MotionToPipe(int xvmc_motion_type, int xvmc_ } static bool -CreateOrResizeBackBuffer(struct pipe_video_context *vpipe, unsigned int width, unsigned int height, +CreateOrResizeBackBuffer(struct vl_context *vctx, unsigned int width, unsigned int height, struct pipe_surface **backbuffer) { + struct pipe_video_context *vpipe; struct pipe_texture template; struct pipe_texture *tex; - assert(vpipe); + assert(vctx); + + vpipe = vctx->vpipe; if (*backbuffer) { if ((*backbuffer)->width != width || (*backbuffer)->height != height) @@ -100,8 +104,7 @@ CreateOrResizeBackBuffer(struct pipe_video_context *vpipe, unsigned int width, u memset(&template, 0, sizeof(struct pipe_texture)); template.target = PIPE_TEXTURE_2D; - /* XXX: Needs to match the drawable's format? */ - template.format = PIPE_FORMAT_X8R8G8B8_UNORM; + template.format = vctx->vscreen->format; template.last_level = 0; template.width[0] = width; template.height[0] = height; @@ -123,7 +126,7 @@ CreateOrResizeBackBuffer(struct pipe_video_context *vpipe, unsigned int width, u /* Clear the backbuffer in case the video doesn't cover the whole window */ /* FIXME: Need to clear every time a frame moves and leaves dirty rects */ - vpipe->clear_surface(vpipe, 0, 0, width, height, 0, *backbuffer); + vpipe->surface_fill(vpipe, *backbuffer, 0, 0, width, height, 0); return true; } @@ -186,7 +189,7 @@ Status XvMCCreateSurface(Display *dpy, XvMCContext *context, XvMCSurface *surfac return XvMCBadSurface; context_priv = context->privData; - vpipe = context_priv->vpipe; + vpipe = context_priv->vctx->vpipe; surface_priv = CALLOC(1, sizeof(XvMCSurfacePrivate)); if (!surface_priv) @@ -266,7 +269,7 @@ Status XvMCRenderSurface(Display *dpy, XvMCContext *context, unsigned int pictur assert(!future_surface || future_surface_priv->context == context); context_priv = context->privData; - vpipe = context_priv->vpipe; + vpipe = context_priv->vctx->vpipe; t_vsfc = target_surface_priv->pipe_vsfc; p_vsfc = past_surface ? past_surface_priv->pipe_vsfc : NULL; @@ -345,15 +348,15 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable, surface_priv = surface->privData; context = surface_priv->context; context_priv = context->privData; - vpipe = context_priv->vpipe; + vpipe = context_priv->vctx->vpipe; - if (!CreateOrResizeBackBuffer(vpipe, width, height, &context_priv->backbuffer)) + if (!CreateOrResizeBackBuffer(context_priv->vctx, width, height, &context_priv->backbuffer)) return BadAlloc; vpipe->render_picture(vpipe, surface_priv->pipe_vsfc, PictureToPipe(flags), &src_rect, context_priv->backbuffer, &dst_rect, surface_priv->disp_fence); - vl_video_bind_drawable(vpipe, drawable); + vl_video_bind_drawable(context_priv->vctx, drawable); vpipe->screen->flush_frontbuffer ( diff --git a/src/gallium/state_trackers/xorg/xvmc/xvmc_private.h b/src/gallium/state_trackers/xorg/xvmc/xvmc_private.h index 42337631ca1..5fb994db740 100644 --- a/src/gallium/state_trackers/xorg/xvmc/xvmc_private.h +++ b/src/gallium/state_trackers/xorg/xvmc/xvmc_private.h @@ -34,13 +34,13 @@ #define BLOCK_SIZE_SAMPLES 64 #define BLOCK_SIZE_BYTES (BLOCK_SIZE_SAMPLES * 2) -struct pipe_video_context; +struct vl_context; struct pipe_surface; struct pipe_fence_handle; typedef struct { - struct pipe_video_context *vpipe; + struct vl_context *vctx; struct pipe_surface *backbuffer; } XvMCContextPrivate; diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c index 317dc44d22f..47e53936749 100644 --- a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c +++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c @@ -45,9 +45,9 @@ dri_surface_from_handle(struct drm_api *api, struct pipe_screen *pscreen, } static struct pipe_surface * -nouveau_dri1_front_surface(struct pipe_context *pipe) +nouveau_dri1_front_surface(struct pipe_screen *screen) { - return nouveau_winsys_screen(pipe->screen)->front; + return nouveau_winsys_screen(screen)->front; } static struct dri1_api nouveau_dri1_api = { @@ -190,6 +190,54 @@ nouveau_drm_create_context(struct drm_api *api, struct pipe_screen *pscreen) return nvws->pctx[i]; } +typedef struct pipe_video_context* (*nouveau_video_create)(struct pipe_context *pipe, + enum pipe_video_profile profile, + enum pipe_video_chroma_format chroma_format, + unsigned width, unsigned height, + unsigned pvctx); + +static struct pipe_video_context * +nouveau_drm_create_video_context(struct drm_api *api, struct pipe_screen *pscreen, + enum pipe_video_profile profile, + enum pipe_video_chroma_format chroma_format, + unsigned width, unsigned height) +{ + struct nouveau_winsys *nvws = nouveau_winsys_screen(pscreen); + nouveau_video_create init; + unsigned chipset = nouveau_screen(pscreen)->device->chipset; + struct pipe_context *pipe; + int i; + + switch (chipset & 0xf0) { + case 0x40: + case 0x60: + init = nv40_video_create; + break; + default: + debug_printf("%s: unknown chipset nv%02x\n", __func__, chipset); + return NULL; + } + + /* Find a free slot for a pipe video context, allocate a new one if needed */ + for (i = 0; i < nvws->nr_pvctx; i++) { + if (nvws->pvctx[i] == NULL) + break; + } + + if (i == nvws->nr_pvctx) { + nvws->nr_pvctx++; + nvws->pvctx = realloc(nvws->pvctx, + sizeof(*nvws->pvctx) * nvws->nr_pvctx); + } + + pipe = nouveau_drm_create_context(api, pscreen); + if (!pipe) + return NULL; + + nvws->pvctx[i] = init(pipe, profile, chroma_format, width, height, i); + return nvws->pvctx[i]; +} + static struct pipe_texture * nouveau_drm_pt_from_name(struct drm_api *api, struct pipe_screen *pscreen, struct pipe_texture *templ, const char *name, @@ -254,6 +302,7 @@ nouveau_drm_handle_from_pt(struct drm_api *api, struct pipe_screen *pscreen, struct drm_api drm_api_hooks = { .create_screen = nouveau_drm_create_screen, .create_context = nouveau_drm_create_context, + .create_video_context = nouveau_drm_create_video_context, .texture_from_shared_handle = nouveau_drm_pt_from_name, .shared_handle_from_texture = nouveau_drm_name_from_pt, .local_handle_from_texture = nouveau_drm_handle_from_pt, diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h index e61e0e0957a..fa4e821e60c 100644 --- a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h +++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h @@ -15,6 +15,8 @@ struct nouveau_winsys { unsigned nr_pctx; struct pipe_context **pctx; + unsigned nr_pvctx; + struct pipe_video_context **pvctx; struct pipe_surface *front; }; diff --git a/src/gallium/winsys/g3dvl/nouveau/Makefile b/src/gallium/winsys/g3dvl/nouveau/Makefile index 2997f6b79ce..4eba18a0d5c 100644 --- a/src/gallium/winsys/g3dvl/nouveau/Makefile +++ b/src/gallium/winsys/g3dvl/nouveau/Makefile @@ -1,50 +1,98 @@ -TARGET = libnouveau_dri.so -GALLIUMDIR = ../../.. -DRMDIR ?= /usr -DRIDIR = ../../../../driclient - -OBJECTS = nouveau_screen_vl.o nouveau_context_vl.o nouveau_swapbuffers.o - -CFLAGS += -g -Wall -Werror=implicit-function-declaration -fPIC \ - -I${GALLIUMDIR}/include \ - -I${GALLIUMDIR}/winsys/g3dvl \ - -I${GALLIUMDIR}/winsys/drm/nouveau \ - -I${DRMDIR}/include \ - -I${DRMDIR}/include/drm \ - -I${DRMDIR}/include/nouveau \ - -I${GALLIUMDIR}/drivers \ - -I${GALLIUMDIR}/auxiliary \ - -I${DRIDIR}/include - -LDFLAGS += -L${DRMDIR}/lib \ - -L${DRIDIR}/lib \ - -L${GALLIUMDIR}/winsys/drm/nouveau/common \ - -L${GALLIUMDIR}/auxiliary/draw \ - -L${GALLIUMDIR}/auxiliary/tgsi \ - -L${GALLIUMDIR}/auxiliary/translate \ - -L${GALLIUMDIR}/auxiliary/rtasm \ - -L${GALLIUMDIR}/auxiliary/cso_cache \ - -L${GALLIUMDIR}/drivers/nv04 \ - -L${GALLIUMDIR}/drivers/nv10 \ - -L${GALLIUMDIR}/drivers/nv20 \ - -L${GALLIUMDIR}/drivers/nv30 \ - -L${GALLIUMDIR}/drivers/nv40 \ - -L${GALLIUMDIR}/drivers/nv50 - -LIBS += -lnouveaudrm -ldriclient -ldrm_nouveau -ldrm -lnv04 -lnv10 -lnv20 -lnv30 -lnv40 -lnv50 -ldraw -ltgsi -ltranslate -lrtasm -lcso_cache -lm - -############################################# - -.PHONY = all clean libdriclient - -all: ${TARGET} - -${TARGET}: ${OBJECTS} libdriclient - $(CC) ${LDFLAGS} -shared -o $@ ${OBJECTS} ${LIBS} - -libdriclient: - cd ${DRIDIR}/src; ${MAKE} - -clean: - cd ${DRIDIR}/src; ${MAKE} clean - rm -rf ${OBJECTS} ${TARGET} +# This makefile produces a libXvMCg3dvl.so which is +# based on DRM/DRI + +TOP = ../../../../.. +include $(TOP)/configs/current + +XVMC_MAJOR = 1 +XVMC_MINOR = 0 +XVMC_LIB = XvMCg3dvl +XVMC_LIB_NAME = lib$(XVMC_LIB).so +XVMC_LIB_DEPS = $(EXTRA_LIB_PATH) -lXvMC -lXv -lX11 -lm + +SOURCES = drm_nouveau_winsys.c + +DRIVER_INCLUDES = $(shell pkg-config libdrm libdrm_nouveau --cflags-only-I) \ + -I$(TOP)/src/gallium/winsys/drm/nouveau \ + -I$(TOP)/src/driclient/include +DRIVER_DEFINES = $(shell pkg-config libdrm libdrm_nouveau --cflags-only-other) + +PIPE_DRIVERS = \ + $(TOP)/src/gallium/winsys/drm/nouveau/drm/libnouveaudrm.a \ + $(TOP)/src/gallium/drivers/nv04/libnv04.a \ + $(TOP)/src/gallium/drivers/nv10/libnv10.a \ + $(TOP)/src/gallium/drivers/nv20/libnv20.a \ + $(TOP)/src/gallium/drivers/nv30/libnv30.a \ + $(TOP)/src/gallium/drivers/nv40/libnv40.a \ + $(TOP)/src/gallium/drivers/nv50/libnv50.a \ + $(TOP)/src/gallium/drivers/nouveau/libnouveau.a + +DRI_LIB_DEPS += $(shell pkg-config libdrm_nouveau --libs) + +############################################################### + +INCLUDES = $(DRIVER_INCLUDES) \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/auxiliary \ + -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/src/gallium/winsys/g3dvl \ + -I$(TOP)/src/driclient/include + +DEFINES += $(DRIVER_DEFINES) \ + -DGALLIUM_SOFTPIPE \ + -DGALLIUM_TRACE + +# XXX: Hack, if we include libxvmctracker.a in LIBS none of the symbols are +# pulled in by the linker because xsp_winsys.c doesn't refer to them +OBJECTS = $(SOURCES:.c=.o) $(TOP)/src/gallium/state_trackers/xorg/xvmc/*.o + +LIBS = $(PIPE_DRIVERS) \ + $(TOP)/src/driclient/lib/libdriclient.a \ + $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ + $(TOP)/src/gallium/auxiliary/vl/libvl.a \ + $(TOP)/src/gallium/auxiliary/draw/libdraw.a \ + $(TOP)/src/gallium/auxiliary/tgsi/libtgsi.a \ + $(TOP)/src/gallium/auxiliary/translate/libtranslate.a \ + $(TOP)/src/gallium/auxiliary/cso_cache/libcso_cache.a \ + $(TOP)/src/gallium/auxiliary/rtasm/librtasm.a \ + $(TOP)/src/gallium/auxiliary/util/libutil.a + +.c.o: + $(CC) -c $(INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@ + +.S.o: + $(CC) -c $(INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@ + +.PHONY: default $(TOP)/$(LIB_DIR)/gallium clean + +default: depend $(TOP)/$(LIB_DIR)/gallium $(TOP)/$(LIB_DIR)/gallium/$(XVMC_LIB_NAME) + +$(TOP)/$(LIB_DIR)/gallium: + @mkdir -p $(TOP)/$(LIB_DIR)/gallium + +# Make the libXvMCg3dvl.so library +$(TOP)/$(LIB_DIR)/gallium/$(XVMC_LIB_NAME): $(OBJECTS) $(LIBS) Makefile + $(MKLIB) -o $(XVMC_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \ + -major $(XVMC_MAJOR) -minor $(XVMC_MINOR) $(MKLIB_OPTIONS) \ + -install $(TOP)/$(LIB_DIR)/gallium -id $(INSTALL_LIB_DIR)/lib$(XVMC_LIB).1.dylib \ + $(XVMC_LIB_DEPS) $(DRI_LIB_DEPS) $(OBJECTS) $(LIBS) + +depend: $(SOURCES) Makefile + $(RM) depend + touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDES) $(SOURCES) + +#install: default +# $(INSTALL) -d $(INSTALL_DIR)/include/GL +# $(INSTALL) -d $(INSTALL_DIR)/$(LIB_DIR) +# $(INSTALL) -m 644 $(TOP)/include/GL/*.h $(INSTALL_DIR)/include/GL +# @if [ -e $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) ]; then \ +# $(INSTALL) $(TOP)/$(LIB_DIR)/libGL* $(INSTALL_DIR)/$(LIB_DIR); \ +# fi + +clean: Makefile + $(RM) $(TOP)/$(LIB_DIR)/gallium/$(XVMC_LIB_NAME) + $(RM) *.o *~ + $(RM) depend depend.bak + +-include depend diff --git a/src/gallium/winsys/g3dvl/nouveau/drm_nouveau_winsys.c b/src/gallium/winsys/g3dvl/nouveau/drm_nouveau_winsys.c new file mode 100644 index 00000000000..257aa0a1201 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/drm_nouveau_winsys.c @@ -0,0 +1,393 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include <vl_winsys.h> +#include <driclient.h> +#include <state_tracker/dri1_api.h> +#include <pipe/p_video_context.h> +#include <pipe/p_state.h> +#include <util/u_memory.h> + +struct vl_dri_screen +{ + struct vl_screen base; + Visual *visual; + struct drm_api *api; + dri_screen_t *dri_screen; + dri_framebuffer_t dri_framebuf; + struct dri1_api *api_hooks; +}; + +struct vl_dri_context +{ + struct vl_context base; + boolean is_locked; + boolean lost_lock; + drmLock *lock; + dri_context_t *dri_context; + int fd; + struct pipe_video_context *vpipe; + dri_drawable_t *drawable; +}; + +static void +vl_dri_lock(void *priv) +{ + struct vl_dri_context *vl_dri_ctx = priv; + drm_context_t hw_context; + char ret = 0; + + assert(priv); + + hw_context = vl_dri_ctx->dri_context->drm_context; + + DRM_CAS(vl_dri_ctx->lock, hw_context, DRM_LOCK_HELD | hw_context, ret); + if (ret) { + drmGetLock(vl_dri_ctx->fd, hw_context, 0); + vl_dri_ctx->lost_lock = TRUE; + } + vl_dri_ctx->is_locked = TRUE; +} + +static void +vl_dri_unlock(void *priv) +{ + struct vl_dri_context *vl_dri_ctx = priv; + drm_context_t hw_context; + + assert(priv); + + hw_context = vl_dri_ctx->dri_context->drm_context; + + vl_dri_ctx->is_locked = FALSE; + DRM_UNLOCK(vl_dri_ctx->fd, vl_dri_ctx->lock, hw_context); +} + +static boolean +vl_dri_is_locked(void *priv) +{ + struct vl_dri_context *vl_dri_ctx = priv; + + assert(priv); + + return vl_dri_ctx->is_locked; +} + +static boolean +vl_dri_lost_lock(void *priv) +{ + struct vl_dri_context *vl_dri_ctx = priv; + + assert(priv); + + return vl_dri_ctx->lost_lock; +} + +static void +vl_dri_clear_lost_lock(void *priv) +{ + struct vl_dri_context *vl_dri_ctx = priv; + + assert(priv); + + vl_dri_ctx->lost_lock = FALSE; +} + +struct dri1_api_lock_funcs dri1_lf = +{ + .lock = vl_dri_lock, + .unlock = vl_dri_unlock, + .is_locked = vl_dri_is_locked, + .is_lock_lost = vl_dri_lost_lock, + .clear_lost_lock = vl_dri_clear_lost_lock +}; + +static void +vl_dri_copy_version(struct dri1_api_version *dst, dri_version_t *src) +{ + assert(src); + assert(dst); + dst->major = src->major; + dst->minor = src->minor; + dst->patch_level = src->patch; +} + +static boolean +vl_dri_intersect_src_bbox(struct drm_clip_rect *dst, int dst_x, int dst_y, + const struct drm_clip_rect *src, const struct drm_clip_rect *bbox) +{ + int xy1; + int xy2; + + assert(dst); + assert(src); + assert(bbox); + + xy1 = ((int)src->x1 > (int)bbox->x1 + dst_x) ? src->x1 : + (int)bbox->x1 + dst_x; + xy2 = ((int)src->x2 < (int)bbox->x2 + dst_x) ? src->x2 : + (int)bbox->x2 + dst_x; + if (xy1 >= xy2 || xy1 < 0) + return FALSE; + + dst->x1 = xy1; + dst->x2 = xy2; + + xy1 = ((int)src->y1 > (int)bbox->y1 + dst_y) ? src->y1 : + (int)bbox->y1 + dst_y; + xy2 = ((int)src->y2 < (int)bbox->y2 + dst_y) ? src->y2 : + (int)bbox->y2 + dst_y; + if (xy1 >= xy2 || xy1 < 0) + return FALSE; + + dst->y1 = xy1; + dst->y2 = xy2; + return TRUE; +} + +static void +vl_clip_copy(struct vl_dri_context *vl_dri_ctx, + struct pipe_surface *dst, + struct pipe_surface *src, + const struct drm_clip_rect *src_bbox) +{ + struct pipe_video_context *vpipe = vl_dri_ctx->base.vpipe; + struct drm_clip_rect clip; + struct drm_clip_rect *cur; + int i; + + assert(vl_dri_ctx); + assert(dst); + assert(src); + assert(src_bbox); + + assert(vl_dri_ctx->drawable->cliprects); + assert(vl_dri_ctx->drawable->num_cliprects > 0); + + cur = vl_dri_ctx->drawable->cliprects; + + for (i = 0; i < vl_dri_ctx->drawable->num_cliprects; ++i) { + if (vl_dri_intersect_src_bbox(&clip, vl_dri_ctx->drawable->x, vl_dri_ctx->drawable->y, cur++, src_bbox)) + vpipe->surface_copy + ( + vpipe, dst, clip.x1, clip.y1, src, + (int)clip.x1 - vl_dri_ctx->drawable->x, + (int)clip.y1 - vl_dri_ctx->drawable->y, + clip.x2 - clip.x1, clip.y2 - clip.y1 + ); + } +} + +static void +vl_dri_update_drawables_locked(struct vl_dri_context *vl_dri_ctx) +{ + struct vl_dri_screen *vl_dri_scrn; + + assert(vl_dri_ctx); + + vl_dri_scrn = (struct vl_dri_screen*)vl_dri_ctx->base.vscreen; + + if (vl_dri_ctx->lost_lock) { + vl_dri_ctx->lost_lock = FALSE; + DRI_VALIDATE_DRAWABLE_INFO(vl_dri_scrn->dri_screen, vl_dri_ctx->drawable); + } +} + +static void +vl_dri_flush_frontbuffer(struct pipe_screen *screen, + struct pipe_surface *surf, void *context_private) +{ + struct vl_dri_context *vl_dri_ctx = (struct vl_dri_context*)context_private; + struct vl_dri_screen *vl_dri_scrn; + struct drm_clip_rect src_bbox; + boolean save_lost_lock = FALSE; + + assert(screen); + assert(surf); + assert(context_private); + + vl_dri_scrn = (struct vl_dri_screen*)vl_dri_ctx->base.vscreen; + + vl_dri_lock(vl_dri_ctx); + + save_lost_lock = vl_dri_ctx->lost_lock; + + vl_dri_update_drawables_locked(vl_dri_ctx); + + src_bbox.x1 = 0; + src_bbox.x2 = vl_dri_ctx->drawable->w; + src_bbox.y1 = 0; + src_bbox.y2 = vl_dri_ctx->drawable->h; + +#if 0 + if (vl_dri_scrn->_api_hooks->present_locked) + vl_dri_scrn->api_hooks->present_locked(pipe, surf, + vl_dri_ctx->drawable->cliprects, + vl_dri_ctx->drawable->num_cliprects, + vl_dri_ctx->drawable->x, vl_dri_drawable->y, + &bbox, NULL /*fence*/); + else +#endif + if (vl_dri_scrn->api_hooks->front_srf_locked) { + struct pipe_surface *front = vl_dri_scrn->api_hooks->front_srf_locked(screen); + + if (front) + vl_clip_copy(vl_dri_ctx, front, surf, &src_bbox); + + //st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, fence); + } + + vl_dri_ctx->lost_lock = save_lost_lock; + + vl_dri_unlock(vl_dri_ctx); +} + +Drawable +vl_video_bind_drawable(struct vl_context *vctx, Drawable drawable) +{ + struct vl_dri_context *vl_dri_ctx = (struct vl_dri_context*)vctx; + struct vl_dri_screen *vl_dri_scrn; + dri_drawable_t *dri_drawable; + Drawable old_drawable = None; + + assert(vctx); + + if (vl_dri_ctx->drawable) + old_drawable = vl_dri_ctx->drawable->x_drawable; + + vl_dri_scrn = (struct vl_dri_screen*)vl_dri_ctx->base.vscreen; + driCreateDrawable(vl_dri_scrn->dri_screen, drawable, &dri_drawable); + vl_dri_ctx->drawable = dri_drawable; + + return old_drawable; +} + +struct vl_screen* +vl_screen_create(Display *display, int screen) +{ + struct vl_dri_screen *vl_dri_scrn; + struct dri1_create_screen_arg arg; + + assert(display); + + vl_dri_scrn = CALLOC_STRUCT(vl_dri_screen); + if (!vl_dri_scrn) + return NULL; + + driCreateScreen(display, screen, &vl_dri_scrn->dri_screen, &vl_dri_scrn->dri_framebuf); + vl_dri_scrn->api = drm_api_create(); + + arg.base.mode = DRM_CREATE_DRI1; + arg.lf = &dri1_lf; + arg.ddx_info = vl_dri_scrn->dri_framebuf.private; + arg.ddx_info_size = vl_dri_scrn->dri_framebuf.private_size; + arg.sarea = vl_dri_scrn->dri_screen->sarea; + vl_dri_copy_version(&arg.ddx_version, &vl_dri_scrn->dri_screen->ddx); + vl_dri_copy_version(&arg.dri_version, &vl_dri_scrn->dri_screen->dri); + vl_dri_copy_version(&arg.drm_version, &vl_dri_scrn->dri_screen->drm); + arg.api = NULL; + + vl_dri_scrn->base.pscreen = vl_dri_scrn->api->create_screen(vl_dri_scrn->api, + vl_dri_scrn->dri_screen->fd, + &arg.base); + + if (!vl_dri_scrn->base.pscreen) { + FREE(vl_dri_scrn); + return NULL; + } + + vl_dri_scrn->visual = XDefaultVisual(display, screen); + vl_dri_scrn->api_hooks = arg.api; + vl_dri_scrn->base.pscreen->flush_frontbuffer = vl_dri_flush_frontbuffer; + /* XXX: Safe to call this while unlocked? */ + vl_dri_scrn->base.format = vl_dri_scrn->api_hooks->front_srf_locked(vl_dri_scrn->base.pscreen)->format; + + return &vl_dri_scrn->base; +} + +void vl_screen_destroy(struct vl_screen *vscreen) +{ + struct vl_dri_screen *vl_dri_scrn = (struct vl_dri_screen*)vscreen; + + assert(vscreen); + + vl_dri_scrn->base.pscreen->destroy(vl_dri_scrn->base.pscreen); + driDestroyScreen(vl_dri_scrn->dri_screen); + FREE(vl_dri_scrn); +} + +struct vl_context* +vl_video_create(struct vl_screen *vscreen, + enum pipe_video_profile profile, + enum pipe_video_chroma_format chroma_format, + unsigned width, unsigned height) +{ + struct vl_dri_screen *vl_dri_scrn = (struct vl_dri_screen*)vscreen; + struct vl_dri_context *vl_dri_ctx; + + vl_dri_ctx = CALLOC_STRUCT(vl_dri_context); + if (!vl_dri_ctx) + return NULL; + + /* XXX: Is default visual correct/sufficient here? */ + driCreateContext(vl_dri_scrn->dri_screen, vl_dri_scrn->visual, &vl_dri_ctx->dri_context); + + if (!vl_dri_scrn->api->create_video_context) { + debug_printf("[G3DVL] No video support found on %s/%s.\n", + vl_dri_scrn->base.pscreen->get_vendor(vl_dri_scrn->base.pscreen), + vl_dri_scrn->base.pscreen->get_name(vl_dri_scrn->base.pscreen)); + FREE(vl_dri_ctx); + return NULL; + } + + vl_dri_ctx->base.vpipe = vl_dri_scrn->api->create_video_context(vl_dri_scrn->api, + vscreen->pscreen, + profile, chroma_format, + width, height); + + if (!vl_dri_ctx->base.vpipe) { + FREE(vl_dri_ctx); + return NULL; + } + + vl_dri_ctx->base.vpipe->priv = vl_dri_ctx; + vl_dri_ctx->base.vscreen = vscreen; + vl_dri_ctx->fd = vl_dri_scrn->dri_screen->fd; + vl_dri_ctx->lock = (drmLock*)&vl_dri_scrn->dri_screen->sarea->lock; + + return &vl_dri_ctx->base; +} + +void vl_video_destroy(struct vl_context *vctx) +{ + struct vl_dri_context *vl_dri_ctx = (struct vl_dri_context*)vctx; + + assert(vctx); + + vl_dri_ctx->base.vpipe->destroy(vl_dri_ctx->base.vpipe); + FREE(vl_dri_ctx); +} diff --git a/src/gallium/winsys/g3dvl/vl_winsys.h b/src/gallium/winsys/g3dvl/vl_winsys.h index b4fa0d67a1b..d95e9c58335 100644 --- a/src/gallium/winsys/g3dvl/vl_winsys.h +++ b/src/gallium/winsys/g3dvl/vl_winsys.h @@ -1,8 +1,8 @@ /************************************************************************** - * + * * Copyright 2009 Younes Manton. * All Rights Reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including @@ -10,11 +10,11 @@ * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. @@ -22,7 +22,7 @@ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * **************************************************************************/ #ifndef vl_winsys_h @@ -35,17 +35,32 @@ struct pipe_screen; struct pipe_video_context; -struct pipe_screen* +struct vl_screen +{ + enum pipe_format format; + struct pipe_screen *pscreen; +}; + +struct vl_context +{ + struct vl_screen *vscreen; + struct pipe_video_context *vpipe; +}; + +struct vl_screen* vl_screen_create(Display *display, int screen); -struct pipe_video_context* -vl_video_create(Display *display, int screen, - struct pipe_screen *p_screen, +void vl_screen_destroy(struct vl_screen *vscreen); + +struct vl_context* +vl_video_create(struct vl_screen *vscreen, enum pipe_video_profile profile, enum pipe_video_chroma_format chroma_format, unsigned width, unsigned height); +void vl_video_destroy(struct vl_context *vctx); + Drawable -vl_video_bind_drawable(struct pipe_video_context *vpipe, Drawable drawable); +vl_video_bind_drawable(struct vl_context *vctx, Drawable drawable); #endif diff --git a/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c b/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c index 08067aad64c..2b32f07c9e8 100644 --- a/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c +++ b/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c @@ -1,8 +1,8 @@ /************************************************************************** - * + * * Copyright 2009 Younes Manton. * All Rights Reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including @@ -10,11 +10,11 @@ * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. @@ -22,7 +22,7 @@ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * **************************************************************************/ #include <vl_winsys.h> @@ -36,7 +36,12 @@ #include <softpipe/sp_video_context.h> #include <softpipe/sp_texture.h> -/* pipe_winsys implementation */ +/* TODO: Find a good way to calculate this */ +static enum pipe_format VisualToPipe(Visual *visual) +{ + assert(visual); + return PIPE_FORMAT_X8R8G8B8_UNORM; +} struct xsp_pipe_winsys { @@ -48,9 +53,9 @@ struct xsp_pipe_winsys struct xsp_context { - Drawable drawable; + struct vl_context base; - void (*pipe_destroy)(struct pipe_video_context *vpipe); + Drawable drawable; }; struct xsp_buffer @@ -218,48 +223,37 @@ static void xsp_destroy(struct pipe_winsys *pws) FREE(xsp_winsys); } -/* Called through pipe_video_context::destroy() */ -static void xsp_pipe_destroy(struct pipe_video_context *vpipe) -{ - struct xsp_context *xsp_context; - - assert(vpipe); - - xsp_context = vpipe->priv; - - /* Call the original destroy */ - xsp_context->pipe_destroy(vpipe); - - FREE(xsp_context); -} - -/* Show starts here */ - Drawable -vl_video_bind_drawable(struct pipe_video_context *vpipe, Drawable drawable) +vl_video_bind_drawable(struct vl_context *vctx, Drawable drawable) { - struct xsp_context *xsp_context; + struct xsp_context *xsp_context = (struct xsp_context*)vctx; Drawable old_drawable; - assert(vpipe); + assert(vctx); - xsp_context = vpipe->priv; old_drawable = xsp_context->drawable; xsp_context->drawable = drawable; return old_drawable; } -struct pipe_screen* +struct vl_screen* vl_screen_create(Display *display, int screen) { + struct vl_screen *vscreen; struct xsp_pipe_winsys *xsp_winsys; assert(display); + vscreen = CALLOC_STRUCT(vl_screen); + if (!vscreen) + return NULL; + xsp_winsys = CALLOC_STRUCT(xsp_pipe_winsys); - if (!xsp_winsys) + if (!xsp_winsys) { + FREE(vscreen); return NULL; + } xsp_winsys->base.buffer_create = xsp_buffer_create; xsp_winsys->base.user_buffer_create = xsp_user_buffer_create; @@ -291,17 +285,36 @@ vl_screen_create(Display *display, int screen) if (!xsp_winsys->fbimage) { FREE(xsp_winsys); + FREE(vscreen); return NULL; } XInitImage(xsp_winsys->fbimage); - return softpipe_create_screen(&xsp_winsys->base); + vscreen->pscreen = softpipe_create_screen(&xsp_winsys->base); + + if (!vscreen->pscreen) { + FREE(vscreen); + XDestroyImage(xsp_winsys->fbimage); + FREE(xsp_winsys); + return NULL; + } + + vscreen->format = VisualToPipe(XDefaultVisual(display, screen)); + + return vscreen; +} + +void vl_screen_destroy(struct vl_screen *vscreen) +{ + assert(vscreen); + + vscreen->pscreen->destroy(vscreen->pscreen); + FREE(vscreen); } -struct pipe_video_context* -vl_video_create(Display *display, int screen, - struct pipe_screen *p_screen, +struct vl_context* +vl_video_create(struct vl_screen *vscreen, enum pipe_video_profile profile, enum pipe_video_chroma_format chroma_format, unsigned width, unsigned height) @@ -309,10 +322,10 @@ vl_video_create(Display *display, int screen, struct pipe_video_context *vpipe; struct xsp_context *xsp_context; - assert(p_screen); + assert(vscreen); assert(width && height); - vpipe = sp_video_create(p_screen, profile, chroma_format, width, height); + vpipe = sp_video_create(vscreen->pscreen, profile, chroma_format, width, height); if (!vpipe) return NULL; @@ -322,11 +335,17 @@ vl_video_create(Display *display, int screen, return NULL; } - /* Override this so we can free our xsp_context when the pipe is freed */ - xsp_context->pipe_destroy = vpipe->destroy; - vpipe->destroy = xsp_pipe_destroy; - vpipe->priv = xsp_context; + xsp_context->base.vpipe = vpipe; + xsp_context->base.vscreen = vscreen; + + return &xsp_context->base; +} + +void vl_video_destroy(struct vl_context *vctx) +{ + assert(vctx); - return vpipe; + vctx->vpipe->destroy(vctx->vpipe); + FREE(vctx); } |