Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright © 2010-2011 Intel Corporation
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the
  6.  * "Software"), to deal in the Software without restriction, including
  7.  * without limitation the rights to use, copy, modify, merge, publish,
  8.  * distribute, sub license, and/or sell copies of the Software, and to
  9.  * permit persons to whom the Software is furnished to do so, subject to
  10.  * the following conditions:
  11.  *
  12.  * The above copyright notice and this permission notice (including the
  13.  * next paragraph) shall be included in all copies or substantial portions
  14.  * of the Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  17.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  18.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  19.  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
  20.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  21.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  22.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23.  *
  24.  * Authors:
  25.  *    Zhou Chang <chang.zhou@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.  
  37. #include "i965_defines.h"
  38. #include "i965_drv_video.h"
  39. #include "i965_encoder.h"
  40. #include "gen6_vme.h"
  41. #include "gen6_mfc.h"
  42.  
  43. #define SURFACE_STATE_PADDED_SIZE               MAX(SURFACE_STATE_PADDED_SIZE_GEN6, SURFACE_STATE_PADDED_SIZE_GEN7)
  44. #define SURFACE_STATE_OFFSET(index)             (SURFACE_STATE_PADDED_SIZE * index)
  45. #define BINDING_TABLE_OFFSET(index)             (SURFACE_STATE_OFFSET(MAX_MEDIA_SURFACES_GEN6) + sizeof(unsigned int) * index)
  46.  
  47. #define CURBE_ALLOCATION_SIZE   37              /* in 256-bit */
  48. #define CURBE_TOTAL_DATA_LENGTH (4 * 32)        /* in byte, it should be less than or equal to CURBE_ALLOCATION_SIZE * 32 */
  49. #define CURBE_URB_ENTRY_LENGTH  4               /* in 256-bit, it should be less than or equal to CURBE_TOTAL_DATA_LENGTH / 32 */
  50.  
  51. enum VIDEO_CODING_TYPE{
  52.     VIDEO_CODING_AVC = 0,
  53.     VIDEO_CODING_SUM
  54. };
  55.  
  56. enum AVC_VME_KERNEL_TYPE{
  57.     AVC_VME_INTRA_SHADER = 0,
  58.     AVC_VME_INTER_SHADER,
  59.     AVC_VME_BATCHBUFFER,
  60.     AVC_VME_KERNEL_SUM
  61. };
  62.  
  63. static const uint32_t gen6_vme_intra_frame[][4] = {
  64. #include "shaders/vme/intra_frame.g6b"
  65. };
  66.  
  67. static const uint32_t gen6_vme_inter_frame[][4] = {
  68. #include "shaders/vme/inter_frame.g6b"
  69. };
  70.  
  71. static const uint32_t gen6_vme_batchbuffer[][4] = {
  72. #include "shaders/vme/batchbuffer.g6b"
  73. };
  74.  
  75. static struct i965_kernel gen6_vme_kernels[] = {
  76.     {
  77.         "AVC VME Intra Frame",
  78.         AVC_VME_INTRA_SHADER,                   /*index*/
  79.         gen6_vme_intra_frame,                  
  80.         sizeof(gen6_vme_intra_frame),          
  81.         NULL
  82.     },
  83.     {
  84.         "AVC VME inter Frame",
  85.         AVC_VME_INTER_SHADER,
  86.         gen6_vme_inter_frame,
  87.         sizeof(gen6_vme_inter_frame),
  88.         NULL
  89.     },
  90.     {
  91.         "AVC VME BATCHBUFFER",
  92.         AVC_VME_BATCHBUFFER,
  93.         gen6_vme_batchbuffer,
  94.         sizeof(gen6_vme_batchbuffer),
  95.         NULL
  96.     },
  97. };
  98.  
  99. /* only used for VME source surface state */
  100. static void
  101. gen6_vme_source_surface_state(VADriverContextP ctx,
  102.                               int index,
  103.                               struct object_surface *obj_surface,
  104.                               struct intel_encoder_context *encoder_context)
  105. {
  106.     struct gen6_vme_context *vme_context = encoder_context->vme_context;
  107.  
  108.     vme_context->vme_surface2_setup(ctx,
  109.                                     &vme_context->gpe_context,
  110.                                     obj_surface,
  111.                                     BINDING_TABLE_OFFSET(index),
  112.                                     SURFACE_STATE_OFFSET(index));
  113. }
  114.  
  115. static void
  116. gen6_vme_media_source_surface_state(VADriverContextP ctx,
  117.                                     int index,
  118.                                     struct object_surface *obj_surface,
  119.                                     struct intel_encoder_context *encoder_context)
  120. {
  121.     struct gen6_vme_context *vme_context = encoder_context->vme_context;
  122.  
  123.     vme_context->vme_media_rw_surface_setup(ctx,
  124.                                             &vme_context->gpe_context,
  125.                                             obj_surface,
  126.                                             BINDING_TABLE_OFFSET(index),
  127.                                             SURFACE_STATE_OFFSET(index));
  128. }
  129.  
  130. static void
  131. gen6_vme_output_buffer_setup(VADriverContextP ctx,
  132.                              struct encode_state *encode_state,
  133.                              int index,
  134.                              struct intel_encoder_context *encoder_context)
  135.  
  136. {
  137.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  138.     struct gen6_vme_context *vme_context = encoder_context->vme_context;
  139.     VAEncSequenceParameterBufferH264 *pSequenceParameter = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer;
  140.     VAEncSliceParameterBufferH264 *pSliceParameter = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[0]->buffer;
  141.     int is_intra = pSliceParameter->slice_type == SLICE_TYPE_I;
  142.     int width_in_mbs = pSequenceParameter->picture_width_in_mbs;
  143.     int height_in_mbs = pSequenceParameter->picture_height_in_mbs;
  144.  
  145.     vme_context->vme_output.num_blocks = width_in_mbs * height_in_mbs;
  146.     vme_context->vme_output.pitch = 16; /* in bytes, always 16 */
  147.  
  148.     if (is_intra)
  149.         vme_context->vme_output.size_block = INTRA_VME_OUTPUT_IN_BYTES;
  150.     else
  151.         vme_context->vme_output.size_block = INTER_VME_OUTPUT_IN_BYTES;
  152.  
  153.     vme_context->vme_output.bo = dri_bo_alloc(i965->intel.bufmgr,
  154.                                               "VME output buffer",
  155.                                               vme_context->vme_output.num_blocks * vme_context->vme_output.size_block,
  156.                                               0x1000);
  157.     assert(vme_context->vme_output.bo);
  158.     vme_context->vme_buffer_suface_setup(ctx,
  159.                                          &vme_context->gpe_context,
  160.                                          &vme_context->vme_output,
  161.                                          BINDING_TABLE_OFFSET(index),
  162.                                          SURFACE_STATE_OFFSET(index));
  163. }
  164.  
  165. static void
  166. gen6_vme_output_vme_batchbuffer_setup(VADriverContextP ctx,
  167.                                       struct encode_state *encode_state,
  168.                                       int index,
  169.                                       struct intel_encoder_context *encoder_context)
  170.  
  171. {
  172.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  173.     struct gen6_vme_context *vme_context = encoder_context->vme_context;
  174.     VAEncSequenceParameterBufferH264 *pSequenceParameter = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer;
  175.     int width_in_mbs = pSequenceParameter->picture_width_in_mbs;
  176.     int height_in_mbs = pSequenceParameter->picture_height_in_mbs;
  177.  
  178.     vme_context->vme_batchbuffer.num_blocks = width_in_mbs * height_in_mbs + 1;
  179.     vme_context->vme_batchbuffer.size_block = 32; /* 2 OWORDs */
  180.     vme_context->vme_batchbuffer.pitch = 16;
  181.     vme_context->vme_batchbuffer.bo = dri_bo_alloc(i965->intel.bufmgr,
  182.                                                    "VME batchbuffer",
  183.                                                    vme_context->vme_batchbuffer.num_blocks * vme_context->vme_batchbuffer.size_block,
  184.                                                    0x1000);
  185.     vme_context->vme_buffer_suface_setup(ctx,
  186.                                          &vme_context->gpe_context,
  187.                                          &vme_context->vme_batchbuffer,
  188.                                          BINDING_TABLE_OFFSET(index),
  189.                                          SURFACE_STATE_OFFSET(index));
  190. }
  191.  
  192. static VAStatus
  193. gen6_vme_surface_setup(VADriverContextP ctx,
  194.                        struct encode_state *encode_state,
  195.                        int is_intra,
  196.                        struct intel_encoder_context *encoder_context)
  197. {
  198.     struct object_surface *obj_surface;
  199.  
  200.     /*Setup surfaces state*/
  201.     /* current picture for encoding */
  202.     obj_surface = encode_state->input_yuv_object;
  203.     gen6_vme_source_surface_state(ctx, 0, obj_surface, encoder_context);
  204.     gen6_vme_media_source_surface_state(ctx, 4, obj_surface, encoder_context);
  205.  
  206.     if (!is_intra) {
  207.         VAEncSliceParameterBufferH264 *slice_param = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[0]->buffer;
  208.         int slice_type;
  209.  
  210.         slice_type = intel_avc_enc_slice_type_fixup(slice_param->slice_type);
  211.         assert(slice_type != SLICE_TYPE_I && slice_type != SLICE_TYPE_SI);
  212.  
  213.         intel_avc_vme_reference_state(ctx, encode_state, encoder_context, 0, 1, gen6_vme_source_surface_state);
  214.  
  215.         if (slice_type == SLICE_TYPE_B)
  216.             intel_avc_vme_reference_state(ctx, encode_state, encoder_context, 1, 2, gen6_vme_source_surface_state);
  217.     }
  218.  
  219.     /* VME output */
  220.     gen6_vme_output_buffer_setup(ctx, encode_state, 3, encoder_context);
  221.     gen6_vme_output_vme_batchbuffer_setup(ctx, encode_state, 5, encoder_context);
  222.  
  223.     return VA_STATUS_SUCCESS;
  224. }
  225.  
  226. static VAStatus gen6_vme_interface_setup(VADriverContextP ctx,
  227.                                          struct encode_state *encode_state,
  228.                                          struct intel_encoder_context *encoder_context)
  229. {
  230.     struct gen6_vme_context *vme_context = encoder_context->vme_context;
  231.     struct gen6_interface_descriptor_data *desc;  
  232.     int i;
  233.     dri_bo *bo;
  234.  
  235.     bo = vme_context->gpe_context.idrt.bo;
  236.     dri_bo_map(bo, 1);
  237.     assert(bo->virtual);
  238.     desc = bo->virtual;
  239.  
  240.     for (i = 0; i < vme_context->vme_kernel_sum; i++) {
  241.         struct i965_kernel *kernel;
  242.         kernel = &vme_context->gpe_context.kernels[i];
  243.         assert(sizeof(*desc) == 32);
  244.         /*Setup the descritor table*/
  245.         memset(desc, 0, sizeof(*desc));
  246.         desc->desc0.kernel_start_pointer = (kernel->bo->offset >> 6);
  247.         desc->desc2.sampler_count = 1; /* FIXME: */
  248.         desc->desc2.sampler_state_pointer = (vme_context->vme_state.bo->offset >> 5);
  249.         desc->desc3.binding_table_entry_count = 1; /* FIXME: */
  250.         desc->desc3.binding_table_pointer = (BINDING_TABLE_OFFSET(0) >> 5);
  251.         desc->desc4.constant_urb_entry_read_offset = 0;
  252.         desc->desc4.constant_urb_entry_read_length = CURBE_URB_ENTRY_LENGTH;
  253.                
  254.         /*kernel start*/
  255.         dri_bo_emit_reloc(bo,  
  256.                           I915_GEM_DOMAIN_INSTRUCTION, 0,
  257.                           0,
  258.                           i * sizeof(*desc) + offsetof(struct gen6_interface_descriptor_data, desc0),
  259.                           kernel->bo);
  260.         /*Sampler State(VME state pointer)*/
  261.         dri_bo_emit_reloc(bo,
  262.                           I915_GEM_DOMAIN_INSTRUCTION, 0,
  263.                           (1 << 2),                                                                     //
  264.                           i * sizeof(*desc) + offsetof(struct gen6_interface_descriptor_data, desc2),
  265.                           vme_context->vme_state.bo);
  266.         desc++;
  267.     }
  268.     dri_bo_unmap(bo);
  269.  
  270.     return VA_STATUS_SUCCESS;
  271. }
  272.  
  273. static VAStatus gen6_vme_constant_setup(VADriverContextP ctx,
  274.                                         struct encode_state *encode_state,
  275.                                         struct intel_encoder_context *encoder_context)
  276. {
  277.     struct gen6_vme_context *vme_context = encoder_context->vme_context;
  278.     // unsigned char *constant_buffer;
  279.     unsigned int *vme_state_message;
  280.     int mv_num = 32;
  281.     if (vme_context->h264_level >= 30) {
  282.         mv_num = 16;
  283.         if (vme_context->h264_level >= 31)
  284.             mv_num = 8;
  285.     }
  286.  
  287.     dri_bo_map(vme_context->gpe_context.curbe.bo, 1);
  288.     assert(vme_context->gpe_context.curbe.bo->virtual);
  289.     // constant_buffer = vme_context->curbe.bo->virtual;
  290.     vme_state_message = (unsigned int *)vme_context->gpe_context.curbe.bo->virtual;
  291.     vme_state_message[31] = mv_num;
  292.        
  293.     /*TODO copy buffer into CURB*/
  294.  
  295.     dri_bo_unmap( vme_context->gpe_context.curbe.bo);
  296.  
  297.     return VA_STATUS_SUCCESS;
  298. }
  299.  
  300. static const unsigned int intra_mb_mode_cost_table[] = {
  301.     0x31110001, // for qp0
  302.     0x09110001, // for qp1
  303.     0x15030001, // for qp2
  304.     0x0b030001, // for qp3
  305.     0x0d030011, // for qp4
  306.     0x17210011, // for qp5
  307.     0x41210011, // for qp6
  308.     0x19210011, // for qp7
  309.     0x25050003, // for qp8
  310.     0x1b130003, // for qp9
  311.     0x1d130003, // for qp10
  312.     0x27070021, // for qp11
  313.     0x51310021, // for qp12
  314.     0x29090021, // for qp13
  315.     0x35150005, // for qp14
  316.     0x2b0b0013, // for qp15
  317.     0x2d0d0013, // for qp16
  318.     0x37170007, // for qp17
  319.     0x61410031, // for qp18
  320.     0x39190009, // for qp19
  321.     0x45250015, // for qp20
  322.     0x3b1b000b, // for qp21
  323.     0x3d1d000d, // for qp22
  324.     0x47270017, // for qp23
  325.     0x71510041, // for qp24 ! center for qp=0..30
  326.     0x49290019, // for qp25
  327.     0x55350025, // for qp26
  328.     0x4b2b001b, // for qp27
  329.     0x4d2d001d, // for qp28
  330.     0x57370027, // for qp29
  331.     0x81610051, // for qp30
  332.     0x57270017, // for qp31
  333.     0x81510041, // for qp32 ! center for qp=31..51
  334.     0x59290019, // for qp33
  335.     0x65350025, // for qp34
  336.     0x5b2b001b, // for qp35
  337.     0x5d2d001d, // for qp36
  338.     0x67370027, // for qp37
  339.     0x91610051, // for qp38
  340.     0x69390029, // for qp39
  341.     0x75450035, // for qp40
  342.     0x6b3b002b, // for qp41
  343.     0x6d3d002d, // for qp42
  344.     0x77470037, // for qp43
  345.     0xa1710061, // for qp44
  346.     0x79490039, // for qp45
  347.     0x85550045, // for qp46
  348.     0x7b4b003b, // for qp47
  349.     0x7d4d003d, // for qp48
  350.     0x87570047, // for qp49
  351.     0xb1810071, // for qp50
  352.     0x89590049  // for qp51
  353. };
  354.  
  355. static void gen6_vme_state_setup_fixup(VADriverContextP ctx,
  356.                                        struct encode_state *encode_state,
  357.                                        struct intel_encoder_context *encoder_context,
  358.                                        unsigned int *vme_state_message)
  359. {
  360.     struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
  361.     VAEncPictureParameterBufferH264 *pic_param = (VAEncPictureParameterBufferH264 *)encode_state->pic_param_ext->buffer;
  362.     VAEncSliceParameterBufferH264 *slice_param = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[0]->buffer;
  363.  
  364.     if (slice_param->slice_type != SLICE_TYPE_I &&
  365.         slice_param->slice_type != SLICE_TYPE_SI)
  366.         return;
  367.  
  368.     if (encoder_context->rate_control_mode == VA_RC_CQP)
  369.         vme_state_message[16] = intra_mb_mode_cost_table[pic_param->pic_init_qp + slice_param->slice_qp_delta];
  370.     else
  371.         vme_state_message[16] = intra_mb_mode_cost_table[mfc_context->bit_rate_control_context[SLICE_TYPE_I].QpPrimeY];
  372. }
  373.  
  374. static VAStatus gen6_vme_vme_state_setup(VADriverContextP ctx,
  375.                                          struct encode_state *encode_state,
  376.                                          int is_intra,
  377.                                          struct intel_encoder_context *encoder_context)
  378. {
  379.     struct gen6_vme_context *vme_context = encoder_context->vme_context;
  380.     unsigned int *vme_state_message;
  381.     int i;
  382.        
  383.     //building VME state message
  384.     dri_bo_map(vme_context->vme_state.bo, 1);
  385.     assert(vme_context->vme_state.bo->virtual);
  386.     vme_state_message = (unsigned int *)vme_context->vme_state.bo->virtual;
  387.    
  388.     if (encoder_context->quality_level != ENCODER_LOW_QUALITY) {
  389.         vme_state_message[0] = 0x01010101;
  390.         vme_state_message[1] = 0x10010101;
  391.         vme_state_message[2] = 0x0F0F0F0F;
  392.         vme_state_message[3] = 0x100F0F0F;
  393.         vme_state_message[4] = 0x01010101;
  394.         vme_state_message[5] = 0x10010101;
  395.         vme_state_message[6] = 0x0F0F0F0F;
  396.         vme_state_message[7] = 0x100F0F0F;
  397.         vme_state_message[8] = 0x01010101;
  398.         vme_state_message[9] = 0x10010101;
  399.         vme_state_message[10] = 0x0F0F0F0F;
  400.         vme_state_message[11] = 0x000F0F0F;
  401.         vme_state_message[12] = 0x00;
  402.         vme_state_message[13] = 0x00;
  403.     } else {
  404.         vme_state_message[0] = 0x10010101;
  405.         vme_state_message[1] = 0x100F0F0F;
  406.         vme_state_message[2] = 0x10010101;
  407.         vme_state_message[3] = 0x000F0F0F;
  408.         vme_state_message[4] = 0;
  409.         vme_state_message[5] = 0;
  410.         vme_state_message[6] = 0;
  411.         vme_state_message[7] = 0;
  412.         vme_state_message[8] = 0;
  413.         vme_state_message[9] = 0;
  414.         vme_state_message[10] = 0;
  415.         vme_state_message[11] = 0;
  416.         vme_state_message[12] = 0;
  417.         vme_state_message[13] = 0;
  418.     }
  419.  
  420.     vme_state_message[14] = 0x4a4a;
  421.     vme_state_message[15] = 0x0;
  422.     vme_state_message[16] = 0x4a4a4a4a;
  423.     vme_state_message[17] = 0x4a4a4a4a;
  424.     vme_state_message[18] = 0x21110100;
  425.     vme_state_message[19] = 0x61514131;
  426.  
  427.     for(i = 20; i < 32; i++) {
  428.         vme_state_message[i] = 0;
  429.     }
  430.     //vme_state_message[16] = 0x42424242;                       //cost function LUT set 0 for Intra
  431.  
  432.     gen6_vme_state_setup_fixup(ctx, encode_state, encoder_context, vme_state_message);
  433.  
  434.     dri_bo_unmap( vme_context->vme_state.bo);
  435.     return VA_STATUS_SUCCESS;
  436. }
  437.  
  438. static void
  439. gen6_vme_fill_vme_batchbuffer(VADriverContextP ctx,
  440.                               struct encode_state *encode_state,
  441.                               int mb_width, int mb_height,
  442.                               int kernel,
  443.                               int transform_8x8_mode_flag,
  444.                               struct intel_encoder_context *encoder_context)
  445. {
  446.     struct gen6_vme_context *vme_context = encoder_context->vme_context;
  447.     int number_mb_cmds;
  448.     int mb_x = 0, mb_y = 0;
  449.     int i, s;
  450.     unsigned int *command_ptr;
  451.  
  452.     dri_bo_map(vme_context->vme_batchbuffer.bo, 1);
  453.     command_ptr = vme_context->vme_batchbuffer.bo->virtual;
  454.  
  455.     for (s = 0; s < encode_state->num_slice_params_ext; s++) {
  456.         VAEncSliceParameterBufferH264 *pSliceParameter = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[s]->buffer;
  457.         int slice_mb_begin = pSliceParameter->macroblock_address;
  458.         int slice_mb_number = pSliceParameter->num_macroblocks;
  459.        
  460.         for (i = 0; i < slice_mb_number;  ) {
  461.             int mb_count = i + slice_mb_begin;    
  462.             mb_x = mb_count % mb_width;
  463.             mb_y = mb_count / mb_width;
  464.             if( i == 0 ) {
  465.                 number_mb_cmds = mb_width;          // we must mark the slice edge.
  466.             } else if ( (i + 128 ) <= slice_mb_number) {
  467.                 number_mb_cmds = 128;
  468.             } else {
  469.                 number_mb_cmds = slice_mb_number - i;
  470.             }
  471.  
  472.             *command_ptr++ = (CMD_MEDIA_OBJECT | (9 - 2));
  473.             *command_ptr++ = kernel;
  474.             *command_ptr++ = 0;
  475.             *command_ptr++ = 0;
  476.             *command_ptr++ = 0;
  477.             *command_ptr++ = 0;
  478.    
  479.             /*inline data */
  480.             *command_ptr++ = (mb_width << 16 | mb_y << 8 | mb_x);
  481.             *command_ptr++ = (number_mb_cmds << 16 | transform_8x8_mode_flag | ((i==0) << 1));
  482.             *command_ptr++ = encoder_context->quality_level;
  483.  
  484.             i += number_mb_cmds;
  485.         }
  486.     }
  487.  
  488.     *command_ptr++ = 0;
  489.     *command_ptr++ = MI_BATCH_BUFFER_END;
  490.  
  491.     dri_bo_unmap(vme_context->vme_batchbuffer.bo);
  492. }
  493.  
  494. static void gen6_vme_media_init(VADriverContextP ctx, struct intel_encoder_context *encoder_context)
  495. {
  496.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  497.     struct gen6_vme_context *vme_context = encoder_context->vme_context;
  498.     dri_bo *bo;
  499.  
  500.     i965_gpe_context_init(ctx, &vme_context->gpe_context);
  501.  
  502.     /* VME output buffer */
  503.     dri_bo_unreference(vme_context->vme_output.bo);
  504.     vme_context->vme_output.bo = NULL;
  505.  
  506.     dri_bo_unreference(vme_context->vme_batchbuffer.bo);
  507.     vme_context->vme_batchbuffer.bo = NULL;
  508.  
  509.     /* VME state */
  510.     dri_bo_unreference(vme_context->vme_state.bo);
  511.     bo = dri_bo_alloc(i965->intel.bufmgr,
  512.                       "Buffer",
  513.                       1024*16, 64);
  514.     assert(bo);
  515.     vme_context->vme_state.bo = bo;
  516. }
  517.  
  518. static void gen6_vme_pipeline_programing(VADriverContextP ctx,
  519.                                          struct encode_state *encode_state,
  520.                                          struct intel_encoder_context *encoder_context)
  521. {
  522.     struct gen6_vme_context *vme_context = encoder_context->vme_context;
  523.     struct intel_batchbuffer *batch = encoder_context->base.batch;
  524.     VAEncPictureParameterBufferH264 *pPicParameter = (VAEncPictureParameterBufferH264 *)encode_state->pic_param_ext->buffer;
  525.     VAEncSliceParameterBufferH264 *pSliceParameter = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[0]->buffer;
  526.     VAEncSequenceParameterBufferH264 *pSequenceParameter = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer;
  527.     int is_intra = pSliceParameter->slice_type == SLICE_TYPE_I;
  528.     int width_in_mbs = pSequenceParameter->picture_width_in_mbs;
  529.     int height_in_mbs = pSequenceParameter->picture_height_in_mbs;
  530.  
  531.     gen6_vme_fill_vme_batchbuffer(ctx,
  532.                                   encode_state,
  533.                                   width_in_mbs, height_in_mbs,
  534.                                   is_intra ? AVC_VME_INTRA_SHADER : AVC_VME_INTER_SHADER,
  535.                                   pPicParameter->pic_fields.bits.transform_8x8_mode_flag,
  536.                                   encoder_context);
  537.  
  538.     intel_batchbuffer_start_atomic(batch, 0x1000);
  539.     gen6_gpe_pipeline_setup(ctx, &vme_context->gpe_context, batch);
  540.     BEGIN_BATCH(batch, 2);
  541.     OUT_BATCH(batch, MI_BATCH_BUFFER_START | (1 << 8));
  542.     OUT_RELOC(batch,
  543.               vme_context->vme_batchbuffer.bo,
  544.               I915_GEM_DOMAIN_COMMAND, 0,
  545.               0);
  546.     ADVANCE_BATCH(batch);
  547.  
  548.     intel_batchbuffer_end_atomic(batch);
  549. }
  550.  
  551. static VAStatus gen6_vme_prepare(VADriverContextP ctx,
  552.                                  struct encode_state *encode_state,
  553.                                  struct intel_encoder_context *encoder_context)
  554. {
  555.     VAStatus vaStatus = VA_STATUS_SUCCESS;
  556.     VAEncSliceParameterBufferH264 *pSliceParameter = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[0]->buffer;
  557.     int is_intra = pSliceParameter->slice_type == SLICE_TYPE_I;
  558.     VAEncSequenceParameterBufferH264 *pSequenceParameter = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer;
  559.     struct gen6_vme_context *vme_context = encoder_context->vme_context;
  560.  
  561.     if (!vme_context->h264_level ||
  562.         (vme_context->h264_level != pSequenceParameter->level_idc)) {
  563.         vme_context->h264_level = pSequenceParameter->level_idc;       
  564.     }  
  565.     /*Setup all the memory object*/
  566.     gen6_vme_surface_setup(ctx, encode_state, is_intra, encoder_context);
  567.     gen6_vme_interface_setup(ctx, encode_state, encoder_context);
  568.     gen6_vme_constant_setup(ctx, encode_state, encoder_context);
  569.     gen6_vme_vme_state_setup(ctx, encode_state, is_intra, encoder_context);
  570.  
  571.     /*Programing media pipeline*/
  572.     gen6_vme_pipeline_programing(ctx, encode_state, encoder_context);
  573.  
  574.     return vaStatus;
  575. }
  576.  
  577. static VAStatus gen6_vme_run(VADriverContextP ctx,
  578.                              struct encode_state *encode_state,
  579.                              struct intel_encoder_context *encoder_context)
  580. {
  581.     struct intel_batchbuffer *batch = encoder_context->base.batch;
  582.  
  583.     intel_batchbuffer_flush(batch);
  584.  
  585.     return VA_STATUS_SUCCESS;
  586. }
  587.  
  588. static VAStatus gen6_vme_stop(VADriverContextP ctx,
  589.                               struct encode_state *encode_state,
  590.                               struct intel_encoder_context *encoder_context)
  591. {
  592.     return VA_STATUS_SUCCESS;
  593. }
  594.  
  595. static VAStatus
  596. gen6_vme_pipeline(VADriverContextP ctx,
  597.                   VAProfile profile,
  598.                   struct encode_state *encode_state,
  599.                   struct intel_encoder_context *encoder_context)
  600. {
  601.     gen6_vme_media_init(ctx, encoder_context);
  602.     gen6_vme_prepare(ctx, encode_state, encoder_context);
  603.     gen6_vme_run(ctx, encode_state, encoder_context);
  604.     gen6_vme_stop(ctx, encode_state, encoder_context);
  605.  
  606.     return VA_STATUS_SUCCESS;
  607. }
  608.  
  609. static void
  610. gen6_vme_context_destroy(void *context)
  611. {
  612.     struct gen6_vme_context *vme_context = context;
  613.  
  614.     i965_gpe_context_destroy(&vme_context->gpe_context);
  615.  
  616.     dri_bo_unreference(vme_context->vme_output.bo);
  617.     vme_context->vme_output.bo = NULL;
  618.  
  619.     dri_bo_unreference(vme_context->vme_state.bo);
  620.     vme_context->vme_state.bo = NULL;
  621.  
  622.     dri_bo_unreference(vme_context->vme_batchbuffer.bo);
  623.     vme_context->vme_batchbuffer.bo = NULL;
  624.  
  625.     free(vme_context);
  626. }
  627.  
  628. Bool gen6_vme_context_init(VADriverContextP ctx, struct intel_encoder_context *encoder_context)
  629. {
  630.     struct gen6_vme_context *vme_context = NULL;
  631.  
  632.     if (encoder_context->codec != CODEC_H264) {
  633.         /* Never get here */
  634.         assert(0);
  635.         return False;
  636.     }
  637.  
  638.     vme_context = calloc(1, sizeof(struct gen6_vme_context));
  639.     vme_context->gpe_context.surface_state_binding_table.length =
  640.         (SURFACE_STATE_PADDED_SIZE + sizeof(unsigned int)) * MAX_MEDIA_SURFACES_GEN6;
  641.  
  642.     vme_context->gpe_context.idrt.max_entries = MAX_INTERFACE_DESC_GEN6;
  643.     vme_context->gpe_context.idrt.entry_size = sizeof(struct gen6_interface_descriptor_data);
  644.     vme_context->gpe_context.curbe.length = CURBE_TOTAL_DATA_LENGTH;
  645.  
  646.     vme_context->gpe_context.vfe_state.max_num_threads = 60 - 1;
  647.     vme_context->gpe_context.vfe_state.num_urb_entries = 16;
  648.     vme_context->gpe_context.vfe_state.gpgpu_mode = 0;
  649.     vme_context->gpe_context.vfe_state.urb_entry_size = 59 - 1;
  650.     vme_context->gpe_context.vfe_state.curbe_allocation_size = CURBE_ALLOCATION_SIZE - 1;
  651.  
  652.     vme_context->video_coding_type = VIDEO_CODING_AVC;
  653.     vme_context->vme_kernel_sum = AVC_VME_KERNEL_SUM;
  654.     i965_gpe_load_kernels(ctx,
  655.                           &vme_context->gpe_context,
  656.                           gen6_vme_kernels,
  657.                           vme_context->vme_kernel_sum);
  658.  
  659.     encoder_context->vme_pipeline = gen6_vme_pipeline;
  660.     vme_context->vme_surface2_setup = i965_gpe_surface2_setup;
  661.     vme_context->vme_media_rw_surface_setup = i965_gpe_media_rw_surface_setup;
  662.     vme_context->vme_buffer_suface_setup = i965_gpe_buffer_suface_setup;
  663.  
  664.     encoder_context->vme_context = vme_context;
  665.     encoder_context->vme_context_destroy = gen6_vme_context_destroy;
  666.  
  667.     return True;
  668. }
  669.