103b705cfSriastradh/* 203b705cfSriastradh * Copyright © 2008 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 * Author: 2403b705cfSriastradh * Zou Nan hai <nanhai.zou@intel.com> 2503b705cfSriastradh * 2603b705cfSriastradh */ 2703b705cfSriastradh#include "intel_xvmc_private.h" 2803b705cfSriastradh#include "i830_reg.h" 2903b705cfSriastradh#include "i965_reg.h" 3003b705cfSriastradh#include "brw_defines.h" 3103b705cfSriastradh#include "brw_structs.h" 3203b705cfSriastradh#define BATCH_STRUCT(x) intelBatchbufferData(&x, sizeof(x), 0) 3303b705cfSriastradh#define URB_SIZE 256 /* XXX */ 3403b705cfSriastradh 3503b705cfSriastradh#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) 3603b705cfSriastradh 3703b705cfSriastradhenum interface { 3803b705cfSriastradh INTRA_INTERFACE = 0, /* non field intra */ 3903b705cfSriastradh NULL_INTERFACE, /* fill with white, do nothing, for debug */ 4003b705cfSriastradh FORWARD_INTERFACE, /* non field forward predict */ 4103b705cfSriastradh BACKWARD_INTERFACE, /* non field backward predict */ 4203b705cfSriastradh F_B_INTERFACE, /* non field forward and backward predict */ 4303b705cfSriastradh FIELD_FORWARD_INTERFACE, /* field forward predict */ 4403b705cfSriastradh FIELD_BACKWARD_INTERFACE, /* field backward predict */ 4503b705cfSriastradh FIELD_F_B_INTERFACE, /* field forward and backward predict */ 4603b705cfSriastradh DUAL_PRIME_INTERFACE 4703b705cfSriastradh}; 4803b705cfSriastradh 4903b705cfSriastradhstatic const uint32_t ipicture_kernel_static[][4] = { 5003b705cfSriastradh#include "shader/mc/ipicture.g4b" 5103b705cfSriastradh}; 5203b705cfSriastradh 5303b705cfSriastradhstatic const uint32_t null_kernel_static[][4] = { 5403b705cfSriastradh#include "shader/mc/null.g4b" 5503b705cfSriastradh}; 5603b705cfSriastradh 5703b705cfSriastradhstatic const uint32_t frame_forward_kernel_static[][4] = { 5803b705cfSriastradh#include "shader/mc/frame_forward.g4b" 5903b705cfSriastradh}; 6003b705cfSriastradh 6103b705cfSriastradhstatic const uint32_t frame_backward_kernel_static[][4] = { 6203b705cfSriastradh#include "shader/mc/frame_backward.g4b" 6303b705cfSriastradh}; 6403b705cfSriastradh 6503b705cfSriastradhstatic const uint32_t frame_f_b_kernel_static[][4] = { 6603b705cfSriastradh#include "shader/mc/frame_f_b.g4b" 6703b705cfSriastradh}; 6803b705cfSriastradh 6903b705cfSriastradhstatic const uint32_t field_forward_kernel_static[][4] = { 7003b705cfSriastradh#include "shader/mc/field_forward.g4b" 7103b705cfSriastradh}; 7203b705cfSriastradh 7303b705cfSriastradhstatic const uint32_t field_backward_kernel_static[][4] = { 7403b705cfSriastradh#include "shader/mc/field_backward.g4b" 7503b705cfSriastradh}; 7603b705cfSriastradh 7703b705cfSriastradhstatic const uint32_t field_f_b_kernel_static[][4] = { 7803b705cfSriastradh#include "shader/mc/field_f_b.g4b" 7903b705cfSriastradh}; 8003b705cfSriastradh 8103b705cfSriastradhstatic const uint32_t dual_prime_kernel_static[][4] = { 8203b705cfSriastradh#include "shader/mc/dual_prime.g4b" 8303b705cfSriastradh}; 8403b705cfSriastradh 8503b705cfSriastradhstatic const uint32_t frame_forward_igd_kernel_static[][4] = { 8603b705cfSriastradh#include "shader/mc/frame_forward_igd.g4b" 8703b705cfSriastradh}; 8803b705cfSriastradh 8903b705cfSriastradhstatic const uint32_t frame_backward_igd_kernel_static[][4] = { 9003b705cfSriastradh#include "shader/mc/frame_backward_igd.g4b" 9103b705cfSriastradh}; 9203b705cfSriastradh 9303b705cfSriastradhstatic const uint32_t frame_f_b_igd_kernel_static[][4] = { 9403b705cfSriastradh#include "shader/mc/frame_f_b_igd.g4b" 9503b705cfSriastradh}; 9603b705cfSriastradh 9703b705cfSriastradhstatic const uint32_t field_forward_igd_kernel_static[][4] = { 9803b705cfSriastradh#include "shader/mc/field_forward_igd.g4b" 9903b705cfSriastradh}; 10003b705cfSriastradh 10103b705cfSriastradhstatic const uint32_t field_backward_igd_kernel_static[][4] = { 10203b705cfSriastradh#include "shader/mc/field_backward_igd.g4b" 10303b705cfSriastradh}; 10403b705cfSriastradh 10503b705cfSriastradhstatic const uint32_t field_f_b_igd_kernel_static[][4] = { 10603b705cfSriastradh#include "shader/mc/field_f_b_igd.g4b" 10703b705cfSriastradh}; 10803b705cfSriastradh 10903b705cfSriastradhstatic const uint32_t dual_prime_igd_kernel_static[][4] = { 11003b705cfSriastradh#include "shader/mc/dual_prime_igd.g4b" 11103b705cfSriastradh}; 11203b705cfSriastradh 11303b705cfSriastradhstruct kernel_struct { 11403b705cfSriastradh const uint32_t(*bin)[4]; 11503b705cfSriastradh uint32_t size; 11603b705cfSriastradh}; 11703b705cfSriastradh 11803b705cfSriastradhstruct kernel_struct kernels_igd[] = { 11903b705cfSriastradh {ipicture_kernel_static, sizeof(ipicture_kernel_static)} 12003b705cfSriastradh , 12103b705cfSriastradh {null_kernel_static, sizeof(null_kernel_static)} 12203b705cfSriastradh , 12303b705cfSriastradh {frame_forward_igd_kernel_static, 12403b705cfSriastradh sizeof(frame_forward_igd_kernel_static)} 12503b705cfSriastradh , 12603b705cfSriastradh {frame_backward_igd_kernel_static, 12703b705cfSriastradh sizeof(frame_backward_igd_kernel_static)} 12803b705cfSriastradh , 12903b705cfSriastradh {frame_f_b_igd_kernel_static, sizeof(frame_f_b_igd_kernel_static)} 13003b705cfSriastradh , 13103b705cfSriastradh {field_forward_igd_kernel_static, 13203b705cfSriastradh sizeof(field_forward_igd_kernel_static)} 13303b705cfSriastradh , 13403b705cfSriastradh {field_backward_igd_kernel_static, 13503b705cfSriastradh sizeof(field_backward_igd_kernel_static)} 13603b705cfSriastradh , 13703b705cfSriastradh {field_f_b_igd_kernel_static, sizeof(field_f_b_igd_kernel_static)} 13803b705cfSriastradh , 13903b705cfSriastradh {dual_prime_igd_kernel_static, sizeof(dual_prime_igd_kernel_static)} 14003b705cfSriastradh}; 14103b705cfSriastradh 14203b705cfSriastradhstruct kernel_struct kernels_965[] = { 14303b705cfSriastradh {ipicture_kernel_static, sizeof(ipicture_kernel_static)} 14403b705cfSriastradh , 14503b705cfSriastradh {null_kernel_static, sizeof(null_kernel_static)} 14603b705cfSriastradh , 14703b705cfSriastradh {frame_forward_kernel_static, sizeof(frame_forward_kernel_static)} 14803b705cfSriastradh , 14903b705cfSriastradh {frame_backward_kernel_static, sizeof(frame_backward_kernel_static)} 15003b705cfSriastradh , 15103b705cfSriastradh {frame_f_b_kernel_static, sizeof(frame_f_b_kernel_static)} 15203b705cfSriastradh , 15303b705cfSriastradh {field_forward_kernel_static, sizeof(field_forward_kernel_static)} 15403b705cfSriastradh , 15503b705cfSriastradh {field_backward_kernel_static, sizeof(field_backward_kernel_static)} 15603b705cfSriastradh , 15703b705cfSriastradh {field_f_b_kernel_static, sizeof(field_f_b_kernel_static)} 15803b705cfSriastradh , 15903b705cfSriastradh {dual_prime_kernel_static, sizeof(dual_prime_kernel_static)} 16003b705cfSriastradh}; 16103b705cfSriastradh 16203b705cfSriastradh#define ALIGN(i,m) (((i) + (m) - 1) & ~((m) - 1)) 16303b705cfSriastradh 16403b705cfSriastradh#define MAX_SURFACE_NUM 10 16503b705cfSriastradh#define DESCRIPTOR_NUM 12 16603b705cfSriastradh 16703b705cfSriastradhstruct media_kernel_obj { 16803b705cfSriastradh dri_bo *bo; 16903b705cfSriastradh}; 17003b705cfSriastradh 17103b705cfSriastradhstruct interface_descriptor_obj { 17203b705cfSriastradh dri_bo *bo; 17303b705cfSriastradh struct media_kernel_obj kernels[DESCRIPTOR_NUM]; 17403b705cfSriastradh}; 17503b705cfSriastradh 17603b705cfSriastradhstruct vfe_state_obj { 17703b705cfSriastradh dri_bo *bo; 17803b705cfSriastradh struct interface_descriptor_obj interface; 17903b705cfSriastradh}; 18003b705cfSriastradh 18103b705cfSriastradhstruct surface_obj { 18203b705cfSriastradh dri_bo *bo; 18303b705cfSriastradh}; 18403b705cfSriastradh 18503b705cfSriastradhstruct surface_state_obj { 18603b705cfSriastradh struct surface_obj surface; 18703b705cfSriastradh dri_bo *bo; 18803b705cfSriastradh}; 18903b705cfSriastradh 19003b705cfSriastradhstruct binding_table_obj { 19103b705cfSriastradh dri_bo *bo; 19203b705cfSriastradh struct surface_state_obj surface_states[MAX_SURFACE_NUM]; 19303b705cfSriastradh}; 19403b705cfSriastradh 19503b705cfSriastradhstruct indirect_data_obj { 19603b705cfSriastradh dri_bo *bo; 19703b705cfSriastradh}; 19803b705cfSriastradh 19903b705cfSriastradhstruct media_state { 20003b705cfSriastradh unsigned int is_g4x:1; 20103b705cfSriastradh unsigned int is_965_q:1; 20203b705cfSriastradh 20303b705cfSriastradh struct vfe_state_obj vfe_state; 20403b705cfSriastradh struct binding_table_obj binding_table; 20503b705cfSriastradh struct indirect_data_obj indirect_data; 20603b705cfSriastradh}; 20703b705cfSriastradhstruct media_state media_state; 20803b705cfSriastradh 20903b705cfSriastradhstatic void free_object(struct media_state *s) 21003b705cfSriastradh{ 21103b705cfSriastradh int i; 21203b705cfSriastradh#define FREE_ONE_BO(bo) drm_intel_bo_unreference(bo) 21303b705cfSriastradh FREE_ONE_BO(s->vfe_state.bo); 21403b705cfSriastradh FREE_ONE_BO(s->vfe_state.interface.bo); 21503b705cfSriastradh for (i = 0; i < DESCRIPTOR_NUM; i++) 21603b705cfSriastradh FREE_ONE_BO(s->vfe_state.interface.kernels[i].bo); 21703b705cfSriastradh FREE_ONE_BO(s->binding_table.bo); 21803b705cfSriastradh for (i = 0; i < MAX_SURFACE_NUM; i++) 21903b705cfSriastradh FREE_ONE_BO(s->binding_table.surface_states[i].bo); 22003b705cfSriastradh FREE_ONE_BO(s->indirect_data.bo); 22103b705cfSriastradh} 22203b705cfSriastradh 22303b705cfSriastradhstatic int alloc_object(struct media_state *s) 22403b705cfSriastradh{ 22503b705cfSriastradh int i; 22603b705cfSriastradh 22703b705cfSriastradh for (i = 0; i < MAX_SURFACE_NUM; i++) { 22803b705cfSriastradh s->binding_table.surface_states[i].bo = 22903b705cfSriastradh drm_intel_bo_alloc(xvmc_driver->bufmgr, "surface_state", 23003b705cfSriastradh sizeof(struct brw_surface_state), 23103b705cfSriastradh 0x1000); 23203b705cfSriastradh if (!s->binding_table.surface_states[i].bo) 23303b705cfSriastradh goto out; 23403b705cfSriastradh } 23503b705cfSriastradh return 0; 23603b705cfSriastradhout: 23703b705cfSriastradh free_object(s); 23803b705cfSriastradh return BadAlloc; 23903b705cfSriastradh} 24003b705cfSriastradh 24103b705cfSriastradhstatic Status destroy_context(Display * display, XvMCContext * context) 24203b705cfSriastradh{ 24303b705cfSriastradh struct intel_xvmc_context *intel_ctx; 24403b705cfSriastradh intel_ctx = context->privData; 24503b705cfSriastradh free(intel_ctx->hw); 24603b705cfSriastradh free(intel_ctx); 24703b705cfSriastradh return Success; 24803b705cfSriastradh} 24903b705cfSriastradh 25003b705cfSriastradh#define STRIDE(w) (w) 25103b705cfSriastradh#define SIZE_YUV420(w, h) (h * (STRIDE(w) + STRIDE(w >> 1))) 25203b705cfSriastradh 25303b705cfSriastradhstatic void flush() 25403b705cfSriastradh{ 25503b705cfSriastradh struct brw_mi_flush flush; 25603b705cfSriastradh memset(&flush, 0, sizeof(flush)); 25703b705cfSriastradh flush.opcode = CMD_MI_FLUSH; 25803b705cfSriastradh flush.flags = (1 << 1); 25903b705cfSriastradh BATCH_STRUCT(flush); 26003b705cfSriastradh} 26103b705cfSriastradh 26203b705cfSriastradhstatic void clear_sf_state() 26303b705cfSriastradh{ 26403b705cfSriastradh struct brw_sf_unit_state sf; 26503b705cfSriastradh memset(&sf, 0, sizeof(sf)); 26603b705cfSriastradh /* TODO */ 26703b705cfSriastradh} 26803b705cfSriastradh 26903b705cfSriastradh/* urb fence must be aligned to cacheline */ 27003b705cfSriastradhstatic void align_urb_fence() 27103b705cfSriastradh{ 27203b705cfSriastradh BATCH_LOCALS; 27303b705cfSriastradh int i, offset_to_next_cacheline; 27403b705cfSriastradh unsigned long batch_offset; 27503b705cfSriastradh BEGIN_BATCH(3); 27603b705cfSriastradh batch_offset = (void *)batch_ptr - xvmc_driver->alloc.ptr; 27703b705cfSriastradh offset_to_next_cacheline = ALIGN(batch_offset, 64) - batch_offset; 27803b705cfSriastradh if (offset_to_next_cacheline <= 12 && offset_to_next_cacheline != 0) { 27903b705cfSriastradh for (i = 0; i < offset_to_next_cacheline / 4; i++) 28003b705cfSriastradh OUT_BATCH(0); 28103b705cfSriastradh ADVANCE_BATCH(); 28203b705cfSriastradh } 28303b705cfSriastradh} 28403b705cfSriastradh 28503b705cfSriastradh/* setup urb layout for media */ 28603b705cfSriastradhstatic void urb_layout() 28703b705cfSriastradh{ 28803b705cfSriastradh BATCH_LOCALS; 28903b705cfSriastradh align_urb_fence(); 29003b705cfSriastradh BEGIN_BATCH(3); 29103b705cfSriastradh OUT_BATCH(BRW_URB_FENCE | 29203b705cfSriastradh UF0_VFE_REALLOC | 29303b705cfSriastradh UF0_CS_REALLOC | 29403b705cfSriastradh UF0_SF_REALLOC | 29503b705cfSriastradh UF0_CLIP_REALLOC | UF0_GS_REALLOC | UF0_VS_REALLOC | 1); 29603b705cfSriastradh OUT_BATCH((0 << UF1_CLIP_FENCE_SHIFT) | 29703b705cfSriastradh (0 << UF1_GS_FENCE_SHIFT) | (0 << UF1_VS_FENCE_SHIFT)); 29803b705cfSriastradh 29903b705cfSriastradh OUT_BATCH(((URB_SIZE) << UF2_VFE_FENCE_SHIFT) | /* VFE_SIZE */ 30003b705cfSriastradh ((URB_SIZE) << UF2_CS_FENCE_SHIFT)); /* CS_SIZE is 0 */ 30103b705cfSriastradh ADVANCE_BATCH(); 30203b705cfSriastradh} 30303b705cfSriastradh 30403b705cfSriastradhstatic void media_state_pointers(struct media_state *media_state) 30503b705cfSriastradh{ 30603b705cfSriastradh BATCH_LOCALS; 30703b705cfSriastradh BEGIN_BATCH(3); 30803b705cfSriastradh OUT_BATCH(BRW_MEDIA_STATE_POINTERS | 1); 30903b705cfSriastradh OUT_BATCH(0); 31003b705cfSriastradh OUT_RELOC(media_state->vfe_state.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); 31103b705cfSriastradh ADVANCE_BATCH(); 31203b705cfSriastradh} 31303b705cfSriastradh 31403b705cfSriastradh/* setup 2D surface for media_read or media_write 31503b705cfSriastradh */ 31603b705cfSriastradhstatic Status setup_media_surface(struct media_state *media_state, 31703b705cfSriastradh int surface_num, dri_bo * bo, 31803b705cfSriastradh unsigned long offset, int w, int h, 31903b705cfSriastradh Bool write) 32003b705cfSriastradh{ 32103b705cfSriastradh struct brw_surface_state s, *ss = &s; 32203b705cfSriastradh 32303b705cfSriastradh memset(ss, 0, sizeof(struct brw_surface_state)); 32403b705cfSriastradh ss->ss0.surface_type = BRW_SURFACE_2D; 32503b705cfSriastradh ss->ss0.surface_format = BRW_SURFACEFORMAT_R8_SINT; 32603b705cfSriastradh ss->ss1.base_addr = offset + bo->offset; 32703b705cfSriastradh ss->ss2.width = w - 1; 32803b705cfSriastradh ss->ss2.height = h - 1; 32903b705cfSriastradh ss->ss3.pitch = w - 1; 33003b705cfSriastradh 33103b705cfSriastradh if (media_state->binding_table.surface_states[surface_num].bo) 33203b705cfSriastradh drm_intel_bo_unreference(media_state-> 33303b705cfSriastradh binding_table.surface_states 33403b705cfSriastradh [surface_num].bo); 33503b705cfSriastradh media_state->binding_table.surface_states[surface_num].bo = 33603b705cfSriastradh drm_intel_bo_alloc(xvmc_driver->bufmgr, "surface_state", 33703b705cfSriastradh sizeof(struct brw_surface_state), 0x1000); 33803b705cfSriastradh if (!media_state->binding_table.surface_states[surface_num].bo) 33903b705cfSriastradh return BadAlloc; 34003b705cfSriastradh 34103b705cfSriastradh drm_intel_bo_subdata(media_state-> 34203b705cfSriastradh binding_table.surface_states[surface_num].bo, 0, 34303b705cfSriastradh sizeof(*ss), ss); 34403b705cfSriastradh 34503b705cfSriastradh drm_intel_bo_emit_reloc(media_state-> 34603b705cfSriastradh binding_table.surface_states[surface_num].bo, 34703b705cfSriastradh offsetof(struct brw_surface_state, ss1), bo, 34803b705cfSriastradh offset, I915_GEM_DOMAIN_RENDER, 34903b705cfSriastradh write ? I915_GEM_DOMAIN_RENDER : 0); 35003b705cfSriastradh 35103b705cfSriastradh return Success; 35203b705cfSriastradh} 35303b705cfSriastradh 35403b705cfSriastradhstatic Status setup_surfaces(struct media_state *media_state, 35503b705cfSriastradh dri_bo * dst_bo, dri_bo * past_bo, 35603b705cfSriastradh dri_bo * future_bo, int w, int h) 35703b705cfSriastradh{ 35803b705cfSriastradh Status ret; 35903b705cfSriastradh ret = setup_media_surface(media_state, 0, dst_bo, 0, w, h, TRUE); 36003b705cfSriastradh if (ret != Success) 36103b705cfSriastradh return ret; 36203b705cfSriastradh ret = 36303b705cfSriastradh setup_media_surface(media_state, 1, dst_bo, w * h, w / 2, h / 2, 36403b705cfSriastradh TRUE); 36503b705cfSriastradh if (ret != Success) 36603b705cfSriastradh return ret; 36703b705cfSriastradh ret = 36803b705cfSriastradh setup_media_surface(media_state, 2, dst_bo, w * h + w * h / 4, 36903b705cfSriastradh w / 2, h / 2, TRUE); 37003b705cfSriastradh if (ret != Success) 37103b705cfSriastradh return ret; 37203b705cfSriastradh if (past_bo) { 37303b705cfSriastradh ret = 37403b705cfSriastradh setup_media_surface(media_state, 4, past_bo, 0, w, h, 37503b705cfSriastradh FALSE); 37603b705cfSriastradh if (ret != Success) 37703b705cfSriastradh return ret; 37803b705cfSriastradh ret = 37903b705cfSriastradh setup_media_surface(media_state, 5, past_bo, w * h, w / 2, 38003b705cfSriastradh h / 2, FALSE); 38103b705cfSriastradh if (ret != Success) 38203b705cfSriastradh return ret; 38303b705cfSriastradh ret = 38403b705cfSriastradh setup_media_surface(media_state, 6, past_bo, 38503b705cfSriastradh w * h + w * h / 4, w / 2, h / 2, FALSE); 38603b705cfSriastradh if (ret != Success) 38703b705cfSriastradh return ret; 38803b705cfSriastradh } 38903b705cfSriastradh if (future_bo) { 39003b705cfSriastradh ret = 39103b705cfSriastradh setup_media_surface(media_state, 7, future_bo, 0, w, h, 39203b705cfSriastradh FALSE); 39303b705cfSriastradh if (ret != Success) 39403b705cfSriastradh return ret; 39503b705cfSriastradh ret = 39603b705cfSriastradh setup_media_surface(media_state, 8, future_bo, w * h, w / 2, 39703b705cfSriastradh h / 2, FALSE); 39803b705cfSriastradh if (ret != Success) 39903b705cfSriastradh return ret; 40003b705cfSriastradh ret = 40103b705cfSriastradh setup_media_surface(media_state, 9, future_bo, 40203b705cfSriastradh w * h + w * h / 4, w / 2, h / 2, FALSE); 40303b705cfSriastradh if (ret != Success) 40403b705cfSriastradh return ret; 40503b705cfSriastradh } 40603b705cfSriastradh return Success; 40703b705cfSriastradh} 40803b705cfSriastradh 40903b705cfSriastradh/* BUFFER SURFACE has a strange format 41003b705cfSriastradh * the size of the surface is in part of w h and d component 41103b705cfSriastradh */ 41203b705cfSriastradh 41303b705cfSriastradhstatic Status setup_blocks(struct media_state *media_state, 41403b705cfSriastradh unsigned int block_size) 41503b705cfSriastradh{ 41603b705cfSriastradh union element { 41703b705cfSriastradh struct { 41803b705cfSriastradh unsigned int w:7; 41903b705cfSriastradh unsigned int h:13; 42003b705cfSriastradh unsigned int d:7; 42103b705cfSriastradh unsigned int pad:7; 42203b705cfSriastradh } whd; 42303b705cfSriastradh unsigned int size; 42403b705cfSriastradh } e; 42503b705cfSriastradh struct brw_surface_state ss; 42603b705cfSriastradh memset(&ss, 0, sizeof(struct brw_surface_state)); 42703b705cfSriastradh ss.ss0.surface_type = BRW_SURFACE_BUFFER; 42803b705cfSriastradh ss.ss0.surface_format = BRW_SURFACEFORMAT_R8_UINT; 42903b705cfSriastradh ss.ss1.base_addr = media_state->indirect_data.bo->offset; 43003b705cfSriastradh 43103b705cfSriastradh e.size = block_size - 1; 43203b705cfSriastradh ss.ss2.width = e.whd.w; 43303b705cfSriastradh ss.ss2.height = e.whd.h; 43403b705cfSriastradh ss.ss3.depth = e.whd.d; 43503b705cfSriastradh ss.ss3.pitch = block_size - 1; 43603b705cfSriastradh 43703b705cfSriastradh if (media_state->binding_table.surface_states[3].bo) 43803b705cfSriastradh drm_intel_bo_unreference(media_state-> 43903b705cfSriastradh binding_table.surface_states[3].bo); 44003b705cfSriastradh 44103b705cfSriastradh media_state->binding_table.surface_states[3].bo = 44203b705cfSriastradh drm_intel_bo_alloc(xvmc_driver->bufmgr, "surface_state", 44303b705cfSriastradh sizeof(struct brw_surface_state), 0x1000); 44403b705cfSriastradh if (!media_state->binding_table.surface_states[3].bo) 44503b705cfSriastradh return BadAlloc; 44603b705cfSriastradh 44703b705cfSriastradh drm_intel_bo_subdata(media_state->binding_table.surface_states[3].bo, 0, 44803b705cfSriastradh sizeof(ss), &ss); 44903b705cfSriastradh 45003b705cfSriastradh drm_intel_bo_emit_reloc(media_state->binding_table.surface_states[3].bo, 45103b705cfSriastradh offsetof(struct brw_surface_state, ss1), 45203b705cfSriastradh media_state->indirect_data.bo, 0, 45303b705cfSriastradh I915_GEM_DOMAIN_SAMPLER, 0); 45403b705cfSriastradh return Success; 45503b705cfSriastradh} 45603b705cfSriastradh 45703b705cfSriastradh/* setup state base address */ 45803b705cfSriastradhstatic void state_base_address() 45903b705cfSriastradh{ 46003b705cfSriastradh BATCH_LOCALS; 46103b705cfSriastradh BEGIN_BATCH(6); 46203b705cfSriastradh OUT_BATCH(BRW_STATE_BASE_ADDRESS | 4); 46303b705cfSriastradh OUT_BATCH(0 | BASE_ADDRESS_MODIFY); 46403b705cfSriastradh OUT_BATCH(0 | BASE_ADDRESS_MODIFY); 46503b705cfSriastradh OUT_BATCH(0 | BASE_ADDRESS_MODIFY); 46603b705cfSriastradh OUT_BATCH(0 | BASE_ADDRESS_MODIFY); 46703b705cfSriastradh OUT_BATCH(0xFFFFF000 | BASE_ADDRESS_MODIFY); 46803b705cfSriastradh ADVANCE_BATCH(); 46903b705cfSriastradh} 47003b705cfSriastradh 47103b705cfSriastradh/* select media pipeline */ 47203b705cfSriastradhstatic void pipeline_select(struct media_state *media_state) 47303b705cfSriastradh{ 47403b705cfSriastradh BATCH_LOCALS; 47503b705cfSriastradh BEGIN_BATCH(1); 47603b705cfSriastradh if (media_state->is_g4x) 47703b705cfSriastradh OUT_BATCH(NEW_PIPELINE_SELECT | PIPELINE_SELECT_MEDIA); 47803b705cfSriastradh else 47903b705cfSriastradh OUT_BATCH(BRW_PIPELINE_SELECT | PIPELINE_SELECT_MEDIA); 48003b705cfSriastradh ADVANCE_BATCH(); 48103b705cfSriastradh} 48203b705cfSriastradh 48303b705cfSriastradh/* kick media object to gpu */ 48403b705cfSriastradhstatic void send_media_object(XvMCMacroBlock * mb, int offset, 48503b705cfSriastradh enum interface interface) 48603b705cfSriastradh{ 48703b705cfSriastradh BATCH_LOCALS; 48803b705cfSriastradh BEGIN_BATCH(13); 48903b705cfSriastradh OUT_BATCH(BRW_MEDIA_OBJECT | 11); 49003b705cfSriastradh OUT_BATCH(interface); 49103b705cfSriastradh if (media_state.is_965_q) { 49203b705cfSriastradh OUT_BATCH(0); 49303b705cfSriastradh OUT_BATCH(0); 49403b705cfSriastradh } else { 49503b705cfSriastradh OUT_BATCH(6 * 128); 49603b705cfSriastradh OUT_RELOC(media_state.indirect_data.bo, 49703b705cfSriastradh I915_GEM_DOMAIN_INSTRUCTION, 0, offset); 49803b705cfSriastradh } 49903b705cfSriastradh 50003b705cfSriastradh OUT_BATCH(mb->x << 4); //g1.0 50103b705cfSriastradh OUT_BATCH(mb->y << 4); 50203b705cfSriastradh OUT_RELOC(media_state.indirect_data.bo, //g1.8 50303b705cfSriastradh I915_GEM_DOMAIN_INSTRUCTION, 0, offset); 50403b705cfSriastradh OUT_BATCH_SHORT(mb->coded_block_pattern); //g1.12 50503b705cfSriastradh OUT_BATCH_SHORT(mb->PMV[0][0][0]); //g1.14 50603b705cfSriastradh OUT_BATCH_SHORT(mb->PMV[0][0][1]); //g1.16 50703b705cfSriastradh OUT_BATCH_SHORT(mb->PMV[0][1][0]); //g1.18 50803b705cfSriastradh OUT_BATCH_SHORT(mb->PMV[0][1][1]); //g1.20 50903b705cfSriastradh 51003b705cfSriastradh OUT_BATCH_SHORT(mb->PMV[1][0][0]); //g1.22 51103b705cfSriastradh OUT_BATCH_SHORT(mb->PMV[1][0][1]); //g1.24 51203b705cfSriastradh OUT_BATCH_SHORT(mb->PMV[1][1][0]); //g1.26 51303b705cfSriastradh OUT_BATCH_SHORT(mb->PMV[1][1][1]); //g1.28 51403b705cfSriastradh OUT_BATCH_CHAR(mb->dct_type); //g1.30 51503b705cfSriastradh OUT_BATCH_CHAR(mb->motion_vertical_field_select); //g1.31 51603b705cfSriastradh 51703b705cfSriastradh if (media_state.is_965_q) 51803b705cfSriastradh OUT_BATCH(0x0); 51903b705cfSriastradh else 52003b705cfSriastradh OUT_BATCH(0xffffffff); 52103b705cfSriastradh ADVANCE_BATCH(); 52203b705cfSriastradh} 52303b705cfSriastradh 52403b705cfSriastradhstatic Status binding_tables(struct media_state *media_state) 52503b705cfSriastradh{ 52603b705cfSriastradh unsigned int binding_table[MAX_SURFACE_NUM]; 52703b705cfSriastradh int i; 52803b705cfSriastradh 52903b705cfSriastradh if (media_state->binding_table.bo) 53003b705cfSriastradh drm_intel_bo_unreference(media_state->binding_table.bo); 53103b705cfSriastradh media_state->binding_table.bo = 53203b705cfSriastradh drm_intel_bo_alloc(xvmc_driver->bufmgr, "binding_table", 53303b705cfSriastradh MAX_SURFACE_NUM * 4, 0x1000); 53403b705cfSriastradh if (!media_state->binding_table.bo) 53503b705cfSriastradh return BadAlloc; 53603b705cfSriastradh 53703b705cfSriastradh for (i = 0; i < MAX_SURFACE_NUM; i++) 53803b705cfSriastradh binding_table[i] = 53903b705cfSriastradh media_state->binding_table.surface_states[i].bo->offset; 54003b705cfSriastradh drm_intel_bo_subdata(media_state->binding_table.bo, 0, 54103b705cfSriastradh sizeof(binding_table), binding_table); 54203b705cfSriastradh 54303b705cfSriastradh for (i = 0; i < MAX_SURFACE_NUM; i++) 54403b705cfSriastradh drm_intel_bo_emit_reloc(media_state->binding_table.bo, 54503b705cfSriastradh i * sizeof(unsigned int), 54603b705cfSriastradh media_state-> 54703b705cfSriastradh binding_table.surface_states[i].bo, 0, 54803b705cfSriastradh I915_GEM_DOMAIN_INSTRUCTION, 0); 54903b705cfSriastradh return Success; 55003b705cfSriastradh} 55103b705cfSriastradh 55203b705cfSriastradhstatic int media_kernels(struct media_state *media_state) 55303b705cfSriastradh{ 55403b705cfSriastradh struct kernel_struct *kernels; 55503b705cfSriastradh int kernel_array_size, i; 55603b705cfSriastradh 55703b705cfSriastradh if (media_state->is_g4x) { 55803b705cfSriastradh kernels = kernels_igd; 55903b705cfSriastradh kernel_array_size = ARRAY_SIZE(kernels_igd); 56003b705cfSriastradh } else { 56103b705cfSriastradh kernels = kernels_965; 56203b705cfSriastradh kernel_array_size = ARRAY_SIZE(kernels_965); 56303b705cfSriastradh } 56403b705cfSriastradh 56503b705cfSriastradh for (i = 0; i < kernel_array_size; i++) { 56603b705cfSriastradh media_state->vfe_state.interface.kernels[i].bo = 56703b705cfSriastradh drm_intel_bo_alloc(xvmc_driver->bufmgr, "kernel", 56803b705cfSriastradh kernels[i].size, 0x1000); 56903b705cfSriastradh if (!media_state->vfe_state.interface.kernels[i].bo) 57003b705cfSriastradh goto out; 57103b705cfSriastradh } 57203b705cfSriastradh 57303b705cfSriastradh for (i = 0; i < kernel_array_size; i++) { 57403b705cfSriastradh dri_bo *bo = media_state->vfe_state.interface.kernels[i].bo; 57503b705cfSriastradh drm_intel_bo_subdata(bo, 0, kernels[i].size, kernels[i].bin); 57603b705cfSriastradh } 57703b705cfSriastradh return 0; 57803b705cfSriastradhout: 57903b705cfSriastradh free_object(media_state); 58003b705cfSriastradh return BadAlloc; 58103b705cfSriastradh} 58203b705cfSriastradh 58303b705cfSriastradhstatic void setup_interface(struct media_state *media_state, enum interface i) 58403b705cfSriastradh{ 58503b705cfSriastradh struct brw_interface_descriptor desc; 58603b705cfSriastradh memset(&desc, 0, sizeof(desc)); 58703b705cfSriastradh 58803b705cfSriastradh desc.desc0.grf_reg_blocks = 15; 58903b705cfSriastradh desc.desc0.kernel_start_pointer = 59003b705cfSriastradh media_state->vfe_state.interface.kernels[i].bo->offset >> 6; 59103b705cfSriastradh 59203b705cfSriastradh desc.desc1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754; 59303b705cfSriastradh 59403b705cfSriastradh /* use same binding table for all interface 59503b705cfSriastradh * may change this if it affect performance 59603b705cfSriastradh */ 59703b705cfSriastradh desc.desc3.binding_table_entry_count = MAX_SURFACE_NUM; 59803b705cfSriastradh desc.desc3.binding_table_pointer = 59903b705cfSriastradh media_state->binding_table.bo->offset >> 5; 60003b705cfSriastradh 60103b705cfSriastradh drm_intel_bo_subdata(media_state->vfe_state.interface.bo, 60203b705cfSriastradh i * sizeof(desc), sizeof(desc), &desc); 60303b705cfSriastradh 60403b705cfSriastradh drm_intel_bo_emit_reloc(media_state->vfe_state.interface.bo, 60503b705cfSriastradh i * sizeof(desc) + 60603b705cfSriastradh offsetof(struct brw_interface_descriptor, 60703b705cfSriastradh desc0), 60803b705cfSriastradh media_state->vfe_state.interface.kernels[i].bo, 60903b705cfSriastradh desc.desc0.grf_reg_blocks, 61003b705cfSriastradh I915_GEM_DOMAIN_INSTRUCTION, 0); 61103b705cfSriastradh 61203b705cfSriastradh drm_intel_bo_emit_reloc(media_state->vfe_state.interface.bo, 61303b705cfSriastradh i * sizeof(desc) + 61403b705cfSriastradh offsetof(struct brw_interface_descriptor, 61503b705cfSriastradh desc3), media_state->binding_table.bo, 61603b705cfSriastradh desc.desc3.binding_table_entry_count, 61703b705cfSriastradh I915_GEM_DOMAIN_INSTRUCTION, 0); 61803b705cfSriastradh} 61903b705cfSriastradh 62003b705cfSriastradhstatic Status interface_descriptor(struct media_state *media_state) 62103b705cfSriastradh{ 62203b705cfSriastradh if (media_state->vfe_state.interface.bo) 62303b705cfSriastradh drm_intel_bo_unreference(media_state->vfe_state.interface.bo); 62403b705cfSriastradh media_state->vfe_state.interface.bo = 62503b705cfSriastradh drm_intel_bo_alloc(xvmc_driver->bufmgr, "interfaces", 62603b705cfSriastradh DESCRIPTOR_NUM * 62703b705cfSriastradh sizeof(struct brw_interface_descriptor), 0x1000); 62803b705cfSriastradh if (!media_state->vfe_state.interface.bo) 62903b705cfSriastradh return BadAlloc; 63003b705cfSriastradh 63103b705cfSriastradh setup_interface(media_state, INTRA_INTERFACE); 63203b705cfSriastradh setup_interface(media_state, NULL_INTERFACE); 63303b705cfSriastradh setup_interface(media_state, FORWARD_INTERFACE); 63403b705cfSriastradh setup_interface(media_state, FIELD_FORWARD_INTERFACE); 63503b705cfSriastradh setup_interface(media_state, BACKWARD_INTERFACE); 63603b705cfSriastradh setup_interface(media_state, FIELD_BACKWARD_INTERFACE); 63703b705cfSriastradh setup_interface(media_state, F_B_INTERFACE); 63803b705cfSriastradh setup_interface(media_state, FIELD_F_B_INTERFACE); 63903b705cfSriastradh setup_interface(media_state, DUAL_PRIME_INTERFACE); 64003b705cfSriastradh return Success; 64103b705cfSriastradh} 64203b705cfSriastradh 64303b705cfSriastradhstatic Status vfe_state(struct media_state *media_state) 64403b705cfSriastradh{ 64503b705cfSriastradh struct brw_vfe_state state; 64603b705cfSriastradh memset(&state, 0, sizeof(state)); 64703b705cfSriastradh 64803b705cfSriastradh /* no scratch space */ 64903b705cfSriastradh state.vfe1.vfe_mode = VFE_GENERIC_MODE; 65003b705cfSriastradh state.vfe1.num_urb_entries = 1; 65103b705cfSriastradh /* XXX TODO */ 65203b705cfSriastradh /* should carefully caculate those values for performance */ 65303b705cfSriastradh state.vfe1.urb_entry_alloc_size = 2; 65403b705cfSriastradh state.vfe1.max_threads = 31; 65503b705cfSriastradh state.vfe2.interface_descriptor_base = 65603b705cfSriastradh media_state->vfe_state.interface.bo->offset >> 4; 65703b705cfSriastradh 65803b705cfSriastradh if (media_state->vfe_state.bo) 65903b705cfSriastradh drm_intel_bo_unreference(media_state->vfe_state.bo); 66003b705cfSriastradh media_state->vfe_state.bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, 66103b705cfSriastradh "vfe state", 66203b705cfSriastradh sizeof(struct 66303b705cfSriastradh brw_vfe_state), 66403b705cfSriastradh 0x1000); 66503b705cfSriastradh if (!media_state->vfe_state.bo) 66603b705cfSriastradh return BadAlloc; 66703b705cfSriastradh 66803b705cfSriastradh drm_intel_bo_subdata(media_state->vfe_state.bo, 0, sizeof(state), 66903b705cfSriastradh &state); 67003b705cfSriastradh 67103b705cfSriastradh drm_intel_bo_emit_reloc(media_state->vfe_state.bo, 67203b705cfSriastradh offsetof(struct brw_vfe_state, vfe2), 67303b705cfSriastradh media_state->vfe_state.interface.bo, 0, 67403b705cfSriastradh I915_GEM_DOMAIN_INSTRUCTION, 0); 67503b705cfSriastradh return Success; 67603b705cfSriastradh} 67703b705cfSriastradh 67803b705cfSriastradhstatic Status render_surface(Display * display, 67903b705cfSriastradh XvMCContext * context, 68003b705cfSriastradh unsigned int picture_structure, 68103b705cfSriastradh XvMCSurface * target_surface, 68203b705cfSriastradh XvMCSurface * past_surface, 68303b705cfSriastradh XvMCSurface * future_surface, 68403b705cfSriastradh unsigned int flags, 68503b705cfSriastradh unsigned int num_macroblocks, 68603b705cfSriastradh unsigned int first_macroblock, 68703b705cfSriastradh XvMCMacroBlockArray * macroblock_array, 68803b705cfSriastradh XvMCBlockArray * blocks) 68903b705cfSriastradh{ 69003b705cfSriastradh 69103b705cfSriastradh intel_xvmc_context_ptr intel_ctx; 69203b705cfSriastradh int i, j; 69303b705cfSriastradh struct i965_xvmc_context *i965_ctx; 69403b705cfSriastradh XvMCMacroBlock *mb; 69503b705cfSriastradh struct intel_xvmc_surface *priv_target_surface = 69603b705cfSriastradh target_surface->privData; 69703b705cfSriastradh struct intel_xvmc_surface *priv_past_surface = 69803b705cfSriastradh past_surface ? past_surface->privData : 0; 69903b705cfSriastradh struct intel_xvmc_surface *priv_future_surface = 70003b705cfSriastradh future_surface ? future_surface->privData : 0; 70103b705cfSriastradh unsigned short *block_ptr; 70203b705cfSriastradh intel_ctx = context->privData; 70303b705cfSriastradh i965_ctx = context->privData; 70403b705cfSriastradh if (!intel_ctx) { 70503b705cfSriastradh XVMC_ERR("Can't find intel xvmc context\n"); 70603b705cfSriastradh return BadValue; 70703b705cfSriastradh } 70803b705cfSriastradh 70903b705cfSriastradh if (media_state.indirect_data.bo) { 71003b705cfSriastradh drm_intel_gem_bo_unmap_gtt(media_state. 71103b705cfSriastradh indirect_data.bo); 71203b705cfSriastradh 71303b705cfSriastradh drm_intel_bo_unreference(media_state.indirect_data.bo); 71403b705cfSriastradh } 71503b705cfSriastradh media_state.indirect_data.bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, 71603b705cfSriastradh "indirect data", 71703b705cfSriastradh 128 * 6 * 71803b705cfSriastradh num_macroblocks, 64); 71903b705cfSriastradh if (!media_state.indirect_data.bo) 72003b705cfSriastradh return BadAlloc; 72103b705cfSriastradh setup_surfaces(&media_state, 72203b705cfSriastradh priv_target_surface->bo, 72303b705cfSriastradh past_surface ? priv_past_surface->bo : NULL, 72403b705cfSriastradh future_surface ? priv_future_surface->bo : NULL, 72503b705cfSriastradh context->width, context->height); 72603b705cfSriastradh setup_blocks(&media_state, 128 * 6 * num_macroblocks); 72703b705cfSriastradh binding_tables(&media_state); 72803b705cfSriastradh interface_descriptor(&media_state); 72903b705cfSriastradh vfe_state(&media_state); 73003b705cfSriastradh 73103b705cfSriastradh drm_intel_gem_bo_map_gtt(media_state.indirect_data.bo); 73203b705cfSriastradh 73303b705cfSriastradh block_ptr = media_state.indirect_data.bo->virtual; 73403b705cfSriastradh for (i = first_macroblock; i < num_macroblocks + first_macroblock; i++) { 73503b705cfSriastradh unsigned short *mb_block_ptr; 73603b705cfSriastradh mb = ¯oblock_array->macro_blocks[i]; 73703b705cfSriastradh mb_block_ptr = &blocks->blocks[(mb->index << 6)]; 73803b705cfSriastradh if (mb->coded_block_pattern & 0x20) { 73903b705cfSriastradh for (j = 0; j < 8; j++) 74003b705cfSriastradh memcpy(block_ptr + 16 * j, mb_block_ptr + 8 * j, 74103b705cfSriastradh 16); 74203b705cfSriastradh mb_block_ptr += 64; 74303b705cfSriastradh } 74403b705cfSriastradh 74503b705cfSriastradh if (mb->coded_block_pattern & 0x10) { 74603b705cfSriastradh for (j = 0; j < 8; j++) 74703b705cfSriastradh memcpy(block_ptr + 16 * j + 8, 74803b705cfSriastradh mb_block_ptr + 8 * j, 16); 74903b705cfSriastradh mb_block_ptr += 64; 75003b705cfSriastradh } 75103b705cfSriastradh block_ptr += 2 * 64; 75203b705cfSriastradh if (mb->coded_block_pattern & 0x08) { 75303b705cfSriastradh for (j = 0; j < 8; j++) 75403b705cfSriastradh memcpy(block_ptr + 16 * j, mb_block_ptr + 8 * j, 75503b705cfSriastradh 16); 75603b705cfSriastradh mb_block_ptr += 64; 75703b705cfSriastradh } 75803b705cfSriastradh 75903b705cfSriastradh if (mb->coded_block_pattern & 0x04) { 76003b705cfSriastradh for (j = 0; j < 8; j++) 76103b705cfSriastradh memcpy(block_ptr + 16 * j + 8, 76203b705cfSriastradh mb_block_ptr + 8 * j, 16); 76303b705cfSriastradh mb_block_ptr += 64; 76403b705cfSriastradh } 76503b705cfSriastradh 76603b705cfSriastradh block_ptr += 2 * 64; 76703b705cfSriastradh if (mb->coded_block_pattern & 0x2) { 76803b705cfSriastradh memcpy(block_ptr, mb_block_ptr, 128); 76903b705cfSriastradh mb_block_ptr += 64; 77003b705cfSriastradh } 77103b705cfSriastradh 77203b705cfSriastradh block_ptr += 64; 77303b705cfSriastradh if (mb->coded_block_pattern & 0x1) 77403b705cfSriastradh memcpy(block_ptr, mb_block_ptr, 128); 77503b705cfSriastradh block_ptr += 64; 77603b705cfSriastradh } 77703b705cfSriastradh { 77803b705cfSriastradh int block_offset = 0; 77903b705cfSriastradh LOCK_HARDWARE(intel_ctx->hw_context); 78003b705cfSriastradh state_base_address(); 78103b705cfSriastradh flush(); 78203b705cfSriastradh clear_sf_state(); 78303b705cfSriastradh pipeline_select(&media_state); 78403b705cfSriastradh urb_layout(); 78503b705cfSriastradh media_state_pointers(&media_state); 78603b705cfSriastradh for (i = first_macroblock; 78703b705cfSriastradh i < num_macroblocks + first_macroblock; 78803b705cfSriastradh i++, block_offset += 128 * 6) { 78903b705cfSriastradh mb = ¯oblock_array->macro_blocks[i]; 79003b705cfSriastradh 79103b705cfSriastradh if (mb->macroblock_type & XVMC_MB_TYPE_INTRA) { 79203b705cfSriastradh send_media_object(mb, block_offset, 79303b705cfSriastradh INTRA_INTERFACE); 79403b705cfSriastradh } else { 79503b705cfSriastradh if (((mb->motion_type & 3) == 79603b705cfSriastradh XVMC_PREDICTION_FRAME)) { 79703b705cfSriastradh if ((mb->macroblock_type & 79803b705cfSriastradh XVMC_MB_TYPE_MOTION_FORWARD)) { 79903b705cfSriastradh if (((mb->macroblock_type & 80003b705cfSriastradh XVMC_MB_TYPE_MOTION_BACKWARD))) 80103b705cfSriastradh send_media_object(mb, 80203b705cfSriastradh block_offset, 80303b705cfSriastradh F_B_INTERFACE); 80403b705cfSriastradh else 80503b705cfSriastradh send_media_object(mb, 80603b705cfSriastradh block_offset, 80703b705cfSriastradh FORWARD_INTERFACE); 80803b705cfSriastradh } else 80903b705cfSriastradh if ((mb->macroblock_type & 81003b705cfSriastradh XVMC_MB_TYPE_MOTION_BACKWARD)) 81103b705cfSriastradh { 81203b705cfSriastradh send_media_object(mb, 81303b705cfSriastradh block_offset, 81403b705cfSriastradh BACKWARD_INTERFACE); 81503b705cfSriastradh } 81603b705cfSriastradh } else if ((mb->motion_type & 3) == 81703b705cfSriastradh XVMC_PREDICTION_FIELD) { 81803b705cfSriastradh if ((mb->macroblock_type & 81903b705cfSriastradh XVMC_MB_TYPE_MOTION_FORWARD)) { 82003b705cfSriastradh if (((mb->macroblock_type & 82103b705cfSriastradh XVMC_MB_TYPE_MOTION_BACKWARD))) 82203b705cfSriastradh send_media_object(mb, 82303b705cfSriastradh block_offset, 82403b705cfSriastradh FIELD_F_B_INTERFACE); 82503b705cfSriastradh else 82603b705cfSriastradh 82703b705cfSriastradh send_media_object(mb, 82803b705cfSriastradh block_offset, 82903b705cfSriastradh FIELD_FORWARD_INTERFACE); 83003b705cfSriastradh } else 83103b705cfSriastradh if ((mb->macroblock_type & 83203b705cfSriastradh XVMC_MB_TYPE_MOTION_BACKWARD)) 83303b705cfSriastradh { 83403b705cfSriastradh send_media_object(mb, 83503b705cfSriastradh block_offset, 83603b705cfSriastradh FIELD_BACKWARD_INTERFACE); 83703b705cfSriastradh } 83803b705cfSriastradh } else { 83903b705cfSriastradh send_media_object(mb, block_offset, 84003b705cfSriastradh DUAL_PRIME_INTERFACE); 84103b705cfSriastradh } 84203b705cfSriastradh } 84303b705cfSriastradh } 84442542f5fSchristos intelFlushBatch(); 84503b705cfSriastradh UNLOCK_HARDWARE(intel_ctx->hw_context); 84603b705cfSriastradh } 84703b705cfSriastradh return Success; 84803b705cfSriastradh} 84903b705cfSriastradh 85003b705cfSriastradhstatic Status create_context(Display * display, XvMCContext * context, 85103b705cfSriastradh int priv_count, CARD32 * priv_data) 85203b705cfSriastradh{ 85303b705cfSriastradh struct intel_xvmc_context *intel_ctx; 85403b705cfSriastradh struct intel_xvmc_hw_context *hw_ctx; 85503b705cfSriastradh hw_ctx = (struct intel_xvmc_hw_context *)priv_data; 85603b705cfSriastradh 85703b705cfSriastradh intel_ctx = calloc(1, sizeof(struct intel_xvmc_context)); 85803b705cfSriastradh if (!intel_ctx) 85903b705cfSriastradh return BadAlloc; 86003b705cfSriastradh intel_ctx->hw = hw_ctx; 86103b705cfSriastradh intel_ctx->surface_bo_size 86203b705cfSriastradh = SIZE_YUV420(context->width, context->height); 86303b705cfSriastradh context->privData = intel_ctx; 86403b705cfSriastradh 86503b705cfSriastradh media_state.is_g4x = hw_ctx->i965.is_g4x; 86603b705cfSriastradh media_state.is_965_q = hw_ctx->i965.is_965_q; 86703b705cfSriastradh 86803b705cfSriastradh if (alloc_object(&media_state)) 86903b705cfSriastradh return BadAlloc; 87003b705cfSriastradh if (media_kernels(&media_state)) 87103b705cfSriastradh return BadAlloc; 87203b705cfSriastradh return Success; 87303b705cfSriastradh} 87403b705cfSriastradh 87503b705cfSriastradhstruct _intel_xvmc_driver i965_xvmc_mc_driver = { 87603b705cfSriastradh .type = XVMC_I965_MPEG2_MC, 87703b705cfSriastradh .create_context = create_context, 87803b705cfSriastradh .destroy_context = destroy_context, 87903b705cfSriastradh .render_surface = render_surface, 88003b705cfSriastradh}; 881