diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/bios_reader/bios_dumper.c | 4 | ||||
-rw-r--r-- | src/i810_reg.h | 12 | ||||
-rw-r--r-- | src/i830.h | 20 | ||||
-rw-r--r-- | src/i830_accel.c | 2 | ||||
-rw-r--r-- | src/i830_debug.c | 4 | ||||
-rw-r--r-- | src/i830_display.c | 22 | ||||
-rw-r--r-- | src/i830_driver.c | 219 | ||||
-rw-r--r-- | src/i830_memory.c | 18 | ||||
-rw-r--r-- | src/i830_ring.h | 17 | ||||
-rw-r--r-- | src/i830_sdvo.c | 4 | ||||
-rw-r--r-- | src/i915_hwmc.c | 36 | ||||
-rw-r--r-- | src/i915_hwmc.h | 2 | ||||
-rw-r--r-- | src/xvmc/Makefile.am | 6 | ||||
-rw-r--r-- | src/xvmc/driDrawable.c | 174 | ||||
-rw-r--r-- | src/xvmc/driDrawable.h | 64 | ||||
-rw-r--r-- | src/xvmc/i915_xvmc.c | 28 | ||||
-rw-r--r-- | src/xvmc/intel_xvmc.c | 79 | ||||
-rw-r--r-- | src/xvmc/intel_xvmc.h | 12 | ||||
-rw-r--r-- | src/xvmc/intel_xvmc_dump.c | 142 |
19 files changed, 477 insertions, 388 deletions
diff --git a/src/bios_reader/bios_dumper.c b/src/bios_reader/bios_dumper.c index e2f3064e..1353edaa 100644 --- a/src/bios_reader/bios_dumper.c +++ b/src/bios_reader/bios_dumper.c @@ -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"); diff --git a/src/i810_reg.h b/src/i810_reg.h index f60656ea..279677c7 100644 --- a/src/i810_reg.h +++ b/src/i810_reg.h @@ -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 @@ -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)) diff --git a/src/i830_accel.c b/src/i830_accel.c index 953a73bc..7784c62a 100644 --- a/src/i830_accel.c +++ b/src/i830_accel.c @@ -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; diff --git a/src/i830_debug.c b/src/i830_debug.c index eff2b740..e90ea22a 100644 --- a/src/i830_debug.c +++ b/src/i830_debug.c @@ -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), diff --git a/src/i830_display.c b/src/i830_display.c index 1122721a..56a718de 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -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; } diff --git a/src/i830_driver.c b/src/i830_driver.c index 9809e4b8..a04cfbca 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -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); diff --git a/src/i830_memory.c b/src/i830_memory.c index 2596e45d..dc48967f 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -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; @@ -1660,6 +1662,22 @@ i830_allocate_hwstatus(ScrnInfoPtr pScrn) } 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) { I830Ptr pI830 = I830PTR(pScrn); diff --git a/src/i830_ring.h b/src/i830_ring.h index cf789eb6..c2078fb4 100644 --- a/src/i830_ring.h +++ b/src/i830_ring.h @@ -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; \ diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c index 23791274..331059bf 100644 --- a/src/i830_sdvo.c +++ b/src/i830_sdvo.c @@ -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) { diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c index c3d3c755..50e11068 100644 --- a/src/i915_hwmc.c +++ b/src/i915_hwmc.c @@ -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), diff --git a/src/i915_hwmc.h b/src/i915_hwmc.h index 0141fb25..7d90afcc 100644 --- a/src/i915_hwmc.h +++ b/src/i915_hwmc.h @@ -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 diff --git a/src/xvmc/Makefile.am b/src/xvmc/Makefile.am index f571743f..345160fb 100644 --- a/src/xvmc/Makefile.am +++ b/src/xvmc/Makefile.am @@ -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@ diff --git a/src/xvmc/driDrawable.c b/src/xvmc/driDrawable.c deleted file mode 100644 index 83863347..00000000 --- a/src/xvmc/driDrawable.c +++ /dev/null @@ -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; -} diff --git a/src/xvmc/driDrawable.h b/src/xvmc/driDrawable.h deleted file mode 100644 index a758c7c7..00000000 --- a/src/xvmc/driDrawable.h +++ /dev/null @@ -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 diff --git a/src/xvmc/i915_xvmc.c b/src/xvmc/i915_xvmc.c index 20b2e613..519de5a3 100644 --- a/src/xvmc/i915_xvmc.c +++ b/src/xvmc/i915_xvmc.c @@ -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); diff --git a/src/xvmc/intel_xvmc.c b/src/xvmc/intel_xvmc.c index 1be8cc6b..ae357aa5 100644 --- a/src/xvmc/intel_xvmc.c +++ b/src/xvmc/intel_xvmc.c @@ -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, diff --git a/src/xvmc/intel_xvmc.h b/src/xvmc/intel_xvmc.h index 55066838..31196238 100644 --- a/src/xvmc/intel_xvmc.h +++ b/src/xvmc/intel_xvmc.h @@ -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 diff --git a/src/xvmc/intel_xvmc_dump.c b/src/xvmc/intel_xvmc_dump.c new file mode 100644 index 00000000..12fc52a5 --- /dev/null +++ b/src/xvmc/intel_xvmc_dump.c @@ -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 = ¯oblock_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 */ + } + +} |