summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorroot <root@xhh-bl32.(none)>2007-06-25 14:07:01 +0800
committerXiang, Haihao <haihao.xiang@intel.com>2007-07-19 17:28:35 +0800
commit8c249765ce788f8adb0325a8e3016a0eae74b13b (patch)
tree0ff5f618ea1128c665e27d07f7feb8c70708fe31
parent2b20b395541f786e4009211e4c56042257b8d114 (diff)
1. using batch buffer
2. implement macroblock_ipicture instruction 3. 16bit INTRA block
-rw-r--r--src/i830.h4
-rw-r--r--src/i830_memory.c29
-rw-r--r--src/i915_hwmc.c216
-rw-r--r--src/i915_hwmc.h15
-rw-r--r--src/xvmc/I915XvMC.c358
-rw-r--r--src/xvmc/I915XvMC.h22
-rw-r--r--src/xvmc/i915_structs.h7
-rw-r--r--src/xvmc/intel_batchbuffer.c61
8 files changed, 530 insertions, 182 deletions
diff --git a/src/i830.h b/src/i830.h
index 21497820..cde15ad6 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -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(&macroblock_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, &macroblock_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, &macroblock_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, &macroblock_array->macro_blocks[first_macroblock]);
+ i915_mc_load_sis_msb_buffers(context);
+ i915_mc_mpeg_set_origin(context, &macroblock_array->macro_blocks[first_macroblock]);
+
for (i = first_macroblock; i < (num_macroblocks + first_macroblock); i++) {
- mb = &macroblock_array->macro_blocks[i];
- i915_mc_mpeg_set_origin(context, mb);
- // &macroblock_array->macro_blocks[first_macroblock]);
+ mb = &macroblock_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;