5ddaf04a8c7401b55749839f12e59fc5ec1c58d5
[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 #include "pipe/p_video_codec.h"
31
32 #include "state_tracker/drm_driver.h"
33
34 #include "util/u_memory.h"
35 #include "util/u_handle_table.h"
36 #include "util/u_rect.h"
37 #include "util/u_sampler.h"
38 #include "util/u_surface.h"
39
40 #include "vl/vl_compositor.h"
41 #include "vl/vl_video_buffer.h"
42 #include "vl/vl_winsys.h"
43
44 #include "va_private.h"
45
46 #include <va/va_drmcommon.h>
47
48 static const enum pipe_format vpp_surface_formats[] = {
49 PIPE_FORMAT_B8G8R8A8_UNORM, PIPE_FORMAT_R8G8B8A8_UNORM,
50 PIPE_FORMAT_B8G8R8X8_UNORM, PIPE_FORMAT_R8G8B8X8_UNORM
51 };
52
53 VAStatus
54 vlVaCreateSurfaces(VADriverContextP ctx, int width, int height, int format,
55 int num_surfaces, VASurfaceID *surfaces)
56 {
57 return vlVaCreateSurfaces2(ctx, format, width, height, surfaces, num_surfaces,
58 NULL, 0);
59 }
60
61 VAStatus
62 vlVaDestroySurfaces(VADriverContextP ctx, VASurfaceID *surface_list, int num_surfaces)
63 {
64 vlVaDriver *drv;
65 int i;
66
67 if (!ctx)
68 return VA_STATUS_ERROR_INVALID_CONTEXT;
69
70 drv = VL_VA_DRIVER(ctx);
71 for (i = 0; i < num_surfaces; ++i) {
72 vlVaSurface *surf = handle_table_get(drv->htab, surface_list[i]);
73 if (surf->buffer)
74 surf->buffer->destroy(surf->buffer);
75 util_dynarray_fini(&surf->subpics);
76 FREE(surf);
77 handle_table_remove(drv->htab, surface_list[i]);
78 }
79
80 return VA_STATUS_SUCCESS;
81 }
82
83 VAStatus
84 vlVaSyncSurface(VADriverContextP ctx, VASurfaceID render_target)
85 {
86 if (!ctx)
87 return VA_STATUS_ERROR_INVALID_CONTEXT;
88
89 return VA_STATUS_SUCCESS;
90 }
91
92 VAStatus
93 vlVaQuerySurfaceStatus(VADriverContextP ctx, VASurfaceID render_target, VASurfaceStatus *status)
94 {
95 if (!ctx)
96 return VA_STATUS_ERROR_INVALID_CONTEXT;
97
98 return VA_STATUS_SUCCESS;
99 }
100
101 VAStatus
102 vlVaQuerySurfaceError(VADriverContextP ctx, VASurfaceID render_target, VAStatus error_status, void **error_info)
103 {
104 if (!ctx)
105 return VA_STATUS_ERROR_INVALID_CONTEXT;
106
107 return VA_STATUS_ERROR_UNIMPLEMENTED;
108 }
109
110 static void
111 upload_sampler(struct pipe_context *pipe, struct pipe_sampler_view *dst,
112 const struct pipe_box *dst_box, const void *src, unsigned src_stride,
113 unsigned src_x, unsigned src_y)
114 {
115 struct pipe_transfer *transfer;
116 void *map;
117
118 map = pipe->transfer_map(pipe, dst->texture, 0, PIPE_TRANSFER_WRITE,
119 dst_box, &transfer);
120 if (!map)
121 return;
122
123 util_copy_rect(map, dst->texture->format, transfer->stride, 0, 0,
124 dst_box->width, dst_box->height,
125 src, src_stride, src_x, src_y);
126
127 pipe->transfer_unmap(pipe, transfer);
128 }
129
130 static VAStatus
131 vlVaPutSubpictures(vlVaSurface *surf, vlVaDriver *drv,
132 struct pipe_surface *surf_draw, struct u_rect *dirty_area,
133 struct u_rect *src_rect, struct u_rect *dst_rect)
134 {
135 vlVaSubpicture *sub;
136 int i;
137
138 if (!(surf->subpics.data || surf->subpics.size))
139 return VA_STATUS_SUCCESS;
140
141 for (i = 0; i < surf->subpics.size/sizeof(vlVaSubpicture *); i++) {
142 struct pipe_blend_state blend;
143 void *blend_state;
144 vlVaBuffer *buf;
145 struct pipe_box box;
146 struct u_rect *s, *d, sr, dr, c;
147 int sw, sh, dw, dh;
148
149 sub = ((vlVaSubpicture **)surf->subpics.data)[i];
150 if (!sub)
151 continue;
152
153 buf = handle_table_get(drv->htab, sub->image->buf);
154 if (!buf)
155 return VA_STATUS_ERROR_INVALID_IMAGE;
156
157 box.x = 0;
158 box.y = 0;
159 box.z = 0;
160 box.width = sub->dst_rect.x1 - sub->dst_rect.x0;
161 box.height = sub->dst_rect.y1 - sub->dst_rect.y0;
162 box.depth = 1;
163
164 s = &sub->src_rect;
165 d = &sub->dst_rect;
166 sw = s->x1 - s->x0;
167 sh = s->y1 - s->y0;
168 dw = d->x1 - d->x0;
169 dh = d->y1 - d->y0;
170 c.x0 = MAX2(d->x0, s->x0);
171 c.y0 = MAX2(d->y0, s->y0);
172 c.x1 = MIN2(d->x0 + dw, src_rect->x1);
173 c.y1 = MIN2(d->y0 + dh, src_rect->y1);
174 sr.x0 = s->x0 + (c.x0 - d->x0)*(sw/(float)dw);
175 sr.y0 = s->y0 + (c.y0 - d->y0)*(sh/(float)dh);
176 sr.x1 = s->x0 + (c.x1 - d->x0)*(sw/(float)dw);
177 sr.y1 = s->y0 + (c.y1 - d->y0)*(sh/(float)dh);
178
179 s = src_rect;
180 d = dst_rect;
181 sw = s->x1 - s->x0;
182 sh = s->y1 - s->y0;
183 dw = d->x1 - d->x0;
184 dh = d->y1 - d->y0;
185 dr.x0 = d->x0 + c.x0*(dw/(float)sw);
186 dr.y0 = d->y0 + c.y0*(dh/(float)sh);
187 dr.x1 = d->x0 + c.x1*(dw/(float)sw);
188 dr.y1 = d->y0 + c.y1*(dh/(float)sh);
189
190 memset(&blend, 0, sizeof(blend));
191 blend.independent_blend_enable = 0;
192 blend.rt[0].blend_enable = 1;
193 blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
194 blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
195 blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ZERO;
196 blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
197 blend.rt[0].rgb_func = PIPE_BLEND_ADD;
198 blend.rt[0].alpha_func = PIPE_BLEND_ADD;
199 blend.rt[0].colormask = PIPE_MASK_RGBA;
200 blend.logicop_enable = 0;
201 blend.logicop_func = PIPE_LOGICOP_CLEAR;
202 blend.dither = 0;
203 blend_state = drv->pipe->create_blend_state(drv->pipe, &blend);
204
205 vl_compositor_clear_layers(&drv->cstate);
206 vl_compositor_set_layer_blend(&drv->cstate, 0, blend_state, false);
207 upload_sampler(drv->pipe, sub->sampler, &box, buf->data,
208 sub->image->pitches[0], 0, 0);
209 vl_compositor_set_rgba_layer(&drv->cstate, &drv->compositor, 0, sub->sampler,
210 &sr, NULL, NULL);
211 vl_compositor_set_layer_dst_area(&drv->cstate, 0, &dr);
212 vl_compositor_render(&drv->cstate, &drv->compositor, surf_draw, dirty_area, false);
213 drv->pipe->delete_blend_state(drv->pipe, blend_state);
214 }
215
216 return VA_STATUS_SUCCESS;
217 }
218
219 VAStatus
220 vlVaPutSurface(VADriverContextP ctx, VASurfaceID surface_id, void* draw, short srcx, short srcy,
221 unsigned short srcw, unsigned short srch, short destx, short desty,
222 unsigned short destw, unsigned short desth, VARectangle *cliprects,
223 unsigned int number_cliprects, unsigned int flags)
224 {
225 vlVaDriver *drv;
226 vlVaSurface *surf;
227 struct pipe_screen *screen;
228 struct pipe_resource *tex;
229 struct pipe_surface surf_templ, *surf_draw;
230 struct vl_screen *vscreen;
231 struct u_rect src_rect, *dirty_area;
232 struct u_rect dst_rect = {destx, destx + destw, desty, desty + desth};
233 VAStatus status;
234
235 if (!ctx)
236 return VA_STATUS_ERROR_INVALID_CONTEXT;
237
238 drv = VL_VA_DRIVER(ctx);
239 surf = handle_table_get(drv->htab, surface_id);
240 if (!surf)
241 return VA_STATUS_ERROR_INVALID_SURFACE;
242
243 screen = drv->pipe->screen;
244 vscreen = drv->vscreen;
245
246 tex = vscreen->texture_from_drawable(vscreen, draw);
247 if (!tex)
248 return VA_STATUS_ERROR_INVALID_DISPLAY;
249
250 dirty_area = vscreen->get_dirty_area(vscreen);
251
252 memset(&surf_templ, 0, sizeof(surf_templ));
253 surf_templ.format = tex->format;
254 surf_draw = drv->pipe->create_surface(drv->pipe, tex, &surf_templ);
255 if (!surf_draw) {
256 pipe_resource_reference(&tex, NULL);
257 return VA_STATUS_ERROR_INVALID_DISPLAY;
258 }
259
260 src_rect.x0 = srcx;
261 src_rect.y0 = srcy;
262 src_rect.x1 = srcw + srcx;
263 src_rect.y1 = srch + srcy;
264
265 vl_compositor_clear_layers(&drv->cstate);
266 vl_compositor_set_buffer_layer(&drv->cstate, &drv->compositor, 0, surf->buffer, &src_rect, NULL, VL_COMPOSITOR_WEAVE);
267 vl_compositor_set_layer_dst_area(&drv->cstate, 0, &dst_rect);
268 vl_compositor_render(&drv->cstate, &drv->compositor, surf_draw, dirty_area, true);
269
270 status = vlVaPutSubpictures(surf, drv, surf_draw, dirty_area, &src_rect, &dst_rect);
271 if (status)
272 return status;
273
274 screen->flush_frontbuffer(screen, tex, 0, 0,
275 vscreen->get_private(vscreen), NULL);
276
277 drv->pipe->flush(drv->pipe, NULL, 0);
278
279 pipe_resource_reference(&tex, NULL);
280 pipe_surface_reference(&surf_draw, NULL);
281
282 return VA_STATUS_SUCCESS;
283 }
284
285 VAStatus
286 vlVaLockSurface(VADriverContextP ctx, VASurfaceID surface, unsigned int *fourcc,
287 unsigned int *luma_stride, unsigned int *chroma_u_stride, unsigned int *chroma_v_stride,
288 unsigned int *luma_offset, unsigned int *chroma_u_offset, unsigned int *chroma_v_offset,
289 unsigned int *buffer_name, void **buffer)
290 {
291 if (!ctx)
292 return VA_STATUS_ERROR_INVALID_CONTEXT;
293
294 return VA_STATUS_ERROR_UNIMPLEMENTED;
295 }
296
297 VAStatus
298 vlVaUnlockSurface(VADriverContextP ctx, VASurfaceID surface)
299 {
300 if (!ctx)
301 return VA_STATUS_ERROR_INVALID_CONTEXT;
302
303 return VA_STATUS_ERROR_UNIMPLEMENTED;
304 }
305
306 VAStatus
307 vlVaQuerySurfaceAttributes(VADriverContextP ctx, VAConfigID config,
308 VASurfaceAttrib *attrib_list, unsigned int *num_attribs)
309 {
310 vlVaDriver *drv;
311 VASurfaceAttrib *attribs;
312 struct pipe_screen *pscreen;
313 int i, j;
314
315 STATIC_ASSERT(ARRAY_SIZE(vpp_surface_formats) <= VL_VA_MAX_IMAGE_FORMATS);
316
317 if (config == VA_INVALID_ID)
318 return VA_STATUS_ERROR_INVALID_CONFIG;
319
320 if (!attrib_list && !num_attribs)
321 return VA_STATUS_ERROR_INVALID_PARAMETER;
322
323 if (!attrib_list) {
324 *num_attribs = VL_VA_MAX_IMAGE_FORMATS + VASurfaceAttribCount;
325 return VA_STATUS_SUCCESS;
326 }
327
328 if (!ctx)
329 return VA_STATUS_ERROR_INVALID_CONTEXT;
330
331 drv = VL_VA_DRIVER(ctx);
332
333 if (!drv)
334 return VA_STATUS_ERROR_INVALID_CONTEXT;
335
336 pscreen = VL_VA_PSCREEN(ctx);
337
338 if (!pscreen)
339 return VA_STATUS_ERROR_INVALID_CONTEXT;
340
341 attribs = CALLOC(VL_VA_MAX_IMAGE_FORMATS + VASurfaceAttribCount,
342 sizeof(VASurfaceAttrib));
343
344 if (!attribs)
345 return VA_STATUS_ERROR_ALLOCATION_FAILED;
346
347 i = 0;
348
349 /* vlVaCreateConfig returns PIPE_VIDEO_PROFILE_UNKNOWN
350 * only for VAEntrypointVideoProc. */
351 if (config == PIPE_VIDEO_PROFILE_UNKNOWN) {
352 for (j = 0; j < ARRAY_SIZE(vpp_surface_formats); ++j) {
353 attribs[i].type = VASurfaceAttribPixelFormat;
354 attribs[i].value.type = VAGenericValueTypeInteger;
355 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
356 attribs[i].value.value.i = PipeFormatToVaFourcc(vpp_surface_formats[j]);
357 i++;
358 }
359 } else {
360 /* Assume VAEntrypointVLD for now. */
361 attribs[i].type = VASurfaceAttribPixelFormat;
362 attribs[i].value.type = VAGenericValueTypeInteger;
363 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
364 attribs[i].value.value.i = VA_FOURCC_NV12;
365 i++;
366 }
367
368 attribs[i].type = VASurfaceAttribMemoryType;
369 attribs[i].value.type = VAGenericValueTypeInteger;
370 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
371 attribs[i].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA |
372 VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME;
373 i++;
374
375 attribs[i].type = VASurfaceAttribExternalBufferDescriptor;
376 attribs[i].value.type = VAGenericValueTypePointer;
377 attribs[i].flags = VA_SURFACE_ATTRIB_SETTABLE;
378 attribs[i].value.value.p = NULL; /* ignore */
379 i++;
380
381 attribs[i].type = VASurfaceAttribMaxWidth;
382 attribs[i].value.type = VAGenericValueTypeInteger;
383 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE;
384 attribs[i].value.value.i = vl_video_buffer_max_size(pscreen);
385 i++;
386
387 attribs[i].type = VASurfaceAttribMaxHeight;
388 attribs[i].value.type = VAGenericValueTypeInteger;
389 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE;
390 attribs[i].value.value.i = vl_video_buffer_max_size(pscreen);
391 i++;
392
393 if (i > *num_attribs) {
394 *num_attribs = i;
395 FREE(attribs);
396 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
397 }
398
399 *num_attribs = i;
400 memcpy(attrib_list, attribs, i * sizeof(VASurfaceAttrib));
401 FREE(attribs);
402
403 return VA_STATUS_SUCCESS;
404 }
405
406 static VAStatus
407 suface_from_external_memory(VADriverContextP ctx, vlVaSurface *surface,
408 VASurfaceAttribExternalBuffers *memory_attibute,
409 int index, VASurfaceID *surfaces,
410 struct pipe_video_buffer *templat)
411 {
412 vlVaDriver *drv;
413 struct pipe_screen *pscreen;
414 struct pipe_resource *resource;
415 struct pipe_resource res_templ;
416 struct winsys_handle whandle;
417 struct pipe_resource *resources[VL_NUM_COMPONENTS];
418
419 if (!ctx)
420 return VA_STATUS_ERROR_INVALID_PARAMETER;
421
422 pscreen = VL_VA_PSCREEN(ctx);
423 drv = VL_VA_DRIVER(ctx);
424
425 if (!memory_attibute || !memory_attibute->buffers ||
426 index > memory_attibute->num_buffers)
427 return VA_STATUS_ERROR_INVALID_PARAMETER;
428
429 if (surface->templat.width != memory_attibute->width ||
430 surface->templat.height != memory_attibute->height ||
431 memory_attibute->num_planes < 1)
432 return VA_STATUS_ERROR_INVALID_PARAMETER;
433
434 switch (memory_attibute->pixel_format) {
435 case VA_FOURCC_RGBA:
436 case VA_FOURCC_RGBX:
437 case VA_FOURCC_BGRA:
438 case VA_FOURCC_BGRX:
439 if (memory_attibute->num_planes != 1)
440 return VA_STATUS_ERROR_INVALID_PARAMETER;
441 break;
442 default:
443 return VA_STATUS_ERROR_INVALID_PARAMETER;
444 }
445
446 memset(&res_templ, 0, sizeof(res_templ));
447 res_templ.target = PIPE_TEXTURE_2D;
448 res_templ.last_level = 0;
449 res_templ.depth0 = 1;
450 res_templ.array_size = 1;
451 res_templ.width0 = memory_attibute->width;
452 res_templ.height0 = memory_attibute->height;
453 res_templ.format = surface->templat.buffer_format;
454 res_templ.bind = PIPE_BIND_SAMPLER_VIEW;
455 res_templ.usage = PIPE_USAGE_DEFAULT;
456
457 memset(&whandle, 0, sizeof(struct winsys_handle));
458 whandle.type = DRM_API_HANDLE_TYPE_FD;
459 whandle.handle = memory_attibute->buffers[index];
460 whandle.stride = memory_attibute->pitches[index];
461
462 resource = pscreen->resource_from_handle(pscreen, &res_templ, &whandle);
463
464 if (!resource)
465 return VA_STATUS_ERROR_ALLOCATION_FAILED;
466
467 memset(resources, 0, sizeof resources);
468 resources[0] = resource;
469
470 surface->buffer = vl_video_buffer_create_ex2(drv->pipe, templat, resources);
471 if (!surface->buffer)
472 return VA_STATUS_ERROR_ALLOCATION_FAILED;
473
474 util_dynarray_init(&surface->subpics);
475 surfaces[index] = handle_table_add(drv->htab, surface);
476
477 if (!surfaces[index]) {
478 surface->buffer->destroy(surface->buffer);
479 return VA_STATUS_ERROR_ALLOCATION_FAILED;
480 }
481
482 return VA_STATUS_SUCCESS;
483 }
484
485 VAStatus
486 vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int format,
487 unsigned int width, unsigned int height,
488 VASurfaceID *surfaces, unsigned int num_surfaces,
489 VASurfaceAttrib *attrib_list, unsigned int num_attribs)
490 {
491 vlVaDriver *drv;
492 VASurfaceAttribExternalBuffers *memory_attibute;
493 struct pipe_video_buffer templat;
494 struct pipe_screen *pscreen;
495 int i;
496 int memory_type;
497 int expected_fourcc;
498 VAStatus vaStatus;
499
500 if (!ctx)
501 return VA_STATUS_ERROR_INVALID_CONTEXT;
502
503 if (!(width && height))
504 return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
505
506 drv = VL_VA_DRIVER(ctx);
507
508 if (!drv)
509 return VA_STATUS_ERROR_INVALID_CONTEXT;
510
511 pscreen = VL_VA_PSCREEN(ctx);
512
513 if (!pscreen)
514 return VA_STATUS_ERROR_INVALID_CONTEXT;
515
516 /* Default. */
517 memory_attibute = NULL;
518 memory_type = VA_SURFACE_ATTRIB_MEM_TYPE_VA;
519 expected_fourcc = 0;
520
521 for (i = 0; i < num_attribs && attrib_list; i++) {
522 if ((attrib_list[i].type == VASurfaceAttribPixelFormat) &&
523 (attrib_list[i].flags & VA_SURFACE_ATTRIB_SETTABLE)) {
524 if (attrib_list[i].value.type != VAGenericValueTypeInteger)
525 return VA_STATUS_ERROR_INVALID_PARAMETER;
526 expected_fourcc = attrib_list[i].value.value.i;
527 }
528
529 if ((attrib_list[i].type == VASurfaceAttribMemoryType) &&
530 (attrib_list[i].flags & VA_SURFACE_ATTRIB_SETTABLE)) {
531
532 if (attrib_list[i].value.type != VAGenericValueTypeInteger)
533 return VA_STATUS_ERROR_INVALID_PARAMETER;
534
535 switch (attrib_list[i].value.value.i) {
536 case VA_SURFACE_ATTRIB_MEM_TYPE_VA:
537 case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME:
538 memory_type = attrib_list[i].value.value.i;
539 break;
540 default:
541 return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
542 }
543 }
544
545 if ((attrib_list[i].type == VASurfaceAttribExternalBufferDescriptor) &&
546 (attrib_list[i].flags == VA_SURFACE_ATTRIB_SETTABLE)) {
547 if (attrib_list[i].value.type != VAGenericValueTypePointer)
548 return VA_STATUS_ERROR_INVALID_PARAMETER;
549 memory_attibute = (VASurfaceAttribExternalBuffers *)attrib_list[i].value.value.p;
550 }
551 }
552
553 if (VA_RT_FORMAT_YUV420 != format &&
554 VA_RT_FORMAT_YUV422 != format &&
555 VA_RT_FORMAT_YUV444 != format &&
556 VA_RT_FORMAT_RGB32 != format) {
557 return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
558 }
559
560 switch (memory_type) {
561 case VA_SURFACE_ATTRIB_MEM_TYPE_VA:
562 break;
563 case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME:
564 if (!memory_attibute)
565 return VA_STATUS_ERROR_INVALID_PARAMETER;
566
567 expected_fourcc = memory_attibute->pixel_format;
568 break;
569 default:
570 assert(0);
571 }
572
573 memset(&templat, 0, sizeof(templat));
574
575 if (expected_fourcc) {
576 templat.buffer_format = VaFourccToPipeFormat(expected_fourcc);
577 templat.interlaced = 0;
578 } else {
579 templat.buffer_format = pscreen->get_video_param
580 (
581 pscreen,
582 PIPE_VIDEO_PROFILE_UNKNOWN,
583 PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
584 PIPE_VIDEO_CAP_PREFERED_FORMAT
585 );
586 templat.interlaced = pscreen->get_video_param
587 (
588 pscreen,
589 PIPE_VIDEO_PROFILE_UNKNOWN,
590 PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
591 PIPE_VIDEO_CAP_PREFERS_INTERLACED
592 );
593 }
594
595 templat.chroma_format = ChromaToPipe(format);
596
597 templat.width = width;
598 templat.height = height;
599
600 memset(surfaces, VA_INVALID_ID, num_surfaces * sizeof(VASurfaceID));
601
602 for (i = 0; i < num_surfaces; i++) {
603 vlVaSurface *surf = CALLOC(1, sizeof(vlVaSurface));
604 if (!surf)
605 goto no_res;
606
607 surf->templat = templat;
608
609 switch (memory_type) {
610 case VA_SURFACE_ATTRIB_MEM_TYPE_VA:
611 surf->buffer = drv->pipe->create_video_buffer(drv->pipe, &templat);
612 if (!surf->buffer) {
613 FREE(surf);
614 goto no_res;
615 }
616 util_dynarray_init(&surf->subpics);
617 surfaces[i] = handle_table_add(drv->htab, surf);
618 break;
619 case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME:
620 vaStatus = suface_from_external_memory(ctx, surf, memory_attibute, i, surfaces, &templat);
621 if (vaStatus != VA_STATUS_SUCCESS) {
622 FREE(surf);
623 goto no_res;
624 }
625 break;
626 default:
627 assert(0);
628 }
629 }
630
631 return VA_STATUS_SUCCESS;
632
633 no_res:
634 if (i)
635 vlVaDestroySurfaces(ctx, surfaces, i);
636
637 return VA_STATUS_ERROR_ALLOCATION_FAILED;
638 }
639
640 VAStatus
641 vlVaQueryVideoProcFilters(VADriverContextP ctx, VAContextID context,
642 VAProcFilterType *filters, unsigned int *num_filters)
643 {
644 unsigned int num = 0;
645
646 if (!ctx)
647 return VA_STATUS_ERROR_INVALID_CONTEXT;
648
649 if (!num_filters || !filters)
650 return VA_STATUS_ERROR_INVALID_PARAMETER;
651
652 filters[num++] = VAProcFilterNone;
653
654 *num_filters = num;
655
656 return VA_STATUS_SUCCESS;
657 }
658
659 VAStatus
660 vlVaQueryVideoProcFilterCaps(VADriverContextP ctx, VAContextID context,
661 VAProcFilterType type, void *filter_caps,
662 unsigned int *num_filter_caps)
663 {
664 unsigned int i;
665
666 if (!ctx)
667 return VA_STATUS_ERROR_INVALID_CONTEXT;
668
669 if (!filter_caps || !num_filter_caps)
670 return VA_STATUS_ERROR_INVALID_PARAMETER;
671
672 i = 0;
673
674 switch (type) {
675 case VAProcFilterNone:
676 break;
677 case VAProcFilterNoiseReduction:
678 case VAProcFilterDeinterlacing:
679 case VAProcFilterSharpening:
680 case VAProcFilterColorBalance:
681 case VAProcFilterSkinToneEnhancement:
682 return VA_STATUS_ERROR_UNIMPLEMENTED;
683 default:
684 assert(0);
685 }
686
687 *num_filter_caps = i;
688
689 return VA_STATUS_SUCCESS;
690 }
691
692 static VAProcColorStandardType vpp_input_color_standards[] = {
693 VAProcColorStandardBT601
694 };
695
696 static VAProcColorStandardType vpp_output_color_standards[] = {
697 VAProcColorStandardBT601
698 };
699
700 VAStatus
701 vlVaQueryVideoProcPipelineCaps(VADriverContextP ctx, VAContextID context,
702 VABufferID *filters, unsigned int num_filters,
703 VAProcPipelineCaps *pipeline_cap)
704 {
705 unsigned int i = 0;
706
707 if (!ctx)
708 return VA_STATUS_ERROR_INVALID_CONTEXT;
709
710 if (!pipeline_cap)
711 return VA_STATUS_ERROR_INVALID_PARAMETER;
712
713 if (num_filters && !filters)
714 return VA_STATUS_ERROR_INVALID_PARAMETER;
715
716 pipeline_cap->pipeline_flags = 0;
717 pipeline_cap->filter_flags = 0;
718 pipeline_cap->num_forward_references = 0;
719 pipeline_cap->num_backward_references = 0;
720 pipeline_cap->num_input_color_standards = Elements(vpp_input_color_standards);
721 pipeline_cap->input_color_standards = vpp_input_color_standards;
722 pipeline_cap->num_output_color_standards = Elements(vpp_output_color_standards);
723 pipeline_cap->output_color_standards = vpp_output_color_standards;
724
725 for (i = 0; i < num_filters; i++) {
726 vlVaBuffer *buf = handle_table_get(VL_VA_DRIVER(ctx)->htab, filters[i]);
727
728 if (!buf || buf->type >= VABufferTypeMax)
729 return VA_STATUS_ERROR_INVALID_BUFFER;
730 }
731
732 return VA_STATUS_SUCCESS;
733 }