diff options
author | Christian König <[email protected]> | 2013-05-15 15:10:11 +0200 |
---|---|---|
committer | Christian König <[email protected]> | 2013-10-26 12:13:36 +0200 |
commit | 80964226e9b8a05c39157f9305c06c0b2861e080 (patch) | |
tree | c4f1c11f0f3e82e0b8167b8cba21de6694f2f9d9 /src/mesa/state_tracker/st_vdpau.c | |
parent | 3d3a0b9b67982a96a4c4d87f78c21204f3a48776 (diff) |
implement NV_vdpau_interop v7
v2: Actually implement interop between the gallium
state tracker and the VDPAU backend.
v3: Make it also available in non legacy contexts,
fix video buffer sharing.
v4: deny interop if we don't have the same screen object
v5: rebased on upstream changes
v6: implemented VDPAUGetSurfaceivNV, improved error handling,
unregister all surfaces in VDPAUFiniNV
v7: squash merge with Mareks changes
Signed-off-by: Christian König <[email protected]>
Diffstat (limited to 'src/mesa/state_tracker/st_vdpau.c')
-rw-r--r-- | src/mesa/state_tracker/st_vdpau.c | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/src/mesa/state_tracker/st_vdpau.c b/src/mesa/state_tracker/st_vdpau.c new file mode 100644 index 00000000000..9b165ee3903 --- /dev/null +++ b/src/mesa/state_tracker/st_vdpau.c @@ -0,0 +1,181 @@ +/************************************************************************** + * + * Copyright 2013 Advanced Micro Devices, Inc. + * 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 THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + **************************************************************************/ + +/* + * Authors: + * Christian König <[email protected]> + * + */ + +#include "main/texobj.h" +#include "main/teximage.h" +#include "main/errors.h" +#include "program/prog_instruction.h" + +#include "pipe/p_state.h" +#include "pipe/p_video_codec.h" + +#include "state_tracker/vdpau_interop.h" + +#include "util/u_inlines.h" + +#include "st_vdpau.h" +#include "st_context.h" +#include "st_texture.h" +#include "st_format.h" + +static void +st_vdpau_map_surface(struct gl_context *ctx, GLenum target, GLenum access, + GLboolean output, struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + const GLvoid *vdpSurface, GLuint index) +{ + int (*getProcAddr)(uint32_t device, uint32_t id, void **ptr); + uint32_t device = (uintptr_t)ctx->vdpDevice; + + struct st_context *st = st_context(ctx); + struct st_texture_object *stObj = st_texture_object(texObj); + struct st_texture_image *stImage = st_texture_image(texImage); + + struct pipe_resource *res; + struct pipe_sampler_view *sv, templ; + gl_format texFormat; + + getProcAddr = ctx->vdpGetProcAddress; + if (output) { + VdpOutputSurfaceGallium *f; + + if (getProcAddr(device, VDP_FUNC_ID_OUTPUT_SURFACE_GALLIUM, (void**)&f)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUMapSurfacesNV"); + return; + } + + res = f((uintptr_t)vdpSurface); + + if (!res) { + _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUMapSurfacesNV"); + return; + } + + } else { + VdpVideoSurfaceGallium *f; + + struct pipe_video_buffer *buffer; + struct pipe_sampler_view **samplers; + + if (getProcAddr(device, VDP_FUNC_ID_VIDEO_SURFACE_GALLIUM, (void**)&f)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUMapSurfacesNV"); + return; + } + + buffer = f((uintptr_t)vdpSurface); + if (!buffer) { + _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUMapSurfacesNV"); + return; + } + + samplers = buffer->get_sampler_view_planes(buffer); + if (!samplers) { + _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUMapSurfacesNV"); + return; + } + + sv = samplers[index >> 1]; + if (!sv) { + _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUMapSurfacesNV"); + return; + } + + res = sv->texture; + } + + if (!res) { + _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUMapSurfacesNV"); + return; + } + + /* do we have different screen objects ? */ + if (res->screen != st->pipe->screen) { + _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUMapSurfacesNV"); + return; + } + + /* switch to surface based */ + if (!stObj->surface_based) { + _mesa_clear_texture_object(ctx, texObj); + stObj->surface_based = GL_TRUE; + } + + texFormat = st_pipe_format_to_mesa_format(res->format); + + _mesa_init_teximage_fields(ctx, texImage, + res->width0, res->height0, 1, 0, GL_RGBA, + texFormat); + + pipe_resource_reference(&stObj->pt, res); + pipe_sampler_view_reference(&stObj->sampler_view, NULL); + pipe_resource_reference(&stImage->pt, res); + + u_sampler_view_default_template(&templ, res, res->format); + templ.u.tex.first_layer = index & 1; + templ.u.tex.last_layer = index & 1; + templ.swizzle_r = GET_SWZ(stObj->base._Swizzle, 0); + templ.swizzle_g = GET_SWZ(stObj->base._Swizzle, 1); + templ.swizzle_b = GET_SWZ(stObj->base._Swizzle, 2); + templ.swizzle_a = GET_SWZ(stObj->base._Swizzle, 3); + stObj->sampler_view = st->pipe->create_sampler_view(st->pipe, res, &templ); + + stObj->width0 = res->width0; + stObj->height0 = res->height0; + stObj->depth0 = 1; + stObj->surface_format = res->format; + + _mesa_dirty_texobj(ctx, texObj); +} + +static void +st_vdpau_unmap_surface(struct gl_context *ctx, GLenum target, GLenum access, + GLboolean output, struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + const GLvoid *vdpSurface, GLuint index) +{ + struct st_texture_object *stObj = st_texture_object(texObj); + struct st_texture_image *stImage = st_texture_image(texImage); + + pipe_resource_reference(&stObj->pt, NULL); + pipe_sampler_view_reference(&stObj->sampler_view, NULL); + pipe_resource_reference(&stImage->pt, NULL); + + _mesa_dirty_texobj(ctx, texObj); +} + +void +st_init_vdpau_functions(struct dd_function_table *functions) +{ + functions->VDPAUMapSurface = st_vdpau_map_surface; + functions->VDPAUUnmapSurface = st_vdpau_unmap_surface; +} |