diff options
author | root <root@xhh-bl32.(none)> | 2007-06-25 14:07:01 +0800 |
---|---|---|
committer | Xiang, Haihao <haihao.xiang@intel.com> | 2007-07-19 17:28:35 +0800 |
commit | 8c249765ce788f8adb0325a8e3016a0eae74b13b (patch) | |
tree | 0ff5f618ea1128c665e27d07f7feb8c70708fe31 | |
parent | 2b20b395541f786e4009211e4c56042257b8d114 (diff) |
1. using batch buffer
2. implement macroblock_ipicture instruction
3. 16bit INTRA block
-rw-r--r-- | src/i830.h | 4 | ||||
-rw-r--r-- | src/i830_memory.c | 29 | ||||
-rw-r--r-- | src/i915_hwmc.c | 216 | ||||
-rw-r--r-- | src/i915_hwmc.h | 15 | ||||
-rw-r--r-- | src/xvmc/I915XvMC.c | 358 | ||||
-rw-r--r-- | src/xvmc/I915XvMC.h | 22 | ||||
-rw-r--r-- | src/xvmc/i915_structs.h | 7 | ||||
-rw-r--r-- | src/xvmc/intel_batchbuffer.c | 61 |
8 files changed, 530 insertions, 182 deletions
@@ -649,10 +649,8 @@ extern long I830CheckAvailableMemory(ScrnInfoPtr pScrn); Bool i830_allocate_2d_memory(ScrnInfoPtr pScrn); Bool i830_allocate_texture_memory(ScrnInfoPtr pScrn); Bool i830_allocate_3d_memory(ScrnInfoPtr pScrn); -Bool i830_allocate_xvmc_surface(ScrnInfoPtr pScrn, i830_memory **surface, - unsigned long size); Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name, - i830_memory **buffer, unsigned long size); + i830_memory **buffer, unsigned long size, int flags); extern Bool I830IsPrimary(ScrnInfoPtr pScrn); extern Bool I830I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg, diff --git a/src/i830_memory.c b/src/i830_memory.c index 7022167b..fcf0ebf9 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -1760,40 +1760,21 @@ i830_xf86AllocateOffscreenLinear(ScreenPtr pScreen, int length, } /* - * Allocate memory for XvMC surface - */ -Bool -i830_allocate_xvmc_surface(ScrnInfoPtr pScrn, i830_memory **surface, unsigned long size) -{ - I830Ptr pI830 = I830PTR(pScrn); - - *surface = i830_allocate_memory(pScrn, "XvMC surface", size, - GTT_PAGE_SIZE, ALIGN_BOTH_ENDS); - - if (!*surface) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate XvMC surface space.\n"); - return FALSE; - } - - return TRUE; -} - -/* * Allocate memory for MC compensation */ -Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name, i830_memory **buffer, unsigned long size) +Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name, + i830_memory **buffer, unsigned long size, + int flags) { - I830Ptr pI830 = I830PTR(pScrn); - *buffer = i830_allocate_memory(pScrn, name, size, - GTT_PAGE_SIZE, ALIGN_BOTH_ENDS); + GTT_PAGE_SIZE, flags); if (!*buffer) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate memory for %s.\n", name); return FALSE; } + return TRUE; } #endif diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c index e5c8bd47..bc5b7286 100644 --- a/src/i915_hwmc.c +++ b/src/i915_hwmc.c @@ -70,10 +70,20 @@ typedef struct _I915XvMCSurfacePriv typedef struct _I915XvMCContextPriv { - i830_memory *mcSubContexts; - drm_handle_t subcontexts_handle; + i830_memory *mcStaticIndirectState; + drm_handle_t sis_handle; + i830_memory *mcSamplerState; + drm_handle_t ssb_handle; + i830_memory *mcMapState; + drm_handle_t msb_handle; + i830_memory *mcPixelShaderProgram; + drm_handle_t psp_handle; + i830_memory *mcPixelShaderConstants; + drm_handle_t psc_handle; i830_memory *mcCorrdata; drm_handle_t corrdata_handle; + i830_memory *mcBatchBuffer; + drm_handle_t batchbuffer_handle; } I915XvMCContextPriv; typedef struct _I915XvMC @@ -120,8 +130,7 @@ static XF86MCSurfaceInfoRec i915_YV12_mpg2_surface = 720, 576, XVMC_MPEG_2, - XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING | - XVMC_INTRA_UNSIGNED, + XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING, &yv12_subpicture_list }; @@ -135,8 +144,7 @@ static XF86MCSurfaceInfoRec i915_YV12_mpg1_surface = 720, 576, XVMC_MPEG_1, - XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING | - XVMC_INTRA_UNSIGNED, + XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING, &yv12_subpicture_list }; @@ -264,11 +272,47 @@ static Bool i915_map_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxpri I830Ptr pI830 = I830PTR(pScrn); if (drmAddMap(pI830->drmSubFD, - (drm_handle_t)(ctxpriv->mcSubContexts->offset + pI830->LinearAddr), - ctxpriv->mcSubContexts->size, DRM_AGP, 0, - (drmAddress)&ctxpriv->subcontexts_handle) < 0) { + (drm_handle_t)(ctxpriv->mcStaticIndirectState->offset + pI830->LinearAddr), + ctxpriv->mcStaticIndirectState->size, DRM_AGP, 0, + (drmAddress)&ctxpriv->sis_handle) < 0) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "[drm] drmAddMap(corrdata_handle) failed!\n"); + "[drm] drmAddMap(sis_handle) failed!\n"); + return FALSE; + } + + if (drmAddMap(pI830->drmSubFD, + (drm_handle_t)(ctxpriv->mcSamplerState->offset + pI830->LinearAddr), + ctxpriv->mcSamplerState->size, DRM_AGP, 0, + (drmAddress)&ctxpriv->ssb_handle) < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[drm] drmAddMap(ssb_handle) failed!\n"); + return FALSE; + } + + if (drmAddMap(pI830->drmSubFD, + (drm_handle_t)(ctxpriv->mcMapState->offset + pI830->LinearAddr), + ctxpriv->mcMapState->size, DRM_AGP, 0, + (drmAddress)&ctxpriv->msb_handle) < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[drm] drmAddMap(msb_handle) failed!\n"); + return FALSE; + } + + if (drmAddMap(pI830->drmSubFD, + (drm_handle_t)(ctxpriv->mcPixelShaderProgram->offset + pI830->LinearAddr), + ctxpriv->mcPixelShaderProgram->size, DRM_AGP, 0, + (drmAddress)&ctxpriv->psp_handle) < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[drm] drmAddMap(psp_handle) failed!\n"); + return FALSE; + } + + if (drmAddMap(pI830->drmSubFD, + (drm_handle_t)(ctxpriv->mcPixelShaderConstants->offset + pI830->LinearAddr), + ctxpriv->mcPixelShaderConstants->size, DRM_AGP, 0, + (drmAddress)&ctxpriv->psc_handle) < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[drm] drmAddMap(psc_handle) failed!\n"); return FALSE; } @@ -281,6 +325,15 @@ static Bool i915_map_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxpri return FALSE; } + if (drmAddMap(pI830->drmSubFD, + (drm_handle_t)(ctxpriv->mcBatchBuffer->offset + pI830->LinearAddr), + ctxpriv->mcBatchBuffer->size, DRM_AGP, 0, + (drmAddress)&ctxpriv->batchbuffer_handle) < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[drm] drmAddMap(batchbuffer_handle) failed!\n"); + return FALSE; + } + return TRUE; } @@ -288,26 +341,87 @@ static void i915_unmap_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxp { I830Ptr pI830 = I830PTR(pScrn); - if (ctxpriv->subcontexts_handle) { - drmRmMap(pI830->drmSubFD, ctxpriv->subcontexts_handle); - ctxpriv->subcontexts_handle = 0; + if (ctxpriv->sis_handle) { + drmRmMap(pI830->drmSubFD, ctxpriv->sis_handle); + ctxpriv->sis_handle = 0; + } + + if (ctxpriv->ssb_handle) { + drmRmMap(pI830->drmSubFD, ctxpriv->ssb_handle); + ctxpriv->ssb_handle = 0; + } + + if (ctxpriv->msb_handle) { + drmRmMap(pI830->drmSubFD, ctxpriv->msb_handle); + ctxpriv->msb_handle = 0; + } + + if (ctxpriv->psp_handle) { + drmRmMap(pI830->drmSubFD, ctxpriv->psp_handle); + ctxpriv->psp_handle = 0; + } + + if (ctxpriv->psc_handle) { + drmRmMap(pI830->drmSubFD, ctxpriv->psc_handle); + ctxpriv->psc_handle = 0; } if (ctxpriv->corrdata_handle) { drmRmMap(pI830->drmSubFD, ctxpriv->corrdata_handle); ctxpriv->corrdata_handle = 0; } + + if (ctxpriv->batchbuffer_handle) { + drmRmMap(pI830->drmSubFD, ctxpriv->batchbuffer_handle); + ctxpriv->batchbuffer_handle = 0; + } } static Bool i915_allocate_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxpriv) { - if (!i830_allocate_xvmc_buffer(pScrn, "buffers for context subsets", - &(ctxpriv->mcSubContexts), 8 * 1024)) { + I830Ptr pI830 = I830PTR(pScrn); + int flags = (IS_I915G(pI830) || IS_I915GM(pI830)) ? + (ALIGN_BOTH_ENDS | NEED_PHYSICAL_ADDR) : ALIGN_BOTH_ENDS; + + if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Static Indirect State", + &(ctxpriv->mcStaticIndirectState), 4 * 1024, + flags)) { + return FALSE; + } + + if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Sampler State", + &(ctxpriv->mcSamplerState), 4 * 1024, + flags)) { + return FALSE; + } + + if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Map State", + &(ctxpriv->mcMapState), 4 * 1024, + flags)) { + return FALSE; + } + + if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Pixel Shader Program", + &(ctxpriv->mcPixelShaderProgram), 4 * 1024, + flags)) { + return FALSE; + } + + if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Pixel Shader Constants", + &(ctxpriv->mcPixelShaderConstants), 4 * 1024, + flags)) { + return FALSE; + } + + if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Correction Data Buffer", + &(ctxpriv->mcCorrdata), 512 * 1024, + ALIGN_BOTH_ENDS)) { return FALSE; } - if (!i830_allocate_xvmc_buffer(pScrn, "Correction Data Buffer", - &(ctxpriv->mcCorrdata), 1 * 1024 * 1024)) { + if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]batch buffer", + &(ctxpriv->mcBatchBuffer), 8 * 1024, + ALIGN_BOTH_ENDS)) { return FALSE; } @@ -317,15 +431,40 @@ static Bool i915_allocate_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *c static void i915_free_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxpriv) { - if (ctxpriv->mcSubContexts) { - i830_free_memory(pScrn, ctxpriv->mcSubContexts); - ctxpriv->mcSubContexts = NULL; + if (ctxpriv->mcStaticIndirectState) { + i830_free_memory(pScrn, ctxpriv->mcStaticIndirectState); + ctxpriv->mcStaticIndirectState = NULL; + } + + if (ctxpriv->mcSamplerState) { + i830_free_memory(pScrn, ctxpriv->mcSamplerState); + ctxpriv->mcSamplerState = NULL; + } + + if (ctxpriv->mcMapState) { + i830_free_memory(pScrn, ctxpriv->mcMapState); + ctxpriv->mcMapState = NULL; + } + + if (ctxpriv->mcPixelShaderProgram) { + i830_free_memory(pScrn, ctxpriv->mcPixelShaderProgram); + ctxpriv->mcPixelShaderProgram = NULL; + } + + if (ctxpriv->mcPixelShaderConstants) { + i830_free_memory(pScrn, ctxpriv->mcPixelShaderConstants); + ctxpriv->mcPixelShaderConstants = NULL; } if (ctxpriv->mcCorrdata) { i830_free_memory(pScrn, ctxpriv->mcCorrdata); ctxpriv->mcCorrdata = NULL; } + + if (ctxpriv->mcBatchBuffer) { + i830_free_memory(pScrn, ctxpriv->mcBatchBuffer); + ctxpriv->mcBatchBuffer = NULL; + } } /************************************************************************** @@ -347,6 +486,7 @@ static int I915XvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext, { I830Ptr pI830 = I830PTR(pScrn); DRIInfoPtr pDRIInfo = pI830->pDRIInfo; + I830DRIPtr pI830DRI = pDRIInfo->devPrivate; I915XvMCCreateContextRec *contextRec = NULL; I915XvMCPtr pXvMC = pI830->xvmc; I915XvMCContextPriv *ctxpriv = NULL; @@ -419,16 +559,37 @@ static int I915XvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext, } contextRec->ctxno = i; - contextRec->subcontexts.handle = ctxpriv->subcontexts_handle; - contextRec->subcontexts.offset = ctxpriv->mcSubContexts->offset; - contextRec->subcontexts.size = ctxpriv->mcSubContexts->size; + contextRec->sis.handle = ctxpriv->sis_handle; + contextRec->sis.offset = ctxpriv->mcStaticIndirectState->offset; + contextRec->sis.size = ctxpriv->mcStaticIndirectState->size; + contextRec->sis.bus_addr = ctxpriv->mcStaticIndirectState->bus_addr; + contextRec->ssb.handle = ctxpriv->ssb_handle; + contextRec->ssb.offset = ctxpriv->mcSamplerState->offset; + contextRec->ssb.size = ctxpriv->mcSamplerState->size; + contextRec->ssb.bus_addr = ctxpriv->mcSamplerState->bus_addr; + contextRec->msb.handle = ctxpriv->msb_handle; + contextRec->msb.offset = ctxpriv->mcMapState->offset; + contextRec->msb.size = ctxpriv->mcMapState->size; + contextRec->msb.bus_addr = ctxpriv->mcMapState->bus_addr; + contextRec->psp.handle = ctxpriv->psp_handle; + contextRec->psp.offset = ctxpriv->mcPixelShaderProgram->offset; + contextRec->psp.size = ctxpriv->mcPixelShaderProgram->size; + contextRec->psp.bus_addr = ctxpriv->mcPixelShaderProgram->bus_addr; + contextRec->psc.handle = ctxpriv->psc_handle; + contextRec->psc.offset = ctxpriv->mcPixelShaderConstants->offset; + contextRec->psc.size = ctxpriv->mcPixelShaderConstants->size; + contextRec->psc.bus_addr = ctxpriv->mcPixelShaderConstants->bus_addr; contextRec->corrdata.handle = ctxpriv->corrdata_handle; contextRec->corrdata.offset = ctxpriv->mcCorrdata->offset; contextRec->corrdata.size = ctxpriv->mcCorrdata->size; + contextRec->batchbuffer.handle = ctxpriv->batchbuffer_handle; + contextRec->batchbuffer.offset = ctxpriv->mcBatchBuffer->offset; + contextRec->batchbuffer.size = ctxpriv->mcBatchBuffer->size; contextRec->sarea_size = pDRIInfo->SAREASize; contextRec->sarea_priv_offset = sizeof(XF86DRISAREARec); contextRec->screen = pScrn->pScreen->myNum; contextRec->depth = pScrn->bitsPerPixel; + contextRec->deviceID = pI830DRI->deviceID; contextRec->initAttrs = vx->xvAttr; pXvMC->ncontexts++; @@ -482,7 +643,9 @@ static int I915XvMCCreateSurface(ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf, ctx = pSurf->context; bufsize = size_yuv420(ctx->width, ctx->height); - if (!i830_allocate_xvmc_surface(pScrn, &(sfpriv->surface), bufsize)) { + if (!i830_allocate_xvmc_buffer(pScrn, "XvMC surface", + &(sfpriv->surface), bufsize, + ALIGN_BOTH_ENDS)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[XvMC] I915XvMCCreateSurface: Failed to allocate XvMC surface space!\n"); xfree(sfpriv); @@ -510,7 +673,6 @@ static int I915XvMCCreateSurface(ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf, if (!pXvMC->surfaces[srfno]) break; } - surfaceRec->srfno = srfno; surfaceRec->srf.handle = sfpriv->surface_handle; surfaceRec->srf.offset = sfpriv->surface->offset; @@ -567,7 +729,9 @@ static int I915XvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp, ctx = pSubp->context; bufsize = size_xx44(ctx->width, ctx->height); - if (!i830_allocate_xvmc_surface(pScrn, &(sfpriv->surface), bufsize)) { + if (!i830_allocate_xvmc_buffer(pScrn, "XvMC surface", + &(sfpriv->surface), bufsize, + ALIGN_BOTH_ENDS)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[XvMC] I915XvMCCreateSurface: Failed to allocate XvMC surface space!\n"); xfree(sfpriv); diff --git a/src/i915_hwmc.h b/src/i915_hwmc.h index 42d2b295..a4b4220a 100644 --- a/src/i915_hwmc.h +++ b/src/i915_hwmc.h @@ -39,21 +39,28 @@ typedef struct struct hwmc_buffer { - unsigned handle; - unsigned offset; - unsigned size; + drm_handle_t handle; + unsigned long offset; + unsigned long size; + unsigned long bus_addr; }; typedef struct { unsigned ctxno; /* XvMC private context reference number */ drm_context_t drmcontext; - struct hwmc_buffer subcontexts; + struct hwmc_buffer sis; + struct hwmc_buffer ssb; + struct hwmc_buffer msb; + struct hwmc_buffer psp; + struct hwmc_buffer psc; struct hwmc_buffer corrdata;/* Correction Data Buffer */ + struct hwmc_buffer batchbuffer; unsigned sarea_size; unsigned sarea_priv_offset; unsigned screen; unsigned depth; + int deviceID; I915XvMCAttrHolder initAttrs; } I915XvMCCreateContextRec; diff --git a/src/xvmc/I915XvMC.c b/src/xvmc/I915XvMC.c index 0257d53c..3df6ebe9 100644 --- a/src/xvmc/I915XvMC.c +++ b/src/xvmc/I915XvMC.c @@ -196,19 +196,24 @@ _STATIC_ unsigned long size_yuv420(int w, int h) return h * (yPitch + uvPitch); } -_STATIC_ void i915_flush_with_flush_bit_clear(i915XvMCContext *pI915XvMC) +_STATIC_ void i915_flush(i915XvMCContext *pI915XvMC, int map, int render) { struct i915_mi_flush mi_flush; memset(&mi_flush, 0, sizeof(mi_flush)); mi_flush.dw0.type = CMD_MI; mi_flush.dw0.opcode = OPC_MI_FLUSH; - mi_flush.dw0.map_cache_invalidate = 1; - mi_flush.dw0.render_cache_flush_inhibit = 0; + mi_flush.dw0.map_cache_invalidate = map; + mi_flush.dw0.render_cache_flush_inhibit = render; intelBatchbufferData(pI915XvMC, &mi_flush, sizeof(mi_flush), 0); } +_STATIC_ void i915_flush_with_flush_bit_clear(i915XvMCContext *pI915XvMC) +{ + i915_flush(pI915XvMC, 1, 0); +} + /* for MC picture rendering */ _STATIC_ void i915_mc_static_indirect_state_buffer(XvMCContext *context, XvMCSurface *surface, @@ -314,6 +319,8 @@ _STATIC_ void i915_mc_static_indirect_state_buffer(XvMCContext *context, dest_buffer_variables_mpeg->dw1.tff = 0; } + dest_buffer_variables_mpeg->dw1.v_subsample_factor = MC_SUB_1V; + dest_buffer_variables_mpeg->dw1.h_subsample_factor = MC_SUB_1H; dest_buffer_variables_mpeg->dw1.picture_width = (w >> 4); /* in macroblocks */ dest_buffer_variables_mpeg->dw2.picture_coding_type = picture_coding_type; @@ -389,7 +396,7 @@ _STATIC_ void i915_mc_map_state_buffer(XvMCContext *context, tm->tm2.cube_face = 0; tm->tm2.pitch = (privFuture->yStride >> 2) - 1; - /* 3DSATE_MAP_STATE: U*/ + /* 3DSATE_MAP_STATE: U */ map_state = (struct i915_3dstate_map_state *)(++tm); memset(map_state, 0, sizeof(*map_state)); map_state->dw0.type = CMD_3D; @@ -484,7 +491,7 @@ _STATIC_ void i915_mc_map_state_buffer(XvMCContext *context, tm->tm2.pitch = (privFuture->uvStride >> 2) - 1; } -_STATIC_ void i915_mc_load_indirect_buffer(XvMCContext *context) +_STATIC_ void i915_mc_load_sis_msb_buffers(XvMCContext *context) { struct i915_3dstate_load_indirect *load_indirect; sis_state *sis = NULL; @@ -492,6 +499,7 @@ _STATIC_ void i915_mc_load_indirect_buffer(XvMCContext *context) i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; void *base = NULL; unsigned size; + int mem_select = 1; i915_flush_with_flush_bit_clear(pI915XvMC); @@ -501,22 +509,38 @@ _STATIC_ void i915_mc_load_indirect_buffer(XvMCContext *context) load_indirect = (struct i915_3dstate_load_indirect *)base; load_indirect->dw0.type = CMD_3D; load_indirect->dw0.opcode = OPC_3DSTATE_LOAD_INDIRECT; - load_indirect->dw0.mem_select = 1; /* Bearlake only */ load_indirect->dw0.block_mask = BLOCK_SIS | BLOCK_MSB; load_indirect->dw0.length = (size >> 2) - 2; + if (pI915XvMC->deviceID == PCI_CHIP_I915_G || + pI915XvMC->deviceID == PCI_CHIP_I915_GM) + mem_select = 0; + + load_indirect->dw0.mem_select = mem_select; + /* SIS */ sis = (sis_state *)(++load_indirect); sis->dw0.valid = 1; - sis->dw0.buffer_address = (pI915XvMC->sis.offset >> 2); + sis->dw0.force = 1; sis->dw1.length = 16; // 4 * 3 + 2 + 3 - 1 + if (mem_select) + sis->dw0.buffer_address = (pI915XvMC->sis.offset >> 2); + else + sis->dw0.buffer_address = (pI915XvMC->sis.bus_addr >> 2); + + /* MSB */ msb = (msb_state *)(++sis); msb->dw0.valid = 1; - msb->dw0.buffer_address = (pI915XvMC->msb.offset >> 2); + msb->dw0.force = 1; msb->dw1.length = 23; // 3 * 8 - 1 + if (mem_select) + msb->dw0.buffer_address = (pI915XvMC->msb.offset >> 2); + else + msb->dw0.buffer_address = (pI915XvMC->msb.bus_addr >> 2); + intelBatchbufferData(pI915XvMC, base, size, 0); free(base); } @@ -537,6 +561,21 @@ _STATIC_ void i915_mc_mpeg_set_origin(XvMCContext *context, XvMCMacroBlock *mb) intelBatchbufferData(pI915XvMC, &set_origin, sizeof(set_origin), 0); } +_STATIC_ void i915_mc_mpeg_macroblock_ipicture(XvMCContext *context, XvMCMacroBlock *mb) +{ + struct i915_3dmpeg_macroblock_ipicture macroblock_ipicture; + i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; + + /* 3DMPEG_MACROBLOCK_IPICTURE */ + memset(¯oblock_ipicture, 0, sizeof(macroblock_ipicture)); + macroblock_ipicture.dw0.type = CMD_3D; + macroblock_ipicture.dw0.opcode = OPC_3DMPEG_MACROBLOCK_IPICTURE; + macroblock_ipicture.dw0.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD); + + intelBatchbufferData(pI915XvMC, ¯oblock_ipicture, sizeof(macroblock_ipicture), 0); +} + + _STATIC_ void i915_mc_mpeg_macroblock_0mv(XvMCContext *context, XvMCMacroBlock *mb) { struct i915_3dmpeg_macroblock_0mv macroblock_0mv; @@ -553,14 +592,16 @@ _STATIC_ void i915_mc_mpeg_macroblock_0mv(XvMCContext *context, XvMCMacroBlock * macroblock_0mv.header.dw1.h263_4mv = 0; /* should be 0 */ macroblock_0mv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD); +/* if (!mb->coded_block_pattern) macroblock_0mv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME; +*/ macroblock_0mv.header.dw1.motion_type = 0; // (mb->motion_type & 0x3); macroblock_0mv.header.dw1.vertical_field_select = 0; // mb->motion_vertical_field_select & 0xf; macroblock_0mv.header.dw1.coded_block_pattern = mb->coded_block_pattern; macroblock_0mv.header.dw1.skipped_macroblocks = 0; - + intelBatchbufferData(pI915XvMC, ¯oblock_0mv, sizeof(macroblock_0mv), 0); } @@ -584,7 +625,7 @@ _STATIC_ void i915_mc_mpeg_macroblock_1fbmv(XvMCContext *context, XvMCMacroBlock macroblock_1fbmv.header.dw1.h263_4mv = 0; /* should be 0 */ macroblock_1fbmv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD); - if (!mb->coded_block_pattern) + if (!(mb->coded_block_pattern & 0x3f)) macroblock_1fbmv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME; macroblock_1fbmv.header.dw1.motion_type = (mb->motion_type & 0x03); @@ -629,7 +670,7 @@ _STATIC_ void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock macroblock_2fbmv.header.dw1.h263_4mv = 0; /* should be 0 */ macroblock_2fbmv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD); - if (!mb->coded_block_pattern) + if (!(mb->coded_block_pattern & 0x3f)) macroblock_2fbmv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME; macroblock_2fbmv.header.dw1.motion_type = (mb->motion_type & 0x03); @@ -941,6 +982,7 @@ _STATIC_ void i915_mc_one_time_state_initialization(XvMCContext *context) i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; unsigned size; void *base = NULL; + int mem_select = 1; /* 3DSTATE_LOAD_STATE_IMMEDIATE_1 */ size = sizeof(*load_state_immediate_1) + sizeof(*s3) + sizeof(*s6); @@ -988,10 +1030,15 @@ _STATIC_ void i915_mc_one_time_state_initialization(XvMCContext *context) load_indirect = (struct i915_3dstate_load_indirect *)base; load_indirect->dw0.type = CMD_3D; load_indirect->dw0.opcode = OPC_3DSTATE_LOAD_INDIRECT; - load_indirect->dw0.mem_select = 1; /* Bearlake only */ load_indirect->dw0.block_mask = BLOCK_DIS | BLOCK_SSB | BLOCK_PSP | BLOCK_PSC; load_indirect->dw0.length = (size >> 2) - 2; + if (pI915XvMC->deviceID == PCI_CHIP_I915_G || + pI915XvMC->deviceID == PCI_CHIP_I915_GM) + mem_select = 0; + + load_indirect->dw0.mem_select = mem_select; + /* DIS */ dis = (dis_state *)(++load_indirect); dis->dw0.valid = 0; @@ -1001,26 +1048,38 @@ _STATIC_ void i915_mc_one_time_state_initialization(XvMCContext *context) /* SSB */ ssb = (ssb_state *)(++dis); ssb->dw0.valid = 1; - ssb->dw0.buffer_address = (pI915XvMC->ssb.offset >> 2); ssb->dw1.length = 7; /* 8 - 1 */ + if (mem_select) + ssb->dw0.buffer_address = (pI915XvMC->ssb.offset >> 2); + else + ssb->dw0.buffer_address = (pI915XvMC->ssb.bus_addr >> 2); + /* PSP */ psp = (psp_state *)(++ssb); psp->dw0.valid = 1; - psp->dw0.buffer_address = (pI915XvMC->psp.offset >> 2); psp->dw1.length = 66; /* 4 + 16 + 16 + 31 - 1 */ + if (mem_select) + psp->dw0.buffer_address = (pI915XvMC->psp.offset >> 2); + else + psp->dw0.buffer_address = (pI915XvMC->psp.bus_addr >> 2); + /* PSC */ psc = (psc_state *)(++psp); psc->dw0.valid = 1; - psc->dw0.buffer_address = (pI915XvMC->psc.offset >> 2); psc->dw1.length = 5; /* 6 - 1 */ + if (mem_select) + psc->dw0.buffer_address = (pI915XvMC->psc.offset >> 2); + else + psc->dw0.buffer_address = (pI915XvMC->psc.bus_addr >> 2); + intelBatchbufferData(pI915XvMC, base, size, 0); free(base); } -_STATIC_ void i915_mc_start_rendering(XvMCContext *context) +_STATIC_ void i915_mc_invalidate_subcontext_buffers(XvMCContext *context, unsigned mask) { struct i915_3dstate_load_indirect *load_indirect = NULL; sis_state *sis = NULL; @@ -1031,58 +1090,99 @@ _STATIC_ void i915_mc_start_rendering(XvMCContext *context) psc_state *psc = NULL; i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; unsigned size; - void *base = NULL; + void *base = NULL, *ptr = NULL; /* flush */ i915_flush_with_flush_bit_clear(pI915XvMC); + size = sizeof(*load_indirect); + if (mask & BLOCK_SIS) + size += sizeof(*sis); + if (mask & BLOCK_DIS) + size += sizeof(*dis); + if (mask & BLOCK_SSB) + size += sizeof(*ssb); + if (mask & BLOCK_MSB) + size += sizeof(*msb); + if (mask & BLOCK_PSP) + size += sizeof(*psp); + if (mask & BLOCK_PSC) + size += sizeof(*psc); + + if (size == sizeof(*load_indirect)) { + printf("There must be at least one bit set\n"); + return; + } + /* 3DSTATE_LOAD_INDIRECT */ - size = sizeof(*load_indirect) + sizeof(*sis) + sizeof(*dis) + - sizeof(*ssb) + sizeof(*msb) + sizeof(*psp) + sizeof(*psc); base = calloc(1, size); load_indirect = (struct i915_3dstate_load_indirect *)base; load_indirect->dw0.type = CMD_3D; load_indirect->dw0.opcode = OPC_3DSTATE_LOAD_INDIRECT; - load_indirect->dw0.mem_select = 1; /* Bearlake only */ - load_indirect->dw0.block_mask = BLOCK_SIS | BLOCK_DIS | - BLOCK_SSB | BLOCK_MSB | BLOCK_PSP | BLOCK_PSC; + + if (pI915XvMC->deviceID == PCI_CHIP_I915_G || + pI915XvMC->deviceID == PCI_CHIP_I915_GM) + load_indirect->dw0.mem_select = 0; + else + load_indirect->dw0.mem_select = 1; + + load_indirect->dw0.block_mask = mask; load_indirect->dw0.length = (size >> 2) - 2; + ptr = ++load_indirect; /* SIS */ - sis = (sis_state *)(++load_indirect); - sis->dw0.valid = 0; - sis->dw0.buffer_address = 0; - sis->dw1.length = 0; + if (mask & BLOCK_SIS) { + sis = (sis_state *)ptr; + sis->dw0.valid = 0; + sis->dw0.buffer_address = 0; + sis->dw1.length = 0; + ptr = ++sis; + } /* DIS */ - dis = (dis_state *)(++sis); - dis->dw0.valid = 0; - dis->dw0.reset = 0; - dis->dw0.buffer_address = 0; + if (mask & BLOCK_DIS) { + dis = (dis_state *)ptr; + dis->dw0.valid = 0; + dis->dw0.reset = 0; + dis->dw0.buffer_address = 0; + ptr = ++dis; + } /* SSB */ - ssb = (ssb_state *)(++dis); - ssb->dw0.valid = 0; - ssb->dw0.buffer_address = 0; - ssb->dw1.length = 0; + if (mask & BLOCK_SSB) { + ssb = (ssb_state *)ptr; + ssb->dw0.valid = 0; + ssb->dw0.buffer_address = 0; + ssb->dw1.length = 0; + ptr = ++ssb; + } /* MSB */ - msb = (msb_state *)(++ssb); - msb->dw0.valid = 0; - msb->dw0.buffer_address = 0; - msb->dw1.length = 0; + if (mask & BLOCK_MSB) { + msb = (msb_state *)ptr; + msb->dw0.valid = 0; + msb->dw0.buffer_address = 0; + msb->dw1.length = 0; + ptr = ++msb; + } /* PSP */ - psp = (psp_state *)(++msb); - psp->dw0.valid = 0; - psp->dw0.buffer_address = 0; - psp->dw1.length = 0; - + if (mask & BLOCK_PSP) { + psp = (psp_state *)ptr; + psp->dw0.valid = 0; + psp->dw0.buffer_address = 0; + psp->dw1.length = 0; + ptr = ++psp; + } + /* PSC */ - psc = (psc_state *)(++psp); - psc->dw0.valid = 0; - psc->dw0.buffer_address = 0; - psc->dw1.length = 0; + if (mask & BLOCK_PSC) { + psc = (psc_state *)ptr; + psc->dw0.valid = 0; + psc->dw0.buffer_address = 0; + psc->dw1.length = 0; + ptr = ++psc; + } intelBatchbufferData(pI915XvMC, base, size, 0); free(base); @@ -1091,9 +1191,37 @@ _STATIC_ void i915_mc_start_rendering(XvMCContext *context) _STATIC_ int i915_xvmc_map_buffers(i915XvMCContext *pI915XvMC) { if (drmMap(pI915XvMC->fd, - pI915XvMC->subcontexts.handle, - pI915XvMC->subcontexts.size, - (drmAddress *)&pI915XvMC->subcontexts.map) != 0) { + pI915XvMC->sis.handle, + pI915XvMC->sis.size, + (drmAddress *)&pI915XvMC->sis.map) != 0) { + return -1; + } + + if (drmMap(pI915XvMC->fd, + pI915XvMC->ssb.handle, + pI915XvMC->ssb.size, + (drmAddress *)&pI915XvMC->ssb.map) != 0) { + return -1; + } + + if (drmMap(pI915XvMC->fd, + pI915XvMC->msb.handle, + pI915XvMC->msb.size, + (drmAddress *)&pI915XvMC->msb.map) != 0) { + return -1; + } + + if (drmMap(pI915XvMC->fd, + pI915XvMC->psp.handle, + pI915XvMC->psp.size, + (drmAddress *)&pI915XvMC->psp.map) != 0) { + return -1; + } + + if (drmMap(pI915XvMC->fd, + pI915XvMC->psc.handle, + pI915XvMC->psc.size, + (drmAddress *)&pI915XvMC->psc.map) != 0) { return -1; } @@ -1104,20 +1232,41 @@ _STATIC_ int i915_xvmc_map_buffers(i915XvMCContext *pI915XvMC) return -1; } - pI915XvMC->sis.map = pI915XvMC->subcontexts.map; - pI915XvMC->msb.map = pI915XvMC->subcontexts.map + 1 * 1024; - pI915XvMC->ssb.map = pI915XvMC->subcontexts.map + 2 * 1024; - pI915XvMC->psp.map = pI915XvMC->subcontexts.map + 3 * 1024; - pI915XvMC->psc.map = pI915XvMC->subcontexts.map + 4 * 1024; + if (drmMap(pI915XvMC->fd, + pI915XvMC->batchbuffer.handle, + pI915XvMC->batchbuffer.size, + (drmAddress *)&pI915XvMC->batchbuffer.map) != 0) { + return -1; + } return 0; } _STATIC_ void i915_xvmc_unmap_buffers(i915XvMCContext *pI915XvMC) { - if (pI915XvMC->subcontexts.map) { - drmUnmap(pI915XvMC->subcontexts.map, pI915XvMC->subcontexts.size); - pI915XvMC->subcontexts.map = NULL; + if (pI915XvMC->sis.map) { + drmUnmap(pI915XvMC->sis.map, pI915XvMC->sis.size); + pI915XvMC->sis.map = NULL; + } + + if (pI915XvMC->ssb.map) { + drmUnmap(pI915XvMC->ssb.map, pI915XvMC->ssb.size); + pI915XvMC->ssb.map = NULL; + } + + if (pI915XvMC->msb.map) { + drmUnmap(pI915XvMC->msb.map, pI915XvMC->msb.size); + pI915XvMC->msb.map = NULL; + } + + if (pI915XvMC->psp.map) { + drmUnmap(pI915XvMC->psp.map, pI915XvMC->psp.size); + pI915XvMC->psp.map = NULL; + } + + if (pI915XvMC->psc.map) { + drmUnmap(pI915XvMC->psc.map, pI915XvMC->psc.size); + pI915XvMC->psc.map = NULL; } if (pI915XvMC->corrdata.map) { @@ -1125,11 +1274,10 @@ _STATIC_ void i915_xvmc_unmap_buffers(i915XvMCContext *pI915XvMC) pI915XvMC->corrdata.map = NULL; } - pI915XvMC->sis.map = NULL; - pI915XvMC->msb.map = NULL; - pI915XvMC->ssb.map = NULL; - pI915XvMC->psp.map = NULL; - pI915XvMC->psc.map = NULL; + if (pI915XvMC->batchbuffer.map) { + drmUnmap(pI915XvMC->batchbuffer.map, pI915XvMC->batchbuffer.size); + pI915XvMC->batchbuffer.map = NULL; + } } /* @@ -1714,22 +1862,38 @@ Status XvMCCreateContext(Display *display, XvPortID port, tmpComm = (I915XvMCCreateContextRec *)priv_data; pI915XvMC->ctxno = tmpComm->ctxno; - pI915XvMC->subcontexts.handle = tmpComm->subcontexts.handle; - pI915XvMC->subcontexts.offset = tmpComm->subcontexts.offset; - pI915XvMC->subcontexts.size = tmpComm->subcontexts.size; - pI915XvMC->sis.offset = pI915XvMC->subcontexts.offset; - pI915XvMC->sis.size = 1024; - pI915XvMC->msb.offset = pI915XvMC->subcontexts.offset + 1 * 1024; - pI915XvMC->msb.size = 1024; - pI915XvMC->ssb.offset = pI915XvMC->subcontexts.offset + 2 * 1024; - pI915XvMC->ssb.size = 1024; - pI915XvMC->psp.offset = pI915XvMC->subcontexts.offset + 3 * 1024; - pI915XvMC->psp.size = 1024; - pI915XvMC->psc.offset = pI915XvMC->subcontexts.offset + 4 * 1024; - pI915XvMC->psc.size = 1024; + pI915XvMC->deviceID = tmpComm->deviceID; + pI915XvMC->sis.handle = tmpComm->sis.handle; + pI915XvMC->sis.offset = tmpComm->sis.offset; + pI915XvMC->sis.size = tmpComm->sis.size; + pI915XvMC->ssb.handle = tmpComm->ssb.handle; + pI915XvMC->ssb.offset = tmpComm->ssb.offset; + pI915XvMC->ssb.size = tmpComm->ssb.size; + pI915XvMC->msb.handle = tmpComm->msb.handle; + pI915XvMC->msb.offset = tmpComm->msb.offset; + pI915XvMC->msb.size = tmpComm->msb.size; + pI915XvMC->psp.handle = tmpComm->psp.handle; + pI915XvMC->psp.offset = tmpComm->psp.offset; + pI915XvMC->psp.size = tmpComm->psp.size; + pI915XvMC->psc.handle = tmpComm->psc.handle; + pI915XvMC->psc.offset = tmpComm->psc.offset; + pI915XvMC->psc.size = tmpComm->psc.size; + + if (pI915XvMC->deviceID == PCI_CHIP_I915_G || + pI915XvMC->deviceID == PCI_CHIP_I915_GM) { + pI915XvMC->sis.bus_addr = tmpComm->sis.bus_addr; + pI915XvMC->ssb.bus_addr = tmpComm->ssb.bus_addr; + pI915XvMC->msb.bus_addr = tmpComm->msb.bus_addr; + pI915XvMC->psp.bus_addr = tmpComm->psp.bus_addr; + pI915XvMC->psc.bus_addr = tmpComm->psc.bus_addr; + } + pI915XvMC->corrdata.handle = tmpComm->corrdata.handle; pI915XvMC->corrdata.offset = tmpComm->corrdata.offset; pI915XvMC->corrdata.size = tmpComm->corrdata.size; + pI915XvMC->batchbuffer.handle = tmpComm->batchbuffer.handle; + pI915XvMC->batchbuffer.offset = tmpComm->batchbuffer.offset; + pI915XvMC->batchbuffer.size = tmpComm->batchbuffer.size; pI915XvMC->sarea_size = tmpComm->sarea_size; pI915XvMC->sarea_priv_offset = tmpComm->sarea_priv_offset; pI915XvMC->screen = tmpComm->screen; @@ -1859,6 +2023,7 @@ Status XvMCCreateContext(Display *display, XvPortID port, pthread_mutex_init(&pI915XvMC->ctxmutex, NULL); intelInitBatchBuffer(pI915XvMC); pI915XvMC->ref = 1; + pI915XvMC->inited_mc = 0; return Success; } @@ -2190,7 +2355,15 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context, } LOCK_HARDWARE(pI915XvMC); - i915_mc_start_rendering(context); + // if (!pI915XvMC->inited_mc) { + i915_mc_invalidate_subcontext_buffers(context, BLOCK_SIS | BLOCK_SSB + | BLOCK_MSB | BLOCK_PSP | BLOCK_PSC); + i915_mc_sampler_state_buffer(context); + i915_mc_pixel_shader_program_buffer(context); + i915_mc_pixel_shader_constants_buffer(context); + i915_mc_one_time_state_initialization(context); + pI915XvMC->inited_mc = 1; + //} intelFlushBatch(pI915XvMC, TRUE); UNLOCK_HARDWARE(pI915XvMC); @@ -2232,36 +2405,23 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context, memcpy(corrdata_ptr, block_ptr, bspm); corrdata_ptr += bspm; } - //memset(privTarget->srf.map, 0x7f, 128); + /* Lock */ LOCK_HARDWARE(pI915XvMC); - i915_mc_sampler_state_buffer(context); - i915_mc_pixel_shader_program_buffer(context); - i915_mc_pixel_shader_constants_buffer(context); - i915_mc_one_time_state_initialization(context); - intelFlushBatch(pI915XvMC, TRUE); - i915_mc_static_indirect_state_buffer(context, target_surface, picture_structure, flags, picture_coding_type); i915_mc_map_state_buffer(context, privTarget, privPast, privFuture); - i915_mc_load_indirect_buffer(context); - intelFlushBatch(pI915XvMC, TRUE); - // i915_mc_mpeg_set_origin(context, ¯oblock_array->macro_blocks[first_macroblock]); + i915_mc_load_sis_msb_buffers(context); + i915_mc_mpeg_set_origin(context, ¯oblock_array->macro_blocks[first_macroblock]); + for (i = first_macroblock; i < (num_macroblocks + first_macroblock); i++) { - mb = ¯oblock_array->macro_blocks[i]; - i915_mc_mpeg_set_origin(context, mb); - // ¯oblock_array->macro_blocks[first_macroblock]); + mb = ¯oblock_array->macro_blocks[i]; /* Intra Blocks */ if (mb->macroblock_type & XVMC_MB_TYPE_INTRA) { - i915_mc_mpeg_macroblock_0mv(context, mb); - intelFlushBatch(pI915XvMC, TRUE); - continue; - } - - /* Frame Picture */ - if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) { + i915_mc_mpeg_macroblock_ipicture(context, mb); + } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) { /* Frame Picture */ switch (mb->motion_type & 3) { case XVMC_PREDICTION_FIELD: /* Field Based */ i915_mc_mpeg_macroblock_2fbmv(context, mb); @@ -2269,7 +2429,7 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context, case XVMC_PREDICTION_FRAME: /* Frame Based */ i915_mc_mpeg_macroblock_1fbmv(context, mb); - break; + break; case XVMC_PREDICTION_DUAL_PRIME: /* Dual Prime */ i915_mc_mpeg_macroblock_2fbmv(context, mb); @@ -2298,7 +2458,7 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context, break; } } /* Field Picture */ - intelFlushBatch(pI915XvMC, TRUE); + i915_flush(pI915XvMC, 0, 1); } intelFlushBatch(pI915XvMC, TRUE); diff --git a/src/xvmc/I915XvMC.h b/src/xvmc/I915XvMC.h index e3a83d9f..a27ea66d 100644 --- a/src/xvmc/I915XvMC.h +++ b/src/xvmc/I915XvMC.h @@ -37,14 +37,25 @@ THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include <X11/Xutil.h> #define I915_SUBPIC_PALETTE_SIZE 16 +#define MAX_SUBCONTEXT_LEN 1024 + +#define PCI_CHIP_I915_G 0x2582 +#define PCI_CHIP_I915_GM 0x2592 +#define PCI_CHIP_I945_G 0x2772 +#define PCI_CHIP_I945_GM 0x27A2 +#define PCI_CHIP_I945_GME 0x27AE +#define PCI_CHIP_G33_G 0x29C2 +#define PCI_CHIP_Q35_G 0x29B2 +#define PCI_CHIP_Q33_G 0x29D2 /*************************************************************************** // i915XvMCDrmMap: Holds the data about the DRM maps ***************************************************************************/ typedef struct _i915XvMCDrmMap { drm_handle_t handle; - unsigned offset; - unsigned size; + unsigned long offset; + unsigned long size; + unsigned long bus_addr; drmAddress map; } i915XvMCDrmMap, *i915XvMCDrmMapPtr; @@ -66,7 +77,8 @@ typedef struct _i915XvMCContext { int lock; /* Lightweight lock to avoid locking twice */ int locked; volatile drmI830Sarea *sarea; - + int inited_mc; + drmLock *driHwLock; drm_context_t hHWContext; /* drmcontext; */ drm_handle_t hsarea; /* Handle to drm shared memory area */ @@ -90,14 +102,16 @@ typedef struct _i915XvMCContext { XID id; XVisualInfo visualInfo; void *drawHash; + int deviceID; i915XvMCDrmMap sis; i915XvMCDrmMap msb; i915XvMCDrmMap ssb; i915XvMCDrmMap psp; i915XvMCDrmMap psc; - i915XvMCDrmMap subcontexts; + i915XvMCDrmMap corrdata; + i915XvMCDrmMap batchbuffer; struct { unsigned start_offset; diff --git a/src/xvmc/i915_structs.h b/src/xvmc/i915_structs.h index cd842a80..05a23aa5 100644 --- a/src/xvmc/i915_structs.h +++ b/src/xvmc/i915_structs.h @@ -253,6 +253,13 @@ struct i915_3dstate_dest_buffer_variables #define MPEG_P_PICTURE 2 #define MPEG_B_PICTURE 3 +#define MC_SUB_1H 0 +#define MC_SUB_2H 1 +#define MC_SUB_4H 2 + +#define MC_SUB_1V 0 +#define MC_SUB_2V 1 + struct i915_3dstate_dest_buffer_variables_mpeg { struct { diff --git a/src/xvmc/intel_batchbuffer.c b/src/xvmc/intel_batchbuffer.c index 080a939c..dd543300 100644 --- a/src/xvmc/intel_batchbuffer.c +++ b/src/xvmc/intel_batchbuffer.c @@ -19,6 +19,8 @@ #include "I915XvMC.h" #include "intel_batchbuffer.h" +#define MI_BATCH_BUFFER_END (0xA << 23) + int intelEmitIrqLocked(i915XvMCContext *pI915XvMC) { drmI830IrqEmit ie; @@ -56,7 +58,8 @@ void intelWaitIrq(i915XvMCContext *pI915XvMC, int seq) void intelDestroyBatchBuffer(i915XvMCContext *pI915XvMC) { if (pI915XvMC->alloc.offset) { - // FIXME: free the memory allocated from AGP + pI915XvMC->alloc.ptr = NULL; + pI915XvMC->alloc.offset = 0; } else if (pI915XvMC->alloc.ptr) { free(pI915XvMC->alloc.ptr); pI915XvMC->alloc.ptr = NULL; @@ -68,11 +71,17 @@ void intelDestroyBatchBuffer(i915XvMCContext *pI915XvMC) void intelInitBatchBuffer(i915XvMCContext *pI915XvMC) { - pI915XvMC->alloc.offset = 0; - pI915XvMC->alloc.size = 16 * 1024; - pI915XvMC->alloc.ptr = malloc(pI915XvMC->alloc.size); - pI915XvMC->alloc.active_buf = 0; + if (pI915XvMC->batchbuffer.map) { + pI915XvMC->alloc.size = pI915XvMC->batchbuffer.size; + pI915XvMC->alloc.offset = pI915XvMC->batchbuffer.offset; + pI915XvMC->alloc.ptr = pI915XvMC->batchbuffer.map; + } else { + pI915XvMC->alloc.size = 8 * 1024; + pI915XvMC->alloc.offset = 0; + pI915XvMC->alloc.ptr = malloc(pI915XvMC->alloc.size); + } + pI915XvMC->alloc.active_buf = 0; assert(pI915XvMC->alloc.ptr); } @@ -85,37 +94,33 @@ void intelBatchbufferRequireSpace(i915XvMCContext *pI915XvMC, unsigned sz) void intelBatchbufferData(i915XvMCContext *pI915XvMC, const void *data, unsigned bytes, unsigned flags) { - int extra = 0; - assert((bytes & 0x3) == 0); - if (bytes & 0x7) - extra = 1; - - intelBatchbufferRequireSpace(pI915XvMC, bytes + extra << 2); + intelBatchbufferRequireSpace(pI915XvMC, bytes); memcpy(pI915XvMC->batch.ptr, data, bytes); pI915XvMC->batch.ptr += bytes; pI915XvMC->batch.space -= bytes; - if (extra) { - *(int *)(pI915XvMC->batch.ptr) = 0; - pI915XvMC->batch.ptr += 4; - pI915XvMC->batch.space -= 4; - } - assert(pI915XvMC->batch.space >= 0); } +#define MI_FLUSH ((0 << 29) | (4 << 23)) +#define FLUSH_MAP_CACHE (1 << 0) +#define FLUSH_RENDER_CACHE (0 << 2) +#define FLUSH_WRITE_DIRTY_STATE (1 << 4) void intelRefillBatchLocked(i915XvMCContext *pI915XvMC, Bool allow_unlock ) { - unsigned last_irq = pI915XvMC->alloc.irq_emitted; unsigned half = pI915XvMC->alloc.size >> 1; unsigned buf = (pI915XvMC->alloc.active_buf ^= 1); + unsigned dword[2]; + dword[0] = MI_FLUSH | FLUSH_WRITE_DIRTY_STATE | FLUSH_RENDER_CACHE | FLUSH_MAP_CACHE; + dword[1] = 0; + intelCmdIoctl(pI915XvMC, (char *)&dword[0], sizeof(dword)); pI915XvMC->alloc.irq_emitted = intelEmitIrqLocked(pI915XvMC); - if (last_irq) { - intelWaitIrq(pI915XvMC, last_irq); + if (pI915XvMC->alloc.irq_emitted) { + intelWaitIrq(pI915XvMC, pI915XvMC->alloc.irq_emitted); } pI915XvMC->batch.start_offset = pI915XvMC->alloc.offset + buf * half; @@ -143,7 +148,16 @@ void intelFlushBatchLocked(i915XvMCContext *pI915XvMC, batch.DR4 = 0; if (pI915XvMC->alloc.offset) { - // FIXME: MI_BATCH_BUFFER_END + if ((batch.used & 0x4) == 0) { + ((int *)pI915XvMC->batch.ptr)[0] = 0; + ((int *)pI915XvMC->batch.ptr)[1] = MI_BATCH_BUFFER_END; + batch.used += 0x8; + pI915XvMC->batch.ptr += 0x8; + } else { + ((int *)pI915XvMC->batch.ptr)[0] = MI_BATCH_BUFFER_END; + batch.used += 0x4; + pI915XvMC->batch.ptr += 0x4; + } } pI915XvMC->batch.start_offset += batch.used; @@ -165,7 +179,10 @@ void intelFlushBatchLocked(i915XvMCContext *pI915XvMC, assert(batch.start + batch.used <= pI915XvMC->alloc.offset + pI915XvMC->alloc.size); if (pI915XvMC->alloc.offset) { - // DRM_I830_BATCHBUFFER + if (drmCommandWrite(pI915XvMC->fd, DRM_I830_BATCHBUFFER, &batch, sizeof(batch))) { + fprintf(stderr, "DRM_I830_BATCHBUFFER: %d\n", -errno); + exit(1); + } } else { drmI830CmdBuffer cmd; cmd.buf = (char *)pI915XvMC->alloc.ptr + batch.start; |