Merge branch 'master' into drm-gem

This commit is contained in:
Eric Anholt 2008-06-05 14:57:18 -07:00
commit 432d07fb17
19 changed files with 477 additions and 388 deletions

View File

@ -36,6 +36,10 @@
#include <pciaccess.h>
#include <err.h>
#ifndef DEFFILEMODE
#define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) /* 0666*/
#endif
static void usage(void)
{
fprintf(stderr, "usage: bios_dumper <filename>\n");

View File

@ -491,6 +491,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* - new bits for i810
* - new register hwstam (mask)
*/
#define PWRCTXA 0x2088 /* 965GM+ only */
#define PWRCTX_EN (1<<0)
#define HWSTAM 0x2098 /* p290 */
#define IER 0x20a0 /* p291 */
#define IIR 0x20a4 /* p292 */
@ -528,7 +530,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#define FWATER_BLC 0x20d8
#define FWATER_BLC2 0x20dc
#define FWATER_BLC_SELF 0x20e0
#define MM_BURST_LENGTH 0x00700000
#define MM_FIFO_WATERMARK 0x0001F000
#define LM_BURST_LENGTH 0x00000700
@ -1152,6 +1153,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define RENCLK_GATE_D2 0x6208
#define RAMCLK_GATE_D 0x6210 /* CRL only */
#define DEUC 0x6214 /* CRL only */
/*
* This is a PCI config space register to manipulate backlight brightness
@ -1251,6 +1253,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define SDVO_CLOCK_OUTPUT_INVERT (1 << 18)
#define SDVOC_GANG_MODE (1 << 16)
#define SDVO_BORDER_ENABLE (1 << 7)
/** new with 965, default is to be set */
#define SDVO_VSYNC_ACTIVE_HIGH (1 << 4)
#define SDVO_HSYNC_ACTIVE_HIGH (1 << 3)
/** 915/945 only, read-only bit */
#define SDVOB_PCIE_CONCURRENCY (1 << 3)
#define SDVO_DETECTED (1 << 2)
/* Bits to be preserved when writing */
@ -2102,6 +2108,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define DSPARB 0x70030
#define DSPARB_CSTART_SHIFT 7
#define DSPARB_BSTART_SHIFT 0
#define DSPARB_BEND_SHIFT 9 /* on 855 */
#define DSPARB_AEND_SHIFT 0
#define DSPFW1 0x70034
#define DSPFW2 0x70038
#define DSPFW3 0x7003c

View File

@ -428,6 +428,8 @@ typedef struct _I830Rec {
i830_memory *logical_context;
i830_memory *power_context;
#ifdef XF86DRI
i830_memory *back_buffer;
i830_memory *third_buffer;
@ -557,10 +559,6 @@ typedef struct _I830Rec {
Bool StolenOnly;
Bool swfSaved;
uint32_t saveSWF0;
uint32_t saveSWF4;
Bool checkDevices;
/* Driver phase/state information */
@ -582,6 +580,7 @@ typedef struct _I830Rec {
enum backlight_control backlight_control_method;
uint32_t saveDSPARB;
uint32_t saveDSPACNTR;
uint32_t saveDSPBCNTR;
uint32_t savePIPEACONF;
@ -652,6 +651,10 @@ typedef struct _I830Rec {
uint32_t saveFBC_CONTROL2;
uint32_t saveFBC_CONTROL;
uint32_t saveFBC_FENCE_OFF;
uint32_t saveRENCLK_GATE_D1;
uint32_t saveRENCLK_GATE_D2;
uint32_t saveDSPCLK_GATE_D;
uint32_t saveRAMCLK_GATE_D;
enum last_3d *last_3d;
@ -775,6 +778,7 @@ void i830_free_memory(ScrnInfoPtr pScrn, i830_memory *mem);
extern long I830CheckAvailableMemory(ScrnInfoPtr pScrn);
Bool i830_allocate_2d_memory(ScrnInfoPtr pScrn);
Bool i830_allocate_texture_memory(ScrnInfoPtr pScrn);
Bool i830_allocate_pwrctx(ScrnInfoPtr pScrn);
Bool i830_allocate_3d_memory(ScrnInfoPtr pScrn);
#ifdef INTEL_XVMC
Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name,
@ -858,6 +862,14 @@ i830_get_transformed_coordinates_3d(int x, int y, PictTransformPtr transform,
void i830_enter_render(ScrnInfoPtr);
static inline void
i830_wait_ring_idle(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
I830WaitLpRing(pScrn, pI830->LpRing->mem->size - 8, 0);
}
static inline int i830_fb_compression_supported(I830Ptr pI830)
{
if (!IS_MOBILE(pI830))

View File

@ -201,7 +201,7 @@ I830Sync(ScrnInfoPtr pScrn)
ADVANCE_BATCH();
}
I830WaitLpRing(pScrn, pI830->LpRing->mem->size - 8, 0);
i830_wait_ring_idle(pScrn);
pI830->LpRing->space = pI830->LpRing->mem->size - 8;
pI830->nextColorExpandBuf = 0;

View File

@ -546,10 +546,6 @@ static struct i830SnapshotRec {
DEFINEREG(FBC_FENCE_OFF),
DEFINEREG(FBC_MOD_NUM),
DEFINEREG(FWATER_BLC),
DEFINEREG(FWATER_BLC2),
DEFINEREG(FWATER_BLC_SELF),
DEFINEREG2(FPA0, i830_debug_fp),
DEFINEREG2(FPA1, i830_debug_fp),
DEFINEREG2(DPLL_A, i830_debug_dpll),

View File

@ -241,13 +241,15 @@ static void intel_clock(I830Ptr pI830, int refclk, intel_clock_t *clock)
}
static void
i830PrintPll(char *prefix, intel_clock_t *clock)
i830PrintPll(ScrnInfoPtr pScrn, char *prefix, intel_clock_t *clock)
{
ErrorF("%s: dotclock %d vco %d ((m %d, m1 %d, m2 %d), n %d, (p %d, p1 %d, p2 %d))\n",
prefix, clock->dot, clock->vco,
clock->m, clock->m1, clock->m2,
clock->n,
clock->p, clock->p1, clock->p2);
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"%s: dotclock %d vco %d ((m %d, m1 %d, m2 %d), n %d, "
"(p %d, p1 %d, p2 %d))\n",
prefix, clock->dot, clock->vco,
clock->m, clock->m1, clock->m2,
clock->n,
clock->p, clock->p1, clock->p2);
}
/**
@ -1077,6 +1079,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
int dspstride_reg = (plane == 0) ? DSPASTRIDE : DSPBSTRIDE;
int dsppos_reg = (plane == 0) ? DSPAPOS : DSPBPOS;
int dspsize_reg = (plane == 0) ? DSPASIZE : DSPBSIZE;
int pipestat_reg = (pipe == 0) ? PIPEASTAT : PIPEBSTAT;
int i;
int refclk;
intel_clock_t clock;
@ -1267,7 +1270,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
"Adjusted mode for pipe %c:\n", pipe == 0 ? 'A' : 'B');
xf86PrintModeline(pScrn->scrnIndex, adjusted_mode);
}
i830PrintPll("chosen", &clock);
i830PrintPll(pScrn, "chosen", &clock);
}
if (dpll & DPLL_VCO_ENABLE)
@ -1376,6 +1379,9 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
#endif
i830WaitForVblank(pScrn);
/* Clear any FIFO underrun status that may have occurred normally */
OUTREG(pipestat_reg, INREG(pipestat_reg) | FIFO_UNDERRUN);
}
@ -1760,7 +1766,7 @@ i830_crtc_clock_get(ScrnInfoPtr pScrn, xf86CrtcPtr crtc)
* configuration being accurate, which it isn't necessarily.
*/
if (0)
i830PrintPll("probed", &clock);
i830PrintPll(pScrn, "probed", &clock);
return clock.dot;
}

View File

@ -692,11 +692,6 @@ I830MapMem(ScrnInfoPtr pScrn)
(void **) &pI830->FbBase);
if (err)
return FALSE;
/* KLUDGE ALERT -- rewrite the PTEs to turn off the CD and WT bits */
#if HAVE_MPROTECT
mprotect (pI830->FbBase, pI830->FbMapSize, PROT_NONE);
mprotect (pI830->FbBase, pI830->FbMapSize, PROT_READ|PROT_WRITE);
#endif
#else
pI830->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
pI830->PciTag,
@ -934,6 +929,53 @@ I830SetupOutputs(ScrnInfoPtr pScrn)
}
}
static void
i830_init_clock_gating(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
/* Disable clock gating reported to work incorrectly according to the specs.
*/
if (IS_IGD_GM(pI830)) {
OUTREG(RENCLK_GATE_D1, 0);
OUTREG(RENCLK_GATE_D2, 0);
OUTREG(RAMCLK_GATE_D, 0);
OUTREG(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE |
OVRUNIT_CLOCK_GATE_DISABLE |
OVCUNIT_CLOCK_GATE_DISABLE);
} else if (IS_I965GM(pI830)) {
OUTREG(RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE);
OUTREG(RENCLK_GATE_D2, 0);
OUTREG(DSPCLK_GATE_D, 0);
OUTREG(RAMCLK_GATE_D, 0);
OUTREG16(DEUC, 0);
} else if (IS_I965G(pI830)) {
OUTREG(RENCLK_GATE_D1, I965_RCZ_CLOCK_GATE_DISABLE |
I965_RCC_CLOCK_GATE_DISABLE |
I965_RCPB_CLOCK_GATE_DISABLE |
I965_ISC_CLOCK_GATE_DISABLE |
I965_FBC_CLOCK_GATE_DISABLE);
OUTREG(RENCLK_GATE_D2, 0);
} else if (IS_I855(pI830) || IS_I865G(pI830)) {
OUTREG(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE);
} else if (IS_I830(pI830)) {
OUTREG(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE);
}
}
static void
i830_init_bios_control(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
/* Set "extended desktop" */
OUTREG(SWF0, INREG(SWF0) | (1 << 21));
/* Set "driver loaded", "OS unknown", "APM 1.2" */
OUTREG(SWF4, (INREG(SWF4) & ~((3 << 19) | (7 << 16))) |
(1 << 23) | (2 << 16));
}
static int
I830LVDSPresent(ScrnInfoPtr pScrn)
{
@ -992,10 +1034,6 @@ PreInitCleanup(ScrnInfoPtr pScrn)
if (pI830->entityPrivate)
pI830->entityPrivate->pScrn_2 = NULL;
}
if (pI830->swfSaved) {
OUTREG(SWF0, pI830->saveSWF0);
OUTREG(SWF4, pI830->saveSWF4);
}
if (pI830->MMIOBase)
I830UnmapMMIO(pScrn);
I830FreeRec(pScrn);
@ -1461,19 +1499,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
i830TakeRegSnapshot(pScrn);
#if 1
pI830->saveSWF0 = INREG(SWF0);
pI830->saveSWF4 = INREG(SWF4);
pI830->swfSaved = TRUE;
/* Set "extended desktop" */
OUTREG(SWF0, pI830->saveSWF0 | (1 << 21));
/* Set "driver loaded", "OS unknown", "APM 1.2" */
OUTREG(SWF4, (pI830->saveSWF4 & ~((3 << 19) | (7 << 16))) |
(1 << 23) | (2 << 16));
#endif
if (DEVICE_ID(pI830->PciInfo) == PCI_CHIP_E7221_G)
num_pipe = 1;
else
@ -1708,12 +1733,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
pI830->noAccel = TRUE;
}
/* Don't need MMIO access anymore. */
if (pI830->swfSaved) {
OUTREG(SWF0, pI830->saveSWF0);
OUTREG(SWF4, pI830->saveSWF4);
}
/* Set display resolution */
xf86SetDpi(pScrn, 0, 0);
@ -1820,7 +1839,6 @@ i830_stop_ring(ScrnInfoPtr pScrn, Bool flush)
if (temp & RING_VALID) {
i830_refresh_ring(pScrn);
I830Sync(pScrn);
DO_RING_IDLE();
}
OUTREG(LP_RING + RING_LEN, 0);
@ -1890,37 +1908,48 @@ i830_refresh_ring(ScrnInfoPtr pScrn)
i830MarkSync(pScrn);
}
/*
* This should be called everytime the X server gains control of the screen,
* before any video modes are programmed (ScreenInit, EnterVT).
/**
* Sets up the DSPARB register to split the display fifo appropriately between
* the display planes.
*
* Adjusting this register requires that the planes be off, thus as a side
* effect they are disabled by this function.
*/
static void
SetHWOperatingState(ScrnInfoPtr pScrn)
i830_set_dsparb(ScrnInfoPtr pScrn)
{
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
I830Ptr pI830 = I830PTR(pScrn);
int i;
DPRINTF(PFX, "SetHWOperatingState\n");
/* Disable clock gating reported to work incorrectly according to the specs.
/* Disable outputs & pipes since DSPARB can only be updated when they're
* off.
*/
if (IS_IGD_GM(pI830)) {
OUTREG(RENCLK_GATE_D1, 0);
OUTREG(RENCLK_GATE_D2, 0);
OUTREG(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE);
} else if (IS_I965GM(pI830)) {
OUTREG(RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE);
} else if (IS_I965G(pI830)) {
OUTREG(RENCLK_GATE_D1,
I965_RCC_CLOCK_GATE_DISABLE | I965_ISC_CLOCK_GATE_DISABLE);
} else if (IS_I855(pI830) || IS_I865G(pI830)) {
OUTREG(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE);
} else if (IS_I830(pI830)) {
OUTREG(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE);
for (i = 0; i < xf86_config->num_output; i++) {
xf86OutputPtr output = xf86_config->output[i];
output->funcs->dpms(output, DPMSModeOff);
}
i830WaitForVblank(pScrn);
for (i = 0; i < xf86_config->num_crtc; i++) {
xf86CrtcPtr crtc = xf86_config->crtc[i];
crtc->funcs->dpms(crtc, DPMSModeOff);
}
i830WaitForVblank(pScrn);
i830_start_ring(pScrn);
if (!pI830->SWCursor)
I830InitHWCursor(pScrn);
/* Fixup FIFO defaults:
* we don't use plane C at all so we can allocate all but one of the 96
* FIFO RAM entries equally between planes A and B.
*/
if (IS_I9XX(pI830)) {
if (IS_I965GM(pI830) || IS_IGD_GM(pI830))
OUTREG(DSPARB, (127 << DSPARB_CSTART_SHIFT) |
(64 << DSPARB_BSTART_SHIFT));
else
OUTREG(DSPARB, (95 << DSPARB_CSTART_SHIFT) |
(48 << DSPARB_BSTART_SHIFT));
} else {
OUTREG(DSPARB, 254 << DSPARB_BEND_SHIFT | 128 << DSPARB_AEND_SHIFT);
}
}
enum pipe {
@ -1987,6 +2016,8 @@ SaveHWState(ScrnInfoPtr pScrn)
}
/* Save video mode information for native mode-setting. */
pI830->saveDSPARB = INREG(DSPARB);
pI830->saveDSPACNTR = INREG(DSPACNTR);
pI830->savePIPEACONF = INREG(PIPEACONF);
pI830->savePIPEASRC = INREG(PIPEASRC);
@ -2060,6 +2091,14 @@ SaveHWState(ScrnInfoPtr pScrn)
pI830->saveSWF[15] = INREG(SWF31);
pI830->saveSWF[16] = INREG(SWF32);
pI830->saveDSPCLK_GATE_D = INREG(DSPCLK_GATE_D);
pI830->saveRENCLK_GATE_D1 = INREG(RENCLK_GATE_D1);
if (IS_I965G(pI830)) {
pI830->saveRENCLK_GATE_D2 = INREG(RENCLK_GATE_D2);
pI830->saveRAMCLK_GATE_D = INREG(RAMCLK_GATE_D);
}
if (IS_MOBILE(pI830) && !IS_I830(pI830))
pI830->saveLVDS = INREG(LVDS);
pI830->savePFIT_CONTROL = INREG(PFIT_CONTROL);
@ -2117,6 +2156,15 @@ RestoreHWState(ScrnInfoPtr pScrn)
if (!IS_I830(pI830) && !IS_845G(pI830))
OUTREG(PFIT_CONTROL, pI830->savePFIT_CONTROL);
OUTREG(DSPARB, pI830->saveDSPARB);
OUTREG(DSPCLK_GATE_D, pI830->saveDSPCLK_GATE_D);
OUTREG(RENCLK_GATE_D1, pI830->saveRENCLK_GATE_D1);
if (IS_I965G(pI830)) {
OUTREG(RENCLK_GATE_D2, pI830->saveRENCLK_GATE_D2);
OUTREG(RAMCLK_GATE_D, pI830->saveRAMCLK_GATE_D);
}
/*
* Pipe regs
* To restore the saved state, we first need to program the PLL regs,
@ -2294,6 +2342,10 @@ RestoreHWState(ScrnInfoPtr pScrn)
OUTREG(FBC_CONTROL, pI830->saveFBC_CONTROL);
}
/* Clear any FIFO underrun status that may have occurred normally */
OUTREG(PIPEASTAT, INREG(PIPEASTAT) | FIFO_UNDERRUN);
OUTREG(PIPEBSTAT, INREG(PIPEBSTAT) | FIFO_UNDERRUN);
vgaHWRestore(pScrn, vgaReg, VGA_SR_FONTS);
vgaHWLock(hwp);
@ -2443,6 +2495,22 @@ I830BlockHandler(int i,
if (pScrn->vtSema && !pI830->noAccel && !pI830->directRenderingEnabled)
I830EmitFlush(pScrn);
/*
* Check for FIFO underruns at block time (which amounts to just
* periodically). If this happens, it means our DSPARB or some other
* memory arbitration setting is wrong for the current configuration
* (except for mode setting, where it may occur naturally).
* Check & ack the condition.
*/
if (INREG(PIPEASTAT) & FIFO_UNDERRUN) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "underrun on pipe A!\n");
OUTREG(PIPEASTAT, INREG(PIPEASTAT) | FIFO_UNDERRUN);
}
if (INREG(PIPEBSTAT) & FIFO_UNDERRUN) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "underrun on pipe B!\n");
OUTREG(PIPEBSTAT, INREG(PIPEBSTAT) | FIFO_UNDERRUN);
}
I830VideoBlockHandler(i, blockData, pTimeout, pReadmask);
}
@ -2504,6 +2572,10 @@ i830_try_memory_allocation(ScrnInfoPtr pScrn)
if (!i830_allocate_2d_memory(pScrn))
goto failed;
if (IS_I965GM(pI830) || IS_IGD_GM(pI830))
if (!i830_allocate_pwrctx(pScrn))
goto failed;
if (dri && !i830_allocate_3d_memory(pScrn))
goto failed;
@ -2762,8 +2834,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
}
/* Enable FB compression if possible */
if (i830_fb_compression_supported(pI830) && !IS_I965GM(pI830)
&& !IS_IGD_GM(pI830))
if (i830_fb_compression_supported(pI830))
pI830->fb_compression = TRUE;
else
pI830->fb_compression = FALSE;
@ -2825,6 +2896,9 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
return FALSE;
}
if (pI830->power_context)
OUTREG(PWRCTXA, pI830->power_context->offset | PWRCTX_EN);
I830UnmapMMIO(pScrn);
i830_fixup_mtrrs(pScrn);
@ -3102,20 +3176,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
if (serverGeneration == 1)
xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
if (IS_I965G(pI830)) {
/* turn off clock gating */
#if 0
OUTREG(0x6204, 0x70804000);
OUTREG(0x6208, 0x00000001);
#else
OUTREG(0x6204, 0x70000000);
#endif
/* Enable DAP stateless accesses.
* Required for all i965 steppings.
*/
OUTREG(SVG_WORK_CTL, 0x00000010);
}
pI830->starting = FALSE;
pI830->closing = FALSE;
pI830->suspended = FALSE;
@ -3296,7 +3356,19 @@ I830EnterVT(int scrnIndex, int flags)
}
i830_stop_ring(pScrn, FALSE);
SetHWOperatingState(pScrn);
i830_start_ring(pScrn);
if (!pI830->SWCursor)
I830InitHWCursor(pScrn);
/* Set the DSPARB register. This disables the outputs, which is about to
* happen (likely) in xf86SetDesiredModes anyway.
*/
i830_set_dsparb(pScrn);
/* Tell the BIOS that we're in control of mode setting now. */
i830_init_bios_control(pScrn);
i830_init_clock_gating(pScrn);
/* Clear the framebuffer */
memset(pI830->FbBase + pScrn->fbOffset, 0,
@ -3311,9 +3383,6 @@ I830EnterVT(int scrnIndex, int flags)
}
i830DescribeOutputConfiguration(pScrn);
i830_stop_ring(pScrn, TRUE);
SetHWOperatingState(pScrn);
#ifdef XF86DRI
if (pI830->directRenderingEnabled) {
/* HW status is fixed, we need to set it up before any drm
@ -3346,10 +3415,9 @@ I830EnterVT(int scrnIndex, int flags)
int i;
I830DRIResume(screenInfo.screens[scrnIndex]);
i830_refresh_ring(pScrn);
I830Sync(pScrn);
DO_RING_IDLE();
sarea->texAge++;
for(i = 0; i < I830_NR_TEX_REGIONS+1 ; i++)
@ -3449,6 +3517,9 @@ I830CloseScreen(int scrnIndex, ScreenPtr pScreen)
}
#endif
if (IS_I965GM(pI830) || IS_IGD_GM(pI830))
OUTREG(PWRCTXA, 0);
if (I830IsPrimary(pScrn)) {
xf86GARTCloseScreen(scrnIndex);

View File

@ -116,6 +116,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/* Our hardware status area is just a single page */
#define HWSTATUS_PAGE_SIZE GTT_PAGE_SIZE
#define PWRCTX_SIZE GTT_PAGE_SIZE
static i830_memory *
i830_allocate_aperture(ScrnInfoPtr pScrn, const char *name,
@ -341,6 +342,7 @@ i830_reset_allocations(ScrnInfoPtr pScrn)
pI830->gen4_render_state_mem = NULL;
pI830->overlay_regs = NULL;
pI830->logical_context = NULL;
pI830->power_context = NULL;
#ifdef XF86DRI
pI830->back_buffer = NULL;
pI830->third_buffer = NULL;
@ -1659,6 +1661,22 @@ i830_allocate_hwstatus(ScrnInfoPtr pScrn)
return TRUE;
}
Bool
i830_allocate_pwrctx(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
pI830->power_context = i830_allocate_memory(pScrn, "power context",
PWRCTX_SIZE, GTT_PAGE_SIZE,
NEED_LIFETIME_FIXED);
if (!pI830->power_context) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Failed to allocate power context.\n");
return FALSE;
}
return TRUE;
}
Bool
i830_allocate_3d_memory(ScrnInfoPtr pScrn)
{

View File

@ -75,28 +75,13 @@ union intfloat {
pI830->ring_emitting = 0; \
} while (0)
/*
* XXX Note: the head/tail masks are different for 810 and i830.
* If the i810 always sets the higher bits to 0, then this shouldn't be
* a problem. Check this!
*/
#define DO_RING_IDLE() do { \
int _head; \
int _tail; \
do { \
_head = INREG(LP_RING + RING_HEAD) & I830_HEAD_MASK; \
_tail = INREG(LP_RING + RING_TAIL) & I830_TAIL_MASK; \
DELAY(10); \
} while (_head != _tail); \
} while (0)
#define BEGIN_LP_RING(n) \
do { \
if (pI830->ring_emitting != 0) \
FatalError("%s: BEGIN_LP_RING called without closing " \
"ADVANCE_LP_RING\n", __FUNCTION__); \
if ((n) > 2 && (I810_DEBUG&DEBUG_ALWAYS_SYNC)) \
DO_RING_IDLE(); \
i830_wait_ring_idle(pScrn); \
pI830->ring_emitting = (n) * 4; \
if ((n) & 1) \
pI830->ring_emitting += 4; \

View File

@ -873,7 +873,9 @@ i830_sdvo_mode_set(xf86OutputPtr output, DisplayModePtr mode,
/* Set the SDVO control regs. */
if (IS_I965G(pI830)) {
sdvox = SDVO_BORDER_ENABLE;
sdvox = SDVO_BORDER_ENABLE |
SDVO_VSYNC_ACTIVE_HIGH |
SDVO_HSYNC_ACTIVE_HIGH;
} else {
sdvox = INREG(dev_priv->output_device);
switch (dev_priv->output_device) {

View File

@ -95,8 +95,6 @@ typedef struct _I915XvMC
PutImageFuncPtr savePutImage;
} I915XvMC, *I915XvMCPtr;
#define ARRARY_SIZE(a) (sizeof(a) / sizeof(a[0]))
/*
static int yv12_subpicture_index_list[2] =
{
@ -161,6 +159,22 @@ static XF86ImagePtr i915_subpicture_list[2] =
};
#endif
/* Check context size not exceed surface type max */
static void
i915_check_context_size(XvMCContextPtr ctx)
{
int i;
for (i = 0; i < ARRAY_SIZE(ppSI); i++) {
if (ctx->surface_type_id == ppSI[i]->surface_type_id) {
if (ctx->width > ppSI[i]->max_width)
ctx->width = ppSI[i]->max_width;
if (ctx->height > ppSI[i]->max_height)
ctx->height = ppSI[i]->max_height;
}
}
}
/*
* Init and clean up the screen private parts of XvMC.
*/
@ -430,6 +444,8 @@ static int i915_xvmc_create_context (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
return BadAlloc;
}
i915_check_context_size(pContext);
*priv = xcalloc(1, sizeof(I915XvMCCreateContextRec));
contextRec = (I915XvMCCreateContextRec *)*priv;
@ -776,10 +792,9 @@ static int i915_xvmc_put_image(ScrnInfoPtr pScrn,
struct intel_xvmc_command *xvmc_cmd = (struct intel_xvmc_command *)buf;
int ret;
if (pI830->XvMCEnabled) {
if (FOURCC_XVMC == id) {
switch (xvmc_cmd->command) {
case INTEL_XVMC_COMMAND_DISPLAY:
if (FOURCC_XVMC == id) {
switch (xvmc_cmd->command) {
case INTEL_XVMC_COMMAND_DISPLAY:
if ((xvmc_cmd->srfNo >= I915_XVMC_MAX_SURFACES) ||
!pXvMC->surfaces[xvmc_cmd->srfNo] ||
!pXvMC->sfprivs[xvmc_cmd->srfNo]) {
@ -793,10 +808,9 @@ static int i915_xvmc_put_image(ScrnInfoPtr pScrn,
id = xvmc_cmd->real_id;
pI830->IsXvMCSurface = 1;
break;
default:
return 0;
}
}
default:
return 0;
}
}
ret = pXvMC->savePutImage(pScrn, src_x, src_y, drw_x, drw_y, src_w, src_h,
@ -850,7 +864,7 @@ static void i915_xvmc_fini(ScrnInfoPtr pScrn)
static XF86MCAdaptorRec pAdapt =
{
.name = "Intel(R) Textured Video",
.num_surfaces = ARRARY_SIZE(ppSI),
.num_surfaces = ARRAY_SIZE(ppSI),
.surfaces = ppSI,
#if 0
.num_subpictures = ARRARY_SIZE(i915_subpicture_list),

View File

@ -32,7 +32,7 @@
#define STRIDE(w) (((w) + 0x3ff) & ~0x3ff)
#define SIZE_Y420(w, h) (h * STRIDE(w))
#define SIZE_UV420(w, h) ((h >> 1) * STRIDE(w >> 1))
#define SIZE_YUV420(w, h) (h * (STRIDE(w) + STRIDE(w >> 1)))
#define SIZE_YUV420(w, h) (SIZE_Y420(w,h) + SIZE_UV420(w,h) * 2)
#define SIZE_XX44(w, h) (h * STRIDE(w))
#define I915_NUM_XVMC_ATTRIBUTES 0x02

View File

@ -11,6 +11,7 @@ libI810XvMC_la_LIBADD = @DRI_LIBS@
libIntelXvMC_la_SOURCES = intel_xvmc.c \
intel_xvmc.h \
intel_xvmc_dump.c \
i915_structs.h \
i915_program.h \
i915_xvmc.c \
@ -19,9 +20,8 @@ libIntelXvMC_la_SOURCES = intel_xvmc.c \
intel_batchbuffer.h \
xf86dri.c \
xf86dri.h \
xf86dristr.h \
driDrawable.c \
driDrawable.h
xf86dristr.h
libIntelXvMC_la_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ @XVMCLIB_CFLAGS@ -I$(top_srcdir)/src -DTRUE=1 -DFALSE=0
libIntelXvMC_la_LDFLAGS = -version-number 1:0:0
libIntelXvMC_la_LIBADD = @DRI_LIBS@

View File

@ -1,174 +0,0 @@
/*****************************************************************************
* driDrawable.c: Lean Version of DRI utilities.
*
* Copyright (c) 2005 Thomas Hellstrom. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <X11/Xlibint.h>
#include <X11/Xutil.h>
#include "xf86drm.h"
#include "drm.h"
#include "xf86dri.h"
#include "drm_sarea.h"
#include "driDrawable.h"
static unsigned
drawStamp(volatile drm_sarea_t * pSarea, int index)
{
return pSarea->drawableTable[index].stamp;
}
int
getDRIDrawableInfoLocked(void *drawHash, Display * display, int screen,
Drawable draw, unsigned lockFlags, int drmFD, drm_context_t drmContext,
drmAddress sarea, Bool updateInfo, drawableInfo ** info,
unsigned long infoSize)
{
drawableInfo *drawInfo;
void *res;
drm_drawable_t drmDraw = 0;
volatile drm_sarea_t *pSarea = (drm_sarea_t *) sarea;
drm_clip_rect_t *clipFront, *clipBack;
int ret;
if (drmHashLookup(drawHash, (unsigned long)draw, &res)) {
/*
* The drawable is unknown to us. Create it and put it in the
* hash table.
*/
DRM_UNLOCK(drmFD, &pSarea->lock, drmContext);
if (!uniDRICreateDrawable(display, screen, draw, &drmDraw)) {
DRM_LOCK(drmFD, &pSarea->lock, drmContext, lockFlags);
return 1;
}
DRM_LOCK(drmFD, &pSarea->lock, drmContext, lockFlags);
drawInfo = (drawableInfo *) malloc(infoSize);
if (!drawInfo)
return 1;
drawInfo->drmDraw = drmDraw;
drawInfo->stamp = 0;
drawInfo->clipFront = 0;
drawInfo->clipBack = 0;
drmHashInsert(drawHash, (unsigned long)draw, drawInfo);
} else {
drawInfo = res;
}
drawInfo->touched = FALSE;
while (!drawInfo->clipFront
|| drawInfo->stamp != drawStamp(pSarea, drawInfo->index)) {
/*
* The drawable has been touched since we last got info about it.
* obtain new info from the X server.
*/
drawInfo->touched = TRUE;
if (updateInfo || !drawInfo->clipFront) {
DRM_UNLOCK(drmFD, &pSarea->lock, drmContext);
ret = uniDRIGetDrawableInfo(display, screen, draw,
&drawInfo->index, &drawInfo->stamp, &drawInfo->x,
&drawInfo->y, &drawInfo->w, &drawInfo->h,
&drawInfo->numClipFront, &clipFront,
&drawInfo->backX, &drawInfo->backY,
&drawInfo->numClipBack, &clipBack);
DRM_LIGHT_LOCK(drmFD, &pSarea->lock, drmContext);
/*
* Error. Probably the drawable is destroyed. Return error and old values.
*/
if (!ret) {
free(drawInfo);
drawInfo = NULL;
drmHashDelete(drawHash, (unsigned long)draw);
DRM_UNLOCK(drmFD, &pSarea->lock, drmContext);
uniDRIDestroyDrawable(display, screen, draw);
DRM_LOCK(drmFD, &pSarea->lock, drmContext, lockFlags);
return 1;
}
if (drawInfo->stamp != drawStamp(pSarea, drawInfo->index)) {
/*
* The info is already outdated. Sigh. Have another go.
*/
XFree(clipFront);
XFree(clipBack);
continue;
}
if (drawInfo->clipFront)
XFree(drawInfo->clipFront);
drawInfo->clipFront = clipFront;
if (drawInfo->clipBack)
XFree(drawInfo->clipBack);
drawInfo->clipBack = clipBack;
} else {
if (!drawInfo->clipFront)
drawInfo->clipFront = (drm_clip_rect_t *) ~ 0UL;
drawInfo->stamp = drawStamp(pSarea, drawInfo->index);
}
}
*info = drawInfo;
return 0;
}
void
driDestroyHashContents(void *drawHash)
{
unsigned long key;
void *content;
drawableInfo *drawInfo;
if (drmHashFirst(drawHash, &key, &content) < 1)
return;
drawInfo = (drawableInfo *) content;
if (drawInfo->clipBack)
XFree(drawInfo->clipBack);
if (drawInfo->clipFront)
XFree(drawInfo->clipFront);
free(drawInfo);
while (drmHashNext(drawHash, &key, &content) == 1) {
drawInfo = (drawableInfo *) content;
if (drawInfo->clipBack)
XFree(drawInfo->clipBack);
if (drawInfo->clipFront)
XFree(drawInfo->clipFront);
free(drawInfo);
}
return;
}

View File

@ -1,64 +0,0 @@
/*****************************************************************************
* driDrawable.h: Lean Version of DRI utilities.
*
* Copyright (c) 2005 Thomas Hellstrom. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _DRIDRAWABLE_H
#define _DRIDRAWABLE_H
typedef struct _drawableInfo
{
drm_drawable_t drmDraw;
unsigned stamp;
unsigned index;
drm_clip_rect_t *clipFront;
drm_clip_rect_t *clipBack;
int x;
int y;
int w;
int h;
int backX;
int backY;
int numClipFront;
int numClipBack;
Bool touched;
} drawableInfo;
/*
* Get updated info about the drawable "draw". The drawableInfo record returned is malloced
* and administrated internally. Never free it unless you know exactly what you are doing.
* The drm hash table "drawHash" needs to be initialized externally.
*/
extern int
getDRIDrawableInfoLocked(void *drawHash, Display * display, int screen,
Drawable draw, unsigned lockFlags, int drmFD, drm_context_t drmContext,
drmAddress sarea, Bool updateInfo, drawableInfo ** info,
unsigned long infoSize);
/*
* Free all resources created by the above function. Typically done on exit.
*/
extern void driDestroyHashContents(void *drawHash);
#endif

View File

@ -38,18 +38,6 @@
#define VOFFSET(surface) (surface->srf.offset + \
SIZE_Y420(surface->width, surface->height))
/* Lookup tables to speed common calculations */
static unsigned int mb_bytes[] = {
000, 128, 128, 256, 128, 256, 256, 384, // 0
128, 256, 256, 384, 256, 384, 384, 512, // 1
128, 256, 256, 384, 256, 384, 384, 512, // 10
256, 384, 384, 512, 384, 512, 512, 640, // 11
128, 256, 256, 384, 256, 384, 384, 512, // 100
256, 384, 384, 512, 384, 512, 512, 640, // 101
256, 384, 384, 512, 384, 512, 512, 640, // 110
384, 512, 512, 640, 512, 640, 640, 768 // 111
};
typedef union {
short s[4];
uint u[2];
@ -1608,9 +1596,6 @@ static void i915_release_resource(Display *display, XvMCContext *context)
pI915XvMC->ref--;
i915_xvmc_unmap_buffers(pI915XvMC);
driDestroyHashContents(pI915XvMC->drawHash);
drmHashDestroy(pI915XvMC->drawHash);
free(pI915XvMC);
context->privData = NULL;
}
@ -1683,13 +1668,6 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
pSAREA = (drm_sarea_t *)xvmc_driver->sarea_address;
pI915XvMC->sarea = (drmI830Sarea*)((char*)pSAREA + pI915XvMC->sarea_priv_offset);
if (NULL == (pI915XvMC->drawHash = drmHashCreate())) {
XVMC_ERR("Could not allocate drawable hash table.");
free(pI915XvMC);
context->privData = NULL;
return BadAlloc;
}
if (i915_xvmc_map_buffers(pI915XvMC)) {
i915_xvmc_unmap_buffers(pI915XvMC);
free(pI915XvMC);
@ -1941,7 +1919,7 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
XVMC_INFO("no coded blocks present!");
}
bspm = mb_bytes[mb->coded_block_pattern];
bspm = mb_bytes_420[mb->coded_block_pattern];
if (!bspm)
continue;
@ -1997,7 +1975,7 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
XVMC_ERR("Invalid Macroblock Parameters found.");
break;
}
} else { /* Frame Picture */
} else { /* Field Picture */
switch (mb->motion_type & 3) {
case XVMC_PREDICTION_FIELD: /* Field Based */
i915_mc_mpeg_macroblock_1fbmv(context, mb);
@ -2015,7 +1993,7 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
XVMC_ERR("Invalid Macroblock Parameters found.");
break;
}
} /* Field Picture */
}
}
intelFlushBatch(TRUE);

View File

@ -26,7 +26,78 @@
*/
#include "intel_xvmc.h"
/* global */
struct _intel_xvmc_driver *xvmc_driver = NULL;
/* Lookup tables to speed common calculations for coded_block_pattern */
/* each block is ((8*8) * sizeof(short)) */
unsigned int mb_bytes_420[] = {
0, /* 0 */
128, /* 1 */
128, /* 10 */
256, /* 11 */
128, /* 100 */
256, /* 101 */
256, /* 110 */
384, /* 111 */
128, /* 1000 */
256, /* 1001 */
256, /* 1010 */
384, /* 1011 */
256, /* 1100 */
384, /* 1101 */
384, /* 1110 */
512, /* 1111 */
128, /* 10000 */
256, /* 10001 */
256, /* 10010 */
384, /* 10011 */
256, /* 10100 */
384, /* 10101 */
384, /* 10110 */
512, /* 10111 */
256, /* 11000 */
384, /* 11001 */
384, /* 11010 */
512, /* 11011 */
384, /* 11100 */
512, /* 11101 */
512, /* 11110 */
640, /* 11111 */
128, /* 100000 */
256, /* 100001 */
256, /* 100010 */
384, /* 100011 */
256, /* 100100 */
384, /* 100101 */
384, /* 100110 */
512, /* 100111 */
256, /* 101000 */
384, /* 101001 */
384, /* 101010 */
512, /* 101011 */
384, /* 101100 */
512, /* 101101 */
512, /* 101110 */
640, /* 101111 */
256, /* 110000 */
384, /* 110001 */
384, /* 110010 */
512, /* 110011 */
384, /* 110100 */
512, /* 110101 */
512, /* 110110 */
640, /* 110111 */
384, /* 111000 */
512, /* 111001 */
512, /* 111010 */
640, /* 111011 */
512, /* 111100 */
640, /* 111101 */
640, /* 111110 */
768 /* 111111 */
};
static int error_base;
static int event_base;
@ -360,6 +431,8 @@ Status XvMCCreateContext(Display *display, XvPortID port,
intelInitBatchBuffer();
intel_xvmc_dump_open();
return Success;
}
@ -407,6 +480,8 @@ Status XvMCDestroyContext(Display *display, XvMCContext *context)
xvmc_driver->fd = -1;
intelFiniBatchBuffer();
intel_xvmc_dump_close();
}
return Success;
}
@ -595,6 +670,10 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
if (!target_surface)
return XvMCBadSurface;
intel_xvmc_dump_render(context, picture_structure, target_surface,
past_surface, future_surface, flags, num_macroblocks,
first_macroblock, macroblock_array, blocks);
ret = (xvmc_driver->render_surface)(display, context, picture_structure,
target_surface, past_surface, future_surface, flags,
num_macroblocks, first_macroblock, macroblock_array,

View File

@ -53,7 +53,6 @@
#include <drm_sarea.h>
#include "xf86dri.h"
#include "driDrawable.h"
#include "intel_batchbuffer.h"
@ -250,4 +249,15 @@ static inline const char* intel_xvmc_decoder_string(int flag)
extern intel_xvmc_context_ptr intel_xvmc_find_context(XID id);
extern intel_xvmc_surface_ptr intel_xvmc_find_surface(XID id);
extern unsigned int mb_bytes_420[64];
/* dump function */
extern void intel_xvmc_dump_open(void);
extern void intel_xvmc_dump_close(void);
extern void intel_xvmc_dump_render(XvMCContext *context, unsigned int picture_structure,
XvMCSurface *target_surface, XvMCSurface *past_surface,
XvMCSurface *future_surface, unsigned int flags,
unsigned int num_macroblocks, unsigned int first_macroblock,
XvMCMacroBlockArray *macroblock_array, XvMCBlockArray *blocks);
#endif

142
src/xvmc/intel_xvmc_dump.c Normal file
View File

@ -0,0 +1,142 @@
/*
* Copyright © 2008 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Authors:
* Zhenyu Wang <zhenyu.z.wang@intel.com>
*
*/
#include "intel_xvmc.h"
#define DUMPFILE "./intel_xvmc_dump"
static int xvmc_dump = 0;
static FILE *fp = NULL;
void intel_xvmc_dump_open(void)
{
char *d = NULL;
if (xvmc_dump)
return;
if (d = getenv("INTEL_XVMC_DUMP"))
xvmc_dump = 1;
if (xvmc_dump) {
fp = fopen(DUMPFILE, "a");
if (!fp)
xvmc_dump = 0;
}
}
void intel_xvmc_dump_close(void)
{
if (xvmc_dump) {
fclose(fp);
xvmc_dump = 0;
}
}
void intel_xvmc_dump_render(XvMCContext *context, unsigned int picture_structure,
XvMCSurface *target, XvMCSurface *past, XvMCSurface *future, unsigned int flags,
unsigned int num_macroblocks, unsigned int first_macroblock,
XvMCMacroBlockArray *macroblock_array, XvMCBlockArray *blocks)
{
int i;
XvMCMacroBlock *mb;
if (!xvmc_dump)
return;
fprintf(fp, "========== new surface rendering ==========\n");
fprintf(fp, "Context (id:%d) (surface_type_id:%d) (width:%d) (height:%d)\n",
context->context_id, context->surface_type_id, context->width, context->height);
if (picture_structure == XVMC_FRAME_PICTURE)
fprintf(fp, "picture structure: frame picture\n");
else if (picture_structure == XVMC_TOP_FIELD)
fprintf(fp, "picture structure: top field picture (%s)\n",
(flags == XVMC_SECOND_FIELD)?"second":"first");
else if (picture_structure == XVMC_BOTTOM_FIELD)
fprintf(fp, "picture structure: bottom field picture (%s)\n",
(flags == XVMC_SECOND_FIELD)?"second":"first");
if (!past && !future)
fprintf(fp, "picture type: I\n");
else if (past && !future)
fprintf(fp, "picture type: P\n");
else if (past && future)
fprintf(fp, "picture type: B\n");
else
fprintf(fp, "picture type: Bad!\n");
fprintf(fp, "target picture: id (%d) width (%d) height (%d)\n", target->surface_id,
target->width, target->height);
if (past)
fprintf(fp, "past picture: id (%d) width (%d) height (%d)\n", past->surface_id,
past->width, past->height);
if (future)
fprintf(fp, "future picture: id (%d) width (%d) height (%d)\n", future->surface_id,
future->width, future->height);
fprintf(fp, "num macroblocks: %d, first macroblocks %d\n", num_macroblocks, first_macroblock);
for (i = first_macroblock; i < (first_macroblock + num_macroblocks); i++) {
mb = &macroblock_array->macro_blocks[i];
fprintf(fp, "- MB(%d): ", i);
fprintf(fp, "x (%d) y (%d) ", mb->x, mb->y);
fprintf(fp, "macroblock type (");
if (mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD)
fprintf(fp, "motion_forward ");
if (mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD)
fprintf(fp, "motion_backward ");
if (mb->macroblock_type & XVMC_MB_TYPE_PATTERN)
fprintf(fp, "pattern ");
if (mb->macroblock_type & XVMC_MB_TYPE_INTRA)
fprintf(fp, "intra ");
fprintf(fp, ") ");
fprintf(fp, "mc type ");
if (mb->motion_type & XVMC_PREDICTION_FIELD)
fprintf(fp, "(field) ");
else if (mb->motion_type & XVMC_PREDICTION_FRAME)
fprintf(fp, "(frame) ");
else if (mb->motion_type & XVMC_PREDICTION_DUAL_PRIME)
fprintf(fp, "(dual-prime) ");
else if (mb->motion_type & XVMC_PREDICTION_16x8)
fprintf(fp, "(16x8) ");
else if (mb->motion_type & XVMC_PREDICTION_4MV)
fprintf(fp, "(4MV) ");
else
fprintf(fp, "(none) ");
if (mb->dct_type == XVMC_DCT_TYPE_FRAME)
fprintf(fp, "dct type (frame) ");
else if (mb->dct_type == XVMC_DCT_TYPE_FIELD)
fprintf(fp, "dct type (field) ");
fprintf(fp, "coded_block_pattern (0x%x)\n", mb->coded_block_pattern);
/* XXX mv dump */
}
}