a08f61ddb9
git-svn-id: svn://kolibrios.org@6146 a494cfbc-eb01-0410-851d-a64ba20cac60
2404 lines
91 KiB
C
2404 lines
91 KiB
C
/*
|
|
* Copyright © 2011 Intel Corporation
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
* copy of this software and associated documentation files (the
|
|
* "Software"), to deal in the Software without restriction, including
|
|
* without limitation the rights to use, copy, modify, merge, publish,
|
|
* distribute, sub license, and/or sell copies of the Software, and to
|
|
* permit persons to whom the Software is furnished to do so, subject to
|
|
* the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice (including the
|
|
* next paragraph) shall be included in all copies or substantial portions
|
|
* of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
* IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
*
|
|
* Authors:
|
|
* Li Xiaowei <xiaowei.a.li@intel.com>
|
|
* Li Zhong <zhong.li@intel.com>
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
#include <math.h>
|
|
|
|
#include "intel_batchbuffer.h"
|
|
#include "intel_driver.h"
|
|
#include "i965_defines.h"
|
|
#include "i965_structs.h"
|
|
#include "gen75_vpp_vebox.h"
|
|
#include "intel_media.h"
|
|
|
|
#define PI 3.1415926
|
|
|
|
extern VAStatus
|
|
i965_MapBuffer(VADriverContextP ctx, VABufferID buf_id, void **);
|
|
|
|
extern VAStatus
|
|
i965_UnmapBuffer(VADriverContextP ctx, VABufferID buf_id);
|
|
|
|
extern VAStatus
|
|
i965_DeriveImage(VADriverContextP ctx, VABufferID surface, VAImage *out_image);
|
|
|
|
extern VAStatus
|
|
i965_DestroyImage(VADriverContextP ctx, VAImageID image);
|
|
|
|
VAStatus
|
|
vpp_surface_convert(VADriverContextP ctx, struct object_surface *src_obj_surf,
|
|
struct object_surface *dst_obj_surf)
|
|
{
|
|
VAStatus va_status = VA_STATUS_SUCCESS;
|
|
|
|
assert(src_obj_surf->orig_width == dst_obj_surf->orig_width);
|
|
assert(src_obj_surf->orig_height == dst_obj_surf->orig_height);
|
|
|
|
VARectangle src_rect, dst_rect;
|
|
src_rect.x = dst_rect.x = 0;
|
|
src_rect.y = dst_rect.y = 0;
|
|
src_rect.width = dst_rect.width = src_obj_surf->orig_width;
|
|
src_rect.height = dst_rect.height = dst_obj_surf->orig_height;
|
|
|
|
struct i965_surface src_surface, dst_surface;
|
|
src_surface.base = (struct object_base *)src_obj_surf;
|
|
src_surface.type = I965_SURFACE_TYPE_SURFACE;
|
|
src_surface.flags = I965_SURFACE_FLAG_FRAME;
|
|
|
|
dst_surface.base = (struct object_base *)dst_obj_surf;
|
|
dst_surface.type = I965_SURFACE_TYPE_SURFACE;
|
|
dst_surface.flags = I965_SURFACE_FLAG_FRAME;
|
|
|
|
va_status = i965_image_processing(ctx,
|
|
&src_surface,
|
|
&src_rect,
|
|
&dst_surface,
|
|
&dst_rect);
|
|
return va_status;
|
|
}
|
|
|
|
static VAStatus
|
|
vpp_surface_scaling(VADriverContextP ctx, struct object_surface *src_obj_surf,
|
|
struct object_surface *dst_obj_surf, uint32_t flags)
|
|
{
|
|
VAStatus va_status = VA_STATUS_SUCCESS;
|
|
|
|
assert(src_obj_surf->fourcc == VA_FOURCC_NV12);
|
|
assert(dst_obj_surf->fourcc == VA_FOURCC_NV12);
|
|
|
|
VARectangle src_rect, dst_rect;
|
|
src_rect.x = 0;
|
|
src_rect.y = 0;
|
|
src_rect.width = src_obj_surf->orig_width;
|
|
src_rect.height = src_obj_surf->orig_height;
|
|
|
|
dst_rect.x = 0;
|
|
dst_rect.y = 0;
|
|
dst_rect.width = dst_obj_surf->orig_width;
|
|
dst_rect.height = dst_obj_surf->orig_height;
|
|
|
|
va_status = i965_scaling_processing(ctx,
|
|
src_obj_surf,
|
|
&src_rect,
|
|
dst_obj_surf,
|
|
&dst_rect,
|
|
flags);
|
|
|
|
return va_status;
|
|
}
|
|
|
|
void hsw_veb_dndi_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
|
|
{
|
|
struct i965_driver_data *i965 = i965_driver_data(ctx);
|
|
unsigned int* p_table ;
|
|
unsigned int progressive_dn = 1;
|
|
unsigned int dndi_top_first = 0;
|
|
unsigned int is_mcdi_enabled = 0;
|
|
|
|
if (proc_ctx->is_di_enabled) {
|
|
const VAProcFilterParameterBufferDeinterlacing * const deint_params =
|
|
proc_ctx->filter_di;
|
|
|
|
progressive_dn = 0;
|
|
|
|
/* If we are in "First Frame" mode, i.e. past frames are not
|
|
available for motion measure, then don't use the TFF flag */
|
|
dndi_top_first = !(deint_params->flags & (proc_ctx->is_first_frame ?
|
|
VA_DEINTERLACING_BOTTOM_FIELD :
|
|
VA_DEINTERLACING_BOTTOM_FIELD_FIRST));
|
|
|
|
is_mcdi_enabled =
|
|
(deint_params->algorithm == VAProcDeinterlacingMotionCompensated);
|
|
}
|
|
|
|
/*
|
|
VAProcFilterParameterBufferDeinterlacing *di_param =
|
|
(VAProcFilterParameterBufferDeinterlacing *) proc_ctx->filter_di;
|
|
|
|
VAProcFilterParameterBuffer * dn_param =
|
|
(VAProcFilterParameterBuffer *) proc_ctx->filter_dn;
|
|
*/
|
|
p_table = (unsigned int *)proc_ctx->dndi_state_table.ptr;
|
|
|
|
if (IS_HASWELL(i965->intel.device_info))
|
|
*p_table ++ = 0; // reserved . w0
|
|
|
|
*p_table ++ = ( 140 << 24 | // denoise STAD threshold . w1
|
|
192 << 16 | // dnmh_history_max
|
|
0 << 12 | // reserved
|
|
7 << 8 | // dnmh_delta[3:0]
|
|
38 ); // denoise ASD threshold
|
|
|
|
*p_table ++ = ( 0 << 30 | // reserved . w2
|
|
0 << 24 | // temporal diff th
|
|
0 << 22 | // reserved.
|
|
0 << 16 | // low temporal diff th
|
|
2 << 13 | // STMM C2
|
|
1 << 8 | // denoise moving pixel th
|
|
38 ); // denoise th for sum of complexity measure
|
|
|
|
*p_table ++ = ( 0 << 30 | // reserved . w3
|
|
12<< 24 | // good neighbor th[5:0]
|
|
9 << 20 | // CAT slope minus 1
|
|
5 << 16 | // SAD Tight in
|
|
0 << 14 | // smooth mv th
|
|
0 << 12 | // reserved
|
|
1 << 8 | // bne_edge_th[3:0]
|
|
20 ); // block noise estimate noise th
|
|
|
|
*p_table ++ = ( 0 << 31 | // STMM blending constant select. w4
|
|
64 << 24 | // STMM trc1
|
|
125<< 16 | // STMM trc2
|
|
0 << 14 | // reserved
|
|
30 << 8 | // VECM_mul
|
|
150 ); // maximum STMM
|
|
|
|
*p_table ++ = ( 118<< 24 | // minumum STMM . W5
|
|
0 << 22 | // STMM shift down
|
|
1 << 20 | // STMM shift up
|
|
5 << 16 | // STMM output shift
|
|
100 << 8 | // SDI threshold
|
|
5 ); // SDI delta
|
|
|
|
*p_table ++ = ( 50 << 24 | // SDI fallback mode 1 T1 constant . W6
|
|
100 << 16 | // SDI fallback mode 1 T2 constant
|
|
37 << 8 | // SDI fallback mode 2 constant(angle2x1)
|
|
175 ); // FMD temporal difference threshold
|
|
|
|
*p_table ++ = ( 16 << 24 | // FMD #1 vertical difference th . w7
|
|
100<< 16 | // FMD #2 vertical difference th
|
|
0 << 14 | // CAT th1
|
|
2 << 8 | // FMD tear threshold
|
|
is_mcdi_enabled << 7 | // MCDI Enable, use motion compensated deinterlace algorithm
|
|
progressive_dn << 6 | // progressive DN
|
|
0 << 4 | // reserved
|
|
dndi_top_first << 3 | // DN/DI Top First
|
|
0 ); // reserved
|
|
|
|
*p_table ++ = ( 0 << 29 | // reserved . W8
|
|
32 << 23 | // dnmh_history_init[5:0]
|
|
10 << 19 | // neighborPixel th
|
|
0 << 18 | // reserved
|
|
0 << 16 | // FMD for 2nd field of previous frame
|
|
25 << 10 | // MC pixel consistency th
|
|
0 << 8 | // FMD for 1st field for current frame
|
|
10 << 4 | // SAD THB
|
|
5 ); // SAD THA
|
|
|
|
*p_table ++ = ( 0 << 24 | // reserved
|
|
140<< 16 | // chr_dnmh_stad_th
|
|
0 << 13 | // reserved
|
|
1 << 12 | // chrome denoise enable
|
|
13 << 6 | // chr temp diff th
|
|
7 ); // chr temp diff low
|
|
|
|
if (IS_GEN8(i965->intel.device_info) ||
|
|
IS_GEN9(i965->intel.device_info))
|
|
*p_table ++ = 0; // parameters for hot pixel,
|
|
}
|
|
|
|
//Set default values for STDE
|
|
void set_std_table_default(struct intel_vebox_context *proc_ctx, unsigned int *p_table) {
|
|
|
|
//DWord 15
|
|
*p_table ++ = ( 0 << 31 | // Reserved
|
|
0x3F8 << 21 | // SATB1 (10 bits, default 8, optimized value -8)
|
|
31 << 14 | // SATP3
|
|
6 << 7 | // SATP2
|
|
0x7A ); // SATP1 (7 bits, default 6, optimized value -6)
|
|
|
|
//DWord 16
|
|
*p_table ++ = ( 0 << 31 | // Reserved
|
|
297 << 20 | // SATS0
|
|
124 << 10 | // SATB3
|
|
8 ); // SATB2
|
|
|
|
//DWord 17
|
|
*p_table ++ = ( 0 << 22 | // Reserved
|
|
297 << 11 | // SATS2
|
|
85 ); // SATS1
|
|
|
|
//DWord 18
|
|
*p_table ++ = ( 14 << 25 | // HUEP3
|
|
6 << 18 | // HUEP2
|
|
0x7A << 11 | // HUEP1 (7 bits, default value -6 = 7Ah)
|
|
256 ); // SATS3
|
|
|
|
//DWord 19
|
|
*p_table ++ = ( 0 << 30 | // Reserved
|
|
256 << 20 | // HUEB3
|
|
8 << 10 | // HUEB2
|
|
0x3F8 ); // HUEB1 (10 bits, default value 8, optimized value -8)
|
|
|
|
//DWord 20
|
|
*p_table ++ = ( 0 << 22 | // Reserved
|
|
85 << 11 | // HUES1
|
|
384 ); // HUES0
|
|
|
|
//DWord 21
|
|
*p_table ++ = ( 0 << 22 | // Reserved
|
|
256 << 11 | // HUES3
|
|
384 ); // HUES2
|
|
|
|
//DWord 22
|
|
*p_table ++ = ( 0 << 31 | // Reserved
|
|
0 << 21 | // SATB1_DARK
|
|
31 << 14 | // SATP3_DARK
|
|
31 << 7 | // SATP2_DARK
|
|
0x7B ); // SATP1_DARK (7 bits, default value -11 = FF5h, optimized value -5)
|
|
|
|
//DWord 23
|
|
*p_table ++ = ( 0 << 31 | // Reserved
|
|
305 << 20 | // SATS0_DARK
|
|
124 << 10 | // SATB3_DARK
|
|
124 ); // SATB2_DARK
|
|
|
|
//DWord 24
|
|
*p_table ++ = ( 0 << 22 | // Reserved
|
|
256 << 11 | // SATS2_DARK
|
|
220 ); // SATS1_DARK
|
|
|
|
//DWord 25
|
|
*p_table ++ = ( 14 << 25 | // HUEP3_DARK
|
|
14 << 18 | // HUEP2_DARK
|
|
14 << 11 | // HUEP1_DARK
|
|
256 ); // SATS3_DARK
|
|
|
|
//DWord 26
|
|
*p_table ++ = ( 0 << 30 | // Reserved
|
|
56 << 20 | // HUEB3_DARK
|
|
56 << 10 | // HUEB2_DARK
|
|
56 ); // HUEB1_DARK
|
|
|
|
//DWord 27
|
|
*p_table ++ = ( 0 << 22 | // Reserved
|
|
256 << 11 | // HUES1_DARK
|
|
256 ); // HUES0_DARK
|
|
|
|
//DWord 28
|
|
*p_table ++ = ( 0 << 22 | // Reserved
|
|
256 << 11 | // HUES3_DARK
|
|
256 ); // HUES2_DARK
|
|
}
|
|
|
|
//Set values for STDE factor 3
|
|
void set_std_table_3(struct intel_vebox_context *proc_ctx, unsigned int *p_table) {
|
|
|
|
//DWord 15
|
|
*p_table ++ = ( 0 << 31 | // Reserved
|
|
1016 << 21 | // SATB1 (10 bits, default 8, optimized value 1016)
|
|
31 << 14 | // SATP3
|
|
6 << 7 | // SATP2
|
|
122 ); // SATP1 (7 bits, default 6, optimized value 122)
|
|
|
|
//DWord 16
|
|
*p_table ++ = ( 0 << 31 | // Reserved
|
|
297 << 20 | // SATS0
|
|
124 << 10 | // SATB3
|
|
8 ); // SATB2
|
|
|
|
//DWord 17
|
|
*p_table ++ = ( 0 << 22 | // Reserved
|
|
297 << 11 | // SATS2
|
|
85 ); // SATS1
|
|
|
|
//DWord 18
|
|
*p_table ++ = ( 14 << 25 | // HUEP3
|
|
6 << 18 | // HUEP2
|
|
122 << 11 | // HUEP1 (7 bits, default value -6 = 7Ah, optimized 122)
|
|
256 ); // SATS3
|
|
|
|
//DWord 19
|
|
*p_table ++ = ( 0 << 30 | // Reserved
|
|
56 << 20 | // HUEB3 (default 256, optimized 56)
|
|
8 << 10 | // HUEB2
|
|
1016 ); // HUEB1 (10 bits, default value 8, optimized value 1016)
|
|
|
|
//DWord 20
|
|
*p_table ++ = ( 0 << 22 | // Reserved
|
|
85 << 11 | // HUES1
|
|
384 ); // HUES0
|
|
|
|
//DWord 21
|
|
*p_table ++ = ( 0 << 22 | // Reserved
|
|
256 << 11 | // HUES3
|
|
384 ); // HUES2
|
|
|
|
//DWord 22
|
|
*p_table ++ = ( 0 << 31 | // Reserved
|
|
0 << 21 | // SATB1_DARK
|
|
31 << 14 | // SATP3_DARK
|
|
31 << 7 | // SATP2_DARK
|
|
123 ); // SATP1_DARK (7 bits, default value -11 = FF5h, optimized value 123)
|
|
|
|
//DWord 23
|
|
*p_table ++ = ( 0 << 31 | // Reserved
|
|
305 << 20 | // SATS0_DARK
|
|
124 << 10 | // SATB3_DARK
|
|
124 ); // SATB2_DARK
|
|
|
|
//DWord 24
|
|
*p_table ++ = ( 0 << 22 | // Reserved
|
|
256 << 11 | // SATS2_DARK
|
|
220 ); // SATS1_DARK
|
|
|
|
//DWord 25
|
|
*p_table ++ = ( 14 << 25 | // HUEP3_DARK
|
|
14 << 18 | // HUEP2_DARK
|
|
14 << 11 | // HUEP1_DARK
|
|
256 ); // SATS3_DARK
|
|
|
|
//DWord 26
|
|
*p_table ++ = ( 0 << 30 | // Reserved
|
|
56 << 20 | // HUEB3_DARK
|
|
56 << 10 | // HUEB2_DARK
|
|
56 ); // HUEB1_DARK
|
|
|
|
//DWord 27
|
|
*p_table ++ = ( 0 << 22 | // Reserved
|
|
256 << 11 | // HUES1_DARK
|
|
256 ); // HUES0_DARK
|
|
|
|
//DWord 28
|
|
*p_table ++ = ( 0 << 22 | // Reserved
|
|
256 << 11 | // HUES3_DARK
|
|
256 ); // HUES2_DARK
|
|
}
|
|
|
|
//Set values for STDE factor 6
|
|
void set_std_table_6(struct intel_vebox_context *proc_ctx, unsigned int *p_table) {
|
|
|
|
//DWord 15
|
|
*p_table ++ = ( 0 << 31 | // Reserved
|
|
0 << 21 | // SATB1 (10 bits, default 8, optimized value 0)
|
|
31 << 14 | // SATP3
|
|
31 << 7 | // SATP2 (default 6, optimized 31)
|
|
114 ); // SATP1 (7 bits, default 6, optimized value 114)
|
|
|
|
//DWord 16
|
|
*p_table ++ = ( 0 << 31 | // Reserved
|
|
467 << 20 | // SATS0 (default 297, optimized 467)
|
|
124 << 10 | // SATB3
|
|
124 ); // SATB2
|
|
|
|
//DWord 17
|
|
*p_table ++ = ( 0 << 22 | // Reserved
|
|
256 << 11 | // SATS2 (default 297, optimized 256)
|
|
176 ); // SATS1
|
|
|
|
//DWord 18
|
|
*p_table ++ = ( 14 << 25 | // HUEP3
|
|
14 << 18 | // HUEP2
|
|
14 << 11 | // HUEP1 (7 bits, default value -6 = 7Ah, optimized value 14)
|
|
256 ); // SATS3
|
|
|
|
//DWord 19
|
|
*p_table ++ = ( 0 << 30 | // Reserved
|
|
56 << 20 | // HUEB3
|
|
56 << 10 | // HUEB2
|
|
56 ); // HUEB1 (10 bits, default value 8, optimized value 56)
|
|
|
|
//DWord 20
|
|
*p_table ++ = ( 0 << 22 | // Reserved
|
|
256 << 11 | // HUES1
|
|
256 ); // HUES0
|
|
|
|
//DWord 21
|
|
*p_table ++ = ( 0 << 22 | // Reserved
|
|
256 << 11 | // HUES3
|
|
256 ); // HUES2
|
|
|
|
//DWord 22
|
|
*p_table ++ = ( 0 << 31 | // Reserved
|
|
0 << 21 | // SATB1_DARK
|
|
31 << 14 | // SATP3_DARK
|
|
31 << 7 | // SATP2_DARK
|
|
123 ); // SATP1_DARK (7 bits, default value -11 = FF5h, optimized value 123)
|
|
|
|
//DWord 23
|
|
*p_table ++ = ( 0 << 31 | // Reserved
|
|
305 << 20 | // SATS0_DARK
|
|
124 << 10 | // SATB3_DARK
|
|
124 ); // SATB2_DARK
|
|
|
|
//DWord 24
|
|
*p_table ++ = ( 0 << 22 | // Reserved
|
|
256 << 11 | // SATS2_DARK
|
|
220 ); // SATS1_DARK
|
|
|
|
//DWord 25
|
|
*p_table ++ = ( 14 << 25 | // HUEP3_DARK
|
|
14 << 18 | // HUEP2_DARK
|
|
14 << 11 | // HUEP1_DARK
|
|
256 ); // SATS3_DARK
|
|
|
|
//DWord 26
|
|
*p_table ++ = ( 0 << 30 | // Reserved
|
|
56 << 20 | // HUEB3_DARK
|
|
56 << 10 | // HUEB2_DARK
|
|
56 ); // HUEB1_DARK
|
|
|
|
//DWord 27
|
|
*p_table ++ = ( 0 << 22 | // Reserved
|
|
256 << 11 | // HUES1_DARK
|
|
256 ); // HUES0_DARK
|
|
|
|
//DWord 28
|
|
*p_table ++ = ( 0 << 22 | // Reserved
|
|
256 << 11 | // HUES3_DARK
|
|
256 ); // HUES2_DARK
|
|
}
|
|
|
|
//Set values for STDE factor 9
|
|
void set_std_table_9(struct intel_vebox_context *proc_ctx, unsigned int *p_table) {
|
|
|
|
//DWord 15
|
|
*p_table ++ = ( 0 << 31 | // Reserved
|
|
0 << 21 | // SATB1 (10 bits, default 8, optimized value 0)
|
|
31 << 14 | // SATP3
|
|
31 << 7 | // SATP2 (default 6, optimized 31)
|
|
108 ); // SATP1 (7 bits, default 6, optimized value 108)
|
|
|
|
//DWord 16
|
|
*p_table ++ = ( 0 << 31 | // Reserved
|
|
721 << 20 | // SATS0 (default 297, optimized 721)
|
|
124 << 10 | // SATB3
|
|
124 ); // SATB2
|
|
|
|
//DWord 17
|
|
*p_table ++ = ( 0 << 22 | // Reserved
|
|
256 << 11 | // SATS2 (default 297, optimized 256)
|
|
156 ); // SATS1 (default 176, optimized 156)
|
|
|
|
//DWord 18
|
|
*p_table ++ = ( 14 << 25 | // HUEP3
|
|
14 << 18 | // HUEP2
|
|
14 << 11 | // HUEP1 (7 bits, default value -6 = 7Ah, optimized value 14)
|
|
256 ); // SATS3
|
|
|
|
//DWord 19
|
|
*p_table ++ = ( 0 << 30 | // Reserved
|
|
56 << 20 | // HUEB3
|
|
56 << 10 | // HUEB2
|
|
56 ); // HUEB1 (10 bits, default value 8, optimized value 56)
|
|
|
|
//DWord 20
|
|
*p_table ++ = ( 0 << 22 | // Reserved
|
|
256 << 11 | // HUES1
|
|
256 ); // HUES0
|
|
|
|
//DWord 21
|
|
*p_table ++ = ( 0 << 22 | // Reserved
|
|
256 << 11 | // HUES3
|
|
256 ); // HUES2
|
|
|
|
//DWord 22
|
|
*p_table ++ = ( 0 << 31 | // Reserved
|
|
0 << 21 | // SATB1_DARK
|
|
31 << 14 | // SATP3_DARK
|
|
31 << 7 | // SATP2_DARK
|
|
123 ); // SATP1_DARK (7 bits, default value -11 = FF5h, optimized value 123)
|
|
|
|
//DWord 23
|
|
*p_table ++ = ( 0 << 31 | // Reserved
|
|
305 << 20 | // SATS0_DARK
|
|
124 << 10 | // SATB3_DARK
|
|
124 ); // SATB2_DARK
|
|
|
|
//DWord 24
|
|
*p_table ++ = ( 0 << 22 | // Reserved
|
|
256 << 11 | // SATS2_DARK
|
|
220 ); // SATS1_DARK
|
|
|
|
//DWord 25
|
|
*p_table ++ = ( 14 << 25 | // HUEP3_DARK
|
|
14 << 18 | // HUEP2_DARK
|
|
14 << 11 | // HUEP1_DARK
|
|
256 ); // SATS3_DARK
|
|
|
|
//DWord 26
|
|
*p_table ++ = ( 0 << 30 | // Reserved
|
|
56 << 20 | // HUEB3_DARK
|
|
56 << 10 | // HUEB2_DARK
|
|
56 ); // HUEB1_DARK
|
|
|
|
//DWord 27
|
|
*p_table ++ = ( 0 << 22 | // Reserved
|
|
256 << 11 | // HUES1_DARK
|
|
256 ); // HUES0_DARK
|
|
|
|
//DWord 28
|
|
*p_table ++ = ( 0 << 22 | // Reserved
|
|
256 << 11 | // HUES3_DARK
|
|
256 ); // HUES2_DARK
|
|
}
|
|
|
|
|
|
void hsw_veb_iecp_std_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
|
|
{
|
|
unsigned int *p_table = proc_ctx->iecp_state_table.ptr + 0 ;
|
|
|
|
if(!(proc_ctx->filters_mask & VPP_IECP_STD_STE)){
|
|
memset(p_table, 0, 29 * 4);
|
|
}else{
|
|
int stde_factor = 0; //default value
|
|
VAProcFilterParameterBuffer * std_param = (VAProcFilterParameterBuffer *) proc_ctx->filter_iecp_std;
|
|
stde_factor = std_param->value;
|
|
|
|
//DWord 0
|
|
*p_table ++ = ( 154 << 24 | // V_Mid
|
|
110 << 16 | // U_Mid
|
|
14 << 10 | // Hue_Max
|
|
31 << 4 | // Sat_Max
|
|
0 << 3 | // Reserved
|
|
0 << 2 | // Output Control is set to output the 1=STD score /0=Output Pixels
|
|
1 << 1 | // Set STE Enable
|
|
1 ); // Set STD Enable
|
|
|
|
//DWord 1
|
|
*p_table ++ = ( 0 << 31 | // Reserved
|
|
4 << 28 | // Diamond Margin
|
|
0 << 21 | // Diamond_du
|
|
3 << 18 | // HS_Margin
|
|
79 << 10 | // Cos(alpha)
|
|
0 << 8 | // Reserved
|
|
101 ); // Sin(alpha)
|
|
|
|
//DWord 2
|
|
*p_table ++ = ( 0 << 21 | // Reserved
|
|
100 << 13 | // Diamond_alpha
|
|
35 << 7 | // Diamond_Th
|
|
0 );
|
|
|
|
//DWord 3
|
|
*p_table ++ = ( 254 << 24 | // Y_point_3
|
|
47 << 16 | // Y_point_2
|
|
46 << 8 | // Y_point_1
|
|
1 << 7 | // VY_STD_Enable
|
|
0 ); // Reserved
|
|
|
|
//DWord 4
|
|
*p_table ++ = ( 0 << 18 | // Reserved
|
|
31 << 13 | // Y_slope_2
|
|
31 << 8 | // Y_slope_1
|
|
255 ); // Y_point_4
|
|
|
|
//DWord 5
|
|
*p_table ++ = ( 400 << 16 | // INV_Skin_types_margin = 20* Skin_Type_margin => 20*20
|
|
3300 ); // INV_Margin_VYL => 1/Margin_VYL
|
|
|
|
//DWord 6
|
|
*p_table ++ = ( 216 << 24 | // P1L
|
|
46 << 16 | // P0L
|
|
1600 ); // INV_Margin_VYU
|
|
|
|
//DWord 7
|
|
*p_table ++ = ( 130 << 24 | // B1L
|
|
133 << 16 | // B0L
|
|
236 << 8 | // P3L
|
|
236 ); // P2L
|
|
|
|
//DWord 8
|
|
*p_table ++ = ( 0 << 27 | // Reserved
|
|
0x7FB << 16 | // S0L (11 bits, Default value: -5 = FBh, pad it with 1s to make it 11bits)
|
|
130 << 8 | // B3L
|
|
130 );
|
|
|
|
//DWord 9
|
|
*p_table ++ = ( 0 << 22 | // Reserved
|
|
0 << 11 | // S2L
|
|
0); // S1L
|
|
|
|
//DWord 10
|
|
*p_table ++ = ( 0 << 27 | // Reserved
|
|
66 << 19 | // P1U
|
|
46 << 11 | // P0U
|
|
0 ); // S3
|
|
|
|
//DWord 11
|
|
*p_table ++ = ( 163 << 24 | // B1U
|
|
143 << 16 | // B0U
|
|
236 << 8 | // P3U
|
|
150 ); // P2U
|
|
|
|
//DWord 12
|
|
*p_table ++ = ( 0 << 27 | // Reserved
|
|
256 << 16 | // S0U
|
|
200 << 8 | // B3U
|
|
200 ); // B2U
|
|
|
|
//DWord 13
|
|
*p_table ++ = ( 0 << 22 | // Reserved
|
|
0x74D << 11 | // S2U (11 bits, Default value -179 = F4Dh)
|
|
113 ); // S1U
|
|
|
|
//DWoord 14
|
|
*p_table ++ = ( 0 << 28 | // Reserved
|
|
20 << 20 | // Skin_types_margin
|
|
120 << 12 | // Skin_types_thresh
|
|
1 << 11 | // Skin_Types_Enable
|
|
0 ); // S3U
|
|
|
|
//Set DWord 15 through DWord 28 in their respective methods.
|
|
switch(stde_factor) {
|
|
case 3:
|
|
set_std_table_3(proc_ctx, p_table);
|
|
break;
|
|
|
|
case 6:
|
|
set_std_table_6(proc_ctx, p_table);
|
|
break;
|
|
|
|
case 9:
|
|
set_std_table_9(proc_ctx, p_table);
|
|
break;
|
|
|
|
default:
|
|
set_std_table_default(proc_ctx, p_table);
|
|
break;
|
|
}
|
|
}//end of else
|
|
}
|
|
|
|
void hsw_veb_iecp_ace_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
|
|
{
|
|
unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 116);
|
|
|
|
if(!(proc_ctx->filters_mask & VPP_IECP_ACE)){
|
|
memset(p_table, 0, 13 * 4);
|
|
}else{
|
|
*p_table ++ = 0x00000068;
|
|
*p_table ++ = 0x4c382410;
|
|
*p_table ++ = 0x9c887460;
|
|
*p_table ++ = 0xebd8c4b0;
|
|
*p_table ++ = 0x604c3824;
|
|
|
|
*p_table ++ = 0xb09c8874;
|
|
*p_table ++ = 0x0000d8c4;
|
|
*p_table ++ = 0x00000000;
|
|
*p_table ++ = 0x00000000;
|
|
*p_table ++ = 0x00000000;
|
|
|
|
*p_table ++ = 0x00000000;
|
|
*p_table ++ = 0x00000000;
|
|
*p_table ++ = 0x00000000;
|
|
}
|
|
}
|
|
|
|
void hsw_veb_iecp_tcc_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
|
|
{
|
|
unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 168);
|
|
// VAProcFilterParameterBuffer * tcc_param =
|
|
// (VAProcFilterParameterBuffer *) proc_ctx->filter_iecp_tcc;
|
|
|
|
if(!(proc_ctx->filters_mask & VPP_IECP_TCC)){
|
|
memset(p_table, 0, 11 * 4);
|
|
}else{
|
|
*p_table ++ = 0x00000000;
|
|
*p_table ++ = 0x00000000;
|
|
*p_table ++ = 0x1e34cc91;
|
|
*p_table ++ = 0x3e3cce91;
|
|
*p_table ++ = 0x02e80195;
|
|
|
|
*p_table ++ = 0x0197046b;
|
|
*p_table ++ = 0x01790174;
|
|
*p_table ++ = 0x00000000;
|
|
*p_table ++ = 0x00000000;
|
|
*p_table ++ = 0x03030000;
|
|
|
|
*p_table ++ = 0x009201c0;
|
|
}
|
|
}
|
|
|
|
void hsw_veb_iecp_pro_amp_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
|
|
{
|
|
unsigned int contrast = 0x80; //default
|
|
int brightness = 0x00; //default
|
|
int cos_c_s = 256 ; //default
|
|
int sin_c_s = 0; //default
|
|
unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 212);
|
|
|
|
if(!(proc_ctx->filters_mask & VPP_IECP_PRO_AMP)){
|
|
memset(p_table, 0, 2 * 4);
|
|
}else {
|
|
float src_saturation = 1.0;
|
|
float src_hue = 0.0;
|
|
float src_contrast = 1.0;
|
|
float src_brightness = 0.0;
|
|
float tmp_value = 0.0;
|
|
unsigned int i = 0;
|
|
|
|
VAProcFilterParameterBufferColorBalance * amp_params =
|
|
(VAProcFilterParameterBufferColorBalance *) proc_ctx->filter_iecp_amp;
|
|
|
|
for (i = 0; i < proc_ctx->filter_iecp_amp_num_elements; i++){
|
|
VAProcColorBalanceType attrib = amp_params[i].attrib;
|
|
|
|
if(attrib == VAProcColorBalanceHue) {
|
|
src_hue = amp_params[i].value; //(-180.0, 180.0)
|
|
}else if(attrib == VAProcColorBalanceSaturation) {
|
|
src_saturation = amp_params[i].value; //(0.0, 10.0)
|
|
}else if(attrib == VAProcColorBalanceBrightness) {
|
|
src_brightness = amp_params[i].value; // (-100.0, 100.0)
|
|
brightness = intel_format_convert(src_brightness, 7, 4, 1);
|
|
}else if(attrib == VAProcColorBalanceContrast) {
|
|
src_contrast = amp_params[i].value; // (0.0, 10.0)
|
|
contrast = intel_format_convert(src_contrast, 4, 7, 0);
|
|
}
|
|
}
|
|
|
|
tmp_value = cos(src_hue/180*PI) * src_contrast * src_saturation;
|
|
cos_c_s = intel_format_convert(tmp_value, 7, 8, 1);
|
|
|
|
tmp_value = sin(src_hue/180*PI) * src_contrast * src_saturation;
|
|
sin_c_s = intel_format_convert(tmp_value, 7, 8, 1);
|
|
|
|
*p_table ++ = ( 0 << 28 | //reserved
|
|
contrast << 17 | //contrast value (U4.7 format)
|
|
0 << 13 | //reserved
|
|
brightness << 1| // S7.4 format
|
|
1);
|
|
|
|
*p_table ++ = ( cos_c_s << 16 | // cos(h) * contrast * saturation
|
|
sin_c_s); // sin(h) * contrast * saturation
|
|
|
|
}
|
|
}
|
|
|
|
|
|
void hsw_veb_iecp_csc_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
|
|
{
|
|
unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 220);
|
|
float tran_coef[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
|
|
float v_coef[3] = {0.0, 0.0, 0.0};
|
|
float u_coef[3] = {0.0, 0.0, 0.0};
|
|
int is_transform_enabled = 0;
|
|
|
|
if(!(proc_ctx->filters_mask & VPP_IECP_CSC)){
|
|
memset(p_table, 0, 8 * 4);
|
|
return;
|
|
}
|
|
|
|
if(proc_ctx->fourcc_input == VA_FOURCC_RGBA &&
|
|
(proc_ctx->fourcc_output == VA_FOURCC_NV12 ||
|
|
proc_ctx->fourcc_output == VA_FOURCC_YV12 ||
|
|
proc_ctx->fourcc_output == VA_FOURCC_YVY2 ||
|
|
proc_ctx->fourcc_output == VA_FOURCC_AYUV)) {
|
|
|
|
tran_coef[0] = 0.257;
|
|
tran_coef[1] = 0.504;
|
|
tran_coef[2] = 0.098;
|
|
tran_coef[3] = -0.148;
|
|
tran_coef[4] = -0.291;
|
|
tran_coef[5] = 0.439;
|
|
tran_coef[6] = 0.439;
|
|
tran_coef[7] = -0.368;
|
|
tran_coef[8] = -0.071;
|
|
|
|
u_coef[0] = 16 * 4;
|
|
u_coef[1] = 128 * 4;
|
|
u_coef[2] = 128 * 4;
|
|
|
|
is_transform_enabled = 1;
|
|
}else if((proc_ctx->fourcc_input == VA_FOURCC_NV12 ||
|
|
proc_ctx->fourcc_input == VA_FOURCC_YV12 ||
|
|
proc_ctx->fourcc_input == VA_FOURCC_YUY2 ||
|
|
proc_ctx->fourcc_input == VA_FOURCC_AYUV) &&
|
|
proc_ctx->fourcc_output == VA_FOURCC_RGBA) {
|
|
tran_coef[0] = 1.164;
|
|
tran_coef[1] = 0.000;
|
|
tran_coef[2] = 1.569;
|
|
tran_coef[3] = 1.164;
|
|
tran_coef[4] = -0.813;
|
|
tran_coef[5] = -0.392;
|
|
tran_coef[6] = 1.164;
|
|
tran_coef[7] = 2.017;
|
|
tran_coef[8] = 0.000;
|
|
|
|
v_coef[0] = -16 * 4;
|
|
v_coef[1] = -128 * 4;
|
|
v_coef[2] = -128 * 4;
|
|
|
|
is_transform_enabled = 1;
|
|
}else if(proc_ctx->fourcc_input != proc_ctx->fourcc_output){
|
|
//enable when input and output format are different.
|
|
is_transform_enabled = 1;
|
|
}
|
|
|
|
if(is_transform_enabled == 0){
|
|
memset(p_table, 0, 8 * 4);
|
|
}else{
|
|
*p_table ++ = ( 0 << 29 | //reserved
|
|
intel_format_convert(tran_coef[1], 2, 10, 1) << 16 | //c1, s2.10 format
|
|
intel_format_convert(tran_coef[0], 2, 10, 1) << 3 | //c0, s2.10 format
|
|
0 << 2 | //reserved
|
|
0 << 1 | // yuv_channel swap
|
|
is_transform_enabled);
|
|
|
|
*p_table ++ = ( 0 << 26 | //reserved
|
|
intel_format_convert(tran_coef[3], 2, 10, 1) << 13 |
|
|
intel_format_convert(tran_coef[2], 2, 10, 1));
|
|
|
|
*p_table ++ = ( 0 << 26 | //reserved
|
|
intel_format_convert(tran_coef[5], 2, 10, 1) << 13 |
|
|
intel_format_convert(tran_coef[4], 2, 10, 1));
|
|
|
|
*p_table ++ = ( 0 << 26 | //reserved
|
|
intel_format_convert(tran_coef[7], 2, 10, 1) << 13 |
|
|
intel_format_convert(tran_coef[6], 2, 10, 1));
|
|
|
|
*p_table ++ = ( 0 << 13 | //reserved
|
|
intel_format_convert(tran_coef[8], 2, 10, 1));
|
|
|
|
*p_table ++ = ( 0 << 22 | //reserved
|
|
intel_format_convert(u_coef[0], 10, 0, 1) << 11 |
|
|
intel_format_convert(v_coef[0], 10, 0, 1));
|
|
|
|
*p_table ++ = ( 0 << 22 | //reserved
|
|
intel_format_convert(u_coef[1], 10, 0, 1) << 11 |
|
|
intel_format_convert(v_coef[1], 10, 0, 1));
|
|
|
|
*p_table ++ = ( 0 << 22 | //reserved
|
|
intel_format_convert(u_coef[2], 10, 0, 1) << 11 |
|
|
intel_format_convert(v_coef[2], 10, 0, 1));
|
|
}
|
|
}
|
|
|
|
void hsw_veb_iecp_aoi_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
|
|
{
|
|
unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 252);
|
|
// VAProcFilterParameterBuffer * tcc_param =
|
|
// (VAProcFilterParameterBuffer *) proc_ctx->filter_iecp_tcc;
|
|
|
|
if(!(proc_ctx->filters_mask & VPP_IECP_AOI)){
|
|
memset(p_table, 0, 3 * 4);
|
|
}else{
|
|
*p_table ++ = 0x00000000;
|
|
*p_table ++ = 0x00030000;
|
|
*p_table ++ = 0x00030000;
|
|
}
|
|
}
|
|
|
|
void hsw_veb_state_table_setup(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
|
|
{
|
|
if(proc_ctx->filters_mask & VPP_DNDI_MASK) {
|
|
dri_bo *dndi_bo = proc_ctx->dndi_state_table.bo;
|
|
dri_bo_map(dndi_bo, 1);
|
|
proc_ctx->dndi_state_table.ptr = dndi_bo->virtual;
|
|
|
|
hsw_veb_dndi_table(ctx, proc_ctx);
|
|
|
|
dri_bo_unmap(dndi_bo);
|
|
}
|
|
|
|
if(proc_ctx->filters_mask & VPP_IECP_MASK) {
|
|
dri_bo *iecp_bo = proc_ctx->iecp_state_table.bo;
|
|
dri_bo_map(iecp_bo, 1);
|
|
proc_ctx->iecp_state_table.ptr = iecp_bo->virtual;
|
|
|
|
hsw_veb_iecp_std_table(ctx, proc_ctx);
|
|
hsw_veb_iecp_ace_table(ctx, proc_ctx);
|
|
hsw_veb_iecp_tcc_table(ctx, proc_ctx);
|
|
hsw_veb_iecp_pro_amp_table(ctx, proc_ctx);
|
|
hsw_veb_iecp_csc_table(ctx, proc_ctx);
|
|
hsw_veb_iecp_aoi_table(ctx, proc_ctx);
|
|
|
|
dri_bo_unmap(iecp_bo);
|
|
}
|
|
}
|
|
|
|
void hsw_veb_state_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
|
|
{
|
|
struct intel_batchbuffer *batch = proc_ctx->batch;
|
|
|
|
BEGIN_VEB_BATCH(batch, 6);
|
|
OUT_VEB_BATCH(batch, VEB_STATE | (6 - 2));
|
|
OUT_VEB_BATCH(batch,
|
|
0 << 26 | // state surface control bits
|
|
0 << 11 | // reserved.
|
|
0 << 10 | // pipe sync disable
|
|
proc_ctx->current_output_type << 8 | // DI output frame
|
|
1 << 7 | // 444->422 downsample method
|
|
1 << 6 | // 422->420 downsample method
|
|
proc_ctx->is_first_frame << 5 | // DN/DI first frame
|
|
proc_ctx->is_di_enabled << 4 | // DI enable
|
|
proc_ctx->is_dn_enabled << 3 | // DN enable
|
|
proc_ctx->is_iecp_enabled << 2 | // global IECP enabled
|
|
0 << 1 | // ColorGamutCompressionEnable
|
|
0 ) ; // ColorGamutExpansionEnable.
|
|
|
|
OUT_RELOC(batch,
|
|
proc_ctx->dndi_state_table.bo,
|
|
I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
|
|
|
|
OUT_RELOC(batch,
|
|
proc_ctx->iecp_state_table.bo,
|
|
I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
|
|
|
|
OUT_RELOC(batch,
|
|
proc_ctx->gamut_state_table.bo,
|
|
I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
|
|
|
|
OUT_RELOC(batch,
|
|
proc_ctx->vertex_state_table.bo,
|
|
I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
|
|
|
|
ADVANCE_VEB_BATCH(batch);
|
|
}
|
|
|
|
void hsw_veb_surface_state(VADriverContextP ctx, struct intel_vebox_context *proc_ctx, unsigned int is_output)
|
|
{
|
|
struct intel_batchbuffer *batch = proc_ctx->batch;
|
|
unsigned int u_offset_y = 0, v_offset_y = 0;
|
|
unsigned int is_uv_interleaved = 0, tiling = 0, swizzle = 0;
|
|
unsigned int surface_format = PLANAR_420_8;
|
|
struct object_surface* obj_surf = NULL;
|
|
unsigned int surface_pitch = 0;
|
|
unsigned int half_pitch_chroma = 0;
|
|
|
|
if(is_output){
|
|
obj_surf = proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface;
|
|
}else {
|
|
obj_surf = proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface;
|
|
}
|
|
|
|
assert(obj_surf->fourcc == VA_FOURCC_NV12 ||
|
|
obj_surf->fourcc == VA_FOURCC_YUY2 ||
|
|
obj_surf->fourcc == VA_FOURCC_AYUV ||
|
|
obj_surf->fourcc == VA_FOURCC_RGBA);
|
|
|
|
if (obj_surf->fourcc == VA_FOURCC_NV12) {
|
|
surface_format = PLANAR_420_8;
|
|
surface_pitch = obj_surf->width;
|
|
is_uv_interleaved = 1;
|
|
half_pitch_chroma = 0;
|
|
} else if (obj_surf->fourcc == VA_FOURCC_YUY2) {
|
|
surface_format = YCRCB_NORMAL;
|
|
surface_pitch = obj_surf->width * 2;
|
|
is_uv_interleaved = 0;
|
|
half_pitch_chroma = 0;
|
|
} else if (obj_surf->fourcc == VA_FOURCC_AYUV) {
|
|
surface_format = PACKED_444A_8;
|
|
surface_pitch = obj_surf->width * 4;
|
|
is_uv_interleaved = 0;
|
|
half_pitch_chroma = 0;
|
|
} else if (obj_surf->fourcc == VA_FOURCC_RGBA) {
|
|
surface_format = R8G8B8A8_UNORM_SRGB;
|
|
surface_pitch = obj_surf->width * 4;
|
|
is_uv_interleaved = 0;
|
|
half_pitch_chroma = 0;
|
|
}
|
|
|
|
u_offset_y = obj_surf->y_cb_offset;
|
|
v_offset_y = obj_surf->y_cr_offset;
|
|
|
|
dri_bo_get_tiling(obj_surf->bo, &tiling, &swizzle);
|
|
|
|
BEGIN_VEB_BATCH(batch, 6);
|
|
OUT_VEB_BATCH(batch, VEB_SURFACE_STATE | (6 - 2));
|
|
OUT_VEB_BATCH(batch,
|
|
0 << 1 | // reserved
|
|
is_output); // surface indentification.
|
|
|
|
OUT_VEB_BATCH(batch,
|
|
(obj_surf->height - 1) << 18 | // height . w3
|
|
(obj_surf->width -1 ) << 4 | // width
|
|
0); // reserve
|
|
|
|
OUT_VEB_BATCH(batch,
|
|
surface_format << 28 | // surface format, YCbCr420. w4
|
|
is_uv_interleaved << 27 | // interleave chrome , two seperate palar
|
|
0 << 20 | // reserved
|
|
(surface_pitch - 1) << 3 | // surface pitch, 64 align
|
|
half_pitch_chroma << 2 | // half pitch for chrome
|
|
!!tiling << 1 | // tiled surface, linear surface used
|
|
(tiling == I915_TILING_Y)); // tiled walk, ignored when liner surface
|
|
|
|
OUT_VEB_BATCH(batch,
|
|
0 << 29 | // reserved . w5
|
|
0 << 16 | // X offset for V(Cb)
|
|
0 << 15 | // reserved
|
|
u_offset_y); // Y offset for V(Cb)
|
|
|
|
OUT_VEB_BATCH(batch,
|
|
0 << 29 | // reserved . w6
|
|
0 << 16 | // X offset for V(Cr)
|
|
0 << 15 | // reserved
|
|
v_offset_y ); // Y offset for V(Cr)
|
|
|
|
ADVANCE_VEB_BATCH(batch);
|
|
}
|
|
|
|
void hsw_veb_dndi_iecp_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
|
|
{
|
|
struct intel_batchbuffer *batch = proc_ctx->batch;
|
|
unsigned char frame_ctrl_bits = 0;
|
|
const unsigned int width64 = ALIGN(proc_ctx->width_input, 64);
|
|
|
|
/* s1:update the previous and current input */
|
|
/* tempFrame = proc_ctx->frame_store[FRAME_IN_PREVIOUS];
|
|
proc_ctx->frame_store[FRAME_IN_PREVIOUS] = proc_ctx->frame_store[FRAME_IN_CURRENT]; ;
|
|
proc_ctx->frame_store[FRAME_IN_CURRENT] = tempFrame;
|
|
|
|
if(proc_ctx->surface_input_vebox != -1){
|
|
vpp_surface_copy(ctx, proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id,
|
|
proc_ctx->surface_input_vebox);
|
|
} else {
|
|
vpp_surface_copy(ctx, proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id,
|
|
proc_ctx->surface_input);
|
|
}
|
|
*/
|
|
/*s2: update the STMM input and output */
|
|
/* tempFrame = proc_ctx->frame_store[FRAME_IN_STMM];
|
|
proc_ctx->frame_store[FRAME_IN_STMM] = proc_ctx->frame_store[FRAME_OUT_STMM]; ;
|
|
proc_ctx->frame_store[FRAME_OUT_STMM] = tempFrame;
|
|
*/
|
|
/*s3:set reloc buffer address */
|
|
BEGIN_VEB_BATCH(batch, 10);
|
|
OUT_VEB_BATCH(batch, VEB_DNDI_IECP_STATE | (10 - 2));
|
|
OUT_VEB_BATCH(batch, (width64 - 1));
|
|
OUT_RELOC(batch,
|
|
proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface->bo,
|
|
I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);
|
|
OUT_RELOC(batch,
|
|
proc_ctx->frame_store[FRAME_IN_PREVIOUS].obj_surface->bo,
|
|
I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);
|
|
OUT_RELOC(batch,
|
|
proc_ctx->frame_store[FRAME_IN_STMM].obj_surface->bo,
|
|
I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);
|
|
OUT_RELOC(batch,
|
|
proc_ctx->frame_store[FRAME_OUT_STMM].obj_surface->bo,
|
|
I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
|
|
OUT_RELOC(batch,
|
|
proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].obj_surface->bo,
|
|
I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
|
|
OUT_RELOC(batch,
|
|
proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface->bo,
|
|
I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
|
|
OUT_RELOC(batch,
|
|
proc_ctx->frame_store[FRAME_OUT_PREVIOUS].obj_surface->bo,
|
|
I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
|
|
OUT_RELOC(batch,
|
|
proc_ctx->frame_store[FRAME_OUT_STATISTIC].obj_surface->bo,
|
|
I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
|
|
|
|
ADVANCE_VEB_BATCH(batch);
|
|
}
|
|
|
|
static void
|
|
frame_store_reset(VEBFrameStore *fs)
|
|
{
|
|
fs->obj_surface = NULL;
|
|
fs->surface_id = VA_INVALID_ID;
|
|
fs->is_internal_surface = 0;
|
|
fs->is_scratch_surface = 0;
|
|
}
|
|
|
|
static void
|
|
frame_store_clear(VEBFrameStore *fs, VADriverContextP ctx)
|
|
{
|
|
if (fs->obj_surface && fs->is_scratch_surface) {
|
|
VASurfaceID surface_id = fs->obj_surface->base.id;
|
|
i965_DestroySurfaces(ctx, &surface_id, 1);
|
|
}
|
|
frame_store_reset(fs);
|
|
}
|
|
|
|
static VAStatus
|
|
gen75_vebox_ensure_surfaces_storage(VADriverContextP ctx,
|
|
struct intel_vebox_context *proc_ctx)
|
|
{
|
|
struct i965_driver_data * const i965 = i965_driver_data(ctx);
|
|
struct object_surface *input_obj_surface, *output_obj_surface;
|
|
unsigned int input_fourcc, output_fourcc;
|
|
unsigned int input_sampling, output_sampling;
|
|
unsigned int input_tiling, output_tiling;
|
|
unsigned int i, swizzle;
|
|
drm_intel_bo *bo;
|
|
VAStatus status;
|
|
|
|
/* Determine input surface info. Use native VEBOX format whenever
|
|
possible. i.e. when the input surface format is not supported
|
|
by the VEBOX engine, then allocate a temporary surface (live
|
|
during the whole VPP pipeline lifetime)
|
|
|
|
XXX: derive an actual surface format compatible with the input
|
|
surface chroma format */
|
|
input_obj_surface = proc_ctx->surface_input_vebox_object ?
|
|
proc_ctx->surface_input_vebox_object : proc_ctx->surface_input_object;
|
|
if (input_obj_surface->bo) {
|
|
input_fourcc = input_obj_surface->fourcc;
|
|
input_sampling = input_obj_surface->subsampling;
|
|
dri_bo_get_tiling(input_obj_surface->bo, &input_tiling, &swizzle);
|
|
input_tiling = !!input_tiling;
|
|
}
|
|
else {
|
|
input_fourcc = VA_FOURCC_NV12;
|
|
input_sampling = SUBSAMPLE_YUV420;
|
|
input_tiling = 1;
|
|
status = i965_check_alloc_surface_bo(ctx, input_obj_surface,
|
|
input_tiling, input_fourcc, input_sampling);
|
|
if (status != VA_STATUS_SUCCESS)
|
|
return status;
|
|
}
|
|
|
|
/* Determine output surface info.
|
|
|
|
XXX: derive an actual surface format compatible with the input
|
|
surface chroma format */
|
|
output_obj_surface = proc_ctx->surface_output_vebox_object ?
|
|
proc_ctx->surface_output_vebox_object : proc_ctx->surface_output_object;
|
|
if (output_obj_surface->bo) {
|
|
output_fourcc = output_obj_surface->fourcc;
|
|
output_sampling = output_obj_surface->subsampling;
|
|
dri_bo_get_tiling(output_obj_surface->bo, &output_tiling, &swizzle);
|
|
output_tiling = !!output_tiling;
|
|
}
|
|
else {
|
|
output_fourcc = VA_FOURCC_NV12;
|
|
output_sampling = SUBSAMPLE_YUV420;
|
|
output_tiling = 1;
|
|
status = i965_check_alloc_surface_bo(ctx, output_obj_surface,
|
|
output_tiling, output_fourcc, output_sampling);
|
|
if (status != VA_STATUS_SUCCESS)
|
|
return status;
|
|
}
|
|
|
|
/* Update VEBOX pipeline formats */
|
|
proc_ctx->fourcc_input = input_fourcc;
|
|
proc_ctx->fourcc_output = output_fourcc;
|
|
if (input_fourcc != output_fourcc)
|
|
proc_ctx->is_iecp_enabled = 1; // IECP needed for format conversion
|
|
|
|
/* Create pipeline surfaces */
|
|
for (i = 0; i < ARRAY_ELEMS(proc_ctx->frame_store); i ++) {
|
|
struct object_surface *obj_surface;
|
|
VASurfaceID new_surface;
|
|
|
|
if (proc_ctx->frame_store[i].obj_surface)
|
|
continue; // user allocated surface, not VEBOX internal
|
|
|
|
status = i965_CreateSurfaces(ctx, proc_ctx->width_input,
|
|
proc_ctx->height_input, VA_RT_FORMAT_YUV420, 1, &new_surface);
|
|
if (status != VA_STATUS_SUCCESS)
|
|
return status;
|
|
|
|
obj_surface = SURFACE(new_surface);
|
|
assert(obj_surface != NULL);
|
|
|
|
if (i <= FRAME_IN_PREVIOUS || i == FRAME_OUT_CURRENT_DN) {
|
|
status = i965_check_alloc_surface_bo(ctx, obj_surface,
|
|
input_tiling, input_fourcc, input_sampling);
|
|
}
|
|
else if (i == FRAME_IN_STMM || i == FRAME_OUT_STMM) {
|
|
status = i965_check_alloc_surface_bo(ctx, obj_surface,
|
|
1, input_fourcc, input_sampling);
|
|
}
|
|
else if (i >= FRAME_OUT_CURRENT) {
|
|
status = i965_check_alloc_surface_bo(ctx, obj_surface,
|
|
output_tiling, output_fourcc, output_sampling);
|
|
}
|
|
if (status != VA_STATUS_SUCCESS)
|
|
return status;
|
|
|
|
proc_ctx->frame_store[i].obj_surface = obj_surface;
|
|
proc_ctx->frame_store[i].is_internal_surface = 1;
|
|
proc_ctx->frame_store[i].is_scratch_surface = 1;
|
|
}
|
|
|
|
/* Allocate DNDI state table */
|
|
drm_intel_bo_unreference(proc_ctx->dndi_state_table.bo);
|
|
bo = drm_intel_bo_alloc(i965->intel.bufmgr, "vebox: dndi state Buffer",
|
|
0x1000, 0x1000);
|
|
proc_ctx->dndi_state_table.bo = bo;
|
|
if (!bo)
|
|
return VA_STATUS_ERROR_ALLOCATION_FAILED;
|
|
|
|
/* Allocate IECP state table */
|
|
drm_intel_bo_unreference(proc_ctx->iecp_state_table.bo);
|
|
bo = drm_intel_bo_alloc(i965->intel.bufmgr, "vebox: iecp state Buffer",
|
|
0x1000, 0x1000);
|
|
proc_ctx->iecp_state_table.bo = bo;
|
|
if (!bo)
|
|
return VA_STATUS_ERROR_ALLOCATION_FAILED;
|
|
|
|
/* Allocate Gamut state table */
|
|
drm_intel_bo_unreference(proc_ctx->gamut_state_table.bo);
|
|
bo = drm_intel_bo_alloc(i965->intel.bufmgr, "vebox: gamut state Buffer",
|
|
0x1000, 0x1000);
|
|
proc_ctx->gamut_state_table.bo = bo;
|
|
if (!bo)
|
|
return VA_STATUS_ERROR_ALLOCATION_FAILED;
|
|
|
|
/* Allocate vertex state table */
|
|
drm_intel_bo_unreference(proc_ctx->vertex_state_table.bo);
|
|
bo = drm_intel_bo_alloc(i965->intel.bufmgr, "vebox: vertex state Buffer",
|
|
0x1000, 0x1000);
|
|
proc_ctx->vertex_state_table.bo = bo;
|
|
if (!bo)
|
|
return VA_STATUS_ERROR_ALLOCATION_FAILED;
|
|
|
|
return VA_STATUS_SUCCESS;
|
|
}
|
|
|
|
static VAStatus
|
|
gen75_vebox_ensure_surfaces(VADriverContextP ctx,
|
|
struct intel_vebox_context *proc_ctx)
|
|
{
|
|
struct i965_driver_data * const i965 = i965_driver_data(ctx);
|
|
struct object_surface *obj_surface;
|
|
VEBFrameStore *ifs, *ofs;
|
|
bool is_new_frame = 0;
|
|
int i;
|
|
|
|
/* Update the previous input surface */
|
|
obj_surface = proc_ctx->surface_input_object;
|
|
|
|
is_new_frame = proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id !=
|
|
obj_surface->base.id;
|
|
if (is_new_frame) {
|
|
ifs = &proc_ctx->frame_store[FRAME_IN_PREVIOUS];
|
|
ofs = &proc_ctx->frame_store[proc_ctx->is_dn_enabled ?
|
|
FRAME_OUT_CURRENT_DN : FRAME_IN_CURRENT];
|
|
do {
|
|
const VAProcPipelineParameterBuffer * const pipe =
|
|
proc_ctx->pipeline_param;
|
|
|
|
if (pipe->num_forward_references < 1)
|
|
break;
|
|
if (pipe->forward_references[0] == VA_INVALID_ID)
|
|
break;
|
|
|
|
obj_surface = SURFACE(pipe->forward_references[0]);
|
|
if (!obj_surface || obj_surface->base.id == ifs->surface_id)
|
|
break;
|
|
|
|
frame_store_clear(ifs, ctx);
|
|
if (obj_surface->base.id == ofs->surface_id) {
|
|
*ifs = *ofs;
|
|
frame_store_reset(ofs);
|
|
}
|
|
else {
|
|
ifs->obj_surface = obj_surface;
|
|
ifs->surface_id = obj_surface->base.id;
|
|
ifs->is_internal_surface = 0;
|
|
ifs->is_scratch_surface = 0;
|
|
}
|
|
} while (0);
|
|
}
|
|
|
|
/* Update the input surface */
|
|
obj_surface = proc_ctx->surface_input_vebox_object ?
|
|
proc_ctx->surface_input_vebox_object : proc_ctx->surface_input_object;
|
|
|
|
ifs = &proc_ctx->frame_store[FRAME_IN_CURRENT];
|
|
frame_store_clear(ifs, ctx);
|
|
ifs->obj_surface = obj_surface;
|
|
ifs->surface_id = proc_ctx->surface_input_object->base.id;
|
|
ifs->is_internal_surface = proc_ctx->surface_input_vebox_object != NULL;
|
|
ifs->is_scratch_surface = 0;
|
|
|
|
/* Update the Spatial Temporal Motion Measure (STMM) surfaces */
|
|
if (is_new_frame) {
|
|
const VEBFrameStore tmpfs = proc_ctx->frame_store[FRAME_IN_STMM];
|
|
proc_ctx->frame_store[FRAME_IN_STMM] =
|
|
proc_ctx->frame_store[FRAME_OUT_STMM];
|
|
proc_ctx->frame_store[FRAME_OUT_STMM] = tmpfs;
|
|
}
|
|
|
|
/* Reset the output surfaces to defaults. i.e. clean from user surfaces */
|
|
for (i = FRAME_OUT_CURRENT_DN; i <= FRAME_OUT_PREVIOUS; i++) {
|
|
ofs = &proc_ctx->frame_store[i];
|
|
if (!ofs->is_scratch_surface)
|
|
ofs->obj_surface = NULL;
|
|
ofs->surface_id = proc_ctx->surface_input_object->base.id;
|
|
}
|
|
|
|
/* Update the output surfaces */
|
|
obj_surface = proc_ctx->surface_output_vebox_object ?
|
|
proc_ctx->surface_output_vebox_object : proc_ctx->surface_output_object;
|
|
|
|
proc_ctx->current_output_type = 2;
|
|
if (proc_ctx->filters_mask == VPP_DNDI_DN && !proc_ctx->is_iecp_enabled)
|
|
proc_ctx->current_output = FRAME_OUT_CURRENT_DN;
|
|
else if (proc_ctx->is_di_adv_enabled && !proc_ctx->is_first_frame) {
|
|
proc_ctx->current_output_type = 0;
|
|
proc_ctx->current_output = proc_ctx->is_second_field ?
|
|
FRAME_OUT_CURRENT : FRAME_OUT_PREVIOUS;
|
|
}
|
|
else
|
|
proc_ctx->current_output = FRAME_OUT_CURRENT;
|
|
ofs = &proc_ctx->frame_store[proc_ctx->current_output];
|
|
frame_store_clear(ofs, ctx);
|
|
ofs->obj_surface = obj_surface;
|
|
ofs->surface_id = proc_ctx->surface_input_object->base.id;
|
|
ofs->is_internal_surface = proc_ctx->surface_output_vebox_object != NULL;
|
|
ofs->is_scratch_surface = 0;
|
|
|
|
return VA_STATUS_SUCCESS;
|
|
}
|
|
|
|
int hsw_veb_pre_format_convert(VADriverContextP ctx,
|
|
struct intel_vebox_context *proc_ctx)
|
|
{
|
|
VAStatus va_status;
|
|
struct i965_driver_data *i965 = i965_driver_data(ctx);
|
|
struct object_surface* obj_surf_input = proc_ctx->surface_input_object;
|
|
struct object_surface* obj_surf_output = proc_ctx->surface_output_object;
|
|
struct object_surface* obj_surf_input_vebox;
|
|
struct object_surface* obj_surf_output_vebox;
|
|
|
|
proc_ctx->format_convert_flags = 0;
|
|
|
|
proc_ctx->width_input = obj_surf_input->orig_width;
|
|
proc_ctx->height_input = obj_surf_input->orig_height;
|
|
proc_ctx->width_output = obj_surf_output->orig_width;
|
|
proc_ctx->height_output = obj_surf_output->orig_height;
|
|
|
|
/* only partial frame is not supported to be processed */
|
|
/*
|
|
assert(proc_ctx->width_input == proc_ctx->pipeline_param->surface_region->width);
|
|
assert(proc_ctx->height_input == proc_ctx->pipeline_param->surface_region->height);
|
|
assert(proc_ctx->width_output == proc_ctx->pipeline_param->output_region->width);
|
|
assert(proc_ctx->height_output == proc_ctx->pipeline_param->output_region->height);
|
|
*/
|
|
|
|
if(proc_ctx->width_output != proc_ctx->width_input ||
|
|
proc_ctx->height_output != proc_ctx->height_input){
|
|
proc_ctx->format_convert_flags |= POST_SCALING_CONVERT;
|
|
}
|
|
|
|
/* convert the following format to NV12 format */
|
|
if(obj_surf_input->fourcc == VA_FOURCC_YV12 ||
|
|
obj_surf_input->fourcc == VA_FOURCC_I420 ||
|
|
obj_surf_input->fourcc == VA_FOURCC_IMC1 ||
|
|
obj_surf_input->fourcc == VA_FOURCC_IMC3 ||
|
|
obj_surf_input->fourcc == VA_FOURCC_RGBA ||
|
|
obj_surf_input->fourcc == VA_FOURCC_BGRA){
|
|
|
|
proc_ctx->format_convert_flags |= PRE_FORMAT_CONVERT;
|
|
|
|
} else if(obj_surf_input->fourcc == VA_FOURCC_AYUV ||
|
|
obj_surf_input->fourcc == VA_FOURCC_YUY2 ||
|
|
obj_surf_input->fourcc == VA_FOURCC_NV12){
|
|
// nothing to do here
|
|
} else {
|
|
/* not support other format as input */
|
|
assert(0);
|
|
}
|
|
|
|
if (proc_ctx->format_convert_flags & PRE_FORMAT_CONVERT) {
|
|
if(proc_ctx->surface_input_vebox_object == NULL){
|
|
va_status = i965_CreateSurfaces(ctx,
|
|
proc_ctx->width_input,
|
|
proc_ctx->height_input,
|
|
VA_RT_FORMAT_YUV420,
|
|
1,
|
|
&(proc_ctx->surface_input_vebox));
|
|
assert(va_status == VA_STATUS_SUCCESS);
|
|
obj_surf_input_vebox = SURFACE(proc_ctx->surface_input_vebox);
|
|
assert(obj_surf_input_vebox);
|
|
|
|
if (obj_surf_input_vebox) {
|
|
proc_ctx->surface_input_vebox_object = obj_surf_input_vebox;
|
|
i965_check_alloc_surface_bo(ctx, obj_surf_input_vebox, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
|
|
}
|
|
}
|
|
|
|
vpp_surface_convert(ctx, proc_ctx->surface_input_object, proc_ctx->surface_input_vebox_object);
|
|
}
|
|
|
|
/* create one temporary NV12 surfaces for conversion*/
|
|
if(obj_surf_output->fourcc == VA_FOURCC_YV12 ||
|
|
obj_surf_output->fourcc == VA_FOURCC_I420 ||
|
|
obj_surf_output->fourcc == VA_FOURCC_IMC1 ||
|
|
obj_surf_output->fourcc == VA_FOURCC_IMC3 ||
|
|
obj_surf_output->fourcc == VA_FOURCC_RGBA ||
|
|
obj_surf_output->fourcc == VA_FOURCC_BGRA) {
|
|
|
|
proc_ctx->format_convert_flags |= POST_FORMAT_CONVERT;
|
|
} else if(obj_surf_output->fourcc == VA_FOURCC_AYUV ||
|
|
obj_surf_output->fourcc == VA_FOURCC_YUY2 ||
|
|
obj_surf_output->fourcc == VA_FOURCC_NV12){
|
|
/* Nothing to do here */
|
|
} else {
|
|
/* not support other format as input */
|
|
assert(0);
|
|
}
|
|
|
|
if(proc_ctx->format_convert_flags & POST_FORMAT_CONVERT ||
|
|
proc_ctx->format_convert_flags & POST_SCALING_CONVERT){
|
|
if(proc_ctx->surface_output_vebox_object == NULL){
|
|
va_status = i965_CreateSurfaces(ctx,
|
|
proc_ctx->width_input,
|
|
proc_ctx->height_input,
|
|
VA_RT_FORMAT_YUV420,
|
|
1,
|
|
&(proc_ctx->surface_output_vebox));
|
|
assert(va_status == VA_STATUS_SUCCESS);
|
|
obj_surf_output_vebox = SURFACE(proc_ctx->surface_output_vebox);
|
|
assert(obj_surf_output_vebox);
|
|
|
|
if (obj_surf_output_vebox) {
|
|
proc_ctx->surface_output_vebox_object = obj_surf_output_vebox;
|
|
i965_check_alloc_surface_bo(ctx, obj_surf_output_vebox, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(proc_ctx->format_convert_flags & POST_SCALING_CONVERT){
|
|
if(proc_ctx->surface_output_scaled_object == NULL){
|
|
va_status = i965_CreateSurfaces(ctx,
|
|
proc_ctx->width_output,
|
|
proc_ctx->height_output,
|
|
VA_RT_FORMAT_YUV420,
|
|
1,
|
|
&(proc_ctx->surface_output_scaled));
|
|
assert(va_status == VA_STATUS_SUCCESS);
|
|
obj_surf_output_vebox = SURFACE(proc_ctx->surface_output_scaled);
|
|
assert(obj_surf_output_vebox);
|
|
|
|
if (obj_surf_output_vebox) {
|
|
proc_ctx->surface_output_scaled_object = obj_surf_output_vebox;
|
|
i965_check_alloc_surface_bo(ctx, obj_surf_output_vebox, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int hsw_veb_post_format_convert(VADriverContextP ctx,
|
|
struct intel_vebox_context *proc_ctx)
|
|
{
|
|
struct object_surface *obj_surface = NULL;
|
|
|
|
obj_surface = proc_ctx->frame_store[proc_ctx->current_output].obj_surface;
|
|
|
|
if (proc_ctx->format_convert_flags & POST_COPY_CONVERT) {
|
|
/* copy the saved frame in the second call */
|
|
vpp_surface_convert(ctx, obj_surface, proc_ctx->surface_output_object);
|
|
} else if(!(proc_ctx->format_convert_flags & POST_FORMAT_CONVERT) &&
|
|
!(proc_ctx->format_convert_flags & POST_SCALING_CONVERT)){
|
|
/* Output surface format is covered by vebox pipeline and
|
|
* processed picture is already store in output surface
|
|
* so nothing will be done here */
|
|
} else if ((proc_ctx->format_convert_flags & POST_FORMAT_CONVERT) &&
|
|
!(proc_ctx->format_convert_flags & POST_SCALING_CONVERT)){
|
|
/* convert and copy NV12 to YV12/IMC3/IMC2/RGBA output*/
|
|
vpp_surface_convert(ctx, obj_surface, proc_ctx->surface_output_object);
|
|
|
|
} else if(proc_ctx->format_convert_flags & POST_SCALING_CONVERT) {
|
|
VAProcPipelineParameterBuffer * const pipe = proc_ctx->pipeline_param;
|
|
/* scaling, convert and copy NV12 to YV12/IMC3/IMC2/RGBA output*/
|
|
assert(obj_surface->fourcc == VA_FOURCC_NV12);
|
|
|
|
/* first step :surface scaling */
|
|
vpp_surface_scaling(ctx, obj_surface,
|
|
proc_ctx->surface_output_scaled_object, pipe->filter_flags);
|
|
|
|
/* second step: color format convert and copy to output */
|
|
obj_surface = proc_ctx->surface_output_object;
|
|
|
|
if(obj_surface->fourcc == VA_FOURCC_NV12 ||
|
|
obj_surface->fourcc == VA_FOURCC_YV12 ||
|
|
obj_surface->fourcc == VA_FOURCC_I420 ||
|
|
obj_surface->fourcc == VA_FOURCC_YUY2 ||
|
|
obj_surface->fourcc == VA_FOURCC_IMC1 ||
|
|
obj_surface->fourcc == VA_FOURCC_IMC3 ||
|
|
obj_surface->fourcc == VA_FOURCC_RGBA) {
|
|
vpp_surface_convert(ctx, proc_ctx->surface_output_scaled_object, obj_surface);
|
|
}else {
|
|
assert(0);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static VAStatus
|
|
gen75_vebox_init_pipe_params(VADriverContextP ctx,
|
|
struct intel_vebox_context *proc_ctx)
|
|
{
|
|
struct i965_driver_data * const i965 = i965_driver_data(ctx);
|
|
const VAProcPipelineParameterBuffer * const pipe = proc_ctx->pipeline_param;
|
|
VAProcFilterParameterBuffer *filter;
|
|
unsigned int i;
|
|
|
|
proc_ctx->filters_mask = 0;
|
|
for (i = 0; i < pipe->num_filters; i++) {
|
|
struct object_buffer * const obj_buffer = BUFFER(pipe->filters[i]);
|
|
|
|
assert(obj_buffer && obj_buffer->buffer_store);
|
|
if (!obj_buffer || !obj_buffer->buffer_store)
|
|
return VA_STATUS_ERROR_INVALID_PARAMETER;
|
|
|
|
filter = (VAProcFilterParameterBuffer *)
|
|
obj_buffer->buffer_store->buffer;
|
|
switch (filter->type) {
|
|
case VAProcFilterNoiseReduction:
|
|
proc_ctx->filters_mask |= VPP_DNDI_DN;
|
|
proc_ctx->filter_dn = filter;
|
|
break;
|
|
case VAProcFilterDeinterlacing:
|
|
proc_ctx->filters_mask |= VPP_DNDI_DI;
|
|
proc_ctx->filter_di = filter;
|
|
break;
|
|
case VAProcFilterColorBalance:
|
|
proc_ctx->filters_mask |= VPP_IECP_PRO_AMP;
|
|
proc_ctx->filter_iecp_amp = filter;
|
|
proc_ctx->filter_iecp_amp_num_elements = obj_buffer->num_elements;
|
|
break;
|
|
case VAProcFilterSkinToneEnhancement:
|
|
proc_ctx->filters_mask |= VPP_IECP_STD_STE;
|
|
proc_ctx->filter_iecp_std = filter;
|
|
break;
|
|
default:
|
|
WARN_ONCE("unsupported filter (type: %d)\n", filter->type);
|
|
return VA_STATUS_ERROR_UNSUPPORTED_FILTER;
|
|
}
|
|
}
|
|
return VA_STATUS_SUCCESS;
|
|
}
|
|
|
|
static VAStatus
|
|
gen75_vebox_init_filter_params(VADriverContextP ctx,
|
|
struct intel_vebox_context *proc_ctx)
|
|
{
|
|
proc_ctx->format_convert_flags = 0; /* initialized in hsw_veb_pre_format_convert() */
|
|
|
|
proc_ctx->is_iecp_enabled = (proc_ctx->filters_mask & VPP_IECP_MASK) != 0;
|
|
proc_ctx->is_dn_enabled = (proc_ctx->filters_mask & VPP_DNDI_DN) != 0;
|
|
proc_ctx->is_di_enabled = (proc_ctx->filters_mask & VPP_DNDI_DI) != 0;
|
|
proc_ctx->is_di_adv_enabled = 0;
|
|
proc_ctx->is_first_frame = 0;
|
|
proc_ctx->is_second_field = 0;
|
|
|
|
/* Check whether we are deinterlacing the second field */
|
|
if (proc_ctx->is_di_enabled) {
|
|
const VAProcFilterParameterBufferDeinterlacing * const deint_params =
|
|
proc_ctx->filter_di;
|
|
|
|
const unsigned int tff =
|
|
!(deint_params->flags & VA_DEINTERLACING_BOTTOM_FIELD_FIRST);
|
|
const unsigned int is_top_field =
|
|
!(deint_params->flags & VA_DEINTERLACING_BOTTOM_FIELD);
|
|
|
|
if ((tff ^ is_top_field) != 0) {
|
|
struct object_surface * const obj_surface =
|
|
proc_ctx->surface_input_object;
|
|
|
|
if (proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id != obj_surface->base.id) {
|
|
WARN_ONCE("invalid surface provided for second field\n");
|
|
return VA_STATUS_ERROR_INVALID_PARAMETER;
|
|
}
|
|
proc_ctx->is_second_field = 1;
|
|
}
|
|
}
|
|
|
|
/* Check whether we are deinterlacing the first frame */
|
|
if (proc_ctx->is_di_enabled) {
|
|
const VAProcFilterParameterBufferDeinterlacing * const deint_params =
|
|
proc_ctx->filter_di;
|
|
|
|
switch (deint_params->algorithm) {
|
|
case VAProcDeinterlacingBob:
|
|
proc_ctx->is_first_frame = 1;
|
|
break;
|
|
case VAProcDeinterlacingMotionAdaptive:
|
|
case VAProcDeinterlacingMotionCompensated:
|
|
if (proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id == VA_INVALID_ID)
|
|
proc_ctx->is_first_frame = 1;
|
|
else if (proc_ctx->is_second_field) {
|
|
/* At this stage, we have already deinterlaced the
|
|
first field successfully. So, the first frame flag
|
|
is trigerred if the previous field was deinterlaced
|
|
without reference frame */
|
|
if (proc_ctx->frame_store[FRAME_IN_PREVIOUS].surface_id == VA_INVALID_ID)
|
|
proc_ctx->is_first_frame = 1;
|
|
}
|
|
else {
|
|
const VAProcPipelineParameterBuffer * const pipe =
|
|
proc_ctx->pipeline_param;
|
|
|
|
if (pipe->num_forward_references < 1 ||
|
|
pipe->forward_references[0] == VA_INVALID_ID) {
|
|
WARN_ONCE("A forward temporal reference is needed for Motion adaptive/compensated deinterlacing !!!\n");
|
|
return VA_STATUS_ERROR_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
proc_ctx->is_di_adv_enabled = 1;
|
|
break;
|
|
default:
|
|
WARN_ONCE("unsupported deinterlacing algorithm (%d)\n",
|
|
deint_params->algorithm);
|
|
return VA_STATUS_ERROR_UNSUPPORTED_FILTER;
|
|
}
|
|
}
|
|
return VA_STATUS_SUCCESS;
|
|
}
|
|
|
|
VAStatus
|
|
gen75_vebox_process_picture(VADriverContextP ctx,
|
|
struct intel_vebox_context *proc_ctx)
|
|
{
|
|
VAStatus status;
|
|
|
|
status = gen75_vebox_init_pipe_params(ctx, proc_ctx);
|
|
if (status != VA_STATUS_SUCCESS)
|
|
return status;
|
|
|
|
status = gen75_vebox_init_filter_params(ctx, proc_ctx);
|
|
if (status != VA_STATUS_SUCCESS)
|
|
return status;
|
|
|
|
hsw_veb_pre_format_convert(ctx, proc_ctx);
|
|
|
|
status = gen75_vebox_ensure_surfaces(ctx, proc_ctx);
|
|
if (status != VA_STATUS_SUCCESS)
|
|
return status;
|
|
|
|
status = gen75_vebox_ensure_surfaces_storage(ctx, proc_ctx);
|
|
if (status != VA_STATUS_SUCCESS)
|
|
return status;
|
|
|
|
if (proc_ctx->format_convert_flags & POST_COPY_CONVERT) {
|
|
assert(proc_ctx->is_second_field);
|
|
/* directly copy the saved frame in the second call */
|
|
} else {
|
|
intel_batchbuffer_start_atomic_veb(proc_ctx->batch, 0x1000);
|
|
intel_batchbuffer_emit_mi_flush(proc_ctx->batch);
|
|
hsw_veb_state_table_setup(ctx, proc_ctx);
|
|
hsw_veb_state_command(ctx, proc_ctx);
|
|
hsw_veb_surface_state(ctx, proc_ctx, INPUT_SURFACE);
|
|
hsw_veb_surface_state(ctx, proc_ctx, OUTPUT_SURFACE);
|
|
hsw_veb_dndi_iecp_command(ctx, proc_ctx);
|
|
intel_batchbuffer_end_atomic(proc_ctx->batch);
|
|
intel_batchbuffer_flush(proc_ctx->batch);
|
|
}
|
|
|
|
hsw_veb_post_format_convert(ctx, proc_ctx);
|
|
|
|
return VA_STATUS_SUCCESS;
|
|
}
|
|
|
|
void gen75_vebox_context_destroy(VADriverContextP ctx,
|
|
struct intel_vebox_context *proc_ctx)
|
|
{
|
|
int i;
|
|
|
|
if(proc_ctx->surface_input_vebox != VA_INVALID_ID){
|
|
i965_DestroySurfaces(ctx, &proc_ctx->surface_input_vebox, 1);
|
|
proc_ctx->surface_input_vebox = VA_INVALID_ID;
|
|
proc_ctx->surface_input_vebox_object = NULL;
|
|
}
|
|
|
|
if(proc_ctx->surface_output_vebox != VA_INVALID_ID){
|
|
i965_DestroySurfaces(ctx, &proc_ctx->surface_output_vebox, 1);
|
|
proc_ctx->surface_output_vebox = VA_INVALID_ID;
|
|
proc_ctx->surface_output_vebox_object = NULL;
|
|
}
|
|
|
|
if(proc_ctx->surface_output_scaled != VA_INVALID_ID){
|
|
i965_DestroySurfaces(ctx, &proc_ctx->surface_output_scaled, 1);
|
|
proc_ctx->surface_output_scaled = VA_INVALID_ID;
|
|
proc_ctx->surface_output_scaled_object = NULL;
|
|
}
|
|
|
|
for (i = 0; i < ARRAY_ELEMS(proc_ctx->frame_store); i++)
|
|
frame_store_clear(&proc_ctx->frame_store[i], ctx);
|
|
|
|
/* dndi state table */
|
|
drm_intel_bo_unreference(proc_ctx->dndi_state_table.bo);
|
|
proc_ctx->dndi_state_table.bo = NULL;
|
|
|
|
/* iecp state table */
|
|
drm_intel_bo_unreference(proc_ctx->iecp_state_table.bo);
|
|
proc_ctx->iecp_state_table.bo = NULL;
|
|
|
|
/* gamut statu table */
|
|
drm_intel_bo_unreference(proc_ctx->gamut_state_table.bo);
|
|
proc_ctx->gamut_state_table.bo = NULL;
|
|
|
|
/* vertex state table */
|
|
drm_intel_bo_unreference(proc_ctx->vertex_state_table.bo);
|
|
proc_ctx->vertex_state_table.bo = NULL;
|
|
|
|
intel_batchbuffer_free(proc_ctx->batch);
|
|
|
|
free(proc_ctx);
|
|
}
|
|
|
|
struct intel_vebox_context * gen75_vebox_context_init(VADriverContextP ctx)
|
|
{
|
|
struct intel_driver_data *intel = intel_driver_data(ctx);
|
|
struct intel_vebox_context *proc_context = calloc(1, sizeof(struct intel_vebox_context));
|
|
int i;
|
|
|
|
assert(proc_context);
|
|
proc_context->batch = intel_batchbuffer_new(intel, I915_EXEC_VEBOX, 0);
|
|
|
|
for (i = 0; i < ARRAY_ELEMS(proc_context->frame_store); i++)
|
|
proc_context->frame_store[i].surface_id = VA_INVALID_ID;
|
|
|
|
proc_context->filters_mask = 0;
|
|
proc_context->surface_output_object = NULL;
|
|
proc_context->surface_input_object = NULL;
|
|
proc_context->surface_input_vebox = VA_INVALID_ID;
|
|
proc_context->surface_input_vebox_object = NULL;
|
|
proc_context->surface_output_vebox = VA_INVALID_ID;
|
|
proc_context->surface_output_vebox_object = NULL;
|
|
proc_context->surface_output_scaled = VA_INVALID_ID;
|
|
proc_context->surface_output_scaled_object = NULL;
|
|
proc_context->filters_mask = 0;
|
|
proc_context->format_convert_flags = 0;
|
|
|
|
return proc_context;
|
|
}
|
|
|
|
void bdw_veb_state_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
|
|
{
|
|
struct intel_batchbuffer *batch = proc_ctx->batch;
|
|
|
|
BEGIN_VEB_BATCH(batch, 0xc);
|
|
OUT_VEB_BATCH(batch, VEB_STATE | (0xc - 2));
|
|
OUT_VEB_BATCH(batch,
|
|
0 << 25 | // state surface control bits
|
|
0 << 23 | // reserved.
|
|
0 << 22 | // gamut expansion position
|
|
0 << 15 | // reserved.
|
|
0 << 14 | // single slice vebox enable
|
|
0 << 13 | // hot pixel filter enable
|
|
0 << 12 | // alpha plane enable
|
|
0 << 11 | // vignette enable
|
|
0 << 10 | // demosaic enable
|
|
proc_ctx->current_output_type << 8 | // DI output frame
|
|
1 << 7 | // 444->422 downsample method
|
|
1 << 6 | // 422->420 downsample method
|
|
proc_ctx->is_first_frame << 5 | // DN/DI first frame
|
|
proc_ctx->is_di_enabled << 4 | // DI enable
|
|
proc_ctx->is_dn_enabled << 3 | // DN enable
|
|
proc_ctx->is_iecp_enabled << 2 | // global IECP enabled
|
|
0 << 1 | // ColorGamutCompressionEnable
|
|
0 ) ; // ColorGamutExpansionEnable.
|
|
|
|
OUT_RELOC(batch,
|
|
proc_ctx->dndi_state_table.bo,
|
|
I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
|
|
|
|
OUT_VEB_BATCH(batch, 0);
|
|
|
|
OUT_RELOC(batch,
|
|
proc_ctx->iecp_state_table.bo,
|
|
I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
|
|
|
|
OUT_VEB_BATCH(batch, 0);
|
|
|
|
OUT_RELOC(batch,
|
|
proc_ctx->gamut_state_table.bo,
|
|
I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
|
|
|
|
OUT_VEB_BATCH(batch, 0);
|
|
|
|
OUT_RELOC(batch,
|
|
proc_ctx->vertex_state_table.bo,
|
|
I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
|
|
|
|
OUT_VEB_BATCH(batch, 0);
|
|
|
|
OUT_VEB_BATCH(batch, 0);/*caputre pipe state pointer*/
|
|
OUT_VEB_BATCH(batch, 0);
|
|
|
|
ADVANCE_VEB_BATCH(batch);
|
|
}
|
|
|
|
void bdw_veb_dndi_iecp_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
|
|
{
|
|
struct intel_batchbuffer *batch = proc_ctx->batch;
|
|
unsigned char frame_ctrl_bits = 0;
|
|
const unsigned int width64 = ALIGN(proc_ctx->width_input, 64);
|
|
|
|
BEGIN_VEB_BATCH(batch, 0x14);
|
|
OUT_VEB_BATCH(batch, VEB_DNDI_IECP_STATE | (0x14 - 2));//DWord 0
|
|
OUT_VEB_BATCH(batch, (width64 - 1));
|
|
|
|
OUT_RELOC(batch,
|
|
proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface->bo,
|
|
I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);//DWord 2
|
|
OUT_VEB_BATCH(batch,0);//DWord 3
|
|
|
|
OUT_RELOC(batch,
|
|
proc_ctx->frame_store[FRAME_IN_PREVIOUS].obj_surface->bo,
|
|
I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);//DWord 4
|
|
OUT_VEB_BATCH(batch,0);//DWord 5
|
|
|
|
OUT_RELOC(batch,
|
|
proc_ctx->frame_store[FRAME_IN_STMM].obj_surface->bo,
|
|
I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);//DWord 6
|
|
OUT_VEB_BATCH(batch,0);//DWord 7
|
|
|
|
OUT_RELOC(batch,
|
|
proc_ctx->frame_store[FRAME_OUT_STMM].obj_surface->bo,
|
|
I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 8
|
|
OUT_VEB_BATCH(batch,0);//DWord 9
|
|
|
|
OUT_RELOC(batch,
|
|
proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].obj_surface->bo,
|
|
I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 10
|
|
OUT_VEB_BATCH(batch,0);//DWord 11
|
|
|
|
OUT_RELOC(batch,
|
|
proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface->bo,
|
|
I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 12
|
|
OUT_VEB_BATCH(batch,0);//DWord 13
|
|
|
|
OUT_RELOC(batch,
|
|
proc_ctx->frame_store[FRAME_OUT_PREVIOUS].obj_surface->bo,
|
|
I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 14
|
|
OUT_VEB_BATCH(batch,0);//DWord 15
|
|
|
|
OUT_RELOC(batch,
|
|
proc_ctx->frame_store[FRAME_OUT_STATISTIC].obj_surface->bo,
|
|
I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 16
|
|
OUT_VEB_BATCH(batch,0);//DWord 17
|
|
|
|
OUT_VEB_BATCH(batch,0);//DWord 18
|
|
OUT_VEB_BATCH(batch,0);//DWord 19
|
|
|
|
ADVANCE_VEB_BATCH(batch);
|
|
}
|
|
|
|
VAStatus
|
|
gen8_vebox_process_picture(VADriverContextP ctx,
|
|
struct intel_vebox_context *proc_ctx)
|
|
{
|
|
VAStatus status;
|
|
|
|
status = gen75_vebox_init_pipe_params(ctx, proc_ctx);
|
|
if (status != VA_STATUS_SUCCESS)
|
|
return status;
|
|
|
|
status = gen75_vebox_init_filter_params(ctx, proc_ctx);
|
|
if (status != VA_STATUS_SUCCESS)
|
|
return status;
|
|
|
|
hsw_veb_pre_format_convert(ctx, proc_ctx);
|
|
|
|
status = gen75_vebox_ensure_surfaces(ctx, proc_ctx);
|
|
if (status != VA_STATUS_SUCCESS)
|
|
return status;
|
|
|
|
status = gen75_vebox_ensure_surfaces_storage(ctx, proc_ctx);
|
|
if (status != VA_STATUS_SUCCESS)
|
|
return status;
|
|
|
|
if (proc_ctx->format_convert_flags & POST_COPY_CONVERT) {
|
|
assert(proc_ctx->is_second_field);
|
|
/* directly copy the saved frame in the second call */
|
|
} else {
|
|
intel_batchbuffer_start_atomic_veb(proc_ctx->batch, 0x1000);
|
|
intel_batchbuffer_emit_mi_flush(proc_ctx->batch);
|
|
hsw_veb_state_table_setup(ctx, proc_ctx);
|
|
bdw_veb_state_command(ctx, proc_ctx);
|
|
hsw_veb_surface_state(ctx, proc_ctx, INPUT_SURFACE);
|
|
hsw_veb_surface_state(ctx, proc_ctx, OUTPUT_SURFACE);
|
|
bdw_veb_dndi_iecp_command(ctx, proc_ctx);
|
|
intel_batchbuffer_end_atomic(proc_ctx->batch);
|
|
intel_batchbuffer_flush(proc_ctx->batch);
|
|
}
|
|
|
|
hsw_veb_post_format_convert(ctx, proc_ctx);
|
|
|
|
return VA_STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
void
|
|
skl_veb_dndi_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
|
|
{
|
|
unsigned int* p_table ;
|
|
unsigned int progressive_dn = 1;
|
|
unsigned int dndi_top_first = 0;
|
|
unsigned int is_mcdi_enabled = 0;
|
|
|
|
if (proc_ctx->is_di_enabled) {
|
|
const VAProcFilterParameterBufferDeinterlacing * const deint_params =
|
|
proc_ctx->filter_di;
|
|
|
|
progressive_dn = 0;
|
|
|
|
/* If we are in "First Frame" mode, i.e. past frames are not
|
|
available for motion measure, then don't use the TFF flag */
|
|
dndi_top_first = !(deint_params->flags & (proc_ctx->is_first_frame ?
|
|
VA_DEINTERLACING_BOTTOM_FIELD :
|
|
VA_DEINTERLACING_BOTTOM_FIELD_FIRST));
|
|
|
|
is_mcdi_enabled =
|
|
(deint_params->algorithm == VAProcDeinterlacingMotionCompensated);
|
|
}
|
|
|
|
/*
|
|
VAProcFilterParameterBufferDeinterlacing *di_param =
|
|
(VAProcFilterParameterBufferDeinterlacing *) proc_ctx->filter_di;
|
|
|
|
VAProcFilterParameterBuffer * dn_param =
|
|
(VAProcFilterParameterBuffer *) proc_ctx->filter_dn;
|
|
*/
|
|
p_table = (unsigned int *)proc_ctx->dndi_state_table.ptr;
|
|
|
|
*p_table ++ = ( 140 << 20 | // denoise stad threshold . w1
|
|
192 << 12 | // dnmh_history_max
|
|
7 << 8 | // dnmh_delta[3:0]
|
|
1 ); // denoise moving pixel threshold
|
|
|
|
*p_table ++ = ( 38 << 20 | // denoise asd threshold
|
|
0 << 10 | // temporal diff th
|
|
0 ); // low temporal diff th
|
|
|
|
*p_table ++ = ( progressive_dn << 28 | // progressive dn
|
|
38 << 16 | // denoise th for sum of complexity measure
|
|
32 << 10 | // dnmh_history_init[5:0]
|
|
0 ); // reserved
|
|
|
|
*p_table ++ = ( 0 << 28 | // hot pixel count
|
|
0 << 20 | // hot pixel threshold
|
|
1 << 12 | // block noise estimate edge threshold
|
|
20 ); // block noise estimate noise threshold
|
|
|
|
*p_table ++ = ( 140<< 16 | // chroma denoise stad threshold
|
|
0 << 13 | // reserved
|
|
1 << 12 | // chrome denoise enable
|
|
13 << 6 | // chr temp diff th
|
|
7 ); // chr temp diff low
|
|
|
|
*p_table ++ = 0; // weight
|
|
|
|
*p_table ++ = ( 0 << 16 | // dn_thmax
|
|
0 ); // dn_thmin
|
|
|
|
*p_table ++ = ( 0 << 16 | // dn_prt5
|
|
0 ); // dn_dyn_thmin
|
|
|
|
*p_table ++ = ( 0 << 16 | // dn_prt4
|
|
0 ); // dn_prt3
|
|
|
|
*p_table ++ = ( 0 << 16 | // dn_prt2
|
|
0 ); // dn_prt1
|
|
|
|
*p_table ++ = ( 0 << 16 | // dn_prt0
|
|
0 << 10 | // dn_wd22
|
|
0 << 5 | // dh_wd21
|
|
0 ); // dh_wd20
|
|
|
|
*p_table ++ = ( 0 << 25 | // dn_wd12
|
|
0 << 20 | // dn_wd11
|
|
0 << 15 | // dn_wd10
|
|
0 << 10 | // dn_wd02
|
|
0 << 5 | // dn_wd01
|
|
0 ); // dn_wd00
|
|
|
|
*p_table ++ = ( 2 << 10 | // stmm c2
|
|
9 << 6 | // cat slope minus 1
|
|
5 << 2 | // sad tight threshold
|
|
0 ); // smooth mv th
|
|
|
|
*p_table ++ = ( 0 << 31 | // stmm blending constant select
|
|
64 << 24 | // stmm trc1
|
|
125<< 16 | // stmm trc2
|
|
0 << 14 | // reserved
|
|
30 << 8 | // multiplier for vecm
|
|
150 ); // maximum stmm
|
|
|
|
*p_table ++ = ( 118<< 24 | // minumum stmm
|
|
0 << 22 | // stmm shift down
|
|
1 << 20 | // stmm shift up
|
|
5 << 16 | // stmm output shift
|
|
100 << 8 | // sdi threshold
|
|
5 ); // sdi delta
|
|
|
|
*p_table ++ = ( 50 << 24 | // sdi fallback mode 1 t1 constant
|
|
100 << 16 | // sdi fallback mode 1 t2 constant
|
|
37 << 8 | // sdi fallback mode 2 constant(angle2x1)
|
|
175 ); // fmd temporal difference threshold
|
|
|
|
*p_table ++ = ( 16 << 24 | // fmd #1 vertical difference th . w7
|
|
100<< 16 | // fmd #2 vertical difference th
|
|
0 << 14 | // cat threshold
|
|
2 << 8 | // fmd tear threshold
|
|
is_mcdi_enabled << 7 | // mcdi enable, use motion compensated deinterlace algorithm
|
|
dndi_top_first << 3 | // dn/di top first
|
|
0 ); // reserved
|
|
|
|
*p_table ++ = ( 10 << 19 | // neighbor pixel threshold
|
|
0 << 16 | // fmd for 2nd field of previous frame
|
|
25 << 10 | // mc pixel consistency threshold
|
|
0 << 8 | // fmd for 1st field for current frame
|
|
10 << 4 | // sad thb
|
|
5 ); // sad tha
|
|
}
|
|
|
|
void skl_veb_iecp_csc_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
|
|
{
|
|
unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 220);
|
|
float tran_coef[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
|
|
float v_coef[3] = {0.0, 0.0, 0.0};
|
|
float u_coef[3] = {0.0, 0.0, 0.0};
|
|
int is_transform_enabled = 0;
|
|
|
|
if(!(proc_ctx->filters_mask & VPP_IECP_CSC)){
|
|
memset(p_table, 0, 12 * 4);
|
|
return;
|
|
}
|
|
|
|
if(proc_ctx->fourcc_input == VA_FOURCC_RGBA &&
|
|
(proc_ctx->fourcc_output == VA_FOURCC_NV12 ||
|
|
proc_ctx->fourcc_output == VA_FOURCC_YV12 ||
|
|
proc_ctx->fourcc_output == VA_FOURCC_YVY2 ||
|
|
proc_ctx->fourcc_output == VA_FOURCC_AYUV)) {
|
|
|
|
tran_coef[0] = 0.257;
|
|
tran_coef[1] = 0.504;
|
|
tran_coef[2] = 0.098;
|
|
tran_coef[3] = -0.148;
|
|
tran_coef[4] = -0.291;
|
|
tran_coef[5] = 0.439;
|
|
tran_coef[6] = 0.439;
|
|
tran_coef[7] = -0.368;
|
|
tran_coef[8] = -0.071;
|
|
|
|
u_coef[0] = 16 * 4;
|
|
u_coef[1] = 128 * 4;
|
|
u_coef[2] = 128 * 4;
|
|
|
|
is_transform_enabled = 1;
|
|
}else if((proc_ctx->fourcc_input == VA_FOURCC_NV12 ||
|
|
proc_ctx->fourcc_input == VA_FOURCC_YV12 ||
|
|
proc_ctx->fourcc_input == VA_FOURCC_YUY2 ||
|
|
proc_ctx->fourcc_input == VA_FOURCC_AYUV) &&
|
|
proc_ctx->fourcc_output == VA_FOURCC_RGBA) {
|
|
tran_coef[0] = 1.164;
|
|
tran_coef[1] = 0.000;
|
|
tran_coef[2] = 1.569;
|
|
tran_coef[3] = 1.164;
|
|
tran_coef[4] = -0.813;
|
|
tran_coef[5] = -0.392;
|
|
tran_coef[6] = 1.164;
|
|
tran_coef[7] = 2.017;
|
|
tran_coef[8] = 0.000;
|
|
|
|
v_coef[0] = -16 * 4;
|
|
v_coef[1] = -128 * 4;
|
|
v_coef[2] = -128 * 4;
|
|
|
|
is_transform_enabled = 1;
|
|
}else if(proc_ctx->fourcc_input != proc_ctx->fourcc_output){
|
|
//enable when input and output format are different.
|
|
is_transform_enabled = 1;
|
|
}
|
|
|
|
if(is_transform_enabled == 0){
|
|
memset(p_table, 0, 12 * 4);
|
|
}else{
|
|
*p_table ++ = ( is_transform_enabled << 31 |
|
|
0 << 29 | // yuv_channel swap
|
|
intel_format_convert(tran_coef[0], 2, 16, 1)); //c0, s2.16 format
|
|
|
|
*p_table ++ = ( 0 << 19 | //reserved
|
|
intel_format_convert(tran_coef[1], 2, 16, 1)); //c1, s2.16 format
|
|
|
|
*p_table ++ = ( 0 << 19 | //reserved
|
|
intel_format_convert(tran_coef[2], 2, 16, 1)); //c2, s2.16 format
|
|
|
|
*p_table ++ = ( 0 << 19 | //reserved
|
|
intel_format_convert(tran_coef[3], 2, 16, 1)); //c3, s2.16 format
|
|
|
|
*p_table ++ = ( 0 << 19 | //reserved
|
|
intel_format_convert(tran_coef[4], 2, 16, 1)); //c4, s2.16 format
|
|
|
|
*p_table ++ = ( 0 << 19 | //reserved
|
|
intel_format_convert(tran_coef[5], 2, 16, 1)); //c5, s2.16 format
|
|
|
|
*p_table ++ = ( 0 << 19 | //reserved
|
|
intel_format_convert(tran_coef[6], 2, 16, 1)); //c6, s2.16 format
|
|
|
|
*p_table ++ = ( 0 << 19 | //reserved
|
|
intel_format_convert(tran_coef[7], 2, 16, 1)); //c7, s2.16 format
|
|
|
|
*p_table ++ = ( 0 << 19 | //reserved
|
|
intel_format_convert(tran_coef[8], 2, 16, 1)); //c8, s2.16 format
|
|
|
|
*p_table ++ = ( intel_format_convert(u_coef[0], 16, 0, 1) << 16 |
|
|
intel_format_convert(v_coef[0], 16, 0, 1));
|
|
|
|
*p_table ++ = ( intel_format_convert(u_coef[1], 16, 0, 1) << 16 |
|
|
intel_format_convert(v_coef[1], 16, 0, 1));
|
|
|
|
*p_table ++ = ( intel_format_convert(u_coef[2], 16, 0, 1) << 16 |
|
|
intel_format_convert(v_coef[2], 16, 0, 1));
|
|
}
|
|
}
|
|
|
|
void skl_veb_iecp_aoi_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
|
|
{
|
|
unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 27 * sizeof(unsigned int));
|
|
|
|
if (!(proc_ctx->filters_mask & VPP_IECP_AOI)) {
|
|
memset(p_table, 0, 3 * 4);
|
|
} else {
|
|
*p_table ++ = 0x00000000;
|
|
*p_table ++ = 0x00030000;
|
|
*p_table ++ = 0x00030000;
|
|
}
|
|
}
|
|
|
|
void skl_veb_state_table_setup(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
|
|
{
|
|
if(proc_ctx->filters_mask & VPP_DNDI_MASK) {
|
|
dri_bo *dndi_bo = proc_ctx->dndi_state_table.bo;
|
|
dri_bo_map(dndi_bo, 1);
|
|
proc_ctx->dndi_state_table.ptr = dndi_bo->virtual;
|
|
|
|
skl_veb_dndi_table(ctx, proc_ctx);
|
|
|
|
dri_bo_unmap(dndi_bo);
|
|
}
|
|
|
|
if(proc_ctx->filters_mask & VPP_IECP_MASK) {
|
|
dri_bo *iecp_bo = proc_ctx->iecp_state_table.bo;
|
|
dri_bo_map(iecp_bo, 1);
|
|
proc_ctx->iecp_state_table.ptr = iecp_bo->virtual;
|
|
|
|
hsw_veb_iecp_std_table(ctx, proc_ctx);
|
|
hsw_veb_iecp_ace_table(ctx, proc_ctx);
|
|
hsw_veb_iecp_tcc_table(ctx, proc_ctx);
|
|
hsw_veb_iecp_pro_amp_table(ctx, proc_ctx);
|
|
skl_veb_iecp_csc_table(ctx, proc_ctx);
|
|
skl_veb_iecp_aoi_table(ctx, proc_ctx);
|
|
|
|
dri_bo_unmap(iecp_bo);
|
|
}
|
|
}
|
|
|
|
void
|
|
skl_veb_state_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
|
|
{
|
|
struct intel_batchbuffer *batch = proc_ctx->batch;
|
|
|
|
BEGIN_VEB_BATCH(batch, 0x10);
|
|
OUT_VEB_BATCH(batch, VEB_STATE | (0x10 - 2));
|
|
OUT_VEB_BATCH(batch,
|
|
0 << 25 | // state surface control bits
|
|
0 << 23 | // reserved.
|
|
0 << 22 | // gamut expansion position
|
|
0 << 15 | // reserved.
|
|
0 << 14 | // single slice vebox enable
|
|
0 << 13 | // hot pixel filter enable
|
|
0 << 12 | // alpha plane enable
|
|
0 << 11 | // vignette enable
|
|
0 << 10 | // demosaic enable
|
|
proc_ctx->current_output_type << 8 | // DI output frame
|
|
1 << 7 | // 444->422 downsample method
|
|
1 << 6 | // 422->420 downsample method
|
|
proc_ctx->is_first_frame << 5 | // DN/DI first frame
|
|
proc_ctx->is_di_enabled << 4 | // DI enable
|
|
proc_ctx->is_dn_enabled << 3 | // DN enable
|
|
proc_ctx->is_iecp_enabled << 2 | // global IECP enabled
|
|
0 << 1 | // ColorGamutCompressionEnable
|
|
0 ) ; // ColorGamutExpansionEnable.
|
|
|
|
OUT_RELOC(batch,
|
|
proc_ctx->dndi_state_table.bo,
|
|
I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
|
|
|
|
OUT_VEB_BATCH(batch, 0);
|
|
|
|
OUT_RELOC(batch,
|
|
proc_ctx->iecp_state_table.bo,
|
|
I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
|
|
|
|
OUT_VEB_BATCH(batch, 0);
|
|
|
|
OUT_RELOC(batch,
|
|
proc_ctx->gamut_state_table.bo,
|
|
I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
|
|
|
|
OUT_VEB_BATCH(batch, 0);
|
|
|
|
OUT_RELOC(batch,
|
|
proc_ctx->vertex_state_table.bo,
|
|
I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
|
|
|
|
OUT_VEB_BATCH(batch, 0);
|
|
|
|
OUT_VEB_BATCH(batch, 0);/*caputre pipe state pointer*/
|
|
OUT_VEB_BATCH(batch, 0);
|
|
|
|
OUT_VEB_BATCH(batch, 0);/*lace lut table state pointer*/
|
|
OUT_VEB_BATCH(batch, 0);
|
|
|
|
OUT_VEB_BATCH(batch, 0);/*gamma correction values address*/
|
|
OUT_VEB_BATCH(batch, 0);
|
|
|
|
ADVANCE_VEB_BATCH(batch);
|
|
}
|
|
|
|
void skl_veb_surface_state(VADriverContextP ctx, struct intel_vebox_context *proc_ctx, unsigned int is_output)
|
|
{
|
|
struct intel_batchbuffer *batch = proc_ctx->batch;
|
|
unsigned int u_offset_y = 0, v_offset_y = 0;
|
|
unsigned int is_uv_interleaved = 0, tiling = 0, swizzle = 0;
|
|
unsigned int surface_format = PLANAR_420_8;
|
|
struct object_surface* obj_surf = NULL;
|
|
unsigned int surface_pitch = 0;
|
|
unsigned int half_pitch_chroma = 0;
|
|
unsigned int derived_pitch;
|
|
|
|
if (is_output) {
|
|
obj_surf = proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface;
|
|
} else {
|
|
obj_surf = proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface;
|
|
}
|
|
|
|
assert(obj_surf->fourcc == VA_FOURCC_NV12 ||
|
|
obj_surf->fourcc == VA_FOURCC_YUY2 ||
|
|
obj_surf->fourcc == VA_FOURCC_AYUV ||
|
|
obj_surf->fourcc == VA_FOURCC_RGBA);
|
|
|
|
if (obj_surf->fourcc == VA_FOURCC_NV12) {
|
|
surface_format = PLANAR_420_8;
|
|
surface_pitch = obj_surf->width;
|
|
is_uv_interleaved = 1;
|
|
half_pitch_chroma = 0;
|
|
} else if (obj_surf->fourcc == VA_FOURCC_YUY2) {
|
|
surface_format = YCRCB_NORMAL;
|
|
surface_pitch = obj_surf->width * 2;
|
|
is_uv_interleaved = 0;
|
|
half_pitch_chroma = 0;
|
|
} else if (obj_surf->fourcc == VA_FOURCC_AYUV) {
|
|
surface_format = PACKED_444A_8;
|
|
surface_pitch = obj_surf->width * 4;
|
|
is_uv_interleaved = 0;
|
|
half_pitch_chroma = 0;
|
|
} else if (obj_surf->fourcc == VA_FOURCC_RGBA) {
|
|
surface_format = R8G8B8A8_UNORM_SRGB;
|
|
surface_pitch = obj_surf->width * 4;
|
|
is_uv_interleaved = 0;
|
|
half_pitch_chroma = 0;
|
|
}
|
|
|
|
derived_pitch = surface_pitch;
|
|
|
|
u_offset_y = obj_surf->y_cb_offset;
|
|
v_offset_y = obj_surf->y_cr_offset;
|
|
|
|
dri_bo_get_tiling(obj_surf->bo, &tiling, &swizzle);
|
|
|
|
BEGIN_VEB_BATCH(batch, 9);
|
|
OUT_VEB_BATCH(batch, VEB_SURFACE_STATE | (9 - 2));
|
|
OUT_VEB_BATCH(batch,
|
|
0 << 1 | // reserved
|
|
is_output); // surface indentification.
|
|
|
|
OUT_VEB_BATCH(batch,
|
|
(obj_surf->height - 1) << 18 | // height . w3
|
|
(obj_surf->width -1 ) << 4 | // width
|
|
0); // reserve
|
|
|
|
OUT_VEB_BATCH(batch,
|
|
surface_format << 28 | // surface format, YCbCr420. w4
|
|
is_uv_interleaved << 27 | // interleave chrome , two seperate palar
|
|
0 << 20 | // reserved
|
|
(surface_pitch - 1) << 3 | // surface pitch, 64 align
|
|
half_pitch_chroma << 2 | // half pitch for chrome
|
|
!!tiling << 1 | // tiled surface, linear surface used
|
|
(tiling == I915_TILING_Y)); // tiled walk, ignored when liner surface
|
|
|
|
OUT_VEB_BATCH(batch,
|
|
0 << 16 | // X offset for V(Cb)
|
|
u_offset_y); // Y offset for V(Cb)
|
|
|
|
OUT_VEB_BATCH(batch,
|
|
0 << 16 | // X offset for V(Cr)
|
|
v_offset_y ); // Y offset for V(Cr)
|
|
|
|
OUT_VEB_BATCH(batch, 0);
|
|
|
|
OUT_VEB_BATCH(batch, derived_pitch - 1);
|
|
|
|
OUT_VEB_BATCH(batch, 0);
|
|
|
|
ADVANCE_VEB_BATCH(batch);
|
|
}
|
|
|
|
VAStatus
|
|
gen9_vebox_process_picture(VADriverContextP ctx,
|
|
struct intel_vebox_context *proc_ctx)
|
|
{
|
|
VAStatus status;
|
|
|
|
status = gen75_vebox_init_pipe_params(ctx, proc_ctx);
|
|
if (status != VA_STATUS_SUCCESS)
|
|
return status;
|
|
|
|
status = gen75_vebox_init_filter_params(ctx, proc_ctx);
|
|
if (status != VA_STATUS_SUCCESS)
|
|
return status;
|
|
|
|
hsw_veb_pre_format_convert(ctx, proc_ctx);
|
|
|
|
status = gen75_vebox_ensure_surfaces(ctx, proc_ctx);
|
|
if (status != VA_STATUS_SUCCESS)
|
|
return status;
|
|
|
|
status = gen75_vebox_ensure_surfaces_storage(ctx, proc_ctx);
|
|
if (status != VA_STATUS_SUCCESS)
|
|
return status;
|
|
|
|
if (proc_ctx->format_convert_flags & POST_COPY_CONVERT) {
|
|
assert(proc_ctx->is_second_field);
|
|
/* directly copy the saved frame in the second call */
|
|
} else {
|
|
intel_batchbuffer_start_atomic_veb(proc_ctx->batch, 0x1000);
|
|
intel_batchbuffer_emit_mi_flush(proc_ctx->batch);
|
|
skl_veb_state_table_setup(ctx, proc_ctx);
|
|
skl_veb_state_command(ctx, proc_ctx);
|
|
skl_veb_surface_state(ctx, proc_ctx, INPUT_SURFACE);
|
|
skl_veb_surface_state(ctx, proc_ctx, OUTPUT_SURFACE);
|
|
bdw_veb_dndi_iecp_command(ctx, proc_ctx);
|
|
intel_batchbuffer_end_atomic(proc_ctx->batch);
|
|
intel_batchbuffer_flush(proc_ctx->batch);
|
|
}
|
|
|
|
hsw_veb_post_format_convert(ctx, proc_ctx);
|
|
|
|
return VA_STATUS_SUCCESS;
|
|
}
|