1/* 2 * Copyright © 2006 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 "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 * SOFTWARE. 22 * 23 * Authors: 24 * Xiang Haihao <haihao.xiang@intel.com> 25 * 26 */ 27 28#include <sys/ioctl.h> 29 30#include "i915_xvmc.h" 31#include "i915_structs.h" 32#include "i915_program.h" 33 34#define YOFFSET(surface) (surface->srf.offset) 35#define UOFFSET(surface) (surface->srf.offset + \ 36 SIZE_Y420(surface->width, surface->height) + \ 37 SIZE_UV420(surface->width, surface->height)) 38#define VOFFSET(surface) (surface->srf.offset + \ 39 SIZE_Y420(surface->width, surface->height)) 40 41typedef union { 42 int16_t component[2]; 43 int32_t v; 44} vector_t; 45 46#if 0 47static int findOverlap(unsigned int width, unsigned int height, 48 short *dstX, short *dstY, 49 short *srcX, short *srcY, 50 unsigned short *areaW, unsigned short *areaH) 51{ 52 int w, h; 53 unsigned int mWidth, mHeight; 54 55 w = *areaW; 56 h = *areaH; 57 58 if ((*dstX >= width) || (*dstY >= height)) 59 return 1; 60 61 if (*dstX < 0) { 62 w += *dstX; 63 *srcX -= *dstX; 64 *dstX = 0; 65 } 66 67 if (*dstY < 0) { 68 h += *dstY; 69 *srcY -= *dstY; 70 *dstY = 0; 71 } 72 73 if ((w <= 0) || ((h <= 0))) 74 return 1; 75 76 mWidth = width - *dstX; 77 mHeight = height - *dstY; 78 *areaW = (w <= mWidth) ? w : mWidth; 79 *areaH = (h <= mHeight) ? h : mHeight; 80 return 0; 81} 82#endif 83 84static void i915_inst_arith(unsigned int *inst, 85 unsigned int op, 86 unsigned int dest, 87 unsigned int mask, 88 unsigned int saturate, 89 unsigned int src0, unsigned int src1, unsigned int src2) 90{ 91 dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest)); 92 *inst = (op | A0_DEST(dest) | mask | saturate | A0_SRC0(src0)); 93 inst++; 94 *inst = (A1_SRC0(src0) | A1_SRC1(src1)); 95 inst++; 96 *inst = (A2_SRC1(src1) | A2_SRC2(src2)); 97} 98 99static void i915_inst_decl(unsigned int *inst, 100 unsigned int type, 101 unsigned int nr, 102 unsigned int d0_flags) 103{ 104 unsigned int reg = UREG(type, nr); 105 106 *inst = (D0_DCL | D0_DEST(reg) | d0_flags); 107 inst++; 108 *inst = D1_MBZ; 109 inst++; 110 *inst = D2_MBZ; 111} 112 113static void i915_inst_texld(unsigned int *inst, 114 unsigned int op, 115 unsigned int dest, 116 unsigned int coord, 117 unsigned int sampler) 118{ 119 dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest)); 120 *inst = (op | T0_DEST(dest) | T0_SAMPLER(sampler)); 121 inst++; 122 *inst = T1_ADDRESS_REG(coord); 123 inst++; 124 *inst = T2_MBZ; 125} 126 127static void i915_emit_batch(void *data, int size, int flag) 128{ 129 intelBatchbufferData(data, size, flag); 130} 131 132/* one time context initialization buffer */ 133static uint32_t *one_time_load_state_imm1; 134static uint32_t *one_time_load_indirect; 135static int one_time_load_state_imm1_size, one_time_load_indirect_size; 136 137/* load indirect buffer for mc rendering */ 138static uint32_t *mc_render_load_indirect; 139static int mc_render_load_indirect_size; 140 141static void i915_mc_one_time_context_init(XvMCContext *context) 142{ 143 unsigned int dest, src0, src1, src2; 144 i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; 145 int i; 146 struct i915_3dstate_sampler_state *sampler_state; 147 struct i915_3dstate_pixel_shader_program *pixel_shader_program; 148 struct i915_3dstate_pixel_shader_constants *pixel_shader_constants; 149 150 /* sampler static state */ 151 sampler_state = (struct i915_3dstate_sampler_state *)pI915XvMC->ssb.map; 152 /* pixel shader static state */ 153 pixel_shader_program = (struct i915_3dstate_pixel_shader_program *)pI915XvMC->psp.map; 154 /* pixel shader contant static state */ 155 pixel_shader_constants = (struct i915_3dstate_pixel_shader_constants *)pI915XvMC->psc.map; 156 157 memset(sampler_state, 0, sizeof(*sampler_state)); 158 sampler_state->dw0.type = CMD_3D; 159 sampler_state->dw0.opcode = OPC_3DSTATE_SAMPLER_STATE; 160 sampler_state->dw0.length = 6; 161 sampler_state->dw1.sampler_masker = SAMPLER_SAMPLER0 | SAMPLER_SAMPLER1; 162 163 sampler_state->sampler0.ts0.reverse_gamma = 0; 164 sampler_state->sampler0.ts0.planar2packet = 0; 165 sampler_state->sampler0.ts0.color_conversion = 0; 166 sampler_state->sampler0.ts0.chromakey_index = 0; 167 sampler_state->sampler0.ts0.base_level = 0; 168 sampler_state->sampler0.ts0.mip_filter = MIPFILTER_NONE; /* NONE */ 169 sampler_state->sampler0.ts0.mag_filter = MAPFILTER_LINEAR; /* LINEAR */ 170 sampler_state->sampler0.ts0.min_filter = MAPFILTER_LINEAR; /* LINEAR */ 171 sampler_state->sampler0.ts0.lod_bias = 0; /* 0.0 */ 172 sampler_state->sampler0.ts0.shadow_enable = 0; 173 sampler_state->sampler0.ts0.max_anisotropy = ANISORATIO_2; 174 sampler_state->sampler0.ts0.shadow_function = PREFILTEROP_ALWAYS; 175 sampler_state->sampler0.ts1.min_lod = 0; /* 0.0 Maximum Mip Level */ 176 sampler_state->sampler0.ts1.kill_pixel = 0; 177 sampler_state->sampler0.ts1.keyed_texture_filter = 0; 178 sampler_state->sampler0.ts1.chromakey_enable = 0; 179 sampler_state->sampler0.ts1.tcx_control = TEXCOORDMODE_CLAMP; 180 sampler_state->sampler0.ts1.tcy_control = TEXCOORDMODE_CLAMP; 181 sampler_state->sampler0.ts1.tcz_control = TEXCOORDMODE_CLAMP; 182 sampler_state->sampler0.ts1.normalized_coor = 0; 183 sampler_state->sampler0.ts1.map_index = 0; 184 sampler_state->sampler0.ts1.east_deinterlacer = 0; 185 sampler_state->sampler0.ts2.default_color = 0; 186 187 sampler_state->sampler1.ts0.reverse_gamma = 0; 188 sampler_state->sampler1.ts0.planar2packet = 0; 189 sampler_state->sampler1.ts0.color_conversion = 0; 190 sampler_state->sampler1.ts0.chromakey_index = 0; 191 sampler_state->sampler1.ts0.base_level = 0; 192 sampler_state->sampler1.ts0.mip_filter = MIPFILTER_NONE; /* NONE */ 193 sampler_state->sampler1.ts0.mag_filter = MAPFILTER_LINEAR; /* LINEAR */ 194 sampler_state->sampler1.ts0.min_filter = MAPFILTER_LINEAR; /* LINEAR */ 195 sampler_state->sampler1.ts0.lod_bias = 0; /* 0.0 */ 196 sampler_state->sampler1.ts0.shadow_enable = 0; 197 sampler_state->sampler1.ts0.max_anisotropy = ANISORATIO_2; 198 sampler_state->sampler1.ts0.shadow_function = PREFILTEROP_ALWAYS; 199 sampler_state->sampler1.ts1.min_lod = 0; /* 0.0 Maximum Mip Level */ 200 sampler_state->sampler1.ts1.kill_pixel = 0; 201 sampler_state->sampler1.ts1.keyed_texture_filter = 0; 202 sampler_state->sampler1.ts1.chromakey_enable = 0; 203 sampler_state->sampler1.ts1.tcx_control = TEXCOORDMODE_CLAMP; 204 sampler_state->sampler1.ts1.tcy_control = TEXCOORDMODE_CLAMP; 205 sampler_state->sampler1.ts1.tcz_control = TEXCOORDMODE_CLAMP; 206 sampler_state->sampler1.ts1.normalized_coor = 0; 207 sampler_state->sampler1.ts1.map_index = 1; 208 sampler_state->sampler1.ts1.east_deinterlacer = 0; 209 sampler_state->sampler1.ts2.default_color = 0; 210 211 memset(pixel_shader_program, 0, sizeof(*pixel_shader_program)); 212 pixel_shader_program->shader0.type = CMD_3D; 213 pixel_shader_program->shader0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM; 214 pixel_shader_program->shader0.retain = 1; 215 pixel_shader_program->shader0.length = 2; /* 1 inst */ 216 i = 0; 217 218 dest = UREG(REG_TYPE_OC, 0); 219 src0 = UREG(REG_TYPE_CONST, 0); 220 src1 = 0; 221 src2 = 0; 222 i915_inst_arith(&pixel_shader_program->inst0[i], A0_MOV, 223 dest, A0_DEST_CHANNEL_ALL, A0_DEST_SATURATE, src0, src1, src2); 224 225 pixel_shader_program->shader1.type = CMD_3D; 226 pixel_shader_program->shader1.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM; 227 pixel_shader_program->shader1.retain = 1; 228 pixel_shader_program->shader1.length = 14; /* 5 inst */ 229 i = 0; 230 /* dcl t0.xy */ 231 i915_inst_decl(&pixel_shader_program->inst1[i], REG_TYPE_T, T_TEX0, D0_CHANNEL_XY); 232 i+=3; 233 /* dcl t1.xy */ 234 i915_inst_decl(&pixel_shader_program->inst1[i], REG_TYPE_T, T_TEX1, D0_CHANNEL_XY); 235 /* dcl_2D s0 */ 236 i += 3; 237 i915_inst_decl(&pixel_shader_program->inst1[i], REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D); 238 /* texld r0, t0, s0 */ 239 i += 3; 240 dest = UREG(REG_TYPE_R, 0); 241 src0 = UREG(REG_TYPE_T, 0); /* COORD */ 242 src1 = UREG(REG_TYPE_S, 0); /* SAMPLER */ 243 i915_inst_texld(&pixel_shader_program->inst1[i], T0_TEXLD, dest, src0, src1); 244 /* mov oC, r0 */ 245 i += 3; 246 dest = UREG(REG_TYPE_OC, 0); 247 src0 = UREG(REG_TYPE_R, 0); 248 src1 = src2 = 0; 249 i915_inst_arith(&pixel_shader_program->inst1[i], A0_MOV, dest, A0_DEST_CHANNEL_ALL, 250 A0_DEST_SATURATE, src0, src1, src2); 251 252 253 pixel_shader_program->shader2.type = CMD_3D; 254 pixel_shader_program->shader2.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM; 255 pixel_shader_program->shader2.retain = 1; 256 pixel_shader_program->shader2.length = 14; /* 5 inst */ 257 i = 0; 258 /* dcl t2.xy */ 259 i915_inst_decl(&pixel_shader_program->inst2[i], REG_TYPE_T, T_TEX2, D0_CHANNEL_XY); 260 /* dcl t3.xy */ 261 i += 3; 262 i915_inst_decl(&pixel_shader_program->inst2[i], REG_TYPE_T, T_TEX3, D0_CHANNEL_XY); 263 /* dcl_2D s1 */ 264 i += 3; 265 i915_inst_decl(&pixel_shader_program->inst2[i], REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D); 266 /* texld r0, t2, s1 */ 267 i += 3; 268 dest = UREG(REG_TYPE_R, 0); 269 src0 = UREG(REG_TYPE_T, 2); /* COORD */ 270 src1 = UREG(REG_TYPE_S, 1); /* SAMPLER */ 271 i915_inst_texld(&pixel_shader_program->inst2[i], T0_TEXLD, dest, src0, src1); 272 /* mov oC, r0 */ 273 i += 3; 274 dest = UREG(REG_TYPE_OC, 0); 275 src0 = UREG(REG_TYPE_R, 0); 276 src1 = src2 = 0; 277 i915_inst_arith(&pixel_shader_program->inst2[i], A0_MOV, dest, A0_DEST_CHANNEL_ALL, 278 A0_DEST_SATURATE, src0, src1, src2); 279 280 /* Shader 3 */ 281 pixel_shader_program->shader3.type = CMD_3D; 282 pixel_shader_program->shader3.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM; 283 pixel_shader_program->shader3.retain = 1; 284 pixel_shader_program->shader3.length = 29; /* 10 inst */ 285 i = 0; 286 /* dcl t0.xy */ 287 i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX0, D0_CHANNEL_XY); 288 /* dcl t1.xy */ 289 i += 3; 290 i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX1, D0_CHANNEL_XY); 291 /* dcl t2.xy */ 292 i += 3; 293 i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX2, D0_CHANNEL_XY); 294 /* dcl t3.xy */ 295 i += 3; 296 i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX3, D0_CHANNEL_XY); 297 /* dcl_2D s0 */ 298 i += 3; 299 i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D); 300 /* dcl_2D s1 */ 301 i += 3; 302 i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D); 303 /* texld r0, t0, s0 */ 304 i += 3; 305 dest = UREG(REG_TYPE_R, 0); 306 src0 = UREG(REG_TYPE_T, 0); /* COORD */ 307 src1 = UREG(REG_TYPE_S, 0); /* SAMPLER */ 308 i915_inst_texld(&pixel_shader_program->inst3[i], T0_TEXLD, dest, src0, src1); 309 /* texld r1, t2, s1 */ 310 i += 3; 311 dest = UREG(REG_TYPE_R, 1); 312 src0 = UREG(REG_TYPE_T, 2); /* COORD */ 313 src1 = UREG(REG_TYPE_S, 1); /* SAMPLER */ 314 i915_inst_texld(&pixel_shader_program->inst3[i], T0_TEXLD, dest, src0, src1); 315 /* add r0, r0, r1 */ 316 i += 3; 317 dest = UREG(REG_TYPE_R, 0); 318 src0 = UREG(REG_TYPE_R, 0); 319 src1 = UREG(REG_TYPE_R, 1); 320 src2 = 0; 321 i915_inst_arith(&pixel_shader_program->inst3[i], A0_ADD, dest, A0_DEST_CHANNEL_ALL, 322 0 /* A0_DEST_SATURATE */, src0, src1, src2); 323 /* mul oC, r0, c0 */ 324 i += 3; 325 dest = UREG(REG_TYPE_OC, 0); 326 src0 = UREG(REG_TYPE_R, 0); 327 src1 = UREG(REG_TYPE_CONST, 0); 328 src2 = 0; 329 i915_inst_arith(&pixel_shader_program->inst3[i], A0_MUL, dest, A0_DEST_CHANNEL_ALL, 330 A0_DEST_SATURATE, src0, src1, src2); 331 332 memset(pixel_shader_constants, 0, sizeof(*pixel_shader_constants)); 333 pixel_shader_constants->dw0.type = CMD_3D; 334 pixel_shader_constants->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_CONSTANTS; 335 pixel_shader_constants->dw0.length = 4; 336 pixel_shader_constants->dw1.reg_mask = REG_CR0; 337 pixel_shader_constants->value.x = 0.5; 338 pixel_shader_constants->value.y = 0.5; 339 pixel_shader_constants->value.z = 0.5; 340 pixel_shader_constants->value.w = 0.5; 341 342} 343 344static void i915_mc_one_time_state_init(XvMCContext *context) 345{ 346 struct s3_dword *s3 = NULL; 347 struct s6_dword *s6 = NULL; 348 dis_state *dis = NULL; 349 ssb_state *ssb = NULL; 350 psp_state *psp = NULL; 351 psc_state *psc = NULL; 352 i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; 353 struct i915_3dstate_load_state_immediate_1 *load_state_immediate_1; 354 struct i915_3dstate_load_indirect *load_indirect; 355 int mem_select; 356 357 /* 3DSTATE_LOAD_STATE_IMMEDIATE_1 */ 358 one_time_load_state_imm1_size = sizeof(*load_state_immediate_1) + sizeof(*s3) + sizeof(*s6); 359 one_time_load_state_imm1 = calloc(1, one_time_load_state_imm1_size); 360 load_state_immediate_1 = (struct i915_3dstate_load_state_immediate_1 *)one_time_load_state_imm1; 361 load_state_immediate_1->dw0.type = CMD_3D; 362 load_state_immediate_1->dw0.opcode = OPC_3DSTATE_LOAD_STATE_IMMEDIATE_1; 363 load_state_immediate_1->dw0.load_s3 = 1; 364 load_state_immediate_1->dw0.load_s6 = 1; 365 load_state_immediate_1->dw0.length = (one_time_load_state_imm1_size >> 2) - 2; 366 367 s3 = (struct s3_dword *)(++load_state_immediate_1); 368 s3->set0_pcd = 1; 369 s3->set1_pcd = 1; 370 s3->set2_pcd = 1; 371 s3->set3_pcd = 1; 372 s3->set4_pcd = 1; 373 s3->set5_pcd = 1; 374 s3->set6_pcd = 1; 375 s3->set7_pcd = 1; 376 377 s6 = (struct s6_dword *)(++s3); 378 s6->alpha_test_enable = 0; 379 s6->alpha_test_function = 0; 380 s6->alpha_reference_value = 0; 381 s6->depth_test_enable = 1; 382 s6->depth_test_function = 0; 383 s6->color_buffer_blend = 0; 384 s6->color_blend_function = 0; 385 s6->src_blend_factor = 1; 386 s6->dest_blend_factor = 1; 387 s6->depth_buffer_write = 0; 388 s6->color_buffer_write = 1; 389 s6->triangle_pv = 0; 390 391 /* 3DSTATE_LOAD_INDIRECT */ 392 one_time_load_indirect_size = sizeof(*load_indirect) + sizeof(*dis) + sizeof(*ssb) + sizeof(*psp) + sizeof(*psc); 393 one_time_load_indirect = calloc(1, one_time_load_indirect_size); 394 load_indirect = (struct i915_3dstate_load_indirect *)one_time_load_indirect; 395 load_indirect->dw0.type = CMD_3D; 396 load_indirect->dw0.opcode = OPC_3DSTATE_LOAD_INDIRECT; 397 load_indirect->dw0.block_mask = BLOCK_DIS | BLOCK_SSB | BLOCK_PSP | BLOCK_PSC; 398 load_indirect->dw0.length = (one_time_load_indirect_size >> 2) - 2; 399 400 if (pI915XvMC->deviceID == PCI_CHIP_I915_G || 401 pI915XvMC->deviceID == PCI_CHIP_I915_GM) 402 mem_select = 0; /* use physical address */ 403 else 404 mem_select = 1; /* use gfx address */ 405 406 load_indirect->dw0.mem_select = mem_select; 407 408 409 /* Dynamic indirect state buffer */ 410 dis = (dis_state *)(++load_indirect); 411 dis->dw0.valid = 0; 412 dis->dw0.reset = 0; 413 dis->dw0.buffer_address = 0; 414 415 /* Sample state buffer */ 416 ssb = (ssb_state *)(++dis); 417 ssb->dw0.valid = 1; 418 ssb->dw0.force = 1; 419 ssb->dw1.length = 7; /* 8 - 1 */ 420 421 if (mem_select) 422 ssb->dw0.buffer_address = (pI915XvMC->ssb.offset >> 2); 423 else 424 ssb->dw0.buffer_address = (pI915XvMC->ssb.bus_addr >> 2); 425 426 /* Pixel shader program buffer */ 427 psp = (psp_state *)(++ssb); 428 psp->dw0.valid = 1; 429 psp->dw0.force = 1; 430 psp->dw1.length = 66; /* 4 + 16 + 16 + 31 - 1 */ 431 432 if (mem_select) 433 psp->dw0.buffer_address = (pI915XvMC->psp.offset >> 2); 434 else 435 psp->dw0.buffer_address = (pI915XvMC->psp.bus_addr >> 2); 436 437 /* Pixel shader constant buffer */ 438 psc = (psc_state *)(++psp); 439 psc->dw0.valid = 1; 440 psc->dw0.force = 1; 441 psc->dw1.length = 5; /* 6 - 1 */ 442 443 if (mem_select) 444 psc->dw0.buffer_address = (pI915XvMC->psc.offset >> 2); 445 else 446 psc->dw0.buffer_address = (pI915XvMC->psc.bus_addr >> 2); 447} 448 449static void i915_mc_one_time_state_emit(void) 450{ 451 i915_emit_batch(one_time_load_state_imm1, one_time_load_state_imm1_size, 0); 452 i915_emit_batch(one_time_load_indirect, one_time_load_indirect_size, 0); 453} 454 455static void i915_mc_static_indirect_state_init(XvMCContext *context) 456{ 457 i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; 458 struct i915_mc_static_indirect_state_buffer *buffer_info = 459 (struct i915_mc_static_indirect_state_buffer *)pI915XvMC->sis.map; 460 461 memset(buffer_info, 0, sizeof(*buffer_info)); 462 /* dest Y */ 463 buffer_info->dest_y.dw0.type = CMD_3D; 464 buffer_info->dest_y.dw0.opcode = OPC_3DSTATE_BUFFER_INFO; 465 buffer_info->dest_y.dw0.length = 1; 466 buffer_info->dest_y.dw1.aux_id = 0; 467 buffer_info->dest_y.dw1.buffer_id = BUFFERID_COLOR_BACK; 468 buffer_info->dest_y.dw1.fence_regs = 0; /* disabled */ /* FIXME: tiled y for performance */ 469 buffer_info->dest_y.dw1.tiled_surface = 0; /* linear */ 470 buffer_info->dest_y.dw1.walk = TILEWALK_XMAJOR; 471 472 /* dest U */ 473 buffer_info->dest_u.dw0.type = CMD_3D; 474 buffer_info->dest_u.dw0.opcode = OPC_3DSTATE_BUFFER_INFO; 475 buffer_info->dest_u.dw0.length = 1; 476 buffer_info->dest_u.dw1.aux_id = 0; 477 buffer_info->dest_u.dw1.buffer_id = BUFFERID_COLOR_AUX; 478 buffer_info->dest_u.dw1.fence_regs = 0; 479 buffer_info->dest_u.dw1.tiled_surface = 0; 480 buffer_info->dest_u.dw1.walk = TILEWALK_XMAJOR; 481 482 /* dest V */ 483 buffer_info->dest_v.dw0.type = CMD_3D; 484 buffer_info->dest_v.dw0.opcode = OPC_3DSTATE_BUFFER_INFO; 485 buffer_info->dest_v.dw0.length = 1; 486 buffer_info->dest_v.dw1.aux_id = 1; 487 buffer_info->dest_v.dw1.buffer_id = BUFFERID_COLOR_AUX; 488 buffer_info->dest_v.dw1.fence_regs = 0; 489 buffer_info->dest_v.dw1.tiled_surface = 0; 490 buffer_info->dest_v.dw1.walk = TILEWALK_XMAJOR; 491 492 buffer_info->dest_buf.dw0.type = CMD_3D; 493 buffer_info->dest_buf.dw0.opcode = OPC_3DSTATE_DEST_BUFFER_VARIABLES; 494 buffer_info->dest_buf.dw0.length = 0; 495 buffer_info->dest_buf.dw1.dest_v_bias = 8; /* 0.5 */ 496 buffer_info->dest_buf.dw1.dest_h_bias = 8; /* 0.5 */ 497 buffer_info->dest_buf.dw1.color_fmt = COLORBUFFER_8BIT; 498 buffer_info->dest_buf.dw1.v_ls = 0; /* fill later */ 499 buffer_info->dest_buf.dw1.v_ls_offset = 0; /* fill later */ 500 501 buffer_info->dest_buf_mpeg.dw0.type = CMD_3D; 502 buffer_info->dest_buf_mpeg.dw0.opcode = OPC_3DSTATE_DEST_BUFFER_VARIABLES_MPEG; 503 buffer_info->dest_buf_mpeg.dw0.length = 1; 504 buffer_info->dest_buf_mpeg.dw1.decode_mode = MPEG_DECODE_MC; 505 buffer_info->dest_buf_mpeg.dw1.rcontrol = 0; /* for MPEG-1/MPEG-2 */ 506 buffer_info->dest_buf_mpeg.dw1.bidir_avrg_control = 0; /* for MPEG-1/MPEG-2/MPEG-4 */ 507 buffer_info->dest_buf_mpeg.dw1.abort_on_error = 1; 508 buffer_info->dest_buf_mpeg.dw1.intra8 = 0; /* 16-bit formatted correction data */ 509 buffer_info->dest_buf_mpeg.dw1.tff = 1; /* fill later */ 510 511 buffer_info->dest_buf_mpeg.dw1.v_subsample_factor = MC_SUB_1V; 512 buffer_info->dest_buf_mpeg.dw1.h_subsample_factor = MC_SUB_1H; 513 514 buffer_info->corr.dw0.type = CMD_3D; 515 buffer_info->corr.dw0.opcode = OPC_3DSTATE_BUFFER_INFO; 516 buffer_info->corr.dw0.length = 1; 517 buffer_info->corr.dw1.aux_id = 0; 518 buffer_info->corr.dw1.buffer_id = BUFFERID_MC_INTRA_CORR; 519 buffer_info->corr.dw1.aux_id = 0; 520 buffer_info->corr.dw1.fence_regs = 0; 521 buffer_info->corr.dw1.tiled_surface = 0; 522 buffer_info->corr.dw1.walk = 0; 523 buffer_info->corr.dw1.pitch = 0; 524 buffer_info->corr.dw2.base_address = (pI915XvMC->corrdata.offset >> 2); /* starting DWORD address */ 525} 526 527static void i915_mc_static_indirect_state_set(XvMCContext *context, XvMCSurface *dest, 528 unsigned int picture_structure, unsigned int flags, unsigned int picture_coding_type) 529{ 530 i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; 531 i915XvMCSurface *pI915Surface = (i915XvMCSurface *)dest->privData; 532 struct i915_mc_static_indirect_state_buffer *buffer_info = 533 (struct i915_mc_static_indirect_state_buffer *)pI915XvMC->sis.map; 534 unsigned int w = dest->width; 535 536 buffer_info->dest_y.dw1.pitch = (pI915Surface->yStride >> 2); /* in DWords */ 537 buffer_info->dest_y.dw2.base_address = (YOFFSET(pI915Surface) >> 2); /* starting DWORD address */ 538 buffer_info->dest_u.dw1.pitch = (pI915Surface->uvStride >> 2); /* in DWords */ 539 buffer_info->dest_u.dw2.base_address = (UOFFSET(pI915Surface) >> 2); /* starting DWORD address */ 540 buffer_info->dest_v.dw1.pitch = (pI915Surface->uvStride >> 2); /* in Dwords */ 541 buffer_info->dest_v.dw2.base_address = (VOFFSET(pI915Surface) >> 2); /* starting DWORD address */ 542 543 if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) { 544 ; 545 } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_TOP_FIELD) { 546 buffer_info->dest_buf.dw1.v_ls = 1; 547 } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_BOTTOM_FIELD) { 548 buffer_info->dest_buf.dw1.v_ls = 1; 549 buffer_info->dest_buf.dw1.v_ls_offset = 1; 550 } 551 552 if (picture_structure & XVMC_FRAME_PICTURE) { 553 ; 554 } else if (picture_structure & XVMC_TOP_FIELD) { 555 if (flags & XVMC_SECOND_FIELD) 556 buffer_info->dest_buf_mpeg.dw1.tff = 0; 557 else 558 buffer_info->dest_buf_mpeg.dw1.tff = 1; 559 } else if (picture_structure & XVMC_BOTTOM_FIELD) { 560 if (flags & XVMC_SECOND_FIELD) 561 buffer_info->dest_buf_mpeg.dw1.tff = 1; 562 else 563 buffer_info->dest_buf_mpeg.dw1.tff = 0; 564 } 565 566 buffer_info->dest_buf_mpeg.dw1.picture_width = (dest->width >> 4); /* in macroblocks */ 567 buffer_info->dest_buf_mpeg.dw2.picture_coding_type = picture_coding_type; 568} 569 570static void i915_mc_map_state_init(XvMCContext *context) 571{ 572 i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; 573 unsigned int w = context->width; 574 unsigned int h = context->height; 575 struct i915_mc_map_state *map_state; 576 577 map_state = (struct i915_mc_map_state *)pI915XvMC->msb.map; 578 579 memset(map_state, 0, sizeof(*map_state)); 580 581 /* 3DSATE_MAP_STATE: Y */ 582 map_state->y_map.dw0.type = CMD_3D; 583 map_state->y_map.dw0.opcode = OPC_3DSTATE_MAP_STATE; 584 map_state->y_map.dw0.retain = 1; 585 map_state->y_map.dw0.length = 6; 586 map_state->y_map.dw1.map_mask = MAP_MAP0 | MAP_MAP1; 587 588 /* Y Forward (Past) */ 589 map_state->y_forward.tm0.v_ls_offset = 0; 590 map_state->y_forward.tm0.v_ls = 0; 591 map_state->y_forward.tm1.tile_walk = TILEWALK_XMAJOR; 592 map_state->y_forward.tm1.tiled_surface = 0; 593 map_state->y_forward.tm1.utilize_fence_regs = 0; 594 map_state->y_forward.tm1.texel_fmt = 0; /* 8bit */ 595 map_state->y_forward.tm1.surface_fmt = 1; /* 8bit */ 596 map_state->y_forward.tm1.width = w - 1; 597 map_state->y_forward.tm1.height = h - 1; 598 map_state->y_forward.tm2.depth = 0; 599 map_state->y_forward.tm2.max_lod = 0; 600 map_state->y_forward.tm2.cube_face = 0; 601 602 /* Y Backward (Future) */ 603 map_state->y_backward.tm0.v_ls_offset = 0; 604 map_state->y_backward.tm0.v_ls = 0; 605 map_state->y_backward.tm1.tile_walk = TILEWALK_XMAJOR; 606 map_state->y_backward.tm1.tiled_surface = 0; 607 map_state->y_backward.tm1.utilize_fence_regs = 0; 608 map_state->y_backward.tm1.texel_fmt = 0; /* 8bit */ 609 map_state->y_backward.tm1.surface_fmt = 1; /* 8bit */ 610 map_state->y_backward.tm1.width = w - 1; 611 map_state->y_backward.tm1.height = h - 1; 612 map_state->y_backward.tm2.depth = 0; 613 map_state->y_backward.tm2.max_lod = 0; 614 map_state->y_backward.tm2.cube_face = 0; 615 616 /* 3DSATE_MAP_STATE: U */ 617 map_state->u_map.dw0.type = CMD_3D; 618 map_state->u_map.dw0.opcode = OPC_3DSTATE_MAP_STATE; 619 map_state->u_map.dw0.retain = 1; 620 map_state->u_map.dw0.length = 6; 621 map_state->u_map.dw1.map_mask = MAP_MAP0 | MAP_MAP1; 622 623 /* U Forward */ 624 map_state->u_forward.tm0.v_ls_offset = 0; 625 map_state->u_forward.tm0.v_ls = 0; 626 map_state->u_forward.tm1.tile_walk = TILEWALK_XMAJOR; 627 map_state->u_forward.tm1.tiled_surface = 0; 628 map_state->u_forward.tm1.utilize_fence_regs = 0; 629 map_state->u_forward.tm1.texel_fmt = 0; /* 8bit */ 630 map_state->u_forward.tm1.surface_fmt = 1; /* 8bit */ 631 map_state->u_forward.tm1.width = (w >> 1) - 1; 632 map_state->u_forward.tm1.height = (h >> 1) - 1; 633 map_state->u_forward.tm2.depth = 0; 634 map_state->u_forward.tm2.max_lod = 0; 635 map_state->u_forward.tm2.cube_face = 0; 636 637 /* U Backward */ 638 map_state->u_backward.tm0.v_ls_offset = 0; 639 map_state->u_backward.tm0.v_ls = 0; 640 map_state->u_backward.tm1.tile_walk = TILEWALK_XMAJOR; 641 map_state->u_backward.tm1.tiled_surface = 0; 642 map_state->u_backward.tm1.utilize_fence_regs = 0; 643 map_state->u_backward.tm1.texel_fmt = 0; 644 map_state->u_backward.tm1.surface_fmt = 1; 645 map_state->u_backward.tm1.width = (w >> 1) - 1; 646 map_state->u_backward.tm1.height = (h >> 1) - 1; 647 map_state->u_backward.tm2.depth = 0; 648 map_state->u_backward.tm2.max_lod = 0; 649 map_state->u_backward.tm2.cube_face = 0; 650 651 /* 3DSATE_MAP_STATE: V */ 652 map_state->v_map.dw0.type = CMD_3D; 653 map_state->v_map.dw0.opcode = OPC_3DSTATE_MAP_STATE; 654 map_state->v_map.dw0.retain = 1; 655 map_state->v_map.dw0.length = 6; 656 map_state->v_map.dw1.map_mask = MAP_MAP0 | MAP_MAP1; 657 658 /* V Forward */ 659 map_state->v_forward.tm0.v_ls_offset = 0; 660 map_state->v_forward.tm0.v_ls = 0; 661 map_state->v_forward.tm1.tile_walk = TILEWALK_XMAJOR; 662 map_state->v_forward.tm1.tiled_surface = 0; 663 map_state->v_forward.tm1.utilize_fence_regs = 0; 664 map_state->v_forward.tm1.texel_fmt = 0; 665 map_state->v_forward.tm1.surface_fmt = 1; 666 map_state->v_forward.tm1.width = (w >> 1) - 1; 667 map_state->v_forward.tm1.height = (h >> 1) - 1; 668 map_state->v_forward.tm2.depth = 0; 669 map_state->v_forward.tm2.max_lod = 0; 670 map_state->v_forward.tm2.cube_face = 0; 671 672 /* V Backward */ 673 map_state->v_backward.tm0.v_ls_offset = 0; 674 map_state->v_backward.tm0.v_ls = 0; 675 map_state->v_backward.tm1.tile_walk = TILEWALK_XMAJOR; 676 map_state->v_backward.tm1.tiled_surface = 0; 677 map_state->v_backward.tm1.utilize_fence_regs = 0; 678 map_state->v_backward.tm1.texel_fmt = 0; 679 map_state->v_backward.tm1.surface_fmt = 1; 680 map_state->v_backward.tm1.width = (w >> 1) - 1; 681 map_state->v_backward.tm1.height = (h >> 1) - 1; 682 map_state->v_backward.tm2.depth = 0; 683 map_state->v_backward.tm2.max_lod = 0; 684 map_state->v_backward.tm2.cube_face = 0; 685} 686 687static void i915_mc_map_state_set(XvMCContext *context, 688 i915XvMCSurface *privPast, 689 i915XvMCSurface *privFuture) 690{ 691 i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; 692 struct i915_mc_map_state *map_state; 693 694 map_state = (struct i915_mc_map_state *)pI915XvMC->msb.map; 695 696 map_state->y_forward.tm0.base_address = (YOFFSET(privPast) >> 2); 697 map_state->y_forward.tm2.pitch = (privPast->yStride >> 2) - 1; /* in DWords - 1 */ 698 map_state->y_backward.tm0.base_address = (YOFFSET(privFuture) >> 2); 699 map_state->y_backward.tm2.pitch = (privFuture->yStride >> 2) - 1; 700 map_state->u_forward.tm0.base_address = (UOFFSET(privPast) >> 2); 701 map_state->u_forward.tm2.pitch = (privPast->uvStride >> 2) - 1; /* in DWords - 1 */ 702 map_state->u_backward.tm0.base_address = (UOFFSET(privFuture) >> 2); 703 map_state->u_backward.tm2.pitch = (privFuture->uvStride >> 2) - 1; 704 map_state->v_forward.tm0.base_address = (VOFFSET(privPast) >> 2); 705 map_state->v_forward.tm2.pitch = (privPast->uvStride >> 2) - 1; /* in DWords - 1 */ 706 map_state->v_backward.tm0.base_address = (VOFFSET(privFuture) >> 2); 707 map_state->v_backward.tm2.pitch = (privFuture->uvStride >> 2) - 1; 708} 709 710static void i915_flush(int map, int render) 711{ 712 struct i915_mi_flush mi_flush; 713 714 memset(&mi_flush, 0, sizeof(mi_flush)); 715 mi_flush.dw0.type = CMD_MI; 716 mi_flush.dw0.opcode = OPC_MI_FLUSH; 717 mi_flush.dw0.map_cache_invalidate = map; 718 mi_flush.dw0.render_cache_flush_inhibit = render; 719 720 intelBatchbufferData(&mi_flush, sizeof(mi_flush), 0); 721} 722 723static void i915_mc_load_indirect_render_init(XvMCContext *context) 724{ 725 i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; 726 sis_state *sis; 727 msb_state *msb; 728 struct i915_3dstate_load_indirect *load_indirect; 729 int mem_select; 730 731 mc_render_load_indirect_size = sizeof(*load_indirect) + sizeof(*sis) 732 + sizeof(*msb); 733 mc_render_load_indirect = calloc(1, mc_render_load_indirect_size); 734 735 load_indirect = (struct i915_3dstate_load_indirect *)mc_render_load_indirect; 736 load_indirect->dw0.type = CMD_3D; 737 load_indirect->dw0.opcode = OPC_3DSTATE_LOAD_INDIRECT; 738 load_indirect->dw0.block_mask = BLOCK_SIS | BLOCK_MSB; 739 load_indirect->dw0.length = (mc_render_load_indirect_size >> 2) - 2; 740 741 if (pI915XvMC->deviceID == PCI_CHIP_I915_G || 742 pI915XvMC->deviceID == PCI_CHIP_I915_GM) 743 mem_select = 0; 744 else 745 mem_select = 1; 746 747 load_indirect->dw0.mem_select = mem_select; 748 749 /* Static Indirect state buffer (dest buffer info) */ 750 sis = (sis_state *)(++load_indirect); 751 sis->dw0.valid = 1; 752 sis->dw0.force = 1; 753 sis->dw1.length = 16; /* 4 * 3 + 2 + 3 - 1 */ 754 755 if (mem_select) 756 sis->dw0.buffer_address = (pI915XvMC->sis.offset >> 2); 757 else 758 sis->dw0.buffer_address = (pI915XvMC->sis.bus_addr >> 2); 759 760 /* Map state buffer (reference buffer info) */ 761 msb = (msb_state *)(++sis); 762 msb->dw0.valid = 1; 763 msb->dw0.force = 1; 764 msb->dw1.length = 23; /* 3 * 8 - 1 */ 765 766 if (mem_select) 767 msb->dw0.buffer_address = (pI915XvMC->msb.offset >> 2); 768 else 769 msb->dw0.buffer_address = (pI915XvMC->msb.bus_addr >> 2); 770} 771 772static void i915_mc_load_indirect_render_emit(void) 773{ 774 i915_emit_batch(mc_render_load_indirect, mc_render_load_indirect_size, 0); 775} 776 777static void i915_mc_mpeg_set_origin(XvMCContext *context, XvMCMacroBlock *mb) 778{ 779 struct i915_3dmpeg_set_origin set_origin; 780 781 /* 3DMPEG_SET_ORIGIN */ 782 memset(&set_origin, 0, sizeof(set_origin)); 783 set_origin.dw0.type = CMD_3D; 784 set_origin.dw0.opcode = OPC_3DMPEG_SET_ORIGIN; 785 set_origin.dw0.length = 0; 786 set_origin.dw1.h_origin = mb->x; 787 set_origin.dw1.v_origin = mb->y; 788 789 intelBatchbufferData(&set_origin, sizeof(set_origin), 0); 790} 791 792static void i915_mc_mpeg_macroblock_ipicture(XvMCContext *context, XvMCMacroBlock *mb) 793{ 794 struct i915_3dmpeg_macroblock_ipicture macroblock_ipicture; 795 796 /* 3DMPEG_MACROBLOCK_IPICTURE */ 797 memset(¯oblock_ipicture, 0, sizeof(macroblock_ipicture)); 798 macroblock_ipicture.dw0.type = CMD_3D; 799 macroblock_ipicture.dw0.opcode = OPC_3DMPEG_MACROBLOCK_IPICTURE; 800 macroblock_ipicture.dw0.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD); 801 802 intelBatchbufferData(¯oblock_ipicture, sizeof(macroblock_ipicture), 0); 803} 804 805#if 0 806static void i915_mc_mpeg_macroblock_0mv(XvMCContext *context, XvMCMacroBlock *mb) 807{ 808 struct i915_3dmpeg_macroblock_0mv macroblock_0mv; 809 810 /* 3DMPEG_MACROBLOCK(0mv) */ 811 memset(¯oblock_0mv, 0, sizeof(macroblock_0mv)); 812 macroblock_0mv.header.dw0.type = CMD_3D; 813 macroblock_0mv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK; 814 macroblock_0mv.header.dw0.length = 0; 815 macroblock_0mv.header.dw1.mb_intra = 1; /* should be 1 */ 816 macroblock_0mv.header.dw1.forward = 0; /* should be 0 */ 817 macroblock_0mv.header.dw1.backward = 0; /* should be 0 */ 818 macroblock_0mv.header.dw1.h263_4mv = 0; /* should be 0 */ 819 macroblock_0mv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD); 820 821/* 822 if (!mb->coded_block_pattern) 823 macroblock_0mv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME; 824*/ 825 826 macroblock_0mv.header.dw1.motion_type = 0; // (mb->motion_type & 0x3); 827 macroblock_0mv.header.dw1.vertical_field_select = 0; // mb->motion_vertical_field_select & 0xf; 828 macroblock_0mv.header.dw1.coded_block_pattern = mb->coded_block_pattern; 829 macroblock_0mv.header.dw1.skipped_macroblocks = 0; 830 831 intelBatchbufferData(¯oblock_0mv, sizeof(macroblock_0mv), 0); 832} 833#endif 834 835static void i915_mc_mpeg_macroblock_1fbmv(XvMCContext *context, XvMCMacroBlock *mb) 836{ 837 struct i915_3dmpeg_macroblock_1fbmv macroblock_1fbmv; 838 vector_t mv0[2]; 839 840 /* 3DMPEG_MACROBLOCK(1fbmv) */ 841 memset(¯oblock_1fbmv, 0, sizeof(macroblock_1fbmv)); 842 macroblock_1fbmv.header.dw0.type = CMD_3D; 843 macroblock_1fbmv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK; 844 macroblock_1fbmv.header.dw0.length = 2; 845 macroblock_1fbmv.header.dw1.mb_intra = 0; /* should be 0 */ 846 macroblock_1fbmv.header.dw1.forward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD) ? 1 : 0); 847 macroblock_1fbmv.header.dw1.backward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD) ? 1 : 0); 848 macroblock_1fbmv.header.dw1.h263_4mv = 0; /* should be 0 */ 849 macroblock_1fbmv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD); 850 851 if (!(mb->coded_block_pattern & 0x3f)) 852 macroblock_1fbmv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME; 853 854 macroblock_1fbmv.header.dw1.motion_type = (mb->motion_type & 0x03); 855 macroblock_1fbmv.header.dw1.vertical_field_select = (mb->motion_vertical_field_select & 0x0f); 856 macroblock_1fbmv.header.dw1.coded_block_pattern = mb->coded_block_pattern; 857 macroblock_1fbmv.header.dw1.skipped_macroblocks = 0; 858 859 mv0[0].component[0] = mb->PMV[0][0][0]; 860 mv0[0].component[1] = mb->PMV[0][0][1]; 861 mv0[1].component[0] = mb->PMV[0][1][0]; 862 mv0[1].component[1] = mb->PMV[0][1][1]; 863 864 macroblock_1fbmv.dw2 = mv0[0].v; 865 macroblock_1fbmv.dw3 = mv0[1].v; 866 867 intelBatchbufferData(¯oblock_1fbmv, sizeof(macroblock_1fbmv), 0); 868} 869 870static void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock *mb, unsigned int ps) 871{ 872 struct i915_3dmpeg_macroblock_2fbmv macroblock_2fbmv; 873 vector_t mv0[2]; 874 vector_t mv1[2]; 875 876 /* 3DMPEG_MACROBLOCK(2fbmv) */ 877 memset(¯oblock_2fbmv, 0, sizeof(macroblock_2fbmv)); 878 macroblock_2fbmv.header.dw0.type = CMD_3D; 879 macroblock_2fbmv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK; 880 macroblock_2fbmv.header.dw0.length = 4; 881 macroblock_2fbmv.header.dw1.mb_intra = 0; /* should be 0 */ 882 macroblock_2fbmv.header.dw1.forward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD) ? 1 : 0); 883 macroblock_2fbmv.header.dw1.backward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD) ? 1 : 0); 884 macroblock_2fbmv.header.dw1.h263_4mv = 0; /* should be 0 */ 885 macroblock_2fbmv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD); 886 887 if (!(mb->coded_block_pattern & 0x3f)) 888 macroblock_2fbmv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME; 889 890 macroblock_2fbmv.header.dw1.motion_type = (mb->motion_type & 0x03); 891 macroblock_2fbmv.header.dw1.vertical_field_select = (mb->motion_vertical_field_select & 0x0f); 892 macroblock_2fbmv.header.dw1.coded_block_pattern = mb->coded_block_pattern; 893 macroblock_2fbmv.header.dw1.skipped_macroblocks = 0; 894 895 mv0[0].component[0] = mb->PMV[0][0][0]; 896 mv0[0].component[1] = mb->PMV[0][0][1]; 897 mv0[1].component[0] = mb->PMV[0][1][0]; 898 mv0[1].component[1] = mb->PMV[0][1][1]; 899 mv1[0].component[0] = mb->PMV[1][0][0]; 900 mv1[0].component[1] = mb->PMV[1][0][1]; 901 mv1[1].component[0] = mb->PMV[1][1][0]; 902 mv1[1].component[1] = mb->PMV[1][1][1]; 903 904 if ((ps & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) { 905 if ((mb->motion_type & 3) == XVMC_PREDICTION_FIELD) { 906 mv0[0].component[1] = mb->PMV[0][0][1] >> 1; 907 mv0[1].component[1] = mb->PMV[0][1][1] >> 1; 908 mv1[0].component[1] = mb->PMV[1][0][1] >> 1; 909 mv1[1].component[1] = mb->PMV[1][1][1] >> 1; 910 } else if ((mb->motion_type & 3) == XVMC_PREDICTION_DUAL_PRIME) { 911 mv0[0].component[1] = mb->PMV[0][0][1] >> 1; 912 mv0[1].component[1] = mb->PMV[0][1][1] >> 1; // MPEG2 MV[0][1] isn't used 913 mv1[0].component[1] = mb->PMV[1][0][1] >> 1; 914 mv1[1].component[1] = mb->PMV[1][1][1] >> 1; 915 } 916 } 917 918 macroblock_2fbmv.dw2 = mv0[0].v; 919 macroblock_2fbmv.dw3 = mv0[1].v; 920 macroblock_2fbmv.dw4 = mv1[0].v; 921 macroblock_2fbmv.dw5 = mv1[1].v; 922 923 intelBatchbufferData(¯oblock_2fbmv, sizeof(macroblock_2fbmv), 0); 924} 925 926#if 0 927static void i915_mc_invalidate_subcontext_buffers(XvMCContext *context, unsigned int mask) 928{ 929 struct i915_3dstate_load_indirect *load_indirect = NULL; 930 sis_state *sis = NULL; 931 dis_state *dis = NULL; 932 ssb_state *ssb = NULL; 933 msb_state *msb = NULL; 934 psp_state *psp = NULL; 935 psc_state *psc = NULL; 936 i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; 937 unsigned int size; 938 void *base = NULL, *ptr = NULL; 939 940 size = sizeof(*load_indirect); 941 if (mask & BLOCK_SIS) 942 size += sizeof(*sis); 943 if (mask & BLOCK_DIS) 944 size += sizeof(*dis); 945 if (mask & BLOCK_SSB) 946 size += sizeof(*ssb); 947 if (mask & BLOCK_MSB) 948 size += sizeof(*msb); 949 if (mask & BLOCK_PSP) 950 size += sizeof(*psp); 951 if (mask & BLOCK_PSC) 952 size += sizeof(*psc); 953 954 if (size == sizeof(*load_indirect)) { 955 XVMC_ERR("There must be at least one bit set\n"); 956 return; 957 } 958 959 /* 3DSTATE_LOAD_INDIRECT */ 960 base = calloc(1, size); 961 load_indirect = (struct i915_3dstate_load_indirect *)base; 962 load_indirect->dw0.type = CMD_3D; 963 load_indirect->dw0.opcode = OPC_3DSTATE_LOAD_INDIRECT; 964 965 if (pI915XvMC->deviceID == PCI_CHIP_I915_G || 966 pI915XvMC->deviceID == PCI_CHIP_I915_GM || 967 pI915XvMC->deviceID == PCI_CHIP_I945_G || 968 pI915XvMC->deviceID == PCI_CHIP_I945_GM) 969 load_indirect->dw0.mem_select = 0; 970 else 971 load_indirect->dw0.mem_select = 1; 972 973 load_indirect->dw0.block_mask = mask; 974 load_indirect->dw0.length = (size >> 2) - 2; 975 ptr = ++load_indirect; 976 977 /* SIS */ 978 if (mask & BLOCK_SIS) { 979 sis = (sis_state *)ptr; 980 sis->dw0.valid = 0; 981 sis->dw0.buffer_address = 0; 982 sis->dw1.length = 0; 983 ptr = ++sis; 984 } 985 986 /* DIS */ 987 if (mask & BLOCK_DIS) { 988 dis = (dis_state *)ptr; 989 dis->dw0.valid = 0; 990 dis->dw0.reset = 0; 991 dis->dw0.buffer_address = 0; 992 ptr = ++dis; 993 } 994 995 /* SSB */ 996 if (mask & BLOCK_SSB) { 997 ssb = (ssb_state *)ptr; 998 ssb->dw0.valid = 0; 999 ssb->dw0.buffer_address = 0; 1000 ssb->dw1.length = 0; 1001 ptr = ++ssb; 1002 } 1003 1004 /* MSB */ 1005 if (mask & BLOCK_MSB) { 1006 msb = (msb_state *)ptr; 1007 msb->dw0.valid = 0; 1008 msb->dw0.buffer_address = 0; 1009 msb->dw1.length = 0; 1010 ptr = ++msb; 1011 } 1012 1013 /* PSP */ 1014 if (mask & BLOCK_PSP) { 1015 psp = (psp_state *)ptr; 1016 psp->dw0.valid = 0; 1017 psp->dw0.buffer_address = 0; 1018 psp->dw1.length = 0; 1019 ptr = ++psp; 1020 } 1021 1022 /* PSC */ 1023 if (mask & BLOCK_PSC) { 1024 psc = (psc_state *)ptr; 1025 psc->dw0.valid = 0; 1026 psc->dw0.buffer_address = 0; 1027 psc->dw1.length = 0; 1028 ptr = ++psc; 1029 } 1030 1031 intelBatchbufferData(base, size, 0); 1032 free(base); 1033} 1034#endif 1035 1036static int i915_xvmc_map_buffers(i915XvMCContext *pI915XvMC) 1037{ 1038 if (drmMap(xvmc_driver->fd, 1039 pI915XvMC->sis.handle, 1040 pI915XvMC->sis.size, 1041 (drmAddress *)&pI915XvMC->sis.map) != 0) { 1042 return -1; 1043 } 1044 1045 if (drmMap(xvmc_driver->fd, 1046 pI915XvMC->ssb.handle, 1047 pI915XvMC->ssb.size, 1048 (drmAddress *)&pI915XvMC->ssb.map) != 0) { 1049 return -1; 1050 } 1051 1052 if (drmMap(xvmc_driver->fd, 1053 pI915XvMC->msb.handle, 1054 pI915XvMC->msb.size, 1055 (drmAddress *)&pI915XvMC->msb.map) != 0) { 1056 return -1; 1057 } 1058 1059 if (drmMap(xvmc_driver->fd, 1060 pI915XvMC->psp.handle, 1061 pI915XvMC->psp.size, 1062 (drmAddress *)&pI915XvMC->psp.map) != 0) { 1063 return -1; 1064 } 1065 1066 if (drmMap(xvmc_driver->fd, 1067 pI915XvMC->psc.handle, 1068 pI915XvMC->psc.size, 1069 (drmAddress *)&pI915XvMC->psc.map) != 0) { 1070 return -1; 1071 } 1072 1073 if (drmMap(xvmc_driver->fd, 1074 pI915XvMC->corrdata.handle, 1075 pI915XvMC->corrdata.size, 1076 (drmAddress *)&pI915XvMC->corrdata.map) != 0) { 1077 return -1; 1078 } 1079 1080 return 0; 1081} 1082 1083static void i915_xvmc_unmap_buffers(i915XvMCContext *pI915XvMC) 1084{ 1085 if (pI915XvMC->sis.map) { 1086 drmUnmap(pI915XvMC->sis.map, pI915XvMC->sis.size); 1087 pI915XvMC->sis.map = NULL; 1088 } 1089 1090 if (pI915XvMC->ssb.map) { 1091 drmUnmap(pI915XvMC->ssb.map, pI915XvMC->ssb.size); 1092 pI915XvMC->ssb.map = NULL; 1093 } 1094 1095 if (pI915XvMC->msb.map) { 1096 drmUnmap(pI915XvMC->msb.map, pI915XvMC->msb.size); 1097 pI915XvMC->msb.map = NULL; 1098 } 1099 1100 if (pI915XvMC->psp.map) { 1101 drmUnmap(pI915XvMC->psp.map, pI915XvMC->psp.size); 1102 pI915XvMC->psp.map = NULL; 1103 } 1104 1105 if (pI915XvMC->psc.map) { 1106 drmUnmap(pI915XvMC->psc.map, pI915XvMC->psc.size); 1107 pI915XvMC->psc.map = NULL; 1108 } 1109 1110 if (pI915XvMC->corrdata.map) { 1111 drmUnmap(pI915XvMC->corrdata.map, pI915XvMC->corrdata.size); 1112 pI915XvMC->corrdata.map = NULL; 1113 } 1114} 1115 1116#if 0 1117/* 1118 * Video post processing 1119 */ 1120static void i915_yuv2rgb_map_state_buffer(XvMCSurface *target_surface) 1121{ 1122 struct i915_3dstate_map_state *map_state; 1123 struct texture_map *tm; 1124 i915XvMCSurface *privTarget = NULL; 1125 i915XvMCContext *pI915XvMC = NULL; 1126 unsigned int w = target_surface->width, h = target_surface->height; 1127 1128 privTarget = (i915XvMCSurface *)target_surface->privData; 1129 pI915XvMC = (i915XvMCContext *)privTarget->privContext; 1130 /* 3DSATE_MAP_STATE */ 1131 map_state = (struct i915_3dstate_map_state *)pI915XvMC->msb.map; 1132 memset(map_state, 0, sizeof(*map_state)); 1133 map_state->dw0.type = CMD_3D; 1134 map_state->dw0.opcode = OPC_3DSTATE_MAP_STATE; 1135 map_state->dw0.retain = 0; 1136 map_state->dw0.length = 9; 1137 map_state->dw1.map_mask = MAP_MAP0 | MAP_MAP1 | MAP_MAP2; 1138 1139 /* texture map 0: V Plane */ 1140 tm = (struct texture_map *)(++map_state); 1141 memset(tm, 0, sizeof(*tm)); 1142 tm->tm0.v_ls_offset = 0; 1143 tm->tm0.v_ls = 0; 1144 tm->tm0.base_address = VOFFSET(privTarget); 1145 tm->tm1.tile_walk = TILEWALK_XMAJOR; 1146 tm->tm1.tiled_surface = 0; 1147 tm->tm1.utilize_fence_regs = 1; 1148 tm->tm1.texel_fmt = 0; 1149 tm->tm1.surface_fmt = 1; 1150 tm->tm1.width = (w >> 1) - 1; 1151 tm->tm1.height = (h >> 1) - 1; 1152 tm->tm2.depth = 0; 1153 tm->tm2.max_lod = 0; 1154 tm->tm2.cube_face = 0; 1155 tm->tm2.pitch = (privTarget->uvStride >> 2) - 1; /* in DWords - 1 */ 1156 1157 /* texture map 1: Y Plane */ 1158 ++tm; 1159 memset(tm, 0, sizeof(*tm)); 1160 tm->tm0.v_ls_offset = 0; 1161 tm->tm0.v_ls = 0; 1162 tm->tm0.base_address = YOFFSET(privTarget); 1163 tm->tm1.tile_walk = TILEWALK_XMAJOR; 1164 tm->tm1.tiled_surface = 0; 1165 tm->tm1.utilize_fence_regs = 1; 1166 tm->tm1.texel_fmt = 0; 1167 tm->tm1.surface_fmt = 1; 1168 tm->tm1.width = w - 1; 1169 tm->tm1.height = h - 1; 1170 tm->tm2.depth = 0; 1171 tm->tm2.max_lod = 0; 1172 tm->tm2.cube_face = 0; 1173 tm->tm2.pitch = (privTarget->yStride >> 2) - 1; /* in DWords - 1 */ 1174 1175 /* texture map 2: U Plane */ 1176 ++tm; 1177 memset(tm, 0, sizeof(*tm)); 1178 tm->tm0.v_ls_offset = 0; 1179 tm->tm0.v_ls = 0; 1180 tm->tm0.base_address = UOFFSET(privTarget); 1181 tm->tm1.tile_walk = TILEWALK_XMAJOR; 1182 tm->tm1.tiled_surface = 0; 1183 tm->tm1.utilize_fence_regs = 1; 1184 tm->tm1.texel_fmt = 0; 1185 tm->tm1.surface_fmt = 1; 1186 tm->tm1.width = (w >> 1) - 1; 1187 tm->tm1.height = (h >> 1) - 1; 1188 tm->tm2.depth = 0; 1189 tm->tm2.max_lod = 0; 1190 tm->tm2.cube_face = 0; 1191 tm->tm2.pitch = (privTarget->uvStride >> 2) - 1; /* in DWords - 1 */ 1192} 1193#endif 1194 1195#if 0 1196static void i915_yuv2rgb_sampler_state_buffer(XvMCSurface *surface) 1197{ 1198 struct i915_3dstate_sampler_state *sampler_state; 1199 struct texture_sampler *ts; 1200 i915XvMCSurface *privSurface = (i915XvMCSurface *)surface->privData; 1201 i915XvMCContext *pI915XvMC = (i915XvMCContext *)privSurface->privContext; 1202 1203 /* 3DSATE_SAMPLER_STATE */ 1204 sampler_state = (struct i915_3dstate_sampler_state *)pI915XvMC->ssb.map; 1205 memset(sampler_state, 0, sizeof(*sampler_state)); 1206 sampler_state->dw0.type = CMD_3D; 1207 sampler_state->dw0.opcode = OPC_3DSTATE_SAMPLER_STATE; 1208 sampler_state->dw0.length = 9; 1209 sampler_state->dw1.sampler_masker = SAMPLER_SAMPLER0 | SAMPLER_SAMPLER1 | SAMPLER_SAMPLER2; 1210 1211 /* Sampler 0 */ 1212 ts = (struct texture_sampler *)(++sampler_state); 1213 memset(ts, 0, sizeof(*ts)); 1214 ts->ts0.reverse_gamma = 0; 1215 ts->ts0.planar2packet = 1; 1216 ts->ts0.color_conversion = 1; 1217 ts->ts0.chromakey_index = 0; 1218 ts->ts0.base_level = 0; 1219 ts->ts0.mip_filter = MIPFILTER_NONE; /* NONE */ 1220 ts->ts0.mag_filter = MAPFILTER_LINEAR; /* LINEAR */ 1221 ts->ts0.min_filter = MAPFILTER_LINEAR; /* LINEAR */ 1222 ts->ts0.lod_bias = 0; 1223 ts->ts0.shadow_enable = 0; 1224 ts->ts0.max_anisotropy = ANISORATIO_2; 1225 ts->ts0.shadow_function = PREFILTEROP_ALWAYS; 1226 ts->ts1.min_lod = 0; /* Maximum Mip Level */ 1227 ts->ts1.kill_pixel = 0; 1228 ts->ts1.keyed_texture_filter = 0; 1229 ts->ts1.chromakey_enable = 0; 1230 ts->ts1.tcx_control = TEXCOORDMODE_CLAMP; 1231 ts->ts1.tcy_control = TEXCOORDMODE_CLAMP; 1232 ts->ts1.tcz_control = TEXCOORDMODE_CLAMP; 1233 ts->ts1.normalized_coor = 0; 1234 ts->ts1.map_index = 0; 1235 ts->ts1.east_deinterlacer = 0; 1236 ts->ts2.default_color = 0; 1237 1238 /* Sampler 1 */ 1239 ++ts; 1240 memset(ts, 0, sizeof(*ts)); 1241 ts->ts0.reverse_gamma = 0; 1242 ts->ts0.planar2packet = 1; 1243 ts->ts0.color_conversion = 1; 1244 ts->ts0.chromakey_index = 0; 1245 ts->ts0.base_level = 0; 1246 ts->ts0.mip_filter = MIPFILTER_NONE; /* NONE */ 1247 ts->ts0.mag_filter = MAPFILTER_LINEAR; /* LINEAR */ 1248 ts->ts0.min_filter = MAPFILTER_LINEAR; /* LINEAR */ 1249 ts->ts0.lod_bias = 0; 1250 ts->ts0.shadow_enable = 0; 1251 ts->ts0.max_anisotropy = ANISORATIO_2; 1252 ts->ts0.shadow_function = PREFILTEROP_ALWAYS; 1253 ts->ts1.min_lod = 0; /* Maximum Mip Level */ 1254 ts->ts1.kill_pixel = 0; 1255 ts->ts1.keyed_texture_filter = 0; 1256 ts->ts1.chromakey_enable = 0; 1257 ts->ts1.tcx_control = TEXCOORDMODE_CLAMP; 1258 ts->ts1.tcy_control = TEXCOORDMODE_CLAMP; 1259 ts->ts1.tcz_control = TEXCOORDMODE_CLAMP; 1260 ts->ts1.normalized_coor = 0; 1261 ts->ts1.map_index = 1; 1262 ts->ts1.east_deinterlacer = 0; 1263 ts->ts2.default_color = 0; 1264 1265 /* Sampler 2 */ 1266 ++ts; 1267 memset(ts, 0, sizeof(*ts)); 1268 ts->ts0.reverse_gamma = 0; 1269 ts->ts0.planar2packet = 1; 1270 ts->ts0.color_conversion = 1; 1271 ts->ts0.chromakey_index = 0; 1272 ts->ts0.base_level = 0; 1273 ts->ts0.mip_filter = MIPFILTER_NONE; /* NONE */ 1274 ts->ts0.mag_filter = MAPFILTER_LINEAR; /* LINEAR */ 1275 ts->ts0.min_filter = MAPFILTER_LINEAR; /* LINEAR */ 1276 ts->ts0.lod_bias = 0; 1277 ts->ts0.shadow_enable = 0; 1278 ts->ts0.max_anisotropy = ANISORATIO_2; 1279 ts->ts0.shadow_function = PREFILTEROP_ALWAYS; 1280 ts->ts1.min_lod = 0; /* Maximum Mip Level */ 1281 ts->ts1.kill_pixel = 0; 1282 ts->ts1.keyed_texture_filter = 0; 1283 ts->ts1.chromakey_enable = 0; 1284 ts->ts1.tcx_control = TEXCOORDMODE_CLAMP; 1285 ts->ts1.tcy_control = TEXCOORDMODE_CLAMP; 1286 ts->ts1.tcz_control = TEXCOORDMODE_CLAMP; 1287 ts->ts1.normalized_coor = 0; 1288 ts->ts1.map_index = 2; 1289 ts->ts1.east_deinterlacer = 0; 1290 ts->ts2.default_color = 0; 1291} 1292#endif 1293 1294#if 0 1295static void i915_yuv2rgb_static_indirect_state_buffer(XvMCSurface *surface, 1296 unsigned int dstaddr, 1297 int dstpitch) 1298{ 1299 struct i915_3dstate_buffer_info *buffer_info; 1300 struct i915_3dstate_dest_buffer_variables *dest_buffer_variables; 1301 i915XvMCSurface *privSurface = (i915XvMCSurface *)surface->privData; 1302 i915XvMCContext *pI915XvMC = (i915XvMCContext *)privSurface->privContext; 1303 1304 /* 3DSTATE_BUFFER_INFO */ 1305 buffer_info = (struct i915_3dstate_buffer_info *)pI915XvMC->sis.map; 1306 memset(buffer_info, 0, sizeof(*buffer_info)); 1307 buffer_info->dw0.type = CMD_3D; 1308 buffer_info->dw0.opcode = OPC_3DSTATE_BUFFER_INFO; 1309 buffer_info->dw0.length = 1; 1310 buffer_info->dw1.aux_id = 0; 1311 buffer_info->dw1.buffer_id = BUFFERID_COLOR_BACK; 1312 buffer_info->dw1.fence_regs = 1; 1313 buffer_info->dw1.tiled_surface = 0; /* linear */ 1314 buffer_info->dw1.walk = TILEWALK_XMAJOR; 1315 buffer_info->dw1.pitch = dstpitch; 1316 buffer_info->dw2.base_address = dstaddr; 1317 1318 /* 3DSTATE_DEST_BUFFER_VARIABLES */ 1319 dest_buffer_variables = (struct i915_3dstate_dest_buffer_variables *)(++buffer_info); 1320 memset(dest_buffer_variables, 0, sizeof(*dest_buffer_variables)); 1321 dest_buffer_variables->dw0.type = CMD_3D; 1322 dest_buffer_variables->dw0.opcode = OPC_3DSTATE_DEST_BUFFER_VARIABLES; 1323 dest_buffer_variables->dw0.length = 0; 1324 dest_buffer_variables->dw1.dest_v_bias = 8; /* FIXME 0x1000 .5 ??? */ 1325 dest_buffer_variables->dw1.dest_h_bias = 8; 1326 dest_buffer_variables->dw1.color_fmt = COLORBUFFER_A8R8G8B8; /* FIXME */ 1327} 1328#endif 1329 1330#if 0 1331static void i915_yuv2rgb_pixel_shader_program_buffer(XvMCSurface *surface) 1332{ 1333 struct i915_3dstate_pixel_shader_program *pixel_shader_program; 1334 i915XvMCSurface *privSurface = (i915XvMCSurface *)surface->privData; 1335 i915XvMCContext *pI915XvMC = (i915XvMCContext *)privSurface->privContext; 1336 unsigned int *inst; 1337 unsigned int dest, src0, src1; 1338 1339 /* Shader 0 */ 1340 pixel_shader_program = (struct i915_3dstate_pixel_shader_program *)pI915XvMC->psp.map; 1341 memset(pixel_shader_program, 0, sizeof(*pixel_shader_program)); 1342 pixel_shader_program->dw0.type = CMD_3D; 1343 pixel_shader_program->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM; 1344 pixel_shader_program->dw0.retain = 0; 1345 pixel_shader_program->dw0.length = 23; 1346 /* dcl t0.xy */ 1347 inst = (unsigned int*)(++pixel_shader_program); 1348 i915_inst_decl(inst, REG_TYPE_T, T_TEX0, D0_CHANNEL_XY); 1349 /* dcl t1.xy */ 1350 inst += 3; 1351 i915_inst_decl(inst, REG_TYPE_T, T_TEX1, D0_CHANNEL_XY); 1352 /* dcl_2D s0 */ 1353 inst += 3; 1354 i915_inst_decl(inst, REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D); 1355 /* dcl_2D s1 */ 1356 inst += 3; 1357 i915_inst_decl(inst, REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D); 1358 /* dcl_2D s2 */ 1359 inst += 3; 1360 i915_inst_decl(inst, REG_TYPE_S, 2, D0_SAMPLE_TYPE_2D); 1361 /* texld r0 t1 s0 */ 1362 inst += 3; 1363 dest = UREG(REG_TYPE_R, 0); 1364 src0 = UREG(REG_TYPE_T, 1); /* COORD */ 1365 src1 = UREG(REG_TYPE_S, 0); /* SAMPLER */ 1366 i915_inst_texld(inst, T0_TEXLD, dest, src0, src1); 1367 /* texld r0 t0 s1 */ 1368 inst += 3; 1369 dest = UREG(REG_TYPE_R, 0); 1370 src0 = UREG(REG_TYPE_T, 0); /* COORD */ 1371 src1 = UREG(REG_TYPE_S, 1); /* SAMPLER */ 1372 i915_inst_texld(inst, T0_TEXLD, dest, src0, src1); 1373 /* texld oC t1 s2 */ 1374 inst += 3; 1375 dest = UREG(REG_TYPE_OC, 0); 1376 src0 = UREG(REG_TYPE_T, 1); /* COORD */ 1377 src1 = UREG(REG_TYPE_S, 2); /* SAMPLER */ 1378 i915_inst_texld(inst, T0_TEXLD, dest, src0, src1); 1379} 1380#endif 1381 1382#if 0 1383static void i915_yuv2rgb_proc(XvMCSurface *surface) 1384{ 1385 i915XvMCSurface *privSurface = (i915XvMCSurface *)surface->privData; 1386 i915XvMCContext *pI915XvMC = (i915XvMCContext *)privSurface->privContext; 1387 struct i915_3dstate_load_state_immediate_1 *load_state_immediate_1 = NULL; 1388 struct s2_dword *s2 = NULL; 1389 struct s3_dword *s3 = NULL; 1390 struct s4_dword *s4 = NULL; 1391 struct s5_dword *s5 = NULL; 1392 struct s6_dword *s6 = NULL; 1393 struct s7_dword *s7 = NULL; 1394 struct i915_3dstate_scissor_rectangle scissor_rectangle; 1395 struct i915_3dstate_load_indirect *load_indirect = NULL; 1396 sis_state *sis = NULL; 1397 ssb_state *ssb = NULL; 1398 msb_state *msb = NULL; 1399 psp_state *psp = NULL; 1400 struct i915_3dprimitive *_3dprimitive = NULL; 1401 struct vertex_data *vd = NULL; 1402 unsigned int size; 1403 void *base = NULL; 1404 1405 /* 3DSTATE_LOAD_STATE_IMMEDIATE_1 */ 1406 size = sizeof(*load_state_immediate_1) + sizeof(*s2) + sizeof(*s3) + 1407 sizeof(*s4) + sizeof(*s5) + sizeof(*s6) + sizeof(*s7); 1408 base = calloc(1, size); 1409 load_state_immediate_1 = (struct i915_3dstate_load_state_immediate_1 *)base; 1410 load_state_immediate_1->dw0.type = CMD_3D; 1411 load_state_immediate_1->dw0.opcode = OPC_3DSTATE_LOAD_STATE_IMMEDIATE_1; 1412 load_state_immediate_1->dw0.load_s2 = 1; 1413 load_state_immediate_1->dw0.load_s3 = 1; 1414 load_state_immediate_1->dw0.load_s4 = 1; 1415 load_state_immediate_1->dw0.load_s5 = 1; 1416 load_state_immediate_1->dw0.load_s6 = 1; 1417 load_state_immediate_1->dw0.load_s7 = 1; 1418 load_state_immediate_1->dw0.length = 5; 1419 1420 s2 = (struct s2_dword *)(++load_state_immediate_1); 1421 s2->set0_texcoord_fmt = TEXCOORDFMT_2FP; 1422 s2->set1_texcoord_fmt = TEXCOORDFMT_2FP; 1423 s2->set2_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT; 1424 s2->set3_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT; 1425 s2->set4_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT; 1426 s2->set5_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT; 1427 s2->set6_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT; 1428 s2->set7_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT; 1429 1430 s3 = (struct s3_dword *)(++s2); 1431 s4 = (struct s4_dword *)(++s3); 1432 s4->position_mask = VERTEXHAS_XY; 1433 s4->cull_mode = CULLMODE_NONE; 1434 s4->color_shade_mode = SHADEMODE_FLAT; 1435 s4->specular_shade_mode = SHADEMODE_FLAT; 1436 s4->fog_shade_mode = SHADEMODE_FLAT; 1437 s4->alpha_shade_mode = SHADEMODE_FLAT; 1438 s4->line_width = 0x2; /* FIXME: 1.0??? */ 1439 s4->point_width = 0x1; 1440 1441 s5 = (struct s5_dword *)(++s4); 1442 s6 = (struct s6_dword *)(++s5); 1443 s6->src_blend_factor = 1; 1444 s6->dest_blend_factor = 1; 1445 s6->color_buffer_write = 1; 1446 1447 s7 = (struct s7_dword *)(++s6); 1448 intelBatchbufferData(base, size, 0); 1449 free(base); 1450 1451 /* 3DSTATE_3DSTATE_SCISSOR_RECTANGLE */ 1452 scissor_rectangle.dw0.type = CMD_3D; 1453 scissor_rectangle.dw0.opcode = OPC_3DSTATE_SCISSOR_RECTANGLE; 1454 scissor_rectangle.dw0.length = 1; 1455 scissor_rectangle.dw1.min_x = 0; 1456 scissor_rectangle.dw1.min_y = 0; 1457 scissor_rectangle.dw2.max_x = 2047; 1458 scissor_rectangle.dw2.max_y = 2047; 1459 intelBatchbufferData(&scissor_rectangle, sizeof(scissor_rectangle), 0); 1460 1461 /* 3DSTATE_LOAD_INDIRECT */ 1462 size = sizeof(*load_indirect) + sizeof(*sis) + sizeof(*ssb) + sizeof(*msb) + sizeof(*psp); 1463 base = calloc(1, size); 1464 load_indirect = (struct i915_3dstate_load_indirect *)base; 1465 load_indirect->dw0.type = CMD_3D; 1466 load_indirect->dw0.opcode = OPC_3DSTATE_LOAD_INDIRECT; 1467 load_indirect->dw0.mem_select = 1; /* Bearlake only */ 1468 load_indirect->dw0.block_mask = BLOCK_SIS | BLOCK_SSB | BLOCK_MSB | BLOCK_PSP; 1469 load_indirect->dw0.length = 7; 1470 1471 /* SIS */ 1472 sis = (sis_state *)(++load_indirect); 1473 sis->dw0.valid = 1; 1474 sis->dw0.buffer_address = pI915XvMC->sis.offset; 1475 sis->dw1.length = ((sizeof(struct i915_3dstate_buffer_info) + 1476 sizeof(struct i915_3dstate_dest_buffer_variables)) >> 2) - 1; 1477 1478 /* SSB */ 1479 ssb = (ssb_state *)(++sis); 1480 ssb->dw0.valid = 1; 1481 ssb->dw0.buffer_address = pI915XvMC->ssb.offset; 1482 ssb->dw1.length = ((sizeof(struct i915_3dstate_sampler_state) + 1483 sizeof(struct texture_sampler) * 3) >> 2) - 1; 1484 1485 /* MSB */ 1486 msb = (msb_state *)(++ssb); 1487 msb->dw0.valid = 1; 1488 msb->dw0.buffer_address = pI915XvMC->msb.offset; 1489 msb->dw1.length = ((sizeof(struct i915_3dstate_map_state) + 1490 sizeof(struct texture_map) * 3) >> 2) - 1; 1491 1492 /* PSP */ 1493 psp = (psp_state *)(++msb); 1494 psp->dw0.valid = 1; 1495 psp->dw0.buffer_address = pI915XvMC->psp.offset; 1496 psp->dw1.length = ((sizeof(struct i915_3dstate_pixel_shader_program) + 1497 sizeof(union shader_inst)) >> 2) - 1; 1498 1499 intelBatchbufferData(base, size, 0); 1500 free(base); 1501 1502 /* 3DPRIMITIVE */ 1503 size = sizeof(*_3dprimitive) + sizeof(*vd) * 3; 1504 base = calloc(1, size); 1505 _3dprimitive = (struct i915_3dprimitive *)base; 1506 _3dprimitive->dw0.inline_prim.type = CMD_3D; 1507 _3dprimitive->dw0.inline_prim.opcode = OPC_3DPRIMITIVE; 1508 _3dprimitive->dw0.inline_prim.vertex_location = VERTEX_INLINE; 1509 _3dprimitive->dw0.inline_prim.prim = PRIM_RECTLIST; 1510 _3dprimitive->dw0.inline_prim.length = size - 2; 1511 1512 vd = (struct vertex_data *)(++_3dprimitive); 1513 vd->x = 0; /* FIXME!!! */ 1514 vd->x = 0; /* FIXME */ 1515 vd->tc0.tcx = 0; 1516 vd->tc0.tcy = 0; 1517 vd->tc1.tcx = 0; 1518 vd->tc1.tcy = 0; 1519 1520 ++vd; 1521 vd->x = 0; /* FIXME!!! */ 1522 vd->x = 0; /* FIXME */ 1523 vd->tc0.tcx = 0; 1524 vd->tc0.tcy = 0; 1525 vd->tc1.tcx = 0; 1526 vd->tc1.tcy = 0; 1527 1528 ++vd; 1529 vd->x = 0; /* FIXME!!! */ 1530 vd->x = 0; /* FIXME */ 1531 vd->tc0.tcx = 0; 1532 vd->tc0.tcy = 0; 1533 vd->tc1.tcx = 0; 1534 vd->tc1.tcy = 0; 1535 1536 intelBatchbufferData(base, size, 0); 1537 free(base); 1538} 1539#endif 1540 1541/* 1542 * Function: i915_release_resource 1543 */ 1544static void i915_release_resource(Display *display, XvMCContext *context) 1545{ 1546 i915XvMCContext *pI915XvMC; 1547 1548 if (!(pI915XvMC = context->privData)) 1549 return; 1550 1551 pI915XvMC->ref--; 1552 i915_xvmc_unmap_buffers(pI915XvMC); 1553 1554 free(pI915XvMC); 1555 context->privData = NULL; 1556} 1557 1558static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context, 1559 int priv_count, CARD32 *priv_data) 1560{ 1561 i915XvMCContext *pI915XvMC = NULL; 1562 I915XvMCCreateContextRec *tmpComm = NULL; 1563 1564 XVMC_DBG("%s\n", __FUNCTION__); 1565 1566 if (priv_count != (sizeof(I915XvMCCreateContextRec) >> 2)) { 1567 XVMC_ERR("_xvmc_create_context() returned incorrect data size!"); 1568 XVMC_INFO("\tExpected %d, got %d", 1569 (int)(sizeof(I915XvMCCreateContextRec) >> 2),priv_count); 1570 _xvmc_destroy_context(display, context); 1571 XFree(priv_data); 1572 context->privData = NULL; 1573 return BadValue; 1574 } 1575 1576 context->privData = (void *)calloc(1, sizeof(i915XvMCContext)); 1577 if (!context->privData) { 1578 XVMC_ERR("Unable to allocate resources for XvMC context."); 1579 return BadAlloc; 1580 } 1581 pI915XvMC = (i915XvMCContext *)context->privData; 1582 1583 tmpComm = (I915XvMCCreateContextRec *)priv_data; 1584 pI915XvMC->ctxno = tmpComm->ctxno; 1585 pI915XvMC->deviceID = tmpComm->deviceID; 1586 pI915XvMC->sis.handle = tmpComm->sis.handle; 1587 pI915XvMC->sis.offset = tmpComm->sis.offset; 1588 pI915XvMC->sis.size = tmpComm->sis.size; 1589 pI915XvMC->ssb.handle = tmpComm->ssb.handle; 1590 pI915XvMC->ssb.offset = tmpComm->ssb.offset; 1591 pI915XvMC->ssb.size = tmpComm->ssb.size; 1592 pI915XvMC->msb.handle = tmpComm->msb.handle; 1593 pI915XvMC->msb.offset = tmpComm->msb.offset; 1594 pI915XvMC->msb.size = tmpComm->msb.size; 1595 pI915XvMC->psp.handle = tmpComm->psp.handle; 1596 pI915XvMC->psp.offset = tmpComm->psp.offset; 1597 pI915XvMC->psp.size = tmpComm->psp.size; 1598 pI915XvMC->psc.handle = tmpComm->psc.handle; 1599 pI915XvMC->psc.offset = tmpComm->psc.offset; 1600 pI915XvMC->psc.size = tmpComm->psc.size; 1601 1602 if (pI915XvMC->deviceID == PCI_CHIP_I915_G || 1603 pI915XvMC->deviceID == PCI_CHIP_I915_GM) { 1604 pI915XvMC->sis.bus_addr = tmpComm->sis.bus_addr; 1605 pI915XvMC->ssb.bus_addr = tmpComm->ssb.bus_addr; 1606 pI915XvMC->msb.bus_addr = tmpComm->msb.bus_addr; 1607 pI915XvMC->psp.bus_addr = tmpComm->psp.bus_addr; 1608 pI915XvMC->psc.bus_addr = tmpComm->psc.bus_addr; 1609 } 1610 1611 pI915XvMC->corrdata.handle = tmpComm->corrdata.handle; 1612 pI915XvMC->corrdata.offset = tmpComm->corrdata.offset; 1613 pI915XvMC->corrdata.size = tmpComm->corrdata.size; 1614 1615 /* Must free the private data we were passed from X */ 1616 XFree(priv_data); 1617 priv_data = NULL; 1618 1619 if (i915_xvmc_map_buffers(pI915XvMC)) { 1620 i915_xvmc_unmap_buffers(pI915XvMC); 1621 free(pI915XvMC); 1622 context->privData = NULL; 1623 return BadAlloc; 1624 } 1625 1626 /* Initialize private context values */ 1627 pI915XvMC->yStride = STRIDE(context->width); 1628 pI915XvMC->uvStride = STRIDE(context->width >> 1); 1629 pI915XvMC->haveXv = 0; 1630 pI915XvMC->dual_prime = 0; 1631 pI915XvMC->last_flip = 0; 1632 pI915XvMC->port = context->port; 1633 pI915XvMC->ref = 1; 1634 1635 /* pre-init state buffers */ 1636 i915_mc_one_time_context_init(context); 1637 i915_mc_one_time_state_init(context); 1638 1639 i915_mc_static_indirect_state_init(context); 1640 1641 i915_mc_map_state_init(context); 1642 1643 i915_mc_load_indirect_render_init(context); 1644 return Success; 1645} 1646 1647static int i915_xvmc_mc_destroy_context(Display *display, XvMCContext *context) 1648{ 1649 i915XvMCContext *pI915XvMC; 1650 1651 if (!(pI915XvMC = context->privData)) 1652 return XvMCBadContext; 1653 1654 /* Pass Control to the X server to destroy the drm_context_t */ 1655 i915_release_resource(display,context); 1656 1657 free(one_time_load_state_imm1); 1658 free(one_time_load_indirect); 1659 free(mc_render_load_indirect); 1660 return Success; 1661} 1662 1663static Status i915_xvmc_mc_create_surface(Display *display, 1664 XvMCContext *context, XvMCSurface *surface, int priv_count, 1665 CARD32 *priv_data) 1666{ 1667 i915XvMCContext *pI915XvMC; 1668 i915XvMCSurface *pI915Surface; 1669 I915XvMCCreateSurfaceRec *tmpComm = NULL; 1670 1671 if (!(pI915XvMC = context->privData)) 1672 return XvMCBadContext; 1673 1674 XVMC_DBG("%s\n", __FUNCTION__); 1675 1676 if (priv_count != (sizeof(I915XvMCCreateSurfaceRec) >> 2)) { 1677 XVMC_ERR("_xvmc_create_surface() returned incorrect data size!"); 1678 XVMC_INFO("\tExpected %d, got %d", 1679 (int)(sizeof(I915XvMCCreateSurfaceRec) >> 2), priv_count); 1680 _xvmc_destroy_surface(display, surface); 1681 XFree(priv_data); 1682 return BadAlloc; 1683 } 1684 1685 PPTHREAD_MUTEX_LOCK(); 1686 surface->privData = (i915XvMCSurface *)malloc(sizeof(i915XvMCSurface)); 1687 1688 if (!(pI915Surface = surface->privData)) { 1689 PPTHREAD_MUTEX_UNLOCK(); 1690 return BadAlloc; 1691 } 1692 1693 /* Initialize private values */ 1694 pI915Surface->last_render = 0; 1695 pI915Surface->last_flip = 0; 1696 pI915Surface->yStride = pI915XvMC->yStride; 1697 pI915Surface->uvStride = pI915XvMC->uvStride; 1698 pI915Surface->width = context->width; 1699 pI915Surface->height = context->height; 1700 pI915Surface->privContext = pI915XvMC; 1701 pI915Surface->privSubPic = NULL; 1702 pI915Surface->srf.map = NULL; 1703 1704 tmpComm = (I915XvMCCreateSurfaceRec *)priv_data; 1705 1706 pI915Surface->srfNo = tmpComm->srfno; 1707 pI915Surface->srf.handle = tmpComm->srf.handle; 1708 pI915Surface->srf.offset = tmpComm->srf.offset; 1709 pI915Surface->srf.size = tmpComm->srf.size; 1710 1711 XFree(priv_data); 1712 1713 if (drmMap(xvmc_driver->fd, 1714 pI915Surface->srf.handle, 1715 pI915Surface->srf.size, 1716 (drmAddress *)&pI915Surface->srf.map) != 0) { 1717 XVMC_ERR("mapping surface memory failed!\n"); 1718 _xvmc_destroy_surface(display, surface); 1719 free(pI915Surface); 1720 surface->privData = NULL; 1721 PPTHREAD_MUTEX_UNLOCK(); 1722 return BadAlloc; 1723 } 1724 1725 pI915XvMC->ref++; 1726 PPTHREAD_MUTEX_UNLOCK(); 1727 return 0; 1728} 1729 1730 1731static int i915_xvmc_mc_destroy_surface(Display *display, XvMCSurface *surface) 1732{ 1733 i915XvMCSurface *pI915Surface; 1734 i915XvMCContext *pI915XvMC; 1735 1736 if (!display || !surface) 1737 return BadValue; 1738 1739 if (!(pI915Surface = surface->privData)) 1740 return XvMCBadSurface; 1741 1742 if (!(pI915XvMC = pI915Surface->privContext)) 1743 return XvMCBadSurface; 1744 1745 if (pI915Surface->last_flip) 1746 XvMCSyncSurface(display,surface); 1747 1748 if (pI915Surface->srf.map) 1749 drmUnmap(pI915Surface->srf.map, pI915Surface->srf.size); 1750 1751 free(pI915Surface); 1752 surface->privData = NULL; 1753 pI915XvMC->ref--; 1754 1755 return Success; 1756} 1757 1758 1759static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context, 1760 unsigned int picture_structure, 1761 XvMCSurface *target_surface, 1762 XvMCSurface *past_surface, 1763 XvMCSurface *future_surface, 1764 unsigned int flags, 1765 unsigned int num_macroblocks, 1766 unsigned int first_macroblock, 1767 XvMCMacroBlockArray *macroblock_array, 1768 XvMCBlockArray *blocks) 1769{ 1770 int i; 1771 int picture_coding_type = MPEG_I_PICTURE; 1772 /* correction data buffer */ 1773 char *corrdata_ptr; 1774 int corrdata_size = 0; 1775 1776 /* Block Pointer */ 1777 short *block_ptr; 1778 /* Current Macroblock Pointer */ 1779 XvMCMacroBlock *mb; 1780 1781 intel_xvmc_context_ptr intel_ctx; 1782 1783 i915XvMCSurface *privTarget = NULL; 1784 i915XvMCSurface *privFuture = NULL; 1785 i915XvMCSurface *privPast = NULL; 1786 i915XvMCContext *pI915XvMC = NULL; 1787 1788 XVMC_DBG("%s\n", __FUNCTION__); 1789 1790 /* Check Parameters for validity */ 1791 if (!display || !context || !target_surface) { 1792 XVMC_ERR("Invalid Display, Context or Target!"); 1793 return BadValue; 1794 } 1795 1796 if (!num_macroblocks) 1797 return Success; 1798 1799 if (!macroblock_array || !blocks) { 1800 XVMC_ERR("Invalid block data!"); 1801 return BadValue; 1802 } 1803 1804 if (macroblock_array->num_blocks < (num_macroblocks + first_macroblock)) { 1805 XVMC_ERR("Too many macroblocks requested for MB array size."); 1806 return BadValue; 1807 } 1808 1809 if (!(pI915XvMC = context->privData)) 1810 return XvMCBadContext; 1811 1812 if (!(privTarget = target_surface->privData)) 1813 return XvMCBadSurface; 1814 1815 if (context->surface_type_id >= SURFACE_TYPE_MAX) { 1816 XVMC_ERR("Unsupprted surface_type_id %d.", context->surface_type_id); 1817 return BadValue; 1818 } 1819 1820 intel_ctx = intel_xvmc_find_context(context->context_id); 1821 if (!intel_ctx) { 1822 XVMC_ERR("Can't find intel xvmc context\n"); 1823 return BadValue; 1824 } 1825 1826 /* P Frame Test */ 1827 if (!past_surface) { 1828 /* Just to avoid some ifs later. */ 1829 privPast = privTarget; 1830 } else { 1831 if (!(privPast = past_surface->privData)) { 1832 XVMC_ERR("Invalid Past Surface!"); 1833 return XvMCBadSurface; 1834 } 1835 picture_coding_type = MPEG_P_PICTURE; 1836 } 1837 1838 /* B Frame Test */ 1839 if (!future_surface) { 1840 privFuture = privPast; // privTarget; 1841 } else { 1842 if (!past_surface) { 1843 XVMC_ERR("No Past Surface!"); 1844 return BadValue; 1845 } 1846 1847 if (!(privFuture = future_surface->privData)) { 1848 XVMC_ERR("Invalid Future Surface!"); 1849 return XvMCBadSurface; 1850 } 1851 1852 picture_coding_type = MPEG_B_PICTURE; 1853 } 1854 1855 LOCK_HARDWARE(intel_ctx->hw_context); 1856 corrdata_ptr = pI915XvMC->corrdata.map; 1857 corrdata_size = 0; 1858 1859 for (i = first_macroblock; i < (num_macroblocks + first_macroblock); i++) { 1860 int bspm = 0; 1861 mb = ¯oblock_array->macro_blocks[i]; 1862 block_ptr = &(blocks->blocks[mb->index << 6]); 1863 1864 /* Lockup can happen if the coordinates are too far out of range */ 1865 if (mb->x > (target_surface->width >> 4)) { 1866 mb->x = 0; 1867 XVMC_INFO("reset x"); 1868 } 1869 1870 if (mb->y > (target_surface->height >> 4)) { 1871 mb->y = 0; 1872 XVMC_INFO("reset y"); 1873 } 1874 1875 /* Catch no pattern case */ 1876 if (!(mb->macroblock_type & XVMC_MB_TYPE_PATTERN) && 1877 !(mb->macroblock_type & XVMC_MB_TYPE_INTRA) && 1878 mb->coded_block_pattern) { 1879 mb->coded_block_pattern = 0; 1880 XVMC_INFO("no coded blocks present!"); 1881 } 1882 1883 bspm = mb_bytes_420[mb->coded_block_pattern]; 1884 1885 if (!bspm) 1886 continue; 1887 1888 corrdata_size += bspm; 1889 1890 if (corrdata_size > pI915XvMC->corrdata.size) { 1891 XVMC_ERR("correction data buffer overflow."); 1892 break; 1893 } 1894 memcpy(corrdata_ptr, block_ptr, bspm); 1895 corrdata_ptr += bspm; 1896 } 1897 1898 i915_flush(1, 0); 1899 // i915_mc_invalidate_subcontext_buffers(context, BLOCK_SIS | BLOCK_DIS | BLOCK_SSB 1900 // | BLOCK_MSB | BLOCK_PSP | BLOCK_PSC); 1901 1902 i915_mc_one_time_state_emit(); 1903 1904 i915_mc_static_indirect_state_set(context, target_surface, picture_structure, 1905 flags, picture_coding_type); 1906 /* setup reference surfaces */ 1907 i915_mc_map_state_set(context, privPast, privFuture); 1908 1909 i915_mc_load_indirect_render_emit(); 1910 1911 i915_mc_mpeg_set_origin(context, ¯oblock_array->macro_blocks[first_macroblock]); 1912 1913 for (i = first_macroblock; i < (num_macroblocks + first_macroblock); i++) { 1914 mb = ¯oblock_array->macro_blocks[i]; 1915 1916 /* Intra Blocks */ 1917 if (mb->macroblock_type & XVMC_MB_TYPE_INTRA) { 1918 i915_mc_mpeg_macroblock_ipicture(context, mb); 1919 } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) { 1920 /* Frame Picture */ 1921 switch (mb->motion_type & 3) { 1922 case XVMC_PREDICTION_FIELD: /* Field Based */ 1923 i915_mc_mpeg_macroblock_2fbmv(context, mb, picture_structure); 1924 break; 1925 1926 case XVMC_PREDICTION_FRAME: /* Frame Based */ 1927 i915_mc_mpeg_macroblock_1fbmv(context, mb); 1928 break; 1929 1930 case XVMC_PREDICTION_DUAL_PRIME: /* Dual Prime */ 1931 i915_mc_mpeg_macroblock_2fbmv(context, mb, picture_structure); 1932 break; 1933 1934 default: /* No Motion Type */ 1935 XVMC_ERR("Invalid Macroblock Parameters found."); 1936 break; 1937 } 1938 } else { /* Field Picture */ 1939 switch (mb->motion_type & 3) { 1940 case XVMC_PREDICTION_FIELD: /* Field Based */ 1941 i915_mc_mpeg_macroblock_1fbmv(context, mb); 1942 break; 1943 1944 case XVMC_PREDICTION_16x8: /* 16x8 MC */ 1945 i915_mc_mpeg_macroblock_2fbmv(context, mb, picture_structure); 1946 break; 1947 1948 case XVMC_PREDICTION_DUAL_PRIME: /* Dual Prime */ 1949 i915_mc_mpeg_macroblock_1fbmv(context, mb); 1950 break; 1951 1952 default: /* No Motion Type */ 1953 XVMC_ERR("Invalid Macroblock Parameters found."); 1954 break; 1955 } 1956 } 1957 } 1958 1959 intelFlushBatch(TRUE); 1960 xvmc_driver->last_render = xvmc_driver->alloc.irq_emitted; 1961 privTarget->last_render = xvmc_driver->last_render; 1962 1963 UNLOCK_HARDWARE(intel_ctx->hw_context); 1964 return 0; 1965} 1966 1967static int i915_xvmc_mc_put_surface(Display *display,XvMCSurface *surface, 1968 Drawable draw, short srcx, short srcy, 1969 unsigned short srcw, unsigned short srch, 1970 short destx, short desty, 1971 unsigned short destw, unsigned short desth, 1972 int flags, struct intel_xvmc_command *data) 1973{ 1974 i915XvMCContext *pI915XvMC; 1975 i915XvMCSurface *pI915Surface; 1976 i915XvMCSubpicture *pI915SubPic; 1977 1978 if (!(pI915Surface = surface->privData)) 1979 return XvMCBadSurface; 1980 1981 if (!(pI915XvMC = pI915Surface->privContext)) 1982 return XvMCBadSurface; 1983 1984 PPTHREAD_MUTEX_LOCK(); 1985 1986 data->command = INTEL_XVMC_COMMAND_DISPLAY; 1987 data->ctxNo = pI915XvMC->ctxno; 1988 data->srfNo = pI915Surface->srfNo; 1989 pI915SubPic = pI915Surface->privSubPic; 1990 data->subPicNo = (!pI915SubPic ? 0 : pI915SubPic->srfNo); 1991 data->real_id = FOURCC_YV12; 1992 data->flags = flags; 1993 1994 PPTHREAD_MUTEX_UNLOCK(); 1995 1996 return 0; 1997} 1998 1999static int i915_xvmc_mc_get_surface_status(Display *display, 2000 XvMCSurface *surface, int *stat) 2001{ 2002 i915XvMCSurface *pI915Surface; 2003 i915XvMCContext *pI915XvMC; 2004 2005 if (!display || !surface || !stat) 2006 return BadValue; 2007 2008 *stat = 0; 2009 2010 if (!(pI915Surface = surface->privData)) 2011 return XvMCBadSurface; 2012 2013 if (!(pI915XvMC = pI915Surface->privContext)) 2014 return XvMCBadSurface; 2015 2016 PPTHREAD_MUTEX_LOCK(); 2017 if (pI915Surface->last_flip) { 2018 /* This can not happen */ 2019 if (pI915XvMC->last_flip < pI915Surface->last_flip) { 2020 XVMC_ERR("Context last flip is less than surface last flip."); 2021 PPTHREAD_MUTEX_UNLOCK(); 2022 return BadValue; 2023 } 2024 2025 /* 2026 If the context has 2 or more flips after this surface it 2027 cannot be displaying. Don't bother to check. 2028 */ 2029 if (!(pI915XvMC->last_flip > (pI915Surface->last_flip + 1))) { 2030 /* 2031 If this surface was the last flipped it is either displaying 2032 or about to be so don't bother checking. 2033 */ 2034 if (pI915XvMC->last_flip == pI915Surface->last_flip) { 2035 *stat |= XVMC_DISPLAYING; 2036 } 2037 } 2038 } 2039 2040 PPTHREAD_MUTEX_UNLOCK(); 2041 return 0; 2042} 2043 2044/* XXX WIP code */ 2045#if 0 2046Status XvMCHideSurface(Display *display, XvMCSurface *surface) 2047{ 2048 i915XvMCSurface *pI915Surface; 2049 i915XvMCContext *pI915XvMC; 2050 int stat = 0, ret; 2051 2052 if (!display || !surface) 2053 return BadValue; 2054 2055 if (!(pI915Surface = surface->privData)) 2056 return XvMCBadSurface; 2057 2058 /* Get the associated context pointer */ 2059 if (!(pI915XvMC = pI915Surface->privContext)) 2060 return XvMCBadSurface; 2061 2062 XvMCSyncSurface(display, surface); 2063 2064 /* 2065 Get the status of the surface, if it is not currently displayed 2066 we don't need to worry about it. 2067 */ 2068 if ((ret = XvMCGetSurfaceStatus(display, surface, &stat)) != Success) 2069 return ret; 2070 2071 if (!(stat & XVMC_DISPLAYING)) 2072 return Success; 2073 2074 /* FIXME: */ 2075 return Success; 2076} 2077 2078Status i915_xvmc_create_subpict(Display *display, XvMCContext *context, 2079 XvMCSubpicture *subpicture, 2080 unsigned short width, unsigned short height, 2081 int xvimage_id) 2082{ 2083 Status ret; 2084 i915XvMCContext *pI915XvMC; 2085 i915XvMCSubpicture *pI915Subpicture; 2086 I915XvMCCreateSurfaceRec *tmpComm = NULL; 2087 int priv_count; 2088 uint *priv_data; 2089 2090 if (!subpicture || !context || !display) 2091 return BadValue; 2092 2093 pI915XvMC = (i915XvMCContext *)context->privData; 2094 2095 if (!pI915XvMC) 2096 return XvMCBadContext; 2097 2098 subpicture->privData = 2099 (i915XvMCSubpicture *)malloc(sizeof(i915XvMCSubpicture)); 2100 2101 if (!subpicture->privData) 2102 return BadAlloc; 2103 2104 PPTHREAD_MUTEX_LOCK(); 2105 subpicture->context_id = context->context_id; 2106 subpicture->xvimage_id = xvimage_id; 2107 subpicture->width = width; 2108 subpicture->height = height; 2109 pI915Subpicture = (i915XvMCSubpicture *)subpicture->privData; 2110 2111 XLockDisplay(display); 2112 if ((ret = _xvmc_create_subpicture(display, context, subpicture, 2113 &priv_count, &priv_data))) { 2114 XUnlockDisplay(display); 2115 XVMC_ERR("Unable to create XvMCSubpicture."); 2116 free(pI915Subpicture); 2117 subpicture->privData = NULL; 2118 PPTHREAD_MUTEX_UNLOCK(); 2119 return ret; 2120 } 2121 XUnlockDisplay(display); 2122 2123 if (priv_count != (sizeof(I915XvMCCreateSurfaceRec) >> 2)) { 2124 XVMC_ERR("_xvmc_create_subpicture() returned incorrect data size!"); 2125 XVMC_INFO("\tExpected %d, got %d", 2126 (int)(sizeof(I915XvMCCreateSurfaceRec) >> 2), priv_count); 2127 XLockDisplay(display); 2128 _xvmc_destroy_subpicture(display, subpicture); 2129 XUnlockDisplay(display); 2130 XFree(priv_data); 2131 free(pI915Subpicture); 2132 subpicture->privData = NULL; 2133 PPTHREAD_MUTEX_UNLOCK(); 2134 return BadAlloc; 2135 } 2136 2137 tmpComm = (I915XvMCCreateSurfaceRec *)priv_data; 2138 pI915Subpicture->srfNo = tmpComm->srfno; 2139 pI915Subpicture->srf.handle = tmpComm->srf.handle; 2140 pI915Subpicture->srf.offset = tmpComm->srf.offset; 2141 pI915Subpicture->srf.size = tmpComm->srf.size; 2142 XFree(priv_data); 2143 2144 if (drmMap(pI915XvMC->fd, 2145 pI915Subpicture->srf.handle, 2146 pI915Subpicture->srf.size, 2147 (drmAddress *)&pI915Subpicture->srf.map) != 0) { 2148 XLockDisplay(display); 2149 _xvmc_destroy_subpicture(display, subpicture); 2150 XUnlockDisplay(display); 2151 free(pI915Subpicture); 2152 subpicture->privData = NULL; 2153 PPTHREAD_MUTEX_UNLOCK(); 2154 return BadAlloc; 2155 } 2156 2157 /* subpicture */ 2158 subpicture->num_palette_entries = I915_SUBPIC_PALETTE_SIZE; 2159 subpicture->entry_bytes = 3; 2160 strncpy(subpicture->component_order, "YUV", 4); 2161 2162 /* Initialize private values */ 2163 pI915Subpicture->privContext = pI915XvMC; 2164 pI915Subpicture->last_render= 0; 2165 pI915Subpicture->last_flip = 0; 2166 pI915Subpicture->pitch = ((subpicture->width + 3) & ~3); 2167 2168 switch(subpicture->xvimage_id) { 2169 case FOURCC_IA44: 2170 case FOURCC_AI44: 2171 break; 2172 2173 default: 2174 drmUnmap(pI915Subpicture->srf.map, pI915Subpicture->srf.size); 2175 XLockDisplay(display); 2176 _xvmc_destroy_subpicture(display, subpicture); 2177 XUnlockDisplay(display); 2178 free(pI915Subpicture); 2179 subpicture->privData = NULL; 2180 PPTHREAD_MUTEX_UNLOCK(); 2181 return BadMatch; 2182 } 2183 2184 pI915XvMC->ref++; 2185 PPTHREAD_MUTEX_UNLOCK(); 2186 return Success; 2187} 2188 2189Status i915_xvmc_clear_subpict(Display *display, XvMCSubpicture *subpicture, 2190 short x, short y, 2191 unsigned short width, unsigned short height, 2192 unsigned int color) 2193{ 2194 i915XvMCContext *pI915XvMC; 2195 i915XvMCSubpicture *pI915Subpicture; 2196 2197 if (!display || !subpicture) 2198 return BadValue; 2199 2200 if (!(pI915Subpicture = subpicture->privData)) 2201 return XvMCBadSubpicture; 2202 2203 if (!(pI915XvMC = pI915Subpicture->privContext)) 2204 return XvMCBadSubpicture; 2205 2206 if ((x < 0) || (x + width) > subpicture->width) 2207 return BadValue; 2208 2209 if ((y < 0) || (y + height) > subpicture->height) 2210 return BadValue; 2211 2212 /* FIXME: clear the area */ 2213 2214 return Success; 2215} 2216 2217Status i915_xvmc_composite_subpict(Display *display, XvMCSubpicture *subpicture, 2218 XvImage *image, 2219 short srcx, short srcy, 2220 unsigned short width, unsigned short height, 2221 short dstx, short dsty) 2222{ 2223 i915XvMCContext *pI915XvMC; 2224 i915XvMCSubpicture *pI915Subpicture; 2225 2226 if (!display || !subpicture) 2227 return BadValue; 2228 2229 if (!(pI915Subpicture = subpicture->privData)) 2230 return XvMCBadSubpicture; 2231 2232 if (!(pI915XvMC = pI915Subpicture->privContext)) 2233 return XvMCBadSubpicture; 2234 2235 if ((srcx < 0) || (srcx + width) > subpicture->width) 2236 return BadValue; 2237 2238 if ((srcy < 0) || (srcy + height) > subpicture->height) 2239 return BadValue; 2240 2241 if ((dstx < 0) || (dstx + width) > subpicture->width) 2242 return BadValue; 2243 2244 if ((dsty < 0) || (dsty + width) > subpicture->height) 2245 return BadValue; 2246 2247 if (image->id != subpicture->xvimage_id) 2248 return BadMatch; 2249 2250 /* FIXME */ 2251 return Success; 2252} 2253 2254 2255Status i915_xvmc_destroy_subpict(Display *display, XvMCSubpicture *subpicture) 2256{ 2257 i915XvMCSubpicture *pI915Subpicture; 2258 i915XvMCContext *pI915XvMC; 2259 2260 if (!display || !subpicture) 2261 return BadValue; 2262 2263 if (!(pI915Subpicture = subpicture->privData)) 2264 return XvMCBadSubpicture; 2265 2266 if (!(pI915XvMC = pI915Subpicture->privContext)) 2267 return XvMCBadSubpicture; 2268 2269 if (pI915Subpicture->last_render) 2270 XvMCSyncSubpicture(display, subpicture); 2271 2272 if (pI915Subpicture->srf.map) 2273 drmUnmap(pI915Subpicture->srf.map, pI915Subpicture->srf.size); 2274 2275 PPTHREAD_MUTEX_LOCK(); 2276 XLockDisplay(display); 2277 _xvmc_destroy_subpicture(display,subpicture); 2278 XUnlockDisplay(display); 2279 2280 free(pI915Subpicture); 2281 subpicture->privData = NULL; 2282 pI915XvMC->ref--; 2283 PPTHREAD_MUTEX_UNLOCK(); 2284 2285 return Success; 2286} 2287 2288 2289Status i915_xvmc_set_subpict_palette(Display *display, 2290 XvMCSubpicture *subpicture, 2291 unsigned char *palette) 2292{ 2293 i915XvMCSubpicture *pI915Subpicture; 2294 int i, j; 2295 2296 if (!display || !subpicture) 2297 return BadValue; 2298 2299 if (!(pI915Subpicture = subpicture->privData)) 2300 return XvMCBadSubpicture; 2301 2302 j = 0; 2303 for (i = 0; i < 16; i++) { 2304 pI915Subpicture->palette[0][i] = palette[j++]; 2305 pI915Subpicture->palette[1][i] = palette[j++]; 2306 pI915Subpicture->palette[2][i] = palette[j++]; 2307 } 2308 2309 /* FIXME: Update the subpicture with the new palette */ 2310 return Success; 2311} 2312 2313Status i915_xvmc_blend_subpict(Display *display, XvMCSurface *target_surface, 2314 XvMCSubpicture *subpicture, 2315 short subx, short suby, 2316 unsigned short subw, unsigned short subh, 2317 short surfx, short surfy, 2318 unsigned short surfw, unsigned short surfh) 2319{ 2320 i915XvMCSubpicture *pI915Subpicture; 2321 i915XvMCSurface *privTargetSurface; 2322 2323 if (!display || !target_surface) 2324 return BadValue; 2325 2326 if (!(privTargetSurface = target_surface->privData)) 2327 return XvMCBadSurface; 2328 2329 if (subpicture) { 2330 if (!(pI915Subpicture = subpicture->privData)) 2331 return XvMCBadSubpicture; 2332 2333 if ((FOURCC_AI44 != subpicture->xvimage_id) && 2334 (FOURCC_IA44 != subpicture->xvimage_id)) 2335 return XvMCBadSubpicture; 2336 2337 privTargetSurface->privSubPic = pI915Subpicture; 2338 } else { 2339 privTargetSurface->privSubPic = NULL; 2340 } 2341 2342 return Success; 2343} 2344 2345Status i915_xvmc_blend_subpict2(Display *display, 2346 XvMCSurface *source_surface, 2347 XvMCSurface *target_surface, 2348 XvMCSubpicture *subpicture, 2349 short subx, short suby, 2350 unsigned short subw, unsigned short subh, 2351 short surfx, short surfy, 2352 unsigned short surfw, unsigned short surfh) 2353{ 2354 i915XvMCContext *pI915XvMC; 2355 i915XvMCSubpicture *pI915Subpicture; 2356 i915XvMCSurface *privSourceSurface; 2357 i915XvMCSurface *privTargetSurface; 2358 2359 if (!display || !source_surface || !target_surface) 2360 return BadValue; 2361 2362 if (!(privSourceSurface = source_surface->privData)) 2363 return XvMCBadSurface; 2364 2365 if (!(privTargetSurface = target_surface->privData)) 2366 return XvMCBadSurface; 2367 2368 if (!(pI915XvMC = privTargetSurface->privContext)) 2369 return XvMCBadSurface; 2370 2371 if (((surfx + surfw) > privTargetSurface->width) || 2372 ((surfy + surfh) > privTargetSurface->height)) 2373 return BadValue; 2374 2375 if ((privSourceSurface->width != privTargetSurface->width) || 2376 (privTargetSurface->height != privTargetSurface->height)) 2377 return BadValue; 2378 2379 if (XvMCSyncSurface(display, source_surface)) 2380 return BadValue; 2381 2382 /* FIXME: update Target Surface */ 2383 2384 if (subpicture) { 2385 if (((subx + subw) > subpicture->width) || 2386 ((suby + subh) > subpicture->height)) 2387 return BadValue; 2388 2389 if (!(pI915Subpicture = subpicture->privData)) 2390 return XvMCBadSubpicture; 2391 2392 if ((FOURCC_AI44 != subpicture->xvimage_id) && 2393 (FOURCC_IA44 != subpicture->xvimage_id)) 2394 return XvMCBadSubpicture; 2395 2396 privTargetSurface->privSubPic = pI915Subpicture; 2397 } else { 2398 privTargetSurface->privSubPic = NULL; 2399 } 2400 2401 return Success; 2402} 2403 2404Status i915_xvmc_sync_subpict(Display *display, XvMCSubpicture *subpicture) 2405{ 2406 Status ret; 2407 int stat = 0; 2408 2409 if (!display || !subpicture) 2410 return BadValue; 2411 2412 do { 2413 ret = XvMCGetSubpictureStatus(display, subpicture, &stat); 2414 } while(!ret && (stat & XVMC_RENDERING)); 2415 2416 return ret; 2417} 2418 2419Status i915_xvmc_flush_subpict(Display *display, XvMCSubpicture *subpicture) 2420{ 2421 i915XvMCSubpicture *pI915Subpicture; 2422 2423 if (!display || !subpicture) 2424 return BadValue; 2425 2426 if (!(pI915Subpicture = subpicture->privData)) 2427 return XvMCBadSubpicture; 2428 2429 return Success; 2430} 2431 2432Status i915_xvmc_get_subpict_status(Display *display, XvMCSubpicture *subpicture, 2433 int *stat) 2434{ 2435 i915XvMCSubpicture *pI915Subpicture; 2436 i915XvMCContext *pI915XvMC; 2437 2438 if (!display || !subpicture || stat) 2439 return BadValue; 2440 2441 *stat = 0; 2442 2443 if (!(pI915Subpicture = subpicture->privData)) 2444 return XvMCBadSubpicture; 2445 2446 if (!(pI915XvMC = pI915Subpicture->privContext)) 2447 return XvMCBadSubpicture; 2448 2449 PPTHREAD_MUTEX_LOCK(); 2450 2451 PPTHREAD_MUTEX_UNLOCK(); 2452 return Success; 2453} 2454 2455#endif 2456 2457struct _intel_xvmc_driver i915_xvmc_mc_driver = { 2458 .type = XVMC_I915_MPEG2_MC, 2459 .num_ctx = 0, 2460 .ctx_list = NULL, 2461 .create_context = i915_xvmc_mc_create_context, 2462 .destroy_context = i915_xvmc_mc_destroy_context, 2463 .create_surface = i915_xvmc_mc_create_surface, 2464 .destroy_surface = i915_xvmc_mc_destroy_surface, 2465 .render_surface = i915_xvmc_mc_render_surface, 2466 .put_surface = i915_xvmc_mc_put_surface, 2467 .get_surface_status = i915_xvmc_mc_get_surface_status, 2468}; 2469