Subversion Repositories Kolibri OS

Rev

Rev 5361 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5361 serge 1
/*
2
 * Copyright © 2009 Intel Corporation
3
 *
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:
11
 *
12
 * The above copyright notice and this permission notice (including the
13
 * next paragraph) shall be included in all copies or substantial portions
14
 * of the Software.
15
 *
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.
23
 *
24
 * Authors:
25
 *    Xiang Haihao 
26
 *    Zou Nan hai 
27
 *
28
 */
29
 
30
#include "sysdeps.h"
31
#include 
32
 
33
#ifdef HAVE_VA_X11
34
# include "i965_output_dri.h"
35
#endif
36
 
37
#ifdef HAVE_VA_WAYLAND
38
# include "i965_output_wayland.h"
39
#endif
40
 
41
#include "intel_driver.h"
42
#include "intel_memman.h"
43
#include "intel_batchbuffer.h"
44
#include "i965_defines.h"
45
#include "i965_drv_video.h"
46
#include "i965_decoder.h"
47
#include "i965_encoder.h"
48
 
49
#define CONFIG_ID_OFFSET                0x01000000
50
#define CONTEXT_ID_OFFSET               0x02000000
51
#define SURFACE_ID_OFFSET               0x04000000
52
#define BUFFER_ID_OFFSET                0x08000000
53
#define IMAGE_ID_OFFSET                 0x0a000000
54
#define SUBPIC_ID_OFFSET                0x10000000
55
 
56
#define HAS_MPEG2_DECODING(ctx)  ((ctx)->codec_info->has_mpeg2_decoding && \
57
                                  (ctx)->intel.has_bsd)
58
 
59
#define HAS_MPEG2_ENCODING(ctx)  ((ctx)->codec_info->has_mpeg2_encoding && \
60
                                  (ctx)->intel.has_bsd)
61
 
62
#define HAS_H264_DECODING(ctx)  ((ctx)->codec_info->has_h264_decoding && \
63
                                 (ctx)->intel.has_bsd)
64
 
65
#define HAS_H264_ENCODING(ctx)  ((ctx)->codec_info->has_h264_encoding && \
66
                                 (ctx)->intel.has_bsd)
67
 
68
#define HAS_VC1_DECODING(ctx)   ((ctx)->codec_info->has_vc1_decoding && \
69
                                 (ctx)->intel.has_bsd)
70
 
71
#define HAS_JPEG_DECODING(ctx)  ((ctx)->codec_info->has_jpeg_decoding && \
72
                                 (ctx)->intel.has_bsd)
73
 
74
#define HAS_VPP(ctx)    ((ctx)->codec_info->has_vpp)
75
 
76
#define HAS_ACCELERATED_GETIMAGE(ctx)   ((ctx)->codec_info->has_accelerated_getimage)
77
 
78
#define HAS_ACCELERATED_PUTIMAGE(ctx)   ((ctx)->codec_info->has_accelerated_putimage)
79
 
80
#define HAS_TILED_SURFACE(ctx) ((ctx)->codec_info->has_tiled_surface)
81
 
82
#define HAS_VP8_DECODING(ctx)   ((ctx)->codec_info->has_vp8_decoding && \
83
                                 (ctx)->intel.has_bsd)
84
 
85
#define HAS_VP8_ENCODING(ctx)   ((ctx)->codec_info->has_vp8_encoding && \
86
                                 (ctx)->intel.has_bsd)
87
 
88
#define HAS_H264_MVC_DECODING(ctx) \
89
    (HAS_H264_DECODING(ctx) && (ctx)->codec_info->h264_mvc_dec_profiles)
90
 
91
#define HAS_H264_MVC_DECODING_PROFILE(ctx, profile)                     \
92
    (HAS_H264_MVC_DECODING(ctx) &&                                      \
93
     ((ctx)->codec_info->h264_mvc_dec_profiles & (1U << profile)))
94
 
95
#define HAS_H264_MVC_ENCODING(ctx)  ((ctx)->codec_info->has_h264_mvc_encoding && \
96
                                     (ctx)->intel.has_bsd)
97
 
98
static int get_sampling_from_fourcc(unsigned int fourcc);
99
 
100
/* Check whether we are rendering to X11 (VA/X11 or VA/GLX API) */
101
#define IS_VA_X11(ctx) \
102
    (((ctx)->display_type & VA_DISPLAY_MAJOR_MASK) == VA_DISPLAY_X11)
103
 
104
/* Check whether we are rendering to Wayland */
105
#define IS_VA_WAYLAND(ctx) \
106
    (((ctx)->display_type & VA_DISPLAY_MAJOR_MASK) == VA_DISPLAY_WAYLAND)
107
 
108
#define I965_BIT        1
109
#define I965_2BITS      (I965_BIT << 1)
110
#define I965_4BITS      (I965_BIT << 2)
111
#define I965_8BITS      (I965_BIT << 3)
112
#define I965_16BITS     (I965_BIT << 4)
113
#define I965_32BITS     (I965_BIT << 5)
114
 
115
#define PLANE_0         0
116
#define PLANE_1         1
117
#define PLANE_2         2
118
 
119
#define OFFSET_0        0
120
#define OFFSET_4        4
121
#define OFFSET_8        8
122
#define OFFSET_16       16
123
#define OFFSET_24       24
124
 
125
/* hfactor, vfactor, num_planes, bpp[], num_components, components[] */
126
#define I_NV12  2, 2, 2, {I965_8BITS, I965_4BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_1, OFFSET_0}, {PLANE_1, OFFSET_8} }
127
#define I_I420  2, 2, 3, {I965_8BITS, I965_2BITS, I965_2BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_1, OFFSET_0}, {PLANE_2, OFFSET_0} }
128
#define I_IYUV  I_I420
129
#define I_IMC3  I_I420
130
#define I_YV12  2, 2, 3, {I965_8BITS, I965_2BITS, I965_2BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_2, OFFSET_0}, {PLANE_1, OFFSET_0} }
131
#define I_IMC1  I_YV12
132
 
133
#define I_422H  2, 1, 3, {I965_8BITS, I965_4BITS, I965_4BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_1, OFFSET_0}, {PLANE_2, OFFSET_0} }
134
#define I_422V  1, 2, 3, {I965_8BITS, I965_4BITS, I965_4BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_1, OFFSET_0}, {PLANE_2, OFFSET_0} }
135
#define I_YV16  2, 1, 3, {I965_8BITS, I965_4BITS, I965_4BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_2, OFFSET_0}, {PLANE_1, OFFSET_0} }
136
#define I_YUY2  2, 1, 1, {I965_32BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_24} }
137
#define I_UYVY  2, 1, 1, {I965_32BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_16} }
138
 
139
#define I_444P  1, 1, 3, {I965_8BITS, I965_8BITS, I965_8BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_1, OFFSET_0}, {PLANE_2, OFFSET_0} }
140
 
141
#define I_411P  4, 1, 3, {I965_8BITS, I965_2BITS, I965_2BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_1, OFFSET_0}, {PLANE_2, OFFSET_0} }
142
 
143
#define I_Y800  1, 1, 1, {I965_8BITS}, 1, { {PLANE_0, OFFSET_0} }
144
 
145
#define I_RGBA  1, 1, 1, {I965_32BITS}, 4, { {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_16}, {PLANE_0, OFFSET_24} }
146
#define I_RGBX  1, 1, 1, {I965_32BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_16} }
147
#define I_BGRA  1, 1, 1, {I965_32BITS}, 4, { {PLANE_0, OFFSET_16}, {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_24} }
148
#define I_BGRX  1, 1, 1, {I965_32BITS}, 3, { {PLANE_0, OFFSET_16}, {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_0} }
149
 
150
#define I_ARGB  1, 1, 1, {I965_32BITS}, 4, { {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_16}, {PLANE_0, OFFSET_24}, {PLANE_0, OFFSET_0} }
151
#define I_ABGR  1, 1, 1, {I965_32BITS}, 4, { {PLANE_0, OFFSET_24}, {PLANE_0, OFFSET_16}, {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_0} }
152
 
153
#define I_IA88  1, 1, 1, {I965_16BITS}, 2, { {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_8} }
154
#define I_AI88  1, 1, 1, {I965_16BITS}, 2, { {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_0} }
155
 
156
#define I_IA44  1, 1, 1, {I965_8BITS}, 2, { {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_4} }
157
#define I_AI44  1, 1, 1, {I965_8BITS}, 2, { {PLANE_0, OFFSET_4}, {PLANE_0, OFFSET_0} }
158
 
159
/* flag */
160
#define I_S             1
161
#define I_I             2
162
#define I_SI            (I_S | I_I)
163
 
164
#define DEF_FOUCC_INFO(FOURCC, FORMAT, SUB, FLAG)       { VA_FOURCC_##FOURCC, I965_COLOR_##FORMAT, SUBSAMPLE_##SUB, FLAG, I_##FOURCC }
165
#define DEF_YUV(FOURCC, SUB, FLAG)                      DEF_FOUCC_INFO(FOURCC, YUV, SUB, FLAG)
166
#define DEF_RGB(FOURCC, SUB, FLAG)                      DEF_FOUCC_INFO(FOURCC, RGB, SUB, FLAG)
167
#define DEF_INDEX(FOURCC, SUB, FLAG)                    DEF_FOUCC_INFO(FOURCC, INDEX, SUB, FLAG)
168
 
169
static const i965_fourcc_info i965_fourcc_infos[] = {
170
    DEF_YUV(NV12, YUV420, I_SI),
171
    DEF_YUV(I420, YUV420, I_SI),
172
    DEF_YUV(IYUV, YUV420, I_S),
173
    DEF_YUV(IMC3, YUV420, I_S),
174
    DEF_YUV(YV12, YUV420, I_SI),
175
    DEF_YUV(IMC1, YUV420, I_S),
176
 
177
    DEF_YUV(422H, YUV422H, I_SI),
178
    DEF_YUV(422V, YUV422V, I_S),
179
    DEF_YUV(YV16, YUV422H, I_S),
180
    DEF_YUV(YUY2, YUV422H, I_SI),
181
    DEF_YUV(UYVY, YUV422H, I_SI),
182
 
183
    DEF_YUV(444P, YUV444, I_S),
184
 
185
    DEF_YUV(411P, YUV411, I_S),
186
 
187
    DEF_YUV(Y800, YUV400, I_S),
188
 
189
    DEF_RGB(RGBA, RGBX, I_SI),
190
    DEF_RGB(RGBX, RGBX, I_SI),
191
    DEF_RGB(BGRA, RGBX, I_SI),
192
    DEF_RGB(BGRX, RGBX, I_SI),
193
 
194
    DEF_RGB(ARGB, RGBX, I_I),
195
    DEF_RGB(ABGR, RGBX, I_I),
196
 
197
    DEF_INDEX(IA88, RGBX, I_I),
198
    DEF_INDEX(AI88, RGBX, I_I),
199
 
200
    DEF_INDEX(IA44, RGBX, I_I),
201
    DEF_INDEX(AI44, RGBX, I_I)
202
};
203
 
204
const i965_fourcc_info *
205
get_fourcc_info(unsigned int fourcc)
206
{
207
    unsigned int i;
208
 
209
    for (i = 0; ARRAY_ELEMS(i965_fourcc_infos); i++) {
210
        const i965_fourcc_info * const info = &i965_fourcc_infos[i];
211
 
212
        if (info->fourcc == fourcc)
213
            return info;
214
    }
215
 
216
    return NULL;
217
}
218
 
219
enum {
220
    I965_SURFACETYPE_RGBA = 1,
221
    I965_SURFACETYPE_YUV,
222
    I965_SURFACETYPE_INDEXED
223
};
224
 
225
/* List of supported display attributes */
226
static const VADisplayAttribute i965_display_attributes[] = {
227
    {
228
        VADisplayAttribBrightness,
229
        -100, 100, DEFAULT_BRIGHTNESS,
230
        VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE
231
    },
232
 
233
    {
234
        VADisplayAttribContrast,
235
        0, 100, DEFAULT_CONTRAST,
236
        VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE
237
    },
238
 
239
    {
240
        VADisplayAttribHue,
241
        -180, 180, DEFAULT_HUE,
242
        VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE
243
    },
244
 
245
    {
246
        VADisplayAttribSaturation,
247
        0, 100, DEFAULT_SATURATION,
248
        VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE
249
    },
250
 
251
    {
252
        VADisplayAttribRotation,
253
        0, 3, VA_ROTATION_NONE,
254
        VA_DISPLAY_ATTRIB_GETTABLE|VA_DISPLAY_ATTRIB_SETTABLE
255
    },
256
};
257
 
258
/* List of supported image formats */
259
typedef struct {
260
    unsigned int        type;
261
    VAImageFormat       va_format;
262
} i965_image_format_map_t;
263
 
264
static const i965_image_format_map_t
265
i965_image_formats_map[I965_MAX_IMAGE_FORMATS + 1] = {
266
    { I965_SURFACETYPE_YUV,
267
      { VA_FOURCC_YV12, VA_LSB_FIRST, 12, } },
268
    { I965_SURFACETYPE_YUV,
269
      { VA_FOURCC_I420, VA_LSB_FIRST, 12, } },
270
    { I965_SURFACETYPE_YUV,
271
      { VA_FOURCC_NV12, VA_LSB_FIRST, 12, } },
272
    { I965_SURFACETYPE_YUV,
273
      { VA_FOURCC_YUY2, VA_LSB_FIRST, 16, } },
274
    { I965_SURFACETYPE_YUV,
275
      { VA_FOURCC_UYVY, VA_LSB_FIRST, 16, } },
276
    { I965_SURFACETYPE_YUV,
277
      { VA_FOURCC_422H, VA_LSB_FIRST, 16, } },
278
    { I965_SURFACETYPE_RGBA,
279
      { VA_FOURCC_RGBX, VA_LSB_FIRST, 32, 24, 0x000000ff, 0x0000ff00, 0x00ff0000 } },
280
    { I965_SURFACETYPE_RGBA,
281
      { VA_FOURCC_BGRX, VA_LSB_FIRST, 32, 24, 0x00ff0000, 0x0000ff00, 0x000000ff } },
282
};
283
 
284
/* List of supported subpicture formats */
285
typedef struct {
286
    unsigned int        type;
287
    unsigned int        format;
288
    VAImageFormat       va_format;
289
    unsigned int        va_flags;
290
} i965_subpic_format_map_t;
291
 
292
#define COMMON_SUBPICTURE_FLAGS                 \
293
    (VA_SUBPICTURE_DESTINATION_IS_SCREEN_COORD| \
294
     VA_SUBPICTURE_GLOBAL_ALPHA)
295
 
296
static const i965_subpic_format_map_t
297
i965_subpic_formats_map[I965_MAX_SUBPIC_FORMATS + 1] = {
298
    { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_P4A4_UNORM,
299
      { VA_FOURCC_IA44, VA_MSB_FIRST, 8, },
300
      COMMON_SUBPICTURE_FLAGS },
301
    { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_A4P4_UNORM,
302
      { VA_FOURCC_AI44, VA_MSB_FIRST, 8, },
303
      COMMON_SUBPICTURE_FLAGS },
304
    { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_P8A8_UNORM,
305
      { VA_FOURCC_IA88, VA_MSB_FIRST, 16, },
306
      COMMON_SUBPICTURE_FLAGS },
307
    { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_A8P8_UNORM,
308
      { VA_FOURCC_AI88, VA_MSB_FIRST, 16, },
309
      COMMON_SUBPICTURE_FLAGS },
310
     { I965_SURFACETYPE_RGBA, I965_SURFACEFORMAT_B8G8R8A8_UNORM,
311
      { VA_FOURCC_BGRA, VA_LSB_FIRST, 32,
312
        32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 },
313
      COMMON_SUBPICTURE_FLAGS },
314
    { I965_SURFACETYPE_RGBA, I965_SURFACEFORMAT_R8G8B8A8_UNORM,
315
      { VA_FOURCC_RGBA, VA_LSB_FIRST, 32,
316
        32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 },
317
      COMMON_SUBPICTURE_FLAGS },
318
};
319
 
320
static const i965_subpic_format_map_t *
321
get_subpic_format(const VAImageFormat *va_format)
322
{
323
    unsigned int i;
324
    for (i = 0; i965_subpic_formats_map[i].type != 0; i++) {
325
        const i965_subpic_format_map_t * const m = &i965_subpic_formats_map[i];
326
        if (m->va_format.fourcc == va_format->fourcc &&
327
            (m->type == I965_SURFACETYPE_RGBA ?
328
             (m->va_format.byte_order == va_format->byte_order &&
329
              m->va_format.red_mask   == va_format->red_mask   &&
330
              m->va_format.green_mask == va_format->green_mask &&
331
              m->va_format.blue_mask  == va_format->blue_mask  &&
332
              m->va_format.alpha_mask == va_format->alpha_mask) : 1))
333
            return m;
334
    }
335
    return NULL;
336
}
337
 
338
#define I965_PACKED_HEADER_BASE         0
339
#define I965_PACKED_MISC_HEADER_BASE    3
340
 
341
int
342
va_enc_packed_type_to_idx(int packed_type)
343
{
344
    int idx = 0;
345
 
346
    if (packed_type & VAEncPackedHeaderMiscMask) {
347
        idx = I965_PACKED_MISC_HEADER_BASE;
348
        packed_type = (~VAEncPackedHeaderMiscMask & packed_type);
349
        ASSERT_RET(packed_type > 0, 0);
350
        idx += (packed_type - 1);
351
    } else {
352
        idx = I965_PACKED_HEADER_BASE;
353
 
354
        switch (packed_type) {
355
        case VAEncPackedHeaderSequence:
356
            idx = I965_PACKED_HEADER_BASE + 0;
357
            break;
358
 
359
        case VAEncPackedHeaderPicture:
360
            idx = I965_PACKED_HEADER_BASE + 1;
361
            break;
362
 
363
        case VAEncPackedHeaderSlice:
364
            idx = I965_PACKED_HEADER_BASE + 2;
365
            break;
366
 
367
        default:
368
            /* Should not get here */
369
            ASSERT_RET(0, 0);
370
            break;
371
        }
372
    }
373
 
374
    ASSERT_RET(idx < 4, 0);
375
    return idx;
376
}
377
 
378
VAStatus
379
i965_QueryConfigProfiles(VADriverContextP ctx,
380
                         VAProfile *profile_list,       /* out */
381
                         int *num_profiles)             /* out */
382
{
383
    struct i965_driver_data * const i965 = i965_driver_data(ctx);
384
    int i = 0;
385
 
386
    if (HAS_MPEG2_DECODING(i965) ||
387
        HAS_MPEG2_ENCODING(i965)) {
388
        profile_list[i++] = VAProfileMPEG2Simple;
389
        profile_list[i++] = VAProfileMPEG2Main;
390
    }
391
 
392
    if (HAS_H264_DECODING(i965) ||
393
        HAS_H264_ENCODING(i965)) {
394
        profile_list[i++] = VAProfileH264ConstrainedBaseline;
395
        profile_list[i++] = VAProfileH264Main;
396
        profile_list[i++] = VAProfileH264High;
397
    }
398
    if (HAS_H264_MVC_DECODING_PROFILE(i965, VAProfileH264MultiviewHigh))
399
        profile_list[i++] = VAProfileH264MultiviewHigh;
400
    if (HAS_H264_MVC_DECODING_PROFILE(i965, VAProfileH264StereoHigh))
401
        profile_list[i++] = VAProfileH264StereoHigh;
402
 
403
    if (HAS_VC1_DECODING(i965)) {
404
        profile_list[i++] = VAProfileVC1Simple;
405
        profile_list[i++] = VAProfileVC1Main;
406
        profile_list[i++] = VAProfileVC1Advanced;
407
    }
408
 
409
    if (HAS_VPP(i965)) {
410
        profile_list[i++] = VAProfileNone;
411
    }
412
 
413
    if (HAS_JPEG_DECODING(i965)) {
414
        profile_list[i++] = VAProfileJPEGBaseline;
415
    }
416
 
417
    if (HAS_VP8_DECODING(i965) ||
418
        HAS_VP8_ENCODING(i965)) {
419
        profile_list[i++] = VAProfileVP8Version0_3;
420
    }
421
 
422
    if (HAS_H264_MVC_ENCODING(i965)) {
423
        profile_list[i++] = VAProfileH264MultiviewHigh;
424
        profile_list[i++] = VAProfileH264StereoHigh;
425
    }
426
 
427
    /* If the assert fails then I965_MAX_PROFILES needs to be bigger */
428
    ASSERT_RET(i <= I965_MAX_PROFILES, VA_STATUS_ERROR_OPERATION_FAILED);
429
    *num_profiles = i;
430
 
431
    return VA_STATUS_SUCCESS;
432
}
433
 
434
VAStatus
435
i965_QueryConfigEntrypoints(VADriverContextP ctx,
436
                            VAProfile profile,
437
                            VAEntrypoint *entrypoint_list,      /* out */
438
                            int *num_entrypoints)               /* out */
439
{
440
    struct i965_driver_data * const i965 = i965_driver_data(ctx);
441
    int n = 0;
442
 
443
    switch (profile) {
444
    case VAProfileMPEG2Simple:
445
    case VAProfileMPEG2Main:
446
        if (HAS_MPEG2_DECODING(i965))
447
            entrypoint_list[n++] = VAEntrypointVLD;
448
 
449
        if (HAS_MPEG2_ENCODING(i965))
450
            entrypoint_list[n++] = VAEntrypointEncSlice;
451
 
452
        break;
453
 
454
    case VAProfileH264ConstrainedBaseline:
455
    case VAProfileH264Main:
456
    case VAProfileH264High:
457
        if (HAS_H264_DECODING(i965))
458
            entrypoint_list[n++] = VAEntrypointVLD;
459
 
460
        if (HAS_H264_ENCODING(i965))
461
            entrypoint_list[n++] = VAEntrypointEncSlice;
462
 
463
        break;
464
   case VAProfileH264MultiviewHigh:
465
   case VAProfileH264StereoHigh:
466
       if (HAS_H264_MVC_DECODING_PROFILE(i965, profile))
467
            entrypoint_list[n++] = VAEntrypointVLD;
468
 
469
       if (HAS_H264_MVC_ENCODING(i965))
470
            entrypoint_list[n++] = VAEntrypointEncSlice;
471
        break;
472
 
473
    case VAProfileVC1Simple:
474
    case VAProfileVC1Main:
475
    case VAProfileVC1Advanced:
476
        if (HAS_VC1_DECODING(i965))
477
            entrypoint_list[n++] = VAEntrypointVLD;
478
        break;
479
 
480
    case VAProfileNone:
481
        if (HAS_VPP(i965))
482
            entrypoint_list[n++] = VAEntrypointVideoProc;
483
        break;
484
 
485
    case VAProfileJPEGBaseline:
486
        if (HAS_JPEG_DECODING(i965))
487
            entrypoint_list[n++] = VAEntrypointVLD;
488
        break;
489
 
490
    case VAProfileVP8Version0_3:
491
        if (HAS_VP8_DECODING(i965))
492
            entrypoint_list[n++] = VAEntrypointVLD;
493
 
494
        if (HAS_VP8_ENCODING(i965))
495
            entrypoint_list[n++] = VAEntrypointEncSlice;
496
 
497
    default:
498
        break;
499
    }
500
 
501
    /* If the assert fails then I965_MAX_ENTRYPOINTS needs to be bigger */
502
    ASSERT_RET(n <= I965_MAX_ENTRYPOINTS, VA_STATUS_ERROR_OPERATION_FAILED);
503
    *num_entrypoints = n;
504
    return n > 0 ? VA_STATUS_SUCCESS : VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
505
}
506
 
507
static VAStatus
508
i965_validate_config(VADriverContextP ctx, VAProfile profile,
509
    VAEntrypoint entrypoint)
510
{
511
    struct i965_driver_data * const i965 = i965_driver_data(ctx);
512
    VAStatus va_status;
513
 
514
    /* Validate profile & entrypoint */
515
    switch (profile) {
516
    case VAProfileMPEG2Simple:
517
    case VAProfileMPEG2Main:
518
        if ((HAS_MPEG2_DECODING(i965) && entrypoint == VAEntrypointVLD) ||
519
            (HAS_MPEG2_ENCODING(i965) && entrypoint == VAEntrypointEncSlice)) {
520
            va_status = VA_STATUS_SUCCESS;
521
        } else {
522
            va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
523
        }
524
        break;
525
 
526
    case VAProfileH264ConstrainedBaseline:
527
    case VAProfileH264Main:
528
    case VAProfileH264High:
529
        if ((HAS_H264_DECODING(i965) && entrypoint == VAEntrypointVLD) ||
530
            (HAS_H264_ENCODING(i965) && entrypoint == VAEntrypointEncSlice)) {
531
            va_status = VA_STATUS_SUCCESS;
532
        } else {
533
            va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
534
        }
535
        break;
536
 
537
    case VAProfileVC1Simple:
538
    case VAProfileVC1Main:
539
    case VAProfileVC1Advanced:
540
        if (HAS_VC1_DECODING(i965) && entrypoint == VAEntrypointVLD) {
541
            va_status = VA_STATUS_SUCCESS;
542
        } else {
543
            va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
544
        }
545
        break;
546
 
547
    case VAProfileNone:
548
        if (HAS_VPP(i965) && VAEntrypointVideoProc == entrypoint) {
549
            va_status = VA_STATUS_SUCCESS;
550
        } else {
551
            va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
552
        }
553
        break;
554
 
555
    case VAProfileJPEGBaseline:
556
        if (HAS_JPEG_DECODING(i965) && entrypoint == VAEntrypointVLD) {
557
            va_status = VA_STATUS_SUCCESS;
558
        } else {
559
            va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
560
        }
561
        break;
562
 
563
    case VAProfileVP8Version0_3:
564
        if ((HAS_VP8_DECODING(i965) && entrypoint == VAEntrypointVLD) ||
565
            (HAS_VP8_ENCODING(i965) && entrypoint == VAEntrypointEncSlice)) {
566
            va_status = VA_STATUS_SUCCESS;
567
        } else {
568
            va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
569
        }
570
        break;
571
 
572
    case VAProfileH264MultiviewHigh:
573
    case VAProfileH264StereoHigh:
574
        if ((HAS_H264_MVC_DECODING_PROFILE(i965, profile) &&
575
             entrypoint == VAEntrypointVLD) ||
576
            (HAS_H264_MVC_ENCODING(i965) && entrypoint == VAEntrypointEncSlice)) {
577
            va_status = VA_STATUS_SUCCESS;
578
        } else {
579
            va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
580
        }
581
 
582
        break;
583
 
584
    default:
585
        va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
586
        break;
587
    }
588
    return va_status;
589
}
590
 
591
static uint32_t
592
i965_get_default_chroma_formats(VADriverContextP ctx, VAProfile profile,
593
    VAEntrypoint entrypoint)
594
{
595
    struct i965_driver_data * const i965 = i965_driver_data(ctx);
596
    uint32_t chroma_formats = VA_RT_FORMAT_YUV420;
597
 
598
    switch (profile) {
599
    case VAProfileH264ConstrainedBaseline:
600
    case VAProfileH264Main:
601
    case VAProfileH264High:
602
        if (HAS_H264_DECODING(i965) && entrypoint == VAEntrypointVLD)
603
            chroma_formats |= i965->codec_info->h264_dec_chroma_formats;
604
        break;
605
 
606
    case VAProfileH264MultiviewHigh:
607
    case VAProfileH264StereoHigh:
608
        if (HAS_H264_MVC_DECODING(i965) && entrypoint == VAEntrypointVLD)
609
            chroma_formats |= i965->codec_info->h264_dec_chroma_formats;
610
        break;
611
 
612
    case VAProfileJPEGBaseline:
613
        if (HAS_JPEG_DECODING(i965) && entrypoint == VAEntrypointVLD)
614
            chroma_formats |= i965->codec_info->jpeg_dec_chroma_formats;
615
        break;
616
 
617
    default:
618
        break;
619
    }
620
    return chroma_formats;
621
}
622
 
623
VAStatus
624
i965_GetConfigAttributes(VADriverContextP ctx,
625
                         VAProfile profile,
626
                         VAEntrypoint entrypoint,
627
                         VAConfigAttrib *attrib_list,  /* in/out */
628
                         int num_attribs)
629
{
630
    VAStatus va_status;
631
    struct i965_driver_data *i965 = i965_driver_data(ctx);
632
    int i;
633
 
634
    va_status = i965_validate_config(ctx, profile, entrypoint);
635
    if (va_status != VA_STATUS_SUCCESS)
636
        return va_status;
637
 
638
    /* Other attributes don't seem to be defined */
639
    /* What to do if we don't know the attribute? */
640
    for (i = 0; i < num_attribs; i++) {
641
        switch (attrib_list[i].type) {
642
        case VAConfigAttribRTFormat:
643
            attrib_list[i].value = i965_get_default_chroma_formats(ctx,
644
                profile, entrypoint);
645
            break;
646
 
647
        case VAConfigAttribRateControl:
648
            if (entrypoint == VAEntrypointEncSlice) {
649
                attrib_list[i].value = VA_RC_CQP;
650
 
651
                if (profile != VAProfileMPEG2Main &&
652
                    profile != VAProfileMPEG2Simple)
653
                    attrib_list[i].value |= VA_RC_CBR;
654
                break;
655
            }
656
 
657
        case VAConfigAttribEncPackedHeaders:
658
            if (entrypoint == VAEntrypointEncSlice) {
659
                attrib_list[i].value = VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_PICTURE | VA_ENC_PACKED_HEADER_MISC;
660
                if (profile == VAProfileH264ConstrainedBaseline ||
661
                    profile == VAProfileH264Main ||
662
                    profile == VAProfileH264High ||
663
                    profile == VAProfileH264StereoHigh ||
664
                    profile == VAProfileH264MultiviewHigh) {
665
                    attrib_list[i].value |= (VA_ENC_PACKED_HEADER_RAW_DATA |
666
                                             VA_ENC_PACKED_HEADER_SLICE);
667
                }
668
                break;
669
            }
670
 
671
	case VAConfigAttribEncMaxRefFrames:
672
	    if (entrypoint == VAEntrypointEncSlice) {
673
		attrib_list[i].value = (1 << 16) | (1 << 0);
674
		break;
675
	    }
676
 
677
	case VAConfigAttribEncQualityRange:
678
	    if (entrypoint == VAEntrypointEncSlice) {
679
		attrib_list[i].value = 1;
680
                if (profile == VAProfileH264ConstrainedBaseline ||
681
                    profile == VAProfileH264Main ||
682
                    profile == VAProfileH264High )
683
                    attrib_list[i].value = ENCODER_QUALITY_RANGE;
684
		break;
685
	    }
686
 
687
        default:
688
            /* Do nothing */
689
            attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
690
            break;
691
        }
692
    }
693
 
694
    return VA_STATUS_SUCCESS;
695
}
696
 
697
static void
698
i965_destroy_config(struct object_heap *heap, struct object_base *obj)
699
{
700
    object_heap_free(heap, obj);
701
}
702
 
703
static VAConfigAttrib *
704
i965_lookup_config_attribute(struct object_config *obj_config,
705
    VAConfigAttribType type)
706
{
707
    int i;
708
 
709
    for (i = 0; i < obj_config->num_attribs; i++) {
710
        VAConfigAttrib * const attrib = &obj_config->attrib_list[i];
711
        if (attrib->type == type)
712
            return attrib;
713
    }
714
    return NULL;
715
}
716
 
717
static VAStatus
718
i965_append_config_attribute(struct object_config *obj_config,
719
    const VAConfigAttrib *new_attrib)
720
{
721
    VAConfigAttrib *attrib;
722
 
723
    if (obj_config->num_attribs >= I965_MAX_CONFIG_ATTRIBUTES)
724
        return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
725
 
726
    attrib = &obj_config->attrib_list[obj_config->num_attribs++];
727
    attrib->type = new_attrib->type;
728
    attrib->value = new_attrib->value;
729
    return VA_STATUS_SUCCESS;
730
}
731
 
