2 * Copyright © 2014 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sub license, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 #include "i965_drv_video.h"
35 /* Extra set of chroma formats supported for H.264 decoding (beyond YUV 4:2:0) */
36 #define EXTRA_H264_DEC_CHROMA_FORMATS \
39 /* Extra set of chroma formats supported for JPEG decoding (beyond YUV 4:2:0) */
40 #define EXTRA_JPEG_DEC_CHROMA_FORMATS \
41 (VA_RT_FORMAT_YUV400 | VA_RT_FORMAT_YUV411 | VA_RT_FORMAT_YUV422 | \
44 /* Extra set of chroma formats supported for JPEG encoding (beyond YUV 4:2:0) */
45 #define EXTRA_JPEG_ENC_CHROMA_FORMATS \
46 (VA_RT_FORMAT_YUV400| VA_RT_FORMAT_YUV422 | VA_RT_FORMAT_YUV444)
48 /* Defines VA profile as a 32-bit unsigned integer mask */
49 #define VA_PROFILE_MASK(PROFILE) \
50 (1U << VAProfile##PROFILE)
52 extern struct hw_context *i965_proc_context_init(VADriverContextP, struct object_config *);
53 extern struct hw_context *g4x_dec_hw_context_init(VADriverContextP, struct object_config *);
54 extern bool genx_render_init(VADriverContextP);
56 static struct hw_codec_info g4x_hw_codec_info = {
57 .dec_hw_context_init = g4x_dec_hw_context_init,
58 .enc_hw_context_init = NULL,
59 .proc_hw_context_init = NULL,
60 .render_init = genx_render_init,
61 .post_processing_context_init = NULL,
65 .min_linear_wpitch = 16,
66 .min_linear_hpitch = 16,
68 .has_mpeg2_decoding = 1,
73 extern struct hw_context *ironlake_dec_hw_context_init(VADriverContextP, struct object_config *);
74 extern void i965_post_processing_context_init(VADriverContextP, void *, struct intel_batchbuffer *);
76 static struct hw_codec_info ilk_hw_codec_info = {
77 .dec_hw_context_init = ironlake_dec_hw_context_init,
78 .enc_hw_context_init = NULL,
79 .proc_hw_context_init = i965_proc_context_init,
80 .render_init = genx_render_init,
81 .post_processing_context_init = i965_post_processing_context_init,
85 .min_linear_wpitch = 16,
86 .min_linear_hpitch = 16,
88 .has_mpeg2_decoding = 1,
89 .has_h264_decoding = 1,
91 .has_accelerated_putimage = 1,
96 static void gen6_hw_codec_preinit(VADriverContextP ctx, struct hw_codec_info *codec_info);
98 extern struct hw_context *gen6_dec_hw_context_init(VADriverContextP, struct object_config *);
99 extern struct hw_context *gen6_enc_hw_context_init(VADriverContextP, struct object_config *);
100 static struct hw_codec_info snb_hw_codec_info = {
101 .dec_hw_context_init = gen6_dec_hw_context_init,
102 .enc_hw_context_init = gen6_enc_hw_context_init,
103 .proc_hw_context_init = i965_proc_context_init,
104 .render_init = genx_render_init,
105 .post_processing_context_init = i965_post_processing_context_init,
106 .preinit_hw_codec = gen6_hw_codec_preinit,
110 .min_linear_wpitch = 16,
111 .min_linear_hpitch = 16,
113 .h264_mvc_dec_profiles = VA_PROFILE_MASK(H264StereoHigh),
114 .h264_dec_chroma_formats = EXTRA_H264_DEC_CHROMA_FORMATS,
116 .has_mpeg2_decoding = 1,
117 .has_h264_decoding = 1,
118 .has_h264_encoding = 1,
119 .has_vc1_decoding = 1,
121 .has_accelerated_getimage = 1,
122 .has_accelerated_putimage = 1,
123 .has_tiled_surface = 1,
124 .has_di_motion_adptive = 1,
128 { VAProcFilterNoiseReduction, I965_RING_NULL },
129 { VAProcFilterDeinterlacing, I965_RING_NULL },
133 static void gen7_hw_codec_preinit(VADriverContextP ctx, struct hw_codec_info *codec_info);
135 extern struct hw_context *gen7_dec_hw_context_init(VADriverContextP, struct object_config *);
136 extern struct hw_context *gen7_enc_hw_context_init(VADriverContextP, struct object_config *);
137 static struct hw_codec_info ivb_hw_codec_info = {
138 .dec_hw_context_init = gen7_dec_hw_context_init,
139 .enc_hw_context_init = gen7_enc_hw_context_init,
140 .proc_hw_context_init = i965_proc_context_init,
141 .render_init = genx_render_init,
142 .post_processing_context_init = i965_post_processing_context_init,
143 .preinit_hw_codec = gen7_hw_codec_preinit,
147 .min_linear_wpitch = 64,
148 .min_linear_hpitch = 16,
150 .h264_mvc_dec_profiles = VA_PROFILE_MASK(H264StereoHigh),
151 .h264_dec_chroma_formats = EXTRA_H264_DEC_CHROMA_FORMATS,
152 .jpeg_dec_chroma_formats = EXTRA_JPEG_DEC_CHROMA_FORMATS,
154 .has_mpeg2_decoding = 1,
155 .has_mpeg2_encoding = 1,
156 .has_h264_decoding = 1,
157 .has_h264_encoding = 1,
158 .has_vc1_decoding = 1,
159 .has_jpeg_decoding = 1,
161 .has_accelerated_getimage = 1,
162 .has_accelerated_putimage = 1,
163 .has_tiled_surface = 1,
164 .has_di_motion_adptive = 1,
168 { VAProcFilterNoiseReduction, I965_RING_NULL },
169 { VAProcFilterDeinterlacing, I965_RING_NULL },
173 static void hsw_hw_codec_preinit(VADriverContextP ctx, struct hw_codec_info *codec_info);
175 extern struct hw_context *gen75_dec_hw_context_init(VADriverContextP, struct object_config *);
176 extern struct hw_context *gen75_enc_hw_context_init(VADriverContextP, struct object_config *);
177 extern struct hw_context *gen75_proc_context_init(VADriverContextP, struct object_config *);
178 static struct hw_codec_info hsw_hw_codec_info = {
179 .dec_hw_context_init = gen75_dec_hw_context_init,
180 .enc_hw_context_init = gen75_enc_hw_context_init,
181 .proc_hw_context_init = gen75_proc_context_init,
182 .render_init = genx_render_init,
183 .post_processing_context_init = i965_post_processing_context_init,
184 .preinit_hw_codec = hsw_hw_codec_preinit,
188 .min_linear_wpitch = 64,
189 .min_linear_hpitch = 16,
191 .h264_mvc_dec_profiles = (VA_PROFILE_MASK(H264StereoHigh) |
192 VA_PROFILE_MASK(H264MultiviewHigh)),
193 .h264_dec_chroma_formats = EXTRA_H264_DEC_CHROMA_FORMATS,
194 .jpeg_dec_chroma_formats = EXTRA_JPEG_DEC_CHROMA_FORMATS,
196 .has_mpeg2_decoding = 1,
197 .has_mpeg2_encoding = 1,
198 .has_h264_decoding = 1,
199 .has_h264_encoding = 1,
200 .has_vc1_decoding = 1,
201 .has_jpeg_decoding = 1,
203 .has_accelerated_getimage = 1,
204 .has_accelerated_putimage = 1,
205 .has_tiled_surface = 1,
206 .has_di_motion_adptive = 1,
207 .has_di_motion_compensated = 1,
208 .has_h264_mvc_encoding = 1,
212 { VAProcFilterNoiseReduction, I965_RING_VEBOX },
213 { VAProcFilterDeinterlacing, I965_RING_VEBOX },
214 { VAProcFilterSharpening, I965_RING_NULL },
215 { VAProcFilterColorBalance, I965_RING_VEBOX},
216 { VAProcFilterSkinToneEnhancement, I965_RING_VEBOX},
220 extern struct hw_context *gen8_dec_hw_context_init(VADriverContextP, struct object_config *);
221 extern struct hw_context *gen8_enc_hw_context_init(VADriverContextP, struct object_config *);
222 extern void gen8_post_processing_context_init(VADriverContextP, void *, struct intel_batchbuffer *);
223 static struct hw_codec_info bdw_hw_codec_info = {
224 .dec_hw_context_init = gen8_dec_hw_context_init,
225 .enc_hw_context_init = gen8_enc_hw_context_init,
226 .proc_hw_context_init = gen75_proc_context_init,
227 .render_init = gen8_render_init,
228 .post_processing_context_init = gen8_post_processing_context_init,
232 .min_linear_wpitch = 64,
233 .min_linear_hpitch = 16,
235 .h264_mvc_dec_profiles = (VA_PROFILE_MASK(H264StereoHigh) |
236 VA_PROFILE_MASK(H264MultiviewHigh)),
237 .h264_dec_chroma_formats = EXTRA_H264_DEC_CHROMA_FORMATS,
238 .jpeg_dec_chroma_formats = EXTRA_JPEG_DEC_CHROMA_FORMATS,
240 .has_mpeg2_decoding = 1,
241 .has_mpeg2_encoding = 1,
242 .has_h264_decoding = 1,
243 .has_h264_encoding = 1,
244 .has_vc1_decoding = 1,
245 .has_jpeg_decoding = 1,
247 .has_accelerated_getimage = 1,
248 .has_accelerated_putimage = 1,
249 .has_tiled_surface = 1,
250 .has_di_motion_adptive = 1,
251 .has_di_motion_compensated = 1,
252 .has_vp8_decoding = 1,
253 .has_h264_mvc_encoding = 1,
257 { VAProcFilterNoiseReduction, I965_RING_VEBOX },
258 { VAProcFilterDeinterlacing, I965_RING_VEBOX },
259 { VAProcFilterSharpening, I965_RING_NULL }, /* need to rebuild the shader for BDW */
260 { VAProcFilterColorBalance, I965_RING_VEBOX},
261 { VAProcFilterSkinToneEnhancement, I965_RING_VEBOX},
265 static struct hw_codec_info chv_hw_codec_info = {
266 .dec_hw_context_init = gen8_dec_hw_context_init,
267 .enc_hw_context_init = gen8_enc_hw_context_init,
268 .proc_hw_context_init = gen75_proc_context_init,
269 .render_init = gen8_render_init,
270 .post_processing_context_init = gen8_post_processing_context_init,
274 .min_linear_wpitch = 64,
275 .min_linear_hpitch = 16,
277 .h264_mvc_dec_profiles = (VA_PROFILE_MASK(H264StereoHigh) |
278 VA_PROFILE_MASK(H264MultiviewHigh)),
279 .h264_dec_chroma_formats = EXTRA_H264_DEC_CHROMA_FORMATS,
280 .jpeg_dec_chroma_formats = EXTRA_JPEG_DEC_CHROMA_FORMATS,
281 .jpeg_enc_chroma_formats = EXTRA_JPEG_ENC_CHROMA_FORMATS,
283 .has_mpeg2_decoding = 1,
284 .has_mpeg2_encoding = 1,
285 .has_h264_decoding = 1,
286 .has_h264_encoding = 1,
287 .has_vc1_decoding = 1,
288 .has_jpeg_decoding = 1,
289 .has_jpeg_encoding = 1,
291 .has_accelerated_getimage = 1,
292 .has_accelerated_putimage = 1,
293 .has_tiled_surface = 1,
294 .has_di_motion_adptive = 1,
295 .has_di_motion_compensated = 1,
296 .has_vp8_decoding = 1,
297 .has_h264_mvc_encoding = 1,
301 { VAProcFilterNoiseReduction, I965_RING_VEBOX },
302 { VAProcFilterDeinterlacing, I965_RING_VEBOX },
303 { VAProcFilterSharpening, I965_RING_NULL }, /* need to rebuild the shader for BDW */
304 { VAProcFilterColorBalance, I965_RING_VEBOX},
305 { VAProcFilterSkinToneEnhancement, I965_RING_VEBOX},
309 /* TODO: Add the separate call back function for Gen9 */
310 static struct hw_codec_info skl_hw_codec_info = {
311 .dec_hw_context_init = gen8_dec_hw_context_init,
312 .enc_hw_context_init = gen8_enc_hw_context_init,
313 .proc_hw_context_init = gen75_proc_context_init,
314 .render_init = gen8_render_init,
315 .post_processing_context_init = gen8_post_processing_context_init,
319 .min_linear_wpitch = 64,
320 .min_linear_hpitch = 16,
322 .h264_mvc_dec_profiles = (VA_PROFILE_MASK(H264StereoHigh) |
323 VA_PROFILE_MASK(H264MultiviewHigh)),
324 .h264_dec_chroma_formats = EXTRA_H264_DEC_CHROMA_FORMATS,
325 .jpeg_dec_chroma_formats = EXTRA_JPEG_DEC_CHROMA_FORMATS,
327 .has_mpeg2_decoding = 1,
328 .has_mpeg2_encoding = 1,
329 .has_h264_decoding = 1,
330 .has_h264_encoding = 1,
331 .has_vc1_decoding = 1,
332 .has_jpeg_decoding = 1,
334 .has_accelerated_getimage = 1,
335 .has_accelerated_putimage = 1,
336 .has_tiled_surface = 1,
337 .has_di_motion_adptive = 1,
338 .has_di_motion_compensated = 1,
339 .has_vp8_decoding = 1,
340 .has_h264_mvc_encoding = 1,
344 { VAProcFilterNoiseReduction, I965_RING_VEBOX },
345 { VAProcFilterDeinterlacing, I965_RING_VEBOX },
346 { VAProcFilterSharpening, I965_RING_NULL }, /* need to rebuild the shader for BDW */
347 { VAProcFilterColorBalance, I965_RING_VEBOX},
348 { VAProcFilterSkinToneEnhancement, I965_RING_VEBOX},
352 struct hw_codec_info *
353 i965_get_codec_info(int devid)
357 #define CHIPSET(id, family, dev, str) case id: return &family##_hw_codec_info;
358 #include "i965_pciids.h"
364 static const struct intel_device_info g4x_device_info = {
368 .max_wm_threads = 50, /* 10 * 5 */
373 static const struct intel_device_info ilk_device_info = {
377 .max_wm_threads = 72, /* 12 * 6 */
380 static const struct intel_device_info snb_gt1_device_info = {
385 .max_wm_threads = 40,
388 static const struct intel_device_info snb_gt2_device_info = {
393 .max_wm_threads = 80,
396 static const struct intel_device_info ivb_gt1_device_info = {
401 .max_wm_threads = 48,
406 static const struct intel_device_info ivb_gt2_device_info = {
411 .max_wm_threads = 172,
416 static const struct intel_device_info byt_device_info = {
421 .max_wm_threads = 48,
427 static const struct intel_device_info hsw_gt1_device_info = {
432 .max_wm_threads = 102,
437 static const struct intel_device_info hsw_gt2_device_info = {
442 .max_wm_threads = 204,
447 static const struct intel_device_info hsw_gt3_device_info = {
452 .max_wm_threads = 408,
457 static const struct intel_device_info bdw_device_info = {
461 .max_wm_threads = 64, /* per PSD */
464 static const struct intel_device_info chv_device_info = {
468 .max_wm_threads = 64, /* per PSD */
473 static const struct intel_device_info skl_device_info = {
477 .max_wm_threads = 64, /* per PSD */
480 const struct intel_device_info *
481 i965_get_device_info(int devid)
485 #define CHIPSET(id, family, dev, str) case id: return &dev##_device_info;
486 #include "i965_pciids.h"
492 static void cpuid(unsigned int op,
493 uint32_t *eax, uint32_t *ebx,
494 uint32_t *ecx, uint32_t *edx)
496 __cpuid_count(op, 0, *eax, *ebx, *ecx, *edx);
500 * This function doesn't check the length. And the caller should
501 * assure that the length of input string should be greater than 48.
503 static int intel_driver_detect_cpustring(char *model_id)
507 if (model_id == NULL)
510 rdata = (uint32_t *)model_id;
512 /* obtain the max supported extended CPUID info */
513 cpuid(0x80000000, &rdata[0], &rdata[1], &rdata[2], &rdata[3]);
515 /* If the max extended CPUID info is less than 0x80000004, fail */
516 if (rdata[0] < 0x80000004)
519 /* obtain the CPUID string */
520 cpuid(0x80000002, &rdata[0], &rdata[1], &rdata[2], &rdata[3]);
521 cpuid(0x80000003, &rdata[4], &rdata[5], &rdata[6], &rdata[7]);
522 cpuid(0x80000004, &rdata[8], &rdata[9], &rdata[10], &rdata[11]);
524 *(model_id + 48) = '\0';
529 * the hook_list for HSW.
530 * It is captured by /proc/cpuinfo and the space character is stripped.
532 const static char *hsw_cpu_hook_list[] = {
533 "Intel(R)Pentium(R)3556U",
534 "Intel(R)Pentium(R)3560Y",
535 "Intel(R)Pentium(R)3550M",
536 "Intel(R)Celeron(R)2980U",
537 "Intel(R)Celeron(R)2955U",
538 "Intel(R)Celeron(R)2950M",
541 static void hsw_hw_codec_preinit(VADriverContextP ctx, struct hw_codec_info *codec_info)
543 char model_string[64];
544 char *model_ptr, *tmp_ptr;
545 int i, model_len, list_len;
548 memset(model_string, 0, sizeof(model_string));
550 /* If it can't detect cpu model_string, leave it alone */
551 if (intel_driver_detect_cpustring(model_string))
554 /* strip the cpufreq info */
555 model_ptr = model_string;
556 tmp_ptr = strstr(model_ptr, "@");
561 /* strip the space character and convert to the lower case */
562 model_ptr = model_string;
563 model_len = strlen(model_string);
564 for (i = 0; i < model_len; i++) {
565 if (model_string[i] != ' ') {
566 *model_ptr = model_string[i];
573 list_len = sizeof(hsw_cpu_hook_list) / sizeof(char *);
574 model_len = strlen(model_string);
575 for (i = 0; i < list_len; i++) {
576 model_ptr = (char *)hsw_cpu_hook_list[i];
578 if (strlen(model_ptr) != model_len)
581 if (strncasecmp(model_string, model_ptr, model_len) == 0) {
588 codec_info->has_h264_encoding = 0;
589 codec_info->has_h264_mvc_encoding = 0;
590 codec_info->has_mpeg2_encoding = 0;
596 * the hook_list for Sandybride.
597 * It is captured by /proc/cpuinfo and the space character is stripped.
599 const static char *gen6_cpu_hook_list[] = {
600 "Intel(R)Celeron(R)CPU847",
601 "Intel(R)Celeron(R)CPU867",
604 static void gen6_hw_codec_preinit(VADriverContextP ctx, struct hw_codec_info *codec_info)
606 char model_string[64];
607 char *model_ptr, *tmp_ptr;
608 int i, model_len, list_len;
611 memset(model_string, 0, sizeof(model_string));
613 /* If it can't detect cpu model_string, leave it alone */
614 if (intel_driver_detect_cpustring(model_string))
617 /* strip the cpufreq info */
618 model_ptr = model_string;
619 tmp_ptr = strstr(model_ptr, "@");
624 /* strip the space character and convert to the lower case */
625 model_ptr = model_string;
626 model_len = strlen(model_string);
627 for (i = 0; i < model_len; i++) {
628 if (model_string[i] != ' ') {
629 *model_ptr = model_string[i];
636 list_len = sizeof(gen6_cpu_hook_list) / sizeof(char *);
637 model_len = strlen(model_string);
638 for (i = 0; i < list_len; i++) {
639 model_ptr = (char *)gen6_cpu_hook_list[i];
641 if (strlen(model_ptr) != model_len)
644 if (strncasecmp(model_string, model_ptr, model_len) == 0) {
651 codec_info->has_h264_encoding = 0;
657 * the hook_list for Ivybridge.
658 * It is captured by /proc/cpuinfo and the space character is stripped.
660 const static char *gen7_cpu_hook_list[] = {
661 "Intel(R)Celeron(R)CPU1007U",
664 static void gen7_hw_codec_preinit(VADriverContextP ctx, struct hw_codec_info *codec_info)
666 char model_string[64];
667 char *model_ptr, *tmp_ptr;
668 int i, model_len, list_len;
671 memset(model_string, 0, sizeof(model_string));
673 /* If it can't detect cpu model_string, leave it alone */
674 if (intel_driver_detect_cpustring(model_string))
677 /* strip the cpufreq info */
678 model_ptr = model_string;
679 tmp_ptr = strstr(model_ptr, "@");
684 /* strip the space character and convert to the lower case */
685 model_ptr = model_string;
686 model_len = strlen(model_string);
687 for (i = 0; i < model_len; i++) {
688 if (model_string[i] != ' ') {
689 *model_ptr = model_string[i];
696 list_len = sizeof(gen7_cpu_hook_list) / sizeof(char *);
697 model_len = strlen(model_string);
698 for (i = 0; i < list_len; i++) {
699 model_ptr = (char *)gen7_cpu_hook_list[i];
701 if (strlen(model_ptr) != model_len)
704 if (strncasecmp(model_string, model_ptr, model_len) == 0) {
711 codec_info->has_h264_encoding = 0;
712 codec_info->has_mpeg2_encoding = 0;