Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3769 Serge 1
/*
2
 * Copyright © 2011 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
 *   Li Xiaowei 
26
 */
27
 
28
#include 
29
#include 
30
#include 
31
#include 
32
#include 
33
 
34
#include "intel_batchbuffer.h"
35
#include "intel_driver.h"
36
#include "i965_defines.h"
37
#include "i965_structs.h"
38
#include "gen75_vpp_vebox.h"
39
 
40
#define PI  3.1415926
41
 
42
extern VAStatus
43
i965_CreateSurfaces(VADriverContextP ctx,
44
                    int width,
45
                    int height,
46
                    int format,
47
                    int num_surfaces,
48
                    VASurfaceID *surfaces);
49
 
50
int format_convert(float src, int out_int_bits, int out_frac_bits,int out_sign_flag)
51
{
52
     unsigned char negative_flag = (src < 0.0) ? 1 : 0;
53
     float src_1 = (!negative_flag)? src: -src ;
54
     unsigned int factor = 1 << out_frac_bits;
55
     int output_value = 0;
56
 
57
     unsigned int integer_part = 0;//floor(src_1);
58
     unsigned int fraction_part = ((int)((src_1 - integer_part) * factor)) & (factor - 1) ;
59
 
60
     output_value = (integer_part << out_frac_bits) | fraction_part;
61
 
62
     if(negative_flag)
63
         output_value = (~output_value + 1) & ((1 <<(out_int_bits + out_frac_bits)) -1);
64
 
65
     if(out_sign_flag == 1 && negative_flag)
66
     {
67
          output_value |= negative_flag <<(out_int_bits + out_frac_bits);
68
     }
69
     return output_value;
70
}
71
 