732
static VAStatus
733
i965_ensure_config_attribute(struct object_config *obj_config,
734
    const VAConfigAttrib *new_attrib)
735
{
736
    VAConfigAttrib *attrib;
737
 
738
    /* Check for existing attributes */
739
    attrib = i965_lookup_config_attribute(obj_config, new_attrib->type);
740
    if (attrib) {
741
        /* Update existing attribute */
742
        attrib->value = new_attrib->value;
743
        return VA_STATUS_SUCCESS;
744
    }
745
    return i965_append_config_attribute(obj_config, new_attrib);
746
}
747
 
748
VAStatus
749
i965_CreateConfig(VADriverContextP ctx,
750
                  VAProfile profile,
751
                  VAEntrypoint entrypoint,
752
                  VAConfigAttrib *attrib_list,
753
                  int num_attribs,
754
                  VAConfigID *config_id)        /* out */
755
{
756
    struct i965_driver_data * const i965 = i965_driver_data(ctx);
757
    struct object_config *obj_config;
758
    int configID;
759
    int i;
760
    VAStatus vaStatus;
761
 
762
    vaStatus = i965_validate_config(ctx, profile, entrypoint);
763
 
764
    if (VA_STATUS_SUCCESS != vaStatus) {
765
        return vaStatus;
766
    }
767
 
768
    configID = NEW_CONFIG_ID();
769
    obj_config = CONFIG(configID);
770
 
771
    if (NULL == obj_config) {
772
        vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
773
        return vaStatus;
774
    }
775
 
776
    obj_config->profile = profile;
777
    obj_config->entrypoint = entrypoint;
778
    obj_config->num_attribs = 0;
779
 
780
    for (i = 0; i < num_attribs; i++) {
781
        vaStatus = i965_ensure_config_attribute(obj_config, &attrib_list[i]);
782
        if (vaStatus != VA_STATUS_SUCCESS)
783
            break;
784
    }
785
 
786
    if (vaStatus == VA_STATUS_SUCCESS) {
787
        VAConfigAttrib attrib, *attrib_found;
788
        attrib.type = VAConfigAttribRTFormat;
789
        attrib.value = i965_get_default_chroma_formats(ctx, profile, entrypoint);
790
        attrib_found = i965_lookup_config_attribute(obj_config, attrib.type);
791
        if (!attrib_found || !attrib_found->value)
792
            vaStatus = i965_append_config_attribute(obj_config, &attrib);
793
        else if (!(attrib_found->value & attrib.value))
794
            vaStatus = VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
795
    }
796
 
797
    /* Error recovery */
798
    if (VA_STATUS_SUCCESS != vaStatus) {
799
        i965_destroy_config(&i965->config_heap, (struct object_base *)obj_config);
800
    } else {
801
        *config_id = configID;
802
    }
803
 
804
    return vaStatus;
805
}
806
 
807
VAStatus
808
i965_DestroyConfig(VADriverContextP ctx, VAConfigID config_id)
809
{
810
    struct i965_driver_data *i965 = i965_driver_data(ctx);
811
    struct object_config *obj_config = CONFIG(config_id);
812
    VAStatus vaStatus;
813
 
814
    if (NULL == obj_config) {
815
        vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
816
        return vaStatus;
817
    }
818
 
819
    i965_destroy_config(&i965->config_heap, (struct object_base *)obj_config);
820
    return VA_STATUS_SUCCESS;
821
}
822
 
823
VAStatus i965_QueryConfigAttributes(VADriverContextP ctx,
824
                                    VAConfigID config_id,
825
                                    VAProfile *profile,                 /* out */
826
                                    VAEntrypoint *entrypoint,           /* out */
827
                                    VAConfigAttrib *attrib_list,        /* out */
828
                                    int *num_attribs)                   /* out */
829
{
830
    struct i965_driver_data *i965 = i965_driver_data(ctx);
831
    struct object_config *obj_config = CONFIG(config_id);
832
    VAStatus vaStatus = VA_STATUS_SUCCESS;
833
    int i;
834
 
835
    ASSERT_RET(obj_config, VA_STATUS_ERROR_INVALID_CONFIG);
836
    *profile = obj_config->profile;
837
    *entrypoint = obj_config->entrypoint;
838
    *num_attribs = obj_config->num_attribs;
839
 
840
    for(i = 0; i < obj_config->num_attribs; i++) {
841
        attrib_list[i] = obj_config->attrib_list[i];
842
    }
843
 
844
    return vaStatus;
845
}
846
 
847
void
848
i965_destroy_surface_storage(struct object_surface *obj_surface)
849
{
850
    if (!obj_surface)
851
        return;
852
 
853
    dri_bo_unreference(obj_surface->bo);
854
    obj_surface->bo = NULL;
855
 
856
    if (obj_surface->free_private_data != NULL) {
857
        obj_surface->free_private_data(&obj_surface->private_data);
858
        obj_surface->private_data = NULL;
859
    }
860
}
861
 
862
static void
863
i965_destroy_surface(struct object_heap *heap, struct object_base *obj)
864
{
865
    struct object_surface *obj_surface = (struct object_surface *)obj;
866
 
867
    i965_destroy_surface_storage(obj_surface);
868
    object_heap_free(heap, obj);
869
}
870
 
871
static VAStatus
872
i965_surface_native_memory(VADriverContextP ctx,
873
                           struct object_surface *obj_surface,
874
                           int format,
875
                           int expected_fourcc)
876
{
877
    struct i965_driver_data *i965 = i965_driver_data(ctx);
878
    int tiling = HAS_TILED_SURFACE(i965);
879
 
880
    if (!expected_fourcc)
881
        return VA_STATUS_SUCCESS;
882
 
883
    // todo, should we disable tiling for 422 format?
884
    if (expected_fourcc == VA_FOURCC_I420 ||
885
        expected_fourcc == VA_FOURCC_IYUV ||
886
        expected_fourcc == VA_FOURCC_YV12 ||
887
        expected_fourcc == VA_FOURCC_YV16)
888
        tiling = 0;
889
 
890
    i965_check_alloc_surface_bo(ctx, obj_surface, tiling, expected_fourcc, get_sampling_from_fourcc(expected_fourcc));
891
 
892
    return VA_STATUS_SUCCESS;
893
}
894
 
895
static VAStatus
896
i965_suface_external_memory(VADriverContextP ctx,
897
                            struct object_surface *obj_surface,
898
                            int external_memory_type,
899
                            VASurfaceAttribExternalBuffers *memory_attibute,
900
                            int index)
901
{
902
    struct i965_driver_data *i965 = i965_driver_data(ctx);
903
 
904
    if (!memory_attibute ||
905
        !memory_attibute->buffers ||
906
        index > memory_attibute->num_buffers)
907
        return VA_STATUS_ERROR_INVALID_PARAMETER;
908
 
909
    ASSERT_RET(obj_surface->orig_width == memory_attibute->width, VA_STATUS_ERROR_INVALID_PARAMETER);
910
    ASSERT_RET(obj_surface->orig_height == memory_attibute->height, VA_STATUS_ERROR_INVALID_PARAMETER);
911
    ASSERT_RET(memory_attibute->num_planes >= 1, VA_STATUS_ERROR_INVALID_PARAMETER);
912
 
913
    obj_surface->fourcc = memory_attibute->pixel_format;
914
    obj_surface->width = memory_attibute->pitches[0];
915
    obj_surface->size = memory_attibute->data_size;
916
 
917
    if (memory_attibute->num_planes == 1)
918
        obj_surface->height = memory_attibute->data_size / obj_surface->width;
919
    else
920
        obj_surface->height = memory_attibute->offsets[1] / obj_surface->width;
921
 
922
    obj_surface->x_cb_offset = 0; /* X offset is always 0 */
923
    obj_surface->x_cr_offset = 0;
924
 
925
    switch (obj_surface->fourcc) {
926
    case VA_FOURCC_NV12:
927
        ASSERT_RET(memory_attibute->num_planes == 2, VA_STATUS_ERROR_INVALID_PARAMETER);
928
        ASSERT_RET(memory_attibute->pitches[0] == memory_attibute->pitches[1], VA_STATUS_ERROR_INVALID_PARAMETER);
929
 
930
        obj_surface->subsampling = SUBSAMPLE_YUV420;
931
        obj_surface->y_cb_offset = obj_surface->height;
932
        obj_surface->y_cr_offset = obj_surface->height;
933
        obj_surface->cb_cr_width = obj_surface->orig_width / 2;
934
        obj_surface->cb_cr_height = obj_surface->orig_height / 2;
935
        obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
936
 
937
        break;
938
 
939
    case VA_FOURCC_YV12:
940
    case VA_FOURCC_IMC1:
941
        ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
942
        ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
943
 
944
        obj_surface->subsampling = SUBSAMPLE_YUV420;
945
        obj_surface->y_cr_offset = obj_surface->height;
946
        obj_surface->y_cb_offset = memory_attibute->offsets[2] / obj_surface->width;
947
        obj_surface->cb_cr_width = obj_surface->orig_width / 2;
948
        obj_surface->cb_cr_height = obj_surface->orig_height / 2;
949
        obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
950
 
951
        break;
952
 
953
    case VA_FOURCC_I420:
954
    case VA_FOURCC_IYUV:
955
    case VA_FOURCC_IMC3:
956
        ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
957
        ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
958
 
959
        obj_surface->subsampling = SUBSAMPLE_YUV420;
960
        obj_surface->y_cb_offset = obj_surface->height;
961
        obj_surface->y_cr_offset = memory_attibute->offsets[2] / obj_surface->width;
962
        obj_surface->cb_cr_width = obj_surface->orig_width / 2;
963
        obj_surface->cb_cr_height = obj_surface->orig_height / 2;
964
        obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
965
 
966
        break;
967
 
968
    case VA_FOURCC_YUY2:
969
    case VA_FOURCC_UYVY:
970
        ASSERT_RET(memory_attibute->num_planes == 1, VA_STATUS_ERROR_INVALID_PARAMETER);
971
 
972
        obj_surface->subsampling = SUBSAMPLE_YUV422H;
973
        obj_surface->y_cb_offset = 0;
974
        obj_surface->y_cr_offset = 0;
975
        obj_surface->cb_cr_width = obj_surface->orig_width / 2;
976
        obj_surface->cb_cr_height = obj_surface->orig_height;
977
        obj_surface->cb_cr_pitch = memory_attibute->pitches[0];
978
 
979
        break;
980
 
981
    case VA_FOURCC_RGBA:
982
    case VA_FOURCC_RGBX:
983
    case VA_FOURCC_BGRA:
984
    case VA_FOURCC_BGRX:
985
        ASSERT_RET(memory_attibute->num_planes == 1, VA_STATUS_ERROR_INVALID_PARAMETER);
986
 
987
        obj_surface->subsampling = SUBSAMPLE_RGBX;
988
        obj_surface->y_cb_offset = 0;
989
        obj_surface->y_cr_offset = 0;
990
        obj_surface->cb_cr_width = 0;
991
        obj_surface->cb_cr_height = 0;
992
        obj_surface->cb_cr_pitch = 0;
993
 
994
        break;
995
 
996
    case VA_FOURCC_Y800: /* monochrome surface */
997
        ASSERT_RET(memory_attibute->num_planes == 1, VA_STATUS_ERROR_INVALID_PARAMETER);
998
 
999
        obj_surface->subsampling = SUBSAMPLE_YUV400;
1000
        obj_surface->y_cb_offset = 0;
1001
        obj_surface->y_cr_offset = 0;
1002
        obj_surface->cb_cr_width = 0;
1003
        obj_surface->cb_cr_height = 0;
1004
        obj_surface->cb_cr_pitch = 0;
1005
 
1006
        break;
1007
 
1008
    case VA_FOURCC_411P:
1009
        ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
1010
        ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
1011
 
1012
        obj_surface->subsampling = SUBSAMPLE_YUV411;
1013
        obj_surface->y_cb_offset = 0;
1014
        obj_surface->y_cr_offset = 0;
1015
        obj_surface->cb_cr_width = obj_surface->orig_width / 4;
1016
        obj_surface->cb_cr_height = obj_surface->orig_height;
1017
        obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
1018
 
1019
        break;
1020
 
1021
    case VA_FOURCC_422H:
1022
        ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
1023
        ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
1024
 
1025
        obj_surface->subsampling = SUBSAMPLE_YUV422H;
1026
        obj_surface->y_cb_offset = obj_surface->height;
1027
        obj_surface->y_cr_offset = memory_attibute->offsets[2] / obj_surface->width;
1028
        obj_surface->cb_cr_width = obj_surface->orig_width / 2;
1029
        obj_surface->cb_cr_height = obj_surface->orig_height;
1030
        obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
1031
 
1032
        break;
1033
 
1034
    case VA_FOURCC_YV16:
1035
        assert(memory_attibute->num_planes == 3);
1036
        assert(memory_attibute->pitches[1] == memory_attibute->pitches[2]);
1037
 
1038
        obj_surface->subsampling = SUBSAMPLE_YUV422H;
1039
        obj_surface->y_cr_offset = memory_attibute->offsets[1] / obj_surface->width;
1040
        obj_surface->y_cb_offset = memory_attibute->offsets[2] / obj_surface->width;
1041
        obj_surface->cb_cr_width = obj_surface->orig_width / 2;
1042
        obj_surface->cb_cr_height = obj_surface->orig_height;
1043
        obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
1044
 
1045
        break;
1046
 
1047
    case VA_FOURCC_422V:
1048
        ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
1049
        ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
1050
 
1051
        obj_surface->subsampling = SUBSAMPLE_YUV422H;
1052
        obj_surface->y_cb_offset = obj_surface->height;
1053
        obj_surface->y_cr_offset = memory_attibute->offsets[2] / obj_surface->width;
1054
        obj_surface->cb_cr_width = obj_surface->orig_width;
1055
        obj_surface->cb_cr_height = obj_surface->orig_height / 2;
1056
        obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
1057
 
1058
        break;
1059
 
1060
    case VA_FOURCC_444P:
1061
        ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
1062
        ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
1063
 
1064
        obj_surface->subsampling = SUBSAMPLE_YUV444;
1065
        obj_surface->y_cb_offset = obj_surface->height;
1066
        obj_surface->y_cr_offset = memory_attibute->offsets[2] / obj_surface->width;
1067
        obj_surface->cb_cr_width = obj_surface->orig_width;
1068
        obj_surface->cb_cr_height = obj_surface->orig_height;
1069
        obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
1070
 
1071
        break;
1072
 
1073
    default:
1074
 
1075
        return VA_STATUS_ERROR_INVALID_PARAMETER;
1076
    }
1077
 
1078
    if (external_memory_type == I965_SURFACE_MEM_GEM_FLINK)
1079
        obj_surface->bo = drm_intel_bo_gem_create_from_name(i965->intel.bufmgr,
1080
                                                            "gem flinked vaapi surface",
1081
                                                            memory_attibute->buffers[index]);
1082
//    else if (external_memory_type == I965_SURFACE_MEM_DRM_PRIME)
1083
//        obj_surface->bo = drm_intel_bo_gem_create_from_prime(i965->intel.bufmgr,
1084
//                                                             memory_attibute->buffers[index],
1085
//                                                             obj_surface->size);
1086
 
1087
    if (!obj_surface->bo)
1088
        return VA_STATUS_ERROR_INVALID_PARAMETER;
1089
 
1090
    return VA_STATUS_SUCCESS;
1091
}
1092
 
1093
/* byte-per-pixel of the first plane */
1094
static int
1095
bpp_1stplane_by_fourcc(unsigned int fourcc)
1096
{
1097
    const i965_fourcc_info *info = get_fourcc_info(fourcc);
1098
 
1099
    if (info && (info->flag & I_S))
1100
        return info->bpp[0] / 8;
1101
    else
1102
        return 0;
1103
}
1104
 
1105
static VAStatus
1106
i965_CreateSurfaces2(
1107
    VADriverContextP    ctx,
1108
    unsigned int        format,
1109
    unsigned int        width,
1110
    unsigned int        height,
1111
    VASurfaceID        *surfaces,
1112
    unsigned int        num_surfaces,
1113
    VASurfaceAttrib    *attrib_list,
1114
    unsigned int        num_attribs
1115
    )
1116
{
1117
    struct i965_driver_data *i965 = i965_driver_data(ctx);
1118
    int i,j;
1119
    VAStatus vaStatus = VA_STATUS_SUCCESS;
1120
    int expected_fourcc = 0;
1121
    int memory_type = I965_SURFACE_MEM_NATIVE; /* native */
1122
    VASurfaceAttribExternalBuffers *memory_attibute = NULL;
1123
 
1124
    for (i = 0; i < num_attribs && attrib_list; i++) {
1125
        if ((attrib_list[i].type == VASurfaceAttribPixelFormat) &&
1126
            (attrib_list[i].flags & VA_SURFACE_ATTRIB_SETTABLE)) {
1127
            ASSERT_RET(attrib_list[i].value.type == VAGenericValueTypeInteger, VA_STATUS_ERROR_INVALID_PARAMETER);
1128
            expected_fourcc = attrib_list[i].value.value.i;
1129
        }
1130
 
1131
        if ((attrib_list[i].type == VASurfaceAttribMemoryType) &&
1132
            (attrib_list[i].flags & VA_SURFACE_ATTRIB_SETTABLE)) {
1133
 
1134
            ASSERT_RET(attrib_list[i].value.type == VAGenericValueTypeInteger, VA_STATUS_ERROR_INVALID_PARAMETER);
1135
 
1136
            if (attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM)
1137
                memory_type = I965_SURFACE_MEM_GEM_FLINK; /* flinked GEM handle */
1138
            else if (attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME)
1139
                memory_type = I965_SURFACE_MEM_DRM_PRIME; /* drm prime fd */
1140
            else if (attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_VA)
1141
                memory_type = I965_SURFACE_MEM_NATIVE; /* va native memory, to be allocated */
1142
        }
1143
 
1144
        if ((attrib_list[i].type == VASurfaceAttribExternalBufferDescriptor) &&
1145
            (attrib_list[i].flags == VA_SURFACE_ATTRIB_SETTABLE)) {
1146
            ASSERT_RET(attrib_list[i].value.type == VAGenericValueTypePointer, VA_STATUS_ERROR_INVALID_PARAMETER);
1147
            memory_attibute = (VASurfaceAttribExternalBuffers *)attrib_list[i].value.value.p;
1148
        }
1149
    }
1150
 
1151
    /* support 420 & 422 & RGB32 format, 422 and RGB32 are only used
1152
     * for post-processing (including color conversion) */
1153
    if (VA_RT_FORMAT_YUV420 != format &&
1154
        VA_RT_FORMAT_YUV422 != format &&
1155
        VA_RT_FORMAT_YUV444 != format &&
1156
        VA_RT_FORMAT_YUV411 != format &&
1157
        VA_RT_FORMAT_YUV400 != format &&
1158
        VA_RT_FORMAT_RGB32  != format) {
1159
        return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
1160
    }
1161
 
1162
    for (i = 0; i < num_surfaces; i++) {
1163
        int surfaceID = NEW_SURFACE_ID();
1164
        struct object_surface *obj_surface = SURFACE(surfaceID);
1165
 
1166
        if (NULL == obj_surface) {
1167
            vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1168
            break;
1169
        }
1170
 
1171
        surfaces[i] = surfaceID;
1172
        obj_surface->status = VASurfaceReady;
1173
        obj_surface->orig_width = width;
1174
        obj_surface->orig_height = height;
1175
        obj_surface->user_disable_tiling = false;
1176
        obj_surface->user_h_stride_set = false;
1177
        obj_surface->user_v_stride_set = false;
1178
 
1179
        obj_surface->subpic_render_idx = 0;
1180
        for(j = 0; j < I965_MAX_SUBPIC_SUM; j++){
1181
           obj_surface->subpic[j] = VA_INVALID_ID;
1182
           obj_surface->obj_subpic[j] = NULL;
1183
        }
1184
 
1185
        assert(i965->codec_info->min_linear_wpitch);
1186
        assert(i965->codec_info->min_linear_hpitch);
1187
        obj_surface->width = ALIGN(width, i965->codec_info->min_linear_wpitch);
1188
        obj_surface->height = ALIGN(height, i965->codec_info->min_linear_hpitch);
1189
        obj_surface->flags = SURFACE_REFERENCED;
1190
        obj_surface->fourcc = 0;
1191
        obj_surface->bo = NULL;
1192
        obj_surface->locked_image_id = VA_INVALID_ID;
1193
        obj_surface->private_data = NULL;
1194
        obj_surface->free_private_data = NULL;
1195
        obj_surface->subsampling = SUBSAMPLE_YUV420;
1196
 
1197
        switch (memory_type) {
1198
        case I965_SURFACE_MEM_NATIVE:
1199
            if (memory_attibute) {
1200
                if (!(memory_attibute->flags & VA_SURFACE_EXTBUF_DESC_ENABLE_TILING))
1201
                    obj_surface->user_disable_tiling = true;
1202
 
1203
                if (memory_attibute->pixel_format) {
1204
                    if (expected_fourcc)
1205
                        ASSERT_RET(memory_attibute->pixel_format == expected_fourcc, VA_STATUS_ERROR_INVALID_PARAMETER);
1206
                    else
1207
                        expected_fourcc = memory_attibute->pixel_format;
1208
                }
1209
                ASSERT_RET(expected_fourcc, VA_STATUS_ERROR_INVALID_PARAMETER);
1210
                if (memory_attibute->pitches[0]) {
1211
                    int bpp_1stplane = bpp_1stplane_by_fourcc(expected_fourcc);
1212
                    ASSERT_RET(bpp_1stplane, VA_STATUS_ERROR_INVALID_PARAMETER);
1213
                    obj_surface->width = memory_attibute->pitches[0]/bpp_1stplane;
1214
                    obj_surface->user_h_stride_set = true;
1215
                    ASSERT_RET(IS_ALIGNED(obj_surface->width, 16), VA_STATUS_ERROR_INVALID_PARAMETER);
1216
                    ASSERT_RET(obj_surface->width >= width, VA_STATUS_ERROR_INVALID_PARAMETER);
1217
 
1218
                    if (memory_attibute->offsets[1]) {
1219
                        ASSERT_RET(!memory_attibute->offsets[0], VA_STATUS_ERROR_INVALID_PARAMETER);
1220
                        obj_surface->height = memory_attibute->offsets[1]/memory_attibute->pitches[0];
1221
                        obj_surface->user_v_stride_set = true;
1222
                        ASSERT_RET(IS_ALIGNED(obj_surface->height, 16), VA_STATUS_ERROR_INVALID_PARAMETER);
1223
                        ASSERT_RET(obj_surface->height >= height, VA_STATUS_ERROR_INVALID_PARAMETER);
1224
                    }
1225
                }
1226
            }
1227
            i965_surface_native_memory(ctx,
1228
                                       obj_surface,
1229
                                       format,
1230
                                       expected_fourcc);
1231
            break;
1232
 
1233
        case I965_SURFACE_MEM_GEM_FLINK:
1234
        case I965_SURFACE_MEM_DRM_PRIME:
1235
            i965_suface_external_memory(ctx,
1236
                                        obj_surface,
1237
                                        memory_type,
1238
                                        memory_attibute,
1239
                                        i);
1240
            break;
1241
        }
1242
    }
1243
 
1244
    /* Error recovery */
1245
    if (VA_STATUS_SUCCESS != vaStatus) {
1246
        /* surfaces[i-1] was the last successful allocation */
1247
        for (; i--; ) {
1248
            struct object_surface *obj_surface = SURFACE(surfaces[i]);
1249
 
1250
            surfaces[i] = VA_INVALID_SURFACE;
1251
            assert(obj_surface);
1252
            i965_destroy_surface(&i965->surface_heap, (struct object_base *)obj_surface);
1253
        }
1254
    }
1255
 
1256
    return vaStatus;
1257
}
1258
 
1259
VAStatus
1260
i965_CreateSurfaces(VADriverContextP ctx,
1261
                    int width,
1262
                    int height,
1263
                    int format,
1264
                    int num_surfaces,
1265
                    VASurfaceID *surfaces)      /* out */
1266
{
1267
    return i965_CreateSurfaces2(ctx,
1268
                                format,
1269
                                width,
1270
                                height,
1271
                                surfaces,
1272
                                num_surfaces,
1273
                                NULL,
1274
                                0);
1275
}
1276
 
1277
VAStatus
1278
i965_DestroySurfaces(VADriverContextP ctx,
1279
                     VASurfaceID *surface_list,
1280
                     int num_surfaces)
1281
{
1282
    struct i965_driver_data *i965 = i965_driver_data(ctx);
1283
    int i;
1284
 
1285
    for (i = num_surfaces; i--; ) {
1286
        struct object_surface *obj_surface = SURFACE(surface_list[i]);
1287
 
1288
        ASSERT_RET(obj_surface, VA_STATUS_ERROR_INVALID_SURFACE);
1289
        i965_destroy_surface(&i965->surface_heap, (struct object_base *)obj_surface);
1290
    }
1291
 
1292
    return VA_STATUS_SUCCESS;
1293
}
1294
 
1295
VAStatus
1296
i965_QueryImageFormats(VADriverContextP ctx,
1297
                       VAImageFormat *format_list,      /* out */
1298
                       int *num_formats)                /* out */
1299
{
1300
    int n;
1301
 
1302
    for (n = 0; i965_image_formats_map[n].va_format.fourcc != 0; n++) {
1303
        const i965_image_format_map_t * const m = &i965_image_formats_map[n];
1304
        if (format_list)
1305
            format_list[n] = m->va_format;
1306
    }
1307
 
1308
    if (num_formats)
1309
        *num_formats = n;
1310
 
1311
    return VA_STATUS_SUCCESS;
1312
}
1313
 
1314
/*
1315
 * Guess the format when the usage of a VA surface is unknown
1316
 * 1. Without a valid context: YV12
1317
 * 2. The current context is valid:
1318
 *    a) always NV12 on GEN6 and later
1319
 *    b) I420 for MPEG-2 and NV12 for other codec on GEN4 & GEN5
1320
 */
1321
static void
1322
i965_guess_surface_format(VADriverContextP ctx,
1323
                          VASurfaceID surface,
1324
                          unsigned int *fourcc,
1325
                          unsigned int *is_tiled)
1326
{
1327
    struct i965_driver_data *i965 = i965_driver_data(ctx);
1328
    struct object_context *obj_context = NULL;
1329
    struct object_config *obj_config = NULL;
1330
 
1331
    *fourcc = VA_FOURCC_YV12;
1332
    *is_tiled = 0;
1333
 
1334
    if (i965->current_context_id == VA_INVALID_ID)
1335
        return;
1336
 
1337
    obj_context = CONTEXT(i965->current_context_id);
1338
 
1339
    if (!obj_context)
1340
        return;
1341
 
1342
    obj_config = obj_context->obj_config;
1343
    assert(obj_config);
1344
 
1345
    if (!obj_config)
1346
        return;
1347
 
1348
    if (IS_GEN6(i965->intel.device_info) ||
1349
        IS_GEN7(i965->intel.device_info) ||
1350
        IS_GEN8(i965->intel.device_info)) {
1351
        *fourcc = VA_FOURCC_NV12;
1352
        *is_tiled = 1;
1353
        return;
1354
    }
1355
 
1356
    switch (obj_config->profile) {
1357
    case VAProfileMPEG2Simple:
1358
    case VAProfileMPEG2Main:
1359
        *fourcc = VA_FOURCC_I420;
1360
        *is_tiled = 0;
1361
        break;
1362
 
1363
    default:
1364
        *fourcc = VA_FOURCC_NV12;
1365
        *is_tiled = 0;
1366
        break;
1367
    }
1368
}
1369
 
1370
VAStatus
1371
i965_QuerySubpictureFormats(VADriverContextP ctx,
1372
                            VAImageFormat *format_list,         /* out */
1373
                            unsigned int *flags,                /* out */
1374
                            unsigned int *num_formats)          /* out */
1375
{
1376
    int n;
1377
 
1378
    for (n = 0; i965_subpic_formats_map[n].va_format.fourcc != 0; n++) {
1379
        const i965_subpic_format_map_t * const m = &i965_subpic_formats_map[n];
1380
        if (format_list)
1381
            format_list[n] = m->va_format;
1382
        if (flags)
1383
            flags[n] = m->va_flags;
1384
    }
1385
 
1386
    if (num_formats)
1387
        *num_formats = n;
1388
 
1389
    return VA_STATUS_SUCCESS;
1390
}
1391
 
1392
static void
1393
i965_destroy_subpic(struct object_heap *heap, struct object_base *obj)
1394
{
1395
    //    struct object_subpic *obj_subpic = (struct object_subpic *)obj;
1396
 
1397
    object_heap_free(heap, obj);
1398
}
1399
 
1400
VAStatus
1401
i965_CreateSubpicture(VADriverContextP ctx,
1402
                      VAImageID image,
1403
                      VASubpictureID *subpicture)         /* out */
1404
{
1405
    struct i965_driver_data *i965 = i965_driver_data(ctx);
1406
    VASubpictureID subpicID = NEW_SUBPIC_ID()
1407
    struct object_subpic *obj_subpic = SUBPIC(subpicID);
1408
 
1409
    if (!obj_subpic)
1410
        return VA_STATUS_ERROR_ALLOCATION_FAILED;
1411
 
1412
    struct object_image *obj_image = IMAGE(image);
1413
    if (!obj_image)
1414
        return VA_STATUS_ERROR_INVALID_IMAGE;
1415
 
1416
    const i965_subpic_format_map_t * const m = get_subpic_format(&obj_image->image.format);
1417
    if (!m)
1418
        return VA_STATUS_ERROR_UNKNOWN; /* XXX: VA_STATUS_ERROR_UNSUPPORTED_FORMAT? */
1419
 
1420
    *subpicture = subpicID;
1421
    obj_subpic->image  = image;
1422
    obj_subpic->obj_image = obj_image;
1423
    obj_subpic->format = m->format;
1424
    obj_subpic->width  = obj_image->image.width;
1425
    obj_subpic->height = obj_image->image.height;
1426
    obj_subpic->pitch  = obj_image->image.pitches[0];
1427
    obj_subpic->bo     = obj_image->bo;
1428
    obj_subpic->global_alpha = 1.0;
1429
 
1430
    return VA_STATUS_SUCCESS;
1431
}
1432
 
1433
VAStatus
1434
i965_DestroySubpicture(VADriverContextP ctx,
1435
                       VASubpictureID subpicture)
1436
{
1437
    struct i965_driver_data *i965 = i965_driver_data(ctx);
1438
    struct object_subpic *obj_subpic = SUBPIC(subpicture);
1439
 
1440
    if (!obj_subpic)
1441
        return VA_STATUS_ERROR_INVALID_SUBPICTURE;
1442
 
1443
    ASSERT_RET(obj_subpic->obj_image, VA_STATUS_ERROR_INVALID_SUBPICTURE);
1444
    i965_destroy_subpic(&i965->subpic_heap, (struct object_base *)obj_subpic);
1445
    return VA_STATUS_SUCCESS;
1446
}
1447
 
1448
VAStatus
1449
i965_SetSubpictureImage(VADriverContextP ctx,
1450
                        VASubpictureID subpicture,
1451
                        VAImageID image)
1452
{
1453
    /* TODO */
1454
    return VA_STATUS_ERROR_UNIMPLEMENTED;
1455
}
1456
 
1457
VAStatus
1458
i965_SetSubpictureChromakey(VADriverContextP ctx,
1459
                            VASubpictureID subpicture,
1460
                            unsigned int chromakey_min,
1461
                            unsigned int chromakey_max,
1462
                            unsigned int chromakey_mask)
1463
{
1464
    /* TODO */
1465
    return VA_STATUS_ERROR_UNIMPLEMENTED;
1466
}
1467
 
1468
VAStatus
1469
i965_SetSubpictureGlobalAlpha(VADriverContextP ctx,
1470
                              VASubpictureID subpicture,
1471
                              float global_alpha)
