1 /*
2 * Copyright (c) 2011 Intel Corporation. All Rights Reserved.
3 * Copyright (c) Imagination Technologies Limited, UK
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
15 * of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 * Authors:
26 * Waldo Bastian <waldo.bastian@intel.com>
27 *
28 */
29
30 #include <va/va_backend.h>
31 #include <va/va_backend_tpi.h>
32 #include <va/va_backend_egl.h>
33 #ifdef PSBVIDEO_MRFL_VPP
34 #include <va/va_backend_vpp.h>
35 #endif
36 #ifdef PSBVIDEO_MFLD
37 #include <va/va_backend_vpp.h>
38 #endif
39 #include <va/va_drmcommon.h>
40 #include <va/va_android.h>
41 #include <va/va_tpi.h>
42
43 #include "psb_drv_video.h"
44 #include "psb_texture.h"
45 #include "psb_cmdbuf.h"
46 #ifndef BAYTRAIL
47 #include "pnw_cmdbuf.h"
48 #include "tng_cmdbuf.h"
49 #endif
50 #ifdef PSBVIDEO_MRFL_VPP
51 #include "vsp_cmdbuf.h"
52 #endif
53 #include "psb_surface.h"
54
55 #include "pnw_MPEG2.h"
56 #include "pnw_MPEG4.h"
57 #include "pnw_H264.h"
58 #include "pnw_VC1.h"
59 #include "tng_jpegdec.h"
60 #include "tng_VP8.h"
61 #include "tng_yuv_processor.h"
62
63 #ifdef PSBVIDEO_MFLD
64 #include "pnw_MPEG4ES.h"
65 #include "pnw_H264ES.h"
66 #include "pnw_H263ES.h"
67 #include "pnw_jpeg.h"
68 #endif
69 #ifdef PSBVIDEO_MRFL
70 #include "tng_H264ES.h"
71 #include "tng_H263ES.h"
72 #include "tng_MPEG4ES.h"
73 #include "tng_jpegES.h"
74 #endif
75 #ifdef PSBVIDEO_MRFL_VPP
76 #include "vsp_VPP.h"
77 #include "vsp_vp8.h"
78 #endif
79 #include "psb_output.h"
80 #include <stdio.h>
81 #include <string.h>
82 #include <stdarg.h>
83 #include <time.h>
84 #include <unistd.h>
85 #include <wsbm/wsbm_pool.h>
86 #include <wsbm/wsbm_manager.h>
87 #include <wsbm/wsbm_util.h>
88 #include <wsbm/wsbm_fencemgr.h>
89 #include <linux/videodev2.h>
90 #include <errno.h>
91
92 #include "psb_def.h"
93 #include "psb_drv_debug.h"
94 #ifndef BAYTRAIL
95 #include "psb_ws_driver.h"
96 #endif
97 #include "pnw_rotate.h"
98 #include "psb_surface_attrib.h"
99 #include "android/psb_gralloc.h"
100
101 #ifndef PSB_PACKAGE_VERSION
102 #define PSB_PACKAGE_VERSION "Undefined"
103 #endif
104
105 #define PSB_DRV_VERSION PSB_PACKAGE_VERSION
106 #define PSB_CHG_REVISION "(0X00000071)"
107
108 #define PSB_STR_VENDOR_MRST "Intel GMA500-MRST-" PSB_DRV_VERSION " " PSB_CHG_REVISION
109 #define PSB_STR_VENDOR_MFLD "Intel GMA500-MFLD-" PSB_DRV_VERSION " " PSB_CHG_REVISION
110 #define PSB_STR_VENDOR_MRFL "Intel GMA500-MRFL-" PSB_DRV_VERSION " " PSB_CHG_REVISION
111 #define PSB_STR_VENDOR_BAYTRAIL "Intel GMA500-BAYTRAIL-" PSB_DRV_VERSION " " PSB_CHG_REVISION
112 #define PSB_STR_VENDOR_LEXINGTON "Intel GMA500-LEXINGTON-" PSB_DRV_VERSION " " PSB_CHG_REVISION
113
114 #define MAX_UNUSED_BUFFERS 16
115
116 #define PSB_SURFACE_UNAVAILABLE 0x40000000
117
118 #define PSB_MAX_FLIP_DELAY (1000/30/10)
119
120 #define PSB_SURFACE_UNAVAILABLE 0x40000000
121
122 #include <signal.h>
123
124 #define EXPORT __attribute__ ((visibility("default")))
125
126 #define INIT_DRIVER_DATA psb_driver_data_p driver_data = (psb_driver_data_p) ctx->pDriverData;
127
128 #ifdef PSBVIDEO_MRFL_VPP
129 #define INIT_FORMAT_VTABLE format_vtable_p format_vtable = ((profile < PSB_MAX_PROFILES) && (entrypoint < PSB_MAX_ENTRYPOINTS)) ? (profile == VAProfileNone? driver_data->vpp_profile : driver_data->profile2Format[profile][entrypoint]) : NULL;
130 #endif
131 #ifdef PSBVIDEO_MFLD
132 #define INIT_FORMAT_VTABLE format_vtable_p format_vtable = ((profile < PSB_MAX_PROFILES) && (entrypoint < PSB_MAX_ENTRYPOINTS)) ? (profile == VAProfileNone? driver_data->vpp_profile : driver_data->profile2Format[profile][entrypoint]) : NULL;
133 #endif
134
135 #define CONFIG(id) ((object_config_p) object_heap_lookup( &driver_data->config_heap, id ))
136 #define CONTEXT(id) ((object_context_p) object_heap_lookup( &driver_data->context_heap, id ))
137 #define SURFACE(id) ((object_surface_p) object_heap_lookup( &driver_data->surface_heap, id ))
138 #define BUFFER(id) ((object_buffer_p) object_heap_lookup( &driver_data->buffer_heap, id ))
139
140 #define CONFIG_ID_OFFSET 0x01000000
141 #define CONTEXT_ID_OFFSET 0x02000000
142 #define SURFACE_ID_OFFSET 0x03000000
143 #define BUFFER_ID_OFFSET 0x04000000
144 #define IMAGE_ID_OFFSET 0x05000000
145 #define SUBPIC_ID_OFFSET 0x06000000
146
147 static int psb_get_device_info(VADriverContextP ctx);
148
149
150 void psb_init_surface_pvr2dbuf(psb_driver_data_p driver_data);
151 void psb_free_surface_pvr2dbuf(psb_driver_data_p driver_data);
152
psb_QueryConfigProfiles(VADriverContextP ctx,VAProfile * profile_list,int * num_profiles)153 VAStatus psb_QueryConfigProfiles(
154 VADriverContextP ctx,
155 VAProfile *profile_list, /* out */
156 int *num_profiles /* out */
157 )
158 {
159 DEBUG_FUNC_ENTER
160 (void) ctx; /* unused */
161 int i = 0;
162 VAStatus vaStatus = VA_STATUS_SUCCESS;
163 INIT_DRIVER_DATA
164
165 CHECK_INVALID_PARAM(profile_list == NULL);
166 CHECK_INVALID_PARAM(num_profiles == NULL);
167
168 #ifdef PSBVIDEO_MRFL_VPP
169 profile_list[i++] = VAProfileNone;
170 #endif
171 // profile_list[i++] = VAProfileMPEG2Simple;
172 profile_list[i++] = VAProfileMPEG2Main;
173 profile_list[i++] = VAProfileMPEG4Simple;
174 profile_list[i++] = VAProfileMPEG4AdvancedSimple;
175 // profile_list[i++] = VAProfileMPEG4Main;
176 profile_list[i++] = VAProfileH264Baseline;
177 profile_list[i++] = VAProfileH264Main;
178 profile_list[i++] = VAProfileH264High;
179 profile_list[i++] = VAProfileH264StereoHigh;
180 profile_list[i++] = VAProfileVC1Simple;
181 profile_list[i++] = VAProfileVC1Main;
182 profile_list[i++] = VAProfileVC1Advanced;
183
184 if (IS_MRFL(driver_data) || IS_BAYTRAIL(driver_data)) {
185 profile_list[i++] = VAProfileH263Baseline;
186 profile_list[i++] = VAProfileJPEGBaseline;
187 profile_list[i++] = VAProfileVP8Version0_3;
188 } else if (IS_MFLD(driver_data)) {
189 profile_list[i++] = VAProfileH263Baseline;
190 profile_list[i++] = VAProfileJPEGBaseline;
191 }
192 profile_list[i++] = VAProfileH264ConstrainedBaseline;
193
194 /* If the assert fails then PSB_MAX_PROFILES needs to be bigger */
195 ASSERT(i <= PSB_MAX_PROFILES);
196 *num_profiles = i;
197 DEBUG_FUNC_EXIT
198 return VA_STATUS_SUCCESS;
199 }
200
psb_QueryConfigEntrypoints(VADriverContextP ctx,VAProfile profile,VAEntrypoint * entrypoint_list,int * num_entrypoints)201 VAStatus psb_QueryConfigEntrypoints(
202 VADriverContextP ctx,
203 VAProfile profile,
204 VAEntrypoint *entrypoint_list, /* out */
205 int *num_entrypoints /* out */
206 )
207 {
208 DEBUG_FUNC_ENTER
209 INIT_DRIVER_DATA
210 VAStatus vaStatus = VA_STATUS_SUCCESS;
211 int entrypoints = 0;
212 int i;
213
214 CHECK_INVALID_PARAM(entrypoint_list == NULL);
215 CHECK_INVALID_PARAM((num_entrypoints == NULL) || (profile >= PSB_MAX_PROFILES));
216
217 for (i = 0; i < PSB_MAX_ENTRYPOINTS; i++) {
218 #ifndef BAYTRAIL
219 #ifdef PSBVIDEO_MRFL_VPP
220 if (profile == VAProfileNone && driver_data->vpp_profile &&
221 i == VAEntrypointVideoProc) {
222 entrypoints++;
223 *entrypoint_list++ = i;
224 } else
225 #endif
226 #endif
227 if (profile != VAProfileNone && driver_data->profile2Format[profile][i]) {
228 entrypoints++;
229 *entrypoint_list++ = i;
230 }
231 }
232
233 /* If the assert fails then PSB_MAX_ENTRYPOINTS needs to be bigger */
234 ASSERT(entrypoints <= PSB_MAX_ENTRYPOINTS);
235
236 if (0 == entrypoints) {
237 return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
238 }
239
240 *num_entrypoints = entrypoints;
241 DEBUG_FUNC_EXIT
242 return VA_STATUS_SUCCESS;
243 }
244
245 /*
246 * Figure out if we should return VA_STATUS_ERROR_UNSUPPORTED_PROFILE
247 * or VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT
248 */
psb__error_unsupported_profile_entrypoint(psb_driver_data_p driver_data,VAProfile profile,VAEntrypoint __maybe_unused entrypoint)249 static VAStatus psb__error_unsupported_profile_entrypoint(psb_driver_data_p driver_data, VAProfile profile, VAEntrypoint __maybe_unused entrypoint)
250 {
251 /* Does the driver support _any_ entrypoint for this profile? */
252 if (profile < PSB_MAX_PROFILES) {
253 int i;
254
255 /* Do the parameter check for MFLD and MRFLD */
256 if (profile == VAProfileNone)
257 return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
258
259 for (i = 0; i < PSB_MAX_ENTRYPOINTS; i++) {
260 if (driver_data->profile2Format[profile][i]) {
261 /* There is an entrypoint, so the profile is supported */
262 return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
263 }
264 }
265 }
266 return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
267 }
268
psb_GetConfigAttributes(VADriverContextP ctx,VAProfile profile,VAEntrypoint entrypoint,VAConfigAttrib * attrib_list,int num_attribs)269 VAStatus psb_GetConfigAttributes(
270 VADriverContextP ctx,
271 VAProfile profile,
272 VAEntrypoint entrypoint,
273 VAConfigAttrib *attrib_list, /* in/out */
274 int num_attribs
275 )
276 {
277 DEBUG_FUNC_ENTER
278 INIT_DRIVER_DATA
279
280 #if defined(BAYTRAIL)
281 format_vtable_p format_vtable = driver_data->profile2Format[profile][entrypoint];
282 #elif defined(PSBVIDEO_MRFL_VPP)
283 INIT_FORMAT_VTABLE
284 #else
285 format_vtable_p format_vtable = driver_data->profile2Format[profile][entrypoint];
286 #endif
287 int i;
288 VAStatus vaStatus = VA_STATUS_SUCCESS;
289 if (NULL == format_vtable) {
290 return psb__error_unsupported_profile_entrypoint(driver_data, profile, entrypoint);
291 }
292
293 CHECK_INVALID_PARAM(attrib_list == NULL);
294 CHECK_INVALID_PARAM(num_attribs <= 0);
295
296 /* Generic attributes */
297 for (i = 0; i < num_attribs; i++) {
298 switch (attrib_list[i].type) {
299 case VAConfigAttribRTFormat:
300 attrib_list[i].value = VA_RT_FORMAT_YUV420;
301 if (entrypoint == VAEntrypointEncPicture)
302 attrib_list[i].value |= VA_RT_FORMAT_YUV422;
303 if ((profile == VAProfileJPEGBaseline) && (entrypoint == VAEntrypointVLD))
304 attrib_list[i].value |= VA_RT_FORMAT_YUV444;
305 break;
306
307 default:
308 attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
309 break;
310 }
311 }
312 /* format specific attributes */
313 format_vtable->queryConfigAttributes(profile, entrypoint, attrib_list, num_attribs);
314 DEBUG_FUNC_EXIT
315 return VA_STATUS_SUCCESS;
316 }
317
psb__update_attribute(object_config_p obj_config,VAConfigAttrib * attrib)318 static VAStatus psb__update_attribute(object_config_p obj_config, VAConfigAttrib *attrib)
319 {
320 int i;
321 /* Check existing attributes */
322 for (i = 0; i < obj_config->attrib_count; i++) {
323 if (obj_config->attrib_list[i].type == attrib->type) {
324 /* Update existing attribute */
325 obj_config->attrib_list[i].value = attrib->value;
326 return VA_STATUS_SUCCESS;
327 }
328 }
329 if (obj_config->attrib_count < PSB_MAX_CONFIG_ATTRIBUTES) {
330 i = obj_config->attrib_count;
331 obj_config->attrib_list[i].type = attrib->type;
332 obj_config->attrib_list[i].value = attrib->value;
333 obj_config->attrib_count++;
334 return VA_STATUS_SUCCESS;
335 }
336 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
337 }
338
psb__validate_config(object_config_p obj_config)339 static VAStatus psb__validate_config(object_config_p obj_config)
340 {
341 int i;
342 /* Check all attributes */
343 for (i = 0; i < obj_config->attrib_count; i++) {
344 switch (obj_config->attrib_list[i].type) {
345 case VAConfigAttribRTFormat:
346 if (!(obj_config->attrib_list[i].value == VA_RT_FORMAT_YUV420
347 || (obj_config->attrib_list[i].value == VA_RT_FORMAT_YUV422 &&
348 obj_config->entrypoint == VAEntrypointEncPicture)
349 || (obj_config->attrib_list[i].value == (VA_RT_FORMAT_YUV444 | VA_RT_FORMAT_YUV420 )))) {
350 return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
351 }
352 break;
353
354 default:
355 /*
356 * Ignore unknown attributes here, it
357 * may be format specific.
358 */
359 break;
360 }
361 }
362 return VA_STATUS_SUCCESS;
363 }
364
psb_get_active_entrypoint_number(VADriverContextP ctx,unsigned int entrypoint)365 static int psb_get_active_entrypoint_number(
366 VADriverContextP ctx,
367 unsigned int entrypoint)
368 {
369 INIT_DRIVER_DATA;
370 struct drm_lnc_video_getparam_arg arg;
371 int count = 0;
372 int ret;
373
374 if (VAEntrypointVLD > entrypoint ||
375 entrypoint > VAEntrypointEncPicture) {
376 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s :Invalid entrypoint %d.\n",
377 __FUNCTION__, entrypoint);
378 return -1;
379 }
380
381 arg.key = PNW_VIDEO_QUERY_ENTRY;
382 arg.value = (uint64_t)((unsigned long) &count);
383 arg.arg = (uint64_t)((unsigned int)&entrypoint);
384 ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset,
385 &arg, sizeof(arg));
386 if (ret) {
387 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s drmCommandWriteRead fails %d.\n",
388 __FUNCTION__, ret);
389 return -1;
390 }
391
392 return count;
393 }
394
psb_CreateConfig(VADriverContextP ctx,VAProfile profile,VAEntrypoint entrypoint,VAConfigAttrib * attrib_list,int num_attribs,VAConfigID * config_id)395 VAStatus psb_CreateConfig(
396 VADriverContextP ctx,
397 VAProfile profile,
398 VAEntrypoint entrypoint,
399 VAConfigAttrib *attrib_list,
400 int num_attribs,
401 VAConfigID *config_id /* out */
402 )
403 {
404 DEBUG_FUNC_ENTER
405 INIT_DRIVER_DATA
406 #if defined(BAYTRAIL)
407 format_vtable_p format_vtable = driver_data->profile2Format[profile][entrypoint];
408 #elif defined(PSBVIDEO_MRFL_VPP)
409 INIT_FORMAT_VTABLE
410 #else
411 format_vtable_p format_vtable = driver_data->profile2Format[profile][entrypoint];
412 #endif
413 VAStatus vaStatus = VA_STATUS_SUCCESS;
414 int configID;
415 object_config_p obj_config;
416 int i;
417
418 drv_debug_msg(VIDEO_DEBUG_INIT, "CreateConfig profile:%d, entrypoint:%d, num_attribs:%d.\n",
419 profile, entrypoint, num_attribs);
420 /*echo 8 > /sys/module/pvrsrvkm/parameters/no_ec will disable error concealment*/
421 if ((profile == VAProfileH264ConstrainedBaseline) && (VAEntrypointVLD == entrypoint)) {
422 char ec_disable[2];
423 FILE *ec_fp = fopen("/sys/module/pvrsrvkm/parameters/no_ec", "r");
424 if (ec_fp) {
425 if (fgets(ec_disable, 2, ec_fp) != NULL) {
426 /* force profile to VAProfileH264High */
427 if (strcmp(ec_disable, "8") == 0) {
428 drv_debug_msg(VIDEO_DEBUG_INIT, "disabled error concealment by setting profile to VAProfileH264High\n");
429 profile = VAProfileH264High;
430 }
431 }
432 fclose(ec_fp);
433 }
434 }
435
436 CHECK_INVALID_PARAM(config_id == NULL);
437 CHECK_INVALID_PARAM(num_attribs < 0);
438 CHECK_INVALID_PARAM(attrib_list == NULL);
439
440 if (NULL == format_vtable) {
441 vaStatus = psb__error_unsupported_profile_entrypoint(driver_data, profile, entrypoint);
442 }
443
444 CHECK_VASTATUS();
445
446 if ((IS_MFLD(driver_data)) &&
447 ((VAEntrypointEncPicture == entrypoint)
448 || (VAEntrypointEncSlice == entrypoint))) {
449 int active_slc, active_pic;
450 /* Only allow one encoding entrypoint at the sametime.
451 * But if video encoding request comes when process JPEG encoding,
452 * it will wait until current JPEG picture encoding finish.
453 * Further JPEG encoding should fall back to software path.*/
454 active_slc = psb_get_active_entrypoint_number(ctx, VAEntrypointEncSlice);
455 active_pic = psb_get_active_entrypoint_number(ctx, VAEntrypointEncPicture);
456
457 if (active_slc > 0) {
458 drv_debug_msg(VIDEO_DEBUG_ERROR, "There already is a active video encoding entrypoint."
459 "Entrypoint %d isn't available.\n", entrypoint);
460 return VA_STATUS_ERROR_HW_BUSY;
461 }
462 else if (active_pic > 0 && VAEntrypointEncPicture == entrypoint) {
463 drv_debug_msg(VIDEO_DEBUG_ERROR, "There already is a active picture encoding entrypoint."
464 "Entrypoint %d isn't available.\n", entrypoint);
465 return VA_STATUS_ERROR_HW_BUSY;
466 }
467 }
468
469 configID = object_heap_allocate(&driver_data->config_heap);
470 obj_config = CONFIG(configID);
471 CHECK_ALLOCATION(obj_config);
472
473 MEMSET_OBJECT(obj_config, struct object_config_s);
474
475 obj_config->profile = profile;
476 obj_config->format_vtable = format_vtable;
477 obj_config->entrypoint = entrypoint;
478 obj_config->attrib_list[0].type = VAConfigAttribRTFormat;
479 obj_config->attrib_list[0].value = VA_RT_FORMAT_YUV420;
480 obj_config->attrib_count = 1;
481
482 for (i = 0; i < num_attribs; i++) {
483 if (attrib_list[i].type > VAConfigAttribTypeMax)
484 return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
485
486 vaStatus = psb__update_attribute(obj_config, &(attrib_list[i]));
487 if (VA_STATUS_SUCCESS != vaStatus) {
488 break;
489 }
490 }
491
492 if (VA_STATUS_SUCCESS == vaStatus) {
493 vaStatus = psb__validate_config(obj_config);
494 }
495
496 if (VA_STATUS_SUCCESS == vaStatus) {
497 vaStatus = format_vtable->validateConfig(obj_config);
498 }
499
500 /* Error recovery */
501 if (VA_STATUS_SUCCESS != vaStatus) {
502 object_heap_free(&driver_data->config_heap, (object_base_p) obj_config);
503 } else {
504 *config_id = configID;
505 }
506
507 #ifdef PSBVIDEO_MSVDX_EC
508 if((getenv("PSB_VIDEO_NOEC") == NULL)
509 && (profile == VAProfileH264ConstrainedBaseline)) {
510 drv_debug_msg(VIDEO_DEBUG_INIT, "profile is VAProfileH264ConstrainedBaseline, error concealment is enabled. \n");
511 driver_data->ec_enabled = 1;
512 } else {
513 driver_data->ec_enabled = 0;
514 }
515
516 if (profile == VAProfileVP8Version0_3 ||
517 profile == VAProfileH264Baseline ||
518 profile == VAProfileH264Main ||
519 profile == VAProfileH264High ||
520 profile == VAProfileH264ConstrainedBaseline)
521 driver_data->ec_enabled = 1;
522
523 if (!IS_MRFL(driver_data)) {
524 if (profile == VAProfileMPEG4Simple ||
525 profile == VAProfileMPEG4AdvancedSimple ||
526 profile == VAProfileMPEG4Main)
527 driver_data->ec_enabled = 1;
528 }
529
530 #else
531 driver_data->ec_enabled = 0;
532 #endif
533
534 DEBUG_FUNC_EXIT
535 return vaStatus;
536 }
537
psb_DestroyConfig(VADriverContextP ctx,VAConfigID config_id)538 VAStatus psb_DestroyConfig(
539 VADriverContextP ctx,
540 VAConfigID config_id
541 )
542 {
543 DEBUG_FUNC_ENTER
544 INIT_DRIVER_DATA
545 VAStatus vaStatus = VA_STATUS_SUCCESS;
546 object_config_p obj_config;
547
548 obj_config = CONFIG(config_id);
549 CHECK_CONFIG(obj_config);
550
551 object_heap_free(&driver_data->config_heap, (object_base_p) obj_config);
552 DEBUG_FUNC_EXIT
553 return vaStatus;
554 }
555
psb_QueryConfigAttributes(VADriverContextP ctx,VAConfigID config_id,VAProfile * profile,VAEntrypoint * entrypoint,VAConfigAttrib * attrib_list,int * num_attribs)556 VAStatus psb_QueryConfigAttributes(
557 VADriverContextP ctx,
558 VAConfigID config_id,
559 VAProfile *profile, /* out */
560 VAEntrypoint *entrypoint, /* out */
561 VAConfigAttrib *attrib_list, /* out */
562 int *num_attribs /* out */
563 )
564 {
565 DEBUG_FUNC_ENTER
566 INIT_DRIVER_DATA
567 VAStatus vaStatus = VA_STATUS_SUCCESS;
568 object_config_p obj_config;
569 int i;
570
571 CHECK_INVALID_PARAM(profile == NULL);
572 CHECK_INVALID_PARAM(entrypoint == NULL);
573 CHECK_INVALID_PARAM(attrib_list == NULL);
574 CHECK_INVALID_PARAM(num_attribs == NULL);
575
576 obj_config = CONFIG(config_id);
577 CHECK_CONFIG(obj_config);
578
579 *profile = obj_config->profile;
580 *entrypoint = obj_config->entrypoint;
581 *num_attribs = obj_config->attrib_count;
582 for (i = 0; i < obj_config->attrib_count; i++) {
583 attrib_list[i] = obj_config->attrib_list[i];
584 }
585
586 DEBUG_FUNC_EXIT
587 return vaStatus;
588 }
589
psb__destroy_surface(psb_driver_data_p driver_data,object_surface_p obj_surface)590 void psb__destroy_surface(psb_driver_data_p driver_data, object_surface_p obj_surface)
591 {
592 if (NULL != obj_surface) {
593 /* delete subpicture association */
594 psb_SurfaceDeassociateSubpict(driver_data, obj_surface);
595
596 obj_surface->is_ref_surface = 0;
597
598 psb_surface_sync(obj_surface->psb_surface);
599 psb_surface_destroy(obj_surface->psb_surface);
600
601 if (obj_surface->out_loop_surface) {
602 psb_surface_destroy(obj_surface->out_loop_surface);
603 }
604
605 if (obj_surface->scaling_surface) {
606 psb_surface_destroy(obj_surface->scaling_surface);
607 }
608
609 free(obj_surface->psb_surface);
610 object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
611 }
612 }
613
psb__checkSurfaceDimensions(psb_driver_data_p driver_data,int width,int height)614 VAStatus psb__checkSurfaceDimensions(psb_driver_data_p driver_data, int width, int height)
615 {
616 if (driver_data->video_sd_disabled) {
617 return VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
618 }
619 if ((width <= 0) || (width * height > 5120 * 5120) || (height <= 0)) {
620 return VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
621 }
622 if (driver_data->video_hd_disabled) {
623 if ((width > 1024) || (height > 576)) {
624 return VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
625 }
626 }
627
628 return VA_STATUS_SUCCESS;
629 }
630
psb_GetSurfaceAttributes(VADriverContextP __maybe_unused ctx,VAConfigID __maybe_unused config,VASurfaceAttrib * attrib_list,unsigned int num_attribs)631 VAStatus psb_GetSurfaceAttributes(
632 VADriverContextP __maybe_unused ctx,
633 VAConfigID __maybe_unused config,
634 VASurfaceAttrib *attrib_list,
635 unsigned int num_attribs
636 )
637 {
638 DEBUG_FUNC_ENTER
639
640 uint32_t i;
641 VAStatus vaStatus = VA_STATUS_SUCCESS;
642
643 CHECK_INVALID_PARAM(attrib_list == NULL);
644 CHECK_INVALID_PARAM(num_attribs <= 0);
645
646 /* Generic attributes */
647 for (i = 0; i < num_attribs; i++) {
648 switch (attrib_list[i].type) {
649 case VASurfaceAttribMemoryType:
650 attrib_list[i].flags = VA_SURFACE_ATTRIB_SETTABLE | VA_SURFACE_ATTRIB_GETTABLE;
651 attrib_list[i].value.type = VAGenericValueTypeInteger;
652 attrib_list[i].value.value.i =
653 VA_SURFACE_ATTRIB_MEM_TYPE_VA |
654 VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR |
655 VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM |
656 VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC |
657 VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_ION;
658 break;
659
660 case VASurfaceAttribExternalBufferDescriptor:
661 attrib_list[i].flags = VA_SURFACE_ATTRIB_SETTABLE;
662 attrib_list[i].value.type = VAGenericValueTypePointer;
663 break;
664
665 default:
666 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
667 break;
668 }
669 }
670
671 DEBUG_FUNC_EXIT
672 return VA_STATUS_SUCCESS;
673
674 }
675
676 #ifdef PSBVIDEO_MSVDX_DEC_TILING
psb__tile_stride_log2_256(int w)677 unsigned long psb__tile_stride_log2_256(int w)
678 {
679 int stride_mode = 0;
680
681 if (512 >= w)
682 stride_mode = 1;
683 else if (1024 >= w)
684 stride_mode = 2;
685 else if (2048 >= w)
686 stride_mode = 3;
687 else if (4096 >= w)
688 stride_mode = 4;
689
690 return stride_mode;
691 }
692
psb__tile_stride_log2_512(int w)693 unsigned long psb__tile_stride_log2_512(int w)
694 {
695 int stride_mode = 0;
696
697 if (512 >= w)
698 stride_mode = 0;
699 else if (1024 >= w)
700 stride_mode = 1;
701 else if (2048 >= w)
702 stride_mode = 2;
703 else if (4096 >= w)
704 stride_mode = 3;
705
706 return stride_mode;
707 }
708 #endif
709
psb_CreateSurfaces(VADriverContextP __maybe_unused ctx,int __maybe_unused width,int __maybe_unused height,int __maybe_unused format,int __maybe_unused num_surfaces,VASurfaceID __maybe_unused * surface_list)710 VAStatus psb_CreateSurfaces(
711 VADriverContextP __maybe_unused ctx,
712 int __maybe_unused width,
713 int __maybe_unused height,
714 int __maybe_unused format,
715 int __maybe_unused num_surfaces,
716 VASurfaceID __maybe_unused * surface_list /* out */
717 )
718 {
719 return VA_STATUS_ERROR_UNIMPLEMENTED;
720 }
721
psb_CreateSurfaces2(VADriverContextP ctx,unsigned int format,unsigned int width,unsigned int height,VASurfaceID * surface_list,unsigned int num_surfaces,VASurfaceAttrib * attrib_list,unsigned int num_attribs)722 VAStatus psb_CreateSurfaces2(
723 VADriverContextP ctx,
724 unsigned int format,
725 unsigned int width,
726 unsigned int height,
727 VASurfaceID *surface_list, /* out */
728 unsigned int num_surfaces,
729 VASurfaceAttrib *attrib_list,
730 unsigned int num_attribs
731 )
732 {
733 DEBUG_FUNC_ENTER
734 INIT_DRIVER_DATA
735 VAStatus vaStatus = VA_STATUS_SUCCESS;
736 unsigned int i;
737 int height_origin, buffer_stride = 0;
738 driver_data->protected = (VA_RT_FORMAT_PROTECTED & format);
739 unsigned long fourcc;
740 unsigned int flags = 0;
741 int memory_type = -1;
742 unsigned int initalized_info_flag = 1;
743 VASurfaceAttribExternalBuffers *pExternalBufDesc = NULL;
744 PsbSurfaceAttributeTPI attribute_tpi;
745
746 CHECK_INVALID_PARAM(num_surfaces <= 0);
747 CHECK_SURFACE(surface_list);
748
749 if ((attrib_list != NULL) && (num_attribs > 0)) {
750 for (i = 0; i < num_attribs; i++, attrib_list++) {
751 if (!attrib_list)
752 return VA_STATUS_ERROR_INVALID_PARAMETER;
753 switch (attrib_list->type) {
754 case VASurfaceAttribExternalBufferDescriptor:
755 {
756 pExternalBufDesc = (VASurfaceAttribExternalBuffers *)attrib_list->value.value.p;
757 if (pExternalBufDesc == NULL) {
758 drv_debug_msg(VIDEO_DEBUG_ERROR, "Invalid VASurfaceAttribExternalBuffers.\n");
759 return VA_STATUS_ERROR_INVALID_PARAMETER;
760 }
761 attribute_tpi.type = memory_type;
762 attribute_tpi.buffers = malloc(sizeof(long) * pExternalBufDesc->num_buffers);
763 attribute_tpi.width = pExternalBufDesc->width;
764 attribute_tpi.height = pExternalBufDesc->height;
765 attribute_tpi.count = pExternalBufDesc->num_buffers;
766 memcpy((void*)attribute_tpi.buffers, (void*)pExternalBufDesc->buffers,
767 sizeof(pExternalBufDesc->buffers[0]) *
768 pExternalBufDesc->num_buffers);
769 attribute_tpi.pixel_format = pExternalBufDesc->pixel_format;
770 attribute_tpi.size = pExternalBufDesc->data_size;
771 attribute_tpi.luma_stride = pExternalBufDesc->pitches[0];
772 attribute_tpi.chroma_u_stride = pExternalBufDesc->pitches[1];
773 attribute_tpi.chroma_v_stride = pExternalBufDesc->pitches[2];
774 attribute_tpi.luma_offset = pExternalBufDesc->offsets[0];
775 attribute_tpi.chroma_u_offset = pExternalBufDesc->offsets[1];
776 attribute_tpi.chroma_v_offset = pExternalBufDesc->offsets[2];
777 attribute_tpi.reserved[0] = (unsigned long) pExternalBufDesc->private_data;
778 if (pExternalBufDesc->flags & VA_SURFACE_EXTBUF_DESC_ENABLE_TILING)
779 attribute_tpi.tiling = 1;
780 else
781 attribute_tpi.tiling = 0;
782 }
783 break;
784 case VASurfaceAttribMemoryType:
785 {
786 switch (attrib_list->value.value.i) {
787 case VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR:
788 memory_type = VAExternalMemoryUserPointer;
789 break;
790 case VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM:
791 memory_type = VAExternalMemoryKernelDRMBufffer;
792 break;
793 case VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC:
794 memory_type = VAExternalMemoryAndroidGrallocBuffer;
795 break;
796 case VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_ION:
797 memory_type = VAExternalMemoryIONSharedFD;
798 break;
799 case VA_SURFACE_ATTRIB_MEM_TYPE_VA:
800 memory_type = VAExternalMemoryNULL;
801 break;
802 default:
803 drv_debug_msg(VIDEO_DEBUG_ERROR, "Unsupported memory type.\n");
804 return VA_STATUS_ERROR_INVALID_PARAMETER;
805
806 }
807 }
808 break;
809 case VASurfaceAttribUsageHint:
810 {
811 /* Share info is to be initialized when created sufaces by default (for the data producer)
812 * VPP Read indicate we do not NOT touch share info (for data consumer, which share buffer with data
813 * producer, such as of VPP).
814 */
815 drv_debug_msg(VIDEO_DEBUG_GENERAL, "VASurfaceAttribUsageHint.\n");
816 if ((attrib_list->value.value.i & VA_SURFACE_ATTRIB_USAGE_HINT_VPP_READ)!= 0){
817 initalized_info_flag = 0;
818 drv_debug_msg(VIDEO_DEBUG_GENERAL, "explicat not initialized share info.\n");
819 }
820 }
821 break;
822 default:
823 drv_debug_msg(VIDEO_DEBUG_ERROR, "Unsupported attribute.\n");
824 return VA_STATUS_ERROR_INVALID_PARAMETER;
825 }
826 }
827 }
828
829 if ((memory_type == -1 && pExternalBufDesc != NULL) ||
830 (memory_type != -1 && pExternalBufDesc == NULL)) {
831 return VA_STATUS_ERROR_INVALID_PARAMETER;
832 }
833 else if(memory_type !=-1 && pExternalBufDesc != NULL) {
834 attribute_tpi.type = memory_type;
835 //set initialized share info in reserverd 1, by default we will initialized share_info
836 attribute_tpi.reserved[2] = (unsigned int)initalized_info_flag;
837 vaStatus = psb_CreateSurfacesWithAttribute(ctx, width, height, format, num_surfaces, surface_list, (VASurfaceAttributeTPI *)&attribute_tpi);
838 pExternalBufDesc->private_data = (void *)(attribute_tpi.reserved[1]);
839 if (attribute_tpi.buffers) free(attribute_tpi.buffers);
840 return vaStatus;
841 }
842
843 format = format & (~VA_RT_FORMAT_PROTECTED);
844
845 /* We only support one format */
846 if ((VA_RT_FORMAT_YUV420 != format)
847 && (VA_RT_FORMAT_YUV422 != format)
848 && (VA_RT_FORMAT_YUV444 != format)) {
849 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
850 DEBUG_FAILURE;
851 return vaStatus;
852 }
853
854 vaStatus = psb__checkSurfaceDimensions(driver_data, width, height);
855 CHECK_VASTATUS();
856
857 /* Adjust height to be a multiple of 32 (height of macroblock in interlaced mode) */
858 height_origin = height;
859 height = (height + 0x1f) & ~0x1f;
860
861
862 for (i = 0; i < num_surfaces; i++) {
863 int surfaceID;
864 object_surface_p obj_surface;
865 psb_surface_p psb_surface;
866
867 surfaceID = object_heap_allocate(&driver_data->surface_heap);
868 obj_surface = SURFACE(surfaceID);
869 if (NULL == obj_surface) {
870 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
871 DEBUG_FAILURE;
872 break;
873 }
874 MEMSET_OBJECT(obj_surface, struct object_surface_s);
875
876 obj_surface->surface_id = surfaceID;
877 surface_list[i] = surfaceID;
878 obj_surface->context_id = -1;
879 obj_surface->width = width;
880 obj_surface->height = height;
881 obj_surface->width_r = width;
882 obj_surface->height_r = height;
883 obj_surface->height_origin = height_origin;
884 obj_surface->share_info = NULL;
885
886 psb_surface = (psb_surface_p) calloc(1, sizeof(struct psb_surface_s));
887 if (NULL == psb_surface) {
888 object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
889 obj_surface->surface_id = VA_INVALID_SURFACE;
890 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
891 DEBUG_FAILURE;
892 break;
893 }
894
895 switch (format) {
896 case VA_RT_FORMAT_YUV444:
897 fourcc = VA_FOURCC_YV32; /* allocate 4 planar */
898 break;
899 case VA_RT_FORMAT_YUV422:
900 fourcc = VA_FOURCC_YV16;
901 break;
902 case VA_RT_FORMAT_YUV420:
903 default:
904 fourcc = VA_FOURCC_NV12;
905 break;
906 }
907
908 flags |= driver_data->protected ? IS_PROTECTED : 0;
909 vaStatus = psb_surface_create(driver_data, width, height, fourcc,
910 flags, psb_surface);
911
912 if (VA_STATUS_SUCCESS != vaStatus) {
913 free(psb_surface);
914 object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
915 obj_surface->surface_id = VA_INVALID_SURFACE;
916 DEBUG_FAILURE;
917 break;
918 }
919 buffer_stride = psb_surface->stride;
920 /* by default, surface fourcc is NV12 */
921 psb_surface->extra_info[4] = fourcc;
922 psb_surface->extra_info[8] = fourcc;
923 obj_surface->psb_surface = psb_surface;
924 }
925
926 /* Error recovery */
927 if (VA_STATUS_SUCCESS != vaStatus) {
928 /* surface_list[i-1] was the last successful allocation */
929 for (; i--;) {
930 object_surface_p obj_surface = SURFACE(surface_list[i]);
931 psb__destroy_surface(driver_data, obj_surface);
932 surface_list[i] = VA_INVALID_SURFACE;
933 }
934 drv_debug_msg(VIDEO_DEBUG_ERROR, "CreateSurfaces failed\n");
935 return vaStatus;
936 }
937 DEBUG_FUNC_EXIT
938 return vaStatus;
939 }
940
psb_DestroySurfaces(VADriverContextP ctx,VASurfaceID * surface_list,int num_surfaces)941 VAStatus psb_DestroySurfaces(
942 VADriverContextP ctx,
943 VASurfaceID *surface_list,
944 int num_surfaces
945 )
946 {
947 INIT_DRIVER_DATA
948 int i, j;
949 object_context_p obj_context = NULL;
950 VAStatus vaStatus = VA_STATUS_SUCCESS;
951
952 if (num_surfaces <= 0) {
953 return VA_STATUS_ERROR_INVALID_PARAMETER;
954 }
955
956 CHECK_SURFACE(surface_list);
957
958 #if 0
959 /* Free PVR2D buffer wrapped from the surfaces */
960 psb_free_surface_pvr2dbuf(driver_data);
961 #endif
962
963 /* Make validation happy */
964 for (i = 0; i < num_surfaces; i++) {
965 object_surface_p obj_surface = SURFACE(surface_list[i]);
966 if (obj_surface == NULL) {
967 return VA_STATUS_ERROR_INVALID_SURFACE;
968 }
969 if (obj_surface->derived_imgcnt > 0) {
970 drv_debug_msg(VIDEO_DEBUG_ERROR, "Some surface is deriving by images\n");
971 return VA_STATUS_ERROR_OPERATION_FAILED;
972 }
973 }
974
975 for (i = 0; i < num_surfaces; i++) {
976 object_surface_p obj_surface = SURFACE(surface_list[i]);
977 if (obj_surface == NULL)
978 return VA_STATUS_ERROR_INVALID_SURFACE;
979
980 if (driver_data->cur_displaying_surface == surface_list[i]) {
981 /* Surface is being displaying. Need to stop overlay here */
982 psb_coverlay_stop(ctx);
983 }
984
985 obj_context = CONTEXT(obj_surface->context_id);
986 if (obj_context != NULL) {
987 for (j = 0; j < obj_context->num_render_targets; j++) {
988 if (obj_context->render_targets[j] == obj_surface->surface_id) {
989 obj_context->render_targets[j] = VA_INVALID_SURFACE;
990 break;
991 }
992 }
993 }
994
995 drv_debug_msg(VIDEO_DEBUG_INIT, "%s : obj_surface->surface_id = 0x%x\n",__FUNCTION__, obj_surface->surface_id);
996 if (obj_surface->share_info) {
997 psb_DestroySurfaceGralloc(obj_surface);
998 }
999 psb__destroy_surface(driver_data, obj_surface);
1000 surface_list[i] = VA_INVALID_SURFACE;
1001 }
1002
1003 DEBUG_FUNC_EXIT
1004 return VA_STATUS_SUCCESS;
1005 }
1006
psb_new_context(psb_driver_data_p driver_data,uint64_t ctx_type)1007 int psb_new_context(psb_driver_data_p driver_data, uint64_t ctx_type)
1008 {
1009 struct drm_lnc_video_getparam_arg arg;
1010 int ret = 0;
1011
1012 arg.key = IMG_VIDEO_NEW_CONTEXT;
1013 arg.value = (uint64_t)((unsigned long) & ctx_type);
1014 ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset,
1015 &arg, sizeof(arg));
1016 if (ret != 0)
1017 drv_debug_msg(VIDEO_DEBUG_ERROR, "Set context %d failed\n", ctx_type);
1018
1019 return ret;
1020 }
1021
1022 #ifdef PSBVIDEO_MSVDX_DEC_TILING
psb_update_context(psb_driver_data_p driver_data,unsigned long ctx_type)1023 int psb_update_context(psb_driver_data_p driver_data, unsigned long ctx_type)
1024 {
1025 struct drm_lnc_video_getparam_arg arg;
1026 int ret = 0;
1027
1028 arg.key = IMG_VIDEO_UPDATE_CONTEXT;
1029 arg.value = (uint64_t)((unsigned long) & ctx_type);
1030 ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset,
1031 &arg, sizeof(arg));
1032 if (ret != 0)
1033 drv_debug_msg(VIDEO_DEBUG_ERROR, "Update context %d failed\n", ctx_type);
1034
1035 return ret;
1036 }
1037 #endif
1038
psb_rm_context(psb_driver_data_p driver_data)1039 int psb_rm_context(psb_driver_data_p driver_data)
1040 {
1041 struct drm_lnc_video_getparam_arg arg;
1042 int tmp;
1043 int ret = 0;
1044
1045 arg.key = IMG_VIDEO_RM_CONTEXT;
1046 arg.value = (uint64_t)((unsigned long) & tmp); /* value is ignored */
1047 ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset,
1048 &arg, sizeof(arg));
1049 if (ret != 0)
1050 drv_debug_msg(VIDEO_DEBUG_ERROR, "Remove context failed\n");
1051
1052 return ret;
1053 }
1054
psb_CreateContext(VADriverContextP ctx,VAConfigID config_id,int picture_width,int picture_height,int flag,VASurfaceID * render_targets,int num_render_targets,VAContextID * context)1055 VAStatus psb_CreateContext(
1056 VADriverContextP ctx,
1057 VAConfigID config_id,
1058 int picture_width,
1059 int picture_height,
1060 int flag,
1061 VASurfaceID *render_targets,
1062 int num_render_targets,
1063 VAContextID *context /* out */
1064 )
1065 {
1066 DEBUG_FUNC_ENTER
1067 INIT_DRIVER_DATA
1068 VAStatus vaStatus = VA_STATUS_SUCCESS;
1069 object_config_p obj_config;
1070 int cmdbuf_num, encode = 0, proc = 0;
1071 int i;
1072 drv_debug_msg(VIDEO_DEBUG_ERROR, "CreateContext config_id:%d, pic_w:%d, pic_h:%d, flag:%d, num_render_targets:%d, render_targets: %p.\n",
1073 config_id, picture_width, picture_height, flag, num_render_targets, render_targets);
1074
1075 CHECK_INVALID_PARAM(num_render_targets < 0);
1076
1077 //CHECK_SURFACE(render_targets);
1078 CHECK_CONTEXT(context);
1079
1080 vaStatus = psb__checkSurfaceDimensions(driver_data, picture_width, picture_height);
1081 CHECK_VASTATUS();
1082
1083 obj_config = CONFIG(config_id);
1084 CHECK_CONFIG(obj_config);
1085
1086 int contextID = object_heap_allocate(&driver_data->context_heap);
1087 object_context_p obj_context = CONTEXT(contextID);
1088 CHECK_ALLOCATION(obj_context);
1089
1090 *context = contextID;
1091
1092 MEMSET_OBJECT(obj_context, struct object_context_s);
1093
1094 obj_context->driver_data = driver_data;
1095 obj_context->current_render_target = NULL;
1096 obj_context->ec_target = NULL;
1097 obj_context->ec_candidate = NULL;
1098 obj_context->is_oold = driver_data->is_oold;
1099 obj_context->context_id = contextID;
1100 obj_context->config_id = config_id;
1101 obj_context->picture_width = picture_width;
1102 obj_context->picture_height = picture_height;
1103 obj_context->num_render_targets = num_render_targets;
1104 obj_context->msvdx_scaling = 0;
1105 #ifdef SLICE_HEADER_PARSING
1106 obj_context->msvdx_frame_end = 0;
1107 for (i = 0; i < obj_config->attrib_count; i++) {
1108 if ((obj_config->attrib_list[i].type == VAConfigAttribDecSliceMode) &&
1109 (obj_config->attrib_list[i].value == VA_DEC_SLICE_MODE_SUBSAMPLE)) {
1110 obj_context->modular_drm = 1;
1111 break;
1112 }
1113 }
1114 #endif
1115 obj_context->scaling_width = 0;
1116 obj_context->scaling_height = 0;
1117
1118 if (num_render_targets > 0) {
1119 obj_context->render_targets = (VASurfaceID *) calloc(1, num_render_targets * sizeof(VASurfaceID));
1120 if (obj_context->render_targets == NULL) {
1121 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1122 DEBUG_FAILURE;
1123
1124 object_heap_free(&driver_data->context_heap, (object_base_p) obj_context);
1125
1126 return vaStatus;
1127 }
1128 }
1129
1130 /* allocate buffer points for vaRenderPicture */
1131 obj_context->num_buffers = 10;
1132 obj_context->buffer_list = (object_buffer_p *) calloc(1, sizeof(object_buffer_p) * obj_context->num_buffers);
1133 if (obj_context->buffer_list == NULL) {
1134 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1135 DEBUG_FAILURE;
1136
1137 if (NULL != obj_context->render_targets)
1138 free(obj_context->render_targets);
1139 object_heap_free(&driver_data->context_heap, (object_base_p) obj_context);
1140
1141 return vaStatus;
1142 }
1143
1144 memset(obj_context->buffers_unused, 0, sizeof(obj_context->buffers_unused));
1145 memset(obj_context->buffers_unused_count, 0, sizeof(obj_context->buffers_unused_count));
1146 memset(obj_context->buffers_unused_tail, 0, sizeof(obj_context->buffers_unused_tail));
1147 memset(obj_context->buffers_active, 0, sizeof(obj_context->buffers_active));
1148
1149 if (obj_config->entrypoint == VAEntrypointEncSlice
1150 || obj_config->entrypoint == VAEntrypointEncPicture) {
1151 encode = 1;
1152 }
1153 #ifdef PSBVIDEO_MRFL_VPP
1154 if (obj_config->entrypoint == VAEntrypointVideoProc)
1155 proc = 1;
1156
1157 //todo: fixme
1158 if (obj_config->entrypoint == VAEntrypointEncSlice && obj_config->profile == VAProfileVP8Version0_3){
1159 proc = 1;
1160 encode = 0;
1161 }
1162 #endif
1163
1164 if (encode)
1165 cmdbuf_num = LNC_MAX_CMDBUFS_ENCODE;
1166 else if (proc)
1167 cmdbuf_num = VSP_MAX_CMDBUFS;
1168 else
1169 cmdbuf_num = PSB_MAX_CMDBUFS;
1170
1171 if (num_render_targets > 0 && (render_targets != NULL)) {
1172 for (i = 0; i < num_render_targets; i++) {
1173 object_surface_p obj_surface = SURFACE(render_targets[i]);
1174 psb_surface_p psb_surface;
1175
1176 if (NULL == obj_surface) {
1177 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE;
1178 DEBUG_FAILURE;
1179 break;
1180 }
1181
1182 if (!driver_data->protected && obj_surface->share_info)
1183 obj_surface->share_info->force_output_method = 0;
1184
1185 psb_surface = obj_surface->psb_surface;
1186
1187 /* Clear format specific surface info */
1188 obj_context->render_targets[i] = render_targets[i];
1189 obj_surface->context_id = contextID; /* Claim ownership of surface */
1190 #ifdef PSBVIDEO_MSVDX_DEC_TILING
1191 if (GET_SURFACE_INFO_tiling(psb_surface)) {
1192 #ifdef BAYTRAIL
1193 obj_context->msvdx_tile = psb__tile_stride_log2_512(obj_surface->width);
1194 #else
1195 if (obj_config->entrypoint == VAEntrypointVideoProc && obj_config->profile == VAProfileNone)
1196 // It's for two pass rotation case
1197 // Need the source surface width for tile stride setting
1198 obj_context->msvdx_tile = psb__tile_stride_log2_256(obj_context->picture_width);
1199 else
1200 obj_context->msvdx_tile = psb__tile_stride_log2_256(obj_surface->width);
1201 #endif
1202 }
1203 #endif
1204 #if 0
1205 /* for decode, move the surface into |TT */
1206 if ((encode == 0) && /* decode */
1207 ((psb_surface->buf.pl_flags & DRM_PSB_FLAG_MEM_RAR) == 0)) /* surface not in RAR */
1208 psb_buffer_setstatus(&obj_surface->psb_surface->buf,
1209 WSBM_PL_FLAG_TT | WSBM_PL_FLAG_SHARED, DRM_PSB_FLAG_MEM_MMU);
1210 #endif
1211 }
1212 } else if (num_render_targets > 0) {
1213 for (i = 0; i < num_render_targets; i++) {
1214 obj_context->render_targets[i] = VA_INVALID_SURFACE;
1215 }
1216 }
1217
1218 obj_context->va_flags = flag;
1219 obj_context->format_vtable = obj_config->format_vtable;
1220 obj_context->format_data = NULL;
1221
1222 if (VA_STATUS_SUCCESS == vaStatus) {
1223 vaStatus = obj_context->format_vtable->createContext(obj_context, obj_config);
1224 }
1225
1226 /* Error recovery */
1227 if (VA_STATUS_SUCCESS != vaStatus) {
1228 obj_context->context_id = -1;
1229 obj_context->config_id = -1;
1230 obj_context->picture_width = 0;
1231 obj_context->picture_height = 0;
1232 if (NULL != obj_context->render_targets)
1233 free(obj_context->render_targets);
1234 free(obj_context->buffer_list);
1235 obj_context->num_buffers = 0;
1236 obj_context->render_targets = NULL;
1237 obj_context->num_render_targets = 0;
1238 obj_context->va_flags = 0;
1239 object_heap_free(&driver_data->context_heap, (object_base_p) obj_context);
1240
1241 return vaStatus;
1242 }
1243
1244 /* initialize cmdbuf */
1245 for (i = 0; i < PNW_MAX_CMDBUFS_ENCODE; i++) {
1246 obj_context->pnw_cmdbuf_list[i] = NULL;
1247 }
1248
1249 #ifdef PSBVIDEO_MRFL
1250 for (i = 0; i < TNG_MAX_CMDBUFS_ENCODE; i++) {
1251 obj_context->tng_cmdbuf_list[i] = NULL;
1252 }
1253 #endif
1254
1255 #ifdef PSBVIDEO_MRFL_VPP
1256 for (i = 0; i < VSP_MAX_CMDBUFS; i++) {
1257 obj_context->vsp_cmdbuf_list[i] = NULL;
1258 }
1259 #endif
1260
1261 for (i = 0; i < PSB_MAX_CMDBUFS; i++) {
1262 obj_context->cmdbuf_list[i] = NULL;
1263 }
1264
1265 for (i = 0; i < cmdbuf_num; i++) {
1266 void *cmdbuf = NULL;
1267 #ifndef BAYTRAIL
1268 if (encode) { /* Topaz encode context */
1269 #ifdef PSBVIDEO_MRFL
1270 if (IS_MRFL(obj_context->driver_data))
1271 cmdbuf = calloc(1, sizeof(struct tng_cmdbuf_s));
1272 #endif
1273 #ifdef PSBVIDEO_MFLD
1274 if (IS_MFLD(obj_context->driver_data))
1275 cmdbuf = calloc(1, sizeof(struct pnw_cmdbuf_s));
1276 #endif
1277 } else if (proc) { /* VSP VPP context */
1278 /* VED two pass rotation under VPP API */
1279 if (driver_data->ved_vpp)
1280 cmdbuf = calloc(1, sizeof(struct psb_cmdbuf_s));
1281 #ifdef PSBVIDEO_MRFL_VPP
1282 else if (IS_MRFL(obj_context->driver_data))
1283 cmdbuf = calloc(1, sizeof(struct vsp_cmdbuf_s));
1284 #endif
1285 } else /* MSVDX decode context */
1286 #endif
1287 cmdbuf = calloc(1, sizeof(struct psb_cmdbuf_s));
1288
1289 if (NULL == cmdbuf) {
1290 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1291 DEBUG_FAILURE;
1292 break;
1293 }
1294
1295 #ifndef BAYTRAIL
1296 if (encode) { /* Topaz encode context */
1297
1298 #ifdef PSBVIDEO_MRFL
1299 if (IS_MRFL(obj_context->driver_data))
1300 vaStatus = tng_cmdbuf_create(obj_context, driver_data, (tng_cmdbuf_p)cmdbuf);
1301 #endif
1302 #ifdef PSBVIDEO_MFLD
1303 if (IS_MFLD(obj_context->driver_data))
1304 vaStatus = pnw_cmdbuf_create(obj_context, driver_data, (pnw_cmdbuf_p)cmdbuf);
1305 #endif
1306 } else if (proc) { /* VSP VPP context */
1307 if (driver_data->ved_vpp)
1308 vaStatus = psb_cmdbuf_create(obj_context, driver_data, (psb_cmdbuf_p)cmdbuf);
1309 #ifdef PSBVIDEO_MRFL_VPP
1310 else if (IS_MRFL(obj_context->driver_data))
1311 vaStatus = vsp_cmdbuf_create(obj_context, driver_data, (vsp_cmdbuf_p)cmdbuf);
1312 #endif
1313 } else /* MSVDX decode context */
1314 #endif
1315 vaStatus = psb_cmdbuf_create(obj_context, driver_data, (psb_cmdbuf_p)cmdbuf);
1316
1317 if (VA_STATUS_SUCCESS != vaStatus) {
1318 free(cmdbuf);
1319 DEBUG_FAILURE;
1320 break;
1321 }
1322
1323 #ifndef BAYTRAIL
1324 if (encode) { /* Topaz encode context */
1325 if (i >= LNC_MAX_CMDBUFS_ENCODE) {
1326 free(cmdbuf);
1327 DEBUG_FAILURE;
1328 break;
1329 }
1330
1331 #ifdef PSBVIDEO_MRFL
1332 if (IS_MRFL(obj_context->driver_data))
1333 obj_context->tng_cmdbuf_list[i] = (tng_cmdbuf_p)cmdbuf;
1334 #endif
1335 #ifdef PSBVIDEO_MFLD
1336 if (IS_MFLD(obj_context->driver_data))
1337 obj_context->pnw_cmdbuf_list[i] = (pnw_cmdbuf_p)cmdbuf;
1338 #endif
1339 } else if (proc) { /* VSP VPP context */
1340 if (driver_data->ved_vpp)
1341 obj_context->cmdbuf_list[i] = (psb_cmdbuf_p)cmdbuf;
1342 #ifdef PSBVIDEO_MRFL_VPP
1343 else if (IS_MRFL(obj_context->driver_data))
1344 obj_context->vsp_cmdbuf_list[i] = (vsp_cmdbuf_p)cmdbuf;
1345 #endif
1346 } else /* MSVDX decode context */
1347 #endif
1348 obj_context->cmdbuf_list[i] = (psb_cmdbuf_p)cmdbuf;
1349 }
1350
1351 obj_context->cmdbuf_current = -1;
1352 obj_context->cmdbuf = NULL;
1353 obj_context->pnw_cmdbuf = NULL;
1354 obj_context->tng_cmdbuf = NULL;
1355 #ifdef PSBVIDEO_MRFL_VPP
1356 obj_context->vsp_cmdbuf = NULL;
1357 #endif
1358 obj_context->frame_count = 0;
1359 obj_context->slice_count = 0;
1360 obj_context->msvdx_context = ((driver_data->msvdx_context_base & 0xff0000) >> 16) |
1361 ((contextID & 0xff000000) >> 16);
1362 #ifdef ANDROID
1363 obj_context->msvdx_context = ((driver_data->drm_fd & 0xf) << 4) |
1364 ((unsigned int)gettid() & 0xf);
1365 #endif
1366 obj_context->profile = obj_config->profile;
1367 obj_context->entry_point = obj_config->entrypoint;
1368
1369 /* Error recovery */
1370 if (VA_STATUS_SUCCESS != vaStatus) {
1371 if (cmdbuf_num > LNC_MAX_CMDBUFS_ENCODE)
1372 cmdbuf_num = LNC_MAX_CMDBUFS_ENCODE;
1373 for (i = 0; i < cmdbuf_num; i++) {
1374 #ifndef BAYTRAIL
1375 if (obj_context->pnw_cmdbuf_list[i]) {
1376 pnw_cmdbuf_destroy(obj_context->pnw_cmdbuf_list[i]);
1377 free(obj_context->pnw_cmdbuf_list[i]);
1378 obj_context->pnw_cmdbuf_list[i] = NULL;
1379 }
1380 #endif
1381 #ifdef PSBVIDEO_MRFL
1382 if (obj_context->tng_cmdbuf_list[i]) {
1383 tng_cmdbuf_destroy(obj_context->tng_cmdbuf_list[i]);
1384 free(obj_context->tng_cmdbuf_list[i]);
1385 obj_context->tng_cmdbuf_list[i] = NULL;
1386 }
1387 #endif
1388 if (obj_context->cmdbuf_list[i]) {
1389 psb_cmdbuf_destroy(obj_context->cmdbuf_list[i]);
1390 free(obj_context->cmdbuf_list[i]);
1391 obj_context->cmdbuf_list[i] = NULL;
1392 }
1393 #ifdef PSBVIDEO_MRFL_VPP
1394 if (obj_context->vsp_cmdbuf_list[i]) {
1395 vsp_cmdbuf_destroy(obj_context->vsp_cmdbuf_list[i]);
1396 free(obj_context->vsp_cmdbuf_list[i]);
1397 obj_context->vsp_cmdbuf_list[i] = NULL;
1398 }
1399 #endif
1400 }
1401
1402 obj_context->cmdbuf = NULL;
1403 #ifdef PSBVIDEO_MRFL_VPP
1404 obj_context->vsp_cmdbuf = NULL;
1405 #endif
1406
1407 obj_context->context_id = -1;
1408 obj_context->config_id = -1;
1409 obj_context->picture_width = 0;
1410 obj_context->picture_height = 0;
1411 if (NULL != obj_context->render_targets)
1412 free(obj_context->render_targets);
1413 free(obj_context->buffer_list);
1414 obj_context->num_buffers = 0;
1415 obj_context->render_targets = NULL;
1416 obj_context->num_render_targets = 0;
1417 obj_context->va_flags = 0;
1418 object_heap_free(&driver_data->context_heap, (object_base_p) obj_context);
1419 }
1420 obj_context->ctp_type = (((obj_config->profile << 8) |
1421 obj_config->entrypoint | driver_data->protected) & 0xffff);
1422
1423 /* VSP's PM rely on VPP ctx, so ved vpp use diferent profile/level for ctx */
1424 if (driver_data->ved_vpp)
1425 obj_context->ctp_type = (((obj_config->profile << 8) |
1426 VAEntrypointVLD | driver_data->protected) & 0xffff);
1427
1428 if (!encode) {
1429 obj_context->ctp_type |= ((obj_context->msvdx_tile & 0xff) << 16);
1430 }
1431
1432 if (obj_context->ctp_type & VAEntrypointVLD) {
1433 if (render_targets == NULL) {
1434 obj_context->ctp_type |= PSB_SURFACE_UNAVAILABLE;
1435 }
1436 }
1437
1438 if (obj_context->ctp_type & VAEntrypointVLD) {
1439 if (render_targets == NULL) {
1440 obj_context->ctp_type |= PSB_SURFACE_UNAVAILABLE;
1441 }
1442 }
1443
1444 if (obj_config->profile == VAProfileVC1Simple ||
1445 obj_config->profile == VAProfileVC1Main ||
1446 obj_config->profile == VAProfileVC1Advanced) {
1447 uint64_t width_in_mb = ((driver_data->render_rect.x + driver_data->render_rect.width + 15) / 16);
1448 obj_context->ctp_type |= (width_in_mb << 32);
1449 }
1450
1451 /* add ctx_num to save vp8 enc context num to support dual vp8 encoding */
1452 int ret = psb_new_context(driver_data, obj_context->ctp_type | driver_data->protected);
1453 if (ret)
1454 vaStatus = VA_STATUS_ERROR_UNKNOWN;
1455
1456 DEBUG_FUNC_EXIT
1457 return vaStatus;
1458 }
1459
psb__allocate_malloc_buffer(object_buffer_p obj_buffer,int size)1460 static VAStatus psb__allocate_malloc_buffer(object_buffer_p obj_buffer, int size)
1461 {
1462 VAStatus vaStatus = VA_STATUS_SUCCESS;
1463
1464 obj_buffer->buffer_data = realloc(obj_buffer->buffer_data, size);
1465 CHECK_ALLOCATION(obj_buffer->buffer_data);
1466
1467 return vaStatus;
1468 }
1469
1470 static VAStatus psb__unmap_buffer(object_buffer_p obj_buffer);
1471
psb__allocate_BO_buffer(psb_driver_data_p driver_data,object_context_p __maybe_unused obj_context,object_buffer_p obj_buffer,int size,unsigned char * data,VABufferType type)1472 static VAStatus psb__allocate_BO_buffer(psb_driver_data_p driver_data, object_context_p __maybe_unused obj_context, object_buffer_p obj_buffer, int size, unsigned char *data, VABufferType type)
1473 {
1474 VAStatus vaStatus = VA_STATUS_SUCCESS;
1475
1476 ASSERT(NULL == obj_buffer->buffer_data);
1477
1478 if (obj_buffer->psb_buffer && (psb_bs_queued == obj_buffer->psb_buffer->status)) {
1479 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Abandoning BO for buffer %08x type %s\n", obj_buffer->base.id,
1480 buffer_type_to_string(obj_buffer->type));
1481 /* need to set psb_buffer aside and get another one */
1482 obj_buffer->psb_buffer->status = psb_bs_abandoned;
1483 obj_buffer->psb_buffer = NULL;
1484 obj_buffer->size = 0;
1485 obj_buffer->alloc_size = 0;
1486 }
1487
1488 if (type == VAProtectedSliceDataBufferType) {
1489 if (obj_buffer->psb_buffer) {
1490 drv_debug_msg(VIDEO_DEBUG_GENERAL, "RAR: old RAR slice buffer with RAR handle 0%08x, current RAR handle 0x%08x\n",
1491 obj_buffer->psb_buffer->rar_handle, (uint32_t)data);
1492 drv_debug_msg(VIDEO_DEBUG_GENERAL, "RAR: force old RAR buffer destroy and new buffer re-allocation by set size=0\n");
1493 obj_buffer->alloc_size = 0;
1494 }
1495 }
1496
1497 if (obj_buffer->alloc_size < (unsigned int)size) {
1498 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Buffer size mismatch: Need %d, currently have %d\n", size, obj_buffer->alloc_size);
1499 if (obj_buffer->psb_buffer) {
1500 if (obj_buffer->buffer_data) {
1501 psb__unmap_buffer(obj_buffer);
1502 }
1503 psb_buffer_destroy(obj_buffer->psb_buffer);
1504 obj_buffer->alloc_size = 0;
1505 } else {
1506 obj_buffer->psb_buffer = (psb_buffer_p) calloc(1, sizeof(struct psb_buffer_s));
1507 if (NULL == obj_buffer->psb_buffer) {
1508 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1509 DEBUG_FAILURE;
1510 }
1511 }
1512 if (VA_STATUS_SUCCESS == vaStatus) {
1513 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Allocate new GPU buffers for vaCreateBuffer:type=%s,size=%d.\n",
1514 buffer_type_to_string(obj_buffer->type), size);
1515
1516 size = (size + 0x7fff) & ~0x7fff; /* Round up */
1517 if (obj_buffer->type == VAImageBufferType) /* Xserver side PutSurface, Image/subpicture buffer
1518 * should be shared between two process
1519 */
1520 vaStatus = psb_buffer_create(driver_data, size, psb_bt_cpu_vpu_shared, obj_buffer->psb_buffer);
1521 #ifndef BAYTRAIL
1522 else if (obj_buffer->type == VAProtectedSliceDataBufferType) {
1523 vaStatus = psb_buffer_reference_imr(driver_data, (uint32_t)data, obj_buffer->psb_buffer);
1524 }
1525 #endif
1526 else if (obj_buffer->type == VAEncCodedBufferType)
1527 vaStatus = psb_buffer_create(driver_data, size, psb_bt_cpu_vpu, obj_buffer->psb_buffer);
1528 else
1529 vaStatus = psb_buffer_create(driver_data, size, psb_bt_cpu_vpu, obj_buffer->psb_buffer);
1530
1531 if (VA_STATUS_SUCCESS != vaStatus) {
1532 free(obj_buffer->psb_buffer);
1533 obj_buffer->psb_buffer = NULL;
1534 DEBUG_FAILURE;
1535 } else {
1536 obj_buffer->alloc_size = size;
1537 }
1538 }
1539 }
1540 return vaStatus;
1541 }
1542
psb__map_buffer(object_buffer_p obj_buffer)1543 static VAStatus psb__map_buffer(object_buffer_p obj_buffer)
1544 {
1545 if (obj_buffer->psb_buffer) {
1546 return psb_buffer_map(obj_buffer->psb_buffer, &obj_buffer->buffer_data);
1547 }
1548 return VA_STATUS_SUCCESS;
1549 }
1550
psb__unmap_buffer(object_buffer_p obj_buffer)1551 static VAStatus psb__unmap_buffer(object_buffer_p obj_buffer)
1552 {
1553 if (obj_buffer->psb_buffer) {
1554 obj_buffer->buffer_data = NULL;
1555 return psb_buffer_unmap(obj_buffer->psb_buffer);
1556 }
1557 return VA_STATUS_SUCCESS;
1558 }
1559
psb__destroy_buffer(psb_driver_data_p driver_data,object_buffer_p obj_buffer)1560 static void psb__destroy_buffer(psb_driver_data_p driver_data, object_buffer_p obj_buffer)
1561 {
1562 if (obj_buffer->psb_buffer) {
1563 if (obj_buffer->buffer_data) {
1564 psb__unmap_buffer(obj_buffer);
1565 }
1566 psb_buffer_destroy(obj_buffer->psb_buffer);
1567 free(obj_buffer->psb_buffer);
1568 obj_buffer->psb_buffer = NULL;
1569 }
1570
1571 if (NULL != obj_buffer->buffer_data) {
1572 free(obj_buffer->buffer_data);
1573 obj_buffer->buffer_data = NULL;
1574 obj_buffer->size = 0;
1575 }
1576
1577 object_heap_free(&driver_data->buffer_heap, (object_base_p) obj_buffer);
1578 }
1579
psb__suspend_buffer(psb_driver_data_p driver_data,object_buffer_p obj_buffer)1580 void psb__suspend_buffer(psb_driver_data_p driver_data, object_buffer_p obj_buffer)
1581 {
1582 if (obj_buffer->context) {
1583 VABufferType type = obj_buffer->type;
1584 object_context_p obj_context = obj_buffer->context;
1585
1586 if (type >= PSB_MAX_BUFFERTYPES) {
1587 drv_debug_msg(VIDEO_DEBUG_ERROR, "Invalid buffer type %d\n", type);
1588 return;
1589 }
1590
1591 /* Remove buffer from active list */
1592 *obj_buffer->pptr_prev_next = obj_buffer->ptr_next;
1593
1594 /* Add buffer to tail of unused list */
1595 obj_buffer->ptr_next = NULL;
1596 obj_buffer->last_used = obj_context->frame_count;
1597 if (obj_context->buffers_unused_tail[type]) {
1598 obj_buffer->pptr_prev_next = &(obj_context->buffers_unused_tail[type]->ptr_next);
1599 } else {
1600 obj_buffer->pptr_prev_next = &(obj_context->buffers_unused[type]);
1601 }
1602 *obj_buffer->pptr_prev_next = obj_buffer;
1603 obj_context->buffers_unused_tail[type] = obj_buffer;
1604 obj_context->buffers_unused_count[type]++;
1605
1606 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Adding buffer %08x type %s to unused list. unused count = %d\n", obj_buffer->base.id,
1607 buffer_type_to_string(obj_buffer->type), obj_context->buffers_unused_count[type]);
1608
1609 object_heap_suspend_object((object_base_p) obj_buffer, 1); /* suspend */
1610 return;
1611 }
1612
1613 if (obj_buffer->psb_buffer && (psb_bs_queued == obj_buffer->psb_buffer->status)) {
1614 /* need to set psb_buffer aside */
1615 obj_buffer->psb_buffer->status = psb_bs_abandoned;
1616 obj_buffer->psb_buffer = NULL;
1617 }
1618
1619 psb__destroy_buffer(driver_data, obj_buffer);
1620 }
1621
psb__destroy_context(psb_driver_data_p driver_data,object_context_p obj_context)1622 static void psb__destroy_context(psb_driver_data_p driver_data, object_context_p obj_context)
1623 {
1624 int encode, i;
1625
1626 if (obj_context->entry_point == VAEntrypointEncSlice)
1627 encode = 1;
1628 else
1629 encode = 0;
1630
1631 obj_context->format_vtable->destroyContext(obj_context);
1632
1633 for (i = 0; i < PSB_MAX_BUFFERTYPES; i++) {
1634 object_buffer_p obj_buffer;
1635 obj_buffer = obj_context->buffers_active[i];
1636 for (; obj_buffer; obj_buffer = obj_buffer->ptr_next) {
1637 drv_debug_msg(VIDEO_DEBUG_INIT, "%s: destroying active buffer %08x\n", __FUNCTION__, obj_buffer->base.id);
1638 psb__destroy_buffer(driver_data, obj_buffer);
1639 }
1640 obj_buffer = obj_context->buffers_unused[i];
1641 for (; obj_buffer; obj_buffer = obj_buffer->ptr_next) {
1642 drv_debug_msg(VIDEO_DEBUG_INIT, "%s: destroying unused buffer %08x\n", __FUNCTION__, obj_buffer->base.id);
1643 psb__destroy_buffer(driver_data, obj_buffer);
1644 }
1645 obj_context->buffers_unused_count[i] = 0;
1646 }
1647 #ifndef BAYTRAIL
1648 for (i = 0; i < LNC_MAX_CMDBUFS_ENCODE; i++) {
1649 if (obj_context->pnw_cmdbuf_list[i]) {
1650 pnw_cmdbuf_destroy(obj_context->pnw_cmdbuf_list[i]);
1651 free(obj_context->pnw_cmdbuf_list[i]);
1652 obj_context->pnw_cmdbuf_list[i] = NULL;
1653 }
1654 }
1655 #endif
1656 #ifdef PSBVIDEO_MRFL
1657 for (i = 0; i < TNG_MAX_CMDBUFS_ENCODE; i++) {
1658 if (obj_context->tng_cmdbuf_list[i]) {
1659 tng_cmdbuf_destroy(obj_context->tng_cmdbuf_list[i]);
1660 free(obj_context->tng_cmdbuf_list[i]);
1661 obj_context->tng_cmdbuf_list[i] = NULL;
1662 }
1663 }
1664 #endif
1665 #ifdef PSBVIDEO_MRFL_VPP
1666 for (i = 0; i < VSP_MAX_CMDBUFS; i++) {
1667 if (obj_context->vsp_cmdbuf_list[i]) {
1668 vsp_cmdbuf_destroy(obj_context->vsp_cmdbuf_list[i]);
1669 free(obj_context->vsp_cmdbuf_list[i]);
1670 obj_context->vsp_cmdbuf_list[i] = NULL;
1671 }
1672 }
1673 #endif
1674
1675 for (i = 0; i < PSB_MAX_CMDBUFS; i++) {
1676 if (obj_context->cmdbuf_list[i]) {
1677 psb_cmdbuf_destroy(obj_context->cmdbuf_list[i]);
1678 free(obj_context->cmdbuf_list[i]);
1679 obj_context->cmdbuf_list[i] = NULL;
1680 }
1681 }
1682 obj_context->cmdbuf = NULL;
1683 #ifdef PSBVIDEO_MRFL_VPP
1684 obj_context->vsp_cmdbuf = NULL;
1685 #endif
1686
1687 obj_context->context_id = -1;
1688 obj_context->config_id = -1;
1689 obj_context->picture_width = 0;
1690 obj_context->picture_height = 0;
1691 if (obj_context->render_targets)
1692 free(obj_context->render_targets);
1693 obj_context->render_targets = NULL;
1694 obj_context->num_render_targets = 0;
1695 obj_context->va_flags = 0;
1696
1697 obj_context->current_render_target = NULL;
1698 obj_context->ec_target = NULL;
1699 obj_context->ec_candidate = NULL;
1700 if (obj_context->buffer_list)
1701 free(obj_context->buffer_list);
1702 obj_context->num_buffers = 0;
1703
1704 object_heap_free(&driver_data->context_heap, (object_base_p) obj_context);
1705
1706 psb_rm_context(driver_data);
1707 }
1708
psb_DestroyContext(VADriverContextP ctx,VAContextID context)1709 VAStatus psb_DestroyContext(
1710 VADriverContextP ctx,
1711 VAContextID context
1712 )
1713 {
1714 DEBUG_FUNC_ENTER
1715 INIT_DRIVER_DATA
1716 VAStatus vaStatus = VA_STATUS_SUCCESS;
1717 object_context_p obj_context = CONTEXT(context);
1718 CHECK_CONTEXT(obj_context);
1719
1720 psb__destroy_context(driver_data, obj_context);
1721
1722 DEBUG_FUNC_EXIT
1723 return vaStatus;
1724 }
1725
psb__CreateBuffer(psb_driver_data_p driver_data,object_context_p obj_context,VABufferType type,unsigned int size,unsigned int num_elements,unsigned char * data,VABufferID * buf_desc)1726 VAStatus psb__CreateBuffer(
1727 psb_driver_data_p driver_data,
1728 object_context_p obj_context, /* in */
1729 VABufferType type, /* in */
1730 unsigned int size, /* in */
1731 unsigned int num_elements, /* in */
1732 unsigned char *data, /* in */
1733 VABufferID *buf_desc /* out */
1734 )
1735 {
1736 DEBUG_FUNC_ENTER
1737 VAStatus vaStatus = VA_STATUS_SUCCESS;
1738 int bufferID;
1739 object_buffer_p obj_buffer;
1740 int unused_count;
1741
1742 /*PSB_MAX_BUFFERTYPES is the size of array buffers_unused*/
1743 if (type >= PSB_MAX_BUFFERTYPES) {
1744 drv_debug_msg(VIDEO_DEBUG_ERROR, "Invalid buffer type %d\n", type);
1745 return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
1746 }
1747
1748
1749 obj_buffer = obj_context ? obj_context->buffers_unused[type] : NULL;
1750 unused_count = obj_context ? obj_context->buffers_unused_count[type] : 0;
1751
1752 /*
1753 * Buffer Management
1754 * For each buffer type, maintain
1755 * - a LRU sorted list of unused buffers
1756 * - a list of active buffers
1757 * We only create a new buffer when
1758 * - no unused buffers are available
1759 * - the last unused buffer is still queued
1760 * - the last unused buffer was used very recently and may still be fenced
1761 * - used recently is defined as within the current frame_count (subject to tweaks)
1762 *
1763 * The buffer that is returned will be moved to the list of active buffers
1764 * - vaDestroyBuffer and vaRenderPicture will move the active buffer back to the list of unused buffers
1765 */
1766 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Requesting buffer creation, size=%d,elements=%d,type=%s\n", size, num_elements,
1767 buffer_type_to_string(type));
1768
1769 /* on MFLD, data is IMR offset, and could be 0 */
1770 /*
1771 if ((type == VAProtectedSliceDataBufferType) && (data == NULL)) {
1772 drv_debug_msg(VIDEO_DEBUG_ERROR, "RAR: Create protected slice buffer, but RAR handle is NULL\n");
1773 return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE ;
1774 }
1775 */
1776
1777 if (obj_buffer && obj_buffer->psb_buffer) {
1778 if (psb_bs_queued == obj_buffer->psb_buffer->status) {
1779 /* Buffer is still queued, allocate new buffer instead */
1780 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Skipping idle buffer %08x, still queued\n", obj_buffer->base.id);
1781 obj_buffer = NULL;
1782 } else if ((obj_buffer->last_used == obj_context->frame_count) && (unused_count < MAX_UNUSED_BUFFERS)) {
1783 /* Buffer was used for this frame, allocate new buffer instead */
1784 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Skipping idle buffer %08x, recently used. Unused = %d\n", obj_buffer->base.id, unused_count);
1785 obj_buffer = NULL;
1786 } else if (obj_context->frame_count - obj_buffer->last_used < 5) {
1787 /* Buffer was used for previous frame, allocate new buffer instead */
1788 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Skipping idle buffer %08x used by frame %d. Unused = %d\n", obj_buffer->base.id, obj_buffer->last_used, unused_count);
1789 obj_buffer = NULL;
1790 }
1791 }
1792
1793 if (obj_buffer) {
1794 bufferID = obj_buffer->base.id;
1795 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Reusing buffer %08x type %s from unused list. Unused = %d\n", bufferID,
1796 buffer_type_to_string(type), unused_count);
1797
1798 /* Remove from unused list */
1799 obj_context->buffers_unused[type] = obj_buffer->ptr_next;
1800 if (obj_context->buffers_unused[type]) {
1801 obj_context->buffers_unused[type]->pptr_prev_next = &(obj_context->buffers_unused[type]);
1802 ASSERT(obj_context->buffers_unused_tail[type] != obj_buffer);
1803 } else {
1804 ASSERT(obj_context->buffers_unused_tail[type] == obj_buffer);
1805 obj_context->buffers_unused_tail[type] = 0;
1806 }
1807 obj_context->buffers_unused_count[type]--;
1808
1809 object_heap_suspend_object((object_base_p)obj_buffer, 0); /* Make BufferID valid again */
1810 ASSERT(type == obj_buffer->type);
1811 ASSERT(obj_context == obj_buffer->context);
1812 } else {
1813 bufferID = object_heap_allocate(&driver_data->buffer_heap);
1814 obj_buffer = BUFFER(bufferID);
1815 CHECK_ALLOCATION(obj_buffer);
1816
1817 MEMSET_OBJECT(obj_buffer, struct object_buffer_s);
1818
1819 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Allocating new buffer %08x type %s.\n", bufferID, buffer_type_to_string(type));
1820 obj_buffer->type = type;
1821 obj_buffer->buffer_data = NULL;
1822 obj_buffer->psb_buffer = NULL;
1823 obj_buffer->size = 0;
1824 obj_buffer->max_num_elements = 0;
1825 obj_buffer->alloc_size = 0;
1826 obj_buffer->context = obj_context;
1827 }
1828 if (obj_context) {
1829 /* Add to front of active list */
1830 obj_buffer->ptr_next = obj_context->buffers_active[type];
1831 if (obj_buffer->ptr_next) {
1832 obj_buffer->ptr_next->pptr_prev_next = &(obj_buffer->ptr_next);
1833 }
1834 obj_buffer->pptr_prev_next = &(obj_context->buffers_active[type]);
1835 *obj_buffer->pptr_prev_next = obj_buffer;
1836 }
1837
1838 switch (obj_buffer->type) {
1839 case VABitPlaneBufferType:
1840 case VASliceDataBufferType:
1841 case VAResidualDataBufferType:
1842 case VAImageBufferType:
1843 case VASliceGroupMapBufferType:
1844 case VAEncCodedBufferType:
1845 case VAProtectedSliceDataBufferType:
1846 #ifdef SLICE_HEADER_PARSING
1847 case VAParseSliceHeaderGroupBufferType:
1848 #endif
1849 vaStatus = psb__allocate_BO_buffer(driver_data, obj_context,obj_buffer, size * num_elements, data, obj_buffer->type);
1850 DEBUG_FAILURE;
1851 break;
1852 case VAPictureParameterBufferType:
1853 case VAIQMatrixBufferType:
1854 case VASliceParameterBufferType:
1855 case VAMacroblockParameterBufferType:
1856 case VADeblockingParameterBufferType:
1857 case VAEncPackedHeaderParameterBufferType:
1858 case VAEncPackedHeaderDataBufferType:
1859 case VAEncSequenceParameterBufferType:
1860 case VAEncPictureParameterBufferType:
1861 case VAEncSliceParameterBufferType:
1862 case VAQMatrixBufferType:
1863 case VAEncMiscParameterBufferType:
1864 case VAProbabilityBufferType:
1865 case VAHuffmanTableBufferType:
1866 case VAProcPipelineParameterBufferType:
1867 case VAProcFilterParameterBufferType:
1868 #ifdef SLICE_HEADER_PARSING
1869 case VAParsePictureParameterBufferType:
1870 #endif
1871 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Allocate new malloc buffers for vaCreateBuffer:type=%s,size=%d, buffer_data=%p.\n",
1872 buffer_type_to_string(type), size, obj_buffer->buffer_data);
1873 vaStatus = psb__allocate_malloc_buffer(obj_buffer, size * num_elements);
1874 DEBUG_FAILURE;
1875 break;
1876
1877 default:
1878 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
1879 DEBUG_FAILURE;
1880 break;;
1881 }
1882
1883 if (VA_STATUS_SUCCESS == vaStatus) {
1884 obj_buffer->size = size;
1885 obj_buffer->max_num_elements = num_elements;
1886 obj_buffer->num_elements = num_elements;
1887 if (data && (obj_buffer->type != VAProtectedSliceDataBufferType)) {
1888 vaStatus = psb__map_buffer(obj_buffer);
1889 if (VA_STATUS_SUCCESS == vaStatus) {
1890 memcpy(obj_buffer->buffer_data, data, size * num_elements);
1891
1892 psb__unmap_buffer(obj_buffer);
1893 }
1894 }
1895 }
1896 if (VA_STATUS_SUCCESS == vaStatus) {
1897 *buf_desc = bufferID;
1898 } else {
1899 psb__destroy_buffer(driver_data, obj_buffer);
1900 }
1901
1902 DEBUG_FUNC_EXIT
1903 return vaStatus;
1904 }
1905
psb_CreateBuffer(VADriverContextP ctx,VAContextID context,VABufferType type,unsigned int size,unsigned int num_elements,void * data,VABufferID * buf_desc)1906 VAStatus psb_CreateBuffer(
1907 VADriverContextP ctx,
1908 VAContextID context, /* in */
1909 VABufferType type, /* in */
1910 unsigned int size, /* in */
1911 unsigned int num_elements, /* in */
1912 void *data, /* in */
1913 VABufferID *buf_desc /* out */
1914 )
1915 {
1916 DEBUG_FUNC_ENTER
1917 INIT_DRIVER_DATA
1918 VAStatus vaStatus = VA_STATUS_SUCCESS;
1919
1920 CHECK_INVALID_PARAM(num_elements <= 0);
1921
1922 switch (type) {
1923 case VABitPlaneBufferType:
1924 case VASliceDataBufferType:
1925 case VAProtectedSliceDataBufferType:
1926 case VAResidualDataBufferType:
1927 case VASliceGroupMapBufferType:
1928 case VAPictureParameterBufferType:
1929 case VAIQMatrixBufferType:
1930 case VASliceParameterBufferType:
1931 case VAMacroblockParameterBufferType:
1932 case VADeblockingParameterBufferType:
1933 case VAEncCodedBufferType:
1934 case VAEncSequenceParameterBufferType:
1935 case VAEncPictureParameterBufferType:
1936 case VAEncSliceParameterBufferType:
1937 case VAEncPackedHeaderParameterBufferType:
1938 case VAEncPackedHeaderDataBufferType:
1939 case VAQMatrixBufferType:
1940 case VAEncMiscParameterBufferType:
1941 case VAProbabilityBufferType:
1942 case VAHuffmanTableBufferType:
1943 case VAProcPipelineParameterBufferType:
1944 case VAProcFilterParameterBufferType:
1945 #ifdef SLICE_HEADER_PARSING
1946 case VAParsePictureParameterBufferType:
1947 case VAParseSliceHeaderGroupBufferType:
1948 #endif
1949 break;
1950
1951 default:
1952 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
1953 DEBUG_FAILURE;
1954 return vaStatus;
1955 }
1956
1957 object_context_p obj_context = CONTEXT(context);
1958 CHECK_CONTEXT(obj_context);
1959 CHECK_INVALID_PARAM(buf_desc == NULL);
1960
1961 vaStatus = psb__CreateBuffer(driver_data, obj_context, type, size, num_elements, data, buf_desc);
1962
1963 DEBUG_FUNC_EXIT
1964 return vaStatus;
1965 }
1966
1967
psb_BufferInfo(VADriverContextP ctx,VABufferID buf_id,VABufferType * type,unsigned int * size,unsigned int * num_elements)1968 VAStatus psb_BufferInfo(
1969 VADriverContextP ctx,
1970 VABufferID buf_id, /* in */
1971 VABufferType *type, /* out */
1972 unsigned int *size, /* out */
1973 unsigned int *num_elements /* out */
1974 )
1975 {
1976 DEBUG_FUNC_ENTER
1977 INIT_DRIVER_DATA
1978 VAStatus vaStatus = VA_STATUS_SUCCESS;
1979
1980 object_buffer_p obj_buffer = BUFFER(buf_id);
1981 CHECK_BUFFER(obj_buffer);
1982
1983 *type = obj_buffer->type;
1984 *size = obj_buffer->size;
1985 *num_elements = obj_buffer->num_elements;
1986 DEBUG_FUNC_EXIT
1987 return VA_STATUS_SUCCESS;
1988 }
1989
1990
psb_BufferSetNumElements(VADriverContextP ctx,VABufferID buf_id,unsigned int num_elements)1991 VAStatus psb_BufferSetNumElements(
1992 VADriverContextP ctx,
1993 VABufferID buf_id, /* in */
1994 unsigned int num_elements /* in */
1995 )
1996 {
1997 DEBUG_FUNC_ENTER
1998 INIT_DRIVER_DATA
1999 VAStatus vaStatus = VA_STATUS_SUCCESS;
2000 object_buffer_p obj_buffer = BUFFER(buf_id);
2001 CHECK_BUFFER(obj_buffer);
2002
2003 if ((num_elements <= 0) || (num_elements > obj_buffer->max_num_elements)) {
2004 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
2005 }
2006 if (VA_STATUS_SUCCESS == vaStatus) {
2007 obj_buffer->num_elements = num_elements;
2008 }
2009
2010 DEBUG_FUNC_EXIT
2011 return vaStatus;
2012 }
2013
psb_MapBuffer(VADriverContextP ctx,VABufferID buf_id,void ** pbuf)2014 VAStatus psb_MapBuffer(
2015 VADriverContextP ctx,
2016 VABufferID buf_id, /* in */
2017 void **pbuf /* out */
2018 )
2019 {
2020 DEBUG_FUNC_ENTER
2021 INIT_DRIVER_DATA
2022 VAStatus vaStatus = VA_STATUS_SUCCESS;
2023 object_buffer_p obj_buffer = BUFFER(buf_id);
2024 CHECK_BUFFER(obj_buffer);
2025
2026 CHECK_INVALID_PARAM(pbuf == NULL);
2027
2028 vaStatus = psb__map_buffer(obj_buffer);
2029 CHECK_VASTATUS();
2030
2031 if (NULL != obj_buffer->buffer_data) {
2032 *pbuf = obj_buffer->buffer_data;
2033
2034 /* specifically for Topaz encode
2035 * write validate coded data offset in CodedBuffer
2036 */
2037 if (obj_buffer->type == VAEncCodedBufferType)
2038 psb_codedbuf_map_mangle(ctx, obj_buffer, pbuf);
2039 /* *(IMG_UINT32 *)((unsigned char *)obj_buffer->buffer_data + 4) = 16; */
2040 } else {
2041 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
2042 }
2043 DEBUG_FUNC_EXIT
2044 return vaStatus;
2045 }
2046
psb_UnmapBuffer(VADriverContextP ctx,VABufferID buf_id)2047 VAStatus psb_UnmapBuffer(
2048 VADriverContextP ctx,
2049 VABufferID buf_id /* in */
2050 )
2051 {
2052 DEBUG_FUNC_ENTER
2053 INIT_DRIVER_DATA
2054 VAStatus vaStatus = VA_STATUS_SUCCESS;
2055 object_buffer_p obj_buffer = BUFFER(buf_id);
2056 CHECK_BUFFER(obj_buffer);
2057
2058 vaStatus = psb__unmap_buffer(obj_buffer);
2059 DEBUG_FUNC_EXIT
2060 return vaStatus;
2061 }
2062
2063
psb_DestroyBuffer(VADriverContextP ctx,VABufferID buffer_id)2064 VAStatus psb_DestroyBuffer(
2065 VADriverContextP ctx,
2066 VABufferID buffer_id
2067 )
2068 {
2069 DEBUG_FUNC_ENTER
2070 INIT_DRIVER_DATA
2071 VAStatus vaStatus = VA_STATUS_SUCCESS;
2072 object_buffer_p obj_buffer = BUFFER(buffer_id);
2073 if (NULL == obj_buffer) {
2074 return vaStatus;
2075 }
2076 psb__suspend_buffer(driver_data, obj_buffer);
2077 DEBUG_FUNC_EXIT
2078 return vaStatus;
2079 }
2080
2081
psb_BeginPicture(VADriverContextP ctx,VAContextID context,VASurfaceID render_target)2082 VAStatus psb_BeginPicture(
2083 VADriverContextP ctx,
2084 VAContextID context,
2085 VASurfaceID render_target
2086 )
2087 {
2088 DEBUG_FUNC_ENTER
2089 INIT_DRIVER_DATA
2090 VAStatus vaStatus = VA_STATUS_SUCCESS;
2091 object_context_p obj_context;
2092 object_surface_p obj_surface;
2093 object_config_p obj_config;
2094 unsigned int i = 0, j = VA_INVALID_ID;
2095
2096 obj_context = CONTEXT(context);
2097 CHECK_CONTEXT(obj_context);
2098
2099 /* Must not be within BeginPicture / EndPicture already */
2100 ASSERT(obj_context->current_render_target == NULL);
2101
2102 obj_surface = SURFACE(render_target);
2103 CHECK_SURFACE(obj_surface);
2104
2105 obj_context->current_render_surface_id = render_target;
2106 obj_context->current_render_target = obj_surface;
2107 obj_context->slice_count = 0;
2108
2109 obj_config = CONFIG(obj_context->config_id);
2110 if (obj_config == NULL)
2111 return VA_STATUS_ERROR_INVALID_CONFIG;
2112
2113 for (i = 0; i < (unsigned int)obj_context->num_render_targets; i++) {
2114 if (obj_context->render_targets[i] == obj_surface->surface_id) {
2115 break;
2116 } else if (SURFACE(obj_context->render_targets[i]) == NULL) {
2117 j = (i < j) ? i : j;
2118 }
2119 }
2120
2121 if (i >= (unsigned int)obj_context->num_render_targets) {
2122 if (j < (unsigned int)obj_context->num_render_targets) {
2123 obj_context->render_targets[j] = obj_surface->surface_id;
2124 obj_surface->context_id = obj_context->context_id;
2125
2126 #ifdef PSBVIDEO_MSVDX_DEC_TILING
2127 if (GET_SURFACE_INFO_tiling(obj_surface->psb_surface)) {
2128 #ifdef BAYTRAIL
2129 obj_context->msvdx_tile = psb__tile_stride_log2_512(obj_surface->width);
2130 #else
2131 if ( (obj_config != NULL) &&
2132 (obj_config->entrypoint == VAEntrypointVideoProc) &&
2133 (obj_config->profile == VAProfileNone)) {
2134 obj_context->msvdx_tile = psb__tile_stride_log2_256(obj_context->picture_width);
2135 } else {
2136 obj_context->msvdx_tile = psb__tile_stride_log2_256(obj_surface->width);
2137 }
2138 #endif
2139 }
2140
2141 obj_context->msvdx_tile &= 0xf; /* clear rotate tile */
2142 obj_context->ctp_type &= (~PSB_CTX_TILING_MASK); /* clear tile context */
2143 obj_context->ctp_type |= ((obj_context->msvdx_tile & 0xff) << 16);
2144 obj_context->ctp_type &= (~PSB_SURFACE_UNAVAILABLE);
2145 psb_update_context(driver_data, obj_context->ctp_type | driver_data->protected);
2146 #endif
2147 }
2148 }
2149
2150 /* if the surface is decode render target, and in displaying */
2151 if (obj_config &&
2152 (obj_config->entrypoint != VAEntrypointEncSlice) &&
2153 (driver_data->cur_displaying_surface == render_target))
2154 drv_debug_msg(VIDEO_DEBUG_ERROR, "WARNING: rendering a displaying surface, may see tearing\n");
2155
2156 if (VA_STATUS_SUCCESS == vaStatus) {
2157 vaStatus = obj_context->format_vtable->beginPicture(obj_context);
2158 }
2159
2160 #ifdef ANDROID
2161 /* want msvdx to do rotate
2162 * but check per-context stream type: interlace or not
2163 */
2164 if ((obj_config->entrypoint != VAEntrypointEncSlice) &&
2165 (obj_config->entrypoint != VAEntrypointEncPicture)) {
2166 psb_RecalcAlternativeOutput(obj_context);
2167 }
2168 #endif
2169 #ifdef PSBVIDEO_MRFL_VPP_ROTATE
2170 if (driver_data->vpp_on && GET_SURFACE_INFO_tiling(obj_surface->psb_surface))
2171 driver_data->disable_msvdx_rotate = 0;
2172 #endif
2173 if (obj_context->interlaced_stream || driver_data->disable_msvdx_rotate) {
2174 int i = 0;
2175 obj_context->msvdx_rotate = 0;
2176 if (obj_context->num_render_targets > 0) {
2177 for (i = 0; i < obj_context->num_render_targets; i++) {
2178 object_surface_p obj_surface = SURFACE(obj_context->render_targets[i]);
2179 /*we invalidate all surfaces's rotate buffer share info here.*/
2180 if (obj_surface && obj_surface->share_info) {
2181 obj_surface->share_info->surface_rotate = 0;
2182 }
2183 }
2184 }
2185 }
2186 else
2187 obj_context->msvdx_rotate = driver_data->msvdx_rotate_want;
2188
2189 /* the main surface track current rotate information
2190 * try to reuse the allocated rotate surfaces and don't destroy them
2191 * thus the rotation info in obj_surface->out_loop_surface may not be updated
2192 */
2193
2194 SET_SURFACE_INFO_rotate(obj_surface->psb_surface, obj_context->msvdx_rotate);
2195
2196 if (CONTEXT_SCALING(obj_context) && obj_config->entrypoint != VAEntrypointEncSlice)
2197 if(VA_STATUS_SUCCESS != psb_CreateScalingSurface(obj_context, obj_surface)) {
2198 obj_context->msvdx_scaling = 0;
2199 ALOGE("%s: fail to allocate scaling surface", __func__);
2200 }
2201
2202 if (CONTEXT_ROTATE(obj_context)) {
2203 #ifdef PSBVIDEO_MRFL_VPP_ROTATE
2204 /* The VSP rotation is just for 1080P with tilling */
2205 if (driver_data->vpp_on && GET_SURFACE_INFO_tiling(obj_surface->psb_surface)) {
2206 if (obj_config->entrypoint == VAEntrypointVideoProc)
2207 vaStatus = psb_CreateRotateSurface(obj_context, obj_surface, obj_context->msvdx_rotate);
2208 else {
2209 SET_SURFACE_INFO_rotate(obj_surface->psb_surface, 0);
2210 obj_context->msvdx_rotate = 0;
2211 vaStatus = psb_DestroyRotateBuffer(obj_context, obj_surface);
2212 }
2213 } else
2214 #endif
2215 vaStatus = psb_CreateRotateSurface(obj_context, obj_surface, obj_context->msvdx_rotate);
2216 if (VA_STATUS_SUCCESS !=vaStatus)
2217 ALOGE("%s: fail to allocate out loop surface", __func__);
2218
2219 } else {
2220 if (obj_surface && obj_surface->share_info) {
2221 obj_surface->share_info->metadata_rotate = VAROTATION2HAL(driver_data->va_rotate);
2222 obj_surface->share_info->surface_rotate = VAROTATION2HAL(obj_context->msvdx_rotate);
2223 }
2224 }
2225
2226 if (obj_surface && obj_surface->share_info &&
2227 obj_config->entrypoint == VAEntrypointVLD) {
2228 obj_surface->share_info->crop_width = driver_data->render_rect.width;
2229 obj_surface->share_info->crop_height = driver_data->render_rect.height;
2230 }
2231
2232 if (driver_data->is_oold && !obj_surface->psb_surface->in_loop_buf) {
2233 psb_surface_p psb_surface = obj_surface->psb_surface;
2234
2235 psb_surface->in_loop_buf = calloc(1, sizeof(struct psb_buffer_s));
2236 CHECK_ALLOCATION(psb_surface->in_loop_buf);
2237
2238 /* FIXME: For RAR surface, need allocate RAR buffer */
2239 vaStatus = psb_buffer_create(obj_context->driver_data,
2240 psb_surface->size,
2241 psb_bt_surface,
2242 psb_surface->in_loop_buf);
2243 } else if (!driver_data->is_oold && obj_surface->psb_surface->in_loop_buf) {
2244 psb_surface_p psb_surface = obj_surface->psb_surface;
2245
2246 psb_buffer_destroy(psb_surface->in_loop_buf);
2247 free(psb_surface->in_loop_buf);
2248 psb_surface->in_loop_buf = NULL;
2249 }
2250 obj_context->is_oold = driver_data->is_oold;
2251
2252 drv_debug_msg(VIDEO_DEBUG_GENERAL, "---BeginPicture 0x%08x for frame %d --\n",
2253 render_target, obj_context->frame_count);
2254 psb__trace_message("------Trace frame %d------\n", obj_context->frame_count);
2255
2256 DEBUG_FUNC_EXIT
2257 return vaStatus;
2258 }
2259
psb_RenderPicture(VADriverContextP ctx,VAContextID context,VABufferID * buffers,int num_buffers)2260 VAStatus psb_RenderPicture(
2261 VADriverContextP ctx,
2262 VAContextID context,
2263 VABufferID *buffers,
2264 int num_buffers
2265 )
2266 {
2267 DEBUG_FUNC_ENTER
2268 INIT_DRIVER_DATA
2269 VAStatus vaStatus = VA_STATUS_SUCCESS;
2270 object_context_p obj_context;
2271 object_buffer_p *buffer_list;
2272 int i;
2273
2274 obj_context = CONTEXT(context);
2275 CHECK_CONTEXT(obj_context);
2276
2277 CHECK_INVALID_PARAM(num_buffers <= 0);
2278 /* Don't crash on NULL pointers */
2279 CHECK_BUFFER(buffers);
2280 /* Must be within BeginPicture / EndPicture */
2281 ASSERT(obj_context->current_render_target != NULL);
2282
2283 if (num_buffers > obj_context->num_buffers) {
2284 free(obj_context->buffer_list);
2285
2286 obj_context->buffer_list = (object_buffer_p *) calloc(1, sizeof(object_buffer_p) * num_buffers);
2287 if (obj_context->buffer_list == NULL) {
2288 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
2289 obj_context->num_buffers = 0;
2290 }
2291
2292 obj_context->num_buffers = num_buffers;
2293 }
2294 buffer_list = obj_context->buffer_list;
2295
2296 if (VA_STATUS_SUCCESS == vaStatus) {
2297 /* Lookup buffer references */
2298 for (i = 0; i < num_buffers; i++) {
2299 object_buffer_p obj_buffer = BUFFER(buffers[i]);
2300 CHECK_BUFFER(obj_buffer);
2301
2302 buffer_list[i] = obj_buffer;
2303 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Render buffer %08x type %s\n", obj_buffer->base.id,
2304 buffer_type_to_string(obj_buffer->type));
2305 }
2306 }
2307
2308 if (VA_STATUS_SUCCESS == vaStatus) {
2309 vaStatus = obj_context->format_vtable->renderPicture(obj_context, buffer_list, num_buffers);
2310 }
2311
2312 if (buffer_list) {
2313 /* Release buffers */
2314 for (i = 0; i < num_buffers; i++) {
2315 if (buffer_list[i]) {
2316 psb__suspend_buffer(driver_data, buffer_list[i]);
2317 }
2318 }
2319 }
2320
2321 DEBUG_FUNC_EXIT
2322 return vaStatus;
2323 }
2324
psb_EndPicture(VADriverContextP ctx,VAContextID context)2325 VAStatus psb_EndPicture(
2326 VADriverContextP ctx,
2327 VAContextID context
2328 )
2329 {
2330 DEBUG_FUNC_ENTER
2331 INIT_DRIVER_DATA
2332 VAStatus vaStatus;
2333 object_context_p obj_context;
2334
2335 obj_context = CONTEXT(context);
2336 CHECK_CONTEXT(obj_context);
2337
2338 vaStatus = obj_context->format_vtable->endPicture(obj_context);
2339
2340 drv_debug_msg(VIDEO_DEBUG_GENERAL, "---EndPicture for frame %d --\n", obj_context->frame_count);
2341
2342 obj_context->current_render_target = NULL;
2343 obj_context->frame_count++;
2344
2345 psb__trace_message("FrameCount = %03d\n", obj_context->frame_count);
2346 drv_debug_msg(VIDEO_DEBUG_GENERAL, "FrameCount = %03d\n", obj_context->frame_count);
2347 psb__trace_message(NULL);
2348
2349
2350 //psb_SyncSurface(ctx, obj_context->current_render_surface_id);
2351 DEBUG_FUNC_EXIT
2352 return vaStatus;
2353 }
2354
2355
psb__surface_usage(psb_driver_data_p driver_data,object_surface_p obj_surface,int * decode,int * encode,int * rc_enable,int * proc)2356 static void psb__surface_usage(
2357 psb_driver_data_p driver_data,
2358 object_surface_p obj_surface,
2359 int *decode, int *encode, int *rc_enable, int *proc
2360 )
2361 {
2362 object_context_p obj_context;
2363 object_config_p obj_config;
2364 VAEntrypoint tmp;
2365 unsigned int eRCmode;
2366 int i;
2367
2368
2369 *decode = 0;
2370 *encode = 0;
2371 *rc_enable = 0;
2372 *proc = 0;
2373
2374 obj_context = CONTEXT(obj_surface->context_id);
2375 if (NULL == obj_context) /* not associate with a context */
2376 return;
2377
2378 obj_config = CONFIG(obj_context->config_id);
2379 if (NULL == obj_config) /* not have a validate context */
2380 return;
2381
2382 tmp = obj_config->entrypoint;
2383
2384 *encode = (tmp == VAEntrypointEncSlice) || (tmp == VAEntrypointEncPicture);
2385 *decode = (VAEntrypointVLD <= tmp) && (tmp <= VAEntrypointDeblocking);
2386 #ifdef PSBVIDEO_MRFL_VPP
2387 *proc = (VAEntrypointVideoProc == tmp);
2388 #endif
2389
2390 if (*encode) {
2391 for (i = 0; i < obj_config->attrib_count; i++) {
2392 if (obj_config->attrib_list[i].type == VAConfigAttribRateControl)
2393 break;
2394 }
2395
2396 if (i >= obj_config->attrib_count)
2397 eRCmode = VA_RC_NONE;
2398 else
2399 eRCmode = obj_config->attrib_list[i].value;
2400
2401 if (eRCmode == VA_RC_NONE)
2402 *rc_enable = 0;
2403 else
2404 *rc_enable = 1;
2405 }
2406 }
2407
psb_SyncSurface(VADriverContextP ctx,VASurfaceID render_target)2408 VAStatus psb_SyncSurface(
2409 VADriverContextP ctx,
2410 VASurfaceID render_target
2411 )
2412 {
2413 DEBUG_FUNC_ENTER
2414 INIT_DRIVER_DATA
2415 VAStatus vaStatus = VA_STATUS_SUCCESS;
2416 object_surface_p obj_surface;
2417 int decode = 0, encode = 0, rc_enable = 0, proc = 0;
2418 object_context_p obj_context = NULL;
2419 object_config_p obj_config = NULL;
2420
2421 drv_debug_msg(VIDEO_DEBUG_GENERAL, "psb_SyncSurface: 0x%08x\n", render_target);
2422
2423 obj_surface = SURFACE(render_target);
2424 CHECK_SURFACE(obj_surface);
2425
2426 obj_context = CONTEXT(obj_surface->context_id);
2427 if (obj_context) {
2428 obj_config = CONFIG(obj_context->config_id);
2429 }
2430
2431 /* The cur_displaying_surface indicates the surface being displayed by overlay.
2432 * The diaplay_timestamp records the time point of put surface, which would
2433 * be set to zero while using texture blit.*/
2434
2435 /* don't use mutex here for performance concern... */
2436 //pthread_mutex_lock(&output->output_mutex);
2437 if (render_target == driver_data->cur_displaying_surface)
2438 vaStatus = VA_STATUS_ERROR_SURFACE_IN_DISPLAYING;
2439 else if ((VA_INVALID_SURFACE != driver_data->cur_displaying_surface) /* use overlay */
2440 && (render_target == driver_data->last_displaying_surface)) { /* It's the last displaying surface*/
2441 object_surface_p cur_obj_surface = SURFACE(driver_data->cur_displaying_surface);
2442 /* The flip operation on current displaying surface could be delayed to
2443 * next VBlank and hadn't been finished yet. Then, the last displaying
2444 * surface shouldn't be freed, because the hardware may not
2445 * complete loading data of it. Any change of the last surface could
2446 * have a impect on the scrren.*/
2447 if (NULL != cur_obj_surface) {
2448 while ((GetTickCount() - cur_obj_surface->display_timestamp) < PSB_MAX_FLIP_DELAY)
2449 usleep(PSB_MAX_FLIP_DELAY * 1000);
2450 }
2451 }
2452 //pthread_mutex_unlock(&output->output_mutex);
2453
2454 if (vaStatus != VA_STATUS_ERROR_SURFACE_IN_DISPLAYING) {
2455 #ifdef PSBVIDEO_MRFL_VPP_ROTATE
2456 /* For VPP buffer, will sync the rotated buffer */
2457 if (obj_config && obj_config->entrypoint == VAEntrypointVideoProc) {
2458 if (GET_SURFACE_INFO_tiling(obj_surface->psb_surface) &&
2459 (obj_context->msvdx_rotate == VA_ROTATION_90 || obj_context->msvdx_rotate == VA_ROTATION_270) &&
2460 obj_surface->out_loop_surface)
2461 vaStatus = psb_surface_sync(obj_surface->out_loop_surface);
2462 else
2463 vaStatus = psb_surface_sync(obj_surface->psb_surface);
2464 } else
2465 #endif
2466 vaStatus = psb_surface_sync(obj_surface->psb_surface);
2467 }
2468
2469 /* report any error of decode for Android */
2470 psb__surface_usage(driver_data, obj_surface, &decode, &encode, &rc_enable, &proc);
2471 #if 0
2472 if (decode && IS_MRST(driver_data)) {
2473 struct drm_lnc_video_getparam_arg arg;
2474 uint32_t ret, handle, fw_status = 0;
2475 handle = wsbmKBufHandle(wsbmKBuf(obj_surface->psb_surface->buf.drm_buf));
2476 arg.key = IMG_VIDEO_DECODE_STATUS;
2477 arg.arg = (uint64_t)((unsigned long) & handle);
2478 arg.value = (uint64_t)((unsigned long) & fw_status);
2479 ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset,
2480 &arg, sizeof(arg));
2481 if (ret == 0) {
2482 if (fw_status != 0)
2483 vaStatus = VA_STATUS_ERROR_DECODING_ERROR;
2484 } else {
2485 drv_debug_msg(VIDEO_DEBUG_GENERAL, "IMG_VIDEO_DECODE_STATUS ioctl return failed.\n");
2486 vaStatus = VA_STATUS_ERROR_UNKNOWN;
2487 }
2488 } else if (proc && IS_MRFL(driver_data)) {
2489 /* FIXME: does it need a new surface sync mechanism for FRC? */
2490 }
2491 #endif
2492 if (proc && IS_MRFL(driver_data)) {
2493 /* FIXME: does it need a new surface sync mechanism for FRC? */
2494 }
2495
2496 //psb__dump_NV_buffers(obj_surface->psb_surface, 0, 0, obj_surface->width, obj_surface->height);
2497 //psb__dump_NV_buffers(obj_surface->psb_surface_rotate, 0, 0, obj_surface->height, ((obj_surface->width + 0x1f) & (~0x1f)));
2498 if (obj_surface->scaling_surface)
2499 psb__dump_NV12_buffers(obj_surface->scaling_surface, 0, 0, obj_surface->width_s, obj_surface->height_s);
2500 DEBUG_FAILURE;
2501 DEBUG_FUNC_EXIT
2502 return vaStatus;
2503 }
2504
2505
psb_QuerySurfaceStatus(VADriverContextP ctx,VASurfaceID render_target,VASurfaceStatus * status)2506 VAStatus psb_QuerySurfaceStatus(
2507 VADriverContextP ctx,
2508 VASurfaceID render_target,
2509 VASurfaceStatus *status /* out */
2510 )
2511 {
2512 DEBUG_FUNC_ENTER
2513 INIT_DRIVER_DATA
2514 VAStatus vaStatus = VA_STATUS_SUCCESS;
2515 object_surface_p obj_surface;
2516 VASurfaceStatus surface_status;
2517 int frame_skip = 0, encode = 0, decode = 0, rc_enable = 0, proc = 0;
2518 object_context_p obj_context = NULL;
2519
2520 obj_surface = SURFACE(render_target);
2521 CHECK_SURFACE(obj_surface);
2522
2523 CHECK_INVALID_PARAM(status == NULL);
2524
2525 psb__surface_usage(driver_data, obj_surface, &decode, &encode, &rc_enable, &proc);
2526 #ifdef PSBVIDEO_MRFL_VPP_ROTATE
2527 /* For VPP 1080P, will query the rotated buffer */
2528 if (proc) {
2529 obj_context = CONTEXT(obj_surface->context_id);
2530 CHECK_CONTEXT(obj_context);
2531 if (GET_SURFACE_INFO_tiling(obj_surface->psb_surface) &&
2532 (obj_context->msvdx_rotate == VA_ROTATION_90 || obj_context->msvdx_rotate == VA_ROTATION_270) &&
2533 obj_surface->out_loop_surface)
2534 vaStatus = psb_surface_query_status(obj_surface->out_loop_surface, &surface_status);
2535 else
2536 vaStatus = psb_surface_query_status(obj_surface->psb_surface, &surface_status);
2537 } else
2538 #endif
2539 vaStatus = psb_surface_query_status(obj_surface->psb_surface, &surface_status);
2540
2541 /* The cur_displaying_surface indicates the surface being displayed by overlay.
2542 * The diaplay_timestamp records the time point of put surface, which would
2543 * be set to zero while using texture blit.*/
2544 pthread_mutex_lock(&driver_data->output_mutex);
2545 if (render_target == driver_data->cur_displaying_surface)
2546 surface_status = VASurfaceDisplaying;
2547 else if ((VA_INVALID_SURFACE != driver_data->cur_displaying_surface) /* use overlay */
2548 && (render_target == driver_data->last_displaying_surface)) { /* It's the last displaying surface*/
2549 object_surface_p cur_obj_surface = SURFACE(driver_data->cur_displaying_surface);
2550 /*The flip operation on current displaying surface could be delayed to
2551 * next VBlank and hadn't been finished yet. Then, the last displaying
2552 * surface shouldn't be freed, because the hardware may not
2553 * complete loading data of it. Any change of the last surface could
2554 * have a impect on the scrren.*/
2555 if ((NULL != cur_obj_surface)
2556 && ((GetTickCount() - cur_obj_surface->display_timestamp) < PSB_MAX_FLIP_DELAY)) {
2557 surface_status = VASurfaceDisplaying;
2558 }
2559 }
2560 pthread_mutex_unlock(&driver_data->output_mutex);
2561
2562 /* try to get frameskip flag for encode */
2563 #ifndef BAYTRAIL
2564 if (!decode) {
2565 /* The rendering surface may not be associated with any context. So driver should
2566 check the frame skip flag even variable encode is 0 */
2567 #ifdef PSBVIDEO_MRFL
2568 if (IS_MRFL(driver_data))
2569 tng_surface_get_frameskip(driver_data, obj_surface->psb_surface, &frame_skip);
2570 else
2571 #endif
2572 pnw_surface_get_frameskip(driver_data, obj_surface->psb_surface, &frame_skip);
2573
2574 if (frame_skip == 1) {
2575 surface_status = surface_status | VASurfaceSkipped;
2576 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s next frame of 0x%08x is skipped",
2577 __FUNCTION__, render_target);
2578 }
2579 } else
2580 #endif
2581 if (decode) {
2582 #ifdef ANDROID
2583 if (obj_surface->psb_surface->buf.handle) {
2584 buffer_handle_t handle = obj_surface->psb_surface->buf.handle;
2585 int display_status;
2586 int err;
2587 err = gralloc_getdisplaystatus(handle, &display_status);
2588 if (!err) {
2589 if (display_status)
2590 surface_status = VASurfaceDisplaying;
2591 else
2592 surface_status = VASurfaceReady;
2593 } else {
2594 surface_status = VASurfaceReady;
2595 }
2596
2597 /* if not used by display, then check whether surface used by widi */
2598 if (surface_status == VASurfaceReady && obj_surface->share_info) {
2599 if (obj_surface->share_info->renderStatus == 1) {
2600 surface_status = VASurfaceDisplaying;
2601 }
2602 }
2603 }
2604 #endif
2605 } else if (proc) {
2606 /* FIXME: does it need a new surface sync mechanism for FRC? */
2607 }
2608
2609 *status = surface_status;
2610 DEBUG_FUNC_EXIT
2611 return vaStatus;
2612 }
2613
psb_QuerySurfaceError(VADriverContextP ctx,VASurfaceID render_target,VAStatus error_status,void ** error_info)2614 VAStatus psb_QuerySurfaceError(
2615 VADriverContextP ctx,
2616 VASurfaceID render_target,
2617 VAStatus error_status,
2618 void **error_info /*out*/
2619 )
2620 {
2621 DEBUG_FUNC_ENTER
2622 INIT_DRIVER_DATA
2623 VAStatus vaStatus = VA_STATUS_SUCCESS;
2624 object_surface_p obj_surface;
2625 uint32_t i;
2626
2627 obj_surface = SURFACE(render_target);
2628 CHECK_SURFACE(obj_surface);
2629
2630 #ifdef PSBVIDEO_MSVDX_EC
2631 if (driver_data->ec_enabled == 0) {
2632 #else
2633 {
2634 #endif
2635 drv_debug_msg(VIDEO_DEBUG_GENERAL, "error concealment is not supported for this profile.\n");
2636 error_info = NULL;
2637 return VA_STATUS_ERROR_UNKNOWN;
2638 }
2639
2640 if (error_status == VA_STATUS_ERROR_DECODING_ERROR) {
2641 drm_psb_msvdx_decode_status_t *decode_status = driver_data->msvdx_decode_status;
2642 struct drm_lnc_video_getparam_arg arg;
2643 uint32_t ret, handle;
2644 handle = wsbmKBufHandle(wsbmKBuf(obj_surface->psb_surface->buf.drm_buf));
2645
2646 arg.key = IMG_VIDEO_MB_ERROR;
2647 arg.arg = (uint64_t)((unsigned long) & handle);
2648 arg.value = (uint64_t)((unsigned long)decode_status);
2649 ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset,
2650 &arg, sizeof(arg));
2651 if (ret != 0) {
2652 drv_debug_msg(VIDEO_DEBUG_GENERAL,"return value is %d drmCommandWriteRead\n",ret);
2653 return VA_STATUS_ERROR_UNKNOWN;
2654 }
2655 #ifndef _FOR_FPGA_
2656 if (decode_status->num_region > MAX_MB_ERRORS) {
2657 drv_debug_msg(VIDEO_DEBUG_GENERAL, "too much mb errors are reported.\n");
2658 return VA_STATUS_ERROR_UNKNOWN;
2659 }
2660 i = 0;
2661 for (i = 0; i < decode_status->num_region; ++i) {
2662 driver_data->surface_mb_error[i].status = 1;
2663 driver_data->surface_mb_error[i].start_mb = decode_status->mb_regions[i].start;
2664 driver_data->surface_mb_error[i].end_mb = decode_status->mb_regions[i].end;
2665 //driver_data->surface_mb_error[i].start_mb = decode_status->start_error_mb_list[i];
2666 //driver_data->surface_mb_error[i].end_mb = decode_status->end_error_mb_list[i];
2667 //driver_data->surface_mb_error[i].decode_error_type = decode_status->slice_missing_or_error[i];
2668 }
2669 #endif
2670 driver_data->surface_mb_error[i].status = -1;
2671 *error_info = driver_data->surface_mb_error;
2672 } else {
2673 error_info = NULL;
2674 return VA_STATUS_ERROR_UNKNOWN;
2675 }
2676 DEBUG_FUNC_EXIT
2677 return vaStatus;
2678 }
2679
2680 #define PSB_MAX_SURFACE_ATTRIBUTES 16
2681
2682 VAStatus psb_QuerySurfaceAttributes(VADriverContextP ctx,
2683 VAConfigID config,
2684 VASurfaceAttrib *attrib_list,
2685 unsigned int *num_attribs)
2686 {
2687 DEBUG_FUNC_ENTER
2688 INIT_DRIVER_DATA
2689
2690 VAStatus vaStatus = VA_STATUS_SUCCESS;
2691 object_config_p obj_config;
2692 unsigned int i = 0;
2693
2694 CHECK_INVALID_PARAM(num_attribs == NULL);
2695
2696 if (attrib_list == NULL) {
2697 *num_attribs = PSB_MAX_SURFACE_ATTRIBUTES;
2698 return VA_STATUS_SUCCESS;
2699 }
2700
2701 obj_config = CONFIG(config);
2702 CHECK_CONFIG(obj_config);
2703
2704 VASurfaceAttrib *attribs = NULL;
2705 attribs = malloc(PSB_MAX_SURFACE_ATTRIBUTES *sizeof(VASurfaceAttrib));
2706 if (attribs == NULL)
2707 return VA_STATUS_ERROR_ALLOCATION_FAILED;
2708
2709 attribs[i].type = VASurfaceAttribPixelFormat;
2710 attribs[i].value.type = VAGenericValueTypeInteger;
2711 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
2712 attribs[i].value.value.i = VA_FOURCC('N', 'V', '1', '2');
2713 i++;
2714
2715 attribs[i].type = VASurfaceAttribMemoryType;
2716 attribs[i].value.type = VAGenericValueTypeInteger;
2717 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
2718 if (obj_config->entrypoint == VAEntrypointEncSlice && obj_config->profile == VAProfileVP8Version0_3) {
2719 attribs[i].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA |
2720 VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM |
2721 VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC |
2722 VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_ION;
2723 } else {
2724 attribs[i].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA |
2725 VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM |
2726 VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR |
2727 VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC |
2728 VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_ION;
2729 }
2730 i++;
2731
2732 attribs[i].type = VASurfaceAttribExternalBufferDescriptor;
2733 attribs[i].value.type = VAGenericValueTypePointer;
2734 attribs[i].flags = VA_SURFACE_ATTRIB_SETTABLE;
2735 attribs[i].value.value.p = NULL;
2736 i++;
2737
2738 //modules have speical formats to support
2739 if (obj_config->entrypoint == VAEntrypointVLD) { /* decode */
2740
2741 } else if (obj_config->entrypoint == VAEntrypointEncSlice || /* encode */
2742 obj_config->entrypoint == VAEntrypointEncPicture) {
2743 #ifdef PSBVIDEO_MFLD
2744 if (IS_MFLD(driver_data)) {}
2745 #endif
2746 #ifdef PSBVIDEO_MRFL
2747 if (IS_MRFL(driver_data)) {}
2748 #endif
2749 #ifdef BAYTRAIL
2750 if (IS_BAYTRAIL(driver_data)) {}
2751 #endif
2752 }
2753 else if (obj_config->entrypoint == VAEntrypointVideoProc) { /* vpp */
2754
2755 }
2756
2757 if (i > *num_attribs) {
2758 *num_attribs = i;
2759 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
2760 }
2761
2762 *num_attribs = i;
2763 memcpy(attrib_list, attribs, i * sizeof(*attribs));
2764 free(attribs);
2765
2766 DEBUG_FUNC_EXIT
2767 return vaStatus;
2768 }
2769
2770 VAStatus psb_LockSurface(
2771 VADriverContextP ctx,
2772 VASurfaceID surface,
2773 unsigned int *fourcc, /* following are output argument */
2774 unsigned int *luma_stride,
2775 unsigned int *chroma_u_stride,
2776 unsigned int *chroma_v_stride,
2777 unsigned int *luma_offset,
2778 unsigned int *chroma_u_offset,
2779 unsigned int *chroma_v_offset,
2780 unsigned int *buffer_name,
2781 void **buffer
2782 )
2783 {
2784 DEBUG_FUNC_ENTER
2785 INIT_DRIVER_DATA
2786 VAStatus vaStatus = VA_STATUS_SUCCESS;
2787 unsigned char *surface_data;
2788 int ret;
2789
2790 object_surface_p obj_surface = SURFACE(surface);
2791 psb_surface_p psb_surface;
2792 CHECK_SURFACE(obj_surface);
2793
2794 psb_surface = obj_surface->psb_surface;
2795 if (buffer_name)
2796 *buffer_name = (uint32_t)(wsbmKBufHandle(wsbmKBuf(psb_surface->buf.drm_buf)));
2797
2798 if (buffer) { /* map the surface buffer */
2799 uint32_t srf_buf_ofs = 0;
2800 ret = psb_buffer_map(&psb_surface->buf, &surface_data);
2801 if (ret) {
2802 *buffer = NULL;
2803 vaStatus = VA_STATUS_ERROR_UNKNOWN;
2804 DEBUG_FAILURE;
2805 return vaStatus;
2806 }
2807 srf_buf_ofs = psb_surface->buf.buffer_ofs;
2808 *buffer = surface_data + srf_buf_ofs;
2809 }
2810
2811 *fourcc = VA_FOURCC_NV12;
2812 *luma_stride = psb_surface->stride;
2813 *chroma_u_stride = psb_surface->stride;
2814 *chroma_v_stride = psb_surface->stride;
2815 *luma_offset = 0;
2816 *chroma_u_offset = obj_surface->height * psb_surface->stride;
2817 *chroma_v_offset = obj_surface->height * psb_surface->stride + 1;
2818 DEBUG_FUNC_EXIT
2819 return vaStatus;
2820 }
2821
2822
2823 VAStatus psb_UnlockSurface(
2824 VADriverContextP ctx,
2825 VASurfaceID surface
2826 )
2827 {
2828 DEBUG_FUNC_ENTER
2829 INIT_DRIVER_DATA
2830 VAStatus vaStatus = VA_STATUS_SUCCESS;
2831
2832 object_surface_p obj_surface = SURFACE(surface);
2833 CHECK_SURFACE(obj_surface);
2834
2835 psb_surface_p psb_surface = obj_surface->psb_surface;
2836
2837 psb_buffer_unmap(&psb_surface->buf);
2838
2839 DEBUG_FUNC_EXIT
2840 return VA_STATUS_SUCCESS;
2841 }
2842
2843 VAStatus psb_GetEGLClientBufferFromSurface(
2844 VADriverContextP ctx,
2845 VASurfaceID surface,
2846 void **buffer
2847 )
2848 {
2849 DEBUG_FUNC_ENTER
2850 INIT_DRIVER_DATA
2851 VAStatus vaStatus = VA_STATUS_SUCCESS;
2852
2853 object_surface_p obj_surface = SURFACE(surface);
2854 CHECK_SURFACE(obj_surface);
2855
2856 psb_surface_p psb_surface = obj_surface->psb_surface;
2857 *buffer = (unsigned char *)psb_surface->bc_buffer;
2858
2859 DEBUG_FUNC_EXIT
2860 return vaStatus;
2861 }
2862
2863 VAStatus psb_PutSurfaceBuf(
2864 VADriverContextP ctx,
2865 VASurfaceID surface,
2866 unsigned char __maybe_unused * data,
2867 int __maybe_unused * data_len,
2868 short __maybe_unused srcx,
2869 short __maybe_unused srcy,
2870 unsigned short __maybe_unused srcw,
2871 unsigned short __maybe_unused srch,
2872 short __maybe_unused destx,
2873 short __maybe_unused desty,
2874 unsigned short __maybe_unused destw,
2875 unsigned short __maybe_unused desth,
2876 VARectangle __maybe_unused * cliprects, /* client supplied clip list */
2877 unsigned int __maybe_unused number_cliprects, /* number of clip rects in the clip list */
2878 unsigned int __maybe_unused flags /* de-interlacing flags */
2879 )
2880 {
2881 DEBUG_FUNC_ENTER
2882 INIT_DRIVER_DATA;
2883 object_surface_p obj_surface = SURFACE(surface);
2884 psb_surface_p psb_surface;
2885
2886 obj_surface = SURFACE(surface);
2887 if (obj_surface == NULL)
2888 return VA_STATUS_ERROR_INVALID_SURFACE;
2889
2890 psb_surface = obj_surface->psb_surface;
2891
2892 #if 0
2893 psb_putsurface_textureblit(ctx, data, surface, srcx, srcy, srcw, srch, destx, desty, destw, desth, 1, /* check subpicture */
2894 obj_surface->width, obj_surface->height,
2895 psb_surface->stride, psb_surface->buf.drm_buf,
2896 psb_surface->buf.pl_flags, 1 /* wrap dst */);
2897 #endif
2898
2899 DEBUG_FUNC_EXIT
2900 return VA_STATUS_SUCCESS;
2901 }
2902
2903 VAStatus psb_SetTimestampForSurface(
2904 VADriverContextP ctx,
2905 VASurfaceID surface,
2906 long long timestamp
2907 )
2908 {
2909 INIT_DRIVER_DATA;
2910 VAStatus vaStatus = VA_STATUS_SUCCESS;
2911 object_surface_p obj_surface = SURFACE(surface);
2912
2913 obj_surface = SURFACE(surface);
2914 CHECK_SURFACE(obj_surface);
2915
2916 if (obj_surface->share_info) {
2917 obj_surface->share_info->timestamp = timestamp;
2918 return VA_STATUS_SUCCESS;
2919 } else {
2920 return VA_STATUS_ERROR_UNKNOWN;
2921 }
2922 }
2923
2924 int LOCK_HARDWARE(psb_driver_data_p driver_data)
2925 {
2926 char ret = 0;
2927
2928 if (driver_data->dri2 || driver_data->dri_dummy)
2929 return 0;
2930
2931 pthread_mutex_lock(&driver_data->drm_mutex);
2932 DRM_CAS(driver_data->drm_lock, driver_data->drm_context,
2933 (DRM_LOCK_HELD | driver_data->drm_context), ret);
2934 if (ret) {
2935 ret = drmGetLock(driver_data->drm_fd, driver_data->drm_context, 0);
2936 /* driver_data->contended_lock=1; */
2937 }
2938
2939 return ret;
2940 }
2941
2942 int UNLOCK_HARDWARE(psb_driver_data_p driver_data)
2943 {
2944 /* driver_data->contended_lock=0; */
2945 if (driver_data->dri2 || driver_data->dri_dummy)
2946 return 0;
2947
2948 DRM_UNLOCK(driver_data->drm_fd, driver_data->drm_lock, driver_data->drm_context);
2949 pthread_mutex_unlock(&driver_data->drm_mutex);
2950
2951 return 0;
2952 }
2953
2954
2955 static void psb__deinitDRM(VADriverContextP ctx)
2956 {
2957 INIT_DRIVER_DATA
2958
2959 if (driver_data->main_pool) {
2960 driver_data->main_pool->takeDown(driver_data->main_pool);
2961 driver_data->main_pool = NULL;
2962 }
2963 if (driver_data->fence_mgr) {
2964 wsbmFenceMgrTTMTakedown(driver_data->fence_mgr);
2965 driver_data->fence_mgr = NULL;
2966 }
2967
2968 if (wsbmIsInitialized())
2969 wsbmTakedown();
2970
2971 driver_data->drm_fd = -1;
2972 }
2973
2974
2975 static VAStatus psb__initDRI(VADriverContextP ctx)
2976 {
2977 INIT_DRIVER_DATA
2978 struct drm_state *drm_state = (struct drm_state *)ctx->drm_state;
2979
2980 assert(dri_state);
2981 #ifdef _FOR_FPGA_
2982 dri_state->driConnectedFlag = VA_DUMMY;
2983 /* ON FPGA machine, psb may co-exist with gfx's drm driver */
2984 dri_state->fd = open("/dev/dri/card1", O_RDWR);
2985 if (dri_state->fd < 0)
2986 dri_state->fd = open("/dev/dri/card0", O_RDWR);
2987 assert(dri_state->fd >= 0);
2988 #endif
2989 assert(dri_state->driConnectedFlag == VA_DRI2 ||
2990 dri_state->driConnectedFlag == VA_DUMMY);
2991
2992 driver_data->drm_fd = drm_state->fd;
2993 driver_data->dri_dummy = 1;
2994 driver_data->dri2 = 0;
2995 driver_data->ws_priv = NULL;
2996 driver_data->bus_id = NULL;
2997
2998 return VA_STATUS_SUCCESS;
2999 }
3000
3001
3002 static VAStatus psb__initTTM(VADriverContextP ctx)
3003 {
3004 INIT_DRIVER_DATA
3005
3006 const char drm_ext[] = "psb_ttm_placement_alphadrop";
3007 union drm_psb_extension_arg arg;
3008 struct _WsbmBufferPool *pool;
3009 int ret;
3010 const char exec_ext[] = "psb_ttm_execbuf_alphadrop";
3011 union drm_psb_extension_arg exec_arg;
3012 const char lncvideo_getparam_ext[] = "lnc_video_getparam";
3013 union drm_psb_extension_arg lncvideo_getparam_arg;
3014
3015 /* init wsbm
3016 * WSBM node is not used in driver, thus can pass NULL Node callback
3017 */
3018 ret = wsbmInit(wsbmNullThreadFuncs(), NULL/*psbVNodeFuncs()*/);
3019 if (ret) {
3020 drv_debug_msg(VIDEO_DEBUG_ERROR, "failed initializing libwsbm.\n");
3021 return VA_STATUS_ERROR_UNKNOWN;
3022 }
3023
3024 strncpy(arg.extension, drm_ext, sizeof(arg.extension));
3025 /* FIXME: should check dri enabled?
3026 * it seems not init dri here at all
3027 */
3028 ret = drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_EXTENSION,
3029 &arg, sizeof(arg));
3030 if (ret != 0 || !arg.rep.exists) {
3031 drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to detect DRM extension \"%s\", fd=%d\n",
3032 drm_ext, driver_data->drm_fd);
3033 drv_debug_msg(VIDEO_DEBUG_ERROR, "found error %s (ret=%d), arg.rep.exists=%d",
3034 strerror(errno), ret, arg.rep.exists);
3035
3036 driver_data->main_pool = NULL;
3037 return VA_STATUS_ERROR_UNKNOWN;
3038 } else {
3039 pool = wsbmTTMPoolInit(driver_data->drm_fd,
3040 arg.rep.driver_ioctl_offset);
3041 if (pool == NULL) {
3042 drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to get ttm pool\n");
3043 return VA_STATUS_ERROR_UNKNOWN;
3044 }
3045 driver_data->main_pool = pool;
3046 }
3047
3048 strncpy(exec_arg.extension, exec_ext, sizeof(exec_arg.extension));
3049 ret = drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_EXTENSION, &exec_arg,
3050 sizeof(exec_arg));
3051 if (ret != 0 || !exec_arg.rep.exists) {
3052 drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to detect DRM extension \"%s\".\n",
3053 exec_ext);
3054 return FALSE;
3055 }
3056 driver_data->execIoctlOffset = exec_arg.rep.driver_ioctl_offset;
3057
3058 strncpy(lncvideo_getparam_arg.extension, lncvideo_getparam_ext, sizeof(lncvideo_getparam_arg.extension));
3059 ret = drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_EXTENSION, &lncvideo_getparam_arg,
3060 sizeof(lncvideo_getparam_arg));
3061 if (ret != 0 || !lncvideo_getparam_arg.rep.exists) {
3062 drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to detect DRM extension \"%s\".\n",
3063 lncvideo_getparam_ext);
3064 /* return FALSE; */ /* not reture FALSE, so it still can run */
3065 }
3066 driver_data->getParamIoctlOffset = lncvideo_getparam_arg.rep.driver_ioctl_offset;
3067 return VA_STATUS_SUCCESS;
3068 }
3069
3070 static VAStatus psb__initDRM(VADriverContextP ctx)
3071 {
3072 VAStatus vaStatus;
3073
3074 vaStatus = psb__initDRI(ctx);
3075
3076 if (vaStatus == VA_STATUS_SUCCESS)
3077 return psb__initTTM(ctx);
3078 else
3079 return vaStatus;
3080 }
3081
3082 VAStatus psb_Terminate(VADriverContextP ctx)
3083 {
3084 DEBUG_FUNC_ENTER
3085 INIT_DRIVER_DATA
3086 object_subpic_p obj_subpic;
3087 object_image_p obj_image;
3088 object_buffer_p obj_buffer;
3089 object_surface_p obj_surface;
3090 object_context_p obj_context;
3091 object_config_p obj_config;
3092 object_heap_iterator iter;
3093
3094 drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: begin to tear down\n");
3095
3096 /* Clean up left over contexts */
3097 obj_context = (object_context_p) object_heap_first(&driver_data->context_heap, &iter);
3098 while (obj_context) {
3099 drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: contextID %08x still allocated, destroying\n", obj_context->base.id);
3100 psb__destroy_context(driver_data, obj_context);
3101 obj_context = (object_context_p) object_heap_next(&driver_data->context_heap, &iter);
3102 }
3103 object_heap_destroy(&driver_data->context_heap);
3104
3105 /* Clean up SubpicIDs */
3106 obj_subpic = (object_subpic_p) object_heap_first(&driver_data->subpic_heap, &iter);
3107 while (obj_subpic) {
3108 drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: subpictureID %08x still allocated, destroying\n", obj_subpic->base.id);
3109 psb__destroy_subpicture(driver_data, obj_subpic);
3110 obj_subpic = (object_subpic_p) object_heap_next(&driver_data->subpic_heap, &iter);
3111 }
3112 object_heap_destroy(&driver_data->subpic_heap);
3113
3114 /* Clean up ImageIDs */
3115 obj_image = (object_image_p) object_heap_first(&driver_data->image_heap, &iter);
3116 while (obj_image) {
3117 drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: imageID %08x still allocated, destroying\n", obj_image->base.id);
3118 psb__destroy_image(driver_data, obj_image);
3119 obj_image = (object_image_p) object_heap_next(&driver_data->image_heap, &iter);
3120 }
3121 object_heap_destroy(&driver_data->image_heap);
3122
3123 /* Clean up left over buffers */
3124 obj_buffer = (object_buffer_p) object_heap_first(&driver_data->buffer_heap, &iter);
3125 while (obj_buffer) {
3126 drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: bufferID %08x still allocated, destroying\n", obj_buffer->base.id);
3127 psb__destroy_buffer(driver_data, obj_buffer);
3128 obj_buffer = (object_buffer_p) object_heap_next(&driver_data->buffer_heap, &iter);
3129 }
3130 object_heap_destroy(&driver_data->buffer_heap);
3131
3132 /* Clean up left over surfaces */
3133
3134 #if 0
3135 /* Free PVR2D buffer wrapped from the surfaces */
3136 psb_free_surface_pvr2dbuf(driver_data);
3137 #endif
3138 obj_surface = (object_surface_p) object_heap_first(&driver_data->surface_heap, &iter);
3139 while (obj_surface) {
3140 drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: surfaceID %08x still allocated, destroying\n", obj_surface->base.id);
3141 psb__destroy_surface(driver_data, obj_surface);
3142 obj_surface = (object_surface_p) object_heap_next(&driver_data->surface_heap, &iter);
3143 }
3144 object_heap_destroy(&driver_data->surface_heap);
3145
3146 /* Clean up configIDs */
3147 obj_config = (object_config_p) object_heap_first(&driver_data->config_heap, &iter);
3148 while (obj_config) {
3149 object_heap_free(&driver_data->config_heap, (object_base_p) obj_config);
3150 obj_config = (object_config_p) object_heap_next(&driver_data->config_heap, &iter);
3151 }
3152 object_heap_destroy(&driver_data->config_heap);
3153
3154 if (driver_data->camera_bo) {
3155 drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: clearup camera global BO\n");
3156
3157 psb_buffer_destroy((psb_buffer_p)driver_data->camera_bo);
3158 free(driver_data->camera_bo);
3159 driver_data->camera_bo = NULL;
3160 }
3161
3162 if (driver_data->rar_bo) {
3163 drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: clearup RAR global BO\n");
3164
3165 psb_buffer_destroy((psb_buffer_p)driver_data->rar_bo);
3166 free(driver_data->rar_bo);
3167 driver_data->rar_bo = NULL;
3168 }
3169
3170 if (driver_data->ws_priv) {
3171 drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: tear down output portion\n");
3172
3173 psb_deinitOutput(ctx);
3174 driver_data->ws_priv = NULL;
3175 }
3176
3177 drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: de-initialized DRM\n");
3178
3179 psb__deinitDRM(ctx);
3180
3181 if (driver_data->msvdx_decode_status)
3182 free(driver_data->msvdx_decode_status);
3183
3184 if (driver_data->surface_mb_error)
3185 free(driver_data->surface_mb_error);
3186
3187 pthread_mutex_destroy(&driver_data->drm_mutex);
3188 free(ctx->pDriverData);
3189 free(ctx->vtable_egl);
3190 free(ctx->vtable_tpi);
3191
3192 ctx->pDriverData = NULL;
3193 drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: goodbye\n\n");
3194
3195 psb__close_log();
3196 DEBUG_FUNC_EXIT
3197 return VA_STATUS_SUCCESS;
3198 }
3199
3200 EXPORT VAStatus __vaDriverInit_0_31(VADriverContextP ctx)
3201 {
3202 psb_driver_data_p driver_data;
3203 struct VADriverVTableTPI *tpi;
3204 struct VADriverVTableEGL *va_egl;
3205 int result;
3206 if (psb_video_trace_fp) {
3207 /* make gdb always stop here */
3208 signal(SIGUSR1, SIG_IGN);
3209 kill(getpid(), SIGUSR1);
3210 }
3211
3212 psb__open_log();
3213
3214 drv_debug_msg(VIDEO_DEBUG_INIT, "vaInitilize: start the journey\n");
3215
3216 ctx->version_major = 0;
3217 ctx->version_minor = 31;
3218
3219 ctx->max_profiles = PSB_MAX_PROFILES;
3220 ctx->max_entrypoints = PSB_MAX_ENTRYPOINTS;
3221 ctx->max_attributes = PSB_MAX_CONFIG_ATTRIBUTES;
3222 ctx->max_image_formats = PSB_MAX_IMAGE_FORMATS;
3223 ctx->max_subpic_formats = PSB_MAX_SUBPIC_FORMATS;
3224 ctx->max_display_attributes = PSB_MAX_DISPLAY_ATTRIBUTES;
3225
3226 ctx->vtable->vaTerminate = psb_Terminate;
3227 ctx->vtable->vaQueryConfigEntrypoints = psb_QueryConfigEntrypoints;
3228 ctx->vtable->vaTerminate = psb_Terminate;
3229 ctx->vtable->vaQueryConfigProfiles = psb_QueryConfigProfiles;
3230 ctx->vtable->vaQueryConfigEntrypoints = psb_QueryConfigEntrypoints;
3231 ctx->vtable->vaQueryConfigAttributes = psb_QueryConfigAttributes;
3232 ctx->vtable->vaCreateConfig = psb_CreateConfig;
3233 ctx->vtable->vaDestroyConfig = psb_DestroyConfig;
3234 ctx->vtable->vaGetConfigAttributes = psb_GetConfigAttributes;
3235 ctx->vtable->vaCreateSurfaces2 = psb_CreateSurfaces2;
3236 ctx->vtable->vaCreateSurfaces = psb_CreateSurfaces;
3237 ctx->vtable->vaGetSurfaceAttributes = psb_GetSurfaceAttributes;
3238 ctx->vtable->vaDestroySurfaces = psb_DestroySurfaces;
3239 ctx->vtable->vaCreateContext = psb_CreateContext;
3240 ctx->vtable->vaDestroyContext = psb_DestroyContext;
3241 ctx->vtable->vaCreateBuffer = psb_CreateBuffer;
3242 ctx->vtable->vaBufferSetNumElements = psb_BufferSetNumElements;
3243 ctx->vtable->vaMapBuffer = psb_MapBuffer;
3244 ctx->vtable->vaUnmapBuffer = psb_UnmapBuffer;
3245 ctx->vtable->vaDestroyBuffer = psb_DestroyBuffer;
3246 ctx->vtable->vaBeginPicture = psb_BeginPicture;
3247 ctx->vtable->vaRenderPicture = psb_RenderPicture;
3248 ctx->vtable->vaEndPicture = psb_EndPicture;
3249 ctx->vtable->vaSyncSurface = psb_SyncSurface;
3250 ctx->vtable->vaQuerySurfaceStatus = psb_QuerySurfaceStatus;
3251 ctx->vtable->vaQuerySurfaceError = psb_QuerySurfaceError;
3252 ctx->vtable->vaPutSurface = psb_PutSurface;
3253 ctx->vtable->vaQueryImageFormats = psb_QueryImageFormats;
3254 ctx->vtable->vaCreateImage = psb_CreateImage;
3255 ctx->vtable->vaDeriveImage = psb_DeriveImage;
3256 ctx->vtable->vaDestroyImage = psb_DestroyImage;
3257 ctx->vtable->vaSetImagePalette = psb_SetImagePalette;
3258 ctx->vtable->vaGetImage = psb_GetImage;
3259 ctx->vtable->vaPutImage = psb_PutImage;
3260 ctx->vtable->vaQuerySubpictureFormats = psb_QuerySubpictureFormats;
3261 ctx->vtable->vaCreateSubpicture = psb_CreateSubpicture;
3262 ctx->vtable->vaDestroySubpicture = psb_DestroySubpicture;
3263 ctx->vtable->vaSetSubpictureImage = psb_SetSubpictureImage;
3264 ctx->vtable->vaSetSubpictureChromakey = psb_SetSubpictureChromakey;
3265 ctx->vtable->vaSetSubpictureGlobalAlpha = psb_SetSubpictureGlobalAlpha;
3266 ctx->vtable->vaAssociateSubpicture = psb_AssociateSubpicture;
3267 ctx->vtable->vaDeassociateSubpicture = psb_DeassociateSubpicture;
3268 ctx->vtable->vaQueryDisplayAttributes = psb_QueryDisplayAttributes;
3269 ctx->vtable->vaGetDisplayAttributes = psb_GetDisplayAttributes;
3270 ctx->vtable->vaSetDisplayAttributes = psb_SetDisplayAttributes;
3271 ctx->vtable->vaQuerySurfaceAttributes = psb_QuerySurfaceAttributes;
3272 ctx->vtable->vaBufferInfo = psb_BufferInfo;
3273 ctx->vtable->vaLockSurface = psb_LockSurface;
3274 ctx->vtable->vaUnlockSurface = psb_UnlockSurface;
3275 #ifdef PSBVIDEO_MRFL_VPP
3276 ctx->vtable_vpp->vaQueryVideoProcFilters = vsp_QueryVideoProcFilters;
3277 ctx->vtable_vpp->vaQueryVideoProcFilterCaps = vsp_QueryVideoProcFilterCaps;
3278 ctx->vtable_vpp->vaQueryVideoProcPipelineCaps = vsp_QueryVideoProcPipelineCaps;
3279 #endif
3280
3281 #ifdef PSBVIDEO_MFLD
3282 ctx->vtable_vpp->vaQueryVideoProcFilters = ved_QueryVideoProcFilters;
3283 ctx->vtable_vpp->vaQueryVideoProcFilterCaps = ved_QueryVideoProcFilterCaps;
3284 ctx->vtable_vpp->vaQueryVideoProcPipelineCaps = ved_QueryVideoProcPipelineCaps;
3285 #endif
3286
3287 ctx->vtable_tpi = calloc(1, sizeof(struct VADriverVTableTPI));
3288 if (NULL == ctx->vtable_tpi)
3289 return VA_STATUS_ERROR_ALLOCATION_FAILED;
3290
3291 tpi = (struct VADriverVTableTPI *)ctx->vtable_tpi;
3292 tpi->vaCreateSurfacesWithAttribute = psb_CreateSurfacesWithAttribute;
3293 tpi->vaPutSurfaceBuf = psb_PutSurfaceBuf;
3294 tpi->vaSetTimestampForSurface = psb_SetTimestampForSurface;
3295
3296 ctx->vtable_egl = calloc(1, sizeof(struct VADriverVTableEGL));
3297 if (NULL == ctx->vtable_egl)
3298 return VA_STATUS_ERROR_ALLOCATION_FAILED;
3299
3300 va_egl = (struct VADriverVTableEGL *)ctx->vtable_egl;
3301 va_egl->vaGetEGLClientBufferFromSurface = psb_GetEGLClientBufferFromSurface;
3302
3303 driver_data = (psb_driver_data_p) calloc(1, sizeof(*driver_data));
3304 ctx->pDriverData = (unsigned char *) driver_data;
3305 if (NULL == driver_data) {
3306 if (ctx->vtable_tpi)
3307 free(ctx->vtable_tpi);
3308 if (ctx->vtable_egl)
3309 free(ctx->vtable_egl);
3310 return VA_STATUS_ERROR_ALLOCATION_FAILED;
3311 }
3312
3313 if (VA_STATUS_SUCCESS != psb__initDRM(ctx)) {
3314 free(ctx->pDriverData);
3315 ctx->pDriverData = NULL;
3316 return VA_STATUS_ERROR_UNKNOWN;
3317 }
3318
3319 pthread_mutex_init(&driver_data->drm_mutex, NULL);
3320
3321 /*
3322 * To read PBO.MSR.CCF Mode and Status Register C-Spec -p112
3323 */
3324 #define PCI_PORT5_REG80_VIDEO_SD_DISABLE 0x0008
3325 #define PCI_PORT5_REG80_VIDEO_HD_DISABLE 0x0010
3326
3327 #if 0
3328 struct drm_psb_hw_info hw_info;
3329 do {
3330 result = drmCommandRead(driver_data->drm_fd, DRM_PSB_HW_INFO, &hw_info, sizeof(hw_info));
3331 } while (result == EAGAIN);
3332
3333 if (result != 0) {
3334 psb__deinitDRM(ctx);
3335 free(ctx->pDriverData);
3336 ctx->pDriverData = NULL;
3337 return VA_STATUS_ERROR_UNKNOWN;
3338 }
3339
3340 driver_data->video_sd_disabled = !!(hw_info.caps & PCI_PORT5_REG80_VIDEO_SD_DISABLE);
3341 driver_data->video_hd_disabled = !!(hw_info.caps & PCI_PORT5_REG80_VIDEO_HD_DISABLE);
3342 drv_debug_msg(VIDEO_DEBUG_GENERAL, "hw_info: rev_id = %08x capabilities = %08x\n", hw_info.rev_id, hw_info.caps);
3343 drv_debug_msg(VIDEO_DEBUG_GENERAL, "hw_info: video_sd_disable=%d,video_hd_disable=%d\n",
3344 driver_data->video_sd_disabled, driver_data->video_hd_disabled);
3345 if (driver_data->video_sd_disabled != 0) {
3346 drv_debug_msg(VIDEO_DEBUG_ERROR, "MRST: hw_info shows video_sd_disable is true,fix it manually\n");
3347 driver_data->video_sd_disabled = 0;
3348 }
3349 if (driver_data->video_hd_disabled != 0) {
3350 drv_debug_msg(VIDEO_DEBUG_ERROR, "MRST: hw_info shows video_hd_disable is true,fix it manually\n");
3351 driver_data->video_hd_disabled = 0;
3352 }
3353 #endif
3354
3355 if (0 != psb_get_device_info(ctx)) {
3356 drv_debug_msg(VIDEO_DEBUG_ERROR, "ERROR: failed to get video device info\n");
3357 driver_data->encode_supported = 1;
3358 driver_data->decode_supported = 1;
3359 driver_data->hd_encode_supported = 1;
3360 driver_data->hd_decode_supported = 1;
3361 }
3362
3363 #if 0
3364 psb_init_surface_pvr2dbuf(driver_data);
3365 #endif
3366
3367 if (VA_STATUS_SUCCESS != psb_initOutput(ctx)) {
3368 pthread_mutex_destroy(&driver_data->drm_mutex);
3369 psb__deinitDRM(ctx);
3370 free(ctx->pDriverData);
3371 ctx->pDriverData = NULL;
3372 return VA_STATUS_ERROR_UNKNOWN;
3373 }
3374
3375 driver_data->msvdx_context_base = (((unsigned int) getpid()) & 0xffff) << 16;
3376 #ifdef PSBVIDEO_MRFL
3377 if (IS_MRFL(driver_data)) {
3378 drv_debug_msg(VIDEO_DEBUG_GENERAL, "merrifield topazhp encoder\n");
3379 driver_data->profile2Format[VAProfileH264Baseline][VAEntrypointEncSlice] = &tng_H264ES_vtable;
3380 driver_data->profile2Format[VAProfileH264Main][VAEntrypointEncSlice] = &tng_H264ES_vtable;
3381 driver_data->profile2Format[VAProfileH264High][VAEntrypointEncSlice] = &tng_H264ES_vtable;
3382 driver_data->profile2Format[VAProfileH264StereoHigh][VAEntrypointEncSlice] = &tng_H264ES_vtable;
3383 driver_data->profile2Format[VAProfileH263Baseline][VAEntrypointEncSlice] = &tng_H263ES_vtable;
3384 driver_data->profile2Format[VAProfileJPEGBaseline][VAEntrypointEncPicture] = &tng_JPEGES_vtable;
3385 driver_data->profile2Format[VAProfileMPEG4Simple][VAEntrypointEncSlice] = &tng_MPEG4ES_vtable;
3386 driver_data->profile2Format[VAProfileMPEG4AdvancedSimple][VAEntrypointEncSlice] = &tng_MPEG4ES_vtable;
3387 driver_data->profile2Format[VAProfileH264ConstrainedBaseline][VAEntrypointEncSlice] = &tng_H264ES_vtable;
3388 }
3389 #endif
3390 #ifdef PSBVIDEO_MRFL_VPP
3391 if (IS_MRFL(driver_data)) {
3392 drv_debug_msg(VIDEO_DEBUG_GENERAL, "merrifield vsp vpp\n");
3393 driver_data->vpp_profile = &vsp_VPP_vtable;
3394 driver_data->profile2Format[VAProfileVP8Version0_3][VAEntrypointEncSlice] = &vsp_VP8_vtable;
3395 }
3396 #endif
3397
3398 #ifdef PSBVIDEO_VXD392
3399 if (IS_MRFL(driver_data) || IS_BAYTRAIL(driver_data)) {
3400 drv_debug_msg(VIDEO_DEBUG_GENERAL, "merrifield VXD392 decoder\n");
3401 driver_data->profile2Format[VAProfileVP8Version0_3][VAEntrypointVLD] = &tng_VP8_vtable;
3402 driver_data->profile2Format[VAProfileJPEGBaseline][VAEntrypointVLD] = &tng_JPEG_vtable;
3403
3404 driver_data->profile2Format[VAProfileMPEG4Simple][VAEntrypointVLD] = &pnw_MPEG4_vtable;
3405 driver_data->profile2Format[VAProfileMPEG4AdvancedSimple][VAEntrypointVLD] = &pnw_MPEG4_vtable;
3406
3407 driver_data->profile2Format[VAProfileMPEG2Simple][VAEntrypointVLD] = &pnw_MPEG2_vtable;
3408 driver_data->profile2Format[VAProfileMPEG2Main][VAEntrypointVLD] = &pnw_MPEG2_vtable;
3409
3410 driver_data->profile2Format[VAProfileH263Baseline][VAEntrypointVLD] = &pnw_MPEG4_vtable;
3411
3412 driver_data->profile2Format[VAProfileH264Baseline][VAEntrypointVLD] = &pnw_H264_vtable;
3413 driver_data->profile2Format[VAProfileH264Main][VAEntrypointVLD] = &pnw_H264_vtable;
3414 driver_data->profile2Format[VAProfileH264High][VAEntrypointVLD] = &pnw_H264_vtable;
3415
3416 driver_data->profile2Format[VAProfileVC1Simple][VAEntrypointVLD] = &pnw_VC1_vtable;
3417 driver_data->profile2Format[VAProfileVC1Main][VAEntrypointVLD] = &pnw_VC1_vtable;
3418 driver_data->profile2Format[VAProfileVC1Advanced][VAEntrypointVLD] = &pnw_VC1_vtable;
3419 driver_data->profile2Format[VAProfileH264ConstrainedBaseline][VAEntrypointVLD] = &pnw_H264_vtable;
3420 }
3421 #endif
3422
3423 #ifdef PSBVIDEO_MRFL_VPP
3424 if (IS_MRFL(driver_data)) {
3425 if (*((unsigned int *)ctx->native_dpy) == 0x56454450 /* VEDP */) {
3426
3427 drv_debug_msg(VIDEO_DEBUG_GENERAL, "merrifield ved vpp\n");
3428 driver_data->vpp_profile = &tng_yuv_processor_vtable;
3429 ctx->vtable_vpp->vaQueryVideoProcFilters = ved_QueryVideoProcFilters;
3430 ctx->vtable_vpp->vaQueryVideoProcFilterCaps = ved_QueryVideoProcFilterCaps;
3431 ctx->vtable_vpp->vaQueryVideoProcPipelineCaps = ved_QueryVideoProcPipelineCaps;
3432 driver_data->ved_vpp = 1;
3433 }
3434 }
3435 #endif
3436
3437 #ifdef PSBVIDEO_MFLD
3438 if (IS_MFLD(driver_data)) {
3439 driver_data->profile2Format[VAProfileH263Baseline][VAEntrypointEncSlice] = &pnw_H263ES_vtable;
3440 driver_data->profile2Format[VAProfileH264Baseline][VAEntrypointEncSlice] = &pnw_H264ES_vtable;
3441 driver_data->profile2Format[VAProfileH264Main][VAEntrypointEncSlice] = &pnw_H264ES_vtable;
3442 driver_data->profile2Format[VAProfileMPEG4Simple][VAEntrypointEncSlice] = &pnw_MPEG4ES_vtable;
3443 driver_data->profile2Format[VAProfileMPEG4AdvancedSimple][VAEntrypointEncSlice] = &pnw_MPEG4ES_vtable;
3444 driver_data->profile2Format[VAProfileJPEGBaseline][VAEntrypointEncPicture] = &pnw_JPEG_vtable;
3445
3446 driver_data->profile2Format[VAProfileMPEG2Main][VAEntrypointVLD] = &pnw_MPEG2_vtable;
3447
3448 driver_data->profile2Format[VAProfileMPEG4Simple][VAEntrypointVLD] = &pnw_MPEG4_vtable;
3449 driver_data->profile2Format[VAProfileMPEG4AdvancedSimple][VAEntrypointVLD] = &pnw_MPEG4_vtable;
3450
3451 driver_data->profile2Format[VAProfileMPEG2Simple][VAEntrypointVLD] = &pnw_MPEG2_vtable;
3452 driver_data->profile2Format[VAProfileMPEG2Main][VAEntrypointVLD] = &pnw_MPEG2_vtable;
3453
3454 driver_data->profile2Format[VAProfileH263Baseline][VAEntrypointVLD] = &pnw_MPEG4_vtable;
3455
3456 driver_data->profile2Format[VAProfileH264Baseline][VAEntrypointVLD] = &pnw_H264_vtable;
3457 driver_data->profile2Format[VAProfileH264Main][VAEntrypointVLD] = &pnw_H264_vtable;
3458 driver_data->profile2Format[VAProfileH264High][VAEntrypointVLD] = &pnw_H264_vtable;
3459
3460 driver_data->profile2Format[VAProfileVC1Simple][VAEntrypointVLD] = &pnw_VC1_vtable;
3461 driver_data->profile2Format[VAProfileVC1Main][VAEntrypointVLD] = &pnw_VC1_vtable;
3462 driver_data->profile2Format[VAProfileVC1Advanced][VAEntrypointVLD] = &pnw_VC1_vtable;
3463 driver_data->profile2Format[VAProfileH264ConstrainedBaseline][VAEntrypointVLD] = &pnw_H264_vtable;
3464
3465 driver_data->vpp_profile = &tng_yuv_processor_vtable;
3466 driver_data->ved_vpp = 1;
3467 }
3468 #endif
3469
3470 result = object_heap_init(&driver_data->config_heap, sizeof(struct object_config_s), CONFIG_ID_OFFSET);
3471 ASSERT(result == 0);
3472
3473 result = object_heap_init(&driver_data->context_heap, sizeof(struct object_context_s), CONTEXT_ID_OFFSET);
3474 ASSERT(result == 0);
3475
3476 result = object_heap_init(&driver_data->surface_heap, sizeof(struct object_surface_s), SURFACE_ID_OFFSET);
3477 ASSERT(result == 0);
3478
3479 result = object_heap_init(&driver_data->buffer_heap, sizeof(struct object_buffer_s), BUFFER_ID_OFFSET);
3480 ASSERT(result == 0);
3481
3482 result = object_heap_init(&driver_data->image_heap, sizeof(struct object_image_s), IMAGE_ID_OFFSET);
3483 ASSERT(result == 0);
3484
3485 result = object_heap_init(&driver_data->subpic_heap, sizeof(struct object_subpic_s), SUBPIC_ID_OFFSET);
3486 ASSERT(result == 0);
3487
3488 driver_data->cur_displaying_surface = VA_INVALID_SURFACE;
3489 driver_data->last_displaying_surface = VA_INVALID_SURFACE;
3490
3491 driver_data->clear_color = 0;
3492 driver_data->blend_color = 0;
3493 driver_data->blend_mode = 0;
3494 driver_data->overlay_auto_paint_color_key = 0;
3495
3496 if (IS_BAYTRAIL(driver_data))
3497 ctx->str_vendor = PSB_STR_VENDOR_BAYTRAIL;
3498 if (IS_MRFL(driver_data))
3499 ctx->str_vendor = PSB_STR_VENDOR_MRFL;
3500 else if (IS_MFLD(driver_data))
3501 {
3502 if (IS_LEXINGTON(driver_data))
3503 ctx->str_vendor = PSB_STR_VENDOR_LEXINGTON;
3504 else
3505 ctx->str_vendor = PSB_STR_VENDOR_MFLD;
3506 }
3507 else
3508 ctx->str_vendor = PSB_STR_VENDOR_MRST;
3509
3510 driver_data->msvdx_decode_status = calloc(1, sizeof(drm_psb_msvdx_decode_status_t));
3511 if (NULL == driver_data->msvdx_decode_status) {
3512 pthread_mutex_destroy(&driver_data->drm_mutex);
3513 return VA_STATUS_ERROR_ALLOCATION_FAILED;
3514 }
3515 driver_data->surface_mb_error = calloc(MAX_MB_ERRORS, sizeof(VASurfaceDecodeMBErrors));
3516 if (NULL == driver_data->surface_mb_error) {
3517 pthread_mutex_destroy(&driver_data->drm_mutex);
3518 return VA_STATUS_ERROR_ALLOCATION_FAILED;
3519 }
3520
3521 drv_debug_msg(VIDEO_DEBUG_INIT, "vaInitilize: succeeded!\n\n");
3522
3523 #ifdef ANDROID
3524 #ifndef PSBVIDEO_VXD392
3525 gralloc_init();
3526 #endif
3527 #endif
3528
3529 return VA_STATUS_SUCCESS;
3530 }
3531
3532
3533 EXPORT VAStatus __vaDriverInit_0_32(VADriverContextP ctx)
3534 {
3535 return __vaDriverInit_0_31(ctx);
3536 }
3537
3538
3539
3540 static int psb_get_device_info(VADriverContextP ctx)
3541 {
3542 INIT_DRIVER_DATA;
3543 struct drm_lnc_video_getparam_arg arg;
3544 unsigned long device_info;
3545 int ret = 0;
3546 unsigned long video_capability;
3547 unsigned long pci_device;
3548
3549 driver_data->dev_id = 0x4100; /* by default MRST */
3550
3551 arg.key = LNC_VIDEO_DEVICE_INFO;
3552 arg.value = (uint64_t)((unsigned long) & device_info);
3553 ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset,
3554 &arg, sizeof(arg));
3555 if (ret != 0) {
3556 drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to get video device info\n");
3557 return ret;
3558 }
3559
3560 pci_device = (device_info >> 16) & 0xffff;
3561 video_capability = device_info & 0xffff;
3562
3563 driver_data->dev_id = pci_device;
3564 drv_debug_msg(VIDEO_DEBUG_INIT, "Retrieve Device ID 0x%08x\n", driver_data->dev_id);
3565
3566 if (IS_MFLD(driver_data) || IS_MRFL(driver_data))
3567 driver_data->encode_supported = 1;
3568 else /* 0x4101 or other device hasn't encode support */
3569 driver_data->encode_supported = 0;
3570
3571 driver_data->decode_supported = 1;
3572 driver_data->hd_decode_supported = 1;
3573 driver_data->hd_encode_supported = 1;
3574
3575 return ret;
3576 }
3577