103b705cfSriastradh/* 203b705cfSriastradh * Copyright © 2006 Intel Corporation 303b705cfSriastradh * 403b705cfSriastradh * Permission is hereby granted, free of charge, to any person obtaining a 503b705cfSriastradh * copy of this software and associated documentation files (the "Software"), 603b705cfSriastradh * to deal in the Software without restriction, including without limitation 703b705cfSriastradh * the rights to use, copy, modify, merge, publish, distribute, sublicense, 803b705cfSriastradh * and/or sell copies of the Software, and to permit persons to whom the 903b705cfSriastradh * Software is furnished to do so, subject to the following conditions: 1003b705cfSriastradh * 1103b705cfSriastradh * The above copyright notice and this permission notice (including the next 1203b705cfSriastradh * paragraph) shall be included in all copies or substantial portions of the 1303b705cfSriastradh * Software. 1403b705cfSriastradh * 1503b705cfSriastradh * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1603b705cfSriastradh * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1703b705cfSriastradh * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1803b705cfSriastradh * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1903b705cfSriastradh * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 2003b705cfSriastradh * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 2103b705cfSriastradh * SOFTWARE. 2203b705cfSriastradh * 2303b705cfSriastradh * Authors: 2403b705cfSriastradh * Xiang Haihao <haihao.xiang@intel.com> 2503b705cfSriastradh * 2603b705cfSriastradh */ 2703b705cfSriastradh 2803b705cfSriastradh#include <sys/ioctl.h> 2903b705cfSriastradh 3003b705cfSriastradh#include "i915_xvmc.h" 3103b705cfSriastradh#include "i915_structs.h" 3203b705cfSriastradh#include "i915_program.h" 3303b705cfSriastradh 3403b705cfSriastradh#define ALIGN(i,m) (((i) + (m) - 1) & ~((m) - 1)) 3503b705cfSriastradh 3603b705cfSriastradh#define STRIDE(w) (ALIGN((w), 1024)) 3703b705cfSriastradh#define SIZE_Y420(w, h) (h * STRIDE(w)) 3803b705cfSriastradh#define SIZE_UV420(w, h) ((h >> 1) * STRIDE(w >> 1)) 3903b705cfSriastradh#define SIZE_YUV420(w, h) (SIZE_Y420(w,h) + SIZE_UV420(w,h) * 2) 4003b705cfSriastradh#define UOFFSET(context) (SIZE_Y420(context->width, context->height)) 4103b705cfSriastradh#define VOFFSET(context) (SIZE_Y420(context->width, context->height) + \ 4203b705cfSriastradh SIZE_UV420(context->width, context->height)) 4303b705cfSriastradh 4403b705cfSriastradhtypedef union { 4503b705cfSriastradh int16_t component[2]; 4603b705cfSriastradh int32_t v; 4703b705cfSriastradh} vector_t; 4803b705cfSriastradh 4903b705cfSriastradhstatic void i915_inst_arith(unsigned int *inst, 5003b705cfSriastradh unsigned int op, 5103b705cfSriastradh unsigned int dest, 5203b705cfSriastradh unsigned int mask, 5303b705cfSriastradh unsigned int saturate, 5403b705cfSriastradh unsigned int src0, unsigned int src1, 5503b705cfSriastradh unsigned int src2) 5603b705cfSriastradh{ 5703b705cfSriastradh dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest)); 5803b705cfSriastradh *inst = (op | A0_DEST(dest) | mask | saturate | A0_SRC0(src0)); 5903b705cfSriastradh inst++; 6003b705cfSriastradh *inst = (A1_SRC0(src0) | A1_SRC1(src1)); 6103b705cfSriastradh inst++; 6203b705cfSriastradh *inst = (A2_SRC1(src1) | A2_SRC2(src2)); 6303b705cfSriastradh} 6403b705cfSriastradh 6503b705cfSriastradhstatic void i915_inst_decl(unsigned int *inst, 6603b705cfSriastradh unsigned int type, 6703b705cfSriastradh unsigned int nr, unsigned int d0_flags) 6803b705cfSriastradh{ 6903b705cfSriastradh unsigned int reg = UREG(type, nr); 7003b705cfSriastradh 7103b705cfSriastradh *inst = (D0_DCL | D0_DEST(reg) | d0_flags); 7203b705cfSriastradh inst++; 7303b705cfSriastradh *inst = D1_MBZ; 7403b705cfSriastradh inst++; 7503b705cfSriastradh *inst = D2_MBZ; 7603b705cfSriastradh} 7703b705cfSriastradh 7803b705cfSriastradhstatic void i915_inst_texld(unsigned int *inst, 7903b705cfSriastradh unsigned int op, 8003b705cfSriastradh unsigned int dest, 8103b705cfSriastradh unsigned int coord, unsigned int sampler) 8203b705cfSriastradh{ 8303b705cfSriastradh dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest)); 8403b705cfSriastradh *inst = (op | T0_DEST(dest) | T0_SAMPLER(sampler)); 8503b705cfSriastradh inst++; 8603b705cfSriastradh *inst = T1_ADDRESS_REG(coord); 8703b705cfSriastradh inst++; 8803b705cfSriastradh *inst = T2_MBZ; 8903b705cfSriastradh} 9003b705cfSriastradh 9103b705cfSriastradhstatic void i915_mc_one_time_context_init(XvMCContext * context) 9203b705cfSriastradh{ 9303b705cfSriastradh unsigned int dest, src0, src1, src2; 9403b705cfSriastradh i915XvMCContext *pI915XvMC = (i915XvMCContext *) context->privData; 9503b705cfSriastradh int i; 9603b705cfSriastradh struct i915_3dstate_sampler_state *sampler_state; 9703b705cfSriastradh struct i915_3dstate_pixel_shader_program *pixel_shader_program; 9803b705cfSriastradh struct i915_3dstate_pixel_shader_constants *pixel_shader_constants; 9903b705cfSriastradh 10003b705cfSriastradh /* sampler static state */ 10103b705cfSriastradh drm_intel_gem_bo_map_gtt(pI915XvMC->ssb_bo); 10203b705cfSriastradh sampler_state = pI915XvMC->ssb_bo->virtual; 10303b705cfSriastradh 10403b705cfSriastradh memset(sampler_state, 0, sizeof(*sampler_state)); 10503b705cfSriastradh sampler_state->dw0.type = CMD_3D; 10603b705cfSriastradh sampler_state->dw0.opcode = OPC_3DSTATE_SAMPLER_STATE; 10703b705cfSriastradh sampler_state->dw0.length = 6; 10803b705cfSriastradh sampler_state->dw1.sampler_masker = SAMPLER_SAMPLER0 | SAMPLER_SAMPLER1; 10903b705cfSriastradh 11003b705cfSriastradh sampler_state->sampler0.ts0.reverse_gamma = 0; 11103b705cfSriastradh sampler_state->sampler0.ts0.planar2packet = 0; 11203b705cfSriastradh sampler_state->sampler0.ts0.color_conversion = 0; 11303b705cfSriastradh sampler_state->sampler0.ts0.chromakey_index = 0; 11403b705cfSriastradh sampler_state->sampler0.ts0.base_level = 0; 11503b705cfSriastradh sampler_state->sampler0.ts0.mip_filter = MIPFILTER_NONE; /* NONE */ 11603b705cfSriastradh sampler_state->sampler0.ts0.mag_filter = MAPFILTER_LINEAR; /* LINEAR */ 11703b705cfSriastradh sampler_state->sampler0.ts0.min_filter = MAPFILTER_LINEAR; /* LINEAR */ 11803b705cfSriastradh sampler_state->sampler0.ts0.lod_bias = 0; /* 0.0 */ 11903b705cfSriastradh sampler_state->sampler0.ts0.shadow_enable = 0; 12003b705cfSriastradh sampler_state->sampler0.ts0.max_anisotropy = ANISORATIO_2; 12103b705cfSriastradh sampler_state->sampler0.ts0.shadow_function = PREFILTEROP_ALWAYS; 12203b705cfSriastradh sampler_state->sampler0.ts1.min_lod = 0; /* 0.0 Maximum Mip Level */ 12303b705cfSriastradh sampler_state->sampler0.ts1.kill_pixel = 0; 12403b705cfSriastradh sampler_state->sampler0.ts1.keyed_texture_filter = 0; 12503b705cfSriastradh sampler_state->sampler0.ts1.chromakey_enable = 0; 12603b705cfSriastradh sampler_state->sampler0.ts1.tcx_control = TEXCOORDMODE_CLAMP; 12703b705cfSriastradh sampler_state->sampler0.ts1.tcy_control = TEXCOORDMODE_CLAMP; 12803b705cfSriastradh sampler_state->sampler0.ts1.tcz_control = TEXCOORDMODE_CLAMP; 12903b705cfSriastradh sampler_state->sampler0.ts1.normalized_coor = 0; 13003b705cfSriastradh sampler_state->sampler0.ts1.map_index = 0; 13103b705cfSriastradh sampler_state->sampler0.ts1.east_deinterlacer = 0; 13203b705cfSriastradh sampler_state->sampler0.ts2.default_color = 0; 13303b705cfSriastradh 13403b705cfSriastradh sampler_state->sampler1.ts0.reverse_gamma = 0; 13503b705cfSriastradh sampler_state->sampler1.ts0.planar2packet = 0; 13603b705cfSriastradh sampler_state->sampler1.ts0.color_conversion = 0; 13703b705cfSriastradh sampler_state->sampler1.ts0.chromakey_index = 0; 13803b705cfSriastradh sampler_state->sampler1.ts0.base_level = 0; 13903b705cfSriastradh sampler_state->sampler1.ts0.mip_filter = MIPFILTER_NONE; /* NONE */ 14003b705cfSriastradh sampler_state->sampler1.ts0.mag_filter = MAPFILTER_LINEAR; /* LINEAR */ 14103b705cfSriastradh sampler_state->sampler1.ts0.min_filter = MAPFILTER_LINEAR; /* LINEAR */ 14203b705cfSriastradh sampler_state->sampler1.ts0.lod_bias = 0; /* 0.0 */ 14303b705cfSriastradh sampler_state->sampler1.ts0.shadow_enable = 0; 14403b705cfSriastradh sampler_state->sampler1.ts0.max_anisotropy = ANISORATIO_2; 14503b705cfSriastradh sampler_state->sampler1.ts0.shadow_function = PREFILTEROP_ALWAYS; 14603b705cfSriastradh sampler_state->sampler1.ts1.min_lod = 0; /* 0.0 Maximum Mip Level */ 14703b705cfSriastradh sampler_state->sampler1.ts1.kill_pixel = 0; 14803b705cfSriastradh sampler_state->sampler1.ts1.keyed_texture_filter = 0; 14903b705cfSriastradh sampler_state->sampler1.ts1.chromakey_enable = 0; 15003b705cfSriastradh sampler_state->sampler1.ts1.tcx_control = TEXCOORDMODE_CLAMP; 15103b705cfSriastradh sampler_state->sampler1.ts1.tcy_control = TEXCOORDMODE_CLAMP; 15203b705cfSriastradh sampler_state->sampler1.ts1.tcz_control = TEXCOORDMODE_CLAMP; 15303b705cfSriastradh sampler_state->sampler1.ts1.normalized_coor = 0; 15403b705cfSriastradh sampler_state->sampler1.ts1.map_index = 1; 15503b705cfSriastradh sampler_state->sampler1.ts1.east_deinterlacer = 0; 15603b705cfSriastradh sampler_state->sampler1.ts2.default_color = 0; 15703b705cfSriastradh 15803b705cfSriastradh drm_intel_gem_bo_unmap_gtt(pI915XvMC->ssb_bo); 15903b705cfSriastradh 16003b705cfSriastradh /* pixel shader static state */ 16103b705cfSriastradh drm_intel_gem_bo_map_gtt(pI915XvMC->psp_bo); 16203b705cfSriastradh pixel_shader_program = pI915XvMC->psp_bo->virtual; 16303b705cfSriastradh 16403b705cfSriastradh memset(pixel_shader_program, 0, sizeof(*pixel_shader_program)); 16503b705cfSriastradh pixel_shader_program->shader0.type = CMD_3D; 16603b705cfSriastradh pixel_shader_program->shader0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM; 16703b705cfSriastradh pixel_shader_program->shader0.retain = 1; 16803b705cfSriastradh pixel_shader_program->shader0.length = 2; /* 1 inst */ 16903b705cfSriastradh i = 0; 17003b705cfSriastradh 17103b705cfSriastradh dest = UREG(REG_TYPE_OC, 0); 17203b705cfSriastradh src0 = UREG(REG_TYPE_CONST, 0); 17303b705cfSriastradh src1 = 0; 17403b705cfSriastradh src2 = 0; 17503b705cfSriastradh i915_inst_arith(&pixel_shader_program->inst0[i], A0_MOV, 17603b705cfSriastradh dest, A0_DEST_CHANNEL_ALL, A0_DEST_SATURATE, src0, src1, 17703b705cfSriastradh src2); 17803b705cfSriastradh 17903b705cfSriastradh pixel_shader_program->shader1.type = CMD_3D; 18003b705cfSriastradh pixel_shader_program->shader1.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM; 18103b705cfSriastradh pixel_shader_program->shader1.retain = 1; 18203b705cfSriastradh pixel_shader_program->shader1.length = 14; /* 5 inst */ 18303b705cfSriastradh i = 0; 18403b705cfSriastradh /* dcl t0.xy */ 18503b705cfSriastradh i915_inst_decl(&pixel_shader_program->inst1[i], REG_TYPE_T, T_TEX0, 18603b705cfSriastradh D0_CHANNEL_XY); 18703b705cfSriastradh i += 3; 18803b705cfSriastradh /* dcl t1.xy */ 18903b705cfSriastradh i915_inst_decl(&pixel_shader_program->inst1[i], REG_TYPE_T, T_TEX1, 19003b705cfSriastradh D0_CHANNEL_XY); 19103b705cfSriastradh /* dcl_2D s0 */ 19203b705cfSriastradh i += 3; 19303b705cfSriastradh i915_inst_decl(&pixel_shader_program->inst1[i], REG_TYPE_S, 0, 19403b705cfSriastradh D0_SAMPLE_TYPE_2D); 19503b705cfSriastradh /* texld r0, t0, s0 */ 19603b705cfSriastradh i += 3; 19703b705cfSriastradh dest = UREG(REG_TYPE_R, 0); 19803b705cfSriastradh src0 = UREG(REG_TYPE_T, 0); /* COORD */ 19903b705cfSriastradh src1 = UREG(REG_TYPE_S, 0); /* SAMPLER */ 20003b705cfSriastradh i915_inst_texld(&pixel_shader_program->inst1[i], T0_TEXLD, dest, src0, 20103b705cfSriastradh src1); 20203b705cfSriastradh /* mov oC, r0 */ 20303b705cfSriastradh i += 3; 20403b705cfSriastradh dest = UREG(REG_TYPE_OC, 0); 20503b705cfSriastradh src0 = UREG(REG_TYPE_R, 0); 20603b705cfSriastradh src1 = src2 = 0; 20703b705cfSriastradh i915_inst_arith(&pixel_shader_program->inst1[i], A0_MOV, dest, 20803b705cfSriastradh A0_DEST_CHANNEL_ALL, A0_DEST_SATURATE, src0, src1, 20903b705cfSriastradh src2); 21003b705cfSriastradh 21103b705cfSriastradh pixel_shader_program->shader2.type = CMD_3D; 21203b705cfSriastradh pixel_shader_program->shader2.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM; 21303b705cfSriastradh pixel_shader_program->shader2.retain = 1; 21403b705cfSriastradh pixel_shader_program->shader2.length = 14; /* 5 inst */ 21503b705cfSriastradh i = 0; 21603b705cfSriastradh /* dcl t2.xy */ 21703b705cfSriastradh i915_inst_decl(&pixel_shader_program->inst2[i], REG_TYPE_T, T_TEX2, 21803b705cfSriastradh D0_CHANNEL_XY); 21903b705cfSriastradh /* dcl t3.xy */ 22003b705cfSriastradh i += 3; 22103b705cfSriastradh i915_inst_decl(&pixel_shader_program->inst2[i], REG_TYPE_T, T_TEX3, 22203b705cfSriastradh D0_CHANNEL_XY); 22303b705cfSriastradh /* dcl_2D s1 */ 22403b705cfSriastradh i += 3; 22503b705cfSriastradh i915_inst_decl(&pixel_shader_program->inst2[i], REG_TYPE_S, 1, 22603b705cfSriastradh D0_SAMPLE_TYPE_2D); 22703b705cfSriastradh /* texld r0, t2, s1 */ 22803b705cfSriastradh i += 3; 22903b705cfSriastradh dest = UREG(REG_TYPE_R, 0); 23003b705cfSriastradh src0 = UREG(REG_TYPE_T, 2); /* COORD */ 23103b705cfSriastradh src1 = UREG(REG_TYPE_S, 1); /* SAMPLER */ 23203b705cfSriastradh i915_inst_texld(&pixel_shader_program->inst2[i], T0_TEXLD, dest, src0, 23303b705cfSriastradh src1); 23403b705cfSriastradh /* mov oC, r0 */ 23503b705cfSriastradh i += 3; 23603b705cfSriastradh dest = UREG(REG_TYPE_OC, 0); 23703b705cfSriastradh src0 = UREG(REG_TYPE_R, 0); 23803b705cfSriastradh src1 = src2 = 0; 23903b705cfSriastradh i915_inst_arith(&pixel_shader_program->inst2[i], A0_MOV, dest, 24003b705cfSriastradh A0_DEST_CHANNEL_ALL, A0_DEST_SATURATE, src0, src1, 24103b705cfSriastradh src2); 24203b705cfSriastradh 24303b705cfSriastradh /* Shader 3 */ 24403b705cfSriastradh pixel_shader_program->shader3.type = CMD_3D; 24503b705cfSriastradh pixel_shader_program->shader3.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM; 24603b705cfSriastradh pixel_shader_program->shader3.retain = 1; 24703b705cfSriastradh pixel_shader_program->shader3.length = 29; /* 10 inst */ 24803b705cfSriastradh i = 0; 24903b705cfSriastradh /* dcl t0.xy */ 25003b705cfSriastradh i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX0, 25103b705cfSriastradh D0_CHANNEL_XY); 25203b705cfSriastradh /* dcl t1.xy */ 25303b705cfSriastradh i += 3; 25403b705cfSriastradh i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX1, 25503b705cfSriastradh D0_CHANNEL_XY); 25603b705cfSriastradh /* dcl t2.xy */ 25703b705cfSriastradh i += 3; 25803b705cfSriastradh i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX2, 25903b705cfSriastradh D0_CHANNEL_XY); 26003b705cfSriastradh /* dcl t3.xy */ 26103b705cfSriastradh i += 3; 26203b705cfSriastradh i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX3, 26303b705cfSriastradh D0_CHANNEL_XY); 26403b705cfSriastradh /* dcl_2D s0 */ 26503b705cfSriastradh i += 3; 26603b705cfSriastradh i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_S, 0, 26703b705cfSriastradh D0_SAMPLE_TYPE_2D); 26803b705cfSriastradh /* dcl_2D s1 */ 26903b705cfSriastradh i += 3; 27003b705cfSriastradh i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_S, 1, 27103b705cfSriastradh D0_SAMPLE_TYPE_2D); 27203b705cfSriastradh /* texld r0, t0, s0 */ 27303b705cfSriastradh i += 3; 27403b705cfSriastradh dest = UREG(REG_TYPE_R, 0); 27503b705cfSriastradh src0 = UREG(REG_TYPE_T, 0); /* COORD */ 27603b705cfSriastradh src1 = UREG(REG_TYPE_S, 0); /* SAMPLER */ 27703b705cfSriastradh i915_inst_texld(&pixel_shader_program->inst3[i], T0_TEXLD, dest, src0, 27803b705cfSriastradh src1); 27903b705cfSriastradh /* texld r1, t2, s1 */ 28003b705cfSriastradh i += 3; 28103b705cfSriastradh dest = UREG(REG_TYPE_R, 1); 28203b705cfSriastradh src0 = UREG(REG_TYPE_T, 2); /* COORD */ 28303b705cfSriastradh src1 = UREG(REG_TYPE_S, 1); /* SAMPLER */ 28403b705cfSriastradh i915_inst_texld(&pixel_shader_program->inst3[i], T0_TEXLD, dest, src0, 28503b705cfSriastradh src1); 28603b705cfSriastradh /* add r0, r0, r1 */ 28703b705cfSriastradh i += 3; 28803b705cfSriastradh dest = UREG(REG_TYPE_R, 0); 28903b705cfSriastradh src0 = UREG(REG_TYPE_R, 0); 29003b705cfSriastradh src1 = UREG(REG_TYPE_R, 1); 29103b705cfSriastradh src2 = 0; 29203b705cfSriastradh i915_inst_arith(&pixel_shader_program->inst3[i], A0_ADD, dest, 29303b705cfSriastradh A0_DEST_CHANNEL_ALL, 0 /* A0_DEST_SATURATE */ , src0, 29403b705cfSriastradh src1, src2); 29503b705cfSriastradh /* mul oC, r0, c0 */ 29603b705cfSriastradh i += 3; 29703b705cfSriastradh dest = UREG(REG_TYPE_OC, 0); 29803b705cfSriastradh src0 = UREG(REG_TYPE_R, 0); 29903b705cfSriastradh src1 = UREG(REG_TYPE_CONST, 0); 30003b705cfSriastradh src2 = 0; 30103b705cfSriastradh i915_inst_arith(&pixel_shader_program->inst3[i], A0_MUL, dest, 30203b705cfSriastradh A0_DEST_CHANNEL_ALL, A0_DEST_SATURATE, src0, src1, 30303b705cfSriastradh src2); 30403b705cfSriastradh 30503b705cfSriastradh drm_intel_gem_bo_unmap_gtt(pI915XvMC->psp_bo); 30603b705cfSriastradh 30703b705cfSriastradh /* pixel shader contant static state */ 30803b705cfSriastradh drm_intel_gem_bo_map_gtt(pI915XvMC->psc_bo); 30903b705cfSriastradh pixel_shader_constants = pI915XvMC->psc_bo->virtual; 31003b705cfSriastradh 31103b705cfSriastradh memset(pixel_shader_constants, 0, sizeof(*pixel_shader_constants)); 31203b705cfSriastradh pixel_shader_constants->dw0.type = CMD_3D; 31303b705cfSriastradh pixel_shader_constants->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_CONSTANTS; 31403b705cfSriastradh pixel_shader_constants->dw0.length = 4; 31503b705cfSriastradh pixel_shader_constants->dw1.reg_mask = REG_CR0; 31603b705cfSriastradh pixel_shader_constants->value.x = 0.5; 31703b705cfSriastradh pixel_shader_constants->value.y = 0.5; 31803b705cfSriastradh pixel_shader_constants->value.z = 0.5; 31903b705cfSriastradh pixel_shader_constants->value.w = 0.5; 32003b705cfSriastradh 32103b705cfSriastradh drm_intel_gem_bo_unmap_gtt(pI915XvMC->psc_bo); 32203b705cfSriastradh} 32303b705cfSriastradh 32403b705cfSriastradhstatic void i915_mc_one_time_state_emit(XvMCContext * context) 32503b705cfSriastradh{ 32603b705cfSriastradh i915XvMCContext *pI915XvMC = (i915XvMCContext *) context->privData; 32703b705cfSriastradh uint32_t load_state_immediate_1, load_indirect, s3_dword, s6_dword; 32803b705cfSriastradh int mem_select; 32903b705cfSriastradh BATCH_LOCALS; 33003b705cfSriastradh 33103b705cfSriastradh /* 3DSTATE_LOAD_STATE_IMMEDIATE_1 */ 33203b705cfSriastradh BEGIN_BATCH(3 + 8); 33303b705cfSriastradh load_state_immediate_1 = OP_3D_LOAD_STATE_IMMEDIATE_1; 33403b705cfSriastradh load_state_immediate_1 |= OP_3D_LOAD_STATE_IMM_LOAD_S3; 33503b705cfSriastradh load_state_immediate_1 |= OP_3D_LOAD_STATE_IMM_LOAD_S6; 33603b705cfSriastradh load_state_immediate_1 |= 3 - 2; /* length */ 33703b705cfSriastradh OUT_BATCH(load_state_immediate_1); 33803b705cfSriastradh 33903b705cfSriastradh s3_dword = S3_SET0_PCD | S3_SET1_PCD | 34003b705cfSriastradh S3_SET2_PCD | S3_SET3_PCD | 34103b705cfSriastradh S3_SET4_PCD | S3_SET5_PCD | 34203b705cfSriastradh S3_SET6_PCD | S3_SET7_PCD; 34303b705cfSriastradh OUT_BATCH(s3_dword); 34403b705cfSriastradh 34503b705cfSriastradh s6_dword = S6_COLOR_BUFFER_WRITE | S6_DEPTH_TEST_ENABLE; 34603b705cfSriastradh s6_dword |= 1 << S6_SRC_BLEND_FACTOR_SHIFT; 34703b705cfSriastradh s6_dword |= 1 << S6_DST_BLEND_FACTOR_SHIFT; 34803b705cfSriastradh OUT_BATCH(s6_dword); 34903b705cfSriastradh 35003b705cfSriastradh /* 3DSTATE_LOAD_INDIRECT */ 35103b705cfSriastradh load_indirect = OP_3D_LOAD_INDIRECT; 35203b705cfSriastradh load_indirect |= (BLOCK_DIS | BLOCK_SSB | BLOCK_PSP | BLOCK_PSC) 35303b705cfSriastradh << BLOCK_MASK_SHIFT; 35403b705cfSriastradh load_indirect |= 8 - 2; /* length */ 35503b705cfSriastradh 35603b705cfSriastradh if (pI915XvMC->use_phys_addr) 35703b705cfSriastradh mem_select = 0; /* use physical address */ 35803b705cfSriastradh else { 35903b705cfSriastradh load_indirect |= OP_3D_LOAD_INDIRECT_GFX_ADDR; 36003b705cfSriastradh mem_select = 1; /* use gfx address */ 36103b705cfSriastradh } 36203b705cfSriastradh 36303b705cfSriastradh OUT_BATCH(load_indirect); 36403b705cfSriastradh 36503b705cfSriastradh /* Dynamic indirect state buffer */ 36603b705cfSriastradh OUT_BATCH(0); /* no dynamic indirect state */ 36703b705cfSriastradh 36803b705cfSriastradh /* Sample state buffer */ 36903b705cfSriastradh OUT_RELOC(pI915XvMC->ssb_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 37003b705cfSriastradh STATE_VALID | STATE_FORCE); 37103b705cfSriastradh OUT_BATCH(7); /* 8 - 1 */ 37203b705cfSriastradh 37303b705cfSriastradh /* Pixel shader program buffer */ 37403b705cfSriastradh OUT_RELOC(pI915XvMC->psp_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 37503b705cfSriastradh STATE_VALID | STATE_FORCE); 37603b705cfSriastradh OUT_BATCH(66); /* 4 + 16 + 16 + 31 - 1 */ 37703b705cfSriastradh 37803b705cfSriastradh /* Pixel shader constant buffer */ 37903b705cfSriastradh OUT_RELOC(pI915XvMC->psc_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 38003b705cfSriastradh STATE_VALID | STATE_FORCE); 38103b705cfSriastradh OUT_BATCH(5); /* 6 - 1 */ 38203b705cfSriastradh ADVANCE_BATCH(); 38303b705cfSriastradh} 38403b705cfSriastradh 38503b705cfSriastradhstatic void i915_mc_static_indirect_state_set(XvMCContext * context, 38603b705cfSriastradh XvMCSurface * dest, 38703b705cfSriastradh unsigned int picture_structure, 38803b705cfSriastradh unsigned int flags, 38903b705cfSriastradh unsigned int picture_coding_type) 39003b705cfSriastradh{ 39103b705cfSriastradh i915XvMCContext *pI915XvMC = (i915XvMCContext *) context->privData; 39203b705cfSriastradh struct intel_xvmc_surface *intel_surf = dest->privData; 39303b705cfSriastradh struct i915_mc_static_indirect_state_buffer *buffer_info; 39403b705cfSriastradh 39503b705cfSriastradh drm_intel_gem_bo_map_gtt(pI915XvMC->sis_bo); 39603b705cfSriastradh buffer_info = pI915XvMC->sis_bo->virtual; 39703b705cfSriastradh 39803b705cfSriastradh memset(buffer_info, 0, sizeof(*buffer_info)); 39903b705cfSriastradh 40003b705cfSriastradh /* dest Y */ 40103b705cfSriastradh buffer_info->dest_y.dw0.type = CMD_3D; 40203b705cfSriastradh buffer_info->dest_y.dw0.opcode = OPC_3DSTATE_BUFFER_INFO; 40303b705cfSriastradh buffer_info->dest_y.dw0.length = 1; 40403b705cfSriastradh buffer_info->dest_y.dw1.aux_id = 0; 40503b705cfSriastradh buffer_info->dest_y.dw1.buffer_id = BUFFERID_COLOR_BACK; 40603b705cfSriastradh buffer_info->dest_y.dw1.fence_regs = 0; /* disabled *//* FIXME: tiled y for performance */ 40703b705cfSriastradh buffer_info->dest_y.dw1.tiled_surface = 0; /* linear */ 40803b705cfSriastradh buffer_info->dest_y.dw1.walk = TILEWALK_XMAJOR; 40903b705cfSriastradh buffer_info->dest_y.dw1.pitch = (pI915XvMC->yStride >> 2); /* in DWords */ 41003b705cfSriastradh buffer_info->dest_y.dw2.base_address = intel_surf->bo->offset >> 2; /* starting DWORD address */ 41103b705cfSriastradh drm_intel_bo_emit_reloc(pI915XvMC->sis_bo, 41203b705cfSriastradh offsetof(typeof(*buffer_info),dest_y.dw2), 41303b705cfSriastradh intel_surf->bo, 0, 41403b705cfSriastradh I915_GEM_DOMAIN_RENDER, 41503b705cfSriastradh I915_GEM_DOMAIN_RENDER); 41603b705cfSriastradh 41703b705cfSriastradh /* dest U */ 41803b705cfSriastradh buffer_info->dest_u.dw0.type = CMD_3D; 41903b705cfSriastradh buffer_info->dest_u.dw0.opcode = OPC_3DSTATE_BUFFER_INFO; 42003b705cfSriastradh buffer_info->dest_u.dw0.length = 1; 42103b705cfSriastradh buffer_info->dest_u.dw1.aux_id = 0; 42203b705cfSriastradh buffer_info->dest_u.dw1.buffer_id = BUFFERID_COLOR_AUX; 42303b705cfSriastradh buffer_info->dest_u.dw1.fence_regs = 0; 42403b705cfSriastradh buffer_info->dest_u.dw1.tiled_surface = 0; 42503b705cfSriastradh buffer_info->dest_u.dw1.walk = TILEWALK_XMAJOR; 42603b705cfSriastradh buffer_info->dest_u.dw1.pitch = (pI915XvMC->uvStride >> 2); /* in DWords */ 42703b705cfSriastradh buffer_info->dest_u.dw2.base_address = 42803b705cfSriastradh (intel_surf->bo->offset + UOFFSET(context)) >> 2; 42903b705cfSriastradh drm_intel_bo_emit_reloc(pI915XvMC->sis_bo, 43003b705cfSriastradh offsetof(typeof(*buffer_info),dest_u.dw2), 43103b705cfSriastradh intel_surf->bo, UOFFSET(context), 43203b705cfSriastradh I915_GEM_DOMAIN_RENDER, 43303b705cfSriastradh I915_GEM_DOMAIN_RENDER); 43403b705cfSriastradh 43503b705cfSriastradh /* dest V */ 43603b705cfSriastradh buffer_info->dest_v.dw0.type = CMD_3D; 43703b705cfSriastradh buffer_info->dest_v.dw0.opcode = OPC_3DSTATE_BUFFER_INFO; 43803b705cfSriastradh buffer_info->dest_v.dw0.length = 1; 43903b705cfSriastradh buffer_info->dest_v.dw1.aux_id = 1; 44003b705cfSriastradh buffer_info->dest_v.dw1.buffer_id = BUFFERID_COLOR_AUX; 44103b705cfSriastradh buffer_info->dest_v.dw1.fence_regs = 0; 44203b705cfSriastradh buffer_info->dest_v.dw1.tiled_surface = 0; 44303b705cfSriastradh buffer_info->dest_v.dw1.walk = TILEWALK_XMAJOR; 44403b705cfSriastradh buffer_info->dest_v.dw1.pitch = (pI915XvMC->uvStride >> 2); /* in Dwords */ 44503b705cfSriastradh buffer_info->dest_v.dw2.base_address = 44603b705cfSriastradh (intel_surf->bo->offset + VOFFSET(context)) >> 2; 44703b705cfSriastradh drm_intel_bo_emit_reloc(pI915XvMC->sis_bo, 44803b705cfSriastradh offsetof(typeof(*buffer_info),dest_v.dw2), 44903b705cfSriastradh intel_surf->bo, VOFFSET(context), 45003b705cfSriastradh I915_GEM_DOMAIN_RENDER, 45103b705cfSriastradh I915_GEM_DOMAIN_RENDER); 45203b705cfSriastradh 45303b705cfSriastradh /* Dest buffer parameters */ 45403b705cfSriastradh buffer_info->dest_buf.dw0.type = CMD_3D; 45503b705cfSriastradh buffer_info->dest_buf.dw0.opcode = OPC_3DSTATE_DEST_BUFFER_VARIABLES; 45603b705cfSriastradh buffer_info->dest_buf.dw0.length = 0; 45703b705cfSriastradh buffer_info->dest_buf.dw1.dest_v_bias = 8; /* 0.5 */ 45803b705cfSriastradh buffer_info->dest_buf.dw1.dest_h_bias = 8; /* 0.5 */ 45903b705cfSriastradh buffer_info->dest_buf.dw1.color_fmt = COLORBUFFER_8BIT; 46003b705cfSriastradh buffer_info->dest_buf.dw1.v_ls = 0; /* fill later */ 46103b705cfSriastradh buffer_info->dest_buf.dw1.v_ls_offset = 0; /* fill later */ 46203b705cfSriastradh if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) { 46303b705cfSriastradh ; 46403b705cfSriastradh } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_TOP_FIELD) { 46503b705cfSriastradh buffer_info->dest_buf.dw1.v_ls = 1; 46603b705cfSriastradh } else if ((picture_structure & XVMC_FRAME_PICTURE) == 46703b705cfSriastradh XVMC_BOTTOM_FIELD) { 46803b705cfSriastradh buffer_info->dest_buf.dw1.v_ls = 1; 46903b705cfSriastradh buffer_info->dest_buf.dw1.v_ls_offset = 1; 47003b705cfSriastradh } 47103b705cfSriastradh 47203b705cfSriastradh /* MPEG buffer parameters */ 47303b705cfSriastradh buffer_info->dest_buf_mpeg.dw0.type = CMD_3D; 47403b705cfSriastradh buffer_info->dest_buf_mpeg.dw0.opcode = 47503b705cfSriastradh OPC_3DSTATE_DEST_BUFFER_VARIABLES_MPEG; 47603b705cfSriastradh buffer_info->dest_buf_mpeg.dw0.length = 1; 47703b705cfSriastradh buffer_info->dest_buf_mpeg.dw1.decode_mode = MPEG_DECODE_MC; 47803b705cfSriastradh buffer_info->dest_buf_mpeg.dw1.rcontrol = 0; /* for MPEG-1/MPEG-2 */ 47903b705cfSriastradh buffer_info->dest_buf_mpeg.dw1.bidir_avrg_control = 0; /* for MPEG-1/MPEG-2/MPEG-4 */ 48003b705cfSriastradh buffer_info->dest_buf_mpeg.dw1.abort_on_error = 1; 48103b705cfSriastradh buffer_info->dest_buf_mpeg.dw1.intra8 = 0; /* 16-bit formatted correction data */ 48203b705cfSriastradh buffer_info->dest_buf_mpeg.dw1.tff = 1; /* fill later */ 48303b705cfSriastradh 48403b705cfSriastradh buffer_info->dest_buf_mpeg.dw1.v_subsample_factor = MC_SUB_1V; 48503b705cfSriastradh buffer_info->dest_buf_mpeg.dw1.h_subsample_factor = MC_SUB_1H; 48603b705cfSriastradh 48703b705cfSriastradh if (picture_structure & XVMC_FRAME_PICTURE) { 48803b705cfSriastradh ; 48903b705cfSriastradh } else if (picture_structure & XVMC_TOP_FIELD) { 49003b705cfSriastradh if (flags & XVMC_SECOND_FIELD) 49103b705cfSriastradh buffer_info->dest_buf_mpeg.dw1.tff = 0; 49203b705cfSriastradh else 49303b705cfSriastradh buffer_info->dest_buf_mpeg.dw1.tff = 1; 49403b705cfSriastradh } else if (picture_structure & XVMC_BOTTOM_FIELD) { 49503b705cfSriastradh if (flags & XVMC_SECOND_FIELD) 49603b705cfSriastradh buffer_info->dest_buf_mpeg.dw1.tff = 1; 49703b705cfSriastradh else 49803b705cfSriastradh buffer_info->dest_buf_mpeg.dw1.tff = 0; 49903b705cfSriastradh } 50003b705cfSriastradh 50103b705cfSriastradh buffer_info->dest_buf_mpeg.dw1.picture_width = (dest->width >> 4); /* in macroblocks */ 50203b705cfSriastradh buffer_info->dest_buf_mpeg.dw2.picture_coding_type = 50303b705cfSriastradh picture_coding_type; 50403b705cfSriastradh 50503b705cfSriastradh buffer_info->corr.dw0.type = CMD_3D; 50603b705cfSriastradh buffer_info->corr.dw0.opcode = OPC_3DSTATE_BUFFER_INFO; 50703b705cfSriastradh buffer_info->corr.dw0.length = 1; 50803b705cfSriastradh buffer_info->corr.dw1.aux_id = 0; 50903b705cfSriastradh buffer_info->corr.dw1.buffer_id = BUFFERID_MC_INTRA_CORR; 51003b705cfSriastradh buffer_info->corr.dw1.aux_id = 0; 51103b705cfSriastradh buffer_info->corr.dw1.fence_regs = 0; 51203b705cfSriastradh buffer_info->corr.dw1.tiled_surface = 0; 51303b705cfSriastradh buffer_info->corr.dw1.walk = 0; 51403b705cfSriastradh buffer_info->corr.dw1.pitch = 0; 51503b705cfSriastradh buffer_info->corr.dw2.base_address = pI915XvMC->corrdata_bo->offset >> 2; /* starting DWORD address */ 51603b705cfSriastradh drm_intel_bo_emit_reloc(pI915XvMC->sis_bo, 51703b705cfSriastradh offsetof(typeof(*buffer_info),corr.dw2), 51803b705cfSriastradh pI915XvMC->corrdata_bo, 0, 51903b705cfSriastradh I915_GEM_DOMAIN_RENDER, 0); 52003b705cfSriastradh 52103b705cfSriastradh drm_intel_gem_bo_unmap_gtt(pI915XvMC->sis_bo); 52203b705cfSriastradh} 52303b705cfSriastradh 52403b705cfSriastradhstatic void i915_mc_map_state_set(XvMCContext * context, 52503b705cfSriastradh struct intel_xvmc_surface * privPast, 52603b705cfSriastradh struct intel_xvmc_surface * privFuture) 52703b705cfSriastradh{ 52803b705cfSriastradh i915XvMCContext *pI915XvMC = (i915XvMCContext *) context->privData; 52903b705cfSriastradh struct i915_mc_map_state *map_state; 53003b705cfSriastradh unsigned int w = context->width; 53103b705cfSriastradh unsigned int h = context->height; 53203b705cfSriastradh 53303b705cfSriastradh drm_intel_gem_bo_map_gtt(pI915XvMC->msb_bo); 53403b705cfSriastradh map_state = pI915XvMC->msb_bo->virtual; 53503b705cfSriastradh 53603b705cfSriastradh memset(map_state, 0, sizeof(*map_state)); 53703b705cfSriastradh 53803b705cfSriastradh /* 3DSATE_MAP_STATE: Y */ 53903b705cfSriastradh map_state->y_map.dw0.type = CMD_3D; 54003b705cfSriastradh map_state->y_map.dw0.opcode = OPC_3DSTATE_MAP_STATE; 54103b705cfSriastradh map_state->y_map.dw0.retain = 1; 54203b705cfSriastradh map_state->y_map.dw0.length = 6; 54303b705cfSriastradh map_state->y_map.dw1.map_mask = MAP_MAP0 | MAP_MAP1; 54403b705cfSriastradh 54503b705cfSriastradh /* Y Forward (Past) */ 54603b705cfSriastradh map_state->y_forward.tm0.v_ls_offset = 0; 54703b705cfSriastradh map_state->y_forward.tm0.v_ls = 0; 54803b705cfSriastradh map_state->y_forward.tm1.tile_walk = TILEWALK_XMAJOR; 54903b705cfSriastradh map_state->y_forward.tm1.tiled_surface = 0; 55003b705cfSriastradh map_state->y_forward.tm1.utilize_fence_regs = 0; 55103b705cfSriastradh map_state->y_forward.tm1.texel_fmt = 0; /* 8bit */ 55203b705cfSriastradh map_state->y_forward.tm1.surface_fmt = 1; /* 8bit */ 55303b705cfSriastradh map_state->y_forward.tm1.width = w - 1; 55403b705cfSriastradh map_state->y_forward.tm1.height = h - 1; 55503b705cfSriastradh map_state->y_forward.tm2.depth = 0; 55603b705cfSriastradh map_state->y_forward.tm2.max_lod = 0; 55703b705cfSriastradh map_state->y_forward.tm2.cube_face = 0; 55803b705cfSriastradh map_state->y_forward.tm0.base_address = privPast->bo->offset >> 2; 55903b705cfSriastradh drm_intel_bo_emit_reloc(pI915XvMC->msb_bo, 56003b705cfSriastradh offsetof(typeof(*map_state),y_forward.tm0), 56103b705cfSriastradh privPast->bo, 0, 56203b705cfSriastradh I915_GEM_DOMAIN_SAMPLER, 0); 56303b705cfSriastradh map_state->y_forward.tm2.pitch = (pI915XvMC->yStride >> 2) - 1; /* in DWords - 1 */ 56403b705cfSriastradh 56503b705cfSriastradh /* Y Backward (Future) */ 56603b705cfSriastradh map_state->y_backward.tm0.v_ls_offset = 0; 56703b705cfSriastradh map_state->y_backward.tm0.v_ls = 0; 56803b705cfSriastradh map_state->y_backward.tm1.tile_walk = TILEWALK_XMAJOR; 56903b705cfSriastradh map_state->y_backward.tm1.tiled_surface = 0; 57003b705cfSriastradh map_state->y_backward.tm1.utilize_fence_regs = 0; 57103b705cfSriastradh map_state->y_backward.tm1.texel_fmt = 0; /* 8bit */ 57203b705cfSriastradh map_state->y_backward.tm1.surface_fmt = 1; /* 8bit */ 57303b705cfSriastradh map_state->y_backward.tm1.width = w - 1; 57403b705cfSriastradh map_state->y_backward.tm1.height = h - 1; 57503b705cfSriastradh map_state->y_backward.tm2.depth = 0; 57603b705cfSriastradh map_state->y_backward.tm2.max_lod = 0; 57703b705cfSriastradh map_state->y_backward.tm2.cube_face = 0; 57803b705cfSriastradh map_state->y_backward.tm0.base_address = privFuture->bo->offset >> 2; 57903b705cfSriastradh drm_intel_bo_emit_reloc(pI915XvMC->msb_bo, 58003b705cfSriastradh offsetof(typeof(*map_state),y_backward.tm0), 58103b705cfSriastradh privFuture->bo, 0, 58203b705cfSriastradh I915_GEM_DOMAIN_SAMPLER, 0); 58303b705cfSriastradh map_state->y_backward.tm2.pitch = (pI915XvMC->yStride >> 2) - 1; 58403b705cfSriastradh 58503b705cfSriastradh /* 3DSATE_MAP_STATE: U */ 58603b705cfSriastradh map_state->u_map.dw0.type = CMD_3D; 58703b705cfSriastradh map_state->u_map.dw0.opcode = OPC_3DSTATE_MAP_STATE; 58803b705cfSriastradh map_state->u_map.dw0.retain = 1; 58903b705cfSriastradh map_state->u_map.dw0.length = 6; 59003b705cfSriastradh map_state->u_map.dw1.map_mask = MAP_MAP0 | MAP_MAP1; 59103b705cfSriastradh 59203b705cfSriastradh /* U Forward */ 59303b705cfSriastradh map_state->u_forward.tm0.v_ls_offset = 0; 59403b705cfSriastradh map_state->u_forward.tm0.v_ls = 0; 59503b705cfSriastradh map_state->u_forward.tm1.tile_walk = TILEWALK_XMAJOR; 59603b705cfSriastradh map_state->u_forward.tm1.tiled_surface = 0; 59703b705cfSriastradh map_state->u_forward.tm1.utilize_fence_regs = 0; 59803b705cfSriastradh map_state->u_forward.tm1.texel_fmt = 0; /* 8bit */ 59903b705cfSriastradh map_state->u_forward.tm1.surface_fmt = 1; /* 8bit */ 60003b705cfSriastradh map_state->u_forward.tm1.width = (w >> 1) - 1; 60103b705cfSriastradh map_state->u_forward.tm1.height = (h >> 1) - 1; 60203b705cfSriastradh map_state->u_forward.tm2.depth = 0; 60303b705cfSriastradh map_state->u_forward.tm2.max_lod = 0; 60403b705cfSriastradh map_state->u_forward.tm2.cube_face = 0; 60503b705cfSriastradh map_state->u_forward.tm0.base_address = 60603b705cfSriastradh (privPast->bo->offset + UOFFSET(context)) >> 2; 60703b705cfSriastradh drm_intel_bo_emit_reloc(pI915XvMC->msb_bo, 60803b705cfSriastradh offsetof(typeof(*map_state),u_forward.tm0), 60903b705cfSriastradh privPast->bo, UOFFSET(context), 61003b705cfSriastradh I915_GEM_DOMAIN_SAMPLER, 0); 61103b705cfSriastradh map_state->u_forward.tm2.pitch = (pI915XvMC->uvStride >> 2) - 1; /* in DWords - 1 */ 61203b705cfSriastradh 61303b705cfSriastradh /* U Backward */ 61403b705cfSriastradh map_state->u_backward.tm0.v_ls_offset = 0; 61503b705cfSriastradh map_state->u_backward.tm0.v_ls = 0; 61603b705cfSriastradh map_state->u_backward.tm1.tile_walk = TILEWALK_XMAJOR; 61703b705cfSriastradh map_state->u_backward.tm1.tiled_surface = 0; 61803b705cfSriastradh map_state->u_backward.tm1.utilize_fence_regs = 0; 61903b705cfSriastradh map_state->u_backward.tm1.texel_fmt = 0; 62003b705cfSriastradh map_state->u_backward.tm1.surface_fmt = 1; 62103b705cfSriastradh map_state->u_backward.tm1.width = (w >> 1) - 1; 62203b705cfSriastradh map_state->u_backward.tm1.height = (h >> 1) - 1; 62303b705cfSriastradh map_state->u_backward.tm2.depth = 0; 62403b705cfSriastradh map_state->u_backward.tm2.max_lod = 0; 62503b705cfSriastradh map_state->u_backward.tm2.cube_face = 0; 62603b705cfSriastradh map_state->u_backward.tm0.base_address = 62703b705cfSriastradh (privFuture->bo->offset + UOFFSET(context)) >> 2; 62803b705cfSriastradh drm_intel_bo_emit_reloc(pI915XvMC->msb_bo, 62903b705cfSriastradh offsetof(typeof(*map_state),u_backward.tm0), 63003b705cfSriastradh privFuture->bo, UOFFSET(context), 63103b705cfSriastradh I915_GEM_DOMAIN_SAMPLER, 0); 63203b705cfSriastradh map_state->u_backward.tm2.pitch = (pI915XvMC->uvStride >> 2) - 1; 63303b705cfSriastradh 63403b705cfSriastradh /* 3DSATE_MAP_STATE: V */ 63503b705cfSriastradh map_state->v_map.dw0.type = CMD_3D; 63603b705cfSriastradh map_state->v_map.dw0.opcode = OPC_3DSTATE_MAP_STATE; 63703b705cfSriastradh map_state->v_map.dw0.retain = 1; 63803b705cfSriastradh map_state->v_map.dw0.length = 6; 63903b705cfSriastradh map_state->v_map.dw1.map_mask = MAP_MAP0 | MAP_MAP1; 64003b705cfSriastradh 64103b705cfSriastradh /* V Forward */ 64203b705cfSriastradh map_state->v_forward.tm0.v_ls_offset = 0; 64303b705cfSriastradh map_state->v_forward.tm0.v_ls = 0; 64403b705cfSriastradh map_state->v_forward.tm1.tile_walk = TILEWALK_XMAJOR; 64503b705cfSriastradh map_state->v_forward.tm1.tiled_surface = 0; 64603b705cfSriastradh map_state->v_forward.tm1.utilize_fence_regs = 0; 64703b705cfSriastradh map_state->v_forward.tm1.texel_fmt = 0; 64803b705cfSriastradh map_state->v_forward.tm1.surface_fmt = 1; 64903b705cfSriastradh map_state->v_forward.tm1.width = (w >> 1) - 1; 65003b705cfSriastradh map_state->v_forward.tm1.height = (h >> 1) - 1; 65103b705cfSriastradh map_state->v_forward.tm2.depth = 0; 65203b705cfSriastradh map_state->v_forward.tm2.max_lod = 0; 65303b705cfSriastradh map_state->v_forward.tm2.cube_face = 0; 65403b705cfSriastradh map_state->v_forward.tm0.base_address = 65503b705cfSriastradh (privPast->bo->offset + VOFFSET(context)) >> 2; 65603b705cfSriastradh drm_intel_bo_emit_reloc(pI915XvMC->msb_bo, 65703b705cfSriastradh offsetof(typeof(*map_state),v_forward.tm0), 65803b705cfSriastradh privPast->bo, VOFFSET(context), 65903b705cfSriastradh I915_GEM_DOMAIN_SAMPLER, 0); 66003b705cfSriastradh map_state->v_forward.tm2.pitch = (pI915XvMC->uvStride >> 2) - 1; /* in DWords - 1 */ 66103b705cfSriastradh 66203b705cfSriastradh /* V Backward */ 66303b705cfSriastradh map_state->v_backward.tm0.v_ls_offset = 0; 66403b705cfSriastradh map_state->v_backward.tm0.v_ls = 0; 66503b705cfSriastradh map_state->v_backward.tm1.tile_walk = TILEWALK_XMAJOR; 66603b705cfSriastradh map_state->v_backward.tm1.tiled_surface = 0; 66703b705cfSriastradh map_state->v_backward.tm1.utilize_fence_regs = 0; 66803b705cfSriastradh map_state->v_backward.tm1.texel_fmt = 0; 66903b705cfSriastradh map_state->v_backward.tm1.surface_fmt = 1; 67003b705cfSriastradh map_state->v_backward.tm1.width = (w >> 1) - 1; 67103b705cfSriastradh map_state->v_backward.tm1.height = (h >> 1) - 1; 67203b705cfSriastradh map_state->v_backward.tm2.depth = 0; 67303b705cfSriastradh map_state->v_backward.tm2.max_lod = 0; 67403b705cfSriastradh map_state->v_backward.tm2.cube_face = 0; 67503b705cfSriastradh map_state->v_backward.tm0.base_address = 67603b705cfSriastradh (privFuture->bo->offset + VOFFSET(context)) >> 2; 67703b705cfSriastradh drm_intel_bo_emit_reloc(pI915XvMC->msb_bo, 67803b705cfSriastradh offsetof(typeof(*map_state),v_backward.tm0), 67903b705cfSriastradh privFuture->bo, VOFFSET(context), 68003b705cfSriastradh I915_GEM_DOMAIN_SAMPLER, 0); 68103b705cfSriastradh map_state->v_backward.tm2.pitch = (pI915XvMC->uvStride >> 2) - 1; 68203b705cfSriastradh 68303b705cfSriastradh drm_intel_gem_bo_unmap_gtt(pI915XvMC->msb_bo); 68403b705cfSriastradh} 68503b705cfSriastradh 68603b705cfSriastradhstatic void i915_mc_load_indirect_render_emit(XvMCContext * context) 68703b705cfSriastradh{ 68803b705cfSriastradh i915XvMCContext *pI915XvMC = (i915XvMCContext *) context->privData; 68903b705cfSriastradh int mem_select; 69003b705cfSriastradh uint32_t load_indirect; 69103b705cfSriastradh BATCH_LOCALS; 69203b705cfSriastradh 69303b705cfSriastradh BEGIN_BATCH(5); 69403b705cfSriastradh load_indirect = OP_3D_LOAD_INDIRECT; 69503b705cfSriastradh load_indirect |= (BLOCK_SIS | BLOCK_MSB) << BLOCK_MASK_SHIFT; 69603b705cfSriastradh load_indirect |= 5 - 2; /* length */ 69703b705cfSriastradh 69803b705cfSriastradh if (pI915XvMC->use_phys_addr) 69903b705cfSriastradh mem_select = 0; /* use physical address */ 70003b705cfSriastradh else { 70103b705cfSriastradh load_indirect |= OP_3D_LOAD_INDIRECT_GFX_ADDR; 70203b705cfSriastradh mem_select = 1; /* use gfx address */ 70303b705cfSriastradh } 70403b705cfSriastradh OUT_BATCH(load_indirect); 70503b705cfSriastradh 70603b705cfSriastradh /* Static Indirect state buffer (dest buffer info) */ 70703b705cfSriastradh OUT_RELOC(pI915XvMC->sis_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 70803b705cfSriastradh STATE_VALID | STATE_FORCE); 70903b705cfSriastradh OUT_BATCH(16); /* 4 * 3 + 2 + 3 - 1 */ 71003b705cfSriastradh 71103b705cfSriastradh /* Map state buffer (reference buffer info) */ 71203b705cfSriastradh OUT_RELOC(pI915XvMC->msb_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 71303b705cfSriastradh STATE_VALID | STATE_FORCE); 71403b705cfSriastradh OUT_BATCH(23); /* 3 * 8 - 1 */ 71503b705cfSriastradh ADVANCE_BATCH(); 71603b705cfSriastradh} 71703b705cfSriastradh 71803b705cfSriastradhstatic void i915_mc_mpeg_set_origin(XvMCContext * context, XvMCMacroBlock * mb) 71903b705cfSriastradh{ 72003b705cfSriastradh struct i915_3dmpeg_set_origin set_origin; 72103b705cfSriastradh 72203b705cfSriastradh /* 3DMPEG_SET_ORIGIN */ 72303b705cfSriastradh memset(&set_origin, 0, sizeof(set_origin)); 72403b705cfSriastradh set_origin.dw0.type = CMD_3D; 72503b705cfSriastradh set_origin.dw0.opcode = OPC_3DMPEG_SET_ORIGIN; 72603b705cfSriastradh set_origin.dw0.length = 0; 72703b705cfSriastradh set_origin.dw1.h_origin = mb->x; 72803b705cfSriastradh set_origin.dw1.v_origin = mb->y; 72903b705cfSriastradh 73003b705cfSriastradh intelBatchbufferData(&set_origin, sizeof(set_origin), 0); 73103b705cfSriastradh} 73203b705cfSriastradh 73303b705cfSriastradhstatic void i915_mc_mpeg_macroblock_ipicture(XvMCContext * context, 73403b705cfSriastradh XvMCMacroBlock * mb) 73503b705cfSriastradh{ 73603b705cfSriastradh struct i915_3dmpeg_macroblock_ipicture macroblock_ipicture; 73703b705cfSriastradh 73803b705cfSriastradh /* 3DMPEG_MACROBLOCK_IPICTURE */ 73903b705cfSriastradh memset(¯oblock_ipicture, 0, sizeof(macroblock_ipicture)); 74003b705cfSriastradh macroblock_ipicture.dw0.type = CMD_3D; 74103b705cfSriastradh macroblock_ipicture.dw0.opcode = OPC_3DMPEG_MACROBLOCK_IPICTURE; 74203b705cfSriastradh macroblock_ipicture.dw0.dct_type = 74303b705cfSriastradh (mb->dct_type == XVMC_DCT_TYPE_FIELD); 74403b705cfSriastradh 74503b705cfSriastradh intelBatchbufferData(¯oblock_ipicture, sizeof(macroblock_ipicture), 74603b705cfSriastradh 0); 74703b705cfSriastradh} 74803b705cfSriastradh 74903b705cfSriastradhstatic void i915_mc_mpeg_macroblock_1fbmv(XvMCContext * context, 75003b705cfSriastradh XvMCMacroBlock * mb) 75103b705cfSriastradh{ 75203b705cfSriastradh struct i915_3dmpeg_macroblock_1fbmv macroblock_1fbmv; 75303b705cfSriastradh vector_t mv0[2]; 75403b705cfSriastradh 75503b705cfSriastradh /* 3DMPEG_MACROBLOCK(1fbmv) */ 75603b705cfSriastradh memset(¯oblock_1fbmv, 0, sizeof(macroblock_1fbmv)); 75703b705cfSriastradh macroblock_1fbmv.header.dw0.type = CMD_3D; 75803b705cfSriastradh macroblock_1fbmv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK; 75903b705cfSriastradh macroblock_1fbmv.header.dw0.length = 2; 76003b705cfSriastradh macroblock_1fbmv.header.dw1.mb_intra = 0; /* should be 0 */ 76103b705cfSriastradh macroblock_1fbmv.header.dw1.forward = 76203b705cfSriastradh ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD) ? 1 : 0); 76303b705cfSriastradh macroblock_1fbmv.header.dw1.backward = 76403b705cfSriastradh ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD) ? 1 : 0); 76503b705cfSriastradh macroblock_1fbmv.header.dw1.h263_4mv = 0; /* should be 0 */ 76603b705cfSriastradh macroblock_1fbmv.header.dw1.dct_type = 76703b705cfSriastradh (mb->dct_type == XVMC_DCT_TYPE_FIELD); 76803b705cfSriastradh 76903b705cfSriastradh if (!(mb->coded_block_pattern & 0x3f)) 77003b705cfSriastradh macroblock_1fbmv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME; 77103b705cfSriastradh 77203b705cfSriastradh macroblock_1fbmv.header.dw1.motion_type = (mb->motion_type & 0x03); 77303b705cfSriastradh macroblock_1fbmv.header.dw1.vertical_field_select = 77403b705cfSriastradh (mb->motion_vertical_field_select & 0x0f); 77503b705cfSriastradh macroblock_1fbmv.header.dw1.coded_block_pattern = 77603b705cfSriastradh mb->coded_block_pattern; 77703b705cfSriastradh macroblock_1fbmv.header.dw1.skipped_macroblocks = 0; 77803b705cfSriastradh 77903b705cfSriastradh mv0[0].component[0] = mb->PMV[0][0][0]; 78003b705cfSriastradh mv0[0].component[1] = mb->PMV[0][0][1]; 78103b705cfSriastradh mv0[1].component[0] = mb->PMV[0][1][0]; 78203b705cfSriastradh mv0[1].component[1] = mb->PMV[0][1][1]; 78303b705cfSriastradh 78403b705cfSriastradh macroblock_1fbmv.dw2 = mv0[0].v; 78503b705cfSriastradh macroblock_1fbmv.dw3 = mv0[1].v; 78603b705cfSriastradh 78703b705cfSriastradh intelBatchbufferData(¯oblock_1fbmv, sizeof(macroblock_1fbmv), 0); 78803b705cfSriastradh} 78903b705cfSriastradh 79003b705cfSriastradhstatic void i915_mc_mpeg_macroblock_2fbmv(XvMCContext * context, 79103b705cfSriastradh XvMCMacroBlock * mb, unsigned int ps) 79203b705cfSriastradh{ 79303b705cfSriastradh struct i915_3dmpeg_macroblock_2fbmv macroblock_2fbmv; 79403b705cfSriastradh vector_t mv0[2]; 79503b705cfSriastradh vector_t mv1[2]; 79603b705cfSriastradh 79703b705cfSriastradh /* 3DMPEG_MACROBLOCK(2fbmv) */ 79803b705cfSriastradh memset(¯oblock_2fbmv, 0, sizeof(macroblock_2fbmv)); 79903b705cfSriastradh macroblock_2fbmv.header.dw0.type = CMD_3D; 80003b705cfSriastradh macroblock_2fbmv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK; 80103b705cfSriastradh macroblock_2fbmv.header.dw0.length = 4; 80203b705cfSriastradh macroblock_2fbmv.header.dw1.mb_intra = 0; /* should be 0 */ 80303b705cfSriastradh macroblock_2fbmv.header.dw1.forward = 80403b705cfSriastradh ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD) ? 1 : 0); 80503b705cfSriastradh macroblock_2fbmv.header.dw1.backward = 80603b705cfSriastradh ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD) ? 1 : 0); 80703b705cfSriastradh macroblock_2fbmv.header.dw1.h263_4mv = 0; /* should be 0 */ 80803b705cfSriastradh macroblock_2fbmv.header.dw1.dct_type = 80903b705cfSriastradh (mb->dct_type == XVMC_DCT_TYPE_FIELD); 81003b705cfSriastradh 81103b705cfSriastradh if (!(mb->coded_block_pattern & 0x3f)) 81203b705cfSriastradh macroblock_2fbmv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME; 81303b705cfSriastradh 81403b705cfSriastradh macroblock_2fbmv.header.dw1.motion_type = (mb->motion_type & 0x03); 81503b705cfSriastradh macroblock_2fbmv.header.dw1.vertical_field_select = 81603b705cfSriastradh (mb->motion_vertical_field_select & 0x0f); 81703b705cfSriastradh macroblock_2fbmv.header.dw1.coded_block_pattern = 81803b705cfSriastradh mb->coded_block_pattern; 81903b705cfSriastradh macroblock_2fbmv.header.dw1.skipped_macroblocks = 0; 82003b705cfSriastradh 82103b705cfSriastradh mv0[0].component[0] = mb->PMV[0][0][0]; 82203b705cfSriastradh mv0[0].component[1] = mb->PMV[0][0][1]; 82303b705cfSriastradh mv0[1].component[0] = mb->PMV[0][1][0]; 82403b705cfSriastradh mv0[1].component[1] = mb->PMV[0][1][1]; 82503b705cfSriastradh mv1[0].component[0] = mb->PMV[1][0][0]; 82603b705cfSriastradh mv1[0].component[1] = mb->PMV[1][0][1]; 82703b705cfSriastradh mv1[1].component[0] = mb->PMV[1][1][0]; 82803b705cfSriastradh mv1[1].component[1] = mb->PMV[1][1][1]; 82903b705cfSriastradh 83003b705cfSriastradh if ((ps & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) { 83103b705cfSriastradh if ((mb->motion_type & 3) == XVMC_PREDICTION_FIELD) { 83203b705cfSriastradh mv0[0].component[1] = mb->PMV[0][0][1] >> 1; 83303b705cfSriastradh mv0[1].component[1] = mb->PMV[0][1][1] >> 1; 83403b705cfSriastradh mv1[0].component[1] = mb->PMV[1][0][1] >> 1; 83503b705cfSriastradh mv1[1].component[1] = mb->PMV[1][1][1] >> 1; 83603b705cfSriastradh } else if ((mb->motion_type & 3) == XVMC_PREDICTION_DUAL_PRIME) { 83703b705cfSriastradh mv0[0].component[1] = mb->PMV[0][0][1] >> 1; 83803b705cfSriastradh mv0[1].component[1] = mb->PMV[0][1][1] >> 1; // MPEG2 MV[0][1] isn't used 83903b705cfSriastradh mv1[0].component[1] = mb->PMV[1][0][1] >> 1; 84003b705cfSriastradh mv1[1].component[1] = mb->PMV[1][1][1] >> 1; 84103b705cfSriastradh } 84203b705cfSriastradh } 84303b705cfSriastradh 84403b705cfSriastradh macroblock_2fbmv.dw2 = mv0[0].v; 84503b705cfSriastradh macroblock_2fbmv.dw3 = mv0[1].v; 84603b705cfSriastradh macroblock_2fbmv.dw4 = mv1[0].v; 84703b705cfSriastradh macroblock_2fbmv.dw5 = mv1[1].v; 84803b705cfSriastradh 84903b705cfSriastradh intelBatchbufferData(¯oblock_2fbmv, sizeof(macroblock_2fbmv), 0); 85003b705cfSriastradh} 85103b705cfSriastradh 85203b705cfSriastradhstatic int i915_xvmc_alloc_one_time_buffers(i915XvMCContext *pI915XvMC) 85303b705cfSriastradh{ 85403b705cfSriastradh pI915XvMC->ssb_bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, 85503b705cfSriastradh "ssb", 85603b705cfSriastradh GTT_PAGE_SIZE, 85703b705cfSriastradh GTT_PAGE_SIZE); 85803b705cfSriastradh if (!pI915XvMC->ssb_bo) 85903b705cfSriastradh return 0; 86003b705cfSriastradh 86103b705cfSriastradh pI915XvMC->psp_bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, 86203b705cfSriastradh "psp", 86303b705cfSriastradh GTT_PAGE_SIZE, 86403b705cfSriastradh GTT_PAGE_SIZE); 86503b705cfSriastradh if (!pI915XvMC->psp_bo) 86603b705cfSriastradh return 0; 86703b705cfSriastradh 86803b705cfSriastradh pI915XvMC->psc_bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, 86903b705cfSriastradh "psc", 87003b705cfSriastradh GTT_PAGE_SIZE, 87103b705cfSriastradh GTT_PAGE_SIZE); 87203b705cfSriastradh if (!pI915XvMC->psc_bo) 87303b705cfSriastradh return 0; 87403b705cfSriastradh 87503b705cfSriastradh return 1; 87603b705cfSriastradh} 87703b705cfSriastradh 87803b705cfSriastradhstatic void i915_xvmc_free_one_time_buffers(i915XvMCContext *pI915XvMC) 87903b705cfSriastradh{ 88003b705cfSriastradh drm_intel_bo_unreference(pI915XvMC->ssb_bo); 88103b705cfSriastradh drm_intel_bo_unreference(pI915XvMC->psp_bo); 88203b705cfSriastradh drm_intel_bo_unreference(pI915XvMC->psc_bo); 88303b705cfSriastradh} 88403b705cfSriastradh 88503b705cfSriastradh/* 88603b705cfSriastradh * Function: i915_release_resource 88703b705cfSriastradh */ 88803b705cfSriastradhstatic void i915_release_resource(Display * display, XvMCContext * context) 88903b705cfSriastradh{ 89003b705cfSriastradh i915XvMCContext *pI915XvMC; 89103b705cfSriastradh 89203b705cfSriastradh if (!(pI915XvMC = context->privData)) 89303b705cfSriastradh return; 89403b705cfSriastradh 89503b705cfSriastradh i915_xvmc_free_one_time_buffers(pI915XvMC); 89603b705cfSriastradh 89703b705cfSriastradh free(pI915XvMC); 89803b705cfSriastradh context->privData = NULL; 89903b705cfSriastradh} 90003b705cfSriastradh 90103b705cfSriastradhstatic Status i915_xvmc_mc_create_context(Display * display, 90203b705cfSriastradh XvMCContext * context, int priv_count, 90303b705cfSriastradh CARD32 * priv_data) 90403b705cfSriastradh{ 90503b705cfSriastradh i915XvMCContext *pI915XvMC = NULL; 90603b705cfSriastradh struct intel_xvmc_hw_context *tmpComm = NULL; 90703b705cfSriastradh 90803b705cfSriastradh if (priv_count != (sizeof(struct intel_xvmc_hw_context) >> 2)) { 90903b705cfSriastradh XVMC_ERR 91003b705cfSriastradh ("_xvmc_create_context() returned incorrect data size!"); 91103b705cfSriastradh XVMC_INFO("\tExpected %d, got %d", 91203b705cfSriastradh (int)(sizeof(struct intel_xvmc_hw_context) >> 2), 91303b705cfSriastradh priv_count); 91403b705cfSriastradh _xvmc_destroy_context(display, context); 91503b705cfSriastradh XFree(priv_data); 91603b705cfSriastradh context->privData = NULL; 91703b705cfSriastradh return BadValue; 91803b705cfSriastradh } 91903b705cfSriastradh 92003b705cfSriastradh context->privData = (void *)calloc(1, sizeof(i915XvMCContext)); 92103b705cfSriastradh if (!context->privData) { 92203b705cfSriastradh XVMC_ERR("Unable to allocate resources for XvMC context."); 92303b705cfSriastradh return BadAlloc; 92403b705cfSriastradh } 92503b705cfSriastradh pI915XvMC = (i915XvMCContext *) context->privData; 92603b705cfSriastradh 92703b705cfSriastradh tmpComm = (struct intel_xvmc_hw_context *) priv_data; 92803b705cfSriastradh pI915XvMC->use_phys_addr = tmpComm->i915.use_phys_addr; 92903b705cfSriastradh pI915XvMC->comm.surface_bo_size = SIZE_YUV420(context->width, 93003b705cfSriastradh context->height); 93103b705cfSriastradh 93203b705cfSriastradh /* Must free the private data we were passed from X */ 93303b705cfSriastradh XFree(priv_data); 93403b705cfSriastradh priv_data = NULL; 93503b705cfSriastradh 93603b705cfSriastradh if (!i915_xvmc_alloc_one_time_buffers(pI915XvMC)) 93703b705cfSriastradh goto free_one_time_buffers; 93803b705cfSriastradh 93903b705cfSriastradh /* Initialize private context values */ 94003b705cfSriastradh pI915XvMC->yStride = STRIDE(context->width); 94103b705cfSriastradh pI915XvMC->uvStride = STRIDE(context->width >> 1); 94203b705cfSriastradh 94303b705cfSriastradh /* pre-init state buffers */ 94403b705cfSriastradh i915_mc_one_time_context_init(context); 94503b705cfSriastradh 94603b705cfSriastradh return Success; 94703b705cfSriastradh 94803b705cfSriastradhfree_one_time_buffers: 94903b705cfSriastradh i915_xvmc_free_one_time_buffers(pI915XvMC); 95003b705cfSriastradh free(pI915XvMC); 95103b705cfSriastradh context->privData = NULL; 95203b705cfSriastradh return BadAlloc; 95303b705cfSriastradh} 95403b705cfSriastradh 95503b705cfSriastradhstatic int i915_xvmc_mc_destroy_context(Display * display, 95603b705cfSriastradh XvMCContext * context) 95703b705cfSriastradh{ 95803b705cfSriastradh i915XvMCContext *pI915XvMC; 95903b705cfSriastradh 96003b705cfSriastradh if (!(pI915XvMC = context->privData)) 96103b705cfSriastradh return XvMCBadContext; 96203b705cfSriastradh 96303b705cfSriastradh /* Pass Control to the X server to destroy the drm_context_t */ 96403b705cfSriastradh i915_release_resource(display, context); 96503b705cfSriastradh 96603b705cfSriastradh return Success; 96703b705cfSriastradh} 96803b705cfSriastradh 96903b705cfSriastradhstatic int i915_xvmc_alloc_render_state_buffers(i915XvMCContext *pI915XvMC) 97003b705cfSriastradh{ 97103b705cfSriastradh pI915XvMC->sis_bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, 97203b705cfSriastradh "sis", 97303b705cfSriastradh GTT_PAGE_SIZE, 97403b705cfSriastradh GTT_PAGE_SIZE); 97503b705cfSriastradh if (!pI915XvMC->sis_bo) 97603b705cfSriastradh return 0; 97703b705cfSriastradh 97803b705cfSriastradh pI915XvMC->msb_bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, 97903b705cfSriastradh "msb", 98003b705cfSriastradh GTT_PAGE_SIZE, 98103b705cfSriastradh GTT_PAGE_SIZE); 98203b705cfSriastradh if (!pI915XvMC->msb_bo) 98303b705cfSriastradh return 0; 98403b705cfSriastradh 98503b705cfSriastradh pI915XvMC->corrdata_bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, 98603b705cfSriastradh "corrdata", 98703b705cfSriastradh CORRDATA_SIZE, 98803b705cfSriastradh GTT_PAGE_SIZE); 98903b705cfSriastradh if (!pI915XvMC->corrdata_bo) 99003b705cfSriastradh return 0; 99103b705cfSriastradh 99203b705cfSriastradh return 1; 99303b705cfSriastradh} 99403b705cfSriastradh 99503b705cfSriastradhstatic void i915_xvmc_free_render_state_buffers(i915XvMCContext *pI915XvMC) 99603b705cfSriastradh{ 99703b705cfSriastradh drm_intel_bo_unreference(pI915XvMC->sis_bo); 99803b705cfSriastradh drm_intel_bo_unreference(pI915XvMC->msb_bo); 99903b705cfSriastradh drm_intel_bo_unreference(pI915XvMC->corrdata_bo); 100003b705cfSriastradh} 100103b705cfSriastradh 100203b705cfSriastradhstatic int i915_xvmc_mc_render_surface(Display * display, XvMCContext * context, 100303b705cfSriastradh unsigned int picture_structure, 100403b705cfSriastradh XvMCSurface * target_surface, 100503b705cfSriastradh XvMCSurface * past_surface, 100603b705cfSriastradh XvMCSurface * future_surface, 100703b705cfSriastradh unsigned int flags, 100803b705cfSriastradh unsigned int num_macroblocks, 100903b705cfSriastradh unsigned int first_macroblock, 101003b705cfSriastradh XvMCMacroBlockArray * macroblock_array, 101103b705cfSriastradh XvMCBlockArray * blocks) 101203b705cfSriastradh{ 101303b705cfSriastradh int i; 101403b705cfSriastradh int picture_coding_type = MPEG_I_PICTURE; 101503b705cfSriastradh /* correction data buffer */ 101603b705cfSriastradh char *corrdata_ptr; 101703b705cfSriastradh int corrdata_size = 0; 101803b705cfSriastradh 101903b705cfSriastradh /* Block Pointer */ 102003b705cfSriastradh short *block_ptr; 102103b705cfSriastradh /* Current Macroblock Pointer */ 102203b705cfSriastradh XvMCMacroBlock *mb; 102303b705cfSriastradh 102403b705cfSriastradh intel_xvmc_context_ptr intel_ctx; 102503b705cfSriastradh 102603b705cfSriastradh struct intel_xvmc_surface *privTarget = NULL; 102703b705cfSriastradh struct intel_xvmc_surface *privFuture = NULL; 102803b705cfSriastradh struct intel_xvmc_surface *privPast = NULL; 102903b705cfSriastradh i915XvMCContext *pI915XvMC = NULL; 103003b705cfSriastradh 103103b705cfSriastradh /* Check Parameters for validity */ 103203b705cfSriastradh if (!display || !context || !target_surface) { 103303b705cfSriastradh XVMC_ERR("Invalid Display, Context or Target!"); 103403b705cfSriastradh return BadValue; 103503b705cfSriastradh } 103603b705cfSriastradh 103703b705cfSriastradh if (!num_macroblocks) 103803b705cfSriastradh return Success; 103903b705cfSriastradh 104003b705cfSriastradh if (!macroblock_array || !blocks) { 104103b705cfSriastradh XVMC_ERR("Invalid block data!"); 104203b705cfSriastradh return BadValue; 104303b705cfSriastradh } 104403b705cfSriastradh 104503b705cfSriastradh if (macroblock_array->num_blocks < (num_macroblocks + first_macroblock)) { 104603b705cfSriastradh XVMC_ERR("Too many macroblocks requested for MB array size."); 104703b705cfSriastradh return BadValue; 104803b705cfSriastradh } 104903b705cfSriastradh 105003b705cfSriastradh if (!(pI915XvMC = context->privData)) 105103b705cfSriastradh return XvMCBadContext; 105203b705cfSriastradh 105303b705cfSriastradh if (!(privTarget = target_surface->privData)) 105403b705cfSriastradh return XvMCBadSurface; 105503b705cfSriastradh 105603b705cfSriastradh if (!i915_xvmc_alloc_render_state_buffers(pI915XvMC)) 105703b705cfSriastradh return BadAlloc; 105803b705cfSriastradh 105903b705cfSriastradh intel_ctx = context->privData; 106003b705cfSriastradh if (!intel_ctx) { 106103b705cfSriastradh XVMC_ERR("Can't find intel xvmc context\n"); 106203b705cfSriastradh return BadValue; 106303b705cfSriastradh } 106403b705cfSriastradh 106503b705cfSriastradh /* P Frame Test */ 106603b705cfSriastradh if (!past_surface) { 106703b705cfSriastradh /* Just to avoid some ifs later. */ 106803b705cfSriastradh privPast = privTarget; 106903b705cfSriastradh } else { 107003b705cfSriastradh if (!(privPast = past_surface->privData)) { 107103b705cfSriastradh return XvMCBadSurface; 107203b705cfSriastradh } 107303b705cfSriastradh picture_coding_type = MPEG_P_PICTURE; 107403b705cfSriastradh } 107503b705cfSriastradh 107603b705cfSriastradh /* B Frame Test */ 107703b705cfSriastradh if (!future_surface) { 107803b705cfSriastradh privFuture = privPast; // privTarget; 107903b705cfSriastradh } else { 108003b705cfSriastradh if (!past_surface) { 108103b705cfSriastradh XVMC_ERR("No Past Surface!"); 108203b705cfSriastradh return BadValue; 108303b705cfSriastradh } 108403b705cfSriastradh 108503b705cfSriastradh if (!(privFuture = future_surface->privData)) { 108603b705cfSriastradh XVMC_ERR("Invalid Future Surface!"); 108703b705cfSriastradh return XvMCBadSurface; 108803b705cfSriastradh } 108903b705cfSriastradh 109003b705cfSriastradh picture_coding_type = MPEG_B_PICTURE; 109103b705cfSriastradh } 109203b705cfSriastradh 109303b705cfSriastradh LOCK_HARDWARE(intel_ctx->hw_context); 109403b705cfSriastradh drm_intel_gem_bo_map_gtt(pI915XvMC->corrdata_bo); 109503b705cfSriastradh corrdata_ptr = pI915XvMC->corrdata_bo->virtual; 109603b705cfSriastradh corrdata_size = 0; 109703b705cfSriastradh 109803b705cfSriastradh for (i = first_macroblock; i < (num_macroblocks + first_macroblock); 109903b705cfSriastradh i++) { 110003b705cfSriastradh int bspm = 0; 110103b705cfSriastradh mb = ¯oblock_array->macro_blocks[i]; 110203b705cfSriastradh block_ptr = &(blocks->blocks[mb->index << 6]); 110303b705cfSriastradh 110403b705cfSriastradh /* Lockup can happen if the coordinates are too far out of range */ 110503b705cfSriastradh if (mb->x > (target_surface->width >> 4)) { 110603b705cfSriastradh mb->x = 0; 110703b705cfSriastradh XVMC_INFO("reset x"); 110803b705cfSriastradh } 110903b705cfSriastradh 111003b705cfSriastradh if (mb->y > (target_surface->height >> 4)) { 111103b705cfSriastradh mb->y = 0; 111203b705cfSriastradh XVMC_INFO("reset y"); 111303b705cfSriastradh } 111403b705cfSriastradh 111503b705cfSriastradh /* Catch no pattern case */ 111603b705cfSriastradh if (!(mb->macroblock_type & XVMC_MB_TYPE_PATTERN) && 111703b705cfSriastradh !(mb->macroblock_type & XVMC_MB_TYPE_INTRA) && 111803b705cfSriastradh mb->coded_block_pattern) { 111903b705cfSriastradh mb->coded_block_pattern = 0; 112003b705cfSriastradh XVMC_INFO("no coded blocks present!"); 112103b705cfSriastradh } 112203b705cfSriastradh 112303b705cfSriastradh bspm = mb_bytes_420[mb->coded_block_pattern]; 112403b705cfSriastradh 112503b705cfSriastradh if (!bspm) 112603b705cfSriastradh continue; 112703b705cfSriastradh 112803b705cfSriastradh corrdata_size += bspm; 112903b705cfSriastradh 113003b705cfSriastradh if (corrdata_size > CORRDATA_SIZE) { 113103b705cfSriastradh XVMC_ERR("correction data buffer overflow."); 113203b705cfSriastradh break; 113303b705cfSriastradh } 113403b705cfSriastradh memcpy(corrdata_ptr, block_ptr, bspm); 113503b705cfSriastradh corrdata_ptr += bspm; 113603b705cfSriastradh } 113703b705cfSriastradh 113803b705cfSriastradh drm_intel_gem_bo_unmap_gtt(pI915XvMC->corrdata_bo); 113903b705cfSriastradh 114003b705cfSriastradh // i915_mc_invalidate_subcontext_buffers(context, BLOCK_SIS | BLOCK_DIS | BLOCK_SSB 114103b705cfSriastradh // | BLOCK_MSB | BLOCK_PSP | BLOCK_PSC); 114203b705cfSriastradh 114303b705cfSriastradh i915_mc_one_time_state_emit(context); 114403b705cfSriastradh 114503b705cfSriastradh i915_mc_static_indirect_state_set(context, target_surface, 114603b705cfSriastradh picture_structure, flags, 114703b705cfSriastradh picture_coding_type); 114803b705cfSriastradh /* setup reference surfaces */ 114903b705cfSriastradh i915_mc_map_state_set(context, privPast, privFuture); 115003b705cfSriastradh 115103b705cfSriastradh i915_mc_load_indirect_render_emit(context); 115203b705cfSriastradh 115303b705cfSriastradh i915_mc_mpeg_set_origin(context, 115403b705cfSriastradh ¯oblock_array->macro_blocks 115503b705cfSriastradh [first_macroblock]); 115603b705cfSriastradh 115703b705cfSriastradh for (i = first_macroblock; i < (num_macroblocks + first_macroblock); 115803b705cfSriastradh i++) { 115903b705cfSriastradh mb = ¯oblock_array->macro_blocks[i]; 116003b705cfSriastradh 116103b705cfSriastradh /* Intra Blocks */ 116203b705cfSriastradh if (mb->macroblock_type & XVMC_MB_TYPE_INTRA) { 116303b705cfSriastradh i915_mc_mpeg_macroblock_ipicture(context, mb); 116403b705cfSriastradh } else if ((picture_structure & XVMC_FRAME_PICTURE) == 116503b705cfSriastradh XVMC_FRAME_PICTURE) { 116603b705cfSriastradh /* Frame Picture */ 116703b705cfSriastradh switch (mb->motion_type & 3) { 116803b705cfSriastradh case XVMC_PREDICTION_FIELD: /* Field Based */ 116903b705cfSriastradh i915_mc_mpeg_macroblock_2fbmv(context, mb, 117003b705cfSriastradh picture_structure); 117103b705cfSriastradh break; 117203b705cfSriastradh 117303b705cfSriastradh case XVMC_PREDICTION_FRAME: /* Frame Based */ 117403b705cfSriastradh i915_mc_mpeg_macroblock_1fbmv(context, mb); 117503b705cfSriastradh break; 117603b705cfSriastradh 117703b705cfSriastradh case XVMC_PREDICTION_DUAL_PRIME: /* Dual Prime */ 117803b705cfSriastradh i915_mc_mpeg_macroblock_2fbmv(context, mb, 117903b705cfSriastradh picture_structure); 118003b705cfSriastradh break; 118103b705cfSriastradh 118203b705cfSriastradh default: /* No Motion Type */ 118303b705cfSriastradh XVMC_ERR 118403b705cfSriastradh ("Invalid Macroblock Parameters found."); 118503b705cfSriastradh break; 118603b705cfSriastradh } 118703b705cfSriastradh } else { /* Field Picture */ 118803b705cfSriastradh switch (mb->motion_type & 3) { 118903b705cfSriastradh case XVMC_PREDICTION_FIELD: /* Field Based */ 119003b705cfSriastradh i915_mc_mpeg_macroblock_1fbmv(context, mb); 119103b705cfSriastradh break; 119203b705cfSriastradh 119303b705cfSriastradh case XVMC_PREDICTION_16x8: /* 16x8 MC */ 119403b705cfSriastradh i915_mc_mpeg_macroblock_2fbmv(context, mb, 119503b705cfSriastradh picture_structure); 119603b705cfSriastradh break; 119703b705cfSriastradh 119803b705cfSriastradh case XVMC_PREDICTION_DUAL_PRIME: /* Dual Prime */ 119903b705cfSriastradh i915_mc_mpeg_macroblock_1fbmv(context, mb); 120003b705cfSriastradh break; 120103b705cfSriastradh 120203b705cfSriastradh default: /* No Motion Type */ 120303b705cfSriastradh XVMC_ERR 120403b705cfSriastradh ("Invalid Macroblock Parameters found."); 120503b705cfSriastradh break; 120603b705cfSriastradh } 120703b705cfSriastradh } 120803b705cfSriastradh } 120903b705cfSriastradh 121042542f5fSchristos intelFlushBatch(); 121103b705cfSriastradh 121203b705cfSriastradh i915_xvmc_free_render_state_buffers(pI915XvMC); 121303b705cfSriastradh 121403b705cfSriastradh UNLOCK_HARDWARE(intel_ctx->hw_context); 121503b705cfSriastradh return 0; 121603b705cfSriastradh} 121703b705cfSriastradh 121803b705cfSriastradhstruct _intel_xvmc_driver i915_xvmc_mc_driver = { 121903b705cfSriastradh .type = XVMC_I915_MPEG2_MC, 122003b705cfSriastradh .num_ctx = 0, 122103b705cfSriastradh .ctx_list = NULL, 122203b705cfSriastradh .create_context = i915_xvmc_mc_create_context, 122303b705cfSriastradh .destroy_context = i915_xvmc_mc_destroy_context, 122403b705cfSriastradh .render_surface = i915_xvmc_mc_render_surface, 122503b705cfSriastradh}; 1226