1472
{
1473
    struct i965_driver_data *i965 = i965_driver_data(ctx);
1474
    struct object_subpic *obj_subpic = SUBPIC(subpicture);
1475
 
1476
    if(global_alpha > 1.0 || global_alpha < 0.0){
1477
       return VA_STATUS_ERROR_INVALID_PARAMETER;
1478
    }
1479
 
1480
    if (!obj_subpic)
1481
        return VA_STATUS_ERROR_INVALID_SUBPICTURE;
1482
 
1483
    obj_subpic->global_alpha  = global_alpha;
1484
 
1485
    return VA_STATUS_SUCCESS;
1486
}
1487
 
1488
VAStatus
1489
i965_AssociateSubpicture(VADriverContextP ctx,
1490
                         VASubpictureID subpicture,
1491
                         VASurfaceID *target_surfaces,
1492
                         int num_surfaces,
1493
                         short src_x, /* upper left offset in subpicture */
1494
                         short src_y,
1495
                         unsigned short src_width,
1496
                         unsigned short src_height,
1497
                         short dest_x, /* upper left offset in surface */
1498
                         short dest_y,
1499
                         unsigned short dest_width,
1500
                         unsigned short dest_height,
1501
                         /*
1502
                          * whether to enable chroma-keying or global-alpha
1503
                          * see VA_SUBPICTURE_XXX values
1504
                          */
1505
                         unsigned int flags)
1506
{
1507
    struct i965_driver_data *i965 = i965_driver_data(ctx);
1508
    struct object_subpic *obj_subpic = SUBPIC(subpicture);
1509
    int i, j;
1510
 
1511
    if (!obj_subpic)
1512
        return VA_STATUS_ERROR_INVALID_SUBPICTURE;
1513
 
1514
    ASSERT_RET(obj_subpic->obj_image, VA_STATUS_ERROR_INVALID_SUBPICTURE);
1515
 
1516
    obj_subpic->src_rect.x      = src_x;
1517
    obj_subpic->src_rect.y      = src_y;
1518
    obj_subpic->src_rect.width  = src_width;
1519
    obj_subpic->src_rect.height = src_height;
1520
    obj_subpic->dst_rect.x      = dest_x;
1521
    obj_subpic->dst_rect.y      = dest_y;
1522
    obj_subpic->dst_rect.width  = dest_width;
1523
    obj_subpic->dst_rect.height = dest_height;
1524
    obj_subpic->flags           = flags;
1525
 
1526
    for (i = 0; i < num_surfaces; i++) {
1527
        struct object_surface *obj_surface = SURFACE(target_surfaces[i]);
1528
        if (!obj_surface)
1529
            return VA_STATUS_ERROR_INVALID_SURFACE;
1530
 
1531
        for(j = 0; j < I965_MAX_SUBPIC_SUM; j ++){
1532
            if(obj_surface->subpic[j] == VA_INVALID_ID){
1533
                assert(obj_surface->obj_subpic[j] == NULL);
1534
                obj_surface->subpic[j] = subpicture;
1535
                obj_surface->obj_subpic[j] = obj_subpic;
1536
                break;
1537
            }
1538
        }
1539
 
1540
        if(j == I965_MAX_SUBPIC_SUM){
1541
            return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
1542
        }
1543
 
1544
    }
1545
    return VA_STATUS_SUCCESS;
1546
}
1547
 
1548
 
1549
VAStatus
1550
i965_DeassociateSubpicture(VADriverContextP ctx,
1551
                           VASubpictureID subpicture,
1552
                           VASurfaceID *target_surfaces,
1553
                           int num_surfaces)
1554
{
1555
    struct i965_driver_data *i965 = i965_driver_data(ctx);
1556
    struct object_subpic *obj_subpic = SUBPIC(subpicture);
1557
    int i, j;
1558
 
1559
    if (!obj_subpic)
1560
        return VA_STATUS_ERROR_INVALID_SUBPICTURE;
1561
 
1562
    for (i = 0; i < num_surfaces; i++) {
1563
        struct object_surface *obj_surface = SURFACE(target_surfaces[i]);
1564
        if (!obj_surface)
1565
            return VA_STATUS_ERROR_INVALID_SURFACE;
1566
 
1567
        for(j = 0; j < I965_MAX_SUBPIC_SUM; j ++){
1568
            if (obj_surface->subpic[j] == subpicture) {
1569
                assert(obj_surface->obj_subpic[j] == obj_subpic);
1570
                obj_surface->subpic[j] = VA_INVALID_ID;
1571
                obj_surface->obj_subpic[j] = NULL;
1572
                break;
1573
            }
1574
        }
1575
 
1576
        if(j == I965_MAX_SUBPIC_SUM){
1577
            return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
1578
        }
1579
    }
1580
    return VA_STATUS_SUCCESS;
1581
}
1582
 
1583
void
1584
i965_reference_buffer_store(struct buffer_store **ptr,
1585
                            struct buffer_store *buffer_store)
1586
{
1587
    assert(*ptr == NULL);
1588
 
1589
    if (buffer_store) {
1590
        buffer_store->ref_count++;
1591
        *ptr = buffer_store;
1592
    }
1593
}
1594
 
1595
void
1596
i965_release_buffer_store(struct buffer_store **ptr)
1597
{
1598
    struct buffer_store *buffer_store = *ptr;
1599
 
1600
    if (buffer_store == NULL)
1601
        return;
1602
 
1603
    assert(buffer_store->bo || buffer_store->buffer);
1604
    assert(!(buffer_store->bo && buffer_store->buffer));
1605
    buffer_store->ref_count--;
1606
 
1607
    if (buffer_store->ref_count == 0) {
1608
        dri_bo_unreference(buffer_store->bo);
1609
        free(buffer_store->buffer);
1610
        buffer_store->bo = NULL;
1611
        buffer_store->buffer = NULL;
1612
        free(buffer_store);
1613
    }
1614
 
1615
    *ptr = NULL;
1616
}
1617
 
1618
static void
1619
i965_destroy_context(struct object_heap *heap, struct object_base *obj)
1620
{
1621
    struct object_context *obj_context = (struct object_context *)obj;
1622
    int i;
1623
 
1624
    if (obj_context->hw_context) {
1625
        obj_context->hw_context->destroy(obj_context->hw_context);
1626
        obj_context->hw_context = NULL;
1627
    }
1628
 
1629
    if (obj_context->codec_type == CODEC_PROC) {
1630
        i965_release_buffer_store(&obj_context->codec_state.proc.pipeline_param);
1631
 
1632
    } else if (obj_context->codec_type == CODEC_ENC) {
1633
        assert(obj_context->codec_state.encode.num_slice_params <= obj_context->codec_state.encode.max_slice_params);
1634
        i965_release_buffer_store(&obj_context->codec_state.encode.pic_param);
1635
        i965_release_buffer_store(&obj_context->codec_state.encode.seq_param);
1636
 
1637
        for (i = 0; i < obj_context->codec_state.encode.num_slice_params; i++)
1638
            i965_release_buffer_store(&obj_context->codec_state.encode.slice_params[i]);
1639
 
1640
        free(obj_context->codec_state.encode.slice_params);
1641
 
1642
        assert(obj_context->codec_state.encode.num_slice_params_ext <= obj_context->codec_state.encode.max_slice_params_ext);
1643
        i965_release_buffer_store(&obj_context->codec_state.encode.pic_param_ext);
1644
        i965_release_buffer_store(&obj_context->codec_state.encode.seq_param_ext);
1645
 
1646
        for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_param); i++)
1647
            i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_param[i]);
1648
 
1649
        for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_data); i++)
1650
            i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data[i]);
1651
 
1652
        for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.misc_param); i++)
1653
            i965_release_buffer_store(&obj_context->codec_state.encode.misc_param[i]);
1654
 
1655
        for (i = 0; i < obj_context->codec_state.encode.num_slice_params_ext; i++)
1656
            i965_release_buffer_store(&obj_context->codec_state.encode.slice_params_ext[i]);
1657
 
1658
        free(obj_context->codec_state.encode.slice_params_ext);
1659
        if (obj_context->codec_state.encode.slice_rawdata_index) {
1660
            free(obj_context->codec_state.encode.slice_rawdata_index);
1661
            obj_context->codec_state.encode.slice_rawdata_index = NULL;
1662
        }
1663
        if (obj_context->codec_state.encode.slice_rawdata_count) {
1664
            free(obj_context->codec_state.encode.slice_rawdata_count);
1665
            obj_context->codec_state.encode.slice_rawdata_count = NULL;
1666
        }
1667
 
1668
        if (obj_context->codec_state.encode.slice_header_index) {
1669
            free(obj_context->codec_state.encode.slice_header_index);
1670
            obj_context->codec_state.encode.slice_header_index = NULL;
1671
        }
1672
 
1673
        for (i = 0; i < obj_context->codec_state.encode.num_packed_header_params_ext; i++)
1674
            i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_params_ext[i]);
1675
        free(obj_context->codec_state.encode.packed_header_params_ext);
1676
 
1677
        for (i = 0; i < obj_context->codec_state.encode.num_packed_header_data_ext; i++)
1678
            i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data_ext[i]);
1679
        free(obj_context->codec_state.encode.packed_header_data_ext);
1680
 
1681
    } else {
1682
        assert(obj_context->codec_state.decode.num_slice_params <= obj_context->codec_state.decode.max_slice_params);
1683
        assert(obj_context->codec_state.decode.num_slice_datas <= obj_context->codec_state.decode.max_slice_datas);
1684
 
1685
        i965_release_buffer_store(&obj_context->codec_state.decode.pic_param);
1686
        i965_release_buffer_store(&obj_context->codec_state.decode.iq_matrix);
1687
        i965_release_buffer_store(&obj_context->codec_state.decode.bit_plane);
1688
 
1689
        for (i = 0; i < obj_context->codec_state.decode.num_slice_params; i++)
1690
            i965_release_buffer_store(&obj_context->codec_state.decode.slice_params[i]);
1691
 
1692
        for (i = 0; i < obj_context->codec_state.decode.num_slice_datas; i++)
1693
            i965_release_buffer_store(&obj_context->codec_state.decode.slice_datas[i]);
1694
 
1695
        free(obj_context->codec_state.decode.slice_params);
1696
        free(obj_context->codec_state.decode.slice_datas);
1697
    }
1698
 
1699
    free(obj_context->render_targets);
1700
    object_heap_free(heap, obj);
1701
}
1702
 
1703
VAStatus
1704
i965_CreateContext(VADriverContextP ctx,
1705
                   VAConfigID config_id,
1706
                   int picture_width,
1707
                   int picture_height,
1708
                   int flag,
1709
                   VASurfaceID *render_targets,
1710
                   int num_render_targets,
1711
                   VAContextID *context)                /* out */
1712
{
1713
    struct i965_driver_data *i965 = i965_driver_data(ctx);
1714
    struct i965_render_state *render_state = &i965->render_state;
1715
    struct object_config *obj_config = CONFIG(config_id);
1716
    struct object_context *obj_context = NULL;
1717
    VAConfigAttrib *attrib;
1718
    VAStatus vaStatus = VA_STATUS_SUCCESS;
1719
    int contextID;
1720
    int i;
1721
 
1722
    if (NULL == obj_config) {
1723
        vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
1724
        return vaStatus;
1725
    }
1726
 
1727
    if (picture_width > i965->codec_info->max_width ||
1728
        picture_height > i965->codec_info->max_height) {
1729
        vaStatus = VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
1730
        return vaStatus;
1731
    }
1732
 
1733
    /* Validate flag */
1734
    /* Validate picture dimensions */
1735
    contextID = NEW_CONTEXT_ID();
1736
    obj_context = CONTEXT(contextID);
1737
 
1738
    if (NULL == obj_context) {
1739
        vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1740
        return vaStatus;
1741
    }
1742
 
1743
    render_state->inited = 1;
1744
 
1745
    switch (obj_config->profile) {
1746
    case VAProfileH264ConstrainedBaseline:
1747
    case VAProfileH264Main:
1748
    case VAProfileH264High:
1749
        if (!HAS_H264_DECODING(i965) &&
1750
            !HAS_H264_ENCODING(i965))
1751
            return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
1752
        render_state->interleaved_uv = 1;
1753
        break;
1754
    case VAProfileH264MultiviewHigh:
1755
    case VAProfileH264StereoHigh:
1756
        if (!HAS_H264_MVC_DECODING(i965))
1757
            return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
1758
        render_state->interleaved_uv = 1;
1759
        break;
1760
    default:
1761
        render_state->interleaved_uv = !!(IS_GEN6(i965->intel.device_info) || IS_GEN7(i965->intel.device_info) || IS_GEN8(i965->intel.device_info));
1762
        break;
1763
    }
1764
 
1765
    *context = contextID;
1766
    obj_context->flags = flag;
1767
    obj_context->context_id = contextID;
1768
    obj_context->obj_config = obj_config;
1769
    obj_context->picture_width = picture_width;
1770
    obj_context->picture_height = picture_height;
1771
    obj_context->num_render_targets = num_render_targets;
1772
    obj_context->render_targets =
1773
        (VASurfaceID *)calloc(num_render_targets, sizeof(VASurfaceID));
1774
    obj_context->hw_context = NULL;
1775
 
1776
    for(i = 0; i < num_render_targets; i++) {
1777
        if (NULL == SURFACE(render_targets[i])) {
1778
            vaStatus = VA_STATUS_ERROR_INVALID_SURFACE;
1779
            break;
1780
        }
1781
 
1782
        obj_context->render_targets[i] = render_targets[i];
1783
    }
1784
 
1785
    if (VA_STATUS_SUCCESS == vaStatus) {
1786
        if (VAEntrypointVideoProc == obj_config->entrypoint) {
1787
            obj_context->codec_type = CODEC_PROC;
1788
            memset(&obj_context->codec_state.proc, 0, sizeof(obj_context->codec_state.proc));
1789
            obj_context->codec_state.proc.current_render_target = VA_INVALID_ID;
1790
            assert(i965->codec_info->proc_hw_context_init);
1791
            obj_context->hw_context = i965->codec_info->proc_hw_context_init(ctx, obj_config);
1792
        } else if (VAEntrypointEncSlice == obj_config->entrypoint) { /*encode routin only*/
1793
            VAConfigAttrib *packed_attrib;
1794
            obj_context->codec_type = CODEC_ENC;
1795
            memset(&obj_context->codec_state.encode, 0, sizeof(obj_context->codec_state.encode));
1796
            obj_context->codec_state.encode.current_render_target = VA_INVALID_ID;
1797
            obj_context->codec_state.encode.max_slice_params = NUM_SLICES;
1798
            obj_context->codec_state.encode.slice_params = calloc(obj_context->codec_state.encode.max_slice_params,
1799
                                                               sizeof(*obj_context->codec_state.encode.slice_params));
1800
            obj_context->codec_state.encode.max_packed_header_params_ext = NUM_SLICES;
1801
            obj_context->codec_state.encode.packed_header_params_ext =
1802
                calloc(obj_context->codec_state.encode.max_packed_header_params_ext,
1803
                       sizeof(struct buffer_store *));
1804
 
1805
            obj_context->codec_state.encode.max_packed_header_data_ext = NUM_SLICES;
1806
            obj_context->codec_state.encode.packed_header_data_ext =
1807
                calloc(obj_context->codec_state.encode.max_packed_header_data_ext,
1808
                       sizeof(struct buffer_store *));
1809
 
1810
            obj_context->codec_state.encode.max_slice_num = NUM_SLICES;
1811
            obj_context->codec_state.encode.slice_rawdata_index =
1812
                calloc(obj_context->codec_state.encode.max_slice_num, sizeof(int));
1813
            obj_context->codec_state.encode.slice_rawdata_count =
1814
                calloc(obj_context->codec_state.encode.max_slice_num, sizeof(int));
1815
 
1816
            obj_context->codec_state.encode.slice_header_index =
1817
                calloc(obj_context->codec_state.encode.max_slice_num, sizeof(int));
1818
 
1819
            obj_context->codec_state.encode.slice_index = 0;
1820
            packed_attrib = i965_lookup_config_attribute(obj_config, VAConfigAttribEncPackedHeaders);
1821
            if (packed_attrib)
1822
                obj_context->codec_state.encode.packed_header_flag = packed_attrib->value;
1823
            else {
1824
                /* use the default value. SPS/PPS/RAWDATA is passed from user
1825
                 * while Slice_header data is generated by driver.
1826
                 */
1827
                obj_context->codec_state.encode.packed_header_flag =
1828
                               VA_ENC_PACKED_HEADER_SEQUENCE |
1829
                               VA_ENC_PACKED_HEADER_PICTURE |
1830
                               VA_ENC_PACKED_HEADER_RAW_DATA;
1831
            }
1832
            assert(i965->codec_info->enc_hw_context_init);
1833
            obj_context->hw_context = i965->codec_info->enc_hw_context_init(ctx, obj_config);
1834
        } else {
1835
            obj_context->codec_type = CODEC_DEC;
1836
            memset(&obj_context->codec_state.decode, 0, sizeof(obj_context->codec_state.decode));
1837
            obj_context->codec_state.decode.current_render_target = -1;
1838
            obj_context->codec_state.decode.max_slice_params = NUM_SLICES;
1839
            obj_context->codec_state.decode.max_slice_datas = NUM_SLICES;
1840
            obj_context->codec_state.decode.slice_params = calloc(obj_context->codec_state.decode.max_slice_params,
1841
                                                               sizeof(*obj_context->codec_state.decode.slice_params));
1842
            obj_context->codec_state.decode.slice_datas = calloc(obj_context->codec_state.decode.max_slice_datas,
1843
                                                              sizeof(*obj_context->codec_state.decode.slice_datas));
1844
 
1845
            assert(i965->codec_info->dec_hw_context_init);
1846
            obj_context->hw_context = i965->codec_info->dec_hw_context_init(ctx, obj_config);
1847
        }
1848
    }
1849
 
1850
    attrib = i965_lookup_config_attribute(obj_config, VAConfigAttribRTFormat);
1851
    if (!attrib)
1852
        return VA_STATUS_ERROR_INVALID_CONFIG;
1853
    obj_context->codec_state.base.chroma_formats = attrib->value;
1854
 
1855
    /* Error recovery */
1856
    if (VA_STATUS_SUCCESS != vaStatus) {
1857
        i965_destroy_context(&i965->context_heap, (struct object_base *)obj_context);
1858
    }
1859
 
1860
    i965->current_context_id = contextID;
1861
 
1862
    return vaStatus;
1863
}
1864
 
1865
VAStatus
1866
i965_DestroyContext(VADriverContextP ctx, VAContextID context)
1867
{
1868
    struct i965_driver_data *i965 = i965_driver_data(ctx);
1869
    struct object_context *obj_context = CONTEXT(context);
1870
 
1871
    ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
1872
 
1873
    if (i965->current_context_id == context)
1874
        i965->current_context_id = VA_INVALID_ID;
1875
 
1876
    i965_destroy_context(&i965->context_heap, (struct object_base *)obj_context);
1877
 
1878
    return VA_STATUS_SUCCESS;
1879
}
1880
 
1881
static void
1882
i965_destroy_buffer(struct object_heap *heap, struct object_base *obj)
1883
{
1884
    struct object_buffer *obj_buffer = (struct object_buffer *)obj;
1885
 
1886
    assert(obj_buffer->buffer_store);
1887
    i965_release_buffer_store(&obj_buffer->buffer_store);
1888
    object_heap_free(heap, obj);
1889
}
1890
 
1891
static VAStatus
1892
i965_create_buffer_internal(VADriverContextP ctx,
1893
                            VAContextID context,
1894
                            VABufferType type,
1895
                            unsigned int size,
1896
                            unsigned int num_elements,
1897
                            void *data,
1898
                            dri_bo *store_bo,
1899
                            VABufferID *buf_id)
1900
{
1901
    struct i965_driver_data *i965 = i965_driver_data(ctx);
1902
    struct object_buffer *obj_buffer = NULL;
1903
    struct buffer_store *buffer_store = NULL;
1904
    int bufferID;
1905
 
1906
    /* Validate type */
1907
    switch (type) {
1908
    case VAPictureParameterBufferType:
1909
    case VAIQMatrixBufferType:
1910
    case VAQMatrixBufferType:
1911
    case VABitPlaneBufferType:
1912
    case VASliceGroupMapBufferType:
1913
    case VASliceParameterBufferType:
1914
    case VASliceDataBufferType:
1915
    case VAMacroblockParameterBufferType:
1916
    case VAResidualDataBufferType:
1917
    case VADeblockingParameterBufferType:
1918
    case VAImageBufferType:
1919
    case VAEncCodedBufferType:
1920
    case VAEncSequenceParameterBufferType:
1921
    case VAEncPictureParameterBufferType:
1922
    case VAEncSliceParameterBufferType:
1923
    case VAEncPackedHeaderParameterBufferType:
1924
    case VAEncPackedHeaderDataBufferType:
1925
    case VAEncMiscParameterBufferType:
1926
    case VAProcPipelineParameterBufferType:
1927
    case VAProcFilterParameterBufferType:
1928
    case VAHuffmanTableBufferType:
1929
    case VAProbabilityBufferType:
1930
        /* Ok */
1931
        break;
1932
 
1933
    default:
1934
        return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
1935
    }
1936
 
1937
    bufferID = NEW_BUFFER_ID();
1938
    obj_buffer = BUFFER(bufferID);
1939
 
1940
    if (NULL == obj_buffer) {
1941
        return VA_STATUS_ERROR_ALLOCATION_FAILED;
1942
    }
1943
 
1944
    if (type == VAEncCodedBufferType) {
1945
        size += I965_CODEDBUFFER_HEADER_SIZE;
1946
        size += 0x1000; /* for upper bound check */
1947
    }
1948
 
1949
    obj_buffer->max_num_elements = num_elements;
1950
    obj_buffer->num_elements = num_elements;
1951
    obj_buffer->size_element = size;
1952
    obj_buffer->type = type;
1953
    obj_buffer->export_refcount = 0;
1954
    obj_buffer->buffer_store = NULL;
1955
    buffer_store = calloc(1, sizeof(struct buffer_store));
1956
    assert(buffer_store);
1957
    buffer_store->ref_count = 1;
1958
 
1959
    if (store_bo != NULL) {
1960
        buffer_store->bo = store_bo;
1961
        dri_bo_reference(buffer_store->bo);
1962
 
1963
        if (data)
1964
            dri_bo_subdata(buffer_store->bo, 0, size * num_elements, data);
1965
    } else if (type == VASliceDataBufferType ||
1966
               type == VAImageBufferType ||
1967
               type == VAEncCodedBufferType ||
1968
               type == VAProbabilityBufferType) {
1969
        buffer_store->bo = dri_bo_alloc(i965->intel.bufmgr,
1970
                                        "Buffer",
1971
                                        size * num_elements, 64);
1972
        assert(buffer_store->bo);
1973
 
1974
        if (type == VAEncCodedBufferType) {
1975
            struct i965_coded_buffer_segment *coded_buffer_segment;
1976
 
1977
            dri_bo_map(buffer_store->bo, 1);
1978
            coded_buffer_segment = (struct i965_coded_buffer_segment *)buffer_store->bo->virtual;
1979
            coded_buffer_segment->base.size = size - I965_CODEDBUFFER_HEADER_SIZE;
1980
            coded_buffer_segment->base.bit_offset = 0;
1981
            coded_buffer_segment->base.status = 0;
1982
            coded_buffer_segment->base.buf = NULL;
1983
            coded_buffer_segment->base.next = NULL;
1984
            coded_buffer_segment->mapped = 0;
1985
            coded_buffer_segment->codec = 0;
1986
            dri_bo_unmap(buffer_store->bo);
1987
        } else if (data) {
1988
            dri_bo_subdata(buffer_store->bo, 0, size * num_elements, data);
1989
        }
1990
 
1991
    } else {
1992
        int msize = size;
1993
 
1994
        if (type == VAEncPackedHeaderDataBufferType) {
1995
            msize = ALIGN(size, 4);
1996
        }
1997
 
1998
        buffer_store->buffer = malloc(msize * num_elements);
1999
        assert(buffer_store->buffer);
2000
 
2001
        if (data)
2002
            memcpy(buffer_store->buffer, data, size * num_elements);
2003
    }
2004
 
2005
    buffer_store->num_elements = obj_buffer->num_elements;
2006
    i965_reference_buffer_store(&obj_buffer->buffer_store, buffer_store);
2007
    i965_release_buffer_store(&buffer_store);
2008
    *buf_id = bufferID;
2009
 
2010
    return VA_STATUS_SUCCESS;
2011
}
2012
 
2013
VAStatus
2014
i965_CreateBuffer(VADriverContextP ctx,
2015
                  VAContextID context,          /* in */
2016
                  VABufferType type,            /* in */
2017
                  unsigned int size,            /* in */
2018
                  unsigned int num_elements,    /* in */
2019
                  void *data,                   /* in */
2020
                  VABufferID *buf_id)           /* out */
2021
{
2022
    return i965_create_buffer_internal(ctx, context, type, size, num_elements, data, NULL, buf_id);
2023
}
2024
 
2025
 
2026
VAStatus
2027
i965_BufferSetNumElements(VADriverContextP ctx,
2028
                          VABufferID buf_id,           /* in */
2029
                          unsigned int num_elements)   /* in */
2030
{
2031
    struct i965_driver_data *i965 = i965_driver_data(ctx);
2032
    struct object_buffer *obj_buffer = BUFFER(buf_id);
2033
    VAStatus vaStatus = VA_STATUS_SUCCESS;
2034
 
2035
    ASSERT_RET(obj_buffer, VA_STATUS_ERROR_INVALID_BUFFER);
2036
 
2037
    if ((num_elements < 0) ||
2038
        (num_elements > obj_buffer->max_num_elements)) {
2039
        vaStatus = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
2040
    } else {
2041
        obj_buffer->num_elements = num_elements;
2042
        if (obj_buffer->buffer_store != NULL) {
2043
            obj_buffer->buffer_store->num_elements = num_elements;
2044
        }
2045
    }
2046
 
2047
    return vaStatus;
2048
}
2049
 
2050
VAStatus
2051
i965_MapBuffer(VADriverContextP ctx,
2052
               VABufferID buf_id,       /* in */
2053
               void **pbuf)             /* out */
2054
{
2055
    struct i965_driver_data *i965 = i965_driver_data(ctx);
2056
    struct object_buffer *obj_buffer = BUFFER(buf_id);
2057
    VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
2058
 
2059
    ASSERT_RET(obj_buffer && obj_buffer->buffer_store, VA_STATUS_ERROR_INVALID_BUFFER);
2060
    ASSERT_RET(obj_buffer->buffer_store->bo || obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_INVALID_BUFFER);
2061
    ASSERT_RET(!(obj_buffer->buffer_store->bo && obj_buffer->buffer_store->buffer), VA_STATUS_ERROR_INVALID_BUFFER);
2062
 
2063
    if (NULL != obj_buffer->buffer_store->bo) {
2064
        unsigned int tiling, swizzle;
2065
 
2066
        dri_bo_get_tiling(obj_buffer->buffer_store->bo, &tiling, &swizzle);
2067
 
2068
        if (tiling != I915_TILING_NONE)
2069
            drm_intel_gem_bo_map_gtt(obj_buffer->buffer_store->bo);
2070
        else
2071
            dri_bo_map(obj_buffer->buffer_store->bo, 1);
2072
 
2073
        ASSERT_RET(obj_buffer->buffer_store->bo->virtual, VA_STATUS_ERROR_OPERATION_FAILED);
2074
        *pbuf = obj_buffer->buffer_store->bo->virtual;
2075
 
2076
        if (obj_buffer->type == VAEncCodedBufferType) {
2077
            int i;
2078
            unsigned char *buffer = NULL;
2079
            struct i965_coded_buffer_segment *coded_buffer_segment = (struct i965_coded_buffer_segment *)(obj_buffer->buffer_store->bo->virtual);
2080
 
2081
            if (!coded_buffer_segment->mapped) {
2082
                unsigned char delimiter0, delimiter1, delimiter2, delimiter3, delimiter4;
2083
 
2084
                coded_buffer_segment->base.buf = buffer = (unsigned char *)(obj_buffer->buffer_store->bo->virtual) + I965_CODEDBUFFER_HEADER_SIZE;
2085
 
2086
                if (coded_buffer_segment->codec == CODEC_H264 ||
2087
                    coded_buffer_segment->codec == CODEC_H264_MVC) {
2088
                    delimiter0 = H264_DELIMITER0;
2089
                    delimiter1 = H264_DELIMITER1;
2090
                    delimiter2 = H264_DELIMITER2;
2091
                    delimiter3 = H264_DELIMITER3;
2092
                    delimiter4 = H264_DELIMITER4;
2093
                } else if (coded_buffer_segment->codec == CODEC_MPEG2) {
2094
                    delimiter0 = MPEG2_DELIMITER0;
2095
                    delimiter1 = MPEG2_DELIMITER1;
2096
                    delimiter2 = MPEG2_DELIMITER2;
2097
                    delimiter3 = MPEG2_DELIMITER3;
2098
                    delimiter4 = MPEG2_DELIMITER4;
2099
                } else {
2100
                    ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_PROFILE);
2101
                }
2102
 
2103
                for (i = 0; i < obj_buffer->size_element - I965_CODEDBUFFER_HEADER_SIZE - 3 - 0x1000; i++) {
2104
                    if ((buffer[i] == delimiter0) &&
2105
                        (buffer[i + 1] == delimiter1) &&
2106
                        (buffer[i + 2] == delimiter2) &&
2107
                        (buffer[i + 3] == delimiter3) &&
2108
                        (buffer[i + 4] == delimiter4))
2109
                        break;
2110
                }
2111
 
2112
                if (i == obj_buffer->size_element - I965_CODEDBUFFER_HEADER_SIZE - 3 - 0x1000) {
2113
                    coded_buffer_segment->base.status |= VA_CODED_BUF_STATUS_SLICE_OVERFLOW_MASK;
2114
                }
2115
 
2116
                coded_buffer_segment->base.size = i;
2117
                coded_buffer_segment->mapped = 1;
2118
            } else {
2119
                assert(coded_buffer_segment->base.buf);
2120
            }
2121
        }
2122
 
2123
        vaStatus = VA_STATUS_SUCCESS;
2124
    } else if (NULL != obj_buffer->buffer_store->buffer) {
2125
        *pbuf = obj_buffer->buffer_store->buffer;
2126
        vaStatus = VA_STATUS_SUCCESS;
2127
    }
2128
 
2129
    return vaStatus;
2130
}
2131
 
2132
VAStatus
2133
i965_UnmapBuffer(VADriverContextP ctx, VABufferID buf_id)
2134
{
2135
    struct i965_driver_data *i965 = i965_driver_data(ctx);
2136
    struct object_buffer *obj_buffer = BUFFER(buf_id);
2137
    VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
2138
 
2139
    if ((buf_id & OBJECT_HEAP_OFFSET_MASK) != BUFFER_ID_OFFSET)
2140
        return VA_STATUS_ERROR_INVALID_BUFFER;
2141
 
2142
    ASSERT_RET(obj_buffer && obj_buffer->buffer_store, VA_STATUS_ERROR_INVALID_BUFFER);
2143
    ASSERT_RET(obj_buffer->buffer_store->bo || obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_OPERATION_FAILED);
2144
    ASSERT_RET(!(obj_buffer->buffer_store->bo && obj_buffer->buffer_store->buffer), VA_STATUS_ERROR_OPERATION_FAILED);
2145
 
2146
    if (NULL != obj_buffer->buffer_store->bo) {
2147
        unsigned int tiling, swizzle;
2148
 
2149
        dri_bo_get_tiling(obj_buffer->buffer_store->bo, &tiling, &swizzle);
2150
 
2151
        if (tiling != I915_TILING_NONE)
2152
            drm_intel_gem_bo_unmap_gtt(obj_buffer->buffer_store->bo);
2153
        else
2154
            dri_bo_unmap(obj_buffer->buffer_store->bo);
2155
 
2156
        vaStatus = VA_STATUS_SUCCESS;
2157
    } else if (NULL != obj_buffer->buffer_store->buffer) {
2158
        /* Do nothing */
2159
        vaStatus = VA_STATUS_SUCCESS;
2160
    }
2161
 
2162
    return vaStatus;
2163
}
2164
 
