st_vdpau.c revision 848b8605
1/************************************************************************** 2 * 3 * Copyright 2013 Advanced Micro Devices, Inc. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28/* 29 * Authors: 30 * Christian König <christian.koenig@amd.com> 31 * 32 */ 33 34#include "main/texobj.h" 35#include "main/teximage.h" 36#include "main/errors.h" 37#include "program/prog_instruction.h" 38 39#include "pipe/p_state.h" 40#include "pipe/p_video_codec.h" 41 42#include "state_tracker/vdpau_interop.h" 43 44#include "util/u_inlines.h" 45 46#include "st_vdpau.h" 47#include "st_context.h" 48#include "st_texture.h" 49#include "st_format.h" 50#include "st_cb_flush.h" 51 52static void 53st_vdpau_map_surface(struct gl_context *ctx, GLenum target, GLenum access, 54 GLboolean output, struct gl_texture_object *texObj, 55 struct gl_texture_image *texImage, 56 const GLvoid *vdpSurface, GLuint index) 57{ 58 int (*getProcAddr)(uint32_t device, uint32_t id, void **ptr); 59 uint32_t device = (uintptr_t)ctx->vdpDevice; 60 61 struct st_context *st = st_context(ctx); 62 struct st_texture_object *stObj = st_texture_object(texObj); 63 struct st_texture_image *stImage = st_texture_image(texImage); 64 65 struct pipe_resource *res; 66 struct pipe_sampler_view templ, **sampler_view; 67 mesa_format texFormat; 68 69 getProcAddr = ctx->vdpGetProcAddress; 70 if (output) { 71 VdpOutputSurfaceGallium *f; 72 73 if (getProcAddr(device, VDP_FUNC_ID_OUTPUT_SURFACE_GALLIUM, (void**)&f)) { 74 _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUMapSurfacesNV"); 75 return; 76 } 77 78 res = f((uintptr_t)vdpSurface); 79 80 if (!res) { 81 _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUMapSurfacesNV"); 82 return; 83 } 84 85 } else { 86 struct pipe_sampler_view *sv; 87 VdpVideoSurfaceGallium *f; 88 89 struct pipe_video_buffer *buffer; 90 struct pipe_sampler_view **samplers; 91 92 if (getProcAddr(device, VDP_FUNC_ID_VIDEO_SURFACE_GALLIUM, (void**)&f)) { 93 _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUMapSurfacesNV"); 94 return; 95 } 96 97 buffer = f((uintptr_t)vdpSurface); 98 if (!buffer) { 99 _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUMapSurfacesNV"); 100 return; 101 } 102 103 samplers = buffer->get_sampler_view_planes(buffer); 104 if (!samplers) { 105 _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUMapSurfacesNV"); 106 return; 107 } 108 109 sv = samplers[index >> 1]; 110 if (!sv) { 111 _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUMapSurfacesNV"); 112 return; 113 } 114 115 res = sv->texture; 116 } 117 118 if (!res) { 119 _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUMapSurfacesNV"); 120 return; 121 } 122 123 /* do we have different screen objects ? */ 124 if (res->screen != st->pipe->screen) { 125 _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUMapSurfacesNV"); 126 return; 127 } 128 129 /* switch to surface based */ 130 if (!stObj->surface_based) { 131 _mesa_clear_texture_object(ctx, texObj); 132 stObj->surface_based = GL_TRUE; 133 } 134 135 texFormat = st_pipe_format_to_mesa_format(res->format); 136 137 _mesa_init_teximage_fields(ctx, texImage, 138 res->width0, res->height0, 1, 0, GL_RGBA, 139 texFormat); 140 141 pipe_resource_reference(&stObj->pt, res); 142 st_texture_release_all_sampler_views(st, stObj); 143 pipe_resource_reference(&stImage->pt, res); 144 145 u_sampler_view_default_template(&templ, res, res->format); 146 templ.u.tex.first_layer = index & 1; 147 templ.u.tex.last_layer = index & 1; 148 templ.swizzle_r = GET_SWZ(stObj->base._Swizzle, 0); 149 templ.swizzle_g = GET_SWZ(stObj->base._Swizzle, 1); 150 templ.swizzle_b = GET_SWZ(stObj->base._Swizzle, 2); 151 templ.swizzle_a = GET_SWZ(stObj->base._Swizzle, 3); 152 153 sampler_view = st_texture_get_sampler_view(st, stObj); 154 *sampler_view = st->pipe->create_sampler_view(st->pipe, res, &templ); 155 156 stObj->width0 = res->width0; 157 stObj->height0 = res->height0; 158 stObj->depth0 = 1; 159 stObj->surface_format = res->format; 160 161 _mesa_dirty_texobj(ctx, texObj); 162} 163 164static void 165st_vdpau_unmap_surface(struct gl_context *ctx, GLenum target, GLenum access, 166 GLboolean output, struct gl_texture_object *texObj, 167 struct gl_texture_image *texImage, 168 const GLvoid *vdpSurface, GLuint index) 169{ 170 struct st_context *st = st_context(ctx); 171 struct st_texture_object *stObj = st_texture_object(texObj); 172 struct st_texture_image *stImage = st_texture_image(texImage); 173 174 pipe_resource_reference(&stObj->pt, NULL); 175 st_texture_release_all_sampler_views(st, stObj); 176 pipe_resource_reference(&stImage->pt, NULL); 177 178 _mesa_dirty_texobj(ctx, texObj); 179 180 st_flush(st, NULL, 0); 181} 182 183void 184st_init_vdpau_functions(struct dd_function_table *functions) 185{ 186 functions->VDPAUMapSurface = st_vdpau_map_surface; 187 functions->VDPAUUnmapSurface = st_vdpau_unmap_surface; 188} 189