diff options
author | Xavier Bachelot <xavier@bachelot.org> | 2008-01-02 19:57:29 +0000 |
---|---|---|
committer | Xavier Bachelot <xavier@bachelot.org> | 2008-01-02 19:57:29 +0000 |
commit | cfd824ea3fc8d710510e3d2446342707566667ec (patch) | |
tree | 950626b7aa8a0653ae1ed63588a880cad3386665 | |
parent | ac43a38d48f8fcdb58a10f843b51abd29acc1132 (diff) |
Second release candidate for 0.3.0release_0_2_901
66 files changed, 36820 insertions, 0 deletions
diff --git a/trunk/COPYING b/trunk/COPYING new file mode 100644 index 000000000000..9adc03c239a6 --- /dev/null +++ b/trunk/COPYING @@ -0,0 +1,17 @@ +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 COPYRIGHT HOLDER(S) OR AUTHOR(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. diff --git a/trunk/ChangeLog b/trunk/ChangeLog new file mode 100644 index 000000000000..401e8084d8ee --- /dev/null +++ b/trunk/ChangeLog @@ -0,0 +1,2002 @@ +2007-10-29 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * src/via_driver.c: (VIAPreInit): + + Redoing the second change of June 10: Printing VideoRAM again + only when it's actually been probed; plus further tiny code + cleanups: comments, line wraps, whitespace. + +2007-10-29 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * src/via_driver.c: (VIAPreInit): + + Redoing the first change of June 10: Putting the chipset and + revision print statements together at the beginning; moving + the reading of the VideoRAM option to after X has parsed the + config file; plus a few small layout tweaks. + +2007-10-05 Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com> + + * src/via_swov.c: (Upd_Video): + + Enable colorkey on secondary. + +2007-10-03 Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com> + + * src/via_driver.c: (VIAPreInit): + + Fix memory detection for P4M900 and CX700. + +2007-09-12 Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com> + + * src/via_bios.h: + * src/via_driver.c: (VIAWriteMode), (VIAAdjustFrame), + (VIASwitchMode): + * src/via_mode.c: (ViaModeSecondaryVGAFetchCount), + (ViaModeSecondaryVGAOffset), (ViaModeSecondaryVGA): + * src/via_swov.c: (Upd_Video): + * src/via_vbe.c: (ViaVbeSetPanelMode), (ViaVbeSetMode): + + Fix offset when using vbe modes on secondary. + +2007-09-11 Xavier Bachelot <xavier-at-bachelot-dot-org> + + * libxvmc/viaLowLevel.c: (initXvMCLowLevel): + * libxvmc/viaLowLevel.h: + * libxvmc/viaLowLevelPro.c: (initXvMCLowLevel): + * src/via.h: + * src/via_accel.c: (viaInitExa): + * src/via_bandwidth.c: (ViaSetPrimaryFIFO): + * src/via_driver.c: (VIASetupDefaultOptions), (VIAPreInit), + (VIASave), (VIARestore), (VIALoadPalette): + * src/via_driver.h: + * src/via_id.c: + * src/via_mode.c: (ViaOutputsDetect): + * src/via_priv.h: + * src/via_swov.c: (Upd_Video): + * src/via_vbe.c: (ViaVbeInitInt10), (ViaVbeGetRefreshRateIndex), + (ViaVbeGetActiveDevices), (ViaVbeSetActiveDevices), + (ViaVbeSetPanelExpansion), (ViaVbeSetRefresh), (ViaVbeSetMode), + (ViaVbeSaveRestore), (ViaVbeModePreInit): + * src/via_xvmc.c: (ViaInitXVMC), (ViaXvMCCreateContext): + + Sync with experimental_branch. + +2007-09-07 Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com> + + * unichrome/via_id.c: + + Added Gigabyte GA-VM900M ID, reported by Alexandre Penasso Teixeira. + +2007-09-07 Gabiel Mansi <gabriel-dot-mansi-at-gmail-dot-com> + + * libxvmc/viaLowLevel.c: (initXvMCLowLevel): + * libxvmc/viaLowLevel.h: + * libxvmc/viaLowLevelPro.c: (initXvMCLowLevel): + * unichrome/via.h: + * unichrome/via_driver.c: (VIASetupDefaultOptions), (VIAPreInit), + (VIASave), (VIARestore), (VIALoadPalette): + * unichrome/via_driver.h: + * unichrome/via_mode.c: (ViaOutputsDetect): + * unichrome/via_swov.c: (Upd_Video): + * unichrome/via_vbe.c: (ViaVbeInitInt10), + (ViaVbeGetRefreshRateIndex), (ViaVbeGetActiveDevices), + (ViaVbeSetActiveDevices), (ViaVbeSetPanelExpansion), + (ViaVbeSetRefresh), (ViaVbeSetMode), (ViaVbeSaveRestore), + (ViaVbeModePreInit): + * unichrome/via_xvmc.c: (ViaInitXVMC), (ViaXvMCCreateContext): + + Merged vn896_branch from revision 361 to 391. + +2007-09-07 Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com> + + * unichrome/via_driver.c: (VIAPreInit): + * unichrome/via_mode.c: (ViaOutputsDetect): + * unichrome/via_vbe.c: (ViaVbeSetActiveDevices): + + Disabled TV detection for P4M900. + +2007-09-07 Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com> + + * unichrome/via_driver.h: + * unichrome/via_vbe.c: (ViaVbeInitInt10), + (ViaVbeGetRefreshRateIndex), (ViaVbeGetActiveDevices), + (ViaVbeSetActiveDevices), (ViaVbeSetPanelExpansion), + (ViaVbeSetRefresh), (ViaVbeSetMode), (ViaVbeModePreInit): + + VBE code cleanup. + +2007-09-02 Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com> + + * unichrome/via_driver.c: (VIASetupDefaultOptions), (VIASave), + (VIARestore): + * unichrome/via_vbe.c: (ViaVbeSetMode): + + Disabled XvDMA for P4M900. + Modified VBE functions calling order. + +2007-08-18 Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com> + + * unichrome/via_driver.c: (VIASetupDefaultOptions): + * unichrome/via_priv.h: + * unichrome/via_swov.c: (Upd_Video): + + Xvideo code cleanup; added maximum resolution with + interpolation for all chipsets. + +2007-08-03 Xavier Bachelot <xavier-at-bachelot-dot-org> + + * src/via_bios.h: + * src/via_mode.h: + * src/via_video.c: (DecideOverlaySupport): + + Add basic support for DDR667. + +2007-07-31 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * src/via_xvmc.c: (ViaInitXVMC): + + Fixed the xvmc name we register. Was still looking for + the old via xvmc library names. + +2007-07-04 Xavier Bachelot <xavier-at-bachelot-dot-org> + + * configure.ac: + * src/via_driver.c: (VIAPreInit): + * src/via_driver.h: + + Bump driver version to 0.2.900. + Do not log detected chipset 2 times. + Remove duplicate changelog entry. + +2007-06-20 Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com> + + * unichrome/via_bandwidth.c: (ViaSetPrimaryFIFO) + + FIFO settings for CX700. + +2007-06-14 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * configure.ac: + * libxvmc/viaLowLevel.h: + * src/via.h: + * src/via_accel.c: (viaFlushPCI), (viaInitPCIe), (viaEnableAgpVQ), + (viaEnablePCIeVQ), (viaDisableVQ), (viaInitialize2DEngine), + (viaAccelSync), (viaInitXAA), (viaInitExa), (viaInitAccel): + * src/via_bandwidth.c: (ViaSetPrimaryFIFO), (ViaSetSecondaryFIFO): + * src/via_dri.c: (VIADRIRingBufferInit): + * src/via_driver.c: (VIASetupDefaultOptions), (VIAPreInit), + (VIALeaveVT), (VIASave), (VIAScreenInit), (VIACloseScreen): + * src/via_driver.h: + * src/via_id.c: (ViaDoubleCheckCLE266Revision), (ViaCheckCardId): + * src/via_id.h: + * src/via_mode.c: (ViaGetMemoryBandwidth), (ViaModePrimary): + * src/via_mode.h: + * src/via_regs.h: + * src/via_swov.c: (viaWaitHQVFlip), (viaWaitHQVDone), + (VIAVidHWDiffInit), (viaCalculateVideoColor), (viaSetColorSpace), + (ViaInitVideoStatusFlag), (ViaSetVidCtl), (AddHQVSurface), + (SetFIFO_V3), (SetFIFO_V3_64or32or32), (SetFIFO_V3_64or32or16), + (SetColorKey), (SetChromaKey), (SetHQVFetch), (Upd_Video), + (VIAVidUpdateOverlay), (ViaOverlayHide): + * src/via_swov.h: + * src/via_vbe.c: (ViaVbeSetMode): + * src/via_video.c: (DecideOverlaySupport), (viaInitVideo), (Flip), + (viaDmaBlitImage), (viaPutImage): + * src/via_video.h: + * src/via_xvmc.c: (ViaInitXVMC): + + Pulled in Changes from the experimental_branch including + - Partial support for VIA_K8M890, VIA_P4M900, VIA_CX700, + VIA_P4M890 + - Added the VideoEngine option to help clean up code + - Ability to enable debugging with the configure script + +2007-06-12 Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com> + + * unichrome/via.h: + * unichrome/via_dri.c: (VIADRIRingBufferInit): + * unichrome/via_driver.c: + * unichrome/via_id.c: + * unichrome/via_id.h: + * unichrome/via_swov.c: (viaCalculateVideoColor), + (viaSetColorSpace), (ViaInitVideoStatusFlag), (ViaSetVidCtl), + (SetFIFO_V3), (SetFIFO_V3_64or32or32), (SetFIFO_V3_64or32or16), + (Upd_Video): + * unichrome/via_vbe.c: (ViaVbeSetMode): + * unichrome/via_video.c: (DecideOverlaySupport): + + Renamed VT3157 to VT3324. + Added check for null data block in vbe. + Remove version check for older version of Xorg. + +2007-06-12 Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com> + + * unichrome/via.h: + + Added missing includes. + +2007-06-10 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * unichrome/via_driver.c: (VIAPreInit): + + Print VideoRAM again only when it's actually been probed. + Further tiny code cleanups: comments, line wraps, whitespace. + +2007-06-10 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * unichrome/via.man: + * unichrome/via_driver.c: (VIAPreInit): + + Move reading of the VideoRAM option to after X has parsed the + config file. Also put the chipset and revision print statements + together and at the beginning. Plus several small layout tweaks. + +2007-06-07 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * Makefile.am: + * configure.ac: + * libxvmc/Makefile.am: + * man/Makefile.am: + * src/Makefile.am: + * src/via_driver.c: + * src/via_driver.h: + + Renaming driver to openchrome_drv.so and XvMC library to + libchromeXvMC.so. + +2007-06-06 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_driver.c: + + Removed the chipset option definitions that aren't in + trunk yet. + +2007-06-06 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_driver.c: + * unichrome/via_driver.h: + * unichrome/via.man: + + Added per-chipset option defaults. This should allow the + driver to work out of the box with almost all hardware and + xorg.conf configurations. + +2007-05-23 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via.h: + + Remove version check for older version of Xorg. This is + really not necessary anymore, and was causing some breakage + with xorg-server's new version numbering. + +2007-05-18 Xavier Bachelot <xavier-at-bachelot-dot-org> + + * libxvmc/Makefile.am: + * libxvmc/viaXvMC.c: (XvMCCreateContext): + + Backport 2 fixes from Xorg tree. + http://gitweb.freedesktop.org/?p=xorg/driver/xf86-video-via.git;a=commit;h=362e03a38682bfcf366242c53444fa36b6052794 + http://gitweb.freedesktop.org/?p=xorg/driver/xf86-video-via.git;a=commit;h=3cd7dac2b5a1c4bfb66bd1b67904d72dc08cbd0e + +2007-05-15 Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com> + + * unichrome/via.h: + * unichrome/via_driver.c: (VIASetupDefaultOptions): + * unichrome/via_driver.h: + * unichrome/via_swov.c: (viaWaitHQVFlip), (SetColorKey), + (SetChromaKey), (Upd_Video): + * unichrome/via_video.c: (Flip), (viaDmaBlitImage), (viaPutImage): + + Xv code cleanup. + +2007-05-10 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_driver.c: + * unichrome/via_driver.h: + * unichrome/via.man: + + Added per chipset option defaults. This should allow the + driver to install and work out of the box with almost all + hardware and xorg.conf configurations. + +2007-05-07 Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com> + + * libxvmc/viaLowLevel.h: + * unichrome/via_accel.c: (viaFlushPCI), (viaDisableVQ), + (viaAccelSync): + * unichrome/via_bandwidth.c: (ViaSetPrimaryFIFO), + (ViaSetSecondaryFIFO): + * unichrome/via_dri.c: (VIADRIRingBufferInit): + * unichrome/via_driver.c: (VIAPreInit): + * unichrome/via_id.c: + * unichrome/via_swov.c: (viaWaitHQVFlip), (VIAVidHWDiffInit), + (viaSetColorSpace), (ViaInitVideoStatusFlag), (ViaSetVidCtl), + (SetFIFO_V3_64or32or32), (SetFIFO_V3_64or32or16), (SetColorKey), + (SetChromaKey), (Upd_Video): + * unichrome/via_video.c: (DecideOverlaySupport), (Flip), + (viaDmaBlitImage), (viaPutImage): + + Fix Xv for P4M890. + +2007-04-30 Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com> + + * unichrome/via_swov.c: (Upd_Video): + * unichrome/via_xvmc.c: (ViaInitXVMC): + + Disable interpolation when the source width is greater than 800, + otherwise the picture wraps around the screen (bug #109). + Fix a typo in ViaInitXVMC (bug #111). + +2007-04-14 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * unichrome/via_id.c: (ViaDoubleCheckCLE266Revision), + (ViaCheckCardId): + + VN -> VM, message tweaks, and trailing white space fixes. + +2007-03-28 Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com> + + * unichrome/via_bandwidth.c: (ViaSetPrimaryFIFO): + * unichrome/via_swov.c: (viaWaitHQVFlip), (VIAVidHWDiffInit), + (viaSetColorSpace), (ViaInitVideoStatusFlag), (ViaSetVidCtl), + (SetFIFO_V3_64or32or32), (SetFIFO_V3_64or32or16), (SetColorKey), + (SetChromaKey), (Upd_Video): + * unichrome/via_video.c: (Flip), (viaDmaBlitImage), (viaPutImage): + + Fix Xv for CX700. + +2007-03-20 Xavier Bachelot <xavier-at-bachelot-dot-org> + + * unichrome/via_bandwidth.c: (ViaSetPrimaryFIFO), + (ViaSetSecondaryFIFO): + * unichrome/via_dri.c: (VIADRIRingBufferInit): + * unichrome/via_driver.c: + * unichrome/via_id.c: + * unichrome/via_id.h: + * unichrome/via_mode.c: (ViaGetMemoryBandwidth), (ViaModePrimary): + * unichrome/via_mode.h: + * unichrome/via_swov.c: (VIAVidHWDiffInit), + (viaCalculateVideoColor), (viaSetColorSpace), + (ViaInitVideoStatusFlag), (SetFIFO_V3), (SetFIFO_V3_64or32or32): + * unichrome/via_video.c: (viaInitVideo): + * unichrome/via_xvmc.c: (ViaInitXVMC): + + Initial support for P4M890. + +2007-03-09 Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com> + + * unichrome/via_accel.c: (viaFlushPCI), (viaAccelSync), + (viaInitXAA): + * unichrome/via_bandwidth.c: (ViaSetPrimaryFIFO), + (ViaSetSecondaryFIFO): + * unichrome/via_driver.c: (VIAPreInit), (VIALeaveVT), + (VIACloseScreen): + * unichrome/via_id.c: + * unichrome/via_id.h: + * unichrome/via_mode.c: (ViaGetMemoryBandwidth), (ViaModePrimary): + * unichrome/via_mode.h: + * unichrome/via_swov.c: (viaWaitHQVFlip), (VIAVidHWDiffInit), + (viaCalculateVideoColor), (viaSetColorSpace), + (ViaInitVideoStatusFlag), (ViaSetVidCtl), (SetFIFO_V3_64or32or32), + (SetFIFO_V3_64or32or16), (SetColorKey), (SetChromaKey), + (Upd_Video): + * unichrome/via_video.c: (DecideOverlaySupport), (viaInitVideo), + (Flip), (viaDmaBlitImage), (viaPutImage): + * unichrome/via_xvmc.c: (ViaInitXVMC): + + Initial support for P4M900. + +2007-03-08 Xavier Bachelot <xavier-at-bachelot-dot-org> + + * unichrome/via_bandwidth.c: (ViaSetPrimaryFIFO), + (ViaSetSecondaryFIFO): + * unichrome/via_dri.c: (VIADRIRingBufferInit): + * unichrome/via_driver.c: + * unichrome/via_id.c: + * unichrome/via_id.h: + * unichrome/via_mode.c: (ViaGetMemoryBandwidth), (ViaModePrimary): + * unichrome/via_mode.h: + * unichrome/via_swov.c: (VIAVidHWDiffInit), + (viaCalculateVideoColor), (viaSetColorSpace), + (ViaInitVideoStatusFlag), (SetFIFO_V3), (SetFIFO_V3_64or32or32): + * unichrome/via_video.c: (DecideOverlaySupport), (viaInitVideo): + * unichrome/via_xvmc.c: (ViaInitXVMC): + + Initial support for CX700. + +2007-03-04 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * unichrome/via.man: + + Textual tweaks and options ordered alphabetically. + +2007-02-16 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * unichrome/via_accel.c: (viaSetClippingRectangle), + (viaAccelSolidHelper), (viaAccelCopyHelper), + (viaSubsequentMono8x8PatternFillRect), + (viaSubsequentColor8x8PatternFillRect), + (viaSubsequentSolidTwoPointLine), (viaSubsequentSolidHorVertLine): + + Limit x value to sixteen bits. Fixes a rendering glitch reported + by Marg Huijgen <mark-dot-sf-dot-net-at-huijgen-dot-tk>; solution + found by Thomas. + +2007-02-10 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_accel.c: (viaFlushDRIEnabled), + (viaSubsequentSolidTwoPointLine): + + Fix line-clipping bug reported by Manuel Bilderbeek + <manuel-dot-bilderbeek-at-oce-dot-com>. + +2007-02-06 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * unichrome/via_driver.c: + + Try CR39 when CR34 says zero during memory detection on + the CLE266. Idea from Luc Verhaegen, patch by Mark Huijgen + <mark-dot-sf-dot-net-at-huijgen-dot-tk>. + +2007-01-20 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * ChangeLog + + Switch encoding of ChangeLog file to Unicode. + Whitespace and format adjustments. + +2007-01-20 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * unichrome/via_driver.c: (VIALoadRgbLut), (VIALoadPalette), + (VIAScreenInit): + + Add ability to change gamma setting. Original patch by + Gonzalo A. de la Vega <gadelavega-at-gmail-dot-com>, + adapted from Luc Verhaegen's implementation. + +2006-12-28 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_accel.c: (viaExaTexUploadToScreen): + + Work around an obscure hardware limitation when texturing from + AGP. + +2006-12-28 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_dri.c: (VIASetAgpMode): + + Fix AGP mode setting. + +2006-12-28 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + Use non-power-of-two textures for EXA whenever possible. + +2006-12-18 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_xvmc.c: + + Thomas needs a good drm test which means we need XvMC. I + have re-enabled it for testing. + +2006-12-15 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via.h: + * unichrome/via_swov.c: + + This is my cleanup commit of the excellent patch that + Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com> provided, + which finishes the XVideo work on the VT3336 chipset. Nice + work Gabriel. + +2006-12-13 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_video.c: + + Don't use HQV Offset for HQV_CONTROL. + +2006-12-11 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_video.c: + * unichrome/via_swov.c: + + Looks like the VT3336 has the same offset as the VT3259 + for the hardware overlay. + +2006-12-10 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_memcpy.c: + * unichrome/via_swov.c: + + Removed the previous changes; I am not ready to rewrite + the assembly code for x86_64. + The ColorSpace registers were being set up incorrectly + for VT3336. + +2006-12-09 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_memcpy.c: + + The ifdef's in memcpy.c only support i386 arch; should + also support i86_64. + +2006-12-09 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_xvmc.c: + + K8M890 does not support XvMC like the other chipsets; + disable it for now. + +2006-12-09 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_video.h: + * unichrome/via_swov.h: + * unichrome/via_swov.c: + + Made K8M890 XV FIFO settings match K8M800. + Enabled XV_DEBUG. + +2006-12-07 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_mode.h: + + Updated the BandwidthTable for K8M890 chipset. + +2006-12-07 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_driver.c: (VIAEnterVT): + + Initialize the AGP ring buffer before command submission. + +2006-12-07 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_driver.c: (VIAEnterVT): + + Blank and clear screen when entering VT. + +2006-12-07 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_driver.c: (VIAEnterVT): + + Blank and clear screen when entering VT. + +2006-12-07 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_accel.c: (viaAccelDMADownload), + (viaExaDownloadFromScreen), (viaInitExa): + + Indent via_accel.c. + +2006-12-07 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_accel.c: (viaAccelDMADownload): + + Fix download from screen which was reusing kernel argument + data that was altered by the kernel. + +2006-12-07 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_accel.c: (viaAccelDMADownload), + (viaExaDownloadFromScreen): + + Reimplement download from screen to something more easily + debuggable. + +2006-12-06 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_driver.c: + + Fixed some of the boolean option changes that are + inverses such as DisableIRQ. + +2006-12-06 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_memory.c: (viaExaFBSave), (viaOffScreenLinear): + + Cause a "FatalError" if EXA is used with an un-patched Xserver, + and an illegal save locked memory action is requested. + +2006-12-06 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_driver.c: (VIAInitialize3DEngine): + + Proper register names in VIAInitialize3DEngine. + +2006-12-06 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_driver.c: (VIALeaveVT), (VIAWriteMode), + (VIACloseScreen): + * unichrome/via_vbe.c: (ViaVbeSetMode): + + Now that we initialize the 3D engine every time we write + mode, make sure this is done before setting up VQ and AGP + so that those settings persist. The GPU will be unstable + otherwise. + Also fix some code comments. + +2006-12-06 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_driver.c: (VIALeaveVT): + + Force 3D context upload after a VT switch. + +2006-12-06 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_dri.c: (viaDRIFBMemcpy), (viaDRIOffscreenSave): + + Fix up previous commit for > 16MB sizes. + +2006-12-06 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_dri.c: (viaDRIOffscreenSave), + (viaDRIOffscreenRestore): + * unichrome/via_driver.c: (VIAEnterVT), (VIALeaveVT): + * unichrome/via_driver.h: + + Back up DRI offscreen memory before leaving VT and restore it + when entering VT. It may be overwritten in between. + Use PCI DMA blit for this if available. + +2006-12-05 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_driver.c: (VIAWriteMode), (VIAInitialize3DEngine): + * unichrome/via_vbe.c: (ViaVbeSetMode): + + With EXA + 3D we need to reinitialize the 3D engine after + a mode switch (possibly the soft reset + 2D engine + initialization). Otherwise the GPU will hang. + +2006-12-05 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_driver.c: (VIAPreInit): + + Fix the dma2d option setting. + +2006-12-05 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_bandwidth.c: (ViaSetPrimaryFIFO): + + Use a more aggressive fifo setting for CLE266 Cx. + Boosts performance. + Please report problems with this. + +2006-12-05 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_video.c: + * unichrome/via_swov.c: + + Added missing hardware overlay support for VT3336. + +2006-12-04 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_driver.c: + + Added patch to fix the K8M890 hang on VT switch; submitted + by Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com>. + +2006-12-01 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via.man: + * unichrome/via_bios.h: + * unichrome/via_dri.c: (VIADRIScreenInit): + * unichrome/via_driver.c: (VIAPreInit): + * unichrome/via_driver.h: + + Remove unused options. + First pass cleaning up option handling. + Make most boolean options work as expected; + (that is, accepting both a "true" and a "false" argument). + +2006-11-30 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_mode.c: + * unichrome/via_accel.c: + + Added patch to fix some of the K8M890 logic; submitted by + Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com>. + +2006-11-28 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_bandwidth.c: + * unichrome/via_accel.c: + + Patched via_bandwidth.c for dumb mistake I made. Thanks, Gabriel + Mansi, for the second set of eyes. Move HWCursor memory allocation + even further in the driver initialization. + +2006-11-25 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_id.c: + * unichrome/via_accel.c: + + Added additional IDs for the K8M890 cards. + Changed memory allocation order for the HW cursor and 2D engine. + +2006-10-29 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * libxvmc/viaLowLevel.c: + * libxvmc/viaLowLevelPro.c: + * unichrome/via_regs.h: + + Via managed to mix up the 2D / 3D engine busy status bits. + Funny we never noticed this before. + +2006-10-24 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_xvmc.c: (ViaXvMCCreateContext): + + Remove VT3314 (CN700, VM800 etc.) mpeg2 AGP DMA support. + +2006-10-11 Xavier Bachelot <xb_ml-at-kelkoo-dot-net> + + reviewed by: Ivor + + * unichrome/via_bios.h: + * unichrome/via_id.c: + * unichrome/via_mode.h: + * unichrome/via_video.c: (DecideOverlaySupport): + + DDR533 memory support and small cleanup. + Fujitsu/Siemens Amilo L7320 pci id (reported by DeNayGo). + +2006-10-03 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_video.c: (viaPutImage): + + Removed some stray debug messages. + +2006-10-02 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * unichrome/via_driver.c: (VIASave), (VIARestore): + + Moved a line to after declarations for picky gcc-2.96, + tweaked comments and debugging lines. + +2006-09-27 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_memory.c: + + Don't include drm headers in non-dri build. + +2006-09-25 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * unichrome/Makefile.am: + + Mention the overall revision number in the log, not just + the driver code revision. + +2006-09-24 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * libxvmc/viaLowLevel.c: (initXvMCLowLevel): + * libxvmc/viaLowLevelPro.c: (initXvMCLowLevel): + * libxvmc/viaXvMC.c: (XvMCSetAttribute): + + Fix a mutex unlocking issue (Luc Verhaegen). + Have the lowlevel drivers check for the correct chipid. + +2006-09-24 Michal Ludvig <michal-at-logix-dot-cz> + + * man/Makefile.am: + + Fix man-page symlink for out-of-tree build (trac ticket #50). + +2006-09-22 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_drmclient.h: + + Include stdint.h instead of re-typedefining CARD32. + +2006-09-22 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * src/via_id.h + * src/via_video.c + * src/via_mode.c + * src/via_mode.h + * src/via_driver.c + * src/via_swov.c + * src/via_bandwidth.c + * src/via_accel.c + * src/via_vbe.c + * src/via_xvmc.c + * src/via_id.c + + Initial code for support of VT3336 cards. + +2006-09-17 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * unichrome/via_driver.c: (VIASave): + + Put in a few extra debugging lines. + +2006-09-05 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * unichrome/via_swov.c: + + Comment and whitespace tweaks. + +2006-09-05 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * unichrome/via_id.c: + + Add an ID (trac ticket #67), note identical numbers, remove + a duplicate, remove obsolete unknown, remove trailing tab. + +2006-08-27 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * unichrome/via_id.c: + + Textual tweaks. + +2006-08-27 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * unichrome/via_dri.c: (VIADRIAgpInit): + + Rearrange declarations to fix compilation problem with gcc-2.96, + reported by Nikolai V. Ivanyushin <nvi-at-sven-dot-ru>. + +2006-08-22 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * unichrome/via_accel.c: + + Whitespace adjustment; getting back close to Xorg. + Comment tweaks and #endif clarifications. + +2006-08-19 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * unichrome/via_swov.c: (viaWaitVideoCommandFire), + (SetVideoWindow): + + Comment tweaks. + +2006-08-18 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * unichrome/via_driver.h: + + Move definition of AGP_SIZE out of #ifdef VIA_HAVE_EXA block, + to make the driver compile again for Xorg-6.8.2. + +2006-08-10 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_mode.c: (ViaModeDotClockTranslate): + * unichrome/via_video.c: (viaPaintColorkey): + + Re-enable Ivor's Dotclock computation. + Enable accelerated redirected colorkey painting for Xv. + +2006-07-28 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_driver.c: (VIAPreInit): + + ...And get default AGP size correct as well. + +2006-07-28 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_accel.c: (viaIsAGP): + * unichrome/via_dri.c: (VIADRIAgpInit): + + Fix false AGP detection and make sure we have the correct AGP + size. + +2006-07-27 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via.man: + * unichrome/via_accel.c: (viaExaUploadToScratch), + (viaExaCheckComposite), (viaIsAGP), (viaInitExa), (viaInitAccel): + * unichrome/via_ch7xxx.c: (ViaCH7xxxInit): + * unichrome/via_dri.c: (VIADRIAgpInit): + * unichrome/via_driver.c: (VIAPreInit), (VIAEnterVT), (VIALeaveVT), + (VIAScreenInit), (VIACloseScreen): + * unichrome/via_driver.h: + + Changes donated by "PConRails, LLC" and "Tungsten Graphics, Inc.": + EXA and memory management optimizations, Manpage update. + New options: + ExaScratchSize + MaxDRIMem + AGPMem + VBESaveRestore + +2006-07-27 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via.h: + * unichrome/via_accel.c: + * unichrome/via_dri.h: + * unichrome/via_driver.h: + * unichrome/via_mode.c: (ViaModeDotClockTranslate): + * unichrome/via_swov.c: (ViaOverlayHide): + * unichrome/via_video.c: (DecideOverlaySupport), + (viaVideoFillPixmap), (viaPaintColorkey), (viaReputImage), + (viaPutImage): + + Changes donated by "PConRails, LLC" and "Tungsten Graphics, Inc.": + Video optimizations: + Paint colorkey correctly under composite manager. + Make sure the driver compiles with Xorg git. + Don't reset the primary display FIFO after XV. It's never touched + by the Xv code, and slows things down in VBE mode. + + +2006-07-11 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * libxvmc/viaXvMC.c: + * unichrome/via_dri.c: + + Change DRM major compatibility from 3.x.x to 2.x.x. + +2006-07-10 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * libxvmc/driDrawable.c: + * libxvmc/viaLowLevel.c: + * libxvmc/viaLowLevelPro.c: (finish_header_agp), + (computeHQVScaleAndFilter): + * libxvmc/viaXvMC.c: (yOffs), (vOffs), (uOffs), (defaultQMatrices), + (releaseDecoder), (grabDecoder), (setupAttribDesc), + (releaseAttribDesc), (releaseContextResources), + (XvMCCreateContext), (XvMCDestroyContext), (XvMCCreateSurface), + (XvMCDestroySurface), (XvMCPutSlice2), (XvMCPutSlice), + (updateXVOverlay), (XvMCPutSurface), (debugControl), + (XvMCBeginSurface), (XvMCSyncSurface), (XvMCLoadQMatrix), + (XvMCRenderSurface), (XvMCCreateBlocks), (XvMCDestroyBlocks), + (XvMCCreateMacroBlocks), (XvMCDestroyMacroBlocks), + (XvMCCreateSubpicture), (XvMCSetSubpicturePalette), (findOverlap), + (XvMCClearSubpicture), (XvMCCompositeSubpicture), + (XvMCBlendSubpicture), (XvMCBlendSubpicture2), + (XvMCSyncSubpicture), (XvMCFlushSubpicture), + (XvMCDestroySubpicture), (XvMCGetSubpictureStatus), + (XvMCFlushSurface), (XvMCGetSurfaceStatus), (XvMCQueryAttributes), + (XvMCSetAttribute), (XvMCGetAttribute), (XvMCHideSurface): + * libxvmc/xf86dri.c: + + Remove the "config.h" includes from libxvmc, as they break it. + I wonder how the openChrome libXvMC has been working? + + Indent viaXvMC.c. + +2006-07-10 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * libxvmc/viaXvMC.c: (XvMCCreateContext): + * unichrome/via_dri.c: (VIADRIRingBufferInit), (VIADRIScreenInit): + * unichrome/via_xvmc.c: (ViaInitXVMC): + + Update DRM version checking. + +2006-07-10 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_swov.c: (viaWaitVideoCommandFire): + + Increase video command fire timeout. + +2006-07-10 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_memory.c: (viaOffScreenLinear): + + Fix dri close screen segfault caused by previous commit. + +2006-06-15 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_dri.c: (VIADRIFBInit): + * unichrome/via_driver.h: + * unichrome/via_memory.c: (viaOffScreenLinear), (VIAAllocLinear): + + Fix severe dri memory allocation bug. (Reported by Trevor Kramer) + +2006-05-11 Ivor Hewitt <ivor-at-ivor-dot-org> + + * configure.ac: + * unichrome/via.h: + * unichrome/via_accel.c: + * unichrome/via_cursor.c: + * unichrome/via_dri.c: + * unichrome/via_driver.h: + * unichrome/via_memcpy.c: + * unichrome/via_memory.c: + * unichrome/via_mode.c: + * unichrome/via_shadow.c: + * unichrome/via_swov.c: + * unichrome/via_vbe.c: + * unichrome/via_vgahw.c: + * unichrome/via_video.c: + * unichrome/via_xvmc.c: + + - Xorg xv ABI compatibility patch. (Marcin Kurek) + +2006-04-14 Ivor Hewitt <ivor-at-ivor-dot-org> + + * libxvmc/Imakefile: + + - Unbreak makefile. + +2006-03-19 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * libxvmc/Makefile.am: + * unichrome/Makefile.am: + + - Backport Makefile changes form xorg. + +2006-03-17 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_driver.c: + + - Update the built-against macro to recognize Xorg if present. + (Reported by Eric Anholt) + +2006-03-17 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * configure.ac: + + - Update compatibility check for XvMC. + +2006-03-17 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_accel.c: (viaInitExa): + * unichrome/via_driver.c: (VIAPreInit): + + - Support EXA 2.0. + +2006-03-13 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_accel.c: (viaSetupForSolidLine), + (viaSubsequentSolidTwoPointLine), (viaSetupForDashedLine): + * unichrome/via_driver.h: + + - Possible fix for XAA bug rendering solid lines as dashed. + (Reported by Lewin Edwards) + +2006-03-08 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + + * libxvmc/Imakefile: + * unichrome/via_swov.c: + * unichrome/via_swov.h: + * unichrome/via_video.c: (viaInitVideo), (viaExitVideo), + * unichrome/via_video.h: + * unichrome/via_xvmc.c: (initViaXvMC), (cleanupViaXvMC), (stride), + * unichrome/via_xvmc.h: + * unichrome/via_xvpriv.h: + + - Run indent on above files after syncing them with Xorg. + +2006-02-23 Xavier Bachelot <xb_ml AT kelkoo DOT net> + + * configure.ac: + + - Fix man pages suffix. + - Bump driver version number to be equal to xorg. + +2006-02-21 Ivor Hewitt <ivor-at-ivor-dot-org> + + * unichrome/via_bios.h: + * unichrome/via_driver.c: (VIAPreInit): + * unichrome/via_mode.h: + * unichrome/via_priv.h: + * unichrome/via_swov.c: (viaOverlayGetV1V3Format), + (viaOverlayGetSrcStartAddress), (viaOverlayGetFetch), + (CreateSurface), (ViaSwovSurfaceCreate), (ViaSwovSurfaceDestroy), + (VIAVidUpdateOverlay), (ViaOverlayHide): + * unichrome/via_video.c: (viaInitVideo), (Flip), (viaDmaBlitImage), + (viaPutImage), (viaQueryImageAttributes): + + - Lets have RV32 too. + - Add 12x8 panel. + +2006-02-10 Ivor Hewitt <ivor-at-ivor-dot-org> + + * unichrome/via.h: + * unichrome/via_bandwidth.c: (ViaSetPrimaryFIFO), + (ViaSetSecondaryFIFO): + * unichrome/via_dri.c: (VIADRIRingBufferInit): + * unichrome/via_mode.c: (ViaModePrimary): + * unichrome/via_swov.c: (VIAVidHWDiffInit), + (viaOverlayGetSrcStartAddress), (viaOverlayGetFetch), + (viaCalculateVideoColor), (viaSetColorSpace), + (ViaInitVideoStatusFlag), (ViaSetVidCtl), (SetFIFO_V3), + (SetFIFO_V3_64or32or32), (SetFIFO_V3_64or32or16), (SetColorKey), + (SetChromaKey), (SetHQVFetch), (Upd_Video): + * unichrome/via_video.c: (DecideOverlaySupport), (viaInitVideo), + (viaDmaBlitImage): + * unichrome/via_xvmc.c: (ViaInitXVMC), (ViaXvMCCreateContext): + + - Get some code exercised for VM800, let's see where it crumbles. + +2006-01-29 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_vbe.c: (ViaVbeSetMode): + + - Fix VBE refresh setting. + +2006-01-29 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_accel.c: (viaInitExa): + * unichrome/via_driver.c: (VIAPreInit): + + - Merge EXA branch revisions 152:155 + +2006-01-29 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_swov.c: + * unichrome/via_video.c: (viaXvError), (viaReputImage), + (viaSetupAdaptors), (viaDmaBlitImage), (viaPutImage): + * unichrome/via_xvpriv.h: + + - Removed time.h and sys/time.h includes from via_swov.c + (Reported by George E Sollish). + - More verbose Xv error reporting. + +2006-01-27 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via.man: + * unichrome/via_3d.c: + * unichrome/via_accel.c: (viaAccelPlaneMaskHelper), (viaInitExa), + (viaInitAccel), (viaExitAccel), (viaFinishInitAccel): + * unichrome/via_driver.c: (VIAPreInit): + * unichrome/via_driver.h: + + - Merge EXA branch revisions 138:152 + +2006-01-27 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_mode.c: (ViaModePrimary): + + - Import Luc's fix for sometimes-blanking CRTs on CLE266. + (Luc Verhaegen) + +2006-01-27 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_swov.c: (viaWaitVideoCommandFire): + + - The previous commit causes problems with older X versions. + Avoid using gettimeofday(). Reported by Paul Bender. + +2006-01-26 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_swov.c: (viaTimeDiff), (viaWaitVideoCommandFire): + + - Make the Xv viaWaitVideoCommandFire loop time out. Better than server hang? + +2006-01-26 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via.man: + * unichrome/via_driver.c: (VIAPreInit): + * unichrome/via_driver.h: + * unichrome/via_video.c: (viaInitVideo): + + - Added a "NoXVDMA" option to disable PCI DMA for Xv image transfers. + May turn out useful to vlc users. + - Updated man page. + +2006-01-26 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_driver.c: + + - Added vgaHWGetIndex to vgaHW symbol list. + (Reported by Ole Sandum) + +2006-01-26 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_swov.c: (ViaOverlayHide): + + - Fix HQV offset bug. + +2006-01-26 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * libxvmc/driDrawable.c: (drawStamp), (getDRIDrawableInfoLocked), + (driDestroyHashContents): + * libxvmc/driDrawable.h: + * libxvmc/viaLowLevel.c: (hwlLock), (hwlUnlock), (timeDiff), + (viaDMATimeStampLowLevel), (viaDMAWaitTimeStamp), + (viaDMAInitTimeStamp), (viaDMACleanupTimeStamp), + (viaMpegGetStatus), (viaMpegIsBusy), (syncDMA), (syncVideo), + (syncAccel), (syncMpeg), (pciFlush), (agpFlush), + (flushXvMCLowLevel), (flushPCIXvMCLowLevel), (pciCommand), + (viaMpegSetSurfaceStride), (viaVideoSetSWFLipLocked), + (viaVideoSWFlipLocked), (viaMpegSetFB), (viaMpegBeginPicture), + (viaMpegReset), (viaMpegWriteSlice), (viaVideoSubPictureOffLocked), + (viaVideoSubPictureLocked), (viaBlit), (syncXvMCLowLevel), + (initXvMCLowLevel), (closeXvMCLowLevel): + * libxvmc/viaLowLevel.h: + * libxvmc/viaLowLevelPro.c: (initHQVShadow), + (setHQVHWDeinterlacing), (setHQVDeblocking), (setHQVStartAddress), + (setHQVColorSpaceConversion), (setHQVFetchLine), (setHQVScale), + (setHQVSingleDestination), (setHQVDeinterlacing), + (setHQVTripleBuffer), (finish_header_agp), (hwlLock), (hwlUnlock), + (timeDiff), (viaDMATimeStampLowLevel), (viaDMAWaitTimeStamp), + (viaDMAInitTimeStamp), (viaDMACleanupTimeStamp), + (viaMpegGetStatus), (viaMpegIsBusy), (syncDMA), (syncVideo), + (syncAccel), (syncMpeg), (pciFlush), (agpFlush), + (uploadHQVDeinterlace), (uploadHQVShadow), (flushXvMCLowLevel), + (flushPCIXvMCLowLevel), (viaMpegSetSurfaceStride), + (viaVideoSetSWFLipLocked), (viaVideoSWFlipLocked), (viaMpegSetFB), + (viaMpegBeginPicture), (viaMpegReset), (viaMpegWriteSlice), + (viaVideoSubPictureOffLocked), (viaVideoSubPictureLocked), + (viaBlit), (syncXvMCLowLevel), (updateLowLevelBuf), + (cleanupLowLevelBuf), (releaseXvMCLowLevel), (initXvMCLowLevel), + (setLowLevelLocking), (closeXvMCLowLevel), (computeDownScaling), + (computeHQVScaleAndFilter), (setupBackBuffer): + * libxvmc/viaXvMCPriv.h: + * libxvmc/vldXvMC.h: + * libxvmc/xf86dri.c: (uniDRIDestroyContext), + (uniDRICreateDrawable), (uniDRIDestroyDrawable), + (uniDRIGetDrawableInfo): + * libxvmc/xf86dri.h: + * libxvmc/xf86dristr.h: + + - Run indent on libXvMC. Sync XvMC with Xorg 7.0. + +2006-01-26 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_dri.c: (VIADRIKernelInit), (VIADRIMapInit): + * unichrome/via_driver.h: + + - Add a framebuffer map for DRI. Don't just assume that the + framebuffer map handle is the physical address. + +2006-01-12 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_accel.c: (viaExaDownloadFromScreen), + (viaExaTexUploadToScreen), (viaExaUploadToScreen), + (viaExaCheckComposite): + * unichrome/via_driver.h: + + - Exa branch revision 132:138 merge. + +2006-01-12 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_swov.c: (CreateSurface): + * unichrome/via_video.c: (viaInitVideo), (Flip), (viaDmaBlitImage): + + - Fix planar Xv Flipping and surface allocation size. + (Reported by Tim, MagicITX) + - Fix Xv dmablit strides and bump drm version for dmablit to 2.9.0, since + there is a direction bug in earlier versions. + +2006-01-09 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * libxvmc/viaXvMC.c: (releaseContextResources): + * unichrome/via_swov.c: (CreateSurface), (ViaSwovSurfaceDestroy): + + - Mark already destroyed XvMC contexts as bad, in case clients + try to destroy them twice. + - Don't try to destroy YV12 buffers when exiting XvMC video. + +2006-01-08 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_accel.c: (viaPixelARGB8888): + + - Merge exa_branch 130:132. Rendering errors. + - Changelog typo. + +2006-01-08 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_3d.c: (viaSet3DFlags), (viaSet3DCompositeOperator): + * unichrome/via_accel.c: (viaIsAGP): + + - Merge exa_branch 127:130. Rendering errors. + +2006-01-08 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/Makefile.am: + + - Modular build fix. (Boris Dusek) + +2006-01-07 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/Imakefile: + * unichrome/via_accel.c: (viaDumpDMA), (viaFlushPCI), + (viaFlushDRIEnabled), (viaSetupCBuffer), (viaAccelClippingHelper), + (viaAccelSolidHelper), (viaAccelPlaneMaskHelper), + (viaAccelTransparentHelper), (viaAccelCopyHelper), + (viaSetupForScreenToScreenCopy), (viaSubsequentScreenToScreenCopy), + (viaSetupForSolidFill), (viaSubsequentSolidFillRect), + (viaSetupForMono8x8PatternFill), + (viaSubsequentMono8x8PatternFillRect), + (viaSetupForColor8x8PatternFill), + (viaSubsequentColor8x8PatternFillRect), + (viaSetupForCPUToScreenColorExpandFill), + (viaSubsequentScanlineCPUToScreenColorExpandFill), + (viaSetupForImageWrite), (viaSubsequentImageWriteRect), + (viaSetupForSolidLine), (viaSubsequentSolidTwoPointLine), + (viaSubsequentSolidHorVertLine), (viaSetupForDashedLine), + (viaAccelMarkSync), (viaExaPrepareSolid), (viaExaSolid), + (viaExaPrepareCopy), (viaExaCopy), (viaExaCompositePictDesc), + (viaExaPrintComposite), (viaBitExpandHelper), (viaPixelARGB8888), + (viaExpandablePixel), (viaCheckUpload), (viaOrder), + (viaExaDownloadFromScreen), (viaExaTexUploadToScreen), + (viaExaUploadToScreen), (viaExaUploadToScratch), + (viaExaCheckComposite), (viaIsAGP), (viaIsOffscreen), + (viaExaPrepareComposite), (viaExaComposite), (viaInitExa), + (viaInitAccel), (viaExitAccel), (viaFinishInitAccel), + (viaAccelBlitRect), (viaAccelFillRect), (viaAccelSyncMarker): + * unichrome/via_dga.c: + * unichrome/via_dmabuffer.h: + * unichrome/via_dri.c: (VIADRIFBInit): + * unichrome/via_driver.c: (VIALeaveVT), (VIAScreenInit), + (VIAWriteMode), (VIACloseScreen): + * unichrome/via_driver.h: + + - Merge in exa_branch from revision 104 to 127. Exa Composite acceleration. + See the branch Changelog for a detailed description of changes. + +2006-01-06 Thomas Hellström + + * unichrome/via_accel.c: (viaExaDownloadFromScreen), + (viaExaUploadToScreen): + * unichrome/via_video.c: (viaDmaBlitImage): + + - Update Xv blit to new blit-combining feature of DRM. + (Idea from Luc Verhaegen/Unichrome). + - Prepare for ugly via_drm.h dmablit IOCTL arg change and via_drm.h + versioning. + +2005-12-29 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_video.c: (viaDmaBlitImage): + + - Fix Xv YUY2/RVXX dmaBlit stride. + +2005-12-26 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * libxvmc/Makefile.am: + + - Modular built two identical XvMC libs. The pro lib was not a pro lib. + Fix this. (Tim Dodge) + +2005-12-15 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_accel.c: (viaInitAccel): + + - Make sure the accel marker system is properly initialized. + +2005-12-08 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_driver.c: (VIAScreenInit): + * unichrome/via_memory.c: (VIAAllocLinear): + + - Protect the accelerated initial sceen clearing with a DRI lock. + - Submit the correct context for drm memory allocation. + +2005-12-08 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_ch7xxx.c: (CH7xxxModeI2C): + * unichrome/via_dri.c: (VIADRIAgpInit): + * unichrome/via_driver.c: (VIAScreenInit): + * unichrome/via_id.c: + + - Moved the memset from previous commit to after dri is initialized, so + that AGP command submission will work. + - Silenced some warnings. + +2005-12-08 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_driver.c: (VIAScreenInit): + * unichrome/via_mode.c: (ViaModePrimary): + * unichrome/via_vbe.c: (ViaVbeSetMode): + + - Moved memset to blank screen from ModeSetting to ScreenInit, in + an attempt to avoid long standing hangs on K8M800. Also use + the 2D engine for this if acceleration is enabled. + +2005-12-07 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * Makefile.in: + + - Removed Makefile.in since it is generated by the build process. + +2005-12-06 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * Makefile.am: + * Makefile.in: + + - Added Makefile.am and Makefile.in to allow running make + in the root directory. + +2005-12-06 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * acinclude.m4: + * autogen.sh: + * configure.ac: + * libxvmc/Makefile.am: + * libxvmc/driDrawable.c: + * libxvmc/viaLowLevel.c: + * libxvmc/viaLowLevelPro.c: + * libxvmc/viaXvMC.c: + * libxvmc/viaXvMCPriv.h: + * libxvmc/xf86dri.c: + * man/Makefile.am: + * unichrome/Makefile.am: + * unichrome/via_accel.c: + * unichrome/via_bandwidth.c: + * unichrome/via_ch7xxx.c: + * unichrome/via_cursor.c: + * unichrome/via_dga.c: + * unichrome/via_dri.c: + * unichrome/via_driver.c: + * unichrome/via_i2c.c: + * unichrome/via_id.c: + * unichrome/via_memcpy.c: + * unichrome/via_memory.c: + * unichrome/via_mode.c: + * unichrome/via_shadow.c: + * unichrome/via_vbe.c: + * unichrome/via_vgahw.c: + * unichrome/via_vt162x.c: + * unichrome/via_xvmc.c: + + - Adjust for modular build. + +2005-12-04 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_vt162x.c: (VT1622ModeCrtc): + + - Fix trac item #13. + This will probably also make TV-out work on some K8M/N800 laptops, + and will probaly fix TV-out after a resume. + +2005-12-02 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * libxvmc/Imakefile: + * libxvmc/xf86dri.c: + + - 64 bit fixes on libviaXvMC* + +2005-12-02 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_accel.c: (viaAccelPlaneMaskHelper), + (viaAccelTransparentHelper), (viaSetupForScreenToScreenCopy), + (viaSetupForSolidFill), (viaSetupForMono8x8PatternFill), + (viaSetupForColor8x8PatternFill), + (viaSetupForCPUToScreenColorExpandFill), (viaSetupForImageWrite), + (viaSetupForSolidLine), (viaSubsequentSolidTwoPointLine), + (viaSetupForDashedLine), (viaAccelMarkSync), (viaExaPrepareSolid), + (viaExaPrepareCopy), (viaInitAccel), (viaDGABlitRect), + (viaDGAFillRect): + * unichrome/via_driver.c: + * unichrome/via_driver.h: + + - Merge exa_branch revisions 91:104: + Add support for EXA planemasks. + Tell loader about some missing EXA functions (Reported by Adam Jackson). + Fix broken XAA dashed lines. + +2005-12-01 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * libxvmc/Imakefile: + * unichrome/Imakefile: + * unichrome/via_driver.c: + + - Remove drmCommandWriteRead from drm loader symbols again. + Ivor had already added it :) + - Fix a typo in unichrome/Imakefile that broke build on x86_64. + - Add $(PICFLAGS) to libxvmc Makefile to make it build on x86_64. + +2005-12-01 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_driver.c: + * unichrome/via_memory.c: (VIAFreeLinear): + + - Add drmCommandWriteRead to drm loader symbols. + - Make the drm freemem call drmCommandWrite. + +2005-11-29 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_accel.c: (viaInitAccel): + * unichrome/via_memory.c: (VIAAllocLinear): + + - Merge exa_branch revisions 86:91 + +2005-11-29 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/Imakefile: + + - Yet another drm.h include fixup. For 6.8 and earlier? + +2005-11-28 Ivor Hewitt <ivor-at-ivor-dot-org> + + * unichrome/via_id.c: + + - Just another id. (Tobias Blom) + +2005-11-28 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/Imakefile: + + - Include the correct drm.h file. This is important for 64 bit builds. + +2005-11-26 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_accel.c: (viaFlushDRIEnabled), (viaSetupCBuffer): + + - Merged EXA branch changes between revisions 84 and 86. + +2005-11-23 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_accel.c: (viaFlushPCI), (viaFlushDRIEnabled), + (viaSetupCBuffer), (viaTearDownCBuffer), (viaEnableVQ), + (viaDisableVQ), (viaAccelSetMode), (viaInitialize2DEngine), + (viaAccelSync), (viaSetClippingRectangle), + (viaAccelClippingHelper), (viaAccelSolidHelper), + (viaAccelTransparentHelper), (viaAccelCopyHelper), + (viaSetupForScreenToScreenCopy), (viaSubsequentScreenToScreenCopy), + (viaSetupForSolidFill), (viaSubsequentSolidFillRect), + (viaSetupForMono8x8PatternFill), + (viaSubsequentMono8x8PatternFillRect), + (viaSetupForColor8x8PatternFill), + (viaSubsequentColor8x8PatternFillRect), + (viaSetupForCPUToScreenColorExpandFill), + (viaSubsequentScanlineCPUToScreenColorExpandFill), + (viaSetupForImageWrite), (viaSubsequentImageWriteRect), + (viaSetupForSolidLine), (viaSubsequentSolidTwoPointLine), + (viaSubsequentSolidHorVertLine), (viaSetupForDashedLine), + (viaSubsequentDashedTwoPointLine), (viaInitXAA), + (viaAccelMarkSync), (viaAccelWaitMarker), (viaExaPrepareSolid), + (viaExaSolid), (viaExaPrepareCopy), (viaExaCopy), + (viaExaDownloadFromScreen), (viaExaUploadToScreen), (viaInitExa), + (viaInitAccel), (viaExitAccel), (viaDGABlitRect), (viaDGAFillRect): + + - Merged EXA branch changes between revisions 74 and 84. Mainly + indentations and minor bugfixes. + +2005-11-15 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_swov.c: (ViaSwovSurfaceCreate), + (ViaSwovSurfaceDestroy): + * unichrome/via_video.c: (viaSetupAdaptors): + * unichrome/via_xvpriv.h: + + - Fix Xv surface destruction and re-allocation. + (Reported by Cedric Berger). + +2005-11-15 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/Imakefile: + * unichrome/via_accel.c: (viaTearDownCBuffer), + (viaAccelSolidHelper), (viaAccelCopyHelper), + (viaExaDownloadFromScreen), (viaExaUploadToScreen): + * unichrome/via_driver.c: (VIAScreenInit): + + - Merged changes in exa_branch revisions 67 to 74. For a detailed + ChangeLog, see that branch. + +2005-11-09 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/Imakefile: + * unichrome/via_accel.c: (viaFlushPCI), (viaFlushDRIEnabled), + (viaSetupCBuffer), (viaTearDownCBuffer), (viaInitAgp), + (viaEnableVQ), (viaDisableVQ), (viaAccelSetMode), + (viaInitialize2DEngine), (viaAccelSync), (viaSetClippingRectangle), + (viaDisableClipping), (viaAccelClippingHelper), + (viaAccelSolidHelper), (viaAccelTransparentHelper), + (viaAccelCopyHelper), (viaSetupForScreenToScreenCopy), + (viaSubsequentScreenToScreenCopy), (viaSetupForSolidFill), + (viaSubsequentSolidFillRect), (viaSetupForMono8x8PatternFill), + (viaSubsequentMono8x8PatternFillRect), + (viaSetupForColor8x8PatternFill), + (viaSubsequentColor8x8PatternFillRect), + (viaSetupForCPUToScreenColorExpandFill), + (viaSubsequentScanlineCPUToScreenColorExpandFill), + (viaSetupForImageWrite), (viaSubsequentImageWriteRect), + (viaSetupForSolidLine), (viaSubsequentSolidTwoPointLine), + (viaSubsequentSolidHorVertLine), (viaSetupForDashedLine), + (viaSubsequentDashedTwoPointLine), (viaInitXAA), + (viaAccelMarkSync), (viaAccelWaitMarker), (viaExaPrepareSolid), + (viaExaSolid), (viaExaDoneSolidCopy), (viaExaPrepareCopy), + (viaExaCopy), (viaExaDownloadFromScreen), (viaExaUploadToScreen), + (viaInitExa), (viaInitAccel), (viaExitAccel), (viaDGABlitRect), + (viaDGAFillRect), (viaDGAWaitMarker): + * unichrome/via_cursor.c: (VIALoadCursorImage): + * unichrome/via_dga.c: + * unichrome/via_dri.c: (VIADRIFBInit), (VIADRIScreenInit), + (VIADRICloseScreen), (VIADRIFinishScreenInit): + * unichrome/via_driver.c: (VIASetup), (VIAPreInit), (VIALeaveVT), + (VIAScreenInit), (VIAWriteMode), (VIACloseScreen), (VIASwitchMode): + * unichrome/via_driver.h: + * unichrome/via_memcpy.c: (viaVidCopyInit): + * unichrome/via_memory.c: (VIAFreeLinear), (offScreenLinear), + (VIAAllocLinear), (VIAInitLinear): + * unichrome/via_priv.h: + * unichrome/via_vbe.c: (ViaVbeSetMode): + + - Merge exa_branch from revision 52 to 67. For a detailed Changelog, + check that branch. + +2005-11-09 Ivor Hewitt <ivor-at-ivor-dot-org> + + * unichrome/via_driver.c: (VIAPreInit): + * unichrome/via_mode.c: (ViaModeDotClockTranslate): + + - Fix pro-mode and remove pro warning. (Paul Bender) + +2005-11-08 Ivor Hewitt <ivor-at-ivor-dot-org> + + * unichrome/via_driver.c: (VIASwitchMode): + + - Don't kickVblank with no DRI enabled. (Joris van Rantwijk) + +2005-11-02 Ivor Hewitt <ivor-at-ivor-dot-org> + + * unichrome/via_mode.c: (ViaGetMemoryBandwidth): + * unichrome/via_mode.h: + + - Give VM800 some bandwidth. + +2005-11-01 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * libxvmc/viaLowLevel.c: (viaDMAInitTimeStamp): + * libxvmc/viaLowLevelPro.c: (viaDMAInitTimeStamp), + (updateLowLevelBuf): + * unichrome/via_drmclient.h: + + - Fix compilation errors caused by the drm / dri update. + (reported by Tarun Kripalani) + +2005-10-31 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_accel.c: (VIAInitAccel): + * unichrome/via_cursor.c: (VIAHWCursorInit): + + - Second attempt at fixing the hw cursor issue. + There were actually two errors involved. + +2005-10-31 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_xvpriv.h: + + - Fix stray include left over by previous commit. + +2005-10-31 Ivor Hewitt <ivor-at-ivor-dot-org> + + * unichrome/via_id.c: + + - Mitac 8889 device id. (Daniel Schindler) + +2005-10-30 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_accel.c: (VIAInitAccel): + + - Revert the hardware cursor fix since it for some strange reason + makes hw cursors white. Need to figure out why. + +2005-10-30 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_video.c: (viaInitVideo), (viaSetupAdaptors), + (nv12cp), (viaDmaBlitImage), (viaPutImage), (nv12Blit): + * unichrome/via_xvpriv.h: + + - Enable DMA Xv image transfers also for PM8X0 / CN400. + YV12 to NV12 conversion is still software but now takes place + in system memory instead of during transfer to framebuffer memory. + CPU usage is much improved on PM8X0. Less so on CN400. + Hardware YV12 to NV12 conversion using the blitter was implemented + and tested but was very slow, probably due to the fact that blitting + only took place one column at a time. Since sync on the 2D engine + currently requires a busy-wait, the approach was not only slow, but + also CPU-consuming. + +2005-10-27 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_video.c: (viaExitVideo), (viaSaveVideo), + (viaRestoreVideo), (VIAVidAdjustFrame): + + - Fix server crash when compiled without -DXvExtension. + +2005-10-27 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_dri.c: (VIADRIRingBufferInit), (VIADRIScreenInit), + (VIADRIFinishScreenInit), (VIADRIMapInit): + * unichrome/via_dri.h: + * unichrome/via_driver.h: + * unichrome/via_drm.h: + * unichrome/via_memory.c: (VIAFreeLinear), (VIAAllocLinear): + * unichrome/via_video.c: (viaInitVideo): + * unichrome/via_xvmc.c: (ViaInitXVMC): + + - Sync dri handling with Xorg. This should hopefully make it run + with Mesa 6.4 again. (Luc Verhaegen, Eric Anholt, me) + +2005-10-27 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_video.c: (viaPutImage): + + - Make via_video.c compile without -DXF86DRI. Was broken with the + dmablit commit. (Reported by Luc Verhaegen) + +2005-10-27 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_accel.c: (VIAInitAccel): + + - Fix HW cursor memory allocation. + +2005-10-18 Ivor Hewitt <ivor-at-ivor-dot-org> + + * unichrome/via_bandwidth.c: (ViaSetPrimaryFIFO), + (ViaSetSecondaryFIFO): + * unichrome/via_driver.c: (VIAPreInit): + * unichrome/via_id.c: + * unichrome/via_id.h: + * unichrome/via_swov.c: (VIAVidHWDiffInit): + + - Remaining device id's lying about. + - Remove PM800 conditionals. + +2005-10-18 Ivor Hewitt <ivor-at-ivor-dot-org> + + * unichrome/via_driver.c: (VIAPreInit): + * unichrome/via_id.c: + * unichrome/via_id.h: + * unichrome/via_mode.h: + + - Device id additions. AsRock P4VM800 reported by Mariano Benedettini + +2005-09-25 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via.h: + * unichrome/via_dri.c: (VIADRIRingBufferInit), + (VIADRIFinishScreenInit): + * unichrome/via_dri.h: + * unichrome/via_driver.h: + * unichrome/via_drm.h: + * unichrome/via_priv.h: + * unichrome/via_swov.c: (viaWaitHQVFlip), (viaWaitHQVFlipClear), + (viaWaitHQVDone), (viaOverlayGetV1V3Format), + (viaOverlayGetSrcStartAddress), (viaOverlayGetFetch), + (viaSetColorSpace), (ViaSetVidCtl), (AddHQVSurface), + (ViaSwovSurfaceCreate), (ViaSwovSurfaceDestroy), + (SetFIFO_V3_64or32or32), (SetFIFO_V3_64or32or16), (SetColorKey), + (SetChromaKey), (SetHQVFetch), (Upd_Video), (VIAVidUpdateOverlay), + (ViaOverlayHide): + * unichrome/via_video.c: (DecideOverlaySupport), (viaResetVideo), + (viaSaveVideo), (viaExitVideo), (viaInitVideo), (viaReputImage), + (viaSetupAdaptors), (viaStopVideo), (Flip), (nv12cp), + (viaDmaBlitImage), (viaPutImage), (viaQueryImageAttributes): + * unichrome/via_xvmc.c: (ViaInitXVMC): + * unichrome/via_xvpriv.h: + + Big Xv update. + - Bring Xv in sync with Xorg, which includes RV15 and RV16 support. + - Add support for PCI DMA Xv image transfer. This requires DRM >= 2.7.0, + and does not yet work on Unichrome Pro group A, since YV12->NV12 + hardware conversion is not yet implemented. + +2005-08-13 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_swov.c: (ViaSwovSurfaceDestroy): + + - Destroy video surfaces on video exit / stop. + +2005-08-13 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_driver.c: (VIAAdjustFrame) + + - Fix Xv panning also for VBEModes. + +2005-08-12 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_driver.c: (VIAEnterVT): + + - Fix segfault on EnterVT when DRI is not enabled. + (Joris van Rantwijk) + +2005-08-12 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_priv.h: + * unichrome/via_swov.c: (VIAVidUpdateOverlay): + * unichrome/via_video.c: (RegionsEqual), (viaReputImage), + (viaSetupAdaptors), (VIAVidAdjustFrame): + + - Fix Xv panning. Speed up overlay updates on window moves. + +2005-08-12 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_video.c: (viaExitVideo): + + - Fix stopvideo for all ports and adaptors. + +2005-08-10 Ivor Hewitt <ivor-at-ivor-dot-org> + + * unichrome/Imakefile: + * unichrome/via_bios.h: + * unichrome/via_ch7xxx.c: (CH7xxxPrintRegs), (ViaCH7xxxDetect), + (CH7xxxSave), (CH7xxxRestore), (CH7xxxDACSenseI2C), + (CH7xxxDACSense), (CH7011ModeIndex), (CH7019ModeIndex), + (CH7xxxModeValid), (CH7xxxModeI2C), (CH7xxxModeCrtc), + (CH7xxxTVPower), (CH7019LCDPower), (ViaCH7xxxInit): + * unichrome/via_ch7xxx.h: + * unichrome/via_driver.c: (VIAPreInit): + * unichrome/via_id.c: + * unichrome/via_mode.c: (ViaTVDetect), (ViaTVInit): + * unichrome/via_vt162x.c: (ViaVT162xDetect), (VT1625DACSenseI2C), + (VT1625DACSense), (VT1621ModeIndex), (VT1622ModeIndex), + (VT1625ModeValid), (VT1622ModeI2C), (VT1622ModeCrtc), + (VT1625Power), (ViaVT162xInit): + * unichrome/via_vt162x.h: + + - Initial steps to incorporating CH7xxx and VT1625 support; + merging patches from David George, Philip Prindeville, Terry Lewis. + +2005-07-30 Ivor Hewitt <ivor-at-ivor-dot-org> + + * libxvmc/Imakefile: + * unichrome/via_mode.c: (ViaGetMemoryBandwidth), + (ViaModePrimaryVGA), (ViaModePrimary): + * unichrome/via_swov.c: + + - Merge fixes from xorg for typos in mode setting and sync set + +2005-07-18 Ivor Hewitt <ivor-at-ivor-dot-org> + + * unichrome/via_id.c: + + - Additional card-id. Reported by Philip Prindeville. + +2005-07-04 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_driver.c: (VIAPreInit), (VIAScreenInit): + * unichrome/via_id.c: + + - Avoid calling DPMS to blank screen during init with VBEModes. + - Add another card ID. + +2005-06-29 Ivor Hewitt <ivor-at-ivor-dot-org> + + * unichrome/via_id.c: + + - Additional card-ids. Patch from Xavier Bachelot + +2005-06-26 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * libxvmc/viaLowLevelPro.c: (finish_header_agp), (syncDMA), + (syncVideo), (pciFlush), (agpFlush), (uploadHQVDeinterlace), + (uploadHQVShadow), (flushXvMCLowLevel), (flushPCIXvMCLowLevel), + (viaMpegSetSurfaceStride), (viaVideoSetSWFLipLocked), + (viaVideoSWFlipLocked), (viaMpegSetFB), (viaMpegBeginPicture), + (viaMpegReset), (viaMpegWriteSlice), (viaVideoSubPictureOffLocked), + (viaVideoSubPictureLocked), (viaBlit), (syncXvMCLowLevel), + (releaseXvMCLowLevel), (initXvMCLowLevel), (closeXvMCLowLevel): + + - Clean up the VIDEO_DMA ifdef mess before xorg inclusion. + - Make VIDEO_DMA wait for DMA quiescent before flipping, pending proper + HQV locking. + - Disable VIDEO_DMA to improve latency pending proper HQV locking. + +2005-06-17 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_mode.c: (ViaSetPrimaryDotclock), + (ViaSetSecondaryDotclock), (ViaComputeProDotClock), + (ViaModeDotClockTranslate): + + - Free dotclock on Unichrome Pro. Pls report problems with + unstable clocks. + - Minor 64-bit fixes. + +2005-06-16 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_xvmc.c: (ViaXvMCCreateContext), + (ViaXvMCCreateSurface), (ViaXvMCCreateSubpicture): + * unichrome/via_xvmc.h: + + - XvMC 64 bit fixes. XvMC now runs on K8M800 64-bit Linux. + +2005-06-12 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_bios.h: + * unichrome/via_i2c.c: + * unichrome/via_mode.c: (ViaTVRestore): + * unichrome/via_vt162x.c: (VT162xPrintRegs), (ViaVT162xDetect), + (VT162xSave), (VT162xRestore), (ViaVT162xInit): + + - Fix up the vt1623 encoder: Correct device ID, number of registers + and most of all reading from the i2cbus it is sitting on. + +2005-06-11 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_dri.c: (VIADRIScreenInit): + + - Update via_dri.c to compile with new libdri. + +2005-06-01 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_mode.c: (ViaModePrimary): + * unichrome/via_vt162x.h: + + - Fix TV-out on Unichrome Pro. To make it work CRT+TV needs to be + enabled in BIOS. Still it will hang the machine or possibly only + the display chip on X server exit. + - Import the 720x576Noscale mode for vt1622A/vt1623 from the Unichrome + driver (Terry Barnaby) + +2005-05-25 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * libxvmc/viaLowLevelPro.c: (setHQVDeinterlacing): + * libxvmc/viaXvMC.c: + * unichrome/via_driver.c: + * unichrome/via_mode.c: (ViaModePrimary): + * unichrome/via_mode.h: + * unichrome/via_vt162x.c: (ViaVT162xDetect): + + - Updated incorrect field order in libViaXvMCPro. + - Fixed warnings about unresolved int10 symbols in the Unichrome driver. + - Updated Unichrome Pro dotclocks - also for TV. + - Made the driver recognize the vt1623 TV encoder on the EPIA SP13000. + - Removed unnecessary define in viaXvMC.c. + +2005-05-16 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * libxvmc/driDrawable.c: (getDRIDrawableInfoLocked): + * libxvmc/viaXvMC.c: (releaseContextResources), + (XvMCCreateContext): + * libxvmc/xf86dri.c: (uniDRIDestroyContext), + (uniDRICreateDrawable), (uniDRIDestroyDrawable), + (uniDRIGetDrawableInfo): + * libxvmc/xf86dri.h: + + - Changed DRI client function names since they clash with + via_dri.so, causing strange problems in, for example, xine. + +2005-05-16 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_dri.c: (VIASetAgpMode), (VIADRIAgpInit): + + - Added better AGP mode control to the DDX. + +2005-05-11 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * prepare-ChangeLogSVN.pl: + + - Added the above file for generation of ChangeLog Entries. + +2005-05-11 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * libxvmc/driDrawable.c: + * libxvmc/viaLowLevel.c: (hwlLock), (hwlUnlock), + (setAGPSyncLowLevel), (viaDMATimeStampLowLevel), + (flushXvMCLowLevel), (flushPCIXvMCLowLevel), + (viaMpegSetSurfaceStride), (viaVideoSetSWFLipLocked), + (viaVideoSWFlipLocked), (viaMpegSetFB), (viaMpegBeginPicture), + (viaMpegReset), (viaMpegWriteSlice), (viaVideoSubPictureOffLocked), + (viaVideoSubPictureLocked), (viaBlit), (syncXvMCLowLevel), + (initXvMCLowLevel), (setLowLevelLocking), (closeXvMCLowLevel): + * libxvmc/viaLowLevel.h: + * libxvmc/viaLowLevelPro.c: (initHQVShadow), + (setHQVHWDeinterlacing), (setHQVDeblocking), (setHQVStartAddress), + (setHQVColorSpaceConversion), (setHQVFetchLine), (setHQVScale), + (setHQVSingleDestination), (setHQVDeinterlacing), + (setHQVTripleBuffer), (hwlLock), (hwlUnlock), (setAGPSyncLowLevel), + (viaDMATimeStampLowLevel), (viaDMAInitTimeStamp), + (uploadHQVDeinterlace), (uploadHQVShadow), (flushXvMCLowLevel), + (flushPCIXvMCLowLevel), (viaMpegSetSurfaceStride), + (viaVideoSetSWFLipLocked), (viaVideoSWFlipLocked), (viaMpegSetFB), + (viaMpegBeginPicture), (viaMpegReset), (viaMpegWriteSlice), + (viaVideoSubPictureOffLocked), (viaVideoSubPictureLocked), + (viaBlit), (syncXvMCLowLevel), (updateLowLevelBuf), + (cleanupLowLevelBuf), (initXvMCLowLevel), (setLowLevelLocking), + (closeXvMCLowLevel), (computeDownScaling), + (computeHQVScaleAndFilter), (setupBackBuffer): + * libxvmc/viaXvMC.c: (grabDecoder), (releaseContextResources), + (XvMCCreateContext), (XvMCCreateSurface), (XvMCPutSlice2), + (XvMCPutSlice), (XvMCPutSurface), (XvMCBeginSurface), + (XvMCSyncSurface), (XvMCLoadQMatrix), (XvMCCreateSubpicture), + (XvMCSetSubpicturePalette), (XvMCClearSubpicture), + (XvMCCompositeSubpicture), (XvMCBlendSubpicture2), + (XvMCSyncSubpicture), (XvMCDestroySubpicture), (XvMCFlushSurface), + (XvMCGetSurfaceStatus), (XvMCQueryAttributes), (XvMCSetAttribute), + (XvMCGetAttribute), (XvMCHideSurface): + * libxvmc/viaXvMCPriv.h: + * unichrome/via_swov.c: (ViaSwovSurfaceCreate): + * unichrome/via_video.c: (viaSetupAdaptors): + * unichrome/via_xvpriv.h: + + - Added ChangeLog to the repository. + - Made the DDX update the overlay if a change in surface format occured + while it's dimensions are still the same. + - Made the XvMCLowLevel struct opaque (void *) and not defined in the + header file. This allows for different definitions for different hardware + - Added a HQV shadow which holds the HQV context for the Unichrome Pro. + The purpose is twofold: + 1. If someone else touched the HQV since we last used it, we can upload the + whole context. + 2. We do not need to read from the HQV, which is bad because we have to + halt the DMA engine to do that. + - Added and activated mpeg deblocking for Unichrome Pro. + - Added a number of HQV utility functions for the upcoming video engine free + output. These are not activated yet. (Unichrome Pro.) + - Added HW deinterlacing functions. Deactivated, since I cannot see any visible + difference. (Unichrome Pro.) diff --git a/trunk/Makefile.am b/trunk/Makefile.am new file mode 100644 index 000000000000..50af7d527d41 --- /dev/null +++ b/trunk/Makefile.am @@ -0,0 +1,24 @@ +# Copyright 2005 Adam Jackson. +# +# 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 +# on the rights to use, copy, modify, merge, publish, distribute, sub +# license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL +# ADAM JACKSON 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. + +AUTOMAKE_OPTIONS = foreign +SUBDIRS = src man libxvmc + +EXTRA_DIST = release_notes-0.3.0 COPYING diff --git a/trunk/acinclude.m4 b/trunk/acinclude.m4 new file mode 100644 index 000000000000..127eed99d8be --- /dev/null +++ b/trunk/acinclude.m4 @@ -0,0 +1,91 @@ +dnl Copyright 2005 Red Hat, Inc +dnl +dnl Permission to use, copy, modify, distribute, and sell this software and its +dnl documentation for any purpose is hereby granted without fee, provided that +dnl the above copyright notice appear in all copies and that both that +dnl copyright notice and this permission notice appear in supporting +dnl documentation. +dnl +dnl The above copyright notice and this permission notice shall be included +dnl in all copies or substantial portions of the Software. +dnl +dnl THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +dnl OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +dnl MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +dnl IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +dnl OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +dnl ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +dnl OTHER DEALINGS IN THE SOFTWARE. +dnl +dnl Except as contained in this notice, the name of the copyright holders shall +dnl not be used in advertising or otherwise to promote the sale, use or +dnl other dealings in this Software without prior written authorization +dnl from the copyright holders. +dnl + +# XORG_DRIVER_CHECK_EXT() +# -------------------------- +# Checks for the $1 define in xorg-server.h (from the sdk). If it +# is defined, then add $1 to $REQUIRED_MODULES. + +AC_DEFUN([XORG_DRIVER_CHECK_EXT],[ + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -I`pkg-config --variable=sdkdir xorg-server`" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include "xorg-server.h" +#if !defined $1 +#error $1 not defined +#endif + ]])], + [_EXT_CHECK=yes], + [_EXT_CHECK=no]) + CFLAGS="$SAVE_CFLAGS" + AC_MSG_CHECKING([if $1 is defined]) + AC_MSG_RESULT([$_EXT_CHECK]) + if test "$_EXT_CHECK" != no; then + REQUIRED_MODULES="$REQUIRED_MODULES $2" + fi +]) +dnl Copyright 2005 Red Hat, Inc +dnl +dnl Permission to use, copy, modify, distribute, and sell this software and its +dnl documentation for any purpose is hereby granted without fee, provided that +dnl the above copyright notice appear in all copies and that both that +dnl copyright notice and this permission notice appear in supporting +dnl documentation. +dnl +dnl The above copyright notice and this permission notice shall be included +dnl in all copies or substantial portions of the Software. +dnl +dnl THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +dnl OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +dnl MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +dnl IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +dnl OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +dnl ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +dnl OTHER DEALINGS IN THE SOFTWARE. +dnl +dnl Except as contained in this notice, the name of the copyright holders shall +dnl not be used in advertising or otherwise to promote the sale, use or +dnl other dealings in this Software without prior written authorization +dnl from the copyright holders. +dnl + +# XORG_RELEASE_VERSION +# -------------------- +# Adds --with/without-release-string and changes the PACKAGE and +# PACKAGE_TARNAME to use "$PACKAGE{_TARNAME}-$RELEASE_VERSION". If +# no option is given, PACKAGE and PACKAGE_TARNAME are unchanged. + +AC_DEFUN([XORG_RELEASE_VERSION],[ + AC_ARG_WITH(release-version, + AC_HELP_STRING([--with-release-version=STRING], + [Use release version string in package name]), + [RELEASE_VERSION="$withval"], + [RELEASE_VERSION=""]) + if test "x$RELEASE_VERSION" != "x"; then + PACKAGE="$PACKAGE-$RELEASE_VERSION" + PACKAGE_TARNAME="$PACKAGE_TARNAME-$RELEASE_VERSION" + AC_MSG_NOTICE([Building with package name set to $PACKAGE]) + fi +]) diff --git a/trunk/autogen.sh b/trunk/autogen.sh new file mode 100755 index 000000000000..904cd6746c87 --- /dev/null +++ b/trunk/autogen.sh @@ -0,0 +1,12 @@ +#! /bin/sh + +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +ORIGDIR=`pwd` +cd $srcdir + +autoreconf -v --install || exit 1 +cd $ORIGDIR || exit $? + +$srcdir/configure --enable-maintainer-mode "$@" diff --git a/trunk/configure.ac b/trunk/configure.ac new file mode 100644 index 000000000000..ab31cbdcd8ad --- /dev/null +++ b/trunk/configure.ac @@ -0,0 +1,192 @@ +# Copyright 2005 Adam Jackson. +# +# 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 +# on the rights to use, copy, modify, merge, publish, distribute, sub +# license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL +# ADAM JACKSON 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. +# +# Process this file with autoconf to produce a configure script + +AC_PREREQ(2.57) +AC_INIT([xf86-video-openchrome], + 0.2.901, + [https://www.openchrome.org/trac/report], + xf86-video-openchrome) + +AC_CONFIG_SRCDIR([Makefile.am]) +AM_CONFIG_HEADER([config.h]) +AC_CONFIG_AUX_DIR(.) + +AM_INIT_AUTOMAKE([dist-bzip2]) + +AM_MAINTAINER_MODE + +# Checks for programs. +AC_DISABLE_STATIC +AC_PROG_LIBTOOL +AC_PROG_CC + +AH_TOP([#include "xorg-server.h"]) + +AC_ARG_WITH(xorg-module-dir, + AC_HELP_STRING([--with-xorg-module-dir=DIR], + [Default xorg module directory [[default=$libdir/xorg/modules]]]), + [moduledir="$withval"], + [moduledir="$libdir/xorg/modules"]) + +AC_ARG_ENABLE(dri, AC_HELP_STRING([--disable-dri], + [Disable DRI support [[default=auto]]]), + [DRI="$enableval"], + [DRI=auto]) + +AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], + [Enable debugging support [[default=no]]]), + [DEBUG="$enableval"], + [DEBUG=no]) + +AC_ARG_ENABLE(xv-debug, AC_HELP_STRING([--enable-xv-debug], + [Enable XVideo debugging support [[default=no]]]), + [XV_DEBUG="$enableval"], + [XV_DEBUG=no]) + +# Checks for extensions +XORG_DRIVER_CHECK_EXT(RANDR, randrproto) +XORG_DRIVER_CHECK_EXT(RENDER, renderproto) +XORG_DRIVER_CHECK_EXT(XV, videoproto) +XORG_DRIVER_CHECK_EXT(XF86DRI, xextproto x11) +XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto) + +# Checks for pkg-config packages +PKG_CHECK_MODULES(XORG, [xorg-server xproto xvmc fontsproto libdrm $REQUIRED_MODULES]) +sdkdir=$(pkg-config --variable=sdkdir xorg-server) + +# Checks for libraries. + +# Checks for header files. +AC_HEADER_STDC + +if test "$DRI" != no; then + AC_CHECK_FILE([${sdkdir}/dri.h], + [have_dri_h="yes"], [have_dri_h="no"]) + AC_CHECK_FILE([${sdkdir}/sarea.h], + [have_sarea_h="yes"], [have_sarea_h="no"]) + AC_CHECK_FILE([${sdkdir}/dristruct.h], + [have_dristruct_h="yes"], [have_dristruct_h="no"]) +fi + +AC_MSG_CHECKING([whether to include DRI support]) +if test x$DRI = xauto; then + if test "$have_dri_h" = yes -a \ + "$have_sarea_h" = yes -a \ + "$have_dristruct_h" = yes; then + DRI="yes" + else + DRI="no" + fi +fi +AC_MSG_RESULT([$DRI]) + +AM_CONDITIONAL(DRI, test x$DRI = xyes) +if test "$DRI" = yes; then + PKG_CHECK_MODULES(DRI, [libdrm xf86driproto]) + AC_DEFINE(XF86DRI,1,[Enable DRI driver support]) + AC_DEFINE(XF86DRI_DEVEL,1,[Enable developmental DRI driver support]) + case "$host_cpu" in + i*86) + XVMC=yes ;; + amd64*|x86_64*) + XVMC=yes ;; + *) + XVMC=no ;; + esac +else + XVMC="no" +fi + +if test "x$XVMC" = xyes; then + AC_CHECK_HEADERS(pthread.h sys/ioctl.h sys/time.h time.h,,[XVMC="no"; break],) +fi + +AC_MSG_CHECKING([whether to build XvMC driver support]) +AC_MSG_RESULT([$XVMC]) + +AM_CONDITIONAL(XVMC, test x$XVMC = xyes) + +AC_CHECK_FILE([${sdkdir}/xf86Module.h], + [have_xf86Module_h="yes"], [have_xf86Module_h="no"]) + +# Check the ABI_VIDEODRV_VERSION +SAVE_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="$CPPFLAGS $XORG_CFLAGS" + +if test "x$have_xf86Module_h" = xyes; then +AC_MSG_CHECKING([whether to use old Xv ABI]) + AC_PREPROC_IFELSE([AC_LANG_PROGRAM([[ +#include "xf86Module.h" +#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 1 +#error Old Xv ABI +#endif + ]])], + [OLD_XVABI=no], + [OLD_XVABI=yes]) +else + OLD_XVABI=yes + echo -n "xf86Module.h not found, " +fi + +CPPFLAGS="$SAVE_CPPFLAGS" + +if test "x$OLD_XVABI" = xyes; then + echo "yes." +else + echo "no." + AC_DEFINE(USE_NEW_XVABI, 1, [Use new Xv ABI (7.1RC1+)]) +fi + +AM_CONDITIONAL(DEBUG, test x$DEBUG = xyes) +if test "$DEBUG" = yes; then + AC_DEFINE(HAVE_DEBUG,1,[Enable debug support]) +fi + +AM_CONDITIONAL(XV_DEBUG, test x$XV_DEBUG = xyes) +if test "$XV_DEBUG" = yes; then + AC_DEFINE(XV_DEBUG,1,[Enable XVideo debug support]) +fi + +AC_SUBST([DRI_CFLAGS]) +AC_SUBST([XORG_CFLAGS]) +AC_SUBST([moduledir]) + +DRIVER_NAME=openchrome +AC_SUBST([DRIVER_NAME]) + +AC_DEFINE(X_USE_LINEARFB,1,[Compatibility define for older Xen]) +AC_DEFINE(X_USE_REGION_NULL,1,[Compatibility define for older Xen]) +AC_DEFINE(X_HAVE_XAAGETROP,1,[Compatibility define for older Xen]) +AC_DEFINE(X_NEED_I2CSTART,1,[Compatibility define for older Xen]) +AC_DEFINE(VIA_HAVE_EXA,1,[Build support for Exa]) + +DRIVER_MAN_SUFFIX="4" +AC_SUBST([DRIVER_MAN_SUFFIX]) + +XORG_RELEASE_VERSION + +AC_OUTPUT([ + Makefile + libxvmc/Makefile + man/Makefile + src/Makefile +]) diff --git a/trunk/libxvmc/Imakefile b/trunk/libxvmc/Imakefile new file mode 100644 index 000000000000..663204ae1523 --- /dev/null +++ b/trunk/libxvmc/Imakefile @@ -0,0 +1,59 @@ +#define DoNormalLib NormalLibXvMC +#define DoSharedLib SharedLibXvMC +#define DoDebugLib DebugLibXvMC +#define DoProfileLib ProfileLibXvMC +/*#define LibName viaXvMC*/ +#define SoRev SOXVMCREV +#define LibHeaders NO + +#include <Threads.tmpl> + +/* Anyone know how to determine this properly? + * Comment out the following to build in the x tree + */ +#define OUTOFTREE + +#ifdef OUTOFTREE +VIADRIVERSRC=../unichrome +#else +VIADRIVERSRC=$(XF86DRIVERSRC)/via +#endif + +#ifdef SharedXvMCReqs +REQUIREDLIBS = SharedXvMCReqs -lXv +#endif + +#if Malloc0ReturnsNull +ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL +#endif + + DEFINES = $(ALLOC_DEFINES) $(PICFLAGS) -DTRUE=1 -DFALSE=0 + INCLUDES = -I$(XINCLUDESRC) -I$(INCLUDESRC) -I$(XLIBSRC) -I$(EXTINCSRC) \ + -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(DRMSRCDIR)/shared-core \ + -I$(DRMSRCDIR)/shared \ + -I$(XF86OSSRC)/linux/drm/kernel -I$(VIADRIVERSRC) + SRCS = viaXvMC.c viaLowLevel.c viaLowLevelPro.c xf86dri.c driDrawable.c + OBJS = viaXvMC.o viaLowLevel.o xf86drm.o xf86drmHash.o \ + xf86drmRandom.o xf86drmSL.o xf86dri.o driDrawable.o + OBJSPRO = viaXvMC.o viaLowLevelPro.o xf86drm.o xf86drmHash.o \ + xf86drmRandom.o xf86drmSL.o xf86dri.o driDrawable.o + LINTLIBS = $(LINTXLIB) + +#include <Library.tmpl> + +SharedLibraryTarget(viaXvMC,$(SoRev),$(OBJS) $(EXTRASHAREDOBJS),.,.) +SharedLibraryTarget(viaXvMCPro,$(SoRev),$(OBJSPRO) $(EXTRASHAREDOBJS),.,.) +InstallSharedLibrary(viaXvMC,$(SoRev),$(SHLIBDIR)) +InstallSharedLibrary(viaXvMCPro,$(SoRev),$(SHLIBDIR)) + +#if defined(LinuxArchitecture) +OS_SUBDIR = linux + +LinkSourceFile(xf86drm.c,$(XF86OSSRC)/$(OS_SUBDIR)/drm) +LinkSourceFile(xf86drmHash.c,$(XF86OSSRC)/$(OS_SUBDIR)/drm) +LinkSourceFile(xf86drmRandom.c,$(XF86OSSRC)/$(OS_SUBDIR)/drm) +LinkSourceFile(xf86drmSL.c,$(XF86OSSRC)/$(OS_SUBDIR)/drm) +#endif + +DependTarget() + diff --git a/trunk/libxvmc/Makefile.am b/trunk/libxvmc/Makefile.am new file mode 100644 index 000000000000..e171c2c9ab2d --- /dev/null +++ b/trunk/libxvmc/Makefile.am @@ -0,0 +1,46 @@ +if XVMC +lib_LTLIBRARIES=libchromeXvMC.la libchromeXvMCPro.la + +libchromeXvMC_la_SOURCES = \ + viaLowLevel.c \ + driDrawable.c \ + viaXvMC.c \ + xf86dri.c \ + viaLowLevel.h \ + driDrawable.h \ + viaXvMCPriv.h \ + xf86dri.h \ + xf86dristr.h \ + vldXvMC.h +libchromeXvMCPro_la_SOURCES = \ + viaLowLevelPro.c \ + driDrawable.c \ + viaXvMC.c \ + xf86dri.c \ + viaLowLevel.h \ + driDrawable.h \ + viaXvMCPriv.h \ + xf86dri.h \ + xf86dristr.h \ + vldXvMC.h + +libchromeXvMC_la_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(top_srcdir)/src -I$(top_srcdir)/libxvmc -DTRUE=1 -DFALSE=0 +libchromeXvMC_la_LDFLAGS = -version-number 1:0:0 +libchromeXvMC_la_LIBADD = @DRI_LIBS@ + +libchromeXvMCPro_la_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(top_srcdir)/src -I$(top_srcdir)/libxvmc -DTRUE=1 -DFALSE=0 +libchromeXvMCPro_la_LDFLAGS = -version-number 1:0:0 +libchromeXvMCPro_la_LIBADD = @DRI_LIBS@ +else +EXTRA_DIST = \ + driDrawable.c \ + driDrawable.h \ + viaLowLevelPro.c \ + viaLowLevel.c \ + viaLowLevel.h \ + viaXvMC.c \ + viaXvMCPriv.h \ + xf86dri.c \ + xf86dri.h \ + xf86dristr.h +endif diff --git a/trunk/libxvmc/driDrawable.c b/trunk/libxvmc/driDrawable.c new file mode 100644 index 000000000000..1072efe07d85 --- /dev/null +++ b/trunk/libxvmc/driDrawable.c @@ -0,0 +1,173 @@ +/***************************************************************************** + * 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/trunk/libxvmc/driDrawable.h b/trunk/libxvmc/driDrawable.h new file mode 100644 index 000000000000..a758c7c711db --- /dev/null +++ b/trunk/libxvmc/driDrawable.h @@ -0,0 +1,64 @@ +/***************************************************************************** + * 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/trunk/libxvmc/viaLowLevel.c b/trunk/libxvmc/viaLowLevel.c new file mode 100644 index 000000000000..2d90f8088813 --- /dev/null +++ b/trunk/libxvmc/viaLowLevel.c @@ -0,0 +1,1055 @@ +/***************************************************************************** + * VIA Unichrome XvMC extension client lib. + * + * Copyright (c) 2004 Thomas Hellström. All rights reserved. + * Copyright (c) 2003 Andreas Robinson. 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. + */ + +/* + * Low-level functions that deal directly with the hardware. In the future, + * these functions might be implemented in a kernel module. Also, some of them + * would benefit from DMA. + * + * Authors: Andreas Robinson 2003. Thomas Hellström 2004. + */ + +#include "viaXvMCPriv.h" +#include "viaLowLevel.h" +#include <time.h> +#include <sys/time.h> +#include <stdio.h> + +typedef struct +{ + CARD32 agp_buffer[LL_AGP_CMDBUF_SIZE]; + CARD32 pci_buffer[LL_PCI_CMDBUF_SIZE]; + unsigned agp_pos; + unsigned pci_pos; + unsigned flip_pos; + int use_agp; + int agp_mode; + int agp_header_start; + int agp_index; + int fd; + drm_context_t *drmcontext; + drmLockPtr hwLock; + drmAddress mmioAddress; + drmAddress fbAddress; + unsigned fbStride; + unsigned fbDepth; + unsigned width; + unsigned height; + unsigned curWaitFlags; + int performLocking; + unsigned errors; + drm_via_mem_t tsMem; + CARD32 tsOffset; + volatile CARD32 *tsP; + CARD32 curTimeStamp; + CARD32 lastReadTimeStamp; + int agpSync; + CARD32 agpSyncTimeStamp; + unsigned chipId; +} XvMCLowLevel; + +/* + * For Other architectures than i386 these might have to be modified for + * bigendian etc. + */ + +#define MPEGIN(xl,reg) \ + *((volatile CARD32 *)(((CARD8 *)(xl)->mmioAddress) + 0xc00 + (reg))) + +#define VIDIN(ctx,reg) \ + *((volatile CARD32 *)(((CARD8 *)(ctx)->mmioAddress) + 0x200 + (reg))) + +#define REGIN(ctx,reg) \ + *((volatile CARD32 *)(((CARD8 *)(ctx)->mmioAddress) + 0x0000 + (reg))) + +#define HQV_CONTROL 0x1D0 +#define HQV_SRC_STARTADDR_Y 0x1D4 +#define HQV_SRC_STARTADDR_U 0x1D8 +#define HQV_SRC_STARTADDR_V 0x1DC +#define HQV_MINIFY_DEBLOCK 0x1E8 + +#define HQV_SW_FLIP 0x00000010 +#define HQV_FLIP_STATUS 0x00000001 +#define HQV_SUBPIC_FLIP 0x00008000 +#define HQV_FLIP_ODD 0x00000020 +#define HQV_DEINTERLACE 0x00010000 +#define HQV_FIELD_2_FRAME 0x00020000 +#define HQV_FRAME_2_FIELD 0x00040000 +#define HQV_FIELD_UV 0x00100000 +#define HQV_DEBLOCK_HOR 0x00008000 +#define HQV_DEBLOCK_VER 0x80000000 + +#define V_COMPOSE_MODE 0x98 +#define V1_COMMAND_FIRE 0x80000000 +#define V3_COMMAND_FIRE 0x40000000 + +/* SUBPICTURE Registers */ +#define SUBP_CONTROL_STRIDE 0x1C0 +#define SUBP_STARTADDR 0x1C4 +#define RAM_TABLE_CONTROL 0x1C8 +#define RAM_TABLE_READ 0x1CC + +/* SUBP_CONTROL_STRIDE 0x3c0 */ +#define SUBP_HQV_ENABLE 0x00010000 +#define SUBP_IA44 0x00020000 +#define SUBP_AI44 0x00000000 +#define SUBP_STRIDE_MASK 0x00001fff +#define SUBP_CONTROL_MASK 0x00070000 + +/* RAM_TABLE_CONTROL 0x3c8 */ +#define RAM_TABLE_RGB_ENABLE 0x00000007 + +#define VIA_REG_STATUS 0x400 +#define VIA_REG_GEMODE 0x004 +#define VIA_REG_SRCBASE 0x030 +#define VIA_REG_DSTBASE 0x034 +#define VIA_REG_PITCH 0x038 +#define VIA_REG_SRCCOLORKEY 0x01C +#define VIA_REG_KEYCONTROL 0x02C +#define VIA_REG_SRCPOS 0x008 +#define VIA_REG_DSTPOS 0x00C +#define VIA_REG_GECMD 0x000 +#define VIA_REG_DIMENSION 0x010 /* width and height */ +#define VIA_REG_FGCOLOR 0x018 + +#define VIA_VR_QUEUE_BUSY 0x00020000 /* Virtual Queue is busy */ +#define VIA_CMD_RGTR_BUSY 0x00000080 /* Command Regulator is busy */ +#define VIA_2D_ENG_BUSY 0x00000002 /* 2D Engine is busy */ +#define VIA_3D_ENG_BUSY 0x00000001 /* 3D Engine is busy */ +#define VIA_GEM_8bpp 0x00000000 +#define VIA_GEM_16bpp 0x00000100 +#define VIA_GEM_32bpp 0x00000300 +#define VIA_GEC_BLT 0x00000001 +#define VIA_PITCH_ENABLE 0x80000000 +#define VIA_GEC_INCX 0x00000000 +#define VIA_GEC_DECY 0x00004000 +#define VIA_GEC_INCY 0x00000000 +#define VIA_GEC_DECX 0x00008000 +#define VIA_GEC_FIXCOLOR_PAT 0x00002000 + +#define VIA_BLIT_CLEAR 0x00 +#define VIA_BLIT_COPY 0xCC +#define VIA_BLIT_FILL 0xF0 +#define VIA_BLIT_SET 0xFF + +#define VIA_SYNCWAITTIMEOUT 50000 /* Might be a bit conservative */ +#define VIA_DMAWAITTIMEOUT 150000 +#define VIA_VIDWAITTIMEOUT 50000 +#define VIA_XVMC_DECODERTIMEOUT 50000 /*(microseconds) */ + +#define H1_ADDR(val) (((val) >> 2) | 0xF0000000) +#define WAITFLAGS(xl, flags) \ + (xl)->curWaitFlags |= (flags) +#define BEGIN_RING_AGP(xl,size) \ + do { \ + if ((xl)->agp_pos > (LL_AGP_CMDBUF_SIZE-(size))) { \ + agpFlush(xl); \ + } \ + } while(0) +#define OUT_RING_AGP(xl, val) \ + (xl)->agp_buffer[(xl)->agp_pos++] = (val) +#define OUT_RING_QW_AGP(xl, val1, val2) \ + do { \ + (xl)->agp_buffer[(xl)->agp_pos++] = (val1); \ + (xl)->agp_buffer[(xl)->agp_pos++] = (val2); \ + } while (0) + +#define LL_HW_LOCK(xl) \ + do { \ + DRM_LOCK((xl)->fd,(xl)->hwLock,*(xl)->drmcontext,0); \ + } while(0); +#define LL_HW_UNLOCK(xl) \ + do { \ + DRM_UNLOCK((xl)->fd,(xl)->hwLock,*(xl)->drmcontext); \ + } while(0); + +/* + * We want to have two concurrent types of thread taking the hardware + * lock simulataneously. One is the video out thread that needs immediate + * access to flip an image. The other is everything else which may have + * the lock for quite some time. This is only so the video out thread can + * sneak in and display an image while other resources are busy. + */ + +void +hwlLock(void *xlp, int videoLock) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + LL_HW_LOCK(xl); +} + +void +hwlUnlock(void *xlp, int videoLock) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + LL_HW_UNLOCK(xl); +} + +static unsigned +timeDiff(struct timeval *now, struct timeval *then) +{ + return (now->tv_usec >= then->tv_usec) ? + now->tv_usec - then->tv_usec : + 1000000 - (then->tv_usec - now->tv_usec); +} + +void +setAGPSyncLowLevel(void *xlp, int val, CARD32 timeStamp) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + xl->agpSync = val; + xl->agpSyncTimeStamp = timeStamp; +} + +CARD32 +viaDMATimeStampLowLevel(void *xlp) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + if (xl->use_agp) { + viaBlit(xl, 32, xl->tsOffset, 1, xl->tsOffset, 1, 1, 1, 0, 0, + VIABLIT_FILL, xl->curTimeStamp); + return xl->curTimeStamp++; + } + return 0; +} + +static void +viaDMAWaitTimeStamp(XvMCLowLevel * xl, CARD32 timeStamp, int doSleep) +{ + struct timeval now, then; + struct timezone here; + struct timespec sleep, rem; + + if (xl->use_agp && (timeStamp > xl->lastReadTimeStamp)) { + sleep.tv_nsec = 1; + sleep.tv_sec = 0; + here.tz_minuteswest = 0; + here.tz_dsttime = 0; + gettimeofday(&then, &here); + + while (timeStamp > (xl->lastReadTimeStamp = *xl->tsP)) { + gettimeofday(&now, &here); + if (timeDiff(&now, &then) > VIA_DMAWAITTIMEOUT) { + if ((timeStamp > (xl->lastReadTimeStamp = *xl->tsP))) { + xl->errors |= LL_DMA_TIMEDOUT; + break; + } + } + if (doSleep) + nanosleep(&sleep, &rem); + } + } +} + +static int +viaDMAInitTimeStamp(XvMCLowLevel * xl) +{ + int ret = 0; + + if (xl->use_agp) { + xl->tsMem.context = *(xl->drmcontext); + xl->tsMem.size = 64; + xl->tsMem.type = VIA_MEM_VIDEO; + if (drmCommandWriteRead(xl->fd, DRM_VIA_ALLOCMEM, &xl->tsMem, + sizeof(xl->tsMem)) < 0) + return ret; + if (xl->tsMem.size != 64) + return -1; + xl->tsOffset = (xl->tsMem.offset + 31) & ~31; + xl->tsP = (CARD32 *) xl->fbAddress + (xl->tsOffset >> 2); + xl->curTimeStamp = 1; + *xl->tsP = 0; + } + return 0; +} + +static int +viaDMACleanupTimeStamp(XvMCLowLevel * xl) +{ + + if (!(xl->tsMem.size) || !xl->use_agp) + return 0; + return drmCommandWrite(xl->fd, DRM_VIA_FREEMEM, &xl->tsMem, + sizeof(xl->tsMem)); +} + +static CARD32 +viaMpegGetStatus(XvMCLowLevel * xl) +{ + return MPEGIN(xl, 0x54); +} + +static int +viaMpegIsBusy(XvMCLowLevel * xl, CARD32 mask, CARD32 idle) +{ + CARD32 tmp = viaMpegGetStatus(xl); + + /* + * Error detected. + * FIXME: Are errors really shown when error concealment is on? + */ + + if (tmp & 0x70) + return 0; + + return (tmp & mask) != idle; +} + +static void +syncDMA(XvMCLowLevel * xl, unsigned int doSleep) +{ + + /* + * Ideally, we'd like to have an interrupt wait here, but, according to second hand + * information, the hardware does not support this, although earlier S3 chips do that. + * It is therefore not implemented into the DRM, and we'll do a user space wait here. + */ + + struct timeval now, then; + struct timezone here; + struct timespec sleep, rem; + + sleep.tv_nsec = 1; + sleep.tv_sec = 0; + here.tz_minuteswest = 0; + here.tz_dsttime = 0; + gettimeofday(&then, &here); + while (!(REGIN(xl, VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY)) { + gettimeofday(&now, &here); + if (timeDiff(&now, &then) > VIA_DMAWAITTIMEOUT) { + if (!(REGIN(xl, VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY)) { + xl->errors |= LL_DMA_TIMEDOUT; + break; + } + } + if (doSleep) + nanosleep(&sleep, &rem); + } + while (REGIN(xl, VIA_REG_STATUS) & VIA_CMD_RGTR_BUSY) { + gettimeofday(&now, &here); + if (timeDiff(&now, &then) > VIA_DMAWAITTIMEOUT) { + if (REGIN(xl, VIA_REG_STATUS) & VIA_CMD_RGTR_BUSY) { + xl->errors |= LL_DMA_TIMEDOUT; + break; + } + } + if (doSleep) + nanosleep(&sleep, &rem); + } +} + +static void +syncVideo(XvMCLowLevel * xl, unsigned int doSleep) +{ + /* + * Wait for HQV completion. Nothing strange here. We assume that the HQV + * Handles syncing to the V1 / V3 engines by itself. It should be safe to + * always wait for SUBPIC_FLIP completion although subpictures are not always + * used. + */ + + struct timeval now, then; + struct timezone here; + struct timespec sleep, rem; + + sleep.tv_nsec = 1; + sleep.tv_sec = 0; + here.tz_minuteswest = 0; + here.tz_dsttime = 0; + gettimeofday(&then, &here); + while (VIDIN(xl, HQV_CONTROL) & (HQV_SW_FLIP | HQV_SUBPIC_FLIP)) { + gettimeofday(&now, &here); + if (timeDiff(&now, &then) > VIA_SYNCWAITTIMEOUT) { + if (VIDIN(xl, HQV_CONTROL) & (HQV_SW_FLIP | HQV_SUBPIC_FLIP)) { + xl->errors |= LL_VIDEO_TIMEDOUT; + break; + } + } + if (doSleep) + nanosleep(&sleep, &rem); + } +} + +static void +syncAccel(XvMCLowLevel * xl, unsigned int mode, unsigned int doSleep) +{ + struct timeval now, then; + struct timezone here; + struct timespec sleep, rem; + CARD32 mask = ((mode & LL_MODE_2D) ? VIA_2D_ENG_BUSY : 0) | + ((mode & LL_MODE_3D) ? VIA_3D_ENG_BUSY : 0); + + sleep.tv_nsec = 1; + sleep.tv_sec = 0; + here.tz_minuteswest = 0; + here.tz_dsttime = 0; + gettimeofday(&then, &here); + while (REGIN(xl, VIA_REG_STATUS) & mask) { + gettimeofday(&now, &here); + if (timeDiff(&now, &then) > VIA_SYNCWAITTIMEOUT) { + if (REGIN(xl, VIA_REG_STATUS) & mask) { + xl->errors |= LL_ACCEL_TIMEDOUT; + break; + } + } + if (doSleep) + nanosleep(&sleep, &rem); + } +} + +static void +syncMpeg(XvMCLowLevel * xl, unsigned int mode, unsigned int doSleep) +{ + /* + * Ideally, we'd like to have an interrupt wait here, but from information from VIA + * at least the MPEG completion interrupt is broken on the CLE266, which was + * discovered during validation of the chip. + */ + + struct timeval now, then; + struct timezone here; + struct timespec sleep, rem; + CARD32 busyMask = 0; + CARD32 idleVal = 0; + CARD32 ret; + + sleep.tv_nsec = 1; + sleep.tv_sec = 0; + here.tz_minuteswest = 0; + here.tz_dsttime = 0; + gettimeofday(&then, &here); + if (mode & LL_MODE_DECODER_SLICE) { + busyMask = VIA_SLICEBUSYMASK; + idleVal = VIA_SLICEIDLEVAL; + } + if (mode & LL_MODE_DECODER_IDLE) { + busyMask |= VIA_BUSYMASK; + idleVal = VIA_IDLEVAL; + } + while (viaMpegIsBusy(xl, busyMask, idleVal)) { + gettimeofday(&now, &here); + if (timeDiff(&now, &then) > VIA_XVMC_DECODERTIMEOUT) { + if (viaMpegIsBusy(xl, busyMask, idleVal)) { + xl->errors |= LL_DECODER_TIMEDOUT; + } + break; + } + if (doSleep) + nanosleep(&sleep, &rem); + } + + ret = viaMpegGetStatus(xl); + if (ret & 0x70) { + xl->errors |= ((ret & 0x70) >> 3); + } + return; +} + +static void +pciFlush(XvMCLowLevel * xl) +{ + int ret; + drm_via_cmdbuffer_t b; + unsigned mode = xl->curWaitFlags; + + b.buf = (char *)xl->pci_buffer; + b.size = xl->pci_pos * sizeof(CARD32); + if (xl->performLocking) + hwlLock(xl, 0); + if ((mode != LL_MODE_VIDEO) && (mode != 0)) + syncDMA(xl, 0); + if ((mode & LL_MODE_2D) || (mode & LL_MODE_3D)) + syncAccel(xl, mode, 0); + if (mode & LL_MODE_VIDEO) + syncVideo(xl, 0); + if (mode & (LL_MODE_DECODER_SLICE | LL_MODE_DECODER_IDLE)) + syncMpeg(xl, mode, 0); + ret = drmCommandWrite(xl->fd, DRM_VIA_PCICMD, &b, sizeof(b)); + if (xl->performLocking) + hwlUnlock(xl, 0); + if (ret) { + xl->errors |= LL_PCI_COMMAND_ERR; + } + xl->pci_pos = 0; + xl->curWaitFlags = 0; +} + +static void +agpFlush(XvMCLowLevel * xl) +{ + drm_via_cmdbuffer_t b; + int ret; + + if (xl->use_agp) { + b.buf = (char *)xl->agp_buffer; + b.size = xl->agp_pos * sizeof(CARD32); + if (xl->agpSync) { + syncXvMCLowLevel(xl, LL_MODE_DECODER_IDLE, 1, + xl->agpSyncTimeStamp); + xl->agpSync = 0; + } + if (xl->performLocking) + hwlLock(xl, 0); + do { + ret = drmCommandWrite(xl->fd, DRM_VIA_CMDBUFFER, &b, sizeof(b)); + } while (-EAGAIN == ret); + if (xl->performLocking) + hwlUnlock(xl, 0); + + if (ret) { + xl->errors |= LL_AGP_COMMAND_ERR; + } else { + xl->agp_pos = 0; + } + xl->curWaitFlags &= LL_MODE_VIDEO; + } else { + unsigned mode = xl->curWaitFlags; + + b.buf = (char *)xl->agp_buffer; + b.size = xl->agp_pos * sizeof(CARD32); + if (xl->performLocking) + hwlLock(xl, 0); + if ((mode != LL_MODE_VIDEO) && (mode != 0)) + syncDMA(xl, 0); + if ((mode & LL_MODE_2D) || (mode & LL_MODE_3D)) + syncAccel(xl, mode, 0); + if (mode & LL_MODE_VIDEO) + syncVideo(xl, 0); + if (mode & (LL_MODE_DECODER_SLICE | LL_MODE_DECODER_IDLE)) + syncMpeg(xl, mode, 0); + ret = drmCommandWrite(xl->fd, DRM_VIA_PCICMD, &b, sizeof(b)); + if (xl->performLocking) + hwlUnlock(xl, 0); + if (ret) { + xl->errors |= LL_PCI_COMMAND_ERR; + } + xl->agp_pos = 0; + xl->curWaitFlags = 0; + } +} + +unsigned +flushXvMCLowLevel(void *xlp) +{ + unsigned errors; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + if (xl->pci_pos) + pciFlush(xl); + if (xl->agp_pos) + agpFlush(xl); + errors = xl->errors; + xl->errors = 0; + return errors; +} + +void +flushPCIXvMCLowLevel(void *xlp) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + if (xl->pci_pos) + pciFlush(xl); + if (!xl->use_agp && xl->agp_pos) + agpFlush(xl); +} + +__inline static void +pciCommand(XvMCLowLevel * xl, unsigned offset, unsigned value, unsigned flags) +{ + if (xl->pci_pos > (LL_PCI_CMDBUF_SIZE - 2)) + pciFlush(xl); + if (flags) + xl->curWaitFlags |= flags; + xl->pci_buffer[xl->pci_pos++] = (offset >> 2) | 0xF0000000; + xl->pci_buffer[xl->pci_pos++] = value; +} + +void +viaMpegSetSurfaceStride(void *xlp, ViaXvMCContext * ctx) +{ + CARD32 y_stride = ctx->yStride; + CARD32 uv_stride = y_stride >> 1; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + BEGIN_RING_AGP(xl, 2); + OUT_RING_QW_AGP(xl, H1_ADDR(0xc50), + (y_stride >> 3) | ((uv_stride >> 3) << 16)); + WAITFLAGS(xl, LL_MODE_DECODER_IDLE); +} + +void +viaVideoSetSWFLipLocked(void *xlp, unsigned yOffs, unsigned uOffs, + unsigned vOffs, unsigned yStride, unsigned uvStride) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + pciCommand(xl, HQV_SRC_STARTADDR_Y | 0x200, yOffs, LL_MODE_VIDEO); + pciCommand(xl, HQV_SRC_STARTADDR_U | 0x200, uOffs, 0); + pciCommand(xl, HQV_SRC_STARTADDR_V | 0x200, vOffs, 0); +} + +void +viaVideoSWFlipLocked(void *xlp, unsigned flags, int progressiveSequence) +{ + CARD32 andWd, orWd; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + andWd = 0; + orWd = 0; + + if ((flags & XVMC_FRAME_PICTURE) == XVMC_BOTTOM_FIELD) { + andWd = 0xFFFFFFFFU; + orWd = HQV_FIELD_UV | + HQV_DEINTERLACE | + HQV_FIELD_2_FRAME | + HQV_FRAME_2_FIELD | + HQV_SW_FLIP | HQV_FLIP_ODD | HQV_FLIP_STATUS | HQV_SUBPIC_FLIP; + } else if ((flags & XVMC_FRAME_PICTURE) == XVMC_TOP_FIELD) { + andWd = ~HQV_FLIP_ODD; + orWd = HQV_FIELD_UV | + HQV_DEINTERLACE | + HQV_FIELD_2_FRAME | + HQV_FRAME_2_FIELD | + HQV_SW_FLIP | HQV_FLIP_STATUS | HQV_SUBPIC_FLIP; + } else if ((flags & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) { + andWd = ~(HQV_DEINTERLACE | + HQV_FRAME_2_FIELD | HQV_FIELD_2_FRAME | HQV_FIELD_UV); + orWd = HQV_SW_FLIP | HQV_FLIP_STATUS | HQV_SUBPIC_FLIP; + } + if (progressiveSequence) { + andWd &= ~HQV_FIELD_UV; + orWd &= ~HQV_FIELD_UV; + } + + pciCommand(xl, HQV_CONTROL | 0x200, (VIDIN(xl, + HQV_CONTROL) & andWd) | orWd, 0); +} + +void +viaMpegSetFB(void *xlp, unsigned i, + unsigned yOffs, unsigned uOffs, unsigned vOffs) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + i *= 12; + BEGIN_RING_AGP(xl, 6); + OUT_RING_QW_AGP(xl, H1_ADDR(0xc20 + i), yOffs >> 3); + OUT_RING_QW_AGP(xl, H1_ADDR(0xc24 + i), uOffs >> 3); + OUT_RING_QW_AGP(xl, H1_ADDR(0xc28 + i), vOffs >> 3); + WAITFLAGS(xl, LL_MODE_DECODER_IDLE); +} + +void +viaMpegBeginPicture(void *xlp, ViaXvMCContext * ctx, + unsigned width, unsigned height, const XvMCMpegControl * control) +{ + + unsigned j, mb_width, mb_height; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + mb_width = (width + 15) >> 4; + + mb_height = + ((control->mpeg_coding == XVMC_MPEG_2) && + (control->flags & XVMC_PROGRESSIVE_SEQUENCE)) ? + 2 * ((height + 31) >> 5) : (((height + 15) >> 4)); + + BEGIN_RING_AGP(xl, 144); + WAITFLAGS(xl, LL_MODE_DECODER_IDLE); + + OUT_RING_QW_AGP(xl, H1_ADDR(0xc00), + ((control->picture_structure & XVMC_FRAME_PICTURE) << 2) | + ((control->picture_coding_type & 3) << 4) | + ((control->flags & XVMC_ALTERNATE_SCAN) ? (1 << 6) : 0)); + + if (!(ctx->intraLoaded)) { + OUT_RING_QW_AGP(xl, H1_ADDR(0xc5c), 0); + for (j = 0; j < 64; j += 4) { + OUT_RING_QW_AGP(xl, H1_ADDR(0xc60), + ctx->intra_quantiser_matrix[j] | + (ctx->intra_quantiser_matrix[j + 1] << 8) | + (ctx->intra_quantiser_matrix[j + 2] << 16) | + (ctx->intra_quantiser_matrix[j + 3] << 24)); + } + ctx->intraLoaded = 1; + } + + if (!(ctx->nonIntraLoaded)) { + OUT_RING_QW_AGP(xl, H1_ADDR(0xc5c), 1); + for (j = 0; j < 64; j += 4) { + OUT_RING_QW_AGP(xl, H1_ADDR(0xc60), + ctx->non_intra_quantiser_matrix[j] | + (ctx->non_intra_quantiser_matrix[j + 1] << 8) | + (ctx->non_intra_quantiser_matrix[j + 2] << 16) | + (ctx->non_intra_quantiser_matrix[j + 3] << 24)); + } + ctx->nonIntraLoaded = 1; + } + + if (!(ctx->chromaIntraLoaded)) { + OUT_RING_QW_AGP(xl, H1_ADDR(0xc5c), 2); + for (j = 0; j < 64; j += 4) { + OUT_RING_QW_AGP(xl, H1_ADDR(0xc60), + ctx->chroma_intra_quantiser_matrix[j] | + (ctx->chroma_intra_quantiser_matrix[j + 1] << 8) | + (ctx->chroma_intra_quantiser_matrix[j + 2] << 16) | + (ctx->chroma_intra_quantiser_matrix[j + 3] << 24)); + } + ctx->chromaIntraLoaded = 1; + } + + if (!(ctx->chromaNonIntraLoaded)) { + OUT_RING_QW_AGP(xl, H1_ADDR(0xc5c), 3); + for (j = 0; j < 64; j += 4) { + OUT_RING_QW_AGP(xl, H1_ADDR(0xc60), + ctx->chroma_non_intra_quantiser_matrix[j] | + (ctx->chroma_non_intra_quantiser_matrix[j + 1] << 8) | + (ctx->chroma_non_intra_quantiser_matrix[j + 2] << 16) | + (ctx->chroma_non_intra_quantiser_matrix[j + 3] << 24)); + } + ctx->chromaNonIntraLoaded = 1; + } + + OUT_RING_QW_AGP(xl, H1_ADDR(0xc90), + ((mb_width * mb_height) & 0x3fff) | + ((control->flags & XVMC_PRED_DCT_FRAME) ? (1 << 14) : 0) | + ((control->flags & XVMC_TOP_FIELD_FIRST) ? (1 << 15) : 0) | + ((control->mpeg_coding == XVMC_MPEG_2) ? (1 << 16) : 0) | + ((mb_width & 0xff) << 18)); + + OUT_RING_QW_AGP(xl, H1_ADDR(0xc94), + ((control->flags & XVMC_CONCEALMENT_MOTION_VECTORS) ? 1 : 0) | + ((control->flags & XVMC_Q_SCALE_TYPE) ? 2 : 0) | + ((control->intra_dc_precision & 3) << 2) | + (((1 + 0x100000 / mb_width) & 0xfffff) << 4) | + ((control->flags & XVMC_INTRA_VLC_FORMAT) ? (1 << 24) : 0)); + + OUT_RING_QW_AGP(xl, H1_ADDR(0xc98), + (((control->FHMV_range) & 0xf) << 0) | + (((control->FVMV_range) & 0xf) << 4) | + (((control->BHMV_range) & 0xf) << 8) | + (((control->BVMV_range) & 0xf) << 12) | + ((control->flags & XVMC_SECOND_FIELD) ? (1 << 20) : 0) | + (0x0a6 << 16)); + +} + +void +viaMpegReset(void *xlp) +{ + int i, j; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + BEGIN_RING_AGP(xl, 100); + WAITFLAGS(xl, LL_MODE_DECODER_IDLE); + + for (i = 0; i < 14; i++) + OUT_RING_QW_AGP(xl, H1_ADDR(0xc08), 0); + + OUT_RING_QW_AGP(xl, H1_ADDR(0xc98), 0x400000); + + for (i = 0; i < 6; i++) { + OUT_RING_QW_AGP(xl, H1_ADDR(0xc0c), 0x43 | 0x20); + for (j = 0xc10; j < 0xc20; j += 4) + OUT_RING_QW_AGP(xl, H1_ADDR(j), 0); + } + + OUT_RING_QW_AGP(xl, H1_ADDR(0xc0c), 0xc3 | 0x20); + for (j = 0xc10; j < 0xc20; j += 4) + OUT_RING_QW_AGP(xl, H1_ADDR(j), 0); + +} + +void +viaMpegWriteSlice(void *xlp, CARD8 * slice, int nBytes, CARD32 sCode) +{ + int i, n, r; + CARD32 *buf; + int count; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + if (xl->errors & (LL_DECODER_TIMEDOUT | + LL_IDCT_FIFO_ERROR | LL_SLICE_FIFO_ERROR | LL_SLICE_FAULT)) + return; + + n = nBytes >> 2; + if (sCode) + nBytes += 4; + r = nBytes & 3; + buf = (CARD32 *) slice; + + if (r) + nBytes += 4 - r; + + nBytes += 8; + + BEGIN_RING_AGP(xl, 4); + WAITFLAGS(xl, LL_MODE_DECODER_IDLE); + + OUT_RING_QW_AGP(xl, H1_ADDR(0xc9c), nBytes); + + if (sCode) + OUT_RING_QW_AGP(xl, H1_ADDR(0xca0), sCode); + + i = 0; + count = 0; + + do { + count += (LL_AGP_CMDBUF_SIZE - 20) >> 1; + count = (count > n) ? n : count; + BEGIN_RING_AGP(xl, (count - i) << 1); + + for (; i < count; i++) { + OUT_RING_QW_AGP(xl, H1_ADDR(0xca0), *buf++); + } + } while (i < n); + + BEGIN_RING_AGP(xl, 6); + + if (r) { + OUT_RING_QW_AGP(xl, H1_ADDR(0xca0), *buf & ((1 << (r << 3)) - 1)); + } + OUT_RING_QW_AGP(xl, H1_ADDR(0xca0), 0); + OUT_RING_QW_AGP(xl, H1_ADDR(0xca0), 0); + +} + +void +viaVideoSubPictureOffLocked(void *xlp) +{ + + CARD32 stride; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + stride = VIDIN(xl, SUBP_CONTROL_STRIDE); + + pciCommand(xl, SUBP_CONTROL_STRIDE | 0x200, stride & ~SUBP_HQV_ENABLE, + LL_MODE_VIDEO); +} + +void +viaVideoSubPictureLocked(void *xlp, ViaXvMCSubPicture * pViaSubPic) +{ + + unsigned i; + CARD32 cWord; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + for (i = 0; i < VIA_SUBPIC_PALETTE_SIZE; ++i) { + pciCommand(xl, RAM_TABLE_CONTROL | 0x200, pViaSubPic->palette[i], + LL_MODE_VIDEO); + } + + pciCommand(xl, SUBP_STARTADDR | 0x200, pViaSubPic->offset, 0); + cWord = (pViaSubPic->stride & SUBP_STRIDE_MASK) | SUBP_HQV_ENABLE; + cWord |= (pViaSubPic->ia44) ? SUBP_IA44 : SUBP_AI44; + pciCommand(xl, SUBP_CONTROL_STRIDE | 0x200, cWord, 0); +} + +void +viaBlit(void *xlp, unsigned bpp, unsigned srcBase, + unsigned srcPitch, unsigned dstBase, unsigned dstPitch, + unsigned w, unsigned h, int xdir, int ydir, unsigned blitMode, + unsigned color) +{ + + CARD32 dwGEMode = 0, srcY = 0, srcX, dstY = 0, dstX; + CARD32 cmd; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + if (!w || !h) + return; + + switch (bpp) { + case 16: + dwGEMode |= VIA_GEM_16bpp; + break; + case 32: + dwGEMode |= VIA_GEM_32bpp; + break; + default: + dwGEMode |= VIA_GEM_8bpp; + break; + } + + srcX = srcBase & 31; + dstX = dstBase & 31; + switch (bpp) { + case 16: + dwGEMode |= VIA_GEM_16bpp; + srcX >>= 2; + dstX >>= 2; + break; + case 32: + dwGEMode |= VIA_GEM_32bpp; + srcX >>= 4; + dstX >>= 4; + break; + default: + dwGEMode |= VIA_GEM_8bpp; + break; + } + + BEGIN_RING_AGP(xl, 20); + WAITFLAGS(xl, LL_MODE_2D); + + OUT_RING_QW_AGP(xl, H1_ADDR(VIA_REG_GEMODE), dwGEMode); + cmd = 0; + + if (xdir < 0) { + cmd |= VIA_GEC_DECX; + srcX += (w - 1); + dstX += (w - 1); + } + if (ydir < 0) { + cmd |= VIA_GEC_DECY; + srcY += (h - 1); + dstY += (h - 1); + } + + switch (blitMode) { + case VIABLIT_TRANSCOPY: + OUT_RING_QW_AGP(xl, H1_ADDR(VIA_REG_SRCCOLORKEY), color); + OUT_RING_QW_AGP(xl, H1_ADDR(VIA_REG_KEYCONTROL), 0x4000); + cmd |= VIA_GEC_BLT | (VIA_BLIT_COPY << 24); + break; + case VIABLIT_FILL: + OUT_RING_QW_AGP(xl, H1_ADDR(VIA_REG_FGCOLOR), color); + cmd |= VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | (VIA_BLIT_FILL << 24); + break; + default: + OUT_RING_QW_AGP(xl, H1_ADDR(VIA_REG_KEYCONTROL), 0x0); + cmd |= VIA_GEC_BLT | (VIA_BLIT_COPY << 24); + } + + OUT_RING_QW_AGP(xl, H1_ADDR(VIA_REG_SRCBASE), (srcBase & ~31) >> 3); + OUT_RING_QW_AGP(xl, H1_ADDR(VIA_REG_DSTBASE), (dstBase & ~31) >> 3); + OUT_RING_QW_AGP(xl, H1_ADDR(VIA_REG_PITCH), VIA_PITCH_ENABLE | + (srcPitch >> 3) | (((dstPitch) >> 3) << 16)); + OUT_RING_QW_AGP(xl, H1_ADDR(VIA_REG_SRCPOS), ((srcY << 16) | srcX)); + OUT_RING_QW_AGP(xl, H1_ADDR(VIA_REG_DSTPOS), ((dstY << 16) | dstX)); + OUT_RING_QW_AGP(xl, H1_ADDR(VIA_REG_DIMENSION), + (((h - 1) << 16) | (w - 1))); + OUT_RING_QW_AGP(xl, H1_ADDR(VIA_REG_GECMD), cmd); +} + +unsigned +syncXvMCLowLevel(void *xlp, unsigned int mode, unsigned int doSleep, + CARD32 timeStamp) +{ + unsigned errors; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + if (mode == 0) { + errors = xl->errors; + xl->errors = 0; + return errors; + } + + if ((mode & (LL_MODE_VIDEO | LL_MODE_3D)) || !xl->use_agp) { + if (xl->performLocking) + hwlLock(xl, 0); + if ((mode != LL_MODE_VIDEO)) + syncDMA(xl, doSleep); + if (mode & LL_MODE_3D) + syncAccel(xl, mode, doSleep); + if (mode & LL_MODE_VIDEO) + syncVideo(xl, doSleep); + if (xl->performLocking) + hwlUnlock(xl, 0); + } else { + viaDMAWaitTimeStamp(xl, timeStamp, doSleep); + } + + if (mode & (LL_MODE_DECODER_SLICE | LL_MODE_DECODER_IDLE)) + syncMpeg(xl, mode, doSleep); + + errors = xl->errors; + xl->errors = 0; + + return errors; +} + +extern void * +initXvMCLowLevel(int fd, drm_context_t * ctx, + drmLockPtr hwLock, drmAddress mmioAddress, + drmAddress fbAddress, unsigned fbStride, unsigned fbDepth, + unsigned width, unsigned height, int useAgp, unsigned chipId) +{ + int ret; + XvMCLowLevel *xl; + + if (chipId == PCI_CHIP_VT3259 || chipId == PCI_CHIP_VT3364) { + fprintf(stderr, "You are using an XvMC driver for the wrong chip.\n"); + fprintf(stderr, "Chipid is 0x%04x.\n", chipId); + return NULL; + } + + xl = (XvMCLowLevel *) malloc(sizeof(XvMCLowLevel)); + + if (!xl) + return NULL; + + xl->agp_pos = 0; + xl->pci_pos = 0; + xl->use_agp = useAgp; + xl->fd = fd; + xl->drmcontext = ctx; + xl->hwLock = hwLock; + xl->mmioAddress = mmioAddress; + xl->fbAddress = fbAddress; + xl->curWaitFlags = 0; + xl->performLocking = 1; + xl->errors = 0; + xl->agpSync = 0; + ret = viaDMAInitTimeStamp(xl); + if (ret) { + free(xl); + return NULL; + } + return xl; +} + +void +setLowLevelLocking(void *xlp, int performLocking) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + xl->performLocking = performLocking; +} + +void +closeXvMCLowLevel(void *xlp) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + viaDMACleanupTimeStamp(xl); + free(xl); +} diff --git a/trunk/libxvmc/viaLowLevel.h b/trunk/libxvmc/viaLowLevel.h new file mode 100644 index 000000000000..59171d790338 --- /dev/null +++ b/trunk/libxvmc/viaLowLevel.h @@ -0,0 +1,141 @@ +/***************************************************************************** + * VIA Unichrome XvMC extension client lib. + * + * Copyright (c) 2004 The Unichrome Project. 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. + */ + +/* + * Authors: Thomas Hellström 2004 - 2005. + */ + +#ifndef VIA_LOWLEVEL_H +#define VIA_LOWLEVEL_H + +/* + * The below define is cache size sensitive. Increasing the AGP buffer size + * will enable the library to do deeper pipelining, but will degrade the + * performance in the drm dma command verifier. + */ + +#define LL_AGP_CMDBUF_SIZE (4096*2) +#define LL_PCI_CMDBUF_SIZE (4096) + +#define LL_MODE_DECODER_SLICE 0x01 +#define LL_MODE_DECODER_IDLE 0x02 +#define LL_MODE_VIDEO 0x04 +#define LL_MODE_2D 0x08 +#define LL_MODE_3D 0x10 + +/* + * Errors + */ + +#define LL_DECODER_TIMEDOUT 0x00000001 +#define LL_IDCT_FIFO_ERROR 0x00000002 +#define LL_SLICE_FIFO_ERROR 0x00000004 +#define LL_SLICE_FAULT 0x00000008 +#define LL_DMA_TIMEDOUT 0x00000010 +#define LL_VIDEO_TIMEDOUT 0x00000020 +#define LL_ACCEL_TIMEDOUT 0x00000040 +#define LL_PCI_COMMAND_ERR 0x00000080 +#define LL_AGP_COMMAND_ERR 0x00000100 + +#define VIA_SLICEBUSYMASK 0x00000200 +#define VIA_BUSYMASK 0x00000207 +#define VIA_SLICEIDLEVAL 0x00000200 +#define VIA_IDLEVAL 0x00000204 + +#include "via_drm.h" +#include "viaXvMCPriv.h" + +#define setRegion(xx,yy,ww,hh,region) \ + do { \ + (region).x = (xx); \ + (region).y = (yy); \ + (region).w = (ww); \ + (region).h = (hh); \ + } while(0) + +#define regionEqual(r1, r2) \ + ((r1).x == (r2).x && \ + (r1).y == (r2).y && \ + (r1).w == (r2).w && \ + (r1).h == (r2).h) + +extern void + *initXvMCLowLevel(int fd, drm_context_t * ctx, + drmLockPtr hwLock, drmAddress mmioAddress, + drmAddress fbAddress, unsigned fbStride, unsigned fbDepth, + unsigned width, unsigned height, int useAgp, unsigned chipId); + +extern void setLowLevelLocking(void *xlp, int perFormLocking); +extern void closeXvMCLowLevel(void *xlp); +extern void flushPCIXvMCLowLevel(void *xlp); +extern CARD32 viaDMATimeStampLowLevel(void *xlp); +extern void setAGPSyncLowLevel(void *xlp, int val, CARD32 timeStamp); + +/* + * These two functions also return and clear the current error status. + */ + +extern unsigned flushXvMCLowLevel(void *xlp); +extern unsigned syncXvMCLowLevel(void *xlp, unsigned int mode, + unsigned int doSleep, CARD32 timeStamp); + +extern void hwlUnlock(void *xlp, int videoLock); +extern void hwlLock(void *xlp, int videoLock); + +extern void viaVideoSetSWFLipLocked(void *xlp, unsigned yOffs, unsigned uOffs, + unsigned vOffs, unsigned yStride, unsigned uvStride); + +extern void viaMpegReset(void *xlp); +extern void viaMpegWriteSlice(void *xlp, CARD8 * slice, + int nBytes, CARD32 sCode); +extern void viaMpegSetSurfaceStride(void *xlp, ViaXvMCContext * ctx); +extern void viaMpegSetFB(void *xlp, unsigned i, unsigned yOffs, + unsigned uOffs, unsigned vOffs); +extern void viaMpegBeginPicture(void *xlp, ViaXvMCContext * ctx, + unsigned width, unsigned height, const XvMCMpegControl * control); + +/* + * Low-level Video functions in viaLowLevel.c + */ + +extern void viaBlit(void *xlp, unsigned bpp, unsigned srcBase, + unsigned srcPitch, unsigned dstBase, unsigned dstPitch, + unsigned w, unsigned h, int xdir, int ydir, + unsigned blitMode, unsigned color); + +extern void viaVideoSWFlipLocked(void *xlp, unsigned flags, + int progressiveSequence); + +extern void viaVideoSubPictureLocked(void *xlp, + ViaXvMCSubPicture * pViaSubPic); +extern void viaVideoSubPictureOffLocked(void *xlp); + +#define PCI_CHIP_VT3204 0x3108 /* K8M800 */ +#define PCI_CHIP_VT3259 0x3118 /* PM800/PM880/CN400 */ +#define PCI_CHIP_CLE3122 0x3122 /* CLE266 */ +#define PCI_CHIP_VT3205 0x7205 /* KM400 */ +#define PCI_CHIP_VT3327 0x3343 /* P4M890 */ +#define PCI_CHIP_VT3364 0x3371 /* P4M900 */ + +#endif diff --git a/trunk/libxvmc/viaLowLevelPro.c b/trunk/libxvmc/viaLowLevelPro.c new file mode 100644 index 000000000000..8c97e28062d3 --- /dev/null +++ b/trunk/libxvmc/viaLowLevelPro.c @@ -0,0 +1,1650 @@ +/***************************************************************************** + * VIA Unichrome XvMC extension client lib. + * + * Copyright (c) 2004 Thomas Hellström. All rights reserved. + * Copyright (c) 2003 Andreas Robinson. 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. + */ + +/* + * Low-level functions that deal directly with the hardware. In the future, + * these functions might be implemented in a kernel module. Also, some of them + * would benefit from DMA. + * + * Authors: + * Andreas Robinson 2003. (Initial decoder interface functions). + * Thomas Hellstrom 2004, 2005 (Blitting functions, AGP and locking, Unichrome Pro Video AGP). + * Ivor Hewitt 2005 (Unichrome Pro modifications and merging). + */ + +/* IH + * I've left the proReg or-ing in case we need/want to implement the V1/V3 + * register toggle too, which also moves the register locations. + * The CN400 has dual mpeg decoders, not sure at the moment whether these + * are also operated through independent registers also. + */ + +#undef VIDEO_DMA +#define HQV_USE_IRQ +#define UNICHROME_PRO + +#include "viaXvMCPriv.h" +#include "viaLowLevel.h" +#include "driDrawable.h" +#include <time.h> +#include <sys/time.h> +#include <stdio.h> + +typedef enum +{ ll_init, ll_agpBuf, ll_pciBuf, ll_timeStamp, ll_llBuf } +LLState; + +typedef struct +{ + drm_via_mem_t mem; + unsigned offset; + unsigned stride; + unsigned height; +} LowLevelBuffer; + +struct _XvMCLowLevel; + +typedef struct _ViaCommandBuffer +{ + CARD32 *buf; + CARD32 waitFlags; + unsigned pos; + unsigned bufSize; + int mode; + int header_start; + int rindex; + void (*flushFunc) (struct _ViaCommandBuffer * cb, + struct _XvMCLowLevel * xl); +} ViaCommandBuffer; + +typedef struct _XvMCLowLevel +{ + ViaCommandBuffer agpBuf, pciBuf, *videoBuf; + int use_agp; + int fd; + drm_context_t *drmcontext; + drmLockPtr hwLock; + drmAddress mmioAddress; + drmAddress fbAddress; + unsigned fbStride; + unsigned fbDepth; + unsigned width; + unsigned height; + int performLocking; + unsigned errors; + drm_via_mem_t tsMem; + CARD32 tsOffset; + volatile CARD32 *tsP; + CARD32 curTimeStamp; + CARD32 lastReadTimeStamp; + int agpSync; + CARD32 agpSyncTimeStamp; + unsigned chipId; + + /* + * Data for video-engine less display + */ + + XvMCRegion sRegion; + XvMCRegion dRegion; + LowLevelBuffer scale; + LowLevelBuffer back; + Bool downScaling; + CARD32 downScaleW; + CARD32 downScaleH; + CARD32 upScaleW; + CARD32 upScaleH; + unsigned fetch; + unsigned line; + LLState state; +} XvMCLowLevel; + +/* + * For Other architectures than i386 these might have to be modified for + * bigendian etc. + */ + +#define MPEGIN(xl,reg) \ + *((volatile CARD32 *)(((CARD8 *)(xl)->mmioAddress) + 0xc00 + (reg))) + +#define VIDIN(ctx,reg) \ + *((volatile CARD32 *)(((CARD8 *)(ctx)->mmioAddress) + 0x200 + (reg))) + +#define REGIN(ctx,reg) \ + *((volatile CARD32 *)(((CARD8 *)(ctx)->mmioAddress) + 0x0000 + (reg))) + +#define HQV_CONTROL 0x1D0 +#define HQV_SRC_OFFSET 0x1CC +#define HQV_SRC_STARTADDR_Y 0x1D4 +#define HQV_SRC_STARTADDR_U 0x1D8 +#define HQV_SRC_STARTADDR_V 0x1DC +#define HQV_MINIFY_DEBLOCK 0x1E8 + +#define REG_HQV1_INDEX 0x00001000 + +#define HQV_SW_FLIP 0x00000010 +#define HQV_FLIP_STATUS 0x00000001 +#define HQV_SUBPIC_FLIP 0x00008000 +#define HQV_FLIP_ODD 0x00000020 +#define HQV_DEINTERLACE 0x00010000 +#define HQV_FIELD_2_FRAME 0x00020000 +#define HQV_FRAME_2_FIELD 0x00040000 +#define HQV_FIELD_UV 0x00100000 +#define HQV_DEBLOCK_HOR 0x00008000 +#define HQV_DEBLOCK_VER 0x80000000 +#define HQV_YUV420 0xC0000000 +#define HQV_YUV422 0x80000000 +#define HQV_ENABLE 0x08000000 +#define HQV_GEN_IRQ 0x00000080 + +#define HQV_SCALE_ENABLE 0x00000800 +#define HQV_SCALE_DOWN 0x00001000 + +#define V_COMPOSE_MODE 0x98 +#define V1_COMMAND_FIRE 0x80000000 +#define V3_COMMAND_FIRE 0x40000000 + +/* SUBPICTURE Registers */ +#define SUBP_CONTROL_STRIDE 0x1C0 +#define SUBP_STARTADDR 0x1C4 +#define RAM_TABLE_CONTROL 0x1C8 +#define RAM_TABLE_READ 0x1CC + +/* SUBP_CONTROL_STRIDE 0x3c0 */ +#define SUBP_HQV_ENABLE 0x00010000 +#define SUBP_IA44 0x00020000 +#define SUBP_AI44 0x00000000 +#define SUBP_STRIDE_MASK 0x00001fff +#define SUBP_CONTROL_MASK 0x00070000 + +/* RAM_TABLE_CONTROL 0x3c8 */ +#define RAM_TABLE_RGB_ENABLE 0x00000007 + +#define VIA_REG_STATUS 0x400 +#define VIA_REG_GEMODE 0x004 +#define VIA_REG_SRCBASE 0x030 +#define VIA_REG_DSTBASE 0x034 +#define VIA_REG_PITCH 0x038 +#define VIA_REG_SRCCOLORKEY 0x01C +#define VIA_REG_KEYCONTROL 0x02C +#define VIA_REG_SRCPOS 0x008 +#define VIA_REG_DSTPOS 0x00C +#define VIA_REG_GECMD 0x000 +#define VIA_REG_DIMENSION 0x010 /* width and height */ +#define VIA_REG_FGCOLOR 0x018 + +#define VIA_VR_QUEUE_BUSY 0x00020000 /* Virtual Queue is busy */ +#define VIA_CMD_RGTR_BUSY 0x00000080 /* Command Regulator is busy */ +#define VIA_2D_ENG_BUSY 0x00000002 /* 2D Engine is busy */ +#define VIA_3D_ENG_BUSY 0x00000001 /* 3D Engine is busy */ +#define VIA_GEM_8bpp 0x00000000 +#define VIA_GEM_16bpp 0x00000100 +#define VIA_GEM_32bpp 0x00000300 +#define VIA_GEC_BLT 0x00000001 +#define VIA_PITCH_ENABLE 0x80000000 +#define VIA_GEC_INCX 0x00000000 +#define VIA_GEC_DECY 0x00004000 +#define VIA_GEC_INCY 0x00000000 +#define VIA_GEC_DECX 0x00008000 +#define VIA_GEC_FIXCOLOR_PAT 0x00002000 + +#define VIA_BLIT_CLEAR 0x00 +#define VIA_BLIT_COPY 0xCC +#define VIA_BLIT_FILL 0xF0 +#define VIA_BLIT_SET 0xFF + +#define VIA_SYNCWAITTIMEOUT 50000 /* Might be a bit conservative */ +#define VIA_DMAWAITTIMEOUT 150000 +#define VIA_VIDWAITTIMEOUT 50000 +#define VIA_XVMC_DECODERTIMEOUT 50000 /*(microseconds) */ + +#define VIA_AGP_HEADER5 0xFE040000 +#define VIA_AGP_HEADER6 0xFE050000 + +typedef struct +{ + CARD32 data; + Bool set; +} HQVRegister; + +#define H1_ADDR(val) (((val) >> 2) | 0xF0000000) +#define WAITFLAGS(cb, flags) \ + (cb)->waitFlags |= (flags) +#define BEGIN_RING_AGP(cb, xl, size) \ + do { \ + if ((cb)->pos > ((cb)->bufSize-(size))) { \ + cb->flushFunc(cb, xl); \ + } \ + } while(0) +#define OUT_RING_AGP(cb, val) do{ \ + (cb)->buf[(cb)->pos++] = (val); \ + } while(0); + +#define OUT_RING_QW_AGP(cb, val1, val2) \ + do { \ + (cb)->buf[(cb)->pos++] = (val1); \ + (cb)->buf[(cb)->pos++] = (val2); \ + } while (0) + +#define BEGIN_HEADER5_AGP(cb, xl, index) \ + do { \ + BEGIN_RING_AGP(cb, xl, 8); \ + (cb)->mode = VIA_AGP_HEADER5; \ + (cb)->rindex = (index); \ + (cb)->header_start = (cb)->pos; \ + (cb)->pos += 4; \ + } while (0) + +#define BEGIN_HEADER6_AGP(cb, xl) \ + do { \ + BEGIN_RING_AGP(cb, xl, 8); \ + (cb)->mode = VIA_AGP_HEADER6; \ + (cb)->header_start = (cb)->pos; \ + (cb)->pos += 4; \ + } while (0) + +#define BEGIN_HEADER5_DATA(cb, xl, size, index) \ + do { \ + if ((cb)->pos > ((cb)->bufSize - ((size) + 16))) { \ + cb->flushFunc(cb, xl); \ + BEGIN_HEADER5_AGP(cb, xl, index); \ + } else if ((cb)->mode && (((cb)->mode != VIA_AGP_HEADER5) || \ + ((cb)->rindex != index))) { \ + finish_header_agp(cb); \ + BEGIN_HEADER5_AGP((cb), xl, (index)); \ + } else if (cb->mode != VIA_AGP_HEADER5) { \ + BEGIN_HEADER5_AGP((cb), xl, (index)); \ + } \ + }while(0) + +#define BEGIN_HEADER6_DATA(cb, xl, size) \ + do{ \ + if ((cb)->pos > (cb->bufSize-(((size) << 1) + 16))) { \ + cb->flushFunc(cb, xl); \ + BEGIN_HEADER6_AGP(cb, xl); \ + } else if ((cb)->mode && ((cb)->mode != VIA_AGP_HEADER6)) { \ + finish_header_agp(cb); \ + BEGIN_HEADER6_AGP(cb, xl); \ + } \ + else if ((cb->mode != VIA_AGP_HEADER6)) { \ + BEGIN_HEADER6_AGP(cb, (xl)); \ + } \ + }while(0) + +#define HQV_SHADOW_BASE 0x3CC +#define HQV_SHADOW_SIZE 13 + +#define SETHQVSHADOW(shadow, offset, value) \ + do { \ + HQVRegister *r = (shadow) + (((offset) - HQV_SHADOW_BASE) >> 2); \ + r->data = (value); \ + r->set = TRUE; \ + } while(0) + +#define GETHQVSHADOW(shadow, offset) ((shadow)[(offset - HQV_SHADOW_BASE) >> 2].data) + +#define LL_HW_LOCK(xl) \ + do { \ + DRM_LOCK((xl)->fd,(xl)->hwLock,*(xl)->drmcontext,0); \ + } while(0); +#define LL_HW_UNLOCK(xl) \ + do { \ + DRM_UNLOCK((xl)->fd,(xl)->hwLock,*(xl)->drmcontext); \ + } while(0); + +static HQVRegister hqvShadow[HQV_SHADOW_SIZE]; + +static void +initHQVShadow(HQVRegister * r) +{ + int i; + + for (i = 0; i < HQV_SHADOW_SIZE; ++i) { + r->data = 0; + r++->set = FALSE; + } +} + +#if 0 +static void +setHQVHWDeinterlacing(HQVRegister * shadow, Bool on, Bool motionDetect, + CARD32 stride, CARD32 height) +{ + CARD32 tmp = GETHQVSHADOW(shadow, 0x3E4); + + if (!on) { + tmp &= ~((1 << 0) | (1 << 12) | (1 << 27) | (1 << 31)); + SETHQVSHADOW(shadow, 0x3E4, tmp); + return; + } + + tmp = (1 << 31) | + (4 << 28) | + (1 << 27) | + (3 << 25) | (1 << 18) | (2 << 14) | (8 << 8) | (8 << 1) | (1 << 0); + + if (motionDetect) + tmp |= (1 << 12); + + SETHQVSHADOW(shadow, 0x3E4, tmp); + + tmp = GETHQVSHADOW(shadow, 0x3DC); + tmp |= (stride * height * 1536) / 1024 & 0x7ff; + + SETHQVSHADOW(shadow, 0x3DC, tmp); + + tmp = GETHQVSHADOW(shadow, 0x3D0); + tmp |= (1 << 23); + + SETHQVSHADOW(shadow, 0x3D0, tmp); +} + +#endif + +static void +setHQVDeblocking(HQVRegister * shadow, Bool on, Bool lowPass) +{ + CARD32 tmp = GETHQVSHADOW(shadow, 0x3DC); + + if (!on) { + tmp &= ~(1 << 27); + SETHQVSHADOW(shadow, 0x3DC, tmp); + return; + } + + tmp |= (8 << 16) | (1 << 27); + if (lowPass) + tmp |= (1 << 26); + SETHQVSHADOW(shadow, 0x3DC, tmp); + + tmp = GETHQVSHADOW(shadow, 0x3D4); + tmp |= (6 << 27); + SETHQVSHADOW(shadow, 0x3D4, tmp); + + tmp = GETHQVSHADOW(shadow, 0x3D8); + tmp |= (19 << 27); + SETHQVSHADOW(shadow, 0x3D8, tmp); +} + +static void +setHQVStartAddress(HQVRegister * shadow, unsigned yOffs, unsigned uOffs, + unsigned stride, unsigned format) +{ + CARD32 tmp = GETHQVSHADOW(shadow, 0x3D4); + + tmp |= yOffs & 0x03FFFFF0; + SETHQVSHADOW(shadow, 0x3D4, tmp); + tmp = GETHQVSHADOW(shadow, 0x3D8); + tmp |= uOffs & 0x03FFFFF0; + SETHQVSHADOW(shadow, 0x3D8, tmp); + tmp = GETHQVSHADOW(shadow, 0x3F8); + tmp |= (stride & 0x1FF8); + SETHQVSHADOW(shadow, 0x3F8, tmp); + tmp = GETHQVSHADOW(shadow, 0x3D0); + + if (format == 0) { + /* + * NV12 + */ + tmp |= (0x0C << 28); + } else if (format == 1) { + /* + * RGB16 + */ + tmp |= (0x02 << 28); + } else if (format == 2) { + /* + * RGB32 + */ + ; + } + SETHQVSHADOW(shadow, 0x3D0, tmp); +} + +#if 0 + +static void +setHQVColorSpaceConversion(HQVRegister * shadow, unsigned depth, Bool on) +{ + CARD32 tmp = GETHQVSHADOW(shadow, 0x3DC); + + if (!on) { + tmp &= ~(1 << 28); + SETHQVSHADOW(shadow, 0x3DC, tmp); + return; + } + + if (depth == 32) + tmp |= (1 << 29); + tmp |= (1 << 28); + tmp &= ~(1 << 15); + SETHQVSHADOW(shadow, 0x3DC, tmp); +} + +static void +setHQVFetchLine(HQVRegister * shadow, unsigned fetch, unsigned lines) +{ + SETHQVSHADOW(shadow, 0x3E0, + ((lines - 1) & 0x7FF) | (((fetch - 1) & 0x1FFF) << 16)); +} + +static void +setHQVScale(HQVRegister * shadow, unsigned horizontal, unsigned vertical) +{ + SETHQVSHADOW(shadow, 0x3E8, + (horizontal & 0xFFFF) | ((vertical & 0xFFFF) << 16)); +} + +static void +setHQVSingleDestination(HQVRegister * shadow, unsigned offset, + unsigned stride) +{ + CARD32 tmp = GETHQVSHADOW(shadow, 0x3D0); + + tmp |= (1 << 6); + + SETHQVSHADOW(shadow, 0x3D0, tmp); + SETHQVSHADOW(shadow, 0x3EC, offset & 0x03FFFFF8); + SETHQVSHADOW(shadow, 0x3F4, stride & 0x1FF8); +} +#endif + +static void +setHQVDeinterlacing(HQVRegister * shadow, CARD32 frameType) +{ + CARD32 tmp = GETHQVSHADOW(shadow, 0x3D0); + + if ((frameType & XVMC_FRAME_PICTURE) == XVMC_TOP_FIELD) { + tmp |= HQV_FIELD_UV | + HQV_DEINTERLACE | HQV_FIELD_2_FRAME | HQV_FRAME_2_FIELD; + } else if ((frameType & XVMC_FRAME_PICTURE) == XVMC_BOTTOM_FIELD) { + tmp |= HQV_FIELD_UV | + HQV_DEINTERLACE | + HQV_FIELD_2_FRAME | HQV_FRAME_2_FIELD | HQV_FLIP_ODD; + } + SETHQVSHADOW(shadow, 0x3D0, tmp); +} + +static void +setHQVTripleBuffer(HQVRegister * shadow, Bool on) +{ + CARD32 tmp = GETHQVSHADOW(shadow, 0x3D0); + + if (on) + tmp |= (1 << 26); + else + tmp &= ~(1 << 26); + SETHQVSHADOW(shadow, 0x3D0, tmp); +} + +static void +finish_header_agp(ViaCommandBuffer * cb) +{ + int numDWords, i; + + CARD32 *hb; + + if (!cb->mode) + return; + numDWords = cb->pos - cb->header_start - 4; + hb = cb->buf + cb->header_start; + switch (cb->mode) { + case VIA_AGP_HEADER5: + hb[0] = VIA_AGP_HEADER5 | cb->rindex; + hb[1] = numDWords; + hb[2] = 0x00F50000; /* SW debug flag. (?) */ + break; + default: + hb[0] = VIA_AGP_HEADER6; + hb[1] = numDWords >> 1; + hb[2] = 0x00F60000; /* SW debug flag. (?) */ + break; + } + hb[3] = 0; + if (numDWords & 3) { + for (i = 0; i < (4 - (numDWords & 3)); ++i) + OUT_RING_AGP(cb, 0x00000000); + } + cb->mode = 0; +} + +void +hwlLock(void *xlp, int videoLock) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + LL_HW_LOCK(xl); +} + +void +hwlUnlock(void *xlp, int videoLock) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + LL_HW_UNLOCK(xl); +} + +static unsigned +timeDiff(struct timeval *now, struct timeval *then) +{ + return (now->tv_usec >= then->tv_usec) ? + now->tv_usec - then->tv_usec : + 1000000 - (then->tv_usec - now->tv_usec); +} + +void +setAGPSyncLowLevel(void *xlp, int val, CARD32 timeStamp) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + xl->agpSync = val; + xl->agpSyncTimeStamp = timeStamp; +} + +CARD32 +viaDMATimeStampLowLevel(void *xlp) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + if (xl->use_agp) { + viaBlit(xl, 32, xl->tsOffset, 1, xl->tsOffset, 1, 1, 1, 0, 0, + VIABLIT_FILL, xl->curTimeStamp); + return xl->curTimeStamp++; + } + return 0; +} + +static void +viaDMAWaitTimeStamp(XvMCLowLevel * xl, CARD32 timeStamp, int doSleep) +{ + struct timeval now, then; + struct timezone here; + struct timespec sleep, rem; + + if (xl->use_agp && (xl->lastReadTimeStamp - timeStamp > (1 << 23))) { + sleep.tv_nsec = 1; + sleep.tv_sec = 0; + here.tz_minuteswest = 0; + here.tz_dsttime = 0; + gettimeofday(&then, &here); + + while (((xl->lastReadTimeStamp = *xl->tsP) - timeStamp) > (1 << 23)) { + gettimeofday(&now, &here); + if (timeDiff(&now, &then) > VIA_DMAWAITTIMEOUT) { + if (((xl->lastReadTimeStamp = + *xl->tsP) - timeStamp) > (1 << 23)) { + xl->errors |= LL_DMA_TIMEDOUT; + break; + } + } + if (doSleep) + nanosleep(&sleep, &rem); + } + } +} + +static int +viaDMAInitTimeStamp(XvMCLowLevel * xl) +{ + int ret = 0; + + if (xl->use_agp) { + xl->tsMem.context = *(xl->drmcontext); + xl->tsMem.size = 64; + xl->tsMem.type = VIA_MEM_VIDEO; + if ((ret = drmCommandWriteRead(xl->fd, DRM_VIA_ALLOCMEM, + &xl->tsMem, sizeof(xl->tsMem))) < 0) + return ret; + if (xl->tsMem.size != 64) + return -1; + xl->tsOffset = (xl->tsMem.offset + 31) & ~31; + xl->tsP = (CARD32 *) xl->fbAddress + (xl->tsOffset >> 2); + xl->curTimeStamp = 1; + *xl->tsP = 0; + } + return 0; +} + +static int +viaDMACleanupTimeStamp(XvMCLowLevel * xl) +{ + + if (!(xl->tsMem.size) || !xl->use_agp) + return 0; + return drmCommandWrite(xl->fd, DRM_VIA_FREEMEM, &xl->tsMem, + sizeof(xl->tsMem)); +} + +static CARD32 +viaMpegGetStatus(XvMCLowLevel * xl) +{ + return MPEGIN(xl, 0x54); +} + +static int +viaMpegIsBusy(XvMCLowLevel * xl, CARD32 mask, CARD32 idle) +{ + CARD32 tmp = viaMpegGetStatus(xl); + + /* + * Error detected. + * FIXME: Are errors really shown when error concealment is on? + */ + + if (tmp & 0x70) + return 0; + + return (tmp & mask) != idle; +} + +static void +syncDMA(XvMCLowLevel * xl, unsigned int doSleep) +{ + + /* + * Ideally, we'd like to have an interrupt wait here, but, according to second hand + * information, the hardware does not support this, although earlier S3 chips do that. + * It is therefore not implemented into the DRM, and we'll do a user space wait here. + */ + + struct timeval now, then; + struct timezone here; + struct timespec sleep, rem; + + sleep.tv_nsec = 1; + sleep.tv_sec = 0; + here.tz_minuteswest = 0; + here.tz_dsttime = 0; + gettimeofday(&then, &here); + while (!(REGIN(xl, VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY)) { + gettimeofday(&now, &here); + if (timeDiff(&now, &then) > VIA_DMAWAITTIMEOUT) { + if (!(REGIN(xl, VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY)) { + xl->errors |= LL_DMA_TIMEDOUT; + break; + } + } + if (doSleep) + nanosleep(&sleep, &rem); + } + while (REGIN(xl, VIA_REG_STATUS) & VIA_CMD_RGTR_BUSY) { + gettimeofday(&now, &here); + if (timeDiff(&now, &then) > VIA_DMAWAITTIMEOUT) { + if (REGIN(xl, VIA_REG_STATUS) & VIA_CMD_RGTR_BUSY) { + xl->errors |= LL_DMA_TIMEDOUT; + break; + } + } + if (doSleep) + nanosleep(&sleep, &rem); + } +} + +#ifdef HQV_USE_IRQ +static void +syncVideo(XvMCLowLevel * xl, unsigned int doSleep) +{ + int proReg = REG_HQV1_INDEX; + + /* + * Wait for HQV completion using completion interrupt. Nothing strange here. + * Note that the interrupt handler clears the HQV_FLIP_STATUS bit, so we + * can't wait on that one. + */ + + if ((VIDIN(xl, HQV_CONTROL | proReg) & (HQV_SW_FLIP | HQV_SUBPIC_FLIP))) { + drm_via_irqwait_t irqw; + + irqw.request.irq = 1; + irqw.request.type = VIA_IRQ_ABSOLUTE; + if (drmCommandWriteRead(xl->fd, DRM_VIA_WAIT_IRQ, &irqw, + sizeof(irqw)) < 0) + xl->errors |= LL_VIDEO_TIMEDOUT; + } +} +#else +static void +syncVideo(XvMCLowLevel * xl, unsigned int doSleep) +{ + /* + * Wait for HQV completion. Nothing strange here. We assume that the HQV + * Handles syncing to the V1 / V3 engines by itself. It should be safe to + * always wait for SUBPIC_FLIP completion although subpictures are not always + * used. + */ + + struct timeval now, then; + struct timezone here; + struct timespec sleep, rem; + + int proReg = REG_HQV1_INDEX; + + sleep.tv_nsec = 1; + sleep.tv_sec = 0; + here.tz_minuteswest = 0; + here.tz_dsttime = 0; + gettimeofday(&then, &here); + while ((VIDIN(xl, + HQV_CONTROL | proReg) & (HQV_SW_FLIP | HQV_SUBPIC_FLIP))) { + gettimeofday(&now, &here); + if (timeDiff(&now, &then) > VIA_SYNCWAITTIMEOUT) { + if ((VIDIN(xl, + HQV_CONTROL | proReg) & (HQV_SW_FLIP | + HQV_SUBPIC_FLIP))) { + xl->errors |= LL_VIDEO_TIMEDOUT; + break; + } + } + if (doSleep) + nanosleep(&sleep, &rem); + } +} +#endif + +static void +syncAccel(XvMCLowLevel * xl, unsigned int mode, unsigned int doSleep) +{ + struct timeval now, then; + struct timezone here; + struct timespec sleep, rem; + CARD32 mask = ((mode & LL_MODE_2D) ? VIA_2D_ENG_BUSY : 0) | + ((mode & LL_MODE_3D) ? VIA_3D_ENG_BUSY : 0); + + sleep.tv_nsec = 1; + sleep.tv_sec = 0; + here.tz_minuteswest = 0; + here.tz_dsttime = 0; + gettimeofday(&then, &here); + while (REGIN(xl, VIA_REG_STATUS) & mask) { + gettimeofday(&now, &here); + if (timeDiff(&now, &then) > VIA_SYNCWAITTIMEOUT) { + if (REGIN(xl, VIA_REG_STATUS) & mask) { + xl->errors |= LL_ACCEL_TIMEDOUT; + break; + } + } + if (doSleep) + nanosleep(&sleep, &rem); + } +} + +static void +syncMpeg(XvMCLowLevel * xl, unsigned int mode, unsigned int doSleep) +{ + /* + * Ideally, we'd like to have an interrupt wait here, but from information from VIA + * at least the MPEG completion interrupt is broken on the CLE266, which was + * discovered during validation of the chip. + */ + + struct timeval now, then; + struct timezone here; + struct timespec sleep, rem; + CARD32 busyMask = 0; + CARD32 idleVal = 0; + CARD32 ret; + + sleep.tv_nsec = 1; + sleep.tv_sec = 0; + here.tz_minuteswest = 0; + here.tz_dsttime = 0; + gettimeofday(&then, &here); + if (mode & LL_MODE_DECODER_SLICE) { + busyMask = VIA_SLICEBUSYMASK; + idleVal = VIA_SLICEIDLEVAL; + } + if (mode & LL_MODE_DECODER_IDLE) { + busyMask |= VIA_BUSYMASK; + idleVal = VIA_IDLEVAL; + } + while (viaMpegIsBusy(xl, busyMask, idleVal)) { + gettimeofday(&now, &here); + if (timeDiff(&now, &then) > VIA_XVMC_DECODERTIMEOUT) { + if (viaMpegIsBusy(xl, busyMask, idleVal)) { + xl->errors |= LL_DECODER_TIMEDOUT; + } + break; + } + if (doSleep) + nanosleep(&sleep, &rem); + } + + ret = viaMpegGetStatus(xl); + if (ret & 0x70) { + xl->errors |= ((ret & 0x70) >> 3); + } + return; +} + +static void +pciFlush(ViaCommandBuffer * cb, XvMCLowLevel * xl) +{ + int ret; + drm_via_cmdbuffer_t b; + unsigned mode = cb->waitFlags; + + finish_header_agp(cb); + b.buf = (char *)cb->buf; + b.size = cb->pos * sizeof(CARD32); + if (xl->performLocking) + hwlLock(xl, 0); + if (((mode == LL_MODE_VIDEO) && (xl->videoBuf == &xl->agpBuf)) || + ((mode != LL_MODE_VIDEO) && (mode != 0))) + syncDMA(xl, 0); + if ((mode & LL_MODE_2D) || (mode & LL_MODE_3D)) { + syncAccel(xl, mode, 0); + } + if (mode & LL_MODE_VIDEO) { + syncVideo(xl, 1); + } + if (mode & (LL_MODE_DECODER_SLICE | LL_MODE_DECODER_IDLE)) { + syncMpeg(xl, mode, 0); + } + ret = drmCommandWrite(xl->fd, DRM_VIA_PCICMD, &b, sizeof(b)); + if (xl->performLocking) + hwlUnlock(xl, 0); + if (ret) { + xl->errors |= LL_PCI_COMMAND_ERR; + } + cb->pos = 0; + cb->waitFlags = 0; +} + +static void +agpFlush(ViaCommandBuffer * cb, XvMCLowLevel * xl) +{ + drm_via_cmdbuffer_t b; + int ret; + int i; + + finish_header_agp(cb); + if (xl->use_agp) { + b.buf = (char *)cb->buf; + b.size = cb->pos * sizeof(CARD32); + if (xl->agpSync) { + syncXvMCLowLevel(xl, LL_MODE_DECODER_IDLE, 1, + xl->agpSyncTimeStamp); + xl->agpSync = 0; + } + if (xl->performLocking) + hwlLock(xl, 0); + do { + ret = drmCommandWrite(xl->fd, DRM_VIA_CMDBUFFER, &b, sizeof(b)); + } while (-EAGAIN == ret); + if (xl->performLocking) + hwlUnlock(xl, 0); + + if (ret) { + xl->errors |= LL_AGP_COMMAND_ERR; + for (i = 0; i < cb->pos; i += 2) { + printf("0x%x, 0x%x\n", (unsigned)cb->buf[i], + (unsigned)cb->buf[i + 1]); + } + exit(-1); + } else { + cb->pos = 0; + } + cb->waitFlags &= LL_MODE_VIDEO; /* FIXME: Check this! */ + } else { + unsigned mode = cb->waitFlags; + + b.buf = (char *)cb->buf; + b.size = cb->pos * sizeof(CARD32); + if (xl->performLocking) + hwlLock(xl, 0); + if (((mode == LL_MODE_VIDEO) && (cb == &xl->agpBuf)) || + ((mode != LL_MODE_VIDEO) && (mode != 0))) + syncDMA(xl, 0); + if ((mode & LL_MODE_2D) || (mode & LL_MODE_3D)) + syncAccel(xl, mode, 0); + if (mode & LL_MODE_VIDEO) + syncVideo(xl, 1); + if (mode & (LL_MODE_DECODER_SLICE | LL_MODE_DECODER_IDLE)) + syncMpeg(xl, mode, 0); + ret = drmCommandWrite(xl->fd, DRM_VIA_PCICMD, &b, sizeof(b)); + if (xl->performLocking) + hwlUnlock(xl, 0); + if (ret) { + xl->errors |= LL_PCI_COMMAND_ERR; + } + cb->pos = 0; + cb->waitFlags = 0; + } +} + +#if 0 /* Needs debugging */ +static void +uploadHQVDeinterlace(XvMCLowLevel * xl, unsigned offset, HQVRegister * shadow, + CARD32 cur_offset, CARD32 prev_offset, CARD32 stride, + Bool top_field_first, CARD32 height) +{ + CARD32 tmp; + ViaCommandBuffer *cb = &xl->agpBuf; + + BEGIN_HEADER6_DATA(cb, xl, 9); + tmp = GETHQVSHADOW(shadow, 0x3F8); + tmp &= ~(3 << 30); + tmp |= (1 << 30); + OUT_RING_QW_AGP(cb, 0x3F8 + offset, tmp); + OUT_RING_QW_AGP(cb, 0x3D4 + offset, prev_offset + + ((top_field_first) ? stride : 0)); + OUT_RING_QW_AGP(cb, 0x3D8 + offset, prev_offset + stride * height); + tmp &= ~(3 << 30); + tmp |= (2 << 30); + OUT_RING_QW_AGP(cb, 0x3F8 + offset, tmp); + OUT_RING_QW_AGP(cb, 0x3D4 + offset, cur_offset + + ((top_field_first) ? 0 : stride)); + OUT_RING_QW_AGP(cb, 0x3D8 + offset, cur_offset + stride * height); + tmp |= (3 << 30); + OUT_RING_QW_AGP(cb, 0x3F8 + offset, tmp); + OUT_RING_QW_AGP(cb, 0x3D4 + offset, cur_offset + + ((top_field_first) ? stride : 0)); + OUT_RING_QW_AGP(cb, 0x3D8 + offset, cur_offset + stride * height); +} + +#endif + +static void +uploadHQVShadow(XvMCLowLevel * xl, unsigned offset, HQVRegister * shadow, + Bool flip) +{ + int i; + CARD32 tmp; + ViaCommandBuffer *cb = xl->videoBuf; + + BEGIN_HEADER6_DATA(cb, xl, HQV_SHADOW_SIZE); + WAITFLAGS(cb, LL_MODE_VIDEO); + + if (shadow[0].set) + OUT_RING_QW_AGP(cb, 0x3CC + offset, 0); + + for (i = 2; i < HQV_SHADOW_SIZE; ++i) { + if (shadow[i].set) { + OUT_RING_QW_AGP(cb, offset + HQV_SHADOW_BASE + (i << 2), + shadow[i].data); + shadow[i].set = FALSE; + } + } + + /* + * Finally the control register for flip. + */ + + if (flip) { + tmp = GETHQVSHADOW(shadow, 0x3D0); + OUT_RING_QW_AGP(cb, offset + HQV_CONTROL + 0x200, + HQV_ENABLE | HQV_GEN_IRQ | HQV_SUBPIC_FLIP | HQV_SW_FLIP | tmp); + } + shadow[0].set = FALSE; + shadow[1].set = FALSE; +} + +unsigned +flushXvMCLowLevel(void *xlp) +{ + unsigned errors; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + if (xl->pciBuf.pos) + pciFlush(&xl->pciBuf, xl); + if (xl->agpBuf.pos) + agpFlush(&xl->agpBuf, xl); + errors = xl->errors; + if (errors) + printf("Error 0x%x\n", errors); + xl->errors = 0; + return errors; +} + +void +flushPCIXvMCLowLevel(void *xlp) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + if (xl->pciBuf.pos) + pciFlush(&xl->pciBuf, xl); + if ((!xl->use_agp && xl->agpBuf.pos)) + agpFlush(&xl->agpBuf, xl); +} + +void +viaMpegSetSurfaceStride(void *xlp, ViaXvMCContext * ctx) +{ + CARD32 y_stride = ctx->yStride; + CARD32 uv_stride = y_stride >> 1; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + ViaCommandBuffer *cb = &xl->agpBuf; + + BEGIN_HEADER6_DATA(cb, xl, 1); + OUT_RING_QW_AGP(cb, 0xc50, (y_stride >> 3) | ((uv_stride >> 3) << 16)); + WAITFLAGS(cb, LL_MODE_DECODER_IDLE); +} + +void +viaVideoSetSWFLipLocked(void *xlp, unsigned yOffs, unsigned uOffs, + unsigned vOffs, unsigned yStride, unsigned uvStride) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + initHQVShadow(hqvShadow); + setHQVStartAddress(hqvShadow, yOffs, vOffs, yStride, 0); + if (xl->videoBuf == &xl->agpBuf) + syncDMA(xl, 1); + syncVideo(xl, 1); + uploadHQVShadow(xl, REG_HQV1_INDEX, hqvShadow, FALSE); + xl->videoBuf->flushFunc(xl->videoBuf, xl); +} + +void +viaVideoSWFlipLocked(void *xlp, unsigned flags, Bool progressiveSequence) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + setHQVDeinterlacing(hqvShadow, flags); + setHQVDeblocking(hqvShadow, + ((flags & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE), TRUE); + setHQVTripleBuffer(hqvShadow, TRUE); + if (xl->videoBuf == &xl->agpBuf) + syncDMA(xl, 1); + syncVideo(xl, 1); + uploadHQVShadow(xl, REG_HQV1_INDEX, hqvShadow, TRUE); + xl->videoBuf->flushFunc(xl->videoBuf, xl); +} + +void +viaMpegSetFB(void *xlp, unsigned i, + unsigned yOffs, unsigned uOffs, unsigned vOffs) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + ViaCommandBuffer *cb = &xl->agpBuf; + + i *= (4 * 2); + BEGIN_HEADER6_DATA(cb, xl, 2); + OUT_RING_QW_AGP(cb, 0xc28 + i, yOffs >> 3); + OUT_RING_QW_AGP(cb, 0xc2c + i, vOffs >> 3); + + WAITFLAGS(cb, LL_MODE_DECODER_IDLE); +} + +void +viaMpegBeginPicture(void *xlp, ViaXvMCContext * ctx, + unsigned width, unsigned height, const XvMCMpegControl * control) +{ + + unsigned j, mb_width, mb_height; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + ViaCommandBuffer *cb = &xl->agpBuf; + + mb_width = (width + 15) >> 4; + + mb_height = + ((control->mpeg_coding == XVMC_MPEG_2) && + (control->flags & XVMC_PROGRESSIVE_SEQUENCE)) ? + 2 * ((height + 31) >> 5) : (((height + 15) >> 4)); + + BEGIN_HEADER6_DATA(cb, xl, 72); + WAITFLAGS(cb, LL_MODE_DECODER_IDLE); + + OUT_RING_QW_AGP(cb, 0xc00, + ((control->picture_structure & XVMC_FRAME_PICTURE) << 2) | + ((control->picture_coding_type & 3) << 4) | + ((control->flags & XVMC_ALTERNATE_SCAN) ? (1 << 6) : 0)); + + if (!(ctx->intraLoaded)) { + OUT_RING_QW_AGP(cb, 0xc5c, 0); + for (j = 0; j < 64; j += 4) { + OUT_RING_QW_AGP(cb, 0xc60, + ctx->intra_quantiser_matrix[j] | + (ctx->intra_quantiser_matrix[j + 1] << 8) | + (ctx->intra_quantiser_matrix[j + 2] << 16) | + (ctx->intra_quantiser_matrix[j + 3] << 24)); + } + ctx->intraLoaded = 1; + } + + if (!(ctx->nonIntraLoaded)) { + OUT_RING_QW_AGP(cb, 0xc5c, 1); + for (j = 0; j < 64; j += 4) { + OUT_RING_QW_AGP(cb, 0xc60, + ctx->non_intra_quantiser_matrix[j] | + (ctx->non_intra_quantiser_matrix[j + 1] << 8) | + (ctx->non_intra_quantiser_matrix[j + 2] << 16) | + (ctx->non_intra_quantiser_matrix[j + 3] << 24)); + } + ctx->nonIntraLoaded = 1; + } + + if (!(ctx->chromaIntraLoaded)) { + OUT_RING_QW_AGP(cb, 0xc5c, 2); + for (j = 0; j < 64; j += 4) { + OUT_RING_QW_AGP(cb, 0xc60, + ctx->chroma_intra_quantiser_matrix[j] | + (ctx->chroma_intra_quantiser_matrix[j + 1] << 8) | + (ctx->chroma_intra_quantiser_matrix[j + 2] << 16) | + (ctx->chroma_intra_quantiser_matrix[j + 3] << 24)); + } + ctx->chromaIntraLoaded = 1; + } + + if (!(ctx->chromaNonIntraLoaded)) { + OUT_RING_QW_AGP(cb, 0xc5c, 3); + for (j = 0; j < 64; j += 4) { + OUT_RING_QW_AGP(cb, 0xc60, + ctx->chroma_non_intra_quantiser_matrix[j] | + (ctx->chroma_non_intra_quantiser_matrix[j + 1] << 8) | + (ctx->chroma_non_intra_quantiser_matrix[j + 2] << 16) | + (ctx->chroma_non_intra_quantiser_matrix[j + 3] << 24)); + } + ctx->chromaNonIntraLoaded = 1; + } + + OUT_RING_QW_AGP(cb, 0xc90, + ((mb_width * mb_height) & 0x3fff) | + ((control->flags & XVMC_PRED_DCT_FRAME) ? (1 << 14) : 0) | + ((control->flags & XVMC_TOP_FIELD_FIRST) ? (1 << 15) : 0) | + ((control->mpeg_coding == XVMC_MPEG_2) ? (1 << 16) : 0) | + ((mb_width & 0xff) << 18)); + + OUT_RING_QW_AGP(cb, 0xc94, + ((control->flags & XVMC_CONCEALMENT_MOTION_VECTORS) ? 1 : 0) | + ((control->flags & XVMC_Q_SCALE_TYPE) ? 2 : 0) | + ((control->intra_dc_precision & 3) << 2) | + (((1 + 0x100000 / mb_width) & 0xfffff) << 4) | + ((control->flags & XVMC_INTRA_VLC_FORMAT) ? (1 << 24) : 0)); + + OUT_RING_QW_AGP(cb, 0xc98, + (((control->FHMV_range) & 0xf) << 0) | + (((control->FVMV_range) & 0xf) << 4) | + (((control->BHMV_range) & 0xf) << 8) | + (((control->BVMV_range) & 0xf) << 12) | + ((control->flags & XVMC_SECOND_FIELD) ? (1 << 20) : 0) | + (0x0a6 << 16)); + +} + +void +viaMpegReset(void *xlp) +{ + int i, j; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + ViaCommandBuffer *cb = &xl->agpBuf; + + BEGIN_HEADER6_DATA(cb, xl, 99); + WAITFLAGS(cb, LL_MODE_DECODER_IDLE); + + OUT_RING_QW_AGP(cb, 0xcf0, 0); + + for (i = 0; i < 6; i++) { + OUT_RING_QW_AGP(cb, 0xcc0, 0); + OUT_RING_QW_AGP(cb, 0xc0c, 0x43 | 0x20); + for (j = 0xc10; j < 0xc20; j += 4) + OUT_RING_QW_AGP(cb, j, 0); + } + + OUT_RING_QW_AGP(cb, 0xc0c, 0x1c3); + for (j = 0xc10; j < 0xc20; j += 4) + OUT_RING_QW_AGP(cb, j, 0); + + for (i = 0; i < 19; i++) + OUT_RING_QW_AGP(cb, 0xc08, 0); + + OUT_RING_QW_AGP(cb, 0xc98, 0x400000); + + for (i = 0; i < 6; i++) { + OUT_RING_QW_AGP(cb, 0xcc0, 0); + OUT_RING_QW_AGP(cb, 0xc0c, 0x1c3 | 0x20); + for (j = 0xc10; j < 0xc20; j += 4) + OUT_RING_QW_AGP(cb, j, 0); + } + OUT_RING_QW_AGP(cb, 0xcf0, 0); + +} + +void +viaMpegWriteSlice(void *xlp, CARD8 * slice, int nBytes, CARD32 sCode) +{ + int i, n, r; + CARD32 *buf; + int count; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + ViaCommandBuffer *cb = &xl->agpBuf; + + if (xl->errors & (LL_DECODER_TIMEDOUT | + LL_IDCT_FIFO_ERROR | LL_SLICE_FIFO_ERROR | LL_SLICE_FAULT)) + return; + + n = nBytes >> 2; + if (sCode) + nBytes += 4; + r = nBytes & 3; + buf = (CARD32 *) slice; + + if (r) + nBytes += 4 - r; + + nBytes += 8; + + BEGIN_HEADER6_DATA(cb, xl, 2); + WAITFLAGS(cb, LL_MODE_DECODER_IDLE); + OUT_RING_QW_AGP(cb, 0xc9c, nBytes); + + if (sCode) + OUT_RING_QW_AGP(cb, 0xca0, sCode); + + i = 0; + count = 0; + + do { + count += (LL_AGP_CMDBUF_SIZE - 20); + count = (count > n) ? n : count; + BEGIN_HEADER5_DATA(cb, xl, (count - i), 0xca0); + + for (; i < count; i++) { + OUT_RING_AGP(cb, *buf++); + } + finish_header_agp(cb); + } while (i < n); + + BEGIN_HEADER5_DATA(cb, xl, 3, 0xca0); + + if (r) { + OUT_RING_AGP(cb, *buf & ((1 << (r << 3)) - 1)); + } + OUT_RING_AGP(cb, 0); + OUT_RING_AGP(cb, 0); + finish_header_agp(cb); +} + +void +viaVideoSubPictureOffLocked(void *xlp) +{ + + CARD32 stride; + int proReg = REG_HQV1_INDEX; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + ViaCommandBuffer *cb = xl->videoBuf; + + if (xl->videoBuf == &xl->agpBuf) + syncDMA(xl, 1); + stride = VIDIN(xl, proReg | SUBP_CONTROL_STRIDE); + WAITFLAGS(cb, LL_MODE_VIDEO); + BEGIN_HEADER6_DATA(cb, xl, 1); + OUT_RING_QW_AGP(cb, proReg | SUBP_CONTROL_STRIDE | 0x200, + stride & ~SUBP_HQV_ENABLE); +} + +void +viaVideoSubPictureLocked(void *xlp, ViaXvMCSubPicture * pViaSubPic) +{ + + unsigned i; + CARD32 cWord; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + int proReg = REG_HQV1_INDEX; + ViaCommandBuffer *cb = xl->videoBuf; + + if (xl->videoBuf == &xl->agpBuf) + syncDMA(xl, 1); + WAITFLAGS(cb, LL_MODE_VIDEO); + BEGIN_HEADER6_DATA(cb, xl, VIA_SUBPIC_PALETTE_SIZE + 2); + for (i = 0; i < VIA_SUBPIC_PALETTE_SIZE; ++i) { + OUT_RING_QW_AGP(cb, proReg | RAM_TABLE_CONTROL | 0x200, + pViaSubPic->palette[i]); + } + + cWord = (pViaSubPic->stride & SUBP_STRIDE_MASK) | SUBP_HQV_ENABLE; + cWord |= (pViaSubPic->ia44) ? SUBP_IA44 : SUBP_AI44; + OUT_RING_QW_AGP(cb, proReg | SUBP_STARTADDR | 0x200, pViaSubPic->offset); + OUT_RING_QW_AGP(cb, proReg | SUBP_CONTROL_STRIDE | 0x200, cWord); +} + +void +viaBlit(void *xlp, unsigned bpp, unsigned srcBase, + unsigned srcPitch, unsigned dstBase, unsigned dstPitch, + unsigned w, unsigned h, int xdir, int ydir, unsigned blitMode, + unsigned color) +{ + + CARD32 dwGEMode = 0, srcY = 0, srcX, dstY = 0, dstX; + CARD32 cmd; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + ViaCommandBuffer *cb = &xl->agpBuf; + + if (!w || !h) + return; + + finish_header_agp(cb); + + switch (bpp) { + case 16: + dwGEMode |= VIA_GEM_16bpp; + break; + case 32: + dwGEMode |= VIA_GEM_32bpp; + break; + default: + dwGEMode |= VIA_GEM_8bpp; + break; + } + + srcX = srcBase & 31; + dstX = dstBase & 31; + switch (bpp) { + case 16: + dwGEMode |= VIA_GEM_16bpp; + srcX >>= 2; + dstX >>= 2; + break; + case 32: + dwGEMode |= VIA_GEM_32bpp; + srcX >>= 4; + dstX >>= 4; + break; + default: + dwGEMode |= VIA_GEM_8bpp; + break; + } + + BEGIN_RING_AGP(cb, xl, 20); + WAITFLAGS(cb, LL_MODE_2D); + + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_GEMODE), dwGEMode); + cmd = 0; + + if (xdir < 0) { + cmd |= VIA_GEC_DECX; + srcX += (w - 1); + dstX += (w - 1); + } + if (ydir < 0) { + cmd |= VIA_GEC_DECY; + srcY += (h - 1); + dstY += (h - 1); + } + + switch (blitMode) { + case VIABLIT_TRANSCOPY: + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_SRCCOLORKEY), color); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_KEYCONTROL), 0x4000); + cmd |= VIA_GEC_BLT | (VIA_BLIT_COPY << 24); + break; + case VIABLIT_FILL: + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_FGCOLOR), color); + cmd |= VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | (VIA_BLIT_FILL << 24); + break; + default: + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_KEYCONTROL), 0x0); + cmd |= VIA_GEC_BLT | (VIA_BLIT_COPY << 24); + } + + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_SRCBASE), (srcBase & ~31) >> 3); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_DSTBASE), (dstBase & ~31) >> 3); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_PITCH), VIA_PITCH_ENABLE | + (srcPitch >> 3) | (((dstPitch) >> 3) << 16)); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_SRCPOS), ((srcY << 16) | srcX)); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_DSTPOS), ((dstY << 16) | dstX)); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_DIMENSION), + (((h - 1) << 16) | (w - 1))); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_GECMD), cmd); +} + +unsigned +syncXvMCLowLevel(void *xlp, unsigned int mode, unsigned int doSleep, + CARD32 timeStamp) +{ + unsigned errors; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + if (mode == 0) { + errors = xl->errors; + xl->errors = 0; + return errors; + } + + if ((mode & (LL_MODE_VIDEO | LL_MODE_3D)) || !xl->use_agp) { + if (xl->performLocking) + hwlLock(xl, 0); + if ((xl->videoBuf == &xl->agpBuf) || (mode != LL_MODE_VIDEO)) + syncDMA(xl, doSleep); + if (mode & LL_MODE_3D) + syncAccel(xl, mode, doSleep); + if (mode & LL_MODE_VIDEO) + syncVideo(xl, doSleep); + if (xl->performLocking) + hwlUnlock(xl, 0); + } else { + viaDMAWaitTimeStamp(xl, timeStamp, doSleep); + } + + if (mode & (LL_MODE_DECODER_SLICE | LL_MODE_DECODER_IDLE)) + syncMpeg(xl, mode, doSleep); + + errors = xl->errors; + xl->errors = 0; + + return errors; +} + +static int +updateLowLevelBuf(XvMCLowLevel * xl, LowLevelBuffer * buf, + unsigned width, unsigned height) +{ + unsigned stride, size; + drm_via_mem_t *mem = &buf->mem; + int ret; + + stride = (width + 31) & ~31; + size = stride * height + (xl->fbDepth >> 3); + + if (size != mem->size) { + if (mem->size) + drmCommandWrite(xl->fd, DRM_VIA_FREEMEM, mem, sizeof(mem)); + mem->context = *(xl->drmcontext); + mem->size = size; + mem->type = VIA_MEM_VIDEO; + + if (((ret = drmCommandWriteRead(xl->fd, DRM_VIA_ALLOCMEM, mem, + sizeof(mem))) < 0) || mem->size != size) { + mem->size = 0; + return -1; + } + } + + buf->offset = (mem->offset + 31) & ~31; + buf->stride = stride; + buf->height = height; + return 0; +} + +static void +cleanupLowLevelBuf(XvMCLowLevel * xl, LowLevelBuffer * buf) +{ + drm_via_mem_t *mem = &buf->mem; + + if (mem->size) + drmCommandWrite(xl->fd, DRM_VIA_FREEMEM, mem, sizeof(mem)); + mem->size = 0; +} + +static void * +releaseXvMCLowLevel(XvMCLowLevel * xl) +{ + switch (xl->state) { + case ll_llBuf: + cleanupLowLevelBuf(xl, &xl->scale); + case ll_timeStamp: + viaDMACleanupTimeStamp(xl); + case ll_pciBuf: + free(xl->pciBuf.buf); + case ll_agpBuf: + free(xl->agpBuf.buf); + case ll_init: + free(xl); + default: + ; + } + return NULL; +} + +void * +initXvMCLowLevel(int fd, drm_context_t * ctx, + drmLockPtr hwLock, drmAddress mmioAddress, + drmAddress fbAddress, unsigned fbStride, unsigned fbDepth, + unsigned width, unsigned height, int useAgp, unsigned chipId) +{ + XvMCLowLevel *xl; + + if (chipId != PCI_CHIP_VT3259 && chipId != PCI_CHIP_VT3364) { + fprintf(stderr, "You are using an XvMC driver for the wrong chip.\n"); + fprintf(stderr, "Chipid is 0x%04x.\n", chipId); + return NULL; + } + + xl = (XvMCLowLevel *) malloc(sizeof(XvMCLowLevel)); + if (!xl) + return NULL; + xl->state = ll_init; + + xl->agpBuf.buf = (CARD32 *) malloc(LL_AGP_CMDBUF_SIZE * sizeof(CARD32)); + if (!xl->agpBuf.buf) + return releaseXvMCLowLevel(xl); + xl->state = ll_agpBuf; + xl->agpBuf.bufSize = LL_AGP_CMDBUF_SIZE; + xl->agpBuf.flushFunc = &agpFlush; + xl->agpBuf.pos = 0; + xl->agpBuf.mode = 0; + xl->agpBuf.waitFlags = 0; + + xl->pciBuf.buf = (CARD32 *) malloc(LL_PCI_CMDBUF_SIZE * sizeof(CARD32)); + if (!xl->pciBuf.buf) + return releaseXvMCLowLevel(xl); + xl->state = ll_pciBuf; + xl->pciBuf.bufSize = LL_PCI_CMDBUF_SIZE; + xl->pciBuf.flushFunc = &pciFlush; + xl->pciBuf.pos = 0; + xl->pciBuf.mode = 0; + xl->pciBuf.waitFlags = 0; + + xl->use_agp = useAgp; + xl->fd = fd; + xl->drmcontext = ctx; + xl->hwLock = hwLock; + xl->mmioAddress = mmioAddress; + xl->fbAddress = fbAddress; + xl->fbDepth = fbDepth; + xl->fbStride = fbStride; + xl->width = width; + xl->height = height; + xl->performLocking = 1; + xl->errors = 0; + xl->agpSync = 0; + xl->chipId = chipId; + + if (viaDMAInitTimeStamp(xl)) + return releaseXvMCLowLevel(xl); + xl->state = ll_timeStamp; + + xl->scale.mem.size = 0; + xl->back.mem.size = 0; + + if (updateLowLevelBuf(xl, &xl->scale, width, height)) + return releaseXvMCLowLevel(xl); + xl->state = ll_llBuf; + +#ifdef VIDEO_DMA + xl->videoBuf = &xl->agpBuf; +#else + xl->videoBuf = &xl->pciBuf; +#endif + + return xl; +} + +void +setLowLevelLocking(void *xlp, int performLocking) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + xl->performLocking = performLocking; +} + +void +closeXvMCLowLevel(void *xlp) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + releaseXvMCLowLevel(xl); +} + +#if 0 /* Under development */ +static CARD32 +computeDownScaling(int dst, int *src) +{ + CARD32 value = 0x800; + + while (*src > dst) { + *src >>= 1; + value--; + } + return value; +} + +static void +computeHQVScaleAndFilter(XvMCLowLevel * xl) +{ + int srcW, srcH; + const XvMCRegion *src = &xl->sRegion, *back = &xl->dRegion; + + xl->downScaling = FALSE; + + if (back->w < src->w || back->h < src->h) { + + xl->downScaling = TRUE; + srcW = src->w; + srcH = src->h; + + xl->downScaleW = (back->w >= srcW) ? 0 : + HQV_SCALE_ENABLE | HQV_SCALE_DOWN | + (computeDownScaling(back->w, &srcW)); + + xl->downScaleH = (back->h >= srcH) ? 0 : + HQV_SCALE_ENABLE | HQV_SCALE_DOWN | + (computeDownScaling(back->h, &srcH)); + + } + + xl->upScaleW = + (back->w == srcW) ? 0 : (0x800 * srcW / back->w) | HQV_SCALE_ENABLE; + xl->upScaleH = + (back->h == srcH) ? 0 : (0x800 * srcH / back->h) | HQV_SCALE_ENABLE; +} + +static int +setupBackBuffer(XvMCLowLevel * xl) +{ + return updateLowLevelBuf(xl, &xl->back, xl->dRegion.w, xl->dRegion.h); +} + +#endif diff --git a/trunk/libxvmc/viaXvMC.c b/trunk/libxvmc/viaXvMC.c new file mode 100644 index 000000000000..bf4692c97c3a --- /dev/null +++ b/trunk/libxvmc/viaXvMC.c @@ -0,0 +1,1947 @@ +/***************************************************************************** + * VIA Unichrome XvMC extension client lib. + * + * Copyright (c) 2004-2005 Thomas Hellström. 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. + */ + +/* + *Author: Thomas Hellström, 2004. + *Bugfixes by among others Pascal Brisset and Terry Barnaby. + *DRI protocol support by Thomas Hellström, 2005. + */ + +#undef WAITPAUSE + +#include "viaXvMCPriv.h" +#include "viaLowLevel.h" +#include <stdio.h> +#include <sys/ioctl.h> +#include <sys/time.h> +#include <time.h> +#include <fourcc.h> +#include <X11/extensions/Xv.h> +#include <xf86drm.h> +#include <pthread.h> +#include "vldXvMC.h" +#include "xf86dri.h" +#include "driDrawable.h" + +#define SAREAPTR(ctx) ((ViaXvMCSAreaPriv *) \ + (((CARD8 *)(ctx)->sAreaAddress) + \ + (ctx)->sAreaPrivOffset)) + +typedef struct +{ + int major; + int minor; + int patchlevel; +} ViaDRMVersion; + +static int error_base; +static int event_base; +static unsigned numContexts = 0; +static int globalFD; +static drmAddress sAreaAddress; +static drmAddress fbAddress; +static drmAddress mmioAddress; +static const ViaDRMVersion drmExpected = { 2, 0, 0 }; +static const ViaDRMVersion drmCompat = { 2, 0, 0 }; + +#define FOURCC_XVMC (('C' << 24) + ('M' << 16) + ('V' << 8) + 'X') + +#define ppthread_mutex_lock(arg) \ + { \ + pthread_mutex_lock(arg); \ + } \ + +#define ppthread_mutex_unlock(arg) \ + { \ + pthread_mutex_unlock(arg); \ + } \ + +static unsigned +yOffs(ViaXvMCSurface * srf) +{ + return srf->offsets[0]; +} + +static unsigned +vOffs(ViaXvMCSurface * srf) +{ + return srf->offsets[0] + srf->yStride * srf->height; +} + +static unsigned +uOffs(ViaXvMCSurface * srf) +{ + return srf->offsets[0] + (srf->yStride * srf->height) + + (srf->yStride >> 1) * (srf->height >> 1); +} + +static void +defaultQMatrices(ViaXvMCContext * ctx) +{ + int i; + + static const char intra[64] = { + 8, 16, 19, 22, 26, 27, 29, 34, 16, 16, 22, 24, 27, 29, 34, 37, + 19, 22, 26, 27, 29, 34, 34, 38, 22, 22, 26, 27, 29, 34, 37, 40, + 22, 26, 27, 29, 32, 35, 40, 48, 26, 27, 29, 32, 35, 40, 48, 58, + 26, 27, 29, 34, 38, 46, 56, 69, 27, 29, 35, 38, 46, 56, 69, 83 + }; + + for (i = 0; i < 64; ++i) { + ctx->intra_quantiser_matrix[i] = intra[i]; + ctx->non_intra_quantiser_matrix[i] = 16; + } + ctx->intraLoaded = 0; + ctx->nonIntraLoaded = 0; +} + +static void +releaseDecoder(ViaXvMCContext * ctx, int clearCtx) +{ + volatile ViaXvMCSAreaPriv *sAPriv; + + sAPriv = SAREAPTR(ctx); + UNICHROME_UNLOCK(ctx->fd, UNICHROME_LOCK_DECODER1, sAPriv, + ctx->drmcontext); +} + +static int +grabDecoder(ViaXvMCContext * ctx, int *hadLastLock) +{ + volatile ViaXvMCSAreaPriv *sAPriv = SAREAPTR(ctx); + int retFtx, lc; + + /* + * Try to grab the decoder. If it is not available we will sleep until + * it becomes available or for a maximum of 20 ms. + * Then try to grab it again, unless a timeout occured. If the decoder is + * available, the lock should be reasonably fast. + */ + + if (ctx->haveDecoder) { + flushXvMCLowLevel(ctx->xl); /* Ignore errors here. */ + + /*fprintf(stderr,"ViaXvMC: ERROR: Trying to re-lock decoder.\n"); */ + *hadLastLock = 1; + return 0; + } + UNICHROME_LOCK(ctx->fd, UNICHROME_LOCK_DECODER1, sAPriv, ctx->drmcontext, + lc, retFtx); + *hadLastLock = (ctx->drmcontext == lc); + + return retFtx; +} + +static void +setupAttribDesc(Display * display, XvPortID port, + const ViaXvMCAttrHolder * attrib, XvAttribute attribDesc[]) +{ + XvAttribute *XvAttribs, *curAD; + int num; + unsigned i, j; + + XLockDisplay(display); + XvAttribs = XvQueryPortAttributes(display, port, &num); + for (i = 0; i < attrib->numAttr; ++i) { + curAD = attribDesc + i; + curAD->flags = 0; + curAD->min_value = 0; + curAD->max_value = 0; + curAD->name = NULL; + for (j = 0; j < num; ++j) { + if (attrib->attributes[i].attribute == + XInternAtom(display, XvAttribs[j].name, TRUE)) { + *curAD = XvAttribs[j]; + curAD->name = strdup(XvAttribs[j].name); + break; + } + } + } + if (XvAttribs) + XFree(XvAttribs); + XUnlockDisplay(display); + +} + +static void +releaseAttribDesc(int numAttr, XvAttribute attribDesc[]) +{ + int i; + + for (i = 0; i < numAttr; ++i) { + if (attribDesc[i].name) + free(attribDesc[i].name); + } +} + +static Status +releaseContextResources(Display * display, XvMCContext * context, + int freePrivate, Status errType) +{ + ViaXvMCContext *pViaXvMC = (ViaXvMCContext *) context->privData; + + switch (pViaXvMC->resources) { + case context_drawHash: + driDestroyHashContents(pViaXvMC->drawHash); + drmHashDestroy(pViaXvMC->drawHash); + case context_lowLevel: + closeXvMCLowLevel(pViaXvMC->xl); + case context_mutex: + pthread_mutex_destroy(&pViaXvMC->ctxMutex); + case context_drmContext: + XLockDisplay(display); + uniDRIDestroyContext(display, pViaXvMC->screen, pViaXvMC->id); + XUnlockDisplay(display); + case context_sAreaMap: + numContexts--; + if (numContexts == 0) + drmUnmap(pViaXvMC->sAreaAddress, pViaXvMC->sAreaSize); + case context_fbMap: + if (numContexts == 0) + drmUnmap(pViaXvMC->fbAddress, pViaXvMC->fbSize); + case context_mmioMap: + if (numContexts == 0) + drmUnmap(pViaXvMC->mmioAddress, pViaXvMC->mmioSize); + case context_fd: + if (numContexts == 0) { + if (pViaXvMC->fd >= 0) + drmClose(pViaXvMC->fd); + } + pViaXvMC->fd = -1; + case context_driConnection: + if (numContexts == 0) { + XLockDisplay(display); + uniDRICloseConnection(display, pViaXvMC->screen); + XUnlockDisplay(display); + } + case context_context: + XLockDisplay(display); + _xvmc_destroy_context(display, context); + XUnlockDisplay(display); + if (!freePrivate) + break; + default: + free(pViaXvMC); + context->privData = NULL; + } + return errType; +} + +Status +XvMCCreateContext(Display * display, XvPortID port, + int surface_type_id, int width, int height, int flags, + XvMCContext * context) +{ + ViaXvMCContext *pViaXvMC; + int priv_count; + uint *priv_data; + uint magic; + unsigned i; + Status ret; + int major, minor; + ViaXvMCCreateContextRec *tmpComm; + drmVersionPtr drmVer; + char *curBusID; + int isCapable; + + /* + * Verify Obvious things first + */ + + if (context == NULL) { + return XvMCBadContext; + } + + if (!(flags & XVMC_DIRECT)) { + fprintf(stderr, "Indirect Rendering not supported! Using Direct.\n"); + } + + /* + *FIXME: Check $DISPLAY for legal values here + */ + + context->surface_type_id = surface_type_id; + context->width = (unsigned short)((width + 15) & ~15); + context->height = (unsigned short)((height + 15) & ~15); + context->flags = flags; + context->port = port; + + /* + * Width, Height, and flags are checked against surface_type_id + * and port for validity inside the X server, no need to check + * here. + */ + + /* Allocate private Context data */ + context->privData = (void *)malloc(sizeof(ViaXvMCContext)); + if (!context->privData) { + fprintf(stderr, "Unable to allocate resources for XvMC context.\n"); + return BadAlloc; + } + + pViaXvMC = (ViaXvMCContext *) context->privData; + pViaXvMC->resources = context_none; + + /* Verify the XvMC extension exists */ + + XLockDisplay(display); + if (!XvMCQueryExtension(display, &event_base, &error_base)) { + fprintf(stderr, "XvMC Extension is not available!\n"); + free(pViaXvMC); + XUnlockDisplay(display); + return BadAlloc; + } + + /* Verify XvMC version */ + ret = XvMCQueryVersion(display, &major, &minor); + if (ret) { + fprintf(stderr, "XvMCQuery Version Failed, unable to determine " + "protocol version!\n"); + } + XUnlockDisplay(display); + + /* FIXME: Check Major and Minor here */ + + XLockDisplay(display); + if ((ret = _xvmc_create_context(display, context, &priv_count, + &priv_data))) { + XUnlockDisplay(display); + fprintf(stderr, "Unable to create XvMC Context!\n"); + return releaseContextResources(display, context, 1, BadAlloc); + } + XUnlockDisplay(display); + + /* + * Check size and version of returned data. + */ + + tmpComm = (ViaXvMCCreateContextRec *) priv_data; + if (priv_count != (sizeof(ViaXvMCCreateContextRec) >> 2)) { + fprintf(stderr, "_xvmc_create_context() returned incorrect " + "data size!\n"); + fprintf(stderr, "\tExpected %d, got %d\n", + ((int)(sizeof(ViaXvMCCreateContextRec) >> 2)), priv_count); + XFree(priv_data); + return releaseContextResources(display, context, 1, BadAlloc); + } + pViaXvMC->resources = context_context; + + if ((tmpComm->major != VIAXVMC_MAJOR) || + (tmpComm->minor != VIAXVMC_MINOR)) { + fprintf(stderr, "Version mismatch between the X via driver\n" + "and the XvMC library. Cannot continue!\n"); + XFree(priv_data); + return releaseContextResources(display, context, 1, BadAlloc); + } + + pViaXvMC->ctxNo = tmpComm->ctxNo; + pViaXvMC->fbOffset = tmpComm->fbOffset; + pViaXvMC->fbSize = tmpComm->fbSize; + pViaXvMC->mmioOffset = tmpComm->mmioOffset; + pViaXvMC->mmioSize = tmpComm->mmioSize; + pViaXvMC->sAreaSize = tmpComm->sAreaSize; + pViaXvMC->sAreaPrivOffset = tmpComm->sAreaPrivOffset; + pViaXvMC->decoderOn = 0; + pViaXvMC->xvMCPort = tmpComm->xvmc_port; + pViaXvMC->useAGP = tmpComm->useAGP; + pViaXvMC->attrib = tmpComm->initAttrs; + pViaXvMC->screen = tmpComm->screen; + pViaXvMC->depth = tmpComm->depth; + pViaXvMC->stride = tmpComm->stride; + pViaXvMC->chipId = tmpComm->chipId; + + /* + * Must free the private data we were passed from X + */ + + XFree(priv_data); + priv_data = NULL; + + /* + * Check for direct rendering capable, establish DRI and DRM connections, + * map framebuffer, DRI shared area and read-only register areas. + * Initial checking for drm has already been done by the server. + * Only do this for the first context we create. + */ + + if (numContexts == 0) { + XLockDisplay(display); + ret = + uniDRIQueryDirectRenderingCapable(display, pViaXvMC->screen, + &isCapable); + if (!ret || !isCapable) { + XUnlockDisplay(display); + fprintf(stderr, + "Direct Rendering is not available on this system!\n"); + return releaseContextResources(display, context, 1, BadAlloc); + } + + if (!uniDRIOpenConnection(display, pViaXvMC->screen, + &pViaXvMC->sAreaOffset, &curBusID)) { + XUnlockDisplay(display); + fprintf(stderr, "Could not open DRI connection to X server!\n"); + return releaseContextResources(display, context, 1, BadAlloc); + } + XUnlockDisplay(display); + + strncpy(pViaXvMC->busIdString, curBusID, 20); + pViaXvMC->busIdString[20] = '\0'; + XFree(curBusID); + + pViaXvMC->resources = context_driConnection; + + if ((pViaXvMC->fd = drmOpen("via", pViaXvMC->busIdString)) < 0) { + fprintf(stderr, "DRM Device for via could not be opened.\n"); + return releaseContextResources(display, context, 1, BadAlloc); + } + globalFD = pViaXvMC->fd; + pViaXvMC->resources = context_fd; + + if (NULL == (drmVer = drmGetVersion(pViaXvMC->fd))) { + fprintf(stderr, "viaXvMC: Could not get drm version."); + return releaseContextResources(display, context, 1, BadAlloc); + } + if ((drmVer->version_major < drmExpected.major) || + (drmVer->version_major > drmCompat.major) || + ((drmVer->version_major == drmExpected.major) && + (drmVer->version_minor < drmExpected.minor))) { + fprintf(stderr, + "viaXvMC: Kernel drm is not compatible with XvMC.\n"); + fprintf(stderr, + "viaXvMC: Kernel drm version: %d.%d.%d " + "and I can work with versions %d.%d.x - %d.x.x\n" + "Please update either this XvMC driver or your kernel DRM.\n", + drmVer->version_major, drmVer->version_minor, + drmVer->version_patchlevel, drmExpected.major, + drmExpected.minor, drmCompat.major); + drmFreeVersion(drmVer); + return releaseContextResources(display, context, 1, BadAlloc); + } + drmFreeVersion(drmVer); + drmGetMagic(pViaXvMC->fd, &magic); + + XLockDisplay(display); + if (!uniDRIAuthConnection(display, pViaXvMC->screen, magic)) { + XUnlockDisplay(display); + fprintf(stderr, + "viaXvMC: X server did not allow DRI. Check permissions.\n"); + return releaseContextResources(display, context, 1, BadAlloc); + } + XUnlockDisplay(display); + + /* + * Map the register memory + */ + + if (drmMap(pViaXvMC->fd, pViaXvMC->mmioOffset, + pViaXvMC->mmioSize, &mmioAddress) < 0) { + fprintf(stderr, + "Unable to map the display chip mmio registers.\n"); + return releaseContextResources(display, context, 1, BadAlloc); + } + pViaXvMC->mmioAddress = mmioAddress; + pViaXvMC->resources = context_mmioMap; + + /* + * Map Framebuffer memory + */ + + if (drmMap(pViaXvMC->fd, pViaXvMC->fbOffset, + pViaXvMC->fbSize, &fbAddress) < 0) { + fprintf(stderr, "Unable to map XvMC Framebuffer.\n"); + return releaseContextResources(display, context, 1, BadAlloc); + } + pViaXvMC->fbAddress = fbAddress; + pViaXvMC->resources = context_fbMap; + + /* + * Map DRI Sarea. + */ + + if (drmMap(pViaXvMC->fd, pViaXvMC->sAreaOffset, + pViaXvMC->sAreaSize, &sAreaAddress) < 0) { + fprintf(stderr, "Unable to map DRI SAREA.\n"); + return releaseContextResources(display, context, 1, BadAlloc); + } + } else { + pViaXvMC->fd = globalFD; + pViaXvMC->mmioAddress = mmioAddress; + pViaXvMC->fbAddress = fbAddress; + } + + pViaXvMC->sAreaAddress = sAreaAddress; + pViaXvMC->resources = context_sAreaMap; + numContexts++; + + /* + * Find a matching visual. Important only for direct drawing to the visible + * frame-buffer. + */ + + XLockDisplay(display); + ret = XMatchVisualInfo(display, pViaXvMC->screen, + (pViaXvMC->depth == 32) ? 24 : pViaXvMC->depth, TrueColor, + &pViaXvMC->visualInfo); + XUnlockDisplay(display); + if (!ret) { + fprintf(stderr, + "viaXvMC: Could not find a matching TrueColor visual.\n"); + return releaseContextResources(display, context, 1, BadAlloc); + } + + if (!uniDRICreateContext(display, pViaXvMC->screen, + pViaXvMC->visualInfo.visual, &pViaXvMC->id, + &pViaXvMC->drmcontext)) { + + fprintf(stderr, "viaXvMC: Could not create DRI context.\n"); + return releaseContextResources(display, context, 1, BadAlloc); + } + + pViaXvMC->resources = context_drmContext; + + for (i = 0; i < VIA_MAX_RENDSURF; ++i) { + pViaXvMC->rendSurf[i] = 0; + } + pViaXvMC->lastSrfDisplaying = ~0; + setupAttribDesc(display, port, &pViaXvMC->attrib, pViaXvMC->attribDesc); + + pViaXvMC->hwLock = (drmLockPtr) pViaXvMC->sAreaAddress; + defaultQMatrices(pViaXvMC); + pViaXvMC->chromaIntraLoaded = 1; + pViaXvMC->chromaNonIntraLoaded = 1; + pViaXvMC->yStride = (width + 31) & ~31; + pViaXvMC->haveDecoder = 0; + pViaXvMC->attribChanged = 1; + pViaXvMC->haveXv = 0; + pViaXvMC->port = context->port; + pthread_mutex_init(&pViaXvMC->ctxMutex, NULL); + pViaXvMC->resources = context_mutex; + pViaXvMC->timeStamp = 0; + setRegion(0, 0, -1, -1, pViaXvMC->sRegion); + setRegion(0, 0, -1, -1, pViaXvMC->dRegion); + + if (NULL == (pViaXvMC->xl = + initXvMCLowLevel(pViaXvMC->fd, &pViaXvMC->drmcontext, + pViaXvMC->hwLock, pViaXvMC->mmioAddress, + pViaXvMC->fbAddress, pViaXvMC->stride, pViaXvMC->depth, + context->width, context->height, + pViaXvMC->useAGP, pViaXvMC->chipId))) { + + fprintf(stderr, "ViaXvMC: Could not allocate timestamp blit area.\n"); + return releaseContextResources(display, context, 1, BadAlloc); + } + pViaXvMC->resources = context_lowLevel; + setAGPSyncLowLevel(pViaXvMC->xl, 1, 0); + + if (NULL == (pViaXvMC->drawHash = drmHashCreate())) { + fprintf(stderr, "ViaXvMC: Could not allocate drawable hash table.\n"); + return releaseContextResources(display, context, 1, BadAlloc); + } + pViaXvMC->resources = context_drawHash; + + if (numContexts == 1) { + hwlLock(pViaXvMC->xl, 1); + setLowLevelLocking(pViaXvMC->xl, 0); + viaVideoSubPictureOffLocked(pViaXvMC->xl); + flushXvMCLowLevel(pViaXvMC->xl); + setLowLevelLocking(pViaXvMC->xl, 1); + hwlUnlock(pViaXvMC->xl, 1); + } + + return Success; +} + +Status +XvMCDestroyContext(Display * display, XvMCContext * context) +{ + ViaXvMCContext *pViaXvMC; + + if (context == NULL) { + return (error_base + XvMCBadContext); + } + if (NULL == (pViaXvMC = context->privData)) { + return (error_base + XvMCBadContext); + } + + /* + * Release decoder if we have it. In case of crash or termination + * before XvMCDestroyContext, the X server will take care of this. + */ + + releaseAttribDesc(pViaXvMC->attrib.numAttr, pViaXvMC->attribDesc); + releaseDecoder(pViaXvMC, 1); + return releaseContextResources(display, context, 1, Success); +} + +Status +XvMCCreateSurface(Display * display, XvMCContext * context, + XvMCSurface * surface) +{ + ViaXvMCContext *pViaXvMC; + ViaXvMCSurface *pViaSurface; + int priv_count; + unsigned *priv_data; + unsigned i; + Status ret; + + if ((surface == NULL) || (context == NULL) || (display == NULL)) { + return BadValue; + } + + pViaXvMC = (ViaXvMCContext *) context->privData; + ppthread_mutex_lock(&pViaXvMC->ctxMutex); + + if (pViaXvMC == NULL) { + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return (error_base + XvMCBadContext); + } + + pViaSurface = surface->privData = + (ViaXvMCSurface *) malloc(sizeof(ViaXvMCSurface)); + if (!surface->privData) { + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return BadAlloc; + } + XLockDisplay(display); + if ((ret = _xvmc_create_surface(display, context, surface, + &priv_count, &priv_data))) { + XUnlockDisplay(display); + free(pViaSurface); + fprintf(stderr, "Unable to create XvMC Surface.\n"); + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return ret; + } + XUnlockDisplay(display); + + pViaSurface->srfNo = priv_data[0]; + + /* + * Store framebuffer offsets to the buffers allocated for this surface. + * For some chipset revisions, surfaces may be double-buffered. + */ + + pViaSurface->numBuffers = priv_data[1]; + for (i = 0; i < pViaSurface->numBuffers; ++i) { + pViaSurface->offsets[i] = priv_data[i + 2]; + } + pViaSurface->curBuf = 0; + + /* Free data returned from xvmc_create_surface */ + + XFree(priv_data); + + pViaSurface->width = context->width; + pViaSurface->height = context->height; + pViaSurface->yStride = pViaXvMC->yStride; + pViaSurface->privContext = pViaXvMC; + pViaSurface->privSubPic = NULL; + pViaSurface->needsSync = 0; + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return Success; +} + +Status +XvMCDestroySurface(Display * display, XvMCSurface * surface) +{ + ViaXvMCSurface *pViaSurface; + + if ((display == NULL) || (surface == NULL)) { + return BadValue; + } + if (surface->privData == NULL) { + return (error_base + XvMCBadSurface); + } + + pViaSurface = (ViaXvMCSurface *) surface->privData; + + XLockDisplay(display); + _xvmc_destroy_surface(display, surface); + XUnlockDisplay(display); + + free(pViaSurface); + surface->privData = NULL; + return Success; +} + +Status +XvMCPutSlice2(Display * display, XvMCContext * context, char *slice, + int nBytes, int sliceCode) +{ + ViaXvMCContext *pViaXvMC; + CARD32 sCode = 0x00010000 | (sliceCode & 0xFF) << 24; + + if ((display == NULL) || (context == NULL)) { + return BadValue; + } + if (NULL == (pViaXvMC = context->privData)) { + return (error_base + XvMCBadContext); + } + ppthread_mutex_lock(&pViaXvMC->ctxMutex); + if (!pViaXvMC->haveDecoder) { + fprintf(stderr, "XvMCPutSlice: This context does not own decoder!\n"); + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return BadAlloc; + } + + viaMpegWriteSlice(pViaXvMC->xl, (CARD8 *) slice, nBytes, sCode); + + flushPCIXvMCLowLevel(pViaXvMC->xl); + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return Success; +} + +Status +XvMCPutSlice(Display * display, XvMCContext * context, char *slice, + int nBytes) +{ + ViaXvMCContext *pViaXvMC; + + if ((display == NULL) || (context == NULL)) { + return BadValue; + } + if (NULL == (pViaXvMC = context->privData)) { + return (error_base + XvMCBadContext); + } + ppthread_mutex_lock(&pViaXvMC->ctxMutex); + + if (!pViaXvMC->haveDecoder) { + fprintf(stderr, "XvMCPutSlice: This context does not own decoder!\n"); + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return BadAlloc; + } + + viaMpegWriteSlice(pViaXvMC->xl, (CARD8 *) slice, nBytes, 0); + flushPCIXvMCLowLevel(pViaXvMC->xl); + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return Success; +} + +static Status +updateXVOverlay(Display * display, ViaXvMCContext * pViaXvMC, + ViaXvMCSurface * pViaSurface, Drawable draw, + short srcx, short srcy, unsigned short srcw, + unsigned short srch, short destx, short desty, + unsigned short destw, unsigned short desth) +{ + ViaXvMCCommandBuffer buf; + ViaXvMCSubPicture *pViaSubPic; + Status ret; + + if (!pViaXvMC->haveXv) { + pViaXvMC->xvImage = + XvCreateImage(display, pViaXvMC->port, FOURCC_XVMC, + (char *)&buf, pViaSurface->width, pViaSurface->height); + pViaXvMC->gc = XCreateGC(display, draw, 0, 0); + pViaXvMC->haveXv = 1; + } + pViaXvMC->draw = draw; + pViaXvMC->xvImage->data = (char *)&buf; + + buf.command = (pViaXvMC->attribChanged) ? + VIA_XVMC_COMMAND_FDISPLAY : VIA_XVMC_COMMAND_DISPLAY; + buf.ctxNo = pViaXvMC->ctxNo | VIA_XVMC_VALID; + buf.srfNo = pViaSurface->srfNo | VIA_XVMC_VALID; + pViaSubPic = pViaSurface->privSubPic; + buf.subPicNo = ((NULL == pViaSubPic) ? 0 : pViaSubPic->srfNo) + | VIA_XVMC_VALID; + buf.attrib = pViaXvMC->attrib; + + XLockDisplay(display); + + if ((ret = XvPutImage(display, pViaXvMC->port, draw, pViaXvMC->gc, + pViaXvMC->xvImage, srcx, srcy, srcw, srch, + destx, desty, destw, desth))) { + XUnlockDisplay(display); + return ret; + } + XSync(display, 0); + XUnlockDisplay(display); + pViaXvMC->attribChanged = 0; + return Success; +} + +Status +XvMCPutSurface(Display * display, XvMCSurface * surface, Drawable draw, + short srcx, short srcy, unsigned short srcw, + unsigned short srch, short destx, short desty, + unsigned short destw, unsigned short desth, int flags) +{ + /* + * This function contains some hairy locking logic. What we really want to + * do is to flip the picture ASAP, to get a low latency and smooth playback. + * However, if somebody else used the overlay since we used it last or if it is + * our first time, we'll have to call X to update the overlay first. Otherwise + * we'll do the overlay update once we've flipped. Since we release the hardware + * lock when we call X, X needs to verify using the SAREA that nobody else flipped + * in a picture between the lock release and the X server control. Similarly + * when the overlay update returns, we have to make sure that we still own the + * overlay. + */ + + ViaXvMCSurface *pViaSurface; + ViaXvMCContext *pViaXvMC; + ViaXvMCSubPicture *pViaSubPic; + volatile ViaXvMCSAreaPriv *sAPriv; + Status ret; + unsigned dispSurface, lastSurface; + int overlayUpdated; + drawableInfo *drawInfo; + XvMCRegion sReg, dReg; + Bool forceUpdate = FALSE; + + if ((display == NULL) || (surface == NULL)) { + return BadValue; + } + if (NULL == (pViaSurface = surface->privData)) { + return (error_base + XvMCBadSurface); + } + if (NULL == (pViaXvMC = pViaSurface->privContext)) { + return (error_base + XvMCBadContext); + } + + ppthread_mutex_lock(&pViaXvMC->ctxMutex); + pViaSubPic = pViaSurface->privSubPic; + sAPriv = SAREAPTR(pViaXvMC); + + setRegion(srcx, srcy, srcw, srch, sReg); + setRegion(destx, desty, destw, desth, dReg); + + if ((!regionEqual(sReg, pViaXvMC->sRegion)) || + (!regionEqual(dReg, pViaXvMC->dRegion))) { + + /* + * Force update of the video overlay to match the new format. + */ + + pViaXvMC->sRegion = sReg; + pViaXvMC->dRegion = dReg; + forceUpdate = TRUE; + } + + hwlLock(pViaXvMC->xl, 1); + + if (getDRIDrawableInfoLocked(pViaXvMC->drawHash, display, + pViaXvMC->screen, draw, 0, pViaXvMC->fd, pViaXvMC->drmcontext, + pViaXvMC->sAreaAddress, FALSE, &drawInfo, sizeof(*drawInfo))) { + + hwlUnlock(pViaXvMC->xl, 1); + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return BadAccess; + } + + setLowLevelLocking(pViaXvMC->xl, 0); + + /* + * Put a surface ID in the SAREA to "authenticate" to the + * X server. + */ + + dispSurface = sAPriv->XvMCDisplaying[pViaXvMC->xvMCPort]; + lastSurface = pViaXvMC->lastSrfDisplaying; + sAPriv->XvMCDisplaying[pViaXvMC->xvMCPort] = + pViaXvMC->lastSrfDisplaying = pViaSurface->srfNo | VIA_XVMC_VALID; + overlayUpdated = 0; + + viaVideoSetSWFLipLocked(pViaXvMC->xl, yOffs(pViaSurface), + uOffs(pViaSurface), vOffs(pViaSurface), pViaSurface->yStride, + pViaSurface->yStride >> 1); + + while ((lastSurface != dispSurface) || forceUpdate) { + + forceUpdate = FALSE; + flushPCIXvMCLowLevel(pViaXvMC->xl); + setLowLevelLocking(pViaXvMC->xl, 1); + hwlUnlock(pViaXvMC->xl, 1); + + /* + * We weren't the last to display. Update the overlay before flipping. + */ + + ret = + updateXVOverlay(display, pViaXvMC, pViaSurface, draw, srcx, srcy, + srcw, srch, destx, desty, destw, desth); + if (ret) { + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return ret; + } + + hwlLock(pViaXvMC->xl, 1); + + if (getDRIDrawableInfoLocked(pViaXvMC->drawHash, display, + pViaXvMC->screen, draw, 0, pViaXvMC->fd, pViaXvMC->drmcontext, + pViaXvMC->sAreaAddress, FALSE, &drawInfo, + sizeof(*drawInfo))) { + + hwlUnlock(pViaXvMC->xl, 1); + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return BadAccess; + } + + setLowLevelLocking(pViaXvMC->xl, 0); + lastSurface = pViaSurface->srfNo | VIA_XVMC_VALID; + dispSurface = sAPriv->XvMCDisplaying[pViaXvMC->xvMCPort]; + overlayUpdated = 1; + } + + /* + * Subpictures + */ + + if (NULL != pViaSubPic) { + if (sAPriv->XvMCSubPicOn[pViaXvMC->xvMCPort] + != (pViaSubPic->srfNo | VIA_XVMC_VALID)) { + sAPriv->XvMCSubPicOn[pViaXvMC->xvMCPort] = + pViaSubPic->srfNo | VIA_XVMC_VALID; + viaVideoSubPictureLocked(pViaXvMC->xl, pViaSubPic); + } + } else { + if (sAPriv->XvMCSubPicOn[pViaXvMC->xvMCPort] & VIA_XVMC_VALID) { + viaVideoSubPictureOffLocked(pViaXvMC->xl); + sAPriv->XvMCSubPicOn[pViaXvMC->xvMCPort] &= ~VIA_XVMC_VALID; + } + } + + /* + * Flip + */ + + viaVideoSWFlipLocked(pViaXvMC->xl, flags, + pViaSurface->progressiveSequence); + flushXvMCLowLevel(pViaXvMC->xl); + + setLowLevelLocking(pViaXvMC->xl, 1); + hwlUnlock(pViaXvMC->xl, 1); + + if (overlayUpdated || !drawInfo->touched) { + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return Success; + } + + /* + * Update overlay + */ + + ret = + updateXVOverlay(display, pViaXvMC, pViaSurface, draw, srcx, srcy, + srcw, srch, destx, desty, destw, desth); + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return ret; + +} + +void +debugControl(const XvMCMpegControl * control) +{ + printf("BVMV_range: %u\n", control->BVMV_range); + printf("BHMV_range: %u\n", control->BHMV_range); + printf("FVMV_range: %u\n", control->FVMV_range); + printf("FHMV_range: %u\n", control->FHMV_range); + printf("picture_structure: %u\n", control->picture_structure); + printf("intra_dc_precision: %u\n", control->intra_dc_precision); + printf("picture_coding_type: %u\n", control->picture_coding_type); + printf("mpeg_coding: %u\n", control->mpeg_coding); + printf("flags: 0x%x\n", control->flags); +} + +Status +XvMCBeginSurface(Display * display, + XvMCContext * context, + XvMCSurface * target_surface, + XvMCSurface * past_surface, + XvMCSurface * future_surface, const XvMCMpegControl * control) +{ + ViaXvMCSurface *targS, *futS, *pastS; + ViaXvMCContext *pViaXvMC; + int hadDecoderLast; + CARD32 timeStamp; + + if ((display == NULL) || (context == NULL) || (target_surface == NULL)) { + return BadValue; + } + + pViaXvMC = context->privData; + + ppthread_mutex_lock(&pViaXvMC->ctxMutex); + if (grabDecoder(pViaXvMC, &hadDecoderLast)) { + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return BadAlloc; + } + pViaXvMC->haveDecoder = 1; + + /* + * We need to wait for decoder idle at next flush, since hardware doesn't queue + * beginsurface requests until the decoder is idle. This is + * done by waiting on the last previous timestamp, or if there was another context + * having the decoder before us, by emitting a new one. + */ + + if (pViaXvMC->useAGP) { + if (!hadDecoderLast || pViaXvMC->timeStamp == 0) { + timeStamp = viaDMATimeStampLowLevel(pViaXvMC->xl); + if (flushXvMCLowLevel(pViaXvMC->xl)) { + releaseDecoder(pViaXvMC, 0); + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return BadAlloc; + } + pViaXvMC->timeStamp = timeStamp; + } else { + timeStamp = pViaXvMC->timeStamp; + } + setAGPSyncLowLevel(pViaXvMC->xl, 1, timeStamp); + } + + if (!hadDecoderLast || !pViaXvMC->decoderOn) { + pViaXvMC->intraLoaded = 0; + pViaXvMC->nonIntraLoaded = 0; + } + + viaMpegReset(pViaXvMC->xl); + + targS = (ViaXvMCSurface *) target_surface->privData; + futS = NULL; + pastS = NULL; + + pViaXvMC->rendSurf[0] = targS->srfNo | VIA_XVMC_VALID; + if (future_surface) { + futS = (ViaXvMCSurface *) future_surface->privData; + futS->needsSync = 0; + } + if (past_surface) { + pastS = (ViaXvMCSurface *) past_surface->privData; + pastS->needsSync = 0; + } + + targS->progressiveSequence = (control->flags & XVMC_PROGRESSIVE_SEQUENCE); + targS->topFieldFirst = (control->flags & XVMC_TOP_FIELD_FIRST); + targS->privSubPic = NULL; + + viaMpegSetSurfaceStride(pViaXvMC->xl, pViaXvMC); + + viaMpegSetFB(pViaXvMC->xl, 0, yOffs(targS), uOffs(targS), vOffs(targS)); + if (past_surface) { + viaMpegSetFB(pViaXvMC->xl, 1, yOffs(pastS), uOffs(pastS), + vOffs(pastS)); + } else { + viaMpegSetFB(pViaXvMC->xl, 1, 0, 0, 0); + } + + if (future_surface) { + viaMpegSetFB(pViaXvMC->xl, 2, yOffs(futS), uOffs(futS), vOffs(futS)); + } else { + viaMpegSetFB(pViaXvMC->xl, 2, 0, 0, 0); + } + + viaMpegBeginPicture(pViaXvMC->xl, pViaXvMC, context->width, + context->height, control); + flushPCIXvMCLowLevel(pViaXvMC->xl); + targS->needsSync = 1; + targS->syncMode = LL_MODE_DECODER_IDLE; + pViaXvMC->decoderOn = 1; + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return Success; +} + +Status +XvMCSyncSurface(Display * display, XvMCSurface * surface) +{ + ViaXvMCSurface *pViaSurface; + ViaXvMCContext *pViaXvMC; + unsigned i; + + if ((display == NULL) || (surface == NULL)) { + return BadValue; + } + if (surface->privData == NULL) { + return (error_base + XvMCBadSurface); + } + + pViaSurface = (ViaXvMCSurface *) surface->privData; + pViaXvMC = pViaSurface->privContext; + + if (pViaXvMC == NULL) { + return (error_base + XvMCBadSurface); + } + + ppthread_mutex_lock(&pViaXvMC->ctxMutex); + + if (pViaSurface->needsSync) { + CARD32 timeStamp = pViaSurface->timeStamp; + int syncMode = pViaSurface->syncMode; + + if (pViaXvMC->useAGP) { + + syncMode = (pViaSurface->syncMode == LL_MODE_2D || + pViaSurface->timeStamp < pViaXvMC->timeStamp) ? + LL_MODE_2D : LL_MODE_DECODER_IDLE; + if (pViaSurface->syncMode != LL_MODE_2D) + timeStamp = pViaXvMC->timeStamp; + + } else if (syncMode != LL_MODE_2D && + pViaXvMC->rendSurf[0] != (pViaSurface->srfNo | VIA_XVMC_VALID)) { + + pViaSurface->needsSync = 0; + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return Success; + } + + if (syncXvMCLowLevel(pViaXvMC->xl, syncMode, 1, + pViaSurface->timeStamp)) { + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return BadValue; + } + pViaSurface->needsSync = 0; + } + + if (pViaXvMC->rendSurf[0] == (pViaSurface->srfNo | VIA_XVMC_VALID)) { + pViaSurface->needsSync = 0; + for (i = 0; i < VIA_MAX_RENDSURF; ++i) { + pViaXvMC->rendSurf[i] = 0; + } + } + + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return Success; +} + +Status +XvMCLoadQMatrix(Display * display, XvMCContext * context, + const XvMCQMatrix * qmx) +{ + ViaXvMCContext * pViaXvMC; + + if ((display == NULL) || (context == NULL)) { + return BadValue; + } + if (NULL == (pViaXvMC = context->privData)) { + return (error_base + XvMCBadContext); + } + + ppthread_mutex_lock(&pViaXvMC->ctxMutex); + if (qmx->load_intra_quantiser_matrix) { + memcpy(pViaXvMC->intra_quantiser_matrix, + qmx->intra_quantiser_matrix, sizeof(qmx->intra_quantiser_matrix)); + pViaXvMC->intraLoaded = 0; + } + + if (qmx->load_non_intra_quantiser_matrix) { + memcpy(pViaXvMC->non_intra_quantiser_matrix, + qmx->non_intra_quantiser_matrix, + sizeof(qmx->non_intra_quantiser_matrix)); + pViaXvMC->nonIntraLoaded = 0; + } + + if (qmx->load_chroma_intra_quantiser_matrix) { + memcpy(pViaXvMC->chroma_intra_quantiser_matrix, + qmx->chroma_intra_quantiser_matrix, + sizeof(qmx->chroma_intra_quantiser_matrix)); + pViaXvMC->chromaIntraLoaded = 0; + } + + if (qmx->load_chroma_non_intra_quantiser_matrix) { + memcpy(pViaXvMC->chroma_non_intra_quantiser_matrix, + qmx->chroma_non_intra_quantiser_matrix, + sizeof(qmx->chroma_non_intra_quantiser_matrix)); + pViaXvMC->chromaNonIntraLoaded = 0; + } + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + + return Success; +} + +/* + * Below, we provide functions unusable for this implementation, but for + * standard completeness. + */ + +Status XvMCRenderSurface + (Display * display, + 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) +{ + return (error_base + XvMCBadContext); +} + +Status XvMCCreateBlocks + (Display * display, + XvMCContext * context, unsigned int num_blocks, XvMCBlockArray * block) +{ + return (error_base + XvMCBadContext); +} + +Status +XvMCDestroyBlocks(Display * display, XvMCBlockArray * block) +{ + return Success; +} + +Status XvMCCreateMacroBlocks + (Display * display, + XvMCContext * context, + unsigned int num_blocks, XvMCMacroBlockArray * blocks) +{ + return (error_base + XvMCBadContext); +} + +Status +XvMCDestroyMacroBlocks(Display * display, XvMCMacroBlockArray * block) +{ + return (error_base + XvMCBadContext); +} + +Status +XvMCCreateSubpicture(Display * display, + XvMCContext * context, + XvMCSubpicture * subpicture, + unsigned short width, unsigned short height, int xvimage_id) +{ + ViaXvMCContext *pViaXvMC; + ViaXvMCSubPicture *pViaSubPic; + int priv_count; + unsigned *priv_data; + Status ret; + + if ((subpicture == NULL) || (context == NULL) || (display == NULL)) { + return BadValue; + } + + pViaXvMC = (ViaXvMCContext *) context->privData; + if (pViaXvMC == NULL) { + return (error_base + XvMCBadContext); + } + + subpicture->privData = (ViaXvMCSubPicture *) + malloc(sizeof(ViaXvMCSubPicture)); + if (!subpicture->privData) { + return BadAlloc; + } + + ppthread_mutex_lock(&pViaXvMC->ctxMutex); + subpicture->width = context->width; + subpicture->height = context->height; + subpicture->xvimage_id = xvimage_id; + pViaSubPic = (ViaXvMCSubPicture *) subpicture->privData; + + XLockDisplay(display); + if ((ret = _xvmc_create_subpicture(display, context, subpicture, + &priv_count, &priv_data))) { + XUnlockDisplay(display); + free(pViaSubPic); + fprintf(stderr, "Unable to create XvMC Subpicture.\n"); + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return ret; + } + XUnlockDisplay(display); + + subpicture->num_palette_entries = VIA_SUBPIC_PALETTE_SIZE; + subpicture->entry_bytes = 3; + strncpy(subpicture->component_order, "YUV", 4); + pViaSubPic->srfNo = priv_data[0]; + pViaSubPic->offset = priv_data[1]; + pViaSubPic->stride = (subpicture->width + 31) & ~31; + pViaSubPic->privContext = pViaXvMC; + pViaSubPic->ia44 = (xvimage_id == FOURCC_IA44); + pViaSubPic->needsSync = 0; + + /* Free data returned from _xvmc_create_subpicture */ + + XFree(priv_data); + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return Success; +} + +Status +XvMCSetSubpicturePalette(Display * display, XvMCSubpicture * subpicture, + unsigned char *palette) +{ + ViaXvMCSubPicture *pViaSubPic; + ViaXvMCContext *pViaXvMC; + volatile ViaXvMCSAreaPriv *sAPriv; + unsigned i; + CARD32 tmp; + + if ((subpicture == NULL) || (display == NULL)) { + return BadValue; + } + if (subpicture->privData == NULL) { + return (error_base + XvMCBadSubpicture); + } + pViaSubPic = (ViaXvMCSubPicture *) subpicture->privData; + for (i = 0; i < VIA_SUBPIC_PALETTE_SIZE; ++i) { + tmp = *palette++ << 8; + tmp |= *palette++ << 16; + tmp |= *palette++ << 24; + tmp |= ((i & 0x0f) << 4) | 0x07; + pViaSubPic->palette[i] = tmp; + } + + pViaXvMC = pViaSubPic->privContext; + ppthread_mutex_lock(&pViaXvMC->ctxMutex); + sAPriv = SAREAPTR(pViaXvMC); + hwlLock(pViaXvMC->xl, 1); + setLowLevelLocking(pViaXvMC->xl, 0); + + /* + * If the subpicture is displaying, Immeadiately update it with the + * new palette. + */ + + if (sAPriv->XvMCSubPicOn[pViaXvMC->xvMCPort] == + (pViaSubPic->srfNo | VIA_XVMC_VALID)) { + viaVideoSubPictureLocked(pViaXvMC->xl, pViaSubPic); + } + flushPCIXvMCLowLevel(pViaXvMC->xl); + setLowLevelLocking(pViaXvMC->xl, 1); + hwlUnlock(pViaXvMC->xl, 1); + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return Success; +} + +static int +findOverlap(unsigned width, unsigned height, + short *dstX, short *dstY, + short *srcX, short *srcY, unsigned short *areaW, unsigned short *areaH) +{ + int w, h; + unsigned mWidth, mHeight; + + w = *areaW; + h = *areaH; + + if ((*dstX >= width) || (*dstY >= height)) + return 1; + if (*dstX < 0) { + w += *dstX; + *srcX -= *dstX; + *dstX = 0; + } + if (*dstY < 0) { + h += *dstY; + *srcY -= *dstY; + *dstY = 0; + } + if ((w <= 0) || ((h <= 0))) + return 1; + mWidth = width - *dstX; + mHeight = height - *dstY; + *areaW = (w <= mWidth) ? w : mWidth; + *areaH = (h <= mHeight) ? h : mHeight; + return 0; +} + +Status +XvMCClearSubpicture(Display * display, + XvMCSubpicture * subpicture, + short x, + short y, unsigned short width, unsigned short height, unsigned int color) +{ + + ViaXvMCContext *pViaXvMC; + ViaXvMCSubPicture *pViaSubPic; + short dummyX, dummyY; + unsigned long bOffs; + + if ((subpicture == NULL) || (display == NULL)) { + return BadValue; + } + if (subpicture->privData == NULL) { + return (error_base + XvMCBadSubpicture); + } + pViaSubPic = (ViaXvMCSubPicture *) subpicture->privData; + pViaXvMC = pViaSubPic->privContext; + ppthread_mutex_lock(&pViaXvMC->ctxMutex); + + /* Clip clearing area so that it fits inside subpicture. */ + + if (findOverlap(subpicture->width, subpicture->height, &x, &y, + &dummyX, &dummyY, &width, &height)) { + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return Success; + } + + bOffs = pViaSubPic->offset + y * pViaSubPic->stride + x; + viaBlit(pViaXvMC->xl, 8, 0, pViaSubPic->stride, bOffs, pViaSubPic->stride, + width, height, 1, 1, VIABLIT_FILL, color); + pViaSubPic->needsSync = 1; + pViaSubPic->timeStamp = viaDMATimeStampLowLevel(pViaXvMC->xl); + if (flushXvMCLowLevel(pViaXvMC->xl)) { + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return BadValue; + } + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return Success; +} + +Status +XvMCCompositeSubpicture(Display * display, + XvMCSubpicture * subpicture, + XvImage * image, + short srcx, + short srcy, + unsigned short width, unsigned short height, short dstx, short dsty) +{ + + unsigned i; + ViaXvMCContext *pViaXvMC; + ViaXvMCSubPicture *pViaSubPic; + CARD8 *dAddr, *sAddr; + + if ((subpicture == NULL) || (display == NULL) || (image == NULL)) { + return BadValue; + } + if (NULL == (pViaSubPic = (ViaXvMCSubPicture *) subpicture->privData)) { + return (error_base + XvMCBadSubpicture); + } + + pViaXvMC = pViaSubPic->privContext; + + if (image->id != subpicture->xvimage_id) + return BadMatch; + + ppthread_mutex_lock(&pViaXvMC->ctxMutex); + + /* + * Clip copy area so that it fits inside subpicture and image. + */ + + if (findOverlap(subpicture->width, subpicture->height, + &dstx, &dsty, &srcx, &srcy, &width, &height)) { + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return Success; + } + if (findOverlap(image->width, image->height, + &srcx, &srcy, &dstx, &dsty, &width, &height)) { + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return Success; + } + + if (pViaSubPic->needsSync) { + if (syncXvMCLowLevel(pViaXvMC->xl, LL_MODE_2D, 0, + pViaSubPic->timeStamp)) { + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return BadValue; + } + pViaSubPic->needsSync = 0; + } + + for (i = 0; i < height; ++i) { + dAddr = (((CARD8 *) pViaXvMC->fbAddress) + + (pViaSubPic->offset + (dsty + i) * pViaSubPic->stride + dstx)); + sAddr = (((CARD8 *) image->data) + + (image->offsets[0] + (srcy + i) * image->pitches[0] + srcx)); + memcpy(dAddr, sAddr, width); + } + + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return Success; +} + +Status +XvMCBlendSubpicture(Display * display, + XvMCSurface * target_surface, + XvMCSubpicture * subpicture, + short subx, + short suby, + unsigned short subw, + unsigned short subh, + short surfx, short surfy, unsigned short surfw, unsigned short surfh) +{ + ViaXvMCSurface *pViaSurface; + ViaXvMCSubPicture *pViaSubPic; + + if ((display == NULL) || target_surface == NULL) { + return BadValue; + } + + if (subx || suby || surfx || surfy || (subw != surfw) || (subh != surfh)) { + fprintf(stderr, "ViaXvMC: Only completely overlapping subpicture " + "supported.\n"); + return BadValue; + } + + if (NULL == (pViaSurface = target_surface->privData)) { + return (error_base + XvMCBadSurface); + } + + if (subpicture) { + + if (NULL == (pViaSubPic = subpicture->privData)) { + return (error_base + XvMCBadSubpicture); + } + + pViaSurface->privSubPic = pViaSubPic; + } else { + pViaSurface->privSubPic = NULL; + } + return Success; +} + +Status +XvMCBlendSubpicture2(Display * display, + XvMCSurface * source_surface, + XvMCSurface * target_surface, + XvMCSubpicture * subpicture, + short subx, + short suby, + unsigned short subw, + unsigned short subh, + short surfx, short surfy, unsigned short surfw, unsigned short surfh) +{ + ViaXvMCSurface *pViaSurface, *pViaSSurface; + ViaXvMCSubPicture *pViaSubPic; + ViaXvMCContext *pViaXvMC; + + unsigned width, height; + + if ((display == NULL) || target_surface == NULL || source_surface == NULL) { + return BadValue; + } + + if (subx || suby || surfx || surfy || (subw != surfw) || (subh != surfh)) { + fprintf(stderr, "ViaXvMC: Only completely overlapping subpicture " + "supported.\n"); + return BadMatch; + } + + if (NULL == (pViaSurface = target_surface->privData)) { + return (error_base + XvMCBadSurface); + } + + if (NULL == (pViaSSurface = source_surface->privData)) { + return (error_base + XvMCBadSurface); + } + pViaXvMC = pViaSurface->privContext; + width = pViaSSurface->width; + height = pViaSSurface->height; + if (width != pViaSurface->width || height != pViaSSurface->height) { + return BadMatch; + } + + if (XvMCSyncSurface(display, source_surface)) { + return BadValue; + } + + ppthread_mutex_lock(&pViaXvMC->ctxMutex); + viaBlit(pViaXvMC->xl, 8, yOffs(pViaSSurface), pViaSSurface->yStride, + yOffs(pViaSurface), pViaSurface->yStride, + width, height, 1, 1, VIABLIT_COPY, 0); + flushPCIXvMCLowLevel(pViaXvMC->xl); + if (pViaXvMC->chipId != PCI_CHIP_VT3259) { + + /* + * YV12 Chroma blit. + */ + + viaBlit(pViaXvMC->xl, 8, uOffs(pViaSSurface), + pViaSSurface->yStride >> 1, uOffs(pViaSurface), + pViaSurface->yStride >> 1, width >> 1, height >> 1, 1, 1, + VIABLIT_COPY, 0); + flushPCIXvMCLowLevel(pViaXvMC->xl); + viaBlit(pViaXvMC->xl, 8, vOffs(pViaSSurface), + pViaSSurface->yStride >> 1, vOffs(pViaSurface), + pViaSurface->yStride >> 1, width >> 1, height >> 1, 1, 1, + VIABLIT_COPY, 0); + } else { + + /* + * NV12 Chroma blit. + */ + + viaBlit(pViaXvMC->xl, 8, vOffs(pViaSSurface), pViaSSurface->yStride, + vOffs(pViaSurface), pViaSurface->yStride, + width, height >> 1, 1, 1, VIABLIT_COPY, 0); + } + pViaSurface->needsSync = 1; + pViaSurface->syncMode = LL_MODE_2D; + pViaSurface->timeStamp = viaDMATimeStampLowLevel(pViaXvMC->xl); + if (flushXvMCLowLevel(pViaXvMC->xl)) { + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return BadValue; + } + if (subpicture) { + + if (NULL == (pViaSubPic = subpicture->privData)) { + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return (error_base + XvMCBadSubpicture); + } + + pViaSurface->privSubPic = pViaSubPic; + } else { + pViaSurface->privSubPic = NULL; + } + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return Success; +} + +Status +XvMCSyncSubpicture(Display * display, XvMCSubpicture * subpicture) +{ + ViaXvMCSubPicture *pViaSubPic; + ViaXvMCContext *pViaXvMC; + Status retVal = 0; + + if ((display == NULL) || subpicture == NULL) { + return BadValue; + } + if (NULL == (pViaSubPic = subpicture->privData)) { + return (error_base + XvMCBadSubpicture); + } + + pViaXvMC = pViaSubPic->privContext; + ppthread_mutex_lock(&pViaXvMC->ctxMutex); + if (pViaSubPic->needsSync) { + if (syncXvMCLowLevel(pViaXvMC->xl, LL_MODE_2D, + 0, pViaSubPic->timeStamp)) { + retVal = BadValue; + } + pViaSubPic->needsSync = 0; + } + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return retVal; +} + +Status +XvMCFlushSubpicture(Display * display, XvMCSubpicture * subpicture) +{ + ViaXvMCSubPicture *pViaSubPic; + + if ((display == NULL) || subpicture == NULL) { + return BadValue; + } + if (NULL == (pViaSubPic = subpicture->privData)) { + return (error_base + XvMCBadSubpicture); + } + + return Success; +} + +Status +XvMCDestroySubpicture(Display * display, XvMCSubpicture * subpicture) +{ + ViaXvMCSubPicture *pViaSubPic; + ViaXvMCContext *pViaXvMC; + volatile ViaXvMCSAreaPriv *sAPriv; + + if ((display == NULL) || subpicture == NULL) { + return BadValue; + } + if (NULL == (pViaSubPic = subpicture->privData)) { + return (error_base + XvMCBadSubpicture); + } + pViaXvMC = pViaSubPic->privContext; + ppthread_mutex_lock(&pViaXvMC->ctxMutex); + + sAPriv = SAREAPTR(pViaXvMC); + hwlLock(pViaXvMC->xl, 1); + setLowLevelLocking(pViaXvMC->xl, 0); + if (sAPriv->XvMCSubPicOn[pViaXvMC->xvMCPort] == + (pViaSubPic->srfNo | VIA_XVMC_VALID)) { + viaVideoSubPictureOffLocked(pViaXvMC->xl); + sAPriv->XvMCSubPicOn[pViaXvMC->xvMCPort] = 0; + } + flushPCIXvMCLowLevel(pViaXvMC->xl); + setLowLevelLocking(pViaXvMC->xl, 1); + hwlUnlock(pViaXvMC->xl, 1); + + XLockDisplay(display); + _xvmc_destroy_subpicture(display, subpicture); + XUnlockDisplay(display); + + free(pViaSubPic); + subpicture->privData = NULL; + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + + return Success; +} + +Status +XvMCGetSubpictureStatus(Display * display, XvMCSubpicture * subpic, int *stat) +{ + ViaXvMCSubPicture *pViaSubPic; + ViaXvMCContext *pViaXvMC; + volatile ViaXvMCSAreaPriv *sAPriv; + + if ((display == NULL) || subpic == NULL) { + return BadValue; + } + if (NULL == (pViaSubPic = subpic->privData)) { + return (error_base + XvMCBadSubpicture); + } + if (stat) { + *stat = 0; + pViaXvMC = pViaSubPic->privContext; + sAPriv = SAREAPTR(pViaXvMC); + if (sAPriv->XvMCSubPicOn[pViaXvMC->xvMCPort] == + (pViaSubPic->srfNo | VIA_XVMC_VALID)) + *stat |= XVMC_DISPLAYING; + } + return Success; +} + +Status +XvMCFlushSurface(Display * display, XvMCSurface * surface) +{ + ViaXvMCSurface *pViaSurface; + ViaXvMCContext *pViaXvMC; + Status ret; + + if ((display == NULL) || surface == NULL) { + return BadValue; + } + if (NULL == (pViaSurface = surface->privData)) { + return (error_base + XvMCBadSurface); + } + + pViaXvMC = pViaSurface->privContext; + ppthread_mutex_lock(&pViaXvMC->ctxMutex); + if (pViaSurface->needsSync) + pViaSurface->timeStamp = pViaXvMC->timeStamp = + viaDMATimeStampLowLevel(pViaXvMC->xl); + ret = (flushXvMCLowLevel(pViaXvMC->xl)) ? BadValue : Success; + if (pViaXvMC->rendSurf[0] == (pViaSurface->srfNo | VIA_XVMC_VALID)) { + hwlLock(pViaXvMC->xl, 0); + pViaXvMC->haveDecoder = 0; + releaseDecoder(pViaXvMC, 0); + hwlUnlock(pViaXvMC->xl, 0); + } + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return ret; +} + +Status +XvMCGetSurfaceStatus(Display * display, XvMCSurface * surface, int *stat) +{ + ViaXvMCSurface *pViaSurface; + ViaXvMCContext *pViaXvMC; + volatile ViaXvMCSAreaPriv *sAPriv; + unsigned i; + int ret = 0; + + if ((display == NULL) || surface == NULL) { + return BadValue; + } + if (NULL == (pViaSurface = surface->privData)) { + return (error_base + XvMCBadSurface); + } + if (stat) { + *stat = 0; + pViaXvMC = pViaSurface->privContext; + ppthread_mutex_lock(&pViaXvMC->ctxMutex); + sAPriv = SAREAPTR(pViaXvMC); + if (sAPriv->XvMCDisplaying[pViaXvMC->xvMCPort] + == (pViaSurface->srfNo | VIA_XVMC_VALID)) + *stat |= XVMC_DISPLAYING; + for (i = 0; i < VIA_MAX_RENDSURF; ++i) { + if (pViaXvMC->rendSurf[i] == + (pViaSurface->srfNo | VIA_XVMC_VALID)) { + *stat |= XVMC_RENDERING; + break; + } + } + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + } + return ret; +} + +XvAttribute * +XvMCQueryAttributes(Display * display, XvMCContext * context, int *number) +{ + ViaXvMCContext *pViaXvMC; + XvAttribute *ret; + unsigned long siz; + + *number = 0; + if ((display == NULL) || (context == NULL)) { + return NULL; + } + + if (NULL == (pViaXvMC = context->privData)) { + return NULL; + } + + ppthread_mutex_lock(&pViaXvMC->ctxMutex); + if (NULL != (ret = (XvAttribute *) + malloc(siz = VIA_NUM_XVMC_ATTRIBUTES * sizeof(XvAttribute)))) { + memcpy(ret, pViaXvMC->attribDesc, siz); + *number = VIA_NUM_XVMC_ATTRIBUTES; + } + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + + return ret; +} + +Status +XvMCSetAttribute(Display * display, + XvMCContext * context, Atom attribute, int value) +{ + int found; + unsigned i; + ViaXvMCContext *pViaXvMC; + ViaXvMCCommandBuffer buf; + + if ((display == NULL) || (context == NULL)) { + return (error_base + XvMCBadContext); + } + + if (NULL == (pViaXvMC = context->privData)) { + return (error_base + XvMCBadContext); + } + + ppthread_mutex_lock(&pViaXvMC->ctxMutex); + + found = 0; + for (i = 0; i < pViaXvMC->attrib.numAttr; ++i) { + if (attribute == pViaXvMC->attrib.attributes[i].attribute) { + if ((!(pViaXvMC->attribDesc[i].flags & XvSettable)) || + value < pViaXvMC->attribDesc[i].min_value || + value > pViaXvMC->attribDesc[i].max_value) { + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return BadValue; + } + pViaXvMC->attrib.attributes[i].value = value; + found = 1; + pViaXvMC->attribChanged = 1; + break; + } + } + if (!found) { + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return BadMatch; + } + if (pViaXvMC->haveXv) { + buf.command = VIA_XVMC_COMMAND_ATTRIBUTES; + pViaXvMC->xvImage->data = (char *)&buf; + buf.ctxNo = pViaXvMC->ctxNo | VIA_XVMC_VALID; + buf.attrib = pViaXvMC->attrib; + XLockDisplay(display); + pViaXvMC->attribChanged = + XvPutImage(display, pViaXvMC->port, pViaXvMC->draw, + pViaXvMC->gc, pViaXvMC->xvImage, 0, 0, 1, 1, 0, 0, 1, 1); + XUnlockDisplay(display); + } + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return Success; +} + +Status +XvMCGetAttribute(Display * display, + XvMCContext * context, Atom attribute, int *value) +{ + int found; + unsigned i; + ViaXvMCContext *pViaXvMC; + + if ((display == NULL) || (context == NULL)) { + return (error_base + XvMCBadContext); + } + + if (NULL == (pViaXvMC = context->privData)) { + return (error_base + XvMCBadContext); + } + + ppthread_mutex_lock(&pViaXvMC->ctxMutex); + found = 0; + for (i = 0; i < pViaXvMC->attrib.numAttr; ++i) { + if (attribute == pViaXvMC->attrib.attributes[i].attribute) { + if (pViaXvMC->attribDesc[i].flags & XvGettable) { + *value = pViaXvMC->attrib.attributes[i].value; + found = 1; + break; + } + } + } + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + + if (!found) + return BadMatch; + return Success; +} + +Status +XvMCHideSurface(Display * display, XvMCSurface * surface) +{ + + ViaXvMCSurface *pViaSurface; + ViaXvMCContext *pViaXvMC; + ViaXvMCSubPicture *pViaSubPic; + volatile ViaXvMCSAreaPriv *sAPriv; + ViaXvMCCommandBuffer buf; + Status ret; + + if ((display == NULL) || (surface == NULL)) { + return BadValue; + } + if (NULL == (pViaSurface = surface->privData)) { + return (error_base + XvMCBadSurface); + } + if (NULL == (pViaXvMC = pViaSurface->privContext)) { + return (error_base + XvMCBadContext); + } + + ppthread_mutex_lock(&pViaXvMC->ctxMutex); + if (!pViaXvMC->haveXv) { + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return Success; + } + + sAPriv = SAREAPTR(pViaXvMC); + hwlLock(pViaXvMC->xl, 1); + + if (sAPriv->XvMCDisplaying[pViaXvMC->xvMCPort] != + (pViaSurface->srfNo | VIA_XVMC_VALID)) { + hwlUnlock(pViaXvMC->xl, 1); + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return Success; + } + setLowLevelLocking(pViaXvMC->xl, 0); + if (NULL != (pViaSubPic = pViaSurface->privSubPic)) { + if (sAPriv->XvMCSubPicOn[pViaXvMC->xvMCPort] == + (pViaSubPic->srfNo | VIA_XVMC_VALID)) { + sAPriv->XvMCSubPicOn[pViaXvMC->xvMCPort] &= ~VIA_XVMC_VALID; + viaVideoSubPictureOffLocked(pViaXvMC->xl); + } + } + flushPCIXvMCLowLevel(pViaXvMC->xl); + setLowLevelLocking(pViaXvMC->xl, 1); + hwlUnlock(pViaXvMC->xl, 1); + + buf.command = VIA_XVMC_COMMAND_UNDISPLAY; + buf.ctxNo = pViaXvMC->ctxNo | VIA_XVMC_VALID; + buf.srfNo = pViaSurface->srfNo | VIA_XVMC_VALID; + pViaXvMC->xvImage->data = (char *)&buf; + if ((ret = XvPutImage(display, pViaXvMC->port, pViaXvMC->draw, + pViaXvMC->gc, pViaXvMC->xvImage, 0, 0, 1, 1, 0, 0, 1, 1))) { + fprintf(stderr, "XvMCPutSurface: Hiding overlay failed.\n"); + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return ret; + } + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return Success; +} diff --git a/trunk/libxvmc/viaXvMCPriv.h b/trunk/libxvmc/viaXvMCPriv.h new file mode 100644 index 000000000000..2b8e63e88a0d --- /dev/null +++ b/trunk/libxvmc/viaXvMCPriv.h @@ -0,0 +1,197 @@ +/***************************************************************************** + * VIA Unichrome XvMC extension client lib. + * + * Copyright (c) 2004 Thomas Hellström. 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 _VIAXVMCPRIV_H +#define _VIAXVMCPRIV_H 1 + +#include <X11/Xlibint.h> +#include <X11/extensions/XvMC.h> +#include <X11/extensions/XvMClib.h> +#include <stdlib.h> +#include <X11/Xutil.h> +#include "vldXvMC.h" +#include "via_xvmc.h" + +typedef struct +{ + int x; + int y; + int w; + int h; +} XvMCRegion; + +extern Status _xvmc_create_context(Display * dpy, XvMCContext * context, + int *priv_count, uint ** priv_data); +extern Status _xvmc_destroy_context(Display * dpy, XvMCContext * context); +extern Status _xvmc_create_surface(Display * dpy, XvMCContext * context, + XvMCSurface * surface, int *priv_count, uint ** priv_data); +extern Status _xvmc_destroy_surface(Display * dpy, XvMCSurface * surface); +extern Status _xvmc_create_subpicture(Display * dpy, XvMCContext * context, + XvMCSubpicture * subpicture, int *priv_count, uint ** priv_data); +extern Status _xvmc_destroy_subpicture(Display * dpy, + XvMCSubpicture * subpicture); + +#define VIA_SUBPIC_PALETTE_SIZE 16 /*Number of colors in subpicture palette */ +#define VIA_CBUFFERSIZE 4096 /*Hardware command buffer size */ +#define VIA_MAX_BUFS 2 /*Number of YUV buffers per surface */ +#define VIA_MAX_RENDSURF 3 /*Maximum numbers of surfaces per context + * that can answer RENDERING to a rendering + * query */ + +typedef enum +{ + context_drawHash, + context_lowLevel, + context_mutex, + context_sAreaMap, + context_fbMap, + context_mmioMap, + context_drmContext, + context_fd, + context_driConnection, + context_context, + context_none +} ContextRes; + +typedef struct +{ + unsigned ctxNo; /* XvMC private context reference number */ + pthread_mutex_t ctxMutex; /* Mutex for multi-threading. Not used */ + drm_context_t drmcontext; /* The drm context */ + drm_handle_t fbOffset; /* Handle to drm frame-buffer area */ + drm_handle_t mmioOffset; /* Handle to drm mmio area */ + drm_handle_t sAreaOffset; /* Handle to drm shared memory area */ + unsigned fbSize; /* Size of drm frame-buffer area */ + unsigned mmioSize; /* Size of drm mmio area */ + unsigned sAreaSize; /* Size of drm shared memory area */ + unsigned sAreaPrivOffset; /* Offset in sarea to private part */ + drmAddress fbAddress; /* Virtual address of frame buffer area */ + drmAddress mmioAddress; /* Virtual address of mmio area */ + drmAddress sAreaAddress; /* Virtual address of shared memory area */ + char busIdString[21]; /* Busid of video card */ + unsigned yStride; /* Y stride of surfaces in this context */ + int fd; /* FD for connection to drm module */ + unsigned char intra_quantiser_matrix[64]; + unsigned char non_intra_quantiser_matrix[64]; + unsigned char chroma_intra_quantiser_matrix[64]; + unsigned char chroma_non_intra_quantiser_matrix[64]; + unsigned rendSurf[VIA_MAX_RENDSURF]; /* Which surfaces answer rendering to + * a rendering query */ + int decoderOn; /* Decoder switched on ? */ + int intraLoaded; /* Intra quantiser matrix loaded in + * decoder? */ + int nonIntraLoaded; /* Non-Intra quantiser matrix loaded + * in decoder */ + int chromaIntraLoaded; + int chromaNonIntraLoaded; + int haveDecoder; /* Does this context own decoder? */ + int attribChanged; /* Attributes have changed and need to + * be uploaded to Xv at next frame + * display */ + drmLockPtr hwLock; /* Virtual address Pointer to the + * heavyweight drm hardware lock */ + unsigned xvMCPort; /* XvMC private port. Corresponds to + * an Xv port, but not by number */ + ViaXvMCAttrHolder attrib; /* This contexts attributes and their + * values */ + XvAttribute attribDesc[VIA_NUM_XVMC_ATTRIBUTES]; /* Attribute decriptions */ + int useAGP; /* Use the AGP ringbuffer to upload data to the chip */ + void *xl; /* Lowlevel context. Opaque to us. */ + int haveXv; /* Have I initialized the Xv + * connection for this surface? */ + XvImage *xvImage; /* Fake Xv Image used for command + * buffer transport to the X server */ + GC gc; /* X GC needed for displaying */ + Drawable draw; /* Drawable to undisplay from */ + XvPortID port; /* Xv Port ID when displaying */ + int lastSrfDisplaying; + ContextRes resources; + CARD32 timeStamp; + CARD32 videoTimeStamp; + XID id; + unsigned screen; + unsigned depth; + unsigned stride; + XVisualInfo visualInfo; + void *drawHash; + CARD32 chipId; + XvMCRegion sRegion; + XvMCRegion dRegion; +} ViaXvMCContext; + +typedef struct +{ + pthread_mutex_t subMutex; /* Currently not used. */ + unsigned srfNo; /* XvMC private surface number */ + unsigned offset; /* Offset into frame-buffer area */ + unsigned stride; /* Storage stride */ + unsigned width; /* Width */ + unsigned height; /* Height */ + CARD32 palette[VIA_SUBPIC_PALETTE_SIZE]; /* YUV Palette */ + ViaXvMCContext *privContext; /* Pointer to context private data */ + int ia44; /* IA44 or AI44 format */ + int needsSync; + CARD32 timeStamp; +} ViaXvMCSubPicture; + +typedef struct +{ + pthread_mutex_t srfMutex; /* For multithreading. Not used. */ + pthread_cond_t bufferAvailable; /* For multithreading. Not used. */ + unsigned srfNo; /* XvMC private surface numbers */ + unsigned numBuffers; /* Number of picture buffers */ + unsigned curBuf; /* Which is the current buffer? */ + unsigned offsets[VIA_MAX_BUFS]; /* Offsets of picture buffers + * into the frame-buffer area */ + unsigned yStride; /* Stride of YUV420 Y component. */ + unsigned width; /* Dimensions */ + unsigned height; + int progressiveSequence; /* Mpeg progressive picture? Hmm? */ + ViaXvMCContext *privContext; /* XvMC context private part. */ + ViaXvMCSubPicture *privSubPic; /* Subpicture to be blended when + * displaying. NULL if none. */ + int needsSync; + int syncMode; + CARD32 timeStamp; + int topFieldFirst; +} ViaXvMCSurface; + +/* + * Take and release the global drm hardware lock. + */ + +#define HW_LOCK(ctx) \ + DRM_LOCK((ctx)->fd,(ctx)->hwLock,(ctx)->drmcontext,0) +#define HW_UNLOCK(ctx) \ + DRM_UNLOCK((ctx)->fd,(ctx->hwLock),(ctx)->drmcontext) + +/* + * Low-level Mpeg functions in viaLowLevel.c + */ + +#define VIABLIT_TRANSCOPY 0 +#define VIABLIT_COPY 1 +#define VIABLIT_FILL 2 + +#endif diff --git a/trunk/libxvmc/vldXvMC.h b/trunk/libxvmc/vldXvMC.h new file mode 100644 index 000000000000..3b9ceff93bf0 --- /dev/null +++ b/trunk/libxvmc/vldXvMC.h @@ -0,0 +1,178 @@ +/***************************************************************************** + * VLD Nonstandard XvMC extension. + * + * Copyright (c) 2004 The Unichrome Project. 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. + * + * Author: Thomas Hellström, 2004. + */ + +#ifndef _VLDXVMC_H +#define _VLDXVMC_H + +#include <X11/Xlib.h> +#include <X11/extensions/XvMC.h> +#include <X11/extensions/XvMClib.h> + +/* + * New "Motion compensation type". + */ + +#define XVMC_VLD 0x0020000 + +/* + * Below Flags to be passed in the XvMCMpegControl structure 'flag' field. + */ + +#define XVMC_PROGRESSIVE_SEQUENCE 0x00000010 + +/* + * Zig-Zag Scan / Alternative Scan. + */ + +#define XVMC_ZIG_ZAG_SCAN 0x00000000 +#define XVMC_ALTERNATE_SCAN 0x00000100 + +/* + * Frame DCT and frame prediction are used. / + * Field prediction + */ + +#define XVMC_PRED_DCT_FRAME 0x00000040 +#define XVMC_PRED_DCT_FIELD 0x00000000 + +/* + * Top / Bottom field first + */ + +#define XVMC_TOP_FIELD_FIRST 0x00000080 +#define XVMC_BOTTOM_FIELD_FIRST 0x00000000 + +/* + * Motion vectors coded in intra macroblocks + */ + +#define XVMC_CONCEALMENT_MOTION_VECTORS 0x00000200 + +/* + * Which of two mappings between quantiser_scale_code + * and quantiser_scale shall apply. + */ + +#define XVMC_Q_SCALE_TYPE 0x00000400 + +/* + * Intra VLC Format: Bit = 0, Bit = 1 + * Intra blocks B-14 B-15 + * Non-intra blocks B-14 B-14 + */ +#define XVMC_INTRA_VLC_FORMAT 0x00000800 + +/* + * Also XVMC_SECOND_FIELD should be set in flags if active. + */ + +#define XVMC_I_PICTURE 1 +#define XVMC_P_PICTURE 2 +#define XVMC_B_PICTURE 3 + +typedef struct _XvMCMpegControl +{ + unsigned BVMV_range, /* Backward vertical motion vector range */ + BHMV_range, /* Backward horizontal motion vector range */ + FVMV_range, /* Forward vertical motion vector range */ + FHMV_range, /* Forward horizontal motion vector range */ + picture_structure, /* XVMC_TOP_FIELD, XVMC_BOTTOM_FIELD, + * XVMC_FRAME_PICTURE + */ + intra_dc_precision, /* 0x00 - 0x03 corresponds to 8 to 11 bits prec. */ + picture_coding_type, /* XVMC_X_PICTURE */ + mpeg_coding, /* XVMC_MPEG_2 */ + flags; /* See above */ +} XvMCMpegControl; + +/* + * The following function is called BEFORE starting sending slices to the + * lib. It grabs the decoder hardware and prepares it for coming slices. + * The function XvMCSyncSurface will release the hardware for other contexts + * in addition to it's current functionality. + */ + +extern Status XvMCBeginSurface(Display * display, + XvMCContext * context, + XvMCSurface * target_surface, + XvMCSurface * past_surface, + XvMCSurface * future_surface, const XvMCMpegControl * control); + +/* + * The quantizer matrix structure. This should be filled in by the user and + * uploaded whenever a change is needed. The lib initializes with + * default matrices and will automatically load the hardware with new matrices + * on decoder context switches. To load data, set the corresponding load flag + * to true and fill in the values. The VIA MPEG2 engine only uses the + * intra_quantiser_matrix and the non_intra_quantiser_matrix. RFC: Are + * the other fields needed for future compatibility? + */ + +typedef struct _XvMCQMatrix +{ + int load_intra_quantiser_matrix; + int load_non_intra_quantiser_matrix; + int load_chroma_intra_quantiser_matrix; + int load_chroma_non_intra_quantiser_matrix; + unsigned char intra_quantiser_matrix[64]; + unsigned char non_intra_quantiser_matrix[64]; + unsigned char chroma_intra_quantiser_matrix[64]; + unsigned char chroma_non_intra_quantiser_matrix[64]; +} XvMCQMatrix; + +/* + * Upload a XvMCQMatrix structure to the clientlib. + * The hardware will start using it the next XvMCBeginSurface. + */ + +extern Status XvMCLoadQMatrix(Display * display, XvMCContext * context, + const XvMCQMatrix * qmx); + +/* + * Put a slice to the decoder. The hardware will start processing it + * immediately. + */ + +extern Status XvMCPutSlice(Display * display, XvMCContext * context, + char *slice, int nBytes); +/* + * Put a slice without the slice start code to the decoder. + * The hardware will start processing it + * immediately. This function is for client optimization. + * XvMCPutSlice(display,context,slice,nBytes) is equivalent to + * XvMCPutSlice2(display,context,slice+4,nBytes-4,slice[3]); + */ + +extern Status XvMCPutSlice2(Display * display, XvMCContext * context, + char *slice, int nBytes, int sliceCode); + +/* + * Debug the XvMCControl structure. For convenience only. + */ + +extern void debugControl(const XvMCMpegControl * control); + +#endif diff --git a/trunk/libxvmc/xf86dri.c b/trunk/libxvmc/xf86dri.c new file mode 100644 index 000000000000..1feb23297de6 --- /dev/null +++ b/trunk/libxvmc/xf86dri.c @@ -0,0 +1,599 @@ +/* $XFree86: xc/lib/GL/dri/XF86dri.c,v 1.13 2002/10/30 12:51:25 alanh Exp $ */ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright 2000 VA Linux Systems, Inc. +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, sub license, 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 NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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: + * Kevin E. Martin <martin@valinux.com> + * Jens Owen <jens@tungstengraphics.com> + * Rickard E. (Rik) Faith <faith@valinux.com> + * + */ + +/* THIS IS NOT AN X CONSORTIUM STANDARD */ + +#define NEED_REPLIES +#include <X11/Xlibint.h> +#include <X11/extensions/Xext.h> +#include <X11/extensions/extutil.h> +#include "xf86dristr.h" + +static XExtensionInfo _xf86dri_info_data; +static XExtensionInfo *xf86dri_info = &_xf86dri_info_data; +static char xf86dri_extension_name[] = XF86DRINAME; + +#define uniDRICheckExtension(dpy,i,val) \ + XextCheckExtension (dpy, i, xf86dri_extension_name, val) + +/***************************************************************************** + * * + * private utility routines * + * * + *****************************************************************************/ + +static int close_display(Display * dpy, XExtCodes * extCodes); +static /* const */ XExtensionHooks xf86dri_extension_hooks = { + NULL, /* create_gc */ + NULL, /* copy_gc */ + NULL, /* flush_gc */ + NULL, /* free_gc */ + NULL, /* create_font */ + NULL, /* free_font */ + close_display, /* close_display */ + NULL, /* wire_to_event */ + NULL, /* event_to_wire */ + NULL, /* error */ + NULL, /* error_string */ +}; + +static +XEXT_GENERATE_FIND_DISPLAY(find_display, xf86dri_info, + xf86dri_extension_name, &xf86dri_extension_hooks, 0, NULL) + + static XEXT_GENERATE_CLOSE_DISPLAY(close_display, xf86dri_info) + +/***************************************************************************** + * * + * public XFree86-DRI Extension routines * + * * + *****************************************************************************/ +#if 0 +#include <stdio.h> +#define TRACE(msg) fprintf(stderr,"uniDRI%s\n", msg); +#else +#define TRACE(msg) +#endif + Bool uniDRIQueryExtension(dpy, event_basep, error_basep) + Display *dpy; + int *event_basep, *error_basep; +{ + XExtDisplayInfo *info = find_display(dpy); + + TRACE("QueryExtension..."); + if (XextHasExtension(info)) { + *event_basep = info->codes->first_event; + *error_basep = info->codes->first_error; + TRACE("QueryExtension... return True"); + return True; + } else { + TRACE("QueryExtension... return False"); + return False; + } +} + +Bool +uniDRIQueryVersion(dpy, majorVersion, minorVersion, patchVersion) + Display *dpy; + int *majorVersion; + int *minorVersion; + int *patchVersion; +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIQueryVersionReply rep; + xXF86DRIQueryVersionReq *req; + + TRACE("QueryVersion..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIQueryVersion, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIQueryVersion; + if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("QueryVersion... return False"); + return False; + } + *majorVersion = rep.majorVersion; + *minorVersion = rep.minorVersion; + *patchVersion = rep.patchVersion; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("QueryVersion... return True"); + return True; +} + +Bool +uniDRIQueryDirectRenderingCapable(dpy, screen, isCapable) + Display *dpy; + int screen; + Bool *isCapable; +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIQueryDirectRenderingCapableReply rep; + xXF86DRIQueryDirectRenderingCapableReq *req; + + TRACE("QueryDirectRenderingCapable..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIQueryDirectRenderingCapable, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIQueryDirectRenderingCapable; + req->screen = screen; + if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("QueryDirectRenderingCapable... return False"); + return False; + } + *isCapable = rep.isCapable; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("QueryDirectRenderingCapable... return True"); + return True; +} + +Bool +uniDRIOpenConnection(dpy, screen, hSAREA, busIdString) + Display *dpy; + int screen; + drm_handle_t *hSAREA; + char **busIdString; +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIOpenConnectionReply rep; + xXF86DRIOpenConnectionReq *req; + + TRACE("OpenConnection..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIOpenConnection, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIOpenConnection; + req->screen = screen; + if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("OpenConnection... return False"); + return False; + } + + *hSAREA = rep.hSAREALow; +#ifdef LONG64 + if (sizeof(drm_handle_t) == 8) { + *hSAREA |= ((unsigned long)rep.hSAREAHigh) << 32; + } +#endif + if (rep.length) { + if (!(*busIdString = (char *)Xcalloc(rep.busIdStringLength + 1, 1))) { + _XEatData(dpy, ((rep.busIdStringLength + 3) & ~3)); + UnlockDisplay(dpy); + SyncHandle(); + TRACE("OpenConnection... return False"); + return False; + } + _XReadPad(dpy, *busIdString, rep.busIdStringLength); + } else { + *busIdString = NULL; + } + UnlockDisplay(dpy); + SyncHandle(); + TRACE("OpenConnection... return True"); + return True; +} + +Bool +uniDRIAuthConnection(dpy, screen, magic) + Display *dpy; + int screen; + drm_magic_t magic; +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIAuthConnectionReq *req; + xXF86DRIAuthConnectionReply rep; + + TRACE("AuthConnection..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIAuthConnection, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIAuthConnection; + req->screen = screen; + req->magic = magic; + rep.authenticated = 0; + if (!_XReply(dpy, (xReply *) & rep, 0, xFalse) || !rep.authenticated) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("AuthConnection... return False"); + return False; + } + UnlockDisplay(dpy); + SyncHandle(); + TRACE("AuthConnection... return True"); + return True; +} + +Bool +uniDRICloseConnection(dpy, screen) + Display *dpy; + int screen; +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRICloseConnectionReq *req; + + TRACE("CloseConnection..."); + + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRICloseConnection, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRICloseConnection; + req->screen = screen; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CloseConnection... return True"); + return True; +} + +Bool +uniDRIGetClientDriverName(dpy, screen, ddxDriverMajorVersion, + ddxDriverMinorVersion, ddxDriverPatchVersion, clientDriverName) + Display *dpy; + int screen; + int *ddxDriverMajorVersion; + int *ddxDriverMinorVersion; + int *ddxDriverPatchVersion; + char **clientDriverName; +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIGetClientDriverNameReply rep; + xXF86DRIGetClientDriverNameReq *req; + + TRACE("GetClientDriverName..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIGetClientDriverName, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIGetClientDriverName; + req->screen = screen; + if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetClientDriverName... return False"); + return False; + } + + *ddxDriverMajorVersion = rep.ddxDriverMajorVersion; + *ddxDriverMinorVersion = rep.ddxDriverMinorVersion; + *ddxDriverPatchVersion = rep.ddxDriverPatchVersion; + + if (rep.length) { + if (!(*clientDriverName = + (char *)Xcalloc(rep.clientDriverNameLength + 1, 1))) { + _XEatData(dpy, ((rep.clientDriverNameLength + 3) & ~3)); + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetClientDriverName... return False"); + return False; + } + _XReadPad(dpy, *clientDriverName, rep.clientDriverNameLength); + } else { + *clientDriverName = NULL; + } + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetClientDriverName... return True"); + return True; +} + +Bool +uniDRICreateContextWithConfig(dpy, screen, configID, context, hHWContext) + Display *dpy; + int screen; + int configID; + XID *context; + drm_context_t *hHWContext; +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRICreateContextReply rep; + xXF86DRICreateContextReq *req; + + TRACE("CreateContext..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRICreateContext, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRICreateContext; + req->visual = configID; + req->screen = screen; + *context = XAllocID(dpy); + req->context = *context; + if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CreateContext... return False"); + return False; + } + *hHWContext = rep.hHWContext; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CreateContext... return True"); + return True; +} + +Bool +uniDRICreateContext(dpy, screen, visual, context, hHWContext) + Display *dpy; + int screen; + Visual *visual; + XID *context; + drm_context_t *hHWContext; +{ + return uniDRICreateContextWithConfig(dpy, screen, visual->visualid, + context, hHWContext); +} + +Bool +uniDRIDestroyContext(Display * ndpy, int screen, XID context) +{ + Display *const dpy = (Display *) ndpy; + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIDestroyContextReq *req; + + TRACE("DestroyContext..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIDestroyContext, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIDestroyContext; + req->screen = screen; + req->context = context; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("DestroyContext... return True"); + return True; +} + +Bool +uniDRICreateDrawable(Display * ndpy, int screen, + Drawable drawable, drm_drawable_t * hHWDrawable) +{ + Display *const dpy = (Display *) ndpy; + XExtDisplayInfo *info = find_display(dpy); + xXF86DRICreateDrawableReply rep; + xXF86DRICreateDrawableReq *req; + + TRACE("CreateDrawable..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRICreateDrawable, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRICreateDrawable; + req->screen = screen; + req->drawable = drawable; + if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CreateDrawable... return False"); + return False; + } + *hHWDrawable = rep.hHWDrawable; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CreateDrawable... return True"); + return True; +} + +Bool +uniDRIDestroyDrawable(Display * ndpy, int screen, Drawable drawable) +{ + Display *const dpy = (Display *) ndpy; + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIDestroyDrawableReq *req; + + TRACE("DestroyDrawable..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIDestroyDrawable, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIDestroyDrawable; + req->screen = screen; + req->drawable = drawable; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("DestroyDrawable... return True"); + return True; +} + +Bool +uniDRIGetDrawableInfo(Display * dpy, int screen, Drawable drawable, + unsigned int *index, unsigned int *stamp, + int *X, int *Y, int *W, int *H, + int *numClipRects, drm_clip_rect_t ** pClipRects, + int *backX, int *backY, + int *numBackClipRects, drm_clip_rect_t ** pBackClipRects) +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIGetDrawableInfoReply rep; + xXF86DRIGetDrawableInfoReq *req; + int total_rects; + + TRACE("GetDrawableInfo..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIGetDrawableInfo, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIGetDrawableInfo; + req->screen = screen; + req->drawable = drawable; + + if (!_XReply(dpy, (xReply *) & rep, 1, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDrawableInfo... return False"); + return False; + } + *index = rep.drawableTableIndex; + *stamp = rep.drawableTableStamp; + *X = (int)rep.drawableX; + *Y = (int)rep.drawableY; + *W = (int)rep.drawableWidth; + *H = (int)rep.drawableHeight; + *numClipRects = rep.numClipRects; + total_rects = *numClipRects; + + *backX = rep.backX; + *backY = rep.backY; + *numBackClipRects = rep.numBackClipRects; + total_rects += *numBackClipRects; + +#if 0 + /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks + * backwards compatibility (Because of the >> 2 shift) but the fix + * enables multi-threaded apps to work. + */ + if (rep.length != ((((SIZEOF(xXF86DRIGetDrawableInfoReply) - + SIZEOF(xGenericReply) + + total_rects * sizeof(drm_clip_rect_t)) + + 3) & ~3) >> 2)) { + _XEatData(dpy, rep.length); + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDrawableInfo... return False"); + return False; + } +#endif + + if (*numClipRects) { + int len = sizeof(drm_clip_rect_t) * (*numClipRects); + + *pClipRects = (drm_clip_rect_t *) Xcalloc(len, 1); + if (*pClipRects) + _XRead(dpy, (char *)*pClipRects, len); + } else { + *pClipRects = NULL; + } + + if (*numBackClipRects) { + int len = sizeof(drm_clip_rect_t) * (*numBackClipRects); + + *pBackClipRects = (drm_clip_rect_t *) Xcalloc(len, 1); + if (*pBackClipRects) + _XRead(dpy, (char *)*pBackClipRects, len); + } else { + *pBackClipRects = NULL; + } + + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDrawableInfo... return True"); + return True; +} + +Bool +uniDRIGetDeviceInfo(dpy, screen, hFrameBuffer, + fbOrigin, fbSize, fbStride, devPrivateSize, pDevPrivate) + Display *dpy; + int screen; + drm_handle_t *hFrameBuffer; + int *fbOrigin; + int *fbSize; + int *fbStride; + int *devPrivateSize; + void **pDevPrivate; +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIGetDeviceInfoReply rep; + xXF86DRIGetDeviceInfoReq *req; + + TRACE("GetDeviceInfo..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIGetDeviceInfo, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIGetDeviceInfo; + req->screen = screen; + if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDeviceInfo... return False"); + return False; + } + + *hFrameBuffer = rep.hFrameBufferLow; +#ifdef LONG64 + if (sizeof(drm_handle_t) == 8) { + *hFrameBuffer |= ((unsigned long)rep.hFrameBufferHigh) << 32; + } +#endif + + *fbOrigin = rep.framebufferOrigin; + *fbSize = rep.framebufferSize; + *fbStride = rep.framebufferStride; + *devPrivateSize = rep.devPrivateSize; + + if (rep.length) { + if (!(*pDevPrivate = (void *)Xcalloc(rep.devPrivateSize, 1))) { + _XEatData(dpy, ((rep.devPrivateSize + 3) & ~3)); + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDeviceInfo... return False"); + return False; + } + _XRead(dpy, (char *)*pDevPrivate, rep.devPrivateSize); + } else { + *pDevPrivate = NULL; + } + + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDeviceInfo... return True"); + return True; +} diff --git a/trunk/libxvmc/xf86dri.h b/trunk/libxvmc/xf86dri.h new file mode 100644 index 000000000000..34197874fefb --- /dev/null +++ b/trunk/libxvmc/xf86dri.h @@ -0,0 +1,116 @@ +/* $XFree86: xc/lib/GL/dri/xf86dri.h,v 1.8 2002/10/30 12:51:25 alanh Exp $ */ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright 2000 VA Linux Systems, Inc. +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, sub license, 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 NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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. + +**************************************************************************/ + +/** + * \file xf86dri.h + * Protocol numbers and function prototypes for DRI X protocol. + * + * \author Kevin E. Martin <martin@valinux.com> + * \author Jens Owen <jens@tungstengraphics.com> + * \author Rickard E. (Rik) Faith <faith@valinux.com> + */ + +#ifndef _XF86DRI_H_ +#define _XF86DRI_H_ + +#include <X11/Xfuncproto.h> +#include <xf86drm.h> + +#define X_XF86DRIQueryVersion 0 +#define X_XF86DRIQueryDirectRenderingCapable 1 +#define X_XF86DRIOpenConnection 2 +#define X_XF86DRICloseConnection 3 +#define X_XF86DRIGetClientDriverName 4 +#define X_XF86DRICreateContext 5 +#define X_XF86DRIDestroyContext 6 +#define X_XF86DRICreateDrawable 7 +#define X_XF86DRIDestroyDrawable 8 +#define X_XF86DRIGetDrawableInfo 9 +#define X_XF86DRIGetDeviceInfo 10 +#define X_XF86DRIAuthConnection 11 +#define X_XF86DRIOpenFullScreen 12 /* Deprecated */ +#define X_XF86DRICloseFullScreen 13 /* Deprecated */ + +#define XF86DRINumberEvents 0 + +#define XF86DRIClientNotLocal 0 +#define XF86DRIOperationNotSupported 1 +#define XF86DRINumberErrors (XF86DRIOperationNotSupported + 1) + +#ifndef _XF86DRI_SERVER_ + +_XFUNCPROTOBEGIN + Bool uniDRIQueryExtension(Display * dpy, int *event_base, + int *error_base); + +Bool uniDRIQueryVersion(Display * dpy, int *majorVersion, int *minorVersion, + int *patchVersion); + +Bool uniDRIQueryDirectRenderingCapable(Display * dpy, int screen, + Bool * isCapable); + +Bool uniDRIOpenConnection(Display * dpy, int screen, drm_handle_t * hSAREA, + char **busIDString); + +Bool uniDRIAuthConnection(Display * dpy, int screen, drm_magic_t magic); + +Bool uniDRICloseConnection(Display * dpy, int screen); + +Bool uniDRIGetClientDriverName(Display * dpy, int screen, + int *ddxDriverMajorVersion, int *ddxDriverMinorVersion, + int *ddxDriverPatchVersion, char **clientDriverName); + +Bool uniDRICreateContext(Display * dpy, int screen, Visual * visual, + XID * ptr_to_returned_context_id, drm_context_t * hHWContext); + +Bool uniDRICreateContextWithConfig(Display * dpy, int screen, int configID, + XID * ptr_to_returned_context_id, drm_context_t * hHWContext); + +extern Bool uniDRIDestroyContext(Display * dpy, int screen, XID context_id); + +extern Bool uniDRICreateDrawable(Display * dpy, int screen, + Drawable drawable, drm_drawable_t * hHWDrawable); + +extern Bool uniDRIDestroyDrawable(Display * dpy, int screen, + Drawable drawable); + +Bool uniDRIGetDrawableInfo(Display * dpy, int screen, Drawable drawable, + unsigned int *index, unsigned int *stamp, + int *X, int *Y, int *W, int *H, + int *numClipRects, drm_clip_rect_t ** pClipRects, + int *backX, int *backY, + int *numBackClipRects, drm_clip_rect_t ** pBackClipRects); + +Bool uniDRIGetDeviceInfo(Display * dpy, int screen, + drm_handle_t * hFrameBuffer, int *fbOrigin, int *fbSize, + int *fbStride, int *devPrivateSize, void **pDevPrivate); + +_XFUNCPROTOEND +#endif /* _XF86DRI_SERVER_ */ +#endif /* _XF86DRI_H_ */ diff --git a/trunk/libxvmc/xf86dristr.h b/trunk/libxvmc/xf86dristr.h new file mode 100644 index 000000000000..3b43438e7f70 --- /dev/null +++ b/trunk/libxvmc/xf86dristr.h @@ -0,0 +1,390 @@ +/* $XFree86: xc/lib/GL/dri/xf86dristr.h,v 1.10 2002/10/30 12:51:25 alanh Exp $ */ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright 2000 VA Linux Systems, Inc. +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, sub license, 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 NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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: + * Kevin E. Martin <martin@valinux.com> + * Jens Owen <jens@tungstengraphics.com> + * Rickard E. (Rik) Fiath <faith@valinux.com> + * + */ + +#ifndef _XF86DRISTR_H_ +#define _XF86DRISTR_H_ + +#include "xf86dri.h" + +#define XF86DRINAME "XFree86-DRI" + +/* The DRI version number. This was originally set to be the same of the + * XFree86 version number. However, this version is really indepedent of + * the XFree86 version. + * + * Version History: + * 4.0.0: Original + * 4.0.1: Patch to bump clipstamp when windows are destroyed, 28 May 02 + * 4.1.0: Add transition from single to multi in DRMInfo rec, 24 Jun 02 + */ +#define XF86DRI_MAJOR_VERSION 4 +#define XF86DRI_MINOR_VERSION 1 +#define XF86DRI_PATCH_VERSION 0 + +typedef struct _XF86DRIQueryVersion +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIQueryVersion */ + CARD16 length B16; +} xXF86DRIQueryVersionReq; + +#define sz_xXF86DRIQueryVersionReq 4 + +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 majorVersion B16; /* major version of DRI protocol */ + CARD16 minorVersion B16; /* minor version of DRI protocol */ + CARD32 patchVersion B32; /* patch version of DRI protocol */ + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRIQueryVersionReply; + +#define sz_xXF86DRIQueryVersionReply 32 + +typedef struct _XF86DRIQueryDirectRenderingCapable +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* X_DRIQueryDirectRenderingCapable */ + CARD16 length B16; + CARD32 screen B32; +} xXF86DRIQueryDirectRenderingCapableReq; + +#define sz_xXF86DRIQueryDirectRenderingCapableReq 8 + +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + BOOL isCapable; + BOOL pad2; + BOOL pad3; + BOOL pad4; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; + CARD32 pad8 B32; + CARD32 pad9 B32; +} xXF86DRIQueryDirectRenderingCapableReply; + +#define sz_xXF86DRIQueryDirectRenderingCapableReply 32 + +typedef struct _XF86DRIOpenConnection +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIOpenConnection */ + CARD16 length B16; + CARD32 screen B32; +} xXF86DRIOpenConnectionReq; + +#define sz_xXF86DRIOpenConnectionReq 8 + +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 hSAREALow B32; + CARD32 hSAREAHigh B32; + CARD32 busIdStringLength B32; + CARD32 pad6 B32; + CARD32 pad7 B32; + CARD32 pad8 B32; +} xXF86DRIOpenConnectionReply; + +#define sz_xXF86DRIOpenConnectionReply 32 + +typedef struct _XF86DRIAuthConnection +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICloseConnection */ + CARD16 length B16; + CARD32 screen B32; + CARD32 magic B32; +} xXF86DRIAuthConnectionReq; + +#define sz_xXF86DRIAuthConnectionReq 12 + +typedef struct +{ + BYTE type; + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 authenticated B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRIAuthConnectionReply; + +#define zx_xXF86DRIAuthConnectionReply 32 + +typedef struct _XF86DRICloseConnection +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICloseConnection */ + CARD16 length B16; + CARD32 screen B32; +} xXF86DRICloseConnectionReq; + +#define sz_xXF86DRICloseConnectionReq 8 + +typedef struct _XF86DRIGetClientDriverName +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIGetClientDriverName */ + CARD16 length B16; + CARD32 screen B32; +} xXF86DRIGetClientDriverNameReq; + +#define sz_xXF86DRIGetClientDriverNameReq 8 + +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 ddxDriverMajorVersion B32; + CARD32 ddxDriverMinorVersion B32; + CARD32 ddxDriverPatchVersion B32; + CARD32 clientDriverNameLength B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRIGetClientDriverNameReply; + +#define sz_xXF86DRIGetClientDriverNameReply 32 + +typedef struct _XF86DRICreateContext +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICreateContext */ + CARD16 length B16; + CARD32 screen B32; + CARD32 visual B32; + CARD32 context B32; +} xXF86DRICreateContextReq; + +#define sz_xXF86DRICreateContextReq 16 + +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 hHWContext B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRICreateContextReply; + +#define sz_xXF86DRICreateContextReply 32 + +typedef struct _XF86DRIDestroyContext +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIDestroyContext */ + CARD16 length B16; + CARD32 screen B32; + CARD32 context B32; +} xXF86DRIDestroyContextReq; + +#define sz_xXF86DRIDestroyContextReq 12 + +typedef struct _XF86DRICreateDrawable +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICreateDrawable */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xXF86DRICreateDrawableReq; + +#define sz_xXF86DRICreateDrawableReq 12 + +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 hHWDrawable B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRICreateDrawableReply; + +#define sz_xXF86DRICreateDrawableReply 32 + +typedef struct _XF86DRIDestroyDrawable +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIDestroyDrawable */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xXF86DRIDestroyDrawableReq; + +#define sz_xXF86DRIDestroyDrawableReq 12 + +typedef struct _XF86DRIGetDrawableInfo +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIGetDrawableInfo */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xXF86DRIGetDrawableInfoReq; + +#define sz_xXF86DRIGetDrawableInfoReq 12 + +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 drawableTableIndex B32; + CARD32 drawableTableStamp B32; + INT16 drawableX B16; + INT16 drawableY B16; + INT16 drawableWidth B16; + INT16 drawableHeight B16; + CARD32 numClipRects B32; + INT16 backX B16; + INT16 backY B16; + CARD32 numBackClipRects B32; +} xXF86DRIGetDrawableInfoReply; + +#define sz_xXF86DRIGetDrawableInfoReply 36 + +typedef struct _XF86DRIGetDeviceInfo +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIGetDeviceInfo */ + CARD16 length B16; + CARD32 screen B32; +} xXF86DRIGetDeviceInfoReq; + +#define sz_xXF86DRIGetDeviceInfoReq 8 + +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 hFrameBufferLow B32; + CARD32 hFrameBufferHigh B32; + CARD32 framebufferOrigin B32; + CARD32 framebufferSize B32; + CARD32 framebufferStride B32; + CARD32 devPrivateSize B32; +} xXF86DRIGetDeviceInfoReply; + +#define sz_xXF86DRIGetDeviceInfoReply 32 + +typedef struct _XF86DRIOpenFullScreen +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIOpenFullScreen */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xXF86DRIOpenFullScreenReq; + +#define sz_xXF86DRIOpenFullScreenReq 12 + +typedef struct +{ + BYTE type; + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 isFullScreen B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRIOpenFullScreenReply; + +#define sz_xXF86DRIOpenFullScreenReply 32 + +typedef struct _XF86DRICloseFullScreen +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICloseFullScreen */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xXF86DRICloseFullScreenReq; + +#define sz_xXF86DRICloseFullScreenReq 12 + +typedef struct +{ + BYTE type; + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xXF86DRICloseFullScreenReply; + +#define sz_xXF86DRICloseFullScreenReply 32 + +#endif /* _XF86DRISTR_H_ */ diff --git a/trunk/man/Makefile.am b/trunk/man/Makefile.am new file mode 100644 index 000000000000..a16c38724c76 --- /dev/null +++ b/trunk/man/Makefile.am @@ -0,0 +1,62 @@ +# $Id: Makefile.am,v 1.4 2005/10/18 00:01:55 alanc Exp $ +# +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation. +# +# 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 OPEN GROUP 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. +# +# Except as contained in this notice, the name of the copyright holders shall +# not be used in advertising or otherwise to promote the sale, use or +# other dealings in this Software without prior written authorization +# from the copyright holders. +# + +drivermandir = $(mandir)/man$(DRIVER_MAN_SUFFIX) + +driverman_MANFILES = @DRIVER_NAME@.man + +driverman_DATA = $(driverman_MANFILES:man=@DRIVER_MAN_SUFFIX@) + +EXTRA_DIST = @DRIVER_NAME@.man + +CLEANFILES = $(driverman_DATA) + +SED = sed + +# Strings to replace in man pages +XORGRELSTRING = @PACKAGE_STRING@ + XORGMANNAME = X Version 11 + +MAN_SUBSTS = \ + -e 's|__vendorversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \ + -e 's|__xorgversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \ + -e 's|__xservername__|Xorg|g' \ + -e 's|__xconfigfile__|xorg.conf|g' \ + -e 's|__projectroot__|$(prefix)|g' \ + -e 's|__appmansuffix__|$(APP_MAN_SUFFIX)|g' \ + -e 's|__drivermansuffix__|$(DRIVER_MAN_SUFFIX)|g' \ + -e 's|__adminmansuffix__|$(ADMIN_MAN_SUFFIX)|g' \ + -e 's|__miscmansuffix__|$(MISC_MAN_SUFFIX)|g' \ + -e 's|__filemansuffix__|$(FILE_MAN_SUFFIX)|g' + +SUFFIXES = .$(DRIVER_MAN_SUFFIX) .man + +.man.$(DRIVER_MAN_SUFFIX): + sed $(MAN_SUBSTS) < $< > $@ + +@DRIVER_NAME@.man: + ln -s -f $(top_srcdir)/src/@DRIVER_NAME@.man . diff --git a/trunk/prepare-ChangeLogSVN.pl b/trunk/prepare-ChangeLogSVN.pl new file mode 100755 index 000000000000..d913dc344725 --- /dev/null +++ b/trunk/prepare-ChangeLogSVN.pl @@ -0,0 +1,603 @@ +#!/usr/bin/perl -w +# -*- Mode: perl; indent-tabs-mode: nil; c-basic-offset: 2 -*- + +# Perl script to create a ChangeLog entry with names of files +# and functions from a svn diff. +# +# Darin Adler <darin@bentspoon.com>, started 20 April 2000 +# Java support added by Maciej Stachowiak <mjs@eazel.com> +# Adapted for subversion by Thomas Hellstrom <unichrome-at-shipmail-dot-org> +# last updated 11 May 2005 +# +# (Someone put a license in here, like maybe GPL.) +# +# TODO: +# For new files, just say "New file" instead of listing +# function names. +# List functions that have been removed too. +# Decide what a good logical order is for the changed files +# other than a normal text "sort" (top level first?) +# (group directories?) (.h before .c?) +# Leave a diff file behind if asked, but in unified format. +# Handle C++ and yacc source files too (other languages?). +# Help merge when there are ChangeLog conflicts or if there's +# already a partly written ChangeLog entry. +# Add command line option to put the ChangeLog into a separate +# file or just spew it out stdout. +# Figure out how to allow -z options from .cvsrc to work without +# letting other bad options work. Currently the -f disables +# everything from the .cvsrc. +# Add CVS version numbers for each file too (can't do that until +# the changes are checked in, though). +# Work around diff stupidity where deleting a function that starts +# with a comment makes diff think that the following function +# has been changed (if the following function starts with a comment +# with the same first line, such as /**) +# Work around diff stupidity where deleting an entire function and +# the blank lines before it makes diff think you've changed the +# previous function. + +use diagnostics; +use strict; + +use English; +use Text::Wrap; + +# For each file, build a list of modified lines. +# Use line numbers from the "after" side of each diff. +print STDERR " Running svn diff to find changes.\n"; +my %changed_line_ranges; +my $file; +open DIFF, "svn diff --diff-cmd diff -x -N |" or die "The svn diff failed: $OS_ERROR.\n"; +while (<DIFF>) + { + $file = $1 if /^Index: (\S+)$/; + if (defined $file + and $file ne "ChangeLog" + and (/^\d+(,\d+)?[acd](\d+)(,(\d+))?/ or /^Binary files/) ) + { + push @{$changed_line_ranges{$file}}, [ $2, $4 || $2 ]; + } + } +close DIFF; +if (!%changed_line_ranges) + { + print STDERR " No changes found.\n"; + exit; + } + +# For each ".c" file, convert line range to function list. +print STDERR " Extracting affected function names from C source files.\n"; +my %function_lists; +foreach my $file (keys %changed_line_ranges) + { + # An empty function list still indicates that something changed. + $function_lists{$file} = ""; + + # Only look for function names in .c files. + next unless $file =~ /\.(c|java)/; + + # Find all the functions in the file. + open SOURCE, $file or next; + my @function_ranges = get_function_line_ranges(\*SOURCE, $file); + close SOURCE; + + # Find all the modified functions. + my @functions; + my %saw_function; + my @change_ranges = (@{$changed_line_ranges{$file}}, []); + my @change_range = (0, 0); + FUNCTION: foreach my $function_range_ref (@function_ranges) + { + my @function_range = @$function_range_ref; + + # Advance to successive change ranges. + for (;; @change_range = @{shift @change_ranges}) + { + last FUNCTION unless @change_range; + + # If past this function, move on to the next one. + next FUNCTION if $change_range[0] > $function_range[1]; + + # If an overlap with this function range, record the function name. + if ($change_range[1] >= $function_range[0] + and $change_range[0] <= $function_range[1]) + { + if (!$saw_function{$function_range[2]}) + { + $saw_function{$function_range[2]} = 1; + push @functions, $function_range[2]; + } + next FUNCTION; + } + } + } + + # Format the list of functions now. + $function_lists{$file} = " (" . join("), (", @functions) . "):" if @functions; + } + +# Get some pieces of the ChangeLog we are about to write. +my $date = sprintf "%d-%02d-%02d", + 1900 + (localtime $BASETIME)[5], # year + 1 + (localtime $BASETIME)[4], # month + (localtime $BASETIME)[3]; # day within month +my $name = $ENV{CHANGE_LOG_NAME} + || $ENV{REAL_NAME} + || (getpwuid $REAL_USER_ID)[6] + || "set REAL_NAME environment variable"; +my $email_address = $ENV{CHANGE_LOG_EMAIL_ADDRESS} + || $ENV{EMAIL_ADDRESS} + || "set EMAIL_ADDRESS environment variable"; + +# Find the change logs. +my %has_log; +my %files; +foreach my $file (sort keys %function_lists) + { + my $prefix = $file; + my $has_log = 0; + while ($prefix) + { + $prefix =~ s-/[^/]+/?$-/- or $prefix = ""; + $has_log = $has_log{$prefix}; + if (!defined $has_log) + { + $has_log = -f "${prefix}ChangeLog"; + $has_log{$prefix} = $has_log; + } + last if $has_log; + } + if (!$has_log) + { + print STDERR "No ChangeLog found for $file.\n"; + } + else + { + push @{$files{$prefix}}, $file; + } + } + +# Get the latest ChangeLog files from svn. +my $logs = ""; +foreach my $prefix (sort keys %files) + { + $logs .= " ${prefix}ChangeLog"; + } +if ($logs) + { + print STDERR " Updating ChangeLog files from svn repository.\n"; + open ERRORS, "svn update$logs |" or die "The svn update of ChangeLog files failed: $OS_ERROR.\n"; + print STDERR " $ARG" while <ERRORS>; + close ERRORS; + } + + +# Write out a new ChangeLog file. +foreach my $prefix (sort keys %files) + { + print STDERR " Editing the ${prefix}ChangeLog file.\n"; + open OLD_CHANGE_LOG, "${prefix}ChangeLog" or die "Could not open ${prefix}ChangeLog file: $OS_ERROR.\n"; + # It's less efficient to read the whole thing into memory than it would be + # to read it while we prepend to it later, but I like doing this part first. + my @old_change_log = <OLD_CHANGE_LOG>; + close OLD_CHANGE_LOG; + open CHANGE_LOG, "> ${prefix}ChangeLog" or die "Could not write ${prefix}ChangeLog\n."; + print CHANGE_LOG "$date $name <$email_address>\n\n"; + print CHANGE_LOG "\treviewed by: <delete if not using a buddy>\n\n"; + foreach my $file (sort @{$files{$prefix}}) + { + my $file_stem = substr $file, length $prefix; + my $lines = wrap("\t", "\t", "XX$file_stem:$function_lists{$file}"); + $lines =~ s/^\tXX/\t* /; + print CHANGE_LOG "$lines\n"; + } + print CHANGE_LOG "\n", @old_change_log; + close CHANGE_LOG; + print STDERR " Done editing ${prefix}ChangeLog.\n"; + } + +# Done. +exit; + +sub get_function_line_ranges + { + my ($file_handle, $file_name) = @_; + + if ($file_name =~ /\.c$/) { + return get_function_line_ranges_for_c ($file_handle, $file_name); + } elsif ($file_name =~ /\.java$/) { + return get_function_line_ranges_for_java ($file_handle, $file_name); + } + return (); + } + +# Read a file and get all the line ranges of the things that look like C functions. +# A function name is the last word before an open parenthesis before the outer +# level open brace. A function starts at the first character after the last close +# brace or semicolon before the function name and ends at the close brace. +# Comment handling is simple-minded but will work for all but pathological cases. +# +# Result is a list of triples: [ start_line, end_line, function_name ]. + +sub get_function_line_ranges_for_c + { + my ($file_handle, $file_name) = @_; + + my @ranges; + + my $in_comment = 0; + my $in_macro = 0; + my $in_parentheses = 0; + my $in_braces = 0; + + my $word = ""; + + my $potential_start = 0; + my $potential_name = ""; + + my $start = 0; + my $name = ""; + + while (<$file_handle>) + { + # Handle continued multi-line comment. + if ($in_comment) + { + next unless s-.*\*/--; + $in_comment = 0; + } + + # Handle continued macro. + if ($in_macro) + { + $in_macro = 0 unless /\\$/; + next; + } + + # Handle start of macro (or any preprocessor directive). + if (/^\s*\#/) + { + $in_macro = 1 if /^([^\\]|\\.)*\\$/; + next; + } + + # Handle comments and quoted text. + while (m-(/\*|//|\'|\")-) # \' and \" keep emacs perl mode happy + { + my $match = $1; + if ($match eq "/*") + { + if (!s-/\*.*?\*/--) + { + s-/\*.*--; + $in_comment = 1; + } + } + elsif ($match eq "//") + { + s-//.*--; + } + else # ' or " + { + if (!s-$match([^\\]|\\.)*?$match--) + { + warn "mismatched quotes at line $INPUT_LINE_NUMBER in $file_name\n"; + s-$match.*--; + } + } + } + + # Find function names. + while (m-(\w+|[(){};])-g) + { + # Open parenthesis. + if ($1 eq "(") + { + $potential_name = $word unless $in_parentheses; + $in_parentheses++; + next; + } + + # Close parenthesis. + if ($1 eq ")") + { + $in_parentheses--; + next; + } + + # Open brace. + if ($1 eq "{") + { + # Promote potiential name to real function name at the + # start of the outer level set of braces (function body?). + if (!$in_braces and $potential_start) + { + $start = $potential_start; + $name = $potential_name; + } + + $in_braces++; + next; + } + + # Close brace. + if ($1 eq "}") + { + $in_braces--; + + # End of an outer level set of braces. + # This could be a function body. + if (!$in_braces and $name) + { + push @ranges, [ $start, $INPUT_LINE_NUMBER, $name ]; + $name = ""; + } + + $potential_start = 0; + $potential_name = ""; + next; + } + + # Semicolon. + if ($1 eq ";") + { + $potential_start = 0; + $potential_name = ""; + next; + } + + # Word. + $word = $1; + if (!$in_parentheses) + { + $potential_start = 0; + $potential_name = ""; + } + if (!$potential_start) + { + $potential_start = $INPUT_LINE_NUMBER; + $potential_name = ""; + } + } + } + + warn "mismatched braces in $file_name\n" if $in_braces; + warn "mismatched parentheses in $file_name\n" if $in_parentheses; + + return @ranges; + } + + + +# Read a file and get all the line ranges of the things that look like Java +# classes, interfaces and methods. +# +# A class or interface name is the word that immediately follows +# `class' or `interface' when followed by an open curly brace and not +# a semicolon. It can appear at the top level, or inside another class +# or interface block, but not inside a function block +# +# A class or interface starts at the first character after the first close +# brace or after the function name and ends at the close brace. +# +# A function name is the last word before an open parenthesis before +# an open brace rather than a semicolon. It can appear at top level or +# inside a class or interface block, but not inside a function block. +# +# A function starts at the first character after the first close +# brace or after the function name and ends at the close brace. +# +# Comment handling is simple-minded but will work for all but pathological cases. +# +# Result is a list of triples: [ start_line, end_line, function_name ]. + +sub get_function_line_ranges_for_java + { + my ($file_handle, $file_name) = @_; + + my @current_scopes; + + my @ranges; + + my $in_comment = 0; + my $in_macro = 0; + my $in_parentheses = 0; + my $in_braces = 0; + my $in_non_block_braces = 0; + my $class_or_interface_just_seen = 0; + + my $word = ""; + + my $potential_start = 0; + my $potential_name = ""; + my $potential_name_is_class_or_interface = 0; + + my $start = 0; + my $name = ""; + my $current_name_is_class_or_interface = 0; + + while (<$file_handle>) + { + # Handle continued multi-line comment. + if ($in_comment) + { + next unless s-.*\*/--; + $in_comment = 0; + } + + # Handle continued macro. + if ($in_macro) + { + $in_macro = 0 unless /\\$/; + next; + } + + # Handle start of macro (or any preprocessor directive). + if (/^\s*\#/) + { + $in_macro = 1 if /^([^\\]|\\.)*\\$/; + next; + } + + # Handle comments and quoted text. + while (m-(/\*|//|\'|\")-) # \' and \" keep emacs perl mode happy + { + my $match = $1; + if ($match eq "/*") + { + if (!s-/\*.*?\*/--) + { + s-/\*.*--; + $in_comment = 1; + } + } + elsif ($match eq "//") + { + s-//.*--; + } + else # ' or " + { + if (!s-$match([^\\]|\\.)*?$match--) + { + warn "mismatched quotes at line $INPUT_LINE_NUMBER in $file_name\n"; + s-$match.*--; + } + } + } + + # Find function names. + while (m-(\w+|[(){};])-g) + { + # Open parenthesis. + if ($1 eq "(") + { + if (!$in_parentheses) { + $potential_name = $word; + $potential_name_is_class_or_interface = 0; + } + $in_parentheses++; + next; + } + + # Close parenthesis. + if ($1 eq ")") + { + $in_parentheses--; + next; + } + + # Open brace. + if ($1 eq "{") + { + # Promote potiential name to real function name at the + # start of the outer level set of braces (function/class/interface body?). + if (!$in_non_block_braces + and (!$in_braces or $current_name_is_class_or_interface) + and $potential_start) + { + if ($name) + { + push @ranges, [ $start, ($INPUT_LINE_NUMBER - 1), + join ('.', @current_scopes) ]; + } + + + $current_name_is_class_or_interface = $potential_name_is_class_or_interface; + + $start = $potential_start; + $name = $potential_name; + + push (@current_scopes, $name); + } else { + $in_non_block_braces++; + } + + $potential_name = ""; + $potential_start = 0; + + $in_braces++; + next; + } + + # Close brace. + if ($1 eq "}") + { + $in_braces--; + + # End of an outer level set of braces. + # This could be a function body. + if (!$in_non_block_braces) + { + if ($name) + { + push @ranges, [ $start, $INPUT_LINE_NUMBER, + join ('.', @current_scopes) ]; + + pop (@current_scopes); + + if (@current_scopes) + { + $current_name_is_class_or_interface = 1; + + $start = $INPUT_LINE_NUMBER + 1; + $name = $current_scopes[$#current_scopes-1]; + } + else + { + $current_name_is_class_or_interface = 0; + $start = 0; + $name = ""; + } + } + } + else + { + $in_non_block_braces-- if $in_non_block_braces; + } + + $potential_start = 0; + $potential_name = ""; + next; + } + + # Semicolon. + if ($1 eq ";") + { + $potential_start = 0; + $potential_name = ""; + next; + } + + if ($1 eq "class" or $1 eq "interface") + { + $class_or_interface_just_seen = 1; + next; + } + + # Word. + $word = $1; + if (!$in_parentheses) + { + if ($class_or_interface_just_seen) { + $potential_name = $word; + $potential_start = $INPUT_LINE_NUMBER; + $class_or_interface_just_seen = 0; + $potential_name_is_class_or_interface = 1; + next; + } + } + if (!$potential_start) + { + $potential_start = $INPUT_LINE_NUMBER; + $potential_name = ""; + } + $class_or_interface_just_seen = 0; + } + } + + warn "mismatched braces in $file_name\n" if $in_braces; + warn "mismatched parentheses in $file_name\n" if $in_parentheses; + + return @ranges; + } diff --git a/trunk/release_notes-0.3.0 b/trunk/release_notes-0.3.0 new file mode 100644 index 000000000000..c50758b4159f --- /dev/null +++ b/trunk/release_notes-0.3.0 @@ -0,0 +1,70 @@ +xf86-video-openchrome-0.3.0 + +This is the first official openchrome driver release. +(http://www.openchrome.org) + +SUPPORTED CHIPSETS : +-------------------- +- CLE266 (VT3122) +- KM400/P4M800 (VT3205) +- K8M800 (VT3204) +- PM800/PM880/CN400 (VT3259) +- VM800/CN700/P4M800Pro (VT3314) +- CX700 (VT3324) +- P4M890 (VT3327) +- K8M890 (VT3336) +- P4M900/VN896 (VT3364) + + +SUPPORTED FEATURES : +-------------------- +- Free modesetting for Unichrome and Unichrome Pro chipset. +- VBE modesetting for everything not natively supported. +- TV-out support. +- EXA acceleration. +- Hardware MPEG2 acceleration. + + +IMPORTANT NOTE : +---------------- +- The driver name is now 'openchrome', and this is what you need to use in + your xorg.conf now (instead of 'via'). The XvMC libraries have also been + renamed, to 'libchromeXvMC.so' and 'libchromeXvMCPro.so'. + + +KNOWN BUGS/LIMITATIONS : +------------------------ +* Laptop panel +- Laptop displays for anything other than CLE266 and KM400/P4M800 are only + supported thru VBE calls. +- Xv is not working on laptop displays for VM800/CN700/P4M800PRO. It is however + working on VGA. +- Virtual terminal is broken on some laptop displays. Use a vesa framebuffer to + work around that (append vga=791 to your kernel command line, for example). + +* XvMC +- The hardware MPEG4 acceleration that is present on some chipsets is not + implemented. +- No XvMC support for CX700 (new, unsupported engine). +- No XvMC support for K8M890, P4M890 and P4M900/VN896 (need to get dri working + for them first). + +* TV output +- TV modes are hardcoded and must be choosen inside a list depending on the TV + encoder. +- Outputs are dependent on each other and will use the least common + denominator. If you're using both VGA/LCD output and TV output, the VGA/LCD + output will be limited by the TV encoder (720x576@50Hz for example). + In other words, there is no dual screen support. + +* Misc. +- Add-on and integrated TMDS encoders are not supported, except thru VBE. + +* Chrome9 +- Chrome9 chipsets' family (P4M900 and K8M890) currently doesn't + support neither AGP DMA nor 3D acceleration. + + +Please note that 3D acceleration is provided by Mesa (http://mesa3d.org) and is +not directly related to openchrome. + diff --git a/trunk/src/Imakefile b/trunk/src/Imakefile new file mode 100644 index 000000000000..e7ca37d0c2b8 --- /dev/null +++ b/trunk/src/Imakefile @@ -0,0 +1,231 @@ +#define IHaveModules +#include <Server.tmpl> + +XCOMM Add a comment into the source if we are building svn code. +all:: svnversion.h + +svnversion.h: + @if [ -f svnrelease.h ]; then \ + echo '#include "svnrelease.h"' > $@.tmp; \ + elif [ -d .svn ]; then \ + echo '#define BUILDCOMMENT "(development build, at svn revision '\ + "`svnversion -nc . | sed -e s/^[^:]*://`"')\n"' > $@.tmp; \ + else date +'#define BUILDCOMMENT "(development build, compiled on %c)\n"' > $@.tmp; fi + + @(chmod 666 $@.tmp 2> /dev/null || /bin/true) + @cmp -s $@ $@.tmp || (mv $@.tmp $@ ; echo created $@) + +.PHONY: svnversion.h + +XCOMM Check the version to see if we need anything special. +#ifdef XF86_VERSION_CURRENT +XCOMM We are using Xfree86 + +XCOMM This needs a seperate check though, debian dfsg-6 needs this +XCOMM but it's version is still 4.3.0.1 - see via_xvmc.c +#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,3,99,3,0) +DEFXVPRIV = -DX_NEED_XVPRIV_H +#endif + +#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,3,99,16,0) +DEFREGIONNULL = -DX_USE_REGION_NULL +#endif + +#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,4,99,2,0) +XCOMM for Imakefile only +#define X_NEED_NEWMODULETARGET 1 +#endif + +#if XF86_VERSION_CURRENT <= XF86_VERSION_NUMERIC(4,4,99,7,0) +XCOMM drm_hw_lock_t is hidden behind __KERNEL__ here +XCOMM use drmLock instead +DEFXNEEDDRMLOCK = -DX_NEED_DRMLOCK +#else +#undef DEFXNEEDDRMLOCK +#endif + +#else +XCOMM We are using X.org +XCOMM The XF86_VERSION stuff just had to be renamed it seems. Why +XCOMM they kept XORG_VERSION at all I don't know, since they are +XCOMM apparently not bothering with altering it. Both the x.org +XCOMM release and a cvs checkout (3m after release) here are +XCOMM 6.7.0.0.0. Luckily, apart from the drm.h location, this is +XCOMM not a problem... yet. -- luc + +DEFXVPRIV = -DX_NEED_XVPRIV_H +DEFREGIONNULL = -DX_USE_REGION_NULL + +#if BuildXF86DRI +XCOMM Since we are unable to properly version, just include the lot. +X_DRM_H_LOCATION = -I$(DRMSRCDIR)/shared-core -I$(DRMSRCDIR)/shared -I$(XF86OSSRC)/shared/drm/kernel +#endif + +XCOMM Include the Xorg changes concerning dlloader (by Adam Jackson). +XCOMM The current changes are not necessary yet, but I've backported +XCOMM them anyway. +#if MakeDllModules +DEFXAAGETROP = -DX_HAVE_XAAGETROP +#endif + +XCOMM We don't need X_NEED_NEWMODULETARGET with X.org +#undef X_NEED_NEWMODULETARGET + +XCOMM I2CBusses require the Start function attached from 6.8 and on +#if XORG_VERSION_MINOR > 7 +DEFI2CSTART = -DX_NEED_I2CSTART +#else +#undef DEFI2CSTART +#endif + +#if XORG_VERSION_MINOR < 7 +XCOMM drm_hw_lock_t is hidden behind __KERNEL__ here +XCOMM use drmLock instead +DEFXNEEDDRMLOCK = -DX_NEED_DRMLOCK +#else +#undef DEFXNEEDDRMLOCK +#endif + +#endif + +#if BuildXF86DRI +DRISRCS = via_dri.c via_xvmc.c +DRIOBJS = via_dri.o via_xvmc.o +DRIINCLUDES = -I$(SERVERSRC)/GL/dri -I$(LIBSRC)/GL/dri \ + $(X_DRM_H_LOCATION) -I$(TOP)/include +DRIDEFINES = $(GLX_DEFINES) +#endif + +#ifdef XF86EXA +EXAINCLUDES = -I$(XF86SRC)/exa +EXADEFINES = -DVIA_HAVE_EXA +#endif + +SRCS = via_driver.c \ + via_3d.c \ + via_accel.c \ + via_bandwidth.c \ + via_ch7xxx.c \ + via_mode.c \ + via_cursor.c \ + via_shadow.c \ + via_dga.c \ + via_video.c \ + via_i2c.c \ + via_id.c \ + via_swov.c \ + via_memory.c \ + via_memcpy.c \ + via_vbe.c \ + via_vgahw.c \ + via_vt162x.c \ + $(DRISRCS) + +OBJS = via_driver.o \ + via_3d.o \ + via_accel.o \ + via_bandwidth.o \ + via_ch7xxx.o \ + via_mode.o \ + via_cursor.o \ + via_shadow.o \ + via_dga.o \ + via_video.o \ + via_i2c.o \ + via_id.o \ + via_swov.o \ + via_memory.o \ + via_memcpy.o \ + via_vbe.o \ + via_vgahw.o \ + via_vt162x.o \ + $(DRIOBJS) + +#if defined(XF86DriverSDK) +INCLUDES = -I. -I../../include +#else +INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) \ + -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \ + -I$(SERVERSRC)/cfb -I$(XF86SRC)/xaa \ + -I$(XF86SRC)/xf1bpp -I$(XF86SRC)/xf4bpp \ + -I$(XF86SRC)/xf24_32bpp -I$(SERVERSRC)/Xext \ + -I$(XF86SRC)/vgahw -I$(XF86SRC)/ramdac \ + -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c \ + -I$(XF86SRC)/rac -I$(XF86SRC)/int10 -I$(XF86SRC) -I$(SERVERSRC)/render \ + -I$(SERVERSRC)/include -I$(XINCLUDESRC) -I$(FONTINCSRC) \ + -I$(EXTINCSRC) -I$(XF86SRC)/vbe -I$(XF86SRC)/shadowfb \ + -I$(SERVERSRC)/fb $(DRIINCLUDES) $(EXAINCLUDES) +#endif + +DEFINES = $(DRIDEFINES) $(DEFXVPRIV) $(DEFREGIONNULL) \ + $(DEFXAAGETROP) $(DEFI2CSTART) $(DEFXNEEDDRMLOCK) $(EXADEFINES) + +#if MakeHasPosixVariableSubstitutions +SubdirLibraryRule($(OBJS)) +#endif + +NormalAsmObjectRule() + +ModuleObjectRule() +#ifdef X_NEED_NEWMODULETARGET +ObjectModuleTarget(via, $(OBJS),drivers) +#else +ObjectModuleTarget(via, $(OBJS)) +#endif + +#ifdef InstallVideoObjectModule +InstallVideoObjectModule(via,$(MODULEDIR)) +#else +InstallObjectModule(via,$(MODULEDIR),drivers) +#endif + +#if !defined(XF86DriverSDK) +CppManTarget(via,) +InstallModuleManPage(via) +#endif + +DependTarget() + +InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_3d.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_3d.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_accel.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_bandwidth.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_bios.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_ch7xxx.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_ch7xxx.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_cursor.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_dga.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_dmabuffer.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_dri.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_dri.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_driver.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_driver.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_drm.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_drmclient.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_i2c.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_id.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_id.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_memcpy.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_memcpy.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_memory.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_mode.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_mode.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_priv.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_regs.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_shadow.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_swov.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_swov.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_vbe.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_vgahw.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_vgahw.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_video.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_video.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_vt162x.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_vt162x.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_xvmc.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_xvmc.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_xvpriv.h,$(DRIVERSDKDIR)/drivers/via) + +InstallDriverSDKObjectModule(via,$(DRIVERSDKMODULEDIR),drivers) diff --git a/trunk/src/Makefile.am b/trunk/src/Makefile.am new file mode 100644 index 000000000000..82a8af1bb246 --- /dev/null +++ b/trunk/src/Makefile.am @@ -0,0 +1,99 @@ +# Copyright 2005 Adam Jackson. +# +# 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 +# on the rights to use, copy, modify, merge, publish, distribute, sub +# license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL +# ADAM JACKSON 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. + +# this is obnoxious: +# -module lets us name the module exactly how we want +# -avoid-version prevents gratuitous .0.0.0 version numbers on the end +# _ladir passes a dummy rpath to libtool so the thing will actually link +# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc. +EXTRA_DIST = svnversion.h +CONFIG_CLEAN_FILES= svnversion.h +AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ +openchrome_drv_la_LTLIBRARIES = openchrome_drv.la +openchrome_drv_la_LDFLAGS = -module -avoid-version +openchrome_drv_ladir = @moduledir@/drivers + +openchrome_drv_la_SOURCES = \ + via_3d_reg.h \ + via_3d.c \ + via_3d.h \ + via_accel.c \ + via_bandwidth.c \ + via_bios.h \ + via_ch7xxx.c \ + via_ch7xxx.h \ + via_cursor.c \ + via_dga.c \ + via_dmabuffer.h \ + via_driver.c \ + via_driver.h \ + via.h \ + via_i2c.c \ + via_id.c \ + via_id.h \ + via_memcpy.c \ + via_memcpy.h \ + via_memory.c \ + via_mode.c \ + via_mode.h \ + via_priv.h \ + via_regs.h \ + via_shadow.c \ + via_swov.c \ + via_swov.h \ + via_vbe.c \ + via_vgahw.c \ + via_vgahw.h \ + via_video.c \ + via_video.h \ + via_vt162x.c \ + via_vt162x.h \ + via_xvpriv.h + +if DRI +openchrome_drv_la_SOURCES += \ + via_dri.c \ + via_dri.h \ + via_drmclient.h \ + via_xvmc.c \ + via_xvmc.h + +else +EXTRA_DIST += \ + via_dri.c \ + via_dri.h \ + via_drmclient.h \ + via_xvmc.c \ + via_xvmc.h +endif + +via_driver.lo: svnversion.h +svnversion.h: + @if [ -f svnrelease.h ]; then \ + echo '#include "svnrelease.h"' > $@.tmp; \ + elif [ -d .svn ]; then \ + echo '#define BUILDCOMMENT "(development build, at svn revision '\ + "`svnversion -nc .. | sed -e s/^[^:]*://`"')\n"' > $@.tmp; \ + else date +'#define BUILDCOMMENT "(development build, compiled on %c)\n"' > $@.tmp; fi + + @(chmod 666 $@.tmp 2> /dev/null || /bin/true) + @cmp -s $@ $@.tmp || (mv $@.tmp $@ ; echo created $@) + +.PHONY: svnversion.h diff --git a/trunk/src/openchrome.man b/trunk/src/openchrome.man new file mode 100644 index 000000000000..8191b53c574a --- /dev/null +++ b/trunk/src/openchrome.man @@ -0,0 +1,234 @@ +.\" Shorthand for double quote that works everywhere, +.\" also within other double quotes: +.ds q \N'34' +.TH OPENCHROME __drivermansuffix__ __vendorversion__ +.SH NAME +openchrome \- video driver for VIA Unichromes +.SH SYNOPSIS +.nf +.B "Section \*qDevice\*q" +.BI " Identifier \*q" string \*q +.B " Driver \*qopenchrome\*q" +\ \ ... +.B EndSection +.fi + +.SH DESCRIPTION +.B openchrome +is an __xservername__ driver for VIA chipsets that have an integrated +Unichrome graphics engine. +.PP +The +.B openchrome +driver supports the following chipsets: CLE266, KM400/KN400, CN400, CN700, +K8M800/K8N800, PM800/PN800, P4M800Pro, VN800, PM880, K8M890/K8N890, +CN896, VN896, and P4M900. +The driver includes 2D acceleration and Xv video overlay extensions. +Flat panel, TV, and VGA outputs are supported, depending on the hardware +configuration. +.PP +3D direct rendering is available using experimental drivers from Mesa +(www.mesa3d.org). There is also an XvMC client library for hardware +acceleration of MPEG1/MPEG2 decoding (not available on the KM/N400) +that uses the Direct Rendering Infrastructure (DRI). +The XvMC client library implements a non-standard +"VLD" extension to the XvMC standard. The current Direct Rendering +Manager (DRM) kernel module is available at dri.sourceforge.net. +.PP +The driver supports free modes for Unichrome Pros (K8M/N800, PM/N800, and +CN400). For plain Unichromes (CLE266, KM/N400), it currently supports +only a limited number of dotclocks, so if you are using X modelines you +must make sure that the dotclock is one of those supported. Supported +dotclocks on plain Unichromes are currently (in MHz): 25.2, 25.312, +26.591, 31.5, 31.704, 32.663, 33.750, 35.5, 36.0, 39.822, 40.0, 41.164, +46.981, 49.5, 50.0, 56.3, 57.284, 64.995, 65.0, 65.028, 74.480, +75.0, 78.8, 81.613, 94.5, 108.0, 108.28, 122.0, 122.726, 135.0, +148.5, 155.8, 157.5, 161.793, 162.0, 175.5, 189.0, 202.5, 204.8, +218.3, 229.5. On top of this, bandwidth restrictions apply for both +Unichromes and Unichrome Pros. +.PP +.SH CONFIGURATION DETAILS +Please refer to __xconfigfile__(__filemansuffix__) for general configuration +details. This section only covers configuration details specific to this +driver. +.PP +The following driver +.B options +are supported: +.TP +.BI "Option \*qAccelMethod\*q \*q" string \*q +The driver supports "XAA" and "EXA" acceleration methods. The default +method is XAA, since EXA is still experimental. Contrary to XAA, EXA +implements acceleration for screen uploads and downlads (if DRI is +enabled) and for the Render/Composite extension. +.TP +.BI "Option \*qActiveDevice\*q \*q" string \*q +Specifies the active device combination. Any string containing "CRT", +"LCD", "DFP", "TV" should be possible. "CRT" represents anything that +is connected to the VGA port, "LCD" and "DFP" are for laptop panels +(not TFT screens attached to the VGA port), "TV" is self-explanatory. +The default is to use what is detected. The driver is currently unable +to use LCD and TV simultaneously, and will favour the LCD. +.TP +.BI "Option \*qAGPMem\*q \*q" integer \*q +Sets the amount of AGP memory that is allocated at X server startup. +The allocated memory will be "integer" kB. This AGP memory is used for +the AGP command buffer (if option "EnableAGPDMA" is set to "true"), for +DRI textures, and for the EXA scratch area. The driver will allocate at +least one system page of AGP memory and, if the AGP command buffer is +used, at least 2MB + one system page. If there is no room for the EXA +scratch area in AGP space, it will be allocated from VRAM. If there is +no room for DRI textures, they will be allocated from the DRI part of +VRAM (see the option "MaxDRIMem"). The default amount of AGP is +32768kB. Note that the AGP aperture set in the BIOS must be able +to accomodate the amount of AGP memory specified here. Otherwise no +AGP memory will be available. It is safe to set a very large AGP +aperture in the BIOS. +.TP +.BI "Option \*qCenter\*q \*q" boolean \*q +Enables or disables image centering on DVI displays. +.TP +.BI "Option \*qDisableIRQ\*q \*q" boolean \*q +Disables the Vblank IRQ. This is a workaround for some mainboards that +have problems with IRQs from the Unichrome engine. With IRQs disabled, +DRI clients have no way to synchronize drawing to Vblank. (This option +is enabled by default on the KM400 and K8M800 chipsets.) +.TP +.BI "Option \*qDisableVQ\*q \*q" boolean \*q +Disables the use of VQ. VQ is enabled by default. +.TP +.BI "Option \*qEnableAGPDMA\*q \*q" boolean \*q +Enables the AGP DMA functionality in DRM. This requires that DRI is enabled +and will force 2D and 3D acceleration to use AGP DMA. The XvMC DRI client +will also make use of this on the CLE266 to consume much less CPU. (This +option is enabled by default on all chipsets except the K8M890 and P4M900.) +.TP +.BI "Option \*qExaNoComposite\*q \*q" boolean \*q +If EXA is enabled (using the option "AccelMethod"), this option enables +or disables acceleration of compositing. Since EXA, and in particular its +composite acceleration, is still experimental, this is a way to disable +a misbehaving composite acceleration. +.TP +.BI "Option \*qExaScratchSize\*q \*q" integer \*q +Sets the size of the EXA scratch area to "integer" kB. This area is +used by EXA as a last place to look for available space for pixmaps. +Too little space will slow compositing down. This option should be set +to the size of the largest pixmap used. If you have a screen width of +over 1024 pixels and use 24 bpp, set this to 8192. Otherwise you can +leave this at the default 4096. The space will be allocated from AGP +memory if available, otherwise from VRAM. +.TP +.BI "Option \*qHWCursor\*q \*q" boolean \*q +Enables or disables the use of hardware cursors. The default is enabled. +.TP +.BI "Option \*qLCDDualEdge\*q \*q" boolean \*q +Enables or disables the use of dual-edge mode to set the LCD. +.TP +.BI "Option \*qMaxDRIMem\*q \*q" integer \*q +Sets the maximum amount of VRAM memory allocated for DRI clients to +"integer" kB. Normally DRI clients get half the available VRAM size, +but in some cases it may make sense to limit this amount. For example, +if you are using a composite manager and you want to give as much memory +as possible to the EXA pixmap storage area. +.TP +.BI "Option \*qMigrationHeuristic\*q \*q" string \*q +Sets the heuristic for EXA pixmap migration. This is an EXA core +option, and on Xorg xserver versions after 1.1.0 this defaults to +"smart". The Openchrome driver performs best with "greedy", so you +should really add this option to your configuration file. The third +possibility is "always", which might become more useful in the future. +.TP +.BI "Option \*qNoAccel\*q \*q" boolean \*q +Disables or enables acceleration. Default: acceleration is enabled. +.TP +.BI "Option \*qNoAGPFor2D\*q \*q" boolean \*q +With this option set, 2D acceleration will not use AGP DMA even if +it is enabled. +.TP +.BI "Option \*qNoXVDMA\*q \*q" boolean \*q +If DRI is enabled, Xv normally uses PCI DMA to transfer video images +from system to frame-buffer memory. This is somewhat slower than +direct copies due to the limitations of the PCI bus, but on the other +hand it decreases CPU usage significantly, particularly on computers +with fast processors. Some video players are buggy and will display +rendering artifacts when PCI DMA is used. If you experience this, +or don't want your PCI bus to be stressed with Xv images, set this +option to "true". This option has no effect when DRI is not enabled. +.TP +.BI "Option \*qPanelSize\*q \*q" string \*q +Specifies the size (width x height) of the LCD panel attached to the +system. The sizes 640x480, 800x600, 1024x768, 1280x1024, and 1400x1050 +are supported. +.TP +.BI "Option \*qRotate\*q \*q" string \*q +Rotates the display either clockwise ("CW") or counterclockwise ("CCW"). +Rotation is only supported unaccelerated. +.TP +.BI "Option \*qShadowFB\*q \*q" boolean \*q +Uses a shadow frame buffer. This is required when rotating the display, +but otherwise defaults to disabled. +.TP +.BI "Option \*qSWCursor\*q \*q" boolean \*q +Enables or disables the use of a software cursor. The default is disabled. +.TP +.BI "Option \*qTVDeflicker\*q \*q" integer \*q +Specifies the deflicker setting for TV output. Valid values are "0", "1", +and "2". 0) No deflicker, 1) 1:1:1 deflicker, 2) 1:2:1 deflicker. +.TP +.BI "Option \*qTVDotCrawl\*q \*q" boolean \*q +Enables or disables dotcrawl. +.TP +.BI "Option \*qTVOutput\*q \*q" string \*q +Specifies which TV output to use. The driver supports "S-Video", +"Composite", "SC", "RGB" and "YCbCr" outputs. Note that on some +EPIA boards the compositer-video port is shared with audio-out and +is selected via a jumper. +.TP +.BI "Option \*qTVType\*q \*q" string \*q +Specifies TV output format. The driver currently supports "NTSC" and +"PAL" timings only. +.TP +.BI "Option \*qVBEModes\*q \*q" boolean \*q +Uses the VBE BIOS calls to set the display mode. This mimics the +behaviour of the vesa video driver but still provides acceleration and +other features. This option may be used if your hardware works with +the vesa driver but not with the Openchrome driver. It may not work +on 64-bit systems. Using "VBEModes" may speed up driver acceleration +significantly due to a more aggressive hardware setting, particularly +on systems with low memory bandwidth. Your refresh rate may be limited +to 60 Hz on some systems. +.TP +.BI "Option \*qVBESaveRestore\*q \*q" boolean \*q +Uses the VBE BIOS calls to save and restore the display state when the +X server is launched. This can be extremely slow on some hardware, and +the system may appear to have locked for 10 seconds or so. The default +is to use the driver builtin function. This option only works if option +"VBEModes" is enabled. +.TP +.BI "Option \*qVideoRAM\*q \*q" integer \*q +Overrides the VideoRAM autodetection. This should never be needed. +.PP +.SH "TV ENCODERS" +Unichromes tend to be paired with several different TV encoders. +.TP +.BI "VIA Technologies VT1621" +Still untested, as no combination with a Unichrome is known or available. +Supports the following normal modes: "640x480" and "800x600". Use +"640x480Over" and "800x600Over" for vertical overscan. These modes +are made available by the driver; modelines provided in __xconfigfile__ +will be ignored. +.TP +.BI "VIA Technologies VT1622, VT1622A, VT1623" +Supports the following modes: "640x480", "800x600", "1024x768", +"848x480", "720x480" (NTSC only) and "720x576" (PAL only). Use +"640x480Over", "800x600Over", "1024x768Over", "848x480Over", +"720x480Over" (NTSC) and "720x576Over" (PAL) for vertical overscan. +The modes "720x480Noscale" (NTSC) and "720x576Noscale" (PAL) (available +on VT1622 only) provide cleaner TV output (unscaled with only minimal +overscan). These modes are made available by the driver; modelines +provided in __xconfigfile__ will be ignored. + +.SH "SEE ALSO" +__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__) +.SH AUTHORS +Authors include: ... diff --git a/trunk/src/via.h b/trunk/src/via.h new file mode 100644 index 000000000000..9e9c105ac6ae --- /dev/null +++ b/trunk/src/via.h @@ -0,0 +1,667 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. 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, sub license, + * 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 NON-INFRINGEMENT. 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. + */ + +#ifndef _VIA_H_ +#define _VIA_H_ 1 + +#include "xorgVersion.h" + +#include <errno.h> +#include <string.h> +#include <stdio.h> +#include <math.h> +#include <assert.h> +#include <stdlib.h> + +/* Video Engines */ +#define VIDEO_ENGINE_UNK 0 /* Unknown video engine */ +#define VIDEO_ENGINE_CLE 1 /* CLE First generaion video engine */ +#define VIDEO_ENGINE_CME 2 /* CME Second generation video engine */ + +/* Video status flag */ + +#define VIDEO_HIDE 0x00000000 /*Video off*/ +#define VIDEO_SHOW 0x80000000 /*Video on*/ +#define VIDEO_ACTIVE 0x10000000 /*Video active*/ +#define VIDEO_MPEG_INUSE 0x08000000 /*Video is used with MPEG */ +#define VIDEO_HQV_INUSE 0x04000000 /*Video is used with HQV*/ +#define VIDEO_CAPTURE0_INUSE 0x02000000 /*Video is used with CAPTURE 0*/ +#define VIDEO_CAPTURE1_INUSE 0x00000000 /*Video is used with CAPTURE 1*/ +#define VIDEO_1_INUSE 0x01000000 /*Video 1 is used with software flip*/ +#define VIDEO_3_INUSE 0x00000000 /*Video 3 is used with software flip*/ +#define VIDEO_ON 0x00100000 +#define MPEG_USE_V1 0x00010000 /*[16] : 1:MPEG use V1, 0:MPEG use V3*/ +#define MPEG_USE_V3 0x00000000 /*[16] : 1:MPEG use V1, 0:MPEG use V3*/ +#define MPEG_USE_HQV 0x00020000 /*[17] : 1:MPEG use HQV,0:MPEG not use HQV*/ +#define MPEG_USE_HW_FLIP 0x00040000 /*[18] : 1:MPEG use H/W flip,0:MPEG use S/W flip*/ +#define MPEG_USE_SW_FLIP 0x00000000 /*[18] : 1:MPEG use H/W flip,0:MPEG use S/W flip*/ +#define CAP0_USE_V1 0x00001000 /*[12] : 1:Capture 0 use V1, 0:Capture 0 use V3*/ +#define CAP0_USE_V3 0x00000000 /*[12] : 1:Capture 0 use V1, 0:Capture 0 use V3*/ +#define CAP0_USE_HQV 0x00002000 /*[13] : 1:Capture 0 use HQV,0:Capture 0 not use HQV*/ +#define CAP0_USE_HW_FLIP 0x00004000 /*[14] : 1:Capture 0 use H/W flip,0:Capture 0 use S/W flip*/ +#define CAP0_USE_CCIR656 0x00008000 /*[15] : 1:Capture 0 use CCIR656,0:Capture 0 CCIR601*/ +#define CAP1_USE_V1 0x00000100 /*[ 8] : 1:Capture 1 use V1, 0:Capture 1 use V3*/ +#define CAP1_USE_V3 0x00000000 /*[ 8] : 1:Capture 1 use V1, 0:Capture 1 use V3*/ +#define CAP1_USE_HQV 0x00000200 /*[ 9] : 1:Capture 1 use HQV,0:Capture 1 not use HQV*/ +#define CAP1_USE_HW_FLIP 0x00000400 /*[10] : 1:Capture 1 use H/W flip,0:Capture 1 use S/W flip */ +#define SW_USE_V1 0x00000010 /*[ 4] : 1:Capture 1 use V1, 0:Capture 1 use V3 */ +#define SW_USE_V3 0x00000000 /*[ 4] : 1:Capture 1 use V1, 0:Capture 1 use V3 */ +#define SW_USE_HQV 0x00000020 /*[ 5] : 1:Capture 1 use HQV,0:Capture 1 not use HQV */ + +/* +#define VIDEO1_INUSE 0x00000010 //[ 4] : 1:Video 1 is used with S/W flip +#define VIDEO1_USE_HQV 0x00000020 //[ 5] : 1:Video 1 use HQV with S/W flip +#define VIDEO3_INUSE 0x00000001 //[ 0] : 1:Video 3 is used with S/W flip +#define VIDEO3_USE_HQV 0x00000002 //[ 1] : 1:Video 3 use HQV with S/W flip +*/ + +/* H/W registers for Video Engine */ + +/* + * bus master + */ +#define PCI_MASTER_ENABLE 0x01 +#define PCI_MASTER_SCATTER 0x00 +#define PCI_MASTER_SINGLE 0x02 +#define PCI_MASTER_GUI 0x00 +#define PCI_MASTER_VIDEO 0x04 +#define PCI_MASTER_INPUT 0x00 +#define PCI_MASTER_OUTPUT 0x08 + +/* + * video registers + */ +#define V_FLAGS 0x00 +#define V_CAP_STATUS 0x04 +#define V_FLIP_STATUS 0x04 +#define V_ALPHA_WIN_START 0x08 +#define V_ALPHA_WIN_END 0x0C +#define V_ALPHA_CONTROL 0x10 +#define V_CRT_STARTADDR 0x14 +#define V_CRT_STARTADDR_2 0x18 +#define V_ALPHA_STRIDE 0x1C +#define V_COLOR_KEY 0x20 +#define V_ALPHA_STARTADDR 0x24 +#define V_CHROMAKEY_LOW 0x28 +#define V_CHROMAKEY_HIGH 0x2C +#define V1_CONTROL 0x30 +#define V12_QWORD_PER_LINE 0x34 +#define V1_STARTADDR_1 0x38 +#define V1_STARTADDR_Y1 V1_STARTADDR_1 +#define V1_STRIDE 0x3C +#define V1_WIN_START_Y 0x40 +#define V1_WIN_START_X 0x42 +#define V1_WIN_END_Y 0x44 +#define V1_WIN_END_X 0x46 +#define V1_STARTADDR_2 0x48 +#define V1_STARTADDR_Y2 V1_STARTADDR_2 +#define V1_ZOOM_CONTROL 0x4C +#define V1_MINI_CONTROL 0x50 +#define V1_STARTADDR_0 0x54 +#define V1_STARTADDR_Y0 V1_STARTADDR_0 +#define V_FIFO_CONTROL 0x58 +#define V1_STARTADDR_3 0x5C +#define V1_STARTADDR_Y3 V1_STARTADDR_3 +#define HI_CONTROL 0x60 +#define SND_COLOR_KEY 0x64 +#define ALPHA_V3_PREFIFO_CONTROL 0x68 +#define V1_SOURCE_HEIGHT 0x6C +#define HI_TRANSPARENT_COLOR 0x70 +#define V_DISPLAY_TEMP 0x74 /* No use */ +#define ALPHA_V3_FIFO_CONTROL 0x78 +#define V3_SOURCE_WIDTH 0x7C +#define V3_COLOR_KEY 0x80 +#define V1_ColorSpaceReg_1 0x84 +#define V1_ColorSpaceReg_2 0x88 +#define V1_STARTADDR_CB0 0x8C +#define V1_OPAQUE_CONTROL 0x90 /* To be deleted */ +#define V3_OPAQUE_CONTROL 0x94 /* To be deleted */ +#define V_COMPOSE_MODE 0x98 +#define V3_STARTADDR_2 0x9C +#define V3_CONTROL 0xA0 +#define V3_STARTADDR_0 0xA4 +#define V3_STARTADDR_1 0xA8 +#define V3_STRIDE 0xAC +#define V3_WIN_START_Y 0xB0 +#define V3_WIN_START_X 0xB2 +#define V3_WIN_END_Y 0xB4 +#define V3_WIN_END_X 0xB6 +#define V3_ALPHA_QWORD_PER_LINE 0xB8 +#define V3_ZOOM_CONTROL 0xBC +#define V3_MINI_CONTROL 0xC0 +#define V3_ColorSpaceReg_1 0xC4 +#define V3_ColorSpaceReg_2 0xC8 +#define V3_DISPLAY_TEMP 0xCC /* No use */ +#define V1_STARTADDR_CB1 0xE4 +#define V1_STARTADDR_CB2 0xE8 +#define V1_STARTADDR_CB3 0xEC +#define V1_STARTADDR_CR0 0xF0 +#define V1_STARTADDR_CR1 0xF4 +#define V1_STARTADDR_CR2 0xF8 +#define V1_STARTADDR_CR3 0xFC + +/* Video Capture Engine Registers + * Capture Port 1 + */ +#define CAP0_MASKS 0x100 +#define CAP1_MASKS 0x104 +#define CAP0_CONTROL 0x110 +#define CAP0_H_RANGE 0x114 +#define CAP0_V_RANGE 0x118 +#define CAP0_SCAL_CONTROL 0x11C +#define CAP0_VBI_H_RANGE 0x120 +#define CAP0_VBI_V_RANGE 0x124 +#define CAP0_VBI_STARTADDR 0x128 +#define CAP0_VBI_STRIDE 0x12C +#define CAP0_ANCIL_COUNT 0x130 +#define CAP0_MAXCOUNT 0x134 +#define CAP0_VBIMAX_COUNT 0x138 +#define CAP0_DATA_COUNT 0x13C +#define CAP0_FB_STARTADDR0 0x140 +#define CAP0_FB_STARTADDR1 0x144 +#define CAP0_FB_STARTADDR2 0x148 +#define CAP0_STRIDE 0x150 +/* Capture Port 2 */ +#define CAP1_CONTROL 0x154 +#define CAP1_SCAL_CONTROL 0x160 +#define CAP1_VBI_H_RANGE 0x164 /*To be deleted*/ +#define CAP1_VBI_V_RANGE 0x168 /*To be deleted*/ +#define CAP1_VBI_STARTADDR 0x16C /*To be deleted*/ +#define CAP1_VBI_STRIDE 0x170 /*To be deleted*/ +#define CAP1_ANCIL_COUNT 0x174 /*To be deleted*/ +#define CAP1_MAXCOUNT 0x178 +#define CAP1_VBIMAX_COUNT 0x17C /*To be deleted*/ +#define CAP1_DATA_COUNT 0x180 +#define CAP1_FB_STARTADDR0 0x184 +#define CAP1_FB_STARTADDR1 0x188 +#define CAP1_STRIDE 0x18C + +/* SUBPICTURE Registers */ +#define SUBP_CONTROL_STRIDE 0x1C0 +#define SUBP_STARTADDR 0x1C4 +#define RAM_TABLE_CONTROL 0x1C8 +#define RAM_TABLE_READ 0x1CC + +/* HQV Registers*/ +#define HQV_CONTROL 0x1D0 +#define HQV_SRC_STARTADDR_Y 0x1D4 +#define HQV_SRC_STARTADDR_U 0x1D8 +#define HQV_SRC_STARTADDR_V 0x1DC +#define HQV_SRC_FETCH_LINE 0x1E0 +#define HQV_FILTER_CONTROL 0x1E4 +#define HQV_MINIFY_CONTROL 0x1E8 +#define HQV_DST_STARTADDR0 0x1EC +#define HQV_DST_STARTADDR1 0x1F0 +#define HQV_DST_STARTADDR2 0x1FC +#define HQV_DST_STRIDE 0x1F4 +#define HQV_SRC_STRIDE 0x1F8 + +#define PRO_HQV1_OFFSET 0x1000 +/* + * Video command definition + */ +/* #define V_ALPHA_CONTROL 0x210 */ +#define ALPHA_WIN_EXPIRENUMBER_4 0x00040000 +#define ALPHA_WIN_CONSTANT_FACTOR_4 0x00004000 +#define ALPHA_WIN_CONSTANT_FACTOR_12 0x0000c000 +#define ALPHA_WIN_BLENDING_CONSTANT 0x00000000 +#define ALPHA_WIN_BLENDING_ALPHA 0x00000001 +#define ALPHA_WIN_BLENDING_GRAPHIC 0x00000002 +#define ALPHA_WIN_PREFIFO_THRESHOLD_12 0x000c0000 +#define ALPHA_WIN_FIFO_THRESHOLD_8 0x000c0000 +#define ALPHA_WIN_FIFO_DEPTH_16 0x00100000 + +/* V_CHROMAKEY_LOW 0x228 */ +#define V_CHROMAKEY_V3 0x80000000 + +/* V1_CONTROL 0x230 */ +#define V1_ENABLE 0x00000001 +#define V1_FULL_SCREEN 0x00000002 +#define V1_YUV422 0x00000000 +#define V1_RGB32 0x00000004 +#define V1_RGB15 0x00000008 +#define V1_RGB16 0x0000000C +#define V1_YCbCr420 0x00000010 +#define V1_COLORSPACE_SIGN 0x00000080 +#define V1_SRC_IS_FIELD_PIC 0x00000200 +#define V1_SRC_IS_FRAME_PIC 0x00000000 +#define V1_BOB_ENABLE 0x00400000 +#define V1_FIELD_BASE 0x00000000 +#define V1_FRAME_BASE 0x01000000 +#define V1_SWAP_SW 0x00000000 +#define V1_SWAP_HW_HQV 0x02000000 +#define V1_SWAP_HW_CAPTURE 0x04000000 +#define V1_SWAP_HW_MC 0x06000000 +/* #define V1_DOUBLE_BUFFERS 0x00000000 */ +/* #define V1_QUADRUPLE_BUFFERS 0x18000000 */ +#define V1_EXPIRE_NUM 0x00050000 +#define V1_EXPIRE_NUM_A 0x000a0000 +#define V1_EXPIRE_NUM_F 0x000f0000 /* jason */ +#define V1_FIFO_EXTENDED 0x00200000 +#define V1_ON_CRT 0x00000000 +#define V1_ON_SND_DISPLAY 0x80000000 +#define V1_FIFO_32V1_32V2 0x00000000 +#define V1_FIFO_48V1_32V2 0x00200000 +#define V1_PREFETCH_ON_3336 0x40000000 /*V1_PREFETCH_ON*/ +#define V1_GAMMA_ENABLE_3336 0x20000000 /*V1_Gamma_ENABLE*/ + +/* V12_QWORD_PER_LINE 0x234 */ +#define V1_FETCH_COUNT 0x3ff00000 +#define V1_FETCHCOUNT_ALIGNMENT 0x0000000f +#define V1_FETCHCOUNT_UNIT 0x00000004 /* Doubld QWORD */ + +/* V1_STRIDE */ +#define V1_STRIDE_YMASK 0x00001fff +#define V1_STRIDE_UVMASK 0x1ff00000 + +/* V1_ZOOM_CONTROL 0x24C */ +#define V1_X_ZOOM_ENABLE 0x80000000 +#define V1_Y_ZOOM_ENABLE 0x00008000 + +/* V1_MINI_CONTROL 0x250 */ +#define V1_X_INTERPOLY 0x00000002 /* X interpolation */ +#define V1_Y_INTERPOLY 0x00000001 /* Y interpolation */ +#define V1_YCBCR_INTERPOLY 0x00000004 /* Y, Cb, Cr all interpolation */ +#define V1_X_DIV_2 0x01000000 +#define V1_X_DIV_4 0x03000000 +#define V1_X_DIV_8 0x05000000 +#define V1_X_DIV_16 0x07000000 +#define V1_Y_DIV_2 0x00010000 +#define V1_Y_DIV_4 0x00030000 +#define V1_Y_DIV_8 0x00050000 +#define V1_Y_DIV_16 0x00070000 + +/* V1_STARTADDR0 0x254 */ +#define SW_FLIP_ODD 0x08000000 + +/* V_FIFO_CONTROL 0x258 + * IA2 has 32 level FIFO for packet mode video format + * 32 level FIFO for planar mode video YV12. with extension reg 230 bit 21 enable + * 16 level FIFO for planar mode video YV12. with extension reg 230 bit 21 disable + * BCos of 128 bits. 1 level in IA2 = 2 level in VT3122 + */ +#define V1_FIFO_DEPTH12 0x0000000B +#define V1_FIFO_DEPTH16 0x0000000F +#define V1_FIFO_DEPTH32 0x0000001F +#define V1_FIFO_DEPTH48 0x0000002F +#define V1_FIFO_DEPTH64 0x0000003F +#define V1_FIFO_THRESHOLD6 0x00000600 +#define V1_FIFO_THRESHOLD8 0x00000800 +#define V1_FIFO_THRESHOLD12 0x00000C00 +#define V1_FIFO_THRESHOLD16 0x00001000 +#define V1_FIFO_THRESHOLD24 0x00001800 +#define V1_FIFO_THRESHOLD32 0x00002000 +#define V1_FIFO_THRESHOLD40 0x00002800 +#define V1_FIFO_THRESHOLD48 0x00003000 +#define V1_FIFO_THRESHOLD56 0x00003800 +#define V1_FIFO_THRESHOLD61 0x00003D00 +#define V1_FIFO_PRETHRESHOLD10 0x0A000000 +#define V1_FIFO_PRETHRESHOLD12 0x0C000000 +#define V1_FIFO_PRETHRESHOLD29 0x1d000000 +#define V1_FIFO_PRETHRESHOLD40 0x28000000 +#define V1_FIFO_PRETHRESHOLD44 0x2c000000 +#define V1_FIFO_PRETHRESHOLD56 0x38000000 +#define V1_FIFO_PRETHRESHOLD61 0x3D000000 + +#define VIDEO_FIFO_DEPTH_VT3336 225 +#define VIDEO_FIFO_THRESHOLD_VT3336 200 +#define VIDEO_FIFO_PRETHRESHOLD_VT3336 250 +#define VIDEO_EXPIRE_NUM_VT3336 31 + +/* ALPHA_V3_FIFO_CONTROL 0x278 + * IA2 has 32 level FIFO for packet mode video format + * 32 level FIFO for planar mode video YV12. with extension reg 230 bit 21 enable + * 16 level FIFO for planar mode video YV12. with extension reg 230 bit 21 disable + * 8 level FIFO for ALPHA + * BCos of 128 bits. 1 level in IA2 = 2 level in VT3122 + */ +#define V3_FIFO_DEPTH16 0x0000000F +#define V3_FIFO_DEPTH24 0x00000017 +#define V3_FIFO_DEPTH32 0x0000001F +#define V3_FIFO_DEPTH48 0x0000002F +#define V3_FIFO_DEPTH64 0x0000003F +#define V3_FIFO_THRESHOLD8 0x00000800 +#define V3_FIFO_THRESHOLD12 0x00000C00 +#define V3_FIFO_THRESHOLD16 0x00001000 +#define V3_FIFO_THRESHOLD24 0x00001800 +#define V3_FIFO_THRESHOLD29 0x00001D00 +#define V3_FIFO_THRESHOLD32 0x00002000 +#define V3_FIFO_THRESHOLD40 0x00002800 +#define V3_FIFO_THRESHOLD48 0x00003000 +#define V3_FIFO_THRESHOLD56 0x00003800 +#define V3_FIFO_THRESHOLD61 0x00003D00 +#define V3_FIFO_PRETHRESHOLD10 0x0000000A +#define V3_FIFO_PRETHRESHOLD12 0x0000000C +#define V3_FIFO_PRETHRESHOLD29 0x0000001d +#define V3_FIFO_PRETHRESHOLD40 0x00000028 +#define V3_FIFO_PRETHRESHOLD44 0x0000002c +#define V3_FIFO_PRETHRESHOLD56 0x00000038 +#define V3_FIFO_PRETHRESHOLD61 0x0000003D +#define V3_FIFO_MASK 0x0000007F +#define V3_FIFO_MASK_3314 0x000000FF +#define ALPHA_FIFO_DEPTH8 0x00070000 +#define ALPHA_FIFO_THRESHOLD4 0x04000000 +#define ALPHA_FIFO_MASK 0xffff0000 +#define ALPHA_FIFO_PRETHRESHOLD4 0x00040000 + +/* IA2 */ +#define ColorSpaceValue_1 0x140020f2 +#define ColorSpaceValue_2 0x0a0a2c00 + +#define ColorSpaceValue_1_3123C0 0x13000DED +#define ColorSpaceValue_2_3123C0 0x13171000 +#define ColorSpaceValue_1_32045 0x13000DED +#define ColorSpaceValue_2_32045 0x13171000 + +/* For TV setting */ +#define ColorSpaceValue_1TV 0x140020f2 +#define ColorSpaceValue_2TV 0x0a0a2c00 + +/* V_COMPOSE_MODE 0x298 */ +#define SELECT_VIDEO_IF_COLOR_KEY 0x00000001 /* select video if (color key),otherwise select graphics */ +#define SELECT_VIDEO3_IF_COLOR_KEY 0x00000020 /* For 3123C0, select video3 if (color key),otherwise select graphics */ +#define SELECT_VIDEO_IF_CHROMA_KEY 0x00000002 /* 0x0000000a //select video if (chroma key ),otherwise select graphics */ +#define ALWAYS_SELECT_VIDEO 0x00000000 /* always select video,Chroma key and Color key disable */ +#define COMPOSE_V1_V3 0x00000000 /* V1 on top of V3 */ +#define COMPOSE_V3_V1 0x00100000 /* V3 on top of V1 */ +#define COMPOSE_V1_TOP 0x00000000 +#define COMPOSE_V3_TOP 0x00100000 +#define V1_COMMAND_FIRE 0x80000000 /* V1 commands fire */ +#define V3_COMMAND_FIRE 0x40000000 /* V3 commands fire */ +#define V_COMMAND_LOAD 0x20000000 /* Video register always loaded */ +#define V_COMMAND_LOAD_VBI 0x10000000 /* Video register always loaded at vbi without waiting source flip */ +#define V3_COMMAND_LOAD 0x08000000 /* CLE_C0 Video3 register always loaded */ +#define V3_COMMAND_LOAD_VBI 0x00000100 /* CLE_C0 Video3 register always loaded at vbi without waiting source flip */ +#define SECOND_DISPLAY_COLOR_KEY_ENABLE 0x00010000 + +/* V3_ZOOM_CONTROL 0x2bc */ +#define V3_X_ZOOM_ENABLE 0x80000000 +#define V3_Y_ZOOM_ENABLE 0x00008000 + +/* V3_MINI_CONTROL 0x2c0 */ +#define V3_X_INTERPOLY 0x00000002 /* X interpolation */ +#define V3_Y_INTERPOLY 0x00000001 /* Y interpolation */ +#define V3_YCBCR_INTERPOLY 0x00000004 /* Y, Cb, Cr all interpolation */ +#define V3_X_DIV_2 0x01000000 +#define V3_X_DIV_4 0x03000000 +#define V3_X_DIV_8 0x05000000 +#define V3_X_DIV_16 0x07000000 +#define V3_Y_DIV_2 0x00010000 +#define V3_Y_DIV_4 0x00030000 +#define V3_Y_DIV_8 0x00050000 +#define V3_Y_DIV_16 0x00070000 + +/* SUBP_CONTROL_STRIDE 0x3c0 */ +#define SUBP_HQV_ENABLE 0x00010000 +#define SUBP_IA44 0x00020000 +#define SUBP_AI44 0x00000000 +#define SUBP_STRIDE_MASK 0x00001fff +#define SUBP_CONTROL_MASK 0x00070000 + +/* RAM_TABLE_CONTROL 0x3c8 */ +#define RAM_TABLE_RGB_ENABLE 0x00000007 + +/* CAPTURE0_CONTROL 0x310 */ +#define C0_ENABLE 0x00000001 +#define BUFFER_2_MODE 0x00000000 +#define BUFFER_3_MODE 0x00000004 +#define BUFFER_4_MODE 0x00000006 +#define SWAP_YUYV 0x00000000 +#define SWAP_UYVY 0x00000100 +#define SWAP_YVYU 0x00000200 +#define SWAP_VYUY 0x00000300 +#define IN_601_8 0x00000000 +#define IN_656_8 0x00000010 +#define IN_601_16 0x00000020 +#define IN_656_16 0x00000030 +#define DEINTER_ODD 0x00000000 +#define DEINTER_EVEN 0x00001000 +#define DEINTER_ODD_EVEN 0x00002000 +#define DEINTER_FRAME 0x00003000 +#define VIP_1 0x00000000 +#define VIP_2 0x00000400 +#define H_FILTER_2 0x00010000 +#define H_FILTER_4 0x00020000 +#define H_FILTER_8_1331 0x00030000 +#define H_FILTER_8_12221 0x00040000 +#define VIP_ENABLE 0x00000008 +#define EN_FIELD_SIG 0x00000800 +#define VREF_INVERT 0x00100000 +#define FIELD_INPUT_INVERSE 0x00400000 +#define FIELD_INVERSE 0x40000000 + +#define C1_H_MINI_EN 0x00000800 +#define C0_H_MINI_EN 0x00000800 +#define C1_V_MINI_EN 0x04000000 +#define C0_V_MINI_EN 0x04000000 +#define C1_H_MINI_2 0x00000400 + +/* CAPTURE1_CONTROL 0x354 */ +#define C1_ENABLE 0x00000001 + +/* V3_CONTROL 0x2A0 */ +#define V3_ENABLE 0x00000001 +#define V3_FULL_SCREEN 0x00000002 +#define V3_YUV422 0x00000000 +#define V3_RGB32 0x00000004 +#define V3_RGB15 0x00000008 +#define V3_RGB16 0x0000000C +#define V3_COLORSPACE_SIGN 0x00000080 +#define V3_EXPIRE_NUM 0x00040000 +#define V3_EXPIRE_NUM_F 0x000f0000 +#define V3_EXPIRE_NUM_3204 0x00100000 +#define V3_EXPIRE_NUM_3205 0x00080000 +#define V3_BOB_ENABLE 0x00400000 +#define V3_FIELD_BASE 0x00000000 +#define V3_FRAME_BASE 0x01000000 +#define V3_SWAP_SW 0x00000000 +#define V3_SWAP_HW_HQV 0x02000000 +#define V3_FLIP_HW_CAPTURE0 0x04000000 +#define V3_FLIP_HW_CAPTURE1 0x06000000 + +/* V3_ALPHA_FETCH_COUNT 0x2B8 */ +#define V3_FETCH_COUNT 0x3ff00000 +#define ALPHA_FETCH_COUNT 0x000003ff + +/* HQV_CONTROL 0x3D0 */ +#define HQV_RGB32 0x00000000 +#define HQV_RGB16 0x20000000 +#define HQV_RGB15 0x30000000 +#define HQV_YUV422 0x80000000 +#define HQV_YUV420 0xC0000000 +#define HQV_ENABLE 0x08000000 +#define HQV_SRC_SW 0x00000000 +#define HQV_SRC_MC 0x01000000 +#define HQV_SRC_CAPTURE0 0x02000000 +#define HQV_SRC_CAPTURE1 0x03000000 +#define HQV_FLIP_EVEN 0x00000000 +#define HQV_FLIP_ODD 0x00000020 +#define HQV_SW_FLIP 0x00000010 /* Write 1 to flip HQV buffer */ +#define HQV_DEINTERLACE 0x00010000 /* First line of odd field will be repeated 3 times */ +#define HQV_FIELD_2_FRAME 0x00020000 /* Src is field. Display each line 2 times */ +#define HQV_FRAME_2_FIELD 0x00040000 /* Src is field. Display field */ +#define HQV_FRAME_UV 0x00000000 /* Src is Non-interleaved */ +#define HQV_FIELD_UV 0x00100000 /* Src is interleaved */ +#define HQV_IDLE 0x00000008 +#define HQV_FLIP_STATUS 0x00000001 +#define HQV_DOUBLE_BUFF 0x00000000 +#define HQV_TRIPLE_BUFF 0x04000000 +#define HQV_SUBPIC_FLIP 0x00008000 +#define HQV_FIFO_STATUS 0x00001000 +#define HQV_GEN_IRQ 0x00000080 +#define HQV_FIFO_DEPTH_1 0x00010000 + +/* HQV_FILTER_CONTROL 0x3E4 */ +#define HQV_H_LOWPASS_2TAP 0x00000001 +#define HQV_H_LOWPASS_4TAP 0x00000002 +#define HQV_H_LOWPASS_8TAP1 0x00000003 /* To be deleted */ +#define HQV_H_LOWPASS_8TAP2 0x00000004 /* To be deleted */ +#define HQV_H_HIGH_PASS 0x00000008 +#define HQV_H_LOW_PASS 0x00000000 +#define HQV_V_LOWPASS_2TAP 0x00010000 +#define HQV_V_LOWPASS_4TAP 0x00020000 +#define HQV_V_LOWPASS_8TAP1 0x00030000 +#define HQV_V_LOWPASS_8TAP2 0x00040000 +#define HQV_V_HIGH_PASS 0x00080000 +#define HQV_V_LOW_PASS 0x00000000 +#define HQV_H_HIPASS_F1_DEFAULT 0x00000040 +#define HQV_H_HIPASS_F2_DEFAULT 0x00000000 +#define HQV_V_HIPASS_F1_DEFAULT 0x00400000 +#define HQV_V_HIPASS_F2_DEFAULT 0x00000000 +#define HQV_H_HIPASS_F1_2TAP 0x00000050 +#define HQV_H_HIPASS_F2_2TAP 0x00000100 +#define HQV_V_HIPASS_F1_2TAP 0x00500000 +#define HQV_V_HIPASS_F2_2TAP 0x01000000 +#define HQV_H_HIPASS_F1_4TAP 0x00000060 +#define HQV_H_HIPASS_F2_4TAP 0x00000200 +#define HQV_V_HIPASS_F1_4TAP 0x00600000 +#define HQV_V_HIPASS_F2_4TAP 0x02000000 +#define HQV_H_HIPASS_F1_8TAP 0x00000080 +#define HQV_H_HIPASS_F2_8TAP 0x00000400 +#define HQV_V_HIPASS_F1_8TAP 0x00800000 +#define HQV_V_HIPASS_F2_8TAP 0x04000000 +/* IA2 NEW */ +#define HQV_V_FILTER2 0x00080000 +#define HQV_H_FILTER2 0x00000008 +#define HQV_H_TAP2_11 0x00000041 +#define HQV_H_TAP4_121 0x00000042 +#define HQV_H_TAP4_1111 0x00000401 +#define HQV_H_TAP8_1331 0x00000221 +#define HQV_H_TAP8_12221 0x00000402 +#define HQV_H_TAP16_1991 0x00000159 +#define HQV_H_TAP16_141041 0x0000026A +#define HQV_H_TAP32 0x0000015A +#define HQV_V_TAP2_11 0x00410000 +#define HQV_V_TAP4_121 0x00420000 +#define HQV_V_TAP4_1111 0x04010000 +#define HQV_V_TAP8_1331 0x02210000 +#define HQV_V_TAP8_12221 0x04020000 +#define HQV_V_TAP16_1991 0x01590000 +#define HQV_V_TAP16_141041 0x026A0000 +#define HQV_V_TAP32 0x015A0000 +#define HQV_V_FILTER_DEFAULT 0x00420000 +#define HQV_H_FILTER_DEFAULT 0x00000040 + + + + +/* HQV_MINI_CONTROL 0x3E8 */ +#define HQV_H_MINIFY_ENABLE 0x00000800 +#define HQV_H_MINIFY_DOWN 0x00001000 +#define HQV_V_MINIFY_ENABLE 0x08000000 +#define HQV_V_MINIFY_DOWN 0x10000000 +#define HQV_VDEBLOCK_FILTER 0x80000000 +#define HQV_HDEBLOCK_FILTER 0x00008000 + + +#define CHROMA_KEY_LOW 0x00FFFFFF +#define CHROMA_KEY_HIGH 0x00FFFFFF + +/* V_CAP_STATUS */ +#define V_ST_UPDATE_NOT_YET 0x00000003 +#define V1_ST_UPDATE_NOT_YET 0x00000001 +#define V3_ST_UPDATE_NOT_YET 0x00000008 + +#define VBI_STATUS 0x00000002 + +/* + * Macros for Video MMIO + */ +#ifndef V4L2 +#define VIDInB(port) *((volatile CARD8 *)(pVia->VidMapBase + (port))) +#define VIDInW(port) *((volatile CARD16 *)(pVia->VidMapBase + (port))) +#define VIDInD(port) *((volatile CARD32 *)(pVia->VidMapBase + (port))) +#define VIDOutB(port, data) *((volatile CARD8 *)(pVia->VidMapBase + (port))) = (data) +#define VIDOutW(port, data) *((volatile CARD16 *)(pVia->VidMapBase + (port))) = (data) +#define VIDOutD(port, data) *((volatile CARD32 *)(pVia->VidMapBase + (port))) = (data) +#define MPGOutD(port, data) *((volatile CARD32 *)(pVia->MpegMapBase +(port))) = (data) +#define MPGInD(port) *((volatile CARD32 *)(pVia->MpegMapBase +(port))) +#endif + +/* + * Macros for GE MMIO + */ +#define GEInW(port) *((volatile CARD16 *)(lpGEMMIO + (port))) +#define GEInD(port) *((volatile CARD32 *)(lpGEMMIO + (port))) +#define GEOutW(port, data) *((volatile CARD16 *)(lpGEMMIO + (port))) = (data) +#define GEOutD(port, data) *((volatile CARD32 *)(lpGEMMIO + (port))) = (data) + +/* + * MPEG 1/2 Slice Engine (at 0xC00 relative to base) + */ + +#define MPG_CONTROL 0x00 +#define MPG_CONTROL_STRUCT 0x03 +#define MPG_CONTROL_STRUCT_TOP 0x01 +#define MPG_CONTROL_STRUCT_BOTTOM 0x02 +#define MPG_CONTROL_STRUCT_FRAME 0x03 + /* Use TOP if interlaced */ +#define MPG_CONTROL_TYPE 0x3C +#define MPG_CONTROL_TYPE_I (0x01 << 2) +#define MPG_CONTROL_TYPE_B (0x02 << 2) +#define MPG_CONTROL_TYPE_P (0x03 << 3) +#define MPG_CONTROL_ALTSCAN 0x40 +#define MPG_BLOCK 0x08 /* Unsure */ +#define MPG_COMMAND 0x0C +#define MPG_DATA1 0x10 +#define MPG_DATA2 0x14 +#define MPG_DATA3 0x18 +#define MPG_DATA4 0x1C + +#define MPG_YPHYSICAL(x) (0x20 + 12*(x)) +#define MPG_CbPHYSICAL(x) (0x24 + 12*(x)) +#define MPG_CrPHYSICAL(x) (0x28 + 12*(x)) + +#define MPG_PITCH 0x50 +#define MPG_STATUS 0x54 + +#define MPG_MATRIX_IDX 0x5C +#define MPG_MATRIX_IDX_INTRA 0x00 +#define MPG_MATRIX_IDX_NON 0x01 +#define MPG_MATRIX_DATA 0x60 + +#define MPG_SLICE_CTRL_1 0x90 +#define MPG_SLICE_MBAMAX 0x2FFF +#define MPG_SLICE_PREDICTIVE_DCT 0x4000 +#define MPG_SLICE_TOP_FIRST 0x8000 +#define MPG_SLICE_MACROBLOCK_WIDTH(x) ((x)<<18) /* in 64's */ +#define MPG_SLICE_CTRL_2 0x94 +#define MPG_SLICE_CONCEAL_MVEC 0x0000001 +#define MPG_SLICE_QSCALE_TYPE 0x0000002 +#define MPG_SLICE_DCPRECISION 0x000000C +#define MPG_SLICE_MACROBQUOT 0x0FFFFF0 +#define MPG_SLICE_INTRAVLC 0x1000000 +#define MPG_SLICE_CTRL_3 0x98 +#define MPG_SLICE_FHMVR 0x0000003 +#define MPG_SLICE_FVMVR 0x000000C +#define MPG_SLICE_BHMVR 0x0000030 +#define MPG_SLICE_BVMVR 0x00000C0 +#define MPG_SLICE_SECOND_FIELD 0x0100000 +#define MPG_SLICE_RESET 0x0400000 +#define MPG_SLICE_LENGTH 0x9C +#define MPG_SLICE_DATA 0xA0 + +#define VBE_DEFAULT_REFRESH 6000 + +#endif /* _VIA_H_ */ diff --git a/trunk/src/via_3d.c b/trunk/src/via_3d.c new file mode 100644 index 000000000000..9ccdaad00856 --- /dev/null +++ b/trunk/src/via_3d.c @@ -0,0 +1,592 @@ +/* + * Copyright 2006 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, sub license, + * 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 NON-INFRINGEMENT. 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. + */ + +#include "via_3d.h" +#include "via_3d_reg.h" +#include <picturestr.h> + +typedef struct +{ + Bool supported; + CARD32 col0; + CARD32 col1; + CARD32 al0; + CARD32 al1; +} ViaCompositeOperator; + +typedef struct +{ + CARD32 pictFormat; + Bool dstSupported; + Bool texSupported; + CARD32 dstFormat; + CARD32 texFormat; +} Via3DFormat; + +static ViaCompositeOperator viaOperatorModes[256]; +static Via3DFormat via3DFormats[256]; + +#define VIA_NUM_3D_OPCODES 19 +#define VIA_NUM_3D_FORMATS 15 +#define VIA_FMT_HASH(arg) (((((arg) >> 1) + (arg)) >> 8) & 0xFF) + +static const CARD32 viaOpCodes[VIA_NUM_3D_OPCODES][5] = { + {PictOpClear, 0x05, 0x45, 0x40, 0x80}, + {PictOpSrc, 0x15, 0x45, 0x50, 0x80}, + {PictOpDst, 0x05, 0x55, 0x40, 0x90}, + {PictOpOver, 0x15, 0x52, 0x50, 0x91}, + {PictOpOverReverse, 0x13, 0x45, 0x52, 0x90}, + {PictOpIn, 0x03, 0x45, 0x42, 0x80}, + {PictOpInReverse, 0x05, 0x42, 0x40, 0x81}, + {PictOpOut, 0x13, 0x45, 0x52, 0x80}, + {PictOpOutReverse, 0x05, 0x52, 0x40, 0x91}, + {PictOpAtop, 0x03, 0x52, 0x42, 0x91}, + {PictOpAtopReverse, 0x13, 0x42, 0x52, 0x81}, + {PictOpXor, 0x15, 0x52, 0x52, 0x91}, + {PictOpAdd, 0x15, 0x55, 0x50, 0x90}, + {PictOpDisjointClear, 0x05, 0x45, 0x40, 0x80}, + {PictOpDisjointSrc, 0x15, 0x45, 0x50, 0x80}, + {PictOpDisjointDst, 0x05, 0x55, 0x40, 0x90}, + {PictOpConjointClear, 0x05, 0x45, 0x40, 0x80}, + {PictOpConjointSrc, 0x15, 0x45, 0x50, 0x80}, + {PictOpConjointDst, 0x05, 0x55, 0x40, 0x90} +}; + +static const CARD32 viaFormats[VIA_NUM_3D_FORMATS][5] = { + {PICT_x1r5g5b5, HC_HDBFM_RGB555, HC_HTXnFM_RGB555, 1, 1}, + {PICT_r5g6b5, HC_HDBFM_RGB565, HC_HTXnFM_RGB565, 1, 1}, + {PICT_a4r4g4b4, HC_HDBFM_ARGB4444, HC_HTXnFM_ARGB4444, 1, 1}, + {PICT_a1r5g5b5, HC_HDBFM_ARGB1555, HC_HTXnFM_ARGB1555, 1, 1}, + {PICT_x1b5g5r5, HC_HDBFM_BGR555, HC_HTXnFM_BGR555, 1, 1}, + {PICT_b5g6r5, HC_HDBFM_BGR565, HC_HTXnFM_BGR565, 1, 1}, + {PICT_a4b4g4r4, HC_HDBFM_ABGR4444, HC_HTXnFM_ABGR4444, 1, 1}, + {PICT_a1b5g5r5, HC_HDBFM_ABGR1555, HC_HTXnFM_ABGR1555, 1, 1}, + {PICT_x8r8g8b8, HC_HDBFM_ARGB0888, HC_HTXnFM_ARGB0888, 1, 1}, + {PICT_a8r8g8b8, HC_HDBFM_ARGB8888, HC_HTXnFM_ARGB8888, 1, 1}, + {PICT_x8b8g8r8, HC_HDBFM_ABGR0888, HC_HTXnFM_ABGR0888, 1, 1}, + {PICT_a8b8g8r8, HC_HDBFM_ABGR8888, HC_HTXnFM_ABGR8888, 1, 1}, + {PICT_a8, 0x00, HC_HTXnFM_A8, 0, 1}, + {PICT_a4, 0x00, HC_HTXnFM_A4, 0, 1}, + {PICT_a1, 0x00, HC_HTXnFM_A1, 0, 1} +}; + +static CARD32 +via3DDstFormat(int format) +{ + return via3DFormats[VIA_FMT_HASH(format)].dstFormat; +} + +static CARD32 +via3DTexFormat(int format) +{ + return via3DFormats[VIA_FMT_HASH(format)].texFormat; +} + +static Bool +via3DDstSupported(int format) +{ + Via3DFormat *fm = via3DFormats + VIA_FMT_HASH(format); + + if (fm->pictFormat != format) + return FALSE; + return fm->dstSupported; +} + +static Bool +via3DTexSupported(int format) +{ + Via3DFormat *fm = via3DFormats + VIA_FMT_HASH(format); + + if (fm->pictFormat != format) + return FALSE; + return fm->texSupported; +} + +static void +viaSet3DDestination(Via3DState * v3d, CARD32 offset, CARD32 pitch, int format) +{ + v3d->drawingDirty = TRUE; /* Affects planemask format. */ + v3d->destDirty = TRUE; + v3d->destOffset = offset; + v3d->destPitch = pitch; + v3d->destFormat = via3DDstFormat(format); + v3d->destDepth = (v3d->destFormat < HC_HDBFM_ARGB0888) ? 16 : 32; +} + +static void +viaSet3DDrawing(Via3DState * v3d, int rop, + CARD32 planeMask, CARD32 solidColor, CARD32 solidAlpha) +{ + v3d->drawingDirty = TRUE; + v3d->rop = rop; + v3d->planeMask = planeMask; + v3d->solidColor = solidColor; + v3d->solidAlpha = solidAlpha; +} + +static void +viaSet3DFlags(Via3DState * v3d, int numTextures, + Bool writeAlpha, Bool writeColor, Bool blend) +{ + v3d->enableDirty = TRUE; + v3d->blendDirty = TRUE; + v3d->numTextures = numTextures; + v3d->writeAlpha = writeAlpha; + v3d->writeColor = writeColor; + v3d->blend = blend; +} + +static Bool +viaOrder(CARD32 val, CARD32 * shift) +{ + *shift = 0; + + while (val > (1 << *shift)) + (*shift)++; + return (val == (1 << *shift)); +} + +static Bool +viaSet3DTexture(Via3DState * v3d, int tex, CARD32 offset, + CARD32 pitch, Bool npot, CARD32 width, CARD32 height, int format, + ViaTextureModes sMode, ViaTextureModes tMode, + ViaTexBlendingModes blendingMode, Bool agpTexture) +{ + ViaTextureUnit *vTex = v3d->tex + tex; + + vTex->textureLevel0Offset = offset; + vTex->npot = npot; + if (!viaOrder(pitch, &vTex->textureLevel0Exp) && !vTex->npot) + return FALSE; + vTex->textureLevel0Pitch = pitch; + if (!viaOrder(width, &vTex->textureLevel0WExp)) + return FALSE; + if (!viaOrder(height, &vTex->textureLevel0HExp)) + return FALSE; + + if (pitch <= 4) { + ErrorF("Warning! texture pitch is leq 4\n"); + } + + vTex->textureFormat = via3DTexFormat(format); + + switch (blendingMode) { + case via_src: + vTex->texCsat = (0x01 << 23) | (0x10 << 14) | (0x03 << 7) | 0x00; + vTex->texAsat = + (0x0B << 14) | ((PICT_FORMAT_A(format) ? 0x04 : 0x02) << 7) | + 0x03; + vTex->texRCa = 0x00000000; + vTex->texRAa = 0x00000000; + vTex->texBColDirty = TRUE; + break; + case via_src_onepix_mask: + vTex->texCsat = (0x01 << 23) | (0x09 << 14) | (0x03 << 7) | 0x00; + vTex->texAsat = + (0x03 << 14) | ((PICT_FORMAT_A(format) ? 0x04 : 0x02) << 7) | + 0x03; + break; + case via_src_onepix_comp_mask: + vTex->texCsat = (0x01 << 23) | (0x09 << 14) | (0x03 << 7) | 0x00; + vTex->texAsat = + (0x03 << 14) | ((PICT_FORMAT_A(format) ? 0x04 : 0x02) << 7) | + 0x03; + break; + case via_mask: + vTex->texCsat = (0x01 << 23) | (0x07 << 14) | (0x04 << 7) | 0x00; + vTex->texAsat = (0x01 << 23) | (0x04 << 14) | (0x02 << 7) | 0x03; + break; + case via_comp_mask: + vTex->texCsat = (0x01 << 23) | (0x03 << 14) | (0x04 << 7) | 0x00; + vTex->texAsat = (0x01 << 23) | (0x04 << 14) | (0x02 << 7) | 0x03; + break; + default: + return FALSE; + } + + vTex->textureDirty = TRUE; + vTex->textureModesS = sMode - via_single; + vTex->textureModesT = tMode - via_single; + + vTex->agpTexture = agpTexture; + return TRUE; +} + +static void +viaSet3DTexBlendCol(Via3DState * v3d, int tex, Bool component, CARD32 color) +{ + CARD32 alpha; + ViaTextureUnit *vTex = v3d->tex + tex; + + vTex->texRAa = (color >> 8) & 0x00FF0000; + if (component) { + vTex->texRCa = (color & 0x00FFFFFF); + } else { + alpha = color >> 24; + vTex->texRCa = alpha | (alpha << 8) | (alpha << 16) | (alpha << 24); + } + vTex->texBColDirty = TRUE; +} + +/* + * Check if compositing operator is supported and return corresponding register setting. + */ + +static void +viaSet3DCompositeOperator(Via3DState * v3d, CARD8 op) +{ + ViaCompositeOperator *vOp = viaOperatorModes + op; + + v3d->blendDirty = TRUE; + if (v3d && vOp->supported) { + v3d->blendCol0 = vOp->col0 << 4; + v3d->blendCol1 = vOp->col1 << 2; + v3d->blendAl0 = vOp->al0 << 4; + v3d->blendAl1 = vOp->al1 << 2; + } +} + +static Bool +via3DOpSupported(CARD8 op) +{ + return viaOperatorModes[op].supported; +} + +static void +via3DEmitQuad(Via3DState * v3d, ViaCommandBuffer * cb, int dstX, int dstY, + int src0X, int src0Y, int src1X, int src1Y, int w, int h) +{ + CARD32 acmd; + float dx1, dx2, dy1, dy2, sx1[2], sx2[2], sy1[2], sy2[2], wf; + double scalex, scaley; + int i, numTex; + ViaTextureUnit *vTex; + + numTex = v3d->numTextures; + dx1 = dstX; + dx2 = dstX + w; + dy1 = dstY; + dy2 = dstY + h; + + if (numTex) { + sx1[0] = src0X; + sx1[1] = src1X; + sy1[0] = src0Y; + sy1[1] = src1Y; + for (i = 0; i < numTex; ++i) { + vTex = v3d->tex + i; + scalex = 1. / (double)((1 << vTex->textureLevel0WExp)); + scaley = 1. / (double)((1 << vTex->textureLevel0HExp)); + sx2[i] = sx1[i] + w; + sy2[i] = sy1[i] + h; + sx1[i] *= scalex; + sy1[i] *= scaley; + sx2[i] *= scalex; + sy2[i] *= scaley; + } + } + + wf = 0.05; + + /* + * Vertex buffer. Emit two 3-point triangles. The W or Z coordinate + * is needed for AGP DMA, and the W coordinate is for some obscure + * reason needed for texture mapping to be done correctly. So emit + * a w value after the x and y coordinates. + */ + + BEGIN_H2(HC_ParaType_CmdVdata, 22 + numTex * 6); + acmd = ((1 << 14) | (1 << 13) | (1 << 11)); + if (numTex) + acmd |= ((1 << 7) | (1 << 8)); + OUT_RING_SubA(0xEC, acmd); + + acmd = 2 << 16; + OUT_RING_SubA(0xEE, acmd); + + OUT_RING(*((CARD32 *) (&dx1))); + OUT_RING(*((CARD32 *) (&dy1))); + OUT_RING(*((CARD32 *) (&wf))); + for (i = 0; i < numTex; ++i) { + OUT_RING(*((CARD32 *) (sx1 + i))); + OUT_RING(*((CARD32 *) (sy1 + i))); + } + + OUT_RING(*((CARD32 *) (&dx2))); + OUT_RING(*((CARD32 *) (&dy1))); + OUT_RING(*((CARD32 *) (&wf))); + for (i = 0; i < numTex; ++i) { + OUT_RING(*((CARD32 *) (sx2 + i))); + OUT_RING(*((CARD32 *) (sy1 + i))); + } + + OUT_RING(*((CARD32 *) (&dx1))); + OUT_RING(*((CARD32 *) (&dy2))); + OUT_RING(*((CARD32 *) (&wf))); + for (i = 0; i < numTex; ++i) { + OUT_RING(*((CARD32 *) (sx1 + i))); + OUT_RING(*((CARD32 *) (sy2 + i))); + } + + OUT_RING(*((CARD32 *) (&dx1))); + OUT_RING(*((CARD32 *) (&dy2))); + OUT_RING(*((CARD32 *) (&wf))); + for (i = 0; i < numTex; ++i) { + OUT_RING(*((CARD32 *) (sx1 + i))); + OUT_RING(*((CARD32 *) (sy2 + i))); + } + + OUT_RING(*((CARD32 *) (&dx2))); + OUT_RING(*((CARD32 *) (&dy1))); + OUT_RING(*((CARD32 *) (&wf))); + for (i = 0; i < numTex; ++i) { + OUT_RING(*((CARD32 *) (sx2 + i))); + OUT_RING(*((CARD32 *) (sy1 + i))); + } + + OUT_RING(*((CARD32 *) (&dx2))); + OUT_RING(*((CARD32 *) (&dy2))); + OUT_RING(*((CARD32 *) (&wf))); + for (i = 0; i < numTex; ++i) { + OUT_RING(*((CARD32 *) (sx2 + i))); + OUT_RING(*((CARD32 *) (sy2 + i))); + } + OUT_RING_SubA(0xEE, + acmd | HC_HPLEND_MASK | HC_HPMValidN_MASK | HC_HE3Fire_MASK); + OUT_RING_SubA(0xEE, + acmd | HC_HPLEND_MASK | HC_HPMValidN_MASK | HC_HE3Fire_MASK); + + ADVANCE_RING; +} + +static void +via3DEmitState(Via3DState * v3d, ViaCommandBuffer * cb, Bool forceUpload) +{ + int i; + Bool saveHas3dState; + ViaTextureUnit *vTex; + + /* + * Destination buffer location, format and pitch. + */ + + if (forceUpload || v3d->destDirty) { + v3d->destDirty = FALSE; + BEGIN_H2(HC_ParaType_NotTex, 3); + + OUT_RING_SubA(HC_SubA_HDBBasL, v3d->destOffset & 0x00FFFFFF); + OUT_RING_SubA(HC_SubA_HDBBasH, v3d->destOffset >> 24); + OUT_RING_SubA(HC_SubA_HDBFM, v3d->destFormat | + (v3d->destPitch & HC_HDBPit_MASK) | HC_HDBLoc_Local); + } + + if (forceUpload || v3d->blendDirty) { + v3d->blendDirty = FALSE; + BEGIN_H2(HC_ParaType_NotTex, 6); + OUT_RING_SubA(HC_SubA_HABLRFCa, 0x00); + OUT_RING_SubA(HC_SubA_HABLRFCb, 0x00); + OUT_RING_SubA(HC_SubA_HABLCsat, v3d->blendCol0); + OUT_RING_SubA(HC_SubA_HABLCop, v3d->blendCol1); + OUT_RING_SubA(HC_SubA_HABLAsat, v3d->blendAl0); + OUT_RING_SubA(HC_SubA_HABLAop, v3d->blendAl1); + } + + if (forceUpload || v3d->drawingDirty) { + + CARD32 planeMaskLo, planeMaskHi; + + v3d->drawingDirty = FALSE; + BEGIN_H2(HC_ParaType_NotTex, 4); + + /* + * Raster operation and Planemask. + */ + + if ( /* v3d->destDepth == 16 Bad Docs? */ FALSE) { + planeMaskLo = (v3d->planeMask & 0x000000FF) << 16; + planeMaskHi = (v3d->planeMask & 0x0000FF00) >> 8; + } else { + planeMaskLo = v3d->planeMask & 0x00FFFFFF; + planeMaskHi = v3d->planeMask >> 24; + } + + OUT_RING_SubA(HC_SubA_HROP, ((v3d->rop & 0x0F) << 8) | planeMaskHi); + OUT_RING_SubA(HC_SubA_HFBBMSKL, planeMaskLo); + + /* + * Solid shading color and alpha. Pixel center at + * floating coordinates (X.5,Y.5). + */ + + OUT_RING_SubA(HC_SubA_HSolidCL, + (v3d->solidColor & 0x00FFFFFF) | (0 << 23)); + OUT_RING_SubA(HC_SubA_HPixGC, + ((v3d->solidColor & 0xFF000000) >> 16) | (0 << 23) | (v3d-> + solidAlpha & 0xFF)); + } + + if (forceUpload || v3d->enableDirty) { + v3d->enableDirty = FALSE; + BEGIN_H2(HC_ParaType_NotTex, 1); + + OUT_RING_SubA(HC_SubA_HEnable, + ((v3d->writeColor) ? HC_HenCW_MASK : 0) | + ((v3d->blend) ? HC_HenABL_MASK : 0) | + ((v3d->numTextures) ? HC_HenTXMP_MASK : 0) | + ((v3d->writeAlpha) ? HC_HenAW_MASK : 0)); + + if (v3d->numTextures) { + BEGIN_H2((HC_ParaType_Tex | (HC_SubType_TexGeneral << 8)), 2); + OUT_RING_SubA(HC_SubA_HTXSMD, (0 << 7) | (0 << 6) | + (((v3d->numTextures - 1) & 0x1) << 3) | (0 << 1) | 1); + OUT_RING_SubA(HC_SubA_HTXSMD, (0 << 7) | (0 << 6) | + (((v3d->numTextures - 1) & 0x1) << 3) | (0 << 1) | 0); + } + } + + for (i = 0; i < v3d->numTextures; ++i) { + vTex = v3d->tex + i; + + if (forceUpload || vTex->textureDirty) { + vTex->textureDirty = FALSE; + + BEGIN_H2((HC_ParaType_Tex | + (((i == 0) ? HC_SubType_Tex0 : HC_SubType_Tex1) << 8)), + 13); + + OUT_RING_SubA(HC_SubA_HTXnFM, (vTex->textureFormat | + (vTex->agpTexture ? HC_HTXnLoc_AGP : HC_HTXnLoc_Local))); + OUT_RING_SubA(HC_SubA_HTXnL0BasL, + vTex->textureLevel0Offset & 0x00FFFFFF); + OUT_RING_SubA(HC_SubA_HTXnL012BasH, + vTex->textureLevel0Offset >> 24); + if (vTex->npot) { + OUT_RING_SubA(HC_SubA_HTXnL0Pit, + (vTex->textureLevel0Pitch & HC_HTXnLnPit_MASK) | + HC_HTXnEnPit_MASK); + } else { + OUT_RING_SubA(HC_SubA_HTXnL0Pit, + vTex->textureLevel0Exp << HC_HTXnLnPitE_SHIFT); + } + OUT_RING_SubA(HC_SubA_HTXnL0_5WE, vTex->textureLevel0WExp); + OUT_RING_SubA(HC_SubA_HTXnL0_5HE, vTex->textureLevel0HExp); + OUT_RING_SubA(HC_SubA_HTXnL0OS, 0x00); + OUT_RING_SubA(HC_SubA_HTXnTB, 0x00); + OUT_RING_SubA(HC_SubA_HTXnMPMD, + (((unsigned)vTex->textureModesT) << 19) | (((unsigned)vTex-> + textureModesS) << 16)); + + OUT_RING_SubA(HC_SubA_HTXnTBLCsat, vTex->texCsat); + OUT_RING_SubA(HC_SubA_HTXnTBLCop, (0x00 << 22) | (0x00 << 19) | + (0x00 << 14) | (0x02 << 11) | + (0x00 << 7) | (0x03 << 3) | 0x02); + OUT_RING_SubA(HC_SubA_HTXnTBLAsat, vTex->texAsat); + OUT_RING_SubA(HC_SubA_HTXnTBLRFog, 0x00); + } + } + + for (i = 0; i < v3d->numTextures; ++i) { + vTex = v3d->tex + i; + + if (forceUpload || vTex->texBColDirty) { + saveHas3dState = cb->has3dState; + vTex->texBColDirty = FALSE; + BEGIN_H2((HC_ParaType_Tex | + (((i == 0) ? HC_SubType_Tex0 : HC_SubType_Tex1) << 8)), + 2); + OUT_RING_SubA(HC_SubA_HTXnTBLRAa, vTex->texRAa); + OUT_RING_SubA(HC_SubA_HTXnTBLRCa, vTex->texRCa); + cb->has3dState = saveHas3dState; + } + } +} + +/* + * Cliprect. Considered not important for the DRM 3D State, so restore the + * has3dState flag afterwards. + */ + +static void +via3DEmitClipRect(Via3DState * v3d, ViaCommandBuffer * cb, int x, int y, + int w, int h) +{ + Bool saveHas3dState; + + saveHas3dState = cb->has3dState; + BEGIN_H2(HC_ParaType_NotTex, 4); + OUT_RING_SubA(HC_SubA_HClipTB, (y << 12) | (y + h)); + OUT_RING_SubA(HC_SubA_HClipLR, (x << 12) | (x + w)); + cb->has3dState = saveHas3dState; +} + +void +viaInit3DState(Via3DState * v3d) +{ + ViaCompositeOperator *op; + int i; + CARD32 tmp, hash; + Via3DFormat *format; + + v3d->setDestination = viaSet3DDestination; + v3d->setDrawing = viaSet3DDrawing; + v3d->setFlags = viaSet3DFlags; + v3d->setTexture = viaSet3DTexture; + v3d->setTexBlendCol = viaSet3DTexBlendCol; + v3d->opSupported = via3DOpSupported; + v3d->setCompositeOperator = viaSet3DCompositeOperator; + v3d->emitQuad = via3DEmitQuad; + v3d->emitState = via3DEmitState; + v3d->emitClipRect = via3DEmitClipRect; + v3d->dstSupported = via3DDstSupported; + v3d->texSupported = via3DTexSupported; + + for (i = 0; i < 256; ++i) { + viaOperatorModes[i].supported = FALSE; + } + + for (i = 0; i < VIA_NUM_3D_OPCODES; ++i) { + op = viaOperatorModes + viaOpCodes[i][0]; + op->supported = TRUE; + op->col0 = viaOpCodes[i][1]; + op->col1 = viaOpCodes[i][2]; + op->al0 = viaOpCodes[i][3]; + op->al1 = viaOpCodes[i][4]; + } + + for (i = 0; i < 256; ++i) { + via3DFormats[i].pictFormat = 0x00; + } + for (i = 0; i < VIA_NUM_3D_FORMATS; ++i) { + tmp = viaFormats[i][0]; + hash = VIA_FMT_HASH(tmp); + format = via3DFormats + hash; + if (format->pictFormat) { + ErrorF("BUG: Bad hash function\n"); + } + format->pictFormat = tmp; + format->dstSupported = (viaFormats[i][3] != 0x00); + format->texSupported = (viaFormats[i][4] != 0x00); + format->dstFormat = viaFormats[i][1]; + format->texFormat = viaFormats[i][2]; + } +} diff --git a/trunk/src/via_3d.h b/trunk/src/via_3d.h new file mode 100644 index 000000000000..c33228e321ae --- /dev/null +++ b/trunk/src/via_3d.h @@ -0,0 +1,121 @@ +/* + * Copyright 2006 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, sub license, + * 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 NON-INFRINGEMENT. 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. + */ + +#ifndef VIA_3D_H +#define VIA_3D_H + +#include "xf86.h" +#include "via_dmabuffer.h" + +#define VIA_NUM_TEXUNITS 2 + +typedef enum +{ + via_single, + via_clamp, + via_repeat, + via_mirror, + via_warp +} ViaTextureModes; + +typedef enum +{ + via_src, + via_src_onepix_mask, + via_src_onepix_comp_mask, + via_mask, + via_comp_mask +} ViaTexBlendingModes; + +typedef struct _ViaTextureUnit +{ + CARD32 textureLevel0Offset; + CARD32 textureLevel0Pitch; + CARD32 textureLevel0Exp; + CARD32 textureLevel0WExp; + CARD32 textureLevel0HExp; + CARD32 textureFormat; + CARD32 textureModesT; + CARD32 textureModesS; + CARD32 texCsat; + CARD32 texRCa; + CARD32 texAsat; + CARD32 texRAa; + Bool agpTexture; + Bool textureDirty; + Bool texBColDirty; + Bool npot; +} ViaTextureUnit; + +typedef struct _Via3DState +{ + Bool destDirty; + Bool blendDirty; + Bool enableDirty; + Bool drawingDirty; + CARD32 rop; + CARD32 planeMask; + CARD32 solidColor; + CARD32 solidAlpha; + CARD32 destOffset; + CARD32 destPitch; + CARD32 destFormat; + int destDepth; + int numTextures; + Bool blend; + CARD32 blendCol0; + CARD32 blendCol1; + CARD32 blendAl0; + CARD32 blendAl1; + Bool writeAlpha; + Bool writeColor; + Bool useDestAlpha; + ViaTextureUnit tex[VIA_NUM_TEXUNITS]; + void (*setDestination) (struct _Via3DState * v3d, CARD32 offset, + CARD32 pitch, int format); + void (*setDrawing) (struct _Via3DState * v3d, int rop, + CARD32 planeMask, CARD32 solidColor, CARD32 solidAlpha); + void (*setFlags) (struct _Via3DState * v3d, int numTextures, + Bool writeAlpha, Bool writeColor, Bool blend); + Bool(*setTexture) (struct _Via3DState * v3d, int tex, CARD32 offset, + CARD32 pitch, Bool nPot, CARD32 width, CARD32 height, int format, + ViaTextureModes sMode, ViaTextureModes tMode, + ViaTexBlendingModes blendingMode, Bool agpTexture); + void (*setTexBlendCol) (struct _Via3DState * v3d, int tex, Bool component, + CARD32 color); + void (*setCompositeOperator) (struct _Via3DState * v3d, CARD8 op); + Bool(*opSupported) (CARD8 op); + void (*emitQuad) (struct _Via3DState * v3d, ViaCommandBuffer * cb, + int dstX, int dstY, int src0X, int src0Y, int src1X, int src1Y, int w, + int h); + void (*emitState) (struct _Via3DState * v3d, ViaCommandBuffer * cb, + Bool forceUpload); + void (*emitClipRect) (struct _Via3DState * v3d, ViaCommandBuffer * cb, + int x, int y, int w, int h); + Bool(*dstSupported) (int format); + Bool(*texSupported) (int format); +} Via3DState; + +void viaInit3DState(Via3DState * v3d); + +#endif diff --git a/trunk/src/via_3d_reg.h b/trunk/src/via_3d_reg.h new file mode 100644 index 000000000000..cf61bb514db1 --- /dev/null +++ b/trunk/src/via_3d_reg.h @@ -0,0 +1,1651 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. 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, sub license, + * 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS 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 VIA_3D_REG_H +#define VIA_3D_REG_H +#define HC_REG_BASE 0x0400 + +#define HC_REG_TRANS_SPACE 0x0040 + +#define HC_ParaN_MASK 0xffffffff +#define HC_Para_MASK 0x00ffffff +#define HC_SubA_MASK 0xff000000 +#define HC_SubA_SHIFT 24 +/* Transmission Setting + */ +#define HC_REG_TRANS_SET 0x003c +#define HC_ParaSubType_MASK 0xff000000 +#define HC_ParaType_MASK 0x00ff0000 +#define HC_ParaOS_MASK 0x0000ff00 +#define HC_ParaAdr_MASK 0x000000ff +#define HC_ParaSubType_SHIFT 24 +#define HC_ParaType_SHIFT 16 +#define HC_ParaOS_SHIFT 8 +#define HC_ParaAdr_SHIFT 0 + +#define HC_ParaType_CmdVdata 0x0000 +#define HC_ParaType_NotTex 0x0001 +#define HC_ParaType_Tex 0x0002 +#define HC_ParaType_Palette 0x0003 +#define HC_ParaType_PreCR 0x0010 +#define HC_ParaType_Auto 0x00fe + +/* Transmission Space + */ +#define HC_REG_Hpara0 0x0040 +#define HC_REG_HpataAF 0x02fc + +/* Read + */ +#define HC_REG_HREngSt 0x0000 +#define HC_REG_HRFIFOempty 0x0004 +#define HC_REG_HRFIFOfull 0x0008 +#define HC_REG_HRErr 0x000c +#define HC_REG_FIFOstatus 0x0010 +/* HC_REG_HREngSt 0x0000 + */ +#define HC_HDASZC_MASK 0x00010000 +#define HC_HSGEMI_MASK 0x0000f000 +#define HC_HLGEMISt_MASK 0x00000f00 +#define HC_HCRSt_MASK 0x00000080 +#define HC_HSE0St_MASK 0x00000040 +#define HC_HSE1St_MASK 0x00000020 +#define HC_HPESt_MASK 0x00000010 +#define HC_HXESt_MASK 0x00000008 +#define HC_HBESt_MASK 0x00000004 +#define HC_HE2St_MASK 0x00000002 +#define HC_HE3St_MASK 0x00000001 +/* HC_REG_HRFIFOempty 0x0004 + */ +#define HC_HRZDempty_MASK 0x00000010 +#define HC_HRTXAempty_MASK 0x00000008 +#define HC_HRTXDempty_MASK 0x00000004 +#define HC_HWZDempty_MASK 0x00000002 +#define HC_HWCDempty_MASK 0x00000001 +/* HC_REG_HRFIFOfull 0x0008 + */ +#define HC_HRZDfull_MASK 0x00000010 +#define HC_HRTXAfull_MASK 0x00000008 +#define HC_HRTXDfull_MASK 0x00000004 +#define HC_HWZDfull_MASK 0x00000002 +#define HC_HWCDfull_MASK 0x00000001 +/* HC_REG_HRErr 0x000c + */ +#define HC_HAGPCMErr_MASK 0x80000000 +#define HC_HAGPCMErrC_MASK 0x70000000 +/* HC_REG_FIFOstatus 0x0010 + */ +#define HC_HRFIFOATall_MASK 0x80000000 +#define HC_HRFIFOATbusy_MASK 0x40000000 +#define HC_HRATFGMDo_MASK 0x00000100 +#define HC_HRATFGMDi_MASK 0x00000080 +#define HC_HRATFRZD_MASK 0x00000040 +#define HC_HRATFRTXA_MASK 0x00000020 +#define HC_HRATFRTXD_MASK 0x00000010 +#define HC_HRATFWZD_MASK 0x00000008 +#define HC_HRATFWCD_MASK 0x00000004 +#define HC_HRATTXTAG_MASK 0x00000002 +#define HC_HRATTXCH_MASK 0x00000001 + +/* AGP Command Setting + */ +#define HC_SubA_HAGPBstL 0x0060 +#define HC_SubA_HAGPBendL 0x0061 +#define HC_SubA_HAGPCMNT 0x0062 +#define HC_SubA_HAGPBpL 0x0063 +#define HC_SubA_HAGPBpH 0x0064 +/* HC_SubA_HAGPCMNT 0x0062 + */ +#define HC_HAGPCMNT_MASK 0x00800000 +#define HC_HCmdErrClr_MASK 0x00400000 +#define HC_HAGPBendH_MASK 0x0000ff00 +#define HC_HAGPBstH_MASK 0x000000ff +#define HC_HAGPBendH_SHIFT 8 +#define HC_HAGPBstH_SHIFT 0 +/* HC_SubA_HAGPBpL 0x0063 + */ +#define HC_HAGPBpL_MASK 0x00fffffc +#define HC_HAGPBpID_MASK 0x00000003 +#define HC_HAGPBpID_PAUSE 0x00000000 +#define HC_HAGPBpID_JUMP 0x00000001 +#define HC_HAGPBpID_STOP 0x00000002 +/* HC_SubA_HAGPBpH 0x0064 + */ +#define HC_HAGPBpH_MASK 0x00ffffff + +/* Miscellaneous Settings + */ +#define HC_SubA_HClipTB 0x0070 +#define HC_SubA_HClipLR 0x0071 +#define HC_SubA_HFPClipTL 0x0072 +#define HC_SubA_HFPClipBL 0x0073 +#define HC_SubA_HFPClipLL 0x0074 +#define HC_SubA_HFPClipRL 0x0075 +#define HC_SubA_HFPClipTBH 0x0076 +#define HC_SubA_HFPClipLRH 0x0077 +#define HC_SubA_HLP 0x0078 +#define HC_SubA_HLPRF 0x0079 +#define HC_SubA_HSolidCL 0x007a +#define HC_SubA_HPixGC 0x007b +#define HC_SubA_HSPXYOS 0x007c +#define HC_SubA_HVertexCNT 0x007d + +#define HC_HClipT_MASK 0x00fff000 +#define HC_HClipT_SHIFT 12 +#define HC_HClipB_MASK 0x00000fff +#define HC_HClipB_SHIFT 0 +#define HC_HClipL_MASK 0x00fff000 +#define HC_HClipL_SHIFT 12 +#define HC_HClipR_MASK 0x00000fff +#define HC_HClipR_SHIFT 0 +#define HC_HFPClipBH_MASK 0x0000ff00 +#define HC_HFPClipBH_SHIFT 8 +#define HC_HFPClipTH_MASK 0x000000ff +#define HC_HFPClipTH_SHIFT 0 +#define HC_HFPClipRH_MASK 0x0000ff00 +#define HC_HFPClipRH_SHIFT 8 +#define HC_HFPClipLH_MASK 0x000000ff +#define HC_HFPClipLH_SHIFT 0 +#define HC_HSolidCH_MASK 0x000000ff +#define HC_HPixGC_MASK 0x00800000 +#define HC_HSPXOS_MASK 0x00fff000 +#define HC_HSPXOS_SHIFT 12 +#define HC_HSPYOS_MASK 0x00000fff + +/* Command + * Command A + */ +#define HC_HCmdHeader_MASK 0xfe000000 /*0xffe00000 */ +#define HC_HE3Fire_MASK 0x00100000 +#define HC_HPMType_MASK 0x000f0000 +#define HC_HEFlag_MASK 0x0000e000 +#define HC_HShading_MASK 0x00001c00 +#define HC_HPMValidN_MASK 0x00000200 +#define HC_HPLEND_MASK 0x00000100 +#define HC_HVCycle_MASK 0x000000ff +#define HC_HVCycle_Style_MASK 0x000000c0 +#define HC_HVCycle_ChgA_MASK 0x00000030 +#define HC_HVCycle_ChgB_MASK 0x0000000c +#define HC_HVCycle_ChgC_MASK 0x00000003 +#define HC_HPMType_Point 0x00000000 +#define HC_HPMType_Line 0x00010000 +#define HC_HPMType_Tri 0x00020000 +#define HC_HPMType_TriWF 0x00040000 +#define HC_HEFlag_NoAA 0x00000000 +#define HC_HEFlag_ab 0x00008000 +#define HC_HEFlag_bc 0x00004000 +#define HC_HEFlag_ca 0x00002000 +#define HC_HShading_Solid 0x00000000 +#define HC_HShading_FlatA 0x00000400 +#define HC_HShading_FlatB 0x00000800 +#define HC_HShading_FlatC 0x00000c00 +#define HC_HShading_Gouraud 0x00001000 +#define HC_HVCycle_Full 0x00000000 +#define HC_HVCycle_AFP 0x00000040 +#define HC_HVCycle_One 0x000000c0 +#define HC_HVCycle_NewA 0x00000000 +#define HC_HVCycle_AA 0x00000010 +#define HC_HVCycle_AB 0x00000020 +#define HC_HVCycle_AC 0x00000030 +#define HC_HVCycle_NewB 0x00000000 +#define HC_HVCycle_BA 0x00000004 +#define HC_HVCycle_BB 0x00000008 +#define HC_HVCycle_BC 0x0000000c +#define HC_HVCycle_NewC 0x00000000 +#define HC_HVCycle_CA 0x00000001 +#define HC_HVCycle_CB 0x00000002 +#define HC_HVCycle_CC 0x00000003 + +/* Command B + */ +#define HC_HLPrst_MASK 0x00010000 +#define HC_HLLastP_MASK 0x00008000 +#define HC_HVPMSK_MASK 0x00007f80 +#define HC_HBFace_MASK 0x00000040 +#define HC_H2nd1VT_MASK 0x0000003f +#define HC_HVPMSK_X 0x00004000 +#define HC_HVPMSK_Y 0x00002000 +#define HC_HVPMSK_Z 0x00001000 +#define HC_HVPMSK_W 0x00000800 +#define HC_HVPMSK_Cd 0x00000400 +#define HC_HVPMSK_Cs 0x00000200 +#define HC_HVPMSK_S 0x00000100 +#define HC_HVPMSK_T 0x00000080 + +/* Enable Setting + */ +#define HC_SubA_HEnable 0x0000 +#define HC_HenTXEnvMap_MASK 0x00200000 +#define HC_HenVertexCNT_MASK 0x00100000 +#define HC_HenCPUDAZ_MASK 0x00080000 +#define HC_HenDASZWC_MASK 0x00040000 +#define HC_HenFBCull_MASK 0x00020000 +#define HC_HenCW_MASK 0x00010000 +#define HC_HenAA_MASK 0x00008000 +#define HC_HenST_MASK 0x00004000 +#define HC_HenZT_MASK 0x00002000 +#define HC_HenZW_MASK 0x00001000 +#define HC_HenAT_MASK 0x00000800 +#define HC_HenAW_MASK 0x00000400 +#define HC_HenSP_MASK 0x00000200 +#define HC_HenLP_MASK 0x00000100 +#define HC_HenTXCH_MASK 0x00000080 +#define HC_HenTXMP_MASK 0x00000040 +#define HC_HenTXPP_MASK 0x00000020 +#define HC_HenTXTR_MASK 0x00000010 +#define HC_HenCS_MASK 0x00000008 +#define HC_HenFOG_MASK 0x00000004 +#define HC_HenABL_MASK 0x00000002 +#define HC_HenDT_MASK 0x00000001 + +/* Z Setting + */ +#define HC_SubA_HZWBBasL 0x0010 +#define HC_SubA_HZWBBasH 0x0011 +#define HC_SubA_HZWBType 0x0012 +#define HC_SubA_HZBiasL 0x0013 +#define HC_SubA_HZWBend 0x0014 +#define HC_SubA_HZWTMD 0x0015 +#define HC_SubA_HZWCDL 0x0016 +#define HC_SubA_HZWCTAGnum 0x0017 +#define HC_SubA_HZCYNum 0x0018 +#define HC_SubA_HZWCFire 0x0019 +/* HC_SubA_HZWBType + */ +#define HC_HZWBType_MASK 0x00800000 +#define HC_HZBiasedWB_MASK 0x00400000 +#define HC_HZONEasFF_MASK 0x00200000 +#define HC_HZOONEasFF_MASK 0x00100000 +#define HC_HZWBFM_MASK 0x00030000 +#define HC_HZWBLoc_MASK 0x0000c000 +#define HC_HZWBPit_MASK 0x00003fff +#define HC_HZWBFM_16 0x00000000 +#define HC_HZWBFM_32 0x00020000 +#define HC_HZWBFM_24 0x00030000 +#define HC_HZWBLoc_Local 0x00000000 +#define HC_HZWBLoc_SyS 0x00004000 +/* HC_SubA_HZWBend + */ +#define HC_HZWBend_MASK 0x00ffe000 +#define HC_HZBiasH_MASK 0x000000ff +#define HC_HZWBend_SHIFT 10 +/* HC_SubA_HZWTMD + */ +#define HC_HZWTMD_MASK 0x00070000 +#define HC_HEBEBias_MASK 0x00007f00 +#define HC_HZNF_MASK 0x000000ff +#define HC_HZWTMD_NeverPass 0x00000000 +#define HC_HZWTMD_LT 0x00010000 +#define HC_HZWTMD_EQ 0x00020000 +#define HC_HZWTMD_LE 0x00030000 +#define HC_HZWTMD_GT 0x00040000 +#define HC_HZWTMD_NE 0x00050000 +#define HC_HZWTMD_GE 0x00060000 +#define HC_HZWTMD_AllPass 0x00070000 +#define HC_HEBEBias_SHIFT 8 +/* HC_SubA_HZWCDL 0x0016 + */ +#define HC_HZWCDL_MASK 0x00ffffff +/* HC_SubA_HZWCTAGnum 0x0017 + */ +#define HC_HZWCTAGnum_MASK 0x00ff0000 +#define HC_HZWCTAGnum_SHIFT 16 +#define HC_HZWCDH_MASK 0x000000ff +#define HC_HZWCDH_SHIFT 0 +/* HC_SubA_HZCYNum 0x0018 + */ +#define HC_HZCYNum_MASK 0x00030000 +#define HC_HZCYNum_SHIFT 16 +#define HC_HZWCQWnum_MASK 0x00003fff +#define HC_HZWCQWnum_SHIFT 0 +/* HC_SubA_HZWCFire 0x0019 + */ +#define HC_ZWCFire_MASK 0x00010000 +#define HC_HZWCQWnumLast_MASK 0x00003fff +#define HC_HZWCQWnumLast_SHIFT 0 + +/* Stencil Setting + */ +#define HC_SubA_HSTREF 0x0023 +#define HC_SubA_HSTMD 0x0024 +/* HC_SubA_HSBFM + */ +#define HC_HSBFM_MASK 0x00030000 +#define HC_HSBLoc_MASK 0x0000c000 +#define HC_HSBPit_MASK 0x00003fff +/* HC_SubA_HSTREF + */ +#define HC_HSTREF_MASK 0x00ff0000 +#define HC_HSTOPMSK_MASK 0x0000ff00 +#define HC_HSTBMSK_MASK 0x000000ff +#define HC_HSTREF_SHIFT 16 +#define HC_HSTOPMSK_SHIFT 8 +/* HC_SubA_HSTMD + */ +#define HC_HSTMD_MASK 0x00070000 +#define HC_HSTOPSF_MASK 0x000001c0 +#define HC_HSTOPSPZF_MASK 0x00000038 +#define HC_HSTOPSPZP_MASK 0x00000007 +#define HC_HSTMD_NeverPass 0x00000000 +#define HC_HSTMD_LT 0x00010000 +#define HC_HSTMD_EQ 0x00020000 +#define HC_HSTMD_LE 0x00030000 +#define HC_HSTMD_GT 0x00040000 +#define HC_HSTMD_NE 0x00050000 +#define HC_HSTMD_GE 0x00060000 +#define HC_HSTMD_AllPass 0x00070000 +#define HC_HSTOPSF_KEEP 0x00000000 +#define HC_HSTOPSF_ZERO 0x00000040 +#define HC_HSTOPSF_REPLACE 0x00000080 +#define HC_HSTOPSF_INCRSAT 0x000000c0 +#define HC_HSTOPSF_DECRSAT 0x00000100 +#define HC_HSTOPSF_INVERT 0x00000140 +#define HC_HSTOPSF_INCR 0x00000180 +#define HC_HSTOPSF_DECR 0x000001c0 +#define HC_HSTOPSPZF_KEEP 0x00000000 +#define HC_HSTOPSPZF_ZERO 0x00000008 +#define HC_HSTOPSPZF_REPLACE 0x00000010 +#define HC_HSTOPSPZF_INCRSAT 0x00000018 +#define HC_HSTOPSPZF_DECRSAT 0x00000020 +#define HC_HSTOPSPZF_INVERT 0x00000028 +#define HC_HSTOPSPZF_INCR 0x00000030 +#define HC_HSTOPSPZF_DECR 0x00000038 +#define HC_HSTOPSPZP_KEEP 0x00000000 +#define HC_HSTOPSPZP_ZERO 0x00000001 +#define HC_HSTOPSPZP_REPLACE 0x00000002 +#define HC_HSTOPSPZP_INCRSAT 0x00000003 +#define HC_HSTOPSPZP_DECRSAT 0x00000004 +#define HC_HSTOPSPZP_INVERT 0x00000005 +#define HC_HSTOPSPZP_INCR 0x00000006 +#define HC_HSTOPSPZP_DECR 0x00000007 + +/* Alpha Setting + */ +#define HC_SubA_HABBasL 0x0030 +#define HC_SubA_HABBasH 0x0031 +#define HC_SubA_HABFM 0x0032 +#define HC_SubA_HATMD 0x0033 +#define HC_SubA_HABLCsat 0x0034 +#define HC_SubA_HABLCop 0x0035 +#define HC_SubA_HABLAsat 0x0036 +#define HC_SubA_HABLAop 0x0037 +#define HC_SubA_HABLRCa 0x0038 +#define HC_SubA_HABLRFCa 0x0039 +#define HC_SubA_HABLRCbias 0x003a +#define HC_SubA_HABLRCb 0x003b +#define HC_SubA_HABLRFCb 0x003c +#define HC_SubA_HABLRAa 0x003d +#define HC_SubA_HABLRAb 0x003e +/* HC_SubA_HABFM + */ +#define HC_HABFM_MASK 0x00030000 +#define HC_HABLoc_MASK 0x0000c000 +#define HC_HABPit_MASK 0x000007ff +/* HC_SubA_HATMD + */ +#define HC_HATMD_MASK 0x00000700 +#define HC_HATREF_MASK 0x000000ff +#define HC_HATMD_NeverPass 0x00000000 +#define HC_HATMD_LT 0x00000100 +#define HC_HATMD_EQ 0x00000200 +#define HC_HATMD_LE 0x00000300 +#define HC_HATMD_GT 0x00000400 +#define HC_HATMD_NE 0x00000500 +#define HC_HATMD_GE 0x00000600 +#define HC_HATMD_AllPass 0x00000700 +/* HC_SubA_HABLCsat + */ +#define HC_HABLCsat_MASK 0x00010000 +#define HC_HABLCa_MASK 0x0000fc00 +#define HC_HABLCa_C_MASK 0x0000c000 +#define HC_HABLCa_OPC_MASK 0x00003c00 +#define HC_HABLFCa_MASK 0x000003f0 +#define HC_HABLFCa_C_MASK 0x00000300 +#define HC_HABLFCa_OPC_MASK 0x000000f0 +#define HC_HABLCbias_MASK 0x0000000f +#define HC_HABLCbias_C_MASK 0x00000008 +#define HC_HABLCbias_OPC_MASK 0x00000007 +/*-- Define the input color. + */ +#define HC_XC_Csrc 0x00000000 +#define HC_XC_Cdst 0x00000001 +#define HC_XC_Asrc 0x00000002 +#define HC_XC_Adst 0x00000003 +#define HC_XC_Fog 0x00000004 +#define HC_XC_HABLRC 0x00000005 +#define HC_XC_minSrcDst 0x00000006 +#define HC_XC_maxSrcDst 0x00000007 +#define HC_XC_mimAsrcInvAdst 0x00000008 +#define HC_XC_OPC 0x00000000 +#define HC_XC_InvOPC 0x00000010 +#define HC_XC_OPCp5 0x00000020 +/*-- Define the input Alpha + */ +#define HC_XA_OPA 0x00000000 +#define HC_XA_InvOPA 0x00000010 +#define HC_XA_OPAp5 0x00000020 +#define HC_XA_0 0x00000000 +#define HC_XA_Asrc 0x00000001 +#define HC_XA_Adst 0x00000002 +#define HC_XA_Fog 0x00000003 +#define HC_XA_minAsrcFog 0x00000004 +#define HC_XA_minAsrcAdst 0x00000005 +#define HC_XA_maxAsrcFog 0x00000006 +#define HC_XA_maxAsrcAdst 0x00000007 +#define HC_XA_HABLRA 0x00000008 +#define HC_XA_minAsrcInvAdst 0x00000008 +#define HC_XA_HABLFRA 0x00000009 +/*-- + */ +#define HC_HABLCa_OPC (HC_XC_OPC << 10) +#define HC_HABLCa_InvOPC (HC_XC_InvOPC << 10) +#define HC_HABLCa_OPCp5 (HC_XC_OPCp5 << 10) +#define HC_HABLCa_Csrc (HC_XC_Csrc << 10) +#define HC_HABLCa_Cdst (HC_XC_Cdst << 10) +#define HC_HABLCa_Asrc (HC_XC_Asrc << 10) +#define HC_HABLCa_Adst (HC_XC_Adst << 10) +#define HC_HABLCa_Fog (HC_XC_Fog << 10) +#define HC_HABLCa_HABLRCa (HC_XC_HABLRC << 10) +#define HC_HABLCa_minSrcDst (HC_XC_minSrcDst << 10) +#define HC_HABLCa_maxSrcDst (HC_XC_maxSrcDst << 10) +#define HC_HABLFCa_OPC (HC_XC_OPC << 4) +#define HC_HABLFCa_InvOPC (HC_XC_InvOPC << 4) +#define HC_HABLFCa_OPCp5 (HC_XC_OPCp5 << 4) +#define HC_HABLFCa_Csrc (HC_XC_Csrc << 4) +#define HC_HABLFCa_Cdst (HC_XC_Cdst << 4) +#define HC_HABLFCa_Asrc (HC_XC_Asrc << 4) +#define HC_HABLFCa_Adst (HC_XC_Adst << 4) +#define HC_HABLFCa_Fog (HC_XC_Fog << 4) +#define HC_HABLFCa_HABLRCa (HC_XC_HABLRC << 4) +#define HC_HABLFCa_minSrcDst (HC_XC_minSrcDst << 4) +#define HC_HABLFCa_maxSrcDst (HC_XC_maxSrcDst << 4) +#define HC_HABLFCa_mimAsrcInvAdst (HC_XC_mimAsrcInvAdst << 4) +#define HC_HABLCbias_HABLRCbias 0x00000000 +#define HC_HABLCbias_Asrc 0x00000001 +#define HC_HABLCbias_Adst 0x00000002 +#define HC_HABLCbias_Fog 0x00000003 +#define HC_HABLCbias_Cin 0x00000004 +/* HC_SubA_HABLCop 0x0035 + */ +#define HC_HABLdot_MASK 0x00010000 +#define HC_HABLCop_MASK 0x00004000 +#define HC_HABLCb_MASK 0x00003f00 +#define HC_HABLCb_C_MASK 0x00003000 +#define HC_HABLCb_OPC_MASK 0x00000f00 +#define HC_HABLFCb_MASK 0x000000fc +#define HC_HABLFCb_C_MASK 0x000000c0 +#define HC_HABLFCb_OPC_MASK 0x0000003c +#define HC_HABLCshift_MASK 0x00000003 +#define HC_HABLCb_OPC (HC_XC_OPC << 8) +#define HC_HABLCb_InvOPC (HC_XC_InvOPC << 8) +#define HC_HABLCb_OPCp5 (HC_XC_OPCp5 << 8) +#define HC_HABLCb_Csrc (HC_XC_Csrc << 8) +#define HC_HABLCb_Cdst (HC_XC_Cdst << 8) +#define HC_HABLCb_Asrc (HC_XC_Asrc << 8) +#define HC_HABLCb_Adst (HC_XC_Adst << 8) +#define HC_HABLCb_Fog (HC_XC_Fog << 8) +#define HC_HABLCb_HABLRCa (HC_XC_HABLRC << 8) +#define HC_HABLCb_minSrcDst (HC_XC_minSrcDst << 8) +#define HC_HABLCb_maxSrcDst (HC_XC_maxSrcDst << 8) +#define HC_HABLFCb_OPC (HC_XC_OPC << 2) +#define HC_HABLFCb_InvOPC (HC_XC_InvOPC << 2) +#define HC_HABLFCb_OPCp5 (HC_XC_OPCp5 << 2) +#define HC_HABLFCb_Csrc (HC_XC_Csrc << 2) +#define HC_HABLFCb_Cdst (HC_XC_Cdst << 2) +#define HC_HABLFCb_Asrc (HC_XC_Asrc << 2) +#define HC_HABLFCb_Adst (HC_XC_Adst << 2) +#define HC_HABLFCb_Fog (HC_XC_Fog << 2) +#define HC_HABLFCb_HABLRCb (HC_XC_HABLRC << 2) +#define HC_HABLFCb_minSrcDst (HC_XC_minSrcDst << 2) +#define HC_HABLFCb_maxSrcDst (HC_XC_maxSrcDst << 2) +#define HC_HABLFCb_mimAsrcInvAdst (HC_XC_mimAsrcInvAdst << 2) +/* HC_SubA_HABLAsat 0x0036 + */ +#define HC_HABLAsat_MASK 0x00010000 +#define HC_HABLAa_MASK 0x0000fc00 +#define HC_HABLAa_A_MASK 0x0000c000 +#define HC_HABLAa_OPA_MASK 0x00003c00 +#define HC_HABLFAa_MASK 0x000003f0 +#define HC_HABLFAa_A_MASK 0x00000300 +#define HC_HABLFAa_OPA_MASK 0x000000f0 +#define HC_HABLAbias_MASK 0x0000000f +#define HC_HABLAbias_A_MASK 0x00000008 +#define HC_HABLAbias_OPA_MASK 0x00000007 +#define HC_HABLAa_OPA (HC_XA_OPA << 10) +#define HC_HABLAa_InvOPA (HC_XA_InvOPA << 10) +#define HC_HABLAa_OPAp5 (HC_XA_OPAp5 << 10) +#define HC_HABLAa_0 (HC_XA_0 << 10) +#define HC_HABLAa_Asrc (HC_XA_Asrc << 10) +#define HC_HABLAa_Adst (HC_XA_Adst << 10) +#define HC_HABLAa_Fog (HC_XA_Fog << 10) +#define HC_HABLAa_minAsrcFog (HC_XA_minAsrcFog << 10) +#define HC_HABLAa_minAsrcAdst (HC_XA_minAsrcAdst << 10) +#define HC_HABLAa_maxAsrcFog (HC_XA_maxAsrcFog << 10) +#define HC_HABLAa_maxAsrcAdst (HC_XA_maxAsrcAdst << 10) +#define HC_HABLAa_HABLRA (HC_XA_HABLRA << 10) +#define HC_HABLFAa_OPA (HC_XA_OPA << 4) +#define HC_HABLFAa_InvOPA (HC_XA_InvOPA << 4) +#define HC_HABLFAa_OPAp5 (HC_XA_OPAp5 << 4) +#define HC_HABLFAa_0 (HC_XA_0 << 4) +#define HC_HABLFAa_Asrc (HC_XA_Asrc << 4) +#define HC_HABLFAa_Adst (HC_XA_Adst << 4) +#define HC_HABLFAa_Fog (HC_XA_Fog << 4) +#define HC_HABLFAa_minAsrcFog (HC_XA_minAsrcFog << 4) +#define HC_HABLFAa_minAsrcAdst (HC_XA_minAsrcAdst << 4) +#define HC_HABLFAa_maxAsrcFog (HC_XA_maxAsrcFog << 4) +#define HC_HABLFAa_maxAsrcAdst (HC_XA_maxAsrcAdst << 4) +#define HC_HABLFAa_minAsrcInvAdst (HC_XA_minAsrcInvAdst << 4) +#define HC_HABLFAa_HABLFRA (HC_XA_HABLFRA << 4) +#define HC_HABLAbias_HABLRAbias 0x00000000 +#define HC_HABLAbias_Asrc 0x00000001 +#define HC_HABLAbias_Adst 0x00000002 +#define HC_HABLAbias_Fog 0x00000003 +#define HC_HABLAbias_Aaa 0x00000004 +/* HC_SubA_HABLAop 0x0037 + */ +#define HC_HABLAop_MASK 0x00004000 +#define HC_HABLAb_MASK 0x00003f00 +#define HC_HABLAb_OPA_MASK 0x00000f00 +#define HC_HABLFAb_MASK 0x000000fc +#define HC_HABLFAb_OPA_MASK 0x0000003c +#define HC_HABLAshift_MASK 0x00000003 +#define HC_HABLAb_OPA (HC_XA_OPA << 8) +#define HC_HABLAb_InvOPA (HC_XA_InvOPA << 8) +#define HC_HABLAb_OPAp5 (HC_XA_OPAp5 << 8) +#define HC_HABLAb_0 (HC_XA_0 << 8) +#define HC_HABLAb_Asrc (HC_XA_Asrc << 8) +#define HC_HABLAb_Adst (HC_XA_Adst << 8) +#define HC_HABLAb_Fog (HC_XA_Fog << 8) +#define HC_HABLAb_minAsrcFog (HC_XA_minAsrcFog << 8) +#define HC_HABLAb_minAsrcAdst (HC_XA_minAsrcAdst << 8) +#define HC_HABLAb_maxAsrcFog (HC_XA_maxAsrcFog << 8) +#define HC_HABLAb_maxAsrcAdst (HC_XA_maxAsrcAdst << 8) +#define HC_HABLAb_HABLRA (HC_XA_HABLRA << 8) +#define HC_HABLFAb_OPA (HC_XA_OPA << 2) +#define HC_HABLFAb_InvOPA (HC_XA_InvOPA << 2) +#define HC_HABLFAb_OPAp5 (HC_XA_OPAp5 << 2) +#define HC_HABLFAb_0 (HC_XA_0 << 2) +#define HC_HABLFAb_Asrc (HC_XA_Asrc << 2) +#define HC_HABLFAb_Adst (HC_XA_Adst << 2) +#define HC_HABLFAb_Fog (HC_XA_Fog << 2) +#define HC_HABLFAb_minAsrcFog (HC_XA_minAsrcFog << 2) +#define HC_HABLFAb_minAsrcAdst (HC_XA_minAsrcAdst << 2) +#define HC_HABLFAb_maxAsrcFog (HC_XA_maxAsrcFog << 2) +#define HC_HABLFAb_maxAsrcAdst (HC_XA_maxAsrcAdst << 2) +#define HC_HABLFAb_minAsrcInvAdst (HC_XA_minAsrcInvAdst << 2) +#define HC_HABLFAb_HABLFRA (HC_XA_HABLFRA << 2) +/* HC_SubA_HABLRAa 0x003d + */ +#define HC_HABLRAa_MASK 0x00ff0000 +#define HC_HABLRFAa_MASK 0x0000ff00 +#define HC_HABLRAbias_MASK 0x000000ff +#define HC_HABLRAa_SHIFT 16 +#define HC_HABLRFAa_SHIFT 8 +/* HC_SubA_HABLRAb 0x003e + */ +#define HC_HABLRAb_MASK 0x0000ff00 +#define HC_HABLRFAb_MASK 0x000000ff +#define HC_HABLRAb_SHIFT 8 + +/* Destination Setting + */ +#define HC_SubA_HDBBasL 0x0040 +#define HC_SubA_HDBBasH 0x0041 +#define HC_SubA_HDBFM 0x0042 +#define HC_SubA_HFBBMSKL 0x0043 +#define HC_SubA_HROP 0x0044 +/* HC_SubA_HDBFM 0x0042 + */ +#define HC_HDBFM_MASK 0x001f0000 +#define HC_HDBLoc_MASK 0x0000c000 +#define HC_HDBPit_MASK 0x00003fff +#define HC_HDBFM_RGB555 0x00000000 +#define HC_HDBFM_RGB565 0x00010000 +#define HC_HDBFM_ARGB4444 0x00020000 +#define HC_HDBFM_ARGB1555 0x00030000 +#define HC_HDBFM_BGR555 0x00040000 +#define HC_HDBFM_BGR565 0x00050000 +#define HC_HDBFM_ABGR4444 0x00060000 +#define HC_HDBFM_ABGR1555 0x00070000 +#define HC_HDBFM_ARGB0888 0x00080000 +#define HC_HDBFM_ARGB8888 0x00090000 +#define HC_HDBFM_ABGR0888 0x000a0000 +#define HC_HDBFM_ABGR8888 0x000b0000 +#define HC_HDBLoc_Local 0x00000000 +#define HC_HDBLoc_Sys 0x00004000 +/* HC_SubA_HROP 0x0044 + */ +#define HC_HROP_MASK 0x00000f00 +#define HC_HFBBMSKH_MASK 0x000000ff +#define HC_HROP_BLACK 0x00000000 +#define HC_HROP_DPon 0x00000100 +#define HC_HROP_DPna 0x00000200 +#define HC_HROP_Pn 0x00000300 +#define HC_HROP_PDna 0x00000400 +#define HC_HROP_Dn 0x00000500 +#define HC_HROP_DPx 0x00000600 +#define HC_HROP_DPan 0x00000700 +#define HC_HROP_DPa 0x00000800 +#define HC_HROP_DPxn 0x00000900 +#define HC_HROP_D 0x00000a00 +#define HC_HROP_DPno 0x00000b00 +#define HC_HROP_P 0x00000c00 +#define HC_HROP_PDno 0x00000d00 +#define HC_HROP_DPo 0x00000e00 +#define HC_HROP_WHITE 0x00000f00 + +/* Fog Setting + */ +#define HC_SubA_HFogLF 0x0050 +#define HC_SubA_HFogCL 0x0051 +#define HC_SubA_HFogCH 0x0052 +#define HC_SubA_HFogStL 0x0053 +#define HC_SubA_HFogStH 0x0054 +#define HC_SubA_HFogOOdMF 0x0055 +#define HC_SubA_HFogOOdEF 0x0056 +#define HC_SubA_HFogEndL 0x0057 +#define HC_SubA_HFogDenst 0x0058 +/* HC_SubA_FogLF 0x0050 + */ +#define HC_FogLF_MASK 0x00000010 +#define HC_FogEq_MASK 0x00000008 +#define HC_FogMD_MASK 0x00000007 +#define HC_FogMD_LocalFog 0x00000000 +#define HC_FogMD_LinearFog 0x00000002 +#define HC_FogMD_ExponentialFog 0x00000004 +#define HC_FogMD_Exponential2Fog 0x00000005 +/* #define HC_FogMD_FogTable 0x00000003 */ + +/* HC_SubA_HFogDenst 0x0058 + */ +#define HC_FogDenst_MASK 0x001fff00 +#define HC_FogEndL_MASK 0x000000ff + +/* Texture subtype definitions + */ +#define HC_SubType_Tex0 0x00000000 +#define HC_SubType_Tex1 0x00000001 +#define HC_SubType_TexGeneral 0x000000fe + +/* Attribute of texture n + */ +#define HC_SubA_HTXnL0BasL 0x0000 +#define HC_SubA_HTXnL1BasL 0x0001 +#define HC_SubA_HTXnL2BasL 0x0002 +#define HC_SubA_HTXnL3BasL 0x0003 +#define HC_SubA_HTXnL4BasL 0x0004 +#define HC_SubA_HTXnL5BasL 0x0005 +#define HC_SubA_HTXnL6BasL 0x0006 +#define HC_SubA_HTXnL7BasL 0x0007 +#define HC_SubA_HTXnL8BasL 0x0008 +#define HC_SubA_HTXnL9BasL 0x0009 +#define HC_SubA_HTXnLaBasL 0x000a +#define HC_SubA_HTXnLbBasL 0x000b +#define HC_SubA_HTXnLcBasL 0x000c +#define HC_SubA_HTXnLdBasL 0x000d +#define HC_SubA_HTXnLeBasL 0x000e +#define HC_SubA_HTXnLfBasL 0x000f +#define HC_SubA_HTXnL10BasL 0x0010 +#define HC_SubA_HTXnL11BasL 0x0011 +#define HC_SubA_HTXnL012BasH 0x0020 +#define HC_SubA_HTXnL345BasH 0x0021 +#define HC_SubA_HTXnL678BasH 0x0022 +#define HC_SubA_HTXnL9abBasH 0x0023 +#define HC_SubA_HTXnLcdeBasH 0x0024 +#define HC_SubA_HTXnLf1011BasH 0x0025 +#define HC_SubA_HTXnL0Pit 0x002b +#define HC_SubA_HTXnL1Pit 0x002c +#define HC_SubA_HTXnL2Pit 0x002d +#define HC_SubA_HTXnL3Pit 0x002e +#define HC_SubA_HTXnL4Pit 0x002f +#define HC_SubA_HTXnL5Pit 0x0030 +#define HC_SubA_HTXnL6Pit 0x0031 +#define HC_SubA_HTXnL7Pit 0x0032 +#define HC_SubA_HTXnL8Pit 0x0033 +#define HC_SubA_HTXnL9Pit 0x0034 +#define HC_SubA_HTXnLaPit 0x0035 +#define HC_SubA_HTXnLbPit 0x0036 +#define HC_SubA_HTXnLcPit 0x0037 +#define HC_SubA_HTXnLdPit 0x0038 +#define HC_SubA_HTXnLePit 0x0039 +#define HC_SubA_HTXnLfPit 0x003a +#define HC_SubA_HTXnL10Pit 0x003b +#define HC_SubA_HTXnL11Pit 0x003c +#define HC_SubA_HTXnL0_5WE 0x004b +#define HC_SubA_HTXnL6_bWE 0x004c +#define HC_SubA_HTXnLc_11WE 0x004d +#define HC_SubA_HTXnL0_5HE 0x0051 +#define HC_SubA_HTXnL6_bHE 0x0052 +#define HC_SubA_HTXnLc_11HE 0x0053 +#define HC_SubA_HTXnL0OS 0x0077 +#define HC_SubA_HTXnTB 0x0078 +#define HC_SubA_HTXnMPMD 0x0079 +#define HC_SubA_HTXnCLODu 0x007a +#define HC_SubA_HTXnFM 0x007b +#define HC_SubA_HTXnTRCH 0x007c +#define HC_SubA_HTXnTRCL 0x007d +#define HC_SubA_HTXnTBC 0x007e +#define HC_SubA_HTXnTRAH 0x007f +#define HC_SubA_HTXnTBLCsat 0x0080 +#define HC_SubA_HTXnTBLCop 0x0081 +#define HC_SubA_HTXnTBLMPfog 0x0082 +#define HC_SubA_HTXnTBLAsat 0x0083 +#define HC_SubA_HTXnTBLRCa 0x0085 +#define HC_SubA_HTXnTBLRCb 0x0086 +#define HC_SubA_HTXnTBLRCc 0x0087 +#define HC_SubA_HTXnTBLRCbias 0x0088 +#define HC_SubA_HTXnTBLRAa 0x0089 +#define HC_SubA_HTXnTBLRFog 0x008a +#define HC_SubA_HTXnBumpM00 0x0090 +#define HC_SubA_HTXnBumpM01 0x0091 +#define HC_SubA_HTXnBumpM10 0x0092 +#define HC_SubA_HTXnBumpM11 0x0093 +#define HC_SubA_HTXnLScale 0x0094 +#define HC_SubA_HTXSMD 0x0000 +/* HC_SubA_HTXnL012BasH 0x0020 + */ +#define HC_HTXnL0BasH_MASK 0x000000ff +#define HC_HTXnL1BasH_MASK 0x0000ff00 +#define HC_HTXnL2BasH_MASK 0x00ff0000 +#define HC_HTXnL1BasH_SHIFT 8 +#define HC_HTXnL2BasH_SHIFT 16 +/* HC_SubA_HTXnL345BasH 0x0021 + */ +#define HC_HTXnL3BasH_MASK 0x000000ff +#define HC_HTXnL4BasH_MASK 0x0000ff00 +#define HC_HTXnL5BasH_MASK 0x00ff0000 +#define HC_HTXnL4BasH_SHIFT 8 +#define HC_HTXnL5BasH_SHIFT 16 +/* HC_SubA_HTXnL678BasH 0x0022 + */ +#define HC_HTXnL6BasH_MASK 0x000000ff +#define HC_HTXnL7BasH_MASK 0x0000ff00 +#define HC_HTXnL8BasH_MASK 0x00ff0000 +#define HC_HTXnL7BasH_SHIFT 8 +#define HC_HTXnL8BasH_SHIFT 16 +/* HC_SubA_HTXnL9abBasH 0x0023 + */ +#define HC_HTXnL9BasH_MASK 0x000000ff +#define HC_HTXnLaBasH_MASK 0x0000ff00 +#define HC_HTXnLbBasH_MASK 0x00ff0000 +#define HC_HTXnLaBasH_SHIFT 8 +#define HC_HTXnLbBasH_SHIFT 16 +/* HC_SubA_HTXnLcdeBasH 0x0024 + */ +#define HC_HTXnLcBasH_MASK 0x000000ff +#define HC_HTXnLdBasH_MASK 0x0000ff00 +#define HC_HTXnLeBasH_MASK 0x00ff0000 +#define HC_HTXnLdBasH_SHIFT 8 +#define HC_HTXnLeBasH_SHIFT 16 +/* HC_SubA_HTXnLcdeBasH 0x0025 + */ +#define HC_HTXnLfBasH_MASK 0x000000ff +#define HC_HTXnL10BasH_MASK 0x0000ff00 +#define HC_HTXnL11BasH_MASK 0x00ff0000 +#define HC_HTXnL10BasH_SHIFT 8 +#define HC_HTXnL11BasH_SHIFT 16 +/* HC_SubA_HTXnL0Pit 0x002b + */ +#define HC_HTXnLnPit_MASK 0x00003fff +#define HC_HTXnEnPit_MASK 0x00080000 +#define HC_HTXnLnPitE_MASK 0x00f00000 +#define HC_HTXnLnPitE_SHIFT 20 +/* HC_SubA_HTXnL0_5WE 0x004b + */ +#define HC_HTXnL0WE_MASK 0x0000000f +#define HC_HTXnL1WE_MASK 0x000000f0 +#define HC_HTXnL2WE_MASK 0x00000f00 +#define HC_HTXnL3WE_MASK 0x0000f000 +#define HC_HTXnL4WE_MASK 0x000f0000 +#define HC_HTXnL5WE_MASK 0x00f00000 +#define HC_HTXnL1WE_SHIFT 4 +#define HC_HTXnL2WE_SHIFT 8 +#define HC_HTXnL3WE_SHIFT 12 +#define HC_HTXnL4WE_SHIFT 16 +#define HC_HTXnL5WE_SHIFT 20 +/* HC_SubA_HTXnL6_bWE 0x004c + */ +#define HC_HTXnL6WE_MASK 0x0000000f +#define HC_HTXnL7WE_MASK 0x000000f0 +#define HC_HTXnL8WE_MASK 0x00000f00 +#define HC_HTXnL9WE_MASK 0x0000f000 +#define HC_HTXnLaWE_MASK 0x000f0000 +#define HC_HTXnLbWE_MASK 0x00f00000 +#define HC_HTXnL7WE_SHIFT 4 +#define HC_HTXnL8WE_SHIFT 8 +#define HC_HTXnL9WE_SHIFT 12 +#define HC_HTXnLaWE_SHIFT 16 +#define HC_HTXnLbWE_SHIFT 20 +/* HC_SubA_HTXnLc_11WE 0x004d + */ +#define HC_HTXnLcWE_MASK 0x0000000f +#define HC_HTXnLdWE_MASK 0x000000f0 +#define HC_HTXnLeWE_MASK 0x00000f00 +#define HC_HTXnLfWE_MASK 0x0000f000 +#define HC_HTXnL10WE_MASK 0x000f0000 +#define HC_HTXnL11WE_MASK 0x00f00000 +#define HC_HTXnLdWE_SHIFT 4 +#define HC_HTXnLeWE_SHIFT 8 +#define HC_HTXnLfWE_SHIFT 12 +#define HC_HTXnL10WE_SHIFT 16 +#define HC_HTXnL11WE_SHIFT 20 +/* HC_SubA_HTXnL0_5HE 0x0051 + */ +#define HC_HTXnL0HE_MASK 0x0000000f +#define HC_HTXnL1HE_MASK 0x000000f0 +#define HC_HTXnL2HE_MASK 0x00000f00 +#define HC_HTXnL3HE_MASK 0x0000f000 +#define HC_HTXnL4HE_MASK 0x000f0000 +#define HC_HTXnL5HE_MASK 0x00f00000 +#define HC_HTXnL1HE_SHIFT 4 +#define HC_HTXnL2HE_SHIFT 8 +#define HC_HTXnL3HE_SHIFT 12 +#define HC_HTXnL4HE_SHIFT 16 +#define HC_HTXnL5HE_SHIFT 20 +/* HC_SubA_HTXnL6_bHE 0x0052 + */ +#define HC_HTXnL6HE_MASK 0x0000000f +#define HC_HTXnL7HE_MASK 0x000000f0 +#define HC_HTXnL8HE_MASK 0x00000f00 +#define HC_HTXnL9HE_MASK 0x0000f000 +#define HC_HTXnLaHE_MASK 0x000f0000 +#define HC_HTXnLbHE_MASK 0x00f00000 +#define HC_HTXnL7HE_SHIFT 4 +#define HC_HTXnL8HE_SHIFT 8 +#define HC_HTXnL9HE_SHIFT 12 +#define HC_HTXnLaHE_SHIFT 16 +#define HC_HTXnLbHE_SHIFT 20 +/* HC_SubA_HTXnLc_11HE 0x0053 + */ +#define HC_HTXnLcHE_MASK 0x0000000f +#define HC_HTXnLdHE_MASK 0x000000f0 +#define HC_HTXnLeHE_MASK 0x00000f00 +#define HC_HTXnLfHE_MASK 0x0000f000 +#define HC_HTXnL10HE_MASK 0x000f0000 +#define HC_HTXnL11HE_MASK 0x00f00000 +#define HC_HTXnLdHE_SHIFT 4 +#define HC_HTXnLeHE_SHIFT 8 +#define HC_HTXnLfHE_SHIFT 12 +#define HC_HTXnL10HE_SHIFT 16 +#define HC_HTXnL11HE_SHIFT 20 +/* HC_SubA_HTXnL0OS 0x0077 + */ +#define HC_HTXnL0OS_MASK 0x003ff000 +#define HC_HTXnLVmax_MASK 0x00000fc0 +#define HC_HTXnLVmin_MASK 0x0000003f +#define HC_HTXnL0OS_SHIFT 12 +#define HC_HTXnLVmax_SHIFT 6 +/* HC_SubA_HTXnTB 0x0078 + */ +#define HC_HTXnTB_MASK 0x00f00000 +#define HC_HTXnFLSe_MASK 0x0000e000 +#define HC_HTXnFLSs_MASK 0x00001c00 +#define HC_HTXnFLTe_MASK 0x00000380 +#define HC_HTXnFLTs_MASK 0x00000070 +#define HC_HTXnFLDs_MASK 0x0000000f +#define HC_HTXnTB_NoTB 0x00000000 +#define HC_HTXnTB_TBC_S 0x00100000 +#define HC_HTXnTB_TBC_T 0x00200000 +#define HC_HTXnTB_TB_S 0x00400000 +#define HC_HTXnTB_TB_T 0x00800000 +#define HC_HTXnFLSe_Nearest 0x00000000 +#define HC_HTXnFLSe_Linear 0x00002000 +#define HC_HTXnFLSe_NonLinear 0x00004000 +#define HC_HTXnFLSe_Sharp 0x00008000 +#define HC_HTXnFLSe_Flat_Gaussian_Cubic 0x0000c000 +#define HC_HTXnFLSs_Nearest 0x00000000 +#define HC_HTXnFLSs_Linear 0x00000400 +#define HC_HTXnFLSs_NonLinear 0x00000800 +#define HC_HTXnFLSs_Flat_Gaussian_Cubic 0x00001800 +#define HC_HTXnFLTe_Nearest 0x00000000 +#define HC_HTXnFLTe_Linear 0x00000080 +#define HC_HTXnFLTe_NonLinear 0x00000100 +#define HC_HTXnFLTe_Sharp 0x00000180 +#define HC_HTXnFLTe_Flat_Gaussian_Cubic 0x00000300 +#define HC_HTXnFLTs_Nearest 0x00000000 +#define HC_HTXnFLTs_Linear 0x00000010 +#define HC_HTXnFLTs_NonLinear 0x00000020 +#define HC_HTXnFLTs_Flat_Gaussian_Cubic 0x00000060 +#define HC_HTXnFLDs_Tex0 0x00000000 +#define HC_HTXnFLDs_Nearest 0x00000001 +#define HC_HTXnFLDs_Linear 0x00000002 +#define HC_HTXnFLDs_NonLinear 0x00000003 +#define HC_HTXnFLDs_Dither 0x00000004 +#define HC_HTXnFLDs_ConstLOD 0x00000005 +#define HC_HTXnFLDs_Ani 0x00000006 +#define HC_HTXnFLDs_AniDither 0x00000007 +/* HC_SubA_HTXnMPMD 0x0079 + */ +#define HC_HTXnMPMD_SMASK 0x00070000 +#define HC_HTXnMPMD_TMASK 0x00380000 +#define HC_HTXnLODDTf_MASK 0x00000007 +#define HC_HTXnXY2ST_MASK 0x00000008 +#define HC_HTXnMPMD_Tsingle 0x00000000 +#define HC_HTXnMPMD_Tclamp 0x00080000 +#define HC_HTXnMPMD_Trepeat 0x00100000 +#define HC_HTXnMPMD_Tmirror 0x00180000 +#define HC_HTXnMPMD_Twrap 0x00200000 +#define HC_HTXnMPMD_Ssingle 0x00000000 +#define HC_HTXnMPMD_Sclamp 0x00010000 +#define HC_HTXnMPMD_Srepeat 0x00020000 +#define HC_HTXnMPMD_Smirror 0x00030000 +#define HC_HTXnMPMD_Swrap 0x00040000 +/* HC_SubA_HTXnCLODu 0x007a + */ +#define HC_HTXnCLODu_MASK 0x000ffc00 +#define HC_HTXnCLODd_MASK 0x000003ff +#define HC_HTXnCLODu_SHIFT 10 +/* HC_SubA_HTXnFM 0x007b + */ +#define HC_HTXnFM_MASK 0x00ff0000 +#define HC_HTXnLoc_MASK 0x00000003 +#define HC_HTXnFM_INDEX 0x00000000 +#define HC_HTXnFM_Intensity 0x00080000 +#define HC_HTXnFM_Lum 0x00100000 +#define HC_HTXnFM_Alpha 0x00180000 +#define HC_HTXnFM_DX 0x00280000 +#define HC_HTXnFM_ARGB16 0x00880000 +#define HC_HTXnFM_ARGB32 0x00980000 +#define HC_HTXnFM_ABGR16 0x00a80000 +#define HC_HTXnFM_ABGR32 0x00b80000 +#define HC_HTXnFM_RGBA16 0x00c80000 +#define HC_HTXnFM_RGBA32 0x00d80000 +#define HC_HTXnFM_BGRA16 0x00e80000 +#define HC_HTXnFM_BGRA32 0x00f80000 +#define HC_HTXnFM_BUMPMAP 0x00380000 +#define HC_HTXnFM_Index1 (HC_HTXnFM_INDEX | 0x00000000) +#define HC_HTXnFM_Index2 (HC_HTXnFM_INDEX | 0x00010000) +#define HC_HTXnFM_Index4 (HC_HTXnFM_INDEX | 0x00020000) +#define HC_HTXnFM_Index8 (HC_HTXnFM_INDEX | 0x00030000) +#define HC_HTXnFM_T1 (HC_HTXnFM_Intensity | 0x00000000) +#define HC_HTXnFM_T2 (HC_HTXnFM_Intensity | 0x00010000) +#define HC_HTXnFM_T4 (HC_HTXnFM_Intensity | 0x00020000) +#define HC_HTXnFM_T8 (HC_HTXnFM_Intensity | 0x00030000) +#define HC_HTXnFM_L1 (HC_HTXnFM_Lum | 0x00000000) +#define HC_HTXnFM_L2 (HC_HTXnFM_Lum | 0x00010000) +#define HC_HTXnFM_L4 (HC_HTXnFM_Lum | 0x00020000) +#define HC_HTXnFM_L8 (HC_HTXnFM_Lum | 0x00030000) +#define HC_HTXnFM_AL44 (HC_HTXnFM_Lum | 0x00040000) +#define HC_HTXnFM_AL88 (HC_HTXnFM_Lum | 0x00050000) +#define HC_HTXnFM_A1 (HC_HTXnFM_Alpha | 0x00000000) +#define HC_HTXnFM_A2 (HC_HTXnFM_Alpha | 0x00010000) +#define HC_HTXnFM_A4 (HC_HTXnFM_Alpha | 0x00020000) +#define HC_HTXnFM_A8 (HC_HTXnFM_Alpha | 0x00030000) +#define HC_HTXnFM_DX1 (HC_HTXnFM_DX | 0x00010000) +#define HC_HTXnFM_DX23 (HC_HTXnFM_DX | 0x00020000) +#define HC_HTXnFM_DX45 (HC_HTXnFM_DX | 0x00030000) +#define HC_HTXnFM_RGB555 (HC_HTXnFM_ARGB16 | 0x00000000) +#define HC_HTXnFM_RGB565 (HC_HTXnFM_ARGB16 | 0x00010000) +#define HC_HTXnFM_ARGB1555 (HC_HTXnFM_ARGB16 | 0x00020000) +#define HC_HTXnFM_ARGB4444 (HC_HTXnFM_ARGB16 | 0x00030000) +#define HC_HTXnFM_ARGB0888 (HC_HTXnFM_ARGB32 | 0x00000000) +#define HC_HTXnFM_ARGB8888 (HC_HTXnFM_ARGB32 | 0x00010000) +#define HC_HTXnFM_BGR555 (HC_HTXnFM_ABGR16 | 0x00000000) +#define HC_HTXnFM_BGR565 (HC_HTXnFM_ABGR16 | 0x00010000) +#define HC_HTXnFM_ABGR1555 (HC_HTXnFM_ABGR16 | 0x00020000) +#define HC_HTXnFM_ABGR4444 (HC_HTXnFM_ABGR16 | 0x00030000) +#define HC_HTXnFM_ABGR0888 (HC_HTXnFM_ABGR32 | 0x00000000) +#define HC_HTXnFM_ABGR8888 (HC_HTXnFM_ABGR32 | 0x00010000) +#define HC_HTXnFM_RGBA5550 (HC_HTXnFM_RGBA16 | 0x00000000) +#define HC_HTXnFM_RGBA5551 (HC_HTXnFM_RGBA16 | 0x00020000) +#define HC_HTXnFM_RGBA4444 (HC_HTXnFM_RGBA16 | 0x00030000) +#define HC_HTXnFM_RGBA8880 (HC_HTXnFM_RGBA32 | 0x00000000) +#define HC_HTXnFM_RGBA8888 (HC_HTXnFM_RGBA32 | 0x00010000) +#define HC_HTXnFM_BGRA5550 (HC_HTXnFM_BGRA16 | 0x00000000) +#define HC_HTXnFM_BGRA5551 (HC_HTXnFM_BGRA16 | 0x00020000) +#define HC_HTXnFM_BGRA4444 (HC_HTXnFM_BGRA16 | 0x00030000) +#define HC_HTXnFM_BGRA8880 (HC_HTXnFM_BGRA32 | 0x00000000) +#define HC_HTXnFM_BGRA8888 (HC_HTXnFM_BGRA32 | 0x00010000) +#define HC_HTXnFM_VU88 (HC_HTXnFM_BUMPMAP | 0x00000000) +#define HC_HTXnFM_LVU655 (HC_HTXnFM_BUMPMAP | 0x00010000) +#define HC_HTXnFM_LVU888 (HC_HTXnFM_BUMPMAP | 0x00020000) +#define HC_HTXnLoc_Local 0x00000000 +#define HC_HTXnLoc_Sys 0x00000002 +#define HC_HTXnLoc_AGP 0x00000003 +/* HC_SubA_HTXnTRAH 0x007f + */ +#define HC_HTXnTRAH_MASK 0x00ff0000 +#define HC_HTXnTRAL_MASK 0x0000ff00 +#define HC_HTXnTBA_MASK 0x000000ff +#define HC_HTXnTRAH_SHIFT 16 +#define HC_HTXnTRAL_SHIFT 8 +/* HC_SubA_HTXnTBLCsat 0x0080 + *-- Define the input texture. + */ +#define HC_XTC_TOPC 0x00000000 +#define HC_XTC_InvTOPC 0x00000010 +#define HC_XTC_TOPCp5 0x00000020 +#define HC_XTC_Cbias 0x00000000 +#define HC_XTC_InvCbias 0x00000010 +#define HC_XTC_0 0x00000000 +#define HC_XTC_Dif 0x00000001 +#define HC_XTC_Spec 0x00000002 +#define HC_XTC_Tex 0x00000003 +#define HC_XTC_Cur 0x00000004 +#define HC_XTC_Adif 0x00000005 +#define HC_XTC_Fog 0x00000006 +#define HC_XTC_Atex 0x00000007 +#define HC_XTC_Acur 0x00000008 +#define HC_XTC_HTXnTBLRC 0x00000009 +#define HC_XTC_Ctexnext 0x0000000a +/*-- + */ +#define HC_HTXnTBLCsat_MASK 0x00800000 +#define HC_HTXnTBLCa_MASK 0x000fc000 +#define HC_HTXnTBLCb_MASK 0x00001f80 +#define HC_HTXnTBLCc_MASK 0x0000003f +#define HC_HTXnTBLCa_TOPC (HC_XTC_TOPC << 14) +#define HC_HTXnTBLCa_InvTOPC (HC_XTC_InvTOPC << 14) +#define HC_HTXnTBLCa_TOPCp5 (HC_XTC_TOPCp5 << 14) +#define HC_HTXnTBLCa_0 (HC_XTC_0 << 14) +#define HC_HTXnTBLCa_Dif (HC_XTC_Dif << 14) +#define HC_HTXnTBLCa_Spec (HC_XTC_Spec << 14) +#define HC_HTXnTBLCa_Tex (HC_XTC_Tex << 14) +#define HC_HTXnTBLCa_Cur (HC_XTC_Cur << 14) +#define HC_HTXnTBLCa_Adif (HC_XTC_Adif << 14) +#define HC_HTXnTBLCa_Fog (HC_XTC_Fog << 14) +#define HC_HTXnTBLCa_Atex (HC_XTC_Atex << 14) +#define HC_HTXnTBLCa_Acur (HC_XTC_Acur << 14) +#define HC_HTXnTBLCa_HTXnTBLRC (HC_XTC_HTXnTBLRC << 14) +#define HC_HTXnTBLCa_Ctexnext (HC_XTC_Ctexnext << 14) +#define HC_HTXnTBLCb_TOPC (HC_XTC_TOPC << 7) +#define HC_HTXnTBLCb_InvTOPC (HC_XTC_InvTOPC << 7) +#define HC_HTXnTBLCb_TOPCp5 (HC_XTC_TOPCp5 << 7) +#define HC_HTXnTBLCb_0 (HC_XTC_0 << 7) +#define HC_HTXnTBLCb_Dif (HC_XTC_Dif << 7) +#define HC_HTXnTBLCb_Spec (HC_XTC_Spec << 7) +#define HC_HTXnTBLCb_Tex (HC_XTC_Tex << 7) +#define HC_HTXnTBLCb_Cur (HC_XTC_Cur << 7) +#define HC_HTXnTBLCb_Adif (HC_XTC_Adif << 7) +#define HC_HTXnTBLCb_Fog (HC_XTC_Fog << 7) +#define HC_HTXnTBLCb_Atex (HC_XTC_Atex << 7) +#define HC_HTXnTBLCb_Acur (HC_XTC_Acur << 7) +#define HC_HTXnTBLCb_HTXnTBLRC (HC_XTC_HTXnTBLRC << 7) +#define HC_HTXnTBLCb_Ctexnext (HC_XTC_Ctexnext << 7) +#define HC_HTXnTBLCc_TOPC (HC_XTC_TOPC << 0) +#define HC_HTXnTBLCc_InvTOPC (HC_XTC_InvTOPC << 0) +#define HC_HTXnTBLCc_TOPCp5 (HC_XTC_TOPCp5 << 0) +#define HC_HTXnTBLCc_0 (HC_XTC_0 << 0) +#define HC_HTXnTBLCc_Dif (HC_XTC_Dif << 0) +#define HC_HTXnTBLCc_Spec (HC_XTC_Spec << 0) +#define HC_HTXnTBLCc_Tex (HC_XTC_Tex << 0) +#define HC_HTXnTBLCc_Cur (HC_XTC_Cur << 0) +#define HC_HTXnTBLCc_Adif (HC_XTC_Adif << 0) +#define HC_HTXnTBLCc_Fog (HC_XTC_Fog << 0) +#define HC_HTXnTBLCc_Atex (HC_XTC_Atex << 0) +#define HC_HTXnTBLCc_Acur (HC_XTC_Acur << 0) +#define HC_HTXnTBLCc_HTXnTBLRC (HC_XTC_HTXnTBLRC << 0) +#define HC_HTXnTBLCc_Ctexnext (HC_XTC_Ctexnext << 0) +/* HC_SubA_HTXnTBLCop 0x0081 + */ +#define HC_HTXnTBLdot_MASK 0x00c00000 +#define HC_HTXnTBLCop_MASK 0x00380000 +#define HC_HTXnTBLCbias_MASK 0x0007c000 +#define HC_HTXnTBLCshift_MASK 0x00001800 +#define HC_HTXnTBLAop_MASK 0x00000380 +#define HC_HTXnTBLAbias_MASK 0x00000078 +#define HC_HTXnTBLAshift_MASK 0x00000003 +#define HC_HTXnTBLCop_Add 0x00000000 +#define HC_HTXnTBLCop_Sub 0x00080000 +#define HC_HTXnTBLCop_Min 0x00100000 +#define HC_HTXnTBLCop_Max 0x00180000 +#define HC_HTXnTBLCop_Mask 0x00200000 +#define HC_HTXnTBLCbias_Cbias (HC_XTC_Cbias << 14) +#define HC_HTXnTBLCbias_InvCbias (HC_XTC_InvCbias << 14) +#define HC_HTXnTBLCbias_0 (HC_XTC_0 << 14) +#define HC_HTXnTBLCbias_Dif (HC_XTC_Dif << 14) +#define HC_HTXnTBLCbias_Spec (HC_XTC_Spec << 14) +#define HC_HTXnTBLCbias_Tex (HC_XTC_Tex << 14) +#define HC_HTXnTBLCbias_Cur (HC_XTC_Cur << 14) +#define HC_HTXnTBLCbias_Adif (HC_XTC_Adif << 14) +#define HC_HTXnTBLCbias_Fog (HC_XTC_Fog << 14) +#define HC_HTXnTBLCbias_Atex (HC_XTC_Atex << 14) +#define HC_HTXnTBLCbias_Acur (HC_XTC_Acur << 14) +#define HC_HTXnTBLCbias_HTXnTBLRC (HC_XTC_HTXnTBLRC << 14) +#define HC_HTXnTBLCshift_1 0x00000000 +#define HC_HTXnTBLCshift_2 0x00000800 +#define HC_HTXnTBLCshift_No 0x00001000 +#define HC_HTXnTBLCshift_DotP 0x00001800 +/*=* John Sheng [2003.7.18] texture combine *=*/ +#define HC_HTXnTBLDOT3 0x00080000 +#define HC_HTXnTBLDOT4 0x000C0000 + +#define HC_HTXnTBLAop_Add 0x00000000 +#define HC_HTXnTBLAop_Sub 0x00000080 +#define HC_HTXnTBLAop_Min 0x00000100 +#define HC_HTXnTBLAop_Max 0x00000180 +#define HC_HTXnTBLAop_Mask 0x00000200 +#define HC_HTXnTBLAbias_Inv 0x00000040 +#define HC_HTXnTBLAbias_Adif 0x00000000 +#define HC_HTXnTBLAbias_Fog 0x00000008 +#define HC_HTXnTBLAbias_Acur 0x00000010 +#define HC_HTXnTBLAbias_HTXnTBLRAbias 0x00000018 +#define HC_HTXnTBLAbias_Atex 0x00000020 +#define HC_HTXnTBLAshift_1 0x00000000 +#define HC_HTXnTBLAshift_2 0x00000001 +#define HC_HTXnTBLAshift_No 0x00000002 +/* #define HC_HTXnTBLAshift_DotP 0x00000003 */ +/* HC_SubA_HTXnTBLMPFog 0x0082 + */ +#define HC_HTXnTBLMPfog_MASK 0x00e00000 +#define HC_HTXnTBLMPfog_0 0x00000000 +#define HC_HTXnTBLMPfog_Adif 0x00200000 +#define HC_HTXnTBLMPfog_Fog 0x00400000 +#define HC_HTXnTBLMPfog_Atex 0x00600000 +#define HC_HTXnTBLMPfog_Acur 0x00800000 +#define HC_HTXnTBLMPfog_GHTXnTBLRFog 0x00a00000 +/* HC_SubA_HTXnTBLAsat 0x0083 + *-- Define the texture alpha input. + */ +#define HC_XTA_TOPA 0x00000000 +#define HC_XTA_InvTOPA 0x00000008 +#define HC_XTA_TOPAp5 0x00000010 +#define HC_XTA_Adif 0x00000000 +#define HC_XTA_Fog 0x00000001 +#define HC_XTA_Acur 0x00000002 +#define HC_XTA_HTXnTBLRA 0x00000003 +#define HC_XTA_Atex 0x00000004 +#define HC_XTA_Atexnext 0x00000005 +/*-- + */ +#define HC_HTXnTBLAsat_MASK 0x00800000 +#define HC_HTXnTBLAMB_MASK 0x00700000 +#define HC_HTXnTBLAa_MASK 0x0007c000 +#define HC_HTXnTBLAb_MASK 0x00000f80 +#define HC_HTXnTBLAc_MASK 0x0000001f +#define HC_HTXnTBLAMB_SHIFT 20 +#define HC_HTXnTBLAa_TOPA (HC_XTA_TOPA << 14) +#define HC_HTXnTBLAa_InvTOPA (HC_XTA_InvTOPA << 14) +#define HC_HTXnTBLAa_TOPAp5 (HC_XTA_TOPAp5 << 14) +#define HC_HTXnTBLAa_Adif (HC_XTA_Adif << 14) +#define HC_HTXnTBLAa_Fog (HC_XTA_Fog << 14) +#define HC_HTXnTBLAa_Acur (HC_XTA_Acur << 14) +#define HC_HTXnTBLAa_HTXnTBLRA (HC_XTA_HTXnTBLRA << 14) +#define HC_HTXnTBLAa_Atex (HC_XTA_Atex << 14) +#define HC_HTXnTBLAa_Atexnext (HC_XTA_Atexnext << 14) +#define HC_HTXnTBLAb_TOPA (HC_XTA_TOPA << 7) +#define HC_HTXnTBLAb_InvTOPA (HC_XTA_InvTOPA << 7) +#define HC_HTXnTBLAb_TOPAp5 (HC_XTA_TOPAp5 << 7) +#define HC_HTXnTBLAb_Adif (HC_XTA_Adif << 7) +#define HC_HTXnTBLAb_Fog (HC_XTA_Fog << 7) +#define HC_HTXnTBLAb_Acur (HC_XTA_Acur << 7) +#define HC_HTXnTBLAb_HTXnTBLRA (HC_XTA_HTXnTBLRA << 7) +#define HC_HTXnTBLAb_Atex (HC_XTA_Atex << 7) +#define HC_HTXnTBLAb_Atexnext (HC_XTA_Atexnext << 7) +#define HC_HTXnTBLAc_TOPA (HC_XTA_TOPA << 0) +#define HC_HTXnTBLAc_InvTOPA (HC_XTA_InvTOPA << 0) +#define HC_HTXnTBLAc_TOPAp5 (HC_XTA_TOPAp5 << 0) +#define HC_HTXnTBLAc_Adif (HC_XTA_Adif << 0) +#define HC_HTXnTBLAc_Fog (HC_XTA_Fog << 0) +#define HC_HTXnTBLAc_Acur (HC_XTA_Acur << 0) +#define HC_HTXnTBLAc_HTXnTBLRA (HC_XTA_HTXnTBLRA << 0) +#define HC_HTXnTBLAc_Atex (HC_XTA_Atex << 0) +#define HC_HTXnTBLAc_Atexnext (HC_XTA_Atexnext << 0) +/* HC_SubA_HTXnTBLRAa 0x0089 + */ +#define HC_HTXnTBLRAa_MASK 0x00ff0000 +#define HC_HTXnTBLRAb_MASK 0x0000ff00 +#define HC_HTXnTBLRAc_MASK 0x000000ff +#define HC_HTXnTBLRAa_SHIFT 16 +#define HC_HTXnTBLRAb_SHIFT 8 +#define HC_HTXnTBLRAc_SHIFT 0 +/* HC_SubA_HTXnTBLRFog 0x008a + */ +#define HC_HTXnTBLRFog_MASK 0x0000ff00 +#define HC_HTXnTBLRAbias_MASK 0x000000ff +#define HC_HTXnTBLRFog_SHIFT 8 +#define HC_HTXnTBLRAbias_SHIFT 0 +/* HC_SubA_HTXnLScale 0x0094 + */ +#define HC_HTXnLScale_MASK 0x0007fc00 +#define HC_HTXnLOff_MASK 0x000001ff +#define HC_HTXnLScale_SHIFT 10 +/* HC_SubA_HTXSMD 0x0000 + */ +#define HC_HTXSMD_MASK 0x00000080 +#define HC_HTXTMD_MASK 0x00000040 +#define HC_HTXNum_MASK 0x00000038 +#define HC_HTXTRMD_MASK 0x00000006 +#define HC_HTXCHCLR_MASK 0x00000001 +#define HC_HTXNum_SHIFT 3 + +/* Texture Palette n + */ +#define HC_SubType_TexPalette0 0x00000000 +#define HC_SubType_TexPalette1 0x00000001 +#define HC_SubType_FogTable 0x00000010 +#define HC_SubType_Stipple 0x00000014 +/* HC_SubA_TexPalette0 0x0000 + */ +#define HC_HTPnA_MASK 0xff000000 +#define HC_HTPnR_MASK 0x00ff0000 +#define HC_HTPnG_MASK 0x0000ff00 +#define HC_HTPnB_MASK 0x000000ff +/* HC_SubA_FogTable 0x0010 + */ +#define HC_HFPn3_MASK 0xff000000 +#define HC_HFPn2_MASK 0x00ff0000 +#define HC_HFPn1_MASK 0x0000ff00 +#define HC_HFPn_MASK 0x000000ff +#define HC_HFPn3_SHIFT 24 +#define HC_HFPn2_SHIFT 16 +#define HC_HFPn1_SHIFT 8 + +/* Auto Testing & Security + */ +#define HC_SubA_HenFIFOAT 0x0000 +#define HC_SubA_HFBDrawFirst 0x0004 +#define HC_SubA_HFBBasL 0x0005 +#define HC_SubA_HFBDst 0x0006 +/* HC_SubA_HenFIFOAT 0x0000 + */ +#define HC_HenFIFOAT_MASK 0x00000020 +#define HC_HenGEMILock_MASK 0x00000010 +#define HC_HenFBASwap_MASK 0x00000008 +#define HC_HenOT_MASK 0x00000004 +#define HC_HenCMDQ_MASK 0x00000002 +#define HC_HenTXCTSU_MASK 0x00000001 +/* HC_SubA_HFBDrawFirst 0x0004 + */ +#define HC_HFBDrawFirst_MASK 0x00000800 +#define HC_HFBQueue_MASK 0x00000400 +#define HC_HFBLock_MASK 0x00000200 +#define HC_HEOF_MASK 0x00000100 +#define HC_HFBBasH_MASK 0x000000ff + +/* GEMI Setting + */ +#define HC_SubA_HTArbRCM 0x0008 +#define HC_SubA_HTArbRZ 0x000a +#define HC_SubA_HTArbWZ 0x000b +#define HC_SubA_HTArbRTX 0x000c +#define HC_SubA_HTArbRCW 0x000d +#define HC_SubA_HTArbE2 0x000e +#define HC_SubA_HArbRQCM 0x0010 +#define HC_SubA_HArbWQCM 0x0011 +#define HC_SubA_HGEMITout 0x0020 +#define HC_SubA_HFthRTXD 0x0040 +#define HC_SubA_HFthRTXA 0x0044 +#define HC_SubA_HCMDQstL 0x0050 +#define HC_SubA_HCMDQendL 0x0051 +#define HC_SubA_HCMDQLen 0x0052 +/* HC_SubA_HTArbRCM 0x0008 + */ +#define HC_HTArbRCM_MASK 0x0000ffff +/* HC_SubA_HTArbRZ 0x000a + */ +#define HC_HTArbRZ_MASK 0x0000ffff +/* HC_SubA_HTArbWZ 0x000b + */ +#define HC_HTArbWZ_MASK 0x0000ffff +/* HC_SubA_HTArbRTX 0x000c + */ +#define HC_HTArbRTX_MASK 0x0000ffff +/* HC_SubA_HTArbRCW 0x000d + */ +#define HC_HTArbRCW_MASK 0x0000ffff +/* HC_SubA_HTArbE2 0x000e + */ +#define HC_HTArbE2_MASK 0x0000ffff +/* HC_SubA_HArbRQCM 0x0010 + */ +#define HC_HTArbRQCM_MASK 0x0000ffff +/* HC_SubA_HArbWQCM 0x0011 + */ +#define HC_HArbWQCM_MASK 0x0000ffff +/* HC_SubA_HGEMITout 0x0020 + */ +#define HC_HGEMITout_MASK 0x000f0000 +#define HC_HNPArbZC_MASK 0x0000ffff +#define HC_HGEMITout_SHIFT 16 +/* HC_SubA_HFthRTXD 0x0040 + */ +#define HC_HFthRTXD_MASK 0x00ff0000 +#define HC_HFthRZD_MASK 0x0000ff00 +#define HC_HFthWZD_MASK 0x000000ff +#define HC_HFthRTXD_SHIFT 16 +#define HC_HFthRZD_SHIFT 8 +/* HC_SubA_HFthRTXA 0x0044 + */ +#define HC_HFthRTXA_MASK 0x000000ff + +/****************************************************************************** +** Define the Halcyon Internal register access constants. For simulator only. +******************************************************************************/ +#define HC_SIMA_HAGPBstL 0x0000 +#define HC_SIMA_HAGPBendL 0x0001 +#define HC_SIMA_HAGPCMNT 0x0002 +#define HC_SIMA_HAGPBpL 0x0003 +#define HC_SIMA_HAGPBpH 0x0004 +#define HC_SIMA_HClipTB 0x0005 +#define HC_SIMA_HClipLR 0x0006 +#define HC_SIMA_HFPClipTL 0x0007 +#define HC_SIMA_HFPClipBL 0x0008 +#define HC_SIMA_HFPClipLL 0x0009 +#define HC_SIMA_HFPClipRL 0x000a +#define HC_SIMA_HFPClipTBH 0x000b +#define HC_SIMA_HFPClipLRH 0x000c +#define HC_SIMA_HLP 0x000d +#define HC_SIMA_HLPRF 0x000e +#define HC_SIMA_HSolidCL 0x000f +#define HC_SIMA_HPixGC 0x0010 +#define HC_SIMA_HSPXYOS 0x0011 +#define HC_SIMA_HCmdA 0x0012 +#define HC_SIMA_HCmdB 0x0013 +#define HC_SIMA_HEnable 0x0014 +#define HC_SIMA_HZWBBasL 0x0015 +#define HC_SIMA_HZWBBasH 0x0016 +#define HC_SIMA_HZWBType 0x0017 +#define HC_SIMA_HZBiasL 0x0018 +#define HC_SIMA_HZWBend 0x0019 +#define HC_SIMA_HZWTMD 0x001a +#define HC_SIMA_HZWCDL 0x001b +#define HC_SIMA_HZWCTAGnum 0x001c +#define HC_SIMA_HZCYNum 0x001d +#define HC_SIMA_HZWCFire 0x001e +/* #define HC_SIMA_HSBBasL 0x001d */ +/* #define HC_SIMA_HSBBasH 0x001e */ +/* #define HC_SIMA_HSBFM 0x001f */ +#define HC_SIMA_HSTREF 0x0020 +#define HC_SIMA_HSTMD 0x0021 +#define HC_SIMA_HABBasL 0x0022 +#define HC_SIMA_HABBasH 0x0023 +#define HC_SIMA_HABFM 0x0024 +#define HC_SIMA_HATMD 0x0025 +#define HC_SIMA_HABLCsat 0x0026 +#define HC_SIMA_HABLCop 0x0027 +#define HC_SIMA_HABLAsat 0x0028 +#define HC_SIMA_HABLAop 0x0029 +#define HC_SIMA_HABLRCa 0x002a +#define HC_SIMA_HABLRFCa 0x002b +#define HC_SIMA_HABLRCbias 0x002c +#define HC_SIMA_HABLRCb 0x002d +#define HC_SIMA_HABLRFCb 0x002e +#define HC_SIMA_HABLRAa 0x002f +#define HC_SIMA_HABLRAb 0x0030 +#define HC_SIMA_HDBBasL 0x0031 +#define HC_SIMA_HDBBasH 0x0032 +#define HC_SIMA_HDBFM 0x0033 +#define HC_SIMA_HFBBMSKL 0x0034 +#define HC_SIMA_HROP 0x0035 +#define HC_SIMA_HFogLF 0x0036 +#define HC_SIMA_HFogCL 0x0037 +#define HC_SIMA_HFogCH 0x0038 +#define HC_SIMA_HFogStL 0x0039 +#define HC_SIMA_HFogStH 0x003a +#define HC_SIMA_HFogOOdMF 0x003b +#define HC_SIMA_HFogOOdEF 0x003c +#define HC_SIMA_HFogEndL 0x003d +#define HC_SIMA_HFogDenst 0x003e +/*---- start of texture 0 setting ---- + */ +#define HC_SIMA_HTX0L0BasL 0x0040 +#define HC_SIMA_HTX0L1BasL 0x0041 +#define HC_SIMA_HTX0L2BasL 0x0042 +#define HC_SIMA_HTX0L3BasL 0x0043 +#define HC_SIMA_HTX0L4BasL 0x0044 +#define HC_SIMA_HTX0L5BasL 0x0045 +#define HC_SIMA_HTX0L6BasL 0x0046 +#define HC_SIMA_HTX0L7BasL 0x0047 +#define HC_SIMA_HTX0L8BasL 0x0048 +#define HC_SIMA_HTX0L9BasL 0x0049 +#define HC_SIMA_HTX0LaBasL 0x004a +#define HC_SIMA_HTX0LbBasL 0x004b +#define HC_SIMA_HTX0LcBasL 0x004c +#define HC_SIMA_HTX0LdBasL 0x004d +#define HC_SIMA_HTX0LeBasL 0x004e +#define HC_SIMA_HTX0LfBasL 0x004f +#define HC_SIMA_HTX0L10BasL 0x0050 +#define HC_SIMA_HTX0L11BasL 0x0051 +#define HC_SIMA_HTX0L012BasH 0x0052 +#define HC_SIMA_HTX0L345BasH 0x0053 +#define HC_SIMA_HTX0L678BasH 0x0054 +#define HC_SIMA_HTX0L9abBasH 0x0055 +#define HC_SIMA_HTX0LcdeBasH 0x0056 +#define HC_SIMA_HTX0Lf1011BasH 0x0057 +#define HC_SIMA_HTX0L0Pit 0x0058 +#define HC_SIMA_HTX0L1Pit 0x0059 +#define HC_SIMA_HTX0L2Pit 0x005a +#define HC_SIMA_HTX0L3Pit 0x005b +#define HC_SIMA_HTX0L4Pit 0x005c +#define HC_SIMA_HTX0L5Pit 0x005d +#define HC_SIMA_HTX0L6Pit 0x005e +#define HC_SIMA_HTX0L7Pit 0x005f +#define HC_SIMA_HTX0L8Pit 0x0060 +#define HC_SIMA_HTX0L9Pit 0x0061 +#define HC_SIMA_HTX0LaPit 0x0062 +#define HC_SIMA_HTX0LbPit 0x0063 +#define HC_SIMA_HTX0LcPit 0x0064 +#define HC_SIMA_HTX0LdPit 0x0065 +#define HC_SIMA_HTX0LePit 0x0066 +#define HC_SIMA_HTX0LfPit 0x0067 +#define HC_SIMA_HTX0L10Pit 0x0068 +#define HC_SIMA_HTX0L11Pit 0x0069 +#define HC_SIMA_HTX0L0_5WE 0x006a +#define HC_SIMA_HTX0L6_bWE 0x006b +#define HC_SIMA_HTX0Lc_11WE 0x006c +#define HC_SIMA_HTX0L0_5HE 0x006d +#define HC_SIMA_HTX0L6_bHE 0x006e +#define HC_SIMA_HTX0Lc_11HE 0x006f +#define HC_SIMA_HTX0L0OS 0x0070 +#define HC_SIMA_HTX0TB 0x0071 +#define HC_SIMA_HTX0MPMD 0x0072 +#define HC_SIMA_HTX0CLODu 0x0073 +#define HC_SIMA_HTX0FM 0x0074 +#define HC_SIMA_HTX0TRCH 0x0075 +#define HC_SIMA_HTX0TRCL 0x0076 +#define HC_SIMA_HTX0TBC 0x0077 +#define HC_SIMA_HTX0TRAH 0x0078 +#define HC_SIMA_HTX0TBLCsat 0x0079 +#define HC_SIMA_HTX0TBLCop 0x007a +#define HC_SIMA_HTX0TBLMPfog 0x007b +#define HC_SIMA_HTX0TBLAsat 0x007c +#define HC_SIMA_HTX0TBLRCa 0x007d +#define HC_SIMA_HTX0TBLRCb 0x007e +#define HC_SIMA_HTX0TBLRCc 0x007f +#define HC_SIMA_HTX0TBLRCbias 0x0080 +#define HC_SIMA_HTX0TBLRAa 0x0081 +#define HC_SIMA_HTX0TBLRFog 0x0082 +#define HC_SIMA_HTX0BumpM00 0x0083 +#define HC_SIMA_HTX0BumpM01 0x0084 +#define HC_SIMA_HTX0BumpM10 0x0085 +#define HC_SIMA_HTX0BumpM11 0x0086 +#define HC_SIMA_HTX0LScale 0x0087 +/*---- end of texture 0 setting ---- 0x008f + */ +#define HC_SIMA_TX0TX1_OFF 0x0050 +/*---- start of texture 1 setting ---- + */ +#define HC_SIMA_HTX1L0BasL (HC_SIMA_HTX0L0BasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L1BasL (HC_SIMA_HTX0L1BasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L2BasL (HC_SIMA_HTX0L2BasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L3BasL (HC_SIMA_HTX0L3BasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L4BasL (HC_SIMA_HTX0L4BasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L5BasL (HC_SIMA_HTX0L5BasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L6BasL (HC_SIMA_HTX0L6BasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L7BasL (HC_SIMA_HTX0L7BasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L8BasL (HC_SIMA_HTX0L8BasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L9BasL (HC_SIMA_HTX0L9BasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1LaBasL (HC_SIMA_HTX0LaBasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1LbBasL (HC_SIMA_HTX0LbBasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1LcBasL (HC_SIMA_HTX0LcBasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1LdBasL (HC_SIMA_HTX0LdBasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1LeBasL (HC_SIMA_HTX0LeBasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1LfBasL (HC_SIMA_HTX0LfBasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L10BasL (HC_SIMA_HTX0L10BasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L11BasL (HC_SIMA_HTX0L11BasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L012BasH (HC_SIMA_HTX0L012BasH + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L345BasH (HC_SIMA_HTX0L345BasH + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L678BasH (HC_SIMA_HTX0L678BasH + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L9abBasH (HC_SIMA_HTX0L9abBasH + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1LcdeBasH (HC_SIMA_HTX0LcdeBasH + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1Lf1011BasH (HC_SIMA_HTX0Lf1011BasH + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L0Pit (HC_SIMA_HTX0L0Pit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L1Pit (HC_SIMA_HTX0L1Pit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L2Pit (HC_SIMA_HTX0L2Pit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L3Pit (HC_SIMA_HTX0L3Pit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L4Pit (HC_SIMA_HTX0L4Pit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L5Pit (HC_SIMA_HTX0L5Pit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L6Pit (HC_SIMA_HTX0L6Pit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L7Pit (HC_SIMA_HTX0L7Pit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L8Pit (HC_SIMA_HTX0L8Pit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L9Pit (HC_SIMA_HTX0L9Pit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1LaPit (HC_SIMA_HTX0LaPit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1LbPit (HC_SIMA_HTX0LbPit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1LcPit (HC_SIMA_HTX0LcPit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1LdPit (HC_SIMA_HTX0LdPit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1LePit (HC_SIMA_HTX0LePit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1LfPit (HC_SIMA_HTX0LfPit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L10Pit (HC_SIMA_HTX0L10Pit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L11Pit (HC_SIMA_HTX0L11Pit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L0_5WE (HC_SIMA_HTX0L0_5WE + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L6_bWE (HC_SIMA_HTX0L6_bWE + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1Lc_11WE (HC_SIMA_HTX0Lc_11WE + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L0_5HE (HC_SIMA_HTX0L0_5HE + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L6_bHE (HC_SIMA_HTX0L6_bHE + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1Lc_11HE (HC_SIMA_HTX0Lc_11HE + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L0OS (HC_SIMA_HTX0L0OS + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1TB (HC_SIMA_HTX0TB + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1MPMD (HC_SIMA_HTX0MPMD + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1CLODu (HC_SIMA_HTX0CLODu + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1FM (HC_SIMA_HTX0FM + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1TRCH (HC_SIMA_HTX0TRCH + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1TRCL (HC_SIMA_HTX0TRCL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1TBC (HC_SIMA_HTX0TBC + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1TRAH (HC_SIMA_HTX0TRAH + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1LTC (HC_SIMA_HTX0LTC + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1LTA (HC_SIMA_HTX0LTA + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1TBLCsat (HC_SIMA_HTX0TBLCsat + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1TBLCop (HC_SIMA_HTX0TBLCop + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1TBLMPfog (HC_SIMA_HTX0TBLMPfog + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1TBLAsat (HC_SIMA_HTX0TBLAsat + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1TBLRCa (HC_SIMA_HTX0TBLRCa + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1TBLRCb (HC_SIMA_HTX0TBLRCb + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1TBLRCc (HC_SIMA_HTX0TBLRCc + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1TBLRCbias (HC_SIMA_HTX0TBLRCbias + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1TBLRAa (HC_SIMA_HTX0TBLRAa + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1TBLRFog (HC_SIMA_HTX0TBLRFog + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1BumpM00 (HC_SIMA_HTX0BumpM00 + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1BumpM01 (HC_SIMA_HTX0BumpM01 + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1BumpM10 (HC_SIMA_HTX0BumpM10 + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1BumpM11 (HC_SIMA_HTX0BumpM11 + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1LScale (HC_SIMA_HTX0LScale + HC_SIMA_TX0TX1_OFF) +/*---- end of texture 1 setting ---- 0xaf + */ +#define HC_SIMA_HTXSMD 0x00b0 +#define HC_SIMA_HenFIFOAT 0x00b1 +#define HC_SIMA_HFBDrawFirst 0x00b2 +#define HC_SIMA_HFBBasL 0x00b3 +#define HC_SIMA_HTArbRCM 0x00b4 +#define HC_SIMA_HTArbRZ 0x00b5 +#define HC_SIMA_HTArbWZ 0x00b6 +#define HC_SIMA_HTArbRTX 0x00b7 +#define HC_SIMA_HTArbRCW 0x00b8 +#define HC_SIMA_HTArbE2 0x00b9 +#define HC_SIMA_HGEMITout 0x00ba +#define HC_SIMA_HFthRTXD 0x00bb +#define HC_SIMA_HFthRTXA 0x00bc +/* Define the texture palette 0 + */ +#define HC_SIMA_HTP0 0x0100 +#define HC_SIMA_HTP1 0x0200 +#define HC_SIMA_FOGTABLE 0x0300 +#define HC_SIMA_STIPPLE 0x0400 +#define HC_SIMA_HE3Fire 0x0440 +#define HC_SIMA_TRANS_SET 0x0441 +#define HC_SIMA_HREngSt 0x0442 +#define HC_SIMA_HRFIFOempty 0x0443 +#define HC_SIMA_HRFIFOfull 0x0444 +#define HC_SIMA_HRErr 0x0445 +#define HC_SIMA_FIFOstatus 0x0446 + +/****************************************************************************** +** Define the AGP command header. +******************************************************************************/ +#define HC_ACMD_MASK 0xfe000000 +#define HC_ACMD_SUB_MASK 0x0c000000 +#define HC_ACMD_HCmdA 0xee000000 +#define HC_ACMD_HCmdB 0xec000000 +#define HC_ACMD_HCmdC 0xea000000 +#define HC_ACMD_H1 0xf0000000 +#define HC_ACMD_H2 0xf2000000 +#define HC_ACMD_H3 0xf4000000 +#define HC_ACMD_H4 0xf6000000 + +#define HC_ACMD_H1IO_MASK 0x000001ff +#define HC_ACMD_H2IO1_MASK 0x001ff000 +#define HC_ACMD_H2IO2_MASK 0x000001ff +#define HC_ACMD_H2IO1_SHIFT 12 +#define HC_ACMD_H2IO2_SHIFT 0 +#define HC_ACMD_H3IO_MASK 0x000001ff +#define HC_ACMD_H3COUNT_MASK 0x01fff000 +#define HC_ACMD_H3COUNT_SHIFT 12 +#define HC_ACMD_H4ID_MASK 0x000001ff +#define HC_ACMD_H4COUNT_MASK 0x01fffe00 +#define HC_ACMD_H4COUNT_SHIFT 9 + +/******************************************************************************** +** Define Header +********************************************************************************/ +#define HC_HEADER2 0xF210F110 + +/******************************************************************************** +** Define Dummy Value +********************************************************************************/ +#define HC_DUMMY 0xCCCCCCCC +/******************************************************************************** +** Define for DMA use +********************************************************************************/ +#define HALCYON_HEADER2 0XF210F110 +#define HALCYON_FIRECMD 0XEE100000 +#define HALCYON_FIREMASK 0XFFF00000 +#define HALCYON_CMDB 0XEC000000 +#define HALCYON_CMDBMASK 0XFFFE0000 +#define HALCYON_SUB_ADDR0 0X00000000 +#define HALCYON_HEADER1MASK 0XFFFFFC00 +#define HALCYON_HEADER1 0XF0000000 +#define HC_SubA_HAGPBstL 0x0060 +#define HC_SubA_HAGPBendL 0x0061 +#define HC_SubA_HAGPCMNT 0x0062 +#define HC_SubA_HAGPBpL 0x0063 +#define HC_SubA_HAGPBpH 0x0064 +#define HC_HAGPCMNT_MASK 0x00800000 +#define HC_HCmdErrClr_MASK 0x00400000 +#define HC_HAGPBendH_MASK 0x0000ff00 +#define HC_HAGPBstH_MASK 0x000000ff +#define HC_HAGPBendH_SHIFT 8 +#define HC_HAGPBstH_SHIFT 0 +#define HC_HAGPBpL_MASK 0x00fffffc +#define HC_HAGPBpID_MASK 0x00000003 +#define HC_HAGPBpID_PAUSE 0x00000000 +#define HC_HAGPBpID_JUMP 0x00000001 +#define HC_HAGPBpID_STOP 0x00000002 +#define HC_HAGPBpH_MASK 0x00ffffff + + +#define VIA_VIDEO_HEADER5 0xFE040000 +#define VIA_VIDEO_HEADER6 0xFE050000 +#define VIA_VIDEO_HEADER7 0xFE060000 +#define VIA_VIDEOMASK 0xFFFF0000 +#endif diff --git a/trunk/src/via_accel.c b/trunk/src/via_accel.c new file mode 100644 index 000000000000..7150ab41de78 --- /dev/null +++ b/trunk/src/via_accel.c @@ -0,0 +1,2723 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * Copyright 2006 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, sub license, + * 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 NON-INFRINGEMENT. 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. + * + * Mostly rewritten and modified for EXA support by Thomas Hellstrom 2005. + */ + +/************************************************************************* + * + * File: via_accel.c + * Content: 2D acceleration function for VIA/S3G UniChrome + * + ************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <X11/Xarch.h> +#include "xaalocal.h" +#include "xaarop.h" +#include "miline.h" + +#include "via.h" +#include "via_driver.h" +#include "via_regs.h" +#include "via_id.h" +#include "via_dmabuffer.h" + +#ifdef X_HAVE_XAAGETROP +#define VIAACCELPATTERNROP(vRop) (XAAGetPatternROP(vRop) << 24) +#define VIAACCELCOPYROP(vRop) (XAAGetCopyROP(vRop) << 24) +#else +#define VIAACCELPATTERNROP(vRop) (XAAPatternROP[vRop] << 24) +#define VIAACCELCOPYROP(vRop) (XAACopyROP[vRop] << 24) +#endif + +/* + * Use PCI MMIO to flush the command buffer when AGP DMA is not available. + */ + +static void +viaDumpDMA(ViaCommandBuffer * buf) +{ + register CARD32 *bp = buf->buf; + CARD32 *endp = bp + buf->pos; + + while (bp != endp) { + if (((bp - buf->buf) & 3) == 0) { + ErrorF("\n %04lx: ", (unsigned long)(bp - buf->buf)); + } + ErrorF("0x%08x ", (unsigned)*bp++); + } + ErrorF("\n"); +} + +void +viaFlushPCI(ViaCommandBuffer * buf) +{ + register CARD32 *bp = buf->buf; + CARD32 transSetting; + CARD32 *endp = bp + buf->pos; + unsigned loop = 0; + register CARD32 offset = 0; + register CARD32 value; + VIAPtr pVia = VIAPTR(buf->pScrn); + + while (bp < endp) { + if (*bp == HALCYON_HEADER2) { + if (++bp == endp) + return; + VIASETREG(VIA_REG_TRANSET, transSetting = *bp++); + while (bp < endp) { + if ((transSetting != HC_ParaType_CmdVdata) && + ((*bp == HALCYON_HEADER2) + || (*bp & HALCYON_HEADER1MASK) == HALCYON_HEADER1)) + break; + VIASETREG(VIA_REG_TRANSPACE, *bp++); + } + } else if ((*bp & HALCYON_HEADER1MASK) == HALCYON_HEADER1) { + + while (bp < endp) { + if (*bp == HALCYON_HEADER2) + break; + if (offset == 0) { + /* + * Not doing this wait will probably stall the processor + * for an unacceptable amount of time in VIASETREG while + * other high priority interrupts may be pending. + */ + if (pVia->Chipset != VIA_P4M890 && pVia->Chipset != VIA_K8M890 && + pVia->Chipset != VIA_P4M900) { + while (!(VIAGETREG(VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY) + && (loop++ < MAXLOOP)) ; + } + while ((VIAGETREG(VIA_REG_STATUS) & + (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY)) && + (loop++ < MAXLOOP)) ; + } + offset = (*bp++ & 0x0FFFFFFF) << 2; + value = *bp++; + VIASETREG(offset, value); + } + } else { + ErrorF("Command stream parser error.\n"); + } + } + buf->pos = 0; + buf->mode = 0; + buf->has3dState = FALSE; +} + +/* + * Flush the command buffer using DRM. If in PCI mode, we can bypass DRM, + * but not for command buffers that contains 3D engine state, since then + * the DRM command verifier will lose track of the 3D engine state. + */ + +#ifdef XF86DRI +static void +viaFlushDRIEnabled(ViaCommandBuffer * cb) +{ + ScrnInfoPtr pScrn = cb->pScrn; + VIAPtr pVia = VIAPTR(pScrn); + char *tmp = (char *)cb->buf; + int tmpSize; + drm_via_cmdbuffer_t b; + + /* + * Align command buffer end for AGP DMA. + */ + + OUT_RING_H1(0x2f8, 0x67676767); + if (pVia->agpDMA && cb->mode == 2 && cb->rindex != HC_ParaType_CmdVdata + && (cb->pos & 1)) { + OUT_RING(HC_DUMMY); + } + + tmpSize = cb->pos * sizeof(CARD32); + if (pVia->agpDMA || (pVia->directRenderingEnabled && cb->has3dState)) { + cb->mode = 0; + cb->has3dState = FALSE; + while (tmpSize > 0) { + b.size = (tmpSize > VIA_DMASIZE) ? VIA_DMASIZE : tmpSize; + tmpSize -= b.size; + b.buf = tmp; + tmp += b.size; + if (drmCommandWrite(pVia->drmFD, + ((pVia->agpDMA) ? DRM_VIA_CMDBUFFER : DRM_VIA_PCICMD), &b, + sizeof(b))) { + ErrorF("DRM command buffer submission failed.\n"); + viaDumpDMA(cb); + return; + } + } + cb->pos = 0; + } else { + viaFlushPCI(cb); + } +} +#endif + +/* + * Initialize a command buffer. Some fields are currently not used since they + * are intended for Unichrome Pro group A video commands. + */ + +int +viaSetupCBuffer(ScrnInfoPtr pScrn, ViaCommandBuffer * buf, unsigned size) +{ +#ifdef XF86DRI + VIAPtr pVia = VIAPTR(pScrn); +#endif + + buf->pScrn = pScrn; + buf->bufSize = ((size == 0) ? VIA_DMASIZE : size) >> 2; + buf->buf = (CARD32 *) xcalloc(buf->bufSize, sizeof(CARD32)); + if (!buf->buf) + return BadAlloc; + buf->waitFlags = 0; + buf->pos = 0; + buf->mode = 0; + buf->header_start = 0; + buf->rindex = 0; + buf->has3dState = FALSE; + buf->flushFunc = viaFlushPCI; +#ifdef XF86DRI + if (pVia->directRenderingEnabled) { + buf->flushFunc = viaFlushDRIEnabled; + } +#endif + return Success; +} + +/* + * Free resources associated with a command buffer. + */ + +void +viaTearDownCBuffer(ViaCommandBuffer * buf) +{ + if (buf && buf->buf) + xfree(buf->buf); + buf->buf = NULL; +} + +/* + * Leftover from VIA's code. + */ +static void +viaInitPCIe(VIAPtr pVia) +{ + VIASETREG(0x41c, 0x00100000); + VIASETREG(0x420, 0x680A0000); + VIASETREG(0x420, 0x02000000); +} + +static void +viaInitAgp(VIAPtr pVia) +{ + VIASETREG(VIA_REG_TRANSET, 0x00100000); + VIASETREG(VIA_REG_TRANSPACE, 0x00000000); + VIASETREG(VIA_REG_TRANSPACE, 0x00333004); + VIASETREG(VIA_REG_TRANSPACE, 0x60000000); + VIASETREG(VIA_REG_TRANSPACE, 0x61000000); + VIASETREG(VIA_REG_TRANSPACE, 0x62000000); + VIASETREG(VIA_REG_TRANSPACE, 0x63000000); + VIASETREG(VIA_REG_TRANSPACE, 0x64000000); + VIASETREG(VIA_REG_TRANSPACE, 0x7D000000); + + VIASETREG(VIA_REG_TRANSET, 0xfe020000); + VIASETREG(VIA_REG_TRANSPACE, 0x00000000); +} + +/* + * Initialize the virtual command queue. Header 2 commands can be put + * in this queue for buffering. AFAIK it doesn't handle Header 1 + * commands, which is really a pity, since it has to be idled before + * issuing a H1 command. + */ + +static void +viaEnableAgpVQ(VIAPtr pVia) +{ + CARD32 + vqStartAddr = pVia->VQStart, + vqEndAddr = pVia->VQEnd, + vqStartL = 0x50000000 | (vqStartAddr & 0xFFFFFF), + vqEndL = 0x51000000 | (vqEndAddr & 0xFFFFFF), + vqStartEndH = 0x52000000 | ((vqStartAddr & 0xFF000000) >> 24) | + ((vqEndAddr & 0xFF000000) >> 16), + vqLen = 0x53000000 | (VIA_VQ_SIZE >> 3); + + + VIASETREG(VIA_REG_TRANSET, 0x00fe0000); + VIASETREG(VIA_REG_TRANSPACE, 0x080003fe); + VIASETREG(VIA_REG_TRANSPACE, 0x0a00027c); + VIASETREG(VIA_REG_TRANSPACE, 0x0b000260); + VIASETREG(VIA_REG_TRANSPACE, 0x0c000274); + VIASETREG(VIA_REG_TRANSPACE, 0x0d000264); + VIASETREG(VIA_REG_TRANSPACE, 0x0e000000); + VIASETREG(VIA_REG_TRANSPACE, 0x0f000020); + VIASETREG(VIA_REG_TRANSPACE, 0x1000027e); + VIASETREG(VIA_REG_TRANSPACE, 0x110002fe); + VIASETREG(VIA_REG_TRANSPACE, 0x200f0060); + VIASETREG(VIA_REG_TRANSPACE, 0x00000006); + VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f); + VIASETREG(VIA_REG_TRANSPACE, 0x44000000); + VIASETREG(VIA_REG_TRANSPACE, 0x45080c04); + VIASETREG(VIA_REG_TRANSPACE, 0x46800408); + + VIASETREG(VIA_REG_TRANSPACE, vqStartEndH); + VIASETREG(VIA_REG_TRANSPACE, vqStartL); + VIASETREG(VIA_REG_TRANSPACE, vqEndL); + VIASETREG(VIA_REG_TRANSPACE, vqLen); +} + +static void +viaEnablePCIeVQ(VIAPtr pVia) +{ + CARD32 + vqStartAddr = pVia->VQStart, + vqEndAddr = pVia->VQEnd, + vqStartL = 0x70000000 | (vqStartAddr & 0xFFFFFF), + vqEndL = 0x71000000 | (vqEndAddr & 0xFFFFFF), + vqStartEndH = 0x72000000 | ((vqStartAddr & 0xFF000000) >> 24) | + ((vqEndAddr & 0xFF000000) >> 16), + vqLen = 0x73000000 | (VIA_VQ_SIZE >> 3); + + VIASETREG(0x41c, 0x00100000); + VIASETREG(0x420, vqStartEndH); + VIASETREG(0x420, vqStartL); + VIASETREG(0x420, vqEndL); + VIASETREG(0x420, vqLen); + VIASETREG(0x420, 0x74301001); + VIASETREG(0x420, 0x00000000); +} + +/* + * Disable the virtual command queue. + */ + +void +viaDisableVQ(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + + switch ( pVia->Chipset ) + { + case VIA_P4M890: + case VIA_K8M890: + VIASETREG(0x41c, 0x00100000); + VIASETREG(0x420, 0x74301000); + break; + default: + VIASETREG(VIA_REG_TRANSET, 0x00fe0000); + VIASETREG(VIA_REG_TRANSPACE, 0x00000004); + VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f); + VIASETREG(VIA_REG_TRANSPACE, 0x44000000); + VIASETREG(VIA_REG_TRANSPACE, 0x45080c04); + VIASETREG(VIA_REG_TRANSPACE, 0x46800408); + break; + } +} + +/* + * Update our 2D state (TwoDContext) with a new mode. + */ + +static Bool +viaAccelSetMode(int bpp, ViaTwodContext * tdc) +{ + switch (bpp) { + case 16: + tdc->mode = VIA_GEM_16bpp; + tdc->bytesPPShift = 1; + return TRUE; + case 32: + tdc->mode = VIA_GEM_32bpp; + tdc->bytesPPShift = 2; + return TRUE; + case 8: + tdc->mode = VIA_GEM_8bpp; + tdc->bytesPPShift = 0; + return TRUE; + default: + tdc->bytesPPShift = 0; + return FALSE; + } +} + +/* + * Initialize the 2D engine and set the 2D context mode to the + * current screen depth. Also enable the virtual queue. + */ + +void +viaInitialize2DEngine(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + int i; + + /* + * init 2D engine regs to reset 2D engine + */ + + for (i = 0x04; i < 0x44; i += 4) { + VIASETREG(i, 0x0); + } + + switch( pVia->Chipset ) { + case VIA_K8M890: + viaInitPCIe(pVia); + break; + default: + viaInitAgp(pVia); + break; + } + + if (pVia->VQStart != 0) { + switch( pVia->Chipset ) { + case VIA_K8M890: + viaEnablePCIeVQ(pVia); + break; + default: + viaEnableAgpVQ(pVia); + break; + } + } else { + viaDisableVQ(pScrn); + } + + viaAccelSetMode(pScrn->bitsPerPixel, tdc); +} + +/* + * Wait for acceleration engines idle. An expensive way to sync. + */ + +void +viaAccelSync(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + int loop = 0; + + mem_barrier(); + + switch (pVia->Chipset) { + case VIA_P4M890: + case VIA_K8M890: + case VIA_P4M900: + while ((VIAGETREG(VIA_REG_STATUS) & + (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY)) && + (loop++ < MAXLOOP)) ; + break; + default: + while (!(VIAGETREG(VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY) + && (loop++ < MAXLOOP)) ; + + while ((VIAGETREG(VIA_REG_STATUS) & + (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY)) && + (loop++ < MAXLOOP)) ; + break; + } +} + +/* + * Set 2D state clipping on. + */ + +static void +viaSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + + tdc->clipping = TRUE; + tdc->clipX1 = (x1 & 0xFFFF); + tdc->clipY1 = y1; + tdc->clipX2 = (x2 & 0xFFFF); + tdc->clipY2 = y2; +} + +/* + * Set 2D state clipping off. + */ + +static void +viaDisableClipping(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + + tdc->clipping = FALSE; +} + +/* + * Emit clipping borders to the command buffer and update the 2D context + * current command with clipping info. + */ + +static int +viaAccelClippingHelper(ViaCommandBuffer * cb, int refY, ViaTwodContext * tdc) +{ + if (tdc->clipping) { + refY = (refY < tdc->clipY1) ? refY : tdc->clipY1; + tdc->cmd |= VIA_GEC_CLIP_ENABLE; + BEGIN_RING(4); + OUT_RING_H1(VIA_REG_CLIPTL, + ((tdc->clipY1 - refY) << 16) | tdc->clipX1); + OUT_RING_H1(VIA_REG_CLIPBR, + ((tdc->clipY2 - refY) << 16) | tdc->clipX2); + } else { + tdc->cmd &= ~VIA_GEC_CLIP_ENABLE; + } + return refY; + +} + +/* + * Emit a solid blit operation to the command buffer. + */ + +static void +viaAccelSolidHelper(ViaCommandBuffer * cb, int x, int y, int w, int h, + unsigned fbBase, CARD32 mode, unsigned pitch, CARD32 fg, CARD32 cmd) +{ + BEGIN_RING(14); + OUT_RING_H1(VIA_REG_GEMODE, mode); + OUT_RING_H1(VIA_REG_DSTBASE, fbBase >> 3); + OUT_RING_H1(VIA_REG_PITCH, VIA_PITCH_ENABLE | (pitch >> 3) << 16); + OUT_RING_H1(VIA_REG_DSTPOS, (y << 16) | (x & 0xFFFF)); + OUT_RING_H1(VIA_REG_DIMENSION, ((h - 1) << 16) | (w - 1)); + OUT_RING_H1(VIA_REG_FGCOLOR, fg); + OUT_RING_H1(VIA_REG_GECMD, cmd); +} + +/* + * Check if we can use a planeMask and update the 2D context accordingly. + */ + +static Bool +viaAccelPlaneMaskHelper(ViaTwodContext * tdc, CARD32 planeMask) +{ + CARD32 modeMask = (1 << ((1 << tdc->bytesPPShift) << 3)) - 1; + CARD32 curMask = 0x00000000; + CARD32 curByteMask; + int i; + + if ((planeMask & modeMask) != modeMask) { + + /* + * Masking doesn't work in 8bpp. + */ + + if (modeMask == 0xFF) { + tdc->keyControl &= 0x0FFFFFFF; + return FALSE; + } + + /* + * Translate the bit planemask to a byte planemask. + */ + + for (i = 0; i < (1 << tdc->bytesPPShift); ++i) { + curByteMask = (0xFF << (i << 3)); + + if ((planeMask & curByteMask) == 0) { + curMask |= (1 << i); + } else if ((planeMask & curByteMask) != curByteMask) { + tdc->keyControl &= 0x0FFFFFFF; + return FALSE; + } + } + ErrorF("DEBUG: planeMask 0x%08x, curMask 0%02x\n", + (unsigned)planeMask, (unsigned)curMask); + + tdc->keyControl = (tdc->keyControl & 0x0FFFFFFF) | (curMask << 28); + } + + return TRUE; +} + +/* + * Emit transparency state and color to the command buffer. + */ + +static void +viaAccelTransparentHelper(ViaTwodContext * tdc, ViaCommandBuffer * cb, + CARD32 keyControl, CARD32 transColor, Bool usePlaneMask) +{ + tdc->keyControl &= ((usePlaneMask) ? 0xF0000000 : 0x00000000); + tdc->keyControl |= (keyControl & 0x0FFFFFFF); + BEGIN_RING(4); + OUT_RING_H1(VIA_REG_KEYCONTROL, tdc->keyControl); + if (keyControl) { + OUT_RING_H1(VIA_REG_SRCCOLORKEY, transColor); + } +} + +/* + * Emit a copy blit operation to the command buffer. + */ + +static void +viaAccelCopyHelper(ViaCommandBuffer * cb, int xs, int ys, int xd, int yd, + int w, int h, unsigned srcFbBase, unsigned dstFbBase, CARD32 mode, + unsigned srcPitch, unsigned dstPitch, CARD32 cmd) +{ + if (cmd & VIA_GEC_DECY) { + ys += h - 1; + yd += h - 1; + } + + if (cmd & VIA_GEC_DECX) { + xs += w - 1; + xd += w - 1; + } + + BEGIN_RING(16); + OUT_RING_H1(VIA_REG_GEMODE, mode); + OUT_RING_H1(VIA_REG_SRCBASE, srcFbBase >> 3); + OUT_RING_H1(VIA_REG_DSTBASE, dstFbBase >> 3); + OUT_RING_H1(VIA_REG_PITCH, VIA_PITCH_ENABLE | + ((dstPitch >> 3) << 16) | (srcPitch >> 3)); + OUT_RING_H1(VIA_REG_SRCPOS, (ys << 16) | (xs & 0xFFFF)); + OUT_RING_H1(VIA_REG_DSTPOS, (yd << 16) | (xd & 0xFFFF)); + OUT_RING_H1(VIA_REG_DIMENSION, ((h - 1) << 16) | (w - 1)); + OUT_RING_H1(VIA_REG_GECMD, cmd); +} + +/* + * XAA functions. Note that the 2047 line blitter limit has been worked around by adding + * min(y1, y2, clipping y) * stride to the offset (which is recommended by VIA docs). + * The y values (including clipping) must be subtracted accordingly. + */ + +static void +viaSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop, + unsigned planemask, int trans_color) +{ + VIAPtr pVia = VIAPTR(pScrn); + CARD32 cmd; + ViaTwodContext *tdc = &pVia->td; + + RING_VARS; + + cmd = VIA_GEC_BLT | VIAACCELCOPYROP(rop); + + if (xdir < 0) + cmd |= VIA_GEC_DECX; + + if (ydir < 0) + cmd |= VIA_GEC_DECY; + + tdc->cmd = cmd; + viaAccelTransparentHelper(tdc, cb, (trans_color != -1) ? 0x4000 : 0x0000, + trans_color, FALSE); +} + +static void +viaSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, + int x2, int y2, int w, int h) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + int sub; + + RING_VARS; + + if (!w || !h) + return; + + sub = viaAccelClippingHelper(cb, y2, tdc); + viaAccelCopyHelper(cb, x1, 0, x2, y2 - sub, w, h, + pScrn->fbOffset + pVia->Bpl * y1, pScrn->fbOffset + pVia->Bpl * sub, + tdc->mode, pVia->Bpl, pVia->Bpl, tdc->cmd); + ADVANCE_RING; +} + +/* + * SetupForSolidFill is also called to set up for lines. + */ + +static void +viaSetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, + unsigned planemask) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + + RING_VARS; + + tdc->cmd = VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | VIAACCELPATTERNROP(rop); + tdc->fgColor = color; + viaAccelTransparentHelper(tdc, cb, 0x00, 0x00, FALSE); +} + +static void +viaSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + int sub; + + RING_VARS; + + if (!w || !h) + return; + + sub = viaAccelClippingHelper(cb, y, tdc); + viaAccelSolidHelper(cb, x, y - sub, w, h, + pScrn->fbOffset + pVia->Bpl * sub, tdc->mode, pVia->Bpl, tdc->fgColor, + tdc->cmd); + ADVANCE_RING; +} + +/* + * Original VIA comment: + * The meaning of the two pattern paremeters to Setup & Subsequent for + * Mono8x8Patterns varies depending on the flag bits. We specify + * HW_PROGRAMMED_BITS, which means our hardware can handle 8x8 patterns + * without caching in the frame buffer. Thus, Setup gets the pattern bits. + * There is no way with BCI to rotate an 8x8 pattern, so we do NOT specify + * HW_PROGRAMMED_ORIGIN. XAA wil rotate it for us and pass the rotated + * pattern to both Setup and Subsequent. If we DID specify PROGRAMMED_ORIGIN, + * then Setup would get the unrotated pattern, and Subsequent gets the + * origin values. + */ + +static void +viaSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int pattern0, int pattern1, + int fg, int bg, int rop, unsigned planemask) +{ + VIAPtr pVia = VIAPTR(pScrn); + int cmd; + ViaTwodContext *tdc = &pVia->td; + + RING_VARS; + + cmd = VIA_GEC_BLT | VIA_GEC_PAT_REG | VIA_GEC_PAT_MONO | + VIAACCELPATTERNROP(rop); + + if (bg == -1) { + cmd |= VIA_GEC_MPAT_TRANS; + } + + tdc->cmd = cmd; + tdc->fgColor = fg; + tdc->bgColor = bg; + tdc->pattern0 = pattern0; + tdc->pattern1 = pattern1; + viaAccelTransparentHelper(tdc, cb, 0x00, 0x00, FALSE); + +} + +static void +viaSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patOffx, + int patOffy, int x, int y, int w, int h) +{ + VIAPtr pVia = VIAPTR(pScrn); + CARD32 patOffset; + ViaTwodContext *tdc = &pVia->td; + CARD32 dstBase; + int sub; + + RING_VARS; + + if (!w || !h) + return; + + patOffset = ((patOffy & 0x7) << 29) | ((patOffx & 0x7) << 26); + sub = viaAccelClippingHelper(cb, y, tdc); + dstBase = pScrn->fbOffset + sub * pVia->Bpl; + + BEGIN_RING(22); + OUT_RING_H1(VIA_REG_GEMODE, tdc->mode); + OUT_RING_H1(VIA_REG_DSTBASE, dstBase >> 3); + OUT_RING_H1(VIA_REG_PITCH, VIA_PITCH_ENABLE | ((pVia->Bpl >> 3) << 16)); + OUT_RING_H1(VIA_REG_DSTPOS, ((y - sub) << 16) | (x & 0xFFFF)); + OUT_RING_H1(VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1))); + OUT_RING_H1(VIA_REG_PATADDR, patOffset); + OUT_RING_H1(VIA_REG_FGCOLOR, tdc->fgColor); + OUT_RING_H1(VIA_REG_BGCOLOR, tdc->bgColor); + OUT_RING_H1(VIA_REG_MONOPAT0, tdc->pattern0); + OUT_RING_H1(VIA_REG_MONOPAT1, tdc->pattern1); + OUT_RING_H1(VIA_REG_GECMD, tdc->cmd); + ADVANCE_RING; +} + +static void +viaSetupForColor8x8PatternFill(ScrnInfoPtr pScrn, int patternx, int patterny, + int rop, unsigned planemask, int trans_color) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + + RING_VARS; + + tdc->cmd = VIA_GEC_BLT | VIAACCELPATTERNROP(rop); + tdc->patternAddr = (patternx * pVia->Bpp + patterny * pVia->Bpl); + viaAccelTransparentHelper(tdc, cb, (trans_color != -1) ? 0x4000 : 0x0000, + trans_color, FALSE); +} + +static void +viaSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn, int patOffx, + int patOffy, int x, int y, int w, int h) +{ + VIAPtr pVia = VIAPTR(pScrn); + CARD32 patAddr; + ViaTwodContext *tdc = &pVia->td; + CARD32 dstBase; + int sub; + + RING_VARS; + + if (!w || !h) + return; + + patAddr = (tdc->patternAddr >> 3) | + ((patOffy & 0x7) << 29) | ((patOffx & 0x7) << 26); + sub = viaAccelClippingHelper(cb, y, tdc); + dstBase = pScrn->fbOffset + sub * pVia->Bpl; + + BEGIN_RING(14); + OUT_RING_H1(VIA_REG_GEMODE, tdc->mode); + OUT_RING_H1(VIA_REG_DSTBASE, dstBase >> 3); + OUT_RING_H1(VIA_REG_PITCH, VIA_PITCH_ENABLE | ((pVia->Bpl >> 3) << 16)); + OUT_RING_H1(VIA_REG_DSTPOS, ((y - sub) << 16) | (x & 0xFFFF)); + OUT_RING_H1(VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1))); + OUT_RING_H1(VIA_REG_PATADDR, patAddr); + OUT_RING_H1(VIA_REG_GECMD, tdc->cmd); + ADVANCE_RING; +} + +/* + * CPU to screen functions cannot use AGP due to complicated syncing. Therefore the + * command buffer is flushed before new command emissions and viaFluchPCI is called + * explicitly instead of cb->flushFunc() at the end of each CPU to screen function. + * Should the buffer get completely filled again by a CPU to screen command emission, + * a horrible error will occur. + */ + +static void +viaSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg, int bg, + int rop, unsigned planemask) +{ + VIAPtr pVia = VIAPTR(pScrn); + int cmd; + ViaTwodContext *tdc = &pVia->td; + + RING_VARS; + + cmd = VIA_GEC_BLT | VIA_GEC_SRC_SYS | VIA_GEC_SRC_MONO | + VIAACCELCOPYROP(rop); + + if (bg == -1) { + cmd |= VIA_GEC_MSRC_TRANS; + } + + tdc->cmd = cmd; + tdc->fgColor = fg; + tdc->bgColor = bg; + + ADVANCE_RING; + + viaAccelTransparentHelper(tdc, cb, 0x0, 0x0, FALSE); +} + +static void +viaSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x, + int y, int w, int h, int skipleft) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + int sub; + + RING_VARS; + + if (skipleft) { + viaSetClippingRectangle(pScrn, (x + skipleft), y, (x + w - 1), + (y + h - 1)); + } + + sub = viaAccelClippingHelper(cb, y, tdc); + BEGIN_RING(4); + OUT_RING_H1(VIA_REG_BGCOLOR, tdc->bgColor); + OUT_RING_H1(VIA_REG_FGCOLOR, tdc->fgColor); + viaAccelCopyHelper(cb, 0, 0, x, y - sub, w, h, 0, + pScrn->fbOffset + sub * pVia->Bpl, tdc->mode, pVia->Bpl, pVia->Bpl, + tdc->cmd); + + viaFlushPCI(cb); + viaDisableClipping(pScrn); +} + +static void +viaSetupForImageWrite(ScrnInfoPtr pScrn, int rop, unsigned planemask, + int trans_color, int bpp, int depth) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + + RING_VARS; + + tdc->cmd = VIA_GEC_BLT | VIA_GEC_SRC_SYS | VIAACCELCOPYROP(rop); + ADVANCE_RING; + viaAccelTransparentHelper(tdc, cb, (trans_color != -1) ? 0x4000 : 0x0000, + trans_color, FALSE); +} + +static void +viaSubsequentImageWriteRect(ScrnInfoPtr pScrn, int x, int y, int w, int h, + int skipleft) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + int sub; + + RING_VARS; + + if (skipleft) { + viaSetClippingRectangle(pScrn, (x + skipleft), y, (x + w - 1), + (y + h - 1)); + } + + sub = viaAccelClippingHelper(cb, y, tdc); + viaAccelCopyHelper(cb, 0, 0, x, y - sub, w, h, 0, + pScrn->fbOffset + pVia->Bpl * sub, tdc->mode, pVia->Bpl, pVia->Bpl, + tdc->cmd); + + viaFlushPCI(cb); + viaDisableClipping(pScrn); +} + +static void +viaSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, + unsigned int planemask) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + + RING_VARS; + + viaAccelTransparentHelper(tdc, cb, 0x00, 0x00, FALSE); + tdc->cmd = VIA_GEC_FIXCOLOR_PAT | VIAACCELPATTERNROP(rop); + tdc->fgColor = color; + tdc->dashed = FALSE; + + BEGIN_RING(6); + OUT_RING_H1(VIA_REG_GEMODE, tdc->mode); + OUT_RING_H1(VIA_REG_MONOPAT0, 0xFF); + OUT_RING_H1(VIA_REG_FGCOLOR, tdc->fgColor); +} + +static void +viaSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int x1, int y1, + int x2, int y2, int flags) +{ + VIAPtr pVia = VIAPTR(pScrn); + int dx, dy, cmd, tmp, error = 1; + ViaTwodContext *tdc = &pVia->td; + CARD32 dstBase; + int sub; + + RING_VARS; + + sub = viaAccelClippingHelper(cb, (y1 < y2) ? y1 : y2, tdc); + cmd = tdc->cmd | VIA_GEC_LINE; + + dx = x2 - x1; + if (dx < 0) { + dx = -dx; + cmd |= VIA_GEC_DECX; /* line will be drawn from right */ + error = 0; + } + + dy = y2 - y1; + if (dy < 0) { + dy = -dy; + cmd |= VIA_GEC_DECY; /* line will be drawn from bottom */ + } + + if (dy > dx) { + tmp = dy; + dy = dx; + dx = tmp; /* Swap 'dx' and 'dy' */ + cmd |= VIA_GEC_Y_MAJOR; /* Y major line */ + } + + if (flags & OMIT_LAST) { + cmd |= VIA_GEC_LASTPIXEL_OFF; + } + + dstBase = pScrn->fbOffset + sub * pVia->Bpl; + y1 -= sub; + y2 -= sub; + + BEGIN_RING(14); + OUT_RING_H1(VIA_REG_DSTBASE, dstBase >> 3); + OUT_RING_H1(VIA_REG_PITCH, VIA_PITCH_ENABLE | ((pVia->Bpl >> 3) << 16)); + + /* + * major = 2*dmaj, minor = 2*dmin, err = -dmaj - ((bias >> octant) & 1) + * K1 = 2*dmin K2 = 2*(dmin - dmax) + * Error Term = (StartX<EndX) ? (2*dmin - dmax - 1) : (2*(dmin - dmax)) + */ + + OUT_RING_H1(VIA_REG_LINE_K1K2, + ((((dy << 1) & 0x3fff) << 16) | (((dy - dx) << 1) & 0x3fff))); + OUT_RING_H1(VIA_REG_LINE_XY, ((y1 << 16) | (x1 & 0xFFFF))); + OUT_RING_H1(VIA_REG_DIMENSION, dx); + OUT_RING_H1(VIA_REG_LINE_ERROR, + (((dy << 1) - dx - error) & 0x3fff) | ((tdc->dashed) ? 0xFF0000 : 0)); + OUT_RING_H1(VIA_REG_GECMD, cmd); + ADVANCE_RING; + +} + +static void +viaSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len, + int dir) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + CARD32 dstBase; + int sub; + + RING_VARS; + + sub = viaAccelClippingHelper(cb, y, tdc); + dstBase = pScrn->fbOffset + sub * pVia->Bpl; + + BEGIN_RING(10); + OUT_RING_H1(VIA_REG_DSTBASE, dstBase >> 3); + OUT_RING_H1(VIA_REG_PITCH, VIA_PITCH_ENABLE | ((pVia->Bpl >> 3) << 16)); + + if (dir == DEGREES_0) { + OUT_RING_H1(VIA_REG_DSTPOS, ((y - sub) << 16) | (x & 0xFFFF)); + OUT_RING_H1(VIA_REG_DIMENSION, (len - 1)); + OUT_RING_H1(VIA_REG_GECMD, tdc->cmd | VIA_GEC_BLT); + } else { + OUT_RING_H1(VIA_REG_DSTPOS, ((y - sub) << 16) | (x & 0xFFFF)); + OUT_RING_H1(VIA_REG_DIMENSION, ((len - 1) << 16)); + OUT_RING_H1(VIA_REG_GECMD, tdc->cmd | VIA_GEC_BLT); + } + ADVANCE_RING; +} + +static void +viaSetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop, + unsigned int planemask, int length, unsigned char *pattern) +{ + VIAPtr pVia = VIAPTR(pScrn); + int cmd; + CARD32 pat = *(CARD32 *) pattern; + ViaTwodContext *tdc = &pVia->td; + + RING_VARS; + + viaAccelTransparentHelper(tdc, cb, 0x00, 0x00, FALSE); + cmd = VIA_GEC_LINE | VIA_GEC_FIXCOLOR_PAT | VIAACCELPATTERNROP(rop); + + if (bg == -1) { + cmd |= VIA_GEC_MPAT_TRANS; + } + + tdc->cmd = cmd; + tdc->fgColor = fg; + tdc->bgColor = bg; + + switch (length) { + case 2: + pat |= pat << 2; /* fall through */ + case 4: + pat |= pat << 4; /* fall through */ + case 8: + pat |= pat << 8; /* fall through */ + case 16: + pat |= pat << 16; + } + + tdc->pattern0 = pat; + tdc->dashed = TRUE; + + BEGIN_RING(8); + OUT_RING_H1(VIA_REG_GEMODE, tdc->mode); + OUT_RING_H1(VIA_REG_FGCOLOR, tdc->fgColor); + OUT_RING_H1(VIA_REG_BGCOLOR, tdc->bgColor); + OUT_RING_H1(VIA_REG_MONOPAT0, tdc->pattern0); +} + +static void +viaSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, + int y2, int flags, int phase) +{ + viaSubsequentSolidTwoPointLine(pScrn, x1, y1, x2, y2, flags); +} + +static int +viaInitXAA(ScreenPtr pScreen) +{ + + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + XAAInfoRecPtr xaaptr; + + /* + * General acceleration flags + */ + + if (!(xaaptr = pVia->AccelInfoRec = XAACreateInfoRec())) + return FALSE; + + xaaptr->Flags = PIXMAP_CACHE | + OFFSCREEN_PIXMAPS | LINEAR_FRAMEBUFFER | MICROSOFT_ZERO_LINE_BIAS | 0; + + if (pScrn->bitsPerPixel == 8) + xaaptr->CachePixelGranularity = 128; + + xaaptr->SetClippingRectangle = viaSetClippingRectangle; + xaaptr->DisableClipping = viaDisableClipping; + xaaptr->ClippingFlags = HARDWARE_CLIP_SOLID_FILL | + HARDWARE_CLIP_SOLID_LINE | + HARDWARE_CLIP_DASHED_LINE | + HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY | + HARDWARE_CLIP_MONO_8x8_FILL | + HARDWARE_CLIP_COLOR_8x8_FILL | + HARDWARE_CLIP_SCREEN_TO_SCREEN_COLOR_EXPAND | 0; + + xaaptr->Sync = viaAccelSync; + + xaaptr->SetupForScreenToScreenCopy = viaSetupForScreenToScreenCopy; + xaaptr->SubsequentScreenToScreenCopy = viaSubsequentScreenToScreenCopy; + xaaptr->ScreenToScreenCopyFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE; + + xaaptr->SetupForSolidFill = viaSetupForSolidFill; + xaaptr->SubsequentSolidFillRect = viaSubsequentSolidFillRect; + xaaptr->SolidFillFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE; + + xaaptr->SetupForMono8x8PatternFill = viaSetupForMono8x8PatternFill; + xaaptr->SubsequentMono8x8PatternFillRect = + viaSubsequentMono8x8PatternFillRect; + xaaptr->Mono8x8PatternFillFlags = NO_PLANEMASK | + HARDWARE_PATTERN_PROGRAMMED_BITS | + HARDWARE_PATTERN_PROGRAMMED_ORIGIN | BIT_ORDER_IN_BYTE_MSBFIRST | 0; + + xaaptr->SetupForColor8x8PatternFill = viaSetupForColor8x8PatternFill; + xaaptr->SubsequentColor8x8PatternFillRect = + viaSubsequentColor8x8PatternFillRect; + xaaptr->Color8x8PatternFillFlags = NO_PLANEMASK | + NO_TRANSPARENCY | + HARDWARE_PATTERN_PROGRAMMED_BITS | + HARDWARE_PATTERN_PROGRAMMED_ORIGIN | 0; + + xaaptr->SetupForSolidLine = viaSetupForSolidLine; + xaaptr->SubsequentSolidTwoPointLine = viaSubsequentSolidTwoPointLine; + xaaptr->SubsequentSolidHorVertLine = viaSubsequentSolidHorVertLine; + xaaptr->SolidBresenhamLineErrorTermBits = 14; + xaaptr->SolidLineFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE; + + xaaptr->SetupForDashedLine = viaSetupForDashedLine; + xaaptr->SubsequentDashedTwoPointLine = viaSubsequentDashedTwoPointLine; + xaaptr->DashPatternMaxLength = 8; + xaaptr->DashedLineFlags = NO_PLANEMASK | + ROP_NEEDS_SOURCE | + LINE_PATTERN_POWER_OF_2_ONLY | LINE_PATTERN_MSBFIRST_LSBJUSTIFIED | 0; + + xaaptr->ScanlineCPUToScreenColorExpandFillFlags = NO_PLANEMASK | + CPU_TRANSFER_PAD_DWORD | + SCANLINE_PAD_DWORD | + BIT_ORDER_IN_BYTE_MSBFIRST | + LEFT_EDGE_CLIPPING | ROP_NEEDS_SOURCE | 0; + + xaaptr->SetupForScanlineCPUToScreenColorExpandFill = + viaSetupForCPUToScreenColorExpandFill; + xaaptr->SubsequentScanlineCPUToScreenColorExpandFill = + viaSubsequentScanlineCPUToScreenColorExpandFill; + xaaptr->ColorExpandBase = pVia->BltBase; + xaaptr->ColorExpandRange = VIA_MMIO_BLTSIZE; + + xaaptr->ImageWriteFlags = NO_PLANEMASK | + CPU_TRANSFER_PAD_DWORD | + SCANLINE_PAD_DWORD | + BIT_ORDER_IN_BYTE_MSBFIRST | + LEFT_EDGE_CLIPPING | ROP_NEEDS_SOURCE | SYNC_AFTER_IMAGE_WRITE | 0; + + /* + * Most Unichromes are much faster using processor to + * framebuffer writes than using the 2D engine for this. + * test with x11perf -shmput500! + */ + + if (pVia->Chipset != VIA_K8M800 && pVia->Chipset != VIA_K8M890 && pVia->Chipset != VIA_P4M900) + xaaptr->ImageWriteFlags |= NO_GXCOPY; + + xaaptr->SetupForImageWrite = viaSetupForImageWrite; + xaaptr->SubsequentImageWriteRect = viaSubsequentImageWriteRect; + xaaptr->ImageWriteBase = pVia->BltBase; + xaaptr->ImageWriteRange = VIA_MMIO_BLTSIZE; + + return XAAInit(pScreen, xaaptr); + +} + +/* + * Mark Sync using the 2D blitter for AGP. NoOp for PCI. + * In the future one could even launch a NULL PCI DMA command + * to have an interrupt generated, provided it is possible to + * write to the PCI DMA engines from the AGP command stream. + */ + +int +viaAccelMarkSync(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + + RING_VARS; + + ++pVia->curMarker; + + /* + * Wrap around without possibly affecting the int sign bit. + */ + + pVia->curMarker &= 0x7FFFFFFF; + + if (pVia->agpDMA) { + BEGIN_RING(2); + OUT_RING_H1(VIA_REG_KEYCONTROL, 0x00); + viaAccelSolidHelper(cb, 0, 0, 1, 1, pVia->markerOffset, + VIA_GEM_32bpp, 4, pVia->curMarker, + (0xF0 << 24) | VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT); + ADVANCE_RING; + } + return pVia->curMarker; +} + +/* + * Wait for the value to get blitted, or in the PCI case for engine idle. + */ + +void +viaAccelWaitMarker(ScreenPtr pScreen, int marker) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + CARD32 uMarker = marker; + + if (pVia->agpDMA) { + while ((pVia->lastMarkerRead - uMarker) > (1 << 24)) + pVia->lastMarkerRead = *pVia->markerBuf; + } else { + viaAccelSync(pScrn); + } +} + +#ifdef VIA_HAVE_EXA + +/* + * Exa functions. It is assumed that EXA does not exceed the blitter limits. + */ + +static Bool +viaExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg) +{ + ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + + RING_VARS; + + if (exaGetPixmapPitch(pPixmap) & 7) + return FALSE; + + if (!viaAccelSetMode(pPixmap->drawable.depth, tdc)) + return FALSE; + + if (!viaAccelPlaneMaskHelper(tdc, planeMask)) + return FALSE; + viaAccelTransparentHelper(tdc, cb, 0x0, 0x0, TRUE); + + tdc->cmd = VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | VIAACCELPATTERNROP(alu); + + tdc->fgColor = fg; + + return TRUE; +} + +static void +viaExaSolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) +{ + ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + CARD32 dstPitch, dstOffset; + + RING_VARS; + + int w = x2 - x1, h = y2 - y1; + + dstPitch = exaGetPixmapPitch(pPixmap); + dstOffset = exaGetPixmapOffset(pPixmap); + + viaAccelSolidHelper(cb, x1, y1, w, h, dstOffset, + tdc->mode, dstPitch, tdc->fgColor, tdc->cmd); + ADVANCE_RING; +} + +static void +viaExaDoneSolidCopy(PixmapPtr pPixmap) +{ +} + +static Bool +viaExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, + int ydir, int alu, Pixel planeMask) +{ + ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + + RING_VARS; + + if (pSrcPixmap->drawable.bitsPerPixel != + pDstPixmap->drawable.bitsPerPixel) + return FALSE; + + if ((tdc->srcPitch = exaGetPixmapPitch(pSrcPixmap)) & 3) + return FALSE; + + if (exaGetPixmapPitch(pDstPixmap) & 7) + return FALSE; + + tdc->srcOffset = exaGetPixmapOffset(pSrcPixmap); + + tdc->cmd = VIA_GEC_BLT | VIAACCELCOPYROP(alu); + if (xdir < 0) + tdc->cmd |= VIA_GEC_DECX; + if (ydir < 0) + tdc->cmd |= VIA_GEC_DECY; + + if (!viaAccelSetMode(pDstPixmap->drawable.bitsPerPixel, tdc)) + return FALSE; + + if (!viaAccelPlaneMaskHelper(tdc, planeMask)) + return FALSE; + viaAccelTransparentHelper(tdc, cb, 0x0, 0x0, TRUE); + + return TRUE; +} + +static void +viaExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, + int width, int height) +{ + ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + CARD32 srcOffset = tdc->srcOffset; + CARD32 dstOffset = exaGetPixmapOffset(pDstPixmap); + + RING_VARS; + + if (!width || !height) + return; + + viaAccelCopyHelper(cb, srcX, srcY, dstX, dstY, width, height, + srcOffset, dstOffset, tdc->mode, tdc->srcPitch, + exaGetPixmapPitch(pDstPixmap), tdc->cmd); + ADVANCE_RING; +} + +#ifdef VIA_DEBUG_COMPOSITE +static void +viaExaCompositePictDesc(PicturePtr pict, char *string, int n) +{ + char format[20]; + char size[20]; + + if (!pict) { + snprintf(string, n, "None"); + return; + } + + switch (pict->format) { + case PICT_x8r8g8b8: + snprintf(format, 20, "RGB8888"); + break; + case PICT_a8r8g8b8: + snprintf(format, 20, "ARGB8888"); + break; + case PICT_r5g6b5: + snprintf(format, 20, "RGB565 "); + break; + case PICT_x1r5g5b5: + snprintf(format, 20, "RGB555 "); + break; + case PICT_a8: + snprintf(format, 20, "A8 "); + break; + case PICT_a1: + snprintf(format, 20, "A1 "); + break; + default: + snprintf(format, 20, "0x%x", (int)pict->format); + break; + } + + snprintf(size, 20, "%dx%d%s", pict->pDrawable->width, + pict->pDrawable->height, pict->repeat ? " R" : ""); + + snprintf(string, n, "0x%lx: fmt %s (%s)", (long)pict->pDrawable, format, + size); +} + +static void +viaExaPrintComposite(CARD8 op, + PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst) +{ + char sop[20]; + char srcdesc[40], maskdesc[40], dstdesc[40]; + + switch (op) { + case PictOpSrc: + sprintf(sop, "Src"); + break; + case PictOpOver: + sprintf(sop, "Over"); + break; + default: + sprintf(sop, "0x%x", (int)op); + break; + } + + viaExaCompositePictDesc(pSrc, srcdesc, 40); + viaExaCompositePictDesc(pMask, maskdesc, 40); + viaExaCompositePictDesc(pDst, dstdesc, 40); + + ErrorF("Composite fallback: op %s, \n" + " src %s, \n" + " mask %s, \n" + " dst %s, \n", sop, srcdesc, maskdesc, dstdesc); +} +#endif /* VIA_DEBUG_COMPOSITE */ + +/* + * Helper for bitdepth expansion. + */ + +static CARD32 +viaBitExpandHelper(CARD32 component, CARD32 bits) +{ + CARD32 tmp, mask; + + mask = (1 << (8 - bits)) - 1; + tmp = component << (8 - bits); + return ((component & 1) ? tmp | mask : tmp); +} + +/* + * Extract the components from a pixel of format "format" to an + * argb8888 pixel. This is used to extract data from one-pixel repeat pixmaps. + * Assumes little endian. + */ + +static void +viaPixelARGB8888(unsigned format, void *pixelP, CARD32 * argb8888) +{ + CARD32 bits, shift, pixel, bpp; + + bpp = PICT_FORMAT_BPP(format); + + if (bpp <= 8) { + pixel = *((CARD8 *) pixelP); + } else if (bpp <= 16) { + pixel = *((CARD16 *) pixelP); + } else { + pixel = *((CARD32 *) pixelP); + } + + switch (PICT_FORMAT_TYPE(format)) { + case PICT_TYPE_A: + bits = PICT_FORMAT_A(format); + *argb8888 = viaBitExpandHelper(pixel & ((1 << bits) - 1), bits) << 24; + return; + case PICT_TYPE_ARGB: + shift = 0; + bits = PICT_FORMAT_B(format); + *argb8888 = viaBitExpandHelper(pixel & ((1 << bits) - 1), bits); + shift += bits; + bits = PICT_FORMAT_G(format); + *argb8888 |= + viaBitExpandHelper((pixel >> shift) & ((1 << bits) - 1), + bits) << 8; + shift += bits; + bits = PICT_FORMAT_R(format); + *argb8888 |= + viaBitExpandHelper((pixel >> shift) & ((1 << bits) - 1), + bits) << 16; + shift += bits; + bits = PICT_FORMAT_A(format); + *argb8888 |= ((bits) ? + viaBitExpandHelper((pixel >> shift) & ((1 << bits) - 1), + bits) : 0xFF) << 24; + return; + case PICT_TYPE_ABGR: + shift = 0; + bits = PICT_FORMAT_B(format); + *argb8888 = viaBitExpandHelper(pixel & ((1 << bits) - 1), bits) << 16; + shift += bits; + bits = PICT_FORMAT_G(format); + *argb8888 |= + viaBitExpandHelper((pixel >> shift) & ((1 << bits) - 1), + bits) << 8; + shift += bits; + bits = PICT_FORMAT_R(format); + *argb8888 |= + viaBitExpandHelper((pixel >> shift) & ((1 << bits) - 1), bits); + shift += bits; + bits = PICT_FORMAT_A(format); + *argb8888 |= ((bits) ? + viaBitExpandHelper((pixel >> shift) & ((1 << bits) - 1), + bits) : 0xFF) << 24; + return; + default: + break; + } + return; +} + +/* + * Check if the above function will work. + */ + +static Bool +viaExpandablePixel(int format) +{ + int formatType = PICT_FORMAT_TYPE(format); + + return (formatType == PICT_TYPE_A || + formatType == PICT_TYPE_ABGR || formatType == PICT_TYPE_ARGB); +} + +/* + * Check if we need to force upload of the whole 3D state (when other + * clients or subsystems have touched the 3D engine). Also tell DRI + * clients and subsystems that we have touched the 3D engine. + */ + +static Bool +viaCheckUpload(ScrnInfoPtr pScrn, Via3DState * v3d) +{ + VIAPtr pVia = VIAPTR(pScrn); + Bool forceUpload; + + forceUpload = (pVia->lastToUpload != v3d); + pVia->lastToUpload = v3d; + +#ifdef XF86DRI + if (pVia->directRenderingEnabled) { + volatile drm_via_sarea_t *saPriv = (drm_via_sarea_t *) + DRIGetSAREAPrivate(pScrn->pScreen); + int myContext = DRIGetContext(pScrn->pScreen); + + forceUpload = forceUpload || (saPriv->ctxOwner != myContext); + saPriv->ctxOwner = myContext; + } +#endif + return forceUpload; +} + +static Bool +viaOrder(CARD32 val, CARD32 * shift) +{ + *shift = 0; + + while (val > (1 << *shift)) + (*shift)++; + return (val == (1 << *shift)); +} + +#ifdef XF86DRI + +static int +viaAccelDMADownload(ScrnInfoPtr pScrn, unsigned long fbOffset, + unsigned srcPitch, unsigned char *dst, + unsigned dstPitch, unsigned w, unsigned h) +{ + VIAPtr pVia = VIAPTR(pScrn); + drm_via_dmablit_t blit[2], *curBlit; + unsigned char *sysAligned = NULL; + Bool doSync[2], useBounceBuffer; + unsigned pitch, numLines[2]; + int curBuf, err, i, ret, blitHeight; + + ret = 0; + + useBounceBuffer = (((unsigned long)dst & 15) || (dstPitch & 15)); + doSync[0] = FALSE; + doSync[1] = FALSE; + curBuf = 1; + blitHeight = h; + pitch = dstPitch; + if (useBounceBuffer) { + pitch = ALIGN_TO(dstPitch, 16); + blitHeight = VIA_DMA_DL_SIZE / pitch; + } + + while (doSync[0] || doSync[1] || h != 0) { + curBuf = 1 - curBuf; + curBlit = &blit[curBuf]; + if (doSync[curBuf]) { + + do { + err = drmCommandWrite(pVia->drmFD, DRM_VIA_BLIT_SYNC, + &curBlit->sync, sizeof(curBlit->sync)); + } while (err == -EAGAIN); + + if (err) + return err; + + doSync[curBuf] = FALSE; + if (useBounceBuffer) { + for (i = 0; i < numLines[curBuf]; ++i) { + memcpy(dst, curBlit->mem_addr, w); + dst += dstPitch; + curBlit->mem_addr += pitch; + } + } + } + + if (h == 0) + continue; + + curBlit->num_lines = (h > blitHeight) ? blitHeight : h; + h -= curBlit->num_lines; + numLines[curBuf] = curBlit->num_lines; + + sysAligned = + (unsigned char *)pVia->dBounce + (curBuf * VIA_DMA_DL_SIZE); + sysAligned = (unsigned char *) + ALIGN_TO((unsigned long)sysAligned, 16); + + curBlit->mem_addr = (useBounceBuffer) ? sysAligned : dst; + curBlit->line_length = w; + curBlit->mem_stride = pitch; + curBlit->fb_addr = fbOffset; + curBlit->fb_stride = srcPitch; + curBlit->to_fb = 0; + fbOffset += curBlit->num_lines * srcPitch; + + do { + err = drmCommandWriteRead(pVia->drmFD, DRM_VIA_DMA_BLIT, curBlit, + sizeof(*curBlit)); + } while (err == -EAGAIN); + + if (err) { + ret = err; + h = 0; + continue; + } + + doSync[curBuf] = TRUE; + } + + return ret; +} + +/* + * Use PCI DMA if we can. If the system alignments don't match, we're using + * an aligned bounce buffer for pipelined PCI DMA and memcpy. + * Throughput for large transfers is around 65 MB/s. + */ + +static Bool +viaExaDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, + char *dst, int dst_pitch) +{ + ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + unsigned srcPitch = exaGetPixmapPitch(pSrc); + unsigned wBytes = (pSrc->drawable.bitsPerPixel * w + 7) >> 3; + unsigned srcOffset; + char *bounceAligned = NULL; + unsigned totSize; + + if (!w || !h) + return TRUE; + + srcOffset = x * pSrc->drawable.bitsPerPixel; + if (srcOffset & 3) + return FALSE; + srcOffset = exaGetPixmapOffset(pSrc) + y * srcPitch + (srcOffset >> 3); + + totSize = wBytes * h; + + exaWaitSync(pScrn->pScreen); + if (totSize < VIA_MIN_DOWNLOAD) { + bounceAligned = (char *)pVia->FBBase + srcOffset; + while (h--) { + memcpy(dst, bounceAligned, wBytes); + dst += dst_pitch; + bounceAligned += srcPitch; + } + return TRUE; + } + + if (!pVia->directRenderingEnabled) + return FALSE; + + if ((srcPitch & 3) || (srcOffset & 3)) { + ErrorF("VIA EXA download src_pitch misaligned\n"); + return FALSE; + } + + if (viaAccelDMADownload(pScrn, srcOffset, srcPitch, (unsigned char *)dst, + dst_pitch, wBytes, h)) + return FALSE; + + return TRUE; +} + +/* + * Upload to framebuffer memory using memcpy to AGP pipelined with a + * 3D engine texture operation from AGP to framebuffer. The AGP buffers (2) + * should be kept rather small for optimal pipelining. + */ + +static Bool +viaExaTexUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src, + int src_pitch) +{ + ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + unsigned dstPitch = exaGetPixmapPitch(pDst); + unsigned wBytes = (w * pDst->drawable.bitsPerPixel + 7) >> 3; + unsigned dstOffset; + CARD32 texWidth, texHeight, texPitch; + int format; + char *dst; + int i, sync[2], yOffs, bufH, bufOffs, height; + Bool buf; + Via3DState *v3d = &pVia->v3d; + + if (!w || !h) + return TRUE; + + if (wBytes * h < VIA_MIN_TEX_UPLOAD) { + dstOffset = x * pDst->drawable.bitsPerPixel; + if (dstOffset & 3) + return FALSE; + dst = + (char *)pVia->FBBase + (exaGetPixmapOffset(pDst) + y * dstPitch + + (dstOffset >> 3)); + exaWaitSync(pScrn->pScreen); + + while (h--) { + memcpy(dst, src, wBytes); + dst += dstPitch; + src += src_pitch; + } + return TRUE; + } + + if (!pVia->texAddr) + return FALSE; + + switch (pDst->drawable.bitsPerPixel) { + case 32: + format = PICT_a8r8g8b8; + break; + case 16: + format = PICT_r5g6b5; + break; + default: + return FALSE; + } + + dstOffset = exaGetPixmapOffset(pDst); + + if (pVia->nPOT[0]) { + texPitch = ALIGN_TO(wBytes, 32); + height = VIA_AGP_UPL_SIZE / texPitch; + } else { + viaOrder(wBytes, &texPitch); + if (texPitch < 3) + texPitch = 3; + height = VIA_AGP_UPL_SIZE >> texPitch; + texPitch = 1 << texPitch; + } + + if (height > 1024) + height = 1024; + viaOrder(w, &texWidth); + texWidth = 1 << texWidth; + + texHeight = height << 1; + bufOffs = texPitch * height; + + v3d->setDestination(v3d, dstOffset, dstPitch, format); + v3d->setDrawing(v3d, 0x0c, 0xFFFFFFFF, 0x000000FF, 0x00); + v3d->setFlags(v3d, 1, TRUE, TRUE, FALSE); + if (!v3d->setTexture(v3d, 0, pVia->texOffset + pVia->agpAddr, texPitch, + pVia->nPOT[0], texWidth, texHeight, format, via_single, + via_single, via_src, TRUE)) + return FALSE; + + v3d->emitState(v3d, &pVia->cb, viaCheckUpload(pScrn, v3d)); + v3d->emitClipRect(v3d, &pVia->cb, 0, 0, pDst->drawable.width, + pDst->drawable.height); + + buf = 1; + yOffs = 0; + sync[0] = -1; + sync[1] = -1; + + while (h) { + buf = (buf) ? 0 : 1; + bufH = (h > height) ? height : h; + dst = pVia->texAddr + ((buf) ? bufOffs : 0); + + if (sync[buf] >= 0) + viaAccelWaitMarker(pScrn->pScreen, sync[buf]); + + for (i = 0; i < bufH; ++i) { + memcpy(dst, src, wBytes); + dst += texPitch; + src += src_pitch; + } + + v3d->emitQuad(v3d, &pVia->cb, x, y + yOffs, 0, (buf) ? height : 0, 0, + 0, w, bufH); + + sync[buf] = viaAccelMarkSync(pScrn->pScreen); + + h -= bufH; + yOffs += bufH; + } + + if (sync[buf] >= 0) + viaAccelWaitMarker(pScrn->pScreen, sync[buf]); + + return TRUE; +} + +/* + * I'm not sure PCI DMA upload is necessary. Seems buggy for widths below 65, + * and I'd guess that in most situations CPU direct writes are faster. + * Use DMA only when alignments match. At least it saves some CPU cycles. + */ + +static Bool +viaExaUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src, + int src_pitch) +{ + ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + drm_via_dmablit_t blit; + unsigned dstPitch = exaGetPixmapPitch(pDst); + unsigned wBytes = (w * pDst->drawable.bitsPerPixel + 7) >> 3; + unsigned dstOffset; + char *dst; + int err; + + dstOffset = x * pDst->drawable.bitsPerPixel; + if (dstOffset & 3) + return FALSE; + dstOffset = exaGetPixmapOffset(pDst) + y * dstPitch + (dstOffset >> 3); + + if (wBytes * h < VIA_MIN_UPLOAD || wBytes < 65) { + dst = (char *)pVia->FBBase + dstOffset; + + exaWaitSync(pScrn->pScreen); + while (h--) { + memcpy(dst, src, wBytes); + dst += dstPitch; + src += src_pitch; + } + return TRUE; + } + + if (!pVia->directRenderingEnabled) + return FALSE; + + if (((unsigned long)src & 15) || (src_pitch & 15)) + return FALSE; + + if ((dstPitch & 3) || (dstOffset & 3)) + return FALSE; + + blit.line_length = wBytes; + blit.num_lines = h; + blit.fb_addr = dstOffset; + blit.fb_stride = dstPitch; + blit.mem_addr = (unsigned char *)src; + blit.mem_stride = src_pitch; + blit.to_fb = 1; + + exaWaitSync(pScrn->pScreen); + while (-EAGAIN == (err = + drmCommandWriteRead(pVia->drmFD, DRM_VIA_DMA_BLIT, &blit, + sizeof(blit)))) ; + if (err < 0) + return FALSE; + + while (-EAGAIN == (err = drmCommandWrite(pVia->drmFD, DRM_VIA_BLIT_SYNC, + &blit.sync, sizeof(blit.sync)))) ; + return (err == 0); +} + +#endif /* XF86DRI */ + +static Bool +viaExaUploadToScratch(PixmapPtr pSrc, PixmapPtr pDst) +{ + + ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + char *src, *dst; + unsigned w, wBytes, srcPitch, h; + CARD32 dstPitch; + + if (!pVia->scratchAddr) + return FALSE; + + *pDst = *pSrc; + w = pSrc->drawable.width; + h = pSrc->drawable.height; + wBytes = (w * pSrc->drawable.bitsPerPixel + 7) >> 3; + + viaOrder(wBytes, &dstPitch); + dstPitch = 1 << dstPitch; + if (dstPitch < 8) + dstPitch = 8; + if (dstPitch * h > pVia->exaScratchSize * 1024) { + ErrorF("EXA UploadToScratch Failed %u %u %u %u\n", + dstPitch, h, dstPitch * h, pVia->exaScratchSize * 1024); + return FALSE; + } + + pDst->devKind = dstPitch; + pDst->devPrivate.ptr = dst = pVia->scratchAddr; + src = pSrc->devPrivate.ptr; + srcPitch = exaGetPixmapPitch(pSrc); + + /* + * Copying to AGP needs not be HW accelerated. + * If scratch is in FB, we are without DRI and HW accel. + */ + + viaAccelSync(pScrn); + + while (h--) { + memcpy(dst, src, wBytes); + dst += dstPitch; + src += srcPitch; + } + + return TRUE; +} + +static Bool +viaExaCheckComposite(int op, PicturePtr pSrcPicture, + PicturePtr pMaskPicture, PicturePtr pDstPicture) +{ + + ScrnInfoPtr pScrn = xf86Screens[pDstPicture->pDrawable->pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + Via3DState *v3d = &pVia->v3d; + + /* + * Reject small composites early. They are done much faster in software. + */ + + if (!pSrcPicture->repeat && + pSrcPicture->pDrawable->width * + pSrcPicture->pDrawable->height < VIA_MIN_COMPOSITE) + return FALSE; + + if (pMaskPicture && + !pMaskPicture->repeat && + pMaskPicture->pDrawable->width * + pMaskPicture->pDrawable->height < VIA_MIN_COMPOSITE) + return FALSE; + + if (pMaskPicture && pMaskPicture->componentAlpha) { +#ifdef VIA_DEBUG_COMPOSITE + ErrorF("Component Alpha operation\n"); +#endif + return FALSE; + } + + if (!v3d->opSupported(op)) { +#ifdef VIA_DEBUG_COMPOSITE +#warning Composite verbose debug turned on. + ErrorF("Operator not supported\n"); + viaExaPrintComposite(op, pSrcPicture, pMaskPicture, pDstPicture); +#endif + return FALSE; + } + + /* + * FIXME: A8 destination formats are currently not supported and do not + * seem supported by the hardware, although there are some leftover + * register settings apparent in the via_3d_reg.h file. We need to fix this + * (if important), by using component ARGB8888 operations with bitmask. + */ + + if (!v3d->dstSupported(pDstPicture->format)) { +#ifdef VIA_DEBUG_COMPOSITE + ErrorF("Destination format not supported:\n"); + viaExaPrintComposite(op, pSrcPicture, pMaskPicture, pDstPicture); +#endif + return FALSE; + } + + if (v3d->texSupported(pSrcPicture->format)) { + if (pMaskPicture && (PICT_FORMAT_A(pMaskPicture->format) == 0 || + !v3d->texSupported(pMaskPicture->format))) { +#ifdef VIA_DEBUG_COMPOSITE + ErrorF("Mask format not supported:\n"); + viaExaPrintComposite(op, pSrcPicture, pMaskPicture, pDstPicture); +#endif + return FALSE; + } + return TRUE; + } +#ifdef VIA_DEBUG_COMPOSITE + ErrorF("Src format not supported:\n"); + viaExaPrintComposite(op, pSrcPicture, pMaskPicture, pDstPicture); +#endif + return FALSE; +} + +static Bool +viaIsAGP(VIAPtr pVia, PixmapPtr pPix, unsigned long *offset) +{ +#ifdef XF86DRI + unsigned long offs; + + if (pVia->directRenderingEnabled && !pVia->IsPCI) { + offs = (unsigned long)pPix->devPrivate.ptr - + (unsigned long)pVia->agpMappedAddr; + + if ((offs - pVia->scratchOffset) < pVia->agpSize) { + *offset = offs + pVia->agpAddr; + return TRUE; + } + } +#endif + return FALSE; +} + +static Bool +viaIsOffscreen(VIAPtr pVia, PixmapPtr pPix) +{ + return ((unsigned long)pPix->devPrivate.ptr - + (unsigned long)pVia->FBBase) < pVia->videoRambytes; +} + +static Bool +viaExaPrepareComposite(int op, PicturePtr pSrcPicture, + PicturePtr pMaskPicture, PicturePtr pDstPicture, + PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst) +{ + CARD32 height, width; + ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + Via3DState *v3d = &pVia->v3d; + int curTex = 0; + ViaTexBlendingModes srcMode; + Bool isAGP; + unsigned long offset; + + v3d->setDestination(v3d, exaGetPixmapOffset(pDst), + exaGetPixmapPitch(pDst), pDstPicture->format); + v3d->setCompositeOperator(v3d, op); + v3d->setDrawing(v3d, 0x0c, 0xFFFFFFFF, 0x000000FF, 0xFF); + + viaOrder(pSrc->drawable.width, &width); + viaOrder(pSrc->drawable.height, &height); + + /* + * For one-pixel repeat mask pictures we avoid using multitexturing by + * modifying the src's texture blending equation and feed the pixel + * value as a constant alpha for the src's texture. Multitexturing on the + * unichromes seems somewhat slow, so this speeds up translucent windows. + */ + + srcMode = via_src; + pVia->maskP = NULL; + if (pMaskPicture && + (pMaskPicture->pDrawable->height == 1) && + (pMaskPicture->pDrawable->width == 1) && + pMaskPicture->repeat && viaExpandablePixel(pMaskPicture->format)) { + pVia->maskP = pMask->devPrivate.ptr; + pVia->maskFormat = pMaskPicture->format; + pVia->componentAlpha = pMaskPicture->componentAlpha; + srcMode = + (pMaskPicture-> + componentAlpha) ? via_src_onepix_comp_mask : via_src_onepix_mask; + } + + /* + * One-Pixel repeat src pictures go as solid color instead of textures. + * Speeds up window shadows. + */ + + pVia->srcP = NULL; + if (pSrcPicture && + (pSrcPicture->pDrawable->height == 1) && + (pSrcPicture->pDrawable->width == 1) && + pSrcPicture->repeat && viaExpandablePixel(pSrcPicture->format)) { + pVia->srcP = pSrc->devPrivate.ptr; + pVia->srcFormat = pSrcPicture->format; + } + + /* + * Exa should be smart enough to eliminate this IN operation. + */ + + if (pVia->srcP && pVia->maskP) { + ErrorF + ("Bad one-pixel IN composite operation. EXA needs to be smarter.\n"); + return FALSE; + } + + if (!pVia->srcP) { + offset = exaGetPixmapOffset(pSrc); + isAGP = viaIsAGP(pVia, pSrc, &offset); + if (!isAGP && !viaIsOffscreen(pVia, pSrc)) + return FALSE; + if (!v3d->setTexture(v3d, curTex, offset, + exaGetPixmapPitch(pSrc), pVia->nPOT[curTex], 1 << width, + 1 << height, pSrcPicture->format, via_repeat, via_repeat, + srcMode, isAGP)) { + return FALSE; + } + curTex++; + } + + if (pMaskPicture && !pVia->maskP) { + offset = exaGetPixmapOffset(pMask); + isAGP = viaIsAGP(pVia, pMask, &offset); + if (!isAGP && !viaIsOffscreen(pVia, pMask)) + return FALSE; + viaOrder(pMask->drawable.width, &width); + viaOrder(pMask->drawable.height, &height); + if (!v3d->setTexture(v3d, curTex, offset, + exaGetPixmapPitch(pMask), pVia->nPOT[curTex], 1 << width, + 1 << height, pMaskPicture->format, via_repeat, via_repeat, + (pMaskPicture->componentAlpha) ? via_comp_mask : via_mask, + isAGP)) { + return FALSE; + } + curTex++; + } + + v3d->setFlags(v3d, curTex, FALSE, TRUE, TRUE); + v3d->emitState(v3d, &pVia->cb, viaCheckUpload(pScrn, v3d)); + v3d->emitClipRect(v3d, &pVia->cb, 0, 0, pDst->drawable.width, + pDst->drawable.height); + + return TRUE; +} + +static void +viaExaComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, + int dstX, int dstY, int width, int height) +{ + ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + Via3DState *v3d = &pVia->v3d; + CARD32 col; + + if (pVia->maskP) { + viaPixelARGB8888(pVia->maskFormat, pVia->maskP, &col); + v3d->setTexBlendCol(v3d, 0, pVia->componentAlpha, col); + } + if (pVia->srcP) { + viaPixelARGB8888(pVia->srcFormat, pVia->srcP, &col); + v3d->setDrawing(v3d, 0x0c, 0xFFFFFFFF, col & 0x00FFFFFF, col >> 24); + srcX = maskX; + srcY = maskY; + } + + if (pVia->maskP || pVia->srcP) + v3d->emitState(v3d, &pVia->cb, viaCheckUpload(pScrn, v3d)); + + v3d->emitQuad(v3d, &pVia->cb, dstX, dstY, srcX, srcY, maskX, maskY, width, + height); +} + +#if (EXA_VERSION_MAJOR >= 2) + +static ExaDriverPtr +viaInitExa(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + ExaDriverPtr pExa = exaDriverAlloc(); + + memset(pExa, 0, sizeof(*pExa)); + + if (!pExa) + return NULL; + + pExa->exa_major = EXA_VERSION_MAJOR; + pExa->exa_minor = EXA_VERSION_MINOR; + pExa->memoryBase = pVia->FBBase; + pExa->memorySize = pVia->FBFreeEnd; + pExa->offScreenBase = pScrn->virtualY * pVia->Bpl; + pExa->pixmapOffsetAlign = 32; + pExa->pixmapPitchAlign = 16; + pExa->flags = EXA_OFFSCREEN_PIXMAPS | + (pVia->nPOT[1] ? 0 : EXA_OFFSCREEN_ALIGN_POT); + pExa->maxX = 2047; + pExa->maxY = 2047; + pExa->WaitMarker = viaAccelWaitMarker; + pExa->MarkSync = viaAccelMarkSync; + pExa->PrepareSolid = viaExaPrepareSolid; + pExa->Solid = viaExaSolid; + pExa->DoneSolid = viaExaDoneSolidCopy; + pExa->PrepareCopy = viaExaPrepareCopy; + pExa->Copy = viaExaCopy; + pExa->DoneCopy = viaExaDoneSolidCopy; + +#ifdef XF86DRI + if (pVia->directRenderingEnabled) { +#ifdef linux + if ((pVia->drmVerMajor > 2) || + ((pVia->drmVerMajor == 2) && (pVia->drmVerMinor >= 7))) { + pExa->DownloadFromScreen = viaExaDownloadFromScreen; + } +#endif /* linux */ + switch (pVia->Chipset) { + case VIA_K8M800: + case VIA_KM400: + pExa->UploadToScreen = viaExaTexUploadToScreen; + break; + default: + pExa->UploadToScreen = NULL; + break; + } + } +#endif /* XF86DRI */ + + pExa->UploadToScratch = viaExaUploadToScratch; + + if (!pVia->noComposite) { + pExa->CheckComposite = viaExaCheckComposite; + pExa->PrepareComposite = viaExaPrepareComposite; + pExa->Composite = viaExaComposite; + pExa->DoneComposite = viaExaDoneSolidCopy; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[EXA] Disabling EXA accelerated composite.\n"); + } + + + if (!exaDriverInit(pScreen, pExa)) { + xfree(pExa); + return NULL; + } + + viaInit3DState(&pVia->v3d); + return pExa; +} + +#else + +/* + * Init EXA. Alignments are 2D engine constraints. + */ + +static ExaDriverPtr +viaInitExa(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + ExaDriverPtr pExa = (ExaDriverPtr) xnfcalloc(sizeof(ExaDriverRec), 1); + + if (!pExa) + return NULL; + + pExa->card.memoryBase = pVia->FBBase; + pExa->card.memorySize = pVia->FBFreeEnd; + pExa->card.offScreenBase = pScrn->virtualY * pVia->Bpl; + pExa->card.pixmapOffsetAlign = 32; + pExa->card.pixmapPitchAlign = 16; + pExa->card.flags = EXA_OFFSCREEN_PIXMAPS | + (pVia->nPOT[1] ? 0 : EXA_OFFSCREEN_ALIGN_POT); + pExa->card.maxX = 2047; + pExa->card.maxY = 2047; + + pExa->accel.WaitMarker = viaAccelWaitMarker; + pExa->accel.MarkSync = viaAccelMarkSync; + pExa->accel.PrepareSolid = viaExaPrepareSolid; + pExa->accel.Solid = viaExaSolid; + pExa->accel.DoneSolid = viaExaDoneSolidCopy; + pExa->accel.PrepareCopy = viaExaPrepareCopy; + pExa->accel.Copy = viaExaCopy; + pExa->accel.DoneCopy = viaExaDoneSolidCopy; + +#ifdef XF86DRI + if (pVia->directRenderingEnabled) { +#ifdef linux + if ((pVia->drmVerMajor > 2) || + ((pVia->drmVerMajor == 2) && (pVia->drmVerMinor >= 7))) { + if (pVia->Chipset != VIA_K8M800) + pExa->accel.UploadToScreen = viaExaUploadToScreen; + pExa->accel.DownloadFromScreen = viaExaDownloadFromScreen; + } +#endif /* linux */ + if (pVia->Chipset == VIA_K8M800) + pExa->accel.UploadToScreen = viaExaTexUploadToScreen; + } +#endif /* XF86DRI */ + + pExa->accel.UploadToScratch = viaExaUploadToScratch; + + if (!pVia->noComposite) { + pExa->accel.CheckComposite = viaExaCheckComposite; + pExa->accel.PrepareComposite = viaExaPrepareComposite; + pExa->accel.Composite = viaExaComposite; + pExa->accel.DoneComposite = viaExaDoneSolidCopy; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[EXA] Disabling EXA accelerated composite.\n"); + } + + if (!exaDriverInit(pScreen, pExa)) { + xfree(pExa); + return NULL; + } + + viaInit3DState(&pVia->v3d); + return pExa; +} + +#endif /* EXA_VERSION_MAJOR */ +#endif /* VIA_HAVE_EXA */ + +/* + * Acceleration init function. Sets up offscreen memory disposition, initializes engines + * and acceleration method. + */ + +Bool +viaInitAccel(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + BoxRec AvailFBArea; + int maxY; + Bool nPOTSupported; + + pVia->VQStart = 0; + if (((pVia->FBFreeEnd - pVia->FBFreeStart) >= VIA_VQ_SIZE) && + pVia->VQEnable) { + pVia->VQStart = pVia->FBFreeEnd - VIA_VQ_SIZE; + pVia->VQEnd = pVia->VQStart + VIA_VQ_SIZE - 1; + pVia->FBFreeEnd -= VIA_VQ_SIZE; + } + + if (pVia->hwcursor) { + pVia->FBFreeEnd -= VIA_CURSOR_SIZE; + pVia->CursorStart = pVia->FBFreeEnd; + } + + viaInitialize2DEngine(pScrn); + + /* + * Sync marker space. + */ + + pVia->FBFreeEnd -= 32; + pVia->markerOffset = (pVia->FBFreeEnd + 31) & ~31; + pVia->markerBuf = (CARD32 *) ((char *)pVia->FBBase + pVia->markerOffset); + *pVia->markerBuf = 0; + pVia->curMarker = 0; + pVia->lastMarkerRead = 0; + + /* + * nPOT textures. DRM versions below 2.11.0 don't allow them. + * Also some CLE266 hardware may not allow nPOT textures for + * texture engine 1. We need to figure that out. + */ + + nPOTSupported = TRUE; +#ifdef XF86DRI + nPOTSupported = (!pVia->directRenderingEnabled) || + (pVia->drmVerMajor > 2) || + ((pVia->drmVerMajor == 2) && (pVia->drmVerMinor >= 11)); +#endif + pVia->nPOT[0] = nPOTSupported; + pVia->nPOT[1] = nPOTSupported; + +#ifdef VIA_HAVE_EXA +#ifdef XF86DRI + pVia->texAddr = NULL; + pVia->dBounce = NULL; + pVia->scratchAddr = NULL; +#endif /* XF86DRI */ + if (pVia->useEXA) { + pVia->exaDriverPtr = viaInitExa(pScreen); + if (!pVia->exaDriverPtr) { + + /* + * Docs recommend turning off also Xv here, but we handle this + * case with the old linear offscreen FB manager through + * VIAInitLinear. + */ + + pVia->NoAccel = TRUE; + return FALSE; + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[EXA] Trying to enable EXA acceleration.\n"); + + pVia->driSize = (pVia->FBFreeEnd - pVia->FBFreeStart) / 2; + + if ((pVia->driSize > (pVia->maxDriSize * 1024)) + && pVia->maxDriSize > 0) + pVia->driSize = pVia->maxDriSize * 1024; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[EXA] Enabled EXA acceleration.\n"); + return TRUE; + } +#endif /* VIA_HAVE_EXA */ + + AvailFBArea.x1 = 0; + AvailFBArea.y1 = 0; + AvailFBArea.x2 = pScrn->displayWidth; + + /* + * Memory distribution for XAA is tricky. We'd like to make the + * pixmap cache no larger than 3 x visible screen size, otherwise + * XAA may get slow for some undetermined reason. + */ + +#ifdef XF86DRI + if (pVia->directRenderingEnabled) { + pVia->driSize = (pVia->FBFreeEnd - pVia->FBFreeStart) / 2; + maxY = pScrn->virtualY + (pVia->driSize / pVia->Bpl); + } else +#endif + { + maxY = pVia->FBFreeEnd / pVia->Bpl; + } + if (maxY > 4 * pScrn->virtualY) + maxY = 4 * pScrn->virtualY; + + pVia->FBFreeStart = (maxY + 1) * pVia->Bpl; + + AvailFBArea.y2 = maxY; + xf86InitFBManager(pScreen, &AvailFBArea); + VIAInitLinear(pScreen); + + pVia->driSize = (pVia->FBFreeEnd - pVia->FBFreeStart - pVia->Bpl); + if ((pVia->driSize > (pVia->maxDriSize * 1024)) && pVia->maxDriSize > 0) + pVia->driSize = pVia->maxDriSize * 1024; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d lines for offscreen memory.\n", + AvailFBArea.y2 - pScrn->virtualY)); + + return viaInitXAA(pScreen); +} + +/* + * Free the used acceleration resources. + */ + +void +viaExitAccel(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + + viaAccelSync(pScrn); + viaTearDownCBuffer(&pVia->cb); + +#ifdef VIA_HAVE_EXA + if (pVia->useEXA) { +#ifdef XF86DRI + if (pVia->directRenderingEnabled) { + if (pVia->texAddr) { + drmCommandWrite(pVia->drmFD, DRM_VIA_FREEMEM, + &pVia->texAGPBuffer, sizeof(drm_via_mem_t)); + pVia->texAddr = NULL; + } + if (pVia->scratchAddr && !pVia->IsPCI && + ((unsigned long)pVia->scratchAddr - + (unsigned long)pVia->agpMappedAddr == + pVia->scratchOffset)) { + drmCommandWrite(pVia->drmFD, DRM_VIA_FREEMEM, + &pVia->scratchAGPBuffer, sizeof(drm_via_mem_t)); + pVia->scratchAddr = NULL; + } + } + if (pVia->dBounce) + xfree(pVia->dBounce); +#endif /* XF86DRI */ + if (pVia->scratchAddr) { + exaOffscreenFree(pScreen, pVia->scratchFBBuffer); + pVia->scratchAddr = NULL; + } + if (pVia->exaDriverPtr) { + exaDriverFini(pScreen); + } + xfree(pVia->exaDriverPtr); + pVia->exaDriverPtr = NULL; + return; + } +#endif /* VIA_HAVE_EXA */ + if (pVia->AccelInfoRec) { + XAADestroyInfoRec(pVia->AccelInfoRec); + pVia->AccelInfoRec = NULL; + } +} + +/* + * Allocate a command buffer and buffers for accelerated upload, download, + * and EXA scratch area. The scratch area resides primarily in AGP memory, + * but reverts to FB if AGP is not available. + */ + +void +viaFinishInitAccel(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + +#ifdef VIA_HAVE_EXA +#ifdef XF86DRI + int size, ret; + + if (pVia->directRenderingEnabled && pVia->useEXA) { + + pVia->dBounce = xcalloc(VIA_DMA_DL_SIZE * 2, 1); + + if (!pVia->IsPCI) { + + /* + * Allocate upload and scratch space. + */ +#if (EXA_VERSION_MAJOR >= 2) + if (pVia->exaDriverPtr->UploadToScreen == viaExaTexUploadToScreen) { +#else + if (pVia->exaDriverPtr->accel.UploadToScreen == + viaExaTexUploadToScreen) { +#endif + size = VIA_AGP_UPL_SIZE * 2 + 32; + pVia->texAGPBuffer.context = 1; + pVia->texAGPBuffer.size = size; + pVia->texAGPBuffer.type = VIA_MEM_AGP; + ret = + drmCommandWriteRead(pVia->drmFD, DRM_VIA_ALLOCMEM, + &pVia->texAGPBuffer, sizeof(drm_via_mem_t)); + + if (ret || size != pVia->texAGPBuffer.size) { + pVia->texAGPBuffer.size = 0; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Allocated %u kiB of AGP memory for system to frame-buffer transfer.\n", + size / 1024); + pVia->texOffset = (pVia->texAGPBuffer.offset + 31) & ~31; + pVia->texAddr = + (char *)pVia->agpMappedAddr + pVia->texOffset; + } + + } + + size = pVia->exaScratchSize * 1024 + 32; + pVia->scratchAGPBuffer.context = 1; + pVia->scratchAGPBuffer.size = size; + pVia->scratchAGPBuffer.type = VIA_MEM_AGP; + ret = + drmCommandWriteRead(pVia->drmFD, DRM_VIA_ALLOCMEM, + &pVia->scratchAGPBuffer, sizeof(drm_via_mem_t)); + if (ret || size != pVia->scratchAGPBuffer.size) { + pVia->scratchAGPBuffer.size = 0; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Allocated %u kiB of AGP memory for EXA scratch area.\n", + size / 1024); + pVia->scratchOffset = + (pVia->scratchAGPBuffer.offset + 31) & ~31; + pVia->scratchAddr = + (char *)pVia->agpMappedAddr + pVia->scratchOffset; + } + + } + } +#endif /* XF86DRI */ + if (!pVia->scratchAddr && pVia->useEXA) { + + pVia->scratchFBBuffer = + exaOffscreenAlloc(pScreen, pVia->exaScratchSize * 1024, + 32, TRUE, NULL, NULL); + if (pVia->scratchFBBuffer) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Allocated %u kiB of framebuffer memory for EXA scratch area.\n", + pVia->exaScratchSize); + pVia->scratchOffset = pVia->scratchFBBuffer->offset; + pVia->scratchAddr = (char *)pVia->FBBase + pVia->scratchOffset; + } + + } +#endif /* VIA_HAVE_EXA */ + if (Success != viaSetupCBuffer(pScrn, &pVia->cb, 0)) { + pVia->NoAccel = TRUE; + viaExitAccel(pScreen); + return; + } +} + +/* + * DGA accelerated functions go here and let them be independent of acceleration + * method. + */ + +void +viaAccelBlitRect(ScrnInfoPtr pScrn, int srcx, int srcy, int w, int h, + int dstx, int dsty) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + unsigned dstOffset = pScrn->fbOffset + dsty * pVia->Bpl; + unsigned srcOffset = pScrn->fbOffset + srcy * pVia->Bpl; + + RING_VARS; + + if (!w || !h) + return; + + if (!pVia->NoAccel) { + + int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; + int ydir = (srcy < dsty) ? -1 : 1; + CARD32 cmd = VIA_GEC_BLT | VIAACCELCOPYROP(GXcopy); + + if (xdir < 0) + cmd |= VIA_GEC_DECX; + if (ydir < 0) + cmd |= VIA_GEC_DECY; + + viaAccelSetMode(pScrn->bitsPerPixel, tdc); + viaAccelTransparentHelper(tdc, cb, 0x0, 0x0, FALSE); + viaAccelCopyHelper(cb, srcx, 0, dstx, 0, w, h, srcOffset, dstOffset, + tdc->mode, pVia->Bpl, pVia->Bpl, cmd); + pVia->accelMarker = viaAccelMarkSync(pScrn->pScreen); + ADVANCE_RING; + } +} + +void +viaAccelFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h, + unsigned long color) +{ + VIAPtr pVia = VIAPTR(pScrn); + unsigned dstBase = pScrn->fbOffset + y * pVia->Bpl; + ViaTwodContext *tdc = &pVia->td; + CARD32 cmd = VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | + VIAACCELPATTERNROP(GXcopy); + RING_VARS; + + if (!w || !h) + return; + + if (!pVia->NoAccel) { + viaAccelSetMode(pScrn->bitsPerPixel, tdc); + viaAccelTransparentHelper(tdc, cb, 0x0, 0x0, FALSE); + viaAccelSolidHelper(cb, x, 0, w, h, dstBase, tdc->mode, + pVia->Bpl, color, cmd); + pVia->accelMarker = viaAccelMarkSync(pScrn->pScreen); + ADVANCE_RING; + } +} + +void +viaAccelFillPixmap(ScrnInfoPtr pScrn, + unsigned long offset, + unsigned long pitch, + int depth, int x, int y, int w, int h, unsigned long color) +{ + VIAPtr pVia = VIAPTR(pScrn); + unsigned dstBase = offset + y * pitch; + ViaTwodContext *tdc = &pVia->td; + CARD32 cmd = VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | + VIAACCELPATTERNROP(GXcopy); + RING_VARS; + + if (!w || !h) + return; + + if (!pVia->NoAccel) { + viaAccelSetMode(depth, tdc); + viaAccelTransparentHelper(tdc, cb, 0x0, 0x0, FALSE); + viaAccelSolidHelper(cb, x, 0, w, h, dstBase, tdc->mode, + pitch, color, cmd); + pVia->accelMarker = viaAccelMarkSync(pScrn->pScreen); + ADVANCE_RING; + } +} + +void +viaAccelSyncMarker(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + + viaAccelWaitMarker(pScrn->pScreen, pVia->accelMarker); +} + +void +viaAccelTextureBlit(ScrnInfoPtr pScrn, unsigned long srcOffset, + unsigned srcPitch, unsigned w, unsigned h, unsigned srcX, unsigned srcY, + unsigned srcFormat, unsigned long dstOffset, unsigned dstPitch, + unsigned dstX, unsigned dstY, unsigned dstFormat, int rotate) +{ + VIAPtr pVia = VIAPTR(pScrn); + unsigned wOrder, hOrder; + Via3DState *v3d = &pVia->v3d; + + viaOrder(w, &wOrder); + viaOrder(h, &hOrder); + + v3d->setDestination(v3d, dstOffset, dstPitch, dstFormat); + v3d->setDrawing(v3d, 0x0c, 0xFFFFFFFF, 0x000000FF, 0x00); + v3d->setFlags(v3d, 1, TRUE, TRUE, FALSE); + v3d->setTexture(v3d, 0, srcOffset, srcPitch, TRUE, 1 << wOrder, + 1 << hOrder, srcFormat, via_single, via_single, via_src, FALSE); + v3d->emitState(v3d, &pVia->cb, viaCheckUpload(pScrn, v3d)); + v3d->emitClipRect(v3d, &pVia->cb, dstX, dstY, w, h); + v3d->emitQuad(v3d, &pVia->cb, dstX, dstY, srcX, srcY, 0, 0, w, h); +} diff --git a/trunk/src/via_bandwidth.c b/trunk/src/via_bandwidth.c new file mode 100644 index 000000000000..e09ca192d0ff --- /dev/null +++ b/trunk/src/via_bandwidth.c @@ -0,0 +1,401 @@ +/* + * Copyright 2004-2005 The Unichrome Project [unichrome.sf.net] + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. 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, sub license, + * 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 NON-INFRINGEMENT. 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "via_driver.h" +#include "via_vgahw.h" +#include "via_id.h" + +/* + * Now that via_bios is no longer such a behemoth and the relevant + * code is moved via_mode.c, this code should be moved to via_mode.c too + * especially as output abstraction will trim via_mode.c down further + */ + +/* + * + */ +static void +ViaSetCLE266APrimaryFIFO(ScrnInfoPtr pScrn, Bool Enable) +{ + VIAPtr pVia = VIAPTR(pScrn); + CARD32 dwGE230, dwGE298; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaSetCLE266APrimaryFIFO: %d\n", Enable)); + + dwGE298 = VIAGETREG(0x298); + VIASETREG(0x298, dwGE298 | 0x20000000); + + dwGE230 = VIAGETREG(0x230); + if (Enable) + dwGE230 |= 0x00200000; + else + dwGE230 &= ~0x00200000; + VIASETREG(0x230, dwGE230); + + dwGE298 = VIAGETREG(0x298); + VIASETREG(0x298, dwGE298 & ~0x20000000); +} + +/* + * + */ +typedef struct { + CARD16 X; + CARD16 Y; + CARD16 Bpp; + CARD8 bRamClock; + CARD8 bTuningValue; +} ViaExpireNumberTable; + +static ViaExpireNumberTable CLE266AExpireNumber[] = { + {1280, 768,32,0x03,0x3}, {1280,1024,32,0x03,0x4}, {1280,1024,32,0x04,0x3}, + {1600,1200,16,0x03,0x4}, {1600,1200,32,0x04,0x4}, {1024, 768,32,0x03,0xA}, + {1400,1050,16,0x03,0x3}, {1400,1050,32,0x03,0x4}, {1400,1050,32,0x04,0x4}, + { 800, 600,32,0x03,0xA}, { 0, 0, 0, 0, 0} +}; + +static ViaExpireNumberTable CLE266CExpireNumber[] = { + {1280, 768,32,0x03,0x3}, {1280,1024,32,0x03,0x4}, {1280,1024,32,0x04,0x4}, + {1600,1200,32,0x03,0x3}, {1600,1200,32,0x04,0x4}, {1024, 768,32,0x03,0xA}, + {1400,1050,32,0x03,0x4}, {1400,1050,32,0x04,0x4}, + { 800, 600,32,0x03,0xA}, { 0, 0, 0, 0, 0} +}; + +static ViaExpireNumberTable KM400ExpireNumber[]={ + {1280,1024,32,0x03,0x3}, {1280,1024,32,0x04,0x9}, {1280, 768,32,0x03,0x3}, + {1280, 768,32,0x04,0x9}, {1400,1050,32,0x03,0x3}, {1400,1050,32,0x04,0x9}, + {1600,1200,32,0x03,0x4}, {1600,1200,32,0x04,0xA}, { 0, 0, 0, 0, 0} +}; + +/* + * + */ +static void +ViaSetPrimaryExpireNumber(ScrnInfoPtr pScrn, DisplayModePtr mode, ViaExpireNumberTable *Expire) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaSetPrimaryExpireNumber\n")); + + for (; Expire->X; Expire++) + if ((Expire->X == mode->CrtcHDisplay) && + (Expire->Y == mode->CrtcVDisplay) && + (Expire->Bpp == pScrn->bitsPerPixel) && + (Expire->bRamClock == pVia->MemClk)) { + ViaSeqMask(hwp, 0x22, Expire->bTuningValue, 0x1F); + return; + } +} + +/* + * + */ +void +ViaSetPrimaryFIFO(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaSetPrimaryFIFO\n")); + + /* standard values */ + ViaSeqMask(hwp, 0x17, 0x1F, 0xFF); + + if (mode->CrtcHDisplay >= 1600) { + ViaSeqMask(hwp, 0x16, 0x0F, 0xBF); + ViaSeqMask(hwp, 0x18, 0x4F, 0xFF); + } else if (mode->CrtcHDisplay >= 1024) { + ViaSeqMask(hwp, 0x16, 0x0C, 0xBF); + ViaSeqMask(hwp, 0x18, 0x4C, 0xFF); + } else { + ViaSeqMask(hwp, 0x16, 0x08, 0xBF); + ViaSeqMask(hwp, 0x18, 0x4E, 0xFF); + } + + switch(pVia->Chipset) { + case VIA_CLE266: + if (CLE266_REV_IS_CX(pVia->ChipRev)) { + if (pVia->HasSecondary) { /* SAMM or DuoView case */ + if (mode->HDisplay >= 1024) { + ViaSeqMask(hwp, 0x16, 0x1C, 0x3F); /* 28 */ + hwp->writeSeq(hwp, 0x17, 0x3F); /* 63 */ + hwp->writeSeq(hwp, 0x18, 0x57); /* 23 */ + } + } else { /* Single view or Simultaneous case */ +#if 0 + if (mode->HDisplay > 1024) { + ViaSeqMask(hwp, 0x16, 0x17, 0x3F); /* 23 */ + hwp->writeSeq(hwp, 0x17, 0x2F); /* 47 */ + hwp->writeSeq(hwp, 0x18, 0x57); /* 23 */ + } +#endif + } + /* originally when setting secondary */ + ViaSetPrimaryExpireNumber(pScrn, mode, CLE266CExpireNumber); + } else { + if ((mode->HDisplay > 1024) && pVia->HasSecondary) { + ViaSetCLE266APrimaryFIFO(pScrn, TRUE); + + ViaSeqMask(hwp, 0x16, 0x17, 0x3F); /* 23 */ + hwp->writeSeq(hwp, 0x17, 0x2F); /* 47 */ + hwp->writeSeq(hwp, 0x18, 0x57); /* 23 */ + } + + /* originally when setting secondary */ + ViaSetPrimaryExpireNumber(pScrn, mode, CLE266AExpireNumber); + } + break; + case VIA_KM400: + if (pVia->HasSecondary) { /* SAMM or DuoView case */ + if ((mode->HDisplay >= 1600) && + (pVia->MemClk <= VIA_MEM_DDR200)) { + ViaSeqMask(hwp, 0x16, 0x09, 0x3F); /* 9 */ + hwp->writeSeq(hwp, 0x17, 0x1C); /* 28 */ + } else { + ViaSeqMask(hwp, 0x16, 0x1C, 0x3F); /* 28 */ + hwp->writeSeq(hwp, 0x17, 0x3F); /* 63 */ + } + } else { + if ((mode->HDisplay > 1280)) + ViaSeqMask(hwp, 0x16, 0x1C, 0x3F); /* 28 */ + else if (mode->HDisplay > 1024) + ViaSeqMask(hwp, 0x16, 0x17, 0x3F); /* 23 */ + else + ViaSeqMask(hwp, 0x16, 0x10, 0x3F); /* 16 */ + hwp->writeSeq(hwp, 0x17, 0x3F); /* 63 */ + } + hwp->writeSeq(hwp, 0x18, 0x57); /* 23 */ + + /* originally when setting secondary */ + ViaSetPrimaryExpireNumber(pScrn, mode, KM400ExpireNumber); + break; + case VIA_K8M800: + hwp->writeSeq(hwp, 0x17, 0xBF); /* 384/2 - 1 = 191 (orig via comment: 384/8) */ + ViaSeqMask(hwp, 0x16, 0x92, 0xBF); /* 328/4 = 82 = 0x52*/ + ViaSeqMask(hwp, 0x18, 0x8a, 0xBF); /* 74 */ + + if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32)) + ViaSeqMask(hwp, 0x22, 0x10, 0x1F); /* 64/4 = 16 */ + else + ViaSeqMask(hwp, 0x22, 0x00, 0x1F); /* 128/4 = overflow = 0 */ + break; + case VIA_PM800: + hwp->writeSeq(hwp, 0x17, 0x5F); /* 95 */ + ViaSeqMask(hwp, 0x16, 0x20, 0xBF); /* 32 */ + ViaSeqMask(hwp, 0x18, 0x10, 0xBF); /* 16 */ + + if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32)) + ViaSeqMask(hwp, 0x22, 0x10, 0x1F); /* 64/4 = 16 */ + else + ViaSeqMask(hwp, 0x22, 0x1F, 0x1F); /* 31 */ + break; + case VIA_VM800: + hwp->writeSeq(hwp, 0x17, 0x2F); + ViaSeqMask(hwp, 0x16, 0x14, 0xBF); + ViaSeqMask(hwp, 0x18, 0x08, 0xBF); + + if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32)) + ViaSeqMask(hwp, 0x22, 0x10, 0x1F); + else + ViaSeqMask(hwp, 0x22, 0x00, 0x1F); + break; + case VIA_K8M890: + case VIA_P4M900: + hwp->writeSeq(hwp, 0x16, 0x92); + hwp->writeSeq(hwp, 0x17, 0xB3); + hwp->writeSeq(hwp, 0x18, 0x8A); + break; + case VIA_P4M890: + break; + case VIA_CX700: + hwp->writeSeq(hwp, 0x16, 0x26); + hwp->writeSeq(hwp, 0x17, 0x5F); + hwp->writeSeq(hwp, 0x18, 0x66); + hwp->writeSeq(hwp, 0x22, 0x1F); + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ViaSetPrimaryFIFO:" + " Chipset %d not implemented\n", pVia->Chipset); + break; + + } +} + +/* + * I've thrown out the LCD requirement. Size > 1024 is not supported + * by any currently known TV encoder anyway. -- Luc. + * + */ +void +ViaSetSecondaryFIFO(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaSetSecondaryFIFO\n")); + + switch (pVia->Chipset) { + case VIA_CLE266: + if (CLE266_REV_IS_CX(pVia->ChipRev)) { + if (mode->HDisplay >= 1024) { + ViaCrtcMask(hwp, 0x6A, 0x20, 0x20); + hwp->writeCrtc(hwp, 0x68, 0xAB); /* depth: 10, threshold: 11 */ + } else { + ViaCrtcMask(hwp, 0x6A, 0x00, 0x20); + hwp->writeCrtc(hwp, 0x68, 0x67); /* depth: 6, threshold: 7 */ + } + } else { + if ((pScrn->bitsPerPixel >= 24) && + (((mode->VDisplay > 768) && (pVia->MemClk <= VIA_MEM_DDR200)) || + ((mode->HDisplay > 1280) && (pVia->MemClk <= VIA_MEM_DDR266)))) { + ViaCrtcMask(hwp, 0x6A, 0x20, 0x20); + hwp->writeCrtc(hwp, 0x68, 0xAB); /* depth: 10, threshold: 11 */ + } else { + ViaCrtcMask(hwp, 0x6A, 0x00, 0x20); + hwp->writeCrtc(hwp, 0x68, 0x67); /* depth: 6, threshold: 7 */ + } + } + break; + case VIA_KM400: + if ((mode->HDisplay >= 1600) && (pVia->MemClk <= VIA_MEM_DDR200)) { + ViaCrtcMask(hwp, 0x6A, 0x20, 0x20); + hwp->writeCrtc(hwp, 0x68, 0xEB); /* depth: 14, threshold: 11 */ + } else if ((pScrn->bitsPerPixel == 32) && + (((mode->HDisplay > 1024) && (pVia->MemClk <= VIA_MEM_DDR333)) || + ((mode->HDisplay >= 1024) && (pVia->MemClk <= VIA_MEM_DDR200)))) { + ViaCrtcMask(hwp, 0x6A, 0x20, 0x20); + hwp->writeCrtc(hwp, 0x68, 0xCA); /* depth: 12, threshold: 10 */ + } else if ((pScrn->bitsPerPixel == 16) && + (((mode->HDisplay > 1280) && (pVia->MemClk <= VIA_MEM_DDR333)) || + ((mode->HDisplay >= 1280) && (pVia->MemClk <= VIA_MEM_DDR200)))) { + ViaCrtcMask(hwp, 0x6A, 0x20, 0x20); + hwp->writeCrtc(hwp, 0x68, 0xAB); /* depth: 10, threshold: 11 */ + } else { + ViaCrtcMask(hwp, 0x6A, 0x00, 0x20); + hwp->writeCrtc(hwp, 0x68, 0x67); /* depth: 6, threshold: 7 */ + } + break; + case VIA_K8M800: + /* depth: (384 /8 -1 -1) = 46 = 0x2E */ + ViaCrtcMask(hwp, 0x68, 0xE0, 0xF0); + ViaCrtcMask(hwp, 0x94, 0x00, 0x80); + ViaCrtcMask(hwp, 0x95, 0x80, 0x80); + + /* threshold: (328/4) = 82 = 0x52 */ + ViaCrtcMask(hwp, 0x68, 0x02, 0x0F); + ViaCrtcMask(hwp, 0x95, 0x50, 0x70); + + /* preq: 74 = 0x4A */ + ViaCrtcMask(hwp, 0x92, 0x0A, 0x0F); + ViaCrtcMask(hwp, 0x95, 0x04, 0x07); + + if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32)) + ViaCrtcMask(hwp, 0x94, 0x10, 0x7F); /* 64/4 */ + else + ViaCrtcMask(hwp, 0x94, 0x20, 0x7F); /* 128/4 */ + break; + case VIA_PM800: + /* depth: 12 - 1 = 0x0B */ + ViaCrtcMask(hwp, 0x68, 0xB0, 0xF0); + ViaCrtcMask(hwp, 0x94, 0x00, 0x80); + ViaCrtcMask(hwp, 0x95, 0x00, 0x80); + + /* threshold: 16 = 0x10 */ + ViaCrtcMask(hwp, 0x68, 0x00, 0x0F); + ViaCrtcMask(hwp, 0x95, 0x10, 0x70); + + /* preq: 8 = 0x08 */ + ViaCrtcMask(hwp, 0x92, 0x08, 0x0F); + ViaCrtcMask(hwp, 0x95, 0x00, 0x07); + + if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32)) + ViaCrtcMask(hwp, 0x94, 0x10, 0x7F); /* 64/4 */ + else + ViaCrtcMask(hwp, 0x94, 0x20, 0x7F); /* 128/4 */ + break; + case VIA_VM800: + ViaCrtcMask(hwp, 0x68, 0xA0, 0xF0); + ViaCrtcMask(hwp, 0x94, 0x00, 0x80); + ViaCrtcMask(hwp, 0x95, 0x00, 0x80); + + ViaCrtcMask(hwp, 0x68, 0x04, 0x0F); + ViaCrtcMask(hwp, 0x95, 0x10, 0x70); + + ViaCrtcMask(hwp, 0x92, 0x08, 0x0F); + ViaCrtcMask(hwp, 0x95, 0x00, 0x07); + + if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32)) + ViaCrtcMask(hwp, 0x94, 0x10, 0x7F); + else + ViaCrtcMask(hwp, 0x94, 0x20, 0x7F); + break; + case VIA_P4M890: + case VIA_K8M890: + case VIA_P4M900: + break; + case VIA_CX700: + ViaCrtcMask(hwp, 0x68, 0xA0, 0xF0); + ViaCrtcMask(hwp, 0x94, 0x00, 0x80); + ViaCrtcMask(hwp, 0x95, 0x00, 0x80); + + ViaCrtcMask(hwp, 0x68, 0x04, 0x0F); + ViaCrtcMask(hwp, 0x95, 0x10, 0x70); + + ViaCrtcMask(hwp, 0x92, 0x08, 0x0F); + ViaCrtcMask(hwp, 0x95, 0x00, 0x07); + + if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32)) + ViaCrtcMask(hwp, 0x94, 0x10, 0x7F); + else + ViaCrtcMask(hwp, 0x94, 0x20, 0x7F); + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ViaSetSecondaryFIFO:" + " Chipset %d not implemented\n", pVia->Chipset); + break; + } +} + +/* + * Wrap around ViaSetCLE266APrimaryFIFO + */ +void +ViaDisablePrimaryFIFO(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaDisablePrimaryFIFO\n")); + + /* Cause of exit XWindow will dump back register value, others chipset no + * need to set extended fifo value */ + if ((pVia->Chipset == VIA_CLE266) && CLE266_REV_IS_AX(pVia->ChipRev) && + ((pScrn->currentMode->HDisplay > 1024) || pVia->HasSecondary)) + ViaSetCLE266APrimaryFIFO(pScrn, FALSE); +} diff --git a/trunk/src/via_bios.h b/trunk/src/via_bios.h new file mode 100644 index 000000000000..0b3f8f35836d --- /dev/null +++ b/trunk/src/via_bios.h @@ -0,0 +1,184 @@ +/* + * Copyright 2004-2005 The Unichrome Project [unichrome.sf.net] + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. 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, sub license, + * 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 NON-INFRINGEMENT. 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. + */ + +#ifndef _VIA_BIOS_H_ +#define _VIA_BIOS_H_ 1 + +#define VIA_PANEL6X4 0 +#define VIA_PANEL8X6 1 +#define VIA_PANEL10X7 2 +#define VIA_PANEL12X7 3 +#define VIA_PANEL12X10 4 +#define VIA_PANEL14X10 5 +#define VIA_PANEL16X12 6 +#define VIA_PANEL12X8 7 +#define VIA_PANEL_INVALID 255 + +#define TVTYPE_NONE 0x00 +#define TVTYPE_NTSC 0x01 +#define TVTYPE_PAL 0x02 +#define TVTYPE_480P 0X03 +#define TVTYPE_576P 0X04 +#define TVTYPE_720P 0X05 +#define TVTYPE_1080I 0X06 + +#define TVOUTPUT_NONE 0x00 +#define TVOUTPUT_COMPOSITE 0x01 +#define TVOUTPUT_SVIDEO 0x02 +#define TVOUTPUT_RGB 0x04 +#define TVOUTPUT_YCBCR 0x08 +#define TVOUTPUT_SC 0x16 + +#define VIA_NONETV 0 +#define VIA_VT1621 1 /* TV2PLUS */ +#define VIA_VT1622 2 /* TV3 */ +#define VIA_VT1623 3 /* also VT1622A */ +#define VIA_VT1625 4 +#define VIA_CH7011 5 +#define VIA_CH7019A 6 +#define VIA_CH7019B 7 +#define VIA_CH7017 8 +#define VIA_CH7304 9 +#define VIA_CH7305 10 + + +#define VIA_TVNORMAL 0 +#define VIA_TVOVER 1 + +#define VIA_DEVICE_NONE 0x00 +#define VIA_DEVICE_CRT 0x01 +#define VIA_DEVICE_LCD 0x02 +#define VIA_DEVICE_TV 0x04 +#define VIA_DEVICE_DFP 0x08 + +/* System Memory CLK */ +#define VIA_MEM_SDR66 0x00 +#define VIA_MEM_SDR100 0x01 +#define VIA_MEM_SDR133 0x02 +#define VIA_MEM_DDR200 0x03 +#define VIA_MEM_DDR266 0x04 +#define VIA_MEM_DDR333 0x05 +#define VIA_MEM_DDR400 0x06 +#define VIA_MEM_DDR533 0x07 +#define VIA_MEM_DDR667 0x08 +#define VIA_MEM_END 0x09 +#define VIA_MEM_NONE 0xFF + +/* Digital Output Bus Width */ +#define VIA_DI_12BIT 0x00 +#define VIA_DI_24BIT 0x01 + +typedef struct _VIABIOSINFO { + int scrnIndex; + + Bool CrtPresent; + Bool CrtActive; + + CARD16 ResolutionIndex; + CARD32 Clock; /* register value for the dotclock */ + Bool ClockExternal; + CARD32 Bandwidth; /* available memory bandwidth */ + + /* Panel/LCD entries */ + Bool PanelPresent; + Bool PanelActive; + Bool ForcePanel; + int PanelIndex; + int PanelSize; + Bool Center; + CARD8 BusWidth; /* Digital Output Bus Width */ + Bool SetDVI; + /* LCD Simultaneous Expand Mode HWCursor Y Scale */ + Bool scaleY; + int panelX; + int panelY; + int resY; + + /* TV entries */ + int TVEncoder; + int TVOutput; + Bool TVActive; + I2CDevPtr TVI2CDev; + int TVType; + Bool TVDotCrawl; + int TVDeflicker; + CARD8 TVRegs[0xFF]; + int TVNumRegs; + + /* TV Callbacks */ + void (*TVSave) (ScrnInfoPtr pScrn); + void (*TVRestore) (ScrnInfoPtr pScrn); + Bool (*TVDACSense) (ScrnInfoPtr pScrn); + ModeStatus (*TVModeValid) (ScrnInfoPtr pScrn, DisplayModePtr mode); + void (*TVModeI2C) (ScrnInfoPtr pScrn, DisplayModePtr mode); + void (*TVModeCrtc) (ScrnInfoPtr pScrn, DisplayModePtr mode); + void (*TVPower) (ScrnInfoPtr pScrn, Bool On); + void (*LCDPower) (ScrnInfoPtr pScrn, Bool On); + DisplayModePtr TVModes; + void (*TVPrintRegs) (ScrnInfoPtr pScrn); + +} VIABIOSInfoRec, *VIABIOSInfoPtr; + +/* Function prototypes */ +/* via_vbe.c */ +void ViaVbeAdjustFrame(int scrnIndex, int x, int y, int flags); +Bool ViaVbeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode); +Bool ViaVbeSaveRestore(ScrnInfoPtr pScrn, vbeSaveRestoreFunction function); +Bool ViaVbeModePreInit(ScrnInfoPtr pScrn); +void ViaVbeDPMS(ScrnInfoPtr pScrn, int mode, int flags); +void ViaVbeDoDPMS(ScrnInfoPtr pScrn, int mode); + +/* via_mode.c */ +void ViaOutputsDetect(ScrnInfoPtr pScrn); +Bool ViaOutputsSelect(ScrnInfoPtr pScrn); +void ViaModesAttach(ScrnInfoPtr pScrn, MonPtr monitorp); +CARD32 ViaGetMemoryBandwidth(ScrnInfoPtr pScrn); +ModeStatus ViaValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags); +void ViaModePrimary(ScrnInfoPtr pScrn, DisplayModePtr mode); +void ViaModeSecondary(ScrnInfoPtr pScrn, DisplayModePtr mode); +void ViaModeSecondaryVGAOffset(ScrnInfoPtr pScrn); +void ViaModeSecondaryVGAFetchCount(ScrnInfoPtr pScrn, int width); +void ViaLCDPower(ScrnInfoPtr pScrn, Bool On); +void ViaTVPower(ScrnInfoPtr pScrn, Bool On); +void ViaTVSave(ScrnInfoPtr pScrn); +void ViaTVRestore(ScrnInfoPtr pScrn); +#ifdef HAVE_DEBUG +void ViaTVPrintRegs(ScrnInfoPtr pScrn); +#endif + +/* in via_bandwidth.c */ +void ViaSetPrimaryFIFO(ScrnInfoPtr pScrn, DisplayModePtr mode); +void ViaSetSecondaryFIFO(ScrnInfoPtr pScrn, DisplayModePtr mode); +void ViaDisablePrimaryFIFO(ScrnInfoPtr pScrn); + +/* via_vt162x.c */ +I2CDevPtr ViaVT162xDetect(ScrnInfoPtr pScrn, I2CBusPtr pBus, CARD8 Address); +void ViaVT162xInit(ScrnInfoPtr pScrn); + +/* via_ch7xxx.c */ +I2CDevPtr ViaCH7xxxDetect(ScrnInfoPtr pScrn, I2CBusPtr pBus, CARD8 Address); +void ViaCH7xxxInit(ScrnInfoPtr pScrn); + +#endif /* _VIA_BIOS_H_ */ diff --git a/trunk/src/via_ch7xxx.c b/trunk/src/via_ch7xxx.c new file mode 100644 index 000000000000..64e3e1f31463 --- /dev/null +++ b/trunk/src/via_ch7xxx.c @@ -0,0 +1,650 @@ +/* + * Copyright 2005 Terry Lewis. All Rights Reserved. + * Copyright 2005 Philip Langdale. All Rights Reserved. (CH7011 additions) + * Copyright 2004 The Unichrome Project [unichrome.sf.net] + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. 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, sub license, + * 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "via_driver.h" +#include "via_vgahw.h" +#include "via_ch7xxx.h" +#include "via_id.h" + +#ifdef HAVE_DEBUG +/* + * + */ +static void +CH7xxxPrintRegs(ScrnInfoPtr pScrn) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + CARD8 i, buf; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Printing registers for %s\n", + pBIOSInfo->TVI2CDev->DevName); + + for (i = 0; i < pBIOSInfo->TVNumRegs; i++) { + xf86I2CReadByte(pBIOSInfo->TVI2CDev, i, &buf); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TV%02X: 0x%02X\n", i, buf); + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "End of TV registers.\n"); +} +#endif /* HAVE_DEBUG */ + +/* + * + */ +I2CDevPtr +ViaCH7xxxDetect(ScrnInfoPtr pScrn, I2CBusPtr pBus, CARD8 Address) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + I2CDevPtr pDev = xf86CreateI2CDevRec(); + CARD8 buf; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaCH7xxxDetect\n")); + + pDev->DevName = "CH7xxx"; + pDev->SlaveAddr = Address; + pDev->pI2CBus = pBus; + + if (!xf86I2CDevInit(pDev)) { + xf86DestroyI2CDevRec(pDev, TRUE); + return NULL; + } + + + if (!xf86I2CReadByte(pDev, 0x4B, &buf)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to read from %s Slave %d.\n", + pBus->BusName, Address); + xf86DestroyI2CDevRec(pDev, TRUE); + return NULL; + } + + switch (buf) { + case 0x17: + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected Chrontel CH7011 TV Encoder\n"); + pBIOSInfo->TVEncoder = VIA_CH7011; + pDev->DevName="CH7011"; + break; + case 0x19: + xf86I2CReadByte(pDev, 0x4A, &buf); + if (buf == 0x81) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected Chrontel CH7019A LVDS Transmitter/TV Encoder\n"); + pBIOSInfo->TVEncoder = VIA_CH7019A; + pDev->DevName="CH7019A"; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected Chrontel CH7019B LVDS Transmitter/TV Encoder\n"); + pBIOSInfo->TVEncoder = VIA_CH7019B; + pDev->DevName="CH7019B"; + } + break; + case 0x1B: + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected Chrontel CH7017 LVDS Transmitter\n"); + pBIOSInfo->TVEncoder = VIA_CH7017; + pDev->DevName="CH7017"; + break; + case 0x3A: + /* single init table --> single channel LVDS transmitter ? */ + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected Chrontel CH7304 LVDS Transmitter\n"); + pBIOSInfo->TVEncoder = VIA_CH7304; + pDev->DevName="CH7304"; + break; + case 0x3B: + /* dual init table --> dual channel LVDS transmitter ? */ + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected Chrontel CH7305 LVDS Transmitter\n"); + pBIOSInfo->TVEncoder = VIA_CH7305; + pDev->DevName="CH7305"; + break; + default: + pBIOSInfo->TVEncoder = VIA_NONETV; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unknown CH7xxx" + " device found. [%x:0x1B contains %x]\n", + Address, buf); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Unknown CH7xxx encoder found\n"); + + xf86DestroyI2CDevRec(pDev,TRUE); + pDev = NULL; + break; + } + + return pDev; +} + +/* + * + */ + +static void +CH7xxxSave(ScrnInfoPtr pScrn) +{ + int i; + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CH7xxxSave\n")); + + for (i = 0; i < pBIOSInfo->TVNumRegs; i++) + xf86I2CReadByte(pBIOSInfo->TVI2CDev, i, &(pBIOSInfo->TVRegs[i])); +} + + +static void +CH7xxxRestore(ScrnInfoPtr pScrn) +{ + int i; + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CH7xxxRestore\n")); + + for (i = 0; i < pBIOSInfo->TVNumRegs; i++) + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, i, pBIOSInfo->TVRegs[i]); +} + +static CARD8 +CH7xxxDACSenseI2C(I2CDevPtr pDev) +{ + CARD8 save, sense; + + /* Turn all DACP on*/ + xf86I2CWriteByte(pDev, 0x49, 0x20); + + /* Make sure Bypass mode is disabled (DACBP) bit0 is set to '0' */ + xf86I2CReadByte(pDev, 0x21, &save); + xf86I2CWriteByte(pDev, 0x21, save & ~0x01); + + /* Set Sense bit0 to '1' */ + xf86I2CReadByte(pDev, 0x20, &save); + xf86I2CWriteByte(pDev, 0x20, save | 0x01); + + /* Set Sense bit0 back to '0' */ + xf86I2CReadByte(pDev, 0x20, &save); + xf86I2CWriteByte(pDev, 0x20, save & ~0x01); + + /* Read DACT status bits */ + xf86I2CReadByte(pDev, 0x20, &sense); + + return (sense & 0x1F); +} + +/* + * A CH7xxx hack. (T. Lewis. S-Video fixed by P. Langdale) + * + * CH7xxx Cable types (C+S and YcBcR untested and almost certainly wrong) + * 0x10 = Composite + * 0x0C = S-Video + * 0x02 = Composite+S-Video + * 0x04 = YcBcR + * 0x00 = Nothing Connected + */ + +static Bool +CH7xxxDACSense(ScrnInfoPtr pScrn) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + CARD8 sense; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CH7xxxDACDetect\n")); + +/* is this needed? IH */ + if (!pBIOSInfo->TVI2CDev || + !pBIOSInfo->TVEncoder) + return FALSE; + + sense = CH7xxxDACSenseI2C(pBIOSInfo->TVI2CDev); + + /* I'm sure these case values are correct, + * but we should get something in any case. + * 0x10 (Composite), 0x0C (S-Video) and 0x00 (Nothing connected) + * seem to be correct however. + */ + switch (sense) { + case 0x10: + pBIOSInfo->TVOutput = TVOUTPUT_COMPOSITE; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CH7xxx: Composite connected.\n"); + return TRUE; + case 0x0C: + pBIOSInfo->TVOutput = TVOUTPUT_SVIDEO; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CH7xxx: S-Video connected.\n"); + return TRUE; + case 0x02: + pBIOSInfo->TVOutput = TVOUTPUT_SC; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CHxxx: Composite+S-Video connected.\n"); + return TRUE; + case 0x04: + pBIOSInfo->TVOutput = TVOUTPUT_YCBCR; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CHxxx: YcBcR Connected.\n"); + return TRUE; + case 0x00: + pBIOSInfo->TVOutput = TVOUTPUT_NONE; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CH7xxx: Nothing connected.\n"); + return FALSE; + default: + pBIOSInfo->TVOutput = TVOUTPUT_NONE; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "CH7xxx: Unknown cable combination: 0x0%2X.\n",sense); + return FALSE; + } +} + +static CARD8 +CH7011ModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + int i; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CH7011ModeIndex\n")); + for (i = 0; CH7011Table[i].Width; i++) { + if ((CH7011Table[i].Width == mode->CrtcHDisplay) && + (CH7011Table[i].Height == mode->CrtcVDisplay) && + (CH7011Table[i].Standard == pBIOSInfo->TVType) && + !(strcmp(CH7011Table[i].name, mode->name))) + return i; + } + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "CH7011ModeIndex:" + " Mode \"%s\" not found in Table\n", mode->name); + return 0xFF; +} + +static CARD8 +CH7019ModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + int i; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CH7019ModeIndex\n")); + for (i = 0; CH7019Table[i].Width; i++) { + if ((CH7019Table[i].Width == mode->CrtcHDisplay) && + (CH7019Table[i].Height == mode->CrtcVDisplay) && + (CH7019Table[i].Standard == pBIOSInfo->TVType) && + !(strcmp(CH7019Table[i].name, mode->name))) + return i; + } + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "CH7019ModeIndex:" + " Mode \"%s\" not found in Table\n", mode->name); + return 0xFF; +} + +/* + * + */ +static ModeStatus +CH7xxxModeValid(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CH7xxxModeValid\n")); + + if ((mode->PrivSize != sizeof(struct CH7xxxModePrivate)) || + ((mode->Private != (void *) &CH7xxxModePrivateNTSC) && + (mode->Private != (void *) &CH7xxxModePrivatePAL))) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Not a mode defined by the TV Encoder.\n"); + return MODE_BAD; + } + + if ((pBIOSInfo->TVType == TVTYPE_NTSC) && + (mode->Private != (void *) &CH7xxxModePrivateNTSC)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TV standard is NTSC. This is a PAL mode.\n"); + return MODE_BAD; + } else if ((pBIOSInfo->TVType == TVTYPE_PAL) && + (mode->Private != (void *) &CH7xxxModePrivatePAL)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TV standard is PAL. This is a NTSC mode.\n"); + return MODE_BAD; + } + + if (pBIOSInfo->TVEncoder == VIA_CH7011) + { + if (CH7011ModeIndex(pScrn, mode) != 0xFF) + return MODE_OK; + } + else + { + if (CH7019ModeIndex(pScrn, mode) != 0xFF) + return MODE_OK; + } + return MODE_BAD; +} + +static void +CH7xxxModeI2C(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + + CARD8 i, j; + + VIABIOSTVMASKTableRec Mask; + struct CH7xxxTableRec Table; + + if (pBIOSInfo->TVEncoder == VIA_CH7011) + { + Table = CH7011Table[CH7011ModeIndex(pScrn, mode)]; + Mask = ch7011MaskTable; + } + else + { + Table = CH7019Table[CH7019ModeIndex(pScrn, mode)]; + Mask = ch7019MaskTable; + } + + DEBUG(xf86DrvMsg(pBIOSInfo->scrnIndex, X_INFO, "CH7011ModeI2C\n")); + + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x49, 0x3E); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x1E, 0xD0); + + for (i = 0,j = 0; (j < Mask.numTV) && (i < VIA_BIOS_TABLE_NUM_TV_REG); i++) { + if (Mask.TV[i] == 0xFF) { + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, i, Table.TV[i]); + j++; + } else { + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, i, pBIOSInfo->TVRegs[i]); + } + } + + if ((pBIOSInfo->TVType == TVTYPE_NTSC) && pBIOSInfo->TVDotCrawl) { + CARD16 *DotCrawl = Table.DotCrawlNTSC; + CARD8 address, save; + + for (i = 1; i < (DotCrawl[0] + 1); i++) { + address = (CARD8)(DotCrawl[i] & 0xFF); + + save = (CARD8)(DotCrawl[i] >> 8); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, address, save); + } + } + + /* + * Only Composite and SVideo have been tested. + */ + switch(pBIOSInfo->TVOutput){ + case TVOUTPUT_COMPOSITE: + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x49, 0x2E); + break; + case TVOUTPUT_SVIDEO: + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x49, 0x32); + break; + case TVOUTPUT_SC: + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x49, 0x3C); + break; + case TVOUTPUT_YCBCR: + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x49, 0x3A); + break; + default: + break; + } + + if (pVia->IsSecondary) { /* Patch as setting 2nd path */ + j = (CARD8)(Mask.misc2 >> 5); + for (i = 0; i < j; i++) + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, Table.Patch2[i] & 0xFF, Table.Patch2[i] >> 8); + } +} + +static void +CH7xxxModeCrtc(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + CARD8 *CRTC, *Misc; + int i, j; + + VIABIOSTVMASKTableRec Mask; + struct CH7xxxTableRec Table; + + if (pBIOSInfo->TVEncoder == VIA_CH7011) + { + Table = CH7011Table[CH7011ModeIndex(pScrn, mode)]; + Mask = ch7011MaskTable; + } + else + { + Table = CH7019Table[CH7019ModeIndex(pScrn, mode)]; + Mask = ch7019MaskTable; + } + + DEBUG(xf86DrvMsg(pBIOSInfo->scrnIndex, X_INFO, "CH7xxxModeCrtc\n")); + + if (pVia->IsSecondary) { + switch (pScrn->bitsPerPixel) { + case 16: + CRTC = Table.CRTC2_16BPP; + break; + case 24: + case 32: + CRTC = Table.CRTC2_32BPP; + break; + case 8: + default: + CRTC = Table.CRTC2_8BPP; + break; + } + Misc = Table.Misc2; + + + for (i = 0, j = 0; i < Mask.numCRTC2; j++) { + if (Mask.CRTC2[j] == 0xFF) { + hwp->writeCrtc(hwp, j + 0x50, CRTC[j]); + i++; + } + } + + if (Mask.misc2 & 0x18) { + pBIOSInfo->Clock = (Misc[3] << 8) & Misc[4]; + /* VIASetUseExternalClock(hwp); */ + } + + ViaCrtcMask(hwp, 0x6A, 0xC0, 0xC0); + ViaCrtcMask(hwp, 0x6B, 0x01, 0x01); + ViaCrtcMask(hwp, 0x6C, 0x01, 0x01); + + /* Disable LCD Scaling */ + if (!pVia->SAMM || pVia->FirstInit) + hwp->writeCrtc(hwp, 0x79, 0x00);} + else { + + CRTC = Table.CRTC1; + Misc = Table.Misc1; + + for (i = 0, j = 0; i < Mask.numCRTC1; j++) { + if (Mask.CRTC1[j] == 0xFF) { + hwp->writeCrtc(hwp, j, CRTC[j]); + i++; + } + } + + ViaCrtcMask(hwp, 0x33, Misc[0], 0x20); + hwp->writeCrtc(hwp, 0x6A, Misc[1]); + + if ((pVia->Chipset == VIA_CLE266) && + CLE266_REV_IS_AX(pVia->ChipRev)) { + hwp->writeCrtc(hwp, 0x6B, Misc[2] | 0x81); + /* Fix TV clock Polarity for CLE266A2 */ + if (pVia->ChipRev == 0x02) + hwp->writeCrtc(hwp, 0x6C, Misc[3] | 0x01); + } else + hwp->writeCrtc(hwp, 0x6B, Misc[2] | 0x01); + + if (Mask.misc1 & 0x30) { + /* CLE266Ax use 2x XCLK */ + if ((pVia->Chipset == VIA_CLE266) && + CLE266_REV_IS_AX(pVia->ChipRev)) + pBIOSInfo->Clock = 0x471C; + else + pBIOSInfo->Clock = (Misc[4] << 8) | Misc[5]; + } + + ViaCrtcMask(hwp, 0x6A, 0x40, 0x40); + ViaCrtcMask(hwp, 0x6B, 0x01, 0x01); + ViaCrtcMask(hwp, 0x6C, 0x01, 0x01); + } + + ViaSeqMask(hwp, 0x1E, 0xC0, 0xC0); /* Enable DI0/DVP0 */ +} + + +/* + * + */ +static void +CH7xxxTVPower(ScrnInfoPtr pScrn, Bool On) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + + if (On){ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CH7xxxTVPower: On\n")); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x49, 0x20); + }else{ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CH7xxxTVPower: Off\n")); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x49, 0x3E); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x1E, 0xD0); + } +} + +static void +CH7019LCDPower(ScrnInfoPtr pScrn, Bool On) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + CARD8 W_Buffer[2], R_Buffer[1]; + int i; + + if (On){ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CH7xxxLCDPower: On\n")); + W_Buffer[0] = 0x63; + W_Buffer[1] = 0x4B; + xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,2, NULL,0); + W_Buffer[0] = 0x66; + W_Buffer[1] = 0x20; + xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,2, NULL,0); + + for (i = 0; i < 10; i++) { + W_Buffer[0] = 0x63; + xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,1, R_Buffer,1); + usleep(100); + W_Buffer[0] = 0x63; + W_Buffer[1] = (R_Buffer[0] | 0x40); + xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,2, NULL,0); + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "CH7xxxLCDPower: [%d]write 0x63 = %X!\n", i+1, W_Buffer[1])); + usleep(1); + W_Buffer[0] = 0x63; + W_Buffer[1] &= ~0x40; + xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,2, NULL,0); + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "CH7xxxLCDPower: [%d]write 0x63 = %X!\n", i+1, W_Buffer[1])); + usleep(100); + W_Buffer[0] = 0x66; + xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,1, R_Buffer,1); + + if (((R_Buffer[0] & 0x44) == 0x44) || (i >= 9)) { + /* PLL lock OK, Turn on VDD */ + usleep(500); + W_Buffer[1] = R_Buffer[0] | 0x01; + xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,2, NULL,0); + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "CH7xxxLCDPower: CH7019 PLL lock ok!\n")); + /* reset data path */ + W_Buffer[0] = 0x48; + xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,1, R_Buffer,1); + W_Buffer[1] = R_Buffer[0] & ~0x08; + xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,2, NULL,0); + usleep(1); + W_Buffer[1] = R_Buffer[0]; + xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,2, NULL,0); + break; + } + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "CH7xxxLCDPower: [%d]CH7019 PLL lock fail!\n", i+1)); + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "CH7xxxLCDPower: [%d]0x66 = %X!\n", i+1, R_Buffer[0])); + } + }else{ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CH7xxxLCDPower: Off\n")); + /* Turn off VDD (Turn off backlignt only) */ + W_Buffer[0] = 0x66; + xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,1, R_Buffer,1); + W_Buffer[1] &= ~0x01; + xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,2, NULL,0); + usleep(100); + /* Turn off LVDS path */ + W_Buffer[0] = 0x63; + xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,1, R_Buffer,1); + W_Buffer[1] = (R_Buffer[0] | 0x40); + xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,2, NULL,0); + } +} + +/* + * + */ +void +ViaCH7xxxInit(ScrnInfoPtr pScrn) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaCH7xxxInit\n")); + + switch (pBIOSInfo->TVEncoder) { + case VIA_CH7011: + pBIOSInfo->TVSave = CH7xxxSave; + pBIOSInfo->TVRestore = CH7xxxRestore; + pBIOSInfo->TVDACSense = CH7xxxDACSense; + pBIOSInfo->TVModeValid = CH7xxxModeValid; + pBIOSInfo->TVModeI2C = CH7xxxModeI2C; + pBIOSInfo->TVModeCrtc = CH7xxxModeCrtc; + pBIOSInfo->TVPower = CH7xxxTVPower; + pBIOSInfo->TVModes = CH7011Modes; + pBIOSInfo->LCDPower = NULL; + pBIOSInfo->TVNumRegs = CH_7011_MAX_NUM_REG; +#ifdef HAVE_DEBUG + pBIOSInfo->TVPrintRegs = CH7xxxPrintRegs; +#endif + break; + case VIA_CH7019A: + case VIA_CH7019B: + pBIOSInfo->TVDACSense = CH7xxxDACSense; + pBIOSInfo->TVSave = CH7xxxSave; + pBIOSInfo->TVRestore = CH7xxxRestore; + pBIOSInfo->TVModeValid = CH7xxxModeValid; + pBIOSInfo->TVModeI2C = CH7xxxModeI2C; + pBIOSInfo->TVModeCrtc = CH7xxxModeCrtc; + pBIOSInfo->TVPower = CH7xxxTVPower; + pBIOSInfo->TVModes = CH7019Modes; + pBIOSInfo->LCDPower = CH7019LCDPower; + pBIOSInfo->TVNumRegs = CH_7019_MAX_NUM_REG; +#ifdef HAVE_DEBUG + pBIOSInfo->TVPrintRegs = CH7xxxPrintRegs; +#endif + break; + default: + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ViaCH7xxxInit missing\n")); + break; + } + + /* Save before continuing */ + if (pBIOSInfo->TVSave) + pBIOSInfo->TVSave(pScrn); +} diff --git a/trunk/src/via_ch7xxx.h b/trunk/src/via_ch7xxx.h new file mode 100644 index 000000000000..f74264202b35 --- /dev/null +++ b/trunk/src/via_ch7xxx.h @@ -0,0 +1,737 @@ +/* + * Copyright 2005 Terry Lewis. All Rights Reserved. + * Copyright 2005 Philip Langdale. All Rights Reserved. (CH7011 additions) + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. 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, sub license, + * 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS 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 _VIA_CH7xxx_H_ +#define _VIA_CH7xxx_H_ 1 + +/*+#define VIA_BIOS_MAX_NUM_TV_REG 0x80 ++#define VIA_BIOS_MAX_NUM_TV_CRTC 32 ++#define VIA_BIOS_NUM_TV_SPECIAL_REG 8 ++#define VIA_BIOS_MAX_NUM_TV_PATCH 8 ++#define VIA_BIOS_NUM_TV_OTHER 16 +*/ + +#define VIA_BIOS_TABLE_NUM_TV_REG 0x23 /* 0x00 - 0x22 */ + +#define CH_7011_MAX_NUM_REG 0x4C /* 0x00 - 0x4B */ +#define CH_7019_MAX_NUM_REG 0x80 /* 0x00 - 0x7F */ + +#define VIA_BIOS_MAX_NUM_TV_CRTC 32 +#define VIA_BIOS_NUM_TV_SPECIAL_REG 8 +#define VIA_BIOS_MAX_NUM_TV_PATCH 8 +#define VIA_BIOS_NUM_TV_OTHER 16 + +struct CH7xxxModePrivate { + char id[12]; /* "CH7xxx" */ + CARD8 Standard; +}; + +static struct CH7xxxModePrivate CH7xxxModePrivateNTSC = { + { 'C', 'H', '7', 'x', 'x', 'x', 0, 0, 0, 0, 0, 0 }, + TVTYPE_NTSC, +}; + +static struct CH7xxxModePrivate CH7xxxModePrivatePAL = { + { 'C', 'H', '7', 'x', 'x', 'x', 0, 0, 0, 0, 0, 0 }, + TVTYPE_PAL, +}; + + +#define MODEPREFIX(name) NULL, NULL, name, 0,M_T_DEFAULT +#define MODESUFFIXNTSC 0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0,FALSE,FALSE,\ + sizeof(struct CH7xxxModePrivate),(void *)&CH7xxxModePrivateNTSC,0,0.0,0.0 +#define MODESUFFIXPAL 0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0,FALSE,FALSE,\ + sizeof(struct CH7xxxModePrivate),(void *)&CH7xxxModePrivatePAL,0,0.0,0.0 + +/* dotclock is just for modeline validation */ +static DisplayModeRec CH7011Modes[]={ + { MODEPREFIX("640x480"), 23520, 640, 656, 744, 784, 0, 480, 487, 491, 600, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("640x480"), 30000, 640, 680, 808, 1000, 0, 480, 520, 523, 600, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("800x600"), 39900, 800, 840, 976, 1064, 0, 600, 604, 620, 750, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("800x600"), 34500, 800, 816, 880, 920, 0, 600, 604, 620, 750, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("1024x768"), 54810, 1024, 1032, 1088, 1160, 0, 768, 780, 792, 945, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("1024x768"), 57000, 1024, 1040, 1112, 1200, 0, 768, 829, 840, 950, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL }, + + { MODEPREFIX("640x480Over"), 20160, 640, 648, 704, 720, 0, 480, 487, 491, 560, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("640x480Over"), 21000, 640, 664, 792, 840, 0, 480, 485, 491, 500, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("800x600Over"), 35910, 800, 840, 984, 1080, 0, 600, 601, 604, 665, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("800x600Over"), 32500, 800, 832, 928, 1000, 0, 600, 600, 604, 650, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("1024x768Over"), 50400, 1024, 1040, 1112, 1200, 0, 768, 772, 776, 840, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("1024x768Over"), 49500, 1024, 1032, 1112, 1200, 0, 768, 771, 776, 825, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL }, + + { MODEPREFIX("720x480"), 25200, 720, 728, 776, 840, 0, 480, 511, 515, 600, 0, V_NHSYNC | V_PVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("720x576"), 28500, 720, 728, 744, 760, 0, 576, 635, 643, 750, 0, V_NHSYNC | V_PVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("720x480Noscale"), 27972, 720, 736, 768, 888, 0, 480, 480, 483, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("720x576Noscale"), 28000, 720, 728, 864, 896, 0, 576, 576, 579, 625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL }, + + { MODEPREFIX(NULL), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MODESUFFIXNTSC }, +}; + +static DisplayModeRec CH7019Modes[]={ + { MODEPREFIX("640x480"), 23520, 640, 656, 744, 784, 0, 480, 487, 491, 600, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("640x480"), 30000, 640, 680, 808, 1000, 0, 480, 520, 523, 600, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("800x600"), 39900, 800, 840, 976, 1064, 0, 600, 604, 620, 750, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("800x600"), 34500, 800, 816, 880, 920, 0, 600, 604, 620, 750, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("1024x768"), 54810, 1024, 1032, 1088, 1160, 0, 768, 780, 792, 945, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("1024x768"), 57000, 1024, 1040, 1112, 1200, 0, 768, 829, 840, 950, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("640x480Over"), 20160, 640, 648, 704, 720, 0, 480, 487, 491, 560, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("640x480Over"), 21000, 640, 664, 792, 840, 0, 480, 485, 491, 500, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("800x600Over"), 35910, 800, 840, 984, 1080, 0, 600, 601, 604, 665, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("800x600Over"), 32500, 800, 832, 928, 1000, 0, 600, 600, 604, 650, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("1024x768Over"), 50400, 1024, 1040, 1112, 1200, 0, 768, 772, 776, 840, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("1024x768Over"), 49500, 1024, 1032, 1112, 1200, 0, 768, 771, 776, 825, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL }, + + { MODEPREFIX(NULL), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MODESUFFIXNTSC }, +}; + + +typedef struct _VIATVMASKTABLE { + CARD8 TV[VIA_BIOS_TABLE_NUM_TV_REG]; + CARD8 CRTC1[VIA_BIOS_MAX_NUM_TV_CRTC]; + CARD8 CRTC2[VIA_BIOS_MAX_NUM_TV_CRTC]; + CARD8 misc1; + CARD8 misc2; + int numTV; + int numCRTC1; + int numCRTC2; +} VIABIOSTVMASKTableRec, *VIABIOSTVMASKTablePtr; + +struct CH7xxxTableRec { + char* name; + CARD16 Width; + CARD16 Height; + int Standard; + + CARD8 TV[VIA_BIOS_TABLE_NUM_TV_REG]; /*35*/ + CARD8 CRTC1[VIA_BIOS_MAX_NUM_TV_CRTC]; + CARD8 Misc1[VIA_BIOS_NUM_TV_SPECIAL_REG]; + CARD8 Misc2[VIA_BIOS_NUM_TV_SPECIAL_REG]; +/*merge these three*/ + CARD8 CRTC2_8BPP[VIA_BIOS_MAX_NUM_TV_CRTC]; + CARD8 CRTC2_16BPP[VIA_BIOS_MAX_NUM_TV_CRTC]; + CARD8 CRTC2_32BPP[VIA_BIOS_MAX_NUM_TV_CRTC]; + CARD16 Patch2[VIA_BIOS_MAX_NUM_TV_PATCH]; + CARD16 DotCrawlNTSC[VIA_BIOS_NUM_TV_OTHER]; +}; + + +static struct CH7xxxTableRec +CH7011Table[] = { + { "640x480", 640, 480, TVTYPE_NTSC, + { 0X6A, /* 0x00 Mode 17 */ + 0X3F, /* 0x01 FF Default 0x27 (was 7F) */ + 0X7E, /* 0x02 VBW Default 0xBE (was 0x7E) */ + 0X8B, /* 0x03 TE Decent Text 0x8B (was 8D) */ + 0X28, /* 0x04 SAV Default 0x50 (was 0x21) */ + 0X2C, /* 0x05 HP Default 0x50 (was 0x2E) */ + 0X05, /* 0x06 VP Default 0x00 (was 0x04) */ + 0X83, /* 0x07 BL Default 0x83 */ + 0X03, /* 0x08 CE Default 0x03 */ + 0X80, /* 0x09 TPC Default 0x80 */ + 0X3F, /* 0x0A PLLM Default 0x3F */ + 0X7E, /* 0x0B PLLN Default 0x7E */ + 0X20, /* 0x0C FSCI Default 0x20 */ + 0X80, /* 0x0D FSCI Default 0x80 */ + 0X00, /* 0x0E FSCI Default 0x08 (was 00) */ + 0X00, /* 0x0F FSCI Default 0xEB (was 00) */ + 0, /* 0x10 CIVC */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* We don't touch these */ + 0X48, /* 0x1C */ + 0X40, /* 0x1D */ + 0XD2, /* 0x1E */ + 0X80, /* 0x1F */ + 0X40, /* 0x20 */ + 0, /* 0x21 */ + 0, /* 0x22 */ }, + { 0X5D, 0X4F, 0X4F, 0X81, 0X52, 0X9E, 0X56, 0XBA, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X8, 0, 0XDF, 0, 0, 0XDF, 0X57, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0X20, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0XF, 0X7F, 0X7F, 0XF, 0X9A, 0X23, 0X8F, 0XEF, 0X57, 0XDF, 0XDF, 0X57, 0X11, 0XA, 0X8, 0X50, 0, 0, 0, 0, 0, 0X28, 0X50, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XF, 0X7F, 0X7F, 0XF, 0X9A, 0X23, 0X8F, 0XEF, 0X57, 0XDF, 0XDF, 0X57, 0X11, 0XA, 0X8, 0X50, 0, 0, 0, 0, 0, 0X50, 0XA0, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XF, 0X7F, 0X7F, 0XF, 0X9A, 0X23, 0X8F, 0XEF, 0X57, 0XDF, 0XDF, 0X57, 0X11, 0XA, 0X8, 0X50, 0, 0, 0, 0, 0, 0XA0, 0X40, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X2284, 0, 0, 0, 0, 0, 0, 0 }, + { 0X2, 0X811, 0X9217, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + + { "640x480", 640, 480, TVTYPE_PAL, + { 0X61, /* 0x00 PAL Mode 14 non-OS 640x480 1:1 */ + 0X27, /* 0x01 FF Default 0x27 (was 7F) */ + 0XBE, /* 0x02 VBW Default 0xBE (was 0x7E) */ + 0X8B, /* 0x03 TE Decent Text 0x8B (was 8D) */ + 0X28, /* 0x04 SAV Default 0x50 (was 0x21) */ + 0X2C, /* 0x05 HP Default 0x50 (was 0x2E) */ + 0X05, /* 0x06 VP Default 0x00 (was 0x04) */ + 0X83, /* 0x07 BL Default 0x83 */ + 0X01, /* 0x08 CE Default 0x03 */ + 0X81, /* 0x09 TPC Default 0x80 */ + 0X04, /* 0x0A PLLM Default 0x3F */ + 0X09, /* 0x0B PLLN Default 0x7E */ + 0X26, /* 0x0C FSCI Default 0x20 */ + 0X6F, /* 0x0D FSCI Default 0x80 */ + 0X1F, /* 0x0E FSCI Default 0x08 */ + 0XD0, /* 0x0F FSCI Default 0xEB */ + 0, /* 0x10 CIVC */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* We don't touch these */ + 0X48, /* 0x1C */ + 0X40, /* 0x1D */ + 0XD2, /* 0x1E */ + 0X80, /* 0x1F */ + 0X40, /* 0x20 */ + 0, /* 0x21 */ + 0, /* 0x22 */ }, + { 0X64, 0X4F, 0X4F, 0X88, 0X53, 0X83, 0X6F, 0XBA, 0, 0X40, 0, 0, 0, 0, 0, 0, 0X11, 0, 0XDF, 0, 0, 0XDF, 0X70, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0X20, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0X47, 0X7F, 0X7F, 0X47, 0X9A, 0X23, 0X95, 0X1E, 0X70, 0XDF, 0XDF, 0X70, 0X51, 0XA, 0X11, 0X5D, 0, 0, 0, 0, 0, 0X28, 0X50, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X47, 0X7F, 0X7F, 0X47, 0X9A, 0X23, 0X95, 0X1E, 0X70, 0XDF, 0XDF, 0X70, 0X51, 0XA, 0X11, 0X5D, 0, 0, 0, 0, 0, 0X50, 0XA0, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X47, 0X7F, 0X7F, 0X47, 0X9A, 0X23, 0X95, 0X1E, 0X70, 0XDF, 0XDF, 0X70, 0X51, 0XA, 0X11, 0X5D, 0, 0, 0, 0, 0, 0XA0, 0X40, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X3284, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + + { "800x600", 800, 600, TVTYPE_NTSC, + { 0XCF, /* 0x00 Mode 29 */ + 0X27, /* 0x01 FF Default 0x27 (was 7F) */ + 0XBE, /* 0x02 VBW Default 0xBE (was 0x76) */ + 0X8B, /* 0x03 TE Decent Text 0x8B (was 8F) */ + 0X59, /* 0x04 SAV*/ + 0X3C, /* 0x05 HP */ + 0X15, /* 0x06 VP */ + 0X66, /* 0x07 BL Default 0x83 */ + 0X3, /* 0x08 CE Default 0x03 */ + 0X88, + 0X59, + 0X2E, + 0X19, + 0X8B, + 0X3A, + 0X63, + 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0X48, + 0X40, + 0XD2, + 0X80, + 0X40, + 0, + 0, }, + { 0X80, 0X63, 0X63, 0X84, 0X69, 0X1A, 0XEC, 0XF0, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X5C, 0, 0X57, 0, 0, 0X57, 0XED, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0X27, 0X1F, 0X1F, 0X27, 0XE3, 0X34, 0X48, 0XD6, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X5C, 0X5D, 0, 0, 0, 0, 0, 0X32, 0X64, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X27, 0X1F, 0X1F, 0X27, 0XE3, 0X34, 0X48, 0XD6, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X5C, 0X5D, 0, 0, 0, 0, 0, 0X64, 0XC8, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X27, 0X1F, 0X1F, 0X27, 0XE3, 0X34, 0X48, 0XD6, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X5C, 0X5D, 0, 0, 0, 0, 0, 0XC8, 0X90, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X5A84, 0, 0, 0, 0, 0, 0, 0 }, + { 0X2, 0X811, 0X5117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + + { "800x600", 800, 600, TVTYPE_PAL, + { 0XC3, 0X7F, 0XE0, 0X8F, 0X39, 0X3F, 0X38, 0X70, 0X3, 0X81, 0X21, 0X56, 0X1F, 0X87, 0X28, 0X18, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80, + 0X40, 0, 0, }, + { 0X73, 0X63, 0X63, 0X97, 0X67, 0X91, 0XEC, 0XF0, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X7E, 0, 0X57, 0, 0, 0X57, 0XED, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0X20, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0XBF, 0X1F, 0X1F, 0XBF, 0XDB, 0X33, 0X38, 0X8E, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X74, 0X4D, 0, 0, 0, 0, 0, 0X32, 0X64, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XBF, 0X1F, 0X1F, 0XBF, 0XDB, 0X33, 0X38, 0X8E, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X74, 0X4D, 0, 0, 0, 0, 0, 0X64, 0XC8, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XBF, 0X1F, 0X1F, 0XBF, 0XDB, 0X33, 0X38, 0X8E, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X74, 0X4D, 0, 0, 0, 0, 0, 0XC8, 0X90, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X3A84, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + +/*check these two modes*/ + { "1024x768", 1024, 768, TVTYPE_NTSC, + { 0XEE, + 0X3F, /* 0x01 FF Default 0x27 (was 7F) */ + 0X7E, + 0X87, + 0X49, + 0X32, + 0X9, + 0X83, + 0X3, + 0X88, + 0X47, + 0X4D, + 0X1B, + 0XE4, + 0X89, + 0X51, + 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0X48, + 0X40, + 0XD2, + 0X80, + 0X40, + 0, + 0, }, + { 0X8C, 0X7F, 0X7F, 0X90, 0X81, 0X8, 0XAF, 0XF5, 0, 0X60, 0, 0, 0, 0, 0, 0, 0XC, 0, 0XFF, 0, 0, 0XFF, 0XB0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0X40, 0X80, 0XE, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0X87, 0XFF, 0XFF, 0X87, 0X23, 0X34, 0X9, 0X3F, 0XB0, 0XFF, 0XFF, 0XB0, 0X9A, 0X13, 0XC, 0X7A, 0, 0, 0, 0, 0, 0X40, 0X80, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X87, 0XFF, 0XFF, 0X87, 0X23, 0X34, 0X9, 0X3F, 0XB0, 0XFF, 0XFF, 0XB0, 0X9A, 0X13, 0XC, 0X7A, 0, 0, 0, 0, 0, 0X80, 0, 0X41, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X87, 0XFF, 0XFF, 0X87, 0X23, 0X34, 0X9, 0X3F, 0XB0, 0XFF, 0XFF, 0XB0, 0X9A, 0X13, 0XC, 0X7A, 0, 0, 0, 0, 0, 0, 0, 0X86, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X4A84, 0, 0, 0, 0, 0, 0, 0 }, + { 0X2, 0X811, 0X6717, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + + { "1024x768", 1024, 768, TVTYPE_PAL, + { 0XE5, 0X7F, 0XE0, 0X8F, 0XC1, 0X3E, 0X4A, 0X70, 0, 0X81, 0X7, 0X2A, 0X20, 0X6D, 0XC2, 0XD7, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80, + 0X40, 0, 0, }, + { 0XAA, 0X7F, 0X7F, 0X8E, 0X83, 0X97, 0XE6, 0XF5, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X11, 0, 0XFF, 0, 0, 0XFF, 0XE7, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0X40, 0X80, 0XE, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XBE, 0XE7, 0XFF, 0XFF, 0XE7, 0X9A, 0X13, 0X7, 0X7B, 0, 0, 0, 0, 0, 0X40, 0X80, 0, 0, 0, 0X80, 0X20, 0X8E, 0, 0, 0 }, + { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XBE, 0XE7, 0XFF, 0XFF, 0XE7, 0X9A, 0X13, 0X7, 0X7B, 0, 0, 0, 0, 0, 0X80, 0, 0X41, 0, 0, 0X80, 0X20, 0X8E, 0, 0, 0 }, + { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XBE, 0XE7, 0XFF, 0XFF, 0XE7, 0X9A, 0X13, 0X7, 0X7B, 0, 0, 0, 0, 0, 0, 0, 0X86, 0, 0, 0X80, 0X20, 0X8E, 0, 0, 0 }, + { 0XC284, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + + { "640x480Over", 640, 480, TVTYPE_NTSC, + { 0X69, /* 0x00 DM Mode 16 640x480 1/1 */ + 0X3F, /* 0x01 FF Default 0x27 (was 7F) */ + 0X7E, /* 0x02 VBW Default 0xBE (was 7E) */ + 0X03, /* 0x03 TE Decent text 0x83 (was 8D) */ + 0X18, /* 0x04 SAV Default 0x50 (was 10) */ + 0X19, /* 0x05 HP Default 0x50 */ + 0XFB, /* 0x06 VP Default 0x00 */ + 0X83, /* 0x07 BL Default 0x83 (NTSC-J 66) */ + 0X03, /* 0x08 CE Default 0x03 */ + 0X80, /* 0x09 TPC Default 0x80 */ + 0X3F, /* 0x0A PLLM Default 0x3F */ + 0X6E, /* 0x0B PLLN Default 0x7E */ + 0X25, /* 0x0C FSCI Default 0x25 */ + 0X24, /* 0x0D FSCI Default 0x24 */ + 0X92, /* 0x0E FSCI Default 0x9C (was 92) */ + 0X49, /* 0x0F FSCI Default 0x7A (was 49) */ + 0X00, /* 0x10 CIVC Default 0x01 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* We don't touch these */ + 0X48, /* 0x1C CM Default 0x00 */ + 0X40, /* 0x1D IC Default 0x88 */ + 0XD2, /* 0x1E GPIO Default 0xC0 */ + 0X80, /* 0x1F IDF Default 0x00 */ + 0X40, /* 0x20 CD */ + 0X00, /* 0x21 DC */ + 0X00, /* 0x22 BCO Default 0x00 */ }, +/* why is this #ifed, what's the difference? */ +#if 0 + { 0X55, 0X4F, 0X4F, 0X99, 0X51, 0X18, 0X2E, 0X3E, 0, 0X40, 0, 0, 0, 0, 0, 0, 0XE7, 0, 0XDF, 0, 0, 0XDF, 0X2F, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0X20, 0X40, 0, 0, 0X87, 0X1C, 0, 0 }, + { 0, 0, 0, 0X87, 0X1C, 0, 0, 0 }, + { 0XCF, 0X7F, 0X7F, 0XCF, 0X92, 0X22, 0X87, 0XBC, 0X2F, 0XDF, 0XDF, 0X2F, 0X11, 0XA, 0XFF, 0X24, 0, 0, 0, 0, 0, 0X28, 0X50, 0, 0, 0, 0X80, 0, 0X80, 0, 0, 0 }, + { 0XCF, 0X7F, 0X7F, 0XCF, 0X92, 0X22, 0X87, 0XBC, 0X2F, 0XDF, 0XDF, 0X2F, 0X11, 0XA, 0XFF, 0X24, 0, 0, 0, 0, 0, 0X50, 0XA0, 0X40, 0, 0, 0X80, 0, 0X80, 0, 0, 0 }, + { 0XCF, 0X7F, 0X7F, 0XCF, 0X92, 0X22, 0X87, 0XBC, 0X2F, 0XDF, 0XDF, 0X2F, 0X11, 0XA, 0XFF, 0X24, 0, 0, 0, 0, 0, 0XA0, 0X40, 0X81, 0, 0, 0X80, 0, 0X80, 0, 0, 0 }, + { 0X7107, 0, 0, 0, 0, 0, 0, 0 }, + { 0X3, 0X811, 0XF416, 0X9F17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, +#else + { 0X5D, 0X4F, 0X4F, 0X81, 0X52, 0X9E, 0XB, 0X3E, 0, 0X60, 0, 0, 0, 0, 0, 0, 0XEE, 0, 0XDF, 0, 0, 0XDF, 0XC, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0X20, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0XF, 0X7F, 0X7F, 0XF, 0X9A, 0X23, 0X8F, 0XFF, 0XC, 0XDF, 0XDF, 0XC, 0X11, 0XA, 0XEE, 0X31, 0, 0, 0, 0, 0, 0X28, 0X50, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XF, 0X7F, 0X7F, 0XF, 0X9A, 0X23, 0X8F, 0XFF, 0XC, 0XDF, 0XDF, 0XC, 0X11, 0XA, 0XEE, 0X31, 0, 0, 0, 0, 0, 0X50, 0XA0, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XF, 0X7F, 0X7F, 0XF, 0X9A, 0X23, 0X8F, 0XFF, 0XC, 0XDF, 0XDF, 0XC, 0X11, 0XA, 0XEE, 0X31, 0, 0, 0, 0, 0, 0XA0, 0X40, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X1184, 0, 0, 0, 0, 0, 0, 0 }, + { 0X2, 0X811, 0XAD17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, +#endif + }, + + { "640x480Over", 640, 480, TVTYPE_PAL, + { 0X60, /* 0x00 DM Mode 13 PAL 640x480 OS 5/4 */ + 0X27, /* 0x01 FF Default 0x27 (was 7F) */ + 0XBE, /* 0x02 VBW Default 0xBE (was 7E) */ + 0X83, /* 0x03 TE Decent text 0x8B (was 8D) */ + 0X10, /* 0x04 SAV Default 0x50 */ + 0X19, /* 0x05 HP Default 0x50 */ + 0XFB, /* 0x06 VP Default 0x00 */ + 0X83, /* 0x07 BL Default 0x83 */ + 0X01, /* 0x08 CE Default 0x03 */ + 0X81, /* 0x09 TPC Default 0x80 */ + 0X0D, /* 0x0A PLLM Default 0x3F */ + 0X0B, /* 0x0B PLLN Default 0x7E */ + 0X30, /* 0x0C FSCI Default 0x25 */ + 0X0A, /* 0x0D FSCI Default 0x24 */ + 0XE7, /* 0x0E FSCI Default 0x9C */ + 0XC4, /* 0x0F FSCI Default 0x7A */ + 0X00, /* 0x10 CIVC Default 0x01 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* We don't touch these */ + 0X48, /* 0x1C CM Default 0x00 */ + 0X40, /* 0x1D IC Default 0x88 */ + 0XD2, /* 0x1E GPIO Default 0xC0 */ + 0X80, /* 0x1F IDF Default 0x00 */ + 0X40, /* 0x20 CD */ + 0X00, /* 0x21 DC */ + 0X00, /* 0x22 BCO Default 0x00 */ }, + { 0X64, 0X4F, 0X4F, 0X88, 0X53, 0X83, 0XF2, 0X1F, 0, 0X40, 0, 0, 0, 0, 0, 0, 0XE5, 0, 0XDF, 0, 0, 0XDF, 0XF3, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0X20, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0X47, 0X7F, 0X7F, 0X47, 0X9A, 0X23, 0X95, 0XFF, 0XF3, 0XDF, 0XDF, 0XF3, 0X9, 0X9, 0XE5, 0X40, 0, 0, 0, 0, 0, 0X28, 0X50, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X47, 0X7F, 0X7F, 0X47, 0X9A, 0X23, 0X95, 0XFF, 0XF3, 0XDF, 0XDF, 0XF3, 0X9, 0X9, 0XE5, 0X40, 0, 0, 0, 0, 0, 0X50, 0XA0, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X47, 0X7F, 0X7F, 0X47, 0X9A, 0X23, 0X95, 0XFF, 0XF3, 0XDF, 0XDF, 0XF3, 0X9, 0X9, 0XE5, 0X40, 0, 0, 0, 0, 0, 0XA0, 0X40, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X3184, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + + { "800x600Over", 800, 600, TVTYPE_NTSC, + { 0XCE, /* 0x00 Mode 28 */ + 0X27, /* 0x01 Default 0x27 (was 7F) */ + 0XBE, /* 0x02 Default 0xBE (was 76) */ + 0X8F, /* 0x03 */ + 0X51, /* 0x04 */ + 0X2E, /* 0x05 */ + 0X10, /* 0x06 */ + 0X83, /* 0x07 */ + 0X3, /* 0x08 */ + 0X81, /* 0x09 */ + 0X13, /* 0x0A */ + 0X3E, /* 0x0B */ + 0X1C, /* 0x0C */ + 0, /* 0x0D */ + 0, /* 0x0E */ + 0, /* 0x0F */ + 0, /* 0x10 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0X48, + 0X40, + 0XD2, + 0X80, + 0X40, 0, 0, }, + { 0X7D, 0X63, 0X63, 0X81, 0X69, 0X18, 0XBA, 0XF0, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X5A, 0, 0X57, 0, 0, 0X57, 0XBB, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0XF, 0X1F, 0X1F, 0XF, 0XE3, 0X34, 0X44, 0XC6, 0XBB, 0X57, 0X57, 0XBB, 0X52, 0X12, 0X3F, 0X59, 0, 0, 0, 0, 0, 0X32, 0X64, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XF, 0X1F, 0X1F, 0XF, 0XE3, 0X34, 0X44, 0XC6, 0XBB, 0X57, 0X57, 0XBB, 0X52, 0X12, 0X3F, 0X59, 0, 0, 0, 0, 0, 0X64, 0XC8, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XF, 0X1F, 0X1F, 0XF, 0XE3, 0X34, 0X44, 0XC6, 0XBB, 0X57, 0X57, 0XBB, 0X52, 0X12, 0X3F, 0X59, 0, 0, 0, 0, 0, 0XC8, 0X90, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X5284, 0, 0, 0, 0, 0, 0, 0 }, + { 0X2, 0X811, 0XD017, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + + { "800x600Over", 800, 600, TVTYPE_PAL, + { 0XC1, 0X7F, 0XE0, 0X8F, 0X20, 0X1D, 0X36, 0X70, 0X3, 0X94, 0X39, 0X87, 0X26, 0X79, 0X8C, 0XC, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80, + 0X40, 0, 0, }, + { 0X71, 0X63, 0X63, 0X95, 0X67, 0X90, 0X6F, 0XF0, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X57, 0, 0X57, 0, 0, 0X57, 0X70, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0X20, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0XAF, 0X1F, 0X1F, 0XAF, 0XDB, 0X33, 0X35, 0X8E, 0X70, 0X57, 0X57, 0X70, 0X52, 0X12, 0X57, 0X5A, 0, 0, 0, 0, 0, 0X32, 0X64, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XAF, 0X1F, 0X1F, 0XAF, 0XDB, 0X33, 0X35, 0X8E, 0X70, 0X57, 0X57, 0X70, 0X52, 0X12, 0X57, 0X5A, 0, 0, 0, 0, 0, 0X64, 0XC8, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XAF, 0X1F, 0X1F, 0XAF, 0XDB, 0X33, 0X35, 0X8E, 0X70, 0X57, 0X57, 0X70, 0X52, 0X12, 0X57, 0X5A, 0, 0, 0, 0, 0, 0XC8, 0X90, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X2184, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + + { "1024x768Over", 1024, 768, TVTYPE_NTSC, + { 0XED, + 0X3F, /* 0x01 FF Default 0x27 (was 7F) */ + 0X7E, + 0X87, + 0X49, + 0X20, + 0, + 0X83, + 0X3, + 0X90, + 0X89, + 0X35, + 0X1F, + 0X61, + 0X1A, + 0X7C, + 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0X48, + 0X40, + 0XD2, + 0X80, + 0X40, + 0, + 0, }, + { 0X8C, 0X7F, 0X7F, 0X90, 0X81, 0X8, 0X46, 0XF5, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X4, 0, 0XFF, 0, 0, 0XFF, 0X47, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0X87, 0XFF, 0XFF, 0X87, 0X23, 0X34, 0X9, 0X38, 0X47, 0XFF, 0XFF, 0X47, 0X9A, 0X13, 0X4, 0X6F, 0, 0, 0, 0, 0, 0X40, 0X80, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X87, 0XFF, 0XFF, 0X87, 0X23, 0X34, 0X9, 0X38, 0X47, 0XFF, 0XFF, 0X47, 0X9A, 0X13, 0X4, 0X6F, 0, 0, 0, 0, 0, 0X80, 0, 0X41, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X87, 0XFF, 0XFF, 0X87, 0X23, 0X34, 0X9, 0X38, 0X47, 0XFF, 0XFF, 0X47, 0X9A, 0X13, 0X4, 0X6F, 0, 0, 0, 0, 0, 0, 0, 0X86, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X5084, 0, 0, 0, 0, 0, 0, 0 }, + { 0X2, 0X811, 0X4517, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + + { "1024x768Over", 1024, 768, TVTYPE_PAL, + { 0XE4, 0X7F, 0XA0, 0X8F, 0XB1, 0X28, 0X37, 0X70, 0, 0X81, 0X10, 0X4C, 0X25, 0XF, 0XBA, 0X1B, + 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80, + 0X40, 0, 0, }, + { 0XAA, 0X7F, 0X7F, 0X8E, 0X84, 0X97, 0X69, 0XF5, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X7, 0, 0XFF, 0, 0, 0XFF, 0X6A, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XB7, 0X6A, 0XFF, 0XFF, 0X6A, 0X9A, 0X13, 0X7, 0X77, 0, 0, 0, 0, 0, 0X40, 0X80, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XB7, 0X6A, 0XFF, 0XFF, 0X6A, 0X9A, 0X13, 0X7, 0X77, 0, 0, 0, 0, 0, 0X80, 0, 0X41, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XB7, 0X6A, 0XFF, 0XFF, 0X6A, 0X9A, 0X13, 0X7, 0X77, 0, 0, 0, 0, 0, 0, 0, 0X86, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XB184, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + + { "720x480", 720, 480, TVTYPE_NTSC, + { 0X89, /* 0x00 DM Mode 19 720x480 1/1 */ + 0X3F, /* 0x01 FF Default 0x27 (was 7F) */ + 0X7E, /* 0x02 VBW Default 0xBE (was 7E) */ + 0X03, /* 0x03 TE Decent text 0x83 (was 8D) */ + 0X18, /* 0x04 SAV Default 0x50 (was 10) */ + 0X19, /* 0x05 HP Default 0x50 */ + 0XFB, /* 0x06 VP Default 0x00 */ + 0X83, /* 0x07 BL Default 0x83 (NTSC-J 66) */ + 0X03, /* 0x08 CE Default 0x03 */ + 0X80, /* 0x09 TPC Default 0x80 */ + 0X3F, /* 0x0A PLLM Default 0x3F */ + 0X7C, /* 0x0B PLLN Default 0x7C */ + 0X21, /* 0x0C FSCI Default 0x25 */ + 0X04, /* 0x0D FSCI Default 0x04 */ + 0X10, /* 0x0E FSCI Default 0x10 */ + 0X41, /* 0x0F FSCI Default 0x41 */ + 0X00, /* 0x10 CIVC Default 0x01 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* We don't touch these */ + 0X48, /* 0x1C CM Default 0x00 */ + 0X40, /* 0x1D IC Default 0x88 */ + 0XD2, /* 0x1E GPIO Default 0xC0 */ + 0X80, /* 0x1F IDF Default 0x00 */ + 0X40, /* 0x20 CD */ + 0X00, /* 0x21 DC */ + 0X00, /* 0x22 BCO Default 0x00 */ }, + { 0X64, 0X59, 0X59, 0X88, 0X5B, 0X81, 0X56, 0X3E, 0, 0X40, 0, 0, 0, 0, 0, 0, 0XFF, 0, 0XDF, 0, 0, 0XDF, 0X57, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0X20, 0X40, 0, 0X4, 0X87, 0X1C, 0, 0 }, + { 0, 0, 0, 0X87, 0X1C, 0, 0, 0 }, + { 0X47, 0XCF, 0XCF, 0X47, 0X9A, 0X23, 0XD9, 0XA, 0X57, 0XDF, 0XDF, 0X57, 0X51, 0XA, 0XFF, 0X3B, 0, 0, 0, 0, 0, 0X2D, 0X5A, 0, 0, 0, 0X80, 0, 0X80, 0, 0, 0 }, + { 0X47, 0XCF, 0XCF, 0X47, 0X9A, 0X23, 0XD9, 0XA, 0X57, 0XDF, 0XDF, 0X57, 0X51, 0XA, 0XFF, 0X3B, 0, 0, 0, 0, 0, 0X5A, 0XB4, 0X40, 0, 0, 0X80, 0, 0X80, 0, 0, 0 }, + { 0X47, 0XCF, 0XCF, 0X47, 0X9A, 0X23, 0XD9, 0XA, 0X57, 0XDF, 0XDF, 0X57, 0X51, 0XA, 0XFF, 0X3B, 0, 0, 0, 0, 0, 0XB4, 0X68, 0X81, 0, 0, 0X80, 0, 0X80, 0, 0, 0 }, + { 0X6E07, 0, 0, 0, 0, 0, 0, 0 }, + { 0X3, 0X811, 0XC316, 0X4C17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + +/* don't we want 720x576 for pal? */ + { "720x480", 720, 480, TVTYPE_PAL, + { 0XE4, 0X7F, 0XA0, 0X8F, 0XB1, 0X28, 0X37, 0X70, 0, 0X81, 0X10, 0X4C, 0X25, 0XF, 0XBA, 0X1B, + 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80, + 0X40, 0, 0, }, + { 0XAA, 0X7F, 0X7F, 0X8E, 0X84, 0X97, 0X69, 0XF5, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X7, 0, 0XFF, 0, 0, 0XFF, 0X6A, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XB7, 0X6A, 0XFF, 0XFF, 0X6A, 0X9A, 0X13, 0X7, 0X77, 0, 0, 0, 0, 0, 0X40, 0X80, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XB7, 0X6A, 0XFF, 0XFF, 0X6A, 0X9A, 0X13, 0X7, 0X77, 0, 0, 0, 0, 0, 0X80, 0, 0X41, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XB7, 0X6A, 0XFF, 0XFF, 0X6A, 0X9A, 0X13, 0X7, 0X77, 0, 0, 0, 0, 0, 0, 0, 0X86, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XB184, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, +}; + +static struct CH7xxxTableRec +CH7019Table[] = { + { "640x480", 640, 480, TVTYPE_NTSC, + { 0X6A, 0X7F, 0X7E, 0X8D, 0X21, 0X2E, 0X4, 0X83, 0X3, 0X80, 0X3F, 0X7E, 0X20, 0X80, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80, + 0X40, 0, 0 }, + { 0X5D, 0X4F, 0X4F, 0X81, 0X52, 0X9E, 0X56, 0XBA, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X8, 0, 0XDF, 0, 0, 0XDF, 0X57, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0X20, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0XF, 0X7F, 0X7F, 0XF, 0X9A, 0X23, 0X8F, 0XEF, 0X57, 0XDF, 0XDF, 0X57, 0X11, 0XA, 0X8, 0X50, 0, 0, 0, 0, 0, 0X28, 0X50, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XF, 0X7F, 0X7F, 0XF, 0X9A, 0X23, 0X8F, 0XEF, 0X57, 0XDF, 0XDF, 0X57, 0X11, 0XA, 0X8, 0X50, 0, 0, 0, 0, 0, 0X50, 0XA0, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XF, 0X7F, 0X7F, 0XF, 0X9A, 0X23, 0X8F, 0XEF, 0X57, 0XDF, 0XDF, 0X57, 0X11, 0XA, 0X8, 0X50, 0, 0, 0, 0, 0, 0XA0, 0X40, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X2284, 0, 0, 0, 0, 0, 0, 0 }, + { 0X2, 0X811, 0X9217, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + + { "640x480", 640, 480, TVTYPE_PAL, + { 0X61, 0X7F, 0XE0, 0X8F, 0X31, 0X35, 0X33, 0X6E, 0X3, 0X81, 0X4, 0X9, 0X26, 0X6F, 0X1F, 0XD0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0X48, 0X40, 0XD2, 0X80, + 0X40, 0, 0 }, + { 0X64, 0X4F, 0X4F, 0X88, 0X53, 0X83, 0X6F, 0XBA, 0, 0X40, 0, 0, 0, 0, 0, 0, 0X11, 0, 0XDF, 0, 0, 0XDF, 0X70, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0X20, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0X47, 0X7F, 0X7F, 0X47, 0X9A, 0X23, 0X95, 0X1E, 0X70, 0XDF, 0XDF, 0X70, 0X51, 0XA, 0X11, 0X5D, 0, 0, 0, 0, 0, 0X28, 0X50, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X47, 0X7F, 0X7F, 0X47, 0X9A, 0X23, 0X95, 0X1E, 0X70, 0XDF, 0XDF, 0X70, 0X51, 0XA, 0X11, 0X5D, 0, 0, 0, 0, 0, 0X50, 0XA0, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X47, 0X7F, 0X7F, 0X47, 0X9A, 0X23, 0X95, 0X1E, 0X70, 0XDF, 0XDF, 0X70, 0X51, 0XA, 0X11, 0X5D, 0, 0, 0, 0, 0, 0XA0, 0X40, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X3284, 0, 0, 0, 0, 0, 0, 0 }, + }, + + { "800x600", 800, 600, TVTYPE_NTSC, + { 0XCF, 0X7F, 0X76, 0X8F, 0X59, 0X3C, 0X15, 0X83, 0X3, 0X88, 0X59, 0X2E, 0X19, 0X8B, 0X3A, 0X63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80, + 0X40, 0, 0}, + { 0X80, 0X63, 0X63, 0X84, 0X69, 0X1A, 0XEC, 0XF0, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X5C, 0, 0X57, 0, 0, 0X57, 0XED, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0X27, 0X1F, 0X1F, 0X27, 0XE3, 0X34, 0X48, 0XD6, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X5C, 0X5D, 0, 0, 0, 0, 0, 0X32, 0X64, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X27, 0X1F, 0X1F, 0X27, 0XE3, 0X34, 0X48, 0XD6, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X5C, 0X5D, 0, 0, 0, 0, 0, 0X64, 0XC8, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X27, 0X1F, 0X1F, 0X27, 0XE3, 0X34, 0X48, 0XD6, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X5C, 0X5D, 0, 0, 0, 0, 0, 0XC8, 0X90, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X5A84, 0, 0, 0, 0, 0, 0, 0 }, + { 0X2, 0X811, 0X5117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + + { "800x600", 800, 600, TVTYPE_PAL, + { 0XC3, 0X7F, 0XE0, 0X8F, 0X39, 0X3F, 0X38, 0X70, 0X3, 0X81, 0X21, 0X56, 0X1F, 0X87, 0X28, 0X18, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80, + 0X40, 0, 0}, + { 0X73, 0X63, 0X63, 0X97, 0X67, 0X91, 0XEC, 0XF0, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X7E, 0, 0X57, 0, 0, 0X57, 0XED, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0X20, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0XBF, 0X1F, 0X1F, 0XBF, 0XDB, 0X33, 0X38, 0X8E, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X74, 0X4D, 0, 0, 0, 0, 0, 0X32, 0X64, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XBF, 0X1F, 0X1F, 0XBF, 0XDB, 0X33, 0X38, 0X8E, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X74, 0X4D, 0, 0, 0, 0, 0, 0X64, 0XC8, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XBF, 0X1F, 0X1F, 0XBF, 0XDB, 0X33, 0X38, 0X8E, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X74, 0X4D, 0, 0, 0, 0, 0, 0XC8, 0X90, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X3A84, 0, 0, 0, 0, 0, 0, 0 }, + }, + + { "1024x768", 1024, 768, TVTYPE_NTSC, + { 0XEE, 0X7F, 0X7E, 0X87, 0X49, 0X32, 0X9, 0X83, 0X3, 0X88, 0X47, 0X4D, 0X1B, 0XE4, 0X89, 0X51, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80, + 0X40, 0, 0}, + { 0X8C, 0X7F, 0X7F, 0X90, 0X81, 0X8, 0XAF, 0XF5, 0, 0X60, 0, 0, 0, 0, 0, 0, 0XC, 0, 0XFF, 0, 0, 0XFF, 0XB0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0X40, 0X80, 0XE, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0X87, 0XFF, 0XFF, 0X87, 0X23, 0X34, 0X9, 0X3F, 0XB0, 0XFF, 0XFF, 0XB0, 0X9A, 0X13, 0XC, 0X7A, 0, 0, 0, |