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