72
void hsw_veb_dndi_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
73
{
74
    unsigned int* p_table ;
75
    /*
76
    VAProcFilterParameterBufferDeinterlacing *di_param =
77
            (VAProcFilterParameterBufferDeinterlacing *) proc_ctx->filter_di;
78
 
79
    VAProcFilterParameterBuffer * dn_param =
80
            (VAProcFilterParameterBuffer *) proc_ctx->filter_dn;
81
    */
82
    p_table = (unsigned int *)proc_ctx->dndi_state_table.ptr;
83
 
84
    *p_table ++ = 0;               // reserved  . w0
85
    *p_table ++ = ( 0   << 24 |    // denoise STAD threshold . w1
86
                    128 << 16 |    // dnmh_history_max
87
 
88
                    8   << 8  |    // dnmh_delta[3:0]
89
 
90
 
91
    *p_table ++ = ( 0  << 30 |    // reserved . w2
92
                    16 << 24 |    // temporal diff th
93
 
94
                    8  << 16 |    // low temporal diff th
95
 
96
 
97
                    64 );         // denoise th for sum of complexity measure
98
 
99
    *p_table ++ = ( 0 << 30  |   // reserved . w3
100
                    4 << 24  |   // good neighbor th[5:0]
101
                    9 << 20  |   // CAT slope minus 1
102
                    5 << 16  |   // SAD Tight in
103
 
104
 
105
                    1 << 8   |   // bne_edge_th[3:0]
106
                    15 );        // block noise estimate noise th
107
 
108
    *p_table ++ = ( 0  << 31  |  // STMM blending constant select. w4
109
                    64 << 24  |  // STMM trc1
110
 
111
 
112
                    2  << 8   |  // VECM_mul
113
                    128 );       // maximum STMM
114
 
115
    *p_table ++ = ( 0  << 24  |  // minumum STMM  . W5
116
 
117
 
118
                    7  << 16  |  // STMM output shift
119
                    128 << 8  |  // SDI threshold
120
                    8 );         // SDI delta
121
 
122
    *p_table ++ = ( 0 << 24  |   // SDI fallback mode 1 T1 constant . W6
123
 
124
 
125
 
126
 
127
    *p_table ++ = ( 32 << 24  |  // FMD #1 vertical difference th . w7
128
                    32 << 16  |  // FMD #2 vertical difference th
129
                    1  << 14  |  // CAT th1
130
                    32 << 8   |  // FMD tear threshold
131
 
132
 
133
 
134
 
135
 
136
 
137
    *p_table ++ = ( 0  << 29  |  // reserved . W8
138
 
139
                    10 << 19  |  // neighborPixel th
140
 
141
 
142
                    25 << 10  |  // MC pixel consistency th
143
 
144
                    10 << 4   |  // SAD THB
145
                    5 );         // SAD THA
146
 
147
    *p_table ++ = ( 0 << 24  |  // reserved
148
 
149
 
150
 
151
 
152
 
153
 
154
}
155
 
156
void hsw_veb_iecp_std_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
157
{
158
    unsigned int *p_table = proc_ctx->iecp_state_table.ptr + 0 ;
159
    /*
160
      VAProcFilterParameterBuffer * std_param =
161
             (VAProcFilterParameterBuffer *) proc_ctx->filter_std;
162
    */
163
    if(!(proc_ctx->filters_mask & VPP_IECP_STD_STE)){
164
        memset(p_table, 0, 29 * 4);
165
    }else{
166
        *p_table ++ = 0x9a6e39f0;
167
        *p_table ++ = 0x400c0000;
168
        *p_table ++ = 0x00001180;
169
        *p_table ++ = 0xfe2f2e00;
170
        *p_table ++ = 0x000000ff;
171
 
172
        *p_table ++ = 0x00140000;
173
        *p_table ++ = 0xd82e0000;
174
        *p_table ++ = 0x8285ecec;
175
        *p_table ++ = 0x00008282;
176
        *p_table ++ = 0x00000000;
177
 
178
        *p_table ++ = 0x02117000;
179
        *p_table ++ = 0xa38fec96;
180
        *p_table ++ = 0x0000c8c8;
181
        *p_table ++ = 0x00000000;
182
        *p_table ++ = 0x01478000;
183
 
184
        *p_table ++ = 0x0007c306;
185
        *p_table ++ = 0x00000000;
186
        *p_table ++ = 0x00000000;
187
        *p_table ++ = 0x1c1bd000;
188
        *p_table ++ = 0x00000000;
189
 
190
        *p_table ++ = 0x00000000;
191
        *p_table ++ = 0x00000000;
192
        *p_table ++ = 0x0007cf80;
193
        *p_table ++ = 0x00000000;
194
        *p_table ++ = 0x00000000;
195
 
196
        *p_table ++ = 0x1c080000;
197
        *p_table ++ = 0x00000000;
198
        *p_table ++ = 0x00000000;
199
        *p_table ++ = 0x00000000;
200
    }
201
}
202
 
203
void hsw_veb_iecp_ace_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
204
{
205
   unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 116);
206
 
207
    if(!(proc_ctx->filters_mask & VPP_IECP_ACE)){
208
        memset(p_table, 0, 13 * 4);
209
    }else{
210
        *p_table ++ = 0x00000068;
211
        *p_table ++ = 0x4c382410;
212
        *p_table ++ = 0x9c887460;
213
        *p_table ++ = 0xebd8c4b0;
214
        *p_table ++ = 0x604c3824;
215
 
216
        *p_table ++ = 0xb09c8874;
217
        *p_table ++ = 0x0000d8c4;
218
        *p_table ++ = 0x00000000;
219
        *p_table ++ = 0x00000000;
220
        *p_table ++ = 0x00000000;
221
 
222
        *p_table ++ = 0x00000000;
223
        *p_table ++ = 0x00000000;
224
        *p_table ++ = 0x00000000;
225
   }
226
}
227
 
228
void hsw_veb_iecp_tcc_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
229
{
230
    unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 168);
231
    /*
232
      VAProcFilterParameterBuffer * tcc_param =
233
              (VAProcFilterParameterBuffer *) proc_ctx->filter_iecp_tcc;
234
   */
235
   if(!(proc_ctx->filters_mask & VPP_IECP_TCC)){
236
        memset(p_table, 0, 11 * 4);
237
    }else{
238
        *p_table ++ = 0x00000000;
239
        *p_table ++ = 0x00000000;
240
        *p_table ++ = 0x1e34cc91;
241
        *p_table ++ = 0x3e3cce91;
242
        *p_table ++ = 0x02e80195;
243
 
244
        *p_table ++ = 0x0197046b;
245
        *p_table ++ = 0x01790174;
246
        *p_table ++ = 0x00000000;
247
        *p_table ++ = 0x00000000;
248
        *p_table ++ = 0x03030000;
249
 
250
        *p_table ++ = 0x009201c0;
251
   }
252
}
253
 
254
void hsw_veb_iecp_pro_amp_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
255
{
256
    unsigned int contrast = 0x80;  //default
257
    int brightness = 0x00;         //default
258
    int cos_c_s    = 256 ;         //default
259
    int sin_c_s    = 0;            //default
260
    unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 212);
261
 
262
    if(!(proc_ctx->filters_mask & VPP_IECP_PRO_AMP)){
263
        memset(p_table, 0, 2 * 4);
264
    }else {
265
        float  tmp_value = 0.0;
266
        float  src_saturation = 1.0;
267
        float  src_hue = 0.0;
268
        float  src_contrast   = 1.0;
269
        /*
270
        float  src_brightness = 0.0;
271
 
272
        VAProcFilterParameterBufferColorBalance * amp_param =
273
        (VAProcFilterParameterBufferColorBalance *) proc_ctx->filter_iecp_amp;
274
        VAProcColorBalanceType attrib = amp_param->attrib;
275
 
276
        if(attrib == VAProcColorBalanceHue) {
277
           src_hue = amp_param->value;         //(-180.0, 180.0)
278
        }else if(attrib == VAProcColorBalanceSaturation) {
279
           src_saturation = amp_param->value; //(0.0, 10.0)
280
        }else if(attrib == VAProcColorBalanceBrightness) {
281
           src_brightness = amp_param->value; // (-100.0, 100.0)
282
           brightness = format_convert(src_brightness, 7, 4, 1);
283
        }else if(attrib == VAProcColorBalanceContrast) {
284
           src_contrast = amp_param->value;  //  (0.0, 10.0)
285
           contrast = format_convert(src_contrast, 4, 7, 0);
286
        }
287
        */
288
        tmp_value = cos(src_hue/180*PI) * src_contrast * src_saturation;
289
        cos_c_s = format_convert(tmp_value, 7, 8, 1);
290
 
291
        tmp_value = sin(src_hue/180*PI) * src_contrast * src_saturation;
292
        sin_c_s = format_convert(tmp_value, 7, 8, 1);
293
 
294
        *p_table ++ = ( 0 << 28 |         //reserved
295
                        contrast << 17 |  //contrast value (U4.7 format)
296
 
297
                        brightness << 1|  // S7.4 format
298
                        1);
299
 
300
        *p_table ++ = ( cos_c_s << 16 |  // cos(h) * contrast * saturation
301
                        sin_c_s);        // sin(h) * contrast * saturation
302
 
303
    }
304
}
305
 
306
 
307
void hsw_veb_iecp_csc_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
308
{
309
    unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 220);
310
    float tran_coef[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
311
    float v_coef[3]    = {0.0, 0.0, 0.0};
312
    float u_coef[3]    = {0.0, 0.0, 0.0};
313
    int   is_transform_enabled = 0;
314
 
315
    if(!(proc_ctx->filters_mask & VPP_IECP_CSC)){
316
        memset(p_table, 0, 8 * 4);
317
        return;
318
    }
319
    /*
320
    VAProcColorStandardType   in_color_std  = proc_ctx->pipeline_param->surface_color_standard;
321
    VAProcColorStandardType   out_color_std = proc_ctx->pipeline_param->output_color_standard;
322
    assert(in_color_std == out_color_std);
323
    */
324
    if(proc_ctx->fourcc_input == VA_FOURCC('R','G','B','A') &&
325
       (proc_ctx->fourcc_output == VA_FOURCC('N','V','1','2') ||
326
        proc_ctx->fourcc_output == VA_FOURCC('Y','V','1','2') ||
327
        proc_ctx->fourcc_output == VA_FOURCC('Y','V','Y','2') ||
328
        proc_ctx->fourcc_output == VA_FOURCC('A','Y','U','V'))) {
329
 
330
         tran_coef[0] = 0.257;
331
         tran_coef[1] = 0.504;
332
         tran_coef[2] = 0.098;
333
         tran_coef[3] = -0.148;
334
         tran_coef[4] = -0.291;
335
         tran_coef[5] = 0.439;
336
         tran_coef[6] = 0.439;
337
         tran_coef[7] = -0.368;
338
         tran_coef[8] = -0.071;
339
 
340
         u_coef[0] = 16 * 4;
341
         u_coef[1] = 128 * 4;
342
         u_coef[2] = 128 * 4;
343
 
344
         is_transform_enabled = 1;
345
    }else if((proc_ctx->fourcc_input  == VA_FOURCC('N','V','1','2') ||
346
              proc_ctx->fourcc_input  == VA_FOURCC('Y','V','1','2') ||
347
              proc_ctx->fourcc_input  == VA_FOURCC('Y','U','Y','2') ||
348
              proc_ctx->fourcc_input  == VA_FOURCC('A','Y','U','V'))&&
349
              proc_ctx->fourcc_output == VA_FOURCC('R','G','B','A')) {
350
 
351
         tran_coef[0] = 1.164;
352
         tran_coef[1] = 0.000;
353
         tran_coef[2] = 1.569;
354
         tran_coef[3] = 1.164;
355
         tran_coef[4] = -0.813;
356
         tran_coef[5] = -0.392;
357
         tran_coef[6] = 1.164;
358
         tran_coef[7] = 2.017;
359
         tran_coef[8] = 0.000;
360
 
361
         v_coef[0] = -16 * 4;
362
         v_coef[1] = -128 * 4;
363
         v_coef[2] = -128 * 4;
364
 
365
        is_transform_enabled = 1;
366
    }else if(proc_ctx->fourcc_input != proc_ctx->fourcc_output){
367
         //enable when input and output format are different.
368
         is_transform_enabled = 1;
369
    }
370
 
371
    if(is_transform_enabled == 0){
372
        memset(p_table, 0, 8 * 4);
373
    }else{
374
        *p_table ++ = ( 0 << 29 | //reserved
375
                        format_convert(tran_coef[1], 2, 10, 1) << 16 | //c1, s2.10 format
376
                        format_convert(tran_coef[0], 2, 10, 1) << 3 |  //c0, s2.10 format
377
 
378
 
379
                        is_transform_enabled);
380
 
381
        *p_table ++ = ( 0 << 26 | //reserved
382
                        format_convert(tran_coef[3], 2, 10, 1) << 13 |
383
                        format_convert(tran_coef[2], 2, 10, 1));
384
 
385
        *p_table ++ = ( 0 << 26 | //reserved
386
                        format_convert(tran_coef[5], 2, 10, 1) << 13 |
387
                        format_convert(tran_coef[4], 2, 10, 1));
388
 
389
        *p_table ++ = ( 0 << 26 | //reserved
390
                        format_convert(tran_coef[7], 2, 10, 1) << 13 |
391
                        format_convert(tran_coef[6], 2, 10, 1));
392
 
393
        *p_table ++ = ( 0 << 13 | //reserved
394
                        format_convert(tran_coef[8], 2, 10, 1));
395
 
396
        *p_table ++ = ( 0 << 22 | //reserved
397
                        format_convert(u_coef[0], 10, 0, 1) << 11 |
398
                        format_convert(v_coef[0], 10, 0, 1));
399
 
400
        *p_table ++ = ( 0 << 22 | //reserved
401
                        format_convert(u_coef[1], 10, 0, 1) << 11 |
402
                        format_convert(v_coef[1], 10, 0, 1));
403
 
404
        *p_table ++ = ( 0 << 22 | //reserved
405
                        format_convert(u_coef[2], 10, 0, 1) << 11 |
406
                        format_convert(v_coef[2], 10, 0, 1));
407
    }
408
}
409
 
410
void hsw_veb_iecp_aoi_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
411
{
412
    unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 252);
413
    /*
414
     VAProcFilterParameterBuffer * tcc_param =
415
             (VAProcFilterParameterBuffer *) proc_ctx->filter_iecp_tcc;
416
    */
417
    if(!(proc_ctx->filters_mask & VPP_IECP_AOI)){
418
        memset(p_table, 0, 3 * 4);
419
    }else{
420
        *p_table ++ = 0x00000000;
421
        *p_table ++ = 0x00030000;
422
        *p_table ++ = 0x00030000;
423
   }
424
}
425
 
