xvmc_vld.c revision 428d7b3d
1428d7b3dSmrg/* 2428d7b3dSmrg * Copyright © 2009 Intel Corporation 3428d7b3dSmrg * 4428d7b3dSmrg * Permission is hereby granted, free of charge, to any person obtaining a 5428d7b3dSmrg * copy of this software and associated documentation files (the "Software"), 6428d7b3dSmrg * to deal in the Software without restriction, including without limitation 7428d7b3dSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8428d7b3dSmrg * and/or sell copies of the Software, and to permit persons to whom the 9428d7b3dSmrg * Software is furnished to do so, subject to the following conditions: 10428d7b3dSmrg * 11428d7b3dSmrg * The above copyright notice and this permission notice (including the next 12428d7b3dSmrg * paragraph) shall be included in all copies or substantial portions of the 13428d7b3dSmrg * Software. 14428d7b3dSmrg * 15428d7b3dSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16428d7b3dSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17428d7b3dSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18428d7b3dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19428d7b3dSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20428d7b3dSmrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21428d7b3dSmrg * SOFTWARE. 22428d7b3dSmrg * 23428d7b3dSmrg * Author: 24428d7b3dSmrg * Zou Nan hai <nanhai.zou@intel.com> 25428d7b3dSmrg */ 26428d7b3dSmrg#include "intel_xvmc_private.h" 27428d7b3dSmrg#include "i830_reg.h" 28428d7b3dSmrg#include "i965_reg.h" 29428d7b3dSmrg#include "brw_defines.h" 30428d7b3dSmrg#include "brw_structs.h" 31428d7b3dSmrg 32428d7b3dSmrg#ifndef ALIGN 33428d7b3dSmrg#define ALIGN(m,n) (((m) + (n) - 1) & ~((n) - 1)) 34428d7b3dSmrg#endif 35428d7b3dSmrg 36428d7b3dSmrg#define BATCH_STRUCT(x) intelBatchbufferData(&x, sizeof(x), 0) 37428d7b3dSmrg#define VLD_MAX_SLICE_SIZE (32 * 1024) 38428d7b3dSmrg#define CS_SIZE 30 39428d7b3dSmrg#define URB_SIZE 384 40428d7b3dSmrg/* idct table */ 41428d7b3dSmrg#define C0 23170 42428d7b3dSmrg#define C1 22725 43428d7b3dSmrg#define C2 21407 44428d7b3dSmrg#define C3 19266 45428d7b3dSmrg#define C4 16383 46428d7b3dSmrg#define C5 12873 47428d7b3dSmrg#define C6 8867 48428d7b3dSmrg#define C7 4520 49428d7b3dSmrgconst uint32_t idct_table[] = { 50428d7b3dSmrg C4, C1, C2, C3, C4, C5, C6, C7, //g5 51428d7b3dSmrg C4, C1, C2, C3, C4, C5, C6, C7, 52428d7b3dSmrg C4, C3, C6, -C7, -C4, -C1, -C2, -C5, 53428d7b3dSmrg C4, C3, C6, -C7, -C4, -C1, -C2, -C5, 54428d7b3dSmrg C4, C5, -C6, -C1, -C4, C7, C2, C3, 55428d7b3dSmrg C4, C5, -C6, -C1, -C4, C7, C2, C3, 56428d7b3dSmrg C4, C7, -C2, -C5, C4, C3, -C6, -C1, 57428d7b3dSmrg C4, C7, -C2, -C5, C4, C3, -C6, -C1, 58428d7b3dSmrg C4, -C7, -C2, C5, C4, -C3, -C6, C1, 59428d7b3dSmrg C4, -C7, -C2, C5, C4, -C3, -C6, C1, 60428d7b3dSmrg C4, -C5, -C6, C1, -C4, -C7, C2, -C3, 61428d7b3dSmrg C4, -C5, -C6, C1, -C4, -C7, C2, -C3, 62428d7b3dSmrg C4, -C3, C6, C7, -C4, C1, -C2, C5, 63428d7b3dSmrg C4, -C3, C6, C7, -C4, C1, -C2, C5, 64428d7b3dSmrg C4, -C1, C2, -C3, C4, -C5, C6, -C7, 65428d7b3dSmrg C4, -C1, C2, -C3, C4, -C5, C6, -C7 //g20 66428d7b3dSmrg}; 67428d7b3dSmrg 68428d7b3dSmrg#undef C0 69428d7b3dSmrg#undef C1 70428d7b3dSmrg#undef C2 71428d7b3dSmrg#undef C3 72428d7b3dSmrg#undef C4 73428d7b3dSmrg#undef C5 74428d7b3dSmrg#undef C6 75428d7b3dSmrg#undef C7 76428d7b3dSmrg 77428d7b3dSmrg#define INTERFACE_NUM 8 78428d7b3dSmrgenum interface { 79428d7b3dSmrg FRAME_INTRA = 0, 80428d7b3dSmrg FRAME_FRAME_PRED_FORWARD, 81428d7b3dSmrg FRAME_FRAME_PRED_BACKWARD, 82428d7b3dSmrg FRAME_FRAME_PRED_BIDIRECT, 83428d7b3dSmrg FRAME_FIELD_PRED_FORWARD, 84428d7b3dSmrg FRAME_FIELD_PRED_BACKWARD, 85428d7b3dSmrg FRAME_FIELD_PRED_BIDIRECT, 86428d7b3dSmrg LIB_INTERFACE 87428d7b3dSmrg}; 88428d7b3dSmrg 89428d7b3dSmrg/*kernels for vld mode*/ 90428d7b3dSmrgstatic uint32_t lib_kernel[][4] = { 91428d7b3dSmrg#include "shader/vld/lib.g4b" 92428d7b3dSmrg}; 93428d7b3dSmrg 94428d7b3dSmrgstatic uint32_t ipicture_kernel[][4] = { 95428d7b3dSmrg#include "shader/vld/ipicture.g4b" 96428d7b3dSmrg}; 97428d7b3dSmrg 98428d7b3dSmrgstatic uint32_t frame_forward_kernel[][4] = { 99428d7b3dSmrg#include "shader/vld/frame_forward.g4b" 100428d7b3dSmrg}; 101428d7b3dSmrg 102428d7b3dSmrgstatic uint32_t frame_backward_kernel[][4] = { 103428d7b3dSmrg#include "shader/vld/frame_backward.g4b" 104428d7b3dSmrg}; 105428d7b3dSmrg 106428d7b3dSmrgstatic uint32_t frame_f_b_kernel[][4] = { 107428d7b3dSmrg#include "shader/vld/frame_f_b.g4b" 108428d7b3dSmrg}; 109428d7b3dSmrg 110428d7b3dSmrgstatic uint32_t field_forward_kernel[][4] = { 111428d7b3dSmrg#include "shader/vld/field_forward.g4b" 112428d7b3dSmrg}; 113428d7b3dSmrg 114428d7b3dSmrgstatic uint32_t field_backward_kernel[][4] = { 115428d7b3dSmrg#include "shader/vld/field_backward.g4b" 116428d7b3dSmrg}; 117428d7b3dSmrg 118428d7b3dSmrgstatic uint32_t field_f_b_kernel[][4] = { 119428d7b3dSmrg#include "shader/vld/field_f_b.g4b" 120428d7b3dSmrg}; 121428d7b3dSmrg 122428d7b3dSmrg/* on Ironlake */ 123428d7b3dSmrgstatic uint32_t lib_kernel_gen5[][4] = { 124428d7b3dSmrg#include "shader/vld/lib.g4b.gen5" 125428d7b3dSmrg}; 126428d7b3dSmrg 127428d7b3dSmrgstatic uint32_t ipicture_kernel_gen5[][4] = { 128428d7b3dSmrg#include "shader/vld/ipicture.g4b.gen5" 129428d7b3dSmrg}; 130428d7b3dSmrg 131428d7b3dSmrgstatic uint32_t frame_forward_kernel_gen5[][4] = { 132428d7b3dSmrg#include "shader/vld/frame_forward.g4b.gen5" 133428d7b3dSmrg}; 134428d7b3dSmrg 135428d7b3dSmrgstatic uint32_t frame_backward_kernel_gen5[][4] = { 136428d7b3dSmrg#include "shader/vld/frame_backward.g4b.gen5" 137428d7b3dSmrg}; 138428d7b3dSmrg 139428d7b3dSmrgstatic uint32_t frame_f_b_kernel_gen5[][4] = { 140428d7b3dSmrg#include "shader/vld/frame_f_b.g4b.gen5" 141428d7b3dSmrg}; 142428d7b3dSmrg 143428d7b3dSmrgstatic uint32_t field_forward_kernel_gen5[][4] = { 144428d7b3dSmrg#include "shader/vld/field_forward.g4b.gen5" 145428d7b3dSmrg}; 146428d7b3dSmrg 147428d7b3dSmrgstatic uint32_t field_backward_kernel_gen5[][4] = { 148428d7b3dSmrg#include "shader/vld/field_backward.g4b.gen5" 149428d7b3dSmrg}; 150428d7b3dSmrg 151428d7b3dSmrgstatic uint32_t field_f_b_kernel_gen5[][4] = { 152428d7b3dSmrg#include "shader/vld/field_f_b.g4b.gen5" 153428d7b3dSmrg}; 154428d7b3dSmrg 155428d7b3dSmrg/*kernels for mc mode*/ 156428d7b3dSmrgstatic uint32_t lib_kernel_idct[][4] = { 157428d7b3dSmrg#include "shader/mc/lib_igd.g4b" 158428d7b3dSmrg}; 159428d7b3dSmrg 160428d7b3dSmrgstatic uint32_t ipicture_kernel_idct[][4] = { 161428d7b3dSmrg#include "shader/mc/ipicture_igd.g4b" 162428d7b3dSmrg}; 163428d7b3dSmrg 164428d7b3dSmrgstatic uint32_t frame_forward_kernel_idct[][4] = { 165428d7b3dSmrg#include "shader/mc/frame_forward_igd.g4b" 166428d7b3dSmrg}; 167428d7b3dSmrg 168428d7b3dSmrgstatic uint32_t frame_backward_kernel_idct[][4] = { 169428d7b3dSmrg#include "shader/mc/frame_backward_igd.g4b" 170428d7b3dSmrg}; 171428d7b3dSmrg 172428d7b3dSmrgstatic uint32_t frame_f_b_kernel_idct[][4] = { 173428d7b3dSmrg#include "shader/mc/frame_f_b_igd.g4b" 174428d7b3dSmrg}; 175428d7b3dSmrg 176428d7b3dSmrgstatic uint32_t field_forward_kernel_idct[][4] = { 177428d7b3dSmrg#include "shader/mc/field_forward_igd.g4b" 178428d7b3dSmrg}; 179428d7b3dSmrg 180428d7b3dSmrgstatic uint32_t field_backward_kernel_idct[][4] = { 181428d7b3dSmrg#include "shader/mc/field_backward_igd.g4b" 182428d7b3dSmrg}; 183428d7b3dSmrg 184428d7b3dSmrgstatic uint32_t field_f_b_kernel_idct[][4] = { 185428d7b3dSmrg#include "shader/mc/field_f_b_igd.g4b" 186428d7b3dSmrg}; 187428d7b3dSmrg 188428d7b3dSmrg/* on Ironlake */ 189428d7b3dSmrgstatic uint32_t lib_kernel_idct_gen5[][4] = { 190428d7b3dSmrg#include "shader/mc/lib_igd.g4b.gen5" 191428d7b3dSmrg}; 192428d7b3dSmrg 193428d7b3dSmrgstatic uint32_t ipicture_kernel_idct_gen5[][4] = { 194428d7b3dSmrg#include "shader/mc/ipicture_igd.g4b.gen5" 195428d7b3dSmrg}; 196428d7b3dSmrg 197428d7b3dSmrgstatic uint32_t frame_forward_kernel_idct_gen5[][4] = { 198428d7b3dSmrg#include "shader/mc/frame_forward_igd.g4b.gen5" 199428d7b3dSmrg}; 200428d7b3dSmrg 201428d7b3dSmrgstatic uint32_t frame_backward_kernel_idct_gen5[][4] = { 202428d7b3dSmrg#include "shader/mc/frame_backward_igd.g4b.gen5" 203428d7b3dSmrg}; 204428d7b3dSmrg 205428d7b3dSmrgstatic uint32_t frame_f_b_kernel_idct_gen5[][4] = { 206428d7b3dSmrg#include "shader/mc/frame_f_b_igd.g4b.gen5" 207428d7b3dSmrg}; 208428d7b3dSmrg 209428d7b3dSmrgstatic uint32_t field_forward_kernel_idct_gen5[][4] = { 210428d7b3dSmrg#include "shader/mc/field_forward_igd.g4b.gen5" 211428d7b3dSmrg}; 212428d7b3dSmrg 213428d7b3dSmrgstatic uint32_t field_backward_kernel_idct_gen5[][4] = { 214428d7b3dSmrg#include "shader/mc/field_backward_igd.g4b.gen5" 215428d7b3dSmrg}; 216428d7b3dSmrg 217428d7b3dSmrgstatic uint32_t field_f_b_kernel_idct_gen5[][4] = { 218428d7b3dSmrg#include "shader/mc/field_f_b_igd.g4b.gen5" 219428d7b3dSmrg}; 220428d7b3dSmrg 221428d7b3dSmrgstruct media_kernel { 222428d7b3dSmrg uint32_t(*bin)[4]; 223428d7b3dSmrg int size; 224428d7b3dSmrg}; 225428d7b3dSmrgstatic struct media_kernel media_kernels[] = { 226428d7b3dSmrg /*kernels for vld mode */ 227428d7b3dSmrg {ipicture_kernel, sizeof(ipicture_kernel)} 228428d7b3dSmrg , 229428d7b3dSmrg {frame_forward_kernel, sizeof(frame_forward_kernel)} 230428d7b3dSmrg , 231428d7b3dSmrg {frame_backward_kernel, sizeof(frame_backward_kernel)} 232428d7b3dSmrg , 233428d7b3dSmrg {frame_f_b_kernel, sizeof(frame_f_b_kernel)} 234428d7b3dSmrg , 235428d7b3dSmrg {field_forward_kernel, sizeof(field_forward_kernel)} 236428d7b3dSmrg , 237428d7b3dSmrg {field_backward_kernel, sizeof(field_backward_kernel)} 238428d7b3dSmrg , 239428d7b3dSmrg {field_f_b_kernel, sizeof(field_f_b_kernel)} 240428d7b3dSmrg , 241428d7b3dSmrg {lib_kernel, sizeof(lib_kernel)} 242428d7b3dSmrg , 243428d7b3dSmrg /*kernels for mc mode */ 244428d7b3dSmrg {ipicture_kernel_idct, sizeof(ipicture_kernel_idct)} 245428d7b3dSmrg , 246428d7b3dSmrg {frame_forward_kernel_idct, sizeof(frame_forward_kernel_idct)} 247428d7b3dSmrg , 248428d7b3dSmrg {frame_backward_kernel_idct, sizeof(frame_backward_kernel_idct)} 249428d7b3dSmrg , 250428d7b3dSmrg {frame_f_b_kernel_idct, sizeof(frame_f_b_kernel_idct)} 251428d7b3dSmrg , 252428d7b3dSmrg {field_forward_kernel_idct, sizeof(field_forward_kernel_idct)} 253428d7b3dSmrg , 254428d7b3dSmrg {field_backward_kernel_idct, sizeof(field_backward_kernel_idct)} 255428d7b3dSmrg , 256428d7b3dSmrg {field_f_b_kernel_idct, sizeof(field_f_b_kernel_idct)} 257428d7b3dSmrg , 258428d7b3dSmrg {lib_kernel_idct, sizeof(lib_kernel_idct)} 259428d7b3dSmrg}; 260428d7b3dSmrg 261428d7b3dSmrgstatic struct media_kernel media_gen5_kernels[] = { 262428d7b3dSmrg /*kernels for vld mode */ 263428d7b3dSmrg {ipicture_kernel_gen5, sizeof(ipicture_kernel_gen5)} 264428d7b3dSmrg , 265428d7b3dSmrg {frame_forward_kernel_gen5, sizeof(frame_forward_kernel_gen5)} 266428d7b3dSmrg , 267428d7b3dSmrg {frame_backward_kernel_gen5, sizeof(frame_backward_kernel_gen5)} 268428d7b3dSmrg , 269428d7b3dSmrg {frame_f_b_kernel_gen5, sizeof(frame_f_b_kernel_gen5)} 270428d7b3dSmrg , 271428d7b3dSmrg {field_forward_kernel_gen5, sizeof(field_forward_kernel_gen5)} 272428d7b3dSmrg , 273428d7b3dSmrg {field_backward_kernel_gen5, sizeof(field_backward_kernel_gen5)} 274428d7b3dSmrg , 275428d7b3dSmrg {field_f_b_kernel_gen5, sizeof(field_f_b_kernel_gen5)} 276428d7b3dSmrg , 277428d7b3dSmrg {lib_kernel_gen5, sizeof(lib_kernel_gen5)} 278428d7b3dSmrg , 279428d7b3dSmrg /*kernels for mc mode */ 280428d7b3dSmrg {ipicture_kernel_idct_gen5, sizeof(ipicture_kernel_idct_gen5)} 281428d7b3dSmrg , 282428d7b3dSmrg {frame_forward_kernel_idct_gen5, sizeof(frame_forward_kernel_idct_gen5)} 283428d7b3dSmrg , 284428d7b3dSmrg {frame_backward_kernel_idct_gen5, 285428d7b3dSmrg sizeof(frame_backward_kernel_idct_gen5)} 286428d7b3dSmrg , 287428d7b3dSmrg {frame_f_b_kernel_idct_gen5, sizeof(frame_f_b_kernel_idct_gen5)} 288428d7b3dSmrg , 289428d7b3dSmrg {field_forward_kernel_idct_gen5, sizeof(field_forward_kernel_idct_gen5)} 290428d7b3dSmrg , 291428d7b3dSmrg {field_backward_kernel_idct_gen5, 292428d7b3dSmrg sizeof(field_backward_kernel_idct_gen5)} 293428d7b3dSmrg , 294428d7b3dSmrg {field_f_b_kernel_idct_gen5, sizeof(field_f_b_kernel_idct_gen5)} 295428d7b3dSmrg , 296428d7b3dSmrg {lib_kernel_idct_gen5, sizeof(lib_kernel_idct_gen5)} 297428d7b3dSmrg}; 298428d7b3dSmrg 299428d7b3dSmrg#define MEDIA_KERNEL_NUM (sizeof(media_kernels)/sizeof(media_kernels[0])) 300428d7b3dSmrg 301428d7b3dSmrgstruct media_kernel_obj { 302428d7b3dSmrg dri_bo *bo; 303428d7b3dSmrg}; 304428d7b3dSmrg 305428d7b3dSmrgstruct interface_descriptor_obj { 306428d7b3dSmrg dri_bo *bo; 307428d7b3dSmrg struct media_kernel_obj kernels[MEDIA_KERNEL_NUM]; 308428d7b3dSmrg}; 309428d7b3dSmrg 310428d7b3dSmrgstruct vfe_state_obj { 311428d7b3dSmrg dri_bo *bo; 312428d7b3dSmrg struct interface_descriptor_obj interface; 313428d7b3dSmrg}; 314428d7b3dSmrg 315428d7b3dSmrgstruct vld_state_obj { 316428d7b3dSmrg dri_bo *bo; 317428d7b3dSmrg}; 318428d7b3dSmrg 319428d7b3dSmrgstruct surface_obj { 320428d7b3dSmrg dri_bo *bo; 321428d7b3dSmrg}; 322428d7b3dSmrg 323428d7b3dSmrgstruct surface_state_obj { 324428d7b3dSmrg struct surface_obj surface; 325428d7b3dSmrg dri_bo *bo; 326428d7b3dSmrg}; 327428d7b3dSmrg 328428d7b3dSmrg#define MAX_SURFACES 12 329428d7b3dSmrgstruct binding_table_obj { 330428d7b3dSmrg dri_bo *bo; 331428d7b3dSmrg struct surface_state_obj surface_states[MAX_SURFACES]; 332428d7b3dSmrg}; 333428d7b3dSmrg 334428d7b3dSmrgstruct slice_data_obj { 335428d7b3dSmrg dri_bo *bo; 336428d7b3dSmrg}; 337428d7b3dSmrg 338428d7b3dSmrgstruct mb_data_obj { 339428d7b3dSmrg dri_bo *bo; 340428d7b3dSmrg}; 341428d7b3dSmrg 342428d7b3dSmrgstruct cs_state_obj { 343428d7b3dSmrg dri_bo *bo; 344428d7b3dSmrg}; 345428d7b3dSmrg 346428d7b3dSmrgstatic struct media_state { 347428d7b3dSmrg struct vfe_state_obj vfe_state; 348428d7b3dSmrg struct vld_state_obj vld_state; 349428d7b3dSmrg struct binding_table_obj binding_table; 350428d7b3dSmrg struct cs_state_obj cs_object; 351428d7b3dSmrg struct slice_data_obj slice_data; 352428d7b3dSmrg struct mb_data_obj mb_data; 353428d7b3dSmrg} media_state; 354428d7b3dSmrg 355428d7b3dSmrg/* XvMCQMatrix * 2 + idct_table + 8 * kernel offset pointer */ 356428d7b3dSmrg#define CS_OBJECT_SIZE (32*20 + sizeof(unsigned int) * 8) 357428d7b3dSmrgstatic void free_object(struct media_state *s) 358428d7b3dSmrg{ 359428d7b3dSmrg int i; 360428d7b3dSmrg#define FREE_ONE_BO(bo) \ 361428d7b3dSmrg if (bo) \ 362428d7b3dSmrg drm_intel_bo_unreference(bo) 363428d7b3dSmrg FREE_ONE_BO(s->vfe_state.bo); 364428d7b3dSmrg FREE_ONE_BO(s->vfe_state.interface.bo); 365428d7b3dSmrg for (i = 0; i < MEDIA_KERNEL_NUM; i++) 366428d7b3dSmrg FREE_ONE_BO(s->vfe_state.interface.kernels[i].bo); 367428d7b3dSmrg FREE_ONE_BO(s->binding_table.bo); 368428d7b3dSmrg for (i = 0; i < MAX_SURFACES; i++) 369428d7b3dSmrg FREE_ONE_BO(s->binding_table.surface_states[i].bo); 370428d7b3dSmrg FREE_ONE_BO(s->slice_data.bo); 371428d7b3dSmrg FREE_ONE_BO(s->mb_data.bo); 372428d7b3dSmrg FREE_ONE_BO(s->cs_object.bo); 373428d7b3dSmrg FREE_ONE_BO(s->vld_state.bo); 374428d7b3dSmrg} 375428d7b3dSmrg 376428d7b3dSmrgstatic int alloc_object(struct media_state *s) 377428d7b3dSmrg{ 378428d7b3dSmrg int i; 379428d7b3dSmrg 380428d7b3dSmrg for (i = 0; i < MAX_SURFACES; i++) { 381428d7b3dSmrg s->binding_table.surface_states[i].bo = 382428d7b3dSmrg drm_intel_bo_alloc(xvmc_driver->bufmgr, "surface_state", 383428d7b3dSmrg sizeof(struct brw_surface_state), 384428d7b3dSmrg 0x1000); 385428d7b3dSmrg if (!s->binding_table.surface_states[i].bo) 386428d7b3dSmrg goto out; 387428d7b3dSmrg } 388428d7b3dSmrg return 0; 389428d7b3dSmrgout: 390428d7b3dSmrg free_object(s); 391428d7b3dSmrg return BadAlloc; 392428d7b3dSmrg} 393428d7b3dSmrg 394428d7b3dSmrgstatic void flush() 395428d7b3dSmrg{ 396428d7b3dSmrg#define FLUSH_STATE_CACHE 1 397428d7b3dSmrg struct brw_mi_flush f; 398428d7b3dSmrg memset(&f, 0, sizeof(f)); 399428d7b3dSmrg f.opcode = CMD_MI_FLUSH; 400428d7b3dSmrg f.flags = (1 << FLUSH_STATE_CACHE); 401428d7b3dSmrg BATCH_STRUCT(f); 402428d7b3dSmrg} 403428d7b3dSmrg 404428d7b3dSmrgstatic Status vfe_state(int vfe_mode) 405428d7b3dSmrg{ 406428d7b3dSmrg struct brw_vfe_state tmp, *vfe_state = &tmp; 407428d7b3dSmrg memset(vfe_state, 0, sizeof(*vfe_state)); 408428d7b3dSmrg if (vfe_mode == VFE_VLD_MODE) { 409428d7b3dSmrg vfe_state->vfe0.extend_vfe_state_present = 1; 410428d7b3dSmrg } else { 411428d7b3dSmrg vfe_state->vfe0.extend_vfe_state_present = 0; 412428d7b3dSmrg } 413428d7b3dSmrg vfe_state->vfe1.vfe_mode = vfe_mode; 414428d7b3dSmrg vfe_state->vfe1.num_urb_entries = 1; 415428d7b3dSmrg vfe_state->vfe1.children_present = 0; 416428d7b3dSmrg vfe_state->vfe1.urb_entry_alloc_size = 2; 417428d7b3dSmrg vfe_state->vfe1.max_threads = 31; 418428d7b3dSmrg vfe_state->vfe2.interface_descriptor_base = 419428d7b3dSmrg media_state.vfe_state.interface.bo->offset >> 4; 420428d7b3dSmrg 421428d7b3dSmrg if (media_state.vfe_state.bo) 422428d7b3dSmrg drm_intel_bo_unreference(media_state.vfe_state.bo); 423428d7b3dSmrg 424428d7b3dSmrg media_state.vfe_state.bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, 425428d7b3dSmrg "vfe state", 426428d7b3dSmrg sizeof(struct 427428d7b3dSmrg brw_vfe_state), 428428d7b3dSmrg 0x1000); 429428d7b3dSmrg if (!media_state.vfe_state.bo) 430428d7b3dSmrg return BadAlloc; 431428d7b3dSmrg 432428d7b3dSmrg drm_intel_bo_subdata(media_state.vfe_state.bo, 0, sizeof(tmp), &tmp); 433428d7b3dSmrg 434428d7b3dSmrg drm_intel_bo_emit_reloc(media_state.vfe_state.bo, 435428d7b3dSmrg offsetof(struct brw_vfe_state, vfe2), 436428d7b3dSmrg media_state.vfe_state.interface.bo, 0, 437428d7b3dSmrg I915_GEM_DOMAIN_INSTRUCTION, 0); 438428d7b3dSmrg return Success; 439428d7b3dSmrg} 440428d7b3dSmrg 441428d7b3dSmrgstatic Status interface_descriptor() 442428d7b3dSmrg{ 443428d7b3dSmrg int i; 444428d7b3dSmrg struct brw_interface_descriptor tmp, *desc = &tmp; 445428d7b3dSmrg 446428d7b3dSmrg if (media_state.vfe_state.interface.bo) 447428d7b3dSmrg drm_intel_bo_unreference(media_state.vfe_state.interface.bo); 448428d7b3dSmrg 449428d7b3dSmrg media_state.vfe_state.interface.bo = 450428d7b3dSmrg drm_intel_bo_alloc(xvmc_driver->bufmgr, "interfaces", 451428d7b3dSmrg MEDIA_KERNEL_NUM * 452428d7b3dSmrg sizeof(struct brw_interface_descriptor), 0x1000); 453428d7b3dSmrg if (!media_state.vfe_state.interface.bo) 454428d7b3dSmrg return BadAlloc; 455428d7b3dSmrg 456428d7b3dSmrg for (i = 0; i < MEDIA_KERNEL_NUM; i++) { 457428d7b3dSmrg memset(desc, 0, sizeof(*desc)); 458428d7b3dSmrg desc->desc0.grf_reg_blocks = 15; 459428d7b3dSmrg desc->desc0.kernel_start_pointer = 460428d7b3dSmrg media_state.vfe_state.interface.kernels[i].bo->offset >> 6; 461428d7b3dSmrg 462428d7b3dSmrg desc->desc1.const_urb_entry_read_offset = 0; 463428d7b3dSmrg desc->desc1.const_urb_entry_read_len = 30; 464428d7b3dSmrg 465428d7b3dSmrg desc->desc3.binding_table_entry_count = MAX_SURFACES - 1; 466428d7b3dSmrg desc->desc3.binding_table_pointer = 467428d7b3dSmrg media_state.binding_table.bo->offset >> 5; 468428d7b3dSmrg 469428d7b3dSmrg drm_intel_bo_subdata(media_state.vfe_state.interface.bo, 470428d7b3dSmrg i * sizeof(tmp), sizeof(tmp), desc); 471428d7b3dSmrg 472428d7b3dSmrg drm_intel_bo_emit_reloc(media_state.vfe_state.interface.bo, 473428d7b3dSmrg i * sizeof(*desc) + offsetof(struct 474428d7b3dSmrg brw_interface_descriptor, 475428d7b3dSmrg desc0), 476428d7b3dSmrg media_state.vfe_state. 477428d7b3dSmrg interface.kernels[i].bo, 478428d7b3dSmrg desc->desc0.grf_reg_blocks, 479428d7b3dSmrg I915_GEM_DOMAIN_INSTRUCTION, 0); 480428d7b3dSmrg 481428d7b3dSmrg drm_intel_bo_emit_reloc(media_state.vfe_state.interface.bo, 482428d7b3dSmrg i * sizeof(*desc) + offsetof(struct 483428d7b3dSmrg brw_interface_descriptor, 484428d7b3dSmrg desc3), 485428d7b3dSmrg media_state.binding_table.bo, 486428d7b3dSmrg desc->desc3.binding_table_entry_count, 487428d7b3dSmrg I915_GEM_DOMAIN_INSTRUCTION, 0); 488428d7b3dSmrg } 489428d7b3dSmrg return Success; 490428d7b3dSmrg} 491428d7b3dSmrg 492428d7b3dSmrgstatic int setup_media_kernels(struct intel_xvmc_hw_context *ctx) 493428d7b3dSmrg{ 494428d7b3dSmrg int i; 495428d7b3dSmrg 496428d7b3dSmrg assert(MEDIA_KERNEL_NUM == 497428d7b3dSmrg sizeof(media_gen5_kernels) / sizeof(media_gen5_kernels[0])); 498428d7b3dSmrg 499428d7b3dSmrg for (i = 0; i < MEDIA_KERNEL_NUM; i++) { 500428d7b3dSmrg if (ctx->i965.is_igdng) 501428d7b3dSmrg media_state.vfe_state.interface.kernels[i].bo = 502428d7b3dSmrg drm_intel_bo_alloc(xvmc_driver->bufmgr, "kernel", 503428d7b3dSmrg media_gen5_kernels[i].size, 504428d7b3dSmrg 0x1000); 505428d7b3dSmrg else 506428d7b3dSmrg media_state.vfe_state.interface.kernels[i].bo = 507428d7b3dSmrg drm_intel_bo_alloc(xvmc_driver->bufmgr, "kernels", 508428d7b3dSmrg media_kernels[i].size, 0x1000); 509428d7b3dSmrg 510428d7b3dSmrg if (!media_state.vfe_state.interface.kernels[i].bo) 511428d7b3dSmrg goto out; 512428d7b3dSmrg } 513428d7b3dSmrg 514428d7b3dSmrg for (i = 0; i < MEDIA_KERNEL_NUM; i++) { 515428d7b3dSmrg dri_bo *bo = media_state.vfe_state.interface.kernels[i].bo; 516428d7b3dSmrg 517428d7b3dSmrg if (ctx->i965.is_igdng) 518428d7b3dSmrg drm_intel_bo_subdata(bo, 0, media_gen5_kernels[i].size, 519428d7b3dSmrg media_gen5_kernels[i].bin); 520428d7b3dSmrg else 521428d7b3dSmrg drm_intel_bo_subdata(bo, 0, media_kernels[i].size, 522428d7b3dSmrg media_kernels[i].bin); 523428d7b3dSmrg } 524428d7b3dSmrg return 0; 525428d7b3dSmrgout: 526428d7b3dSmrg free_object(&media_state); 527428d7b3dSmrg return BadAlloc; 528428d7b3dSmrg} 529428d7b3dSmrg 530428d7b3dSmrgstatic Status binding_tables() 531428d7b3dSmrg{ 532428d7b3dSmrg unsigned int table[MAX_SURFACES]; 533428d7b3dSmrg int i; 534428d7b3dSmrg 535428d7b3dSmrg if (media_state.binding_table.bo) 536428d7b3dSmrg drm_intel_bo_unreference(media_state.binding_table.bo); 537428d7b3dSmrg media_state.binding_table.bo = 538428d7b3dSmrg drm_intel_bo_alloc(xvmc_driver->bufmgr, "binding_table", 539428d7b3dSmrg MAX_SURFACES * 4, 0x1000); 540428d7b3dSmrg if (!media_state.binding_table.bo) 541428d7b3dSmrg return BadAlloc; 542428d7b3dSmrg 543428d7b3dSmrg for (i = 0; i < MAX_SURFACES; i++) { 544428d7b3dSmrg table[i] = 545428d7b3dSmrg media_state.binding_table.surface_states[i].bo->offset; 546428d7b3dSmrg drm_intel_bo_emit_reloc(media_state.binding_table.bo, 547428d7b3dSmrg i * sizeof(unsigned int), 548428d7b3dSmrg media_state. 549428d7b3dSmrg binding_table.surface_states[i].bo, 0, 550428d7b3dSmrg I915_GEM_DOMAIN_INSTRUCTION, 0); 551428d7b3dSmrg } 552428d7b3dSmrg 553428d7b3dSmrg drm_intel_bo_subdata(media_state.binding_table.bo, 0, sizeof(table), 554428d7b3dSmrg table); 555428d7b3dSmrg return Success; 556428d7b3dSmrg} 557428d7b3dSmrg 558428d7b3dSmrgstatic Status cs_init(int interface_offset) 559428d7b3dSmrg{ 560428d7b3dSmrg char buf[CS_OBJECT_SIZE]; 561428d7b3dSmrg unsigned int *lib_reloc; 562428d7b3dSmrg int i; 563428d7b3dSmrg 564428d7b3dSmrg if (media_state.cs_object.bo) 565428d7b3dSmrg drm_intel_bo_unreference(media_state.cs_object.bo); 566428d7b3dSmrg 567428d7b3dSmrg media_state.cs_object.bo = 568428d7b3dSmrg drm_intel_bo_alloc(xvmc_driver->bufmgr, "cs object", CS_OBJECT_SIZE, 569428d7b3dSmrg 64); 570428d7b3dSmrg if (!media_state.cs_object.bo) 571428d7b3dSmrg return BadAlloc; 572428d7b3dSmrg 573428d7b3dSmrg memcpy(buf + 32 * 4, idct_table, sizeof(idct_table)); 574428d7b3dSmrg /* idct lib reloction */ 575428d7b3dSmrg lib_reloc = (unsigned int *)(buf + 32 * 20); 576428d7b3dSmrg for (i = 0; i < 8; i++) 577428d7b3dSmrg lib_reloc[i] = 578428d7b3dSmrg media_state.vfe_state.interface.kernels[LIB_INTERFACE + 579428d7b3dSmrg interface_offset].bo-> 580428d7b3dSmrg offset; 581428d7b3dSmrg drm_intel_bo_subdata(media_state.cs_object.bo, 32 * 4, 582428d7b3dSmrg 32 * 16 + 8 * sizeof(unsigned int), buf + 32 * 4); 583428d7b3dSmrg 584428d7b3dSmrg for (i = 0; i < 8; i++) 585428d7b3dSmrg drm_intel_bo_emit_reloc(media_state.cs_object.bo, 586428d7b3dSmrg 32 * 20 + sizeof(unsigned int) * i, 587428d7b3dSmrg media_state.vfe_state. 588428d7b3dSmrg interface.kernels[LIB_INTERFACE + 589428d7b3dSmrg interface_offset].bo, 590428d7b3dSmrg 0, I915_GEM_DOMAIN_INSTRUCTION, 0); 591428d7b3dSmrg 592428d7b3dSmrg return Success; 593428d7b3dSmrg} 594428d7b3dSmrg 595428d7b3dSmrg#define STRIDE(w) (w) 596428d7b3dSmrg#define SIZE_YUV420(w, h) (h * (STRIDE(w) + STRIDE(w >> 1))) 597428d7b3dSmrgstatic Status create_context(Display * display, XvMCContext * context, 598428d7b3dSmrg int priv_count, CARD32 * priv_data) 599428d7b3dSmrg{ 600428d7b3dSmrg struct intel_xvmc_context *intel_ctx; 601428d7b3dSmrg struct intel_xvmc_hw_context *hw_ctx; 602428d7b3dSmrg hw_ctx = (struct intel_xvmc_hw_context *)priv_data; 603428d7b3dSmrg 604428d7b3dSmrg intel_ctx = calloc(1, sizeof(struct intel_xvmc_context)); 605428d7b3dSmrg if (!intel_ctx) 606428d7b3dSmrg return BadAlloc; 607428d7b3dSmrg intel_ctx->hw = hw_ctx; 608428d7b3dSmrg context->privData = intel_ctx; 609428d7b3dSmrg intel_ctx->surface_bo_size 610428d7b3dSmrg = SIZE_YUV420(context->width, context->height); 611428d7b3dSmrg 612428d7b3dSmrg if (alloc_object(&media_state)) 613428d7b3dSmrg return BadAlloc; 614428d7b3dSmrg 615428d7b3dSmrg if (setup_media_kernels(hw_ctx)) 616428d7b3dSmrg return BadAlloc; 617428d7b3dSmrg return Success; 618428d7b3dSmrg} 619428d7b3dSmrg 620428d7b3dSmrgstatic Status destroy_context(Display * display, XvMCContext * context) 621428d7b3dSmrg{ 622428d7b3dSmrg struct intel_xvmc_context *intel_ctx; 623428d7b3dSmrg intel_ctx = context->privData; 624428d7b3dSmrg free(intel_ctx->hw); 625428d7b3dSmrg free(intel_ctx); 626428d7b3dSmrg return Success; 627428d7b3dSmrg} 628428d7b3dSmrg 629428d7b3dSmrgstatic Status load_qmatrix(Display * display, XvMCContext * context, 630428d7b3dSmrg const XvMCQMatrix * qmx) 631428d7b3dSmrg{ 632428d7b3dSmrg Status ret; 633428d7b3dSmrg ret = cs_init(0); 634428d7b3dSmrg if (ret != Success) 635428d7b3dSmrg return ret; 636428d7b3dSmrg drm_intel_bo_subdata(media_state.cs_object.bo, 0, 64, 637428d7b3dSmrg qmx->intra_quantiser_matrix); 638428d7b3dSmrg drm_intel_bo_subdata(media_state.cs_object.bo, 64, 64, 639428d7b3dSmrg qmx->non_intra_quantiser_matrix); 640428d7b3dSmrg 641428d7b3dSmrg return Success; 642428d7b3dSmrg} 643428d7b3dSmrg 644428d7b3dSmrgstatic Status vld_state(const XvMCMpegControl * control) 645428d7b3dSmrg{ 646428d7b3dSmrg struct brw_vld_state tmp, *vld = &tmp; 647428d7b3dSmrg 648428d7b3dSmrg if (media_state.vld_state.bo) 649428d7b3dSmrg drm_intel_bo_unreference(media_state.vld_state.bo); 650428d7b3dSmrg media_state.vld_state.bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, 651428d7b3dSmrg "vld state", 652428d7b3dSmrg sizeof(struct 653428d7b3dSmrg brw_vld_state), 654428d7b3dSmrg 64); 655428d7b3dSmrg if (!media_state.vld_state.bo) 656428d7b3dSmrg return BadAlloc; 657428d7b3dSmrg 658428d7b3dSmrg memset(vld, 0, sizeof(*vld)); 659428d7b3dSmrg vld->vld0.f_code_0_0 = control->FHMV_range + 1; 660428d7b3dSmrg vld->vld0.f_code_0_1 = control->FVMV_range + 1; 661428d7b3dSmrg vld->vld0.f_code_1_0 = control->BHMV_range + 1; 662428d7b3dSmrg vld->vld0.f_code_1_1 = control->BVMV_range + 1; 663428d7b3dSmrg vld->vld0.intra_dc_precision = control->intra_dc_precision; 664428d7b3dSmrg vld->vld0.picture_structure = control->picture_structure; 665428d7b3dSmrg vld->vld0.top_field_first = !!(control->flags & XVMC_TOP_FIELD_FIRST); 666428d7b3dSmrg vld->vld0.frame_predict_frame_dct = 667428d7b3dSmrg !!(control->flags & XVMC_PRED_DCT_FRAME); 668428d7b3dSmrg vld->vld0.concealment_motion_vector = 669428d7b3dSmrg !!(control->flags & XVMC_CONCEALMENT_MOTION_VECTORS); 670428d7b3dSmrg vld->vld0.quantizer_scale_type = !!(control->flags & XVMC_Q_SCALE_TYPE); 671428d7b3dSmrg vld->vld0.intra_vlc_format = !!(control->flags & XVMC_INTRA_VLC_FORMAT); 672428d7b3dSmrg vld->vld0.scan_order = !!(control->flags & XVMC_ALTERNATE_SCAN); 673428d7b3dSmrg 674428d7b3dSmrg vld->vld1.picture_coding_type = control->picture_coding_type; 675428d7b3dSmrg 676428d7b3dSmrg vld->desc_remap_table0.index_0 = FRAME_INTRA; 677428d7b3dSmrg vld->desc_remap_table0.index_1 = FRAME_FRAME_PRED_FORWARD; 678428d7b3dSmrg vld->desc_remap_table0.index_2 = FRAME_FIELD_PRED_FORWARD; 679428d7b3dSmrg vld->desc_remap_table0.index_3 = FRAME_FIELD_PRED_BIDIRECT; /* dual prime */ 680428d7b3dSmrg vld->desc_remap_table0.index_4 = FRAME_FRAME_PRED_BACKWARD; 681428d7b3dSmrg vld->desc_remap_table0.index_5 = FRAME_FIELD_PRED_BACKWARD; 682428d7b3dSmrg vld->desc_remap_table0.index_6 = FRAME_FRAME_PRED_BIDIRECT; 683428d7b3dSmrg vld->desc_remap_table0.index_7 = FRAME_FIELD_PRED_BIDIRECT; 684428d7b3dSmrg 685428d7b3dSmrg vld->desc_remap_table1.index_8 = FRAME_INTRA; 686428d7b3dSmrg vld->desc_remap_table1.index_9 = FRAME_FRAME_PRED_FORWARD; 687428d7b3dSmrg vld->desc_remap_table1.index_10 = FRAME_FIELD_PRED_FORWARD; 688428d7b3dSmrg vld->desc_remap_table1.index_11 = FRAME_FIELD_PRED_BIDIRECT; 689428d7b3dSmrg vld->desc_remap_table1.index_12 = FRAME_FRAME_PRED_BACKWARD; 690428d7b3dSmrg vld->desc_remap_table1.index_13 = FRAME_FIELD_PRED_BACKWARD; 691428d7b3dSmrg vld->desc_remap_table1.index_14 = FRAME_FRAME_PRED_BIDIRECT; 692428d7b3dSmrg vld->desc_remap_table1.index_15 = FRAME_FIELD_PRED_BIDIRECT; 693428d7b3dSmrg 694428d7b3dSmrg drm_intel_bo_subdata(media_state.vld_state.bo, 0, sizeof(tmp), vld); 695428d7b3dSmrg return Success; 696428d7b3dSmrg} 697428d7b3dSmrg 698428d7b3dSmrgstatic Status setup_media_surface(int index, dri_bo * bo, 699428d7b3dSmrg unsigned long offset, int w, int h, 700428d7b3dSmrg Bool write) 701428d7b3dSmrg{ 702428d7b3dSmrg struct brw_surface_state tmp, *ss = &tmp; 703428d7b3dSmrg memset(ss, 0, sizeof(*ss)); 704428d7b3dSmrg ss->ss0.surface_type = BRW_SURFACE_2D; 705428d7b3dSmrg ss->ss0.surface_format = BRW_SURFACEFORMAT_R8_SINT; 706428d7b3dSmrg ss->ss1.base_addr = offset + bo->offset; 707428d7b3dSmrg ss->ss2.width = w - 1; 708428d7b3dSmrg ss->ss2.height = h - 1; 709428d7b3dSmrg ss->ss3.pitch = w - 1; 710428d7b3dSmrg 711428d7b3dSmrg if (media_state.binding_table.surface_states[index].bo) 712428d7b3dSmrg drm_intel_bo_unreference(media_state. 713428d7b3dSmrg binding_table.surface_states[index]. 714428d7b3dSmrg bo); 715428d7b3dSmrg 716428d7b3dSmrg media_state.binding_table.surface_states[index].bo = 717428d7b3dSmrg drm_intel_bo_alloc(xvmc_driver->bufmgr, "surface_state", 718428d7b3dSmrg sizeof(struct brw_surface_state), 0x1000); 719428d7b3dSmrg if (!media_state.binding_table.surface_states[index].bo) 720428d7b3dSmrg return BadAlloc; 721428d7b3dSmrg 722428d7b3dSmrg drm_intel_bo_subdata(media_state.binding_table.surface_states[index].bo, 723428d7b3dSmrg 0, sizeof(*ss), ss); 724428d7b3dSmrg drm_intel_bo_emit_reloc(media_state.binding_table. 725428d7b3dSmrg surface_states[index].bo, 726428d7b3dSmrg offsetof(struct brw_surface_state, ss1), bo, 727428d7b3dSmrg offset, I915_GEM_DOMAIN_RENDER, 728428d7b3dSmrg write ? I915_GEM_DOMAIN_RENDER : 0); 729428d7b3dSmrg return Success; 730428d7b3dSmrg} 731428d7b3dSmrg 732428d7b3dSmrgstatic Status setup_surface(struct intel_xvmc_surface *target, 733428d7b3dSmrg struct intel_xvmc_surface *past, 734428d7b3dSmrg struct intel_xvmc_surface *future, int w, int h) 735428d7b3dSmrg{ 736428d7b3dSmrg Status ret; 737428d7b3dSmrg ret = setup_media_surface(0, target->bo, 0, w, h, TRUE); 738428d7b3dSmrg if (ret != Success) 739428d7b3dSmrg return ret; 740428d7b3dSmrg ret = setup_media_surface(1, target->bo, w * h, w / 2, h / 2, TRUE); 741428d7b3dSmrg if (ret != Success) 742428d7b3dSmrg return ret; 743428d7b3dSmrg ret = 744428d7b3dSmrg setup_media_surface(2, target->bo, w * h + w * h / 4, w / 2, h / 2, 745428d7b3dSmrg TRUE); 746428d7b3dSmrg if (ret != Success) 747428d7b3dSmrg return ret; 748428d7b3dSmrg if (past) { 749428d7b3dSmrg ret = setup_media_surface(4, past->bo, 0, w, h, FALSE); 750428d7b3dSmrg if (ret != Success) 751428d7b3dSmrg return ret; 752428d7b3dSmrg ret = 753428d7b3dSmrg setup_media_surface(5, past->bo, w * h, w / 2, h / 2, 754428d7b3dSmrg FALSE); 755428d7b3dSmrg if (ret != Success) 756428d7b3dSmrg return ret; 757428d7b3dSmrg ret = 758428d7b3dSmrg setup_media_surface(6, past->bo, w * h + w * h / 4, w / 2, 759428d7b3dSmrg h / 2, FALSE); 760428d7b3dSmrg if (ret != Success) 761428d7b3dSmrg return ret; 762428d7b3dSmrg } 763428d7b3dSmrg if (future) { 764428d7b3dSmrg ret = setup_media_surface(7, future->bo, 0, w, h, FALSE); 765428d7b3dSmrg if (ret != Success) 766428d7b3dSmrg return ret; 767428d7b3dSmrg ret = 768428d7b3dSmrg setup_media_surface(8, future->bo, w * h, w / 2, h / 2, 769428d7b3dSmrg FALSE); 770428d7b3dSmrg if (ret != Success) 771428d7b3dSmrg return ret; 772428d7b3dSmrg ret = 773428d7b3dSmrg setup_media_surface(9, future->bo, w * h + w * h / 4, w / 2, 774428d7b3dSmrg h / 2, FALSE); 775428d7b3dSmrg if (ret != Success) 776428d7b3dSmrg return ret; 777428d7b3dSmrg } 778428d7b3dSmrg return Success; 779428d7b3dSmrg} 780428d7b3dSmrg 781428d7b3dSmrgstatic Status begin_surface(Display * display, XvMCContext * context, 782428d7b3dSmrg XvMCSurface * target, 783428d7b3dSmrg XvMCSurface * past, 784428d7b3dSmrg XvMCSurface * future, 785428d7b3dSmrg const XvMCMpegControl * control) 786428d7b3dSmrg{ 787428d7b3dSmrg struct intel_xvmc_surface *priv_target, *priv_past, *priv_future; 788428d7b3dSmrg intel_xvmc_context_ptr intel_ctx = context->privData; 789428d7b3dSmrg Status ret; 790428d7b3dSmrg 791428d7b3dSmrg priv_target = target->privData; 792428d7b3dSmrg priv_past = past ? past->privData : NULL; 793428d7b3dSmrg priv_future = future ? future->privData : NULL; 794428d7b3dSmrg 795428d7b3dSmrg ret = vld_state(control); 796428d7b3dSmrg if (ret != Success) 797428d7b3dSmrg return ret; 798428d7b3dSmrg ret = setup_surface(priv_target, priv_past, priv_future, 799428d7b3dSmrg context->width, context->height); 800428d7b3dSmrg if (ret != Success) 801428d7b3dSmrg return ret; 802428d7b3dSmrg ret = binding_tables(); 803428d7b3dSmrg if (ret != Success) 804428d7b3dSmrg return ret; 805428d7b3dSmrg ret = interface_descriptor(); 806428d7b3dSmrg if (ret != Success) 807428d7b3dSmrg return ret; 808428d7b3dSmrg ret = vfe_state(VFE_VLD_MODE); 809428d7b3dSmrg if (ret != Success) 810428d7b3dSmrg return ret; 811428d7b3dSmrg 812428d7b3dSmrg LOCK_HARDWARE(intel_ctx->hw_context); 813428d7b3dSmrg flush(); 814428d7b3dSmrg UNLOCK_HARDWARE(intel_ctx->hw_context); 815428d7b3dSmrg return Success; 816428d7b3dSmrg} 817428d7b3dSmrg 818428d7b3dSmrgstatic Status put_slice(Display * display, XvMCContext * context, 819428d7b3dSmrg unsigned char *slice, int nbytes) 820428d7b3dSmrg{ 821428d7b3dSmrg return Success; 822428d7b3dSmrg} 823428d7b3dSmrg 824428d7b3dSmrgstatic void state_base_address(struct intel_xvmc_hw_context *ctx) 825428d7b3dSmrg{ 826428d7b3dSmrg BATCH_LOCALS; 827428d7b3dSmrg 828428d7b3dSmrg if (ctx->i965.is_igdng) { 829428d7b3dSmrg BEGIN_BATCH(8); 830428d7b3dSmrg OUT_BATCH(BRW_STATE_BASE_ADDRESS | 6); 831428d7b3dSmrg OUT_BATCH(0 | BASE_ADDRESS_MODIFY); 832428d7b3dSmrg OUT_BATCH(0 | BASE_ADDRESS_MODIFY); 833428d7b3dSmrg OUT_BATCH(0 | BASE_ADDRESS_MODIFY); 834428d7b3dSmrg OUT_BATCH(0 | BASE_ADDRESS_MODIFY); 835428d7b3dSmrg OUT_BATCH(0 | BASE_ADDRESS_MODIFY); 836428d7b3dSmrg OUT_BATCH(0 | BASE_ADDRESS_MODIFY); 837428d7b3dSmrg OUT_BATCH(0 | BASE_ADDRESS_MODIFY); 838428d7b3dSmrg ADVANCE_BATCH(); 839428d7b3dSmrg } else { 840428d7b3dSmrg BEGIN_BATCH(6); 841428d7b3dSmrg OUT_BATCH(BRW_STATE_BASE_ADDRESS | 4); 842428d7b3dSmrg OUT_BATCH(0 | BASE_ADDRESS_MODIFY); 843428d7b3dSmrg OUT_BATCH(0 | BASE_ADDRESS_MODIFY); 844428d7b3dSmrg OUT_BATCH(0 | BASE_ADDRESS_MODIFY); 845428d7b3dSmrg OUT_BATCH(0 | BASE_ADDRESS_MODIFY); 846428d7b3dSmrg OUT_BATCH(0 | BASE_ADDRESS_MODIFY); 847428d7b3dSmrg ADVANCE_BATCH(); 848428d7b3dSmrg } 849428d7b3dSmrg} 850428d7b3dSmrg 851428d7b3dSmrgstatic void pipeline_select() 852428d7b3dSmrg{ 853428d7b3dSmrg BATCH_LOCALS; 854428d7b3dSmrg BEGIN_BATCH(1); 855428d7b3dSmrg OUT_BATCH(NEW_PIPELINE_SELECT | PIPELINE_SELECT_MEDIA); 856428d7b3dSmrg ADVANCE_BATCH(); 857428d7b3dSmrg} 858428d7b3dSmrg 859428d7b3dSmrgstatic void media_state_pointers(int vfe_mode) 860428d7b3dSmrg{ 861428d7b3dSmrg BATCH_LOCALS; 862428d7b3dSmrg BEGIN_BATCH(3); 863428d7b3dSmrg OUT_BATCH(BRW_MEDIA_STATE_POINTERS | 1); 864428d7b3dSmrg if (vfe_mode == VFE_VLD_MODE) 865428d7b3dSmrg OUT_RELOC(media_state.vld_state.bo, I915_GEM_DOMAIN_INSTRUCTION, 866428d7b3dSmrg 0, 1); 867428d7b3dSmrg else 868428d7b3dSmrg OUT_BATCH(0); 869428d7b3dSmrg OUT_RELOC(media_state.vfe_state.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); 870428d7b3dSmrg ADVANCE_BATCH(); 871428d7b3dSmrg} 872428d7b3dSmrg 873428d7b3dSmrgstatic void align_urb_fence() 874428d7b3dSmrg{ 875428d7b3dSmrg BATCH_LOCALS; 876428d7b3dSmrg int i, offset_to_next_cacheline; 877428d7b3dSmrg unsigned long batch_offset; 878428d7b3dSmrg BEGIN_BATCH(3); 879428d7b3dSmrg batch_offset = (void *)batch_ptr - xvmc_driver->alloc.ptr; 880428d7b3dSmrg offset_to_next_cacheline = ALIGN(batch_offset, 64) - batch_offset; 881428d7b3dSmrg if (offset_to_next_cacheline <= 12 && offset_to_next_cacheline != 0) { 882428d7b3dSmrg for (i = 0; i < offset_to_next_cacheline / 4; i++) 883428d7b3dSmrg OUT_BATCH(0); 884428d7b3dSmrg ADVANCE_BATCH(); 885428d7b3dSmrg } 886428d7b3dSmrg} 887428d7b3dSmrg 888428d7b3dSmrgstatic void urb_layout() 889428d7b3dSmrg{ 890428d7b3dSmrg BATCH_LOCALS; 891428d7b3dSmrg align_urb_fence(); 892428d7b3dSmrg BEGIN_BATCH(3); 893428d7b3dSmrg OUT_BATCH(BRW_URB_FENCE | 894428d7b3dSmrg UF0_VFE_REALLOC | 895428d7b3dSmrg UF0_CS_REALLOC | 896428d7b3dSmrg UF0_SF_REALLOC | 897428d7b3dSmrg UF0_CLIP_REALLOC | UF0_GS_REALLOC | UF0_VS_REALLOC | 1); 898428d7b3dSmrg 899428d7b3dSmrg OUT_BATCH((0 << UF1_CLIP_FENCE_SHIFT) | 900428d7b3dSmrg (0 << UF1_GS_FENCE_SHIFT) | (0 << UF1_VS_FENCE_SHIFT)); 901428d7b3dSmrg 902428d7b3dSmrg OUT_BATCH((0 << UF2_CS_FENCE_SHIFT) | (0 << UF2_SF_FENCE_SHIFT) | ((URB_SIZE - CS_SIZE - 1) << UF2_VFE_FENCE_SHIFT) | /* VFE_SIZE */ 903428d7b3dSmrg ((URB_SIZE) << UF2_CS_FENCE_SHIFT)); /* CS_SIZE */ 904428d7b3dSmrg ADVANCE_BATCH(); 905428d7b3dSmrg} 906428d7b3dSmrg 907428d7b3dSmrgstatic void cs_urb_layout() 908428d7b3dSmrg{ 909428d7b3dSmrg BATCH_LOCALS; 910428d7b3dSmrg BEGIN_BATCH(2); 911428d7b3dSmrg OUT_BATCH(BRW_CS_URB_STATE | 0); 912428d7b3dSmrg OUT_BATCH((CS_SIZE << 4) | /* URB Entry Allocation Size */ 913428d7b3dSmrg (1 << 0)); /* Number of URB Entries */ 914428d7b3dSmrg ADVANCE_BATCH(); 915428d7b3dSmrg} 916428d7b3dSmrg 917428d7b3dSmrgstatic void cs_buffer() 918428d7b3dSmrg{ 919428d7b3dSmrg BATCH_LOCALS; 920428d7b3dSmrg BEGIN_BATCH(2); 921428d7b3dSmrg OUT_BATCH(BRW_CONSTANT_BUFFER | 0 | (1 << 8)); 922428d7b3dSmrg OUT_RELOC(media_state.cs_object.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 923428d7b3dSmrg CS_SIZE); 924428d7b3dSmrg ADVANCE_BATCH(); 925428d7b3dSmrg} 926428d7b3dSmrg 927428d7b3dSmrg/* kick media object to gpu in idct mode*/ 928428d7b3dSmrgstatic void send_media_object(XvMCMacroBlock * mb, dri_bo * bo, 929428d7b3dSmrg uint32_t offset, enum interface interface) 930428d7b3dSmrg{ 931428d7b3dSmrg BATCH_LOCALS; 932428d7b3dSmrg BEGIN_BATCH(13); 933428d7b3dSmrg OUT_BATCH(BRW_MEDIA_OBJECT | 11); 934428d7b3dSmrg OUT_BATCH(interface); 935428d7b3dSmrg OUT_BATCH(6 * 128); 936428d7b3dSmrg OUT_RELOC(bo, I915_GEM_DOMAIN_INSTRUCTION, 0, offset); 937428d7b3dSmrg 938428d7b3dSmrg OUT_BATCH(mb->x << 4); 939428d7b3dSmrg OUT_BATCH(mb->y << 4); 940428d7b3dSmrg OUT_RELOC(bo, I915_GEM_DOMAIN_INSTRUCTION, 0, offset); 941428d7b3dSmrg OUT_BATCH_SHORT(mb->coded_block_pattern); 942428d7b3dSmrg OUT_BATCH_SHORT(mb->PMV[0][0][0]); 943428d7b3dSmrg OUT_BATCH_SHORT(mb->PMV[0][0][1]); 944428d7b3dSmrg OUT_BATCH_SHORT(mb->PMV[0][1][0]); 945428d7b3dSmrg OUT_BATCH_SHORT(mb->PMV[0][1][1]); 946428d7b3dSmrg 947428d7b3dSmrg OUT_BATCH_SHORT(mb->PMV[1][0][0]); 948428d7b3dSmrg OUT_BATCH_SHORT(mb->PMV[1][0][1]); 949428d7b3dSmrg OUT_BATCH_SHORT(mb->PMV[1][1][0]); 950428d7b3dSmrg OUT_BATCH_SHORT(mb->PMV[1][1][1]); 951428d7b3dSmrg OUT_BATCH_CHAR(mb->dct_type); 952428d7b3dSmrg OUT_BATCH_CHAR(mb->motion_vertical_field_select); 953428d7b3dSmrg 954428d7b3dSmrg OUT_BATCH(0xffffffff); 955428d7b3dSmrg ADVANCE_BATCH(); 956428d7b3dSmrg} 957428d7b3dSmrg 958428d7b3dSmrg/* kick media object to gpu in vld mode*/ 959428d7b3dSmrgstatic void vld_send_media_object(dri_bo * bo, 960428d7b3dSmrg int slice_len, int mb_h_pos, int mb_v_pos, 961428d7b3dSmrg int mb_bit_offset, int mb_count, 962428d7b3dSmrg int q_scale_code) 963428d7b3dSmrg{ 964428d7b3dSmrg BATCH_LOCALS; 965428d7b3dSmrg BEGIN_BATCH(6); 966428d7b3dSmrg OUT_BATCH(BRW_MEDIA_OBJECT | 4); 967428d7b3dSmrg OUT_BATCH(0); 968428d7b3dSmrg OUT_BATCH(slice_len); 969428d7b3dSmrg OUT_RELOC(bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); 970428d7b3dSmrg OUT_BATCH((mb_h_pos << 24) | (mb_v_pos << 16) | (mb_count << 8) | 971428d7b3dSmrg (mb_bit_offset)); 972428d7b3dSmrg OUT_BATCH(q_scale_code << 24); 973428d7b3dSmrg ADVANCE_BATCH(); 974428d7b3dSmrg} 975428d7b3dSmrg 976428d7b3dSmrgstatic Status put_slice2(Display * display, XvMCContext * context, 977428d7b3dSmrg unsigned char *slice, int nbytes, int sliceCode) 978428d7b3dSmrg{ 979428d7b3dSmrg unsigned int bit_buf; 980428d7b3dSmrg intel_xvmc_context_ptr intel_ctx = context->privData; 981428d7b3dSmrg struct intel_xvmc_hw_context *hw_ctx = intel_ctx->hw; 982428d7b3dSmrg int q_scale_code, mb_row; 983428d7b3dSmrg 984428d7b3dSmrg mb_row = *(slice - 1) - 1; 985428d7b3dSmrg bit_buf = 986428d7b3dSmrg (slice[0] << 24) | (slice[1] << 16) | (slice[2] << 8) | (slice[3]); 987428d7b3dSmrg 988428d7b3dSmrg q_scale_code = bit_buf >> 27; 989428d7b3dSmrg 990428d7b3dSmrg if (media_state.slice_data.bo) { 991428d7b3dSmrg drm_intel_gem_bo_unmap_gtt(media_state.slice_data.bo); 992428d7b3dSmrg 993428d7b3dSmrg drm_intel_bo_unreference(media_state.slice_data.bo); 994428d7b3dSmrg } 995428d7b3dSmrg media_state.slice_data.bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, 996428d7b3dSmrg "slice data", 997428d7b3dSmrg VLD_MAX_SLICE_SIZE, 64); 998428d7b3dSmrg if (!media_state.slice_data.bo) 999428d7b3dSmrg return BadAlloc; 1000428d7b3dSmrg drm_intel_gem_bo_map_gtt(media_state.slice_data.bo); 1001428d7b3dSmrg 1002428d7b3dSmrg memcpy(media_state.slice_data.bo->virtual, slice, nbytes); 1003428d7b3dSmrg 1004428d7b3dSmrg LOCK_HARDWARE(intel_ctx->hw_context); 1005428d7b3dSmrg state_base_address(hw_ctx); 1006428d7b3dSmrg pipeline_select(); 1007428d7b3dSmrg media_state_pointers(VFE_VLD_MODE); 1008428d7b3dSmrg urb_layout(); 1009428d7b3dSmrg cs_urb_layout(); 1010428d7b3dSmrg cs_buffer(); 1011428d7b3dSmrg vld_send_media_object(media_state.slice_data.bo, 1012428d7b3dSmrg nbytes, 0, mb_row, 6, 127, q_scale_code); 1013428d7b3dSmrg intelFlushBatch(); 1014428d7b3dSmrg UNLOCK_HARDWARE(intel_ctx->hw_context); 1015428d7b3dSmrg 1016428d7b3dSmrg return Success; 1017428d7b3dSmrg} 1018428d7b3dSmrg 1019428d7b3dSmrgstatic Status render_surface(Display * display, 1020428d7b3dSmrg XvMCContext * context, 1021428d7b3dSmrg unsigned int picture_structure, 1022428d7b3dSmrg XvMCSurface * target_surface, 1023428d7b3dSmrg XvMCSurface * past_surface, 1024428d7b3dSmrg XvMCSurface * future_surface, 1025428d7b3dSmrg unsigned int flags, 1026428d7b3dSmrg unsigned int num_macroblocks, 1027428d7b3dSmrg unsigned int first_macroblock, 1028428d7b3dSmrg XvMCMacroBlockArray * macroblock_array, 1029428d7b3dSmrg XvMCBlockArray * blocks) 1030428d7b3dSmrg{ 1031428d7b3dSmrg struct intel_xvmc_surface *priv_target, *priv_past, *priv_future; 1032428d7b3dSmrg intel_xvmc_context_ptr intel_ctx; 1033428d7b3dSmrg XvMCMacroBlock *mb; 1034428d7b3dSmrg Status ret; 1035428d7b3dSmrg unsigned short *block_ptr; 1036428d7b3dSmrg int i, j; 1037428d7b3dSmrg int block_offset = 0; 1038428d7b3dSmrg struct intel_xvmc_hw_context *hw_ctx; 1039428d7b3dSmrg 1040428d7b3dSmrg intel_ctx = context->privData; 1041428d7b3dSmrg 1042428d7b3dSmrg hw_ctx = (struct intel_xvmc_hw_context *)context->privData; 1043428d7b3dSmrg priv_target = target_surface->privData; 1044428d7b3dSmrg priv_past = past_surface ? past_surface->privData : NULL; 1045428d7b3dSmrg priv_future = future_surface ? future_surface->privData : NULL; 1046428d7b3dSmrg 1047428d7b3dSmrg ret = setup_surface(priv_target, priv_past, priv_future, 1048428d7b3dSmrg context->width, context->height); 1049428d7b3dSmrg if (ret != Success) 1050428d7b3dSmrg return ret; 1051428d7b3dSmrg ret = binding_tables(); 1052428d7b3dSmrg if (ret != Success) 1053428d7b3dSmrg return ret; 1054428d7b3dSmrg ret = interface_descriptor(); 1055428d7b3dSmrg if (ret != Success) 1056428d7b3dSmrg return ret; 1057428d7b3dSmrg ret = cs_init(INTERFACE_NUM); 1058428d7b3dSmrg if (ret != Success) 1059428d7b3dSmrg return ret; 1060428d7b3dSmrg ret = vfe_state(VFE_GENERIC_MODE); 1061428d7b3dSmrg if (ret != Success) 1062428d7b3dSmrg return ret; 1063428d7b3dSmrg 1064428d7b3dSmrg if (media_state.mb_data.bo) { 1065428d7b3dSmrg drm_intel_gem_bo_unmap_gtt(media_state.mb_data.bo); 1066428d7b3dSmrg 1067428d7b3dSmrg drm_intel_bo_unreference(media_state.mb_data.bo); 1068428d7b3dSmrg } 1069428d7b3dSmrg unsigned int block_num = 1070428d7b3dSmrg (((context->width + 15) >> 4) * ((context->height + 15) >> 4)); 1071428d7b3dSmrg unsigned int surface_size = (64 * sizeof(short) * 6 * block_num); 1072428d7b3dSmrg media_state.mb_data.bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, 1073428d7b3dSmrg "macroblock data", 1074428d7b3dSmrg surface_size, 64); 1075428d7b3dSmrg if (!media_state.mb_data.bo) 1076428d7b3dSmrg return BadAlloc; 1077428d7b3dSmrg drm_intel_gem_bo_map_gtt(media_state.mb_data.bo); 1078428d7b3dSmrg 1079428d7b3dSmrg block_ptr = media_state.mb_data.bo->virtual; 1080428d7b3dSmrg unsigned short *mb_block_ptr; 1081428d7b3dSmrg for (i = first_macroblock; i < num_macroblocks + first_macroblock; i++) { 1082428d7b3dSmrg mb = ¯oblock_array->macro_blocks[i]; 1083428d7b3dSmrg mb_block_ptr = &blocks->blocks[(mb->index << 6)]; 1084428d7b3dSmrg 1085428d7b3dSmrg if (mb->coded_block_pattern & 0x20) { 1086428d7b3dSmrg for (j = 0; j < 8; j++) 1087428d7b3dSmrg memcpy(block_ptr + 16 * j, mb_block_ptr + 8 * j, 1088428d7b3dSmrg 16); 1089428d7b3dSmrg mb_block_ptr += 64; 1090428d7b3dSmrg } 1091428d7b3dSmrg if (mb->coded_block_pattern & 0x10) { 1092428d7b3dSmrg for (j = 0; j < 8; j++) 1093428d7b3dSmrg memcpy(block_ptr + 16 * j + 8, 1094428d7b3dSmrg mb_block_ptr + 8 * j, 16); 1095428d7b3dSmrg mb_block_ptr += 64; 1096428d7b3dSmrg } 1097428d7b3dSmrg 1098428d7b3dSmrg block_ptr += 2 * 64; 1099428d7b3dSmrg if (mb->coded_block_pattern & 0x08) { 1100428d7b3dSmrg for (j = 0; j < 8; j++) 1101428d7b3dSmrg memcpy(block_ptr + 16 * j, mb_block_ptr + 8 * j, 1102428d7b3dSmrg 16); 1103428d7b3dSmrg mb_block_ptr += 64; 1104428d7b3dSmrg } 1105428d7b3dSmrg if (mb->coded_block_pattern & 0x04) { 1106428d7b3dSmrg for (j = 0; j < 8; j++) 1107428d7b3dSmrg memcpy(block_ptr + 16 * j + 8, 1108428d7b3dSmrg mb_block_ptr + 8 * j, 16); 1109428d7b3dSmrg mb_block_ptr += 64; 1110428d7b3dSmrg } 1111428d7b3dSmrg 1112428d7b3dSmrg block_ptr += 2 * 64; 1113428d7b3dSmrg if (mb->coded_block_pattern & 0x2) { 1114428d7b3dSmrg memcpy(block_ptr, mb_block_ptr, 128); 1115428d7b3dSmrg mb_block_ptr += 64; 1116428d7b3dSmrg } 1117428d7b3dSmrg 1118428d7b3dSmrg block_ptr += 64; 1119428d7b3dSmrg if (mb->coded_block_pattern & 0x1) 1120428d7b3dSmrg memcpy(block_ptr, mb_block_ptr, 128); 1121428d7b3dSmrg block_ptr += 64; 1122428d7b3dSmrg } 1123428d7b3dSmrg 1124428d7b3dSmrg LOCK_HARDWARE(intel_ctx->hw_context); 1125428d7b3dSmrg state_base_address(hw_ctx); 1126428d7b3dSmrg flush(); 1127428d7b3dSmrg pipeline_select(); 1128428d7b3dSmrg urb_layout(); 1129428d7b3dSmrg media_state_pointers(VFE_GENERIC_MODE); 1130428d7b3dSmrg cs_urb_layout(); 1131428d7b3dSmrg cs_buffer(); 1132428d7b3dSmrg for (i = first_macroblock; 1133428d7b3dSmrg i < num_macroblocks + first_macroblock; 1134428d7b3dSmrg i++, block_offset += 128 * 6) { 1135428d7b3dSmrg mb = ¯oblock_array->macro_blocks[i]; 1136428d7b3dSmrg 1137428d7b3dSmrg if (mb->macroblock_type & XVMC_MB_TYPE_INTRA) { 1138428d7b3dSmrg send_media_object(mb, media_state.mb_data.bo, 1139428d7b3dSmrg block_offset, 1140428d7b3dSmrg FRAME_INTRA + INTERFACE_NUM); 1141428d7b3dSmrg } else { 1142428d7b3dSmrg if (((mb->motion_type & 3) == XVMC_PREDICTION_FRAME)) { 1143428d7b3dSmrg if ((mb->macroblock_type & 1144428d7b3dSmrg XVMC_MB_TYPE_MOTION_FORWARD)) { 1145428d7b3dSmrg if ((mb->macroblock_type & 1146428d7b3dSmrg XVMC_MB_TYPE_MOTION_BACKWARD)) { 1147428d7b3dSmrg send_media_object(mb, 1148428d7b3dSmrg media_state.mb_data. 1149428d7b3dSmrg bo, 1150428d7b3dSmrg block_offset, 1151428d7b3dSmrg FRAME_FRAME_PRED_BIDIRECT 1152428d7b3dSmrg + 1153428d7b3dSmrg INTERFACE_NUM); 1154428d7b3dSmrg } else { 1155428d7b3dSmrg send_media_object(mb, 1156428d7b3dSmrg media_state.mb_data. 1157428d7b3dSmrg bo, 1158428d7b3dSmrg block_offset, 1159428d7b3dSmrg FRAME_FRAME_PRED_FORWARD 1160428d7b3dSmrg + 1161428d7b3dSmrg INTERFACE_NUM); 1162428d7b3dSmrg } 1163428d7b3dSmrg } else 1164428d7b3dSmrg if ((mb->macroblock_type & 1165428d7b3dSmrg XVMC_MB_TYPE_MOTION_BACKWARD)) { 1166428d7b3dSmrg send_media_object(mb, 1167428d7b3dSmrg media_state. 1168428d7b3dSmrg mb_data.bo, 1169428d7b3dSmrg block_offset, 1170428d7b3dSmrg FRAME_FRAME_PRED_BACKWARD 1171428d7b3dSmrg + INTERFACE_NUM); 1172428d7b3dSmrg } 1173428d7b3dSmrg } else if ((mb->motion_type & 3) == 1174428d7b3dSmrg XVMC_PREDICTION_FIELD) { 1175428d7b3dSmrg if ((mb->macroblock_type & 1176428d7b3dSmrg XVMC_MB_TYPE_MOTION_FORWARD)) { 1177428d7b3dSmrg if (((mb->macroblock_type & 1178428d7b3dSmrg XVMC_MB_TYPE_MOTION_BACKWARD))) { 1179428d7b3dSmrg send_media_object(mb, 1180428d7b3dSmrg media_state.mb_data. 1181428d7b3dSmrg bo, 1182428d7b3dSmrg block_offset, 1183428d7b3dSmrg FRAME_FIELD_PRED_BIDIRECT 1184428d7b3dSmrg + 1185428d7b3dSmrg INTERFACE_NUM); 1186428d7b3dSmrg } else { 1187428d7b3dSmrg send_media_object(mb, 1188428d7b3dSmrg media_state.mb_data. 1189428d7b3dSmrg bo, 1190428d7b3dSmrg block_offset, 1191428d7b3dSmrg FRAME_FIELD_PRED_FORWARD 1192428d7b3dSmrg + 1193428d7b3dSmrg INTERFACE_NUM); 1194428d7b3dSmrg } 1195428d7b3dSmrg } else 1196428d7b3dSmrg if ((mb->macroblock_type & 1197428d7b3dSmrg XVMC_MB_TYPE_MOTION_BACKWARD)) { 1198428d7b3dSmrg send_media_object(mb, 1199428d7b3dSmrg media_state. 1200428d7b3dSmrg mb_data.bo, 1201428d7b3dSmrg block_offset, 1202428d7b3dSmrg FRAME_FIELD_PRED_BACKWARD 1203428d7b3dSmrg + INTERFACE_NUM); 1204428d7b3dSmrg } 1205428d7b3dSmrg } else { 1206428d7b3dSmrg send_media_object(mb, media_state.mb_data.bo, block_offset, FRAME_FIELD_PRED_BIDIRECT + INTERFACE_NUM); /*dual prime */ 1207428d7b3dSmrg } 1208428d7b3dSmrg } 1209428d7b3dSmrg } 1210428d7b3dSmrg intelFlushBatch(); 1211428d7b3dSmrg UNLOCK_HARDWARE(intel_ctx->hw_context); 1212428d7b3dSmrg return Success; 1213428d7b3dSmrg} 1214428d7b3dSmrg 1215428d7b3dSmrgstruct _intel_xvmc_driver xvmc_vld_driver = { 1216428d7b3dSmrg .type = XVMC_I965_MPEG2_VLD, 1217428d7b3dSmrg .create_context = create_context, 1218428d7b3dSmrg .destroy_context = destroy_context, 1219428d7b3dSmrg .load_qmatrix = load_qmatrix, 1220428d7b3dSmrg .begin_surface = begin_surface, 1221428d7b3dSmrg .render_surface = render_surface, 1222428d7b3dSmrg .put_slice = put_slice, 1223428d7b3dSmrg .put_slice2 = put_slice2 1224428d7b3dSmrg}; 1225