Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  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. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #include <assert.h>
  33.  
  34. #include "intel_batchbuffer.h"
  35. #include "intel_driver.h"
  36. #include "i965_defines.h"
  37. #include "i965_structs.h"
  38. #include "i965_drv_video.h"
  39. #include "gen75_vpp_vebox.h"
  40. #include "i965_post_processing.h"
  41. #include "i965_render.h"
  42.  
  43. #define HAS_PP(ctx) (IS_IRONLAKE((ctx)->intel.device_id) ||     \
  44.                      IS_GEN6((ctx)->intel.device_id) ||         \
  45.                      IS_GEN7((ctx)->intel.device_id))
  46.  
  47. #define SURFACE_STATE_PADDED_SIZE_0_I965        ALIGN(sizeof(struct i965_surface_state), 32)
  48. #define SURFACE_STATE_PADDED_SIZE_1_I965        ALIGN(sizeof(struct i965_surface_state2), 32)
  49. #define SURFACE_STATE_PADDED_SIZE_I965          MAX(SURFACE_STATE_PADDED_SIZE_0_I965, SURFACE_STATE_PADDED_SIZE_1_I965)
  50.  
  51. #define SURFACE_STATE_PADDED_SIZE_0_GEN7        ALIGN(sizeof(struct gen7_surface_state), 32)
  52. #define SURFACE_STATE_PADDED_SIZE_1_GEN7        ALIGN(sizeof(struct gen7_surface_state2), 32)
  53. #define SURFACE_STATE_PADDED_SIZE_GEN7          MAX(SURFACE_STATE_PADDED_SIZE_0_GEN7, SURFACE_STATE_PADDED_SIZE_1_GEN7)
  54.  
  55. #define SURFACE_STATE_PADDED_SIZE               MAX(SURFACE_STATE_PADDED_SIZE_I965, SURFACE_STATE_PADDED_SIZE_GEN7)
  56. #define SURFACE_STATE_OFFSET(index)             (SURFACE_STATE_PADDED_SIZE * index)
  57. #define BINDING_TABLE_OFFSET                    SURFACE_STATE_OFFSET(MAX_PP_SURFACES)
  58.  
  59. #define GPU_ASM_BLOCK_WIDTH         16
  60. #define GPU_ASM_BLOCK_HEIGHT        8
  61. #define GPU_ASM_X_OFFSET_ALIGNMENT  4
  62.  
  63. static const uint32_t pp_null_gen5[][4] = {
  64. #include "shaders/post_processing/gen5_6/null.g4b.gen5"
  65. };
  66.  
  67. static const uint32_t pp_nv12_load_save_nv12_gen5[][4] = {
  68. #include "shaders/post_processing/gen5_6/nv12_load_save_nv12.g4b.gen5"
  69. };
  70.  
  71. static const uint32_t pp_nv12_load_save_pl3_gen5[][4] = {
  72. #include "shaders/post_processing/gen5_6/nv12_load_save_pl3.g4b.gen5"
  73. };
  74.  
  75. static const uint32_t pp_pl3_load_save_nv12_gen5[][4] = {
  76. #include "shaders/post_processing/gen5_6/pl3_load_save_nv12.g4b.gen5"
  77. };
  78.  
  79. static const uint32_t pp_pl3_load_save_pl3_gen5[][4] = {
  80. #include "shaders/post_processing/gen5_6/pl3_load_save_pl3.g4b.gen5"
  81. };
  82.  
  83. static const uint32_t pp_nv12_scaling_gen5[][4] = {
  84. #include "shaders/post_processing/gen5_6/nv12_scaling_nv12.g4b.gen5"
  85. };
  86.  
  87. static const uint32_t pp_nv12_avs_gen5[][4] = {
  88. #include "shaders/post_processing/gen5_6/nv12_avs_nv12.g4b.gen5"
  89. };
  90.  
  91. static const uint32_t pp_nv12_dndi_gen5[][4] = {
  92. #include "shaders/post_processing/gen5_6/nv12_dndi_nv12.g4b.gen5"
  93. };
  94.  
  95. static const uint32_t pp_nv12_dn_gen5[][4] = {
  96. #include "shaders/post_processing/gen5_6/nv12_dn_nv12.g4b.gen5"
  97. };
  98.  
  99. static const uint32_t pp_nv12_load_save_pa_gen5[][4] = {
  100. #include "shaders/post_processing/gen5_6/nv12_load_save_pa.g4b.gen5"
  101. };
  102.  
  103. static const uint32_t pp_pl3_load_save_pa_gen5[][4] = {
  104. #include "shaders/post_processing/gen5_6/pl3_load_save_pa.g4b.gen5"
  105. };
  106.  
  107. static const uint32_t pp_pa_load_save_nv12_gen5[][4] = {
  108. #include "shaders/post_processing/gen5_6/pa_load_save_nv12.g4b.gen5"
  109. };
  110.  
  111. static VAStatus pp_null_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
  112.                                const struct i965_surface *src_surface,
  113.                                const VARectangle *src_rect,
  114.                                struct i965_surface *dst_surface,
  115.                                const VARectangle *dst_rect,
  116.                                void *filter_param);
  117. static VAStatus pp_nv12_avs_initialize_nlas(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
  118.                                             const struct i965_surface *src_surface,
  119.                                             const VARectangle *src_rect,
  120.                                             struct i965_surface *dst_surface,
  121.                                             const VARectangle *dst_rect,
  122.                                             void *filter_param);
  123. static VAStatus pp_nv12_scaling_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
  124.                                        const struct i965_surface *src_surface,
  125.                                        const VARectangle *src_rect,
  126.                                        struct i965_surface *dst_surface,
  127.                                        const VARectangle *dst_rect,
  128.                                        void *filter_param);
  129. static VAStatus gen6_nv12_scaling_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
  130.                                              const struct i965_surface *src_surface,
  131.                                              const VARectangle *src_rect,
  132.                                              struct i965_surface *dst_surface,
  133.                                              const VARectangle *dst_rect,
  134.                                              void *filter_param);
  135. static VAStatus pp_plx_load_save_plx_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
  136.                                             const struct i965_surface *src_surface,
  137.                                             const VARectangle *src_rect,
  138.                                             struct i965_surface *dst_surface,
  139.                                             const VARectangle *dst_rect,
  140.                                             void *filter_param);
  141. static VAStatus pp_nv12_dndi_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
  142.                                     const struct i965_surface *src_surface,
  143.                                     const VARectangle *src_rect,
  144.                                     struct i965_surface *dst_surface,
  145.                                     const VARectangle *dst_rect,
  146.                                     void *filter_param);
  147.  
  148. static VAStatus pp_nv12_dn_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
  149.                                   const struct i965_surface *src_surface,
  150.                                   const VARectangle *src_rect,
  151.                                   struct i965_surface *dst_surface,
  152.                                   const VARectangle *dst_rect,
  153.                                   void *filter_param);
  154.  
  155. static struct pp_module pp_modules_gen5[] = {
  156.     {
  157.         {
  158.             "NULL module (for testing)",
  159.             PP_NULL,
  160.             pp_null_gen5,
  161.             sizeof(pp_null_gen5),
  162.             NULL,
  163.         },
  164.  
  165.         pp_null_initialize,
  166.     },
  167.  
  168.     {
  169.         {
  170.             "NV12_NV12",
  171.             PP_NV12_LOAD_SAVE_N12,
  172.             pp_nv12_load_save_nv12_gen5,
  173.             sizeof(pp_nv12_load_save_nv12_gen5),
  174.             NULL,
  175.         },
  176.  
  177.         pp_plx_load_save_plx_initialize,
  178.     },
  179.  
  180.     {
  181.         {
  182.             "NV12_PL3",
  183.             PP_NV12_LOAD_SAVE_PL3,
  184.             pp_nv12_load_save_pl3_gen5,
  185.             sizeof(pp_nv12_load_save_pl3_gen5),
  186.             NULL,
  187.         },
  188.  
  189.         pp_plx_load_save_plx_initialize,
  190.     },
  191.  
  192.     {
  193.         {
  194.             "PL3_NV12",
  195.             PP_PL3_LOAD_SAVE_N12,
  196.             pp_pl3_load_save_nv12_gen5,
  197.             sizeof(pp_pl3_load_save_nv12_gen5),
  198.             NULL,
  199.         },
  200.  
  201.         pp_plx_load_save_plx_initialize,
  202.     },
  203.  
  204.     {
  205.         {
  206.             "PL3_PL3",
  207.             PP_PL3_LOAD_SAVE_PL3,
  208.             pp_pl3_load_save_pl3_gen5,
  209.             sizeof(pp_pl3_load_save_pl3_gen5),
  210.             NULL,
  211.         },
  212.  
  213.         pp_plx_load_save_plx_initialize
  214.     },
  215.  
  216.     {
  217.         {
  218.             "NV12 Scaling module",
  219.             PP_NV12_SCALING,
  220.             pp_nv12_scaling_gen5,
  221.             sizeof(pp_nv12_scaling_gen5),
  222.             NULL,
  223.         },
  224.  
  225.         pp_nv12_scaling_initialize,
  226.     },
  227.  
  228.     {
  229.         {
  230.             "NV12 AVS module",
  231.             PP_NV12_AVS,
  232.             pp_nv12_avs_gen5,
  233.             sizeof(pp_nv12_avs_gen5),
  234.             NULL,
  235.         },
  236.  
  237.         pp_nv12_avs_initialize_nlas,
  238.     },
  239.  
  240.     {
  241.         {
  242.             "NV12 DNDI module",
  243.             PP_NV12_DNDI,
  244.             pp_nv12_dndi_gen5,
  245.             sizeof(pp_nv12_dndi_gen5),
  246.             NULL,
  247.         },
  248.  
  249.         pp_nv12_dndi_initialize,
  250.     },
  251.  
  252.     {
  253.         {
  254.             "NV12 DN module",
  255.             PP_NV12_DN,
  256.             pp_nv12_dn_gen5,
  257.             sizeof(pp_nv12_dn_gen5),
  258.             NULL,
  259.         },
  260.  
  261.         pp_nv12_dn_initialize,
  262.     },
  263.  
  264.     {
  265.         {
  266.             "NV12_PA module",
  267.             PP_NV12_LOAD_SAVE_PA,
  268.             pp_nv12_load_save_pa_gen5,
  269.             sizeof(pp_nv12_load_save_pa_gen5),
  270.             NULL,
  271.         },
  272.    
  273.         pp_plx_load_save_plx_initialize,
  274.     },
  275.    {
  276.         {
  277.             "PL3_PA module",
  278.             PP_PL3_LOAD_SAVE_PA,
  279.             pp_pl3_load_save_pa_gen5,
  280.             sizeof(pp_pl3_load_save_pa_gen5),
  281.             NULL,
  282.         },
  283.    
  284.         pp_plx_load_save_plx_initialize,
  285.     },
  286.     {
  287.         {
  288.             "PA_NV12 module",
  289.             PP_PA_LOAD_SAVE_NV12,
  290.             pp_pa_load_save_nv12_gen5,
  291.             sizeof(pp_pa_load_save_nv12_gen5),
  292.             NULL,
  293.         },
  294.    
  295.         pp_plx_load_save_plx_initialize,
  296.     },
  297.  
  298. };
  299.  
  300. static const uint32_t pp_null_gen6[][4] = {
  301. #include "shaders/post_processing/gen5_6/null.g6b"
  302. };
  303.  
  304. static const uint32_t pp_nv12_load_save_nv12_gen6[][4] = {
  305. #include "shaders/post_processing/gen5_6/nv12_load_save_nv12.g6b"
  306. };
  307.  
  308. static const uint32_t pp_nv12_load_save_pl3_gen6[][4] = {
  309. #include "shaders/post_processing/gen5_6/nv12_load_save_pl3.g6b"
  310. };
  311.  
  312. static const uint32_t pp_pl3_load_save_nv12_gen6[][4] = {
  313. #include "shaders/post_processing/gen5_6/pl3_load_save_nv12.g6b"
  314. };
  315.  
  316. static const uint32_t pp_pl3_load_save_pl3_gen6[][4] = {
  317. #include "shaders/post_processing/gen5_6/pl3_load_save_pl3.g6b"
  318. };
  319.  
  320. static const uint32_t pp_nv12_scaling_gen6[][4] = {
  321. #include "shaders/post_processing/gen5_6/nv12_avs_nv12.g6b"
  322. };
  323.  
  324. static const uint32_t pp_nv12_avs_gen6[][4] = {
  325. #include "shaders/post_processing/gen5_6/nv12_avs_nv12.g6b"
  326. };
  327.  
  328. static const uint32_t pp_nv12_dndi_gen6[][4] = {
  329. #include "shaders/post_processing/gen5_6/nv12_dndi_nv12.g6b"
  330. };
  331.  
  332. static const uint32_t pp_nv12_dn_gen6[][4] = {
  333. #include "shaders/post_processing/gen5_6/nv12_dn_nv12.g6b"
  334. };
  335.  
  336. static const uint32_t pp_nv12_load_save_pa_gen6[][4] = {
  337. #include "shaders/post_processing/gen5_6/nv12_load_save_pa.g6b"
  338. };
  339.  
  340. static const uint32_t pp_pa_load_save_nv12_gen6[][4] = {
  341. #include "shaders/post_processing/gen5_6/pa_load_save_nv12.g6b"
  342. };
  343.  
  344. static const uint32_t pp_pl3_load_save_pa_gen6[][4] = {
  345. #include "shaders/post_processing/gen5_6/pl3_load_save_pa.g6b"
  346. };
  347.  
  348. static struct pp_module pp_modules_gen6[] = {
  349.     {
  350.         {
  351.             "NULL module (for testing)",
  352.             PP_NULL,
  353.             pp_null_gen6,
  354.             sizeof(pp_null_gen6),
  355.             NULL,
  356.         },
  357.  
  358.         pp_null_initialize,
  359.     },
  360.  
  361.     {
  362.         {
  363.             "NV12_NV12",
  364.             PP_NV12_LOAD_SAVE_N12,
  365.             pp_nv12_load_save_nv12_gen6,
  366.             sizeof(pp_nv12_load_save_nv12_gen6),
  367.             NULL,
  368.         },
  369.  
  370.         pp_plx_load_save_plx_initialize,
  371.     },
  372.  
  373.     {
  374.         {
  375.             "NV12_PL3",
  376.             PP_NV12_LOAD_SAVE_PL3,
  377.             pp_nv12_load_save_pl3_gen6,
  378.             sizeof(pp_nv12_load_save_pl3_gen6),
  379.             NULL,
  380.         },
  381.        
  382.         pp_plx_load_save_plx_initialize,
  383.     },
  384.  
  385.     {
  386.         {
  387.             "PL3_NV12",
  388.             PP_PL3_LOAD_SAVE_N12,
  389.             pp_pl3_load_save_nv12_gen6,
  390.             sizeof(pp_pl3_load_save_nv12_gen6),
  391.             NULL,
  392.         },
  393.  
  394.         pp_plx_load_save_plx_initialize,
  395.     },
  396.  
  397.     {
  398.         {
  399.             "PL3_PL3",
  400.             PP_PL3_LOAD_SAVE_N12,
  401.             pp_pl3_load_save_pl3_gen6,
  402.             sizeof(pp_pl3_load_save_pl3_gen6),
  403.             NULL,
  404.         },
  405.  
  406.         pp_plx_load_save_plx_initialize,
  407.     },
  408.  
  409.     {
  410.         {
  411.             "NV12 Scaling module",
  412.             PP_NV12_SCALING,
  413.             pp_nv12_scaling_gen6,
  414.             sizeof(pp_nv12_scaling_gen6),
  415.             NULL,
  416.         },
  417.  
  418.         gen6_nv12_scaling_initialize,
  419.     },
  420.  
  421.     {
  422.         {
  423.             "NV12 AVS module",
  424.             PP_NV12_AVS,
  425.             pp_nv12_avs_gen6,
  426.             sizeof(pp_nv12_avs_gen6),
  427.             NULL,
  428.         },
  429.  
  430.         pp_nv12_avs_initialize_nlas,
  431.     },
  432.  
  433.     {
  434.         {
  435.             "NV12 DNDI module",
  436.             PP_NV12_DNDI,
  437.             pp_nv12_dndi_gen6,
  438.             sizeof(pp_nv12_dndi_gen6),
  439.             NULL,
  440.         },
  441.  
  442.         pp_nv12_dndi_initialize,
  443.     },
  444.  
  445.     {
  446.         {
  447.             "NV12 DN module",
  448.             PP_NV12_DN,
  449.             pp_nv12_dn_gen6,
  450.             sizeof(pp_nv12_dn_gen6),
  451.             NULL,
  452.         },
  453.  
  454.         pp_nv12_dn_initialize,
  455.     },
  456.     {
  457.         {
  458.             "NV12_PA module",
  459.             PP_NV12_LOAD_SAVE_PA,
  460.             pp_nv12_load_save_pa_gen6,
  461.             sizeof(pp_nv12_load_save_pa_gen6),
  462.             NULL,
  463.         },
  464.    
  465.         pp_plx_load_save_plx_initialize,
  466.     },
  467.     {
  468.         {
  469.             "PL3_PA module",
  470.             PP_PL3_LOAD_SAVE_PA,
  471.             pp_pl3_load_save_pa_gen6,
  472.             sizeof(pp_pl3_load_save_pa_gen6),
  473.             NULL,
  474.         },
  475.    
  476.         pp_plx_load_save_plx_initialize,
  477.     },
  478.     {
  479.         {
  480.             "PA_NV12 module",
  481.             PP_PA_LOAD_SAVE_NV12,
  482.             pp_pa_load_save_nv12_gen6,
  483.             sizeof(pp_pa_load_save_nv12_gen6),
  484.             NULL,
  485.         },
  486.    
  487.         pp_plx_load_save_plx_initialize,
  488.     },
  489.  
  490. };
  491.  
  492. static const uint32_t pp_null_gen7[][4] = {
  493. };
  494.  
  495. static const uint32_t pp_nv12_load_save_nv12_gen7[][4] = {
  496. #include "shaders/post_processing/gen7/pl2_to_pl2.g7b"
  497. };
  498.  
  499. static const uint32_t pp_nv12_load_save_pl3_gen7[][4] = {
  500. #include "shaders/post_processing/gen7/pl2_to_pl3.g7b"
  501. };
  502.  
  503. static const uint32_t pp_pl3_load_save_nv12_gen7[][4] = {
  504. #include "shaders/post_processing/gen7/pl3_to_pl2.g7b"
  505. };
  506.  
  507. static const uint32_t pp_pl3_load_save_pl3_gen7[][4] = {
  508. #include "shaders/post_processing/gen7/pl3_to_pl3.g7b"
  509. };
  510.  
  511. static const uint32_t pp_nv12_scaling_gen7[][4] = {
  512. #include "shaders/post_processing/gen7/avs.g7b"
  513. };
  514.  
  515. static const uint32_t pp_nv12_avs_gen7[][4] = {
  516. #include "shaders/post_processing/gen7/avs.g7b"
  517. };
  518.  
  519. static const uint32_t pp_nv12_dndi_gen7[][4] = {
  520. #include "shaders/post_processing/gen7/dndi.g7b"
  521. };
  522.  
  523. static const uint32_t pp_nv12_dn_gen7[][4] = {
  524. #include "shaders/post_processing/gen7/nv12_dn_nv12.g7b"
  525. };
  526.  
  527. static const uint32_t pp_nv12_load_save_pa_gen7[][4] = {
  528. #include "shaders/post_processing/gen7/pl2_to_pa.g7b"
  529. };
  530.  
  531. static const uint32_t pp_pl3_load_save_pa_gen7[][4] = {
  532. #include "shaders/post_processing/gen7/pl3_to_pa.g7b"
  533. };
  534.  
  535. static const uint32_t pp_pa_load_save_nv12_gen7[][4] = {
  536. #include "shaders/post_processing/gen7/pa_to_pl2.g7b"
  537. };
  538.  
  539. static VAStatus gen7_pp_plx_avs_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
  540.                                            const struct i965_surface *src_surface,
  541.                                            const VARectangle *src_rect,
  542.                                            struct i965_surface *dst_surface,
  543.                                            const VARectangle *dst_rect,
  544.                                            void *filter_param);
  545. static VAStatus gen7_pp_nv12_dndi_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
  546.                                              const struct i965_surface *src_surface,
  547.                                              const VARectangle *src_rect,
  548.                                              struct i965_surface *dst_surface,
  549.                                              const VARectangle *dst_rect,
  550.                                              void *filter_param);
  551. static VAStatus gen7_pp_nv12_dn_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
  552.                                            const struct i965_surface *src_surface,
  553.                                            const VARectangle *src_rect,
  554.                                            struct i965_surface *dst_surface,
  555.                                            const VARectangle *dst_rect,
  556.                                            void *filter_param);
  557.  
  558. static struct pp_module pp_modules_gen7[] = {
  559.     {
  560.         {
  561.             "NULL module (for testing)",
  562.             PP_NULL,
  563.             pp_null_gen7,
  564.             sizeof(pp_null_gen7),
  565.             NULL,
  566.         },
  567.  
  568.         pp_null_initialize,
  569.     },
  570.  
  571.     {
  572.         {
  573.             "NV12_NV12",
  574.             PP_NV12_LOAD_SAVE_N12,
  575.             pp_nv12_load_save_nv12_gen7,
  576.             sizeof(pp_nv12_load_save_nv12_gen7),
  577.             NULL,
  578.         },
  579.  
  580.         gen7_pp_plx_avs_initialize,
  581.     },
  582.  
  583.     {
  584.         {
  585.             "NV12_PL3",
  586.             PP_NV12_LOAD_SAVE_PL3,
  587.             pp_nv12_load_save_pl3_gen7,
  588.             sizeof(pp_nv12_load_save_pl3_gen7),
  589.             NULL,
  590.         },
  591.        
  592.         gen7_pp_plx_avs_initialize,
  593.     },
  594.  
  595.     {
  596.         {
  597.             "PL3_NV12",
  598.             PP_PL3_LOAD_SAVE_N12,
  599.             pp_pl3_load_save_nv12_gen7,
  600.             sizeof(pp_pl3_load_save_nv12_gen7),
  601.             NULL,
  602.         },
  603.  
  604.         gen7_pp_plx_avs_initialize,
  605.     },
  606.  
  607.     {
  608.         {
  609.             "PL3_PL3",
  610.             PP_PL3_LOAD_SAVE_N12,
  611.             pp_pl3_load_save_pl3_gen7,
  612.             sizeof(pp_pl3_load_save_pl3_gen7),
  613.             NULL,
  614.         },
  615.  
  616.         gen7_pp_plx_avs_initialize,
  617.     },
  618.  
  619.     {
  620.         {
  621.             "NV12 Scaling module",
  622.             PP_NV12_SCALING,
  623.             pp_nv12_scaling_gen7,
  624.             sizeof(pp_nv12_scaling_gen7),
  625.             NULL,
  626.         },
  627.  
  628.         gen7_pp_plx_avs_initialize,
  629.     },
  630.  
  631.     {
  632.         {
  633.             "NV12 AVS module",
  634.             PP_NV12_AVS,
  635.             pp_nv12_avs_gen7,
  636.             sizeof(pp_nv12_avs_gen7),
  637.             NULL,
  638.         },
  639.  
  640.         gen7_pp_plx_avs_initialize,
  641.     },
  642.  
  643.     {
  644.         {
  645.             "NV12 DNDI module",
  646.             PP_NV12_DNDI,
  647.             pp_nv12_dndi_gen7,
  648.             sizeof(pp_nv12_dndi_gen7),
  649.             NULL,
  650.         },
  651.  
  652.         gen7_pp_nv12_dndi_initialize,
  653.     },
  654.  
  655.     {
  656.         {
  657.             "NV12 DN module",
  658.             PP_NV12_DN,
  659.             pp_nv12_dn_gen7,
  660.             sizeof(pp_nv12_dn_gen7),
  661.             NULL,
  662.         },
  663.  
  664.         gen7_pp_nv12_dn_initialize,
  665.     },
  666.     {
  667.         {
  668.             "NV12_PA module",
  669.             PP_NV12_LOAD_SAVE_PA,
  670.             pp_nv12_load_save_pa_gen7,
  671.             sizeof(pp_nv12_load_save_pa_gen7),
  672.             NULL,
  673.         },
  674.    
  675.         gen7_pp_plx_avs_initialize,
  676.     },
  677.     {
  678.         {
  679.             "PL3_PA module",
  680.             PP_PL3_LOAD_SAVE_PA,
  681.             pp_pl3_load_save_pa_gen7,
  682.             sizeof(pp_pl3_load_save_pa_gen7),
  683.             NULL,
  684.         },
  685.    
  686.         gen7_pp_plx_avs_initialize,
  687.     },
  688.  
  689.     {
  690.         {
  691.             "PA_NV12 module",
  692.             PP_PA_LOAD_SAVE_NV12,
  693.             pp_pa_load_save_nv12_gen7,
  694.             sizeof(pp_pa_load_save_nv12_gen7),
  695.             NULL,
  696.         },
  697.    
  698.         gen7_pp_plx_avs_initialize,
  699.     },
  700. };
  701.  
  702. static const uint32_t pp_null_gen75[][4] = {
  703. };
  704.  
  705. static const uint32_t pp_nv12_load_save_nv12_gen75[][4] = {
  706. #include "shaders/post_processing/gen7/pl2_to_pl2.g75b"
  707. };
  708.  
  709. static const uint32_t pp_nv12_load_save_pl3_gen75[][4] = {
  710. #include "shaders/post_processing/gen7/pl2_to_pl3.g75b"
  711. };
  712.  
  713. static const uint32_t pp_pl3_load_save_nv12_gen75[][4] = {
  714. #include "shaders/post_processing/gen7/pl3_to_pl2.g75b"
  715. };
  716.  
  717. static const uint32_t pp_pl3_load_save_pl3_gen75[][4] = {
  718. #include "shaders/post_processing/gen7/pl3_to_pl3.g75b"
  719. };
  720.  
  721. static const uint32_t pp_nv12_scaling_gen75[][4] = {
  722. #include "shaders/post_processing/gen7/avs.g75b"
  723. };
  724.  
  725. static const uint32_t pp_nv12_avs_gen75[][4] = {
  726. #include "shaders/post_processing/gen7/avs.g75b"
  727. };
  728.  
  729. static const uint32_t pp_nv12_dndi_gen75[][4] = {
  730. // #include "shaders/post_processing/gen7/dndi.g75b"
  731. };
  732.  
  733. static const uint32_t pp_nv12_dn_gen75[][4] = {
  734. // #include "shaders/post_processing/gen7/nv12_dn_nv12.g75b"
  735. };
  736. static const uint32_t pp_nv12_load_save_pa_gen75[][4] = {
  737. #include "shaders/post_processing/gen7/pl2_to_pa.g75b"
  738. };
  739.  
  740. static const uint32_t pp_pl3_load_save_pa_gen75[][4] = {
  741. #include "shaders/post_processing/gen7/pl3_to_pa.g75b"
  742. };
  743.  
  744. static const uint32_t pp_pa_load_save_nv12_gen75[][4] = {
  745. #include "shaders/post_processing/gen7/pa_to_pl2.g75b"
  746. };
  747.  
  748. static struct pp_module pp_modules_gen75[] = {
  749.     {
  750.         {
  751.             "NULL module (for testing)",
  752.             PP_NULL,
  753.             pp_null_gen75,
  754.             sizeof(pp_null_gen75),
  755.             NULL,
  756.         },
  757.  
  758.         pp_null_initialize,
  759.     },
  760.  
  761.     {
  762.         {
  763.             "NV12_NV12",
  764.             PP_NV12_LOAD_SAVE_N12,
  765.             pp_nv12_load_save_nv12_gen75,
  766.             sizeof(pp_nv12_load_save_nv12_gen75),
  767.             NULL,
  768.         },
  769.  
  770.         gen7_pp_plx_avs_initialize,
  771.     },
  772.  
  773.     {
  774.         {
  775.             "NV12_PL3",
  776.             PP_NV12_LOAD_SAVE_PL3,
  777.             pp_nv12_load_save_pl3_gen75,
  778.             sizeof(pp_nv12_load_save_pl3_gen75),
  779.             NULL,
  780.         },
  781.        
  782.         gen7_pp_plx_avs_initialize,
  783.     },
  784.  
  785.     {
  786.         {
  787.             "PL3_NV12",
  788.             PP_PL3_LOAD_SAVE_N12,
  789.             pp_pl3_load_save_nv12_gen75,
  790.             sizeof(pp_pl3_load_save_nv12_gen75),
  791.             NULL,
  792.         },
  793.  
  794.         gen7_pp_plx_avs_initialize,
  795.     },
  796.  
  797.     {
  798.         {
  799.             "PL3_PL3",
  800.             PP_PL3_LOAD_SAVE_N12,
  801.             pp_pl3_load_save_pl3_gen75,
  802.             sizeof(pp_pl3_load_save_pl3_gen75),
  803.             NULL,
  804.         },
  805.  
  806.         gen7_pp_plx_avs_initialize,
  807.     },
  808.  
  809.     {
  810.         {
  811.             "NV12 Scaling module",
  812.             PP_NV12_SCALING,
  813.             pp_nv12_scaling_gen75,
  814.             sizeof(pp_nv12_scaling_gen75),
  815.             NULL,
  816.         },
  817.  
  818.         gen7_pp_plx_avs_initialize,
  819.     },
  820.  
  821.     {
  822.         {
  823.             "NV12 AVS module",
  824.             PP_NV12_AVS,
  825.             pp_nv12_avs_gen75,
  826.             sizeof(pp_nv12_avs_gen75),
  827.             NULL,
  828.         },
  829.  
  830.         gen7_pp_plx_avs_initialize,
  831.     },
  832.  
  833.     {
  834.         {
  835.             "NV12 DNDI module",
  836.             PP_NV12_DNDI,
  837.             pp_nv12_dndi_gen75,
  838.             sizeof(pp_nv12_dndi_gen75),
  839.             NULL,
  840.         },
  841.  
  842.         gen7_pp_nv12_dndi_initialize,
  843.     },
  844.  
  845.     {
  846.         {
  847.             "NV12 DN module",
  848.             PP_NV12_DN,
  849.             pp_nv12_dn_gen75,
  850.             sizeof(pp_nv12_dn_gen75),
  851.             NULL,
  852.         },
  853.  
  854.         gen7_pp_nv12_dn_initialize,
  855.     },
  856.     {
  857.         {
  858.             "NV12_PA module",
  859.             PP_NV12_LOAD_SAVE_PA,
  860.             pp_nv12_load_save_pa_gen75,
  861.             sizeof(pp_nv12_load_save_pa_gen75),
  862.             NULL,
  863.         },
  864.    
  865.         gen7_pp_plx_avs_initialize,
  866.     },
  867.  
  868.     {
  869.         {
  870.             "PL3_PA module",
  871.             PP_PL3_LOAD_SAVE_PA,
  872.             pp_pl3_load_save_pa_gen75,
  873.             sizeof(pp_pl3_load_save_pa_gen75),
  874.             NULL,
  875.         },
  876.    
  877.         gen7_pp_plx_avs_initialize,
  878.     },
  879.  
  880.     {
  881.         {
  882.             "PA_NV12 module",
  883.             PP_PA_LOAD_SAVE_NV12,
  884.             pp_pa_load_save_nv12_gen75,
  885.             sizeof(pp_pa_load_save_nv12_gen75),
  886.             NULL,
  887.         },
  888.    
  889.         gen7_pp_plx_avs_initialize,
  890.     },
  891.          
  892. };
  893.  
  894. static int
  895. pp_get_surface_fourcc(VADriverContextP ctx, const struct i965_surface *surface)
  896. {
  897.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  898.     int fourcc;
  899.  
  900.     if (surface->type == I965_SURFACE_TYPE_IMAGE) {
  901.         struct object_image *obj_image = IMAGE(surface->id);
  902.         fourcc = obj_image->image.format.fourcc;
  903.     } else {
  904.         struct object_surface *obj_surface = SURFACE(surface->id);
  905.         fourcc = obj_surface->fourcc;
  906.     }
  907.  
  908.     return fourcc;
  909. }
  910.  
  911. static void
  912. pp_set_surface_tiling(struct i965_surface_state *ss, unsigned int tiling)
  913. {
  914.     switch (tiling) {
  915.     case I915_TILING_NONE:
  916.         ss->ss3.tiled_surface = 0;
  917.         ss->ss3.tile_walk = 0;
  918.         break;
  919.     case I915_TILING_X:
  920.         ss->ss3.tiled_surface = 1;
  921.         ss->ss3.tile_walk = I965_TILEWALK_XMAJOR;
  922.         break;
  923.     case I915_TILING_Y:
  924.         ss->ss3.tiled_surface = 1;
  925.         ss->ss3.tile_walk = I965_TILEWALK_YMAJOR;
  926.         break;
  927.     }
  928. }
  929.  
  930. static void
  931. pp_set_surface2_tiling(struct i965_surface_state2 *ss, unsigned int tiling)
  932. {
  933.     switch (tiling) {
  934.     case I915_TILING_NONE:
  935.         ss->ss2.tiled_surface = 0;
  936.         ss->ss2.tile_walk = 0;
  937.         break;
  938.     case I915_TILING_X:
  939.         ss->ss2.tiled_surface = 1;
  940.         ss->ss2.tile_walk = I965_TILEWALK_XMAJOR;
  941.         break;
  942.     case I915_TILING_Y:
  943.         ss->ss2.tiled_surface = 1;
  944.         ss->ss2.tile_walk = I965_TILEWALK_YMAJOR;
  945.         break;
  946.     }
  947. }
  948.  
  949. static void
  950. gen7_pp_set_surface_tiling(struct gen7_surface_state *ss, unsigned int tiling)
  951. {
  952.     switch (tiling) {
  953.     case I915_TILING_NONE:
  954.         ss->ss0.tiled_surface = 0;
  955.         ss->ss0.tile_walk = 0;
  956.         break;
  957.     case I915_TILING_X:
  958.         ss->ss0.tiled_surface = 1;
  959.         ss->ss0.tile_walk = I965_TILEWALK_XMAJOR;
  960.         break;
  961.     case I915_TILING_Y:
  962.         ss->ss0.tiled_surface = 1;
  963.         ss->ss0.tile_walk = I965_TILEWALK_YMAJOR;
  964.         break;
  965.     }
  966. }
  967.  
  968. static void
  969. gen7_pp_set_surface2_tiling(struct gen7_surface_state2 *ss, unsigned int tiling)
  970. {
  971.     switch (tiling) {
  972.     case I915_TILING_NONE:
  973.         ss->ss2.tiled_surface = 0;
  974.         ss->ss2.tile_walk = 0;
  975.         break;
  976.     case I915_TILING_X:
  977.         ss->ss2.tiled_surface = 1;
  978.         ss->ss2.tile_walk = I965_TILEWALK_XMAJOR;
  979.         break;
  980.     case I915_TILING_Y:
  981.         ss->ss2.tiled_surface = 1;
  982.         ss->ss2.tile_walk = I965_TILEWALK_YMAJOR;
  983.         break;
  984.     }
  985. }
  986.  
  987.  
  988. static void
  989. ironlake_pp_interface_descriptor_table(struct i965_post_processing_context *pp_context)
  990. {
  991.     struct i965_interface_descriptor *desc;
  992.     dri_bo *bo;
  993.     int pp_index = pp_context->current_pp;
  994.  
  995.     bo = pp_context->idrt.bo;
  996.     dri_bo_map(bo, 1);
  997.     assert(bo->virtual);
  998.     desc = bo->virtual;
  999.     memset(desc, 0, sizeof(*desc));
  1000.     desc->desc0.grf_reg_blocks = 10;
  1001.     desc->desc0.kernel_start_pointer = pp_context->pp_modules[pp_index].kernel.bo->offset >> 6; /* reloc */
  1002.     desc->desc1.const_urb_entry_read_offset = 0;
  1003.     desc->desc1.const_urb_entry_read_len = 4; /* grf 1-4 */
  1004.     desc->desc2.sampler_state_pointer = pp_context->sampler_state_table.bo->offset >> 5;
  1005.     desc->desc2.sampler_count = 0;
  1006.     desc->desc3.binding_table_entry_count = 0;
  1007.     desc->desc3.binding_table_pointer = (BINDING_TABLE_OFFSET >> 5);
  1008.  
  1009.     dri_bo_emit_reloc(bo,
  1010.                       I915_GEM_DOMAIN_INSTRUCTION, 0,
  1011.                       desc->desc0.grf_reg_blocks,
  1012.                       offsetof(struct i965_interface_descriptor, desc0),
  1013.                       pp_context->pp_modules[pp_index].kernel.bo);
  1014.  
  1015.     dri_bo_emit_reloc(bo,
  1016.                       I915_GEM_DOMAIN_INSTRUCTION, 0,
  1017.                       desc->desc2.sampler_count << 2,
  1018.                       offsetof(struct i965_interface_descriptor, desc2),
  1019.                       pp_context->sampler_state_table.bo);
  1020.  
  1021.     dri_bo_unmap(bo);
  1022.     pp_context->idrt.num_interface_descriptors++;
  1023. }
  1024.  
  1025. static void
  1026. ironlake_pp_vfe_state(struct i965_post_processing_context *pp_context)
  1027. {
  1028.     struct i965_vfe_state *vfe_state;
  1029.     dri_bo *bo;
  1030.  
  1031.     bo = pp_context->vfe_state.bo;
  1032.     dri_bo_map(bo, 1);
  1033.     assert(bo->virtual);
  1034.     vfe_state = bo->virtual;
  1035.     memset(vfe_state, 0, sizeof(*vfe_state));
  1036.     vfe_state->vfe1.max_threads = pp_context->urb.num_vfe_entries - 1;
  1037.     vfe_state->vfe1.urb_entry_alloc_size = pp_context->urb.size_vfe_entry - 1;
  1038.     vfe_state->vfe1.num_urb_entries = pp_context->urb.num_vfe_entries;
  1039.     vfe_state->vfe1.vfe_mode = VFE_GENERIC_MODE;
  1040.     vfe_state->vfe1.children_present = 0;
  1041.     vfe_state->vfe2.interface_descriptor_base =
  1042.         pp_context->idrt.bo->offset >> 4; /* reloc */
  1043.     dri_bo_emit_reloc(bo,
  1044.                       I915_GEM_DOMAIN_INSTRUCTION, 0,
  1045.                       0,
  1046.                       offsetof(struct i965_vfe_state, vfe2),
  1047.                       pp_context->idrt.bo);
  1048.     dri_bo_unmap(bo);
  1049. }
  1050.  
  1051. static void
  1052. ironlake_pp_upload_constants(struct i965_post_processing_context *pp_context)
  1053. {
  1054.     unsigned char *constant_buffer;
  1055.     struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
  1056.  
  1057.     assert(sizeof(*pp_static_parameter) == 128);
  1058.     dri_bo_map(pp_context->curbe.bo, 1);
  1059.     assert(pp_context->curbe.bo->virtual);
  1060.     constant_buffer = pp_context->curbe.bo->virtual;
  1061.     memcpy(constant_buffer, pp_static_parameter, sizeof(*pp_static_parameter));
  1062.     dri_bo_unmap(pp_context->curbe.bo);
  1063. }
  1064.  
  1065. static void
  1066. ironlake_pp_states_setup(VADriverContextP ctx,
  1067.                          struct i965_post_processing_context *pp_context)
  1068. {
  1069.     ironlake_pp_interface_descriptor_table(pp_context);
  1070.     ironlake_pp_vfe_state(pp_context);
  1071.     ironlake_pp_upload_constants(pp_context);
  1072. }
  1073.  
  1074. static void
  1075. ironlake_pp_pipeline_select(VADriverContextP ctx,
  1076.                             struct i965_post_processing_context *pp_context)
  1077. {
  1078.     struct intel_batchbuffer *batch = pp_context->batch;
  1079.  
  1080.     BEGIN_BATCH(batch, 1);
  1081.     OUT_BATCH(batch, CMD_PIPELINE_SELECT | PIPELINE_SELECT_MEDIA);
  1082.     ADVANCE_BATCH(batch);
  1083. }
  1084.  
  1085. static void
  1086. ironlake_pp_urb_layout(VADriverContextP ctx,
  1087.                        struct i965_post_processing_context *pp_context)
  1088. {
  1089.     struct intel_batchbuffer *batch = pp_context->batch;
  1090.     unsigned int vfe_fence, cs_fence;
  1091.  
  1092.     vfe_fence = pp_context->urb.cs_start;
  1093.     cs_fence = pp_context->urb.size;
  1094.  
  1095.     BEGIN_BATCH(batch, 3);
  1096.     OUT_BATCH(batch, CMD_URB_FENCE | UF0_VFE_REALLOC | UF0_CS_REALLOC | 1);
  1097.     OUT_BATCH(batch, 0);
  1098.     OUT_BATCH(batch,
  1099.               (vfe_fence << UF2_VFE_FENCE_SHIFT) |      /* VFE_SIZE */
  1100.               (cs_fence << UF2_CS_FENCE_SHIFT));        /* CS_SIZE */
  1101.     ADVANCE_BATCH(batch);
  1102. }
  1103.  
  1104. static void
  1105. ironlake_pp_state_base_address(VADriverContextP ctx,
  1106.                                struct i965_post_processing_context *pp_context)
  1107. {
  1108.     struct intel_batchbuffer *batch = pp_context->batch;
  1109.  
  1110.     BEGIN_BATCH(batch, 8);
  1111.     OUT_BATCH(batch, CMD_STATE_BASE_ADDRESS | 6);
  1112.     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
  1113.     OUT_RELOC(batch, pp_context->surface_state_binding_table.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, BASE_ADDRESS_MODIFY);
  1114.     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
  1115.     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
  1116.     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
  1117.     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
  1118.     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
  1119.     ADVANCE_BATCH(batch);
  1120. }
  1121.  
  1122. static void
  1123. ironlake_pp_state_pointers(VADriverContextP ctx,
  1124.                            struct i965_post_processing_context *pp_context)
  1125. {
  1126.     struct intel_batchbuffer *batch = pp_context->batch;
  1127.  
  1128.     BEGIN_BATCH(batch, 3);
  1129.     OUT_BATCH(batch, CMD_MEDIA_STATE_POINTERS | 1);
  1130.     OUT_BATCH(batch, 0);
  1131.     OUT_RELOC(batch, pp_context->vfe_state.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
  1132.     ADVANCE_BATCH(batch);
  1133. }
  1134.  
  1135. static void
  1136. ironlake_pp_cs_urb_layout(VADriverContextP ctx,
  1137.                           struct i965_post_processing_context *pp_context)
  1138. {
  1139.     struct intel_batchbuffer *batch = pp_context->batch;
  1140.  
  1141.     BEGIN_BATCH(batch, 2);
  1142.     OUT_BATCH(batch, CMD_CS_URB_STATE | 0);
  1143.     OUT_BATCH(batch,
  1144.               ((pp_context->urb.size_cs_entry - 1) << 4) |     /* URB Entry Allocation Size */
  1145.               (pp_context->urb.num_cs_entries << 0));          /* Number of URB Entries */
  1146.     ADVANCE_BATCH(batch);
  1147. }
  1148.  
  1149. static void
  1150. ironlake_pp_constant_buffer(VADriverContextP ctx,
  1151.                             struct i965_post_processing_context *pp_context)
  1152. {
  1153.     struct intel_batchbuffer *batch = pp_context->batch;
  1154.  
  1155.     BEGIN_BATCH(batch, 2);
  1156.     OUT_BATCH(batch, CMD_CONSTANT_BUFFER | (1 << 8) | (2 - 2));
  1157.     OUT_RELOC(batch, pp_context->curbe.bo,
  1158.               I915_GEM_DOMAIN_INSTRUCTION, 0,
  1159.               pp_context->urb.size_cs_entry - 1);
  1160.     ADVANCE_BATCH(batch);    
  1161. }
  1162.  
  1163. static void
  1164. ironlake_pp_object_walker(VADriverContextP ctx,
  1165.                           struct i965_post_processing_context *pp_context)
  1166. {
  1167.     struct intel_batchbuffer *batch = pp_context->batch;
  1168.     int x, x_steps, y, y_steps;
  1169.     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
  1170.  
  1171.     x_steps = pp_context->pp_x_steps(&pp_context->private_context);
  1172.     y_steps = pp_context->pp_y_steps(&pp_context->private_context);
  1173.  
  1174.     for (y = 0; y < y_steps; y++) {
  1175.         for (x = 0; x < x_steps; x++) {
  1176.             if (!pp_context->pp_set_block_parameter(pp_context, x, y)) {
  1177.                 BEGIN_BATCH(batch, 20);
  1178.                 OUT_BATCH(batch, CMD_MEDIA_OBJECT | 18);
  1179.                 OUT_BATCH(batch, 0);
  1180.                 OUT_BATCH(batch, 0); /* no indirect data */
  1181.                 OUT_BATCH(batch, 0);
  1182.  
  1183.                 /* inline data grf 5-6 */
  1184.                 assert(sizeof(*pp_inline_parameter) == 64);
  1185.                 intel_batchbuffer_data(batch, pp_inline_parameter, sizeof(*pp_inline_parameter));
  1186.  
  1187.                 ADVANCE_BATCH(batch);
  1188.             }
  1189.         }
  1190.     }
  1191. }
  1192.  
  1193. static void
  1194. ironlake_pp_pipeline_setup(VADriverContextP ctx,
  1195.                            struct i965_post_processing_context *pp_context)
  1196. {
  1197.     struct intel_batchbuffer *batch = pp_context->batch;
  1198.  
  1199.     intel_batchbuffer_start_atomic(batch, 0x1000);
  1200.     intel_batchbuffer_emit_mi_flush(batch);
  1201.     ironlake_pp_pipeline_select(ctx, pp_context);
  1202.     ironlake_pp_state_base_address(ctx, pp_context);
  1203.     ironlake_pp_state_pointers(ctx, pp_context);
  1204.     ironlake_pp_urb_layout(ctx, pp_context);
  1205.     ironlake_pp_cs_urb_layout(ctx, pp_context);
  1206.     ironlake_pp_constant_buffer(ctx, pp_context);
  1207.     ironlake_pp_object_walker(ctx, pp_context);
  1208.     intel_batchbuffer_end_atomic(batch);
  1209. }
  1210.  
  1211. // update u/v offset when the surface format are packed yuv
  1212. static void i965_update_src_surface_uv_offset(
  1213.     VADriverContextP    ctx,
  1214.     struct i965_post_processing_context *pp_context,
  1215.     const struct i965_surface *surface)
  1216. {
  1217.     struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
  1218.     int fourcc = pp_get_surface_fourcc(ctx, surface);
  1219.    
  1220.     if (fourcc == VA_FOURCC('Y', 'U', 'Y', '2')) {
  1221.         pp_static_parameter->grf1.source_packed_u_offset = 1;
  1222.         pp_static_parameter->grf1.source_packed_v_offset = 3;
  1223.     }
  1224.     else if (fourcc == VA_FOURCC('U', 'Y', 'V', 'Y')) {
  1225.         pp_static_parameter->grf1.source_packed_y_offset = 1;
  1226.         pp_static_parameter->grf1.source_packed_v_offset = 2;
  1227.     }
  1228.    
  1229. }
  1230.  
  1231. static void i965_update_dst_surface_uv_offset(
  1232.     VADriverContextP    ctx,
  1233.     struct i965_post_processing_context *pp_context,
  1234.     const struct i965_surface *surface)
  1235. {
  1236.     struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
  1237.     int fourcc = pp_get_surface_fourcc(ctx, surface);
  1238.    
  1239.     if (fourcc == VA_FOURCC('Y', 'U', 'Y', '2')) {
  1240.         pp_static_parameter->grf1.r1_2.load_and_save.destination_packed_u_offset = 1;
  1241.         pp_static_parameter->grf1.r1_2.load_and_save.destination_packed_v_offset = 3;
  1242.     }
  1243.     else if (fourcc == VA_FOURCC('U', 'Y', 'V', 'Y')) {
  1244.         pp_static_parameter->grf1.r1_2.load_and_save.destination_packed_y_offset = 1;
  1245.         pp_static_parameter->grf1.r1_2.load_and_save.destination_packed_v_offset = 2;
  1246.     }
  1247.    
  1248. }
  1249.  
  1250. static void
  1251. i965_pp_set_surface_state(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
  1252.                           dri_bo *surf_bo, unsigned long surf_bo_offset,
  1253.                           int width, int height, int pitch, int format,
  1254.                           int index, int is_target)
  1255. {
  1256.     struct i965_surface_state *ss;
  1257.     dri_bo *ss_bo;
  1258.     unsigned int tiling;
  1259.     unsigned int swizzle;
  1260.  
  1261.     dri_bo_get_tiling(surf_bo, &tiling, &swizzle);
  1262.     ss_bo = pp_context->surface_state_binding_table.bo;
  1263.     assert(ss_bo);
  1264.  
  1265.     dri_bo_map(ss_bo, True);
  1266.     assert(ss_bo->virtual);
  1267.     ss = (struct i965_surface_state *)((char *)ss_bo->virtual + SURFACE_STATE_OFFSET(index));
  1268.     memset(ss, 0, sizeof(*ss));
  1269.     ss->ss0.surface_type = I965_SURFACE_2D;
  1270.     ss->ss0.surface_format = format;
  1271.     ss->ss1.base_addr = surf_bo->offset + surf_bo_offset;
  1272.     ss->ss2.width = width - 1;
  1273.     ss->ss2.height = height - 1;
  1274.     ss->ss3.pitch = pitch - 1;
  1275.     pp_set_surface_tiling(ss, tiling);
  1276.     dri_bo_emit_reloc(ss_bo,
  1277.                       I915_GEM_DOMAIN_RENDER, is_target ? I915_GEM_DOMAIN_RENDER : 0,
  1278.                       surf_bo_offset,
  1279.                       SURFACE_STATE_OFFSET(index) + offsetof(struct i965_surface_state, ss1),
  1280.                       surf_bo);
  1281.     ((unsigned int *)((char *)ss_bo->virtual + BINDING_TABLE_OFFSET))[index] = SURFACE_STATE_OFFSET(index);
  1282.     dri_bo_unmap(ss_bo);
  1283. }
  1284.  
  1285. static void
  1286. i965_pp_set_surface2_state(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
  1287.                            dri_bo *surf_bo, unsigned long surf_bo_offset,
  1288.                            int width, int height, int wpitch,
  1289.                            int xoffset, int yoffset,
  1290.                            int format, int interleave_chroma,
  1291.                            int index)
  1292. {
  1293.     struct i965_surface_state2 *ss2;
  1294.     dri_bo *ss2_bo;
  1295.     unsigned int tiling;
  1296.     unsigned int swizzle;
  1297.  
  1298.     dri_bo_get_tiling(surf_bo, &tiling, &swizzle);
  1299.     ss2_bo = pp_context->surface_state_binding_table.bo;
  1300.     assert(ss2_bo);
  1301.  
  1302.     dri_bo_map(ss2_bo, True);
  1303.     assert(ss2_bo->virtual);
  1304.     ss2 = (struct i965_surface_state2 *)((char *)ss2_bo->virtual + SURFACE_STATE_OFFSET(index));
  1305.     memset(ss2, 0, sizeof(*ss2));
  1306.     ss2->ss0.surface_base_address = surf_bo->offset + surf_bo_offset;
  1307.     ss2->ss1.cbcr_pixel_offset_v_direction = 0;
  1308.     ss2->ss1.width = width - 1;
  1309.     ss2->ss1.height = height - 1;
  1310.     ss2->ss2.pitch = wpitch - 1;
  1311.     ss2->ss2.interleave_chroma = interleave_chroma;
  1312.     ss2->ss2.surface_format = format;
  1313.     ss2->ss3.x_offset_for_cb = xoffset;
  1314.     ss2->ss3.y_offset_for_cb = yoffset;
  1315.     pp_set_surface2_tiling(ss2, tiling);
  1316.     dri_bo_emit_reloc(ss2_bo,
  1317.                       I915_GEM_DOMAIN_RENDER, 0,
  1318.                       surf_bo_offset,
  1319.                       SURFACE_STATE_OFFSET(index) + offsetof(struct i965_surface_state2, ss0),
  1320.                       surf_bo);
  1321.     ((unsigned int *)((char *)ss2_bo->virtual + BINDING_TABLE_OFFSET))[index] = SURFACE_STATE_OFFSET(index);
  1322.     dri_bo_unmap(ss2_bo);
  1323. }
  1324.  
  1325. static void
  1326. gen7_pp_set_surface_state(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
  1327.                           dri_bo *surf_bo, unsigned long surf_bo_offset,
  1328.                           int width, int height, int pitch, int format,
  1329.                           int index, int is_target)
  1330. {
  1331.     struct i965_driver_data * const i965 = i965_driver_data(ctx);  
  1332.     struct gen7_surface_state *ss;
  1333.     dri_bo *ss_bo;
  1334.     unsigned int tiling;
  1335.     unsigned int swizzle;
  1336.  
  1337.     dri_bo_get_tiling(surf_bo, &tiling, &swizzle);
  1338.     ss_bo = pp_context->surface_state_binding_table.bo;
  1339.     assert(ss_bo);
  1340.  
  1341.     dri_bo_map(ss_bo, True);
  1342.     assert(ss_bo->virtual);
  1343.     ss = (struct gen7_surface_state *)((char *)ss_bo->virtual + SURFACE_STATE_OFFSET(index));
  1344.     memset(ss, 0, sizeof(*ss));
  1345.     ss->ss0.surface_type = I965_SURFACE_2D;
  1346.     ss->ss0.surface_format = format;
  1347.     ss->ss1.base_addr = surf_bo->offset + surf_bo_offset;
  1348.     ss->ss2.width = width - 1;
  1349.     ss->ss2.height = height - 1;
  1350.     ss->ss3.pitch = pitch - 1;
  1351.     gen7_pp_set_surface_tiling(ss, tiling);
  1352.     if (IS_HASWELL(i965->intel.device_id))
  1353.         gen7_render_set_surface_scs(ss);
  1354.     dri_bo_emit_reloc(ss_bo,
  1355.                       I915_GEM_DOMAIN_RENDER, is_target ? I915_GEM_DOMAIN_RENDER : 0,
  1356.                       surf_bo_offset,
  1357.                       SURFACE_STATE_OFFSET(index) + offsetof(struct gen7_surface_state, ss1),
  1358.                       surf_bo);
  1359.     ((unsigned int *)((char *)ss_bo->virtual + BINDING_TABLE_OFFSET))[index] = SURFACE_STATE_OFFSET(index);
  1360.     dri_bo_unmap(ss_bo);
  1361. }
  1362.  
  1363. static void
  1364. gen7_pp_set_surface2_state(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
  1365.                            dri_bo *surf_bo, unsigned long surf_bo_offset,
  1366.                            int width, int height, int wpitch,
  1367.                            int xoffset, int yoffset,
  1368.                            int format, int interleave_chroma,
  1369.                            int index)
  1370. {
  1371.     struct gen7_surface_state2 *ss2;
  1372.     dri_bo *ss2_bo;
  1373.     unsigned int tiling;
  1374.     unsigned int swizzle;
  1375.  
  1376.     dri_bo_get_tiling(surf_bo, &tiling, &swizzle);
  1377.     ss2_bo = pp_context->surface_state_binding_table.bo;
  1378.     assert(ss2_bo);
  1379.  
  1380.     dri_bo_map(ss2_bo, True);
  1381.     assert(ss2_bo->virtual);
  1382.     ss2 = (struct gen7_surface_state2 *)((char *)ss2_bo->virtual + SURFACE_STATE_OFFSET(index));
  1383.     memset(ss2, 0, sizeof(*ss2));
  1384.     ss2->ss0.surface_base_address = surf_bo->offset + surf_bo_offset;
  1385.     ss2->ss1.cbcr_pixel_offset_v_direction = 0;
  1386.     ss2->ss1.width = width - 1;
  1387.     ss2->ss1.height = height - 1;
  1388.     ss2->ss2.pitch = wpitch - 1;
  1389.     ss2->ss2.interleave_chroma = interleave_chroma;
  1390.     ss2->ss2.surface_format = format;
  1391.     ss2->ss3.x_offset_for_cb = xoffset;
  1392.     ss2->ss3.y_offset_for_cb = yoffset;
  1393.     gen7_pp_set_surface2_tiling(ss2, tiling);
  1394.     dri_bo_emit_reloc(ss2_bo,
  1395.                       I915_GEM_DOMAIN_RENDER, 0,
  1396.                       surf_bo_offset,
  1397.                       SURFACE_STATE_OFFSET(index) + offsetof(struct gen7_surface_state2, ss0),
  1398.                       surf_bo);
  1399.     ((unsigned int *)((char *)ss2_bo->virtual + BINDING_TABLE_OFFSET))[index] = SURFACE_STATE_OFFSET(index);
  1400.     dri_bo_unmap(ss2_bo);
  1401. }
  1402.  
  1403.  
  1404. static void
  1405. pp_set_media_rw_message_surface(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
  1406.                                 const struct i965_surface *surface,
  1407.                                 int base_index, int is_target,
  1408.                                 int *width, int *height, int *pitch, int *offset)
  1409. {
  1410.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  1411.     struct object_surface *obj_surface;
  1412.     struct object_image *obj_image;
  1413.     dri_bo *bo;
  1414.     int fourcc = pp_get_surface_fourcc(ctx, surface);
  1415.     const int Y = 0;
  1416.     const int U = fourcc == VA_FOURCC('Y', 'V', '1', '2') ? 2 : 1;
  1417.     const int V = fourcc == VA_FOURCC('Y', 'V', '1', '2') ? 1 : 2;
  1418.     const int UV = 1;
  1419.     int interleaved_uv = fourcc == VA_FOURCC('N', 'V', '1', '2');
  1420.     int packed_yuv = (fourcc == VA_FOURCC('Y', 'U', 'Y', '2') || fourcc == VA_FOURCC('U', 'Y', 'V', 'Y'));
  1421.  
  1422.     int full_packed_format = (fourcc == VA_FOURCC('R', 'G', 'B', 'A') ||
  1423.                               fourcc == VA_FOURCC('R', 'G', 'B', 'X') ||
  1424.                               fourcc == VA_FOURCC('B', 'G', 'R', 'A') ||
  1425.                               fourcc == VA_FOURCC('B', 'G', 'R', 'X'));
  1426.     int scale_factor_of_1st_plane_width_in_byte = 1;
  1427.                              
  1428.  
  1429.     if (surface->type == I965_SURFACE_TYPE_SURFACE) {
  1430.         obj_surface = SURFACE(surface->id);
  1431.         bo = obj_surface->bo;
  1432.         width[0] = obj_surface->orig_width;
  1433.         height[0] = obj_surface->orig_height;
  1434.         pitch[0] = obj_surface->width;
  1435.         offset[0] = 0;
  1436.  
  1437.         if (full_packed_format) {
  1438.             scale_factor_of_1st_plane_width_in_byte = 4;
  1439.             pitch[0] = obj_surface->width * 4;
  1440.         }
  1441.         else if (packed_yuv ) {
  1442.             scale_factor_of_1st_plane_width_in_byte =  2;
  1443.             pitch[0] = obj_surface->width * 2;
  1444.         }
  1445.         else if (interleaved_uv) {
  1446.             width[1] = obj_surface->orig_width;
  1447.             height[1] = obj_surface->orig_height / 2;
  1448.             pitch[1] = obj_surface->width;
  1449.             offset[1] = offset[0] + obj_surface->width * obj_surface->height;
  1450.         } else {
  1451.             width[1] = obj_surface->orig_width / 2;
  1452.             height[1] = obj_surface->orig_height / 2;
  1453.             pitch[1] = obj_surface->width / 2;
  1454.             offset[1] = offset[0] + obj_surface->width * obj_surface->height;
  1455.             width[2] = obj_surface->orig_width / 2;
  1456.             height[2] = obj_surface->orig_height / 2;
  1457.             pitch[2] = obj_surface->width / 2;
  1458.             offset[2] = offset[1] + (obj_surface->width / 2) * (obj_surface->height / 2);
  1459.         }
  1460.     } else {
  1461.         obj_image = IMAGE(surface->id);
  1462.         bo = obj_image->bo;
  1463.         width[0] = obj_image->image.width;
  1464.         height[0] = obj_image->image.height;
  1465.         pitch[0] = obj_image->image.pitches[0];
  1466.         offset[0] = obj_image->image.offsets[0];
  1467.  
  1468.         if (full_packed_format) {
  1469.             scale_factor_of_1st_plane_width_in_byte = 4;
  1470.         }
  1471.         else if (packed_yuv ) {
  1472.             scale_factor_of_1st_plane_width_in_byte = 2;
  1473.         }
  1474.         else if (interleaved_uv) {
  1475.             width[1] = obj_image->image.width;
  1476.             height[1] = obj_image->image.height / 2;
  1477.             pitch[1] = obj_image->image.pitches[1];
  1478.             offset[1] = obj_image->image.offsets[1];
  1479.         } else {
  1480.             width[1] = obj_image->image.width / 2;
  1481.             height[1] = obj_image->image.height / 2;
  1482.             pitch[1] = obj_image->image.pitches[1];
  1483.             offset[1] = obj_image->image.offsets[1];
  1484.             width[2] = obj_image->image.width / 2;
  1485.             height[2] = obj_image->image.height / 2;
  1486.             pitch[2] = obj_image->image.pitches[2];
  1487.             offset[2] = obj_image->image.offsets[2];
  1488.         }
  1489.     }
  1490.  
  1491.     /* Y surface */
  1492.     i965_pp_set_surface_state(ctx, pp_context,
  1493.                               bo, offset[Y],
  1494.                               width[Y] *scale_factor_of_1st_plane_width_in_byte / 4, height[Y], pitch[Y], I965_SURFACEFORMAT_R8_UNORM,
  1495.                               base_index, is_target);
  1496.  
  1497.     if (!packed_yuv && !full_packed_format) {
  1498.         if (interleaved_uv) {
  1499.             i965_pp_set_surface_state(ctx, pp_context,
  1500.                                       bo, offset[UV],
  1501.                                       width[UV] / 4, height[UV], pitch[UV], I965_SURFACEFORMAT_R8_UNORM,
  1502.                                       base_index + 1, is_target);
  1503.         } else {
  1504.             /* U surface */
  1505.             i965_pp_set_surface_state(ctx, pp_context,
  1506.                                       bo, offset[U],
  1507.                                       width[U] / 4, height[U], pitch[U], I965_SURFACEFORMAT_R8_UNORM,
  1508.                                       base_index + 1, is_target);
  1509.  
  1510.             /* V surface */
  1511.             i965_pp_set_surface_state(ctx, pp_context,
  1512.                                       bo, offset[V],
  1513.                                       width[V] / 4, height[V], pitch[V], I965_SURFACEFORMAT_R8_UNORM,
  1514.                                       base_index + 2, is_target);
  1515.         }
  1516.     }
  1517.  
  1518. }
  1519.  
  1520. static void
  1521. gen7_pp_set_media_rw_message_surface(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
  1522.                                      const struct i965_surface *surface,
  1523.                                      int base_index, int is_target,
  1524.                                      int *width, int *height, int *pitch, int *offset)
  1525. {
  1526.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  1527.     struct object_surface *obj_surface;
  1528.     struct object_image *obj_image;
  1529.     dri_bo *bo;
  1530.     int fourcc = pp_get_surface_fourcc(ctx, surface);
  1531.     const int U = (fourcc == VA_FOURCC('Y', 'V', '1', '2') ||
  1532.                    fourcc == VA_FOURCC('I', 'M', 'C', '1')) ? 2 : 1;
  1533.     const int V = (fourcc == VA_FOURCC('Y', 'V', '1', '2') ||
  1534.                    fourcc == VA_FOURCC('I', 'M', 'C', '1')) ? 1 : 2;
  1535.     int interleaved_uv = fourcc == VA_FOURCC('N', 'V', '1', '2');
  1536.     int packed_yuv = (fourcc == VA_FOURCC('Y', 'U', 'Y', '2') || fourcc == VA_FOURCC('U', 'Y', 'V', 'Y'));
  1537.  
  1538.     if (surface->type == I965_SURFACE_TYPE_SURFACE) {
  1539.         obj_surface = SURFACE(surface->id);
  1540.         bo = obj_surface->bo;
  1541.         width[0] = obj_surface->orig_width;
  1542.         height[0] = obj_surface->orig_height;
  1543.         pitch[0] = obj_surface->width;
  1544.         offset[0] = 0;
  1545.  
  1546.         if (packed_yuv) {
  1547.             if (is_target)
  1548.                 width[0] = obj_surface->orig_width * 2; /* surface format is R8, so double the width */
  1549.             else
  1550.                 width[0] = obj_surface->orig_width;     /* surface foramt is YCBCR, width is specified in units of pixels */
  1551.  
  1552.             pitch[0] = obj_surface->width * 2;
  1553.         }
  1554.  
  1555.         width[1] = obj_surface->cb_cr_width;
  1556.         height[1] = obj_surface->cb_cr_height;
  1557.         pitch[1] = obj_surface->cb_cr_pitch;
  1558.         offset[1] = obj_surface->y_cb_offset * obj_surface->width;
  1559.  
  1560.         width[2] = obj_surface->cb_cr_width;
  1561.         height[2] = obj_surface->cb_cr_height;
  1562.         pitch[2] = obj_surface->cb_cr_pitch;
  1563.         offset[2] = obj_surface->y_cr_offset * obj_surface->width;
  1564.     } else {
  1565.         obj_image = IMAGE(surface->id);
  1566.         bo = obj_image->bo;
  1567.         width[0] = obj_image->image.width;
  1568.         height[0] = obj_image->image.height;
  1569.         pitch[0] = obj_image->image.pitches[0];
  1570.         offset[0] = obj_image->image.offsets[0];
  1571.  
  1572.         if (packed_yuv) {
  1573.             if (is_target)
  1574.                 width[0] = obj_image->image.width * 2;  /* surface format is R8, so double the width */
  1575.             else
  1576.                 width[0] = obj_image->image.width;      /* surface foramt is YCBCR, width is specified in units of pixels */
  1577.         } else if (interleaved_uv) {
  1578.             width[1] = obj_image->image.width / 2;
  1579.             height[1] = obj_image->image.height / 2;
  1580.             pitch[1] = obj_image->image.pitches[1];
  1581.             offset[1] = obj_image->image.offsets[1];
  1582.         } else {
  1583.             width[1] = obj_image->image.width / 2;
  1584.             height[1] = obj_image->image.height / 2;
  1585.             pitch[1] = obj_image->image.pitches[U];
  1586.             offset[1] = obj_image->image.offsets[U];
  1587.             width[2] = obj_image->image.width / 2;
  1588.             height[2] = obj_image->image.height / 2;
  1589.             pitch[2] = obj_image->image.pitches[V];
  1590.             offset[2] = obj_image->image.offsets[V];
  1591.         }
  1592.     }
  1593.  
  1594.     if (is_target) {
  1595.         gen7_pp_set_surface_state(ctx, pp_context,
  1596.                                   bo, 0,
  1597.                                   width[0] / 4, height[0], pitch[0],
  1598.                                   I965_SURFACEFORMAT_R8_SINT,
  1599.                                   base_index, 1);
  1600.  
  1601.         if (!packed_yuv) {
  1602.             if (interleaved_uv) {
  1603.                 gen7_pp_set_surface_state(ctx, pp_context,
  1604.                                           bo, offset[1],
  1605.                                           width[1] / 2, height[1], pitch[1],
  1606.                                           I965_SURFACEFORMAT_R8G8_SINT,
  1607.                                           base_index + 1, 1);
  1608.             } else {
  1609.                 gen7_pp_set_surface_state(ctx, pp_context,
  1610.                                           bo, offset[1],
  1611.                                           width[1] / 4, height[1], pitch[1],
  1612.                                           I965_SURFACEFORMAT_R8_SINT,
  1613.                                           base_index + 1, 1);
  1614.                 gen7_pp_set_surface_state(ctx, pp_context,
  1615.                                           bo, offset[2],
  1616.                                           width[2] / 4, height[2], pitch[2],
  1617.                                           I965_SURFACEFORMAT_R8_SINT,
  1618.                                           base_index + 2, 1);
  1619.             }
  1620.         }
  1621.     } else {
  1622.         int format0 = SURFACE_FORMAT_Y8_UNORM;
  1623.  
  1624.         switch (fourcc) {
  1625.         case VA_FOURCC('Y', 'U', 'Y', '2'):
  1626.             format0 = SURFACE_FORMAT_YCRCB_NORMAL;
  1627.             break;
  1628.  
  1629.         case VA_FOURCC('U', 'Y', 'V', 'Y'):
  1630.             format0 = SURFACE_FORMAT_YCRCB_SWAPY;
  1631.             break;
  1632.  
  1633.         default:
  1634.             break;
  1635.         }
  1636.  
  1637.         gen7_pp_set_surface2_state(ctx, pp_context,
  1638.                                    bo, offset[0],
  1639.                                    width[0], height[0], pitch[0],
  1640.                                    0, 0,
  1641.                                    format0, 0,
  1642.                                    base_index);
  1643.  
  1644.         if (!packed_yuv) {
  1645.             if (interleaved_uv) {
  1646.                 gen7_pp_set_surface2_state(ctx, pp_context,
  1647.                                            bo, offset[1],
  1648.                                            width[1], height[1], pitch[1],
  1649.                                            0, 0,
  1650.                                            SURFACE_FORMAT_R8B8_UNORM, 0,
  1651.                                            base_index + 1);
  1652.             } else {
  1653.                 gen7_pp_set_surface2_state(ctx, pp_context,
  1654.                                            bo, offset[1],
  1655.                                            width[1], height[1], pitch[1],
  1656.                                            0, 0,
  1657.                                            SURFACE_FORMAT_R8_UNORM, 0,
  1658.                                            base_index + 1);
  1659.                 gen7_pp_set_surface2_state(ctx, pp_context,
  1660.                                            bo, offset[2],
  1661.                                            width[2], height[2], pitch[2],
  1662.                                            0, 0,
  1663.                                            SURFACE_FORMAT_R8_UNORM, 0,
  1664.                                            base_index + 2);
  1665.             }
  1666.         }
  1667.     }
  1668. }
  1669.  
  1670. static int
  1671. pp_null_x_steps(void *private_context)
  1672. {
  1673.     return 1;
  1674. }
  1675.  
  1676. static int
  1677. pp_null_y_steps(void *private_context)
  1678. {
  1679.     return 1;
  1680. }
  1681.  
  1682. static int
  1683. pp_null_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
  1684. {
  1685.     return 0;
  1686. }
  1687.  
  1688. static VAStatus
  1689. pp_null_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
  1690.                    const struct i965_surface *src_surface,
  1691.                    const VARectangle *src_rect,
  1692.                    struct i965_surface *dst_surface,
  1693.                    const VARectangle *dst_rect,
  1694.                    void *filter_param)
  1695. {
  1696.     /* private function & data */
  1697.     pp_context->pp_x_steps = pp_null_x_steps;
  1698.     pp_context->pp_y_steps = pp_null_y_steps;
  1699.     pp_context->pp_set_block_parameter = pp_null_set_block_parameter;
  1700.  
  1701.     dst_surface->flags = src_surface->flags;
  1702.  
  1703.     return VA_STATUS_SUCCESS;
  1704. }
  1705.  
  1706. static int
  1707. pp_load_save_x_steps(void *private_context)
  1708. {
  1709.     return 1;
  1710. }
  1711.  
  1712. static int
  1713. pp_load_save_y_steps(void *private_context)
  1714. {
  1715.     struct pp_load_save_context *pp_load_save_context = private_context;
  1716.  
  1717.     return pp_load_save_context->dest_h / 8;
  1718. }
  1719.  
  1720. static int
  1721. pp_load_save_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
  1722. {
  1723.     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
  1724.     struct pp_load_save_context *pp_load_save_context = (struct pp_load_save_context *)&pp_context->private_context;
  1725.  
  1726.     pp_inline_parameter->grf5.destination_block_horizontal_origin = x * 16 + pp_load_save_context->dest_x;
  1727.     pp_inline_parameter->grf5.destination_block_vertical_origin = y * 8 + pp_load_save_context->dest_y;
  1728.  
  1729.     return 0;
  1730. }
  1731.  
  1732. static void calculate_boundary_block_mask(struct i965_post_processing_context *pp_context, const VARectangle *dst_rect)
  1733. {
  1734.     int i;
  1735.     /* x offset of dest surface must be dword aligned.
  1736.      * so we have to extend dst surface on left edge, and mask out pixels not interested
  1737.      */
  1738.     if (dst_rect->x%GPU_ASM_X_OFFSET_ALIGNMENT) {
  1739.         pp_context->block_horizontal_mask_left = 0;
  1740.         for (i=dst_rect->x%GPU_ASM_X_OFFSET_ALIGNMENT; i<GPU_ASM_BLOCK_WIDTH; i++)
  1741.         {
  1742.             pp_context->block_horizontal_mask_left |= 1<<i;
  1743.         }
  1744.     }
  1745.     else {
  1746.         pp_context->block_horizontal_mask_left = 0xffff;
  1747.     }
  1748.    
  1749.     int dst_width_adjust = dst_rect->width + dst_rect->x%GPU_ASM_X_OFFSET_ALIGNMENT;
  1750.     if (dst_width_adjust%GPU_ASM_BLOCK_WIDTH){
  1751.         pp_context->block_horizontal_mask_right = (1 << (dst_width_adjust%GPU_ASM_BLOCK_WIDTH)) - 1;
  1752.     }
  1753.     else {
  1754.         pp_context->block_horizontal_mask_right = 0xffff;
  1755.     }
  1756.    
  1757.     if (dst_rect->height%GPU_ASM_BLOCK_HEIGHT){
  1758.         pp_context->block_vertical_mask_bottom = (1 << (dst_rect->height%GPU_ASM_BLOCK_HEIGHT)) - 1;
  1759.     }
  1760.     else {
  1761.         pp_context->block_vertical_mask_bottom = 0xff;
  1762.     }
  1763.  
  1764. }
  1765. static VAStatus
  1766. pp_plx_load_save_plx_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
  1767.                                 const struct i965_surface *src_surface,
  1768.                                 const VARectangle *src_rect,
  1769.                                 struct i965_surface *dst_surface,
  1770.                                 const VARectangle *dst_rect,
  1771.                                 void *filter_param)
  1772. {
  1773.     struct pp_load_save_context *pp_load_save_context = (struct pp_load_save_context *)&pp_context->private_context;
  1774.     int width[3], height[3], pitch[3], offset[3];
  1775.     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
  1776.     struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
  1777.  
  1778.     /* source surface */
  1779.     pp_set_media_rw_message_surface(ctx, pp_context, src_surface, 1, 0,
  1780.                                     width, height, pitch, offset);
  1781.  
  1782.     /* destination surface */
  1783.     pp_set_media_rw_message_surface(ctx, pp_context, dst_surface, 7, 1,
  1784.                                     width, height, pitch, offset);
  1785.  
  1786.     /* private function & data */
  1787.     pp_context->pp_x_steps = pp_load_save_x_steps;
  1788.     pp_context->pp_y_steps = pp_load_save_y_steps;
  1789.     pp_context->pp_set_block_parameter = pp_load_save_set_block_parameter;
  1790.  
  1791.     int dst_left_edge_extend = dst_rect->x%GPU_ASM_X_OFFSET_ALIGNMENT;;
  1792.     pp_load_save_context->dest_x = dst_rect->x - dst_left_edge_extend;
  1793.     pp_load_save_context->dest_y = dst_rect->y;
  1794.     pp_load_save_context->dest_h = ALIGN(dst_rect->height, 8);
  1795.     pp_load_save_context->dest_w = ALIGN(dst_rect->width+dst_left_edge_extend, 16);
  1796.  
  1797.     pp_inline_parameter->grf5.block_count_x = pp_load_save_context->dest_w / 16;   /* 1 x N */
  1798.     pp_inline_parameter->grf5.number_blocks = pp_load_save_context->dest_w / 16;
  1799.  
  1800.     pp_static_parameter->grf3.horizontal_origin_offset = src_rect->x;
  1801.     pp_static_parameter->grf3.vertical_origin_offset = src_rect->y;
  1802.  
  1803.     // update u/v offset for packed yuv
  1804.     i965_update_src_surface_uv_offset (ctx, pp_context, src_surface);
  1805.     i965_update_dst_surface_uv_offset (ctx, pp_context, dst_surface);
  1806.  
  1807.     dst_surface->flags = src_surface->flags;
  1808.  
  1809.     return VA_STATUS_SUCCESS;
  1810. }
  1811.  
  1812. static int
  1813. pp_scaling_x_steps(void *private_context)
  1814. {
  1815.     return 1;
  1816. }
  1817.  
  1818. static int
  1819. pp_scaling_y_steps(void *private_context)
  1820. {
  1821.     struct pp_scaling_context *pp_scaling_context = private_context;
  1822.  
  1823.     return pp_scaling_context->dest_h / 8;
  1824. }
  1825.  
  1826. static int
  1827. pp_scaling_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
  1828. {
  1829.     struct pp_scaling_context *pp_scaling_context = (struct pp_scaling_context *)&pp_context->private_context;
  1830.     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
  1831.     struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
  1832.     float src_x_steping = pp_inline_parameter->grf5.normalized_video_x_scaling_step;
  1833.     float src_y_steping = pp_static_parameter->grf1.r1_6.normalized_video_y_scaling_step;
  1834.  
  1835.     pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin = src_x_steping * x * 16 + pp_scaling_context->src_normalized_x;
  1836.     pp_inline_parameter->grf5.source_surface_block_normalized_vertical_origin = src_y_steping * y * 8 + pp_scaling_context->src_normalized_y;
  1837.     pp_inline_parameter->grf5.destination_block_horizontal_origin = x * 16 + pp_scaling_context->dest_x;
  1838.     pp_inline_parameter->grf5.destination_block_vertical_origin = y * 8 + pp_scaling_context->dest_y;
  1839.    
  1840.     return 0;
  1841. }
  1842.  
  1843. static VAStatus
  1844. pp_nv12_scaling_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
  1845.                            const struct i965_surface *src_surface,
  1846.                            const VARectangle *src_rect,
  1847.                            struct i965_surface *dst_surface,
  1848.                            const VARectangle *dst_rect,
  1849.                            void *filter_param)
  1850. {
  1851.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  1852.     struct pp_scaling_context *pp_scaling_context = (struct pp_scaling_context *)&pp_context->private_context;
  1853.     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
  1854.     struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
  1855.     struct object_surface *obj_surface;
  1856.     struct i965_sampler_state *sampler_state;
  1857.     int in_w, in_h, in_wpitch, in_hpitch;
  1858.     int out_w, out_h, out_wpitch, out_hpitch;
  1859.  
  1860.     /* source surface */
  1861.     obj_surface = SURFACE(src_surface->id);
  1862.     in_w = obj_surface->orig_width;
  1863.     in_h = obj_surface->orig_height;
  1864.     in_wpitch = obj_surface->width;
  1865.     in_hpitch = obj_surface->height;
  1866.  
  1867.     /* source Y surface index 1 */
  1868.     i965_pp_set_surface_state(ctx, pp_context,
  1869.                               obj_surface->bo, 0,
  1870.                               in_w, in_h, in_wpitch, I965_SURFACEFORMAT_R8_UNORM,
  1871.                               1, 0);
  1872.  
  1873.     /* source UV surface index 2 */
  1874.     i965_pp_set_surface_state(ctx, pp_context,
  1875.                               obj_surface->bo, in_wpitch * in_hpitch,
  1876.                               in_w / 2, in_h / 2, in_wpitch, I965_SURFACEFORMAT_R8G8_UNORM,
  1877.                               2, 0);
  1878.  
  1879.     /* destination surface */
  1880.     obj_surface = SURFACE(dst_surface->id);
  1881.     out_w = obj_surface->orig_width;
  1882.     out_h = obj_surface->orig_height;
  1883.     out_wpitch = obj_surface->width;
  1884.     out_hpitch = obj_surface->height;
  1885.  
  1886.     /* destination Y surface index 7 */
  1887.     i965_pp_set_surface_state(ctx, pp_context,
  1888.                               obj_surface->bo, 0,
  1889.                               out_w / 4, out_h, out_wpitch, I965_SURFACEFORMAT_R8_UNORM,
  1890.                               7, 1);
  1891.  
  1892.     /* destination UV surface index 8 */
  1893.     i965_pp_set_surface_state(ctx, pp_context,
  1894.                               obj_surface->bo, out_wpitch * out_hpitch,
  1895.                               out_w / 4, out_h / 2, out_wpitch, I965_SURFACEFORMAT_R8G8_UNORM,
  1896.                               8, 1);
  1897.  
  1898.     /* sampler state */
  1899.     dri_bo_map(pp_context->sampler_state_table.bo, True);
  1900.     assert(pp_context->sampler_state_table.bo->virtual);
  1901.     sampler_state = pp_context->sampler_state_table.bo->virtual;
  1902.  
  1903.     /* SIMD16 Y index 1 */
  1904.     sampler_state[1].ss0.min_filter = I965_MAPFILTER_LINEAR;
  1905.     sampler_state[1].ss0.mag_filter = I965_MAPFILTER_LINEAR;
  1906.     sampler_state[1].ss1.r_wrap_mode = I965_TEXCOORDMODE_CLAMP;
  1907.     sampler_state[1].ss1.s_wrap_mode = I965_TEXCOORDMODE_CLAMP;
  1908.     sampler_state[1].ss1.t_wrap_mode = I965_TEXCOORDMODE_CLAMP;
  1909.  
  1910.     /* SIMD16 UV index 2 */
  1911.     sampler_state[2].ss0.min_filter = I965_MAPFILTER_LINEAR;
  1912.     sampler_state[2].ss0.mag_filter = I965_MAPFILTER_LINEAR;
  1913.     sampler_state[2].ss1.r_wrap_mode = I965_TEXCOORDMODE_CLAMP;
  1914.     sampler_state[2].ss1.s_wrap_mode = I965_TEXCOORDMODE_CLAMP;
  1915.     sampler_state[2].ss1.t_wrap_mode = I965_TEXCOORDMODE_CLAMP;
  1916.  
  1917.     dri_bo_unmap(pp_context->sampler_state_table.bo);
  1918.  
  1919.     /* private function & data */
  1920.     pp_context->pp_x_steps = pp_scaling_x_steps;
  1921.     pp_context->pp_y_steps = pp_scaling_y_steps;
  1922.     pp_context->pp_set_block_parameter = pp_scaling_set_block_parameter;
  1923.  
  1924.     int dst_left_edge_extend = dst_rect->x%GPU_ASM_X_OFFSET_ALIGNMENT;
  1925.     float src_left_edge_extend = (float)dst_left_edge_extend*src_rect->width/dst_rect->width;
  1926.     pp_scaling_context->dest_x = dst_rect->x - dst_left_edge_extend;
  1927.     pp_scaling_context->dest_y = dst_rect->y;
  1928.     pp_scaling_context->dest_w = ALIGN(dst_rect->width + dst_left_edge_extend, 16);
  1929.     pp_scaling_context->dest_h = ALIGN(dst_rect->height, 8);
  1930.     pp_scaling_context->src_normalized_x = (float)(src_rect->x - src_left_edge_extend)/ in_w;
  1931.     pp_scaling_context->src_normalized_y = (float)src_rect->y / in_h;
  1932.  
  1933.     pp_static_parameter->grf1.r1_6.normalized_video_y_scaling_step = (float) src_rect->height / in_h / dst_rect->height;
  1934.  
  1935.     pp_inline_parameter->grf5.normalized_video_x_scaling_step = (float) (src_rect->width + src_left_edge_extend)/ in_w / (dst_rect->width + dst_left_edge_extend);
  1936.     pp_inline_parameter->grf5.block_count_x = pp_scaling_context->dest_w / 16;   /* 1 x N */
  1937.     pp_inline_parameter->grf5.number_blocks = pp_scaling_context->dest_w / 16;
  1938.  
  1939.     dst_surface->flags = src_surface->flags;
  1940.  
  1941.     return VA_STATUS_SUCCESS;
  1942. }
  1943.  
  1944. static int
  1945. pp_avs_x_steps(void *private_context)
  1946. {
  1947.     struct pp_avs_context *pp_avs_context = private_context;
  1948.  
  1949.     return pp_avs_context->dest_w / 16;
  1950. }
  1951.  
  1952. static int
  1953. pp_avs_y_steps(void *private_context)
  1954. {
  1955.     return 1;
  1956. }
  1957.  
  1958. static int
  1959. pp_avs_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
  1960. {
  1961.     struct pp_avs_context *pp_avs_context = (struct pp_avs_context *)&pp_context->private_context;
  1962.     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
  1963.     struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
  1964.     float src_x_steping, src_y_steping, video_step_delta;
  1965.     int tmp_w = ALIGN(pp_avs_context->dest_h * pp_avs_context->src_w / pp_avs_context->src_h, 16);
  1966.  
  1967.     if (pp_static_parameter->grf4.r4_2.avs.nlas == 0) {
  1968.         src_x_steping = pp_inline_parameter->grf5.normalized_video_x_scaling_step;
  1969.         pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin = src_x_steping * x * 16 + pp_avs_context->src_normalized_x;
  1970.     } else if (tmp_w >= pp_avs_context->dest_w) {
  1971.         pp_inline_parameter->grf5.normalized_video_x_scaling_step = 1.0 / tmp_w;
  1972.         pp_inline_parameter->grf6.video_step_delta = 0;
  1973.        
  1974.         if (x == 0) {
  1975.             pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin = (float)(tmp_w - pp_avs_context->dest_w) / tmp_w / 2 +
  1976.                 pp_avs_context->src_normalized_x;
  1977.         } else {
  1978.             src_x_steping = pp_inline_parameter->grf5.normalized_video_x_scaling_step;
  1979.             video_step_delta = pp_inline_parameter->grf6.video_step_delta;
  1980.             pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin += src_x_steping * 16 +
  1981.                 16 * 15 * video_step_delta / 2;
  1982.         }
  1983.     } else {
  1984.         int n0, n1, n2, nls_left, nls_right;
  1985.         int factor_a = 5, factor_b = 4;
  1986.         float f;
  1987.  
  1988.         n0 = (pp_avs_context->dest_w - tmp_w) / (16 * 2);
  1989.         n1 = (pp_avs_context->dest_w - tmp_w) / 16 - n0;
  1990.         n2 = tmp_w / (16 * factor_a);
  1991.         nls_left = n0 + n2;
  1992.         nls_right = n1 + n2;
  1993.         f = (float) n2 * 16 / tmp_w;
  1994.        
  1995.         if (n0 < 5) {
  1996.             pp_inline_parameter->grf6.video_step_delta = 0.0;
  1997.  
  1998.             if (x == 0) {
  1999.                 pp_inline_parameter->grf5.normalized_video_x_scaling_step = 1.0 / pp_avs_context->dest_w;
  2000.                 pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin = pp_avs_context->src_normalized_x;
  2001.             } else {
  2002.                 src_x_steping = pp_inline_parameter->grf5.normalized_video_x_scaling_step;
  2003.                 video_step_delta = pp_inline_parameter->grf6.video_step_delta;
  2004.                 pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin += src_x_steping * 16 +
  2005.                     16 * 15 * video_step_delta / 2;
  2006.             }
  2007.         } else {
  2008.             if (x < nls_left) {
  2009.                 /* f = a * nls_left * 16 + b * nls_left * 16 * (nls_left * 16 - 1) / 2 */
  2010.                 float a = f / (nls_left * 16 * factor_b);
  2011.                 float b = (f - nls_left * 16 * a) * 2 / (nls_left * 16 * (nls_left * 16 - 1));
  2012.                
  2013.                 pp_inline_parameter->grf6.video_step_delta = b;
  2014.  
  2015.                 if (x == 0) {
  2016.                     pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin = pp_avs_context->src_normalized_x;
  2017.                     pp_inline_parameter->grf5.normalized_video_x_scaling_step = a;
  2018.                 } else {
  2019.                     src_x_steping = pp_inline_parameter->grf5.normalized_video_x_scaling_step;
  2020.                     video_step_delta = pp_inline_parameter->grf6.video_step_delta;
  2021.                     pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin += src_x_steping * 16 +
  2022.                         16 * 15 * video_step_delta / 2;
  2023.                     pp_inline_parameter->grf5.normalized_video_x_scaling_step += 16 * b;
  2024.                 }
  2025.             } else if (x < (pp_avs_context->dest_w / 16 - nls_right)) {
  2026.                 /* scale the center linearly */
  2027.                 src_x_steping = pp_inline_parameter->grf5.normalized_video_x_scaling_step;
  2028.                 video_step_delta = pp_inline_parameter->grf6.video_step_delta;
  2029.                 pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin += src_x_steping * 16 +
  2030.                     16 * 15 * video_step_delta / 2;
  2031.                 pp_inline_parameter->grf6.video_step_delta = 0.0;
  2032.                 pp_inline_parameter->grf5.normalized_video_x_scaling_step = 1.0 / tmp_w;
  2033.             } else {
  2034.                 float a = f / (nls_right * 16 * factor_b);
  2035.                 float b = (f - nls_right * 16 * a) * 2 / (nls_right * 16 * (nls_right * 16 - 1));
  2036.  
  2037.                 src_x_steping = pp_inline_parameter->grf5.normalized_video_x_scaling_step;
  2038.                 video_step_delta = pp_inline_parameter->grf6.video_step_delta;
  2039.                 pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin += src_x_steping * 16 +
  2040.                     16 * 15 * video_step_delta / 2;
  2041.                 pp_inline_parameter->grf6.video_step_delta = -b;
  2042.  
  2043.                 if (x == (pp_avs_context->dest_w / 16 - nls_right))
  2044.                     pp_inline_parameter->grf5.normalized_video_x_scaling_step = a + (nls_right * 16  - 1) * b;
  2045.                 else
  2046.                     pp_inline_parameter->grf5.normalized_video_x_scaling_step -= b * 16;
  2047.             }
  2048.         }
  2049.     }
  2050.  
  2051.     src_y_steping = pp_static_parameter->grf1.r1_6.normalized_video_y_scaling_step;
  2052.     pp_inline_parameter->grf5.source_surface_block_normalized_vertical_origin = src_y_steping * y * 8 + pp_avs_context->src_normalized_y;
  2053.     pp_inline_parameter->grf5.destination_block_horizontal_origin = x * 16 + pp_avs_context->dest_x;
  2054.     pp_inline_parameter->grf5.destination_block_vertical_origin = y * 8 + pp_avs_context->dest_y;
  2055.  
  2056.     return 0;
  2057. }
  2058.  
  2059. static VAStatus
  2060. pp_nv12_avs_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
  2061.                        const struct i965_surface *src_surface,
  2062.                        const VARectangle *src_rect,
  2063.                        struct i965_surface *dst_surface,
  2064.                        const VARectangle *dst_rect,
  2065.                        void *filter_param,
  2066.                        int nlas)
  2067. {
  2068.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  2069.     struct pp_avs_context *pp_avs_context = (struct pp_avs_context *)&pp_context->private_context;
  2070.     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
  2071.     struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
  2072.     struct object_surface *obj_surface;
  2073.     struct i965_sampler_8x8 *sampler_8x8;
  2074.     struct i965_sampler_8x8_state *sampler_8x8_state;
  2075.     int index;
  2076.     int in_w, in_h, in_wpitch, in_hpitch;
  2077.     int out_w, out_h, out_wpitch, out_hpitch;
  2078.     int i;
  2079.  
  2080.     /* surface */
  2081.     obj_surface = SURFACE(src_surface->id);
  2082.     in_w = obj_surface->orig_width;
  2083.     in_h = obj_surface->orig_height;
  2084.     in_wpitch = obj_surface->width;
  2085.     in_hpitch = obj_surface->height;
  2086.  
  2087.     /* source Y surface index 1 */
  2088.     i965_pp_set_surface2_state(ctx, pp_context,
  2089.                                obj_surface->bo, 0,
  2090.                                in_w, in_h, in_wpitch,
  2091.                                0, 0,
  2092.                                SURFACE_FORMAT_Y8_UNORM, 0,
  2093.                                1);
  2094.  
  2095.     /* source UV surface index 2 */
  2096.     i965_pp_set_surface2_state(ctx, pp_context,
  2097.                                obj_surface->bo, in_wpitch * in_hpitch,
  2098.                                in_w / 2, in_h / 2, in_wpitch,
  2099.                                0, 0,
  2100.                                SURFACE_FORMAT_R8B8_UNORM, 0,
  2101.                                2);
  2102.  
  2103.     /* destination surface */
  2104.     obj_surface = SURFACE(dst_surface->id);
  2105.     out_w = obj_surface->orig_width;
  2106.     out_h = obj_surface->orig_height;
  2107.     out_wpitch = obj_surface->width;
  2108.     out_hpitch = obj_surface->height;
  2109.     assert(out_w <= out_wpitch && out_h <= out_hpitch);
  2110.  
  2111.     /* destination Y surface index 7 */
  2112.     i965_pp_set_surface_state(ctx, pp_context,
  2113.                               obj_surface->bo, 0,
  2114.                               out_w / 4, out_h, out_wpitch, I965_SURFACEFORMAT_R8_UNORM,
  2115.                               7, 1);
  2116.  
  2117.     /* destination UV surface index 8 */
  2118.     i965_pp_set_surface_state(ctx, pp_context,
  2119.                               obj_surface->bo, out_wpitch * out_hpitch,
  2120.                               out_w / 4, out_h / 2, out_wpitch, I965_SURFACEFORMAT_R8G8_UNORM,
  2121.                               8, 1);
  2122.  
  2123.     /* sampler 8x8 state */
  2124.     dri_bo_map(pp_context->sampler_state_table.bo_8x8, True);
  2125.     assert(pp_context->sampler_state_table.bo_8x8->virtual);
  2126.     assert(sizeof(*sampler_8x8_state) == sizeof(int) * 138);
  2127.     sampler_8x8_state = pp_context->sampler_state_table.bo_8x8->virtual;
  2128.     memset(sampler_8x8_state, 0, sizeof(*sampler_8x8_state));
  2129.  
  2130.     for (i = 0; i < 17; i++) {
  2131.         /* for Y channel, currently ignore */
  2132.         sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c0 = 0x00;
  2133.         sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c1 = 0x00;
  2134.         sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c2 = 0x08;
  2135.         sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c3 = 0x18;
  2136.         sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c4 = 0x18;
  2137.         sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c5 = 0x08;
  2138.         sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c6 = 0x00;
  2139.         sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c7 = 0x00;
  2140.         sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c0 = 0x00;
  2141.         sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c1 = 0x00;
  2142.         sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c2 = 0x10;
  2143.         sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c3 = 0x10;
  2144.         sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c4 = 0x10;
  2145.         sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c5 = 0x10;
  2146.         sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c6 = 0x00;
  2147.         sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c7 = 0x00;
  2148.         /* for U/V channel, 0.25 */
  2149.         sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c0 = 0x0;
  2150.         sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c1 = 0x0;
  2151.         sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c2 = 0x10;
  2152.         sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c3 = 0x10;
  2153.         sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c4 = 0x10;
  2154.         sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c5 = 0x10;
  2155.         sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c6 = 0x0;
  2156.         sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c7 = 0x0;
  2157.         sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c0 = 0x0;
  2158.         sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c1 = 0x0;
  2159.         sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c2 = 0x10;
  2160.         sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c3 = 0x10;
  2161.         sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c4 = 0x10;
  2162.         sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c5 = 0x10;
  2163.         sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c6 = 0x0;
  2164.         sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c7 = 0x0;
  2165.     }
  2166.  
  2167.     sampler_8x8_state->dw136.default_sharpness_level = 0;
  2168.     sampler_8x8_state->dw137.adaptive_filter_for_all_channel = 1;
  2169.     sampler_8x8_state->dw137.bypass_y_adaptive_filtering = 1;
  2170.     sampler_8x8_state->dw137.bypass_x_adaptive_filtering = 1;
  2171.     dri_bo_unmap(pp_context->sampler_state_table.bo_8x8);
  2172.  
  2173.     /* sampler 8x8 */
  2174.     dri_bo_map(pp_context->sampler_state_table.bo, True);
  2175.     assert(pp_context->sampler_state_table.bo->virtual);
  2176.     assert(sizeof(*sampler_8x8) == sizeof(int) * 16);
  2177.     sampler_8x8 = pp_context->sampler_state_table.bo->virtual;
  2178.  
  2179.     /* sample_8x8 Y index 1 */
  2180.     index = 1;
  2181.     memset(&sampler_8x8[index], 0, sizeof(*sampler_8x8));
  2182.     sampler_8x8[index].dw0.avs_filter_type = AVS_FILTER_ADAPTIVE_8_TAP;
  2183.     sampler_8x8[index].dw0.ief_bypass = 1;
  2184.     sampler_8x8[index].dw0.ief_filter_type = IEF_FILTER_DETAIL;
  2185.     sampler_8x8[index].dw0.ief_filter_size = IEF_FILTER_SIZE_5X5;
  2186.     sampler_8x8[index].dw1.sampler_8x8_state_pointer = pp_context->sampler_state_table.bo_8x8->offset >> 5;
  2187.     sampler_8x8[index].dw2.global_noise_estimation = 22;
  2188.     sampler_8x8[index].dw2.strong_edge_threshold = 8;
  2189.     sampler_8x8[index].dw2.weak_edge_threshold = 1;
  2190.     sampler_8x8[index].dw3.strong_edge_weight = 7;
  2191.     sampler_8x8[index].dw3.regular_weight = 2;
  2192.     sampler_8x8[index].dw3.non_edge_weight = 0;
  2193.     sampler_8x8[index].dw3.gain_factor = 40;
  2194.     sampler_8x8[index].dw4.steepness_boost = 0;
  2195.     sampler_8x8[index].dw4.steepness_threshold = 0;
  2196.     sampler_8x8[index].dw4.mr_boost = 0;
  2197.     sampler_8x8[index].dw4.mr_threshold = 5;
  2198.     sampler_8x8[index].dw5.pwl1_point_1 = 4;
  2199.     sampler_8x8[index].dw5.pwl1_point_2 = 12;
  2200.     sampler_8x8[index].dw5.pwl1_point_3 = 16;
  2201.     sampler_8x8[index].dw5.pwl1_point_4 = 26;
  2202.     sampler_8x8[index].dw6.pwl1_point_5 = 40;
  2203.     sampler_8x8[index].dw6.pwl1_point_6 = 160;
  2204.     sampler_8x8[index].dw6.pwl1_r3_bias_0 = 127;
  2205.     sampler_8x8[index].dw6.pwl1_r3_bias_1 = 98;
  2206.     sampler_8x8[index].dw7.pwl1_r3_bias_2 = 88;
  2207.     sampler_8x8[index].dw7.pwl1_r3_bias_3 = 64;
  2208.     sampler_8x8[index].dw7.pwl1_r3_bias_4 = 44;
  2209.     sampler_8x8[index].dw7.pwl1_r3_bias_5 = 0;
  2210.     sampler_8x8[index].dw8.pwl1_r3_bias_6 = 0;
  2211.     sampler_8x8[index].dw8.pwl1_r5_bias_0 = 3;
  2212.     sampler_8x8[index].dw8.pwl1_r5_bias_1 = 32;
  2213.     sampler_8x8[index].dw8.pwl1_r5_bias_2 = 32;
  2214.     sampler_8x8[index].dw9.pwl1_r5_bias_3 = 58;
  2215.     sampler_8x8[index].dw9.pwl1_r5_bias_4 = 100;
  2216.     sampler_8x8[index].dw9.pwl1_r5_bias_5 = 108;
  2217.     sampler_8x8[index].dw9.pwl1_r5_bias_6 = 88;
  2218.     sampler_8x8[index].dw10.pwl1_r3_slope_0 = -116;
  2219.     sampler_8x8[index].dw10.pwl1_r3_slope_1 = -20;
  2220.     sampler_8x8[index].dw10.pwl1_r3_slope_2 = -96;
  2221.     sampler_8x8[index].dw10.pwl1_r3_slope_3 = -32;
  2222.     sampler_8x8[index].dw11.pwl1_r3_slope_4 = -50;
  2223.     sampler_8x8[index].dw11.pwl1_r3_slope_5 = 0;
  2224.     sampler_8x8[index].dw11.pwl1_r3_slope_6 = 0;
  2225.     sampler_8x8[index].dw11.pwl1_r5_slope_0 = 116;
  2226.     sampler_8x8[index].dw12.pwl1_r5_slope_1 = 0;
  2227.     sampler_8x8[index].dw12.pwl1_r5_slope_2 = 114;
  2228.     sampler_8x8[index].dw12.pwl1_r5_slope_3 = 67;
  2229.     sampler_8x8[index].dw12.pwl1_r5_slope_4 = 9;
  2230.     sampler_8x8[index].dw13.pwl1_r5_slope_5 = -3;
  2231.     sampler_8x8[index].dw13.pwl1_r5_slope_6 = -15;
  2232.     sampler_8x8[index].dw13.limiter_boost = 0;
  2233.     sampler_8x8[index].dw13.minimum_limiter = 10;
  2234.     sampler_8x8[index].dw13.maximum_limiter = 11;
  2235.     sampler_8x8[index].dw14.clip_limiter = 130;
  2236.     dri_bo_emit_reloc(pp_context->sampler_state_table.bo,
  2237.                       I915_GEM_DOMAIN_RENDER,
  2238.                       0,
  2239.                       0,
  2240.                       sizeof(*sampler_8x8) * index + offsetof(struct i965_sampler_8x8, dw1),
  2241.                       pp_context->sampler_state_table.bo_8x8);
  2242.  
  2243.     /* sample_8x8 UV index 2 */
  2244.     index = 2;
  2245.     memset(&sampler_8x8[index], 0, sizeof(*sampler_8x8));
  2246.     sampler_8x8[index].dw0.avs_filter_type = AVS_FILTER_ADAPTIVE_8_TAP;
  2247.     sampler_8x8[index].dw0.ief_bypass = 1;
  2248.     sampler_8x8[index].dw0.ief_filter_type = IEF_FILTER_DETAIL;
  2249.     sampler_8x8[index].dw0.ief_filter_size = IEF_FILTER_SIZE_5X5;
  2250.     sampler_8x8[index].dw1.sampler_8x8_state_pointer = pp_context->sampler_state_table.bo_8x8->offset >> 5;
  2251.     sampler_8x8[index].dw2.global_noise_estimation = 22;
  2252.     sampler_8x8[index].dw2.strong_edge_threshold = 8;
  2253.     sampler_8x8[index].dw2.weak_edge_threshold = 1;
  2254.     sampler_8x8[index].dw3.strong_edge_weight = 7;
  2255.     sampler_8x8[index].dw3.regular_weight = 2;
  2256.     sampler_8x8[index].dw3.non_edge_weight = 0;
  2257.     sampler_8x8[index].dw3.gain_factor = 40;
  2258.     sampler_8x8[index].dw4.steepness_boost = 0;
  2259.     sampler_8x8[index].dw4.steepness_threshold = 0;
  2260.     sampler_8x8[index].dw4.mr_boost = 0;
  2261.     sampler_8x8[index].dw4.mr_threshold = 5;
  2262.     sampler_8x8[index].dw5.pwl1_point_1 = 4;
  2263.     sampler_8x8[index].dw5.pwl1_point_2 = 12;
  2264.     sampler_8x8[index].dw5.pwl1_point_3 = 16;
  2265.     sampler_8x8[index].dw5.pwl1_point_4 = 26;
  2266.     sampler_8x8[index].dw6.pwl1_point_5 = 40;
  2267.     sampler_8x8[index].dw6.pwl1_point_6 = 160;
  2268.     sampler_8x8[index].dw6.pwl1_r3_bias_0 = 127;
  2269.     sampler_8x8[index].dw6.pwl1_r3_bias_1 = 98;
  2270.     sampler_8x8[index].dw7.pwl1_r3_bias_2 = 88;
  2271.     sampler_8x8[index].dw7.pwl1_r3_bias_3 = 64;
  2272.     sampler_8x8[index].dw7.pwl1_r3_bias_4 = 44;
  2273.     sampler_8x8[index].dw7.pwl1_r3_bias_5 = 0;
  2274.     sampler_8x8[index].dw8.pwl1_r3_bias_6 = 0;
  2275.     sampler_8x8[index].dw8.pwl1_r5_bias_0 = 3;
  2276.     sampler_8x8[index].dw8.pwl1_r5_bias_1 = 32;
  2277.     sampler_8x8[index].dw8.pwl1_r5_bias_2 = 32;
  2278.     sampler_8x8[index].dw9.pwl1_r5_bias_3 = 58;
  2279.     sampler_8x8[index].dw9.pwl1_r5_bias_4 = 100;
  2280.     sampler_8x8[index].dw9.pwl1_r5_bias_5 = 108;
  2281.     sampler_8x8[index].dw9.pwl1_r5_bias_6 = 88;
  2282.     sampler_8x8[index].dw10.pwl1_r3_slope_0 = -116;
  2283.     sampler_8x8[index].dw10.pwl1_r3_slope_1 = -20;
  2284.     sampler_8x8[index].dw10.pwl1_r3_slope_2 = -96;
  2285.     sampler_8x8[index].dw10.pwl1_r3_slope_3 = -32;
  2286.     sampler_8x8[index].dw11.pwl1_r3_slope_4 = -50;
  2287.     sampler_8x8[index].dw11.pwl1_r3_slope_5 = 0;
  2288.     sampler_8x8[index].dw11.pwl1_r3_slope_6 = 0;
  2289.     sampler_8x8[index].dw11.pwl1_r5_slope_0 = 116;
  2290.     sampler_8x8[index].dw12.pwl1_r5_slope_1 = 0;
  2291.     sampler_8x8[index].dw12.pwl1_r5_slope_2 = 114;
  2292.     sampler_8x8[index].dw12.pwl1_r5_slope_3 = 67;
  2293.     sampler_8x8[index].dw12.pwl1_r5_slope_4 = 9;
  2294.     sampler_8x8[index].dw13.pwl1_r5_slope_5 = -3;
  2295.     sampler_8x8[index].dw13.pwl1_r5_slope_6 = -15;
  2296.     sampler_8x8[index].dw13.limiter_boost = 0;
  2297.     sampler_8x8[index].dw13.minimum_limiter = 10;
  2298.     sampler_8x8[index].dw13.maximum_limiter = 11;
  2299.     sampler_8x8[index].dw14.clip_limiter = 130;
  2300.     dri_bo_emit_reloc(pp_context->sampler_state_table.bo,
  2301.                       I915_GEM_DOMAIN_RENDER,
  2302.                       0,
  2303.                       0,
  2304.                       sizeof(*sampler_8x8) * index + offsetof(struct i965_sampler_8x8, dw1),
  2305.                       pp_context->sampler_state_table.bo_8x8);
  2306.  
  2307.     dri_bo_unmap(pp_context->sampler_state_table.bo);
  2308.  
  2309.     /* private function & data */
  2310.     pp_context->pp_x_steps = pp_avs_x_steps;
  2311.     pp_context->pp_y_steps = pp_avs_y_steps;
  2312.     pp_context->pp_set_block_parameter = pp_avs_set_block_parameter;
  2313.  
  2314.     int dst_left_edge_extend = dst_rect->x%GPU_ASM_X_OFFSET_ALIGNMENT;
  2315.     float src_left_edge_extend = (float)dst_left_edge_extend*src_rect->width/dst_rect->width;
  2316.     pp_avs_context->dest_x = dst_rect->x - dst_left_edge_extend;
  2317.     pp_avs_context->dest_y = dst_rect->y;
  2318.     pp_avs_context->dest_w = ALIGN(dst_rect->width + dst_left_edge_extend, 16);
  2319.     pp_avs_context->dest_h = ALIGN(dst_rect->height, 8);
  2320.     pp_avs_context->src_normalized_x = (float)(src_rect->x - src_left_edge_extend)/ in_w;
  2321.     pp_avs_context->src_normalized_y = (float)src_rect->y / in_h;
  2322.     pp_avs_context->src_w = src_rect->width + src_left_edge_extend;
  2323.     pp_avs_context->src_h = src_rect->height;
  2324.  
  2325.     pp_static_parameter->grf4.r4_2.avs.nlas = nlas;
  2326.     pp_static_parameter->grf1.r1_6.normalized_video_y_scaling_step = (float) src_rect->height / in_h / dst_rect->height;
  2327.  
  2328.     pp_inline_parameter->grf5.normalized_video_x_scaling_step = (float) (src_rect->width + src_left_edge_extend)/ in_w / (dst_rect->width + dst_left_edge_extend);
  2329.     pp_inline_parameter->grf5.block_count_x = 1;        /* M x 1 */
  2330.     pp_inline_parameter->grf5.number_blocks = pp_avs_context->dest_h / 8;
  2331.     pp_inline_parameter->grf6.video_step_delta = 0.0;
  2332.  
  2333.     dst_surface->flags = src_surface->flags;
  2334.  
  2335.     return VA_STATUS_SUCCESS;
  2336. }
  2337.  
  2338. static VAStatus
  2339. pp_nv12_avs_initialize_nlas(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
  2340.                             const struct i965_surface *src_surface,
  2341.                             const VARectangle *src_rect,
  2342.                             struct i965_surface *dst_surface,
  2343.                             const VARectangle *dst_rect,
  2344.                             void *filter_param)
  2345. {
  2346.     return pp_nv12_avs_initialize(ctx, pp_context,
  2347.                                   src_surface,
  2348.                                   src_rect,
  2349.                                   dst_surface,
  2350.                                   dst_rect,
  2351.                                   filter_param,
  2352.                                   1);
  2353. }
  2354.  
  2355. static VAStatus
  2356. gen6_nv12_scaling_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
  2357.                              const struct i965_surface *src_surface,
  2358.                              const VARectangle *src_rect,
  2359.                              struct i965_surface *dst_surface,
  2360.                              const VARectangle *dst_rect,
  2361.                              void *filter_param)
  2362. {
  2363.     return pp_nv12_avs_initialize(ctx, pp_context,
  2364.                                   src_surface,
  2365.                                   src_rect,
  2366.                                   dst_surface,
  2367.                                   dst_rect,
  2368.                                   filter_param,
  2369.                                   0);    
  2370. }
  2371.  
  2372. static int
  2373. gen7_pp_avs_x_steps(void *private_context)
  2374. {
  2375.     struct pp_avs_context *pp_avs_context = private_context;
  2376.  
  2377.     return pp_avs_context->dest_w / 16;
  2378. }
  2379.  
  2380. static int
  2381. gen7_pp_avs_y_steps(void *private_context)
  2382. {
  2383.     struct pp_avs_context *pp_avs_context = private_context;
  2384.  
  2385.     return pp_avs_context->dest_h / 16;
  2386. }
  2387.  
  2388. static int
  2389. gen7_pp_avs_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
  2390. {
  2391.     struct pp_avs_context *pp_avs_context = (struct pp_avs_context *)&pp_context->private_context;
  2392.     struct gen7_pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
  2393.  
  2394.     pp_inline_parameter->grf7.destination_block_horizontal_origin = x * 16 + pp_avs_context->dest_x;
  2395.     pp_inline_parameter->grf7.destination_block_vertical_origin = y * 16 + pp_avs_context->dest_y;
  2396.     pp_inline_parameter->grf7.constant_0 = 0xffffffff;
  2397.     pp_inline_parameter->grf7.sampler_load_main_video_x_scaling_step = 1.0 / pp_avs_context->src_w;
  2398.  
  2399.     return 0;
  2400. }
  2401.  
  2402. static void gen7_update_src_surface_uv_offset(VADriverContextP    ctx,
  2403.                                               struct i965_post_processing_context *pp_context,
  2404.                                               const struct i965_surface *surface)
  2405. {
  2406.     struct gen7_pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
  2407.     int fourcc = pp_get_surface_fourcc(ctx, surface);
  2408.    
  2409.     if (fourcc == VA_FOURCC('Y', 'U', 'Y', '2')) {
  2410.         pp_static_parameter->grf2.di_destination_packed_y_component_offset = 0;
  2411.         pp_static_parameter->grf2.di_destination_packed_u_component_offset = 1;
  2412.         pp_static_parameter->grf2.di_destination_packed_v_component_offset = 3;
  2413.     } else if (fourcc == VA_FOURCC('U', 'Y', 'V', 'Y')) {
  2414.         pp_static_parameter->grf2.di_destination_packed_y_component_offset = 1;
  2415.         pp_static_parameter->grf2.di_destination_packed_u_component_offset = 0;
  2416.         pp_static_parameter->grf2.di_destination_packed_v_component_offset = 2;
  2417.     }
  2418. }
  2419.  
  2420. static VAStatus
  2421. gen7_pp_plx_avs_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
  2422.                            const struct i965_surface *src_surface,
  2423.                            const VARectangle *src_rect,
  2424.                            struct i965_surface *dst_surface,
  2425.                            const VARectangle *dst_rect,
  2426.                            void *filter_param)
  2427. {
  2428.     struct pp_avs_context *pp_avs_context = (struct pp_avs_context *)&pp_context->private_context;
  2429.     struct gen7_pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
  2430.     struct gen7_sampler_8x8 *sampler_8x8;
  2431.     struct i965_sampler_8x8_state *sampler_8x8_state;
  2432.     int index, i;
  2433.     int width[3], height[3], pitch[3], offset[3];
  2434.     int src_height;
  2435.  
  2436.     /* source surface */
  2437.     gen7_pp_set_media_rw_message_surface(ctx, pp_context, src_surface, 0, 0,
  2438.                                          width, height, pitch, offset);
  2439.     src_height = height[0];
  2440.  
  2441.     /* destination surface */
  2442.     gen7_pp_set_media_rw_message_surface(ctx, pp_context, dst_surface, 24, 1,
  2443.                                          width, height, pitch, offset);
  2444.  
  2445.     /* sampler 8x8 state */
  2446.     dri_bo_map(pp_context->sampler_state_table.bo_8x8, True);
  2447.     assert(pp_context->sampler_state_table.bo_8x8->virtual);
  2448.     assert(sizeof(*sampler_8x8_state) == sizeof(int) * 138);
  2449.     sampler_8x8_state = pp_context->sampler_state_table.bo_8x8->virtual;
  2450.     memset(sampler_8x8_state, 0, sizeof(*sampler_8x8_state));
  2451.  
  2452.     for (i = 0; i < 17; i++) {
  2453.         /* for Y channel, currently ignore */
  2454.         sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c0 = 0x0;
  2455.         sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c1 = 0x0;
  2456.         sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c2 = 0x0;
  2457.         sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c3 = 0x0;
  2458.         sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c4 = 0x0;
  2459.         sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c5 = 0x0;
  2460.         sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c6 = 0x0;
  2461.         sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c7 = 0x0;
  2462.         sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c0 = 0x0;
  2463.         sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c1 = 0x0;
  2464.         sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c2 = 0x0;
  2465.         sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c3 = 0x0;
  2466.         sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c4 = 0x0;
  2467.         sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c5 = 0x0;
  2468.         sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c6 = 0x0;
  2469.         sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c7 = 0x0;
  2470.         /* for U/V channel, 0.25 */
  2471.         sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c0 = 0x0;
  2472.         sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c1 = 0x0;
  2473.         sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c2 = 0x10;
  2474.         sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c3 = 0x10;
  2475.         sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c4 = 0x10;
  2476.         sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c5 = 0x10;
  2477.         sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c6 = 0x0;
  2478.         sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c7 = 0x0;
  2479.         sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c0 = 0x0;
  2480.         sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c1 = 0x0;
  2481.         sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c2 = 0x10;
  2482.         sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c3 = 0x10;
  2483.         sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c4 = 0x10;
  2484.         sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c5 = 0x10;
  2485.         sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c6 = 0x0;
  2486.         sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c7 = 0x0;
  2487.     }
  2488.  
  2489.     sampler_8x8_state->dw136.default_sharpness_level = 0;
  2490.     sampler_8x8_state->dw137.adaptive_filter_for_all_channel = 1;
  2491.     sampler_8x8_state->dw137.bypass_y_adaptive_filtering = 1;
  2492.     sampler_8x8_state->dw137.bypass_x_adaptive_filtering = 1;
  2493.     dri_bo_unmap(pp_context->sampler_state_table.bo_8x8);
  2494.  
  2495.     /* sampler 8x8 */
  2496.     dri_bo_map(pp_context->sampler_state_table.bo, True);
  2497.     assert(pp_context->sampler_state_table.bo->virtual);
  2498.     assert(sizeof(*sampler_8x8) == sizeof(int) * 4);
  2499.     sampler_8x8 = pp_context->sampler_state_table.bo->virtual;
  2500.  
  2501.     /* sample_8x8 Y index 4 */
  2502.     index = 4;
  2503.     memset(&sampler_8x8[index], 0, sizeof(*sampler_8x8));
  2504.     sampler_8x8[index].dw0.global_noise_estimation = 255;
  2505.     sampler_8x8[index].dw0.ief_bypass = 1;
  2506.  
  2507.     sampler_8x8[index].dw1.sampler_8x8_state_pointer = pp_context->sampler_state_table.bo_8x8->offset >> 5;
  2508.  
  2509.     sampler_8x8[index].dw2.weak_edge_threshold = 1;
  2510.     sampler_8x8[index].dw2.strong_edge_threshold = 8;
  2511.     sampler_8x8[index].dw2.r5x_coefficient = 9;
  2512.     sampler_8x8[index].dw2.r5cx_coefficient = 8;
  2513.     sampler_8x8[index].dw2.r5c_coefficient = 3;
  2514.  
  2515.     sampler_8x8[index].dw3.r3x_coefficient = 27;
  2516.     sampler_8x8[index].dw3.r3c_coefficient = 5;
  2517.     sampler_8x8[index].dw3.gain_factor = 40;
  2518.     sampler_8x8[index].dw3.non_edge_weight = 1;
  2519.     sampler_8x8[index].dw3.regular_weight = 2;
  2520.     sampler_8x8[index].dw3.strong_edge_weight = 7;
  2521.     sampler_8x8[index].dw3.ief4_smooth_enable = 0;
  2522.  
  2523.     dri_bo_emit_reloc(pp_context->sampler_state_table.bo,
  2524.                       I915_GEM_DOMAIN_RENDER,
  2525.                       0,
  2526.                       0,
  2527.                       sizeof(*sampler_8x8) * index + offsetof(struct i965_sampler_8x8, dw1),
  2528.                       pp_context->sampler_state_table.bo_8x8);
  2529.  
  2530.     /* sample_8x8 UV index 8 */
  2531.     index = 8;
  2532.     memset(&sampler_8x8[index], 0, sizeof(*sampler_8x8));
  2533.     sampler_8x8[index].dw0.disable_8x8_filter = 0;
  2534.     sampler_8x8[index].dw0.global_noise_estimation = 255;
  2535.     sampler_8x8[index].dw0.ief_bypass = 1;
  2536.     sampler_8x8[index].dw1.sampler_8x8_state_pointer = pp_context->sampler_state_table.bo_8x8->offset >> 5;
  2537.     sampler_8x8[index].dw2.weak_edge_threshold = 1;
  2538.     sampler_8x8[index].dw2.strong_edge_threshold = 8;
  2539.     sampler_8x8[index].dw2.r5x_coefficient = 9;
  2540.     sampler_8x8[index].dw2.r5cx_coefficient = 8;
  2541.     sampler_8x8[index].dw2.r5c_coefficient = 3;
  2542.     sampler_8x8[index].dw3.r3x_coefficient = 27;
  2543.     sampler_8x8[index].dw3.r3c_coefficient = 5;
  2544.     sampler_8x8[index].dw3.gain_factor = 40;
  2545.     sampler_8x8[index].dw3.non_edge_weight = 1;
  2546.     sampler_8x8[index].dw3.regular_weight = 2;
  2547.     sampler_8x8[index].dw3.strong_edge_weight = 7;
  2548.     sampler_8x8[index].dw3.ief4_smooth_enable = 0;
  2549.  
  2550.     dri_bo_emit_reloc(pp_context->sampler_state_table.bo,
  2551.                       I915_GEM_DOMAIN_RENDER,
  2552.                       0,
  2553.                       0,
  2554.                       sizeof(*sampler_8x8) * index + offsetof(struct i965_sampler_8x8, dw1),
  2555.                       pp_context->sampler_state_table.bo_8x8);
  2556.  
  2557.     /* sampler_8x8 V, index 12 */
  2558.     index = 12;
  2559.     memset(&sampler_8x8[index], 0, sizeof(*sampler_8x8));
  2560.     sampler_8x8[index].dw0.disable_8x8_filter = 0;
  2561.     sampler_8x8[index].dw0.global_noise_estimation = 255;
  2562.     sampler_8x8[index].dw0.ief_bypass = 1;
  2563.     sampler_8x8[index].dw1.sampler_8x8_state_pointer = pp_context->sampler_state_table.bo_8x8->offset >> 5;
  2564.     sampler_8x8[index].dw2.weak_edge_threshold = 1;
  2565.     sampler_8x8[index].dw2.strong_edge_threshold = 8;
  2566.     sampler_8x8[index].dw2.r5x_coefficient = 9;
  2567.     sampler_8x8[index].dw2.r5cx_coefficient = 8;
  2568.     sampler_8x8[index].dw2.r5c_coefficient = 3;
  2569.     sampler_8x8[index].dw3.r3x_coefficient = 27;
  2570.     sampler_8x8[index].dw3.r3c_coefficient = 5;
  2571.     sampler_8x8[index].dw3.gain_factor = 40;
  2572.     sampler_8x8[index].dw3.non_edge_weight = 1;
  2573.     sampler_8x8[index].dw3.regular_weight = 2;
  2574.     sampler_8x8[index].dw3.strong_edge_weight = 7;
  2575.     sampler_8x8[index].dw3.ief4_smooth_enable = 0;
  2576.  
  2577.     dri_bo_emit_reloc(pp_context->sampler_state_table.bo,
  2578.                       I915_GEM_DOMAIN_RENDER,
  2579.                       0,
  2580.                       0,
  2581.                       sizeof(*sampler_8x8) * index + offsetof(struct i965_sampler_8x8, dw1),
  2582.                       pp_context->sampler_state_table.bo_8x8);
  2583.  
  2584.     dri_bo_unmap(pp_context->sampler_state_table.bo);
  2585.  
  2586.     /* private function & data */
  2587.     pp_context->pp_x_steps = gen7_pp_avs_x_steps;
  2588.     pp_context->pp_y_steps = gen7_pp_avs_y_steps;
  2589.     pp_context->pp_set_block_parameter = gen7_pp_avs_set_block_parameter;
  2590.  
  2591.     pp_avs_context->dest_x = dst_rect->x;
  2592.     pp_avs_context->dest_y = dst_rect->y;
  2593.     pp_avs_context->dest_w = ALIGN(dst_rect->width, 16);
  2594.     pp_avs_context->dest_h = ALIGN(dst_rect->height, 16);
  2595.     pp_avs_context->src_w = src_rect->width;
  2596.     pp_avs_context->src_h = src_rect->height;
  2597.  
  2598.     int dw = (pp_avs_context->src_w - 1) / 16 + 1;
  2599.     dw = MAX(dw, pp_avs_context->dest_w);
  2600.  
  2601.     pp_static_parameter->grf1.pointer_to_inline_parameter = 7;
  2602.     pp_static_parameter->grf2.avs_wa_enable = 1; /* must be set for GEN7 */
  2603.     pp_static_parameter->grf2.avs_wa_width = dw;
  2604.     pp_static_parameter->grf2.avs_wa_one_div_256_width = (float) 1.0 / (256 * dw);
  2605.     pp_static_parameter->grf2.avs_wa_five_div_256_width = (float) 5.0 / (256 * dw);
  2606.  
  2607.     pp_static_parameter->grf3.sampler_load_horizontal_scaling_step_ratio = (float) pp_avs_context->src_w / pp_avs_context->dest_w;
  2608.     pp_static_parameter->grf4.sampler_load_vertical_scaling_step = (float) src_rect->height / src_height / pp_avs_context->dest_h;
  2609.     pp_static_parameter->grf5.sampler_load_vertical_frame_origin = -(float)pp_avs_context->dest_y / pp_avs_context->dest_h;
  2610.     pp_static_parameter->grf6.sampler_load_horizontal_frame_origin = -(float)pp_avs_context->dest_x / pp_avs_context->dest_w;
  2611.  
  2612.     gen7_update_src_surface_uv_offset(ctx, pp_context, dst_surface);
  2613.  
  2614.     dst_surface->flags = src_surface->flags;
  2615.  
  2616.     return VA_STATUS_SUCCESS;
  2617. }
  2618.  
  2619.  
  2620. static int
  2621. pp_dndi_x_steps(void *private_context)
  2622. {
  2623.     return 1;
  2624. }
  2625.  
  2626. static int
  2627. pp_dndi_y_steps(void *private_context)
  2628. {
  2629.     struct pp_dndi_context *pp_dndi_context = private_context;
  2630.  
  2631.     return pp_dndi_context->dest_h / 4;
  2632. }
  2633.  
  2634. static int
  2635. pp_dndi_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
  2636. {
  2637.     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
  2638.  
  2639.     pp_inline_parameter->grf5.destination_block_horizontal_origin = x * 16;
  2640.     pp_inline_parameter->grf5.destination_block_vertical_origin = y * 4;
  2641.  
  2642.     return 0;
  2643. }
  2644.  
  2645. static
  2646. VAStatus pp_nv12_dndi_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
  2647.                              const struct i965_surface *src_surface,
  2648.                              const VARectangle *src_rect,
  2649.                              struct i965_surface *dst_surface,
  2650.                              const VARectangle *dst_rect,
  2651.                              void *filter_param)
  2652. {
  2653.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  2654.     struct pp_dndi_context *pp_dndi_context = (struct pp_dndi_context *)&pp_context->private_context;
  2655.     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
  2656.     struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
  2657.     struct object_surface *obj_surface;
  2658.     struct i965_sampler_dndi *sampler_dndi;
  2659.     int index;
  2660.     int w, h;
  2661.     int orig_w, orig_h;
  2662.     int dndi_top_first = 1;
  2663.  
  2664.     if (src_surface->flags == I965_SURFACE_FLAG_FRAME)
  2665.         return VA_STATUS_ERROR_FLAG_NOT_SUPPORTED;
  2666.  
  2667.     if (src_surface->flags == I965_SURFACE_FLAG_TOP_FIELD_FIRST)
  2668.         dndi_top_first = 1;
  2669.     else
  2670.         dndi_top_first = 0;
  2671.  
  2672.     /* surface */
  2673.     obj_surface = SURFACE(src_surface->id);
  2674.     orig_w = obj_surface->orig_width;
  2675.     orig_h = obj_surface->orig_height;
  2676.     w = obj_surface->width;
  2677.     h = obj_surface->height;
  2678.  
  2679.     if (pp_context->stmm.bo == NULL) {
  2680.         pp_context->stmm.bo = dri_bo_alloc(i965->intel.bufmgr,
  2681.                                            "STMM surface",
  2682.                                            w * h,
  2683.                                            4096);
  2684.         assert(pp_context->stmm.bo);
  2685.     }
  2686.  
  2687.     /* source UV surface index 2 */
  2688.     i965_pp_set_surface_state(ctx, pp_context,
  2689.                               obj_surface->bo, w * h,
  2690.                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
  2691.                               2, 0);
  2692.  
  2693.     /* source YUV surface index 4 */
  2694.     i965_pp_set_surface2_state(ctx, pp_context,
  2695.                                obj_surface->bo, 0,
  2696.                                orig_w, orig_h, w,
  2697.                                0, h,
  2698.                                SURFACE_FORMAT_PLANAR_420_8, 1,
  2699.                                4);
  2700.  
  2701.     /* source STMM surface index 20 */
  2702.     i965_pp_set_surface_state(ctx, pp_context,
  2703.                               pp_context->stmm.bo, 0,
  2704.                               orig_w, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
  2705.                               20, 1);
  2706.  
  2707.     /* destination surface */
  2708.     obj_surface = SURFACE(dst_surface->id);
  2709.     orig_w = obj_surface->orig_width;
  2710.     orig_h = obj_surface->orig_height;
  2711.     w = obj_surface->width;
  2712.     h = obj_surface->height;
  2713.  
  2714.     /* destination Y surface index 7 */
  2715.     i965_pp_set_surface_state(ctx, pp_context,
  2716.                               obj_surface->bo, 0,
  2717.                               orig_w / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
  2718.                               7, 1);
  2719.  
  2720.     /* destination UV surface index 8 */
  2721.     i965_pp_set_surface_state(ctx, pp_context,
  2722.                               obj_surface->bo, w * h,
  2723.                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
  2724.                               8, 1);
  2725.     /* sampler dndi */
  2726.     dri_bo_map(pp_context->sampler_state_table.bo, True);
  2727.     assert(pp_context->sampler_state_table.bo->virtual);
  2728.     assert(sizeof(*sampler_dndi) == sizeof(int) * 8);
  2729.     sampler_dndi = pp_context->sampler_state_table.bo->virtual;
  2730.  
  2731.     /* sample dndi index 1 */
  2732.     index = 0;
  2733.     sampler_dndi[index].dw0.denoise_asd_threshold = 0;
  2734.     sampler_dndi[index].dw0.denoise_history_delta = 8;          // 0-15, default is 8
  2735.     sampler_dndi[index].dw0.denoise_maximum_history = 128;      // 128-240
  2736.     sampler_dndi[index].dw0.denoise_stad_threshold = 0;
  2737.  
  2738.     sampler_dndi[index].dw1.denoise_threshold_for_sum_of_complexity_measure = 64;
  2739.     sampler_dndi[index].dw1.denoise_moving_pixel_threshold = 4;
  2740.     sampler_dndi[index].dw1.stmm_c2 = 1;
  2741.     sampler_dndi[index].dw1.low_temporal_difference_threshold = 8;
  2742.     sampler_dndi[index].dw1.temporal_difference_threshold = 16;
  2743.  
  2744.     sampler_dndi[index].dw2.block_noise_estimate_noise_threshold = 15;   // 0-31
  2745.     sampler_dndi[index].dw2.block_noise_estimate_edge_threshold = 7;    // 0-15
  2746.     sampler_dndi[index].dw2.denoise_edge_threshold = 7;                 // 0-15
  2747.     sampler_dndi[index].dw2.good_neighbor_threshold = 4;                // 0-63
  2748.  
  2749.     sampler_dndi[index].dw3.maximum_stmm = 128;
  2750.     sampler_dndi[index].dw3.multipler_for_vecm = 2;
  2751.     sampler_dndi[index].dw3.blending_constant_across_time_for_small_values_of_stmm = 0;
  2752.     sampler_dndi[index].dw3.blending_constant_across_time_for_large_values_of_stmm = 64;
  2753.     sampler_dndi[index].dw3.stmm_blending_constant_select = 0;
  2754.  
  2755.     sampler_dndi[index].dw4.sdi_delta = 8;
  2756.     sampler_dndi[index].dw4.sdi_threshold = 128;
  2757.     sampler_dndi[index].dw4.stmm_output_shift = 7;                      // stmm_max - stmm_min = 2 ^ stmm_output_shift
  2758.     sampler_dndi[index].dw4.stmm_shift_up = 0;
  2759.     sampler_dndi[index].dw4.stmm_shift_down = 0;
  2760.     sampler_dndi[index].dw4.minimum_stmm = 0;
  2761.  
  2762.     sampler_dndi[index].dw5.fmd_temporal_difference_threshold = 8;
  2763.     sampler_dndi[index].dw5.sdi_fallback_mode_2_constant = 32;
  2764.     sampler_dndi[index].dw5.sdi_fallback_mode_1_t2_constant = 64;
  2765.     sampler_dndi[index].dw5.sdi_fallback_mode_1_t1_constant = 32;
  2766.  
  2767.     sampler_dndi[index].dw6.dn_enable = 1;
  2768.     sampler_dndi[index].dw6.di_enable = 1;
  2769.     sampler_dndi[index].dw6.di_partial = 0;
  2770.     sampler_dndi[index].dw6.dndi_top_first = dndi_top_first;
  2771.     sampler_dndi[index].dw6.dndi_stream_id = 0;
  2772.     sampler_dndi[index].dw6.dndi_first_frame = 1;
  2773.     sampler_dndi[index].dw6.progressive_dn = 0;
  2774.     sampler_dndi[index].dw6.fmd_tear_threshold = 63;
  2775.     sampler_dndi[index].dw6.fmd2_vertical_difference_threshold = 32;
  2776.     sampler_dndi[index].dw6.fmd1_vertical_difference_threshold = 32;
  2777.  
  2778.     sampler_dndi[index].dw7.fmd_for_1st_field_of_current_frame = 0;
  2779.     sampler_dndi[index].dw7.fmd_for_2nd_field_of_previous_frame = 0;
  2780.     sampler_dndi[index].dw7.vdi_walker_enable = 0;
  2781.     sampler_dndi[index].dw7.column_width_minus1 = 0;
  2782.  
  2783.     dri_bo_unmap(pp_context->sampler_state_table.bo);
  2784.  
  2785.     /* private function & data */
  2786.     pp_context->pp_x_steps = pp_dndi_x_steps;
  2787.     pp_context->pp_y_steps = pp_dndi_y_steps;
  2788.     pp_context->pp_set_block_parameter = pp_dndi_set_block_parameter;
  2789.  
  2790.     pp_static_parameter->grf1.statistics_surface_picth = w / 2;
  2791.     pp_static_parameter->grf1.r1_6.di.top_field_first = dndi_top_first;
  2792.     pp_static_parameter->grf4.r4_2.di.motion_history_coefficient_m2 = 0;
  2793.     pp_static_parameter->grf4.r4_2.di.motion_history_coefficient_m1 = 0;
  2794.  
  2795.     pp_inline_parameter->grf5.block_count_x = w / 16;   /* 1 x N */
  2796.     pp_inline_parameter->grf5.number_blocks = w / 16;
  2797.     pp_inline_parameter->grf5.block_vertical_mask = 0xff;
  2798.     pp_inline_parameter->grf5.block_horizontal_mask = 0xffff;
  2799.  
  2800.     pp_dndi_context->dest_w = w;
  2801.     pp_dndi_context->dest_h = h;
  2802.  
  2803.     dst_surface->flags = I965_SURFACE_FLAG_FRAME;
  2804.  
  2805.     return VA_STATUS_SUCCESS;
  2806. }
  2807.  
  2808. static int
  2809. pp_dn_x_steps(void *private_context)
  2810. {
  2811.     return 1;
  2812. }
  2813.  
  2814. static int
  2815. pp_dn_y_steps(void *private_context)
  2816. {
  2817.     struct pp_dn_context *pp_dn_context = private_context;
  2818.  
  2819.     return pp_dn_context->dest_h / 8;
  2820. }
  2821.  
  2822. static int
  2823. pp_dn_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
  2824. {
  2825.     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
  2826.  
  2827.     pp_inline_parameter->grf5.destination_block_horizontal_origin = x * 16;
  2828.     pp_inline_parameter->grf5.destination_block_vertical_origin = y * 8;
  2829.  
  2830.     return 0;
  2831. }
  2832.  
  2833. static
  2834. VAStatus pp_nv12_dn_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
  2835.                            const struct i965_surface *src_surface,
  2836.                            const VARectangle *src_rect,
  2837.                            struct i965_surface *dst_surface,
  2838.                            const VARectangle *dst_rect,
  2839.                            void *filter_param)
  2840. {
  2841.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  2842.     struct pp_dn_context *pp_dn_context = (struct pp_dn_context *)&pp_context->private_context;
  2843.     struct object_surface *obj_surface;
  2844.     struct i965_sampler_dndi *sampler_dndi;
  2845.     struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
  2846.     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
  2847.  
  2848.     int index;
  2849.     int w, h;
  2850.     int orig_w, orig_h;
  2851.     int dn_strength = 15;
  2852.     int dndi_top_first = 1;
  2853.     int dn_progressive = 0;
  2854.  
  2855.     if (src_surface->flags == I965_SURFACE_FLAG_FRAME) {
  2856.         dndi_top_first = 1;
  2857.         dn_progressive = 1;
  2858.     } else if (src_surface->flags == I965_SURFACE_FLAG_TOP_FIELD_FIRST) {
  2859.         dndi_top_first = 1;
  2860.         dn_progressive = 0;
  2861.     } else {
  2862.         dndi_top_first = 0;
  2863.         dn_progressive = 0;
  2864.     }
  2865.  
  2866.     /* surface */
  2867.     obj_surface = SURFACE(src_surface->id);
  2868.     orig_w = obj_surface->orig_width;
  2869.     orig_h = obj_surface->orig_height;
  2870.     w = obj_surface->width;
  2871.     h = obj_surface->height;
  2872.  
  2873.     if (pp_context->stmm.bo == NULL) {
  2874.         pp_context->stmm.bo = dri_bo_alloc(i965->intel.bufmgr,
  2875.                                            "STMM surface",
  2876.                                            w * h,
  2877.                                            4096);
  2878.         assert(pp_context->stmm.bo);
  2879.     }
  2880.  
  2881.     /* source UV surface index 2 */
  2882.     i965_pp_set_surface_state(ctx, pp_context,
  2883.                               obj_surface->bo, w * h,
  2884.                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
  2885.                               2, 0);
  2886.  
  2887.     /* source YUV surface index 4 */
  2888.     i965_pp_set_surface2_state(ctx, pp_context,
  2889.                                obj_surface->bo, 0,
  2890.                                orig_w, orig_h, w,
  2891.                                0, h,
  2892.                                SURFACE_FORMAT_PLANAR_420_8, 1,
  2893.                                4);
  2894.  
  2895.     /* source STMM surface index 20 */
  2896.     i965_pp_set_surface_state(ctx, pp_context,
  2897.                               pp_context->stmm.bo, 0,
  2898.                               orig_w, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
  2899.                               20, 1);
  2900.  
  2901.     /* destination surface */
  2902.     obj_surface = SURFACE(dst_surface->id);
  2903.     orig_w = obj_surface->orig_width;
  2904.     orig_h = obj_surface->orig_height;
  2905.     w = obj_surface->width;
  2906.     h = obj_surface->height;
  2907.  
  2908.     /* destination Y surface index 7 */
  2909.     i965_pp_set_surface_state(ctx, pp_context,
  2910.                               obj_surface->bo, 0,
  2911.                               orig_w / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
  2912.                               7, 1);
  2913.  
  2914.     /* destination UV surface index 8 */
  2915.     i965_pp_set_surface_state(ctx, pp_context,
  2916.                               obj_surface->bo, w * h,
  2917.                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
  2918.                               8, 1);
  2919.     /* sampler dn */
  2920.     dri_bo_map(pp_context->sampler_state_table.bo, True);
  2921.     assert(pp_context->sampler_state_table.bo->virtual);
  2922.     assert(sizeof(*sampler_dndi) == sizeof(int) * 8);
  2923.     sampler_dndi = pp_context->sampler_state_table.bo->virtual;
  2924.  
  2925.     /* sample dndi index 1 */
  2926.     index = 0;
  2927.     sampler_dndi[index].dw0.denoise_asd_threshold = 0;
  2928.     sampler_dndi[index].dw0.denoise_history_delta = 8;          // 0-15, default is 8
  2929.     sampler_dndi[index].dw0.denoise_maximum_history = 128;      // 128-240
  2930.     sampler_dndi[index].dw0.denoise_stad_threshold = 0;
  2931.  
  2932.     sampler_dndi[index].dw1.denoise_threshold_for_sum_of_complexity_measure = 64;
  2933.     sampler_dndi[index].dw1.denoise_moving_pixel_threshold = 0;
  2934.     sampler_dndi[index].dw1.stmm_c2 = 0;
  2935.     sampler_dndi[index].dw1.low_temporal_difference_threshold = 8;
  2936.     sampler_dndi[index].dw1.temporal_difference_threshold = 16;
  2937.  
  2938.     sampler_dndi[index].dw2.block_noise_estimate_noise_threshold = dn_strength;   // 0-31
  2939.     sampler_dndi[index].dw2.block_noise_estimate_edge_threshold = 7;    // 0-15
  2940.     sampler_dndi[index].dw2.denoise_edge_threshold = 7;                 // 0-15
  2941.     sampler_dndi[index].dw2.good_neighbor_threshold = 7;                // 0-63
  2942.  
  2943.     sampler_dndi[index].dw3.maximum_stmm = 128;
  2944.     sampler_dndi[index].dw3.multipler_for_vecm = 2;
  2945.     sampler_dndi[index].dw3.blending_constant_across_time_for_small_values_of_stmm = 0;
  2946.     sampler_dndi[index].dw3.blending_constant_across_time_for_large_values_of_stmm = 64;
  2947.     sampler_dndi[index].dw3.stmm_blending_constant_select = 0;
  2948.  
  2949.     sampler_dndi[index].dw4.sdi_delta = 8;
  2950.     sampler_dndi[index].dw4.sdi_threshold = 128;
  2951.     sampler_dndi[index].dw4.stmm_output_shift = 7;                      // stmm_max - stmm_min = 2 ^ stmm_output_shift
  2952.     sampler_dndi[index].dw4.stmm_shift_up = 0;
  2953.     sampler_dndi[index].dw4.stmm_shift_down = 0;
  2954.     sampler_dndi[index].dw4.minimum_stmm = 0;
  2955.  
  2956.     sampler_dndi[index].dw5.fmd_temporal_difference_threshold = 0;
  2957.     sampler_dndi[index].dw5.sdi_fallback_mode_2_constant = 0;
  2958.     sampler_dndi[index].dw5.sdi_fallback_mode_1_t2_constant = 0;
  2959.     sampler_dndi[index].dw5.sdi_fallback_mode_1_t1_constant = 0;
  2960.  
  2961.     sampler_dndi[index].dw6.dn_enable = 1;
  2962.     sampler_dndi[index].dw6.di_enable = 0;
  2963.     sampler_dndi[index].dw6.di_partial = 0;
  2964.     sampler_dndi[index].dw6.dndi_top_first = dndi_top_first;
  2965.     sampler_dndi[index].dw6.dndi_stream_id = 1;
  2966.     sampler_dndi[index].dw6.dndi_first_frame = 1;
  2967.     sampler_dndi[index].dw6.progressive_dn = dn_progressive;
  2968.     sampler_dndi[index].dw6.fmd_tear_threshold = 32;
  2969.     sampler_dndi[index].dw6.fmd2_vertical_difference_threshold = 32;
  2970.     sampler_dndi[index].dw6.fmd1_vertical_difference_threshold = 32;
  2971.  
  2972.     sampler_dndi[index].dw7.fmd_for_1st_field_of_current_frame = 2;
  2973.     sampler_dndi[index].dw7.fmd_for_2nd_field_of_previous_frame = 1;
  2974.     sampler_dndi[index].dw7.vdi_walker_enable = 0;
  2975.     sampler_dndi[index].dw7.column_width_minus1 = w / 16;
  2976.  
  2977.     dri_bo_unmap(pp_context->sampler_state_table.bo);
  2978.  
  2979.     /* private function & data */
  2980.     pp_context->pp_x_steps = pp_dn_x_steps;
  2981.     pp_context->pp_y_steps = pp_dn_y_steps;
  2982.     pp_context->pp_set_block_parameter = pp_dn_set_block_parameter;
  2983.  
  2984.     pp_static_parameter->grf1.statistics_surface_picth = w / 2;
  2985.     pp_static_parameter->grf1.r1_6.di.top_field_first = 0;
  2986.     pp_static_parameter->grf4.r4_2.di.motion_history_coefficient_m2 = 64;
  2987.     pp_static_parameter->grf4.r4_2.di.motion_history_coefficient_m1 = 192;
  2988.  
  2989.     pp_inline_parameter->grf5.block_count_x = w / 16;   /* 1 x N */
  2990.     pp_inline_parameter->grf5.number_blocks = w / 16;
  2991.     pp_inline_parameter->grf5.block_vertical_mask = 0xff;
  2992.     pp_inline_parameter->grf5.block_horizontal_mask = 0xffff;
  2993.  
  2994.     pp_dn_context->dest_w = w;
  2995.     pp_dn_context->dest_h = h;
  2996.  
  2997.     return VA_STATUS_SUCCESS;
  2998. }
  2999.  
  3000. static int
  3001. gen7_pp_dndi_x_steps(void *private_context)
  3002. {
  3003.     struct pp_dndi_context *pp_dndi_context = private_context;
  3004.  
  3005.     return pp_dndi_context->dest_w / 16;
  3006. }
  3007.  
  3008. static int
  3009. gen7_pp_dndi_y_steps(void *private_context)
  3010. {
  3011.     struct pp_dndi_context *pp_dndi_context = private_context;
  3012.  
  3013.     return pp_dndi_context->dest_h / 4;
  3014. }
  3015.  
  3016. static int
  3017. gen7_pp_dndi_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
  3018. {
  3019.     struct gen7_pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
  3020.  
  3021.     pp_inline_parameter->grf7.destination_block_horizontal_origin = x * 16;
  3022.     pp_inline_parameter->grf7.destination_block_vertical_origin = y * 4;
  3023.  
  3024.     return 0;
  3025. }
  3026.  
  3027. static VAStatus
  3028. gen7_pp_nv12_dndi_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
  3029.                              const struct i965_surface *src_surface,
  3030.                              const VARectangle *src_rect,
  3031.                              struct i965_surface *dst_surface,
  3032.                              const VARectangle *dst_rect,
  3033.                              void *filter_param)
  3034. {
  3035.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  3036.     struct pp_dndi_context *pp_dndi_context = (struct pp_dndi_context *)&pp_context->private_context;
  3037.     struct gen7_pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
  3038.     struct object_surface *obj_surface;
  3039.     struct gen7_sampler_dndi *sampler_dndi;
  3040.     int index;
  3041.     int w, h;
  3042.     int orig_w, orig_h;
  3043.     int dndi_top_first = 1;
  3044.  
  3045.     if (src_surface->flags == I965_SURFACE_FLAG_FRAME)
  3046.         return VA_STATUS_ERROR_FLAG_NOT_SUPPORTED;
  3047.  
  3048.     if (src_surface->flags == I965_SURFACE_FLAG_TOP_FIELD_FIRST)
  3049.         dndi_top_first = 1;
  3050.     else
  3051.         dndi_top_first = 0;
  3052.  
  3053.     /* surface */
  3054.     obj_surface = SURFACE(src_surface->id);
  3055.     orig_w = obj_surface->orig_width;
  3056.     orig_h = obj_surface->orig_height;
  3057.     w = obj_surface->width;
  3058.     h = obj_surface->height;
  3059.  
  3060.     if (pp_context->stmm.bo == NULL) {
  3061.         pp_context->stmm.bo = dri_bo_alloc(i965->intel.bufmgr,
  3062.                                            "STMM surface",
  3063.                                            w * h,
  3064.                                            4096);
  3065.         assert(pp_context->stmm.bo);
  3066.     }
  3067.  
  3068.     /* source UV surface index 1 */
  3069.     gen7_pp_set_surface_state(ctx, pp_context,
  3070.                               obj_surface->bo, w * h,
  3071.                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
  3072.                               1, 0);
  3073.  
  3074.     /* source YUV surface index 3 */
  3075.     gen7_pp_set_surface2_state(ctx, pp_context,
  3076.                                obj_surface->bo, 0,
  3077.                                orig_w, orig_h, w,
  3078.                                0, h,
  3079.                                SURFACE_FORMAT_PLANAR_420_8, 1,
  3080.                                3);
  3081.  
  3082.     /* source (temporal reference) YUV surface index 4 */
  3083.     gen7_pp_set_surface2_state(ctx, pp_context,
  3084.                                obj_surface->bo, 0,
  3085.                                orig_w, orig_h, w,
  3086.                                0, h,
  3087.                                SURFACE_FORMAT_PLANAR_420_8, 1,
  3088.                                4);
  3089.  
  3090.     /* STMM / History Statistics input surface, index 5 */
  3091.     gen7_pp_set_surface_state(ctx, pp_context,
  3092.                               pp_context->stmm.bo, 0,
  3093.                               orig_w, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
  3094.                               5, 1);
  3095.  
  3096.     /* destination surface */
  3097.     obj_surface = SURFACE(dst_surface->id);
  3098.     orig_w = obj_surface->orig_width;
  3099.     orig_h = obj_surface->orig_height;
  3100.     w = obj_surface->width;
  3101.     h = obj_surface->height;
  3102.  
  3103.     /* destination(Previous frame) Y surface index 27 */
  3104.     gen7_pp_set_surface_state(ctx, pp_context,
  3105.                               obj_surface->bo, 0,
  3106.                               orig_w / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
  3107.                               27, 1);
  3108.  
  3109.     /* destination(Previous frame) UV surface index 28 */
  3110.     gen7_pp_set_surface_state(ctx, pp_context,
  3111.                               obj_surface->bo, w * h,
  3112.                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
  3113.                               28, 1);
  3114.  
  3115.     /* destination(Current frame) Y surface index 30 */
  3116.     gen7_pp_set_surface_state(ctx, pp_context,
  3117.                               obj_surface->bo, 0,
  3118.                               orig_w / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
  3119.                               30, 1);
  3120.  
  3121.     /* destination(Current frame) UV surface index 31 */
  3122.     gen7_pp_set_surface_state(ctx, pp_context,
  3123.                               obj_surface->bo, w * h,
  3124.                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
  3125.                               31, 1);
  3126.  
  3127.     /* STMM output surface, index 33 */
  3128.     gen7_pp_set_surface_state(ctx, pp_context,
  3129.                               pp_context->stmm.bo, 0,
  3130.                               orig_w, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
  3131.                               33, 1);
  3132.  
  3133.  
  3134.     /* sampler dndi */
  3135.     dri_bo_map(pp_context->sampler_state_table.bo, True);
  3136.     assert(pp_context->sampler_state_table.bo->virtual);
  3137.     assert(sizeof(*sampler_dndi) == sizeof(int) * 8);
  3138.     sampler_dndi = pp_context->sampler_state_table.bo->virtual;
  3139.  
  3140.     /* sample dndi index 0 */
  3141.     index = 0;
  3142.     sampler_dndi[index].dw0.denoise_asd_threshold = 0;
  3143.     sampler_dndi[index].dw0.dnmh_delt = 8;
  3144.     sampler_dndi[index].dw0.vdi_walker_y_stride = 0;
  3145.     sampler_dndi[index].dw0.vdi_walker_frame_sharing_enable = 0;
  3146.     sampler_dndi[index].dw0.denoise_maximum_history = 128;      // 128-240
  3147.     sampler_dndi[index].dw0.denoise_stad_threshold = 0;
  3148.  
  3149.     sampler_dndi[index].dw1.denoise_threshold_for_sum_of_complexity_measure = 64;
  3150.     sampler_dndi[index].dw1.denoise_moving_pixel_threshold = 0;
  3151.     sampler_dndi[index].dw1.stmm_c2 = 0;
  3152.     sampler_dndi[index].dw1.low_temporal_difference_threshold = 8;
  3153.     sampler_dndi[index].dw1.temporal_difference_threshold = 16;
  3154.  
  3155.     sampler_dndi[index].dw2.block_noise_estimate_noise_threshold = 15;   // 0-31
  3156.     sampler_dndi[index].dw2.bne_edge_th = 1;
  3157.     sampler_dndi[index].dw2.smooth_mv_th = 0;
  3158.     sampler_dndi[index].dw2.sad_tight_th = 5;
  3159.     sampler_dndi[index].dw2.cat_slope_minus1 = 9;
  3160.     sampler_dndi[index].dw2.good_neighbor_th = 4;
  3161.  
  3162.     sampler_dndi[index].dw3.maximum_stmm = 128;
  3163.     sampler_dndi[index].dw3.multipler_for_vecm = 2;
  3164.     sampler_dndi[index].dw3.blending_constant_across_time_for_small_values_of_stmm = 0;
  3165.     sampler_dndi[index].dw3.blending_constant_across_time_for_large_values_of_stmm = 64;
  3166.     sampler_dndi[index].dw3.stmm_blending_constant_select = 0;
  3167.  
  3168.     sampler_dndi[index].dw4.sdi_delta = 8;
  3169.     sampler_dndi[index].dw4.sdi_threshold = 128;
  3170.     sampler_dndi[index].dw4.stmm_output_shift = 7;                      // stmm_max - stmm_min = 2 ^ stmm_output_shift
  3171.     sampler_dndi[index].dw4.stmm_shift_up = 0;
  3172.     sampler_dndi[index].dw4.stmm_shift_down = 0;
  3173.     sampler_dndi[index].dw4.minimum_stmm = 0;
  3174.  
  3175.     sampler_dndi[index].dw5.fmd_temporal_difference_threshold = 0;
  3176.     sampler_dndi[index].dw5.sdi_fallback_mode_2_constant = 0;
  3177.     sampler_dndi[index].dw5.sdi_fallback_mode_1_t2_constant = 0;
  3178.     sampler_dndi[index].dw5.sdi_fallback_mode_1_t1_constant = 0;
  3179.  
  3180.     sampler_dndi[index].dw6.dn_enable = 0;
  3181.     sampler_dndi[index].dw6.di_enable = 1;
  3182.     sampler_dndi[index].dw6.di_partial = 0;
  3183.     sampler_dndi[index].dw6.dndi_top_first = dndi_top_first;
  3184.     sampler_dndi[index].dw6.dndi_stream_id = 1;
  3185.     sampler_dndi[index].dw6.dndi_first_frame = 1;
  3186.     sampler_dndi[index].dw6.progressive_dn = 0;
  3187.     sampler_dndi[index].dw6.mcdi_enable = 0;
  3188.     sampler_dndi[index].dw6.fmd_tear_threshold = 32;
  3189.     sampler_dndi[index].dw6.cat_th1 = 0;
  3190.     sampler_dndi[index].dw6.fmd2_vertical_difference_threshold = 32;
  3191.     sampler_dndi[index].dw6.fmd1_vertical_difference_threshold = 32;
  3192.  
  3193.     sampler_dndi[index].dw7.sad_tha = 5;
  3194.     sampler_dndi[index].dw7.sad_thb = 10;
  3195.     sampler_dndi[index].dw7.fmd_for_1st_field_of_current_frame = 0;
  3196.     sampler_dndi[index].dw7.mc_pixel_consistency_th = 25;
  3197.     sampler_dndi[index].dw7.fmd_for_2nd_field_of_previous_frame = 0;
  3198.     sampler_dndi[index].dw7.vdi_walker_enable = 0;
  3199.     sampler_dndi[index].dw7.neighborpixel_th = 10;
  3200.     sampler_dndi[index].dw7.column_width_minus1 = w / 16;
  3201.  
  3202.     dri_bo_unmap(pp_context->sampler_state_table.bo);
  3203.  
  3204.     /* private function & data */
  3205.     pp_context->pp_x_steps = gen7_pp_dndi_x_steps;
  3206.     pp_context->pp_y_steps = gen7_pp_dndi_y_steps;
  3207.     pp_context->pp_set_block_parameter = gen7_pp_dndi_set_block_parameter;
  3208.  
  3209.     pp_static_parameter->grf1.di_statistics_surface_pitch_div2 = w / 2;
  3210.     pp_static_parameter->grf1.di_statistics_surface_height_div4 = h / 4;
  3211.     pp_static_parameter->grf1.di_top_field_first = 0;
  3212.     pp_static_parameter->grf1.pointer_to_inline_parameter = 7;
  3213.  
  3214.     pp_static_parameter->grf2.di_destination_packed_y_component_offset = 0;
  3215.     pp_static_parameter->grf2.di_destination_packed_u_component_offset = 1;
  3216.     pp_static_parameter->grf2.di_destination_packed_v_component_offset = 3;
  3217.  
  3218.     pp_static_parameter->grf4.di_hoffset_svf_from_dvf = 0;
  3219.     pp_static_parameter->grf4.di_voffset_svf_from_dvf = 0;
  3220.  
  3221.     pp_dndi_context->dest_w = w;
  3222.     pp_dndi_context->dest_h = h;
  3223.  
  3224.     dst_surface->flags = I965_SURFACE_FLAG_FRAME;
  3225.  
  3226.     return VA_STATUS_SUCCESS;
  3227. }
  3228.  
  3229. static int
  3230. gen7_pp_dn_x_steps(void *private_context)
  3231. {
  3232.     struct pp_dn_context *pp_dn_context = private_context;
  3233.  
  3234.     return pp_dn_context->dest_w / 16;
  3235. }
  3236.  
  3237. static int
  3238. gen7_pp_dn_y_steps(void *private_context)
  3239. {
  3240.     struct pp_dn_context *pp_dn_context = private_context;
  3241.  
  3242.     return pp_dn_context->dest_h / 4;
  3243. }
  3244.  
  3245. static int
  3246. gen7_pp_dn_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
  3247. {
  3248.     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
  3249.  
  3250.     pp_inline_parameter->grf5.destination_block_horizontal_origin = x * 16;
  3251.     pp_inline_parameter->grf5.destination_block_vertical_origin = y * 4;
  3252.  
  3253.     return 0;
  3254. }
  3255.  
  3256. static VAStatus
  3257. gen7_pp_nv12_dn_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
  3258.                            const struct i965_surface *src_surface,
  3259.                            const VARectangle *src_rect,
  3260.                            struct i965_surface *dst_surface,
  3261.                            const VARectangle *dst_rect,
  3262.                            void *filter_param)
  3263. {
  3264.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  3265.     struct pp_dn_context *pp_dn_context = (struct pp_dn_context *)&pp_context->private_context;
  3266.     struct gen7_pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
  3267.     struct object_surface *obj_surface;
  3268.     struct gen7_sampler_dndi *sampler_dn;
  3269.  
  3270.     int index;
  3271.     int w, h;
  3272.     int orig_w, orig_h;
  3273.     int dn_strength = 15;
  3274.     int dndi_top_first = 1;
  3275.     int dn_progressive = 0;
  3276.  
  3277.     if (src_surface->flags == I965_SURFACE_FLAG_FRAME) {
  3278.         dndi_top_first = 1;
  3279.         dn_progressive = 1;
  3280.     } else if (src_surface->flags == I965_SURFACE_FLAG_TOP_FIELD_FIRST) {
  3281.         dndi_top_first = 1;
  3282.         dn_progressive = 0;
  3283.     } else {
  3284.         dndi_top_first = 0;
  3285.         dn_progressive = 0;
  3286.     }
  3287.  
  3288.     /* surface */
  3289.     obj_surface = SURFACE(src_surface->id);
  3290.     orig_w = obj_surface->orig_width;
  3291.     orig_h = obj_surface->orig_height;
  3292.     w = obj_surface->width;
  3293.     h = obj_surface->height;
  3294.  
  3295.     if (pp_context->stmm.bo == NULL) {
  3296.         pp_context->stmm.bo = dri_bo_alloc(i965->intel.bufmgr,
  3297.                                            "STMM surface",
  3298.                                            w * h,
  3299.                                            4096);
  3300.         assert(pp_context->stmm.bo);
  3301.     }
  3302.  
  3303.     /* source UV surface index 1 */
  3304.     gen7_pp_set_surface_state(ctx, pp_context,
  3305.                               obj_surface->bo, w * h,
  3306.                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
  3307.                               1, 0);
  3308.  
  3309.     /* source YUV surface index 3 */
  3310.     gen7_pp_set_surface2_state(ctx, pp_context,
  3311.                                obj_surface->bo, 0,
  3312.                                orig_w, orig_h, w,
  3313.                                0, h,
  3314.                                SURFACE_FORMAT_PLANAR_420_8, 1,
  3315.                                3);
  3316.  
  3317.     /* source (temporal reference) YUV surface index 4 */
  3318.     gen7_pp_set_surface2_state(ctx, pp_context,
  3319.                                obj_surface->bo, 0,
  3320.                                orig_w, orig_h, w,
  3321.                                0, h,
  3322.                                SURFACE_FORMAT_PLANAR_420_8, 1,
  3323.                                4);
  3324.  
  3325.     /* STMM / History Statistics input surface, index 5 */
  3326.     gen7_pp_set_surface_state(ctx, pp_context,
  3327.                               pp_context->stmm.bo, 0,
  3328.                               orig_w, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
  3329.                               5, 1);
  3330.  
  3331.     /* destination surface */
  3332.     obj_surface = SURFACE(dst_surface->id);
  3333.     orig_w = obj_surface->orig_width;
  3334.     orig_h = obj_surface->orig_height;
  3335.     w = obj_surface->width;
  3336.     h = obj_surface->height;
  3337.  
  3338.     /* destination Y surface index 24 */
  3339.     gen7_pp_set_surface_state(ctx, pp_context,
  3340.                               obj_surface->bo, 0,
  3341.                               orig_w / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
  3342.                               24, 1);
  3343.  
  3344.     /* destination UV surface index 25 */
  3345.     gen7_pp_set_surface_state(ctx, pp_context,
  3346.                               obj_surface->bo, w * h,
  3347.                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
  3348.                               25, 1);
  3349.  
  3350.     /* sampler dn */
  3351.     dri_bo_map(pp_context->sampler_state_table.bo, True);
  3352.     assert(pp_context->sampler_state_table.bo->virtual);
  3353.     assert(sizeof(*sampler_dn) == sizeof(int) * 8);
  3354.     sampler_dn = pp_context->sampler_state_table.bo->virtual;
  3355.  
  3356.     /* sample dn index 1 */
  3357.     index = 0;
  3358.     sampler_dn[index].dw0.denoise_asd_threshold = 0;
  3359.     sampler_dn[index].dw0.dnmh_delt = 8;
  3360.     sampler_dn[index].dw0.vdi_walker_y_stride = 0;
  3361.     sampler_dn[index].dw0.vdi_walker_frame_sharing_enable = 0;
  3362.     sampler_dn[index].dw0.denoise_maximum_history = 128;      // 128-240
  3363.     sampler_dn[index].dw0.denoise_stad_threshold = 0;
  3364.  
  3365.     sampler_dn[index].dw1.denoise_threshold_for_sum_of_complexity_measure = 64;
  3366.     sampler_dn[index].dw1.denoise_moving_pixel_threshold = 0;
  3367.     sampler_dn[index].dw1.stmm_c2 = 0;
  3368.     sampler_dn[index].dw1.low_temporal_difference_threshold = 8;
  3369.     sampler_dn[index].dw1.temporal_difference_threshold = 16;
  3370.  
  3371.     sampler_dn[index].dw2.block_noise_estimate_noise_threshold = dn_strength;   // 0-31
  3372.     sampler_dn[index].dw2.bne_edge_th = 1;
  3373.     sampler_dn[index].dw2.smooth_mv_th = 0;
  3374.     sampler_dn[index].dw2.sad_tight_th = 5;
  3375.     sampler_dn[index].dw2.cat_slope_minus1 = 9;
  3376.     sampler_dn[index].dw2.good_neighbor_th = 4;
  3377.  
  3378.     sampler_dn[index].dw3.maximum_stmm = 128;
  3379.     sampler_dn[index].dw3.multipler_for_vecm = 2;
  3380.     sampler_dn[index].dw3.blending_constant_across_time_for_small_values_of_stmm = 0;
  3381.     sampler_dn[index].dw3.blending_constant_across_time_for_large_values_of_stmm = 64;
  3382.     sampler_dn[index].dw3.stmm_blending_constant_select = 0;
  3383.  
  3384.     sampler_dn[index].dw4.sdi_delta = 8;
  3385.     sampler_dn[index].dw4.sdi_threshold = 128;
  3386.     sampler_dn[index].dw4.stmm_output_shift = 7;                      // stmm_max - stmm_min = 2 ^ stmm_output_shift
  3387.     sampler_dn[index].dw4.stmm_shift_up = 0;
  3388.     sampler_dn[index].dw4.stmm_shift_down = 0;
  3389.     sampler_dn[index].dw4.minimum_stmm = 0;
  3390.  
  3391.     sampler_dn[index].dw5.fmd_temporal_difference_threshold = 0;
  3392.     sampler_dn[index].dw5.sdi_fallback_mode_2_constant = 0;
  3393.     sampler_dn[index].dw5.sdi_fallback_mode_1_t2_constant = 0;
  3394.     sampler_dn[index].dw5.sdi_fallback_mode_1_t1_constant = 0;
  3395.  
  3396.     sampler_dn[index].dw6.dn_enable = 1;
  3397.     sampler_dn[index].dw6.di_enable = 0;
  3398.     sampler_dn[index].dw6.di_partial = 0;
  3399.     sampler_dn[index].dw6.dndi_top_first = dndi_top_first;
  3400.     sampler_dn[index].dw6.dndi_stream_id = 1;
  3401.     sampler_dn[index].dw6.dndi_first_frame = 1;
  3402.     sampler_dn[index].dw6.progressive_dn = dn_progressive;
  3403.     sampler_dn[index].dw6.mcdi_enable = 0;
  3404.     sampler_dn[index].dw6.fmd_tear_threshold = 32;
  3405.     sampler_dn[index].dw6.cat_th1 = 0;
  3406.     sampler_dn[index].dw6.fmd2_vertical_difference_threshold = 32;
  3407.     sampler_dn[index].dw6.fmd1_vertical_difference_threshold = 32;
  3408.  
  3409.     sampler_dn[index].dw7.sad_tha = 5;
  3410.     sampler_dn[index].dw7.sad_thb = 10;
  3411.     sampler_dn[index].dw7.fmd_for_1st_field_of_current_frame = 2;
  3412.     sampler_dn[index].dw7.mc_pixel_consistency_th = 25;
  3413.     sampler_dn[index].dw7.fmd_for_2nd_field_of_previous_frame = 1;
  3414.     sampler_dn[index].dw7.vdi_walker_enable = 0;
  3415.     sampler_dn[index].dw7.neighborpixel_th = 10;
  3416.     sampler_dn[index].dw7.column_width_minus1 = w / 16;
  3417.  
  3418.     dri_bo_unmap(pp_context->sampler_state_table.bo);
  3419.  
  3420.     /* private function & data */
  3421.     pp_context->pp_x_steps = gen7_pp_dn_x_steps;
  3422.     pp_context->pp_y_steps = gen7_pp_dn_y_steps;
  3423.     pp_context->pp_set_block_parameter = gen7_pp_dn_set_block_parameter;
  3424.  
  3425.     pp_static_parameter->grf1.di_statistics_surface_pitch_div2 = w / 2;
  3426.     pp_static_parameter->grf1.di_statistics_surface_height_div4 = h / 4;
  3427.     pp_static_parameter->grf1.di_top_field_first = 0;
  3428.     pp_static_parameter->grf1.pointer_to_inline_parameter = 7;
  3429.  
  3430.     pp_static_parameter->grf2.di_destination_packed_y_component_offset = 0;
  3431.     pp_static_parameter->grf2.di_destination_packed_u_component_offset = 1;
  3432.     pp_static_parameter->grf2.di_destination_packed_v_component_offset = 3;
  3433.  
  3434.     pp_static_parameter->grf4.di_hoffset_svf_from_dvf = 0;
  3435.     pp_static_parameter->grf4.di_voffset_svf_from_dvf = 0;
  3436.  
  3437.     pp_dn_context->dest_w = w;
  3438.     pp_dn_context->dest_h = h;
  3439.  
  3440.     dst_surface->flags = src_surface->flags;
  3441.  
  3442.     return VA_STATUS_SUCCESS;
  3443. }
  3444.  
  3445. static VAStatus
  3446. ironlake_pp_initialize(
  3447.     VADriverContextP   ctx,
  3448.     struct i965_post_processing_context *pp_context,
  3449.     const struct i965_surface *src_surface,
  3450.     const VARectangle *src_rect,
  3451.     struct i965_surface *dst_surface,
  3452.     const VARectangle *dst_rect,
  3453.     int                pp_index,
  3454.     void  *filter_param
  3455. )
  3456. {
  3457.     VAStatus va_status;
  3458.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  3459.     struct pp_module *pp_module;
  3460.     dri_bo *bo;
  3461.     int static_param_size, inline_param_size;
  3462.  
  3463.     dri_bo_unreference(pp_context->surface_state_binding_table.bo);
  3464.     bo = dri_bo_alloc(i965->intel.bufmgr,
  3465.                       "surface state & binding table",
  3466.                       (SURFACE_STATE_PADDED_SIZE + sizeof(unsigned int)) * MAX_PP_SURFACES,
  3467.                       4096);
  3468.     assert(bo);
  3469.     pp_context->surface_state_binding_table.bo = bo;
  3470.  
  3471.     dri_bo_unreference(pp_context->curbe.bo);
  3472.     bo = dri_bo_alloc(i965->intel.bufmgr,
  3473.                       "constant buffer",
  3474.                       4096,
  3475.                       4096);
  3476.     assert(bo);
  3477.     pp_context->curbe.bo = bo;
  3478.  
  3479.     dri_bo_unreference(pp_context->idrt.bo);
  3480.     bo = dri_bo_alloc(i965->intel.bufmgr,
  3481.                       "interface discriptor",
  3482.                       sizeof(struct i965_interface_descriptor),
  3483.                       4096);
  3484.     assert(bo);
  3485.     pp_context->idrt.bo = bo;
  3486.     pp_context->idrt.num_interface_descriptors = 0;
  3487.  
  3488.     dri_bo_unreference(pp_context->sampler_state_table.bo);
  3489.     bo = dri_bo_alloc(i965->intel.bufmgr,
  3490.                       "sampler state table",
  3491.                       4096,
  3492.                       4096);
  3493.     assert(bo);
  3494.     dri_bo_map(bo, True);
  3495.     memset(bo->virtual, 0, bo->size);
  3496.     dri_bo_unmap(bo);
  3497.     pp_context->sampler_state_table.bo = bo;
  3498.  
  3499.     dri_bo_unreference(pp_context->sampler_state_table.bo_8x8);
  3500.     bo = dri_bo_alloc(i965->intel.bufmgr,
  3501.                       "sampler 8x8 state ",
  3502.                       4096,
  3503.                       4096);
  3504.     assert(bo);
  3505.     pp_context->sampler_state_table.bo_8x8 = bo;
  3506.  
  3507.     dri_bo_unreference(pp_context->sampler_state_table.bo_8x8_uv);
  3508.     bo = dri_bo_alloc(i965->intel.bufmgr,
  3509.                       "sampler 8x8 state ",
  3510.                       4096,
  3511.                       4096);
  3512.     assert(bo);
  3513.     pp_context->sampler_state_table.bo_8x8_uv = bo;
  3514.  
  3515.     dri_bo_unreference(pp_context->vfe_state.bo);
  3516.     bo = dri_bo_alloc(i965->intel.bufmgr,
  3517.                       "vfe state",
  3518.                       sizeof(struct i965_vfe_state),
  3519.                       4096);
  3520.     assert(bo);
  3521.     pp_context->vfe_state.bo = bo;
  3522.  
  3523.     static_param_size = sizeof(struct pp_static_parameter);
  3524.     inline_param_size = sizeof(struct pp_inline_parameter);
  3525.    
  3526.     memset(pp_context->pp_static_parameter, 0, static_param_size);
  3527.     memset(pp_context->pp_inline_parameter, 0, inline_param_size);
  3528.    
  3529.     assert(pp_index >= PP_NULL && pp_index < NUM_PP_MODULES);
  3530.     pp_context->current_pp = pp_index;
  3531.     pp_module = &pp_context->pp_modules[pp_index];
  3532.    
  3533.     if (pp_module->initialize)
  3534.         va_status = pp_module->initialize(ctx, pp_context,
  3535.                                           src_surface,
  3536.                                           src_rect,
  3537.                                           dst_surface,
  3538.                                           dst_rect,
  3539.                                           filter_param);
  3540.     else
  3541.        va_status = VA_STATUS_ERROR_UNIMPLEMENTED;
  3542.  
  3543.     return va_status;
  3544. }
  3545.  
  3546. static VAStatus
  3547. ironlake_post_processing(
  3548.     VADriverContextP   ctx,
  3549.     struct i965_post_processing_context *pp_context,
  3550.     const struct i965_surface *src_surface,
  3551.     const VARectangle *src_rect,
  3552.     struct i965_surface *dst_surface,
  3553.     const VARectangle *dst_rect,
  3554.     int                pp_index,
  3555.     void *filter_param
  3556. )
  3557. {
  3558.     VAStatus va_status;
  3559.  
  3560.     va_status = ironlake_pp_initialize(ctx, pp_context,
  3561.                                        src_surface,
  3562.                                        src_rect,
  3563.                                        dst_surface,
  3564.                                        dst_rect,
  3565.                                        pp_index,
  3566.                                        filter_param);
  3567.  
  3568.     if (va_status == VA_STATUS_SUCCESS) {
  3569.         ironlake_pp_states_setup(ctx, pp_context);
  3570.         ironlake_pp_pipeline_setup(ctx, pp_context);
  3571.     }
  3572.  
  3573.     return va_status;
  3574. }
  3575.  
  3576. static VAStatus
  3577. gen6_pp_initialize(
  3578.     VADriverContextP   ctx,
  3579.     struct i965_post_processing_context *pp_context,
  3580.     const struct i965_surface *src_surface,
  3581.     const VARectangle *src_rect,
  3582.     struct i965_surface *dst_surface,
  3583.     const VARectangle *dst_rect,
  3584.     int                pp_index,
  3585.     void * filter_param
  3586. )
  3587. {
  3588.     VAStatus va_status;
  3589.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  3590.     struct pp_module *pp_module;
  3591.     dri_bo *bo;
  3592.     int static_param_size, inline_param_size;
  3593.  
  3594.     dri_bo_unreference(pp_context->surface_state_binding_table.bo);
  3595.     bo = dri_bo_alloc(i965->intel.bufmgr,
  3596.                       "surface state & binding table",
  3597.                       (SURFACE_STATE_PADDED_SIZE + sizeof(unsigned int)) * MAX_PP_SURFACES,
  3598.                       4096);
  3599.     assert(bo);
  3600.     pp_context->surface_state_binding_table.bo = bo;
  3601.  
  3602.     dri_bo_unreference(pp_context->curbe.bo);
  3603.     bo = dri_bo_alloc(i965->intel.bufmgr,
  3604.                       "constant buffer",
  3605.                       4096,
  3606.                       4096);
  3607.     assert(bo);
  3608.     pp_context->curbe.bo = bo;
  3609.  
  3610.     dri_bo_unreference(pp_context->idrt.bo);
  3611.     bo = dri_bo_alloc(i965->intel.bufmgr,
  3612.                       "interface discriptor",
  3613.                       sizeof(struct gen6_interface_descriptor_data),
  3614.                       4096);
  3615.     assert(bo);
  3616.     pp_context->idrt.bo = bo;
  3617.     pp_context->idrt.num_interface_descriptors = 0;
  3618.  
  3619.     dri_bo_unreference(pp_context->sampler_state_table.bo);
  3620.     bo = dri_bo_alloc(i965->intel.bufmgr,
  3621.                       "sampler state table",
  3622.                       4096,
  3623.                       4096);
  3624.     assert(bo);
  3625.     dri_bo_map(bo, True);
  3626.     memset(bo->virtual, 0, bo->size);
  3627.     dri_bo_unmap(bo);
  3628.     pp_context->sampler_state_table.bo = bo;
  3629.  
  3630.     dri_bo_unreference(pp_context->sampler_state_table.bo_8x8);
  3631.     bo = dri_bo_alloc(i965->intel.bufmgr,
  3632.                       "sampler 8x8 state ",
  3633.                       4096,
  3634.                       4096);
  3635.     assert(bo);
  3636.     pp_context->sampler_state_table.bo_8x8 = bo;
  3637.  
  3638.     dri_bo_unreference(pp_context->sampler_state_table.bo_8x8_uv);
  3639.     bo = dri_bo_alloc(i965->intel.bufmgr,
  3640.                       "sampler 8x8 state ",
  3641.                       4096,
  3642.                       4096);
  3643.     assert(bo);
  3644.     pp_context->sampler_state_table.bo_8x8_uv = bo;
  3645.  
  3646.     dri_bo_unreference(pp_context->vfe_state.bo);
  3647.     bo = dri_bo_alloc(i965->intel.bufmgr,
  3648.                       "vfe state",
  3649.                       sizeof(struct i965_vfe_state),
  3650.                       4096);
  3651.     assert(bo);
  3652.     pp_context->vfe_state.bo = bo;
  3653.    
  3654.     if (IS_GEN7(i965->intel.device_id)) {
  3655.         static_param_size = sizeof(struct gen7_pp_static_parameter);
  3656.         inline_param_size = sizeof(struct gen7_pp_inline_parameter);
  3657.     } else {
  3658.         static_param_size = sizeof(struct pp_static_parameter);
  3659.         inline_param_size = sizeof(struct pp_inline_parameter);
  3660.     }
  3661.  
  3662.     memset(pp_context->pp_static_parameter, 0, static_param_size);
  3663.     memset(pp_context->pp_inline_parameter, 0, inline_param_size);
  3664.  
  3665.     assert(pp_index >= PP_NULL && pp_index < NUM_PP_MODULES);
  3666.     pp_context->current_pp = pp_index;
  3667.     pp_module = &pp_context->pp_modules[pp_index];
  3668.    
  3669.     if (pp_module->initialize)
  3670.         va_status = pp_module->initialize(ctx, pp_context,
  3671.                                           src_surface,
  3672.                                           src_rect,
  3673.                                           dst_surface,
  3674.                                           dst_rect,
  3675.                                           filter_param);
  3676.     else
  3677.         va_status = VA_STATUS_ERROR_UNIMPLEMENTED;
  3678.  
  3679.     calculate_boundary_block_mask(pp_context, dst_rect);
  3680.  
  3681.     return va_status;
  3682. }
  3683.  
  3684. static void
  3685. gen6_pp_interface_descriptor_table(VADriverContextP   ctx,
  3686.                                    struct i965_post_processing_context *pp_context)
  3687. {
  3688.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  3689.     struct gen6_interface_descriptor_data *desc;
  3690.     dri_bo *bo;
  3691.     int pp_index = pp_context->current_pp;
  3692.  
  3693.     bo = pp_context->idrt.bo;
  3694.     dri_bo_map(bo, True);
  3695.     assert(bo->virtual);
  3696.     desc = bo->virtual;
  3697.     memset(desc, 0, sizeof(*desc));
  3698.     desc->desc0.kernel_start_pointer =
  3699.         pp_context->pp_modules[pp_index].kernel.bo->offset >> 6; /* reloc */
  3700.     desc->desc1.single_program_flow = 1;
  3701.     desc->desc1.floating_point_mode = FLOATING_POINT_IEEE_754;
  3702.     desc->desc2.sampler_count = 1;      /* 1 - 4 samplers used */
  3703.     desc->desc2.sampler_state_pointer =
  3704.         pp_context->sampler_state_table.bo->offset >> 5;
  3705.     desc->desc3.binding_table_entry_count = 0;
  3706.     desc->desc3.binding_table_pointer = (BINDING_TABLE_OFFSET >> 5);
  3707.     desc->desc4.constant_urb_entry_read_offset = 0;
  3708.    
  3709.     if (IS_GEN7(i965->intel.device_id))
  3710.         desc->desc4.constant_urb_entry_read_length = 6; /* grf 1-6 */
  3711.     else
  3712.         desc->desc4.constant_urb_entry_read_length = 4; /* grf 1-4 */
  3713.  
  3714.     dri_bo_emit_reloc(bo,
  3715.                       I915_GEM_DOMAIN_INSTRUCTION, 0,
  3716.                       0,
  3717.                       offsetof(struct gen6_interface_descriptor_data, desc0),
  3718.                       pp_context->pp_modules[pp_index].kernel.bo);
  3719.  
  3720.     dri_bo_emit_reloc(bo,
  3721.                       I915_GEM_DOMAIN_INSTRUCTION, 0,
  3722.                       desc->desc2.sampler_count << 2,
  3723.                       offsetof(struct gen6_interface_descriptor_data, desc2),
  3724.                       pp_context->sampler_state_table.bo);
  3725.  
  3726.     dri_bo_unmap(bo);
  3727.     pp_context->idrt.num_interface_descriptors++;
  3728. }
  3729.  
  3730. static void
  3731. gen6_pp_upload_constants(VADriverContextP ctx,
  3732.                          struct i965_post_processing_context *pp_context)
  3733. {
  3734.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  3735.     unsigned char *constant_buffer;
  3736.     int param_size;
  3737.  
  3738.     assert(sizeof(struct pp_static_parameter) == 128);
  3739.     assert(sizeof(struct gen7_pp_static_parameter) == 192);
  3740.  
  3741.     if (IS_GEN7(i965->intel.device_id))
  3742.         param_size = sizeof(struct gen7_pp_static_parameter);
  3743.     else
  3744.         param_size = sizeof(struct pp_static_parameter);
  3745.  
  3746.     dri_bo_map(pp_context->curbe.bo, 1);
  3747.     assert(pp_context->curbe.bo->virtual);
  3748.     constant_buffer = pp_context->curbe.bo->virtual;
  3749.     memcpy(constant_buffer, pp_context->pp_static_parameter, param_size);
  3750.     dri_bo_unmap(pp_context->curbe.bo);
  3751. }
  3752.  
  3753. static void
  3754. gen6_pp_states_setup(VADriverContextP ctx,
  3755.                      struct i965_post_processing_context *pp_context)
  3756. {
  3757.     gen6_pp_interface_descriptor_table(ctx, pp_context);
  3758.     gen6_pp_upload_constants(ctx, pp_context);
  3759. }
  3760.  
  3761. static void
  3762. gen6_pp_pipeline_select(VADriverContextP ctx,
  3763.                         struct i965_post_processing_context *pp_context)
  3764. {
  3765.     struct intel_batchbuffer *batch = pp_context->batch;
  3766.  
  3767.     BEGIN_BATCH(batch, 1);
  3768.     OUT_BATCH(batch, CMD_PIPELINE_SELECT | PIPELINE_SELECT_MEDIA);
  3769.     ADVANCE_BATCH(batch);
  3770. }
  3771.  
  3772. static void
  3773. gen6_pp_state_base_address(VADriverContextP ctx,
  3774.                            struct i965_post_processing_context *pp_context)
  3775. {
  3776.     struct intel_batchbuffer *batch = pp_context->batch;
  3777.  
  3778.     BEGIN_BATCH(batch, 10);
  3779.     OUT_BATCH(batch, CMD_STATE_BASE_ADDRESS | (10 - 2));
  3780.     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
  3781.     OUT_RELOC(batch, pp_context->surface_state_binding_table.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, BASE_ADDRESS_MODIFY); /* Surface state base address */
  3782.     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
  3783.     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
  3784.     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
  3785.     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
  3786.     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
  3787.     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
  3788.     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
  3789.     ADVANCE_BATCH(batch);
  3790. }
  3791.  
  3792. static void
  3793. gen6_pp_vfe_state(VADriverContextP ctx,
  3794.                   struct i965_post_processing_context *pp_context)
  3795. {
  3796.     struct intel_batchbuffer *batch = pp_context->batch;
  3797.  
  3798.     BEGIN_BATCH(batch, 8);
  3799.     OUT_BATCH(batch, CMD_MEDIA_VFE_STATE | (8 - 2));
  3800.     OUT_BATCH(batch, 0);
  3801.     OUT_BATCH(batch,
  3802.               (pp_context->urb.num_vfe_entries - 1) << 16 |
  3803.               pp_context->urb.num_vfe_entries << 8);
  3804.     OUT_BATCH(batch, 0);
  3805.     OUT_BATCH(batch,
  3806.               (pp_context->urb.size_vfe_entry * 2) << 16 |  /* URB Entry Allocation Size, in 256 bits unit */
  3807.               (pp_context->urb.size_cs_entry * pp_context->urb.num_cs_entries * 2)); /* CURBE Allocation Size, in 256 bits unit */
  3808.     OUT_BATCH(batch, 0);
  3809.     OUT_BATCH(batch, 0);
  3810.     OUT_BATCH(batch, 0);
  3811.     ADVANCE_BATCH(batch);
  3812. }
  3813.  
  3814. static void
  3815. gen6_pp_curbe_load(VADriverContextP ctx,
  3816.                    struct i965_post_processing_context *pp_context)
  3817. {
  3818.     struct intel_batchbuffer *batch = pp_context->batch;
  3819.  
  3820.     assert(pp_context->urb.size_cs_entry * pp_context->urb.num_cs_entries * 2 * 32 <= pp_context->curbe.bo->size);
  3821.  
  3822.     BEGIN_BATCH(batch, 4);
  3823.     OUT_BATCH(batch, CMD_MEDIA_CURBE_LOAD | (4 - 2));
  3824.     OUT_BATCH(batch, 0);
  3825.     OUT_BATCH(batch,
  3826.               pp_context->urb.size_cs_entry * pp_context->urb.num_cs_entries * 2 * 32);
  3827.     OUT_RELOC(batch,
  3828.               pp_context->curbe.bo,
  3829.               I915_GEM_DOMAIN_INSTRUCTION, 0,
  3830.               0);
  3831.     ADVANCE_BATCH(batch);
  3832. }
  3833.  
  3834. static void
  3835. gen6_interface_descriptor_load(VADriverContextP ctx,
  3836.                                struct i965_post_processing_context *pp_context)
  3837. {
  3838.     struct intel_batchbuffer *batch = pp_context->batch;
  3839.  
  3840.     BEGIN_BATCH(batch, 4);
  3841.     OUT_BATCH(batch, CMD_MEDIA_INTERFACE_DESCRIPTOR_LOAD | (4 - 2));
  3842.     OUT_BATCH(batch, 0);
  3843.     OUT_BATCH(batch,
  3844.               pp_context->idrt.num_interface_descriptors * sizeof(struct gen6_interface_descriptor_data));
  3845.     OUT_RELOC(batch,
  3846.               pp_context->idrt.bo,
  3847.               I915_GEM_DOMAIN_INSTRUCTION, 0,
  3848.               0);
  3849.     ADVANCE_BATCH(batch);
  3850. }
  3851.  
  3852. static void update_block_mask_parameter(struct i965_post_processing_context *pp_context, int x, int y, int x_steps, int y_steps)
  3853. {
  3854.     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
  3855.  
  3856.     pp_inline_parameter->grf5.block_vertical_mask = 0xff;
  3857.     pp_inline_parameter->grf6.block_vertical_mask_bottom = pp_context->block_vertical_mask_bottom;
  3858.     // for the first block, it always on the left edge. the second block will reload horizontal_mask from grf6.block_horizontal_mask_middle
  3859.     pp_inline_parameter->grf5.block_horizontal_mask = pp_context->block_horizontal_mask_left;
  3860.     pp_inline_parameter->grf6.block_horizontal_mask_middle = 0xffff;
  3861.     pp_inline_parameter->grf6.block_horizontal_mask_right = pp_context->block_horizontal_mask_right;
  3862.  
  3863.     /* 1 x N */
  3864.     if (x_steps == 1) {
  3865.         if (y == y_steps-1) {
  3866.             pp_inline_parameter->grf5.block_vertical_mask = pp_context->block_vertical_mask_bottom;
  3867.         }
  3868.         else {
  3869.             pp_inline_parameter->grf6.block_vertical_mask_bottom = 0xff;
  3870.         }
  3871.     }
  3872.  
  3873.     /* M x 1 */
  3874.     if (y_steps == 1) {
  3875.         if (x == 0) { // all blocks in this group are on the left edge
  3876.             pp_inline_parameter->grf6.block_horizontal_mask_middle = pp_context->block_horizontal_mask_left;
  3877.             pp_inline_parameter->grf6.block_horizontal_mask_right = pp_context->block_horizontal_mask_left;
  3878.         }
  3879.         else if (x == x_steps-1) {
  3880.             pp_inline_parameter->grf5.block_horizontal_mask = pp_context->block_horizontal_mask_right;
  3881.             pp_inline_parameter->grf6.block_horizontal_mask_middle = pp_context->block_horizontal_mask_right;
  3882.         }
  3883.         else {
  3884.             pp_inline_parameter->grf5.block_horizontal_mask = 0xffff;
  3885.             pp_inline_parameter->grf6.block_horizontal_mask_middle = 0xffff;
  3886.             pp_inline_parameter->grf6.block_horizontal_mask_right = 0xffff;
  3887.         }
  3888.     }
  3889.  
  3890. }
  3891.  
  3892. static void
  3893. gen6_pp_object_walker(VADriverContextP ctx,
  3894.                       struct i965_post_processing_context *pp_context)
  3895. {
  3896.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  3897.     struct intel_batchbuffer *batch = pp_context->batch;
  3898.     int x, x_steps, y, y_steps;
  3899.     int param_size, command_length_in_dws;
  3900.     dri_bo *command_buffer;
  3901.     unsigned int *command_ptr;
  3902.  
  3903.     if (IS_GEN7(i965->intel.device_id))
  3904.         param_size = sizeof(struct gen7_pp_inline_parameter);
  3905.     else
  3906.         param_size = sizeof(struct pp_inline_parameter);
  3907.  
  3908.     x_steps = pp_context->pp_x_steps(&pp_context->private_context);
  3909.     y_steps = pp_context->pp_y_steps(&pp_context->private_context);
  3910.     command_length_in_dws = 6 + (param_size >> 2);
  3911.     command_buffer = dri_bo_alloc(i965->intel.bufmgr,
  3912.                                   "command objects buffer",
  3913.                                   command_length_in_dws * 4 * x_steps * y_steps + 8,
  3914.                                   4096);
  3915.  
  3916.     dri_bo_map(command_buffer, 1);
  3917.     command_ptr = command_buffer->virtual;
  3918.  
  3919.     for (y = 0; y < y_steps; y++) {
  3920.         for (x = 0; x < x_steps; x++) {
  3921.             if (!pp_context->pp_set_block_parameter(pp_context, x, y)) {
  3922.                 // some common block parameter update goes here, apply to all pp functions
  3923.                 if (IS_GEN6(i965->intel.device_id))
  3924.                     update_block_mask_parameter (pp_context, x, y, x_steps, y_steps);
  3925.                
  3926.                 *command_ptr++ = (CMD_MEDIA_OBJECT | (command_length_in_dws - 2));
  3927.                 *command_ptr++ = 0;
  3928.                 *command_ptr++ = 0;
  3929.                 *command_ptr++ = 0;
  3930.                 *command_ptr++ = 0;
  3931.                 *command_ptr++ = 0;
  3932.                 memcpy(command_ptr, pp_context->pp_inline_parameter, param_size);
  3933.                 command_ptr += (param_size >> 2);
  3934.             }
  3935.         }
  3936.     }
  3937.  
  3938.     if (command_length_in_dws * x_steps * y_steps % 2 == 0)
  3939.         *command_ptr++ = 0;
  3940.  
  3941.     *command_ptr = MI_BATCH_BUFFER_END;
  3942.  
  3943.     dri_bo_unmap(command_buffer);
  3944.  
  3945.     BEGIN_BATCH(batch, 2);
  3946.     OUT_BATCH(batch, MI_BATCH_BUFFER_START | (2 << 6));
  3947.     OUT_RELOC(batch, command_buffer,
  3948.               I915_GEM_DOMAIN_COMMAND, 0,
  3949.               0);
  3950.     ADVANCE_BATCH(batch);
  3951.    
  3952.     dri_bo_unreference(command_buffer);
  3953.  
  3954.     /* Have to execute the batch buffer here becuase MI_BATCH_BUFFER_END
  3955.      * will cause control to pass back to ring buffer
  3956.      */
  3957.     intel_batchbuffer_end_atomic(batch);
  3958.     intel_batchbuffer_flush(batch);
  3959.     intel_batchbuffer_start_atomic(batch, 0x1000);
  3960. }
  3961. static void
  3962. gen6_pp_pipeline_setup(VADriverContextP ctx,
  3963.                        struct i965_post_processing_context *pp_context)
  3964. {
  3965.     struct intel_batchbuffer *batch = pp_context->batch;
  3966.  
  3967.     intel_batchbuffer_start_atomic(batch, 0x1000);
  3968.     intel_batchbuffer_emit_mi_flush(batch);
  3969.     gen6_pp_pipeline_select(ctx, pp_context);
  3970.     gen6_pp_state_base_address(ctx, pp_context);
  3971.     gen6_pp_vfe_state(ctx, pp_context);
  3972.     gen6_pp_curbe_load(ctx, pp_context);
  3973.     gen6_interface_descriptor_load(ctx, pp_context);
  3974.     gen6_pp_vfe_state(ctx, pp_context);
  3975.     gen6_pp_object_walker(ctx, pp_context);
  3976.     intel_batchbuffer_end_atomic(batch);
  3977. }
  3978.  
  3979. static VAStatus
  3980. gen6_post_processing(
  3981.     VADriverContextP   ctx,
  3982.     struct i965_post_processing_context *pp_context,
  3983.     const struct i965_surface *src_surface,
  3984.     const VARectangle *src_rect,
  3985.     struct i965_surface *dst_surface,
  3986.     const VARectangle *dst_rect,
  3987.     int                pp_index,
  3988.     void *filter_param
  3989. )
  3990. {
  3991.     VAStatus va_status;
  3992.    
  3993.     va_status = gen6_pp_initialize(ctx, pp_context,
  3994.                                    src_surface,
  3995.                                    src_rect,
  3996.                                    dst_surface,
  3997.                                    dst_rect,
  3998.                                    pp_index,
  3999.                                    filter_param);
  4000.  
  4001.     if (va_status == VA_STATUS_SUCCESS) {
  4002.         gen6_pp_states_setup(ctx, pp_context);
  4003.         gen6_pp_pipeline_setup(ctx, pp_context);
  4004.     }
  4005.  
  4006.     return va_status;
  4007. }
  4008.  
  4009. static VAStatus
  4010. gen75_post_processing(
  4011.     VADriverContextP   ctx,
  4012.     struct i965_post_processing_context *pp_context,
  4013.     const struct i965_surface *src_surface,
  4014.     const VARectangle *src_rect,
  4015.     struct i965_surface *dst_surface,
  4016.     const VARectangle *dst_rect,
  4017.     int                pp_index,
  4018.     void *filter_param
  4019. )
  4020. {
  4021.    VAStatus va_status;
  4022.    struct intel_vebox_context * vebox_ctx = pp_context->pp_vebox_context;
  4023.  
  4024.     assert(pp_index == PP_NV12_DNDI);
  4025.    
  4026.     vebox_ctx->filters_mask    = VPP_DNDI_DI;
  4027.     vebox_ctx->surface_input   = src_surface->id;
  4028.     vebox_ctx->surface_output  = dst_surface->id;
  4029.  
  4030.     va_status = gen75_vebox_process_picture(ctx, vebox_ctx);
  4031.      
  4032.     return va_status;
  4033. }
  4034.  
  4035. static VAStatus
  4036. i965_post_processing_internal(
  4037.     VADriverContextP   ctx,
  4038.     struct i965_post_processing_context *pp_context,
  4039.     const struct i965_surface *src_surface,
  4040.     const VARectangle *src_rect,
  4041.     struct i965_surface *dst_surface,
  4042.     const VARectangle *dst_rect,
  4043.     int                pp_index,
  4044.     void *filter_param
  4045. )
  4046. {
  4047.     VAStatus va_status;
  4048.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  4049.  
  4050.     if(IS_HASWELL(i965->intel.device_id) &&
  4051.         pp_index == PP_NV12_DNDI){
  4052.         va_status = gen75_post_processing(ctx, pp_context, src_surface, src_rect, dst_surface, dst_rect, pp_index, filter_param);
  4053.     }else if (IS_GEN6(i965->intel.device_id) ||
  4054.               IS_GEN7(i965->intel.device_id)){
  4055.         va_status = gen6_post_processing(ctx, pp_context, src_surface, src_rect, dst_surface, dst_rect, pp_index, filter_param);
  4056.     }else{
  4057.         va_status = ironlake_post_processing(ctx, pp_context, src_surface, src_rect, dst_surface, dst_rect, pp_index, filter_param);
  4058.     }
  4059.  
  4060.     return va_status;
  4061. }
  4062.  
  4063. VAStatus
  4064. i965_DestroySurfaces(VADriverContextP ctx,
  4065.                      VASurfaceID *surface_list,
  4066.                      int num_surfaces);
  4067. VAStatus
  4068. i965_CreateSurfaces(VADriverContextP ctx,
  4069.                     int width,
  4070.                     int height,
  4071.                     int format,
  4072.                     int num_surfaces,
  4073.                     VASurfaceID *surfaces);
  4074.  
  4075. static void
  4076. rgb_to_yuv(unsigned int argb,
  4077.            unsigned char *y,
  4078.            unsigned char *u,
  4079.            unsigned char *v,
  4080.            unsigned char *a)
  4081. {
  4082.     int r = ((argb >> 16) & 0xff);
  4083.     int g = ((argb >> 8) & 0xff);
  4084.     int b = ((argb >> 0) & 0xff);
  4085.    
  4086.     *y = (257 * r + 504 * g + 98 * b) / 1000 + 16;
  4087.     *v = (439 * r - 368 * g - 71 * b) / 1000 + 128;
  4088.     *u = (-148 * r - 291 * g + 439 * b) / 1000 + 128;
  4089.     *a = ((argb >> 24) & 0xff);
  4090. }
  4091.  
  4092. static void
  4093. i965_vpp_clear_surface(VADriverContextP ctx,
  4094.                        struct i965_post_processing_context *pp_context,
  4095.                        VASurfaceID surface,
  4096.                        unsigned int color)
  4097. {
  4098.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  4099.     struct intel_batchbuffer *batch = pp_context->batch;
  4100.     struct object_surface *obj_surface = SURFACE(surface);
  4101.     unsigned int blt_cmd, br13;
  4102.     unsigned int tiling = 0, swizzle = 0;
  4103.     int pitch;
  4104.     unsigned char y, u, v, a = 0;
  4105.  
  4106.     /* Currently only support NV12 surface */
  4107.     if (!obj_surface || obj_surface->fourcc != VA_FOURCC('N', 'V', '1', '2'))
  4108.         return;
  4109.  
  4110.     rgb_to_yuv(color, &y, &u, &v, &a);
  4111.  
  4112.     if (a == 0)
  4113.         return;
  4114.  
  4115.     dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
  4116.     blt_cmd = XY_COLOR_BLT_CMD;
  4117.     pitch = obj_surface->width;
  4118.  
  4119.     if (tiling != I915_TILING_NONE) {
  4120.         blt_cmd |= XY_COLOR_BLT_DST_TILED;
  4121.         pitch >>= 2;
  4122.     }
  4123.  
  4124.     br13 = 0xf0 << 16;
  4125.     br13 |= BR13_8;
  4126.     br13 |= pitch;
  4127.  
  4128.     if (IS_GEN6(i965->intel.device_id) ||
  4129.         IS_GEN7(i965->intel.device_id)) {
  4130.         intel_batchbuffer_start_atomic_blt(batch, 48);
  4131.         BEGIN_BLT_BATCH(batch, 12);
  4132.     } else {
  4133.         intel_batchbuffer_start_atomic(batch, 48);
  4134.         BEGIN_BATCH(batch, 12);
  4135.     }
  4136.  
  4137.     OUT_BATCH(batch, blt_cmd);
  4138.     OUT_BATCH(batch, br13);
  4139.     OUT_BATCH(batch,
  4140.               0 << 16 |
  4141.               0);
  4142.     OUT_BATCH(batch,
  4143.               obj_surface->height << 16 |
  4144.               obj_surface->width);
  4145.     OUT_RELOC(batch, obj_surface->bo,
  4146.               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
  4147.               0);
  4148.     OUT_BATCH(batch, y);
  4149.  
  4150.     br13 = 0xf0 << 16;
  4151.     br13 |= BR13_565;
  4152.     br13 |= pitch;
  4153.  
  4154.     OUT_BATCH(batch, blt_cmd);
  4155.     OUT_BATCH(batch, br13);
  4156.     OUT_BATCH(batch,
  4157.               0 << 16 |
  4158.               0);
  4159.     OUT_BATCH(batch,
  4160.               obj_surface->height / 2 << 16 |
  4161.               obj_surface->width / 2);
  4162.     OUT_RELOC(batch, obj_surface->bo,
  4163.               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
  4164.               obj_surface->width * obj_surface->y_cb_offset);
  4165.     OUT_BATCH(batch, v << 8 | u);
  4166.  
  4167.     ADVANCE_BATCH(batch);
  4168.     intel_batchbuffer_end_atomic(batch);
  4169. }
  4170.  
  4171. VASurfaceID
  4172. i965_post_processing(
  4173.     VADriverContextP   ctx,
  4174.     VASurfaceID        surface,
  4175.     const VARectangle *src_rect,
  4176.     const VARectangle *dst_rect,
  4177.     unsigned int       flags,
  4178.     int               *has_done_scaling  
  4179. )
  4180. {
  4181.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  4182.     VASurfaceID in_surface_id = surface;
  4183.     VASurfaceID out_surface_id = VA_INVALID_ID;
  4184.  
  4185.     if (HAS_PP(i965)) {
  4186.         /* Currently only support post processing for NV12 surface */
  4187.         if (i965->render_state.interleaved_uv) {
  4188.             struct object_surface *obj_surface;
  4189.             VAStatus status;
  4190.             struct i965_surface src_surface;
  4191.             struct i965_surface dst_surface;
  4192.  
  4193.             if (flags & I965_PP_FLAG_DEINTERLACING) {
  4194.                 obj_surface = SURFACE(in_surface_id);
  4195.                 status = i965_CreateSurfaces(ctx,
  4196.                                              obj_surface->orig_width,
  4197.                                              obj_surface->orig_height,
  4198.                                              VA_RT_FORMAT_YUV420,
  4199.                                              1,
  4200.                                              &out_surface_id);
  4201.                 assert(status == VA_STATUS_SUCCESS);
  4202.                 obj_surface = SURFACE(out_surface_id);
  4203.                 i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420);
  4204.  
  4205.                 i965_vpp_clear_surface(ctx, i965->pp_context, out_surface_id, 0);
  4206.  
  4207.                 src_surface.id = in_surface_id;
  4208.                 src_surface.type = I965_SURFACE_TYPE_SURFACE;
  4209.                 src_surface.flags = (flags & I965_PP_FLAG_TOP_FIELD) ?
  4210.                     I965_SURFACE_FLAG_TOP_FIELD_FIRST : I965_SURFACE_FLAG_BOTTOM_FIELD_FIRST;
  4211.                 dst_surface.id = out_surface_id;
  4212.                 dst_surface.type = I965_SURFACE_TYPE_SURFACE;
  4213.                 dst_surface.flags = I965_SURFACE_FLAG_FRAME;
  4214.  
  4215.                 i965_post_processing_internal(ctx, i965->pp_context,
  4216.                                               &src_surface,
  4217.                                               src_rect,
  4218.                                               &dst_surface,
  4219.                                               dst_rect,
  4220.                                               PP_NV12_DNDI,
  4221.                                               NULL);
  4222.                printf("Deinterlace is executed here\n");
  4223.             }
  4224.  
  4225.             if (flags & I965_PP_FLAG_AVS) {
  4226.                 struct i965_render_state *render_state = &i965->render_state;
  4227.                 struct intel_region *dest_region = render_state->draw_region;
  4228.  
  4229.                 if (out_surface_id != VA_INVALID_ID)
  4230.                     in_surface_id = out_surface_id;
  4231.  
  4232.                 status = i965_CreateSurfaces(ctx,
  4233.                                              dest_region->width,
  4234.                                              dest_region->height,
  4235.                                              VA_RT_FORMAT_YUV420,
  4236.                                              1,
  4237.                                              &out_surface_id);
  4238.                 assert(status == VA_STATUS_SUCCESS);
  4239.                 obj_surface = SURFACE(out_surface_id);
  4240.                 i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420);
  4241.                 i965_vpp_clear_surface(ctx, i965->pp_context, out_surface_id, 0);
  4242.  
  4243.                 src_surface.id = in_surface_id;
  4244.                 src_surface.type = I965_SURFACE_TYPE_SURFACE;
  4245.                 src_surface.flags = I965_SURFACE_FLAG_FRAME;
  4246.                 dst_surface.id = out_surface_id;
  4247.                 dst_surface.type = I965_SURFACE_TYPE_SURFACE;
  4248.                 dst_surface.flags = I965_SURFACE_FLAG_FRAME;
  4249.  
  4250.                 i965_post_processing_internal(ctx, i965->pp_context,
  4251.                                               &src_surface,
  4252.                                               src_rect,
  4253.                                               &dst_surface,
  4254.                                               dst_rect,
  4255.                                               PP_NV12_AVS,
  4256.                                               NULL);
  4257.  
  4258.                 if (in_surface_id != surface)
  4259.                     i965_DestroySurfaces(ctx, &in_surface_id, 1);
  4260.                
  4261.                 *has_done_scaling = 1;
  4262.             }
  4263.         }
  4264.     }
  4265.  
  4266.     return out_surface_id;
  4267. }      
  4268.  
  4269. static VAStatus
  4270. i965_image_pl3_processing(VADriverContextP ctx,
  4271.                           const struct i965_surface *src_surface,
  4272.                           const VARectangle *src_rect,
  4273.                           struct i965_surface *dst_surface,
  4274.                           const VARectangle *dst_rect)
  4275. {
  4276.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  4277.     struct i965_post_processing_context *pp_context = i965->pp_context;
  4278.     int fourcc = pp_get_surface_fourcc(ctx, dst_surface);
  4279.  
  4280.     if (fourcc == VA_FOURCC('N', 'V', '1', '2')) {
  4281.         i965_post_processing_internal(ctx, i965->pp_context,
  4282.                                       src_surface,
  4283.                                       src_rect,
  4284.                                       dst_surface,
  4285.                                       dst_rect,
  4286.                                       PP_PL3_LOAD_SAVE_N12,
  4287.                                       NULL);
  4288.     } else if (fourcc == VA_FOURCC('I', 'M', 'C', '1') ||
  4289.                fourcc == VA_FOURCC('I', 'M', 'C', '3') ||
  4290.                fourcc == VA_FOURCC('Y', 'V', '1', '2') ||
  4291.                fourcc == VA_FOURCC('I', '4', '2', '0') ) {
  4292.         i965_post_processing_internal(ctx, i965->pp_context,
  4293.                                       src_surface,
  4294.                                       src_rect,
  4295.                                       dst_surface,
  4296.                                       dst_rect,
  4297.                                       PP_PL3_LOAD_SAVE_PL3,
  4298.                                       NULL);
  4299.     } else if (fourcc == VA_FOURCC('Y', 'U', 'Y', '2') ||
  4300.                fourcc == VA_FOURCC('U', 'Y', 'V', 'Y')) {
  4301.         i965_post_processing_internal(ctx, i965->pp_context,
  4302.                                       src_surface,
  4303.                                       src_rect,
  4304.                                       dst_surface,
  4305.                                       dst_rect,
  4306.                                       PP_PL3_LOAD_SAVE_PA,
  4307.                                       NULL);
  4308.  
  4309.     }
  4310.     else {
  4311.         assert(0);
  4312.     }
  4313.  
  4314.     intel_batchbuffer_flush(pp_context->batch);
  4315.  
  4316.     return VA_STATUS_SUCCESS;
  4317. }
  4318.  
  4319. static VAStatus
  4320. i965_image_pl2_processing(VADriverContextP ctx,
  4321.                           const struct i965_surface *src_surface,
  4322.                           const VARectangle *src_rect,
  4323.                           struct i965_surface *dst_surface,
  4324.                           const VARectangle *dst_rect)
  4325. {
  4326.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  4327.     struct i965_post_processing_context *pp_context = i965->pp_context;
  4328.     int fourcc = pp_get_surface_fourcc(ctx, dst_surface);
  4329.  
  4330.     if (fourcc == VA_FOURCC('N', 'V', '1', '2')) {
  4331.         i965_post_processing_internal(ctx, i965->pp_context,
  4332.                                       src_surface,
  4333.                                       src_rect,
  4334.                                       dst_surface,
  4335.                                       dst_rect,
  4336.                                       PP_NV12_LOAD_SAVE_N12,
  4337.                                       NULL);
  4338.     } else if (fourcc == VA_FOURCC('I', 'M', 'C', '1') ||
  4339.                fourcc == VA_FOURCC('I', 'M', 'C', '3') ||
  4340.                fourcc == VA_FOURCC('Y', 'V', '1', '2') ||
  4341.                fourcc == VA_FOURCC('I', '4', '2', '0') ) {
  4342.         i965_post_processing_internal(ctx, i965->pp_context,
  4343.                                       src_surface,
  4344.                                       src_rect,
  4345.                                       dst_surface,
  4346.                                       dst_rect,
  4347.                                       PP_NV12_LOAD_SAVE_PL3,
  4348.                                       NULL);
  4349.     } else if (fourcc == VA_FOURCC('Y', 'U', 'Y', '2') ||
  4350.                fourcc == VA_FOURCC('U', 'Y', 'V', 'Y')) {
  4351.         i965_post_processing_internal(ctx, i965->pp_context,
  4352.                                       src_surface,
  4353.                                       src_rect,
  4354.                                       dst_surface,
  4355.                                       dst_rect,
  4356.                                       PP_NV12_LOAD_SAVE_PA,
  4357.                                       NULL);
  4358.     }
  4359.  
  4360.     intel_batchbuffer_flush(pp_context->batch);
  4361.  
  4362.     return VA_STATUS_SUCCESS;
  4363. }
  4364.  
  4365. static VAStatus
  4366. i965_image_pl1_processing(VADriverContextP ctx,
  4367.                           const struct i965_surface *src_surface,
  4368.                           const VARectangle *src_rect,
  4369.                           struct i965_surface *dst_surface,
  4370.                           const VARectangle *dst_rect)
  4371. {
  4372.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  4373.     struct i965_post_processing_context *pp_context = i965->pp_context;
  4374.     int fourcc = pp_get_surface_fourcc(ctx, dst_surface);
  4375.  
  4376.     if (fourcc == VA_FOURCC('N', 'V', '1', '2')) {
  4377.         i965_post_processing_internal(ctx, i965->pp_context,
  4378.                                       src_surface,
  4379.                                       src_rect,
  4380.                                       dst_surface,
  4381.                                       dst_rect,
  4382.                                       PP_PA_LOAD_SAVE_NV12,
  4383.                                       NULL);
  4384.     }
  4385.     else {
  4386.         return VA_STATUS_ERROR_UNKNOWN;
  4387.     }
  4388.  
  4389.     intel_batchbuffer_flush(pp_context->batch);
  4390.  
  4391.     return VA_STATUS_SUCCESS;
  4392. }
  4393.  
  4394. VAStatus
  4395. i965_image_processing(VADriverContextP ctx,
  4396.                       const struct i965_surface *src_surface,
  4397.                       const VARectangle *src_rect,
  4398.                       struct i965_surface *dst_surface,
  4399.                       const VARectangle *dst_rect)
  4400. {
  4401.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  4402.     VAStatus status = VA_STATUS_ERROR_UNIMPLEMENTED;
  4403.  
  4404.     if (HAS_PP(i965)) {
  4405.         int fourcc = pp_get_surface_fourcc(ctx, src_surface);
  4406.  
  4407.         switch (fourcc) {
  4408.         case VA_FOURCC('Y', 'V', '1', '2'):
  4409.         case VA_FOURCC('I', '4', '2', '0'):
  4410.         case VA_FOURCC('I', 'M', 'C', '1'):
  4411.         case VA_FOURCC('I', 'M', 'C', '3'):
  4412.             status = i965_image_pl3_processing(ctx,
  4413.                                                src_surface,
  4414.                                                src_rect,
  4415.                                                dst_surface,
  4416.                                                dst_rect);
  4417.             break;
  4418.  
  4419.         case  VA_FOURCC('N', 'V', '1', '2'):
  4420.             status = i965_image_pl2_processing(ctx,
  4421.                                                src_surface,
  4422.                                                src_rect,
  4423.                                                dst_surface,
  4424.                                                dst_rect);
  4425.             break;
  4426.         case  VA_FOURCC('Y', 'U', 'Y', '2'):
  4427.         case VA_FOURCC('U', 'Y', 'V', 'Y'):
  4428.             status = i965_image_pl1_processing(ctx,
  4429.                                                src_surface,
  4430.                                                src_rect,
  4431.                                                dst_surface,
  4432.                                                dst_rect);
  4433.             break;
  4434.  
  4435.         default:
  4436.             status = VA_STATUS_ERROR_UNIMPLEMENTED;
  4437.             break;
  4438.         }
  4439.     }
  4440.  
  4441.     return status;
  4442. }    
  4443.  
  4444.  
  4445. static void
  4446. i965_post_processing_context_finalize(struct i965_post_processing_context *pp_context)
  4447. {
  4448.     int i;
  4449.  
  4450.     dri_bo_unreference(pp_context->surface_state_binding_table.bo);
  4451.     pp_context->surface_state_binding_table.bo = NULL;
  4452.  
  4453.     dri_bo_unreference(pp_context->curbe.bo);
  4454.     pp_context->curbe.bo = NULL;
  4455.  
  4456.     dri_bo_unreference(pp_context->sampler_state_table.bo);
  4457.     pp_context->sampler_state_table.bo = NULL;
  4458.  
  4459.     dri_bo_unreference(pp_context->sampler_state_table.bo_8x8);
  4460.     pp_context->sampler_state_table.bo_8x8 = NULL;
  4461.  
  4462.     dri_bo_unreference(pp_context->sampler_state_table.bo_8x8_uv);
  4463.     pp_context->sampler_state_table.bo_8x8_uv = NULL;
  4464.  
  4465.     dri_bo_unreference(pp_context->idrt.bo);
  4466.     pp_context->idrt.bo = NULL;
  4467.     pp_context->idrt.num_interface_descriptors = 0;
  4468.  
  4469.     dri_bo_unreference(pp_context->vfe_state.bo);
  4470.     pp_context->vfe_state.bo = NULL;
  4471.  
  4472.     dri_bo_unreference(pp_context->stmm.bo);
  4473.     pp_context->stmm.bo = NULL;
  4474.  
  4475.     for (i = 0; i < NUM_PP_MODULES; i++) {
  4476.         struct pp_module *pp_module = &pp_context->pp_modules[i];
  4477.  
  4478.         dri_bo_unreference(pp_module->kernel.bo);
  4479.         pp_module->kernel.bo = NULL;
  4480.     }
  4481.  
  4482.     free(pp_context->pp_static_parameter);
  4483.     free(pp_context->pp_inline_parameter);
  4484.     pp_context->pp_static_parameter = NULL;
  4485.     pp_context->pp_inline_parameter = NULL;
  4486. }
  4487.  
  4488. Bool
  4489. i965_post_processing_terminate(VADriverContextP ctx)
  4490. {
  4491.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  4492.     struct i965_post_processing_context *pp_context = i965->pp_context;
  4493.  
  4494.     if (pp_context) {
  4495.        if(IS_HASWELL(i965->intel.device_id)){
  4496.            gen75_vebox_context_destroy(ctx, pp_context->pp_vebox_context);
  4497.         }
  4498.  
  4499.         i965_post_processing_context_finalize(pp_context);
  4500.         free(pp_context);
  4501.     }
  4502.  
  4503.     i965->pp_context = NULL;
  4504.  
  4505.     return True;
  4506. }
  4507.  
  4508. static void
  4509. i965_post_processing_context_init(VADriverContextP ctx,
  4510.                                   struct i965_post_processing_context *pp_context,
  4511.                                   struct intel_batchbuffer *batch)
  4512. {
  4513.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  4514.     int i;
  4515.  
  4516.     printf("%s\n", __FUNCTION__);
  4517.  
  4518.     pp_context->urb.size = URB_SIZE((&i965->intel));
  4519.     pp_context->urb.num_vfe_entries = 32;
  4520.     pp_context->urb.size_vfe_entry = 1;     /* in 512 bits unit */
  4521.     pp_context->urb.num_cs_entries = 1;
  4522.  
  4523.     if (IS_GEN7(i965->intel.device_id))
  4524.         pp_context->urb.size_cs_entry = 4;      /* in 512 bits unit */
  4525.     else
  4526.         pp_context->urb.size_cs_entry = 2;
  4527.  
  4528.    pp_context->urb.vfe_start = 0;
  4529.     pp_context->urb.cs_start = pp_context->urb.vfe_start +
  4530.         pp_context->urb.num_vfe_entries * pp_context->urb.size_vfe_entry;
  4531.     assert(pp_context->urb.cs_start +
  4532.            pp_context->urb.num_cs_entries * pp_context->urb.size_cs_entry <= URB_SIZE((&i965->intel)));
  4533.  
  4534.     assert(NUM_PP_MODULES == ARRAY_ELEMS(pp_modules_gen5));
  4535.     assert(NUM_PP_MODULES == ARRAY_ELEMS(pp_modules_gen6));
  4536.     assert(NUM_PP_MODULES == ARRAY_ELEMS(pp_modules_gen7));
  4537.     assert(NUM_PP_MODULES == ARRAY_ELEMS(pp_modules_gen75));
  4538.  
  4539.     if (IS_HASWELL(i965->intel.device_id))
  4540.         memcpy(pp_context->pp_modules, pp_modules_gen75, sizeof(pp_context->pp_modules));
  4541.     else if (IS_GEN7(i965->intel.device_id))
  4542.         memcpy(pp_context->pp_modules, pp_modules_gen7, sizeof(pp_context->pp_modules));
  4543.     else if (IS_GEN6(i965->intel.device_id))
  4544.         memcpy(pp_context->pp_modules, pp_modules_gen6, sizeof(pp_context->pp_modules));
  4545.     else if (IS_IRONLAKE(i965->intel.device_id))
  4546.         memcpy(pp_context->pp_modules, pp_modules_gen5, sizeof(pp_context->pp_modules));
  4547.  
  4548.     for (i = 0; i < NUM_PP_MODULES; i++) {
  4549.         struct pp_module *pp_module = &pp_context->pp_modules[i];
  4550.         dri_bo_unreference(pp_module->kernel.bo);
  4551.         if (pp_module->kernel.bin && pp_module->kernel.size) {
  4552.             pp_module->kernel.bo = dri_bo_alloc(i965->intel.bufmgr,
  4553.                                                 pp_module->kernel.name,
  4554.                                                 pp_module->kernel.size,
  4555.                                                 4096);
  4556.             assert(pp_module->kernel.bo);
  4557.             dri_bo_subdata(pp_module->kernel.bo, 0, pp_module->kernel.size, pp_module->kernel.bin);
  4558.         } else {
  4559.             pp_module->kernel.bo = NULL;
  4560.         }
  4561.     }
  4562.  
  4563.     /* static & inline parameters */
  4564.     if (IS_GEN7(i965->intel.device_id)) {
  4565.         pp_context->pp_static_parameter = calloc(sizeof(struct gen7_pp_static_parameter), 1);
  4566.         pp_context->pp_inline_parameter = calloc(sizeof(struct gen7_pp_inline_parameter), 1);
  4567.     } else {
  4568.         pp_context->pp_static_parameter = calloc(sizeof(struct pp_static_parameter), 1);
  4569.         pp_context->pp_inline_parameter = calloc(sizeof(struct pp_inline_parameter), 1);
  4570.     }
  4571.  
  4572.     pp_context->batch = batch;
  4573. }
  4574.  
  4575. Bool
  4576. i965_post_processing_init(VADriverContextP ctx)
  4577. {
  4578.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  4579.     struct i965_post_processing_context *pp_context = i965->pp_context;
  4580.  
  4581.     printf("%s\n", __FUNCTION__);
  4582.  
  4583.     if (HAS_PP(i965)) {
  4584.         if (pp_context == NULL) {
  4585.             pp_context = calloc(1, sizeof(*pp_context));
  4586.             i965_post_processing_context_init(ctx, pp_context, i965->batch);
  4587.             i965->pp_context = pp_context;
  4588.  
  4589.             if(IS_HASWELL(i965->intel.device_id)){
  4590.                 pp_context->pp_vebox_context = gen75_vebox_context_init(ctx);
  4591.             }
  4592.         }
  4593.     }
  4594.     printf("%s done\n", __FUNCTION__);
  4595.  
  4596.     return True;
  4597. }
  4598.  
  4599.  
  4600.