426
void hsw_veb_state_table_setup(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
427
{
428
    if(proc_ctx->filters_mask & 0x000000ff) {
429
        dri_bo *dndi_bo = proc_ctx->dndi_state_table.bo;
430
        dri_bo_map(dndi_bo, 1);
431
        proc_ctx->dndi_state_table.ptr = dndi_bo->virtual;
432
 
433
        hsw_veb_dndi_table(ctx, proc_ctx);
434
 
435
        dri_bo_unmap(dndi_bo);
436
    }
437
 
438
    if(proc_ctx->filters_mask & 0x0000ff00 ||
439
       proc_ctx->fourcc_input != proc_ctx->fourcc_output) {
440
        dri_bo *iecp_bo = proc_ctx->iecp_state_table.bo;
441
        dri_bo_map(iecp_bo, 1);
442
        proc_ctx->iecp_state_table.ptr = iecp_bo->virtual;
443
 
444
        hsw_veb_iecp_std_table(ctx, proc_ctx);
445
        hsw_veb_iecp_ace_table(ctx, proc_ctx);
446
        hsw_veb_iecp_tcc_table(ctx, proc_ctx);
447
        hsw_veb_iecp_pro_amp_table(ctx, proc_ctx);
448
        hsw_veb_iecp_csc_table(ctx, proc_ctx);
449
        hsw_veb_iecp_aoi_table(ctx, proc_ctx);
450
 
451
        dri_bo_unmap(iecp_bo);
452
    }
453
}
454
 
455
void hsw_veb_state_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
456
{
457
    struct intel_batchbuffer *batch = proc_ctx->batch;
458
    unsigned int is_dn_enabled   = (proc_ctx->filters_mask & 0x01)? 1: 0;
459
    unsigned int is_di_enabled   = (proc_ctx->filters_mask & 0x02)? 1: 0;
460
    unsigned int is_iecp_enabled = (proc_ctx->filters_mask & 0xff00)?1:0;
461
 
462
    BEGIN_VEB_BATCH(batch, 6);
463
    OUT_VEB_BATCH(batch, VEB_STATE | (6 - 2));
464
    OUT_VEB_BATCH(batch,
465
 
466
 
467
 
468
                  2 << 8  |       // DI output frame
469
 
470
 
471
                  !!(proc_ctx->is_first_frame && (is_di_enabled || is_dn_enabled)) << 5  |   // DN/DI first frame
472
                  is_di_enabled   << 4  |             // DI enable
473
                  is_dn_enabled   << 3  |             // DN enable
474
                  is_iecp_enabled << 2  |             // global IECP enabled
475
 
476
 
477
 
478
    OUT_RELOC(batch,
479
              proc_ctx->dndi_state_table.bo,
480
              I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
481
 
482
    OUT_RELOC(batch,
483
              proc_ctx->iecp_state_table.bo,
484
              I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
485
 
486
    OUT_RELOC(batch,
487
              proc_ctx->gamut_state_table.bo,
488
              I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
489
 
490
    OUT_RELOC(batch,
491
              proc_ctx->vertex_state_table.bo,
492
              I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
493
 
494
    ADVANCE_VEB_BATCH(batch);
495
}
496
 
497
void hsw_veb_surface_state(VADriverContextP ctx, struct intel_vebox_context *proc_ctx, unsigned int is_output)
498
{
499
    struct  i965_driver_data *i965 = i965_driver_data(ctx);
500
    struct intel_batchbuffer *batch = proc_ctx->batch;
501
    unsigned int u_offset_y = 0, v_offset_y = 0;
502
    unsigned int is_uv_interleaved = 0, tiling = 0, swizzle = 0;
503
    unsigned int surface_format = PLANAR_420_8;
504
    struct object_surface* obj_surf = NULL;
505
    unsigned int surface_pitch = 0;
506
    unsigned int half_pitch_chroma = 0;
507
 
508
    if(is_output){
509
         obj_surf = SURFACE(proc_ctx->frame_store[FRAME_OUT_CURRENT].surface_id);
510
    }else {
511
         obj_surf = SURFACE(proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id);
512
    }
513
 
514
    if (obj_surf->fourcc == VA_FOURCC_NV12) {
515
        surface_format = PLANAR_420_8;
516
        surface_pitch = obj_surf->width;
517
        printf("NV12, is_output=%d, width = %d, pitch is =  %d\n",is_output, obj_surf->orig_width, obj_surf->width);
518
        is_uv_interleaved = 1;
519
        half_pitch_chroma = 0;
520
    } else if (obj_surf->fourcc == VA_FOURCC_YUY2) {
521
        surface_format = YCRCB_NORMAL;
522
        surface_pitch = obj_surf->width * 2;
523
        is_uv_interleaved = 0;
524
        half_pitch_chroma = 0;
525
    } else if (obj_surf->fourcc == VA_FOURCC_AYUV) {
526
        surface_format = PACKED_444A_8;
527
        surface_pitch = obj_surf->width * 4;
528
        is_uv_interleaved = 0;
529
        half_pitch_chroma = 0;
530
    } else if (obj_surf->fourcc == VA_FOURCC_RGBA) {
531
        surface_format = R8G8B8A8_UNORM_SRGB;
532
        surface_pitch = obj_surf->width * 4;
533
        is_uv_interleaved = 0;
534
        half_pitch_chroma = 0;
535
    }
536
 
537
    u_offset_y = obj_surf->y_cb_offset;
538
    v_offset_y = obj_surf->y_cr_offset;
539
 
540
    dri_bo_get_tiling(obj_surf->bo, &tiling, &swizzle);
541
 
542
    BEGIN_VEB_BATCH(batch, 6);
543
    OUT_VEB_BATCH(batch, VEB_SURFACE_STATE | (6 - 2));
544
    OUT_VEB_BATCH(batch,
545
 
546
                  is_output);      // surface indentification.
547
 
548
    OUT_VEB_BATCH(batch,
549
                  (proc_ctx->pic_height - 1) << 18 |  // height . w3
550
                  (proc_ctx->pic_width )  << 4  |  // width
551
                  0);                                 // reserve
552
 
553
    OUT_VEB_BATCH(batch,
554
                  surface_format      << 28  |  // surface format, YCbCr420. w4
555
                  is_uv_interleaved   << 27  |  // interleave chrome , two seperate palar
556
 
557
                  (surface_pitch - 1) << 3   |  // surface pitch, 64 align
558
                  half_pitch_chroma   << 2   |  // half pitch for chrome
559
                  !!tiling            << 1   |  // tiled surface, linear surface used
560
                  (tiling == I915_TILING_Y));   // tiled walk, ignored when liner surface
561
 
562
    OUT_VEB_BATCH(batch,
563
 
564
 
565
 
566
                  u_offset_y);   // Y offset for V(Cb)
567
 
568
    OUT_VEB_BATCH(batch,
569
 
570
 
571
 
572
                  v_offset_y );  // Y offset for V(Cr)
573
 
574
    ADVANCE_VEB_BATCH(batch);
575
}
576
 
577
void hsw_veb_dndi_iecp_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
578
{
579
    struct intel_batchbuffer *batch = proc_ctx->batch;
580
    unsigned char frame_ctrl_bits = 0;
581
    unsigned int startingX = 0;
582
    unsigned int endingX = proc_ctx->pic_width;
583
 
584
    BEGIN_VEB_BATCH(batch, 10);
585
    OUT_VEB_BATCH(batch, VEB_DNDI_IECP_STATE | (10 - 2));
586
    OUT_VEB_BATCH(batch,
587
                  startingX << 16 |
588
                  endingX);
589
    OUT_RELOC(batch,
590
              proc_ctx->frame_store[FRAME_IN_CURRENT].bo,
591
              I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);
592
    OUT_RELOC(batch,
593
              proc_ctx->frame_store[FRAME_IN_PREVIOUS].bo,
594
              I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);
595
    OUT_RELOC(batch,
596
              proc_ctx->frame_store[FRAME_IN_STMM].bo,
597
              I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);
598
    OUT_RELOC(batch,
599
              proc_ctx->frame_store[FRAME_OUT_STMM].bo,
600
              I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
601
    OUT_RELOC(batch,
602
              proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].bo,
603
              I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
604
    OUT_RELOC(batch,
605
              proc_ctx->frame_store[FRAME_OUT_CURRENT].bo,
606
              I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
607
    OUT_RELOC(batch,
608
              proc_ctx->frame_store[FRAME_OUT_PREVIOUS].bo,
609
              I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
610
    OUT_RELOC(batch,
611
              proc_ctx->frame_store[FRAME_OUT_STATISTIC].bo,
612
              I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
613
 
614
    ADVANCE_VEB_BATCH(batch);
615
}
616
 
617
 
618
void hsw_veb_surface_reference(VADriverContextP ctx,
619
                              struct intel_vebox_context *proc_ctx)
620
{
621
    struct object_surface * obj_surf;
622
    struct i965_driver_data *i965 = i965_driver_data(ctx);
623
 
624
    /* update the input surface */
625
     obj_surf = SURFACE(proc_ctx->surface_input);
626
     proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id = proc_ctx->surface_input;
627
     proc_ctx->frame_store[FRAME_IN_CURRENT].bo = obj_surf->bo;
628
     proc_ctx->frame_store[FRAME_IN_CURRENT].is_internal_surface = 0;
629
     dri_bo_reference(proc_ctx->frame_store[FRAME_IN_CURRENT].bo);
630
 
631
     /* update the output surface */
632
     if(proc_ctx->filters_mask == VPP_DNDI_DN){
633
         obj_surf = SURFACE(proc_ctx->surface_output);
634
         proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].surface_id = proc_ctx->surface_output;
635
         proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].bo = obj_surf->bo;
636
         proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].is_internal_surface = 0;
637
         dri_bo_reference(proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].bo);
638
     }else {
639
         obj_surf = SURFACE(proc_ctx->surface_output);
640
         proc_ctx->frame_store[FRAME_OUT_CURRENT].surface_id = proc_ctx->surface_output;
641
         proc_ctx->frame_store[FRAME_OUT_CURRENT].bo = obj_surf->bo;
642
         proc_ctx->frame_store[FRAME_OUT_CURRENT].is_internal_surface = 0;
643
         dri_bo_reference(proc_ctx->frame_store[FRAME_OUT_CURRENT].bo);
644
     }
645
}
646
 
647
void hsw_veb_surface_unreference(VADriverContextP ctx,
648
                                 struct intel_vebox_context *proc_ctx)
649
{
650
    /* unreference the input surface */
651
    dri_bo_unreference(proc_ctx->frame_store[FRAME_IN_CURRENT].bo);
652
    proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id = -1;
653
    proc_ctx->frame_store[FRAME_IN_CURRENT].bo = NULL;
654
    proc_ctx->frame_store[FRAME_IN_CURRENT].is_internal_surface = 0;
655
    dri_bo_unreference(proc_ctx->frame_store[FRAME_IN_CURRENT].bo);
656
 
657
    /* unreference the shared output surface */
658
    if(proc_ctx->filters_mask == VPP_DNDI_DN){
659
       proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].surface_id = -1;
660
       proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].bo = NULL;
661
       proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].is_internal_surface = 0;
662
       dri_bo_unreference(proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].bo);
663
    }else{
664
        proc_ctx->frame_store[FRAME_OUT_CURRENT].surface_id = -1;
665
        proc_ctx->frame_store[FRAME_OUT_CURRENT].bo = NULL;
666
        proc_ctx->frame_store[FRAME_OUT_CURRENT].is_internal_surface = 0;
667
        dri_bo_unreference(proc_ctx->frame_store[FRAME_OUT_CURRENT].bo);
668
     }
669
}
670
 
671
void hsw_veb_resource_prepare(VADriverContextP ctx,
672
                              struct intel_vebox_context *proc_ctx)
673
{
674
    VAStatus va_status;
675
    dri_bo *bo;
676
    struct i965_driver_data *i965 = i965_driver_data(ctx);
677
    unsigned int input_fourcc, output_fourcc;
678
    unsigned int input_sampling, output_sampling;
679
    unsigned int input_tiling, output_tiling;
680
    unsigned int i, swizzle;
681
 
682
    struct object_surface* obj_surf_in  = SURFACE(proc_ctx->surface_input);
683
    struct object_surface* obj_surf_out = SURFACE(proc_ctx->surface_output);
684
 
685
    assert(obj_surf_in->orig_width  == obj_surf_out->orig_width &&
686
           obj_surf_in->orig_height == obj_surf_out->orig_height);
687
 
688
    proc_ctx->pic_width   = obj_surf_in->orig_width;
689
    proc_ctx->pic_height  = obj_surf_in->orig_height;
690
 
691
    /* record vebox pipeline input surface format information*/
692
    if(obj_surf_in->bo == NULL){
693
        input_fourcc = VA_FOURCC('N','V','1','2');
694
        input_sampling = SUBSAMPLE_YUV420;
695
        input_tiling = 1;
696
        i965_check_alloc_surface_bo(ctx, obj_surf_in, input_tiling, input_fourcc, input_sampling);
697
    } else {
698
        input_fourcc = obj_surf_in->fourcc;
699
        input_sampling = obj_surf_in->subsampling;
700
        dri_bo_get_tiling(obj_surf_in->bo, &input_tiling, &swizzle);
701
        input_tiling = !!input_tiling;
702
    }
703
 
704
    /* record vebox pipeline output surface format information */
705
    if(obj_surf_out->bo == NULL){
706
        output_fourcc = VA_FOURCC('N','V','1','2');
707
        output_sampling = SUBSAMPLE_YUV420;
708
        output_tiling = 1;
709
        i965_check_alloc_surface_bo(ctx, obj_surf_out, output_tiling, output_fourcc, output_sampling);
710
    }else {
711
        output_fourcc   = obj_surf_out->fourcc;
712
        output_sampling = obj_surf_out->subsampling;
713
        dri_bo_get_tiling(obj_surf_out->bo, &output_tiling, &swizzle);
714
        output_tiling = !!output_tiling;
715
    }
716
 
717
    assert(input_fourcc == VA_FOURCC_NV12 ||
718
           input_fourcc == VA_FOURCC_YUY2 ||
719
           input_fourcc == VA_FOURCC_AYUV ||
720
           input_fourcc == VA_FOURCC_RGBA);
721
    assert(output_fourcc == VA_FOURCC_NV12 ||
722
           output_fourcc == VA_FOURCC_YUY2 ||
723
           output_fourcc == VA_FOURCC_AYUV ||
724
           output_fourcc == VA_FOURCC_RGBA);
725
 
726
    proc_ctx->fourcc_input = input_fourcc;
727
    proc_ctx->fourcc_output = output_fourcc;
728
 
729
    /* allocate vebox pipeline surfaces */
730
    VASurfaceID surfaces[FRAME_STORE_SUM];
731
    va_status = i965_CreateSurfaces(ctx,
732
                                   proc_ctx ->pic_width,
733
                                   proc_ctx ->pic_height,
734
                                   VA_RT_FORMAT_YUV420,
735
                                   FRAME_STORE_SUM,
736
                                   surfaces);
737
    assert(va_status == VA_STATUS_SUCCESS);
738
 
739
    for(i = FRAME_IN_CURRENT; i < FRAME_STORE_SUM; i ++) {
740
        proc_ctx->frame_store[i].surface_id = surfaces[i];
741
        struct object_surface* obj_surf = SURFACE(surfaces[i]);
742
        if( i == FRAME_IN_CURRENT) {
743
            proc_ctx->frame_store[i].surface_id = proc_ctx->surface_input;
744
            proc_ctx->frame_store[i].bo = (SURFACE(proc_ctx->surface_input))->bo;
745
            proc_ctx->frame_store[i].is_internal_surface = 0;
746
            continue;
747
        }else if( i == FRAME_IN_PREVIOUS || i == FRAME_OUT_CURRENT_DN) {
748
            i965_check_alloc_surface_bo(ctx, obj_surf, input_tiling, input_fourcc, input_sampling);
749
        } else if( i == FRAME_IN_STMM || i == FRAME_OUT_STMM){
750
            i965_check_alloc_surface_bo(ctx, obj_surf, 1, input_fourcc, input_sampling);
751
        } else if( i >= FRAME_OUT_CURRENT){
752
            i965_check_alloc_surface_bo(ctx, obj_surf, output_tiling, output_fourcc, output_sampling);
753
        }
754
        proc_ctx->frame_store[i].bo = obj_surf->bo;
755
        dri_bo_reference(proc_ctx->frame_store[i].bo);
756
        proc_ctx->frame_store[i].is_internal_surface = 1;
757
    }
758
 
759
    /* alloc dndi state table  */
760
    dri_bo_unreference(proc_ctx->dndi_state_table.bo);
761
    bo = dri_bo_alloc(i965->intel.bufmgr,
762
                      "vebox: dndi state Buffer",
763
                      0x1000, 0x1000);
764
    proc_ctx->dndi_state_table.bo = bo;
765
    dri_bo_reference(proc_ctx->dndi_state_table.bo);
766
 
767
    /* alloc iecp state table  */
768
    dri_bo_unreference(proc_ctx->iecp_state_table.bo);
769
    bo = dri_bo_alloc(i965->intel.bufmgr,
770
                      "vebox: iecp state Buffer",
771
                      0x1000, 0x1000);
772
    proc_ctx->iecp_state_table.bo = bo;
773
    dri_bo_reference(proc_ctx->iecp_state_table.bo);
774
 
775
    /* alloc gamut state table  */
776
    dri_bo_unreference(proc_ctx->gamut_state_table.bo);
777
    bo = dri_bo_alloc(i965->intel.bufmgr,
778
                      "vebox: gamut state Buffer",
779
                      0x1000, 0x1000);
780
    proc_ctx->gamut_state_table.bo = bo;
781
    dri_bo_reference(proc_ctx->gamut_state_table.bo);
782
 
783
    /* alloc vertex state table  */
784
    dri_bo_unreference(proc_ctx->vertex_state_table.bo);
785
    bo = dri_bo_alloc(i965->intel.bufmgr,
786
                      "vertex: iecp state Buffer",
787
                      0x1000, 0x1000);
788
    proc_ctx->vertex_state_table.bo = bo;
789
    dri_bo_reference(proc_ctx->vertex_state_table.bo);
790
 
791
}
792
 
793
VAStatus gen75_vebox_process_picture(VADriverContextP ctx,
794
                         struct intel_vebox_context *proc_ctx)
795
{
796
    VAStatus va_status = VA_STATUS_SUCCESS;
797
 
798
    if(proc_ctx->is_first_frame)
799
       hsw_veb_resource_prepare(ctx, proc_ctx);
800
 
801
    hsw_veb_surface_reference(ctx, proc_ctx);
802
 
803
    intel_batchbuffer_start_atomic_veb(proc_ctx->batch, 0x1000);
804
    intel_batchbuffer_emit_mi_flush(proc_ctx->batch);
805
    hsw_veb_surface_state(ctx, proc_ctx, INPUT_SURFACE);
806
    hsw_veb_surface_state(ctx, proc_ctx, OUTPUT_SURFACE);
807
    hsw_veb_state_table_setup(ctx, proc_ctx);
808
 
809
    hsw_veb_state_command(ctx, proc_ctx);
810
    hsw_veb_dndi_iecp_command(ctx, proc_ctx);
811
    intel_batchbuffer_end_atomic(proc_ctx->batch);
812
    intel_batchbuffer_flush(proc_ctx->batch);
813
 
814
    hsw_veb_surface_unreference(ctx, proc_ctx);
815
 
816
   if(proc_ctx->is_first_frame)
817
       proc_ctx->is_first_frame = 0;
818
 
819
    return va_status;
820
}
821
 
822
void gen75_vebox_context_destroy(VADriverContextP ctx,
823
                          struct intel_vebox_context *proc_ctx)
824
{
825
    int i;
826
    /* release vebox pipeline surface */
827
    for(i = 0; i < FRAME_STORE_SUM; i ++) {
828
        if(proc_ctx->frame_store[i].is_internal_surface){
829
            dri_bo_unreference(proc_ctx->frame_store[i].bo);
830
        }
831
        proc_ctx->frame_store[i].surface_id = -1;
832
        proc_ctx->frame_store[i].bo = NULL;
833
    }
834
    /* release dndi state table  */
835
    dri_bo_unreference(proc_ctx->dndi_state_table.bo);
836
    proc_ctx->dndi_state_table.bo = NULL;
837
 
838
    /* release iecp state table  */
839
    dri_bo_unreference(proc_ctx->iecp_state_table.bo);
840
    proc_ctx->dndi_state_table.bo = NULL;
841
 
842
    intel_batchbuffer_free(proc_ctx->batch);
843
 
844
    free(proc_ctx);
845
}
846
 
847
struct intel_vebox_context * gen75_vebox_context_init(VADriverContextP ctx)
848
{
849
    struct intel_driver_data *intel = intel_driver_data(ctx);
850
    struct intel_vebox_context *proc_context = calloc(1, sizeof(struct intel_vebox_context));
851
 
852
    proc_context->batch = intel_batchbuffer_new(intel, I915_EXEC_VEBOX, 0);
853
    memset(proc_context->frame_store, 0, sizeof(VEBFrameStore)*FRAME_STORE_SUM);
854
 
855
    proc_context->filters_mask             = 0;
856
    proc_context->is_first_frame           = 1;
857
    proc_context->filters_mask             = 0;
858
 
859
    return proc_context;
860
}
861