1b8e80941Smrg/**************************************************************************
2b8e80941Smrg *
3b8e80941Smrg * Copyright 2010 Thomas Balling Sørensen & Orasanu Lucian.
4b8e80941Smrg * Copyright 2014 Advanced Micro Devices, Inc.
5b8e80941Smrg * All Rights Reserved.
6b8e80941Smrg *
7b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a
8b8e80941Smrg * copy of this software and associated documentation files (the
9b8e80941Smrg * "Software"), to deal in the Software without restriction, including
10b8e80941Smrg * without limitation the rights to use, copy, modify, merge, publish,
11b8e80941Smrg * distribute, sub license, and/or sell copies of the Software, and to
12b8e80941Smrg * permit persons to whom the Software is furnished to do so, subject to
13b8e80941Smrg * the following conditions:
14b8e80941Smrg *
15b8e80941Smrg * The above copyright notice and this permission notice (including the
16b8e80941Smrg * next paragraph) shall be included in all copies or substantial portions
17b8e80941Smrg * of the Software.
18b8e80941Smrg *
19b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20b8e80941Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21b8e80941Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22b8e80941Smrg * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
23b8e80941Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24b8e80941Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25b8e80941Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26b8e80941Smrg *
27b8e80941Smrg **************************************************************************/
28b8e80941Smrg
29b8e80941Smrg#include "pipe/p_screen.h"
30b8e80941Smrg
31b8e80941Smrg#include "util/u_video.h"
32b8e80941Smrg#include "util/u_memory.h"
33b8e80941Smrg
34b8e80941Smrg#include "vl/vl_winsys.h"
35b8e80941Smrg
36b8e80941Smrg#include "va_private.h"
37b8e80941Smrg
38b8e80941Smrg#include "util/u_handle_table.h"
39b8e80941Smrg
40b8e80941SmrgDEBUG_GET_ONCE_BOOL_OPTION(mpeg4, "VAAPI_MPEG4_ENABLED", false)
41b8e80941Smrg
42b8e80941SmrgVAStatus
43b8e80941SmrgvlVaQueryConfigProfiles(VADriverContextP ctx, VAProfile *profile_list, int *num_profiles)
44b8e80941Smrg{
45b8e80941Smrg   struct pipe_screen *pscreen;
46b8e80941Smrg   enum pipe_video_profile p;
47b8e80941Smrg   VAProfile vap;
48b8e80941Smrg
49b8e80941Smrg   if (!ctx)
50b8e80941Smrg      return VA_STATUS_ERROR_INVALID_CONTEXT;
51b8e80941Smrg
52b8e80941Smrg   *num_profiles = 0;
53b8e80941Smrg
54b8e80941Smrg   pscreen = VL_VA_PSCREEN(ctx);
55b8e80941Smrg   for (p = PIPE_VIDEO_PROFILE_MPEG2_SIMPLE; p <= PIPE_VIDEO_PROFILE_VP9_PROFILE2; ++p) {
56b8e80941Smrg      if (u_reduce_video_profile(p) == PIPE_VIDEO_FORMAT_MPEG4 && !debug_get_option_mpeg4())
57b8e80941Smrg         continue;
58b8e80941Smrg
59b8e80941Smrg      if (pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) {
60b8e80941Smrg         vap = PipeToProfile(p);
61b8e80941Smrg         if (vap != VAProfileNone)
62b8e80941Smrg            profile_list[(*num_profiles)++] = vap;
63b8e80941Smrg      }
64b8e80941Smrg   }
65b8e80941Smrg
66b8e80941Smrg   /* Support postprocessing through vl_compositor */
67b8e80941Smrg   profile_list[(*num_profiles)++] = VAProfileNone;
68b8e80941Smrg
69b8e80941Smrg   return VA_STATUS_SUCCESS;
70b8e80941Smrg}
71b8e80941Smrg
72b8e80941SmrgVAStatus
73b8e80941SmrgvlVaQueryConfigEntrypoints(VADriverContextP ctx, VAProfile profile,
74b8e80941Smrg                           VAEntrypoint *entrypoint_list, int *num_entrypoints)
75b8e80941Smrg{
76b8e80941Smrg   struct pipe_screen *pscreen;
77b8e80941Smrg   enum pipe_video_profile p;
78b8e80941Smrg
79b8e80941Smrg   if (!ctx)
80b8e80941Smrg      return VA_STATUS_ERROR_INVALID_CONTEXT;
81b8e80941Smrg
82b8e80941Smrg   *num_entrypoints = 0;
83b8e80941Smrg
84b8e80941Smrg   if (profile == VAProfileNone) {
85b8e80941Smrg      entrypoint_list[(*num_entrypoints)++] = VAEntrypointVideoProc;
86b8e80941Smrg      return VA_STATUS_SUCCESS;
87b8e80941Smrg   }
88b8e80941Smrg
89b8e80941Smrg   p = ProfileToPipe(profile);
90b8e80941Smrg   if (p == PIPE_VIDEO_PROFILE_UNKNOWN)
91b8e80941Smrg      return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
92b8e80941Smrg
93b8e80941Smrg   pscreen = VL_VA_PSCREEN(ctx);
94b8e80941Smrg   if (pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
95b8e80941Smrg				PIPE_VIDEO_CAP_SUPPORTED))
96b8e80941Smrg      entrypoint_list[(*num_entrypoints)++] = VAEntrypointVLD;
97b8e80941Smrg
98b8e80941Smrg   if (pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_ENCODE,
99b8e80941Smrg				PIPE_VIDEO_CAP_SUPPORTED))
100b8e80941Smrg      entrypoint_list[(*num_entrypoints)++] = VAEntrypointEncSlice;
101b8e80941Smrg
102b8e80941Smrg   if (num_entrypoints == 0)
103b8e80941Smrg      return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
104b8e80941Smrg
105b8e80941Smrg   assert(*num_entrypoints <= ctx->max_entrypoints);
106b8e80941Smrg
107b8e80941Smrg   return VA_STATUS_SUCCESS;
108b8e80941Smrg}
109b8e80941Smrg
110b8e80941SmrgVAStatus
111b8e80941SmrgvlVaGetConfigAttributes(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoint,
112b8e80941Smrg                        VAConfigAttrib *attrib_list, int num_attribs)
113b8e80941Smrg{
114b8e80941Smrg   struct pipe_screen *pscreen;
115b8e80941Smrg   int i;
116b8e80941Smrg
117b8e80941Smrg   if (!ctx)
118b8e80941Smrg      return VA_STATUS_ERROR_INVALID_CONTEXT;
119b8e80941Smrg
120b8e80941Smrg   pscreen = VL_VA_PSCREEN(ctx);
121b8e80941Smrg
122b8e80941Smrg   for (i = 0; i < num_attribs; ++i) {
123b8e80941Smrg      unsigned int value;
124b8e80941Smrg      if (entrypoint == VAEntrypointVLD) {
125b8e80941Smrg         switch (attrib_list[i].type) {
126b8e80941Smrg         case VAConfigAttribRTFormat:
127b8e80941Smrg            value = VA_RT_FORMAT_YUV420;
128b8e80941Smrg	    if (pscreen->is_video_format_supported(pscreen, PIPE_FORMAT_P016,
129b8e80941Smrg                                                   ProfileToPipe(profile),
130b8e80941Smrg                                                   PIPE_VIDEO_ENTRYPOINT_BITSTREAM))
131b8e80941Smrg		value |= VA_RT_FORMAT_YUV420_10BPP;
132b8e80941Smrg            break;
133b8e80941Smrg         default:
134b8e80941Smrg            value = VA_ATTRIB_NOT_SUPPORTED;
135b8e80941Smrg            break;
136b8e80941Smrg         }
137b8e80941Smrg      } else if (entrypoint == VAEntrypointEncSlice) {
138b8e80941Smrg         switch (attrib_list[i].type) {
139b8e80941Smrg         case VAConfigAttribRTFormat:
140b8e80941Smrg            value = VA_RT_FORMAT_YUV420;
141b8e80941Smrg            break;
142b8e80941Smrg         case VAConfigAttribRateControl:
143b8e80941Smrg            value = VA_RC_CQP | VA_RC_CBR | VA_RC_VBR;
144b8e80941Smrg            break;
145b8e80941Smrg         case VAConfigAttribEncPackedHeaders:
146b8e80941Smrg            value = 0;
147b8e80941Smrg            break;
148b8e80941Smrg         case VAConfigAttribEncMaxRefFrames:
149b8e80941Smrg            value = 1;
150b8e80941Smrg            break;
151b8e80941Smrg         default:
152b8e80941Smrg            value = VA_ATTRIB_NOT_SUPPORTED;
153b8e80941Smrg            break;
154b8e80941Smrg         }
155b8e80941Smrg      } else if (entrypoint == VAEntrypointVideoProc) {
156b8e80941Smrg         switch (attrib_list[i].type) {
157b8e80941Smrg         case VAConfigAttribRTFormat:
158b8e80941Smrg            value = (VA_RT_FORMAT_YUV420 |
159b8e80941Smrg                     VA_RT_FORMAT_YUV420_10BPP |
160b8e80941Smrg                     VA_RT_FORMAT_RGB32);
161b8e80941Smrg            break;
162b8e80941Smrg         default:
163b8e80941Smrg            value = VA_ATTRIB_NOT_SUPPORTED;
164b8e80941Smrg            break;
165b8e80941Smrg         }
166b8e80941Smrg      } else {
167b8e80941Smrg         value = VA_ATTRIB_NOT_SUPPORTED;
168b8e80941Smrg      }
169b8e80941Smrg      attrib_list[i].value = value;
170b8e80941Smrg   }
171b8e80941Smrg
172b8e80941Smrg   return VA_STATUS_SUCCESS;
173b8e80941Smrg}
174b8e80941Smrg
175b8e80941SmrgVAStatus
176b8e80941SmrgvlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoint,
177b8e80941Smrg                 VAConfigAttrib *attrib_list, int num_attribs, VAConfigID *config_id)
178b8e80941Smrg{
179b8e80941Smrg   vlVaDriver *drv;
180b8e80941Smrg   vlVaConfig *config;
181b8e80941Smrg   struct pipe_screen *pscreen;
182b8e80941Smrg   enum pipe_video_profile p;
183b8e80941Smrg   unsigned int supported_rt_formats;
184b8e80941Smrg
185b8e80941Smrg   if (!ctx)
186b8e80941Smrg      return VA_STATUS_ERROR_INVALID_CONTEXT;
187b8e80941Smrg
188b8e80941Smrg   drv = VL_VA_DRIVER(ctx);
189b8e80941Smrg
190b8e80941Smrg   if (!drv)
191b8e80941Smrg      return VA_STATUS_ERROR_INVALID_CONTEXT;
192b8e80941Smrg
193b8e80941Smrg   config = CALLOC(1, sizeof(vlVaConfig));
194b8e80941Smrg   if (!config)
195b8e80941Smrg      return VA_STATUS_ERROR_ALLOCATION_FAILED;
196b8e80941Smrg
197b8e80941Smrg   if (profile == VAProfileNone && entrypoint == VAEntrypointVideoProc) {
198b8e80941Smrg      config->entrypoint = PIPE_VIDEO_ENTRYPOINT_UNKNOWN;
199b8e80941Smrg      config->profile = PIPE_VIDEO_PROFILE_UNKNOWN;
200b8e80941Smrg      supported_rt_formats = VA_RT_FORMAT_YUV420 |
201b8e80941Smrg                             VA_RT_FORMAT_YUV420_10BPP |
202b8e80941Smrg                             VA_RT_FORMAT_RGB32;
203b8e80941Smrg      for (int i = 0; i < num_attribs; i++) {
204b8e80941Smrg         if (attrib_list[i].type == VAConfigAttribRTFormat) {
205b8e80941Smrg            if (attrib_list[i].value & supported_rt_formats) {
206b8e80941Smrg               config->rt_format = attrib_list[i].value;
207b8e80941Smrg            } else {
208b8e80941Smrg               FREE(config);
209b8e80941Smrg               return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
210b8e80941Smrg            }
211b8e80941Smrg         }
212b8e80941Smrg      }
213b8e80941Smrg
214b8e80941Smrg      /* Default value if not specified in the input attributes. */
215b8e80941Smrg      if (!config->rt_format)
216b8e80941Smrg         config->rt_format = supported_rt_formats;
217b8e80941Smrg
218b8e80941Smrg      mtx_lock(&drv->mutex);
219b8e80941Smrg      *config_id = handle_table_add(drv->htab, config);
220b8e80941Smrg      mtx_unlock(&drv->mutex);
221b8e80941Smrg      return VA_STATUS_SUCCESS;
222b8e80941Smrg   }
223b8e80941Smrg
224b8e80941Smrg   p = ProfileToPipe(profile);
225b8e80941Smrg   if (p == PIPE_VIDEO_PROFILE_UNKNOWN) {
226b8e80941Smrg      FREE(config);
227b8e80941Smrg      return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
228b8e80941Smrg   }
229b8e80941Smrg
230b8e80941Smrg   pscreen = VL_VA_PSCREEN(ctx);
231b8e80941Smrg
232b8e80941Smrg   switch (entrypoint) {
233b8e80941Smrg   case VAEntrypointVLD:
234b8e80941Smrg      if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
235b8e80941Smrg				    PIPE_VIDEO_CAP_SUPPORTED)) {
236b8e80941Smrg         FREE(config);
237b8e80941Smrg         return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
238b8e80941Smrg      }
239b8e80941Smrg
240b8e80941Smrg      config->entrypoint = PIPE_VIDEO_ENTRYPOINT_BITSTREAM;
241b8e80941Smrg      break;
242b8e80941Smrg
243b8e80941Smrg   case VAEntrypointEncSlice:
244b8e80941Smrg      if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_ENCODE,
245b8e80941Smrg				    PIPE_VIDEO_CAP_SUPPORTED)) {
246b8e80941Smrg         FREE(config);
247b8e80941Smrg         return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
248b8e80941Smrg      }
249b8e80941Smrg
250b8e80941Smrg      config->entrypoint = PIPE_VIDEO_ENTRYPOINT_ENCODE;
251b8e80941Smrg      break;
252b8e80941Smrg
253b8e80941Smrg   default:
254b8e80941Smrg      FREE(config);
255b8e80941Smrg      return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
256b8e80941Smrg   }
257b8e80941Smrg
258b8e80941Smrg   config->profile = p;
259b8e80941Smrg   supported_rt_formats = VA_RT_FORMAT_YUV420;
260b8e80941Smrg   if (pscreen->is_video_format_supported(pscreen, PIPE_FORMAT_P016, p,
261b8e80941Smrg					  config->entrypoint))
262b8e80941Smrg      supported_rt_formats |= VA_RT_FORMAT_YUV420_10BPP;
263b8e80941Smrg
264b8e80941Smrg   for (int i = 0; i <num_attribs ; i++) {
265b8e80941Smrg      if (attrib_list[i].type == VAConfigAttribRateControl) {
266b8e80941Smrg         if (attrib_list[i].value == VA_RC_CBR)
267b8e80941Smrg            config->rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_CONSTANT;
268b8e80941Smrg         else if (attrib_list[i].value == VA_RC_VBR)
269b8e80941Smrg            config->rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_VARIABLE;
270b8e80941Smrg         else
271b8e80941Smrg            config->rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_DISABLE;
272b8e80941Smrg      }
273b8e80941Smrg      if (attrib_list[i].type == VAConfigAttribRTFormat) {
274b8e80941Smrg         if (attrib_list[i].value & supported_rt_formats) {
275b8e80941Smrg            config->rt_format = attrib_list[i].value;
276b8e80941Smrg         } else {
277b8e80941Smrg            FREE(config);
278b8e80941Smrg            return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
279b8e80941Smrg         }
280b8e80941Smrg      }
281b8e80941Smrg   }
282b8e80941Smrg
283b8e80941Smrg   /* Default value if not specified in the input attributes. */
284b8e80941Smrg   if (!config->rt_format)
285b8e80941Smrg      config->rt_format = supported_rt_formats;
286b8e80941Smrg
287b8e80941Smrg   mtx_lock(&drv->mutex);
288b8e80941Smrg   *config_id = handle_table_add(drv->htab, config);
289b8e80941Smrg   mtx_unlock(&drv->mutex);
290b8e80941Smrg
291b8e80941Smrg   return VA_STATUS_SUCCESS;
292b8e80941Smrg}
293b8e80941Smrg
294b8e80941SmrgVAStatus
295b8e80941SmrgvlVaDestroyConfig(VADriverContextP ctx, VAConfigID config_id)
296b8e80941Smrg{
297b8e80941Smrg   vlVaDriver *drv;
298b8e80941Smrg   vlVaConfig *config;
299b8e80941Smrg
300b8e80941Smrg   if (!ctx)
301b8e80941Smrg      return VA_STATUS_ERROR_INVALID_CONTEXT;
302b8e80941Smrg
303b8e80941Smrg   drv = VL_VA_DRIVER(ctx);
304b8e80941Smrg
305b8e80941Smrg   if (!drv)
306b8e80941Smrg      return VA_STATUS_ERROR_INVALID_CONTEXT;
307b8e80941Smrg
308b8e80941Smrg   mtx_lock(&drv->mutex);
309b8e80941Smrg   config = handle_table_get(drv->htab, config_id);
310b8e80941Smrg
311b8e80941Smrg   if (!config) {
312b8e80941Smrg      mtx_unlock(&drv->mutex);
313b8e80941Smrg      return VA_STATUS_ERROR_INVALID_CONFIG;
314b8e80941Smrg   }
315b8e80941Smrg
316b8e80941Smrg   FREE(config);
317b8e80941Smrg   handle_table_remove(drv->htab, config_id);
318b8e80941Smrg   mtx_unlock(&drv->mutex);
319b8e80941Smrg
320b8e80941Smrg   return VA_STATUS_SUCCESS;
321b8e80941Smrg}
322b8e80941Smrg
323b8e80941SmrgVAStatus
324b8e80941SmrgvlVaQueryConfigAttributes(VADriverContextP ctx, VAConfigID config_id, VAProfile *profile,
325b8e80941Smrg                          VAEntrypoint *entrypoint, VAConfigAttrib *attrib_list, int *num_attribs)
326b8e80941Smrg{
327b8e80941Smrg   vlVaDriver *drv;
328b8e80941Smrg   vlVaConfig *config;
329b8e80941Smrg
330b8e80941Smrg   if (!ctx)
331b8e80941Smrg      return VA_STATUS_ERROR_INVALID_CONTEXT;
332b8e80941Smrg
333b8e80941Smrg   drv = VL_VA_DRIVER(ctx);
334b8e80941Smrg
335b8e80941Smrg   if (!drv)
336b8e80941Smrg      return VA_STATUS_ERROR_INVALID_CONTEXT;
337b8e80941Smrg
338b8e80941Smrg   mtx_lock(&drv->mutex);
339b8e80941Smrg   config = handle_table_get(drv->htab, config_id);
340b8e80941Smrg   mtx_unlock(&drv->mutex);
341b8e80941Smrg
342b8e80941Smrg   if (!config)
343b8e80941Smrg      return VA_STATUS_ERROR_INVALID_CONFIG;
344b8e80941Smrg
345b8e80941Smrg   *profile = PipeToProfile(config->profile);
346b8e80941Smrg
347b8e80941Smrg   switch (config->entrypoint) {
348b8e80941Smrg   case PIPE_VIDEO_ENTRYPOINT_BITSTREAM:
349b8e80941Smrg      *entrypoint = VAEntrypointVLD;
350b8e80941Smrg      break;
351b8e80941Smrg   case PIPE_VIDEO_ENTRYPOINT_ENCODE:
352b8e80941Smrg      *entrypoint = VAEntrypointEncSlice;
353b8e80941Smrg      break;
354b8e80941Smrg   case PIPE_VIDEO_ENTRYPOINT_UNKNOWN:
355b8e80941Smrg      *entrypoint = VAEntrypointVideoProc;
356b8e80941Smrg      break;
357b8e80941Smrg   default:
358b8e80941Smrg      return VA_STATUS_ERROR_INVALID_CONFIG;
359b8e80941Smrg   }
360b8e80941Smrg
361b8e80941Smrg   *num_attribs = 1;
362b8e80941Smrg   attrib_list[0].type = VAConfigAttribRTFormat;
363b8e80941Smrg   attrib_list[0].value = config->rt_format;
364b8e80941Smrg
365b8e80941Smrg   return VA_STATUS_SUCCESS;
366b8e80941Smrg}
367