2165
VAStatus
2166
i965_DestroyBuffer(VADriverContextP ctx, VABufferID buffer_id)
2167
{
2168
    struct i965_driver_data *i965 = i965_driver_data(ctx);
2169
    struct object_buffer *obj_buffer = BUFFER(buffer_id);
2170
 
2171
    ASSERT_RET(obj_buffer, VA_STATUS_ERROR_INVALID_BUFFER);
2172
 
2173
    i965_destroy_buffer(&i965->buffer_heap, (struct object_base *)obj_buffer);
2174
 
2175
    return VA_STATUS_SUCCESS;
2176
}
2177
 
2178
VAStatus
2179
i965_BeginPicture(VADriverContextP ctx,
2180
                  VAContextID context,
2181
                  VASurfaceID render_target)
2182
{
2183
    struct i965_driver_data *i965 = i965_driver_data(ctx);
2184
    struct object_context *obj_context = CONTEXT(context);
2185
    struct object_surface *obj_surface = SURFACE(render_target);
2186
    struct object_config *obj_config;
2187
    VAStatus vaStatus;
2188
    int i;
2189
 
2190
    ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
2191
    ASSERT_RET(obj_surface, VA_STATUS_ERROR_INVALID_SURFACE);
2192
    obj_config = obj_context->obj_config;
2193
    ASSERT_RET(obj_config, VA_STATUS_ERROR_INVALID_CONFIG);
2194
 
2195
    switch (obj_config->profile) {
2196
    case VAProfileMPEG2Simple:
2197
    case VAProfileMPEG2Main:
2198
        vaStatus = VA_STATUS_SUCCESS;
2199
        break;
2200
 
2201
    case VAProfileH264ConstrainedBaseline:
2202
    case VAProfileH264Main:
2203
    case VAProfileH264High:
2204
        vaStatus = VA_STATUS_SUCCESS;
2205
        break;
2206
 
2207
    case VAProfileH264MultiviewHigh:
2208
    case VAProfileH264StereoHigh:
2209
        if (HAS_H264_MVC_DECODING_PROFILE(i965, obj_config->profile) ||
2210
            HAS_H264_MVC_ENCODING(i965)) {
2211
            vaStatus = VA_STATUS_SUCCESS;
2212
        } else {
2213
            ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_PROFILE);
2214
        }
2215
        break;
2216
 
2217
    case VAProfileVC1Simple:
2218
    case VAProfileVC1Main:
2219
    case VAProfileVC1Advanced:
2220
        vaStatus = VA_STATUS_SUCCESS;
2221
        break;
2222
 
2223
    case VAProfileJPEGBaseline:
2224
        vaStatus = VA_STATUS_SUCCESS;
2225
        break;
2226
 
2227
    case VAProfileNone:
2228
        vaStatus = VA_STATUS_SUCCESS;
2229
        break;
2230
 
2231
    case VAProfileVP8Version0_3:
2232
        vaStatus = VA_STATUS_SUCCESS;
2233
        break;
2234
 
2235
    default:
2236
        ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_PROFILE);
2237
        break;
2238
    }
2239
 
2240
    if (obj_context->codec_type == CODEC_PROC) {
2241
        obj_context->codec_state.proc.current_render_target = render_target;
2242
    } else if (obj_context->codec_type == CODEC_ENC) {
2243
        i965_release_buffer_store(&obj_context->codec_state.encode.pic_param);
2244
 
2245
        for (i = 0; i < obj_context->codec_state.encode.num_slice_params; i++) {
2246
            i965_release_buffer_store(&obj_context->codec_state.encode.slice_params[i]);
2247
        }
2248
 
2249
        obj_context->codec_state.encode.num_slice_params = 0;
2250
 
2251
        /* ext */
2252
        i965_release_buffer_store(&obj_context->codec_state.encode.pic_param_ext);
2253
 
2254
        for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_param); i++)
2255
            i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_param[i]);
2256
 
2257
        for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_data); i++)
2258
            i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data[i]);
2259
 
2260
        for (i = 0; i < obj_context->codec_state.encode.num_slice_params_ext; i++)
2261
            i965_release_buffer_store(&obj_context->codec_state.encode.slice_params_ext[i]);
2262
 
2263
        obj_context->codec_state.encode.num_slice_params_ext = 0;
2264
        obj_context->codec_state.encode.current_render_target = render_target;     /*This is input new frame*/
2265
        obj_context->codec_state.encode.last_packed_header_type = 0;
2266
        memset(obj_context->codec_state.encode.slice_rawdata_index, 0,
2267
               sizeof(int) * obj_context->codec_state.encode.max_slice_num);
2268
        memset(obj_context->codec_state.encode.slice_rawdata_count, 0,
2269
               sizeof(int) * obj_context->codec_state.encode.max_slice_num);
2270
        memset(obj_context->codec_state.encode.slice_header_index, 0,
2271
               sizeof(int) * obj_context->codec_state.encode.max_slice_num);
2272
 
2273
        for (i = 0; i < obj_context->codec_state.encode.num_packed_header_params_ext; i++)
2274
            i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_params_ext[i]);
2275
        for (i = 0; i < obj_context->codec_state.encode.num_packed_header_data_ext; i++)
2276
            i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data_ext[i]);
2277
        obj_context->codec_state.encode.num_packed_header_params_ext = 0;
2278
        obj_context->codec_state.encode.num_packed_header_data_ext = 0;
2279
        obj_context->codec_state.encode.slice_index = 0;
2280
    } else {
2281
        obj_context->codec_state.decode.current_render_target = render_target;
2282
        i965_release_buffer_store(&obj_context->codec_state.decode.pic_param);
2283
        i965_release_buffer_store(&obj_context->codec_state.decode.iq_matrix);
2284
        i965_release_buffer_store(&obj_context->codec_state.decode.bit_plane);
2285
        i965_release_buffer_store(&obj_context->codec_state.decode.huffman_table);
2286
 
2287
        for (i = 0; i < obj_context->codec_state.decode.num_slice_params; i++) {
2288
            i965_release_buffer_store(&obj_context->codec_state.decode.slice_params[i]);
2289
            i965_release_buffer_store(&obj_context->codec_state.decode.slice_datas[i]);
2290
        }
2291
 
2292
        obj_context->codec_state.decode.num_slice_params = 0;
2293
        obj_context->codec_state.decode.num_slice_datas = 0;
2294
    }
2295
 
2296
    return vaStatus;
2297
}
2298
 
2299
#define I965_RENDER_BUFFER(category, name) i965_render_##category##_##name##_buffer(ctx, obj_context, obj_buffer)
2300
 
2301
#define DEF_RENDER_SINGLE_BUFFER_FUNC(category, name, member)           \
2302
    static VAStatus                                                     \
2303
    i965_render_##category##_##name##_buffer(VADriverContextP ctx,      \
2304
                                             struct object_context *obj_context, \
2305
                                             struct object_buffer *obj_buffer) \
2306
    {                                                                   \
2307
        struct category##_state *category = &obj_context->codec_state.category; \
2308
        i965_release_buffer_store(&category->member);                   \
2309
        i965_reference_buffer_store(&category->member, obj_buffer->buffer_store); \
2310
        return VA_STATUS_SUCCESS;                                       \
2311
    }
2312
 
2313
#define DEF_RENDER_MULTI_BUFFER_FUNC(category, name, member)            \
2314
    static VAStatus                                                     \
2315
    i965_render_##category##_##name##_buffer(VADriverContextP ctx,      \
2316
                                             struct object_context *obj_context, \
2317
                                             struct object_buffer *obj_buffer) \
