1 /**************************************************************************
3 * Copyright 2010 Thomas Balling Sørensen & Orasanu Lucian.
4 * Copyright 2014 Advanced Micro Devices, Inc.
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:
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial portions
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.
27 **************************************************************************/
29 #include "pipe/p_screen.h"
30 #include "pipe/p_video_codec.h"
32 #include "util/u_memory.h"
33 #include "util/u_handle_table.h"
34 #include "util/u_rect.h"
35 #include "util/u_sampler.h"
36 #include "util/u_surface.h"
38 #include "vl/vl_compositor.h"
39 #include "vl/vl_winsys.h"
41 #include "va_private.h"
44 vlVaCreateSurfaces(VADriverContextP ctx
, int width
, int height
, int format
,
45 int num_surfaces
, VASurfaceID
*surfaces
)
47 struct pipe_video_buffer templat
= {};
48 struct pipe_screen
*pscreen
;
53 return VA_STATUS_ERROR_INVALID_CONTEXT
;
55 if (!(width
&& height
))
56 return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT
;
58 drv
= VL_VA_DRIVER(ctx
);
59 pscreen
= VL_VA_PSCREEN(ctx
);
61 templat
.buffer_format
= pscreen
->get_video_param
64 PIPE_VIDEO_PROFILE_UNKNOWN
,
65 PIPE_VIDEO_ENTRYPOINT_BITSTREAM
,
66 PIPE_VIDEO_CAP_PREFERED_FORMAT
68 templat
.chroma_format
= ChromaToPipe(format
);
69 templat
.width
= width
;
70 templat
.height
= height
;
71 templat
.interlaced
= pscreen
->get_video_param
74 PIPE_VIDEO_PROFILE_UNKNOWN
,
75 PIPE_VIDEO_ENTRYPOINT_BITSTREAM
,
76 PIPE_VIDEO_CAP_PREFERS_INTERLACED
79 for (i
= 0; i
< num_surfaces
; ++i
) {
80 vlVaSurface
*surf
= CALLOC(1, sizeof(vlVaSurface
));
84 surf
->templat
= templat
;
85 surf
->buffer
= drv
->pipe
->create_video_buffer(drv
->pipe
, &templat
);
86 util_dynarray_init(&surf
->subpics
);
87 surfaces
[i
] = handle_table_add(drv
->htab
, surf
);
90 return VA_STATUS_SUCCESS
;
94 vlVaDestroySurfaces(ctx
, surfaces
, i
);
96 return VA_STATUS_ERROR_ALLOCATION_FAILED
;
100 vlVaDestroySurfaces(VADriverContextP ctx
, VASurfaceID
*surface_list
, int num_surfaces
)
106 return VA_STATUS_ERROR_INVALID_CONTEXT
;
108 drv
= VL_VA_DRIVER(ctx
);
109 for (i
= 0; i
< num_surfaces
; ++i
) {
110 vlVaSurface
*surf
= handle_table_get(drv
->htab
, surface_list
[i
]);
112 surf
->buffer
->destroy(surf
->buffer
);
114 drv
->pipe
->screen
->fence_reference(drv
->pipe
->screen
, &surf
->fence
, NULL
);
115 util_dynarray_fini(&surf
->subpics
);
117 handle_table_remove(drv
->htab
, surface_list
[i
]);
120 return VA_STATUS_SUCCESS
;
124 vlVaSyncSurface(VADriverContextP ctx
, VASurfaceID render_target
)
127 return VA_STATUS_ERROR_INVALID_CONTEXT
;
129 return VA_STATUS_SUCCESS
;
133 vlVaQuerySurfaceStatus(VADriverContextP ctx
, VASurfaceID render_target
, VASurfaceStatus
*status
)
136 return VA_STATUS_ERROR_INVALID_CONTEXT
;
138 return VA_STATUS_SUCCESS
;
142 vlVaQuerySurfaceError(VADriverContextP ctx
, VASurfaceID render_target
, VAStatus error_status
, void **error_info
)
145 return VA_STATUS_ERROR_INVALID_CONTEXT
;
147 return VA_STATUS_ERROR_UNIMPLEMENTED
;
151 upload_sampler(struct pipe_context
*pipe
, struct pipe_sampler_view
*dst
,
152 const struct pipe_box
*dst_box
, const void *src
, unsigned src_stride
,
153 unsigned src_x
, unsigned src_y
)
155 struct pipe_transfer
*transfer
;
158 map
= pipe
->transfer_map(pipe
, dst
->texture
, 0, PIPE_TRANSFER_WRITE
,
163 util_copy_rect(map
, dst
->texture
->format
, transfer
->stride
, 0, 0,
164 dst_box
->width
, dst_box
->height
,
165 src
, src_stride
, src_x
, src_y
);
167 pipe
->transfer_unmap(pipe
, transfer
);
171 vlVaPutSubpictures(vlVaSurface
*surf
, vlVaDriver
*drv
,
172 struct pipe_surface
*surf_draw
, struct u_rect
*dirty_area
,
173 struct u_rect
*src_rect
, struct u_rect
*dst_rect
)
178 if (!(surf
->subpics
.data
|| surf
->subpics
.size
))
179 return VA_STATUS_SUCCESS
;
181 for (i
= 0; i
< surf
->subpics
.size
/sizeof(vlVaSubpicture
*); i
++) {
182 struct pipe_blend_state blend
;
186 struct u_rect
*s
, *d
, sr
, dr
, c
;
189 sub
= ((vlVaSubpicture
**)surf
->subpics
.data
)[i
];
193 buf
= handle_table_get(drv
->htab
, sub
->image
->buf
);
195 return VA_STATUS_ERROR_INVALID_IMAGE
;
200 box
.width
= sub
->dst_rect
.x1
- sub
->dst_rect
.x0
;
201 box
.height
= sub
->dst_rect
.y1
- sub
->dst_rect
.y0
;
210 c
.x0
= MAX2(d
->x0
, s
->x0
);
211 c
.y0
= MAX2(d
->y0
, s
->y0
);
212 c
.x1
= MIN2(d
->x0
+ dw
, src_rect
->x1
);
213 c
.y1
= MIN2(d
->y0
+ dh
, src_rect
->y1
);
214 sr
.x0
= s
->x0
+ (c
.x0
- d
->x0
)*(sw
/(float)dw
);
215 sr
.y0
= s
->y0
+ (c
.y0
- d
->y0
)*(sh
/(float)dh
);
216 sr
.x1
= s
->x0
+ (c
.x1
- d
->x0
)*(sw
/(float)dw
);
217 sr
.y1
= s
->y0
+ (c
.y1
- d
->y0
)*(sh
/(float)dh
);
225 dr
.x0
= d
->x0
+ c
.x0
*(dw
/(float)sw
);
226 dr
.y0
= d
->y0
+ c
.y0
*(dh
/(float)sh
);
227 dr
.x1
= d
->x0
+ c
.x1
*(dw
/(float)sw
);
228 dr
.y1
= d
->y0
+ c
.y1
*(dh
/(float)sh
);
230 memset(&blend
, 0, sizeof(blend
));
231 blend
.independent_blend_enable
= 0;
232 blend
.rt
[0].blend_enable
= 1;
233 blend
.rt
[0].rgb_src_factor
= PIPE_BLENDFACTOR_SRC_ALPHA
;
234 blend
.rt
[0].rgb_dst_factor
= PIPE_BLENDFACTOR_INV_SRC_ALPHA
;
235 blend
.rt
[0].alpha_src_factor
= PIPE_BLENDFACTOR_ZERO
;
236 blend
.rt
[0].alpha_dst_factor
= PIPE_BLENDFACTOR_ZERO
;
237 blend
.rt
[0].rgb_func
= PIPE_BLEND_ADD
;
238 blend
.rt
[0].alpha_func
= PIPE_BLEND_ADD
;
239 blend
.rt
[0].colormask
= PIPE_MASK_RGBA
;
240 blend
.logicop_enable
= 0;
241 blend
.logicop_func
= PIPE_LOGICOP_CLEAR
;
243 blend_state
= drv
->pipe
->create_blend_state(drv
->pipe
, &blend
);
245 vl_compositor_clear_layers(&drv
->cstate
);
246 vl_compositor_set_layer_blend(&drv
->cstate
, 0, blend_state
, false);
247 upload_sampler(drv
->pipe
, sub
->sampler
, &box
, buf
->data
,
248 sub
->image
->pitches
[0], 0, 0);
249 vl_compositor_set_rgba_layer(&drv
->cstate
, &drv
->compositor
, 0, sub
->sampler
,
251 vl_compositor_set_layer_dst_area(&drv
->cstate
, 0, &dr
);
252 vl_compositor_render(&drv
->cstate
, &drv
->compositor
, surf_draw
, dirty_area
, false);
253 drv
->pipe
->delete_blend_state(drv
->pipe
, blend_state
);
256 return VA_STATUS_SUCCESS
;
260 vlVaPutSurface(VADriverContextP ctx
, VASurfaceID surface_id
, void* draw
, short srcx
, short srcy
,
261 unsigned short srcw
, unsigned short srch
, short destx
, short desty
,
262 unsigned short destw
, unsigned short desth
, VARectangle
*cliprects
,
263 unsigned int number_cliprects
, unsigned int flags
)
267 struct pipe_screen
*screen
;
268 struct pipe_resource
*tex
;
269 struct pipe_surface surf_templ
, *surf_draw
;
270 struct u_rect src_rect
, *dirty_area
;
271 struct u_rect dst_rect
= {destx
, destx
+ destw
, desty
, desty
+ desth
};
275 return VA_STATUS_ERROR_INVALID_CONTEXT
;
277 drv
= VL_VA_DRIVER(ctx
);
278 surf
= handle_table_get(drv
->htab
, surface_id
);
280 return VA_STATUS_ERROR_INVALID_SURFACE
;
282 screen
= drv
->pipe
->screen
;
285 screen
->fence_finish(screen
, surf
->fence
, PIPE_TIMEOUT_INFINITE
);
286 screen
->fence_reference(screen
, &surf
->fence
, NULL
);
289 tex
= vl_screen_texture_from_drawable(drv
->vscreen
, (Drawable
)draw
);
291 return VA_STATUS_ERROR_INVALID_DISPLAY
;
293 dirty_area
= vl_screen_get_dirty_area(drv
->vscreen
);
295 memset(&surf_templ
, 0, sizeof(surf_templ
));
296 surf_templ
.format
= tex
->format
;
297 surf_draw
= drv
->pipe
->create_surface(drv
->pipe
, tex
, &surf_templ
);
299 pipe_resource_reference(&tex
, NULL
);
300 return VA_STATUS_ERROR_INVALID_DISPLAY
;
305 src_rect
.x1
= srcw
+ srcx
;
306 src_rect
.y1
= srch
+ srcy
;
308 vl_compositor_clear_layers(&drv
->cstate
);
309 vl_compositor_set_buffer_layer(&drv
->cstate
, &drv
->compositor
, 0, surf
->buffer
, &src_rect
, NULL
, VL_COMPOSITOR_WEAVE
);
310 vl_compositor_set_layer_dst_area(&drv
->cstate
, 0, &dst_rect
);
311 vl_compositor_render(&drv
->cstate
, &drv
->compositor
, surf_draw
, dirty_area
, true);
313 status
= vlVaPutSubpictures(surf
, drv
, surf_draw
, dirty_area
, &src_rect
, &dst_rect
);
317 screen
->flush_frontbuffer
320 vl_screen_get_private(drv
->vscreen
), NULL
323 screen
->fence_reference(screen
, &surf
->fence
, NULL
);
324 drv
->pipe
->flush(drv
->pipe
, &surf
->fence
, 0);
326 pipe_resource_reference(&tex
, NULL
);
327 pipe_surface_reference(&surf_draw
, NULL
);
329 return VA_STATUS_SUCCESS
;
333 vlVaLockSurface(VADriverContextP ctx
, VASurfaceID surface
, unsigned int *fourcc
,
334 unsigned int *luma_stride
, unsigned int *chroma_u_stride
, unsigned int *chroma_v_stride
,
335 unsigned int *luma_offset
, unsigned int *chroma_u_offset
, unsigned int *chroma_v_offset
,
336 unsigned int *buffer_name
, void **buffer
)
339 return VA_STATUS_ERROR_INVALID_CONTEXT
;
341 return VA_STATUS_ERROR_UNIMPLEMENTED
;
345 vlVaUnlockSurface(VADriverContextP ctx
, VASurfaceID surface
)
348 return VA_STATUS_ERROR_INVALID_CONTEXT
;
350 return VA_STATUS_ERROR_UNIMPLEMENTED
;