st/va: implement Context Surface and Buffer
[mesa.git] / src / gallium / state_trackers / va / surface.c
1 /**************************************************************************
2 *
3 * Copyright 2010 Thomas Balling Sørensen & Orasanu Lucian.
4 * Copyright 2014 Advanced Micro Devices, Inc.
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sub license, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial portions
17 * of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22 * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 *
27 **************************************************************************/
28
29 #include "pipe/p_screen.h"
30
31 #include "util/u_memory.h"
32 #include "util/u_handle_table.h"
33 #include "util/u_rect.h"
34
35 #include "vl/vl_compositor.h"
36 #include "vl/vl_winsys.h"
37
38 #include "va_private.h"
39
40 VAStatus
41 vlVaCreateSurfaces(VADriverContextP ctx, int width, int height, int format,
42 int num_surfaces, VASurfaceID *surfaces)
43 {
44 struct pipe_video_buffer templat = {};
45 struct pipe_screen *pscreen;
46 vlVaDriver *drv;
47 int i;
48
49 if (!ctx)
50 return VA_STATUS_ERROR_INVALID_CONTEXT;
51
52 if (!(width && height))
53 return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
54
55 drv = VL_VA_DRIVER(ctx);
56 pscreen = VL_VA_PSCREEN(ctx);
57
58 templat.buffer_format = pscreen->get_video_param
59 (
60 pscreen,
61 PIPE_VIDEO_PROFILE_UNKNOWN,
62 PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
63 PIPE_VIDEO_CAP_PREFERED_FORMAT
64 );
65 templat.chroma_format = ChromaToPipe(format);
66 templat.width = width;
67 templat.height = height;
68 templat.interlaced = pscreen->get_video_param
69 (
70 pscreen,
71 PIPE_VIDEO_PROFILE_UNKNOWN,
72 PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
73 PIPE_VIDEO_CAP_PREFERS_INTERLACED
74 );
75
76 for (i = 0; i < num_surfaces; ++i) {
77 vlVaSurface *surf = CALLOC(1, sizeof(vlVaSurface));
78 if (!surf)
79 goto no_res;
80
81 surf->templat = templat;
82 surfaces[i] = handle_table_add(drv->htab, surf);
83 }
84
85 return VA_STATUS_SUCCESS;
86
87 no_res:
88 if (i)
89 vlVaDestroySurfaces(ctx, surfaces, i);
90
91 return VA_STATUS_ERROR_ALLOCATION_FAILED;
92 }
93
94 VAStatus
95 vlVaDestroySurfaces(VADriverContextP ctx, VASurfaceID *surface_list, int num_surfaces)
96 {
97 vlVaDriver *drv;
98 int i;
99
100 if (!ctx)
101 return VA_STATUS_ERROR_INVALID_CONTEXT;
102
103 drv = VL_VA_DRIVER(ctx);
104 for (i = 0; i < num_surfaces; ++i) {
105 vlVaSurface *surf = handle_table_get(drv->htab, surface_list[i]);
106 if (surf->buffer)
107 surf->buffer->destroy(surf->buffer);
108 if(surf->fence)
109 drv->pipe->screen->fence_reference(drv->pipe->screen, &surf->fence, NULL);
110 FREE(surf);
111 handle_table_remove(drv->htab, surface_list[i]);
112 }
113
114 return VA_STATUS_SUCCESS;
115 }
116
117 VAStatus
118 vlVaSyncSurface(VADriverContextP ctx, VASurfaceID render_target)
119 {
120 if (!ctx)
121 return VA_STATUS_ERROR_INVALID_CONTEXT;
122
123 return VA_STATUS_SUCCESS;
124 }
125
126 VAStatus
127 vlVaQuerySurfaceStatus(VADriverContextP ctx, VASurfaceID render_target, VASurfaceStatus *status)
128 {
129 if (!ctx)
130 return VA_STATUS_ERROR_INVALID_CONTEXT;
131
132 return VA_STATUS_SUCCESS;
133 }
134
135 VAStatus
136 vlVaQuerySurfaceError(VADriverContextP ctx, VASurfaceID render_target, VAStatus error_status, void **error_info)
137 {
138 if (!ctx)
139 return VA_STATUS_ERROR_INVALID_CONTEXT;
140
141 return VA_STATUS_ERROR_UNIMPLEMENTED;
142 }
143
144 VAStatus
145 vlVaPutSurface(VADriverContextP ctx, VASurfaceID surface_id, void* draw, short srcx, short srcy,
146 unsigned short srcw, unsigned short srch, short destx, short desty,
147 unsigned short destw, unsigned short desth, VARectangle *cliprects,
148 unsigned int number_cliprects, unsigned int flags)
149 {
150 vlVaDriver *drv;
151 vlVaSurface *surf;
152 struct pipe_screen *screen;
153 struct pipe_resource *tex;
154 struct pipe_surface surf_templ, *surf_draw;
155 struct u_rect src_rect, *dirty_area;
156
157 if (!ctx)
158 return VA_STATUS_ERROR_INVALID_CONTEXT;
159
160 drv = VL_VA_DRIVER(ctx);
161 surf = handle_table_get(drv->htab, surface_id);
162 if (!surf)
163 return VA_STATUS_ERROR_INVALID_SURFACE;
164
165 screen = drv->pipe->screen;
166
167 if(surf->fence) {
168 screen->fence_finish(screen, surf->fence, PIPE_TIMEOUT_INFINITE);
169 screen->fence_reference(screen, &surf->fence, NULL);
170 }
171
172 tex = vl_screen_texture_from_drawable(drv->vscreen, (Drawable)draw);
173 if (!tex)
174 return VA_STATUS_ERROR_INVALID_DISPLAY;
175
176 dirty_area = vl_screen_get_dirty_area(drv->vscreen);
177
178 memset(&surf_templ, 0, sizeof(surf_templ));
179 surf_templ.format = tex->format;
180 surf_draw = drv->pipe->create_surface(drv->pipe, tex, &surf_templ);
181 if (!surf_draw) {
182 pipe_resource_reference(&tex, NULL);
183 return VA_STATUS_ERROR_INVALID_DISPLAY;
184 }
185
186 src_rect.x0 = srcx;
187 src_rect.y0 = srcy;
188 src_rect.x1 = srcw + srcx;
189 src_rect.y1 = srch + srcy;
190
191 vl_compositor_clear_layers(&drv->cstate);
192 vl_compositor_set_buffer_layer(&drv->cstate, &drv->compositor, 0, surf->buffer, &src_rect, NULL, VL_COMPOSITOR_WEAVE);
193 vl_compositor_render(&drv->cstate, &drv->compositor, surf_draw, dirty_area, true);
194
195 screen->flush_frontbuffer
196 (
197 screen, tex, 0, 0,
198 vl_screen_get_private(drv->vscreen), NULL
199 );
200
201 screen->fence_reference(screen, &surf->fence, NULL);
202 drv->pipe->flush(drv->pipe, &surf->fence, 0);
203
204 pipe_resource_reference(&tex, NULL);
205 pipe_surface_reference(&surf_draw, NULL);
206
207 return VA_STATUS_SUCCESS;
208 }
209
210 VAStatus
211 vlVaLockSurface(VADriverContextP ctx, VASurfaceID surface, unsigned int *fourcc,
212 unsigned int *luma_stride, unsigned int *chroma_u_stride, unsigned int *chroma_v_stride,
213 unsigned int *luma_offset, unsigned int *chroma_u_offset, unsigned int *chroma_v_offset,
214 unsigned int *buffer_name, void **buffer)
215 {
216 if (!ctx)
217 return VA_STATUS_ERROR_INVALID_CONTEXT;
218
219 return VA_STATUS_ERROR_UNIMPLEMENTED;
220 }
221
222 VAStatus
223 vlVaUnlockSurface(VADriverContextP ctx, VASurfaceID surface)
224 {
225 if (!ctx)
226 return VA_STATUS_ERROR_INVALID_CONTEXT;
227
228 return VA_STATUS_ERROR_UNIMPLEMENTED;
229 }