2318
    {                                                                   \
2319
        struct category##_state *category = &obj_context->codec_state.category; \
2320
        if (category->num_##member == category->max_##member) {         \
2321
            category->member = realloc(category->member, (category->max_##member + NUM_SLICES) * sizeof(*category->member)); \
2322
            memset(category->member + category->max_##member, 0, NUM_SLICES * sizeof(*category->member)); \
2323
            category->max_##member += NUM_SLICES;                       \
2324
        }                                                               \
2325
        i965_release_buffer_store(&category->member[category->num_##member]); \
2326
        i965_reference_buffer_store(&category->member[category->num_##member], obj_buffer->buffer_store); \
2327
        category->num_##member++;                                       \
2328
        return VA_STATUS_SUCCESS;                                       \
2329
    }
2330
 
2331
#define I965_RENDER_DECODE_BUFFER(name) I965_RENDER_BUFFER(decode, name)
2332
 
2333
#define DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(name, member) DEF_RENDER_SINGLE_BUFFER_FUNC(decode, name, member)
2334
DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(picture_parameter, pic_param)
2335
DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(iq_matrix, iq_matrix)
2336
DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(bit_plane, bit_plane)
2337
DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(huffman_table, huffman_table)
2338
DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(probability_data, probability_data)
2339
 
2340
#define DEF_RENDER_DECODE_MULTI_BUFFER_FUNC(name, member) DEF_RENDER_MULTI_BUFFER_FUNC(decode, name, member)
2341
DEF_RENDER_DECODE_MULTI_BUFFER_FUNC(slice_parameter, slice_params)
2342
DEF_RENDER_DECODE_MULTI_BUFFER_FUNC(slice_data, slice_datas)
2343
 
2344
static VAStatus
2345
i965_decoder_render_picture(VADriverContextP ctx,
2346
                            VAContextID context,
2347
                            VABufferID *buffers,
2348
                            int num_buffers)
2349
{
2350
    struct i965_driver_data *i965 = i965_driver_data(ctx);
2351
    struct object_context *obj_context = CONTEXT(context);
2352
    VAStatus vaStatus = VA_STATUS_SUCCESS;
2353
    int i;
2354
 
2355
    ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
2356
 
2357
    for (i = 0; i < num_buffers && vaStatus == VA_STATUS_SUCCESS; i++) {
2358
        struct object_buffer *obj_buffer = BUFFER(buffers[i]);
2359
 
2360
        if (!obj_buffer)
2361
            return VA_STATUS_ERROR_INVALID_BUFFER;
2362
 
2363
        switch (obj_buffer->type) {
2364
        case VAPictureParameterBufferType:
2365
            vaStatus = I965_RENDER_DECODE_BUFFER(picture_parameter);
2366
            break;
2367
 
2368
        case VAIQMatrixBufferType:
2369
            vaStatus = I965_RENDER_DECODE_BUFFER(iq_matrix);
2370
            break;
2371
 
2372
        case VABitPlaneBufferType:
2373
            vaStatus = I965_RENDER_DECODE_BUFFER(bit_plane);
2374
            break;
2375
 
2376
        case VASliceParameterBufferType:
2377
            vaStatus = I965_RENDER_DECODE_BUFFER(slice_parameter);
2378
            break;
2379
 
2380
        case VASliceDataBufferType:
2381
            vaStatus = I965_RENDER_DECODE_BUFFER(slice_data);
2382
            break;
2383
 
2384
        case VAHuffmanTableBufferType:
2385
            vaStatus = I965_RENDER_DECODE_BUFFER(huffman_table);
2386
            break;
2387
 
2388
        case VAProbabilityBufferType:
2389
            vaStatus = I965_RENDER_DECODE_BUFFER(probability_data);
2390
            break;
2391
 
2392
        default:
2393
            vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
2394
            break;
2395
        }
2396
    }
2397
 
2398
    return vaStatus;
2399
}
2400
 
2401
#define I965_RENDER_ENCODE_BUFFER(name) I965_RENDER_BUFFER(encode, name)
2402
 
2403
#define DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(name, member) DEF_RENDER_SINGLE_BUFFER_FUNC(encode, name, member)
2404
// DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(sequence_parameter, seq_param)
2405
// DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(picture_parameter, pic_param)
2406
// DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(picture_control, pic_control)
2407
DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(qmatrix, q_matrix)
2408
DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(iqmatrix, iq_matrix)
2409
/* extended buffer */
2410
DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(sequence_parameter_ext, seq_param_ext)
2411
DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(picture_parameter_ext, pic_param_ext)
2412
 
2413
#define DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(name, member) DEF_RENDER_MULTI_BUFFER_FUNC(encode, name, member)
2414
// DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(slice_parameter, slice_params)
2415
DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(slice_parameter_ext, slice_params_ext)
2416
 
2417
DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(packed_header_params_ext, packed_header_params_ext)
2418
DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(packed_header_data_ext, packed_header_data_ext)
2419
 
2420
static VAStatus
2421
i965_encoder_render_packed_header_parameter_buffer(VADriverContextP ctx,
2422
                                                   struct object_context *obj_context,
2423
                                                   struct object_buffer *obj_buffer,
2424
                                                   int type_index)
2425
{
2426
    struct encode_state *encode = &obj_context->codec_state.encode;
2427
 
2428
    ASSERT_RET(obj_buffer->buffer_store->bo == NULL, VA_STATUS_ERROR_INVALID_BUFFER);
2429
    ASSERT_RET(obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_INVALID_BUFFER);
2430
    i965_release_buffer_store(&encode->packed_header_param[type_index]);
2431
    i965_reference_buffer_store(&encode->packed_header_param[type_index], obj_buffer->buffer_store);
2432
 
2433
    return VA_STATUS_SUCCESS;
2434
}
2435
 
2436
static VAStatus
2437
i965_encoder_render_packed_header_data_buffer(VADriverContextP ctx,
2438
                                              struct object_context *obj_context,
2439
                                              struct object_buffer *obj_buffer,
2440
                                              int type_index)
2441
{
2442
    struct encode_state *encode = &obj_context->codec_state.encode;
2443
 
2444
    ASSERT_RET(obj_buffer->buffer_store->bo == NULL, VA_STATUS_ERROR_INVALID_BUFFER);
2445
    ASSERT_RET(obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_INVALID_BUFFER);
2446
    i965_release_buffer_store(&encode->packed_header_data[type_index]);
2447
    i965_reference_buffer_store(&encode->packed_header_data[type_index], obj_buffer->buffer_store);
2448
 
2449
    return VA_STATUS_SUCCESS;
2450
}
2451
 
2452
static VAStatus
2453
i965_encoder_render_misc_parameter_buffer(VADriverContextP ctx,
2454
                                          struct object_context *obj_context,
2455
                                          struct object_buffer *obj_buffer)
2456
{
2457
    struct encode_state *encode = &obj_context->codec_state.encode;
2458
    VAEncMiscParameterBuffer *param = NULL;
2459
 
2460
    ASSERT_RET(obj_buffer->buffer_store->bo == NULL, VA_STATUS_ERROR_INVALID_BUFFER);
2461
    ASSERT_RET(obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_INVALID_BUFFER);
2462
 
2463
    param = (VAEncMiscParameterBuffer *)obj_buffer->buffer_store->buffer;
2464
 
2465
    if (param->type >= ARRAY_ELEMS(encode->misc_param))
2466
        return VA_STATUS_ERROR_INVALID_PARAMETER;
2467
 
2468
    i965_release_buffer_store(&encode->misc_param[param->type]);
2469
    i965_reference_buffer_store(&encode->misc_param[param->type], obj_buffer->buffer_store);
2470
 
2471
    return VA_STATUS_SUCCESS;
2472
}
2473
 
2474
static VAStatus
2475
i965_encoder_render_picture(VADriverContextP ctx,
2476
                            VAContextID context,
2477
                            VABufferID *buffers,
2478
                            int num_buffers)
2479
{
2480
    struct i965_driver_data *i965 = i965_driver_data(ctx);
2481
    struct object_context *obj_context = CONTEXT(context);
2482
    VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
2483
    struct encode_state *encode;
2484
    int i;
2485
 
2486
    ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
2487
 
2488
    encode = &obj_context->codec_state.encode;
2489
    for (i = 0; i < num_buffers; i++) {
2490
        struct object_buffer *obj_buffer = BUFFER(buffers[i]);
2491
 
2492
        if (!obj_buffer)
2493
            return VA_STATUS_ERROR_INVALID_BUFFER;
2494
 
2495
        switch (obj_buffer->type) {
2496
        case VAQMatrixBufferType:
2497
            vaStatus = I965_RENDER_ENCODE_BUFFER(qmatrix);
2498
            break;
2499
 
2500
        case VAIQMatrixBufferType:
2501
            vaStatus = I965_RENDER_ENCODE_BUFFER(iqmatrix);
2502
            break;
2503
 
2504
        case VAEncSequenceParameterBufferType:
2505
            vaStatus = I965_RENDER_ENCODE_BUFFER(sequence_parameter_ext);
2506
            break;
2507
 
2508
        case VAEncPictureParameterBufferType:
2509
            vaStatus = I965_RENDER_ENCODE_BUFFER(picture_parameter_ext);
2510
            break;
2511
 
2512
        case VAEncSliceParameterBufferType:
2513
            vaStatus = I965_RENDER_ENCODE_BUFFER(slice_parameter_ext);
2514
            if (vaStatus == VA_STATUS_SUCCESS) {
2515
                /* When the max number of slices is updated, it also needs
2516
                 * to reallocate the arrays that is used to store
2517
                 * the packed data index/count for the slice
2518
                 */
2519
                if (!(encode->packed_header_flag & VA_ENC_PACKED_HEADER_SLICE)) {
2520
                   encode->slice_index++;
2521
                }
2522
                if (encode->slice_index == encode->max_slice_num) {
2523
                    int slice_num = encode->max_slice_num;
2524
                    encode->slice_rawdata_index = realloc(encode->slice_rawdata_index,
2525
                                                          (slice_num + NUM_SLICES) * sizeof(int));
2526
                    encode->slice_rawdata_count = realloc(encode->slice_rawdata_count,
2527
                                                          (slice_num + NUM_SLICES) * sizeof(int));
2528
                    encode->slice_header_index = realloc(encode->slice_header_index,
2529
                                                          (slice_num + NUM_SLICES) * sizeof(int));
2530
                    memset(encode->slice_rawdata_index + slice_num, 0,
2531
                        sizeof(int) * NUM_SLICES);
2532
                    memset(encode->slice_rawdata_count + slice_num, 0,
2533
                        sizeof(int) * NUM_SLICES);
2534
                    memset(encode->slice_header_index + slice_num, 0,
2535
                        sizeof(int) * NUM_SLICES);
2536
 
2537
                    encode->max_slice_num += NUM_SLICES;
2538
                    if ((encode->slice_rawdata_index == NULL) ||
2539
                        (encode->slice_header_index == NULL)  ||
2540
                        (encode->slice_rawdata_count == NULL)) {
2541
                        vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
2542
                        return vaStatus;
2543
                    }
2544
                }
2545
            }
2546
            break;
2547
 
2548
        case VAEncPackedHeaderParameterBufferType:
2549
        {
2550
            VAEncPackedHeaderParameterBuffer *param = (VAEncPackedHeaderParameterBuffer *)obj_buffer->buffer_store->buffer;
2551
            encode->last_packed_header_type = param->type;
2552
 
2553
            if ((param->type == VAEncPackedHeaderRawData) ||
2554
                (param->type == VAEncPackedHeaderSlice)) {
2555
                vaStatus = I965_RENDER_ENCODE_BUFFER(packed_header_params_ext);
2556
            } else {
2557
                vaStatus = i965_encoder_render_packed_header_parameter_buffer(ctx,
2558
                                                                          obj_context,
2559
                                                                          obj_buffer,
2560
                                                                          va_enc_packed_type_to_idx(encode->last_packed_header_type));
2561
            }
2562
            break;
2563
        }
2564
 
2565
        case VAEncPackedHeaderDataBufferType:
2566
        {
2567
            if (encode->last_packed_header_type == 0) {
2568
                WARN_ONCE("the packed header data is passed without type!\n");
2569
                vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
2570
                return vaStatus;
2571
            }
2572
            if (encode->last_packed_header_type == VAEncPackedHeaderRawData ||
2573
                encode->last_packed_header_type == VAEncPackedHeaderSlice) {
2574
                vaStatus = I965_RENDER_ENCODE_BUFFER(packed_header_data_ext);
2575
 
2576
                /* When the PACKED_SLICE_HEADER flag is passed, it will use
2577
                 * the packed_slice_header as the delimeter to decide how
2578
                 * the packed rawdata is inserted for the given slice.
2579
                 * Otherwise it will use the VAEncSequenceParameterBuffer
2580
                 * as the delimeter
2581
                 */
2582
                if (encode->packed_header_flag & VA_ENC_PACKED_HEADER_SLICE) {
2583
                    /* store the first index of the packed header data for current slice */
2584
                    if (encode->slice_rawdata_index[encode->slice_index] == 0) {
2585
                        encode->slice_rawdata_index[encode->slice_index] =
2586
                            SLICE_PACKED_DATA_INDEX_TYPE | (encode->num_packed_header_data_ext - 1);
2587
                    }
2588
                    encode->slice_rawdata_count[encode->slice_index]++;
2589
                    if (encode->last_packed_header_type == VAEncPackedHeaderSlice) {
2590
                        /* find one packed slice_header delimeter. And the following
2591
                         * packed data is for the next slice
2592
                         */
2593
                        encode->slice_header_index[encode->slice_index] =
2594
                            SLICE_PACKED_DATA_INDEX_TYPE | (encode->num_packed_header_data_ext - 1);
2595
                        encode->slice_index++;
2596
                        /* Reallocate the buffer to record the index/count of
2597
                         * packed_data for one slice.
2598
                         */
2599
                        if (encode->slice_index == encode->max_slice_num) {
2600
                            int slice_num = encode->max_slice_num;
2601
 
2602
                            encode->slice_rawdata_index = realloc(encode->slice_rawdata_index,
2603
                                                          (slice_num + NUM_SLICES) * sizeof(int));
2604
                            encode->slice_rawdata_count = realloc(encode->slice_rawdata_count,
2605
                                                          (slice_num + NUM_SLICES) * sizeof(int));
2606
                            encode->slice_header_index = realloc(encode->slice_header_index,
2607
                                                          (slice_num + NUM_SLICES) * sizeof(int));
2608
                            memset(encode->slice_rawdata_index + slice_num, 0,
2609
                                   sizeof(int) * NUM_SLICES);
2610
                            memset(encode->slice_rawdata_count + slice_num, 0,
2611
                                   sizeof(int) * NUM_SLICES);
2612
                            memset(encode->slice_header_index + slice_num, 0,
2613
                                   sizeof(int) * NUM_SLICES);
2614
                            encode->max_slice_num += NUM_SLICES;
2615
                        }
2616
                    }
2617
                } else {
2618
                    if (vaStatus == VA_STATUS_SUCCESS) {
2619
                        /* store the first index of the packed header data for current slice */
2620
                        if (encode->slice_rawdata_index[encode->slice_index] == 0) {
2621
                            encode->slice_rawdata_index[encode->slice_index] =
2622
                                SLICE_PACKED_DATA_INDEX_TYPE | (encode->num_packed_header_data_ext - 1);
2623
                        }
2624
                        encode->slice_rawdata_count[encode->slice_index]++;
2625
                        if (encode->last_packed_header_type == VAEncPackedHeaderSlice) {
2626
                            if (encode->slice_header_index[encode->slice_index] == 0) {
2627
                                encode->slice_header_index[encode->slice_index] =
2628
                                    SLICE_PACKED_DATA_INDEX_TYPE | (encode->num_packed_header_data_ext - 1);
2629
                            } else {
2630
                                WARN_ONCE("Multi slice header data is passed for"
2631
                                      " slice %d!\n", encode->slice_index);
2632
                            }
2633
                        }
2634
                    }
2635
                }
2636
            } else {
2637
                ASSERT_RET(encode->last_packed_header_type == VAEncPackedHeaderSequence ||
2638
                    encode->last_packed_header_type == VAEncPackedHeaderPicture ||
2639
                    encode->last_packed_header_type == VAEncPackedHeaderSlice ||
2640
                   (((encode->last_packed_header_type & VAEncPackedHeaderMiscMask) == VAEncPackedHeaderMiscMask) &&
2641
                    ((encode->last_packed_header_type & (~VAEncPackedHeaderMiscMask)) != 0)),
2642
                    VA_STATUS_ERROR_ENCODING_ERROR);
2643
                vaStatus = i965_encoder_render_packed_header_data_buffer(ctx,
2644
                                                                     obj_context,
2645
                                                                     obj_buffer,
2646
                                                                     va_enc_packed_type_to_idx(encode->last_packed_header_type));
2647
            }
2648
            encode->last_packed_header_type = 0;
2649
            break;
2650
        }
2651
 
2652
        case VAEncMiscParameterBufferType:
2653
            vaStatus = i965_encoder_render_misc_parameter_buffer(ctx,
2654
                                                                 obj_context,
2655
                                                                 obj_buffer);
2656
            break;
2657
 
2658
        default:
2659
            vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
2660
            break;
2661
        }
2662
    }
2663
 
2664
    return vaStatus;
2665
}
2666
 
2667
#define I965_RENDER_PROC_BUFFER(name) I965_RENDER_BUFFER(proc, name)
2668
 
2669
#define DEF_RENDER_PROC_SINGLE_BUFFER_FUNC(name, member) DEF_RENDER_SINGLE_BUFFER_FUNC(proc, name, member)
2670
DEF_RENDER_PROC_SINGLE_BUFFER_FUNC(pipeline_parameter, pipeline_param)
2671
 
2672
static VAStatus
2673
i965_proc_render_picture(VADriverContextP ctx,
2674
                         VAContextID context,
2675
                         VABufferID *buffers,
2676
                         int num_buffers)
2677
{
2678
    struct i965_driver_data *i965 = i965_driver_data(ctx);
2679
    struct object_context *obj_context = CONTEXT(context);
2680
    VAStatus vaStatus = VA_STATUS_SUCCESS;
2681
    int i;
2682
 
2683
    ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
2684
 
2685
    for (i = 0; i < num_buffers && vaStatus == VA_STATUS_SUCCESS; i++) {
2686
        struct object_buffer *obj_buffer = BUFFER(buffers[i]);
2687
 
2688
        if (!obj_buffer)
2689
            return VA_STATUS_ERROR_INVALID_BUFFER;
2690
 
2691
        switch (obj_buffer->type) {
2692
        case VAProcPipelineParameterBufferType:
2693
            vaStatus = I965_RENDER_PROC_BUFFER(pipeline_parameter);
2694
            break;
2695
 
2696
        default:
2697
            vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
2698
            break;
2699
        }
2700
    }
2701
 
2702
    return vaStatus;
2703
}
2704
 
2705
VAStatus
2706
i965_RenderPicture(VADriverContextP ctx,
2707
                   VAContextID context,
2708
                   VABufferID *buffers,
2709
                   int num_buffers)
2710
{
2711
    struct i965_driver_data *i965 = i965_driver_data(ctx);
2712
    struct object_context *obj_context;
2713
    struct object_config *obj_config;
2714
    VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
2715
 
2716
    obj_context = CONTEXT(context);
2717
    ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
2718
 
2719
    if (num_buffers <= 0)
2720
        return VA_STATUS_ERROR_INVALID_PARAMETER;
2721
 
2722
    obj_config = obj_context->obj_config;
2723
    ASSERT_RET(obj_config, VA_STATUS_ERROR_INVALID_CONFIG);
2724
 
2725
    if (VAEntrypointVideoProc == obj_config->entrypoint) {
2726
        vaStatus = i965_proc_render_picture(ctx, context, buffers, num_buffers);
2727
    } else if (VAEntrypointEncSlice == obj_config->entrypoint ) {
2728
        vaStatus = i965_encoder_render_picture(ctx, context, buffers, num_buffers);
2729
    } else {
2730
        vaStatus = i965_decoder_render_picture(ctx, context, buffers, num_buffers);
2731
    }
2732
 
2733
    return vaStatus;
2734
}
2735
 
2736
VAStatus
2737
i965_EndPicture(VADriverContextP ctx, VAContextID context)
2738
{
2739
    struct i965_driver_data *i965 = i965_driver_data(ctx);
2740
    struct object_context *obj_context = CONTEXT(context);
2741
    struct object_config *obj_config;
2742
 
2743
    ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
2744
    obj_config = obj_context->obj_config;
2745
    ASSERT_RET(obj_config, VA_STATUS_ERROR_INVALID_CONFIG);
2746
 
2747
    if (obj_context->codec_type == CODEC_PROC) {
2748
        ASSERT_RET(VAEntrypointVideoProc == obj_config->entrypoint, VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT);
2749
    } else if (obj_context->codec_type == CODEC_ENC) {
2750
        ASSERT_RET(VAEntrypointEncSlice == obj_config->entrypoint, VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT);
2751
 
2752
        if (obj_context->codec_state.encode.num_packed_header_params_ext !=
2753
               obj_context->codec_state.encode.num_packed_header_data_ext) {
2754
            WARN_ONCE("the packed header/data is not paired for encoding!\n");
2755
            return VA_STATUS_ERROR_INVALID_PARAMETER;
2756
        }
2757
        if (!(obj_context->codec_state.encode.pic_param ||
2758
                obj_context->codec_state.encode.pic_param_ext)) {
2759
            return VA_STATUS_ERROR_INVALID_PARAMETER;
2760
        }
2761
        if (!(obj_context->codec_state.encode.seq_param ||
2762
                obj_context->codec_state.encode.seq_param_ext)) {
2763
            return VA_STATUS_ERROR_INVALID_PARAMETER;
2764
        }
2765
        if ((obj_context->codec_state.encode.num_slice_params <=0) &&
2766
                (obj_context->codec_state.encode.num_slice_params_ext <=0)) {
2767
            return VA_STATUS_ERROR_INVALID_PARAMETER;
2768
        }
2769
 
2770
        if ((obj_context->codec_state.encode.packed_header_flag & VA_ENC_PACKED_HEADER_SLICE) &&
2771
            (obj_context->codec_state.encode.num_slice_params_ext !=
2772
             obj_context->codec_state.encode.slice_index)) {
2773
            WARN_ONCE("packed slice_header data is missing for some slice"
2774
                      " under packed SLICE_HEADER mode\n");
2775
            return VA_STATUS_ERROR_INVALID_PARAMETER;
2776
        }
2777
    } else {
2778
        if (obj_context->codec_state.decode.pic_param == NULL) {
2779
            return VA_STATUS_ERROR_INVALID_PARAMETER;
2780
        }
2781
        if (obj_context->codec_state.decode.num_slice_params <=0) {
2782
            return VA_STATUS_ERROR_INVALID_PARAMETER;
2783
        }
2784
        if (obj_context->codec_state.decode.num_slice_datas <=0) {
2785
            return VA_STATUS_ERROR_INVALID_PARAMETER;
2786
        }
2787
 
2788
        if (obj_context->codec_state.decode.num_slice_params !=
2789
                obj_context->codec_state.decode.num_slice_datas) {
2790
            return VA_STATUS_ERROR_INVALID_PARAMETER;
2791
        }
2792
    }
2793
 
2794
    ASSERT_RET(obj_context->hw_context->run, VA_STATUS_ERROR_OPERATION_FAILED);
2795
    return obj_context->hw_context->run(ctx, obj_config->profile, &obj_context->codec_state, obj_context->hw_context);
2796
}
2797
 
2798
VAStatus
2799
i965_SyncSurface(VADriverContextP ctx,
2800
                 VASurfaceID render_target)
2801
{
2802
    struct i965_driver_data *i965 = i965_driver_data(ctx);
2803
    struct object_surface *obj_surface = SURFACE(render_target);
2804
 
2805
    ASSERT_RET(obj_surface, VA_STATUS_ERROR_INVALID_SURFACE);
2806
 
2807
    if(obj_surface->bo)
2808
        drm_intel_bo_wait_rendering(obj_surface->bo);
2809
 
2810
    return VA_STATUS_SUCCESS;
2811
}
2812
 
2813
VAStatus
2814
i965_QuerySurfaceStatus(VADriverContextP ctx,
2815
                        VASurfaceID render_target,
2816
                        VASurfaceStatus *status)        /* out */
2817
{
2818
    struct i965_driver_data *i965 = i965_driver_data(ctx);
2819
    struct object_surface *obj_surface = SURFACE(render_target);
2820
 
2821
    ASSERT_RET(obj_surface, VA_STATUS_ERROR_INVALID_SURFACE);
2822
 
2823
    if (obj_surface->bo) {
2824
        if (drm_intel_bo_busy(obj_surface->bo)){
2825
            *status = VASurfaceRendering;
2826
        }
2827
        else {
2828
            *status = VASurfaceReady;
2829
        }
2830
    } else {
2831
        *status = VASurfaceReady;
2832
    }
2833
 
2834
    return VA_STATUS_SUCCESS;
2835
}
2836
 
2837
static VADisplayAttribute *
2838
get_display_attribute(VADriverContextP ctx, VADisplayAttribType type)
2839
{
2840
    struct i965_driver_data * const i965 = i965_driver_data(ctx);
2841
    unsigned int i;
2842
 
2843
    if (!i965->display_attributes)
2844
        return NULL;
2845
 
2846
    for (i = 0; i < i965->num_display_attributes; i++) {
2847
        if (i965->display_attributes[i].type == type)
2848
            return &i965->display_attributes[i];
2849
    }
2850
    return NULL;
2851
}
2852
 
2853
static void
2854
i965_display_attributes_terminate(VADriverContextP ctx)
2855
{
2856
    struct i965_driver_data * const i965 = i965_driver_data(ctx);
2857
 
2858
    if (i965->display_attributes) {
2859
        free(i965->display_attributes);
2860
        i965->display_attributes = NULL;
2861
        i965->num_display_attributes = 0;
2862
    }
2863
}
2864
 
2865
static bool
2866
i965_display_attributes_init(VADriverContextP ctx)
2867
{
2868
    struct i965_driver_data * const i965 = i965_driver_data(ctx);
2869
 
2870
    i965->num_display_attributes = ARRAY_ELEMS(i965_display_attributes);
2871
    i965->display_attributes = malloc(
2872
        i965->num_display_attributes * sizeof(i965->display_attributes[0]));
2873
    if (!i965->display_attributes)
2874
        goto error;
2875
 
2876
    memcpy(
2877
        i965->display_attributes,
2878
        i965_display_attributes,
2879
        sizeof(i965_display_attributes)
2880
    );
2881
 
2882
    i965->rotation_attrib = get_display_attribute(ctx, VADisplayAttribRotation);
2883
    i965->brightness_attrib = get_display_attribute(ctx, VADisplayAttribBrightness);
2884
    i965->contrast_attrib = get_display_attribute(ctx, VADisplayAttribContrast);
2885
    i965->hue_attrib = get_display_attribute(ctx, VADisplayAttribHue);
2886
    i965->saturation_attrib = get_display_attribute(ctx, VADisplayAttribSaturation);
2887
 
2888
    if (!i965->rotation_attrib ||
2889
        !i965->brightness_attrib ||
2890
        !i965->contrast_attrib ||
2891
        !i965->hue_attrib ||
2892
        !i965->saturation_attrib) {
2893
        goto error;
2894
    }
2895
    return true;
2896
 
2897
error:
2898
    i965_display_attributes_terminate(ctx);
2899
    return false;
2900
}
2901
 
2902
/*
2903
 * Query display attributes
2904
 * The caller must provide a "attr_list" array that can hold at
2905
 * least vaMaxNumDisplayAttributes() entries. The actual number of attributes
2906
 * returned in "attr_list" is returned in "num_attributes".
2907
 */
2908
VAStatus
2909
i965_QueryDisplayAttributes(
2910
    VADriverContextP    ctx,
2911
    VADisplayAttribute *attribs,        /* out */
2912
    int                *num_attribs_ptr /* out */
2913
)
2914
{
2915
    const int num_attribs = ARRAY_ELEMS(i965_display_attributes);
2916
 
2917
    if (attribs && num_attribs > 0)
2918
        memcpy(attribs, i965_display_attributes, sizeof(i965_display_attributes));
2919
 
2920
    if (num_attribs_ptr)
2921
        *num_attribs_ptr = num_attribs;
2922
 
2923
    return VA_STATUS_SUCCESS;
2924
}
2925
 
2926
/*
2927
 * Get display attributes
2928
 * This function returns the current attribute values in "attr_list".
2929
 * Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field
2930
 * from vaQueryDisplayAttributes() can have their values retrieved.
2931
 */
2932
VAStatus
2933
i965_GetDisplayAttributes(
2934
    VADriverContextP    ctx,
2935
    VADisplayAttribute *attribs,        /* inout */
2936
    int                 num_attribs     /* in */
2937
)
2938
{
2939
    int i;
2940
 
2941
    for (i = 0; i < num_attribs; i++) {
2942
        VADisplayAttribute *src_attrib, * const dst_attrib = &attribs[i];
2943
 
2944
        src_attrib = get_display_attribute(ctx, dst_attrib->type);
2945
        if (src_attrib && (src_attrib->flags & VA_DISPLAY_ATTRIB_GETTABLE)) {
2946
            dst_attrib->min_value = src_attrib->min_value;
2947
            dst_attrib->max_value = src_attrib->max_value;
2948
            dst_attrib->value     = src_attrib->value;
2949
        }
2950
        else
2951
            dst_attrib->flags = VA_DISPLAY_ATTRIB_NOT_SUPPORTED;
2952
    }
2953
    return VA_STATUS_SUCCESS;
2954
}
2955
 
2956
/*
2957
 * Set display attributes
2958
 * Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field
2959
 * from vaQueryDisplayAttributes() can be set.  If the attribute is not settable or
2960
 * the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED
2961
 */
2962
VAStatus
2963
i965_SetDisplayAttributes(
2964
    VADriverContextP    ctx,
2965
    VADisplayAttribute *attribs,        /* in */
2966
    int                 num_attribs     /* in */
2967
)
2968
{
2969
    int i;
2970
 
2971
    for (i = 0; i < num_attribs; i++) {
2972
        VADisplayAttribute *dst_attrib, * const src_attrib = &attribs[i];
2973
 
2974
        dst_attrib = get_display_attribute(ctx, src_attrib->type);
2975
        if (!dst_attrib)
2976
            return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
2977
 
2978
        if (!(dst_attrib->flags & VA_DISPLAY_ATTRIB_SETTABLE))
2979
            continue;
2980
 
2981
        if (src_attrib->value < dst_attrib->min_value ||
2982
            src_attrib->value > dst_attrib->max_value)
2983
            return VA_STATUS_ERROR_INVALID_PARAMETER;
2984
 
2985
        dst_attrib->value = src_attrib->value;
2986
        /* XXX: track modified attributes through timestamps */
2987
    }
2988
    return VA_STATUS_SUCCESS;
2989
}
2990
 
2991
VAStatus
2992
i965_DbgCopySurfaceToBuffer(VADriverContextP ctx,
2993
                            VASurfaceID surface,
2994
                            void **buffer,              /* out */
2995
                            unsigned int *stride)       /* out */
2996
{
2997
    /* TODO */
2998
    return VA_STATUS_ERROR_UNIMPLEMENTED;
2999
}
3000
 
3001
static void
3002
i965_destroy_heap(struct object_heap *heap,
3003
                  void (*func)(struct object_heap *heap, struct object_base *object))
3004
{
3005
    struct object_base *object;
3006
    object_heap_iterator iter;
3007
 
3008
    object = object_heap_first(heap, &iter);
3009
 
3010
    while (object) {
3011
        if (func)
3012
            func(heap, object);
3013
 
3014
        object = object_heap_next(heap, &iter);
3015
    }
3016
 
3017
    object_heap_destroy(heap);
3018
}
3019
 
3020
 
3021
VAStatus
3022
i965_DestroyImage(VADriverContextP ctx, VAImageID image);
3023
 
3024
VAStatus
3025
i965_CreateImage(VADriverContextP ctx,
3026
                 VAImageFormat *format,
3027
                 int width,
3028
                 int height,
3029
                 VAImage *out_image)        /* out */
3030
{
3031
    struct i965_driver_data *i965 = i965_driver_data(ctx);
3032
    struct object_image *obj_image;
3033
    VAStatus va_status = VA_STATUS_ERROR_OPERATION_FAILED;
3034
    VAImageID image_id;
3035
    unsigned int size2, size, awidth, aheight;
3036
 
3037
    out_image->image_id = VA_INVALID_ID;
3038
    out_image->buf      = VA_INVALID_ID;
3039
 
3040
    image_id = NEW_IMAGE_ID();
3041
    if (image_id == VA_INVALID_ID)
3042
        return VA_STATUS_ERROR_ALLOCATION_FAILED;
3043
 
3044
    obj_image = IMAGE(image_id);
3045
    if (!obj_image)
3046
        return VA_STATUS_ERROR_ALLOCATION_FAILED;
3047
    obj_image->bo         = NULL;
3048
    obj_image->palette    = NULL;
3049
    obj_image->derived_surface = VA_INVALID_ID;
3050
 
3051
    VAImage * const image = &obj_image->image;
3052
    image->image_id       = image_id;
3053
    image->buf            = VA_INVALID_ID;
3054
 
3055
    awidth = ALIGN(width, i965->codec_info->min_linear_wpitch);
3056
 
3057
    if ((format->fourcc == VA_FOURCC_YV12) ||
3058
    		(format->fourcc == VA_FOURCC_I420)) {
3059
	if (awidth % 128 != 0) {
3060
		awidth = ALIGN(width, 128);
3061
	}
3062
    }
3063
 
3064
    aheight = ALIGN(height, i965->codec_info->min_linear_hpitch);
3065
    size    = awidth * aheight;
3066
    size2    = (awidth / 2) * (aheight / 2);
3067
 
3068
    image->num_palette_entries = 0;
3069
    image->entry_bytes         = 0;
3070
    memset(image->component_order, 0, sizeof(image->component_order));
3071
 
3072
    switch (format->fourcc) {
3073
    case VA_FOURCC_IA44:
3074
    case VA_FOURCC_AI44:
3075
        image->num_planes = 1;
3076
        image->pitches[0] = awidth;
3077
        image->offsets[0] = 0;
3078
        image->data_size  = image->offsets[0] + image->pitches[0] * aheight;
3079
        image->num_palette_entries = 16;
3080
        image->entry_bytes         = 3;
3081
        image->component_order[0]  = 'R';
3082
        image->component_order[1]  = 'G';
3083
        image->component_order[2]  = 'B';
3084
        break;
3085
    case VA_FOURCC_IA88:
3086
    case VA_FOURCC_AI88:
3087
        image->num_planes = 1;
3088
        image->pitches[0] = awidth * 2;
3089
        image->offsets[0] = 0;
3090
        image->data_size  = image->offsets[0] + image->pitches[0] * aheight;
3091
        image->num_palette_entries = 256;
3092
        image->entry_bytes         = 3;
3093
        image->component_order[0]  = 'R';
3094
        image->component_order[1]  = 'G';
3095
        image->component_order[2]  = 'B';
3096
        break;
3097
    case VA_FOURCC_ARGB:
3098
    case VA_FOURCC_ABGR:
3099
    case VA_FOURCC_BGRA:
3100
    case VA_FOURCC_RGBA:
3101
    case VA_FOURCC_BGRX:
3102
    case VA_FOURCC_RGBX:
3103
        image->num_planes = 1;
3104
        image->pitches[0] = awidth * 4;
3105
        image->offsets[0] = 0;
3106
        image->data_size  = image->offsets[0] + image->pitches[0] * aheight;
3107
        break;
3108
    case VA_FOURCC_YV12:
3109
        image->num_planes = 3;
3110
        image->pitches[0] = awidth;
3111
        image->offsets[0] = 0;
3112
        image->pitches[1] = awidth / 2;
3113
        image->offsets[1] = size;
3114
        image->pitches[2] = awidth / 2;
3115
        image->offsets[2] = size + size2;
3116
        image->data_size  = size + 2 * size2;
3117
        break;
3118
    case VA_FOURCC_I420:
3119
        image->num_planes = 3;
3120
        image->pitches[0] = awidth;
3121
        image->offsets[0] = 0;
3122
        image->pitches[1] = awidth / 2;
3123
        image->offsets[1] = size;
3124
        image->pitches[2] = awidth / 2;
3125
        image->offsets[2] = size + size2;
3126
        image->data_size  = size + 2 * size2;
3127
        break;
3128
    case VA_FOURCC_422H:
3129
        image->num_planes = 3;
3130
        image->pitches[0] = awidth;
3131
        image->offsets[0] = 0;
3132
        image->pitches[1] = awidth / 2;
3133
        image->offsets[1] = size;
3134
        image->pitches[2] = awidth / 2;
3135
        image->offsets[2] = size + (awidth / 2) * aheight;
3136
        image->data_size  = size + 2 * ((awidth / 2) * aheight);
3137
        break;
3138
    case VA_FOURCC_NV12:
3139
        image->num_planes = 2;
3140
        image->pitches[0] = awidth;
3141
        image->offsets[0] = 0;
3142
        image->pitches[1] = awidth;
3143
        image->offsets[1] = size;
3144
        image->data_size  = size + 2 * size2;
3145
        break;
3146
    case VA_FOURCC_YUY2:
3147
    case VA_FOURCC_UYVY:
3148
        image->num_planes = 1;
3149
        image->pitches[0] = awidth * 2;
3150
        image->offsets[0] = 0;
3151
        image->data_size  = size * 2;
3152
        break;
3153
    default:
3154
        goto error;
3155
    }
3156
 
3157
    va_status = i965_CreateBuffer(ctx, 0, VAImageBufferType,
3158
                                  image->data_size, 1, NULL, &image->buf);
3159
    if (va_status != VA_STATUS_SUCCESS)
3160
        goto error;
3161
 
3162
    struct object_buffer *obj_buffer = BUFFER(image->buf);
3163
 
3164
    if (!obj_buffer ||
3165
        !obj_buffer->buffer_store ||
3166
        !obj_buffer->buffer_store->bo)
3167
        return VA_STATUS_ERROR_ALLOCATION_FAILED;
3168
 
3169
    obj_image->bo = obj_buffer->buffer_store->bo;
3170
    dri_bo_reference(obj_image->bo);
3171
 
3172
    if (image->num_palette_entries > 0 && image->entry_bytes > 0) {
3173
        obj_image->palette = malloc(image->num_palette_entries * sizeof(*obj_image->palette));
3174
        if (!obj_image->palette)
3175
            goto error;
3176
    }
3177
 
3178
    image->image_id             = image_id;
3179
    image->format               = *format;
3180
    image->width                = width;
3181
    image->height               = height;
3182
 
3183
    *out_image                  = *image;
3184
    return VA_STATUS_SUCCESS;
3185
 
3186
 error:
3187
    i965_DestroyImage(ctx, image_id);
3188
    return va_status;
3189
}
3190
 
3191
VAStatus
3192
i965_check_alloc_surface_bo(VADriverContextP ctx,
3193
                            struct object_surface *obj_surface,
3194
                            int tiled,
3195
                            unsigned int fourcc,
3196
                            unsigned int subsampling)
3197
{
3198
    struct i965_driver_data *i965 = i965_driver_data(ctx);
3199
    int region_width, region_height;
3200
 
3201
    if (obj_surface->bo) {
3202
        ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
3203
        ASSERT_RET(obj_surface->fourcc == fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
3204
        ASSERT_RET(obj_surface->subsampling == subsampling, VA_STATUS_ERROR_INVALID_SURFACE);
3205
        return VA_STATUS_SUCCESS;
3206
    }
3207
 
3208
    obj_surface->x_cb_offset = 0; /* X offset is always 0 */
3209
    obj_surface->x_cr_offset = 0;
3210
 
3211
    if ((tiled && !obj_surface->user_disable_tiling)) {
3212
        ASSERT_RET(fourcc != VA_FOURCC_I420 &&
3213
               fourcc != VA_FOURCC_IYUV &&
3214
               fourcc != VA_FOURCC_YV12,
3215
               VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT);
3216
        if (obj_surface->user_h_stride_set) {
3217
            ASSERT_RET(IS_ALIGNED(obj_surface->width, 128), VA_STATUS_ERROR_INVALID_PARAMETER);
3218
        } else
3219
            obj_surface->width = ALIGN(obj_surface->orig_width, 128);
3220
 
3221
        if (obj_surface->user_v_stride_set) {
3222
            ASSERT_RET(IS_ALIGNED(obj_surface->height, 32), VA_STATUS_ERROR_INVALID_PARAMETER);
3223
        } else
3224
            obj_surface->height = ALIGN(obj_surface->orig_height, 32);
3225
 
3226
        region_height = obj_surface->height;
3227
 
3228
        switch (fourcc) {
3229
        case VA_FOURCC_NV12:
3230
            assert(subsampling == SUBSAMPLE_YUV420);
3231
            obj_surface->cb_cr_pitch = obj_surface->width;
3232
            obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3233
            obj_surface->cb_cr_height = obj_surface->orig_height / 2;
3234
            obj_surface->y_cb_offset = obj_surface->height;
3235
            obj_surface->y_cr_offset = obj_surface->height;
3236
            region_width = obj_surface->width;
3237
            region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32);
3238
 
3239
            break;
3240
 
3241
        case VA_FOURCC_IMC1:
3242
            assert(subsampling == SUBSAMPLE_YUV420);
3243
            obj_surface->cb_cr_pitch = obj_surface->width;
3244
            obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3245
            obj_surface->cb_cr_height = obj_surface->orig_height / 2;
3246
            obj_surface->y_cr_offset = obj_surface->height;
3247
            obj_surface->y_cb_offset = obj_surface->y_cr_offset + ALIGN(obj_surface->cb_cr_height, 32);
3248
            region_width = obj_surface->width;
3249
            region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
3250
 
3251
            break;
3252
 
3253
        case VA_FOURCC_IMC3:
3254
            assert(subsampling == SUBSAMPLE_YUV420);
3255
            obj_surface->cb_cr_pitch = obj_surface->width;
3256
            obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3257
            obj_surface->cb_cr_height = obj_surface->orig_height / 2;
3258
            obj_surface->y_cb_offset = obj_surface->height;
3259
            obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
3260
            region_width = obj_surface->width;
3261
            region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
3262
 
3263
            break;
3264
 
3265
        case VA_FOURCC_422H:
3266
            assert(subsampling == SUBSAMPLE_YUV422H);
3267
            obj_surface->cb_cr_pitch = obj_surface->width;
3268
            obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3269
            obj_surface->cb_cr_height = obj_surface->orig_height;
3270
            obj_surface->y_cb_offset = obj_surface->height;
3271
            obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
3272
            region_width = obj_surface->width;
3273
            region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
3274
 
3275
            break;
3276
 
3277
        case VA_FOURCC_422V:
3278
            assert(subsampling == SUBSAMPLE_YUV422V);
3279
            obj_surface->cb_cr_pitch = obj_surface->width;
3280
            obj_surface->cb_cr_width = obj_surface->orig_width;
3281
            obj_surface->cb_cr_height = obj_surface->orig_height / 2;
3282
            obj_surface->y_cb_offset = obj_surface->height;
3283
            obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
3284
            region_width = obj_surface->width;
3285
            region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
3286
 
3287
            break;
3288
 
3289
        case VA_FOURCC_411P:
3290
            assert(subsampling == SUBSAMPLE_YUV411);
3291
            obj_surface->cb_cr_pitch = obj_surface->width;
3292
            obj_surface->cb_cr_width = obj_surface->orig_width / 4;
3293
            obj_surface->cb_cr_height = obj_surface->orig_height;
3294
            obj_surface->y_cb_offset = obj_surface->height;
3295
            obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
3296
            region_width = obj_surface->width;
3297
            region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
3298
 
3299
            break;
3300
 
3301
        case VA_FOURCC_444P:
3302
            assert(subsampling == SUBSAMPLE_YUV444);
3303
            obj_surface->cb_cr_pitch = obj_surface->width;
3304
            obj_surface->cb_cr_width = obj_surface->orig_width;
3305
            obj_surface->cb_cr_height = obj_surface->orig_height;
3306
            obj_surface->y_cb_offset = obj_surface->height;
3307
            obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
3308
            region_width = obj_surface->width;
3309
            region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
3310
 
3311
            break;
3312
 
3313
        case VA_FOURCC_Y800:
3314
            assert(subsampling == SUBSAMPLE_YUV400);
3315
            obj_surface->cb_cr_pitch = 0;
3316
            obj_surface->cb_cr_width = 0;
3317
            obj_surface->cb_cr_height = 0;
3318
            obj_surface->y_cb_offset = 0;
3319
            obj_surface->y_cr_offset = 0;
3320
            region_width = obj_surface->width;
3321
            region_height = obj_surface->height;
3322
 
3323
            break;
3324
 
3325
        case VA_FOURCC_YUY2:
3326
        case VA_FOURCC_UYVY:
3327
            assert(subsampling == SUBSAMPLE_YUV422H);
3328
            obj_surface->width = ALIGN(obj_surface->orig_width * 2, 128);
3329
            obj_surface->cb_cr_pitch = obj_surface->width;
3330
            obj_surface->y_cb_offset = 0;
3331
            obj_surface->y_cr_offset = 0;
3332
            obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3333
            obj_surface->cb_cr_height = obj_surface->orig_height / 2;
3334
            region_width = obj_surface->width;
3335
            region_height = obj_surface->height;
3336
 
3337
            break;
3338
 
3339
        case VA_FOURCC_RGBA:
3340
        case VA_FOURCC_RGBX:
3341
        case VA_FOURCC_BGRA:
3342
        case VA_FOURCC_BGRX:
3343
            assert(subsampling == SUBSAMPLE_RGBX);
3344
 
3345
            obj_surface->width = ALIGN(obj_surface->orig_width * 4, 128);
3346
            region_width = obj_surface->width;
3347
            region_height = obj_surface->height;
3348
            break;
3349
 
3350
        default:
3351
            /* Never get here */
3352
            ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT);
3353
            break;
3354
        }
3355
    } else {
3356
        assert(subsampling == SUBSAMPLE_YUV420 ||
3357
               subsampling == SUBSAMPLE_YUV422H ||
3358
               subsampling == SUBSAMPLE_YUV422V ||
3359
               subsampling == SUBSAMPLE_RGBX);
3360
 
3361
        region_width = obj_surface->width;
3362
        region_height = obj_surface->height;
3363
 
3364
        switch (fourcc) {
3365
        case VA_FOURCC_NV12:
3366
            obj_surface->y_cb_offset = obj_surface->height;
3367
            obj_surface->y_cr_offset = obj_surface->height;
3368
            obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3369
            obj_surface->cb_cr_height = obj_surface->orig_height / 2;
3370
            obj_surface->cb_cr_pitch = obj_surface->width;
3371
            region_height = obj_surface->height + obj_surface->height / 2;
3372
            break;
3373
 
3374
        case VA_FOURCC_YV16:
3375
            obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3376
            obj_surface->cb_cr_height = obj_surface->orig_height;
3377
            obj_surface->y_cr_offset = obj_surface->height;
3378
            obj_surface->y_cb_offset = obj_surface->y_cr_offset + ALIGN(obj_surface->cb_cr_height, 32) / 2;
3379
            obj_surface->cb_cr_pitch = obj_surface->width / 2;
3380
            region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32);
3381
            break;
3382
 
3383
        case VA_FOURCC_YV12:
3384
        case VA_FOURCC_I420:
3385
            if (fourcc == VA_FOURCC_YV12) {
3386
                obj_surface->y_cr_offset = obj_surface->height;
3387
                obj_surface->y_cb_offset = obj_surface->height + obj_surface->height / 4;
3388
            } else {
3389
                obj_surface->y_cb_offset = obj_surface->height;
3390
                obj_surface->y_cr_offset = obj_surface->height + obj_surface->height / 4;
3391
            }
3392
 
3393
            obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3394
            obj_surface->cb_cr_height = obj_surface->orig_height / 2;
3395
            obj_surface->cb_cr_pitch = obj_surface->width / 2;
3396
            region_height = obj_surface->height + obj_surface->height / 2;
3397
            break;
3398
 
3399
        case VA_FOURCC_YUY2:
3400
        case VA_FOURCC_UYVY:
3401
            obj_surface->width = ALIGN(obj_surface->orig_width * 2, i965->codec_info->min_linear_wpitch);
3402
            obj_surface->y_cb_offset = 0;
3403
            obj_surface->y_cr_offset = 0;
3404
            obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3405
            obj_surface->cb_cr_height = obj_surface->orig_height;
3406
            obj_surface->cb_cr_pitch = obj_surface->width;
3407
            region_width = obj_surface->width;
3408
            region_height = obj_surface->height;
3409
            break;
3410
        case VA_FOURCC_RGBA:
3411
        case VA_FOURCC_RGBX:
3412
        case VA_FOURCC_BGRA:
3413
        case VA_FOURCC_BGRX:
3414
            obj_surface->width = ALIGN(obj_surface->orig_width * 4, i965->codec_info->min_linear_wpitch);
3415
            region_width = obj_surface->width;
3416
            region_height = obj_surface->height;
3417
            break;
3418
 
3419
        default:
3420
            /* Never get here */
3421
            ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT);
3422
            break;
3423
        }
3424
    }
3425
 
3426
    obj_surface->size = ALIGN(region_width * region_height, 0x1000);
3427
 
3428
    if ((tiled && !obj_surface->user_disable_tiling)) {
3429
        uint32_t tiling_mode = I915_TILING_Y; /* always uses Y-tiled format */
3430
        unsigned long pitch;
3431
 
3432
        obj_surface->bo = drm_intel_bo_alloc_tiled(i965->intel.bufmgr,
3433
                                                   "vaapi surface",
3434
                                                   region_width,
3435
                                                   region_height,
3436
                                                   1,
3437
                                                   &tiling_mode,
3438
                                                   &pitch,
3439
                                                   0);
3440
        assert(tiling_mode == I915_TILING_Y);
3441
        assert(pitch == obj_surface->width);
3442
    } else {
3443
        obj_surface->bo = dri_bo_alloc(i965->intel.bufmgr,
3444
                                       "vaapi surface",
3445
                                       obj_surface->size,
3446
                                       0x1000);
3447
    }
3448
 
3449
    obj_surface->fourcc = fourcc;
3450
    obj_surface->subsampling = subsampling;
3451
    assert(obj_surface->bo);
3452
    return VA_STATUS_SUCCESS;
3453
}
3454
 
3455
VAStatus i965_DeriveImage(VADriverContextP ctx,
3456
                          VASurfaceID surface,
3457
                          VAImage *out_image)        /* out */
3458
{
3459
    struct i965_driver_data *i965 = i965_driver_data(ctx);
3460
    struct object_image *obj_image;
3461
    struct object_surface *obj_surface;
3462
    VAImageID image_id;
3463
    unsigned int w_pitch;
3464
    VAStatus va_status = VA_STATUS_ERROR_OPERATION_FAILED;
3465
 
3466
    out_image->image_id = VA_INVALID_ID;
3467
    obj_surface = SURFACE(surface);
3468
 
3469
    if (!obj_surface)
3470
        return VA_STATUS_ERROR_INVALID_SURFACE;
3471
 
3472
    if (!obj_surface->bo) {
3473
        unsigned int is_tiled = 0;
3474
        unsigned int fourcc = VA_FOURCC_YV12;
3475
        i965_guess_surface_format(ctx, surface, &fourcc, &is_tiled);
3476
        int sampling = get_sampling_from_fourcc(fourcc);
3477
        va_status = i965_check_alloc_surface_bo(ctx, obj_surface, is_tiled, fourcc, sampling);
3478
        if (va_status != VA_STATUS_SUCCESS)
3479
            return va_status;
3480
    }
3481
 
3482
    ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
3483
 
3484
    w_pitch = obj_surface->width;
3485
 
3486
    image_id = NEW_IMAGE_ID();
3487
 
3488
    if (image_id == VA_INVALID_ID)
3489
        return VA_STATUS_ERROR_ALLOCATION_FAILED;
3490
 
3491
    obj_image = IMAGE(image_id);
3492
 
3493
    if (!obj_image)
3494
        return VA_STATUS_ERROR_ALLOCATION_FAILED;
3495
 
3496
    obj_image->bo = NULL;
3497
    obj_image->palette = NULL;
3498
    obj_image->derived_surface = VA_INVALID_ID;
3499
 
3500
    VAImage * const image = &obj_image->image;
3501
 
3502
    memset(image, 0, sizeof(*image));
3503
    image->image_id = image_id;
3504
    image->buf = VA_INVALID_ID;
3505
    image->num_palette_entries = 0;
3506
    image->entry_bytes = 0;
3507
    image->width = obj_surface->orig_width;
3508
    image->height = obj_surface->orig_height;
3509
    image->data_size = obj_surface->size;
3510
 
3511
    image->format.fourcc = obj_surface->fourcc;
3512
    image->format.byte_order = VA_LSB_FIRST;
3513
    image->format.bits_per_pixel = 12;
3514
 
3515
    switch (image->format.fourcc) {
3516
    case VA_FOURCC_YV12:
3517
        image->num_planes = 3;
3518
        image->pitches[0] = w_pitch; /* Y */
3519
        image->offsets[0] = 0;
3520
        image->pitches[1] = obj_surface->cb_cr_pitch; /* V */
3521
        image->offsets[1] = w_pitch * obj_surface->y_cr_offset;
3522
        image->pitches[2] = obj_surface->cb_cr_pitch; /* U */
3523
        image->offsets[2] = w_pitch * obj_surface->y_cb_offset;
3524
        break;
3525
 
3526
    case VA_FOURCC_YV16:
3527
        image->num_planes = 3;
3528
        image->pitches[0] = w_pitch; /* Y */
3529
        image->offsets[0] = 0;
3530
        image->pitches[1] = obj_surface->cb_cr_pitch; /* V */
3531
        image->offsets[1] = w_pitch * obj_surface->y_cr_offset;
3532
        image->pitches[2] = obj_surface->cb_cr_pitch; /* U */
3533
        image->offsets[2] = w_pitch * obj_surface->y_cb_offset;
3534
        break;
3535
 
3536
    case VA_FOURCC_NV12:
3537
        image->num_planes = 2;
3538
        image->pitches[0] = w_pitch; /* Y */
3539
        image->offsets[0] = 0;
3540
        image->pitches[1] = obj_surface->cb_cr_pitch; /* UV */
3541
        image->offsets[1] = w_pitch * obj_surface->y_cb_offset;
3542
        break;
3543
 
3544
    case VA_FOURCC_I420:
3545
    case VA_FOURCC_422H:
3546
    case VA_FOURCC_IMC3:
3547
    case VA_FOURCC_444P:
3548
    case VA_FOURCC_422V:
3549
    case VA_FOURCC_411P:
3550
        image->num_planes = 3;
3551
        image->pitches[0] = w_pitch; /* Y */
3552
        image->offsets[0] = 0;
3553
        image->pitches[1] = obj_surface->cb_cr_pitch; /* U */
3554
        image->offsets[1] = w_pitch * obj_surface->y_cb_offset;
3555
        image->pitches[2] = obj_surface->cb_cr_pitch; /* V */
3556
        image->offsets[2] = w_pitch * obj_surface->y_cr_offset;
3557
        break;
3558
 
3559
    case VA_FOURCC_YUY2:
3560
    case VA_FOURCC_UYVY:
3561
    case VA_FOURCC_Y800:
3562
        image->num_planes = 1;
3563
        image->pitches[0] = obj_surface->width; /* Y, width is aligned already */
3564
        image->offsets[0] = 0;
3565
        break;
3566
    case VA_FOURCC_RGBA:
3567
    case VA_FOURCC_RGBX:
3568
    case VA_FOURCC_BGRA:
3569
    case VA_FOURCC_BGRX:
3570
        image->num_planes = 1;
3571
        image->pitches[0] = obj_surface->width;
3572
        break;
3573
    default:
3574
        goto error;
3575
    }
3576
 
3577
    va_status = i965_create_buffer_internal(ctx, 0, VAImageBufferType,
3578
                                            obj_surface->size, 1, NULL, obj_surface->bo, &image->buf);
3579
    if (va_status != VA_STATUS_SUCCESS)
3580
        goto error;
3581
 
3582
    struct object_buffer *obj_buffer = BUFFER(image->buf);
3583
 
3584
    if (!obj_buffer ||
3585
        !obj_buffer->buffer_store ||
3586
        !obj_buffer->buffer_store->bo)
3587
        return VA_STATUS_ERROR_ALLOCATION_FAILED;
3588
 
3589
    obj_image->bo = obj_buffer->buffer_store->bo;
3590
    dri_bo_reference(obj_image->bo);
3591
 
3592
    if (image->num_palette_entries > 0 && image->entry_bytes > 0) {
3593
        obj_image->palette = malloc(image->num_palette_entries * sizeof(*obj_image->palette));
3594
        if (!obj_image->palette) {
3595
            va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
3596
            goto error;
3597
        }
3598
    }
3599
 
3600
    *out_image = *image;
3601
    obj_surface->flags |= SURFACE_DERIVED;
3602
    obj_image->derived_surface = surface;
3603
 
3604
    return VA_STATUS_SUCCESS;
3605
 
3606
 error:
3607
    i965_DestroyImage(ctx, image_id);
3608
    return va_status;
3609
}
3610
 
3611
static void
3612
i965_destroy_image(struct object_heap *heap, struct object_base *obj)
3613
{
3614
    object_heap_free(heap, obj);
3615
}
3616
 
3617
 
3618
VAStatus
3619
i965_DestroyImage(VADriverContextP ctx, VAImageID image)
3620
{
3621
    struct i965_driver_data *i965 = i965_driver_data(ctx);
3622
    struct object_image *obj_image = IMAGE(image);
3623
    struct object_surface *obj_surface;
3624
 
3625
    if (!obj_image)
3626
        return VA_STATUS_SUCCESS;
3627
 
3628
    dri_bo_unreference(obj_image->bo);
3629
    obj_image->bo = NULL;
3630
 
3631
    if (obj_image->image.buf != VA_INVALID_ID) {
3632
        i965_DestroyBuffer(ctx, obj_image->image.buf);
3633
        obj_image->image.buf = VA_INVALID_ID;
3634
    }
3635
 
3636
    if (obj_image->palette) {
3637
        free(obj_image->palette);
3638
        obj_image->palette = NULL;
3639
    }
3640
 
3641
    obj_surface = SURFACE(obj_image->derived_surface);
3642
 
3643
    if (obj_surface) {
3644
        obj_surface->flags &= ~SURFACE_DERIVED;
3645
    }
3646
 
3647
    i965_destroy_image(&i965->image_heap, (struct object_base *)obj_image);
3648
 
3649
    return VA_STATUS_SUCCESS;
3650
}
3651
 
3652
/*
3653
 * pointer to an array holding the palette data.  The size of the array is
3654
 * num_palette_entries * entry_bytes in size.  The order of the components
3655
 * in the palette is described by the component_order in VASubpicture struct
3656
 */
3657
VAStatus
3658
i965_SetImagePalette(VADriverContextP ctx,
3659
                     VAImageID image,
3660
                     unsigned char *palette)
3661
{
3662
    struct i965_driver_data *i965 = i965_driver_data(ctx);
3663
    unsigned int i;
3664
 
3665
    struct object_image *obj_image = IMAGE(image);
3666
    if (!obj_image)
3667
        return VA_STATUS_ERROR_INVALID_IMAGE;
3668
 
3669
    if (!obj_image->palette)
3670
        return VA_STATUS_ERROR_ALLOCATION_FAILED; /* XXX: unpaletted/error */
3671
 
3672
    for (i = 0; i < obj_image->image.num_palette_entries; i++)
3673
        obj_image->palette[i] = (((unsigned int)palette[3*i + 0] << 16) |
3674
                                 ((unsigned int)palette[3*i + 1] <<  8) |
3675
                                 (unsigned int)palette[3*i + 2]);
3676
    return VA_STATUS_SUCCESS;
3677
}
3678
 
3679
static int
3680
get_sampling_from_fourcc(unsigned int fourcc)
3681
{
3682
    const i965_fourcc_info *info = get_fourcc_info(fourcc);
3683
 
3684
    if (info && (info->flag & I_S))
3685
        return info->subsampling;
3686
    else
3687
        return -1;
3688
}
3689
 
3690
static inline void
3691
memcpy_pic(uint8_t *dst, unsigned int dst_stride,
3692
           const uint8_t *src, unsigned int src_stride,
3693
           unsigned int len, unsigned int height)
3694
{
3695
    unsigned int i;
3696
 
3697
    for (i = 0; i < height; i++) {
3698
        memcpy(dst, src, len);
3699
        dst += dst_stride;
3700
        src += src_stride;
3701
    }
3702
}
3703
 
3704
static VAStatus
3705
get_image_i420(struct object_image *obj_image, uint8_t *image_data,
3706
               struct object_surface *obj_surface,
3707
               const VARectangle *rect)
3708
{
3709
    uint8_t *dst[3], *src[3];
3710
    const int Y = 0;
3711
    const int U = obj_image->image.format.fourcc == obj_surface->fourcc ? 1 : 2;
3712
    const int V = obj_image->image.format.fourcc == obj_surface->fourcc ? 2 : 1;
3713
    unsigned int tiling, swizzle;
3714
    VAStatus va_status = VA_STATUS_SUCCESS;
3715
 
3716
    if (!obj_surface->bo)
3717
        return VA_STATUS_ERROR_INVALID_SURFACE;
3718
 
3719
    ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
3720
    dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
3721
 
3722
    if (tiling != I915_TILING_NONE)
3723
        drm_intel_gem_bo_map_gtt(obj_surface->bo);
3724
    else
3725
        dri_bo_map(obj_surface->bo, 0);
3726
 
3727
    if (!obj_surface->bo->virtual)
3728
        return VA_STATUS_ERROR_INVALID_SURFACE;
3729
 
3730
    /* Dest VA image has either I420 or YV12 format.
3731
       Source VA surface alway has I420 format */
3732
    dst[Y] = image_data + obj_image->image.offsets[Y];
3733
    src[0] = (uint8_t *)obj_surface->bo->virtual;
3734
    dst[U] = image_data + obj_image->image.offsets[U];
3735
    src[1] = src[0] + obj_surface->width * obj_surface->height;
3736
    dst[V] = image_data + obj_image->image.offsets[V];
3737
    src[2] = src[1] + (obj_surface->width / 2) * (obj_surface->height / 2);
3738
 
3739
    /* Y plane */
3740
    dst[Y] += rect->y * obj_image->image.pitches[Y] + rect->x;
3741
    src[0] += rect->y * obj_surface->width + rect->x;
3742
    memcpy_pic(dst[Y], obj_image->image.pitches[Y],
3743
               src[0], obj_surface->width,
3744
               rect->width, rect->height);
3745
 
3746
    /* U plane */
3747
    dst[U] += (rect->y / 2) * obj_image->image.pitches[U] + rect->x / 2;
3748
    src[1] += (rect->y / 2) * obj_surface->width / 2 + rect->x / 2;
3749
    memcpy_pic(dst[U], obj_image->image.pitches[U],
3750
               src[1], obj_surface->width / 2,
3751
               rect->width / 2, rect->height / 2);
3752
 
3753
    /* V plane */
3754
    dst[V] += (rect->y / 2) * obj_image->image.pitches[V] + rect->x / 2;
3755
    src[2] += (rect->y / 2) * obj_surface->width / 2 + rect->x / 2;
3756
    memcpy_pic(dst[V], obj_image->image.pitches[V],
3757
               src[2], obj_surface->width / 2,
3758
               rect->width / 2, rect->height / 2);
3759
 
3760
    if (tiling != I915_TILING_NONE)
3761
        drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
3762
    else
3763
        dri_bo_unmap(obj_surface->bo);
3764
 
3765
    return va_status;
3766
}
3767
 
3768
static VAStatus
3769
get_image_nv12(struct object_image *obj_image, uint8_t *image_data,
3770
               struct object_surface *obj_surface,
3771
               const VARectangle *rect)
3772
{
3773
    uint8_t *dst[2], *src[2];
3774
    unsigned int tiling, swizzle;
3775
    VAStatus va_status = VA_STATUS_SUCCESS;
3776
 
3777
    if (!obj_surface->bo)
3778
        return VA_STATUS_ERROR_INVALID_SURFACE;
3779
 
3780
    assert(obj_surface->fourcc);
3781
    dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
3782
 
3783
    if (tiling != I915_TILING_NONE)
3784
        drm_intel_gem_bo_map_gtt(obj_surface->bo);
3785
    else
3786
        dri_bo_map(obj_surface->bo, 0);
3787
 
3788
    if (!obj_surface->bo->virtual)
3789
        return VA_STATUS_ERROR_INVALID_SURFACE;
3790
 
3791
    /* Both dest VA image and source surface have NV12 format */
3792
    dst[0] = image_data + obj_image->image.offsets[0];
3793
    src[0] = (uint8_t *)obj_surface->bo->virtual;
3794
    dst[1] = image_data + obj_image->image.offsets[1];
3795
    src[1] = src[0] + obj_surface->width * obj_surface->height;
3796
 
3797
    /* Y plane */
3798
    dst[0] += rect->y * obj_image->image.pitches[0] + rect->x;
3799
    src[0] += rect->y * obj_surface->width + rect->x;
3800
    memcpy_pic(dst[0], obj_image->image.pitches[0],
3801
               src[0], obj_surface->width,
3802
               rect->width, rect->height);
3803
 
3804
    /* UV plane */
3805
    dst[1] += (rect->y / 2) * obj_image->image.pitches[1] + (rect->x & -2);
3806
    src[1] += (rect->y / 2) * obj_surface->width + (rect->x & -2);
3807
    memcpy_pic(dst[1], obj_image->image.pitches[1],
3808
               src[1], obj_surface->width,
3809
               rect->width, rect->height / 2);
3810
 
3811
    if (tiling != I915_TILING_NONE)
3812
        drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
3813
    else
3814
        dri_bo_unmap(obj_surface->bo);
3815
 
3816
    return va_status;
3817
}
3818
 
3819
static VAStatus
3820
get_image_yuy2(struct object_image *obj_image, uint8_t *image_data,
3821
               struct object_surface *obj_surface,
3822
               const VARectangle *rect)
3823
{
3824
    uint8_t *dst, *src;
3825
    unsigned int tiling, swizzle;
3826
    VAStatus va_status = VA_STATUS_SUCCESS;
3827
 
3828
    if (!obj_surface->bo)
3829
        return VA_STATUS_ERROR_INVALID_SURFACE;
3830
 
3831
    assert(obj_surface->fourcc);
3832
    dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
3833
 
3834
    if (tiling != I915_TILING_NONE)
3835
        drm_intel_gem_bo_map_gtt(obj_surface->bo);
3836
    else
3837
        dri_bo_map(obj_surface->bo, 0);
3838
 
3839
    if (!obj_surface->bo->virtual)
3840
        return VA_STATUS_ERROR_INVALID_SURFACE;
3841
 
3842
    /* Both dest VA image and source surface have YUYV format */
3843
    dst = image_data + obj_image->image.offsets[0];
3844
    src = (uint8_t *)obj_surface->bo->virtual;
3845
 
3846
    /* Y plane */
3847
    dst += rect->y * obj_image->image.pitches[0] + rect->x*2;
3848
    src += rect->y * obj_surface->width + rect->x*2;
3849
    memcpy_pic(dst, obj_image->image.pitches[0],
3850
               src, obj_surface->width*2,
3851
               rect->width*2, rect->height);
3852
 
3853
    if (tiling != I915_TILING_NONE)
3854
        drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
3855
    else
3856
        dri_bo_unmap(obj_surface->bo);
3857
 
3858
    return va_status;
3859
}
3860
 
3861
static VAStatus
3862
i965_sw_getimage(VADriverContextP ctx,
3863
                 VASurfaceID surface,
3864
                 int x,   /* coordinates of the upper left source pixel */
3865
                 int y,
3866
                 unsigned int width,      /* width and height of the region */
3867
                 unsigned int height,
3868
                 VAImageID image)
3869
{
3870
    struct i965_driver_data *i965 = i965_driver_data(ctx);
3871
    struct i965_render_state *render_state = &i965->render_state;
3872
    VAStatus va_status = VA_STATUS_SUCCESS;
3873
 
3874
    struct object_surface *obj_surface = SURFACE(surface);
3875
    if (!obj_surface)
3876
        return VA_STATUS_ERROR_INVALID_SURFACE;
3877
 
3878
    struct object_image *obj_image = IMAGE(image);
3879
    if (!obj_image)
3880
        return VA_STATUS_ERROR_INVALID_IMAGE;
3881
 
3882
    if (x < 0 || y < 0)
3883
        return VA_STATUS_ERROR_INVALID_PARAMETER;
3884
    if (x + width > obj_surface->orig_width ||
3885
        y + height > obj_surface->orig_height)
3886
        return VA_STATUS_ERROR_INVALID_PARAMETER;
3887
    if (x + width > obj_image->image.width ||
3888
        y + height > obj_image->image.height)
3889
        return VA_STATUS_ERROR_INVALID_PARAMETER;
3890
 
3891
    if (obj_surface->fourcc != obj_image->image.format.fourcc)
3892
        return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
3893
 
3894
    void *image_data = NULL;
3895
 
3896
    va_status = i965_MapBuffer(ctx, obj_image->image.buf, &image_data);
3897
    if (va_status != VA_STATUS_SUCCESS)
3898
        return va_status;
3899
 
3900
    VARectangle rect;
3901
    rect.x = x;
3902
    rect.y = y;
3903
    rect.width = width;
3904
    rect.height = height;
3905
 
3906
    switch (obj_image->image.format.fourcc) {
3907
    case VA_FOURCC_YV12:
3908
    case VA_FOURCC_I420:
3909
        /* I420 is native format for MPEG-2 decoded surfaces */
3910
        if (render_state->interleaved_uv)
3911
            goto operation_failed;
3912
        get_image_i420(obj_image, image_data, obj_surface, &rect);
3913
        break;
3914
    case VA_FOURCC_NV12:
3915
        /* NV12 is native format for H.264 decoded surfaces */
3916
        if (!render_state->interleaved_uv)
3917
            goto operation_failed;
3918
        get_image_nv12(obj_image, image_data, obj_surface, &rect);
3919
        break;
3920
    case VA_FOURCC_YUY2:
3921
        /* YUY2 is the format supported by overlay plane */
3922
        get_image_yuy2(obj_image, image_data, obj_surface, &rect);
3923
        break;
3924
    default:
3925
    operation_failed:
3926
        va_status = VA_STATUS_ERROR_OPERATION_FAILED;
3927
        break;
3928
    }
3929
 
3930
    if (va_status != VA_STATUS_SUCCESS)
3931
        return va_status;
3932
 
3933
    va_status = i965_UnmapBuffer(ctx, obj_image->image.buf);
3934
    return va_status;
3935
}
3936
 
3937
static VAStatus
3938
i965_hw_getimage(VADriverContextP ctx,
3939
                 VASurfaceID surface,
3940
                 int x,   /* coordinates of the upper left source pixel */
3941
                 int y,
3942
                 unsigned int width,      /* width and height of the region */
3943
                 unsigned int height,
3944
                 VAImageID image)
3945
{
3946
    struct i965_driver_data *i965 = i965_driver_data(ctx);
3947
    struct i965_surface src_surface;
3948
    struct i965_surface dst_surface;
3949
    VAStatus va_status = VA_STATUS_SUCCESS;
3950
    VARectangle rect;
3951
    struct object_surface *obj_surface = SURFACE(surface);
3952
    struct object_image *obj_image = IMAGE(image);
3953
 
3954
    if (!obj_surface)
3955
        return VA_STATUS_ERROR_INVALID_SURFACE;
3956
 
3957
    if (!obj_image)
3958
        return VA_STATUS_ERROR_INVALID_IMAGE;
3959
 
3960
    if (x < 0 || y < 0)
3961
        return VA_STATUS_ERROR_INVALID_PARAMETER;
3962
    if (x + width > obj_surface->orig_width ||
3963
        y + height > obj_surface->orig_height)
3964
        return VA_STATUS_ERROR_INVALID_PARAMETER;
3965
    if (x + width > obj_image->image.width ||
3966
        y + height > obj_image->image.height)
3967
        return VA_STATUS_ERROR_INVALID_PARAMETER;
3968
 
3969
    if (!obj_surface->bo)
3970
        return VA_STATUS_SUCCESS;
3971
    assert(obj_image->bo); // image bo is always created, see i965_CreateImage()
3972
 
3973
    rect.x = x;
3974
    rect.y = y;
3975
    rect.width = width;
3976
    rect.height = height;
3977
 
3978
    src_surface.base = (struct object_base *)obj_surface;
3979
    src_surface.type = I965_SURFACE_TYPE_SURFACE;
3980
    src_surface.flags = I965_SURFACE_FLAG_FRAME;
3981
 
3982
    dst_surface.base = (struct object_base *)obj_image;
3983
    dst_surface.type = I965_SURFACE_TYPE_IMAGE;
3984
    dst_surface.flags = I965_SURFACE_FLAG_FRAME;
3985
 
3986
    va_status = i965_image_processing(ctx,
3987
                                      &src_surface,
3988
                                      &rect,
3989
                                      &dst_surface,
3990
                                      &rect);
3991
 
3992
 
3993
    return va_status;
3994
}
3995
 
3996
VAStatus
3997
i965_GetImage(VADriverContextP ctx,
3998
              VASurfaceID surface,
3999
              int x,   /* coordinates of the upper left source pixel */
4000
              int y,
4001
              unsigned int width,      /* width and height of the region */
4002
              unsigned int height,
4003
              VAImageID image)
4004
{
4005
    struct i965_driver_data * const i965 = i965_driver_data(ctx);
4006
    VAStatus va_status = VA_STATUS_SUCCESS;
4007
 
4008
    if (HAS_ACCELERATED_GETIMAGE(i965))
4009
        va_status = i965_hw_getimage(ctx,
4010
                                     surface,
4011
                                     x, y,
4012
                                     width, height,
4013
                                     image);
4014
    else
4015
        va_status = i965_sw_getimage(ctx,
4016
                                     surface,
4017
                                     x, y,
4018
                                     width, height,
4019
                                     image);
4020
 
4021
    return va_status;
4022
}
4023
 
4024
static VAStatus
4025
put_image_i420(struct object_surface *obj_surface,
4026
               const VARectangle *dst_rect,
4027
               struct object_image *obj_image, uint8_t *image_data,
4028
               const VARectangle *src_rect)
4029
{
4030
    uint8_t *dst[3], *src[3];
4031
    const int Y = 0;
4032
    const int U = obj_image->image.format.fourcc == obj_surface->fourcc ? 1 : 2;
4033
    const int V = obj_image->image.format.fourcc == obj_surface->fourcc ? 2 : 1;
4034
    unsigned int tiling, swizzle;
4035
    VAStatus va_status = VA_STATUS_SUCCESS;
4036
 
4037
    ASSERT_RET(obj_surface->bo, VA_STATUS_ERROR_INVALID_SURFACE);
4038
 
4039
    ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
4040
    ASSERT_RET(dst_rect->width == src_rect->width, VA_STATUS_ERROR_UNIMPLEMENTED);
4041
    ASSERT_RET(dst_rect->height == src_rect->height, VA_STATUS_ERROR_UNIMPLEMENTED);
4042
    dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
4043
 
4044
    if (tiling != I915_TILING_NONE)
4045
        drm_intel_gem_bo_map_gtt(obj_surface->bo);
4046
    else
4047
        dri_bo_map(obj_surface->bo, 0);
4048
 
4049
    if (!obj_surface->bo->virtual)
4050
        return VA_STATUS_ERROR_INVALID_SURFACE;
4051
 
4052
    /* Dest VA image has either I420 or YV12 format.
4053
       Source VA surface alway has I420 format */
4054
    dst[0] = (uint8_t *)obj_surface->bo->virtual;
4055
    src[Y] = image_data + obj_image->image.offsets[Y];
4056
    dst[1] = dst[0] + obj_surface->width * obj_surface->height;
4057
    src[U] = image_data + obj_image->image.offsets[U];
4058
    dst[2] = dst[1] + (obj_surface->width / 2) * (obj_surface->height / 2);
4059
    src[V] = image_data + obj_image->image.offsets[V];
4060
 
4061
    /* Y plane */
4062
    dst[0] += dst_rect->y * obj_surface->width + dst_rect->x;
4063
    src[Y] += src_rect->y * obj_image->image.pitches[Y] + src_rect->x;
4064
    memcpy_pic(dst[0], obj_surface->width,
4065
               src[Y], obj_image->image.pitches[Y],
4066
               src_rect->width, src_rect->height);
4067
 
4068
    /* U plane */
4069
    dst[1] += (dst_rect->y / 2) * obj_surface->width / 2 + dst_rect->x / 2;
4070
    src[U] += (src_rect->y / 2) * obj_image->image.pitches[U] + src_rect->x / 2;
4071
    memcpy_pic(dst[1], obj_surface->width / 2,
4072
               src[U], obj_image->image.pitches[U],
4073
               src_rect->width / 2, src_rect->height / 2);
4074
 
4075
    /* V plane */
4076
    dst[2] += (dst_rect->y / 2) * obj_surface->width / 2 + dst_rect->x / 2;
4077
    src[V] += (src_rect->y / 2) * obj_image->image.pitches[V] + src_rect->x / 2;
4078
    memcpy_pic(dst[2], obj_surface->width / 2,
4079
               src[V], obj_image->image.pitches[V],
4080
               src_rect->width / 2, src_rect->height / 2);
4081
 
4082
    if (tiling != I915_TILING_NONE)
4083
        drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
4084
    else
4085
        dri_bo_unmap(obj_surface->bo);
4086
 
4087
    return va_status;
4088
}
4089
 
4090
static VAStatus
4091
put_image_nv12(struct object_surface *obj_surface,
4092
               const VARectangle *dst_rect,
4093
               struct object_image *obj_image, uint8_t *image_data,
4094
               const VARectangle *src_rect)
4095
{
4096
    uint8_t *dst[2], *src[2];
4097
    unsigned int tiling, swizzle;
4098
    VAStatus va_status = VA_STATUS_SUCCESS;
4099
 
4100
    if (!obj_surface->bo)
4101
        return VA_STATUS_ERROR_INVALID_SURFACE;
4102
 
4103
    ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
4104
    ASSERT_RET(dst_rect->width == src_rect->width, VA_STATUS_ERROR_UNIMPLEMENTED);
4105
    ASSERT_RET(dst_rect->height == src_rect->height, VA_STATUS_ERROR_UNIMPLEMENTED);
4106
    dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
4107
 
4108
    if (tiling != I915_TILING_NONE)
4109
        drm_intel_gem_bo_map_gtt(obj_surface->bo);
4110
    else
4111
        dri_bo_map(obj_surface->bo, 0);
4112
 
4113
    if (!obj_surface->bo->virtual)
4114
        return VA_STATUS_ERROR_INVALID_SURFACE;
4115
 
4116
    /* Both dest VA image and source surface have NV12 format */
4117
    dst[0] = (uint8_t *)obj_surface->bo->virtual;
4118
    src[0] = image_data + obj_image->image.offsets[0];
4119
    dst[1] = dst[0] + obj_surface->width * obj_surface->height;
4120
    src[1] = image_data + obj_image->image.offsets[1];
4121
 
4122
    /* Y plane */
4123
    dst[0] += dst_rect->y * obj_surface->width + dst_rect->x;
4124
    src[0] += src_rect->y * obj_image->image.pitches[0] + src_rect->x;
4125
    memcpy_pic(dst[0], obj_surface->width,
4126
               src[0], obj_image->image.pitches[0],
4127
               src_rect->width, src_rect->height);
4128
 
4129
    /* UV plane */
4130
    dst[1] += (dst_rect->y / 2) * obj_surface->width + (dst_rect->x & -2);
4131
    src[1] += (src_rect->y / 2) * obj_image->image.pitches[1] + (src_rect->x & -2);
4132
    memcpy_pic(dst[1], obj_surface->width,
4133
               src[1], obj_image->image.pitches[1],
4134
               src_rect->width, src_rect->height / 2);
4135
 
4136
    if (tiling != I915_TILING_NONE)
4137
        drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
4138
    else
4139
        dri_bo_unmap(obj_surface->bo);
4140
 
4141
    return va_status;
4142
}
4143
 
4144
static VAStatus
4145
put_image_yuy2(struct object_surface *obj_surface,
4146
               const VARectangle *dst_rect,
4147
               struct object_image *obj_image, uint8_t *image_data,
4148
               const VARectangle *src_rect)
4149
{
4150
    uint8_t *dst, *src;
4151
    unsigned int tiling, swizzle;
4152
    VAStatus va_status = VA_STATUS_SUCCESS;
4153
 
4154
    ASSERT_RET(obj_surface->bo, VA_STATUS_ERROR_INVALID_SURFACE);
4155
    ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
4156
    ASSERT_RET(dst_rect->width == src_rect->width, VA_STATUS_ERROR_UNIMPLEMENTED);
4157
    ASSERT_RET(dst_rect->height == src_rect->height, VA_STATUS_ERROR_UNIMPLEMENTED);
4158
    dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
4159
 
4160
    if (tiling != I915_TILING_NONE)
4161
        drm_intel_gem_bo_map_gtt(obj_surface->bo);
4162
    else
4163
        dri_bo_map(obj_surface->bo, 0);
4164
 
4165
    if (!obj_surface->bo->virtual)
4166
        return VA_STATUS_ERROR_INVALID_SURFACE;
4167
 
4168
    /* Both dest VA image and source surface have YUY2 format */
4169
    dst = (uint8_t *)obj_surface->bo->virtual;
4170
    src = image_data + obj_image->image.offsets[0];
4171
 
4172
    /* YUYV packed plane */
4173
    dst += dst_rect->y * obj_surface->width + dst_rect->x*2;
4174
    src += src_rect->y * obj_image->image.pitches[0] + src_rect->x*2;
4175
    memcpy_pic(dst, obj_surface->width*2,
4176
               src, obj_image->image.pitches[0],
4177
               src_rect->width*2, src_rect->height);
4178
 
4179
    if (tiling != I915_TILING_NONE)
4180
        drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
4181
    else
4182
        dri_bo_unmap(obj_surface->bo);
4183
 
4184
    return va_status;
4185
}
4186
 
4187
 
4188
static VAStatus
4189
i965_sw_putimage(VADriverContextP ctx,
4190
                 VASurfaceID surface,
4191
                 VAImageID image,
4192
                 int src_x,
4193
                 int src_y,
4194
                 unsigned int src_width,
4195
                 unsigned int src_height,
4196
                 int dest_x,
4197
                 int dest_y,
4198
                 unsigned int dest_width,
4199
                 unsigned int dest_height)
4200
{
4201
    struct i965_driver_data *i965 = i965_driver_data(ctx);
4202
    struct object_surface *obj_surface = SURFACE(surface);
4203
    struct object_image *obj_image = IMAGE(image);
4204
    VAStatus va_status = VA_STATUS_SUCCESS;
4205
    void *image_data = NULL;
4206
 
4207
    ASSERT_RET(obj_surface, VA_STATUS_ERROR_INVALID_SURFACE);
4208
    ASSERT_RET(obj_image, VA_STATUS_ERROR_INVALID_IMAGE);
4209
 
4210
    if (src_x < 0 || src_y < 0)
4211
        return VA_STATUS_ERROR_INVALID_PARAMETER;
4212
    if (src_x + src_width > obj_image->image.width ||
4213
        src_y + src_height > obj_image->image.height)
4214
        return VA_STATUS_ERROR_INVALID_PARAMETER;
4215
    if (dest_x < 0 || dest_y < 0)
4216
        return VA_STATUS_ERROR_INVALID_PARAMETER;
4217
    if (dest_x + dest_width > obj_surface->orig_width ||
4218
        dest_y + dest_height > obj_surface->orig_height)
4219
        return VA_STATUS_ERROR_INVALID_PARAMETER;
4220
 
4221
    /* XXX: don't allow scaling */
4222
    if (src_width != dest_width || src_height != dest_height)
4223
        return VA_STATUS_ERROR_INVALID_PARAMETER;
4224
 
4225
    if (obj_surface->fourcc) {
4226
        /* Don't allow format mismatch */
4227
        if (obj_surface->fourcc != obj_image->image.format.fourcc)
4228
            return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
4229
    }
4230
 
4231
    else {
4232
        /* VA is surface not used for decoding, use same VA image format */
4233
        va_status = i965_check_alloc_surface_bo(
4234
            ctx,
4235
            obj_surface,
4236
            0, /* XXX: don't use tiled surface */
4237
            obj_image->image.format.fourcc,
4238
            get_sampling_from_fourcc (obj_image->image.format.fourcc));
4239
    }
4240
 
4241
    if (va_status != VA_STATUS_SUCCESS)
4242
        return va_status;
4243
 
4244
    va_status = i965_MapBuffer(ctx, obj_image->image.buf, &image_data);
4245
    if (va_status != VA_STATUS_SUCCESS)
4246
        return va_status;
4247
 
4248
    VARectangle src_rect, dest_rect;
4249
    src_rect.x       = src_x;
4250
    src_rect.y       = src_y;
4251
    src_rect.width   = src_width;
4252
    src_rect.height  = src_height;
4253
    dest_rect.x      = dest_x;
4254
    dest_rect.y      = dest_y;
4255
    dest_rect.width  = dest_width;
4256
    dest_rect.height = dest_height;
4257
 
4258
    switch (obj_image->image.format.fourcc) {
4259
    case VA_FOURCC_YV12:
4260
    case VA_FOURCC_I420:
4261
        va_status = put_image_i420(obj_surface, &dest_rect, obj_image, image_data, &src_rect);
4262
        break;
4263
    case VA_FOURCC_NV12:
4264
        va_status = put_image_nv12(obj_surface, &dest_rect, obj_image, image_data, &src_rect);
4265
        break;
4266
    case VA_FOURCC_YUY2:
4267
        va_status = put_image_yuy2(obj_surface, &dest_rect, obj_image, image_data, &src_rect);
4268
        break;
4269
    default:
4270
        va_status = VA_STATUS_ERROR_OPERATION_FAILED;
4271
        break;
4272
    }
4273
    if (va_status != VA_STATUS_SUCCESS)
4274
        return va_status;
4275
 
4276
    va_status = i965_UnmapBuffer(ctx, obj_image->image.buf);
4277
    return va_status;
4278
}
4279
 
4280
static VAStatus
4281
i965_hw_putimage(VADriverContextP ctx,
4282
                 VASurfaceID surface,
4283
                 VAImageID image,
4284
                 int src_x,
4285
                 int src_y,
4286
                 unsigned int src_width,
4287
                 unsigned int src_height,
4288
                 int dest_x,
4289
                 int dest_y,
4290
                 unsigned int dest_width,
4291
                 unsigned int dest_height)
4292
{
4293
    struct i965_driver_data *i965 = i965_driver_data(ctx);
4294
    struct object_surface *obj_surface = SURFACE(surface);
4295
    struct object_image *obj_image = IMAGE(image);
4296
    struct i965_surface src_surface, dst_surface;
4297
    VAStatus va_status = VA_STATUS_SUCCESS;
4298
    VARectangle src_rect, dst_rect;
4299
 
4300
    ASSERT_RET(obj_surface,VA_STATUS_ERROR_INVALID_SURFACE);
4301
    ASSERT_RET(obj_image && obj_image->bo, VA_STATUS_ERROR_INVALID_IMAGE);
4302
 
4303
    if (src_x < 0 ||
4304
        src_y < 0 ||
4305
        src_x + src_width > obj_image->image.width ||
4306
        src_y + src_height > obj_image->image.height)
4307
        return VA_STATUS_ERROR_INVALID_PARAMETER;
4308
 
4309
    if (dest_x < 0 ||
4310
        dest_y < 0 ||
4311
        dest_x + dest_width > obj_surface->orig_width ||
4312
        dest_y + dest_height > obj_surface->orig_height)
4313
        return VA_STATUS_ERROR_INVALID_PARAMETER;
4314
 
4315
    if (!obj_surface->bo) {
4316
        unsigned int tiling, swizzle;
4317
        int surface_sampling = get_sampling_from_fourcc (obj_image->image.format.fourcc);;
4318
        dri_bo_get_tiling(obj_image->bo, &tiling, &swizzle);
4319
 
4320
        i965_check_alloc_surface_bo(ctx,
4321
                                    obj_surface,
4322
                                    !!tiling,
4323
                                    obj_image->image.format.fourcc,
4324
                                    surface_sampling);
4325
    }
4326
 
4327
    ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
4328
 
4329
    src_surface.base = (struct object_base *)obj_image;
4330
    src_surface.type = I965_SURFACE_TYPE_IMAGE;
4331
    src_surface.flags = I965_SURFACE_FLAG_FRAME;
4332
    src_rect.x = src_x;
4333
    src_rect.y = src_y;
4334
    src_rect.width = src_width;
4335
    src_rect.height = src_height;
4336
 
4337
    dst_surface.base = (struct object_base *)obj_surface;
4338
    dst_surface.type = I965_SURFACE_TYPE_SURFACE;
4339
    dst_surface.flags = I965_SURFACE_FLAG_FRAME;
4340
    dst_rect.x = dest_x;
4341
    dst_rect.y = dest_y;
4342
    dst_rect.width = dest_width;
4343
    dst_rect.height = dest_height;
4344
 
4345
    va_status = i965_image_processing(ctx,
4346
                                      &src_surface,
4347
                                      &src_rect,
4348
                                      &dst_surface,
4349
                                      &dst_rect);
4350
 
4351
    return  va_status;
4352
}
4353
 
4354
static VAStatus
4355
i965_PutImage(VADriverContextP ctx,
4356
              VASurfaceID surface,
4357
              VAImageID image,
4358
              int src_x,
4359
              int src_y,
4360
              unsigned int src_width,
4361
              unsigned int src_height,
4362
              int dest_x,
4363
              int dest_y,
4364
              unsigned int dest_width,
4365
              unsigned int dest_height)
4366
{
4367
    struct i965_driver_data *i965 = i965_driver_data(ctx);
4368
    VAStatus va_status = VA_STATUS_SUCCESS;
4369
 
4370
    if (HAS_ACCELERATED_PUTIMAGE(i965))
4371
        va_status = i965_hw_putimage(ctx,
4372
                                     surface,
4373
                                     image,
4374
                                     src_x,
4375
                                     src_y,
4376
                                     src_width,
4377
                                     src_height,
4378
                                     dest_x,
4379
                                     dest_y,
4380
                                     dest_width,
4381
                                     dest_height);
4382
    else
4383
        va_status = i965_sw_putimage(ctx,
4384
                                     surface,
4385
                                     image,
4386
                                     src_x,
4387
                                     src_y,
4388
                                     src_width,
4389
                                     src_height,
4390
                                     dest_x,
4391
                                     dest_y,
4392
                                     dest_width,
4393
                                     dest_height);
4394
 
4395
    return va_status;
4396
}
4397
 
4398
VAStatus
4399
i965_PutSurface(VADriverContextP ctx,
4400
                VASurfaceID surface,
4401
                void *draw, /* X Drawable */
4402
                short srcx,
4403
                short srcy,
4404
                unsigned short srcw,
4405
                unsigned short srch,
4406
                short destx,
4407
                short desty,
4408
                unsigned short destw,
4409
                unsigned short desth,
4410
                VARectangle *cliprects, /* client supplied clip list */
4411
                unsigned int number_cliprects, /* number of clip rects in the clip list */
4412
                unsigned int flags) /* de-interlacing flags */
4413
{
4414
#ifdef HAVE_VA_X11
4415
    if (IS_VA_X11(ctx)) {
4416
        VARectangle src_rect, dst_rect;
4417
 
4418
        src_rect.x      = srcx;
4419
        src_rect.y      = srcy;
4420
        src_rect.width  = srcw;
4421
        src_rect.height = srch;
4422
 
4423
        dst_rect.x      = destx;
4424
        dst_rect.y      = desty;
4425
        dst_rect.width  = destw;
4426
        dst_rect.height = desth;
4427
 
4428
        return i965_put_surface_dri(ctx, surface, draw, &src_rect, &dst_rect,
4429
                                    cliprects, number_cliprects, flags);
4430
    }
4431
#endif
4432
    return VA_STATUS_ERROR_UNIMPLEMENTED;
4433
}
4434
 
4435
static VAStatus
4436
i965_BufferInfo(
4437
    VADriverContextP ctx,       /* in */
4438
    VABufferID buf_id,          /* in */
4439
    VABufferType *type,         /* out */
4440
    unsigned int *size,         /* out */
4441
    unsigned int *num_elements  /* out */
4442
)
4443
{
4444
    struct i965_driver_data *i965 = NULL;
4445
    struct object_buffer *obj_buffer = NULL;
4446
 
4447
    i965 = i965_driver_data(ctx);
4448
    obj_buffer = BUFFER(buf_id);
4449
 
4450
    ASSERT_RET(obj_buffer, VA_STATUS_ERROR_INVALID_BUFFER);
4451
 
4452
    *type = obj_buffer->type;
4453
    *size = obj_buffer->size_element;
4454
    *num_elements = obj_buffer->num_elements;
4455
 
4456
    return VA_STATUS_SUCCESS;
4457
}
4458
 
4459
static VAStatus
4460
i965_LockSurface(
4461
    VADriverContextP ctx,           /* in */
4462
    VASurfaceID surface,            /* in */
4463
    unsigned int *fourcc,           /* out */
4464
    unsigned int *luma_stride,      /* out */
4465
    unsigned int *chroma_u_stride,  /* out */
4466
    unsigned int *chroma_v_stride,  /* out */
4467
    unsigned int *luma_offset,      /* out */
4468
    unsigned int *chroma_u_offset,  /* out */
4469
    unsigned int *chroma_v_offset,  /* out */
4470
    unsigned int *buffer_name,      /* out */
4471
    void **buffer                   /* out */
4472
)
4473
{
4474
    VAStatus vaStatus = VA_STATUS_SUCCESS;
4475
    struct i965_driver_data *i965 = i965_driver_data(ctx);
4476
    struct object_surface *obj_surface = NULL;
4477
    VAImage tmpImage;
4478
 
4479
    ASSERT_RET(fourcc, VA_STATUS_ERROR_INVALID_PARAMETER);
4480
    ASSERT_RET(luma_stride, VA_STATUS_ERROR_INVALID_PARAMETER);
4481
    ASSERT_RET(chroma_u_stride, VA_STATUS_ERROR_INVALID_PARAMETER);
4482
    ASSERT_RET(chroma_v_stride, VA_STATUS_ERROR_INVALID_PARAMETER);
4483
    ASSERT_RET(luma_offset, VA_STATUS_ERROR_INVALID_PARAMETER);
4484
    ASSERT_RET(chroma_u_offset, VA_STATUS_ERROR_INVALID_PARAMETER);
4485
    ASSERT_RET(chroma_v_offset, VA_STATUS_ERROR_INVALID_PARAMETER);
4486
    ASSERT_RET(buffer_name, VA_STATUS_ERROR_INVALID_PARAMETER);
4487
    ASSERT_RET(buffer, VA_STATUS_ERROR_INVALID_PARAMETER);
4488
 
4489
    tmpImage.image_id = VA_INVALID_ID;
4490
 
4491
    obj_surface = SURFACE(surface);
4492
    if (obj_surface == NULL) {
4493
        // Surface is absent.
4494
        vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
4495
        goto error;
4496
    }
4497
 
4498
    // Lock functionality is absent now.
4499
    if (obj_surface->locked_image_id != VA_INVALID_ID) {
4500
        // Surface is locked already.
4501
        vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
4502
        goto error;
4503
    }
4504
 
4505
    vaStatus = i965_DeriveImage(
4506
        ctx,
4507
        surface,
4508
        &tmpImage);
4509
    if (vaStatus != VA_STATUS_SUCCESS) {
4510
        goto error;
4511
    }
4512
 
4513
    obj_surface->locked_image_id = tmpImage.image_id;
4514
 
4515
    vaStatus = i965_MapBuffer(
4516
        ctx,
4517
        tmpImage.buf,
4518
        buffer);
4519
    if (vaStatus != VA_STATUS_SUCCESS) {
4520
        goto error;
4521
    }
4522
 
4523
    *fourcc = tmpImage.format.fourcc;
4524
    *luma_offset = tmpImage.offsets[0];
4525
    *luma_stride = tmpImage.pitches[0];
4526
    *chroma_u_offset = tmpImage.offsets[1];
4527
    *chroma_u_stride = tmpImage.pitches[1];
4528
    *chroma_v_offset = tmpImage.offsets[2];
4529
    *chroma_v_stride = tmpImage.pitches[2];
4530
    *buffer_name = tmpImage.buf;
4531
 
4532
error:
4533
    if (vaStatus != VA_STATUS_SUCCESS) {
4534
        buffer = NULL;
4535
    }
4536
 
4537
    return vaStatus;
4538
}
4539
 
4540
static VAStatus
4541
i965_UnlockSurface(
4542
    VADriverContextP ctx,   /* in */
4543
    VASurfaceID surface     /* in */
4544
)
4545
{
4546
    VAStatus vaStatus = VA_STATUS_SUCCESS;
4547
    struct i965_driver_data *i965 = i965_driver_data(ctx);
4548
    struct object_image *locked_img = NULL;
4549
    struct object_surface *obj_surface = NULL;
4550
 
4551
    obj_surface = SURFACE(surface);
4552
 
4553
    if (obj_surface == NULL) {
4554
        vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;   // Surface is absent
4555
        return vaStatus;
4556
    }
4557
    if (obj_surface->locked_image_id == VA_INVALID_ID) {
4558
        vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;   // Surface is not locked
4559
        return vaStatus;
4560
    }
4561
 
4562
    locked_img = IMAGE(obj_surface->locked_image_id);
4563
    if (locked_img == NULL || (locked_img->image.image_id == VA_INVALID_ID)) {
4564
        // Work image was deallocated before i965_UnlockSurface()
4565
        vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
4566
        goto error;
4567
    }
4568
 
4569
    vaStatus = i965_UnmapBuffer(
4570
        ctx,
4571
        locked_img->image.buf);
4572
    if (vaStatus != VA_STATUS_SUCCESS) {
4573
        goto error;
4574
    }
4575
 
4576
    vaStatus = i965_DestroyImage(
4577
        ctx,
4578
        locked_img->image.image_id);
4579
    if (vaStatus != VA_STATUS_SUCCESS) {
4580
        goto error;
4581
    }
4582
 
4583
    locked_img->image.image_id = VA_INVALID_ID;
4584
 
4585
 error:
4586
    obj_surface->locked_image_id = VA_INVALID_ID;
4587
 
4588
    return vaStatus;
4589
}
4590
 
4591
static VAStatus
4592
i965_GetSurfaceAttributes(
4593
    VADriverContextP ctx,
4594
    VAConfigID config,
4595
    VASurfaceAttrib *attrib_list,
4596
    unsigned int num_attribs
4597
    )
4598
{
4599
    VAStatus vaStatus = VA_STATUS_SUCCESS;
4600
    struct i965_driver_data *i965 = i965_driver_data(ctx);
4601
    struct object_config *obj_config;
4602
    int i;
4603
 
4604
    if (config == VA_INVALID_ID)
4605
        return VA_STATUS_ERROR_INVALID_CONFIG;
4606
 
4607
    obj_config = CONFIG(config);
4608
 
4609
    if (obj_config == NULL)
4610
        return VA_STATUS_ERROR_INVALID_CONFIG;
4611
 
4612
    if (attrib_list == NULL || num_attribs == 0)
4613
        return VA_STATUS_ERROR_INVALID_PARAMETER;
4614
 
4615
    for (i = 0; i < num_attribs; i++) {
4616
        switch (attrib_list[i].type) {
4617
        case VASurfaceAttribPixelFormat:
4618
            attrib_list[i].value.type = VAGenericValueTypeInteger;
4619
            attrib_list[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4620
 
4621
            if (attrib_list[i].value.value.i == 0) {
4622
                if (IS_G4X(i965->intel.device_info)) {
4623
                    if (obj_config->profile == VAProfileMPEG2Simple ||
4624
                        obj_config->profile == VAProfileMPEG2Main) {
4625
                        attrib_list[i].value.value.i = VA_FOURCC_I420;
4626
                    } else {
4627
                        assert(0);
4628
                        attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4629
                    }
4630
                } else if (IS_IRONLAKE(i965->intel.device_info)) {
4631
                    if (obj_config->profile == VAProfileMPEG2Simple ||
4632
                        obj_config->profile == VAProfileMPEG2Main) {
4633
                        attrib_list[i].value.value.i = VA_FOURCC_I420;
4634
                    } else if (obj_config->profile == VAProfileH264ConstrainedBaseline ||
4635
                               obj_config->profile == VAProfileH264Main ||
4636
                               obj_config->profile == VAProfileH264High) {
4637
                        attrib_list[i].value.value.i = VA_FOURCC_NV12;
4638
                    } else if (obj_config->profile == VAProfileNone) {
4639
                        attrib_list[i].value.value.i = VA_FOURCC_NV12;
4640
                    } else {
4641
                        assert(0);
4642
                        attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4643
                    }
4644
                } else if (IS_GEN6(i965->intel.device_info)) {
4645
                    attrib_list[i].value.value.i = VA_FOURCC_NV12;
4646
                } else if (IS_GEN7(i965->intel.device_info) ||
4647
                           IS_GEN8(i965->intel.device_info)) {
4648
                    if (obj_config->profile == VAProfileJPEGBaseline)
4649
                        attrib_list[i].value.value.i = 0; /* internal format */
4650
                    else
4651
                        attrib_list[i].value.value.i = VA_FOURCC_NV12;
4652
                }
4653
            } else {
4654
                if (IS_G4X(i965->intel.device_info)) {
4655
                    if (obj_config->profile == VAProfileMPEG2Simple ||
4656
                        obj_config->profile == VAProfileMPEG2Main) {
4657
                        if (attrib_list[i].value.value.i != VA_FOURCC_I420) {
4658
                            attrib_list[i].value.value.i = 0;
4659
                            attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4660
                        }
4661
                    } else {
4662
                        assert(0);
4663
                        attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4664
                    }
4665
                } else if (IS_IRONLAKE(i965->intel.device_info)) {
4666
                    if (obj_config->profile == VAProfileMPEG2Simple ||
4667
                        obj_config->profile == VAProfileMPEG2Main) {
4668
                        if (attrib_list[i].value.value.i != VA_FOURCC_I420) {
4669
                            attrib_list[i].value.value.i = 0;
4670
                            attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4671
                        }
4672
                    } else if (obj_config->profile == VAProfileH264ConstrainedBaseline ||
4673
                               obj_config->profile == VAProfileH264Main ||
4674
                               obj_config->profile == VAProfileH264High) {
4675
                        if (attrib_list[i].value.value.i != VA_FOURCC_NV12) {
4676
                            attrib_list[i].value.value.i = 0;
4677
                            attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4678
                        }
4679
                    } else if (obj_config->profile == VAProfileNone) {
4680
                        switch (attrib_list[i].value.value.i) {
4681
                        case VA_FOURCC_NV12:
4682
                        case VA_FOURCC_I420:
4683
                        case VA_FOURCC_YV12:
4684
                        case VA_FOURCC_YUY2:
4685
                        case VA_FOURCC_BGRA:
4686
                        case VA_FOURCC_BGRX:
4687
                        case VA_FOURCC_RGBX:
4688
                        case VA_FOURCC_RGBA:
4689
                            break;
4690
                        default:
4691
                            attrib_list[i].value.value.i = 0;
4692
                            attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4693
                            break;
4694
                        }
4695
                    } else {
4696
                        assert(0);
4697
                        attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4698
                    }
4699
                } else if (IS_GEN6(i965->intel.device_info)) {
4700
                    if (obj_config->entrypoint == VAEntrypointEncSlice ||
4701
                        obj_config->entrypoint == VAEntrypointVideoProc) {
4702
                        switch (attrib_list[i].value.value.i) {
4703
                        case VA_FOURCC_NV12:
4704
                        case VA_FOURCC_I420:
4705
                        case VA_FOURCC_YV12:
4706
                        case VA_FOURCC_YUY2:
4707
                        case VA_FOURCC_BGRA:
4708
                        case VA_FOURCC_BGRX:
4709
                        case VA_FOURCC_RGBX:
4710
                        case VA_FOURCC_RGBA:
4711
                            break;
4712
                        default:
4713
                            attrib_list[i].value.value.i = 0;
4714
                            attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4715
                            break;
4716
                        }
4717
                    } else {
4718
                        if (attrib_list[i].value.value.i != VA_FOURCC_NV12) {
4719
                            attrib_list[i].value.value.i = 0;
4720
                            attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4721
                        }
4722
                    }
4723
                } else if (IS_GEN7(i965->intel.device_info) ||
4724
                           IS_GEN8(i965->intel.device_info)) {
4725
                    if (obj_config->entrypoint == VAEntrypointEncSlice ||
4726
                        obj_config->entrypoint == VAEntrypointVideoProc) {
4727
                        switch (attrib_list[i].value.value.i) {
4728
                        case VA_FOURCC_NV12:
4729
                        case VA_FOURCC_I420:
4730
                        case VA_FOURCC_YV12:
4731
                            break;
4732
                        default:
4733
                            attrib_list[i].value.value.i = 0;
4734
                            attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4735
                            break;
4736
                        }
4737
                    } else {
4738
                        if (obj_config->profile == VAProfileJPEGBaseline) {
4739
                            attrib_list[i].value.value.i = 0;   /* JPEG decoding always uses an internal format */
4740
                            attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4741
                        } else {
4742
                            if (attrib_list[i].value.value.i != VA_FOURCC_NV12) {
4743
                                attrib_list[i].value.value.i = 0;
4744
                                attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4745
                            }
4746
                        }
4747
                    }
4748
                }
4749
            }
4750
 
4751
            break;
4752
        case VASurfaceAttribMinWidth:
4753
            /* FIXME: add support for it later */
4754
            attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4755
            break;
4756
        case VASurfaceAttribMaxWidth:
4757
            attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4758
            break;
4759
        case VASurfaceAttribMinHeight:
4760
            attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4761
            break;
4762
        case VASurfaceAttribMaxHeight:
4763
            attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4764
            break;
4765
        default:
4766
            attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4767
            break;
4768
        }
4769
    }
4770
 
4771
    return vaStatus;
4772
}
4773
 
4774
static VAStatus
4775
i965_QuerySurfaceAttributes(VADriverContextP ctx,
4776
                            VAConfigID config,
4777
                            VASurfaceAttrib *attrib_list,
4778
                            unsigned int *num_attribs)
4779
{
4780
    VAStatus vaStatus = VA_STATUS_SUCCESS;
4781
    struct i965_driver_data *i965 = i965_driver_data(ctx);
4782
    struct object_config *obj_config;
4783
    int i = 0;
4784
    VASurfaceAttrib *attribs = NULL;
4785
 
4786
    if (config == VA_INVALID_ID)
4787
        return VA_STATUS_ERROR_INVALID_CONFIG;
4788
 
4789
    obj_config = CONFIG(config);
4790
 
4791
    if (obj_config == NULL)
4792
        return VA_STATUS_ERROR_INVALID_CONFIG;
4793
 
4794
    if (!attrib_list && !num_attribs)
4795
        return VA_STATUS_ERROR_INVALID_PARAMETER;
4796
 
4797
    if (attrib_list == NULL) {
4798
        *num_attribs = I965_MAX_SURFACE_ATTRIBUTES;
4799
        return VA_STATUS_SUCCESS;
4800
    }
4801
 
4802
    attribs = malloc(I965_MAX_SURFACE_ATTRIBUTES *sizeof(*attribs));
4803
 
4804
    if (attribs == NULL)
4805
        return VA_STATUS_ERROR_ALLOCATION_FAILED;
4806
 
4807
    if (IS_G4X(i965->intel.device_info)) {
4808
        if (obj_config->profile == VAProfileMPEG2Simple ||
4809
            obj_config->profile == VAProfileMPEG2Main) {
4810
            attribs[i].type = VASurfaceAttribPixelFormat;
4811
            attribs[i].value.type = VAGenericValueTypeInteger;
4812
            attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4813
            attribs[i].value.value.i = VA_FOURCC_I420;
4814
            i++;
4815
        }
4816
    } else if (IS_IRONLAKE(i965->intel.device_info)) {
4817
        switch (obj_config->profile) {
4818
        case VAProfileMPEG2Simple:
4819
        case VAProfileMPEG2Main:
4820
            attribs[i].type = VASurfaceAttribPixelFormat;
4821
            attribs[i].value.type = VAGenericValueTypeInteger;
4822
            attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4823
            attribs[i].value.value.i = VA_FOURCC_I420;
4824
            i++;
4825
 
4826
            break;
4827
 
4828
        case VAProfileH264ConstrainedBaseline:
4829
        case VAProfileH264Main:
4830
        case VAProfileH264High:
4831
            attribs[i].type = VASurfaceAttribPixelFormat;
4832
            attribs[i].value.type = VAGenericValueTypeInteger;
4833
            attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4834
            attribs[i].value.value.i = VA_FOURCC_NV12;
4835
            i++;
4836
 
4837
        case VAProfileNone:
4838
            attribs[i].type = VASurfaceAttribPixelFormat;
4839
            attribs[i].value.type = VAGenericValueTypeInteger;
4840
            attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4841
            attribs[i].value.value.i = VA_FOURCC_NV12;
4842
            i++;
4843
 
4844
            attribs[i].type = VASurfaceAttribPixelFormat;
4845
            attribs[i].value.type = VAGenericValueTypeInteger;
4846
            attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4847
            attribs[i].value.value.i = VA_FOURCC_I420;
4848
            i++;
4849
 
4850
            break;
4851
 
4852
        default:
4853
            break;
4854
        }
4855
    } else if (IS_GEN6(i965->intel.device_info)) {
4856
        if (obj_config->entrypoint == VAEntrypointVLD) { /* decode */
4857
            attribs[i].type = VASurfaceAttribPixelFormat;
4858
            attribs[i].value.type = VAGenericValueTypeInteger;
4859
            attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4860
            attribs[i].value.value.i = VA_FOURCC_NV12;
4861
            i++;
4862
        } else if (obj_config->entrypoint == VAEntrypointEncSlice ||  /* encode */
4863
                   obj_config->entrypoint == VAEntrypointVideoProc) { /* vpp */
4864
            attribs[i].type = VASurfaceAttribPixelFormat;
4865
            attribs[i].value.type = VAGenericValueTypeInteger;
4866
            attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4867
            attribs[i].value.value.i = VA_FOURCC_NV12;
4868
            i++;
4869
 
4870
            attribs[i].type = VASurfaceAttribPixelFormat;
4871
            attribs[i].value.type = VAGenericValueTypeInteger;
4872
            attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4873
            attribs[i].value.value.i = VA_FOURCC_I420;
4874
            i++;
4875
 
4876
            attribs[i].type = VASurfaceAttribPixelFormat;
4877
            attribs[i].value.type = VAGenericValueTypeInteger;
4878
            attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4879
            attribs[i].value.value.i = VA_FOURCC_YV12;
4880
            i++;
4881
 
4882
            if (obj_config->entrypoint == VAEntrypointVideoProc) {
4883
                attribs[i].type = VASurfaceAttribPixelFormat;
4884
                attribs[i].value.type = VAGenericValueTypeInteger;
4885
                attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4886
                attribs[i].value.value.i = VA_FOURCC_YUY2;
4887
                i++;
4888
 
4889
                attribs[i].type = VASurfaceAttribPixelFormat;
4890
                attribs[i].value.type = VAGenericValueTypeInteger;
4891
                attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4892
                attribs[i].value.value.i = VA_FOURCC_RGBA;
4893
                i++;
4894
 
4895
                attribs[i].type = VASurfaceAttribPixelFormat;
4896
                attribs[i].value.type = VAGenericValueTypeInteger;
4897
                attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4898
                attribs[i].value.value.i = VA_FOURCC_RGBX;
4899
                i++;
4900
            }
4901
        }
4902
    } else if (IS_GEN7(i965->intel.device_info)) {
4903
        if (obj_config->entrypoint == VAEntrypointVLD) { /* decode */
4904
            if (obj_config->profile == VAProfileJPEGBaseline) {
4905
                attribs[i].type = VASurfaceAttribPixelFormat;
4906
                attribs[i].value.type = VAGenericValueTypeInteger;
4907
                attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4908
                attribs[i].value.value.i = VA_FOURCC_IMC3;
4909
                i++;
4910
 
4911
                attribs[i].type = VASurfaceAttribPixelFormat;
4912
                attribs[i].value.type = VAGenericValueTypeInteger;
4913
                attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4914
                attribs[i].value.value.i = VA_FOURCC_IMC1;
4915
                i++;
4916
 
4917
                attribs[i].type = VASurfaceAttribPixelFormat;
4918
                attribs[i].value.type = VAGenericValueTypeInteger;
4919
                attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4920
                attribs[i].value.value.i = VA_FOURCC_Y800;
4921
                i++;
4922
 
4923
                attribs[i].type = VASurfaceAttribPixelFormat;
4924
                attribs[i].value.type = VAGenericValueTypeInteger;
4925
                attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4926
                attribs[i].value.value.i = VA_FOURCC_411P;
4927
                i++;
4928
 
4929
                attribs[i].type = VASurfaceAttribPixelFormat;
4930
                attribs[i].value.type = VAGenericValueTypeInteger;
4931
                attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4932
                attribs[i].value.value.i = VA_FOURCC_422H;
4933
                i++;
4934
 
4935
                attribs[i].type = VASurfaceAttribPixelFormat;
4936
                attribs[i].value.type = VAGenericValueTypeInteger;
4937
                attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4938
                attribs[i].value.value.i = VA_FOURCC_422V;
4939
                i++;
4940
 
4941
                attribs[i].type = VASurfaceAttribPixelFormat;
4942
                attribs[i].value.type = VAGenericValueTypeInteger;
4943
                attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4944
                attribs[i].value.value.i = VA_FOURCC_444P;
4945
                i++;
4946
            } else {
4947
                attribs[i].type = VASurfaceAttribPixelFormat;
4948
                attribs[i].value.type = VAGenericValueTypeInteger;
4949
                attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4950
                attribs[i].value.value.i = VA_FOURCC_NV12;
4951
                i++;
4952
            }
4953
        } else if (obj_config->entrypoint == VAEntrypointEncSlice ||  /* encode */
4954
                   obj_config->entrypoint == VAEntrypointVideoProc) { /* vpp */
4955
            attribs[i].type = VASurfaceAttribPixelFormat;
4956
            attribs[i].value.type = VAGenericValueTypeInteger;
4957
            attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4958
            attribs[i].value.value.i = VA_FOURCC_NV12;
4959
            i++;
4960
 
4961
            attribs[i].type = VASurfaceAttribPixelFormat;
4962
            attribs[i].value.type = VAGenericValueTypeInteger;
4963
            attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4964
            attribs[i].value.value.i = VA_FOURCC_I420;
4965
            i++;
4966
 
4967
            attribs[i].type = VASurfaceAttribPixelFormat;
4968
            attribs[i].value.type = VAGenericValueTypeInteger;
4969
            attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4970
            attribs[i].value.value.i = VA_FOURCC_YV12;
4971
            i++;
4972
 
4973
            attribs[i].type = VASurfaceAttribPixelFormat;
4974
            attribs[i].value.type = VAGenericValueTypeInteger;
4975
            attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4976
            attribs[i].value.value.i = VA_FOURCC_IMC3;
4977
            i++;
4978
 
4979
            if (obj_config->entrypoint == VAEntrypointVideoProc) {
4980
                attribs[i].type = VASurfaceAttribPixelFormat;
4981
                attribs[i].value.type = VAGenericValueTypeInteger;
4982
                attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4983
                attribs[i].value.value.i = VA_FOURCC_YUY2;
4984
                i++;
4985
 
4986
                attribs[i].type = VASurfaceAttribPixelFormat;
4987
                attribs[i].value.type = VAGenericValueTypeInteger;
4988
                attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4989
                attribs[i].value.value.i = VA_FOURCC_RGBA;
4990
                i++;
4991
 
4992
                attribs[i].type = VASurfaceAttribPixelFormat;
4993
                attribs[i].value.type = VAGenericValueTypeInteger;
4994
                attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4995
                attribs[i].value.value.i = VA_FOURCC_RGBX;
4996
                i++;
4997
 
4998
                attribs[i].type = VASurfaceAttribPixelFormat;
4999
                attribs[i].value.type = VAGenericValueTypeInteger;
5000
                attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5001
                attribs[i].value.value.i = VA_FOURCC_YV16;
5002
                i++;
5003
            }
5004
        }
5005
    } else if (IS_GEN8(i965->intel.device_info)) {
5006
        if (obj_config->entrypoint == VAEntrypointVLD) { /* decode */
5007
            if (obj_config->profile == VAProfileJPEGBaseline) {
5008
                attribs[i].type = VASurfaceAttribPixelFormat;
5009
                attribs[i].value.type = VAGenericValueTypeInteger;
5010
                attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5011
                attribs[i].value.value.i = VA_FOURCC_IMC3;
5012
                i++;
5013
 
5014
                attribs[i].type = VASurfaceAttribPixelFormat;
5015
                attribs[i].value.type = VAGenericValueTypeInteger;
5016
                attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5017
                attribs[i].value.value.i = VA_FOURCC_IMC1;
5018
                i++;
5019
 
5020
                attribs[i].type = VASurfaceAttribPixelFormat;
5021
                attribs[i].value.type = VAGenericValueTypeInteger;
5022
                attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5023
                attribs[i].value.value.i = VA_FOURCC_Y800;
5024
                i++;
5025
 
5026
                attribs[i].type = VASurfaceAttribPixelFormat;
5027
                attribs[i].value.type = VAGenericValueTypeInteger;
5028
                attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5029
                attribs[i].value.value.i = VA_FOURCC_411P;
5030
                i++;
5031
 
5032
                attribs[i].type = VASurfaceAttribPixelFormat;
5033
                attribs[i].value.type = VAGenericValueTypeInteger;
5034
                attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5035
                attribs[i].value.value.i = VA_FOURCC_422H;
5036
                i++;
5037
 
5038
                attribs[i].type = VASurfaceAttribPixelFormat;
5039
                attribs[i].value.type = VAGenericValueTypeInteger;
5040
                attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5041
                attribs[i].value.value.i = VA_FOURCC_422V;
5042
                i++;
5043
 
5044
                attribs[i].type = VASurfaceAttribPixelFormat;
5045
                attribs[i].value.type = VAGenericValueTypeInteger;
5046
                attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5047
                attribs[i].value.value.i = VA_FOURCC_444P;
5048
                i++;
5049
            } else {
5050
                attribs[i].type = VASurfaceAttribPixelFormat;
5051
                attribs[i].value.type = VAGenericValueTypeInteger;
5052
                attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5053
                attribs[i].value.value.i = VA_FOURCC_NV12;
5054
                i++;
5055
            }
5056
        } else if (obj_config->entrypoint == VAEntrypointEncSlice ||  /* encode */
5057
                   obj_config->entrypoint == VAEntrypointVideoProc) { /* vpp */
5058
 
5059
            attribs[i].type = VASurfaceAttribPixelFormat;
5060
            attribs[i].value.type = VAGenericValueTypeInteger;
5061
            attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5062
            attribs[i].value.value.i = VA_FOURCC_NV12;
5063
            i++;
5064
 
5065
            attribs[i].type = VASurfaceAttribPixelFormat;
5066
            attribs[i].value.type = VAGenericValueTypeInteger;
5067
            attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5068
            attribs[i].value.value.i = VA_FOURCC_I420;
5069
            i++;
5070
 
5071
            attribs[i].type = VASurfaceAttribPixelFormat;
5072
            attribs[i].value.type = VAGenericValueTypeInteger;
5073
            attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5074
            attribs[i].value.value.i = VA_FOURCC_YV12;
5075
            i++;
5076
 
5077
            attribs[i].type = VASurfaceAttribPixelFormat;
5078
            attribs[i].value.type = VAGenericValueTypeInteger;
5079
            attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5080
            attribs[i].value.value.i = VA_FOURCC_IMC3;
5081
            i++;
5082
 
5083
            if (obj_config->entrypoint == VAEntrypointVideoProc) {
5084
                attribs[i].type = VASurfaceAttribPixelFormat;
5085
                attribs[i].value.type = VAGenericValueTypeInteger;
5086
                attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5087
                attribs[i].value.value.i = VA_FOURCC_YUY2;
5088
                i++;
5089
 
5090
                attribs[i].type = VASurfaceAttribPixelFormat;
5091
                attribs[i].value.type = VAGenericValueTypeInteger;
5092
                attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5093
                attribs[i].value.value.i = VA_FOURCC_RGBA;
5094
                i++;
5095
 
5096
                attribs[i].type = VASurfaceAttribPixelFormat;
5097
                attribs[i].value.type = VAGenericValueTypeInteger;
5098
                attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5099
                attribs[i].value.value.i = VA_FOURCC_RGBX;
5100
                i++;
5101
 
5102
                attribs[i].type = VASurfaceAttribPixelFormat;
5103
                attribs[i].value.type = VAGenericValueTypeInteger;
5104
                attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5105
                attribs[i].value.value.i = VA_FOURCC_BGRA;
5106
                i++;
5107
 
5108
                attribs[i].type = VASurfaceAttribPixelFormat;
5109
                attribs[i].value.type = VAGenericValueTypeInteger;
5110
                attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5111
                attribs[i].value.value.i = VA_FOURCC_BGRX;
5112
                i++;
5113
 
5114
                attribs[i].type = VASurfaceAttribPixelFormat;
5115
                attribs[i].value.type = VAGenericValueTypeInteger;
5116
                attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5117
                attribs[i].value.value.i = VA_FOURCC_YV16;
5118
                i++;
5119
            }
5120
        }
5121
    }
5122
 
5123
    attribs[i].type = VASurfaceAttribMemoryType;
5124
    attribs[i].value.type = VAGenericValueTypeInteger;
5125
    attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5126
    attribs[i].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA |
5127
        VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM |
5128
        VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME;
5129
    i++;
5130
 
5131
    attribs[i].type = VASurfaceAttribExternalBufferDescriptor;
5132
    attribs[i].value.type = VAGenericValueTypePointer;
5133
    attribs[i].flags = VA_SURFACE_ATTRIB_SETTABLE;
5134
    attribs[i].value.value.p = NULL; /* ignore */
5135
    i++;
5136
 
5137
    if (i > *num_attribs) {
5138
        *num_attribs = i;
5139
        free(attribs);
5140
        return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
5141
    }
5142
 
5143
    *num_attribs = i;
5144
    memcpy(attrib_list, attribs, i * sizeof(*attribs));
5145
    free(attribs);
5146
 
5147
    return vaStatus;
5148
}
5149
 
5150
/* Acquires buffer handle for external API usage (internal implementation) */
5151
static VAStatus
5152
i965_acquire_buffer_handle(struct object_buffer *obj_buffer,
5153
    uint32_t mem_type, VABufferInfo *out_buf_info)
5154
{
5155
    struct buffer_store *buffer_store;
5156
 
5157
    buffer_store = obj_buffer->buffer_store;
5158
    if (!buffer_store || !buffer_store->bo)
5159
        return VA_STATUS_ERROR_INVALID_BUFFER;
5160
 
5161
    /* Synchronization point */
5162
    drm_intel_bo_wait_rendering(buffer_store->bo);
5163
 
5164
    if (obj_buffer->export_refcount > 0) {
5165
        if (obj_buffer->export_state.mem_type != mem_type)
5166
            return VA_STATUS_ERROR_INVALID_PARAMETER;
5167
    }
5168
    else {
5169
        VABufferInfo * const buf_info = &obj_buffer->export_state;
5170
 
5171
        switch (mem_type) {
5172
        case VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM: {
5173
            uint32_t name;
5174
            if (drm_intel_bo_flink(buffer_store->bo, &name) != 0)
5175
                return VA_STATUS_ERROR_INVALID_BUFFER;
5176
            buf_info->handle = name;
5177
            break;
5178
        }
5179
        case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: {
6139 serge 5180
            int fd = -1;
5361 serge 5181
//            if (drm_intel_bo_gem_export_to_prime(buffer_store->bo, &fd) != 0)
5182
//                return VA_STATUS_ERROR_INVALID_BUFFER;
5183
            buf_info->handle = (intptr_t)fd;
5184
            break;
5185
        }
5186
        }
5187
 
5188
        buf_info->type = obj_buffer->type;
5189
        buf_info->mem_type = mem_type;
5190
        buf_info->mem_size =
5191
            obj_buffer->num_elements * obj_buffer->size_element;
5192
    }
5193
 
5194
    obj_buffer->export_refcount++;
5195
    *out_buf_info = obj_buffer->export_state;
5196
    return VA_STATUS_SUCCESS;
5197
}
5198
 
5199
/* Releases buffer handle after usage (internal implementation) */
5200
static VAStatus
5201
i965_release_buffer_handle(struct object_buffer *obj_buffer)
5202
{
5203
    if (obj_buffer->export_refcount == 0)
5204
        return VA_STATUS_ERROR_INVALID_BUFFER;
5205
 
5206
    if (--obj_buffer->export_refcount == 0) {
5207
        VABufferInfo * const buf_info = &obj_buffer->export_state;
5208
 
5209
        switch (buf_info->mem_type) {
5210
        case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: {
5211
            close((intptr_t)buf_info->handle);
5212
            break;
5213
        }
5214
        }
5215
        buf_info->mem_type = 0;
5216
    }
5217
    return VA_STATUS_SUCCESS;
5218
}
5219
 
5220
/** Acquires buffer handle for external API usage */
5221
static VAStatus
5222
i965_AcquireBufferHandle(VADriverContextP ctx, VABufferID buf_id,
5223
    VABufferInfo *buf_info)
5224
{
5225
    struct i965_driver_data * const i965 = i965_driver_data(ctx);
5226
    struct object_buffer * const obj_buffer = BUFFER(buf_id);
5227
    uint32_t i, mem_type;
5228
 
5229
    /* List of supported memory types, in preferred order */
5230
    static const uint32_t mem_types[] = {
5231
        VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME,
5232
        VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM,
5233
 
5234
    };
5235
 
5236
    if (!obj_buffer)
5237
        return VA_STATUS_ERROR_INVALID_BUFFER;
5238
    /* XXX: only VA surface|image like buffers are supported for now */
5239
    if (obj_buffer->type != VAImageBufferType)
5240
        return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
5241
 
5242
    if (!buf_info)
5243
        return VA_STATUS_ERROR_INVALID_PARAMETER;
5244
 
5245
    if (!buf_info->mem_type)
5246
        mem_type = mem_types[0];
5247
    else {
5248
        mem_type = 0;
5249
        for (i = 0; mem_types[i] != 0; i++) {
5250
            if (buf_info->mem_type & mem_types[i]) {
5251
                mem_type = buf_info->mem_type;
5252
                break;
5253
            }
5254
        }
5255
        if (!mem_type)
5256
            return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
5257
    }
5258
    return i965_acquire_buffer_handle(obj_buffer, mem_type, buf_info);
5259
}
5260
 
5261
/** Releases buffer handle after usage from external API */
5262
static VAStatus
5263
i965_ReleaseBufferHandle(VADriverContextP ctx, VABufferID buf_id)
5264
{
5265
    struct i965_driver_data * const i965 = i965_driver_data(ctx);
5266
    struct object_buffer * const obj_buffer = BUFFER(buf_id);
5267
 
5268
    if (!obj_buffer)
5269
        return VA_STATUS_ERROR_INVALID_BUFFER;
5270
 
5271
    return i965_release_buffer_handle(obj_buffer);
5272
}
5273
 
5274
static int
5275
i965_os_has_ring_support(VADriverContextP ctx,
5276
                         int ring)
5277
{
5278
    struct i965_driver_data *const i965 = i965_driver_data(ctx);
5279
 
5280
    switch (ring) {
5281
    case I965_RING_BSD:
5282
        return i965->intel.has_bsd;
5283
 
5284
    case I965_RING_BLT:
5285
        return i965->intel.has_blt;
5286
 
5287
    case I965_RING_VEBOX:
5288
        return i965->intel.has_vebox;
5289
 
5290
    case I965_RING_NULL:
5291
        return 1; /* Always support */
5292
 
5293
    default:
5294
        /* should never get here */
5295
        assert(0);
5296
        break;
5297
    }
5298
 
5299
    return 0;
5300
}
5301
 
5302
/*
5303
 * Query video processing pipeline
5304
 */
5305
VAStatus i965_QueryVideoProcFilters(
5306
    VADriverContextP    ctx,
5307
    VAContextID         context,
5308
    VAProcFilterType   *filters,
5309
    unsigned int       *num_filters
5310
    )
5311
{
5312
    struct i965_driver_data *const i965 = i965_driver_data(ctx);
5313
    unsigned int i = 0, num = 0;
5314
 
5315
    if (!num_filters  || !filters)
5316
        return VA_STATUS_ERROR_INVALID_PARAMETER;
5317
 
5318
    for (i = 0; i < i965->codec_info->num_filters; i++) {
5319
        if (i965_os_has_ring_support(ctx, i965->codec_info->filters[i].ring)) {
5320
            if (num == *num_filters) {
5321
                *num_filters = i965->codec_info->num_filters;
5322
 
5323
                return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
5324
            }
5325
 
5326
            filters[num++] = i965->codec_info->filters[i].type;
5327
        }
5328
    }
5329
 
5330
    *num_filters = num;
5331
 
5332
    return VA_STATUS_SUCCESS;
5333
}
5334
 
5335
VAStatus i965_QueryVideoProcFilterCaps(
5336
    VADriverContextP    ctx,
5337
    VAContextID         context,
5338
    VAProcFilterType    type,
5339
    void               *filter_caps,
5340
    unsigned int       *num_filter_caps
5341
    )
5342
{
5343
    unsigned int i = 0;
5344
    struct i965_driver_data *const i965 = i965_driver_data(ctx);
5345
 
5346
    if (!filter_caps || !num_filter_caps)
5347
        return VA_STATUS_ERROR_INVALID_PARAMETER;
5348
 
5349
    for (i = 0; i < i965->codec_info->num_filters; i++) {
5350
        if (type == i965->codec_info->filters[i].type &&
5351
            i965_os_has_ring_support(ctx, i965->codec_info->filters[i].ring))
5352
            break;
5353
    }
5354
 
5355
    if (i == i965->codec_info->num_filters)
5356
        return VA_STATUS_ERROR_UNSUPPORTED_FILTER;
5357
 
5358
    i = 0;
5359
 
5360
    switch (type) {
5361
    case VAProcFilterNoiseReduction:
5362
    case VAProcFilterSharpening:
5363
        {
5364
            VAProcFilterCap *cap = filter_caps;
5365
 
5366
            if (*num_filter_caps < 1) {
5367
                *num_filter_caps = 1;
5368
                return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
5369
            }
5370
 
5371
            cap->range.min_value = 0.0;
5372
            cap->range.max_value = 1.0;
5373
            cap->range.default_value = 0.5;
5374
            cap->range.step = 0.03125; /* 1.0 / 32 */
5375
            i++;
5376
        }
5377
 
5378
        break;
5379
 
5380
    case VAProcFilterDeinterlacing:
5381
        {
5382
            VAProcFilterCapDeinterlacing *cap = filter_caps;
5383
 
5384
            if (*num_filter_caps < VAProcDeinterlacingCount) {
5385
                *num_filter_caps = VAProcDeinterlacingCount;
5386
                return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
5387
            }
5388
 
5389
            cap->type = VAProcDeinterlacingBob;
5390
            i++;
5391
            cap++;
5392
 
5393
 
5394
            if (i965->codec_info->has_di_motion_adptive) {
5395
                cap->type = VAProcDeinterlacingMotionAdaptive;
5396
                i++;
5397
                cap++;
5398
            }
5399
 
5400
            if (i965->codec_info->has_di_motion_compensated) {
5401
                cap->type = VAProcDeinterlacingMotionCompensated;
5402
                i++;
5403
                cap++;
5404
            }
5405
       }
5406
 
5407
        break;
5408
 
5409
    case VAProcFilterColorBalance:
5410
        {
5411
            VAProcFilterCapColorBalance *cap = filter_caps;
5412
 
5413
            if (*num_filter_caps < VAProcColorBalanceCount) {
5414
                *num_filter_caps = VAProcColorBalanceCount;
5415
                return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
5416
            }
5417
 
5418
            cap->type = VAProcColorBalanceHue;
5419
            cap->range.min_value = -180.0;
5420
            cap->range.max_value = 180.0;
5421
            cap->range.default_value = 0.0;
5422
            cap->range.step = 1.0;
5423
            i++;
5424
            cap++;
5425
 
5426
            cap->type = VAProcColorBalanceSaturation;
5427
            cap->range.min_value = 0.0;
5428
            cap->range.max_value = 10.0;
5429
            cap->range.default_value = 1.0;
5430
            cap->range.step = 0.1;
5431
            i++;
5432
            cap++;
5433
 
5434
            cap->type = VAProcColorBalanceBrightness;
5435
            cap->range.min_value = -100.0;
5436
            cap->range.max_value = 100.0;
5437
            cap->range.default_value = 0.0;
5438
            cap->range.step = 1.0;
5439
            i++;
5440
            cap++;
5441
 
5442
            cap->type = VAProcColorBalanceContrast;
5443
            cap->range.min_value = 0.0;
5444
            cap->range.max_value = 10.0;
5445
            cap->range.default_value = 1.0;
5446
            cap->range.step = 0.1;
5447
            i++;
5448
            cap++;
5449
        }
5450
 
5451
        break;
5452
 
5453
    default:
5454
 
5455
        break;
5456
    }
5457
 
5458
    *num_filter_caps = i;
5459
 
5460
    return VA_STATUS_SUCCESS;
5461
}
5462
 
5463
static VAProcColorStandardType vpp_input_color_standards[VAProcColorStandardCount] = {
5464
    VAProcColorStandardBT601,
5465
};
5466
 
5467
static VAProcColorStandardType vpp_output_color_standards[VAProcColorStandardCount] = {
5468
    VAProcColorStandardBT601,
5469
};
5470
 
5471
VAStatus i965_QueryVideoProcPipelineCaps(
5472
    VADriverContextP ctx,
5473
    VAContextID context,
5474
    VABufferID *filters,
5475
    unsigned int num_filters,
5476
    VAProcPipelineCaps *pipeline_cap     /* out */
5477
    )
5478
{
5479
    struct i965_driver_data * const i965 = i965_driver_data(ctx);
5480
    unsigned int i = 0;
5481
 
5482
    pipeline_cap->pipeline_flags = 0;
5483
    pipeline_cap->filter_flags = 0;
5484
    pipeline_cap->num_forward_references = 0;
5485
    pipeline_cap->num_backward_references = 0;
5486
    pipeline_cap->num_input_color_standards = 1;
5487
    pipeline_cap->input_color_standards = vpp_input_color_standards;
5488
    pipeline_cap->num_output_color_standards = 1;
5489
    pipeline_cap->output_color_standards = vpp_output_color_standards;
5490
 
5491
    for (i = 0; i < num_filters; i++) {
5492
        struct object_buffer *obj_buffer = BUFFER(filters[i]);
5493
 
5494
        if (!obj_buffer ||
5495
            !obj_buffer->buffer_store ||
5496
            !obj_buffer->buffer_store->buffer)
5497
            return VA_STATUS_ERROR_INVALID_BUFFER;
5498
 
5499
        VAProcFilterParameterBufferBase *base = (VAProcFilterParameterBufferBase *)obj_buffer->buffer_store->buffer;
5500
 
5501
        if (base->type == VAProcFilterNoiseReduction) {
5502
            VAProcFilterParameterBuffer *denoise = (VAProcFilterParameterBuffer *)base;
5503
            (void)denoise;
5504
        } else if (base->type == VAProcFilterDeinterlacing) {
5505
            VAProcFilterParameterBufferDeinterlacing *deint = (VAProcFilterParameterBufferDeinterlacing *)base;
5506
 
5507
            ASSERT_RET(deint->algorithm == VAProcDeinterlacingBob ||
5508
                   deint->algorithm == VAProcDeinterlacingMotionAdaptive ||
5509
                   deint->algorithm == VAProcDeinterlacingMotionCompensated,
5510
                   VA_STATUS_ERROR_INVALID_PARAMETER);
5511
 
5512
            if (deint->algorithm == VAProcDeinterlacingMotionAdaptive ||
5513
                deint->algorithm == VAProcDeinterlacingMotionCompensated);
5514
                pipeline_cap->num_forward_references++;
5515
        } else if (base->type == VAProcFilterSkinToneEnhancement) {
5516
                VAProcFilterParameterBuffer *stde = (VAProcFilterParameterBuffer *)base;
5517
                (void)stde;
5518
        }
5519
    }
5520
 
5521
    return VA_STATUS_SUCCESS;
5522
}
5523
 
5524
extern struct hw_codec_info *i965_get_codec_info(int devid);
5525
 
5526
static bool
5527
i965_driver_data_init(VADriverContextP ctx)
5528
{
5529
    struct i965_driver_data *i965 = i965_driver_data(ctx);
5530
 
5531
    i965->codec_info = i965_get_codec_info(i965->intel.device_id);
5532
 
5533
    if (!i965->codec_info)
5534
        return false;
5535
 
5536
    if (object_heap_init(&i965->config_heap,
5537
                         sizeof(struct object_config),
5538
                         CONFIG_ID_OFFSET))
5539
        goto err_config_heap;
5540
    if (object_heap_init(&i965->context_heap,
5541
                         sizeof(struct object_context),
5542
                         CONTEXT_ID_OFFSET))
5543
        goto err_context_heap;
5544
 
5545
    if (object_heap_init(&i965->surface_heap,
5546
                         sizeof(struct object_surface),
5547
                         SURFACE_ID_OFFSET))
5548
        goto err_surface_heap;
5549
    if (object_heap_init(&i965->buffer_heap,
5550
                         sizeof(struct object_buffer),
5551
                         BUFFER_ID_OFFSET))
5552
        goto err_buffer_heap;
5553
    if (object_heap_init(&i965->image_heap,
5554
                         sizeof(struct object_image),
5555
                         IMAGE_ID_OFFSET))
5556
        goto err_image_heap;
5557
    if (object_heap_init(&i965->subpic_heap,
5558
                         sizeof(struct object_subpic),
5559
                         SUBPIC_ID_OFFSET))
5560
        goto err_subpic_heap;
5561
 
5562
    i965->batch = intel_batchbuffer_new(&i965->intel, I915_EXEC_RENDER, 0);
5563
    i965->pp_batch = intel_batchbuffer_new(&i965->intel, I915_EXEC_RENDER, 0);
5564
    _i965InitMutex(&i965->render_mutex);
5565
    _i965InitMutex(&i965->pp_mutex);
5566
 
5567
    return true;
5568
 
5569
err_subpic_heap:
5570
    object_heap_destroy(&i965->image_heap);
5571
err_image_heap:
5572
    object_heap_destroy(&i965->buffer_heap);
5573
err_buffer_heap:
5574
    object_heap_destroy(&i965->surface_heap);
5575
err_surface_heap:
5576
    object_heap_destroy(&i965->context_heap);
5577
err_context_heap:
5578
    object_heap_destroy(&i965->config_heap);
5579
err_config_heap:
5580
 
5581
    return false;
5582
}
5583
 
5584
static void
5585
i965_driver_data_terminate(VADriverContextP ctx)
5586
{
5587
    struct i965_driver_data *i965 = i965_driver_data(ctx);
5588
 
5589
    _i965DestroyMutex(&i965->pp_mutex);
5590
    _i965DestroyMutex(&i965->render_mutex);
5591
 
5592
    if (i965->batch)
5593
        intel_batchbuffer_free(i965->batch);
5594
 
5595
    if (i965->pp_batch)
5596
        intel_batchbuffer_free(i965->pp_batch);
5597
 
5598
    i965_destroy_heap(&i965->subpic_heap, i965_destroy_subpic);
5599
    i965_destroy_heap(&i965->image_heap, i965_destroy_image);
5600
    i965_destroy_heap(&i965->buffer_heap, i965_destroy_buffer);
5601
    i965_destroy_heap(&i965->surface_heap, i965_destroy_surface);
5602
    i965_destroy_heap(&i965->context_heap, i965_destroy_context);
5603
    i965_destroy_heap(&i965->config_heap, i965_destroy_config);
5604
}
5605
 
5606
struct {
5607
    bool (*init)(VADriverContextP ctx);
5608
    void (*terminate)(VADriverContextP ctx);
5609
    int display_type;
5610
} i965_sub_ops[] =  {
5611
    {
5612
        intel_driver_init,
5613
        intel_driver_terminate,
5614
        0,
5615
    },
5616
 
5617
    {
5618
        i965_driver_data_init,
5619
        i965_driver_data_terminate,
5620
        0,
5621
    },
5622
 
5623
    {
5624
        i965_display_attributes_init,
5625
        i965_display_attributes_terminate,
5626
        0,
5627
    },
5628
 
5629
    {
5630
        i965_post_processing_init,
5631
        i965_post_processing_terminate,
5632
        0,
5633
    },
5634
 
5635
    {
5636
        i965_render_init,
5637
        i965_render_terminate,
5638
        0,
5639
    },
5640
 
5641
#ifdef HAVE_VA_WAYLAND
5642
    {
5643
        i965_output_wayland_init,
5644
        i965_output_wayland_terminate,
5645
        VA_DISPLAY_WAYLAND,
5646
    },
5647
#endif
5648
 
5649
#ifdef HAVE_VA_X11
5650
    {
5651
        i965_output_dri_init,
5652
        i965_output_dri_terminate,
5653
        VA_DISPLAY_X11,
5654
    },
5655
#endif
5656
};
5657
 
5658
static VAStatus
5659
i965_Init(VADriverContextP ctx)
5660
{
5661
    struct i965_driver_data *i965 = i965_driver_data(ctx);
5662
    int i;
5663
    const char *chipset;
5664
 
5665
    for (i = 0; i < ARRAY_ELEMS(i965_sub_ops); i++) {
5666
        if ((i965_sub_ops[i].display_type == 0 ||
5667
             i965_sub_ops[i].display_type == (ctx->display_type & VA_DISPLAY_MAJOR_MASK)) &&
5668
            !i965_sub_ops[i].init(ctx))
5669
            break;
5670
    }
5671
 
5672
    if (i965->codec_info->preinit_hw_codec)
5673
        i965->codec_info->preinit_hw_codec(ctx, i965->codec_info);
5674
 
5675
    if (i == ARRAY_ELEMS(i965_sub_ops)) {
5676
        switch (i965->intel.device_id) {
5677
#undef CHIPSET
5678
#define CHIPSET(id, family, dev, str) case id: chipset = str; break;
5679
#include "i965_pciids.h"
5680
        default:
5681
            chipset = "Unknown Intel Chipset";
5682
            break;
5683
        }
5684
 
5685
        sprintf(i965->va_vendor, "%s %s driver for %s - %d.%d.%d",
5686
                INTEL_STR_DRIVER_VENDOR,
5687
                INTEL_STR_DRIVER_NAME,
5688
                chipset,
5689
                INTEL_DRIVER_MAJOR_VERSION,
5690
                INTEL_DRIVER_MINOR_VERSION,
5691
                INTEL_DRIVER_MICRO_VERSION);
5692
 
5693
        if (INTEL_DRIVER_PRE_VERSION > 0) {
5694
            const int len = strlen(i965->va_vendor);
5695
            sprintf(&i965->va_vendor[len], ".pre%d", INTEL_DRIVER_PRE_VERSION);
5696
        }
5697
 
5698
        i965->current_context_id = VA_INVALID_ID;
5699
 
5700
        return VA_STATUS_SUCCESS;
5701
    } else {
5702
        i--;
5703
 
5704
        for (; i >= 0; i--) {
5705
            if (i965_sub_ops[i].display_type == 0 ||
5706
                i965_sub_ops[i].display_type == (ctx->display_type & VA_DISPLAY_MAJOR_MASK)) {
5707
                i965_sub_ops[i].terminate(ctx);
5708
            }
5709
        }
5710
 
5711
        return VA_STATUS_ERROR_UNKNOWN;
5712
    }
5713
}
5714
 
5715
VAStatus
5716
i965_Terminate(VADriverContextP ctx)
5717
{
5718
    struct i965_driver_data *i965 = i965_driver_data(ctx);
5719
    int i;
5720
 
5721
    if (i965) {
5722
        for (i = ARRAY_ELEMS(i965_sub_ops); i > 0; i--)
5723
            if (i965_sub_ops[i - 1].display_type == 0 ||
5724
                i965_sub_ops[i - 1].display_type == (ctx->display_type & VA_DISPLAY_MAJOR_MASK)) {
5725
                i965_sub_ops[i - 1].terminate(ctx);
5726
            }
5727
 
5728
        free(i965);
5729
        ctx->pDriverData = NULL;
5730
    }
5731
 
5732
    return VA_STATUS_SUCCESS;
5733
}
5734
 
5735
VAStatus DLL_EXPORT
5736
VA_DRIVER_INIT_FUNC(VADriverContextP ctx);
5737
 
5738
VAStatus
5739
VA_DRIVER_INIT_FUNC(  VADriverContextP ctx )
5740
{
5741
    struct VADriverVTable * const vtable = ctx->vtable;
5742
    struct VADriverVTableVPP * const vtable_vpp = ctx->vtable_vpp;
5743
 
5744
    struct i965_driver_data *i965;
5745
    VAStatus ret = VA_STATUS_ERROR_UNKNOWN;
5746
 
5747
    ctx->version_major = VA_MAJOR_VERSION;
5748
    ctx->version_minor = VA_MINOR_VERSION;
5749
    ctx->max_profiles = I965_MAX_PROFILES;
5750
    ctx->max_entrypoints = I965_MAX_ENTRYPOINTS;
5751
    ctx->max_attributes = I965_MAX_CONFIG_ATTRIBUTES;
5752
    ctx->max_image_formats = I965_MAX_IMAGE_FORMATS;
5753
    ctx->max_subpic_formats = I965_MAX_SUBPIC_FORMATS;
5754
    ctx->max_display_attributes = 1 + ARRAY_ELEMS(i965_display_attributes);
5755
 
5756
    vtable->vaTerminate = i965_Terminate;
5757
    vtable->vaQueryConfigEntrypoints = i965_QueryConfigEntrypoints;
5758
    vtable->vaQueryConfigProfiles = i965_QueryConfigProfiles;
5759
    vtable->vaQueryConfigAttributes = i965_QueryConfigAttributes;
5760
    vtable->vaCreateConfig = i965_CreateConfig;
5761
    vtable->vaDestroyConfig = i965_DestroyConfig;
5762
    vtable->vaGetConfigAttributes = i965_GetConfigAttributes;
5763
    vtable->vaCreateSurfaces = i965_CreateSurfaces;
5764
    vtable->vaDestroySurfaces = i965_DestroySurfaces;
5765
    vtable->vaCreateContext = i965_CreateContext;
5766
    vtable->vaDestroyContext = i965_DestroyContext;
5767
    vtable->vaCreateBuffer = i965_CreateBuffer;
5768
    vtable->vaBufferSetNumElements = i965_BufferSetNumElements;
5769
    vtable->vaMapBuffer = i965_MapBuffer;
5770
    vtable->vaUnmapBuffer = i965_UnmapBuffer;
5771
    vtable->vaDestroyBuffer = i965_DestroyBuffer;
5772
    vtable->vaBeginPicture = i965_BeginPicture;
5773
    vtable->vaRenderPicture = i965_RenderPicture;
5774
    vtable->vaEndPicture = i965_EndPicture;
5775
    vtable->vaSyncSurface = i965_SyncSurface;
5776
    vtable->vaQuerySurfaceStatus = i965_QuerySurfaceStatus;
5777
    vtable->vaPutSurface = i965_PutSurface;
5778
    vtable->vaQueryImageFormats = i965_QueryImageFormats;
5779
    vtable->vaCreateImage = i965_CreateImage;
5780
    vtable->vaDeriveImage = i965_DeriveImage;
5781
    vtable->vaDestroyImage = i965_DestroyImage;
5782
    vtable->vaSetImagePalette = i965_SetImagePalette;
5783
    vtable->vaGetImage = i965_GetImage;
5784
    vtable->vaPutImage = i965_PutImage;
5785
    vtable->vaQuerySubpictureFormats = i965_QuerySubpictureFormats;
5786
    vtable->vaCreateSubpicture = i965_CreateSubpicture;
5787
    vtable->vaDestroySubpicture = i965_DestroySubpicture;
5788
    vtable->vaSetSubpictureImage = i965_SetSubpictureImage;
5789
    vtable->vaSetSubpictureChromakey = i965_SetSubpictureChromakey;
5790
    vtable->vaSetSubpictureGlobalAlpha = i965_SetSubpictureGlobalAlpha;
5791
    vtable->vaAssociateSubpicture = i965_AssociateSubpicture;
5792
    vtable->vaDeassociateSubpicture = i965_DeassociateSubpicture;
5793
    vtable->vaQueryDisplayAttributes = i965_QueryDisplayAttributes;
5794
    vtable->vaGetDisplayAttributes = i965_GetDisplayAttributes;
5795
    vtable->vaSetDisplayAttributes = i965_SetDisplayAttributes;
5796
    vtable->vaBufferInfo = i965_BufferInfo;
5797
    vtable->vaLockSurface = i965_LockSurface;
5798
    vtable->vaUnlockSurface = i965_UnlockSurface;
5799
    vtable->vaGetSurfaceAttributes = i965_GetSurfaceAttributes;
5800
    vtable->vaQuerySurfaceAttributes = i965_QuerySurfaceAttributes;
5801
    vtable->vaCreateSurfaces2 = i965_CreateSurfaces2;
5802
 
5803
    /* 0.36.0 */
5804
    vtable->vaAcquireBufferHandle = i965_AcquireBufferHandle;
5805
    vtable->vaReleaseBufferHandle = i965_ReleaseBufferHandle;
5806
 
5807
    vtable_vpp->vaQueryVideoProcFilters = i965_QueryVideoProcFilters;
5808
    vtable_vpp->vaQueryVideoProcFilterCaps = i965_QueryVideoProcFilterCaps;
5809
    vtable_vpp->vaQueryVideoProcPipelineCaps = i965_QueryVideoProcPipelineCaps;
5810
 
5811
    i965 = (struct i965_driver_data *)calloc(1, sizeof(*i965));
5812
 
5813
    if (i965 == NULL) {
5814
        ctx->pDriverData = NULL;
5815
 
5816
        return VA_STATUS_ERROR_ALLOCATION_FAILED;
5817
    }
5818
 
5819
    ctx->pDriverData = (void *)i965;
5820
    ret = i965_Init(ctx);
5821
 
5822
    if (ret == VA_STATUS_SUCCESS) {
5823
        ctx->str_vendor = i965->va_vendor;
5824
    } else {
5825
        free(i965);
5826
        ctx->pDriverData = NULL;
5827
    }
5828
 
5829
    return ret;
5830
}