1 /*
2  * Copyright © 2010 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sub license, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the
13  * next paragraph) shall be included in all copies or substantial portions
14  * of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * Authors:
25  *    Xiang Haihao <haihao.xiang@intel.com>
26  *
27  */
28 
29 #ifndef __I965_POST_PROCESSING_H__
30 #define __I965_POST_PROCESSING_H__
31 
32 #include "i965_vpp_avs.h"
33 #include <drm.h>
34 #include <i915_drm.h>
35 #include <intel_bufmgr.h>
36 #include "i965_gpe_utils.h"
37 
38 #define MAX_PP_SURFACES                 48
39 
40 struct i965_gpe_context;
41 
42 enum {
43     PP_NULL = 0,
44     PP_NV12_LOAD_SAVE_N12,
45     PP_NV12_LOAD_SAVE_PL3,
46     PP_PL3_LOAD_SAVE_N12,
47     PP_PL3_LOAD_SAVE_PL3,
48     PP_NV12_SCALING,
49     PP_NV12_AVS,
50     PP_NV12_DNDI,
51     PP_NV12_DN,
52     PP_NV12_LOAD_SAVE_PA,
53     PP_PL3_LOAD_SAVE_PA,
54     PP_PA_LOAD_SAVE_NV12,
55     PP_PA_LOAD_SAVE_PL3,
56     PP_PA_LOAD_SAVE_PA,
57     PP_RGBX_LOAD_SAVE_NV12,
58     PP_NV12_LOAD_SAVE_RGBX,
59     NUM_PP_MODULES,
60 };
61 
62 struct i965_post_processing_context;
63 
64 struct pp_load_save_context {
65     int dest_x;
66     int dest_y;
67     int dest_w;
68     int dest_h;
69 };
70 
71 struct pp_scaling_context {
72     int dest_x; /* in pixel */
73     int dest_y; /* in pixel */
74     int dest_w;
75     int dest_h;
76     float src_normalized_x;
77     float src_normalized_y;
78 };
79 
80 struct pp_avs_context {
81     AVSState state;
82     int dest_x; /* in pixel */
83     int dest_y; /* in pixel */
84     int dest_w;
85     int dest_h;
86     float src_normalized_x;
87     float src_normalized_y;
88     int src_w;
89     int src_h;
90     float horiz_range;
91 };
92 
93 enum {
94     DNDI_FRAME_IN_CURRENT = 0,
95     DNDI_FRAME_IN_PREVIOUS,
96     DNDI_FRAME_IN_STMM,
97     DNDI_FRAME_OUT_STMM,
98     DNDI_FRAME_OUT_CURRENT,
99     DNDI_FRAME_OUT_PREVIOUS,
100     DNDI_FRAME_STORE_COUNT
101 };
102 
103 typedef struct dndi_frame_store {
104     struct object_surface *obj_surface;
105     VASurfaceID surface_id; /* always relative to the input surface */
106     unsigned int is_scratch_surface : 1;
107 } DNDIFrameStore;
108 
109 struct pp_dndi_context {
110     int dest_w;
111     int dest_h;
112     DNDIFrameStore frame_store[DNDI_FRAME_STORE_COUNT];
113 
114     /* Temporary flags live until the current picture is processed */
115     unsigned int is_di_enabled          : 1;
116     unsigned int is_di_adv_enabled      : 1;
117     unsigned int is_first_frame         : 1;
118     unsigned int is_second_field        : 1;
119 };
120 
121 struct pp_dn_context {
122     int dest_w;
123     int dest_h;
124     dri_bo *stmm_bo;
125 };
126 
127 struct i965_post_processing_context;
128 
129 struct pp_module {
130     struct i965_kernel kernel;
131 
132     /* others */
133     VAStatus(*initialize)(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
134                           const struct i965_surface *src_surface,
135                           const VARectangle *src_rect,
136                           struct i965_surface *dst_surface,
137                           const VARectangle *dst_rect,
138                           void *filter_param);
139 };
140 
141 struct pp_static_parameter {
142     struct {
143         /* Procamp r1.0 */
144         float procamp_constant_c0;
145 
146         /* Load and Same r1.1 */
147         unsigned int source_packed_y_offset: 8;
148         unsigned int source_packed_u_offset: 8;
149         unsigned int source_packed_v_offset: 8;
150         unsigned int source_rgb_layout: 8;      // 1 for |R|G|B|X| layout, 0 for |B|G|R|X| layout
151 
152         union {
153             /* Load and Save r1.2 */
154             struct {
155                 unsigned int destination_packed_y_offset: 8;
156                 unsigned int destination_packed_u_offset: 8;
157                 unsigned int destination_packed_v_offset: 8;
158                 unsigned int pad0: 8;
159             } load_and_save;
160 
161             /* CSC r1.2 */
162             struct {
163                 unsigned int pad0: 24;
164                 unsigned int destination_rgb_layout: 8; // 1 for |R|G|B|X| layout, 0 for |B|G|R|X| layout
165             } csc;
166         } r1_2;
167 
168         /* Procamp r1.3 */
169         float procamp_constant_c1;
170 
171         /* Procamp r1.4 */
172         float procamp_constant_c2;
173 
174         /* DI r1.5 */
175         unsigned int statistics_surface_picth: 16; /* Devided by 2 */
176         unsigned int pad1: 16;
177 
178         union {
179             /* DI r1.6 */
180             struct {
181                 unsigned int pad0: 24;
182                 unsigned int top_field_first: 8;
183             } di;
184 
185             /* AVS/Scaling r1.6 */
186             float normalized_video_y_scaling_step;
187         } r1_6;
188 
189         /* Procamp r1.7 */
190         float procamp_constant_c5;
191     } grf1;
192 
193     struct {
194         /* Procamp r2.0 */
195         float procamp_constant_c3;
196 
197         /* MBZ r2.1*/
198         unsigned int pad0;
199 
200         /* WG+CSC r2.2 */
201         float wg_csc_constant_c4;
202 
203         /* WG+CSC r2.3 */
204         float wg_csc_constant_c8;
205 
206         /* Procamp r2.4 */
207         float procamp_constant_c4;
208 
209         /* MBZ r2.5 */
210         unsigned int pad1;
211 
212         /* MBZ r2.6 */
213         unsigned int pad2;
214 
215         /* WG+CSC r2.7 */
216         float wg_csc_constant_c9;
217     } grf2;
218 
219     struct {
220         /* WG+CSC r3.0 */
221         float wg_csc_constant_c0;
222 
223         /* Blending r3.1 */
224         float scaling_step_ratio;
225 
226         /* Blending r3.2 */
227         float normalized_alpha_y_scaling;
228 
229         /* WG+CSC r3.3 */
230         float wg_csc_constant_c4;
231 
232         /* WG+CSC r3.4 */
233         float wg_csc_constant_c1;
234 
235         /* ALL r3.5 */
236         int horizontal_origin_offset: 16;
237         int vertical_origin_offset: 16;
238 
239         /* Shared r3.6*/
240         union {
241             /* Color filll */
242             unsigned int color_pixel;
243 
244             /* WG+CSC */
245             float wg_csc_constant_c2;
246         } r3_6;
247 
248         /* WG+CSC r3.7 */
249         float wg_csc_constant_c3;
250     } grf3;
251 
252     struct {
253         /* WG+CSC r4.0 */
254         float wg_csc_constant_c6;
255 
256         /* ALL r4.1 MBZ ???*/
257         unsigned int pad0;
258 
259         /* Shared r4.2 */
260         union {
261             /* AVS */
262             struct {
263                 unsigned int pad1: 15;
264                 unsigned int nlas: 1;
265                 unsigned int pad2: 16;
266             } avs;
267 
268             /* DI */
269             struct {
270                 unsigned int motion_history_coefficient_m2: 8;
271                 unsigned int motion_history_coefficient_m1: 8;
272                 unsigned int pad0: 16;
273             } di;
274         } r4_2;
275 
276         /* WG+CSC r4.3 */
277         float wg_csc_constant_c7;
278 
279         /* WG+CSC r4.4 */
280         float wg_csc_constant_c10;
281 
282         /* AVS r4.5 */
283         float source_video_frame_normalized_horizontal_origin;
284 
285         /* MBZ r4.6 */
286         unsigned int pad1;
287 
288         /* WG+CSC r4.7 */
289         float wg_csc_constant_c11;
290     } grf4;
291 };
292 
293 struct pp_inline_parameter {
294     struct {
295         /* ALL r5.0 */
296         int destination_block_horizontal_origin: 16;
297         int destination_block_vertical_origin: 16;
298 
299         /* Shared r5.1 */
300         union {
301             /* AVS/Scaling */
302             float source_surface_block_normalized_horizontal_origin;
303 
304             /* FMD */
305             struct {
306                 unsigned int variance_surface_vertical_origin: 16;
307                 unsigned int pad0: 16;
308             } fmd;
309         } r5_1;
310 
311         /* AVS/Scaling r5.2 */
312         float source_surface_block_normalized_vertical_origin;
313 
314         /* Alpha r5.3 */
315         float alpha_surface_block_normalized_horizontal_origin;
316 
317         /* Alpha r5.4 */
318         float alpha_surface_block_normalized_vertical_origin;
319 
320         /* Alpha r5.5 */
321         unsigned int alpha_mask_x: 16;
322         unsigned int alpha_mask_y: 8;
323         unsigned int block_count_x: 8;
324 
325         /* r5.6 */
326         /* we only support M*1 or 1*N block partitation now.
327          *   -- it means asm code only need update this mask from grf6 for the last block
328          */
329         unsigned int block_horizontal_mask: 16;
330         unsigned int block_vertical_mask: 8;
331         unsigned int number_blocks: 8;
332 
333         /* AVS/Scaling r5.7 */
334         float normalized_video_x_scaling_step;
335     } grf5;
336 
337     struct {
338         /* AVS r6.0 */
339         float video_step_delta;
340 
341         /* r6.1 */    // sizeof(int) == 4?
342         unsigned int block_horizontal_mask_right: 16;
343         unsigned int block_vertical_mask_bottom: 8;
344         unsigned int pad1: 8;
345 
346         /* r6.2 */
347         unsigned int block_horizontal_mask_middle: 16;
348         unsigned int pad2: 16;
349 
350         /* r6.3-r6.7 */
351         unsigned int padx[5];
352     } grf6;
353 };
354 
355 struct gen7_pp_static_parameter {
356     struct {
357         /* r1.0-r1.5 */
358         unsigned int padx[6];
359         /* r1.6 */
360         unsigned int di_statistics_surface_pitch_div2: 16;
361         unsigned int di_statistics_surface_height_div4: 16;
362         /* r1.7 */
363         unsigned int di_top_field_first: 8;
364         unsigned int pad0: 16;
365         unsigned int pointer_to_inline_parameter: 8; /* value: 7 */
366     } grf1;
367 
368     struct {
369         /* r2.0 */
370         /* Indicates whether the rgb is swapped for the src surface
371          * 0: RGBX(MSB. X-B-G-R). 1: BGRX(MSB: X-R-G-B)
372          */
373         unsigned int src_avs_rgb_swap: 1;
374         unsigned int pad3: 31;
375 
376         /* r2.1 */
377         unsigned int pad2: 16;
378         unsigned int save_avs_rgb_swap: 1; /* 0: RGB, 1: BGR */
379         unsigned int avs_wa_enable: 1; /* must enabled for GEN7 */
380         unsigned int ief_enable: 1;
381         unsigned int avs_wa_width: 13;
382 
383         /* 2.2 */
384         float avs_wa_one_div_256_width;
385 
386         /* 2.3 */
387         float avs_wa_five_div_256_width;
388 
389         /* 2.4 - 2.6 */
390         unsigned int padx[3];
391 
392         /* r2.7 */
393         unsigned int di_destination_packed_y_component_offset: 8;
394         unsigned int di_destination_packed_u_component_offset: 8;
395         unsigned int di_destination_packed_v_component_offset: 8;
396         unsigned int alpha: 8;
397     } grf2;
398 
399     struct {
400         float sampler_load_horizontal_scaling_step_ratio;
401         unsigned int padx[7];
402     } grf3;
403 
404     struct {
405         float sampler_load_vertical_scaling_step;
406         unsigned int pad0;
407         unsigned int di_hoffset_svf_from_dvf: 16;
408         unsigned int di_voffset_svf_from_dvf: 16;
409         unsigned int padx[5];
410     } grf4;
411 
412     struct {
413         float sampler_load_vertical_frame_origin;
414         unsigned int padx[7];
415     } grf5;
416 
417     struct {
418         float sampler_load_horizontal_frame_origin;
419         unsigned int padx[7];
420     } grf6;
421 
422     struct {
423         /* r7.0 -> r7.3 */
424         float coef_ry;
425         float coef_ru;
426         float coef_rv;
427         float coef_yd;
428 
429         /* r7.4 -> r7.7 */
430         float coef_gy;
431         float coef_gu;
432         float coef_gv;
433         float coef_ud;
434     } grf7;
435 
436     struct {
437         /* r8.0 -> r8.3 */
438         float coef_by;
439         float coef_bu;
440         float coef_bv;
441         float coef_vd;
442 
443         /* r8.4 -> r8.7 */
444         unsigned int padx[4];
445     } grf8;
446 };
447 
448 struct gen7_pp_inline_parameter {
449     struct {
450         /* r9.0 */
451         unsigned int destination_block_horizontal_origin: 16;
452         unsigned int destination_block_vertical_origin: 16;
453         /* r9.1: 0xffffffff */
454         unsigned int constant_0;
455         /* r9.2 */
456         unsigned int pad0;
457         /* r9.3 */
458         unsigned int pad1;
459         /* r9.4 */
460         float sampler_load_main_video_x_scaling_step;
461         /* r9.5 */
462         unsigned int pad2;
463         /* r9.6: must be zero */
464         unsigned int avs_vertical_block_number;
465         /* r9.7: 0 */
466         unsigned int group_id_number;
467     } grf9;
468 
469     struct {
470         unsigned int padx[8];
471     } grf10;
472 };
473 
474 struct i965_post_processing_context {
475     int current_pp;
476     struct pp_module pp_modules[NUM_PP_MODULES];
477     void *pp_static_parameter;
478     void *pp_inline_parameter;
479 
480     struct {
481         dri_bo *bo;
482     } surface_state_binding_table;
483 
484     struct {
485         dri_bo *bo;
486     } curbe;
487 
488     struct {
489         dri_bo *bo;
490         int num_interface_descriptors;
491     } idrt;
492 
493     struct {
494         dri_bo *bo;
495     } vfe_state;
496 
497     struct {
498         dri_bo *bo;
499         dri_bo *bo_8x8;
500         dri_bo *bo_8x8_uv;
501     } sampler_state_table;
502 
503     struct {
504         unsigned int size;
505 
506         unsigned int vfe_start;
507         unsigned int cs_start;
508 
509         unsigned int num_vfe_entries;
510         unsigned int num_cs_entries;
511 
512         unsigned int size_vfe_entry;
513         unsigned int size_cs_entry;
514     } urb;
515 
516     struct {
517         unsigned int gpgpu_mode : 1;
518         unsigned int pad0 : 7;
519         unsigned int max_num_threads : 16;
520         unsigned int num_urb_entries : 8;
521         unsigned int urb_entry_size : 16;
522         unsigned int curbe_allocation_size : 16;
523     } vfe_gpu_state;
524 
525     struct intel_vebox_context *vebox_proc_ctx;
526 
527     struct pp_load_save_context pp_load_save_context;
528     struct pp_scaling_context pp_scaling_context;
529     struct pp_avs_context pp_avs_context;
530     struct pp_dndi_context pp_dndi_context;
531     struct pp_dn_context pp_dn_context;
532     void *private_context; /* pointer to the current private context */
533     void *pipeline_param;  /* pointer to the pipeline parameter */
534     /**
535      * \ref Extra filter flags used as a fast path.
536      *
537      * This corresponds to vaPutSurface() flags, for direct rendering,
538      * or to VAProcPipelineParameterBuffer.filter_flags when the VPP
539      * interfaces are used. In the latter case, this is just a copy of
540      * that field.
541      */
542     unsigned int filter_flags;
543 
544     int (*pp_x_steps)(void *private_context);
545     int (*pp_y_steps)(void *private_context);
546     int (*pp_set_block_parameter)(struct i965_post_processing_context *pp_context, int x, int y);
547 
548     struct intel_batchbuffer *batch;
549 
550     unsigned int block_horizontal_mask_left: 16;
551     unsigned int block_horizontal_mask_right: 16;
552     unsigned int block_vertical_mask_bottom: 8;
553 
554     struct {
555         dri_bo *bo;
556         int bo_size;
557         unsigned int end_offset;
558     } instruction_state;
559 
560     struct {
561         dri_bo *bo;
562     } indirect_state;
563 
564     struct {
565         dri_bo *bo;
566         int bo_size;
567         unsigned int end_offset;
568     } dynamic_state;
569 
570     unsigned int sampler_offset;
571     int sampler_size;
572     unsigned int idrt_offset;
573     int idrt_size;
574     unsigned int curbe_offset;
575     int curbe_size;
576 
577     VAStatus(*intel_post_processing)(VADriverContextP   ctx,
578                                      struct i965_post_processing_context *pp_context,
579                                      const struct i965_surface *src_surface,
580                                      const VARectangle *src_rect,
581                                      struct i965_surface *dst_surface,
582                                      const VARectangle *dst_rect,
583                                      int   pp_index,
584                                      void * filter_param);
585     void (*finalize)(VADriverContextP ctx,
586                      struct i965_post_processing_context *pp_context);
587 
588 
589     struct i965_gpe_context scaling_gpe_context;
590 
591 #define VPPGPE_8BIT_8BIT        (1 << 0)
592 #define VPPGPE_8BIT_10BIT       (1 << 1)
593 #define VPPGPE_10BIT_10BIT      (1 << 2)
594 #define VPPGPE_10BIT_8BIT       (1 << 3)
595 #define VPPGPE_8BIT_420_RGB32   (1 << 4)
596 
597     unsigned int scaling_gpe_context_initialized;
598 };
599 
600 struct i965_proc_context {
601     struct hw_context base;
602     void *driver_context;
603     struct i965_post_processing_context pp_context;
604 };
605 
606 VASurfaceID
607 i965_post_processing(
608     VADriverContextP   ctx,
609     struct object_surface *obj_surface,
610     const VARectangle *src_rect,
611     const VARectangle *dst_rect,
612     unsigned int       va_flags,
613     int                *has_done_scaling,
614     VARectangle *calibrated_rect
615 );
616 
617 VAStatus
618 i965_scaling_processing(
619     VADriverContextP   ctx,
620     struct object_surface *src_surface_obj,
621     const VARectangle *src_rect,
622     struct object_surface *dst_surface_obj,
623     const VARectangle *dst_rect,
624     unsigned int       va_flags
625 );
626 
627 VAStatus
628 i965_image_processing(VADriverContextP ctx,
629                       const struct i965_surface *src_surface,
630                       const VARectangle *src_rect,
631                       struct i965_surface *dst_surface,
632                       const VARectangle *dst_rect);
633 
634 void
635 i965_post_processing_terminate(VADriverContextP ctx);
636 bool
637 i965_post_processing_init(VADriverContextP ctx);
638 
639 
640 extern VAStatus
641 i965_proc_picture(VADriverContextP ctx,
642                   VAProfile profile,
643                   union codec_state *codec_state,
644                   struct hw_context *hw_context);
645 
646 int
647 pp_get_surface_fourcc(VADriverContextP ctx, const struct i965_surface *surface);
648 
649 #endif /* __I965_POST_PROCESSING_H__ */
650